Bug Summary

File:grid.c
Location:line 830, column 30
Description:Access to field 'ascent' results in a dereference of a null pointer (loaded from field 'text_font')

Annotated Source Code

1/*
2 *
3Copyright 1989, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24 *
25 * Author: Jim Fulton, MIT X Consortium
26 */
27
28#include <X11/IntrinsicP.h>
29#include <X11/StringDefs.h>
30#include <X11/Xaw/SimpleP.h>
31#include <X11/Xmu/Converters.h>
32#include <X11/Xos.h>
33#include "gridP.h"
34
35#ifdef XKB
36#include <X11/extensions/XKBbells.h>
37#else
38#define XkbBI_MinorError2 2
39#define XkbBI_Ignore11 11
40#endif
41
42#ifdef XKB
43#define Bell(w,n)XBell((((w)->core.screen)->display), 0) XkbStdBell(XtDisplay(w)(((w)->core.screen)->display), XtWindow(w)((w)->core.window), 50, n)
44#else
45#define Bell(w,n)XBell((((w)->core.screen)->display), 0) XBell(XtDisplay(w)(((w)->core.screen)->display), 0)
46#endif
47
48static GC get_gc(FontGridWidget fgw, Pixel fore);
49static void ClassInitialize(void);
50static void Initialize(Widget request, Widget new, ArgList args,
51 Cardinal *num_args);
52static void Realize(Widget gw, Mask *valueMask,
53 XSetWindowAttributes *attributes);
54static void Destroy(Widget gw);
55static void Resize(Widget gw);
56static void Redisplay(Widget gw, XEvent *event, Region region);
57static void paint_grid(FontGridWidget fgw, int col, int row,
58 int ncols, int nrows);
59static Boolean SetValues(Widget current, Widget request, Widget new,
60 ArgList args, Cardinal *num_args);
61static void Notify(Widget gw, XEvent *event, String *params,
62 Cardinal *nparams);
63
64#define Offset(field) XtOffsetOf(FontGridRec, fontgrid.field)__builtin_offsetof(FontGridRec, fontgrid.field)
65
66static XtResource resources[] = {
67 { XtNfont((char*)&XtStrings[199]), XtCFont((char*)&XtStrings[1017]), XtRFontStruct((char*)&XtStrings[1666]), sizeof(XFontStruct *),
68 Offset(text_font), XtRString((char*)&XtStrings[1797]), (XtPointer) NULL((void*)0) },
69 { XtNcellColumns"cellColumns", XtCCellColumns"CellColumns", XtRInt((char*)&XtStrings[1718]), sizeof(int),
70 Offset(cell_cols), XtRImmediate((char*)&XtStrings[1695]), (XtPointer) 0 },
71 { XtNcellRows"cellRows", XtCCellRows"CellRows", XtRInt((char*)&XtStrings[1718]), sizeof(int),
72 Offset(cell_rows), XtRImmediate((char*)&XtStrings[1695]), (XtPointer) 0 },
73 { XtNcellWidth"cellWidth", XtCCellWidth"CellWidth", XtRInt((char*)&XtStrings[1718]), sizeof(int),
74 Offset(cell_width), XtRImmediate((char*)&XtStrings[1695]), (XtPointer) 0 },
75 { XtNcellHeight"cellHeight", XtCCellHeight"CellHeight", XtRInt((char*)&XtStrings[1718]), sizeof(int),
76 Offset(cell_height), XtRImmediate((char*)&XtStrings[1695]), (XtPointer) 0 },
77 { XtNstartChar"startChar", XtCStartChar"StartChar", XtRLong"Long", sizeof(long),
78 Offset(start_char), XtRImmediate((char*)&XtStrings[1695]), (XtPointer) 0xffffffff },
79#ifndef XRENDER1
80 { XtNforeground((char*)&XtStrings[214]), XtCForeground((char*)&XtStrings[1022]), XtRPixel((char*)&XtStrings[1754]), sizeof(Pixel),
81 Offset(foreground_pixel), XtRString((char*)&XtStrings[1797]), (XtPointer) XtDefaultForeground"XtDefaultForeground" },
82#endif
83 { XtNcenterChars"centerChars", XtCCenterChars"CenterChars", XtRBoolean((char*)&XtStrings[1561]), sizeof(Boolean),
84 Offset(center_chars), XtRImmediate((char*)&XtStrings[1695]), (XtPointer) FALSE0 },
85 { XtNboxChars"boxChars", XtCBoxChars"BoxChars", XtRBoolean((char*)&XtStrings[1561]), sizeof(Boolean),
86 Offset(box_chars), XtRImmediate((char*)&XtStrings[1695]), (XtPointer) FALSE0 },
87 { XtNboxColor"boxColor", XtCForeground((char*)&XtStrings[1022]), XtRPixel((char*)&XtStrings[1754]), sizeof(Pixel),
88 Offset(box_pixel), XtRString((char*)&XtStrings[1797]), (XtPointer) XtDefaultForeground"XtDefaultForeground" },
89 { XtNcallback((char*)&XtStrings[136]), XtCCallback((char*)&XtStrings[952]), XtRCallback((char*)&XtStrings[1569]), sizeof(XtPointer),
90 Offset(callbacks), XtRCallback((char*)&XtStrings[1569]), (XtPointer) NULL((void*)0) },
91 { XtNinternalPad"internalPad", XtCInternalPad"InternalPad", XtRInt((char*)&XtStrings[1718]), sizeof(int),
92 Offset(internal_pad), XtRImmediate((char*)&XtStrings[1695]), (XtPointer) 4 },
93 { XtNgridWidth"gridWidth", XtCGridWidth"GridWidth", XtRInt((char*)&XtStrings[1718]), sizeof(int),
94 Offset(grid_width), XtRImmediate((char*)&XtStrings[1695]), (XtPointer) 1 },
95#ifdef XRENDER1
96 {XtNforeground((char*)&XtStrings[214]), XtCForeground((char*)&XtStrings[1022]), XtRXftColor"XftColor", sizeof(XftColor),
97 Offset(fg_color), XtRString((char*)&XtStrings[1797]), XtDefaultForeground"XtDefaultForeground"},
98 {XtNface"face", XtCFace"Face", XtRXftFont"XftFont", sizeof (XftFont *),
99 Offset (text_face), XtRString((char*)&XtStrings[1797]), NULL((void*)0)},
100#endif
101};
102
103#undef Offset
104
105static char defaultTranslations[] =
106 "<ButtonPress>: notify()";
107
108static XtActionsRec actions_list[] = {
109 { "notify", Notify },
110};
111
112FontGridClassRec fontgridClassRec = {
113 { /* core fields */
114 /* superclass */ (WidgetClass) &simpleClassRec,
115 /* class_name */ "FontGrid",
116 /* widget_size */ sizeof(FontGridRec),
117 /* class_initialize */ ClassInitialize,
118 /* class_part_initialize */ NULL((void*)0),
119 /* class_inited */ FALSE0,
120 /* initialize */ Initialize,
121 /* initialize_hook */ NULL((void*)0),
122 /* realize */ Realize,
123 /* actions */ actions_list,
124 /* num_actions */ XtNumber(actions_list)((Cardinal) (sizeof(actions_list) / sizeof(actions_list[0]))),
125 /* resources */ resources,
126 /* num_resources */ XtNumber(resources)((Cardinal) (sizeof(resources) / sizeof(resources[0]))),
127 /* xrm_class */ NULLQUARK((XrmQuark) 0),
128 /* compress_motion */ TRUE1,
129 /* compress_exposure */ TRUE1,
130 /* compress_enterleave */ TRUE1,
131 /* visible_interest */ FALSE0,
132 /* destroy */ Destroy,
133 /* resize */ Resize,
134 /* expose */ Redisplay,
135 /* set_values */ SetValues,
136 /* set_values_hook */ NULL((void*)0),
137 /* set_values_almost */ XtInheritSetValuesAlmost((XtAlmostProc) _XtInherit),
138 /* get_values_hook */ NULL((void*)0),
139 /* accept_focus */ NULL((void*)0),
140 /* version */ XtVersion(11 * 1000 + 6),
141 /* callback_private */ NULL((void*)0),
142 /* tm_table */ defaultTranslations,
143 /* query_geometry */ XtInheritQueryGeometry((XtGeometryHandler) _XtInherit),
144 /* display_accelerator */ XtInheritDisplayAccelerator((XtStringProc) _XtInherit),
145 /* extension */ NULL((void*)0)
146 },
147 { /* simple fields */
148 /* change_sensitive */ XtInheritChangeSensitive((int (*)(Widget))_XtInherit)
149 }
150};
151
152WidgetClass fontgridWidgetClass = (WidgetClass) &fontgridClassRec;
153
154
155long
156GridFirstChar (Widget w)
157{
158 FontGridWidget fgw = (FontGridWidget) w;
159 XFontStruct *fs = fgw->fontgrid.text_font;
160#ifdef XRENDER1
161 XftFont *xft = fgw->fontgrid.text_face;
162 if (xft)
163 {
164 FcChar32 map[FC_CHARSET_MAP_SIZE(256/32)];
165 FcChar32 next;
166 FcChar32 first;
167 int i;
168
169 first = FcCharSetFirstPage (xft->charset, map, &next);
170 for (i = 0; i < FC_CHARSET_MAP_SIZE(256/32); i++)
171 if (map[i])
172 {
173 FcChar32 bits = map[i];
174 first += i * 32;
175 while (!(bits & 0x1))
176 {
177 bits >>= 1;
178 first++;
179 }
180 break;
181 }
182 return first;
183 }
184 else
185#endif
186 if (fs)
187 {
188 return (fs->min_byte1 << 8) | (fs->min_char_or_byte2);
189 }
190 else
191 return 0;
192}
193
194long
195GridLastChar (Widget w)
196{
197 FontGridWidget fgw = (FontGridWidget) w;
198 XFontStruct *fs = fgw->fontgrid.text_font;
199#ifdef XRENDER1
200 XftFont *xft = fgw->fontgrid.text_face;
201 if (xft)
202 {
203 FcChar32 this, last, next;
204 FcChar32 map[FC_CHARSET_MAP_SIZE(256/32)];
205 int i;
206 last = FcCharSetFirstPage (xft->charset, map, &next);
207 while ((this = FcCharSetNextPage (xft->charset, map, &next)) != FC_CHARSET_DONE((FcChar32) -1))
208 last = this;
209 last &= ~0xff;
210 for (i = FC_CHARSET_MAP_SIZE(256/32) - 1; i >= 0; i--)
211 if (map[i])
212 {
213 FcChar32 bits = map[i];
214 last += i * 32 + 31;
215 while (!(bits & 0x80000000))
216 {
217 last--;
218 bits <<= 1;
219 }
220 break;
221 }
222 return (long) last;
223 }
224 else
225#endif
226 if (fs)
227 {
228 return (fs->max_byte1 << 8) | (fs->max_char_or_byte2);
229 }
230 else
231 return 0;
232}
233
234/*
235 * CI_GET_CHAR_INFO_1D - return the charinfo struct for the indicated 8bit
236 * character. If the character is in the column and exists, then return the
237 * appropriate metrics (note that fonts with common per-character metrics will
238 * return min_bounds).
239 */
240
241#define CI_NONEXISTCHAR(cs)(((cs)->width == 0) && (((cs)->rbearing|(cs)->
lbearing| (cs)->ascent|(cs)->descent) == 0))
(((cs)->width == 0) && \
242 (((cs)->rbearing|(cs)->lbearing| \
243 (cs)->ascent|(cs)->descent) == 0))
244
245#define CI_GET_CHAR_INFO_1D(fs,col,cs){ cs = ((void*)0); if (col >= fs->min_char_or_byte2 &&
col <= fs->max_char_or_byte2) { if (fs->per_char ==
((void*)0)) { cs = &fs->min_bounds; } else { cs = &
fs->per_char[(col - fs->min_char_or_byte2)]; } if ((((cs
)->width == 0) && (((cs)->rbearing|(cs)->lbearing
| (cs)->ascent|(cs)->descent) == 0))) cs = ((void*)0); }
}
\
246{ \
247 cs = NULL((void*)0); \
248 if (col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \
249 if (fs->per_char == NULL((void*)0)) { \
250 cs = &fs->min_bounds; \
251 } else { \
252 cs = &fs->per_char[(col - fs->min_char_or_byte2)]; \
253 } \
254 if (CI_NONEXISTCHAR(cs)(((cs)->width == 0) && (((cs)->rbearing|(cs)->
lbearing| (cs)->ascent|(cs)->descent) == 0))
) \
255 cs = NULL((void*)0); \
256 } \
257}
258
259/*
260 * CI_GET_CHAR_INFO_2D - return the charinfo struct for the indicated row and
261 * column. This is used for fonts that have more than row zero.
262 */
263#define CI_GET_CHAR_INFO_2D(fs,row,col,cs){ cs = ((void*)0); if (row >= fs->min_byte1 && row
<= fs->max_byte1 && col >= fs->min_char_or_byte2
&& col <= fs->max_char_or_byte2) { if (fs->
per_char == ((void*)0)) { cs = &fs->min_bounds; } else
{ cs = &fs->per_char[((row - fs->min_byte1) * (fs->
max_char_or_byte2 - fs->min_char_or_byte2 + 1)) + (col - fs
->min_char_or_byte2)]; } if ((((cs)->width == 0) &&
(((cs)->rbearing|(cs)->lbearing| (cs)->ascent|(cs)->
descent) == 0))) cs = ((void*)0); } }
\
264{ \
265 cs = NULL((void*)0); \
266 if (row >= fs->min_byte1 && row <= fs->max_byte1 && \
267 col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \
268 if (fs->per_char == NULL((void*)0)) { \
269 cs = &fs->min_bounds; \
270 } else { \
271 cs = &fs->per_char[((row - fs->min_byte1) * \
272 (fs->max_char_or_byte2 - \
273 fs->min_char_or_byte2 + 1)) + \
274 (col - fs->min_char_or_byte2)]; \
275 } \
276 if (CI_NONEXISTCHAR(cs)(((cs)->width == 0) && (((cs)->rbearing|(cs)->
lbearing| (cs)->ascent|(cs)->descent) == 0))
) \
277 cs = NULL((void*)0); \
278 } \
279}
280
281static Boolean
282GridHasChar (Widget w, long ch)
283{
284 FontGridWidget fgw = (FontGridWidget) w;
285#ifdef XRENDER1
286 XftFont *xft = fgw->fontgrid.text_face;
287 if (xft)
288 {
289 return FcCharSetHasChar (xft->charset, (FcChar32) ch);
290 }
291 else
292#endif
293 {
294 XFontStruct *fs = fgw->fontgrid.text_font;
295 XCharStruct *cs;
296
297 if (!fs)
298 return False0;
299 if (fs->max_byte1 == 0)
300 {
301 CI_GET_CHAR_INFO_1D (fs, ch, cs){ cs = ((void*)0); if (ch >= fs->min_char_or_byte2 &&
ch <= fs->max_char_or_byte2) { if (fs->per_char == (
(void*)0)) { cs = &fs->min_bounds; } else { cs = &
fs->per_char[(ch - fs->min_char_or_byte2)]; } if ((((cs
)->width == 0) && (((cs)->rbearing|(cs)->lbearing
| (cs)->ascent|(cs)->descent) == 0))) cs = ((void*)0); }
}
;
302 }
303 else
304 {
305 unsigned int r = (ch >> 8);
306 unsigned int c = (ch & 0xff);
307 CI_GET_CHAR_INFO_2D (fs, r, c, cs){ cs = ((void*)0); if (r >= fs->min_byte1 && r <=
fs->max_byte1 && c >= fs->min_char_or_byte2
&& c <= fs->max_char_or_byte2) { if (fs->per_char
== ((void*)0)) { cs = &fs->min_bounds; } else { cs = &
fs->per_char[((r - fs->min_byte1) * (fs->max_char_or_byte2
- fs->min_char_or_byte2 + 1)) + (c - fs->min_char_or_byte2
)]; } if ((((cs)->width == 0) && (((cs)->rbearing
|(cs)->lbearing| (cs)->ascent|(cs)->descent) == 0)))
cs = ((void*)0); } }
;
308 }
309 return cs != NULL((void*)0);
310 }
311}
312
313/*
314 * public routines
315 */
316
317void
318GetFontGridCellDimensions(Widget w, long *startp,
319 int *ncolsp, int *nrowsp)
320{
321 FontGridWidget fgw = (FontGridWidget) w;
322 *startp = fgw->fontgrid.start_char;
323 *ncolsp = fgw->fontgrid.cell_cols;
324 *nrowsp = fgw->fontgrid.cell_rows;
325}
326
327
328void
329GetPrevNextStates(Widget w, Boolint *prevvalidp, Boolint *nextvalidp,
330 Boolint *prev16validp, Boolint *next16validp)
331{
332 FontGridWidget fgw = (FontGridWidget) w;
333 long minn = (long) GridFirstChar (w);
334 long maxn = (long) GridLastChar (w);
335
336 *prev16validp = (fgw->fontgrid.start_char - 0xf00 > minn);
337 *prevvalidp = (fgw->fontgrid.start_char > minn);
338 *nextvalidp = (fgw->fontgrid.start_char +
339 (fgw->fontgrid.cell_cols * fgw->fontgrid.cell_rows)
340 < maxn);
341 *next16validp =((fgw->fontgrid.start_char + 0xf00 +
342 (fgw->fontgrid.cell_cols * fgw->fontgrid.cell_rows))
343 < maxn);
344}
345
346
347
348/*
349 * private routines and methods
350 */
351
352
353static GC
354get_gc(FontGridWidget fgw, Pixel fore)
355{
356 XtGCMask mask;
357 XGCValues gcv;
358
359 mask = (GCForeground(1L<<2) | GCBackground(1L<<3) | GCFunction(1L<<0));
360 gcv.foreground = fore;
361 gcv.background = fgw->core.background_pixel;
362 gcv.function = GXcopy0x3;
363 if (fgw->fontgrid.text_font)
364 {
365 mask |= GCFont(1L<<14);
366 gcv.font = fgw->fontgrid.text_font->fid;
367 }
368 gcv.cap_style = CapProjecting3;
369 mask |= GCCapStyle(1L<<6);
370 if (fgw->fontgrid.grid_width > 0) {
371 mask |= GCLineWidth(1L<<4);
372 gcv.line_width = ((fgw->fontgrid.grid_width < 2) ? 0 :
373 fgw->fontgrid.grid_width);
374 }
375 return (XtGetGC ((Widget) fgw, mask, &gcv));
376}
377
378
379#ifdef XRENDER1
380static XtConvertArgRec xftColorConvertArgs[] = {
381 {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.screen)__builtin_offsetof(WidgetRec, core.screen),
382 sizeof(Screen *)},
383 {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.colormap)__builtin_offsetof(WidgetRec, core.colormap),
384 sizeof(Colormap)}
385};
386
387#define donestr(type, value, tstr){ if (toVal->addr != ((void*)0)) { if (toVal->size <
sizeof(type)) { toVal->size = sizeof(type); XtDisplayStringConversionWarning
(dpy, (char*) fromVal->addr, tstr); return 0; } *(type*)(toVal
->addr) = (value); } else { static type static_val; static_val
= (value); toVal->addr = (XPointer)&static_val; } toVal
->size = sizeof(type); return 1; }
\
388 { \
389 if (toVal->addr != NULL((void*)0)) { \
390 if (toVal->size < sizeof(type)) { \
391 toVal->size = sizeof(type); \
392 XtDisplayStringConversionWarning(dpy, \
393 (char*) fromVal->addr, tstr); \
394 return False0; \
395 } \
396 *(type*)(toVal->addr) = (value); \
397 } \
398 else { \
399 static type static_val; \
400 static_val = (value); \
401 toVal->addr = (XPointer)&static_val; \
402 } \
403 toVal->size = sizeof(type); \
404 return True1; \
405 }
406
407static void
408XmuFreeXftColor (XtAppContext app, XrmValuePtr toVal, XtPointer closure,
409 XrmValuePtr args, Cardinal *num_args)
410{
411 Screen *screen;
412 Colormap colormap;
413 XftColor *color;
414
415 if (*num_args != 2)
416 {
417 XtAppErrorMsg (app,
418 "freeXftColor", "wrongParameters",
419 "XtToolkitError",
420 "Freeing an XftColor requires screen and colormap arguments",
421 (String *) NULL((void*)0), (Cardinal *)NULL((void*)0));
422 return;
423 }
424
425 screen = *((Screen **) args[0].addr);
426 colormap = *((Colormap *) args[1].addr);
427 color = (XftColor *) toVal->addr;
428 XftColorFree (DisplayOfScreen (screen)((screen)->display),
429 DefaultVisual (DisplayOfScreen (screen),((&((_XPrivDisplay)((screen)->display))->screens[XScreenNumberOfScreen
(screen)])->root_visual)
430 XScreenNumberOfScreen (screen))((&((_XPrivDisplay)((screen)->display))->screens[XScreenNumberOfScreen
(screen)])->root_visual)
,
431 colormap, color);
432}
433
434static Boolean
435XmuCvtStringToXftColor(Display *dpy,
436 XrmValue *args, Cardinal *num_args,
437 XrmValue *fromVal, XrmValue *toVal,
438 XtPointer *converter_data)
439{
440 char *spec;
441 XRenderColor renderColor;
442 XftColor xftColor;
443 Screen *screen;
444 Colormap colormap;
445
446 if (*num_args != 2)
447 {
448 XtAppErrorMsg (XtDisplayToApplicationContext (dpy),
449 "cvtStringToXftColor", "wrongParameters",
450 "XtToolkitError",
451 "String to render color conversion needs screen and colormap arguments",
452 (String *) NULL((void*)0), (Cardinal *)NULL((void*)0));
453 return False0;
454 }
455
456 screen = *((Screen **) args[0].addr);
457 colormap = *((Colormap *) args[1].addr);
458
459 spec = (char *) fromVal->addr;
460 if (strcasecmp (spec, XtDefaultForeground"XtDefaultForeground") == 0)
461 {
462 renderColor.red = 0;
463 renderColor.green = 0;
464 renderColor.blue = 0;
465 renderColor.alpha = 0xffff;
466 }
467 else if (strcasecmp (spec, XtDefaultBackground"XtDefaultBackground") == 0)
468 {
469 renderColor.red = 0xffff;
470 renderColor.green = 0xffff;
471 renderColor.blue = 0xffff;
472 renderColor.alpha = 0xffff;
473 }
474 else if (!XRenderParseColor (dpy, spec, &renderColor))
475 return False0;
476 if (!XftColorAllocValue (dpy,
477 DefaultVisual (dpy,((&((_XPrivDisplay)dpy)->screens[XScreenNumberOfScreen
(screen)])->root_visual)
478 XScreenNumberOfScreen (screen))((&((_XPrivDisplay)dpy)->screens[XScreenNumberOfScreen
(screen)])->root_visual)
,
479 colormap,
480 &renderColor,
481 &xftColor))
482 return False0;
483
484 donestr (XftColor, xftColor, XtRXftColor){ if (toVal->addr != ((void*)0)) { if (toVal->size <
sizeof(XftColor)) { toVal->size = sizeof(XftColor); XtDisplayStringConversionWarning
(dpy, (char*) fromVal->addr, "XftColor"); return 0; } *(XftColor
*)(toVal->addr) = (xftColor); } else { static XftColor static_val
; static_val = (xftColor); toVal->addr = (XPointer)&static_val
; } toVal->size = sizeof(XftColor); return 1; }
;
485}
486
487static void
488XmuFreeXftFont (XtAppContext app, XrmValuePtr toVal, XtPointer closure,
489 XrmValuePtr args, Cardinal *num_args)
490{
491 Screen *screen;
492 XftFont *font;
493
494 if (*num_args != 1)
495 {
496 XtAppErrorMsg (app,
497 "freeXftFont", "wrongParameters",
498 "XtToolkitError",
499 "Freeing an XftFont requires screen argument",
500 (String *) NULL((void*)0), (Cardinal *)NULL((void*)0));
501 return;
502 }
503
504 screen = *((Screen **) args[0].addr);
505 font = *((XftFont **) toVal->addr);
506 if (font)
507 XftFontClose (DisplayOfScreen (screen)((screen)->display), font);
508}
509
510static Boolean
511XmuCvtStringToXftFont(Display *dpy,
512 XrmValue *args, Cardinal *num_args,
513 XrmValue *fromVal, XrmValue *toVal,
514 XtPointer *converter_data)
515{
516 char *name;
517 XftFont *font;
518 Screen *screen;
519
520 if (*num_args != 1)
521 {
522 XtAppErrorMsg (XtDisplayToApplicationContext (dpy),
523 "cvtStringToXftFont", "wrongParameters",
524 "XtToolkitError",
525 "String to XftFont conversion needs screen argument",
526 (String *) NULL((void*)0), (Cardinal *)NULL((void*)0));
527 return False0;
528 }
529
530 screen = *((Screen **) args[0].addr);
531 name = (char *) fromVal->addr;
532
533 font = NULL((void*)0);
534 if (name)
535 {
536 font = XftFontOpenName (dpy,
537 XScreenNumberOfScreen (screen),
538 name);
539 if (!font)
540 XtDisplayStringConversionWarning(dpy, (char *) fromVal->addr, XtRXftFont"XftFont");
541 }
542 donestr (XftFont *, font, XtRXftFont){ if (toVal->addr != ((void*)0)) { if (toVal->size <
sizeof(XftFont *)) { toVal->size = sizeof(XftFont *); XtDisplayStringConversionWarning
(dpy, (char*) fromVal->addr, "XftFont"); return 0; } *(XftFont
**)(toVal->addr) = (font); } else { static XftFont * static_val
; static_val = (font); toVal->addr = (XPointer)&static_val
; } toVal->size = sizeof(XftFont *); return 1; }
;
543}
544
545static XtConvertArgRec xftFontConvertArgs[] = {
546 {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.screen)__builtin_offsetof(WidgetRec, core.screen),
547 sizeof(Screen *)},
548};
549
550#endif
551
552static void
553ClassInitialize(void)
554{
555 XtAddConverter (XtRString((char*)&XtStrings[1797]), XtRLong"Long", XmuCvtStringToLong, NULL((void*)0), 0);
556#ifdef XRENDER1
557 XtSetTypeConverter (XtRString((char*)&XtStrings[1797]), XtRXftColor"XftColor",
558 XmuCvtStringToXftColor,
559 xftColorConvertArgs, XtNumber(xftColorConvertArgs)((Cardinal) (sizeof(xftColorConvertArgs) / sizeof(xftColorConvertArgs
[0])))
,
560 XtCacheByDisplay0x003, XmuFreeXftColor);
561 XtSetTypeConverter (XtRString((char*)&XtStrings[1797]), XtRXftFont"XftFont",
562 XmuCvtStringToXftFont,
563 xftFontConvertArgs, XtNumber(xftFontConvertArgs)((Cardinal) (sizeof(xftFontConvertArgs) / sizeof(xftFontConvertArgs
[0])))
,
564 XtCacheByDisplay0x003, XmuFreeXftFont);
565#endif
566}
567
568
569static void
570Initialize(Widget request, Widget new, ArgList args, Cardinal *num_args)
571{
572 FontGridWidget reqfg = (FontGridWidget) request;
573 FontGridWidget newfg = (FontGridWidget) new;
574 XFontStruct *fs = newfg->fontgrid.text_font;
575#ifdef XRENDER1
576 XftFont *xft = newfg->fontgrid.text_face;
577#endif
578 unsigned maxn;
579
580 if (reqfg->fontgrid.cell_cols <= 0)
581 newfg->fontgrid.cell_cols = 16;
582
583 if (reqfg->fontgrid.cell_rows <= 0) {
584#ifdef XRENDER1
585 if (xft)
586 newfg->fontgrid.cell_rows = 16;
587 else
588#endif
589 if (fs && fs->max_byte1 == 0) {
590 newfg->fontgrid.cell_rows = (fs->max_char_or_byte2 /
591 newfg->fontgrid.cell_cols) + 1;
592 if (newfg->fontgrid.cell_rows > 16)
593 newfg->fontgrid.cell_rows = 16;
594 } else
595 newfg->fontgrid.cell_rows = 16;
596 }
597
598 if (reqfg->fontgrid.cell_width <= 0)
599 newfg->fontgrid.cell_width = DefaultCellWidth (newfg)(((newfg)->fontgrid.text_face ? (newfg)->fontgrid.text_face
->max_advance_width : (newfg)->fontgrid.text_font ? (newfg
)->fontgrid.text_font->max_bounds.width : 1) + ((newfg)
->fontgrid.internal_pad * 2))
;
600 if (reqfg->fontgrid.cell_height <= 0)
601 newfg->fontgrid.cell_height = DefaultCellHeight (newfg)(((newfg)->fontgrid.text_face ? (newfg)->fontgrid.text_face
->height : (newfg)->fontgrid.text_font ? (newfg)->fontgrid
.text_font->ascent + (newfg)->fontgrid.text_font->descent
: 1) + ((newfg)->fontgrid.internal_pad * 2))
;
602
603 /* give a nice size that fits one screen full */
604 if (newfg->core.width == 0)
605 newfg->core.width = (newfg->fontgrid.cell_width *
606 newfg->fontgrid.cell_cols +
607 newfg->fontgrid.grid_width *
608 (newfg->fontgrid.cell_cols + 1));
609
610 if (newfg->core.height == 0)
611 newfg->core.height = (newfg->fontgrid.cell_height *
612 newfg->fontgrid.cell_rows +
613 newfg->fontgrid.grid_width *
614 (newfg->fontgrid.cell_rows + 1));
615
616 /*
617 * select the first character
618 */
619
620 if (newfg->fontgrid.start_char == 0xffffffff)
621 newfg->fontgrid.start_char = GridFirstChar(new) & ~0xff;
622 maxn = GridLastChar (new);
623 if (newfg->fontgrid.start_char > maxn)
624 newfg->fontgrid.start_char = (maxn + 1 -
625 (newfg->fontgrid.cell_cols *
626 newfg->fontgrid.cell_rows));
627}
628
629static void
630Realize(Widget gw, Mask *valueMask, XSetWindowAttributes *attributes)
631{
632 FontGridWidget fgw = (FontGridWidget) gw;
633 FontGridPart *p = &fgw->fontgrid;
634
635 p->text_gc = get_gc (fgw, GridForeground (fgw)((fgw)->fontgrid.fg_color.pixel));
636 p->box_gc = get_gc (fgw, p->box_pixel);
637 Resize (gw);
638
639 (*(XtSuperclass(gw)(((gw)->core.widget_class)->core_class.superclass)->core_class.realize)) (gw, valueMask, attributes);
640#ifdef XRENDER1
641 p->draw = XftDrawCreate (XtDisplay (gw)(((gw)->core.screen)->display), XtWindow (gw)((gw)->core.window),
642 DefaultVisual (XtDisplay (gw),((&((_XPrivDisplay)(((gw)->core.screen)->display))->
screens[(((_XPrivDisplay)(((gw)->core.screen)->display)
)->default_screen)])->root_visual)
643 DefaultScreen(XtDisplay (gw)))((&((_XPrivDisplay)(((gw)->core.screen)->display))->
screens[(((_XPrivDisplay)(((gw)->core.screen)->display)
)->default_screen)])->root_visual)
,
644 fgw->core.colormap);
645#endif
646 return;
647}
648
649
650
651static void
652Destroy(Widget gw)
653{
654 FontGridWidget fgw = (FontGridWidget) gw;
655
656 XtReleaseGC (gw, fgw->fontgrid.text_gc);
657 XtReleaseGC (gw, fgw->fontgrid.box_gc);
658}
659
660
661static void
662Resize(Widget gw)
663{
664 FontGridWidget fgw = (FontGridWidget) gw;
665
666 /* recompute in case we've changed size */
667 fgw->fontgrid.cell_width = CellWidth (fgw)(((int)(fgw)->core.width - (fgw)->fontgrid.grid_width) /
(fgw)->fontgrid.cell_cols - (fgw)->fontgrid.grid_width
)
;
668 if (fgw->fontgrid.cell_width <= 0)
669 fgw->fontgrid.cell_width = 1;
670 fgw->fontgrid.cell_height = CellHeight (fgw)(((int)(fgw)->core.height - (fgw)->fontgrid.grid_width)
/ (fgw)->fontgrid.cell_rows - (fgw)->fontgrid.grid_width
)
;
671 if (fgw->fontgrid.cell_height <= 0)
672 fgw->fontgrid.cell_height = 1;
673 fgw->fontgrid.xoff = (fgw->fontgrid.cell_width -
674 DefaultCellWidth (fgw)(((fgw)->fontgrid.text_face ? (fgw)->fontgrid.text_face
->max_advance_width : (fgw)->fontgrid.text_font ? (fgw)
->fontgrid.text_font->max_bounds.width : 1) + ((fgw)->
fontgrid.internal_pad * 2))
) / 2;
675 fgw->fontgrid.yoff = (fgw->fontgrid.cell_height -
676 DefaultCellHeight (fgw)(((fgw)->fontgrid.text_face ? (fgw)->fontgrid.text_face
->height : (fgw)->fontgrid.text_font ? (fgw)->fontgrid
.text_font->ascent + (fgw)->fontgrid.text_font->descent
: 1) + ((fgw)->fontgrid.internal_pad * 2))
) / 2;
677
678}
679
680
681/* ARGSUSED */
682static void
683Redisplay(Widget gw, XEvent *event, Region region)
684{
685 FontGridWidget fgw = (FontGridWidget) gw;
686 XRectangle rect; /* bounding rect for region */
687 int left, right, top, bottom; /* which cells were damaged */
688 int cw, ch; /* cell size */
689
690#ifdef XRENDER1
691 if (!fgw->fontgrid.text_face)
692#endif
693 if (!fgw->fontgrid.text_font) {
694 Bell (gw, XkbBI_BadValue)XBell((((gw)->core.screen)->display), 0);
695 return;
696 }
697
698 /*
699 * compute the left, right, top, and bottom cells that were damaged
700 */
701 XClipBox (region, &rect);
702 cw = fgw->fontgrid.cell_width + fgw->fontgrid.grid_width;
703 ch = fgw->fontgrid.cell_height + fgw->fontgrid.grid_width;
704 if ((left = (((int) rect.x) / cw)) < 0) left = 0;
705 right = (((int) (rect.x + rect.width - 1)) / cw);
706 if ((top = (((int) rect.y) / ch)) < 0) top = 0;
707 bottom = (((int) (rect.y + rect.height - 1)) / ch);
708
709 paint_grid (fgw, left, top, right - left + 1, bottom - top + 1);
710}
711
712
713static void
714paint_grid(FontGridWidget fgw, /* widget in which to draw */
715 int col, int row, /* where to start */
716 int ncols, int nrows) /* number of cells */
717{
718 FontGridPart *p = &fgw->fontgrid;
719 int i, j;
720 Display *dpy = XtDisplay(fgw)(((fgw)->core.screen)->display);
721 Window wind = XtWindow(fgw)((fgw)->core.window);
722 int cw = p->cell_width + p->grid_width;
723 int ch = p->cell_height + p->grid_width;
724 int tcols = p->cell_cols;
725 int trows = p->cell_rows;
726 int x1, y1, x2, y2, x, y;
727 unsigned maxn = GridLastChar ((Widget) fgw);
1
Value assigned to field 'text_font'
728 unsigned n, prevn;
729 int startx;
730
731 if (col + ncols >= tcols) {
2
Taking false branch
732 ncols = tcols - col;
733 if (ncols < 1) return;
734 }
735
736 if (row + nrows >= trows) {
3
Taking false branch
737 nrows = trows - row;
738 if (nrows < 1) return;
739 }
740
741 /*
742 * paint the grid lines for the indicated rows
743 */
744 if (p->grid_width > 0) {
4
Taking false branch
745 int half_grid_width = p->grid_width >> 1;
746 x1 = col * cw + half_grid_width;
747 y1 = row * ch + half_grid_width;
748 x2 = x1 + ncols * cw;
749 y2 = y1 + nrows * ch;
750 for (i = 0, x = x1; i <= ncols; i++, x += cw) {
751 XDrawLine (dpy, wind, p->box_gc, x, y1, x, y2);
752 }
753 for (i = 0, y = y1; i <= nrows; i++, y += ch) {
754 XDrawLine (dpy, wind, p->box_gc, x1, y, x2, y);
755 }
756 }
757 /*
758 * Draw a character in every box; treat all fonts as if they were 16bit
759 * fonts. Store the high eight bits in byte1 and the low eight bits in
760 * byte2.
761 */
762 prevn = p->start_char + col + row * tcols;
763 startx = col * cw + p->internal_pad + p->grid_width;
764 for (j = 0,
7
Loop condition is true. Entering loop body
765 y = row * ch + p->internal_pad + p->grid_width + GridFontAscent (fgw)((fgw)->fontgrid.text_face ? (fgw)->fontgrid.text_face->
ascent : (fgw)->fontgrid.text_font ? (fgw)->fontgrid.text_font
->ascent: 1)
;
5
Within the expansion of the macro 'GridFontAscent':
a
Assuming pointer value is null
766 j < nrows; j++, y += ch) {
6
Assuming 'j' is < 'nrows'
767 n = prevn;
768 for (i = 0, x = startx; i < ncols; i++, x += cw) {
8
Assuming 'i' is < 'ncols'
9
Loop condition is true. Entering loop body
769 int xoff = p->xoff, yoff = p->yoff;
770 if (n > maxn) goto done; /* no break out of nested */
10
Taking false branch
771
772#ifdef XRENDER1
773 if (fgw->fontgrid.text_face)
11
Taking false branch
774 {
775 XftFont *xft = p->text_face;
776 FcChar32 c = n;
777 XGlyphInfo extents;
778 XftTextExtents32 (dpy, xft, &c, 1, &extents);
779 if (p->center_chars)
780 {
781 xoff = (p->cell_width - extents.width) / 2 - extents.x;
782 yoff = (p->cell_height - extents.height) / 2 - extents.y;
783 }
784 if (extents.width && extents.height)
785 {
786 XClearArea (dpy, wind, x + xoff - extents.x,
787 y + yoff - extents.y,
788 extents.width, extents.height, False0);
789 if (p->box_chars)
790 XDrawRectangle (dpy, wind, p->box_gc,
791 x + xoff - extents.x,
792 y + yoff - extents.y,
793 extents.width - 1,
794 extents.height - 1);
795 }
796 XftDrawString32 (p->draw, &p->fg_color, xft,
797 x + xoff, y + yoff, &c, 1);
798 }
799 else
800#endif
801 {
802 XChar2b thechar;
803
804 thechar.byte1 = (n >> 8); /* high eight bits */
805 thechar.byte2 = (n & 255); /* low eight bits */
806 if (p->box_chars || p->center_chars) {
807 XCharStruct metrics;
808 int direction, fontascent, fontdescent;
809
810 XTextExtents16 (p->text_font, &thechar, 1, &direction,
811 &fontascent, &fontdescent, &metrics);
812
813 if (p->center_chars) {
12
Taking false branch
814 /*
815 * We want to move the origin by enough to center the ink
816 * within the cell. The left edge will then be at
817 * (cell_width - (rbearing - lbearing)) / 2; so we subtract
818 * the lbearing to find the origin. Ditto for vertical.
819 */
820 xoff = (((p->cell_width -
821 (metrics.rbearing - metrics.lbearing)) / 2) -
822 p->internal_pad - metrics.lbearing);
823 yoff = (((p->cell_height -
824 (metrics.descent + metrics.ascent)) / 2) -
825 p->internal_pad -
826 p->text_font->ascent + metrics.ascent);
827 }
828 if (p->box_chars) {
13
Taking true branch
829 XDrawRectangle (dpy, wind, p->box_gc,
830 x + xoff, y + yoff - p->text_font->ascent,
14
Access to field 'ascent' results in a dereference of a null pointer (loaded from field 'text_font')
831 metrics.width - 1,
832 fontascent + fontdescent - 1);
833 }
834 }
835 XDrawString16 (dpy, wind, p->text_gc, x + xoff, y + yoff,
836 &thechar, 1);
837 }
838 n++;
839 }
840 prevn += tcols;
841 }
842
843 done:
844 /*
845 * paint the grid lines for the indicated rows
846 */
847 if (p->grid_width > 0) {
848 int half_grid_width = p->grid_width >> 1;
849 x1 = col * cw + half_grid_width;
850 y1 = row * ch + half_grid_width;
851 x2 = x1 + ncols * cw;
852 y2 = y1 + nrows * ch;
853 for (i = 0, x = x1; i <= ncols; i++, x += cw) {
854 XDrawLine (dpy, wind, p->box_gc, x, y1, x, y2);
855 }
856 for (i = 0, y = y1; i <= nrows; i++, y += ch) {
857 XDrawLine (dpy, wind, p->box_gc, x1, y, x2, y);
858 }
859 }
860
861
862 return;
863}
864
865static Boolean
866PageBlank (Widget w, long first, long last)
867{
868 while (first <= last)
869 {
870 if (GridHasChar (w, first))
871 return False0;
872 first++;
873 }
874 return True1;
875}
876
877/*ARGSUSED*/
878static Boolean
879SetValues(Widget current, Widget request, Widget new,
880 ArgList args, Cardinal *num_args)
881{
882 FontGridWidget curfg = (FontGridWidget) current;
883 FontGridWidget newfg = (FontGridWidget) new;
884 Boolean redisplay = FALSE0;
885
886 if (curfg->fontgrid.text_font != newfg->fontgrid.text_font ||
887 curfg->fontgrid.internal_pad != newfg->fontgrid.internal_pad) {
888 newfg->fontgrid.cell_width = DefaultCellWidth (newfg)(((newfg)->fontgrid.text_face ? (newfg)->fontgrid.text_face
->max_advance_width : (newfg)->fontgrid.text_font ? (newfg
)->fontgrid.text_font->max_bounds.width : 1) + ((newfg)
->fontgrid.internal_pad * 2))
;
889 newfg->fontgrid.cell_height = DefaultCellHeight (newfg)(((newfg)->fontgrid.text_face ? (newfg)->fontgrid.text_face
->height : (newfg)->fontgrid.text_font ? (newfg)->fontgrid
.text_font->ascent + (newfg)->fontgrid.text_font->descent
: 1) + ((newfg)->fontgrid.internal_pad * 2))
;
890 redisplay = TRUE1;
891 }
892
893 if (GridForeground(curfg)((curfg)->fontgrid.fg_color.pixel) != GridForeground (newfg)((newfg)->fontgrid.fg_color.pixel)) {
894 XtReleaseGC (new, curfg->fontgrid.text_gc);
895 newfg->fontgrid.text_gc = get_gc (newfg, GridForeground (newfg)((newfg)->fontgrid.fg_color.pixel));
896 redisplay = TRUE1;
897 }
898
899 if (curfg->fontgrid.box_pixel != newfg->fontgrid.box_pixel) {
900 XtReleaseGC (new, curfg->fontgrid.text_gc);
901 newfg->fontgrid.box_gc = get_gc (newfg, newfg->fontgrid.box_pixel);
902 redisplay = TRUE1;
903 }
904
905 if (curfg->fontgrid.center_chars != newfg->fontgrid.center_chars ||
906 curfg->fontgrid.box_chars != newfg->fontgrid.box_chars)
907 redisplay = TRUE1;
908
909 if (curfg->fontgrid.start_char != newfg->fontgrid.start_char) {
910 long maxn = GridLastChar (new);
911 long page = newfg->fontgrid.cell_cols * newfg->fontgrid.cell_rows;
912 long dir = page;
913 long start = newfg->fontgrid.start_char;
914
915 if (start < curfg->fontgrid.start_char)
916 dir = -page;
917
918 if (start < 0)
919 start = 0;
920 if (start > maxn)
921 start = (maxn / page) * page;
922
923 while (PageBlank (new, start, start + page - 1))
924 {
925 long next = start + dir;
926
927 if (next < 0 || maxn < next)
928 break;
929 start = next;
930 }
931
932 newfg->fontgrid.start_char = start;
933 redisplay = (curfg->fontgrid.start_char != newfg->fontgrid.start_char);
934 }
935
936 return redisplay;
937}
938
939
940/* ARGSUSED */
941static void
942Notify(Widget gw, XEvent *event, String *params, Cardinal *nparams)
943{
944 FontGridWidget fgw = (FontGridWidget) gw;
945 int x, y; /* where the event happened */
946 FontGridCharRec rec; /* callback data */
947
948 /*
949 * only allow events with (x,y)
950 */
951 switch (event->type) {
952 case KeyPress2:
953 case KeyRelease3:
954 x = event->xkey.x;
955 y = event->xkey.y;
956 break;
957 case ButtonPress4:
958 case ButtonRelease5:
959 x = event->xbutton.x;
960 y = event->xbutton.y;
961 break;
962 case MotionNotify6:
963 x = event->xmotion.x;
964 y = event->xmotion.y;
965 break;
966 default:
967 Bell (gw, XkbBI_Ignore)XBell((((gw)->core.screen)->display), 0);
968 return;
969 }
970
971 /*
972 * compute the callback data
973 */
974 {
975 int cw = fgw->fontgrid.cell_width + fgw->fontgrid.grid_width;
976 int ch = fgw->fontgrid.cell_height + fgw->fontgrid.grid_width;
977 unsigned n;
978
979 if (x > (fgw->fontgrid.cell_cols * cw)) {
980 Bell (gw, XkbBI_InvalidLocation)XBell((((gw)->core.screen)->display), 0);
981 return;
982 }
983
984 n= (fgw->fontgrid.start_char +
985 ((y / ch) * fgw->fontgrid.cell_cols) + (x / cw));
986
987 rec.thefont = fgw->fontgrid.text_font;
988#ifdef XRENDER1
989 rec.theface = fgw->fontgrid.text_face;
990#endif
991 rec.thechar = n;
992 }
993
994 XtCallCallbacks (gw, XtNcallback((char*)&XtStrings[136]), (XtPointer) &rec);
995}
996