File: | src/Font.c |
Location: | line 111, column 5 |
Description: | Null pointer passed as an argument to a 'nonnull' parameter |
1 | /* | ||||
2 | |||||
3 | Copyright 1986, 1998 The Open Group | ||||
4 | Copyright (c) 2000 The XFree86 Project, Inc. | ||||
5 | |||||
6 | Permission to use, copy, modify, distribute, and sell this software and its | ||||
7 | documentation for any purpose is hereby granted without fee, provided that | ||||
8 | the above copyright notice appear in all copies and that both that | ||||
9 | copyright notice and this permission notice appear in supporting | ||||
10 | documentation. | ||||
11 | |||||
12 | The above copyright notice and this permission notice shall be included in | ||||
13 | all copies or substantial portions of the Software. | ||||
14 | |||||
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
18 | X CONSORTIUM OR THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
21 | SOFTWARE. | ||||
22 | |||||
23 | Except as contained in this notice, the name of the X Consortium or of the | ||||
24 | XFree86 Project shall not be used in advertising or otherwise to promote the | ||||
25 | sale, use or other dealings in this Software without prior written | ||||
26 | authorization from the X Consortium and the XFree86 Project. | ||||
27 | |||||
28 | */ | ||||
29 | |||||
30 | #ifdef HAVE_CONFIG_H1 | ||||
31 | #include <config.h> | ||||
32 | #endif | ||||
33 | #include "Xlibint.h" | ||||
34 | |||||
35 | #if defined(XF86BIGFONT1) && !defined(MUSTCOPY) | ||||
36 | #define USE_XF86BIGFONT | ||||
37 | #endif | ||||
38 | #ifdef USE_XF86BIGFONT | ||||
39 | #include <sys/types.h> | ||||
40 | #ifdef HAS_SHM1 | ||||
41 | #include <sys/ipc.h> | ||||
42 | #include <sys/shm.h> | ||||
43 | #endif | ||||
44 | |||||
45 | #include <stdio.h> | ||||
46 | #include <stdlib.h> | ||||
47 | #include <X11/extensions/xf86bigfproto.h> | ||||
48 | #endif | ||||
49 | |||||
50 | #include "Xlcint.h" | ||||
51 | #include "XlcPubI.h" | ||||
52 | |||||
53 | |||||
54 | static XFontStruct *_XQueryFont( | ||||
55 | Display* /* dpy */, | ||||
56 | Font /* fid */, | ||||
57 | unsigned long /* seq */ | ||||
58 | ); | ||||
59 | |||||
60 | #ifdef USE_XF86BIGFONT | ||||
61 | |||||
62 | /* Private data for this extension. */ | ||||
63 | typedef struct { | ||||
64 | XExtCodes *codes; | ||||
65 | CARD32 serverSignature; | ||||
66 | CARD32 serverCapabilities; | ||||
67 | } XF86BigfontCodes; | ||||
68 | |||||
69 | /* Additional bit masks that can be set in serverCapabilities */ | ||||
70 | #define CAP_VerifiedLocal256 256 | ||||
71 | |||||
72 | static XF86BigfontCodes *_XF86BigfontCodes( | ||||
73 | Display* /* dpy */ | ||||
74 | ); | ||||
75 | |||||
76 | static XFontStruct *_XF86BigfontQueryFont( | ||||
77 | Display* /* dpy */, | ||||
78 | XF86BigfontCodes* /* extcodes */, | ||||
79 | Font /* fid */, | ||||
80 | unsigned long /* seq */ | ||||
81 | ); | ||||
82 | |||||
83 | void _XF86BigfontFreeFontMetrics( | ||||
84 | XFontStruct* /* fs */ | ||||
85 | ); | ||||
86 | |||||
87 | #endif /* USE_XF86BIGFONT */ | ||||
88 | |||||
89 | |||||
90 | XFontStruct *XLoadQueryFont( | ||||
91 | register Display *dpy, | ||||
92 | _Xconstconst char *name) | ||||
93 | { | ||||
94 | XFontStruct *font_result; | ||||
95 | register long nbytes; | ||||
96 | Font fid; | ||||
97 | xOpenFontReq *req; | ||||
98 | unsigned long seq; | ||||
99 | #ifdef USE_XF86BIGFONT | ||||
100 | XF86BigfontCodes *extcodes = _XF86BigfontCodes(dpy); | ||||
101 | #endif | ||||
102 | |||||
103 | if (_XF86LoadQueryLocaleFont(dpy, name, &font_result, (Font *)0)) | ||||
| |||||
104 | return font_result; | ||||
105 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | ||||
106 | GetReq(OpenFont, req)req = (xOpenFontReq *) _XGetRequest(dpy, 45, 12); | ||||
107 | seq = dpy->request; | ||||
108 | nbytes = req->nbytes = name ? strlen(name) : 0; | ||||
| |||||
| |||||
109 | req->fid = fid = XAllocID(dpy)((*((_XPrivDisplay)dpy)->resource_alloc)((dpy))); | ||||
110 | req->length += (nbytes+3)>>2; | ||||
111 | Data (dpy, name, nbytes){ if (dpy->bufptr + (nbytes) <= dpy->bufmax) { memcpy (dpy->bufptr, name, (int)nbytes); dpy->bufptr += ((nbytes ) + 3) & ~3; } else _XSend(dpy, name, nbytes); }; | ||||
| |||||
112 | font_result = NULL((void*)0); | ||||
113 | #ifdef USE_XF86BIGFONT | ||||
114 | if (extcodes) { | ||||
115 | font_result = _XF86BigfontQueryFont(dpy, extcodes, fid, seq); | ||||
116 | seq = 0; | ||||
117 | } | ||||
118 | #endif | ||||
119 | if (!font_result) | ||||
120 | font_result = _XQueryFont(dpy, fid, seq); | ||||
121 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | ||||
122 | SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy); | ||||
123 | return font_result; | ||||
124 | } | ||||
125 | |||||
126 | XFontStruct *XQueryFont ( | ||||
127 | register Display *dpy, | ||||
128 | Font fid) | ||||
129 | { | ||||
130 | XFontStruct *font_result; | ||||
131 | #ifdef USE_XF86BIGFONT | ||||
132 | XF86BigfontCodes *extcodes = _XF86BigfontCodes(dpy); | ||||
133 | #endif | ||||
134 | |||||
135 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | ||||
136 | font_result = NULL((void*)0); | ||||
137 | #ifdef USE_XF86BIGFONT | ||||
138 | if (extcodes) { | ||||
139 | font_result = _XF86BigfontQueryFont(dpy, extcodes, fid, 0L); | ||||
140 | } | ||||
141 | #endif | ||||
142 | if (!font_result) | ||||
143 | font_result = _XQueryFont(dpy, fid, 0L); | ||||
144 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | ||||
145 | SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy); | ||||
146 | return font_result; | ||||
147 | } | ||||
148 | |||||
149 | int | ||||
150 | XFreeFont( | ||||
151 | register Display *dpy, | ||||
152 | XFontStruct *fs) | ||||
153 | { | ||||
154 | register xResourceReq *req; | ||||
155 | register _XExtension *ext; | ||||
156 | |||||
157 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | ||||
158 | /* call out to any extensions interested */ | ||||
159 | for (ext = dpy->ext_procs; ext; ext = ext->next) | ||||
160 | if (ext->free_Font) (*ext->free_Font)(dpy, fs, &ext->codes); | ||||
161 | GetResReq (CloseFont, fs->fid, req)req = (xResourceReq *) _XGetRequest(dpy, 46, 8); req->id = (fs->fid); | ||||
162 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | ||||
163 | SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy); | ||||
164 | if (fs->per_char) { | ||||
165 | #ifdef USE_XF86BIGFONT | ||||
166 | _XF86BigfontFreeFontMetrics(fs); | ||||
167 | #else | ||||
168 | Xfree ((char *) fs->per_char)free(((char *) fs->per_char)); | ||||
169 | #endif | ||||
170 | } | ||||
171 | _XFreeExtData(fs->ext_data); | ||||
172 | if (fs->properties) | ||||
173 | Xfree ((char *) fs->properties)free(((char *) fs->properties)); | ||||
174 | Xfree ((char *) fs)free(((char *) fs)); | ||||
175 | return 1; | ||||
176 | } | ||||
177 | |||||
178 | |||||
179 | static XFontStruct * | ||||
180 | _XQueryFont ( | ||||
181 | register Display *dpy, | ||||
182 | Font fid, | ||||
183 | unsigned long seq) | ||||
184 | { | ||||
185 | register XFontStruct *fs; | ||||
186 | register long nbytes; | ||||
187 | xQueryFontReply reply; | ||||
188 | register xResourceReq *req; | ||||
189 | register _XExtension *ext; | ||||
190 | _XAsyncHandler async; | ||||
191 | _XAsyncErrorState async_state; | ||||
192 | |||||
193 | if (seq) { | ||||
194 | async_state.min_sequence_number = seq; | ||||
195 | async_state.max_sequence_number = seq; | ||||
196 | async_state.error_code = BadName15; | ||||
197 | async_state.major_opcode = X_OpenFont45; | ||||
198 | async_state.minor_opcode = 0; | ||||
199 | async_state.error_count = 0; | ||||
200 | async.next = dpy->async_handlers; | ||||
201 | async.handler = _XAsyncErrorHandler; | ||||
202 | async.data = (XPointer)&async_state; | ||||
203 | dpy->async_handlers = &async; | ||||
204 | } | ||||
205 | GetResReq(QueryFont, fid, req)req = (xResourceReq *) _XGetRequest(dpy, 47, 8); req->id = (fid); | ||||
206 | if (!_XReply (dpy, (xReply *) &reply, | ||||
207 | ((SIZEOF(xQueryFontReply)60 - SIZEOF(xReply)32) >> 2), xFalse0)) { | ||||
208 | if (seq) | ||||
209 | DeqAsyncHandler(dpy, &async){ if (dpy->async_handlers == (&async)) dpy->async_handlers = (&async)->next; else _XDeqAsyncHandler(dpy, &async ); }; | ||||
210 | return (XFontStruct *)NULL((void*)0); | ||||
211 | } | ||||
212 | if (seq) | ||||
213 | DeqAsyncHandler(dpy, &async){ if (dpy->async_handlers == (&async)) dpy->async_handlers = (&async)->next; else _XDeqAsyncHandler(dpy, &async ); }; | ||||
214 | if (! (fs = (XFontStruct *) Xmalloc (sizeof (XFontStruct))malloc(((sizeof (XFontStruct)) == 0 ? 1 : (sizeof (XFontStruct )))))) { | ||||
215 | _XEatData(dpy, (unsigned long)(reply.nFontProps * SIZEOF(xFontProp)8 + | ||||
216 | reply.nCharInfos * SIZEOF(xCharInfo)12)); | ||||
217 | return (XFontStruct *)NULL((void*)0); | ||||
218 | } | ||||
219 | fs->ext_data = NULL((void*)0); | ||||
220 | fs->fid = fid; | ||||
221 | fs->direction = reply.drawDirection; | ||||
222 | fs->min_char_or_byte2 = reply.minCharOrByte2; | ||||
223 | fs->max_char_or_byte2 = reply.maxCharOrByte2; | ||||
224 | fs->min_byte1 = reply.minByte1; | ||||
225 | fs->max_byte1 = reply.maxByte1; | ||||
226 | fs->default_char = reply.defaultChar; | ||||
227 | fs->all_chars_exist = reply.allCharsExist; | ||||
228 | fs->ascent = cvtINT16toInt (reply.fontAscent)(reply.fontAscent); | ||||
229 | fs->descent = cvtINT16toInt (reply.fontDescent)(reply.fontDescent); | ||||
230 | |||||
231 | #ifdef MUSTCOPY | ||||
232 | { | ||||
233 | xCharInfo *xcip; | ||||
234 | |||||
235 | xcip = (xCharInfo *) &reply.minBounds; | ||||
236 | fs->min_bounds.lbearing = cvtINT16toShort(xcip->leftSideBearing)(xcip->leftSideBearing); | ||||
237 | fs->min_bounds.rbearing = cvtINT16toShort(xcip->rightSideBearing)(xcip->rightSideBearing); | ||||
238 | fs->min_bounds.width = cvtINT16toShort(xcip->characterWidth)(xcip->characterWidth); | ||||
239 | fs->min_bounds.ascent = cvtINT16toShort(xcip->ascent)(xcip->ascent); | ||||
240 | fs->min_bounds.descent = cvtINT16toShort(xcip->descent)(xcip->descent); | ||||
241 | fs->min_bounds.attributes = xcip->attributes; | ||||
242 | |||||
243 | xcip = (xCharInfo *) &reply.maxBounds; | ||||
244 | fs->max_bounds.lbearing = cvtINT16toShort(xcip->leftSideBearing)(xcip->leftSideBearing); | ||||
245 | fs->max_bounds.rbearing = cvtINT16toShort(xcip->rightSideBearing)(xcip->rightSideBearing); | ||||
246 | fs->max_bounds.width = cvtINT16toShort(xcip->characterWidth)(xcip->characterWidth); | ||||
247 | fs->max_bounds.ascent = cvtINT16toShort(xcip->ascent)(xcip->ascent); | ||||
248 | fs->max_bounds.descent = cvtINT16toShort(xcip->descent)(xcip->descent); | ||||
249 | fs->max_bounds.attributes = xcip->attributes; | ||||
250 | } | ||||
251 | #else | ||||
252 | /* XXX the next two statements won't work if short isn't 16 bits */ | ||||
253 | fs->min_bounds = * (XCharStruct *) &reply.minBounds; | ||||
254 | fs->max_bounds = * (XCharStruct *) &reply.maxBounds; | ||||
255 | #endif /* MUSTCOPY */ | ||||
256 | |||||
257 | fs->n_properties = reply.nFontProps; | ||||
258 | /* | ||||
259 | * if no properties defined for the font, then it is bad | ||||
260 | * font, but shouldn't try to read nothing. | ||||
261 | */ | ||||
262 | fs->properties = NULL((void*)0); | ||||
263 | if (fs->n_properties > 0) { | ||||
264 | nbytes = reply.nFontProps * sizeof(XFontProp); | ||||
265 | fs->properties = (XFontProp *) Xmalloc ((unsigned) nbytes)malloc((((unsigned) nbytes) == 0 ? 1 : ((unsigned) nbytes))); | ||||
266 | nbytes = reply.nFontProps * SIZEOF(xFontProp)8; | ||||
267 | if (! fs->properties) { | ||||
268 | Xfree((char *) fs)free(((char *) fs)); | ||||
269 | _XEatData(dpy, (unsigned long) | ||||
270 | (nbytes + reply.nCharInfos * SIZEOF(xCharInfo)12)); | ||||
271 | return (XFontStruct *)NULL((void*)0); | ||||
272 | } | ||||
273 | _XRead32 (dpy, (long *)fs->properties, nbytes); | ||||
274 | } | ||||
275 | /* | ||||
276 | * If no characters in font, then it is a bad font, but | ||||
277 | * shouldn't try to read nothing. | ||||
278 | */ | ||||
279 | /* have to unpack charinfos on some machines (CRAY) */ | ||||
280 | fs->per_char = NULL((void*)0); | ||||
281 | if (reply.nCharInfos > 0){ | ||||
282 | nbytes = reply.nCharInfos * sizeof(XCharStruct); | ||||
283 | if (! (fs->per_char = (XCharStruct *) Xmalloc ((unsigned) nbytes)malloc((((unsigned) nbytes) == 0 ? 1 : ((unsigned) nbytes))))) { | ||||
284 | if (fs->properties) Xfree((char *) fs->properties)free(((char *) fs->properties)); | ||||
285 | Xfree((char *) fs)free(((char *) fs)); | ||||
286 | _XEatData(dpy, (unsigned long) | ||||
287 | (reply.nCharInfos * SIZEOF(xCharInfo)12)); | ||||
288 | return (XFontStruct *)NULL((void*)0); | ||||
289 | } | ||||
290 | |||||
291 | #ifdef MUSTCOPY | ||||
292 | { | ||||
293 | register XCharStruct *cs = fs->per_char; | ||||
294 | register int i; | ||||
295 | |||||
296 | for (i = 0; i < reply.nCharInfos; i++, cs++) { | ||||
297 | xCharInfo xcip; | ||||
298 | |||||
299 | _XRead(dpy, (char *)&xcip, SIZEOF(xCharInfo)12); | ||||
300 | cs->lbearing = cvtINT16toShort(xcip.leftSideBearing)(xcip.leftSideBearing); | ||||
301 | cs->rbearing = cvtINT16toShort(xcip.rightSideBearing)(xcip.rightSideBearing); | ||||
302 | cs->width = cvtINT16toShort(xcip.characterWidth)(xcip.characterWidth); | ||||
303 | cs->ascent = cvtINT16toShort(xcip.ascent)(xcip.ascent); | ||||
304 | cs->descent = cvtINT16toShort(xcip.descent)(xcip.descent); | ||||
305 | cs->attributes = xcip.attributes; | ||||
306 | } | ||||
307 | } | ||||
308 | #else | ||||
309 | nbytes = reply.nCharInfos * SIZEOF(xCharInfo)12; | ||||
310 | _XRead16 (dpy, (char *)fs->per_char, nbytes)_XRead((dpy), (char *)((char *)fs->per_char), (nbytes)); | ||||
311 | #endif | ||||
312 | } | ||||
313 | |||||
314 | /* call out to any extensions interested */ | ||||
315 | for (ext = dpy->ext_procs; ext; ext = ext->next) | ||||
316 | if (ext->create_Font) (*ext->create_Font)(dpy, fs, &ext->codes); | ||||
317 | return fs; | ||||
318 | } | ||||
319 | |||||
320 | #ifdef USE_XF86BIGFONT | ||||
321 | |||||
322 | /* Magic cookie for finding the right XExtData structure on the display's | ||||
323 | extension list. */ | ||||
324 | static int XF86BigfontNumber = 1040697125; | ||||
325 | |||||
326 | static int | ||||
327 | _XF86BigfontFreeCodes ( | ||||
328 | XExtData *extension) | ||||
329 | { | ||||
330 | /* Don't Xfree(extension->private_data) because it is on the same malloc | ||||
331 | chunk as extension. */ | ||||
332 | /* Don't Xfree(extension->private_data->codes) because this is shared with | ||||
333 | the display's ext_procs list. */ | ||||
334 | return 0; | ||||
335 | } | ||||
336 | |||||
337 | static XF86BigfontCodes * | ||||
338 | _XF86BigfontCodes ( | ||||
339 | register Display *dpy) | ||||
340 | { | ||||
341 | XEDataObject dpy_union; | ||||
342 | XExtData *pData; | ||||
343 | XF86BigfontCodes *pCodes; | ||||
344 | char *envval; | ||||
345 | |||||
346 | dpy_union.display = dpy; | ||||
347 | |||||
348 | /* If the server is known to support the XF86Bigfont extension, | ||||
349 | * return the extension codes. If the server is known to not support | ||||
350 | * the extension, don't bother checking again. | ||||
351 | */ | ||||
352 | pData = XFindOnExtensionList(XEHeadOfExtensionList(dpy_union), | ||||
353 | XF86BigfontNumber); | ||||
354 | if (pData) | ||||
355 | return (XF86BigfontCodes *) pData->private_data; | ||||
356 | |||||
357 | pData = (XExtData *) Xmalloc(sizeof(XExtData) + sizeof(XF86BigfontCodes))malloc(((sizeof(XExtData) + sizeof(XF86BigfontCodes)) == 0 ? 1 : (sizeof(XExtData) + sizeof(XF86BigfontCodes)))); | ||||
358 | if (!pData) { | ||||
359 | /* Out of luck. */ | ||||
360 | return (XF86BigfontCodes *) NULL((void*)0); | ||||
361 | } | ||||
362 | |||||
363 | /* See if the server supports the XF86Bigfont extension. */ | ||||
364 | envval = getenv("XF86BIGFONT_DISABLE"); /* Let the user disable it. */ | ||||
365 | if (envval != NULL((void*)0) && envval[0] != '\0') | ||||
366 | pCodes = NULL((void*)0); | ||||
367 | else { | ||||
368 | XExtCodes *codes = XInitExtension(dpy, XF86BIGFONTNAME"XFree86-Bigfont"); | ||||
369 | if (codes == NULL((void*)0)) | ||||
370 | pCodes = NULL((void*)0); | ||||
371 | else { | ||||
372 | pCodes = (XF86BigfontCodes *) &pData[1]; | ||||
373 | pCodes->codes = codes; | ||||
374 | } | ||||
375 | } | ||||
376 | pData->number = XF86BigfontNumber; | ||||
377 | pData->private_data = (XPointer) pCodes; | ||||
378 | pData->free_private = _XF86BigfontFreeCodes; | ||||
379 | XAddToExtensionList(XEHeadOfExtensionList(dpy_union), pData); | ||||
380 | if (pCodes) { | ||||
381 | int result; | ||||
382 | |||||
383 | /* See if the server supports the XF86BigfontQueryFont request. */ | ||||
384 | xXF86BigfontQueryVersionReply reply; | ||||
385 | register xXF86BigfontQueryVersionReq *req; | ||||
386 | |||||
387 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | ||||
388 | |||||
389 | GetReq(XF86BigfontQueryVersion, req)req = (xXF86BigfontQueryVersionReq *) _XGetRequest(dpy, 0, 4); | ||||
390 | req->reqType = pCodes->codes->major_opcode; | ||||
391 | req->xf86bigfontReqType = X_XF86BigfontQueryVersion0; | ||||
392 | |||||
393 | result = _XReply (dpy, (xReply *) &reply, | ||||
394 | (SIZEOF(xXF86BigfontQueryVersionReply)32 - SIZEOF(xReply)32) >> 2, | ||||
395 | xFalse0); | ||||
396 | |||||
397 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | ||||
398 | SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy); | ||||
399 | |||||
400 | if(!result) | ||||
401 | goto ignore_extension; | ||||
402 | |||||
403 | /* No need to provide backward compatibility with version 1.0. It | ||||
404 | was never widely distributed. */ | ||||
405 | if (!(reply.majorVersion > 1 | ||||
406 | || (reply.majorVersion == 1 && reply.minorVersion >= 1))) | ||||
407 | goto ignore_extension; | ||||
408 | |||||
409 | pCodes->serverSignature = reply.signature; | ||||
410 | pCodes->serverCapabilities = reply.capabilities; | ||||
411 | } | ||||
412 | return pCodes; | ||||
413 | |||||
414 | ignore_extension: | ||||
415 | /* No need to Xfree(pCodes) or Xfree(pCodes->codes), see | ||||
416 | _XF86BigfontFreeCodes comment. */ | ||||
417 | pCodes = (XF86BigfontCodes *) NULL((void*)0); | ||||
418 | pData->private_data = (XPointer) pCodes; | ||||
419 | return pCodes; | ||||
420 | } | ||||
421 | |||||
422 | static int | ||||
423 | _XF86BigfontFreeNop ( | ||||
424 | XExtData *extension) | ||||
425 | { | ||||
426 | return 0; | ||||
427 | } | ||||
428 | |||||
429 | static XFontStruct * | ||||
430 | _XF86BigfontQueryFont ( | ||||
431 | register Display *dpy, | ||||
432 | XF86BigfontCodes *extcodes, | ||||
433 | Font fid, | ||||
434 | unsigned long seq) | ||||
435 | { | ||||
436 | register XFontStruct *fs; | ||||
437 | register long nbytes; | ||||
438 | xXF86BigfontQueryFontReply reply; | ||||
439 | register xXF86BigfontQueryFontReq *req; | ||||
440 | register _XExtension *ext; | ||||
441 | _XAsyncHandler async1; | ||||
442 | _XAsyncErrorState async1_state; | ||||
443 | _XAsyncHandler async2; | ||||
444 | _XAsyncErrorState async2_state; | ||||
445 | |||||
446 | if (seq) { | ||||
447 | async1_state.min_sequence_number = seq; | ||||
448 | async1_state.max_sequence_number = seq; | ||||
449 | async1_state.error_code = BadName15; | ||||
450 | async1_state.major_opcode = X_OpenFont45; | ||||
451 | async1_state.minor_opcode = 0; | ||||
452 | async1_state.error_count = 0; | ||||
453 | async1.next = dpy->async_handlers; | ||||
454 | async1.handler = _XAsyncErrorHandler; | ||||
455 | async1.data = (XPointer)&async1_state; | ||||
456 | dpy->async_handlers = &async1; | ||||
457 | } | ||||
458 | |||||
459 | GetReq(XF86BigfontQueryFont, req)req = (xXF86BigfontQueryFontReq *) _XGetRequest(dpy, 1, 12); | ||||
460 | req->reqType = extcodes->codes->major_opcode; | ||||
461 | req->xf86bigfontReqType = X_XF86BigfontQueryFont1; | ||||
462 | req->id = fid; | ||||
463 | req->flags = (extcodes->serverCapabilities & XF86Bigfont_CAP_LocalShm1 | ||||
464 | ? XF86Bigfont_FLAGS_Shm1 : 0); | ||||
465 | |||||
466 | /* The function _XQueryFont benefits from a "magic" error handler for | ||||
467 | BadFont coming from a X_QueryFont request. (See function _XReply.) | ||||
468 | We have to establish an error handler ourselves. */ | ||||
469 | async2_state.min_sequence_number = dpy->request; | ||||
470 | async2_state.max_sequence_number = dpy->request; | ||||
471 | async2_state.error_code = BadFont7; | ||||
472 | async2_state.major_opcode = extcodes->codes->major_opcode; | ||||
473 | async2_state.minor_opcode = X_XF86BigfontQueryFont1; | ||||
474 | async2_state.error_count = 0; | ||||
475 | async2.next = dpy->async_handlers; | ||||
476 | async2.handler = _XAsyncErrorHandler; | ||||
477 | async2.data = (XPointer)&async2_state; | ||||
478 | dpy->async_handlers = &async2; | ||||
479 | |||||
480 | if (!_XReply (dpy, (xReply *) &reply, | ||||
481 | ((SIZEOF(xXF86BigfontQueryFontReply)72 - SIZEOF(xReply)32) >> 2), xFalse0)) { | ||||
482 | DeqAsyncHandler(dpy, &async2){ if (dpy->async_handlers == (&async2)) dpy->async_handlers = (&async2)->next; else _XDeqAsyncHandler(dpy, &async2 ); }; | ||||
483 | if (seq) | ||||
484 | DeqAsyncHandler(dpy, &async1){ if (dpy->async_handlers == (&async1)) dpy->async_handlers = (&async1)->next; else _XDeqAsyncHandler(dpy, &async1 ); }; | ||||
485 | return (XFontStruct *)NULL((void*)0); | ||||
486 | } | ||||
487 | DeqAsyncHandler(dpy, &async2){ if (dpy->async_handlers == (&async2)) dpy->async_handlers = (&async2)->next; else _XDeqAsyncHandler(dpy, &async2 ); }; | ||||
488 | if (seq) | ||||
489 | DeqAsyncHandler(dpy, &async1){ if (dpy->async_handlers == (&async1)) dpy->async_handlers = (&async1)->next; else _XDeqAsyncHandler(dpy, &async1 ); }; | ||||
490 | if (! (fs = (XFontStruct *) Xmalloc (sizeof (XFontStruct))malloc(((sizeof (XFontStruct)) == 0 ? 1 : (sizeof (XFontStruct )))))) { | ||||
491 | _XEatData(dpy, | ||||
492 | reply.nFontProps * SIZEOF(xFontProp)8 | ||||
493 | + (reply.nCharInfos > 0 && reply.shmid == (CARD32)(-1) | ||||
494 | ? reply.nUniqCharInfos * SIZEOF(xCharInfo)12 | ||||
495 | + (reply.nCharInfos+1)/2 * 2 * sizeof(CARD16) | ||||
496 | : 0)); | ||||
497 | return (XFontStruct *)NULL((void*)0); | ||||
498 | } | ||||
499 | fs->ext_data = NULL((void*)0); | ||||
500 | fs->fid = fid; | ||||
501 | fs->direction = reply.drawDirection; | ||||
502 | fs->min_char_or_byte2 = reply.minCharOrByte2; | ||||
503 | fs->max_char_or_byte2 = reply.maxCharOrByte2; | ||||
504 | fs->min_byte1 = reply.minByte1; | ||||
505 | fs->max_byte1 = reply.maxByte1; | ||||
506 | fs->default_char = reply.defaultChar; | ||||
507 | fs->all_chars_exist = reply.allCharsExist; | ||||
508 | fs->ascent = cvtINT16toInt (reply.fontAscent)(reply.fontAscent); | ||||
509 | fs->descent = cvtINT16toInt (reply.fontDescent)(reply.fontDescent); | ||||
510 | |||||
511 | /* XXX the next two statements won't work if short isn't 16 bits */ | ||||
512 | fs->min_bounds = * (XCharStruct *) &reply.minBounds; | ||||
513 | fs->max_bounds = * (XCharStruct *) &reply.maxBounds; | ||||
514 | |||||
515 | fs->n_properties = reply.nFontProps; | ||||
516 | /* | ||||
517 | * if no properties defined for the font, then it is bad | ||||
518 | * font, but shouldn't try to read nothing. | ||||
519 | */ | ||||
520 | fs->properties = NULL((void*)0); | ||||
521 | if (fs->n_properties > 0) { | ||||
522 | nbytes = reply.nFontProps * sizeof(XFontProp); | ||||
523 | fs->properties = (XFontProp *) Xmalloc ((unsigned) nbytes)malloc((((unsigned) nbytes) == 0 ? 1 : ((unsigned) nbytes))); | ||||
524 | nbytes = reply.nFontProps * SIZEOF(xFontProp)8; | ||||
525 | if (! fs->properties) { | ||||
526 | Xfree((char *) fs)free(((char *) fs)); | ||||
527 | _XEatData(dpy, | ||||
528 | nbytes | ||||
529 | + (reply.nCharInfos > 0 && reply.shmid == (CARD32)(-1) | ||||
530 | ? reply.nUniqCharInfos * SIZEOF(xCharInfo)12 | ||||
531 | + (reply.nCharInfos+1)/2 * 2 * sizeof(CARD16) | ||||
532 | : 0)); | ||||
533 | return (XFontStruct *)NULL((void*)0); | ||||
534 | } | ||||
535 | _XRead32 (dpy, (long *)fs->properties, nbytes); | ||||
536 | } | ||||
537 | |||||
538 | fs->per_char = NULL((void*)0); | ||||
539 | if (reply.nCharInfos > 0) { | ||||
540 | /* fprintf(stderr, "received font metrics, nCharInfos = %d, nUniqCharInfos = %d, shmid = %d\n", reply.nCharInfos, reply.nUniqCharInfos, reply.shmid); */ | ||||
541 | if (reply.shmid == (CARD32)(-1)) { | ||||
542 | xCharInfo* pUniqCI; | ||||
543 | CARD16* pIndex2UniqIndex; | ||||
544 | int i; | ||||
545 | |||||
546 | nbytes = reply.nUniqCharInfos * SIZEOF(xCharInfo)12 | ||||
547 | + (reply.nCharInfos+1)/2 * 2 * sizeof(CARD16); | ||||
548 | pUniqCI = (xCharInfo *) Xmalloc (nbytes)malloc(((nbytes) == 0 ? 1 : (nbytes))); | ||||
549 | if (!pUniqCI) { | ||||
550 | if (fs->properties) Xfree((char *) fs->properties)free(((char *) fs->properties)); | ||||
551 | Xfree((char *) fs)free(((char *) fs)); | ||||
552 | _XEatData(dpy, nbytes); | ||||
553 | return (XFontStruct *)NULL((void*)0); | ||||
554 | } | ||||
555 | if (! (fs->per_char = (XCharStruct *) Xmalloc (reply.nCharInfos * sizeof(XCharStruct))malloc(((reply.nCharInfos * sizeof(XCharStruct)) == 0 ? 1 : ( reply.nCharInfos * sizeof(XCharStruct)))))) { | ||||
556 | Xfree((char *) pUniqCI)free(((char *) pUniqCI)); | ||||
557 | if (fs->properties) Xfree((char *) fs->properties)free(((char *) fs->properties)); | ||||
558 | Xfree((char *) fs)free(((char *) fs)); | ||||
559 | _XEatData(dpy, nbytes); | ||||
560 | return (XFontStruct *)NULL((void*)0); | ||||
561 | } | ||||
562 | _XRead16 (dpy, (char *) pUniqCI, nbytes)_XRead((dpy), (char *)((char *) pUniqCI), (nbytes)); | ||||
563 | pIndex2UniqIndex = (CARD16*) (pUniqCI + reply.nUniqCharInfos); | ||||
564 | for (i = 0; i < reply.nCharInfos; i++) { | ||||
565 | if (pIndex2UniqIndex[i] >= reply.nUniqCharInfos) { | ||||
566 | fprintf(stderrstderr, "_XF86BigfontQueryFont: server returned wrong data\n"); | ||||
567 | Xfree((char *) pUniqCI)free(((char *) pUniqCI)); | ||||
568 | if (fs->properties) Xfree((char *) fs->properties)free(((char *) fs->properties)); | ||||
569 | Xfree((char *) fs)free(((char *) fs)); | ||||
570 | return (XFontStruct *)NULL((void*)0); | ||||
571 | } | ||||
572 | /* XXX the next statement won't work if short isn't 16 bits */ | ||||
573 | fs->per_char[i] = * (XCharStruct *) &pUniqCI[pIndex2UniqIndex[i]]; | ||||
574 | } | ||||
575 | Xfree((char *) pUniqCI)free(((char *) pUniqCI)); | ||||
576 | } else { | ||||
577 | #ifdef HAS_SHM1 | ||||
578 | XExtData *pData; | ||||
579 | XEDataObject fs_union; | ||||
580 | char *addr; | ||||
581 | |||||
582 | pData = (XExtData *) Xmalloc(sizeof(XExtData))malloc(((sizeof(XExtData)) == 0 ? 1 : (sizeof(XExtData)))); | ||||
583 | if (!pData) { | ||||
584 | if (fs->properties) Xfree((char *) fs->properties)free(((char *) fs->properties)); | ||||
585 | Xfree((char *) fs)free(((char *) fs)); | ||||
586 | return (XFontStruct *)NULL((void*)0); | ||||
587 | } | ||||
588 | |||||
589 | /* In some cases (e.g. an ssh daemon forwarding an X session to | ||||
590 | a remote machine) it is possible that the X server thinks we | ||||
591 | are running on the same machine (because getpeername() and | ||||
592 | LocalClient() cannot know about the forwarding) but we are | ||||
593 | not really local. Therefore, when we attach the first shared | ||||
594 | memory segment, we verify that we are on the same machine as | ||||
595 | the X server by checking that 1. shmat() succeeds, 2. the | ||||
596 | segment has a sufficient size, 3. it contains the X server's | ||||
597 | signature. Then we set the CAP_VerifiedLocal bit to indicate | ||||
598 | the verification was successful. */ | ||||
599 | |||||
600 | if ((addr = shmat(reply.shmid, NULL((void*)0), SHM_RDONLY010000)) == (char *)-1) { | ||||
601 | if (extcodes->serverCapabilities & CAP_VerifiedLocal256) | ||||
602 | fprintf(stderrstderr, "_XF86BigfontQueryFont: could not attach shm segment\n"); | ||||
603 | Xfree((char *) pData)free(((char *) pData)); | ||||
604 | if (fs->properties) Xfree((char *) fs->properties)free(((char *) fs->properties)); | ||||
605 | Xfree((char *) fs)free(((char *) fs)); | ||||
606 | /* Stop requesting shared memory transport from now on. */ | ||||
607 | extcodes->serverCapabilities &= ~ XF86Bigfont_CAP_LocalShm1; | ||||
608 | return (XFontStruct *)NULL((void*)0); | ||||
609 | } | ||||
610 | |||||
611 | if (!(extcodes->serverCapabilities & CAP_VerifiedLocal256)) { | ||||
612 | struct shmid_ds buf; | ||||
613 | if (!(shmctl(reply.shmid, IPC_STAT2, &buf) >= 0 | ||||
614 | && buf.shm_segsz >= reply.shmsegoffset + reply.nCharInfos * sizeof(XCharStruct) + sizeof(CARD32) | ||||
615 | && *(CARD32 *)(addr + reply.shmsegoffset + reply.nCharInfos * sizeof(XCharStruct)) == extcodes->serverSignature)) { | ||||
616 | shmdt(addr); | ||||
617 | Xfree((char *) pData)free(((char *) pData)); | ||||
618 | if (fs->properties) Xfree((char *) fs->properties)free(((char *) fs->properties)); | ||||
619 | Xfree((char *) fs)free(((char *) fs)); | ||||
620 | /* Stop requesting shared memory transport from now on. */ | ||||
621 | extcodes->serverCapabilities &= ~ XF86Bigfont_CAP_LocalShm1; | ||||
622 | return (XFontStruct *)NULL((void*)0); | ||||
623 | } | ||||
624 | extcodes->serverCapabilities |= CAP_VerifiedLocal256; | ||||
625 | } | ||||
626 | |||||
627 | pData->number = XF86BigfontNumber; | ||||
628 | pData->private_data = (XPointer) addr; | ||||
629 | pData->free_private = _XF86BigfontFreeNop; | ||||
630 | fs_union.font = fs; | ||||
631 | XAddToExtensionList(XEHeadOfExtensionList(fs_union), pData); | ||||
632 | |||||
633 | fs->per_char = (XCharStruct *) (addr + reply.shmsegoffset); | ||||
634 | #else | ||||
635 | fprintf(stderrstderr, "_XF86BigfontQueryFont: try recompiling libX11 with HasShm, Xserver has shm support\n"); | ||||
636 | if (fs->properties) Xfree((char *) fs->properties)free(((char *) fs->properties)); | ||||
637 | Xfree((char *) fs)free(((char *) fs)); | ||||
638 | /* Stop requesting shared memory transport from now on. */ | ||||
639 | extcodes->serverCapabilities &= ~ XF86Bigfont_CAP_LocalShm1; | ||||
640 | return (XFontStruct *)NULL((void*)0); | ||||
641 | #endif | ||||
642 | } | ||||
643 | } | ||||
644 | |||||
645 | /* call out to any extensions interested */ | ||||
646 | for (ext = dpy->ext_procs; ext; ext = ext->next) | ||||
647 | if (ext->create_Font) (*ext->create_Font)(dpy, fs, &ext->codes); | ||||
648 | return fs; | ||||
649 | } | ||||
650 | |||||
651 | void | ||||
652 | _XF86BigfontFreeFontMetrics (XFontStruct *fs) | ||||
653 | { | ||||
654 | #ifdef HAS_SHM1 | ||||
655 | XExtData *pData; | ||||
656 | XEDataObject fs_union; | ||||
657 | |||||
658 | fs_union.font = fs; | ||||
659 | if ((pData = XFindOnExtensionList(XEHeadOfExtensionList(fs_union), | ||||
660 | XF86BigfontNumber))) | ||||
661 | shmdt ((char *) pData->private_data); | ||||
662 | else | ||||
663 | Xfree ((char *) fs->per_char)free(((char *) fs->per_char)); | ||||
664 | #else | ||||
665 | Xfree ((char *) fs->per_char)free(((char *) fs->per_char)); | ||||
666 | #endif | ||||
667 | } | ||||
668 | |||||
669 | #endif /* USE_XF86BIGFONT */ | ||||
670 | |||||
671 | int _XF86LoadQueryLocaleFont( | ||||
672 | Display *dpy, | ||||
673 | _Xconstconst char *name, | ||||
674 | XFontStruct **xfp, | ||||
675 | Font *fidp) | ||||
676 | { | ||||
677 | int l; | ||||
678 | const char *charset, *p; | ||||
679 | char buf[256]; | ||||
680 | XFontStruct *fs; | ||||
681 | XLCd lcd; | ||||
682 | |||||
683 | if (!name) | ||||
684 | return 0; | ||||
685 | l = strlen(name); | ||||
686 | if (l < 2 || name[l - 1] != '*' || name[l - 2] != '-') | ||||
687 | return 0; | ||||
688 | charset = NULL((void*)0); | ||||
689 | /* next three lines stolen from _XkbGetCharset() */ | ||||
690 | lcd = _XlcCurrentLC(); | ||||
691 | if ((lcd = _XlcCurrentLC()) != 0) | ||||
692 | charset = XLC_PUBLIC(lcd, encoding_name)(((XLCdPublic) lcd->core)->pub.encoding_name); | ||||
693 | if (!charset || (p = strrchr(charset, '-')) == 0 || p == charset || p[1] == 0 || (p[1] == '*' && p[2] == 0)) { | ||||
694 | /* prefer latin1 if no encoding found */ | ||||
695 | charset = "ISO8859-1"; | ||||
696 | p = charset + 7; | ||||
697 | } | ||||
698 | if (l - 2 - (p - charset) < 0) | ||||
699 | return 0; | ||||
700 | if (_XlcNCompareISOLatin1(name + l - 2 - (p - charset), charset, p - charset)) | ||||
701 | return 0; | ||||
702 | if (strlen(p + 1) + l - 1 >= sizeof(buf) - 1) | ||||
703 | return 0; | ||||
704 | strcpy(buf, name); | ||||
705 | strcpy(buf + l - 1, p + 1); | ||||
706 | fs = XLoadQueryFont(dpy, buf); | ||||
707 | if (!fs) | ||||
708 | return 0; | ||||
709 | if (xfp) { | ||||
710 | *xfp = fs; | ||||
711 | if (fidp) | ||||
712 | *fidp = fs->fid; | ||||
713 | } else if (fidp) { | ||||
714 | if (fs->per_char) { | ||||
715 | #ifdef USE_XF86BIGFONT | ||||
716 | _XF86BigfontFreeFontMetrics(fs); | ||||
717 | #else | ||||
718 | Xfree ((char *) fs->per_char)free(((char *) fs->per_char)); | ||||
719 | #endif | ||||
720 | } | ||||
721 | _XFreeExtData(fs->ext_data); | ||||
722 | if (fs->properties) | ||||
723 | Xfree ((char *) fs->properties)free(((char *) fs->properties)); | ||||
724 | *fidp = fs->fid; | ||||
725 | Xfree ((char *) fs)free(((char *) fs)); | ||||
726 | } else { | ||||
727 | XFreeFont(dpy, fs); | ||||
728 | } | ||||
729 | return 1; | ||||
730 | } |