XEmacs 21.2.9
[chise/xemacs-chise.git.1] / src / glyphs-widget.c
1 /* Widget-specific glyph objects.
2    Copyright (C) 1998 Andy Piper
3
4 This file is part of XEmacs.
5
6 XEmacs is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
10
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with XEmacs; see the file COPYING.  If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.  */
20
21 /* Synched up with: Not in FSF. */
22
23 /* written by Andy Piper <andy@xemacs.org> */
24
25 #include <config.h>
26 #include "lisp.h"
27 #include "lstream.h"
28 #include "console.h"
29 #include "device.h"
30 #include "faces.h"
31 #include "glyphs.h"
32 #include "objects.h"
33 #include "bytecode.h"
34 #include "window.h"
35 #include "buffer.h"
36 #include "frame.h"
37 #include "insdel.h"
38 #include "opaque.h"
39
40 DEFINE_IMAGE_INSTANTIATOR_FORMAT (button);
41 DEFINE_IMAGE_INSTANTIATOR_FORMAT (combo);
42 Lisp_Object Qcombo;
43 DEFINE_IMAGE_INSTANTIATOR_FORMAT (edit);
44 Lisp_Object Qedit;
45 DEFINE_IMAGE_INSTANTIATOR_FORMAT (scrollbar);
46 Lisp_Object Qscrollbar;
47 DEFINE_IMAGE_INSTANTIATOR_FORMAT (widget);
48 #if 0
49 DEFINE_IMAGE_INSTANTIATOR_FORMAT (group);
50 Lisp_Object Qgroup;
51 #endif
52 DEFINE_IMAGE_INSTANTIATOR_FORMAT (label);
53 Lisp_Object Qlabel;
54 DEFINE_IMAGE_INSTANTIATOR_FORMAT (progress);
55 Lisp_Object Qprogress;
56
57 Lisp_Object Q_descriptor, Q_height, Q_width, Q_properties, Q_items;
58 Lisp_Object Q_image, Q_text, Q_percent;
59
60 #define WIDGET_BORDER_HEIGHT 2
61 #define WIDGET_BORDER_WIDTH 4
62
63 /* TODO:
64    - more complex controls.
65    - tooltips for controls.
66  */
67
68 /* In windows normal windows work in pixels, dialog boxes work in
69    dialog box units. Why? sigh. We could reuse the metrics for dialogs
70    if this were not the case. As it is we have to position things
71    pixel wise. I'm not even sure that X has this problem at least for
72    buttons in groups. */
73 Lisp_Object
74 widget_face_font_info (Lisp_Object domain, Lisp_Object face,
75                        int *height, int *width)
76 {
77   Lisp_Object font_instance = FACE_FONT (face, domain, Vcharset_ascii);
78
79   if (height)
80     *height = XFONT_INSTANCE (font_instance)->height;
81   if (width)
82     *width = XFONT_INSTANCE (font_instance)->width;
83   
84   return font_instance;
85 }
86
87 void
88 widget_text_to_pixel_conversion (Lisp_Object domain, Lisp_Object face,
89                                  int th, int tw,
90                                  int* height, int* width)
91 {
92   int ch=0, cw=0;
93   widget_face_font_info (domain, face, &ch, &cw);
94   if (height)
95     *height = th * (ch + 2 * WIDGET_BORDER_HEIGHT);
96   if (width)
97     *width = tw * cw + 2 * WIDGET_BORDER_WIDTH;
98 }
99
100 static int
101 widget_possible_dest_types (void)
102 {
103   return IMAGE_WIDGET_MASK;
104 }
105
106 static void
107 check_valid_glyph_or_image (Lisp_Object data)
108 {
109   Lisp_Object glyph = data;
110   if (SYMBOLP (data))
111     glyph = XSYMBOL (data)->value;
112
113   if (IMAGE_INSTANCEP (glyph))
114     CHECK_IMAGE_INSTANCE (glyph);
115   else if (!CONSP (glyph))
116     CHECK_BUFFER_GLYPH (glyph);
117 }
118
119 static void
120 check_valid_anything (Lisp_Object data)
121 {
122 }
123
124 static void
125 check_valid_callback (Lisp_Object data)
126 {
127     if (!SYMBOLP (data)
128         && !COMPILED_FUNCTIONP (data)
129         && !CONSP (data))
130     {
131         signal_simple_error (":callback must be a function or expression", data);
132     }
133 }
134
135 static void
136 check_valid_symbol (Lisp_Object data)
137 {
138     CHECK_SYMBOL (data);
139 }
140
141 static void
142 check_valid_string_or_vector (Lisp_Object data)
143 {
144     if (!STRINGP (data) && !VECTORP (data))
145         signal_simple_error (":descriptor must be a string or a vector", data);
146 }
147
148 static void
149 check_valid_item_list (Lisp_Object data)
150 {
151   Lisp_Object rest;
152   Lisp_Object items;
153   Fcheck_valid_plist (data);
154   
155   items = Fplist_get (data, Q_items, Qnil);
156
157   CHECK_LIST (items);
158   EXTERNAL_LIST_LOOP (rest, items)
159     {
160       CHECK_STRING (XCAR (rest));
161     }
162 }
163
164 /* wire widget property invocations to specific widgets ...  The
165  problem we are solving here is that when instantiators get converted
166  to instances they lose some type information (they just become
167  subwindows or widgets for example). For widgets we need to preserve
168  this type information so that we can do widget specific operations on
169  the instances. This is encoded in the widget type
170  field. widget_property gets invoked by decoding the primary type
171  (Qwidget), widget property then invokes based on the secondary type
172  (Qedit for example). It is debatable that we should wire things in this
173  generalised way rather than treating widgets specially in
174  image_instance_property. */
175 static Lisp_Object 
176 widget_property (Lisp_Object image_instance, Lisp_Object prop)
177 {
178   struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
179   struct image_instantiator_methods* meths;
180
181   /* first see if its a general property ... */
182   if (!NILP (Fplist_member (IMAGE_INSTANCE_WIDGET_PROPS (ii), prop)))
183     return Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii), prop, Qnil);
184
185   /* .. then try device specific methods ... */
186   meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii), 
187                                    IMAGE_INSTANCE_WIDGET_TYPE (ii), 
188                                    ERROR_ME_NOT);
189   if (meths && HAS_IIFORMAT_METH_P (meths, property))
190     return IIFORMAT_METH (meths, property, (image_instance, prop));
191   /* ... then format specific methods ... */
192   meths = decode_device_ii_format (Qnil, IMAGE_INSTANCE_WIDGET_TYPE (ii), 
193                                    ERROR_ME_NOT);
194   if (meths && HAS_IIFORMAT_METH_P (meths, property))
195     return IIFORMAT_METH (meths, property, (image_instance, prop));
196   /* ... then fail */
197   return Qunbound;
198 }
199
200 static Lisp_Object 
201 widget_set_property (Lisp_Object image_instance, Lisp_Object prop, Lisp_Object val)
202 {
203   struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
204   struct image_instantiator_methods* meths;
205   Lisp_Object ret;
206
207   /* try device specific methods first ... */
208   meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii), 
209                                    IMAGE_INSTANCE_WIDGET_TYPE (ii), 
210                                    ERROR_ME_NOT);
211   if (meths && HAS_IIFORMAT_METH_P (meths, set_property)
212       &&
213       !UNBOUNDP (ret = 
214                  IIFORMAT_METH (meths, set_property, (image_instance, prop, val))))
215     {
216       return ret;
217     }
218   /* ... then format specific methods ... */
219   meths = decode_device_ii_format (Qnil, IMAGE_INSTANCE_WIDGET_TYPE (ii), 
220                                    ERROR_ME_NOT);
221   if (meths && HAS_IIFORMAT_METH_P (meths, set_property)
222       &&
223       !UNBOUNDP (ret = 
224                  IIFORMAT_METH (meths, set_property, (image_instance, prop, val))))
225     {
226       return ret;
227     }
228   /* we didn't do any device specific properties, so shove the property in our plist */
229   IMAGE_INSTANCE_WIDGET_PROPS (ii)
230     = Fplist_put (IMAGE_INSTANCE_WIDGET_PROPS (ii), prop, val);
231   return val;
232 }
233
234 static void
235 widget_validate (Lisp_Object instantiator)
236 {
237   Lisp_Object desc = find_keyword_in_vector (instantiator, Q_descriptor);
238   struct gui_item gui;
239   if (NILP (desc))
240     signal_simple_error ("Must supply :descriptor", instantiator);
241
242   if (VECTORP (desc))
243       gui_parse_item_keywords (desc, &gui);
244
245   if (!NILP (find_keyword_in_vector (instantiator, Q_width))
246              && !NILP (find_keyword_in_vector (instantiator, Q_pixel_width)))
247     signal_simple_error ("Must supply only one of :width and :pixel-width", instantiator);
248
249   if (!NILP (find_keyword_in_vector (instantiator, Q_height))
250              && !NILP (find_keyword_in_vector (instantiator, Q_pixel_height)))
251     signal_simple_error ("Must supply only one of :height and :pixel-height", instantiator);
252 }
253
254 static void
255 combo_validate (Lisp_Object instantiator)
256 {
257   widget_validate (instantiator);
258   if (NILP (find_keyword_in_vector (instantiator, Q_properties)))
259     signal_simple_error ("Must supply item list", instantiator);
260 }
261
262 /* we need to convert things like glyphs to images, eval expressions
263    etc.*/
264 static Lisp_Object
265 widget_normalize (Lisp_Object inst, Lisp_Object console_type)
266 {
267   /* This function can call lisp */
268   Lisp_Object glyph = find_keyword_in_vector (inst, Q_image);
269
270   /* we need to eval glyph if its an expression, we do this for the
271      same reasons we normalize file to data. */
272   if (!NILP (glyph))
273     {
274       int i;
275       struct gcpro gcpro1;
276       if (SYMBOLP (glyph))
277         glyph = XSYMBOL (glyph)->value;
278       GCPRO1 (glyph);
279
280       if (CONSP (glyph))
281         glyph = Feval (glyph);
282       /* substitute the new glyph */
283       for (i = 0; i < XVECTOR_LENGTH (inst); i++)
284         {
285           if (EQ (Q_image, XVECTOR_DATA (inst)[i]))
286             {
287               XVECTOR_DATA (inst)[i+1] = glyph;
288               break;
289             }
290         }
291       UNGCPRO;
292     }
293   return inst;
294 }
295
296 static void
297 initialize_widget_image_instance (struct Lisp_Image_Instance *ii, Lisp_Object type)
298 {
299   /*  initialize_subwindow_image_instance (ii);*/
300   IMAGE_INSTANCE_WIDGET_TYPE (ii) = type;
301   IMAGE_INSTANCE_WIDGET_PROPS (ii) = Qnil;
302   IMAGE_INSTANCE_WIDGET_FACE (ii) = Vwidget_face;
303   gui_item_init (&IMAGE_INSTANCE_WIDGET_ITEM (ii));
304 }
305
306 /* Instantiate a button widget. Unfortunately instantiated widgets are
307    particular to a frame since they need to have a parent. It's not
308    like images where you just select the image into the context you
309    want to display it in and BitBlt it. So images instances can have a
310    many-to-one relationship with things you see, whereas widgets can
311    only be one-to-one (i.e. per frame) */
312 static void
313 widget_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator,
314                       Lisp_Object pointer_fg, Lisp_Object pointer_bg,
315                       int dest_mask, Lisp_Object domain, int default_textheight,
316                       int default_pixheight)
317 {
318   struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
319   struct gui_item* pgui = &IMAGE_INSTANCE_WIDGET_ITEM (ii);
320   Lisp_Object face = find_keyword_in_vector (instantiator, Q_face);
321   Lisp_Object height = find_keyword_in_vector (instantiator, Q_height);
322   Lisp_Object width = find_keyword_in_vector (instantiator, Q_width);
323   Lisp_Object pixwidth = find_keyword_in_vector (instantiator, Q_pixel_width);
324   Lisp_Object pixheight = find_keyword_in_vector (instantiator, Q_pixel_height);
325   Lisp_Object desc = find_keyword_in_vector (instantiator, Q_descriptor);
326   Lisp_Object glyph = find_keyword_in_vector (instantiator, Q_image);
327   int pw=0, ph=0, tw=0, th=0;
328   
329   /* this just does pixel type sizing */
330   subwindow_instantiate (image_instance, instantiator, pointer_fg, pointer_bg,
331                          dest_mask, domain);
332
333   if (!(dest_mask & IMAGE_WIDGET_MASK))
334     incompatible_image_types (instantiator, dest_mask, IMAGE_WIDGET_MASK);
335
336   initialize_widget_image_instance (ii, XVECTOR_DATA (instantiator)[0]);
337
338   /* retrieve the fg and bg colors */
339   if (!NILP (face))
340     IMAGE_INSTANCE_WIDGET_FACE (ii) = Fget_face (face);
341   
342   /* data items for some widgets */
343   IMAGE_INSTANCE_WIDGET_PROPS (ii) = 
344     find_keyword_in_vector (instantiator, Q_properties);
345
346   /* retrieve the gui item information. This is easy if we have been
347      provided with a vector, more difficult if we have just been given
348      keywords */
349   if (STRINGP (desc) || NILP (desc))
350     {
351       /* big cheat - we rely on the fact that a gui item looks like an instantiator */
352       gui_parse_item_keywords_no_errors (instantiator, pgui);
353       IMAGE_INSTANCE_WIDGET_TEXT (ii) = desc;
354     }
355   else
356     gui_parse_item_keywords_no_errors (desc, pgui);
357
358   /* normalize size information */
359   if (!NILP (width))
360     tw = XINT (width);
361   if (!NILP (height))
362     th = XINT (height);
363   if (!NILP (pixwidth))
364     pw = XINT (pixwidth);
365   if (!NILP (pixheight))
366     ph = XINT (pixheight);
367
368   /* for a widget with an image pick up the dimensions from that */
369   if (!NILP (glyph))
370     {
371       if (!pw && !tw)
372         pw = glyph_width (glyph, Qnil, DEFAULT_INDEX, domain) 
373           + 2 * WIDGET_BORDER_WIDTH;
374       if (!ph && !th)
375         ph = glyph_height (glyph, Qnil, DEFAULT_INDEX, domain) 
376           + 2 * WIDGET_BORDER_HEIGHT;
377     }
378
379   /* if we still don' t have sizes, guess from text size */
380   if (!tw && !pw && !NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
381     tw = XSTRING_LENGTH (IMAGE_INSTANCE_WIDGET_TEXT (ii));
382   if (!th && !ph)
383     {
384       if (default_textheight)
385         th = default_textheight;
386       else if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
387         th = 1;
388       else
389         ph = default_pixheight;
390     }
391   
392   if (tw !=0 || th !=0)
393     widget_text_to_pixel_conversion (domain,
394                                      IMAGE_INSTANCE_WIDGET_FACE (ii),
395                                      th, tw, th ? &ph : 0, tw ? &pw : 0);
396
397   IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii) = pw;
398   IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii) = ph;
399 }
400
401 static void
402 widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
403                     Lisp_Object pointer_fg, Lisp_Object pointer_bg,
404                     int dest_mask, Lisp_Object domain)
405 {
406   widget_instantiate_1 (image_instance, instantiator, pointer_fg,
407                                pointer_bg, dest_mask, domain, 1, 0);
408 }
409
410 static void
411 combo_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
412                    Lisp_Object pointer_fg, Lisp_Object pointer_bg,
413                    int dest_mask, Lisp_Object domain)
414 {
415   Lisp_Object data = Fplist_get (find_keyword_in_vector (instantiator, Q_properties),
416                                  Q_items, Qnil);
417   int len;
418   GET_LIST_LENGTH (data, len);
419   widget_instantiate_1 (image_instance, instantiator, pointer_fg,
420                         pointer_bg, dest_mask, domain, len + 1, 0);
421 }
422
423 /* Instantiate a static control */
424 static void
425 static_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
426                     Lisp_Object pointer_fg, Lisp_Object pointer_bg,
427                     int dest_mask, Lisp_Object domain)
428 {
429   widget_instantiate_1 (image_instance, instantiator, pointer_fg,
430                         pointer_bg, dest_mask, domain, 0, 4);
431 }
432
433 \f
434 /************************************************************************/
435 /*                            initialization                            */
436 /************************************************************************/
437
438 void
439 syms_of_glyphs_widget (void)
440 {
441   defkeyword (&Q_descriptor, ":descriptor");
442   defkeyword (&Q_height, ":height");
443   defkeyword (&Q_width, ":width");
444   defkeyword (&Q_properties, ":properties");
445   defkeyword (&Q_items, ":items");
446   defkeyword (&Q_image, ":image");
447   defkeyword (&Q_percent, ":percent");
448   defkeyword (&Q_text, "text");
449 }
450
451 void
452 image_instantiator_format_create_glyphs_widget (void)
453 {
454 #define VALID_GUI_KEYWORDS(type) \
455   IIFORMAT_VALID_KEYWORD (type, Q_active, check_valid_anything); \
456   IIFORMAT_VALID_KEYWORD (type, Q_suffix, check_valid_anything); \
457   IIFORMAT_VALID_KEYWORD (type, Q_keys, check_valid_string);            \
458   IIFORMAT_VALID_KEYWORD (type, Q_style, check_valid_symbol);           \
459   IIFORMAT_VALID_KEYWORD (type, Q_selected, check_valid_anything);      \
460   IIFORMAT_VALID_KEYWORD (type, Q_filter, check_valid_anything);                \
461   IIFORMAT_VALID_KEYWORD (type, Q_config, check_valid_symbol);          \
462   IIFORMAT_VALID_KEYWORD (type, Q_included, check_valid_anything);      \
463   IIFORMAT_VALID_KEYWORD (type, Q_key_sequence, check_valid_string);    \
464   IIFORMAT_VALID_KEYWORD (type, Q_accelerator, check_valid_string);     \
465   IIFORMAT_VALID_KEYWORD (type, Q_label, check_valid_anything);         \
466   IIFORMAT_VALID_KEYWORD (type, Q_callback, check_valid_callback);              \
467   IIFORMAT_VALID_KEYWORD (type, Q_descriptor, check_valid_string_or_vector)
468
469 #define VALID_WIDGET_KEYWORDS(type) \
470   IIFORMAT_VALID_KEYWORD (type, Q_width, check_valid_int);              \
471   IIFORMAT_VALID_KEYWORD (type, Q_height, check_valid_int);             \
472   IIFORMAT_VALID_KEYWORD (type, Q_pixel_width, check_valid_int);        \
473   IIFORMAT_VALID_KEYWORD (type, Q_pixel_height, check_valid_int);       \
474   IIFORMAT_VALID_KEYWORD (type, Q_face, check_valid_face)
475
476   /* we only do this for properties */
477   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT_NO_SYM (widget, "widget");
478   IIFORMAT_HAS_METHOD (widget, property);
479   IIFORMAT_HAS_METHOD (widget, set_property);
480
481   /* widget image-instantiator types - buttons */
482   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (button, "button");
483   IIFORMAT_HAS_SHARED_METHOD (button, validate, widget);
484   IIFORMAT_HAS_SHARED_METHOD (button, possible_dest_types, widget);
485   IIFORMAT_HAS_SHARED_METHOD (button, instantiate, widget);
486   IIFORMAT_HAS_SHARED_METHOD (button, normalize, widget);
487   IIFORMAT_VALID_KEYWORD (button, Q_image, check_valid_glyph_or_image);
488   VALID_WIDGET_KEYWORDS (button);
489   VALID_GUI_KEYWORDS (button);
490
491   /* edit fields */
492   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (edit, "edit");
493   IIFORMAT_HAS_SHARED_METHOD (edit, validate, widget);
494   IIFORMAT_HAS_SHARED_METHOD (edit, possible_dest_types, widget);
495   IIFORMAT_HAS_SHARED_METHOD (edit, instantiate, widget);
496   VALID_WIDGET_KEYWORDS (edit);
497   VALID_GUI_KEYWORDS (edit);
498
499   /* combo box */
500   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (combo, "combo");
501   IIFORMAT_HAS_METHOD (combo, validate);
502   IIFORMAT_HAS_SHARED_METHOD (combo, possible_dest_types, widget);
503   IIFORMAT_HAS_METHOD (combo, instantiate);
504   VALID_GUI_KEYWORDS (combo);
505
506   IIFORMAT_VALID_KEYWORD (combo, Q_width, check_valid_int);
507   IIFORMAT_VALID_KEYWORD (combo, Q_height, check_valid_int);
508   IIFORMAT_VALID_KEYWORD (combo, Q_pixel_width, check_valid_int);
509   IIFORMAT_VALID_KEYWORD (combo, Q_face, check_valid_face);
510   IIFORMAT_VALID_KEYWORD (combo, Q_properties, check_valid_item_list);
511
512   /* scrollbar */
513   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (scrollbar, "scrollbar");
514   IIFORMAT_HAS_SHARED_METHOD (scrollbar, validate, widget);
515   IIFORMAT_HAS_SHARED_METHOD (scrollbar, possible_dest_types, widget);
516   IIFORMAT_HAS_SHARED_METHOD (scrollbar, instantiate, widget);
517   VALID_GUI_KEYWORDS (scrollbar);
518
519   IIFORMAT_VALID_KEYWORD (scrollbar, Q_pixel_width, check_valid_int);
520   IIFORMAT_VALID_KEYWORD (scrollbar, Q_pixel_height, check_valid_int);
521   IIFORMAT_VALID_KEYWORD (scrollbar, Q_face, check_valid_face);
522
523   /* progress guage */
524   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (progress, "progress");
525   IIFORMAT_HAS_SHARED_METHOD (progress, validate, widget);
526   IIFORMAT_HAS_SHARED_METHOD (progress, possible_dest_types, widget);
527   IIFORMAT_HAS_SHARED_METHOD (progress, instantiate, widget);
528   VALID_WIDGET_KEYWORDS (progress);
529   VALID_GUI_KEYWORDS (progress);
530
531   /* labels */
532   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (label, "label");
533   IIFORMAT_HAS_SHARED_METHOD (label, possible_dest_types, widget);
534   IIFORMAT_HAS_SHARED_METHOD (label, instantiate, static);
535   VALID_WIDGET_KEYWORDS (label);
536   IIFORMAT_VALID_KEYWORD (label, Q_descriptor, check_valid_string);
537
538 #if 0
539   /* group */
540   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (group, "group");
541   IIFORMAT_HAS_SHARED_METHOD (group, possible_dest_types, widget);
542   IIFORMAT_HAS_METHOD (group, instantiate);
543
544   IIFORMAT_VALID_KEYWORD (group, Q_width, check_valid_int);
545   IIFORMAT_VALID_KEYWORD (group, Q_height, check_valid_int);
546   IIFORMAT_VALID_KEYWORD (group, Q_pixel_width, check_valid_int);
547   IIFORMAT_VALID_KEYWORD (group, Q_pixel_height, check_valid_int);
548   IIFORMAT_VALID_KEYWORD (group, Q_face, check_valid_face);
549   IIFORMAT_VALID_KEYWORD (group, Q_background, check_valid_string);
550   IIFORMAT_VALID_KEYWORD (group, Q_descriptor, check_valid_string);
551 #endif
552 }
553
554 void
555 vars_of_glyphs_widget (void)
556 {
557 }