Mercurial > hg > xemacs-beta
annotate lwlib/lwlib.c @ 5797:a1808d52a34a
If the position of a window's cached point is deleted, use buffer point instead
src/ChangeLog addition:
2014-06-17 Aidan Kehoe <kehoea@parhasard.net>
* extents.h:
* window.c:
* window.c (unshow_buffer):
* window.c (Fset_window_buffer):
Use extents, rather than markers, for the window buffer point
cache, so that when the text containing that window buffer point
is deleted, the window display code uses the buffer's actual point
instead of the position that the marker had been moved to.
Fixes Michael Heinrich's problem of
http://mid.gmane.org/6zr42uxtf5.fsf@elektra.science-computing.de ,
introduced by Ben's patch of
https://bitbucket.org/xemacs/xemacs/commits/047d37eb70d70f43803 .
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Tue, 17 Jun 2014 20:55:45 +0100 |
parents | ade4c7e2c6cb |
children |
rev | line source |
---|---|
428 | 1 /* A general interface to the widgets of different toolkits. |
2 Copyright (C) 1992, 1993, 1994 Lucid, Inc. | |
3 Copyright (C) 1995 Tinker Systems and INS Engineering Corp. | |
4 | |
5 This file is part of the Lucid Widget Library. | |
6 | |
5422
ade4c7e2c6cb
Migrate lwlib/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
4759
diff
changeset
|
7 The Lucid Widget Library is free software: you can redistribute it |
ade4c7e2c6cb
Migrate lwlib/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
4759
diff
changeset
|
8 and/or modify it under the terms of the GNU General Public License as |
ade4c7e2c6cb
Migrate lwlib/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
4759
diff
changeset
|
9 published by the Free Software Foundation, either version 3 of the |
ade4c7e2c6cb
Migrate lwlib/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
4759
diff
changeset
|
10 License, or (at your option) any later version. |
428 | 11 |
5422
ade4c7e2c6cb
Migrate lwlib/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
4759
diff
changeset
|
12 The Lucid Widget Library is distributed in the hope that it will be |
ade4c7e2c6cb
Migrate lwlib/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
4759
diff
changeset
|
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
ade4c7e2c6cb
Migrate lwlib/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
4759
diff
changeset
|
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
ade4c7e2c6cb
Migrate lwlib/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
4759
diff
changeset
|
15 General Public License for more details. |
428 | 16 |
17 You should have received a copy of the GNU General Public License | |
5422
ade4c7e2c6cb
Migrate lwlib/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
4759
diff
changeset
|
18 along with the Lucid Widget Library. If not, see |
ade4c7e2c6cb
Migrate lwlib/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
4759
diff
changeset
|
19 <http://www.gnu.org/licenses/>. */ |
428 | 20 |
21 #include <config.h> | |
22 #include <stdio.h> | |
23 #include <stdlib.h> | |
24 #include <string.h> | |
25 #include <sys/types.h> | |
26 #ifdef HAVE_UNISTD_H | |
27 #include <unistd.h> | |
28 #endif | |
29 #include <X11/StringDefs.h> | |
30 #include "lwlib-internal.h" | |
31 #include "lwlib-utils.h" | |
32 | |
33 #ifdef NEED_LUCID | |
34 #include "lwlib-Xlw.h" | |
35 #endif | |
36 #ifdef NEED_MOTIF | |
37 #include "lwlib-Xm.h" | |
434 | 38 #ifdef LWLIB_WIDGETS_MOTIF |
39 #include <Xm/Xm.h> | |
40 #endif | |
428 | 41 #endif |
42 #ifdef NEED_ATHENA | |
43 #include "lwlib-Xaw.h" | |
44 #endif | |
45 | |
46 /* #### Does a check need to be put back in here to make sure we have | |
47 sufficient defines to function properly or are the checks in the | |
48 makefile sufficient? */ | |
49 | |
50 /* List of all widgets managed by the library. Note that each "widget" | |
51 listed here may actually be a tree of widgets; for example, a | |
52 single entry here might represent a single menubar or popup menu, | |
53 each of which might be implemented with a tree of widgets. | |
54 */ | |
55 static widget_info *all_widget_info = NULL; | |
56 | |
57 /* boolean flag indicating that the menubar is active */ | |
58 int lw_menu_active = 0; | |
59 | |
60 /* X11 menubar widget */ | |
61 Widget lw_menubar_widget = NULL; | |
62 | |
63 /* whether the last menu operation was a keyboard accelerator */ | |
64 int lw_menu_accelerate = False; | |
65 | |
66 | |
67 /* Forward declarations */ | |
434 | 68 static void instantiate_widget_instance (widget_instance *instance); |
69 static void free_widget_value_args (widget_value* wv); | |
428 | 70 |
71 | |
72 /* utility functions for widget_instance and widget_info */ | |
73 static char * | |
442 | 74 safe_strdup (const char *s) |
428 | 75 { |
76 char *result; | |
77 if (! s) return 0; | |
78 result = (char *) malloc (strlen (s) + 1); | |
79 if (! result) | |
80 return 0; | |
81 strcpy (result, s); | |
82 return result; | |
83 } | |
84 | |
85 static void | |
86 safe_free_str (char *s) | |
87 { | |
88 if (s) free (s); | |
89 } | |
90 | |
91 static widget_value *widget_value_free_list = 0; | |
92 | |
93 widget_value * | |
94 malloc_widget_value (void) | |
95 { | |
96 widget_value *wv; | |
97 if (widget_value_free_list) | |
98 { | |
99 wv = widget_value_free_list; | |
100 widget_value_free_list = wv->free_list; | |
101 wv->free_list = 0; | |
102 } | |
103 else | |
104 { | |
105 wv = (widget_value *) malloc (sizeof (widget_value)); | |
106 } | |
107 if (wv) | |
108 { | |
438 | 109 memset (wv, '\0', sizeof (widget_value)); |
428 | 110 } |
111 return wv; | |
112 } | |
113 | |
114 /* this is analogous to free(). It frees only what was allocated | |
115 by malloc_widget_value(), and no substructures. | |
116 */ | |
117 void | |
118 free_widget_value (widget_value *wv) | |
119 { | |
120 if (wv->free_list) | |
121 abort (); | |
122 wv->free_list = widget_value_free_list; | |
123 widget_value_free_list = wv; | |
124 } | |
125 | |
126 static void | |
127 free_widget_value_contents (widget_value *wv) | |
128 { | |
129 if (wv->name) free (wv->name); | |
130 if (wv->value) free (wv->value); | |
131 if (wv->key) free (wv->key); | |
132 | |
133 /* #### - all of this 0xDEADBEEF stuff should be unnecessary | |
134 in production code... it should be conditionalized. */ | |
135 wv->name = wv->value = wv->key = (char *) 0xDEADBEEF; | |
136 | |
137 if (wv->toolkit_data && wv->free_toolkit_data) | |
138 { | |
139 XtFree ((char *) wv->toolkit_data); | |
140 wv->toolkit_data = (void *) 0xDEADBEEF; | |
141 } | |
142 #ifdef NEED_SCROLLBARS | |
143 if (wv->scrollbar_data) | |
144 { | |
145 free (wv->scrollbar_data); | |
146 wv->scrollbar_data = NULL; | |
147 } | |
148 #endif | |
149 if (wv->contents && (wv->contents != (widget_value*)1)) | |
150 { | |
151 free_widget_value_tree (wv->contents); | |
152 wv->contents = (widget_value *) 0xDEADBEEF; | |
153 } | |
434 | 154 |
155 free_widget_value_args (wv); | |
156 | |
428 | 157 if (wv->next) |
158 { | |
159 free_widget_value_tree (wv->next); | |
160 wv->next = (widget_value *) 0xDEADBEEF; | |
161 } | |
162 } | |
163 | |
164 void | |
165 free_widget_value_tree (widget_value *wv) | |
166 { | |
167 if (!wv) | |
168 return; | |
169 | |
170 free_widget_value_contents (wv); | |
171 free_widget_value (wv); | |
172 } | |
173 | |
174 #ifdef NEED_SCROLLBARS | |
175 | |
176 static void | |
177 copy_scrollbar_values (widget_value *val, widget_value *copy) | |
178 { | |
179 if (!copy->scrollbar_data) | |
180 copy->scrollbar_data = | |
181 (scrollbar_values *) malloc (sizeof (scrollbar_values)); | |
182 | |
183 if (val->scrollbar_data) | |
184 *copy->scrollbar_data = *val->scrollbar_data; | |
185 else | |
438 | 186 memset (copy->scrollbar_data, '\0', sizeof (scrollbar_values)); |
428 | 187 } |
188 | |
189 /* | |
190 * Return true if old->scrollbar_data were not equivalent | |
3025 | 191 * to new_->scrollbar_data. |
428 | 192 */ |
193 static Boolean | |
1201 | 194 merge_scrollbar_values (widget_value *old, widget_value *new_) |
428 | 195 { |
196 Boolean changed = False; | |
197 | |
1201 | 198 if (new_->scrollbar_data && !old->scrollbar_data) |
428 | 199 { |
1201 | 200 copy_scrollbar_values (new_, old); |
428 | 201 changed = True; |
202 } | |
1201 | 203 else if (!new_->scrollbar_data && old->scrollbar_data) |
428 | 204 { |
205 free (old->scrollbar_data); | |
206 old->scrollbar_data = NULL; | |
207 } | |
1201 | 208 else if (new_->scrollbar_data && old->scrollbar_data) |
428 | 209 { |
210 scrollbar_values *old_sb = old->scrollbar_data; | |
1201 | 211 scrollbar_values *new_sb = new_->scrollbar_data; |
428 | 212 |
213 if ((old_sb->line_increment != new_sb->line_increment) || | |
214 (old_sb->page_increment != new_sb->page_increment) || | |
215 (old_sb->minimum != new_sb->minimum) || | |
216 (old_sb->maximum != new_sb->maximum) || | |
217 (old_sb->slider_size != new_sb->slider_size) || | |
218 (old_sb->slider_position != new_sb->slider_position) || | |
219 (old_sb->scrollbar_width != new_sb->scrollbar_width) || | |
220 (old_sb->scrollbar_height != new_sb->scrollbar_height) || | |
221 (old_sb->scrollbar_x != new_sb->scrollbar_x) || | |
222 (old_sb->scrollbar_y != new_sb->scrollbar_y)) | |
223 changed = True; | |
224 | |
225 *old_sb = *new_sb; | |
226 } | |
227 | |
228 return changed; | |
229 } | |
230 | |
231 #endif /* NEED_SCROLLBARS */ | |
232 | |
771 | 233 #ifdef HAVE_X_WIDGETS |
434 | 234 /* |
235 * Return true if old->args was not equivalent | |
3025 | 236 * to new_->args. |
434 | 237 */ |
238 static Boolean | |
3025 | 239 merge_widget_value_args (widget_value *old, widget_value *new_) |
434 | 240 { |
241 Boolean changed = False; | |
242 | |
3025 | 243 if (new_->args && !old->args) |
434 | 244 { |
3025 | 245 lw_copy_widget_value_args (new_, old); |
434 | 246 changed = True; |
247 } | |
248 /* Generally we don't want to lose values that are already in the | |
249 widget. */ | |
3025 | 250 else if (!new_->args && old->args) |
434 | 251 { |
3025 | 252 lw_copy_widget_value_args (old, new_); |
434 | 253 changed = True; |
254 } | |
3025 | 255 else if (new_->args && old->args && new_->args != old->args) |
434 | 256 { |
257 /* #### Do something more sensible here than just copying the | |
258 new values (like actually merging the values). */ | |
3025 | 259 lw_copy_widget_value_args (new_, old); |
434 | 260 changed = True; |
261 } | |
3025 | 262 else if (new_->args && new_->args == old->args && new_->args->args_changed == True) |
450 | 263 { |
264 changed = True; | |
265 } | |
434 | 266 |
267 return changed; | |
268 } | |
771 | 269 #endif /* HAVE_X_WIDGETS */ |
434 | 270 |
428 | 271 /* Make a complete copy of a widget_value tree. Store CHANGE into |
272 the widget_value tree's `change' field. */ | |
273 | |
442 | 274 widget_value * |
428 | 275 copy_widget_value_tree (widget_value *val, change_type change) |
276 { | |
277 widget_value *copy; | |
278 | |
279 if (!val) | |
280 return NULL; | |
281 if (val == (widget_value *) 1) | |
282 return val; | |
283 | |
284 copy = malloc_widget_value (); | |
285 if (copy) | |
286 { | |
287 /* #### - don't seg fault *here* if out of memory. Menus will be | |
288 truncated inexplicably. */ | |
289 copy->type = val->type; | |
290 copy->name = safe_strdup (val->name); | |
291 copy->value = safe_strdup (val->value); | |
292 copy->key = safe_strdup (val->key); | |
293 copy->accel = val->accel; | |
294 copy->enabled = val->enabled; | |
295 copy->selected = val->selected; | |
296 copy->edited = False; | |
297 copy->change = change; | |
298 copy->contents = copy_widget_value_tree (val->contents, change); | |
299 copy->call_data = val->call_data; | |
300 copy->next = copy_widget_value_tree (val->next, change); | |
301 copy->toolkit_data = NULL; | |
302 copy->free_toolkit_data = False; | |
434 | 303 |
304 lw_copy_widget_value_args (val, copy); | |
428 | 305 #ifdef NEED_SCROLLBARS |
306 copy_scrollbar_values (val, copy); | |
307 #endif | |
308 } | |
309 return copy; | |
310 } | |
311 | |
312 /* This function is used to implement incremental menu construction. */ | |
313 | |
314 widget_value * | |
315 replace_widget_value_tree (widget_value *node, widget_value *newtree) | |
316 { | |
317 widget_value *copy; | |
318 | |
319 if (!node || !newtree) | |
320 abort (); | |
321 | |
322 copy = copy_widget_value_tree (newtree, STRUCTURAL_CHANGE); | |
323 | |
324 free_widget_value_contents (node); | |
325 *node = *copy; | |
326 free_widget_value (copy); /* free the node, but not its contents. */ | |
327 return node; | |
328 } | |
329 | |
330 static widget_info * | |
442 | 331 allocate_widget_info (const char *type, const char *name, |
428 | 332 LWLIB_ID id, widget_value *val, |
333 lw_callback pre_activate_cb, lw_callback selection_cb, | |
334 lw_callback post_activate_cb) | |
335 { | |
336 widget_info *info = (widget_info *) malloc (sizeof (widget_info)); | |
337 info->type = safe_strdup (type); | |
338 info->name = safe_strdup (name); | |
339 info->id = id; | |
340 info->val = copy_widget_value_tree (val, STRUCTURAL_CHANGE); | |
341 info->busy = False; | |
342 info->pre_activate_cb = pre_activate_cb; | |
343 info->selection_cb = selection_cb; | |
344 info->post_activate_cb = post_activate_cb; | |
345 info->instances = NULL; | |
346 | |
347 info->next = all_widget_info; | |
348 all_widget_info = info; | |
349 | |
350 return info; | |
351 } | |
352 | |
353 static void | |
354 free_widget_info (widget_info *info) | |
355 { | |
356 safe_free_str (info->type); | |
357 safe_free_str (info->name); | |
358 free_widget_value_tree (info->val); | |
438 | 359 memset (info, '\0', sizeof (widget_info)); |
428 | 360 free (info); |
361 } | |
362 | |
363 static void | |
2286 | 364 mark_widget_destroyed (Widget widget, XtPointer closure, |
365 XtPointer UNUSED (call_data)) | |
428 | 366 { |
367 widget_instance *instance = (widget_instance*)closure; | |
368 | |
369 /* be very conservative */ | |
370 if (instance->widget == widget) | |
371 instance->widget = NULL; | |
372 } | |
373 | |
374 static widget_instance * | |
375 allocate_widget_instance (widget_info *info, Widget parent, Boolean pop_up_p) | |
376 { | |
377 widget_instance *instance = | |
378 (widget_instance *) malloc (sizeof (widget_instance)); | |
379 instance->parent = parent; | |
380 instance->pop_up_p = pop_up_p; | |
381 instance->info = info; | |
382 instance->next = info->instances; | |
383 info->instances = instance; | |
384 | |
385 instantiate_widget_instance (instance); | |
386 | |
387 XtAddCallback (instance->widget, XtNdestroyCallback, | |
388 mark_widget_destroyed, (XtPointer)instance); | |
389 return instance; | |
390 } | |
391 | |
392 static void | |
393 free_widget_instance (widget_instance *instance) | |
394 { | |
438 | 395 memset (instance, '\0', sizeof (widget_instance)); |
428 | 396 free (instance); |
397 } | |
398 | |
399 static widget_info * | |
400 get_widget_info (LWLIB_ID id, Boolean remove_p) | |
401 { | |
402 widget_info *info; | |
403 widget_info *prev; | |
404 for (prev = NULL, info = all_widget_info; | |
405 info; | |
406 prev = info, info = info->next) | |
407 if (info->id == id) | |
408 { | |
409 if (remove_p) | |
410 { | |
411 if (prev) | |
412 prev->next = info->next; | |
413 else | |
414 all_widget_info = info->next; | |
415 } | |
416 return info; | |
417 } | |
418 return NULL; | |
419 } | |
420 | |
421 /* Internal function used by the library dependent implementation to get the | |
422 widget_value for a given widget in an instance */ | |
423 widget_info * | |
424 lw_get_widget_info (LWLIB_ID id) | |
425 { | |
426 return get_widget_info (id, 0); | |
427 } | |
428 | |
429 static int | |
430 map_widget_values (widget_value *value, int (*mapfunc) (widget_value *value, | |
431 void *closure), | |
432 void *closure) | |
433 { | |
434 int retval = 0; | |
435 | |
436 if (value->contents) | |
437 retval = map_widget_values (value->contents, mapfunc, closure); | |
438 if (retval) | |
439 return retval; | |
440 | |
441 if (value->next) | |
442 retval = map_widget_values (value->next, mapfunc, closure); | |
443 if (retval) | |
444 return retval; | |
445 | |
446 return (mapfunc) (value, closure); | |
447 } | |
448 | |
449 int | |
450 lw_map_widget_values (LWLIB_ID id, int (*mapfunc) (widget_value *value, | |
451 void *closure), | |
452 void *closure) | |
453 { | |
454 widget_info *info = get_widget_info (id, 0); | |
455 | |
456 if (!info) | |
457 abort (); | |
458 | |
459 if (info->val) | |
460 return map_widget_values (info->val, mapfunc, closure); | |
461 return 0; | |
462 } | |
463 | |
464 static widget_instance * | |
465 get_widget_instance (Widget widget, Boolean remove_p) | |
466 { | |
467 widget_info *info; | |
468 widget_instance *instance; | |
469 widget_instance *prev; | |
470 for (info = all_widget_info; info; info = info->next) | |
471 for (prev = NULL, instance = info->instances; | |
472 instance; | |
473 prev = instance, instance = instance->next) | |
474 if (instance->widget == widget) | |
475 { | |
476 if (remove_p) | |
477 { | |
478 if (prev) | |
479 prev->next = instance->next; | |
480 else | |
481 info->instances = instance->next; | |
482 } | |
483 return instance; | |
484 } | |
485 return (widget_instance *) 0; | |
486 } | |
487 | |
488 static widget_instance* | |
489 find_instance (LWLIB_ID id, Widget parent, Boolean pop_up_p) | |
490 { | |
491 widget_info *info = get_widget_info (id, False); | |
492 widget_instance *instance; | |
493 | |
494 if (info) | |
495 for (instance = info->instances; instance; instance = instance->next) | |
496 if (instance->parent == parent && instance->pop_up_p == pop_up_p) | |
497 return instance; | |
498 | |
499 return NULL; | |
500 } | |
501 | |
502 | |
503 /* utility function for widget_value */ | |
504 static Boolean | |
442 | 505 safe_strcmp (const char *s1, const char *s2) |
428 | 506 { |
507 if (!!s1 ^ !!s2) return True; | |
508 return (s1 && s2) ? strcmp (s1, s2) : s1 ? False : !!s2; | |
509 } | |
510 | |
511 #if 0 | |
512 # define EXPLAIN(name, oc, nc, desc, a1, a2) \ | |
513 printf ("Change: \"%s\"\tmax(%s=%d,%s=%d)\t%s %d %d\n", \ | |
514 name, \ | |
515 (oc == NO_CHANGE ? "none" : \ | |
516 (oc == INVISIBLE_CHANGE ? "invisible" : \ | |
517 (oc == VISIBLE_CHANGE ? "visible" : \ | |
518 (oc == STRUCTURAL_CHANGE ? "structural" : "???")))), \ | |
519 oc, \ | |
520 (nc == NO_CHANGE ? "none" : \ | |
521 (nc == INVISIBLE_CHANGE ? "invisible" : \ | |
522 (nc == VISIBLE_CHANGE ? "visible" : \ | |
523 (nc == STRUCTURAL_CHANGE ? "structural" : "???")))), \ | |
524 nc, desc, a1, a2) | |
525 #else | |
526 # define EXPLAIN(name, oc, nc, desc, a1, a2) | |
527 #endif | |
528 | |
529 | |
530 static widget_value * | |
531 merge_widget_value (widget_value *val1, widget_value *val2, int level) | |
532 { | |
533 change_type change; | |
534 widget_value *merged_next; | |
535 widget_value *merged_contents; | |
536 | |
537 if (!val1) | |
538 { | |
539 if (val2) | |
540 return copy_widget_value_tree (val2, STRUCTURAL_CHANGE); | |
541 else | |
542 return NULL; | |
543 } | |
544 if (!val2) | |
545 { | |
546 free_widget_value_tree (val1); | |
547 return NULL; | |
548 } | |
549 | |
550 change = NO_CHANGE; | |
551 | |
552 if (val1->type != val2->type) | |
553 { | |
554 EXPLAIN (val1->name, change, STRUCTURAL_CHANGE, "type change", | |
555 val1->type, val2->type); | |
556 change = max (change, STRUCTURAL_CHANGE); | |
557 val1->type = val2->type; | |
558 } | |
559 if (safe_strcmp (val1->name, val2->name)) | |
560 { | |
561 EXPLAIN (val1->name, change, STRUCTURAL_CHANGE, "name change", | |
562 val1->name, val2->name); | |
563 change = max (change, STRUCTURAL_CHANGE); | |
564 safe_free_str (val1->name); | |
565 val1->name = safe_strdup (val2->name); | |
566 } | |
567 if (safe_strcmp (val1->value, val2->value)) | |
568 { | |
569 EXPLAIN (val1->name, change, VISIBLE_CHANGE, "value change", | |
570 val1->value, val2->value); | |
571 change = max (change, VISIBLE_CHANGE); | |
572 safe_free_str (val1->value); | |
573 val1->value = safe_strdup (val2->value); | |
574 } | |
575 if (safe_strcmp (val1->key, val2->key)) | |
576 { | |
577 EXPLAIN (val1->name, change, VISIBLE_CHANGE, "key change", | |
578 val1->key, val2->key); | |
579 change = max (change, VISIBLE_CHANGE); | |
580 safe_free_str (val1->key); | |
581 val1->key = safe_strdup (val2->key); | |
582 } | |
583 if (val1->accel != val2->accel) | |
584 { | |
585 EXPLAIN (val1->name, change, VISIBLE_CHANGE, "accelerator change", | |
586 val1->accel, val2->accel); | |
587 change = max (change, VISIBLE_CHANGE); | |
588 val1->accel = val2->accel; | |
589 } | |
590 if (val1->enabled != val2->enabled) | |
591 { | |
592 EXPLAIN (val1->name, change, VISIBLE_CHANGE, "enablement change", | |
593 val1->enabled, val2->enabled); | |
594 change = max (change, VISIBLE_CHANGE); | |
595 val1->enabled = val2->enabled; | |
596 } | |
597 if (val1->selected != val2->selected) | |
598 { | |
599 EXPLAIN (val1->name, change, VISIBLE_CHANGE, "selection change", | |
600 val1->selected, val2->selected); | |
601 change = max (change, VISIBLE_CHANGE); | |
602 val1->selected = val2->selected; | |
603 } | |
604 if (val1->call_data != val2->call_data) | |
605 { | |
606 EXPLAIN (val1->name, change, INVISIBLE_CHANGE, "call-data change", | |
607 val1->call_data, val2->call_data); | |
608 change = max (change, INVISIBLE_CHANGE); | |
609 val1->call_data = val2->call_data; | |
610 } | |
771 | 611 #ifdef HAVE_X_WIDGETS |
434 | 612 if (merge_widget_value_args (val1, val2)) |
613 { | |
614 EXPLAIN (val1->name, change, VISIBLE_CHANGE, "widget change", 0, 0); | |
615 change = max (change, VISIBLE_CHANGE); | |
616 } | |
617 #endif | |
618 | |
428 | 619 #ifdef NEED_SCROLLBARS |
620 if (merge_scrollbar_values (val1, val2)) | |
621 { | |
622 EXPLAIN (val1->name, change, VISIBLE_CHANGE, "scrollbar change", 0, 0); | |
623 change = max (change, VISIBLE_CHANGE); | |
624 } | |
625 #endif | |
626 | |
627 if (level > 0) | |
628 { | |
629 merged_contents = | |
630 merge_widget_value (val1->contents, val2->contents, level - 1); | |
631 | |
632 if (val1->contents && !merged_contents) | |
633 { | |
634 EXPLAIN (val1->name, change, INVISIBLE_CHANGE, "(contents gone)", | |
635 0, 0); | |
636 change = max (change, INVISIBLE_CHANGE); | |
637 } | |
638 else if (merged_contents && merged_contents->change != NO_CHANGE) | |
639 { | |
640 EXPLAIN (val1->name, change, INVISIBLE_CHANGE, "(contents change)", | |
641 0, 0); | |
642 change = max (change, INVISIBLE_CHANGE); | |
643 } | |
644 | |
645 val1->contents = merged_contents; | |
646 } | |
647 | |
648 merged_next = merge_widget_value (val1->next, val2->next, level); | |
649 | |
650 if (val1->next && !merged_next) | |
651 { | |
652 EXPLAIN (val1->name, change, STRUCTURAL_CHANGE, "(following gone)", | |
653 0, 0); | |
654 change = max (change, STRUCTURAL_CHANGE); | |
655 } | |
656 else if (merged_next) | |
657 { | |
658 if (merged_next->change) | |
659 { | |
660 EXPLAIN (val1->name, change, merged_next->change, "(following change)", | |
661 0, 0); | |
2286 | 662 change = max (change, merged_next->change); |
428 | 663 } |
664 } | |
665 | |
666 val1->next = merged_next; | |
667 | |
668 val1->change = change; | |
669 | |
670 if (change > NO_CHANGE && val1->toolkit_data) | |
671 { | |
672 if (val1->free_toolkit_data) | |
673 XtFree ((char *) val1->toolkit_data); | |
674 val1->toolkit_data = NULL; | |
675 } | |
676 | |
677 return val1; | |
678 } | |
679 | |
680 | |
681 /* modifying the widgets */ | |
682 static Widget | |
442 | 683 name_to_widget (widget_instance *instance, const char *name) |
428 | 684 { |
685 Widget widget = NULL; | |
686 | |
687 if (!instance->widget) | |
688 return NULL; | |
689 | |
690 if (!strcmp (XtName (instance->widget), name)) | |
691 widget = instance->widget; | |
692 else | |
693 { | |
694 int length = strlen (name) + 2; | |
695 char *real_name = (char *) alloca (length); | |
696 real_name [0] = '*'; | |
697 strcpy (real_name + 1, name); | |
698 | |
699 widget = XtNameToWidget (instance->widget, real_name); | |
700 } | |
701 return widget; | |
702 } | |
703 | |
704 static void | |
705 set_one_value (widget_instance *instance, widget_value *val, Boolean deep_p) | |
706 { | |
707 Widget widget = name_to_widget (instance, val->name); | |
708 | |
709 if (widget) | |
710 { | |
711 #ifdef NEED_LUCID | |
712 if (lw_lucid_widget_p (instance->widget)) | |
713 xlw_update_one_widget (instance, widget, val, deep_p); | |
714 #endif | |
715 #ifdef NEED_MOTIF | |
716 if (lw_motif_widget_p (instance->widget)) | |
717 xm_update_one_widget (instance, widget, val, deep_p); | |
718 #endif | |
719 #ifdef NEED_ATHENA | |
720 if (lw_xaw_widget_p (instance->widget)) | |
721 xaw_update_one_widget (instance, widget, val, deep_p); | |
722 #endif | |
723 } | |
724 } | |
725 | |
726 static void | |
727 update_one_widget_instance (widget_instance *instance, Boolean deep_p) | |
728 { | |
729 widget_value *val; | |
730 | |
731 if (!instance->widget) | |
732 /* the widget was destroyed */ | |
733 return; | |
734 | |
735 for (val = instance->info->val; val; val = val->next) | |
736 if (val->change != NO_CHANGE) | |
737 set_one_value (instance, val, deep_p); | |
738 } | |
739 | |
740 static void | |
741 update_all_widget_values (widget_info *info, Boolean deep_p) | |
742 { | |
743 widget_instance *instance; | |
744 widget_value *val; | |
745 | |
746 for (instance = info->instances; instance; instance = instance->next) | |
747 update_one_widget_instance (instance, deep_p); | |
748 | |
749 for (val = info->val; val; val = val->next) | |
450 | 750 { |
751 val->change = NO_CHANGE; | |
752 if (val->args) | |
753 val->args->args_changed = False; | |
754 } | |
428 | 755 } |
756 | |
757 void | |
758 lw_modify_all_widgets (LWLIB_ID id, widget_value *val, Boolean deep_p) | |
759 { | |
760 widget_info *info = get_widget_info (id, False); | |
761 widget_value *new_val; | |
762 widget_value *next_new_val; | |
763 widget_value *cur; | |
764 widget_value *prev; | |
765 widget_value *next; | |
766 int found; | |
767 | |
768 if (!info) | |
769 return; | |
770 | |
771 for (new_val = val; new_val; new_val = new_val->next) | |
772 { | |
773 next_new_val = new_val->next; | |
774 new_val->next = NULL; | |
775 found = False; | |
776 for (prev = NULL, cur = info->val; cur; prev = cur, cur = cur->next) | |
777 if (!strcmp (cur->name, new_val->name)) | |
778 { | |
779 found = True; | |
780 next = cur->next; | |
781 cur->next = NULL; | |
782 cur = merge_widget_value (cur, new_val, deep_p ? 1000 : 1); | |
783 if (prev) | |
784 prev->next = cur ? cur : next; | |
785 else | |
786 info->val = cur ? cur : next; | |
787 if (cur) | |
788 cur->next = next; | |
789 break; | |
790 } | |
791 if (!found) | |
792 { | |
793 /* Could not find it, add it */ | |
794 if (prev) | |
795 prev->next = copy_widget_value_tree (new_val, STRUCTURAL_CHANGE); | |
796 else | |
797 info->val = copy_widget_value_tree (new_val, STRUCTURAL_CHANGE); | |
798 } | |
799 new_val->next = next_new_val; | |
800 } | |
801 | |
802 update_all_widget_values (info, deep_p); | |
803 } | |
804 | |
805 | |
806 /* creating the widgets */ | |
807 | |
808 static void | |
809 initialize_widget_instance (widget_instance *instance) | |
810 { | |
811 widget_value *val; | |
812 | |
813 for (val = instance->info->val; val; val = val->next) | |
814 val->change = STRUCTURAL_CHANGE; | |
815 | |
816 update_one_widget_instance (instance, True); | |
817 | |
818 for (val = instance->info->val; val; val = val->next) | |
450 | 819 { |
820 val->change = NO_CHANGE; | |
821 if (val->args) | |
822 val->args->args_changed = False; | |
823 } | |
428 | 824 } |
825 | |
1201 | 826 #if defined (NEED_LUCID) || defined (NEED_ATHENA) || defined (NEED_MOTIF) |
827 | |
442 | 828 /* strcasecmp() is not sufficiently portable or standard, |
829 and it's easier just to write our own. */ | |
830 static int | |
831 ascii_strcasecmp (const char *s1, const char *s2) | |
832 { | |
833 while (1) | |
834 { | |
835 char c1 = *s1++; | |
836 char c2 = *s2++; | |
837 if (c1 >= 'A' && c1 <= 'Z') c1 += 'a' - 'A'; | |
838 if (c2 >= 'A' && c2 <= 'Z') c2 += 'a' - 'A'; | |
839 if (c1 != c2) return c1 - c2; | |
840 if (c1 == '\0') return 0; | |
841 } | |
842 } | |
428 | 843 |
844 static widget_creation_function | |
450 | 845 find_in_table (const char *type, const widget_creation_entry table[]) |
428 | 846 { |
450 | 847 const widget_creation_entry *cur; |
428 | 848 for (cur = table; cur->type; cur++) |
442 | 849 if (!ascii_strcasecmp (type, cur->type)) |
428 | 850 return cur->function; |
851 return NULL; | |
852 } | |
853 | |
872 | 854 #endif |
855 | |
428 | 856 static Boolean |
442 | 857 dialog_spec_p (const char *name) |
428 | 858 { |
859 /* return True if name matches [EILPQeilpq][1-9][Bb] or | |
860 [EILPQeilpq][1-9][Bb][Rr][1-9] */ | |
861 if (!name) | |
862 return False; | |
863 | |
864 switch (name [0]) | |
865 { | |
866 case 'E': case 'I': case 'L': case 'P': case 'Q': | |
867 case 'e': case 'i': case 'l': case 'p': case 'q': | |
868 if (name [1] >= '0' && name [1] <= '9') | |
869 { | |
870 if (name [2] != 'B' && name [2] != 'b') | |
871 return False; | |
872 if (!name [3]) | |
873 return True; | |
874 if ((name [3] == 'T' || name [3] == 't') && !name [4]) | |
875 return True; | |
876 if ((name [3] == 'R' || name [3] == 'r') | |
877 && name [4] >= '0' && name [4] <= '9' && !name [5]) | |
878 return True; | |
879 return False; | |
880 } | |
881 else | |
882 return False; | |
883 | |
884 default: | |
885 return False; | |
886 } | |
887 } | |
888 | |
889 static void | |
890 instantiate_widget_instance (widget_instance *instance) | |
891 { | |
892 widget_creation_function function = NULL; | |
893 | |
894 #ifdef NEED_LUCID | |
895 if (!function) | |
896 function = find_in_table (instance->info->type, xlw_creation_table); | |
897 #endif | |
898 #ifdef NEED_MOTIF | |
899 if (!function) | |
900 function = find_in_table (instance->info->type, xm_creation_table); | |
901 #endif | |
902 #ifdef NEED_ATHENA | |
903 if (!function) | |
904 function = find_in_table (instance->info->type, xaw_creation_table); | |
905 #endif | |
906 | |
907 if (!function) | |
908 { | |
909 if (dialog_spec_p (instance->info->type)) | |
910 { | |
911 #ifdef LWLIB_DIALOGS_MOTIF | |
912 if (!function) | |
913 function = xm_create_dialog; | |
914 #endif | |
915 #ifdef LWLIB_DIALOGS_ATHENA | |
916 if (!function) | |
917 function = xaw_create_dialog; | |
918 #endif | |
919 #ifdef LWLIB_DIALOGS_LUCID | |
920 /* not yet (not ever?) */ | |
921 #endif | |
922 } | |
923 } | |
924 | |
925 if (!function) | |
926 { | |
927 fprintf (stderr, "No creation function for widget type %s\n", | |
928 instance->info->type); | |
929 abort (); | |
930 } | |
931 | |
932 instance->widget = (*function) (instance); | |
933 | |
934 if (!instance->widget) | |
935 abort (); | |
936 | |
937 /* XtRealizeWidget (instance->widget);*/ | |
938 } | |
939 | |
940 void | |
442 | 941 lw_register_widget (const char *type, const char *name, |
428 | 942 LWLIB_ID id, widget_value *val, |
943 lw_callback pre_activate_cb, lw_callback selection_cb, | |
944 lw_callback post_activate_cb) | |
945 { | |
946 if (!get_widget_info (id, False)) | |
947 allocate_widget_info (type, name, id, val, pre_activate_cb, selection_cb, | |
948 post_activate_cb); | |
949 } | |
950 | |
951 Widget | |
952 lw_get_widget (LWLIB_ID id, Widget parent, Boolean pop_up_p) | |
953 { | |
954 widget_instance *instance = find_instance (id, parent, pop_up_p); | |
955 return instance ? instance->widget : NULL; | |
956 } | |
957 | |
958 Widget | |
959 lw_make_widget (LWLIB_ID id, Widget parent, Boolean pop_up_p) | |
960 { | |
961 widget_instance *instance = find_instance (id, parent, pop_up_p); | |
962 | |
963 if (!instance) | |
964 { | |
965 widget_info *info = get_widget_info (id, False); | |
966 if (!info) | |
967 return NULL; | |
968 instance = allocate_widget_instance (info, parent, pop_up_p); | |
969 initialize_widget_instance (instance); | |
970 } | |
971 if (!instance->widget) | |
972 abort (); | |
973 return instance->widget; | |
974 } | |
975 | |
976 Widget | |
442 | 977 lw_create_widget (const char *type, const char *name, |
428 | 978 LWLIB_ID id, widget_value *val, |
979 Widget parent, Boolean pop_up_p, lw_callback pre_activate_cb, | |
980 lw_callback selection_cb, lw_callback post_activate_cb) | |
981 { | |
982 lw_register_widget (type, name, id, val, pre_activate_cb, selection_cb, | |
983 post_activate_cb); | |
984 return lw_make_widget (id, parent, pop_up_p); | |
985 } | |
986 | |
987 | |
988 /* destroying the widgets */ | |
989 static void | |
990 destroy_one_instance (widget_instance *instance) | |
991 { | |
992 /* Remove the destroy callback on the widget; that callback will try to | |
993 dereference the instance object (to set its widget slot to 0, since the | |
994 widget is dead.) Since the instance is now dead, we don't have to worry | |
995 about the fact that its widget is dead too. | |
996 | |
997 This happens in the Phase2Destroy of the widget, so this callback would | |
998 not have been run until arbitrarily long after the instance was freed. | |
999 */ | |
1000 if (instance->widget) | |
1001 XtRemoveCallback (instance->widget, XtNdestroyCallback, | |
1002 mark_widget_destroyed, (XtPointer)instance); | |
1003 | |
1004 if (instance->widget) | |
1005 { | |
1006 /* The else are pretty tricky here, including the empty statement | |
1007 at the end because it would be very bad to destroy a widget | |
1008 twice. */ | |
1009 #ifdef NEED_LUCID | |
1010 if (lw_lucid_widget_p (instance->widget)) | |
1011 xlw_destroy_instance (instance); | |
1012 else | |
1013 #endif | |
1014 #ifdef NEED_MOTIF | |
1015 if (lw_motif_widget_p (instance->widget)) | |
1016 xm_destroy_instance (instance); | |
1017 else | |
1018 #endif | |
1019 #ifdef NEED_ATHENA | |
1020 if (lw_xaw_widget_p (instance->widget)) | |
1021 xaw_destroy_instance (instance); | |
1022 else | |
1023 #endif | |
1024 { | |
1025 /* do not remove the empty statement */ | |
1026 ; | |
1027 } | |
1028 } | |
1029 | |
1030 free_widget_instance (instance); | |
1031 } | |
1032 | |
1033 void | |
1034 lw_destroy_widget (Widget w) | |
1035 { | |
1036 widget_instance *instance = get_widget_instance (w, True); | |
1037 | |
1038 if (instance) | |
1039 { | |
1040 widget_info *info = instance->info; | |
1041 /* instance has already been removed from the list; free it */ | |
1042 destroy_one_instance (instance); | |
1043 /* if there are no instances left, free the info too */ | |
1044 if (!info->instances) | |
1045 lw_destroy_all_widgets (info->id); | |
1046 } | |
1047 } | |
1048 | |
1049 void | |
1050 lw_destroy_all_widgets (LWLIB_ID id) | |
1051 { | |
1052 widget_info *info = get_widget_info (id, True); | |
1053 widget_instance *instance; | |
1054 widget_instance *next; | |
1055 | |
1056 if (info) | |
1057 { | |
1058 for (instance = info->instances; instance; ) | |
1059 { | |
1060 next = instance->next; | |
1061 destroy_one_instance (instance); | |
1062 instance = next; | |
1063 } | |
1064 free_widget_info (info); | |
1065 } | |
1066 } | |
1067 | |
1068 void | |
442 | 1069 lw_destroy_everything (void) |
428 | 1070 { |
1071 while (all_widget_info) | |
1072 lw_destroy_all_widgets (all_widget_info->id); | |
1073 } | |
1074 | |
1075 void | |
442 | 1076 lw_destroy_all_pop_ups (void) |
428 | 1077 { |
1078 widget_info *info; | |
1079 widget_info *next; | |
1080 widget_instance *instance; | |
1081 | |
1082 for (info = all_widget_info; info; info = next) | |
1083 { | |
1084 next = info->next; | |
1085 instance = info->instances; | |
1086 if (instance && instance->pop_up_p) | |
1087 lw_destroy_all_widgets (info->id); | |
1088 } | |
1089 } | |
1090 | |
1091 Widget | |
1092 lw_raise_all_pop_up_widgets (void) | |
1093 { | |
1094 widget_info *info; | |
1095 widget_instance *instance; | |
1096 Widget result = NULL; | |
1097 | |
1098 for (info = all_widget_info; info; info = info->next) | |
1099 for (instance = info->instances; instance; instance = instance->next) | |
1100 if (instance->pop_up_p) | |
1101 { | |
1102 Widget widget = instance->widget; | |
1103 if (widget) | |
1104 { | |
1105 if (XtIsManaged (widget) | |
1106 #ifdef NEED_MOTIF | |
1107 /* What a complete load of crap!!!! | |
1108 When a dialogShell is on the screen, it is not managed! | |
1109 */ | |
1110 || (lw_motif_widget_p (instance->widget) && | |
1111 XtIsManaged (first_child (widget))) | |
1112 #endif | |
1113 ) | |
1114 { | |
1115 if (!result) | |
1116 result = widget; | |
1117 XMapRaised (XtDisplay (widget), XtWindow (widget)); | |
1118 } | |
1119 } | |
1120 } | |
1121 return result; | |
1122 } | |
1123 | |
1124 static void | |
1125 lw_pop_all_widgets (LWLIB_ID id, Boolean up) | |
1126 { | |
1127 widget_info *info = get_widget_info (id, False); | |
1128 widget_instance *instance; | |
1129 | |
1130 if (info) | |
1131 for (instance = info->instances; instance; instance = instance->next) | |
1132 if (instance->pop_up_p && instance->widget) | |
1133 { | |
1134 #ifdef NEED_LUCID | |
1135 if (lw_lucid_widget_p (instance->widget)) | |
1136 { | |
1137 XtRealizeWidget (instance->widget); | |
1138 xlw_pop_instance (instance, up); | |
1139 } | |
1140 #endif | |
1141 #ifdef NEED_MOTIF | |
1142 if (lw_motif_widget_p (instance->widget)) | |
1143 { | |
1144 XtRealizeWidget (instance->widget); | |
1145 xm_pop_instance (instance, up); | |
1146 } | |
1147 #endif | |
1148 #ifdef NEED_ATHENA | |
1149 if (lw_xaw_widget_p (instance->widget)) | |
1150 { | |
1151 XtRealizeWidget (XtParent (instance->widget)); | |
1152 XtRealizeWidget (instance->widget); | |
1153 xaw_pop_instance (instance, up); | |
1154 } | |
1155 #endif | |
1156 } | |
1157 } | |
1158 | |
1159 void | |
1160 lw_pop_up_all_widgets (LWLIB_ID id) | |
1161 { | |
1162 lw_pop_all_widgets (id, True); | |
1163 } | |
1164 | |
1165 void | |
1166 lw_pop_down_all_widgets (LWLIB_ID id) | |
1167 { | |
1168 lw_pop_all_widgets (id, False); | |
1169 } | |
1170 | |
1171 void | |
1172 lw_popup_menu (Widget widget, XEvent *event) | |
1173 { | |
1174 #ifdef LWLIB_MENUBARS_LUCID | |
1175 if (lw_lucid_widget_p (widget)) | |
1176 xlw_popup_menu (widget, event); | |
1177 #endif | |
1178 #ifdef LWLIB_MENUBARS_MOTIF | |
1179 if (lw_motif_widget_p (widget)) | |
1180 xm_popup_menu (widget, event); | |
1181 #endif | |
1182 #ifdef LWLIB_MENUBARS_ATHENA | |
1183 if (lw_xaw_widget_p (widget)) | |
1184 xaw_popup_menu (widget, event); /* not implemented */ | |
1185 #endif | |
1186 } | |
1187 | |
1188 /* get the values back */ | |
1189 static Boolean | |
1190 get_one_value (widget_instance *instance, widget_value *val) | |
1191 { | |
1192 Widget widget = name_to_widget (instance, val->name); | |
1193 | |
1194 if (widget) | |
1195 { | |
1196 #ifdef NEED_LUCID | |
1197 if (lw_lucid_widget_p (instance->widget)) | |
1198 xlw_update_one_value (instance, widget, val); | |
1199 #endif | |
1200 #ifdef NEED_MOTIF | |
1201 if (lw_motif_widget_p (instance->widget)) | |
1202 xm_update_one_value (instance, widget, val); | |
1203 #endif | |
1204 #ifdef NEED_ATHENA | |
1205 if (lw_xaw_widget_p (instance->widget)) | |
1206 xaw_update_one_value (instance, widget, val); | |
1207 #endif | |
1208 return True; | |
1209 } | |
1210 else | |
1211 return False; | |
1212 } | |
1213 | |
1214 Boolean | |
1215 lw_get_some_values (LWLIB_ID id, widget_value *val_out) | |
1216 { | |
1217 widget_info *info = get_widget_info (id, False); | |
1218 widget_instance *instance; | |
1219 widget_value *val; | |
1220 Boolean result = False; | |
1221 | |
1222 if (!info) | |
1223 return False; | |
1224 | |
1225 instance = info->instances; | |
1226 if (!instance) | |
1227 return False; | |
1228 | |
1229 for (val = val_out; val; val = val->next) | |
1230 if (get_one_value (instance, val)) | |
1231 result = True; | |
1232 | |
1233 return result; | |
1234 } | |
1235 | |
1236 widget_value* | |
1237 lw_get_all_values (LWLIB_ID id) | |
1238 { | |
1239 widget_info *info = get_widget_info (id, False); | |
1240 widget_value *val = info->val; | |
1241 if (lw_get_some_values (id, val)) | |
1242 return val; | |
1243 else | |
1244 return NULL; | |
1245 } | |
1246 | |
1247 /* internal function used by the library dependent implementation to get the | |
1248 widget_value for a given widget in an instance */ | |
1249 widget_value* | |
1250 lw_get_widget_value_for_widget (widget_instance *instance, Widget w) | |
1251 { | |
1252 char *name = XtName (w); | |
1253 widget_value *cur; | |
1254 for (cur = instance->info->val; cur; cur = cur->next) | |
1255 if (!strcmp (cur->name, name)) | |
1256 return cur; | |
1257 return NULL; | |
1258 } | |
1259 | |
1260 | |
1261 /* update other instances value when one thing changed */ | |
1262 /* This function can be used as a an XtCallback for the widgets that get | |
1263 modified to update other instances of the widgets. Closure should be the | |
1264 widget_instance. */ | |
1265 void | |
1266 lw_internal_update_other_instances (Widget widget, XtPointer closure, | |
2286 | 1267 XtPointer UNUSED (call_data)) |
428 | 1268 { |
1269 /* To forbid recursive calls */ | |
1270 static Boolean updating; | |
1271 | |
1272 widget_instance *instance = (widget_instance*)closure; | |
1273 char *name = XtName (widget); | |
1274 widget_info *info; | |
1275 widget_instance *cur; | |
1276 widget_value *val; | |
1277 | |
1278 /* never recurse as this could cause infinite recursions. */ | |
1279 if (updating) | |
1280 return; | |
1281 | |
1282 /* protect against the widget being destroyed */ | |
1283 if (XtWidgetBeingDestroyedP (widget)) | |
1284 return; | |
1285 | |
1286 /* Return immediately if there are no other instances */ | |
1287 info = instance->info; | |
1288 if (!info->instances->next) | |
1289 return; | |
1290 | |
1291 updating = True; | |
1292 | |
1293 for (val = info->val; val && strcmp (val->name, name); val = val->next); | |
1294 | |
1295 if (val && get_one_value (instance, val)) | |
1296 for (cur = info->instances; cur; cur = cur->next) | |
1297 if (cur != instance) | |
1298 set_one_value (cur, val, True); | |
1299 | |
1300 updating = False; | |
1301 } | |
1302 | |
1303 | |
1304 | |
1305 /* get the id */ | |
1306 | |
1307 LWLIB_ID | |
1308 lw_get_widget_id (Widget w) | |
1309 { | |
1310 widget_instance *instance = get_widget_instance (w, False); | |
1311 | |
1312 return instance ? instance->info->id : 0; | |
1313 } | |
1314 | |
1315 | |
1316 /* set the keyboard focus */ | |
1317 void | |
1318 lw_set_keyboard_focus (Widget parent, Widget w) | |
1319 { | |
1320 #if defined(NEED_MOTIF) && !defined(LESSTIF_VERSION) | |
1321 /* This loses with Lesstif v0.75a */ | |
1322 xm_set_keyboard_focus (parent, w); | |
1323 #else | |
1324 XtSetKeyboardFocus (parent, w); | |
1325 #endif | |
1326 } | |
1327 | |
1328 | |
1329 /* Show busy */ | |
1330 static void | |
2286 | 1331 show_one_widget_busy (Widget w, Boolean UNUSED (flag)) |
428 | 1332 { |
1333 Pixel foreground = 0; | |
1334 Pixel background = 1; | |
1335 Widget widget_to_invert = XtNameToWidget (w, "*sheet"); | |
1336 Arg al [2]; | |
1337 | |
1338 if (!widget_to_invert) | |
1339 widget_to_invert = w; | |
1340 | |
1341 XtSetArg (al [0], XtNforeground, &foreground); | |
1342 XtSetArg (al [1], XtNbackground, &background); | |
1343 XtGetValues (widget_to_invert, al, 2); | |
1344 | |
1345 XtSetArg (al [0], XtNforeground, background); | |
1346 XtSetArg (al [1], XtNbackground, foreground); | |
1347 XtSetValues (widget_to_invert, al, 2); | |
1348 } | |
1349 | |
1350 void | |
1351 lw_show_busy (Widget w, Boolean busy) | |
1352 { | |
1353 widget_instance *instance = get_widget_instance (w, False); | |
1354 widget_info *info; | |
1355 widget_instance *next; | |
1356 | |
1357 if (instance) | |
1358 { | |
1359 info = instance->info; | |
1360 if (info->busy != busy) | |
1361 { | |
1362 for (next = info->instances; next; next = next->next) | |
1363 if (next->widget) | |
1364 show_one_widget_busy (next->widget, busy); | |
1365 info->busy = busy; | |
1366 } | |
1367 } | |
1368 } | |
1369 | |
1370 void lw_add_value_args_to_args (widget_value* wv, ArgList addto, int* offset) | |
1371 { | |
1372 int i; | |
434 | 1373 if (wv->args && wv->args->nargs) |
428 | 1374 { |
434 | 1375 for (i = 0; i<wv->args->nargs; i++) |
428 | 1376 { |
434 | 1377 addto[i + *offset] = wv->args->args[i]; |
428 | 1378 } |
434 | 1379 *offset += wv->args->nargs; |
428 | 1380 } |
1381 } | |
1382 | |
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
1383 XtArgVal lw_get_value_arg (widget_value* wv, const String name) |
639 | 1384 { |
1385 int i; | |
1386 if (wv->args) | |
1387 { | |
1388 for (i = 0; i < wv->args->nargs; i++) | |
1389 { | |
1390 if (!strcmp (wv->args->args[i].name, name)) | |
1391 { | |
1392 return wv->args->args[i].value; | |
1393 } | |
1394 } | |
1395 } | |
1396 return (XtArgVal)0; | |
1397 } | |
1398 | |
434 | 1399 void lw_add_widget_value_arg (widget_value* wv, String name, XtArgVal value) |
1400 { | |
442 | 1401 int i = 0; |
434 | 1402 if (!wv->args) |
1403 { | |
1404 wv->args = (widget_args *) malloc (sizeof (widget_args)); | |
438 | 1405 memset (wv->args, '\0', sizeof (widget_args)); |
434 | 1406 wv->args->ref_count = 1; |
1407 wv->args->nargs = 0; | |
1408 wv->args->args = (ArgList) malloc (sizeof (Arg) * 10); | |
438 | 1409 memset (wv->args->args, '\0', sizeof (Arg) * 10); |
434 | 1410 } |
1411 | |
1412 if (wv->args->nargs > 10) | |
1413 return; | |
1414 | |
450 | 1415 /* Register the change. */ |
1416 wv->args->args_changed = True; | |
442 | 1417 /* If the arg is already there then we must replace it. */ |
1418 for (i = 0; i < wv->args->nargs; i++) | |
1419 { | |
1420 if (!strcmp (wv->args->args[i].name, name)) | |
1421 { | |
1422 XtSetArg (wv->args->args [i], name, value); | |
1423 break; | |
1424 } | |
1425 } | |
1426 if (i >= wv->args->nargs) | |
1427 { | |
1428 XtSetArg (wv->args->args [wv->args->nargs], name, value); wv->args->nargs++; | |
1429 } | |
434 | 1430 } |
1431 | |
1432 static void free_widget_value_args (widget_value* wv) | |
1433 { | |
1434 if (wv->args) | |
1435 { | |
1436 if (--wv->args->ref_count <= 0) | |
1437 { | |
1438 #ifdef LWLIB_WIDGETS_MOTIF | |
1439 int i; | |
1440 for (i = 0; i < wv->args->nargs; i++) | |
1441 { | |
1442 if (!strcmp (wv->args->args[i].name, XmNfontList)) | |
1443 XmFontListFree ((XmFontList)wv->args->args[i].value); | |
1444 } | |
1445 #endif | |
1446 free (wv->args->args); | |
1447 free (wv->args); | |
442 | 1448 wv->args = 0; |
434 | 1449 } |
1450 } | |
1451 } | |
1452 | |
1453 void lw_copy_widget_value_args (widget_value* val, widget_value* copy) | |
1454 { | |
442 | 1455 if (val == copy || val->args == copy->args) |
1456 return; | |
1457 | |
1458 if (copy->args) | |
434 | 1459 { |
442 | 1460 free_widget_value_args (copy); |
434 | 1461 } |
442 | 1462 |
1463 if (val->args) | |
434 | 1464 { |
1465 copy->args = val->args; | |
1466 copy->args->ref_count++; | |
1467 } | |
1468 } | |
1469 | |
442 | 1470 /* Remove %_ and convert %% to %. We can do this in-place because we |
1471 are always shortening, never lengthening, the string. */ | |
1472 void | |
1473 lw_remove_accelerator_spec (char *val) | |
1474 { | |
1475 char *foo = val, *bar = val; | |
1476 | |
1477 while (*bar) | |
1478 { | |
1479 if (*bar == '%' && *(bar+1) == '_') | |
1480 bar += 2; | |
1481 else if (*bar == '%' && *(bar+1) == '%') | |
1482 { | |
1483 *foo++ = *bar++; | |
1484 bar++; | |
1485 } | |
1486 else | |
1487 *foo++ = *bar++; | |
1488 } | |
1489 *foo = '\0'; | |
1490 } |