Mercurial > emacs
annotate oldXMenu/Internal.c @ 72550:666bd542be19
(get_window_cursor_type): Replace BOX cursor on images
with a hollow box cursor if image is larger than 32x32 (or the default
frame font if that is bigger). Replace any other cursor on images
with hollow box cursor, as redisplay doesn't support bar and hbar
cursors on images.
author | Kim F. Storm <storm@cua.dk> |
---|---|
date | Sun, 27 Aug 2006 22:23:07 +0000 |
parents | e8a3fb527b77 |
children | ce127a46b1ca d04d8ccb3c41 c5406394f567 |
rev | line source |
---|---|
25858 | 1 #include "copyright.h" |
2 | |
3 /* Copyright Massachusetts Institute of Technology 1985 */ | |
68640
e8a3fb527b77
Update years in copyright notice; nfc.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
65000
diff
changeset
|
4 /* Copyright (C) 2002, 2003, 2004, 2005, |
e8a3fb527b77
Update years in copyright notice; nfc.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
65000
diff
changeset
|
5 2006 Free Software Foundation, Inc. */ |
25858 | 6 |
7 /* | |
8 * XMenu: MIT Project Athena, X Window system menu package | |
9 * | |
10 * XMenuInternal.c - XMenu internal (not user visible) routines. | |
11 * | |
12 * Author: Tony Della Fera, DEC | |
13 * November, 1985 | |
14 * | |
15 */ | |
16 | |
17 #include <config.h> | |
18 #include "XMenuInt.h" | |
19 | |
20 /* | |
21 * Toggle color macro. | |
22 */ | |
23 #define toggle_color(x) \ | |
24 ((x) == menu->bkgnd_color ? menu->s_frg_color : menu->bkgnd_color) | |
25 | |
26 /* | |
27 * Internal Window creation queue sizes. | |
28 */ | |
29 #define S_QUE_SIZE 300 | |
30 #define P_QUE_SIZE 20 | |
31 #define BUFFER_SIZE (S_QUE_SIZE >= P_QUE_SIZE ? S_QUE_SIZE : P_QUE_SIZE) | |
32 | |
33 | |
34 /* | |
35 * XMWinQue - Internal window creation queue datatype. | |
36 */ | |
37 typedef struct _xmwinquedef { | |
38 int sq_size; | |
39 XMSelect *sq[S_QUE_SIZE]; | |
40 XMSelect **sq_ptr; | |
41 int pq_size; | |
42 XMPane *pq[P_QUE_SIZE]; | |
43 XMPane **pq_ptr; | |
44 } XMWinQue; | |
45 | |
46 /* | |
47 * _XMWinQue - Internal static window creation queue. | |
48 */ | |
49 static Bool _XMWinQueIsInit = False; | |
50 static XMWinQue _XMWinQue; | |
51 | |
52 /* | |
53 * _XMErrorCode - Global XMenu error code. | |
54 */ | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
55 int _XMErrorCode = XME_NO_ERROR; |
25858 | 56 /* |
57 * _XMErrorList - Global XMenu error code description strings. | |
58 */ | |
59 char * | |
60 _XMErrorList[XME_CODE_COUNT] = { | |
61 "No error", /* XME_NO_ERROR */ | |
62 "Menu not initialized", /* XME_NOT_INIT */ | |
63 "Argument out of bounds", /* XME_ARG_BOUNDS */ | |
64 "Pane not found", /* XME_P_NOT_FOUND */ | |
65 "Selection not found", /* XME_S_NOT_FOUND */ | |
66 "Invalid menu style parameter", /* XME_STYLE_PARAM */ | |
67 "Unable to grab mouse", /* XME_GRAB_MOUSE */ | |
68 "Unable to interpret locator", /* XME_INTERP_LOC */ | |
69 "Unable to calloc memory", /* XME_CALLOC */ | |
70 "Unable to create XAssocTable", /* XME_CREATE_ASSOC */ | |
71 "Unable to store bitmap", /* XME_STORE_BITMAP */ | |
72 "Unable to make tile pixmaps", /* XME_MAKE_TILES */ | |
73 "Unable to make pixmap", /* XME_MAKE_PIXMAP */ | |
74 "Unable to create cursor", /* XME_CREATE_CURSOR */ | |
75 "Unable to open font", /* XME_OPEN_FONT */ | |
76 "Unable to create windows", /* XME_CREATE_WINDOW */ | |
77 "Unable to create transparencies", /* XME_CREATE_TRANSP */ | |
78 }; | |
79 | |
80 /* | |
81 * _XMEventHandler - Internal event handler variable. | |
82 */ | |
83 int (*_XMEventHandler)() = NULL; | |
84 | |
85 | |
86 | |
87 /* | |
88 * _XMWinQueInit - Internal routine to initialize the window | |
89 * queue. | |
90 */ | |
91 _XMWinQueInit() | |
92 { | |
93 /* | |
94 * If the queue is not initialized initialize it. | |
95 */ | |
96 if (!_XMWinQueIsInit) { | |
97 /* | |
98 * Blank the queue structure. | |
99 */ | |
100 register int i; | |
101 | |
102 for (i = 0; i < S_QUE_SIZE; i++) | |
103 _XMWinQue.sq[i] = 0; | |
104 | |
105 for (i = 0; i < P_QUE_SIZE; i++) | |
106 _XMWinQue.pq[i] = 0; | |
107 | |
108 _XMWinQue.sq_size = _XMWinQue.pq_size = 0; | |
109 | |
110 /* | |
111 * Initialize the next free location pointers. | |
112 */ | |
113 _XMWinQue.sq_ptr = _XMWinQue.sq; | |
114 _XMWinQue.pq_ptr = _XMWinQue.pq; | |
115 } | |
116 } | |
117 | |
118 | |
119 | |
120 /* | |
121 * _XMWinQueAddPane - Internal routine to add a pane to the pane | |
122 * window queue. | |
123 */ | |
124 int | |
125 _XMWinQueAddPane(display, menu, p_ptr) | |
126 register Display *display; | |
127 register XMenu *menu; /* Menu being manipulated. */ | |
128 register XMPane *p_ptr; /* XMPane being queued. */ | |
129 { | |
130 /* | |
131 * If the queue is currently full then flush it. | |
132 */ | |
133 if (_XMWinQue.pq_size == P_QUE_SIZE) { | |
134 if (_XMWinQueFlush(display, menu, 0, 0) == _FAILURE) return(_FAILURE); | |
135 } | |
136 | |
137 /* | |
138 * Insert the new XMPane pointer and increment the queue pointer | |
139 * and the queue size. | |
140 */ | |
141 *_XMWinQue.pq_ptr = p_ptr; | |
142 _XMWinQue.pq_ptr++; | |
143 _XMWinQue.pq_size++; | |
144 | |
145 /* | |
146 * All went well, return successfully. | |
147 */ | |
148 _XMErrorCode = XME_NO_ERROR; | |
149 return(_SUCCESS); | |
150 } | |
151 | |
152 | |
153 | |
154 /* | |
155 * _XMWinQueAddSelection - Internal routine to add a selection to | |
156 * the selection window queue. | |
157 */ | |
158 int | |
159 _XMWinQueAddSelection(display, menu, s_ptr) | |
160 register Display *display; | |
161 register XMenu *menu; /* Menu being manipulated. */ | |
162 register XMSelect *s_ptr; /* XMSelection being queued. */ | |
163 { | |
164 /* | |
165 * If this entry will overflow the queue then flush it. | |
166 */ | |
167 if (_XMWinQue.sq_size == S_QUE_SIZE) { | |
168 if (_XMWinQueFlush(display, menu, 0, 0) == _FAILURE) return(_FAILURE); | |
169 } | |
170 | |
171 /* | |
172 * Insert the new XMSelect pointer and increment the queue pointer | |
173 * and the queue size. | |
174 */ | |
175 *_XMWinQue.sq_ptr = s_ptr; | |
176 _XMWinQue.sq_ptr++; | |
177 _XMWinQue.sq_size++; | |
178 | |
179 /* | |
180 * All went well, return successfully. | |
181 */ | |
182 _XMErrorCode = XME_NO_ERROR; | |
183 return(_SUCCESS); | |
184 } | |
185 | |
186 | |
187 | |
188 /* | |
189 * _XMWinQueFlush - Internal routine to flush the pane and | |
190 * selection window queues. | |
191 */ | |
192 int | |
193 _XMWinQueFlush(display, menu, pane, select) | |
194 register Display *display; | |
195 register XMenu *menu; /* Menu being manipulated. */ | |
196 register XMPane *pane; /* Current pane. */ | |
197 { | |
198 register int pq_index; /* Pane queue index. */ | |
199 register int sq_index; /* Selection queue index. */ | |
200 register XMPane *p_ptr; /* XMPane pointer. */ | |
201 register XMSelect *s_ptr; /* XMSelect pointer. */ | |
202 unsigned long valuemask; /* Which attributes to set. */ | |
203 XSetWindowAttributes *attributes; /* Attributes to be set. */ | |
204 | |
205 /* | |
206 * If the pane window queue is not empty... | |
207 */ | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
208 |
25858 | 209 if (_XMWinQue.pq_size > 0) { |
210 /* | |
211 * set up attributes for pane window to be created. | |
212 */ | |
213 valuemask = (CWBackPixmap | CWBorderPixel | CWOverrideRedirect); | |
214 attributes = (XSetWindowAttributes *)malloc(sizeof(XSetWindowAttributes)); | |
215 attributes->border_pixel = menu->p_bdr_color; | |
216 attributes->background_pixmap = menu->inact_pixmap; | |
217 attributes->override_redirect = True; | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
218 |
25858 | 219 /* |
220 * Create all the pending panes in order, so that the | |
221 * current pane will be on top, with the others | |
222 * stacked appropriately under it. | |
223 */ | |
224 for (pq_index = _XMWinQue.pq_size - 1; | |
225 pq_index >= 0; | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
226 pq_index--) |
25858 | 227 { |
228 p_ptr = _XMWinQue.pq[pq_index]; /* Retrieve next pane. */ | |
229 if (p_ptr == pane) break; | |
230 p_ptr->window = XCreateWindow(display, | |
231 menu->parent, | |
232 p_ptr->window_x, | |
233 p_ptr->window_y, | |
234 p_ptr->window_w, | |
235 p_ptr->window_h, | |
236 menu->p_bdr_width, | |
237 CopyFromParent, | |
238 InputOutput, | |
239 CopyFromParent, | |
240 valuemask, | |
241 attributes); | |
242 XMakeAssoc(display, menu->assoc_tab, p_ptr->window, p_ptr); | |
243 XSelectInput(display, p_ptr->window, menu->p_events); | |
244 } | |
245 for (pq_index = 0; | |
246 pq_index < _XMWinQue.pq_size; | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
247 pq_index++) |
25858 | 248 { |
249 p_ptr = _XMWinQue.pq[pq_index]; /* Retrieve next pane. */ | |
250 p_ptr->window = XCreateWindow(display, | |
251 menu->parent, | |
252 p_ptr->window_x, | |
253 p_ptr->window_y, | |
254 p_ptr->window_w, | |
255 p_ptr->window_h, | |
256 menu->p_bdr_width, | |
257 CopyFromParent, | |
258 InputOutput, | |
259 CopyFromParent, | |
260 valuemask, | |
261 attributes); | |
262 XMakeAssoc(display, menu->assoc_tab, p_ptr->window, p_ptr); | |
263 XSelectInput(display, p_ptr->window, menu->p_events); | |
264 if (p_ptr == pane) break; | |
265 } | |
266 | |
267 /* | |
268 * Reset the pane queue pointer and size. | |
269 */ | |
270 _XMWinQue.pq_size = 0; | |
271 _XMWinQue.pq_ptr = _XMWinQue.pq; | |
272 } | |
273 | |
274 /* | |
275 * If the selection window queue is not empty... | |
276 */ | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
277 |
25858 | 278 if (_XMWinQue.sq_size > 0) { |
279 | |
280 for (sq_index = 0; sq_index < _XMWinQue.sq_size; sq_index++) { | |
281 /* | |
282 * Retrieve the XMSelect pointer. | |
283 */ | |
284 s_ptr = _XMWinQue.sq[sq_index]; | |
285 s_ptr->window = XCreateWindow(display, | |
286 s_ptr->parent_p->window, | |
287 s_ptr->window_x, | |
288 s_ptr->window_y, | |
289 s_ptr->window_w, | |
290 s_ptr->window_h, | |
291 0, /* border width*/ | |
292 CopyFromParent, | |
293 InputOnly, | |
294 CopyFromParent, | |
295 0, | |
296 attributes); | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
297 |
25858 | 298 /* |
299 * Insert the new window id and its | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
300 * associated XMSelect structure into the |
25858 | 301 * association table. |
302 */ | |
303 XMakeAssoc(display, menu->assoc_tab, s_ptr->window, s_ptr); | |
304 XSelectInput(display, s_ptr->window, menu->s_events); | |
305 } | |
306 | |
307 /* | |
308 * Reset the selection queue pointer and size. | |
309 */ | |
310 _XMWinQue.sq_size = 0; | |
311 _XMWinQue.sq_ptr = _XMWinQue.sq; | |
312 } | |
313 | |
314 /* | |
315 * Flush X's internal queues. | |
316 */ | |
317 XFlush(display); | |
318 | |
319 /* | |
320 * All went well, return successfully. | |
321 */ | |
322 _XMErrorCode = XME_NO_ERROR; | |
323 return(_SUCCESS); | |
324 } | |
325 | |
326 | |
327 | |
328 /* | |
329 * _XMGetPanePtr - Given a menu pointer and a pane index number, return | |
330 * a pane pointer that points to the indexed pane. | |
331 */ | |
332 XMPane * | |
333 _XMGetPanePtr(menu, p_num) | |
334 register XMenu *menu; /* Menu to find the pane in. */ | |
335 register int p_num; /* Index number of pane to find. */ | |
336 { | |
337 register XMPane *p_ptr; /* Pane pointer to be returned. */ | |
338 register int i; /* Loop counter. */ | |
339 | |
340 /* | |
341 * Is the pane number out of range? | |
342 */ | |
343 if ((p_num < 0) || (p_num > (menu->p_count - 1))) { | |
344 _XMErrorCode = XME_P_NOT_FOUND; | |
345 return(NULL); | |
346 } | |
347 | |
348 /* | |
349 * Find the right pane. | |
350 */ | |
351 p_ptr = menu->p_list->next; | |
352 for (i = 0; i < p_num; i++) p_ptr = p_ptr->next; | |
353 | |
354 /* | |
355 * Return successfully. | |
356 */ | |
357 _XMErrorCode = XME_NO_ERROR; | |
358 return(p_ptr); | |
359 } | |
360 | |
361 | |
362 | |
363 /* | |
364 * _XMGetSelectionPtr - Given pane pointer and a selection index number, | |
365 * return a selection pointer that points to the | |
366 * indexed selection. | |
367 */ | |
368 XMSelect * | |
369 _XMGetSelectionPtr(p_ptr, s_num) | |
370 register XMPane *p_ptr; /* Pane to find the selection in. */ | |
371 register int s_num; /* Index number of the selection to find. */ | |
372 { | |
373 register XMSelect *s_ptr; /* Selection pointer to be returned. */ | |
374 register int i; /* Loop counter. */ | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
375 |
25858 | 376 /* |
377 * Is the selection number out of range? | |
378 */ | |
379 if ((s_num < 0) || (s_num > (p_ptr->s_count - 1))) { | |
380 _XMErrorCode = XME_S_NOT_FOUND; | |
381 return(NULL); | |
382 } | |
383 | |
384 /* | |
385 * Find the right selection. | |
386 */ | |
387 s_ptr = p_ptr->s_list->next; | |
388 for (i = 0; i < s_num; i++) s_ptr = s_ptr->next; | |
389 | |
390 /* | |
391 * Return successfully. | |
392 */ | |
393 _XMErrorCode = XME_NO_ERROR; | |
394 return(s_ptr); | |
395 } | |
396 | |
397 | |
398 | |
399 /* | |
400 * _XMRecomputeGlobals - Internal subroutine to recompute menu wide | |
401 * global values. | |
402 */ | |
403 _XMRecomputeGlobals(display, menu) | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
404 register Display *display; /*X11 display variable. */ |
25858 | 405 register XMenu *menu; /* Menu object to compute from. */ |
406 { | |
407 register XMPane *p_ptr; /* Pane pointer. */ | |
408 register XMSelect *s_ptr; /* Selection pointer. */ | |
409 | |
410 register int max_p_label = 0; /* Maximum pane label width. */ | |
411 register int max_s_label = 0; /* Maximum selection label width. */ | |
412 register int s_count = 0; /* Maximum selection count. */ | |
413 | |
414 int p_s_pad; /* Pane <-> selection padding. */ | |
415 int p_s_diff; /* Pane <-> selection separation. */ | |
416 | |
417 int p_height; /* Pane window height. */ | |
418 int p_width; /* Pane window width. */ | |
419 int s_width; /* Selection window width. */ | |
420 | |
421 int screen; /* DefaultScreen holder. */ | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
422 |
25858 | 423 /* |
424 * For each pane... | |
425 */ | |
426 for ( | |
427 p_ptr = menu->p_list->next; | |
428 p_ptr != menu->p_list; | |
429 p_ptr = p_ptr->next | |
430 ){ | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
431 |
25858 | 432 /* |
433 * Recompute maximum pane label width. | |
434 */ | |
435 max_p_label = max(max_p_label, p_ptr->label_width); | |
436 | |
437 /* | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
438 * Recompute maximum selection count. |
25858 | 439 */ |
440 s_count = max(s_count, p_ptr->s_count); | |
441 | |
442 /* | |
443 * For each selection in the current pane... | |
444 */ | |
445 for ( | |
446 s_ptr = p_ptr->s_list->next; | |
447 s_ptr != p_ptr->s_list; | |
448 s_ptr = s_ptr->next | |
449 ){ | |
450 | |
451 /* | |
452 * Recompute maximum selection label width. | |
453 */ | |
454 max_s_label = max(max_s_label, s_ptr->label_width); | |
455 } | |
456 } | |
457 | |
458 /* | |
459 * Recompute pane height. | |
460 */ | |
461 p_height = (menu->flag_height << 1) + (menu->s_y_off * s_count); | |
462 | |
463 /* | |
464 * Recompute horizontal padding between the pane window and the | |
465 * selection windows. | |
466 */ | |
467 p_s_pad = menu->p_x_off << 1; | |
468 | |
469 /* | |
470 * Recompute pane and selection window widths. | |
471 * This is done by first computing the window sizes from the maximum | |
472 * label widths. If the spacing between the selection window and the | |
473 * containing pane window is less than the pane selection padding value | |
474 * (twice the pane X offset) then change the size of the pane to be | |
475 * the size of the selection window plus the padding. If, however the | |
476 * spacing between the selection window and the containing pane window | |
477 * is more than the pane selection padding value increase the size of | |
478 * the selection to its maximum possible value (the pane width minus | |
479 * the pane selection padding value). | |
480 */ | |
481 p_width = max_p_label + p_s_pad; | |
482 s_width = max_s_label + (menu->s_fnt_pad << 1) + (menu->s_bdr_width << 1); | |
483 p_s_diff = p_width - s_width; | |
484 if (p_s_diff < p_s_pad) { | |
485 p_width = s_width + p_s_pad; | |
486 } | |
487 else if (p_s_diff > p_s_pad) { | |
488 s_width = p_width - p_s_pad; | |
489 } | |
490 | |
491 /* | |
492 * Reset menu wide global values. | |
493 */ | |
494 menu->s_count = s_count; | |
495 menu->p_height = p_height; | |
496 menu->p_width = p_width; | |
497 menu->s_width = s_width; | |
498 | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
499 /* |
25858 | 500 * Ensure that the origin of the menu is placed so that |
501 * None of the panes ore selections are off the screen. | |
502 */ | |
503 screen = DefaultScreen(display); | |
504 if (menu->x_pos + menu->width > DisplayWidth(display, screen)) | |
505 menu->x_pos = DisplayWidth(display, screen) - menu->width; | |
506 else if (menu->x_pos < 0) menu->x_pos = 0; | |
507 if(menu->y_pos + menu->height > DisplayHeight(display, screen)) | |
508 menu->y_pos = DisplayHeight(display, screen) - menu->height; | |
509 else if (menu->y_pos < 0) menu->y_pos = 0; | |
510 } | |
511 | |
512 | |
513 /* | |
514 * _XMRecomputePane - Internal subroutine to recompute pane | |
515 * window dependencies. | |
516 */ | |
517 int | |
518 _XMRecomputePane(display, menu, p_ptr, p_num) | |
519 register Display *display; /* Standard X display variable. */ | |
520 register XMenu *menu; /* Menu object being recomputed. */ | |
521 register XMPane *p_ptr; /* Pane pointer. */ | |
522 register int p_num; /* Pane sequence number. */ | |
523 { | |
524 register int window_x; /* Recomputed window X coordinate. */ | |
525 register int window_y; /* Recomputed window Y coordinate. */ | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
526 |
25858 | 527 unsigned long change_mask; /* Value mask to reconfigure window. */ |
528 XWindowChanges *changes; /* Values to use in configure window. */ | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
529 |
25858 | 530 register Bool config_p = False; /* Reconfigure pane window? */ |
531 | |
532 /* | |
533 * Update the pane serial number. | |
534 */ | |
535 p_ptr->serial = p_num; | |
536 | |
537 /* | |
538 * Recompute window X and Y coordinates. | |
539 */ | |
540 switch (menu->menu_style) { | |
541 case LEFT: | |
542 window_x = menu->p_x_off * ((menu->p_count - 1) - p_num); | |
543 window_y = menu->p_y_off * ((menu->p_count - 1) - p_num); | |
544 break; | |
545 case RIGHT: | |
546 window_x = menu->p_x_off * p_num; | |
547 window_y = menu->p_y_off * ((menu->p_count - 1) - p_num); | |
548 break; | |
549 case CENTER: | |
550 window_x = 0; | |
551 window_y = menu->p_y_off * ((menu->p_count - 1) - p_num); | |
552 break; | |
553 default: | |
554 /* Error! Invalid style parameter. */ | |
555 _XMErrorCode = XME_STYLE_PARAM; | |
556 return(_FAILURE); | |
557 } | |
558 window_x += menu->x_pos; | |
559 window_y += menu->y_pos; | |
560 | |
561 /* | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
562 * If the newly compute pane coordinates differ from the |
25858 | 563 * current coordinates, reset the current coordinates and |
564 * reconfigure the pane. | |
565 */ | |
566 if ( | |
567 (window_x != p_ptr->window_x) || | |
568 (window_y != p_ptr->window_y) | |
569 ){ | |
570 /* | |
571 * Reset the coordinates and schedule | |
572 * the pane for reconfiguration. | |
573 */ | |
574 p_ptr->window_x = window_x; | |
575 p_ptr->window_y = window_y; | |
576 config_p = True; | |
577 } | |
578 | |
579 /* | |
580 * If the local pane width and height differs from the | |
581 * menu pane width and height, reset the local values. | |
582 */ | |
583 if ( | |
584 (p_ptr->window_w != menu->p_width) || | |
585 (p_ptr->window_h != menu->p_height) | |
586 ){ | |
587 /* | |
588 * Reset window width and height and schedule | |
589 * the pane for reconfiguration. | |
590 */ | |
591 p_ptr->window_w = menu->p_width; | |
592 p_ptr->window_h = menu->p_height; | |
593 config_p = True; | |
594 } | |
595 | |
596 /* | |
597 * If we need to reconfigure the pane window do it now. | |
598 */ | |
599 if (config_p == True) { | |
600 /* | |
601 * If the pane window has already been created then | |
602 * reconfigure the existing window, otherwise queue | |
603 * it for creation with the new configuration. | |
604 */ | |
605 if (p_ptr->window) { | |
606 change_mask = (CWX | CWY | CWWidth | CWHeight); | |
607 changes = (XWindowChanges *)malloc(sizeof(XWindowChanges)); | |
608 changes->x = p_ptr->window_x; | |
609 changes->y = p_ptr->window_y; | |
610 changes->width = p_ptr->window_w; | |
611 changes->height = p_ptr->window_h; | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
612 |
25858 | 613 XConfigureWindow( |
614 display, | |
615 p_ptr->window, | |
616 change_mask, | |
617 changes | |
618 ); | |
619 free(changes); | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
620 |
25858 | 621 } |
622 else { | |
623 if (_XMWinQueAddPane(display, menu, p_ptr) == _FAILURE) { | |
624 return(_FAILURE); | |
625 } | |
626 } | |
627 } | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
628 |
25858 | 629 /* |
630 * Recompute label X position. | |
631 */ | |
632 switch (menu->p_style) { | |
633 case LEFT: | |
634 p_ptr->label_x = menu->p_x_off + menu->p_fnt_pad; | |
635 break; | |
636 case RIGHT: | |
637 p_ptr->label_x = menu->p_width - | |
638 (p_ptr->label_width + menu->p_x_off + menu->p_fnt_pad); | |
639 break; | |
640 case CENTER: | |
641 p_ptr->label_x = (menu->p_width - p_ptr->label_width) >> 1; | |
642 break; | |
643 default: | |
644 /* Error! Invalid style parameter. */ | |
645 _XMErrorCode = XME_STYLE_PARAM; | |
646 return(_FAILURE); | |
647 } | |
648 /* | |
649 * Recompute label Y positions. | |
650 */ | |
651 p_ptr->label_uy = menu->p_fnt_pad + menu->p_fnt_info->max_bounds.ascent; | |
652 p_ptr->label_ly = (menu->p_height - menu->p_fnt_pad - menu->p_fnt_info->max_bounds.descent); | |
653 | |
654 /* | |
655 * All went well, return successfully. | |
656 */ | |
657 _XMErrorCode = XME_NO_ERROR; | |
658 return(_SUCCESS); | |
659 } | |
660 | |
661 | |
662 | |
663 /* | |
664 * _XMRecomputeSelection - Internal subroutine to recompute | |
665 * selection window dependencies. | |
666 */ | |
667 int | |
668 _XMRecomputeSelection(display, menu, s_ptr, s_num) | |
669 register Display *display; | |
670 register XMenu *menu; /* Menu object being recomputed. */ | |
671 register XMSelect *s_ptr; /* Selection pointer. */ | |
672 register int s_num; /* Selection sequence number. */ | |
673 { | |
674 register Bool config_s = False; /* Reconfigure selection window? */ | |
675 XWindowChanges *changes; /* Values to change in configure. */ | |
676 unsigned long change_mask; /* Value mask for XConfigureWindow. */ | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
677 |
25858 | 678 /* |
679 * If the selection serial numbers are out of order, begin | |
680 * resequencing selections. Recompute selection window coordinates | |
681 * and serial number. | |
682 * | |
683 * When selections are created they are given a serial number of | |
684 * -1, this causes this routine to give a new selection | |
685 * its initial coordinates and serial number. | |
686 */ | |
687 if (s_ptr->serial != s_num) { | |
688 /* | |
689 * Fix the sequence number. | |
690 */ | |
691 s_ptr->serial = s_num; | |
692 /* | |
693 * Recompute window X and Y coordinates. | |
694 */ | |
695 s_ptr->window_x = menu->s_x_off; | |
696 s_ptr->window_y = menu->flag_height + (menu->s_y_off * s_num); | |
697 /* | |
698 * We must reconfigure the window. | |
699 */ | |
700 config_s = True; | |
701 } | |
702 | |
703 /* | |
704 * If the local selection width and height differs from the | |
705 * menu selection width and height, reset the local values. | |
706 */ | |
707 if ( | |
708 (s_ptr->window_w != menu->s_width) || | |
709 (s_ptr->window_h != menu->s_height) | |
710 ){ | |
711 /* | |
712 * We must reconfigure the window. | |
713 */ | |
714 config_s = True; | |
715 /* | |
716 * Reset window width and height. | |
717 */ | |
718 s_ptr->window_w = menu->s_width; | |
719 s_ptr->window_h = menu->s_height; | |
720 } | |
721 | |
722 /* | |
723 * If we need to reconfigure the selection window do it now. | |
724 */ | |
725 if (config_s == True) { | |
726 /* | |
727 * If the selection window has already been created then | |
728 * reconfigure the existing window, otherwise queue it | |
729 * for creation with the new configuration. | |
730 */ | |
731 if (s_ptr->window) { | |
732 changes = (XWindowChanges *)malloc(sizeof(XWindowChanges)); | |
733 change_mask = (CWX | CWY | CWWidth | CWHeight); | |
734 changes = (XWindowChanges *)malloc(sizeof(XWindowChanges)); | |
735 changes->x = s_ptr->window_x; | |
736 changes->y = s_ptr->window_y; | |
737 changes->width = s_ptr->window_w; | |
738 changes->height = s_ptr->window_h; | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
739 |
25858 | 740 XConfigureWindow( |
741 display, | |
742 s_ptr->window, | |
743 change_mask, | |
744 changes | |
745 ); | |
746 free(changes); | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
747 |
25858 | 748 } |
749 else { | |
750 if (_XMWinQueAddSelection(display, menu, s_ptr) == _FAILURE) { | |
751 return(_FAILURE); | |
752 } | |
753 } | |
754 } | |
755 | |
756 /* | |
757 * Recompute label X position. | |
758 */ | |
759 switch (menu->s_style) { | |
760 case LEFT: | |
761 s_ptr->label_x = menu->s_bdr_width + menu->s_fnt_pad + s_ptr->window_x; | |
762 break; | |
763 case RIGHT: | |
764 s_ptr->label_x = s_ptr->window_x + menu->s_width - | |
765 (s_ptr->label_width + menu->s_bdr_width + menu->s_fnt_pad); | |
766 break; | |
767 case CENTER: | |
768 s_ptr->label_x = s_ptr->window_x + ((menu->s_width - s_ptr->label_width) >> 1); | |
769 break; | |
770 default: | |
771 /* Error! Invalid style parameter. */ | |
772 _XMErrorCode = XME_STYLE_PARAM; | |
773 return(_FAILURE); | |
774 } | |
775 /* | |
776 * Recompute label Y position. | |
777 */ | |
778 s_ptr->label_y = s_ptr->window_y + menu->s_fnt_info->max_bounds.ascent + menu->s_fnt_pad + menu->s_bdr_width; | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
779 |
25858 | 780 /* |
781 * All went well, return successfully. | |
782 */ | |
783 _XMErrorCode = XME_NO_ERROR; | |
784 return(_SUCCESS); | |
785 } | |
786 | |
787 | |
788 | |
789 /* | |
790 * _XMTransToOrigin - Internal subroutine to translate the point at | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
791 * the center of the current pane and selection to the |
25858 | 792 * the menu origin. |
793 * | |
794 * WARNING! ****** Be certain that all menu dependencies have been | |
795 * recomputed before calling this routine or | |
796 * unpredictable results will follow. | |
797 */ | |
798 _XMTransToOrigin(display, menu, p_ptr, s_ptr, x_pos, y_pos, orig_x, orig_y) | |
799 Display *display; /* Not used. Included for consistency. */ | |
800 register XMenu *menu; /* Menu being computed against. */ | |
801 register XMPane *p_ptr; /* Current pane pointer. */ | |
802 register XMSelect *s_ptr; /* Current selection pointer. */ | |
803 int x_pos; /* X coordinate of point to translate. */ | |
804 int y_pos; /* Y coordinate of point to translate. */ | |
805 int *orig_x; /* Return value X coord. of the menu origin. */ | |
806 int *orig_y; /* Return value Y coord. of the menu origin. */ | |
807 { | |
808 register int l_orig_x; /* Local X coordinate of the menu origin. */ | |
809 register int l_orig_y; /* Local Y coordinate of the menu origin. */ | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
810 |
25858 | 811 /* |
812 * Translate the menu origin such that the cursor hot point will be in the | |
813 * center of the desired current selection and pane. | |
814 * If the current selection pointer is NULL then assume that the hot point | |
815 * will be in the center of the current pane flag. | |
816 */ | |
817 | |
818 if (s_ptr == NULL) { | |
819 /* | |
820 * Translate from the center of the pane flag to the upper left | |
821 * of the current pane window. | |
822 */ | |
823 l_orig_x = x_pos - (menu->p_width >> 1) - menu->p_bdr_width; | |
824 l_orig_y = y_pos - (menu->flag_height >> 1) - menu->p_bdr_width; | |
825 } | |
826 else { | |
827 /* | |
828 * First translate from the center of the current selection | |
829 * to the upper left of the current selection window. | |
830 */ | |
831 l_orig_x = x_pos - (menu->s_width >> 1); | |
832 l_orig_y = y_pos - (menu->s_height >> 1); | |
833 | |
834 /* | |
835 * Then translate to the upper left of the current pane window. | |
836 */ | |
837 l_orig_x -= (s_ptr->window_x + menu->p_bdr_width); | |
838 l_orig_y -= (s_ptr->window_y + menu->p_bdr_width); | |
839 } | |
840 | |
841 /* | |
842 * Finally translate to the upper left of the menu. | |
843 */ | |
844 l_orig_x -= (p_ptr->window_x - menu->x_pos); | |
845 l_orig_y -= (p_ptr->window_y - menu->y_pos); | |
846 | |
847 /* | |
848 * Set the return values. | |
849 */ | |
850 *orig_x = l_orig_x; | |
851 *orig_y = l_orig_y; | |
852 } | |
853 | |
854 /* | |
855 * _XMRefreshPane - Internal subroutine to completely refresh | |
856 * the contents of a pane. | |
857 */ | |
858 _XMRefreshPane(display, menu, pane) | |
859 register Display *display; | |
860 register XMenu *menu; | |
861 register XMPane *pane; | |
862 { | |
863 register XMSelect *s_list = pane->s_list; | |
864 register XMSelect *s_ptr; | |
865 | |
866 /* | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
867 * First clear the pane. |
25858 | 868 */ |
869 XClearWindow(display, pane->window); | |
870 if (!pane->activated) { | |
871 XFillRectangle(display, | |
872 pane->window, | |
873 menu->inverse_select_GC, | |
874 pane->label_x - menu->p_fnt_pad, | |
875 pane->label_uy - menu->p_fnt_info->max_bounds.ascent - menu->p_fnt_pad, | |
876 pane->label_width + (menu->p_fnt_pad << 1), | |
877 menu->flag_height); | |
878 | |
879 XFillRectangle(display, | |
880 pane->window, | |
881 menu->inverse_select_GC, | |
882 pane->label_x - menu->p_fnt_pad, | |
883 pane->label_ly - menu->p_fnt_info->max_bounds.ascent - menu->p_fnt_pad, | |
884 pane->label_width + (menu->p_fnt_pad << 1), | |
885 menu->flag_height); | |
886 } | |
887 if (!pane->active) { | |
888 XDrawString(display, | |
889 pane->window, | |
890 menu->inact_GC, | |
891 pane->label_x, pane->label_uy, | |
892 pane->label, pane->label_length); | |
893 XDrawString(display, | |
894 pane->window, | |
895 menu->inact_GC, | |
896 pane->label_x, pane->label_ly, | |
897 pane->label, pane->label_length); | |
898 } | |
899 else { | |
900 XDrawString(display, | |
901 pane->window, | |
902 menu->pane_GC, | |
903 pane->label_x, pane->label_uy, | |
904 pane->label, pane->label_length); | |
905 XDrawString(display, | |
906 pane->window, | |
907 menu->pane_GC, | |
908 pane->label_x, pane->label_ly, | |
909 pane->label, pane->label_length); | |
910 | |
911 /* | |
912 * Finally refresh each selection if the pane is activated. | |
913 */ | |
914 if (pane->activated) { | |
915 for (s_ptr = s_list->next; s_ptr != s_list; s_ptr = s_ptr->next) | |
916 _XMRefreshSelection(display, menu, s_ptr); | |
917 } | |
918 } | |
919 } | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
920 |
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
921 |
25858 | 922 |
923 | |
924 /* | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
925 * _XMRefreshSelection - Internal subroutine that refreshes |
25858 | 926 * a single selection window. |
927 */ | |
928 _XMRefreshSelection(display, menu, select) | |
929 register Display *display; | |
930 register XMenu *menu; | |
931 register XMSelect *select; | |
932 { | |
933 register int width = select->window_w; | |
934 register int height = select->window_h; | |
935 register int bdr_width = menu->s_bdr_width; | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
936 |
25858 | 937 if (select->type == SEPARATOR) { |
938 XDrawLine(display, | |
939 select->parent_p->window, | |
940 menu->normal_select_GC, | |
941 select->window_x, | |
942 select->window_y + height / 2, | |
943 select->window_x + width, | |
944 select->window_y + height / 2); | |
945 } | |
946 else if (select->activated) { | |
947 if (menu->menu_mode == INVERT) { | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
948 XFillRectangle(display, |
25858 | 949 select->parent_p->window, |
950 menu->normal_select_GC, | |
951 select->window_x, select->window_y, | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
952 width, height); |
25858 | 953 XDrawString(display, |
954 select->parent_p->window, | |
955 menu->inverse_select_GC, | |
956 select->label_x, | |
957 select->label_y, | |
958 select->label, select->label_length); | |
959 } | |
960 else { | |
961 /* | |
962 * Using BOX mode. | |
963 * Since most drawing routines with arbitrary width lines | |
964 * are slow compared to raster-ops lets use a raster-op to | |
965 * draw the boxes. | |
966 */ | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
967 |
25858 | 968 XDrawRectangle(display, |
969 select->parent_p->window, | |
970 menu->normal_select_GC, | |
971 select->window_x + (bdr_width >> 1), | |
972 select->window_y + (bdr_width >> 1 ), | |
973 width - bdr_width, | |
974 height - bdr_width); | |
975 XDrawString(display, | |
976 select->parent_p->window, | |
977 menu->normal_select_GC, | |
978 select->label_x, | |
979 select->label_y, | |
980 select->label, select->label_length); | |
981 } | |
982 } | |
983 else { | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
25858
diff
changeset
|
984 XClearArea(display, |
25858 | 985 select->parent_p->window, |
986 select->window_x, select->window_y, | |
987 width, height, | |
988 False); | |
989 if (select->active) { | |
990 XDrawString(display, | |
991 select->parent_p->window, | |
992 menu->normal_select_GC, | |
993 select->label_x, | |
994 select->label_y, | |
995 select->label, select->label_length); | |
996 } | |
997 else { | |
998 XDrawString(display, | |
999 select->parent_p->window, | |
1000 menu->inact_GC, | |
1001 select->label_x, | |
1002 select->label_y, | |
1003 select->label, select->label_length); | |
1004 } | |
1005 } | |
1006 } | |
1007 | |
52401 | 1008 /* arch-tag: 3ac61957-0852-4e72-8b88-7dfab1a5dee9 |
1009 (do not change this comment) */ |