FontNames.c revision bd8e7fb0
11ab64890Smrg/*
21ab64890Smrg
31ab64890SmrgCopyright 1986, 1998  The Open Group
41ab64890Smrg
51ab64890SmrgPermission to use, copy, modify, distribute, and sell this software and its
61ab64890Smrgdocumentation for any purpose is hereby granted without fee, provided that
71ab64890Smrgthe above copyright notice appear in all copies and that both that
81ab64890Smrgcopyright notice and this permission notice appear in supporting
91ab64890Smrgdocumentation.
101ab64890Smrg
111ab64890SmrgThe above copyright notice and this permission notice shall be included in
121ab64890Smrgall copies or substantial portions of the Software.
131ab64890Smrg
141ab64890SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
151ab64890SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
161ab64890SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
171ab64890SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
181ab64890SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
191ab64890SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
201ab64890Smrg
211ab64890SmrgExcept as contained in this notice, the name of The Open Group shall not be
221ab64890Smrgused in advertising or otherwise to promote the sale, use or other dealings
231ab64890Smrgin this Software without prior written authorization from The Open Group.
241ab64890Smrg
251ab64890Smrg*/
261ab64890Smrg
271ab64890Smrg
281ab64890Smrg#ifdef HAVE_CONFIG_H
291ab64890Smrg#include <config.h>
301ab64890Smrg#endif
311ab64890Smrg#include "Xlibint.h"
32eb411b4bSmrg#include <limits.h>
331ab64890Smrg
341ab64890Smrgchar **
351ab64890SmrgXListFonts(
361ab64890Smrgregister Display *dpy,
371ab64890Smrg_Xconst char *pattern,  /* null-terminated */
381ab64890Smrgint maxNames,
391ab64890Smrgint *actualCount)	/* RETURN */
4061b2299dSmrg{
411ab64890Smrg    register long nbytes;
421ab64890Smrg    register unsigned i;
431ab64890Smrg    register int length;
44eb411b4bSmrg    char **flist = NULL;
45eb411b4bSmrg    char *ch = NULL;
46c9e7fb8dSmrg    char *chstart;
47eb411b4bSmrg    char *chend;
48eb411b4bSmrg    int count = 0;
491ab64890Smrg    xListFontsReply rep;
501ab64890Smrg    register xListFontsReq *req;
51dac667f7Smrg    unsigned long rlen = 0;
521ab64890Smrg
531ab64890Smrg    LockDisplay(dpy);
541ab64890Smrg    GetReq(ListFonts, req);
551ab64890Smrg    req->maxNames = maxNames;
561ab64890Smrg    nbytes = req->nbytes = pattern ? strlen (pattern) : 0;
571ab64890Smrg    req->length += (nbytes + 3) >> 2;
581ab64890Smrg    _XSend (dpy, pattern, nbytes);
591ab64890Smrg    /* use _XSend instead of Data, since following _XReply will flush buffer */
601ab64890Smrg
611ab64890Smrg    if (!_XReply (dpy, (xReply *)&rep, 0, xFalse)) {
621ab64890Smrg	*actualCount = 0;
631ab64890Smrg	UnlockDisplay(dpy);
641ab64890Smrg	SyncHandle();
651ab64890Smrg	return (char **) NULL;
661ab64890Smrg    }
671ab64890Smrg
681ab64890Smrg    if (rep.nFonts) {
69eb411b4bSmrg	flist = Xmalloc (rep.nFonts * sizeof(char *));
70dac667f7Smrg	if (rep.length > 0 && rep.length < (INT_MAX >> 2)) {
71eb411b4bSmrg	    rlen = rep.length << 2;
72eb411b4bSmrg	    ch = Xmalloc(rlen + 1);
731ab64890Smrg	    /* +1 to leave room for last null-terminator */
74eb411b4bSmrg	}
751ab64890Smrg
761ab64890Smrg	if ((! flist) || (! ch)) {
77cf2acddeSmrg	    Xfree(flist);
78cf2acddeSmrg	    Xfree(ch);
79eb411b4bSmrg	    _XEatDataWords(dpy, rep.length);
801ab64890Smrg	    *actualCount = 0;
811ab64890Smrg	    UnlockDisplay(dpy);
821ab64890Smrg	    SyncHandle();
831ab64890Smrg	    return (char **) NULL;
841ab64890Smrg	}
851ab64890Smrg
861ab64890Smrg	_XReadPad (dpy, ch, rlen);
871ab64890Smrg	/*
881ab64890Smrg	 * unpack into null terminated strings.
891ab64890Smrg	 */
90c9e7fb8dSmrg	chstart = ch;
91bd8e7fb0Smrg	chend = ch + rlen;
921ab64890Smrg	length = *(unsigned char *)ch;
931ab64890Smrg	*ch = 1; /* make sure it is non-zero for XFreeFontNames */
941ab64890Smrg	for (i = 0; i < rep.nFonts; i++) {
95eb411b4bSmrg	    if (ch + length < chend) {
96eb411b4bSmrg		flist[i] = ch + 1;  /* skip over length */
97eb411b4bSmrg		ch += length + 1;  /* find next length ... */
98bd8e7fb0Smrg		length = *(unsigned char *)ch;
99bd8e7fb0Smrg		*ch = '\0';  /* and replace with null-termination */
100bd8e7fb0Smrg		count++;
101dac667f7Smrg	    } else {
102c9e7fb8dSmrg                Xfree(chstart);
103dac667f7Smrg                Xfree(flist);
104dac667f7Smrg                flist = NULL;
105dac667f7Smrg                count = 0;
106dac667f7Smrg                break;
107dac667f7Smrg            }
1081ab64890Smrg	}
1091ab64890Smrg    }
110eb411b4bSmrg    *actualCount = count;
1111ab64890Smrg    UnlockDisplay(dpy);
1121ab64890Smrg    SyncHandle();
1131ab64890Smrg    return (flist);
1141ab64890Smrg}
1151ab64890Smrg
1161ab64890Smrgint
1171ab64890SmrgXFreeFontNames(char **list)
11861b2299dSmrg{
1191ab64890Smrg	if (list) {
1201ab64890Smrg		if (!*(list[0]-1)) { /* from ListFontsWithInfo */
1211ab64890Smrg			register char **names;
1221ab64890Smrg			for (names = list+1; *names; names++)
1231ab64890Smrg				Xfree (*names);
1241ab64890Smrg		}
1251ab64890Smrg		Xfree (list[0]-1);
126c555af55Smrg		Xfree (list);
1271ab64890Smrg	}
1281ab64890Smrg	return 1;
1291ab64890Smrg}
130