Mercurial > hg > xemacs-beta
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"); |