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