comparison src/gui.c @ 418:e804706bfb8c r21-2-17

Import from CVS: tag r21-2-17
author cvs
date Mon, 13 Aug 2007 11:23:13 +0200
parents 697ef44129c6
children 41dbb7a9d5f2
comparison
equal deleted inserted replaced
417:43a18b32d56e 418:e804706bfb8c
95 data))); 95 data)));
96 } 96 }
97 } 97 }
98 98
99 /* 99 /*
100 * Initialize the gui_item structure by setting all (GC-protected)
101 * fields to their default values. The defaults are t for :active and
102 * :included values, and nil for others.
103 */
104 void
105 gui_item_init (struct gui_item *pgui_item)
106 {
107 pgui_item->name = Qnil;
108 pgui_item->callback = Qnil;
109 pgui_item->suffix = Qnil;
110 pgui_item->active = Qt;
111 pgui_item->included = Qt;
112 pgui_item->config = Qnil;
113 pgui_item->filter = Qnil;
114 pgui_item->style = Qnil;
115 pgui_item->selected = Qnil;
116 pgui_item->keys = Qnil;
117 }
118
119 /*
120 * Add a value VAL associated with keyword KEY into PGUI_ITEM 100 * Add a value VAL associated with keyword KEY into PGUI_ITEM
121 * structure. If KEY is not a keyword, or is an unknown keyword, then 101 * structure. If KEY is not a keyword, or is an unknown keyword, then
122 * error is signaled. 102 * error is signaled.
123 */ 103 */
124 void 104 void
125 gui_item_add_keyval_pair (struct gui_item *pgui_item, 105 gui_item_add_keyval_pair (Lisp_Object gui_item,
126 Lisp_Object key, Lisp_Object val, 106 Lisp_Object key, Lisp_Object val,
127 Error_behavior errb) 107 Error_behavior errb)
128 { 108 {
109 struct Lisp_Gui_Item* pgui_item = XGUI_ITEM (gui_item);
110
129 if (!KEYWORDP (key)) 111 if (!KEYWORDP (key))
130 signal_simple_error_2 ("Non-keyword in gui item", key, pgui_item->name); 112 signal_simple_error_2 ("Non-keyword in gui item", key, pgui_item->name);
131 113
132 if (EQ (key, Q_suffix)) pgui_item->suffix = val; 114 if (EQ (key, Q_suffix)) pgui_item->suffix = val;
133 else if (EQ (key, Q_active)) pgui_item->active = val; 115 else if (EQ (key, Q_active)) pgui_item->active = val;
142 else if (EQ (key, Q_label)) ; /* ignored for 21.0 implement in 21.2 */ 124 else if (EQ (key, Q_label)) ; /* ignored for 21.0 implement in 21.2 */
143 else if (ERRB_EQ (errb, ERROR_ME)) 125 else if (ERRB_EQ (errb, ERROR_ME))
144 signal_simple_error_2 ("Unknown keyword in gui item", key, pgui_item->name); 126 signal_simple_error_2 ("Unknown keyword in gui item", key, pgui_item->name);
145 } 127 }
146 128
129 void
130 gui_item_init (Lisp_Object gui_item)
131 {
132 struct Lisp_Gui_Item *lp = XGUI_ITEM (gui_item);
133
134 lp->name = Qnil;
135 lp->callback = Qnil;
136 lp->suffix = Qnil;
137 lp->active = Qt;
138 lp->included = Qt;
139 lp->config = Qnil;
140 lp->filter = Qnil;
141 lp->style = Qnil;
142 lp->selected = Qnil;
143 lp->keys = Qnil;
144 }
145
146 Lisp_Object
147 allocate_gui_item ()
148 {
149 struct Lisp_Gui_Item *lp =
150 alloc_lcrecord_type (struct Lisp_Gui_Item, &lrecord_gui_item);
151 Lisp_Object val;
152
153 zero_lcrecord (lp);
154 XSETGUI_ITEM (val, lp);
155
156 gui_item_init (val);
157
158 return val;
159 }
160
147 /* 161 /*
148 * ITEM is a lisp vector, describing a menu item or a button. The 162 * ITEM is a lisp vector, describing a menu item or a button. The
149 * function extracts the description of the item into the PGUI_ITEM 163 * function extracts the description of the item into the PGUI_ITEM
150 * structure. 164 * structure.
151 */ 165 */
152 static void 166 static Lisp_Object
153 gui_parse_item_keywords_internal (Lisp_Object item, struct gui_item *pgui_item, 167 make_gui_item_from_keywords_internal (Lisp_Object item,
154 Error_behavior errb) 168 Error_behavior errb)
155 { 169 {
156 int length, plist_p, start; 170 int length, plist_p, start;
157 Lisp_Object *contents; 171 Lisp_Object *contents;
172 Lisp_Object gui_item = allocate_gui_item ();
173 struct Lisp_Gui_Item* pgui_item = XGUI_ITEM (gui_item);
158 174
159 CHECK_VECTOR (item); 175 CHECK_VECTOR (item);
160 length = XVECTOR_LENGTH (item); 176 length = XVECTOR_LENGTH (item);
161 contents = XVECTOR_DATA (item); 177 contents = XVECTOR_DATA (item);
162 178
202 218
203 for (i = start; i < length;) 219 for (i = start; i < length;)
204 { 220 {
205 Lisp_Object key = contents [i++]; 221 Lisp_Object key = contents [i++];
206 Lisp_Object val = contents [i++]; 222 Lisp_Object val = contents [i++];
207 gui_item_add_keyval_pair (pgui_item, key, val, errb); 223 gui_item_add_keyval_pair (gui_item, key, val, errb);
208 } 224 }
209 } 225 }
210 } 226 return gui_item;
211 227 }
228
229 Lisp_Object
230 gui_parse_item_keywords (Lisp_Object item)
231 {
232 return make_gui_item_from_keywords_internal (item, ERROR_ME);
233 }
234
235 Lisp_Object
236 gui_parse_item_keywords_no_errors (Lisp_Object item)
237 {
238 return make_gui_item_from_keywords_internal (item, ERROR_ME_NOT);
239 }
240
241 /* convert a gui item into plist properties */
212 void 242 void
213 gui_parse_item_keywords (Lisp_Object item, struct gui_item *pgui_item) 243 gui_add_item_keywords_to_plist (Lisp_Object plist, Lisp_Object gui_item)
214 { 244 {
215 gui_parse_item_keywords_internal (item, pgui_item, ERROR_ME); 245 struct Lisp_Gui_Item* pgui_item = XGUI_ITEM (gui_item);
216 } 246
217 247 if (!NILP (pgui_item->callback))
218 void 248 Fplist_put (plist, Q_callback, pgui_item->callback);
219 gui_parse_item_keywords_no_errors (Lisp_Object item, struct gui_item *pgui_item) 249 if (!NILP (pgui_item->suffix))
220 { 250 Fplist_put (plist, Q_suffix, pgui_item->suffix);
221 gui_parse_item_keywords_internal (item, pgui_item, ERROR_ME_NOT); 251 if (!NILP (pgui_item->active))
252 Fplist_put (plist, Q_active, pgui_item->active);
253 if (!NILP (pgui_item->included))
254 Fplist_put (plist, Q_included, pgui_item->included);
255 if (!NILP (pgui_item->config))
256 Fplist_put (plist, Q_config, pgui_item->config);
257 if (!NILP (pgui_item->filter))
258 Fplist_put (plist, Q_filter, pgui_item->filter);
259 if (!NILP (pgui_item->style))
260 Fplist_put (plist, Q_style, pgui_item->style);
261 if (!NILP (pgui_item->selected))
262 Fplist_put (plist, Q_selected, pgui_item->selected);
263 if (!NILP (pgui_item->keys))
264 Fplist_put (plist, Q_keys, pgui_item->keys);
222 } 265 }
223 266
224 /* 267 /*
225 * Decide whether a GUI item is active by evaluating its :active form 268 * Decide whether a GUI item is active by evaluating its :active form
226 * if any 269 * if any
227 */ 270 */
228 int 271 int
229 gui_item_active_p (CONST struct gui_item *pgui_item) 272 gui_item_active_p (Lisp_Object gui_item)
230 { 273 {
231 /* This function can call lisp */ 274 /* This function can call lisp */
232 275
233 /* Shortcut to avoid evaluating Qt each time */ 276 /* Shortcut to avoid evaluating Qt each time */
234 return (EQ (pgui_item->active, Qt) 277 return (EQ (XGUI_ITEM (gui_item)->active, Qt)
235 || !NILP (Feval (pgui_item->active))); 278 || !NILP (Feval (XGUI_ITEM (gui_item)->active)));
236 } 279 }
237 280
238 /* 281 /*
239 * Decide whether a GUI item is selected by evaluating its :selected form 282 * Decide whether a GUI item is selected by evaluating its :selected form
240 * if any 283 * if any
241 */ 284 */
242 int 285 int
243 gui_item_selected_p (CONST struct gui_item *pgui_item) 286 gui_item_selected_p (Lisp_Object gui_item)
244 { 287 {
245 /* This function can call lisp */ 288 /* This function can call lisp */
246 289
247 /* Shortcut to avoid evaluating Qt each time */ 290 /* Shortcut to avoid evaluating Qt each time */
248 return (EQ (pgui_item->selected, Qt) 291 return (EQ (XGUI_ITEM (gui_item)->selected, Qt)
249 || !NILP (Feval (pgui_item->selected))); 292 || !NILP (Feval (XGUI_ITEM (gui_item)->selected)));
250 } 293 }
251 294
252 /* 295 /*
253 * Decide whether a GUI item is included by evaluating its :included 296 * Decide whether a GUI item is included by evaluating its :included
254 * form if given, and testing its :config form against supplied CONFLIST 297 * form if given, and testing its :config form against supplied CONFLIST
255 * configuration variable 298 * configuration variable
256 */ 299 */
257 int 300 int
258 gui_item_included_p (CONST struct gui_item *pgui_item, Lisp_Object conflist) 301 gui_item_included_p (Lisp_Object gui_item, Lisp_Object conflist)
259 { 302 {
260 /* This function can call lisp */ 303 /* This function can call lisp */
304 struct Lisp_Gui_Item* pgui_item = XGUI_ITEM (gui_item);
261 305
262 /* Evaluate :included first. Shortcut to avoid evaluating Qt each time */ 306 /* Evaluate :included first. Shortcut to avoid evaluating Qt each time */
263 if (!EQ (pgui_item->included, Qt) 307 if (!EQ (pgui_item->included, Qt)
264 && NILP (Feval (pgui_item->included))) 308 && NILP (Feval (pgui_item->included)))
265 return 0; 309 return 0;
287 * signaled. 331 * signaled.
288 * Return value is the offset to the terminating null character into the 332 * Return value is the offset to the terminating null character into the
289 * buffer. 333 * buffer.
290 */ 334 */
291 unsigned int 335 unsigned int
292 gui_item_display_flush_left (CONST struct gui_item *pgui_item, 336 gui_item_display_flush_left (Lisp_Object gui_item,
293 char* buf, Bytecount buf_len) 337 char* buf, Bytecount buf_len)
294 { 338 {
295 char *p = buf; 339 char *p = buf;
296 Bytecount len; 340 Bytecount len;
341 struct Lisp_Gui_Item* pgui_item = XGUI_ITEM (gui_item);
297 342
298 /* Copy item name first */ 343 /* Copy item name first */
299 CHECK_STRING (pgui_item->name); 344 CHECK_STRING (pgui_item->name);
300 len = XSTRING_LENGTH (pgui_item->name); 345 len = XSTRING_LENGTH (pgui_item->name);
301 if (len > buf_len) 346 if (len > buf_len)
334 * signaled. 379 * signaled.
335 * Return value is the offset to the terminating null character into the 380 * Return value is the offset to the terminating null character into the
336 * buffer. 381 * buffer.
337 */ 382 */
338 unsigned int 383 unsigned int
339 gui_item_display_flush_right (CONST struct gui_item *pgui_item, 384 gui_item_display_flush_right (Lisp_Object gui_item,
340 char* buf, Bytecount buf_len) 385 char* buf, Bytecount buf_len)
341 { 386 {
387 struct Lisp_Gui_Item* pgui_item = XGUI_ITEM (gui_item);
342 *buf = 0; 388 *buf = 0;
343 389
344 /* Have keys? */ 390 /* Have keys? */
345 if (!menubar_show_keybindings) 391 if (!menubar_show_keybindings)
346 return 0; 392 return 0;
372 /* No keys - no right flush display */ 418 /* No keys - no right flush display */
373 return 0; 419 return 0;
374 } 420 }
375 #endif /* HAVE_WINDOW_SYSTEM */ 421 #endif /* HAVE_WINDOW_SYSTEM */
376 422
377 Lisp_Object 423 static Lisp_Object
378 mark_gui_item (struct gui_item* p, void (*markobj) (Lisp_Object)) 424 mark_gui_item (Lisp_Object obj, void (*markobj) (Lisp_Object))
379 { 425 {
426 struct Lisp_Gui_Item *p = XGUI_ITEM (obj);
427
380 markobj (p->name); 428 markobj (p->name);
381 markobj (p->callback); 429 markobj (p->callback);
382 markobj (p->suffix); 430 markobj (p->suffix);
383 markobj (p->active); 431 markobj (p->active);
384 markobj (p->included); 432 markobj (p->included);
389 markobj (p->keys); 437 markobj (p->keys);
390 438
391 return Qnil; 439 return Qnil;
392 } 440 }
393 441
442 static unsigned long
443 gui_item_hash (Lisp_Object obj, int depth)
444 {
445 struct Lisp_Gui_Item *p = XGUI_ITEM (obj);
446
447 return HASH2 (HASH5 (internal_hash (p->name, depth + 1),
448 internal_hash (p->callback, depth + 1),
449 internal_hash (p->suffix, depth + 1),
450 internal_hash (p->active, depth + 1),
451 internal_hash (p->included, depth + 1)),
452 HASH5 (internal_hash (p->config, depth + 1),
453 internal_hash (p->filter, depth + 1),
454 internal_hash (p->style, depth + 1),
455 internal_hash (p->selected, depth + 1),
456 internal_hash (p->keys, depth + 1)));
457 }
458
394 int 459 int
395 gui_item_hash (Lisp_Object hashtable, struct gui_item* g, int slot) 460 gui_item_id_hash (Lisp_Object hashtable, Lisp_Object gitem, int slot)
396 { 461 {
397 int hashid = HASH2 (internal_hash (g->callback, 0), internal_hash (g->name, 0)); 462 int hashid = gui_item_hash (gitem, 0);
398 int id = GUI_ITEM_ID_BITS (hashid, slot); 463 int id = GUI_ITEM_ID_BITS (hashid, slot);
399 while (!NILP (Fgethash (make_int (id), 464 while (!NILP (Fgethash (make_int (id),
400 hashtable, Qnil))) 465 hashtable, Qnil)))
401 { 466 {
402 id = GUI_ITEM_ID_BITS (id + 1, slot); 467 id = GUI_ITEM_ID_BITS (id + 1, slot);
403 } 468 }
404 return id; 469 return id;
405 } 470 }
471
472 static int
473 gui_item_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
474 {
475 struct Lisp_Gui_Item *p1 = XGUI_ITEM (obj1);
476 struct Lisp_Gui_Item *p2 = XGUI_ITEM (obj2);
477
478 if (!(internal_equal (p1->name, p2->name, depth + 1)
479 &&
480 internal_equal (p1->callback, p2->callback, depth + 1)
481 &&
482 EQ (p1->suffix, p2->suffix)
483 &&
484 EQ (p1->active, p2->active)
485 &&
486 EQ (p1->included, p2->included)
487 &&
488 EQ (p1->config, p2->config)
489 &&
490 EQ (p1->filter, p2->filter)
491 &&
492 EQ (p1->style, p2->style)
493 &&
494 EQ (p1->selected, p2->selected)
495 &&
496 EQ (p1->keys, p2->keys)))
497 return 0;
498 return 1;
499 }
500
501 static void
502 print_gui_item (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
503 {
504 struct Lisp_Gui_Item *g = XGUI_ITEM (obj);
505 char buf[20];
506
507 if (print_readably)
508 error ("printing unreadable object #<gui-item 0x%x>", g->header.uid);
509
510 write_c_string ("#<gui-item ", printcharfun);
511 sprintf (buf, "0x%x>", g->header.uid);
512 write_c_string (buf, printcharfun);
513 }
514
515 DEFINE_LRECORD_IMPLEMENTATION ("gui-item", gui_item,
516 mark_gui_item, print_gui_item,
517 0, gui_item_equal,
518 gui_item_hash,
519 struct Lisp_Gui_Item);
406 520
407 void 521 void
408 syms_of_gui (void) 522 syms_of_gui (void)
409 { 523 {
410 defkeyword (&Q_active, ":active"); 524 defkeyword (&Q_active, ":active");