FontNames.c revision c9e7fb8d
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;
91eb411b4bSmrg	chend = ch + (rlen + 1);
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 ... */
98dac667f7Smrg		if (ch <= chend) {
99dac667f7Smrg		    length = *(unsigned char *)ch;
100dac667f7Smrg		    *ch = '\0';  /* and replace with null-termination */
101dac667f7Smrg		    count++;
102dac667f7Smrg		} else {
103c9e7fb8dSmrg                    Xfree(chstart);
104dac667f7Smrg                    Xfree(flist);
105dac667f7Smrg                    flist = NULL;
106dac667f7Smrg                    count = 0;
107dac667f7Smrg                    break;
108dac667f7Smrg		}
109dac667f7Smrg	    } else {
110c9e7fb8dSmrg                Xfree(chstart);
111dac667f7Smrg                Xfree(flist);
112dac667f7Smrg                flist = NULL;
113dac667f7Smrg                count = 0;
114dac667f7Smrg                break;
115dac667f7Smrg            }
1161ab64890Smrg	}
1171ab64890Smrg    }
118eb411b4bSmrg    *actualCount = count;
1191ab64890Smrg    UnlockDisplay(dpy);
1201ab64890Smrg    SyncHandle();
1211ab64890Smrg    return (flist);
1221ab64890Smrg}
1231ab64890Smrg
1241ab64890Smrgint
1251ab64890SmrgXFreeFontNames(char **list)
12661b2299dSmrg{
1271ab64890Smrg	if (list) {
1281ab64890Smrg		if (!*(list[0]-1)) { /* from ListFontsWithInfo */
1291ab64890Smrg			register char **names;
1301ab64890Smrg			for (names = list+1; *names; names++)
1311ab64890Smrg				Xfree (*names);
1321ab64890Smrg		}
1331ab64890Smrg		Xfree (list[0]-1);
134c555af55Smrg		Xfree (list);
1351ab64890Smrg	}
1361ab64890Smrg	return 1;
1371ab64890Smrg}
138