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