2006-11-25 09:33:55 -07:00
|
|
|
/*
|
|
|
|
|
|
|
|
Copyright 1986, 1998 The Open Group
|
|
|
|
|
|
|
|
Permission to use, copy, modify, distribute, and sell this software and its
|
|
|
|
documentation for any purpose is hereby granted without fee, provided that
|
|
|
|
the above copyright notice appear in all copies and that both that
|
|
|
|
copyright notice and this permission notice appear in supporting
|
|
|
|
documentation.
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
|
|
|
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
|
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
|
|
|
|
Except as contained in this notice, the name of The Open Group shall not be
|
|
|
|
used in advertising or otherwise to promote the sale, use or other dealings
|
|
|
|
in this Software without prior written authorization from The Open Group.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include <config.h>
|
|
|
|
#endif
|
|
|
|
#include "Xlibint.h"
|
2019-08-04 07:34:52 -06:00
|
|
|
#include "reallocarray.h"
|
2013-05-23 16:42:07 -06:00
|
|
|
#include <limits.h>
|
2006-11-25 09:33:55 -07:00
|
|
|
|
2013-04-28 10:55:55 -06:00
|
|
|
#if defined(XF86BIGFONT)
|
2006-11-25 09:33:55 -07:00
|
|
|
#define USE_XF86BIGFONT
|
|
|
|
#endif
|
|
|
|
#ifdef USE_XF86BIGFONT
|
|
|
|
extern void _XF86BigfontFreeFontMetrics(
|
|
|
|
XFontStruct* /* fs */
|
|
|
|
);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
char **XListFontsWithInfo(
|
|
|
|
register Display *dpy,
|
|
|
|
_Xconst char *pattern, /* null-terminated */
|
|
|
|
int maxNames,
|
|
|
|
int *actualCount, /* RETURN */
|
|
|
|
XFontStruct **info) /* RETURN */
|
2009-05-03 06:59:09 -06:00
|
|
|
{
|
2013-05-23 16:42:07 -06:00
|
|
|
unsigned long nbytes;
|
|
|
|
unsigned long reply_left; /* unused data left in reply buffer */
|
2006-11-25 09:33:55 -07:00
|
|
|
register int i;
|
|
|
|
register XFontStruct *fs;
|
2013-05-23 16:42:07 -06:00
|
|
|
unsigned int size = 0;
|
2006-11-25 09:33:55 -07:00
|
|
|
XFontStruct *finfo = NULL;
|
|
|
|
char **flist = NULL;
|
|
|
|
xListFontsWithInfoReply reply;
|
|
|
|
register xListFontsReq *req;
|
|
|
|
int j;
|
|
|
|
|
|
|
|
LockDisplay(dpy);
|
|
|
|
GetReq(ListFontsWithInfo, req);
|
|
|
|
req->maxNames = maxNames;
|
|
|
|
nbytes = req->nbytes = pattern ? strlen (pattern) : 0;
|
|
|
|
req->length += (nbytes + 3) >> 2;
|
|
|
|
_XSend (dpy, pattern, nbytes);
|
|
|
|
/* use _XSend instead of Data, since subsequent _XReply will flush buffer */
|
|
|
|
|
|
|
|
for (i = 0; ; i++) {
|
|
|
|
if (!_XReply (dpy, (xReply *) &reply,
|
2009-05-03 06:59:09 -06:00
|
|
|
((SIZEOF(xListFontsWithInfoReply) -
|
2006-11-25 09:33:55 -07:00
|
|
|
SIZEOF(xGenericReply)) >> 2), xFalse)) {
|
2013-05-23 16:42:07 -06:00
|
|
|
reply.nameLength = 0; /* avoid trying to read more replies */
|
|
|
|
reply_left = 0;
|
|
|
|
goto badmem;
|
2006-11-25 09:33:55 -07:00
|
|
|
}
|
2013-05-23 16:42:07 -06:00
|
|
|
reply_left = reply.length -
|
|
|
|
((SIZEOF(xListFontsWithInfoReply) - SIZEOF(xGenericReply)) >> 2);
|
|
|
|
if (reply.nameLength == 0) {
|
|
|
|
_XEatDataWords(dpy, reply_left);
|
2006-11-25 09:33:55 -07:00
|
|
|
break;
|
2013-05-23 16:42:07 -06:00
|
|
|
}
|
|
|
|
if (reply.nReplies >= (INT_MAX - i)) /* avoid overflowing size */
|
|
|
|
goto badmem;
|
2006-11-25 09:33:55 -07:00
|
|
|
if ((i + reply.nReplies) >= size) {
|
|
|
|
size = i + reply.nReplies + 1;
|
|
|
|
|
2013-05-23 16:42:07 -06:00
|
|
|
if (size >= (INT_MAX / sizeof(XFontStruct)))
|
|
|
|
goto badmem;
|
|
|
|
|
2006-11-25 09:33:55 -07:00
|
|
|
if (finfo) {
|
2013-05-23 16:42:07 -06:00
|
|
|
XFontStruct * tmp_finfo;
|
|
|
|
char ** tmp_flist;
|
2006-11-25 09:33:55 -07:00
|
|
|
|
2019-08-04 07:34:52 -06:00
|
|
|
tmp_finfo = Xreallocarray (finfo, size, sizeof(XFontStruct));
|
2013-04-28 10:55:55 -06:00
|
|
|
if (tmp_finfo)
|
|
|
|
finfo = tmp_finfo;
|
2013-05-23 16:42:07 -06:00
|
|
|
else
|
|
|
|
goto badmem;
|
|
|
|
|
2019-08-04 07:34:52 -06:00
|
|
|
tmp_flist = Xreallocarray (flist, size + 1, sizeof(char *));
|
2013-04-28 10:55:55 -06:00
|
|
|
if (tmp_flist)
|
|
|
|
flist = tmp_flist;
|
2013-05-23 16:42:07 -06:00
|
|
|
else
|
|
|
|
goto badmem;
|
2006-11-25 09:33:55 -07:00
|
|
|
}
|
|
|
|
else {
|
2019-08-04 07:34:52 -06:00
|
|
|
if (! (finfo = Xmallocarray(size, sizeof(XFontStruct))))
|
2006-11-25 09:33:55 -07:00
|
|
|
goto clearwire;
|
2019-08-04 07:34:52 -06:00
|
|
|
if (! (flist = Xmallocarray(size + 1, sizeof(char *)))) {
|
2013-09-28 11:03:13 -06:00
|
|
|
Xfree(finfo);
|
2006-11-25 09:33:55 -07:00
|
|
|
goto clearwire;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fs = &finfo[i];
|
|
|
|
|
|
|
|
fs->ext_data = NULL;
|
|
|
|
fs->per_char = NULL;
|
|
|
|
fs->fid = None;
|
|
|
|
fs->direction = reply.drawDirection;
|
|
|
|
fs->min_char_or_byte2 = reply.minCharOrByte2;
|
|
|
|
fs->max_char_or_byte2 = reply.maxCharOrByte2;
|
|
|
|
fs->min_byte1 = reply.minByte1;
|
|
|
|
fs->max_byte1 = reply.maxByte1;
|
|
|
|
fs->default_char = reply.defaultChar;
|
|
|
|
fs->all_chars_exist = reply.allCharsExist;
|
|
|
|
fs->ascent = cvtINT16toInt (reply.fontAscent);
|
|
|
|
fs->descent = cvtINT16toInt (reply.fontDescent);
|
2009-05-03 06:59:09 -06:00
|
|
|
|
2006-11-25 09:33:55 -07:00
|
|
|
/* XXX the next two statements won't work if short isn't 16 bits */
|
|
|
|
fs->min_bounds = * (XCharStruct *) &reply.minBounds;
|
|
|
|
fs->max_bounds = * (XCharStruct *) &reply.maxBounds;
|
|
|
|
|
|
|
|
fs->n_properties = reply.nFontProps;
|
2013-05-23 16:42:07 -06:00
|
|
|
fs->properties = NULL;
|
2006-11-25 09:33:55 -07:00
|
|
|
if (fs->n_properties > 0) {
|
2013-05-23 16:42:07 -06:00
|
|
|
/* nFontProps is a CARD16 */
|
2006-11-25 09:33:55 -07:00
|
|
|
nbytes = reply.nFontProps * SIZEOF(xFontProp);
|
2013-05-23 16:42:07 -06:00
|
|
|
if ((nbytes >> 2) <= reply_left) {
|
2019-08-04 07:34:52 -06:00
|
|
|
fs->properties = Xmallocarray (reply.nFontProps,
|
|
|
|
sizeof(XFontProp));
|
2013-05-23 16:42:07 -06:00
|
|
|
}
|
|
|
|
if (! fs->properties)
|
|
|
|
goto badmem;
|
2006-11-25 09:33:55 -07:00
|
|
|
_XRead32 (dpy, (long *)fs->properties, nbytes);
|
2013-05-23 16:42:07 -06:00
|
|
|
reply_left -= (nbytes >> 2);
|
|
|
|
}
|
2006-11-25 09:33:55 -07:00
|
|
|
|
2013-05-23 16:42:07 -06:00
|
|
|
/* nameLength is a CARD8 */
|
|
|
|
nbytes = reply.nameLength + 1;
|
2006-11-25 09:33:55 -07:00
|
|
|
if (!i)
|
2013-05-23 16:42:07 -06:00
|
|
|
nbytes++; /* make first string 1 byte longer, to match XListFonts */
|
|
|
|
flist[i] = Xmalloc (nbytes);
|
2006-11-25 09:33:55 -07:00
|
|
|
if (! flist[i]) {
|
2013-09-28 11:03:13 -06:00
|
|
|
if (finfo[i].properties) Xfree(finfo[i].properties);
|
2006-11-25 09:33:55 -07:00
|
|
|
goto badmem;
|
|
|
|
}
|
|
|
|
if (!i) {
|
|
|
|
*flist[0] = 0; /* zero to distinguish from XListFonts */
|
|
|
|
flist[0]++;
|
|
|
|
}
|
|
|
|
flist[i][reply.nameLength] = '\0';
|
|
|
|
_XReadPad (dpy, flist[i], (long) reply.nameLength);
|
|
|
|
}
|
|
|
|
*info = finfo;
|
|
|
|
*actualCount = i;
|
|
|
|
if (flist)
|
|
|
|
flist[i] = NULL; /* required in case XFreeFontNames is called */
|
|
|
|
UnlockDisplay(dpy);
|
|
|
|
SyncHandle();
|
|
|
|
return (flist);
|
|
|
|
|
|
|
|
|
|
|
|
badmem:
|
|
|
|
/* Free all memory allocated by this function. */
|
|
|
|
for (j=(i-1); (j >= 0); j--) {
|
2013-09-28 11:03:13 -06:00
|
|
|
if (j == 0)
|
|
|
|
flist[j]--; /* was incremented above */
|
|
|
|
Xfree(flist[j]);
|
|
|
|
if (finfo[j].properties) Xfree(finfo[j].properties);
|
2006-11-25 09:33:55 -07:00
|
|
|
}
|
2015-04-06 14:57:55 -06:00
|
|
|
Xfree(flist);
|
|
|
|
Xfree(finfo);
|
2006-11-25 09:33:55 -07:00
|
|
|
|
|
|
|
clearwire:
|
|
|
|
/* Clear the wire. */
|
2013-05-23 16:42:07 -06:00
|
|
|
_XEatDataWords(dpy, reply_left);
|
|
|
|
while ((reply.nameLength != 0) &&
|
|
|
|
_XReply(dpy, (xReply *) &reply,
|
|
|
|
((SIZEOF(xListFontsWithInfoReply) - SIZEOF(xGenericReply))
|
|
|
|
>> 2), xTrue));
|
2006-11-25 09:33:55 -07:00
|
|
|
UnlockDisplay(dpy);
|
|
|
|
SyncHandle();
|
2013-05-23 16:42:07 -06:00
|
|
|
*info = NULL;
|
|
|
|
*actualCount = 0;
|
2006-11-25 09:33:55 -07:00
|
|
|
return (char **) NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2007-09-30 04:11:57 -06:00
|
|
|
XFreeFontInfo (
|
|
|
|
char **names,
|
|
|
|
XFontStruct *info,
|
|
|
|
int actualCount)
|
2006-11-25 09:33:55 -07:00
|
|
|
{
|
|
|
|
register int i;
|
|
|
|
if (names) {
|
|
|
|
Xfree (names[0]-1);
|
|
|
|
for (i = 1; i < actualCount; i++) {
|
|
|
|
Xfree (names[i]);
|
|
|
|
}
|
2013-09-28 11:03:13 -06:00
|
|
|
Xfree(names);
|
2006-11-25 09:33:55 -07:00
|
|
|
}
|
|
|
|
if (info) {
|
|
|
|
for (i = 0; i < actualCount; i++) {
|
|
|
|
if (info[i].per_char)
|
|
|
|
#ifdef USE_XF86BIGFONT
|
|
|
|
_XF86BigfontFreeFontMetrics(&info[i]);
|
|
|
|
#else
|
2013-09-28 11:03:13 -06:00
|
|
|
Xfree (info[i].per_char);
|
2006-11-25 09:33:55 -07:00
|
|
|
#endif
|
|
|
|
if (info[i].properties)
|
2013-09-28 11:03:13 -06:00
|
|
|
Xfree (info[i].properties);
|
2006-11-25 09:33:55 -07:00
|
|
|
}
|
2013-09-28 11:03:13 -06:00
|
|
|
Xfree(info);
|
2006-11-25 09:33:55 -07:00
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|