This source file includes following definitions.
- _XMWinQueInit
- _XMWinQueAddPane
- _XMWinQueAddSelection
- _XMWinQueFlush
- _XMGetPanePtr
- _XMGetSelectionPtr
- _XMRecomputeGlobals
- _XMRecomputePane
- _XMRecomputeSelection
- _XMTransToOrigin
- _XMRefreshPane
- _XMRefreshSelection
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 #include "XMenuInt.h"
51
52
53
54
55 #define S_QUE_SIZE 300
56 #define P_QUE_SIZE 20
57
58
59
60
61
62 typedef struct _xmwinquedef {
63 int sq_size;
64 XMSelect *sq[S_QUE_SIZE];
65 XMSelect **sq_ptr;
66 int pq_size;
67 XMPane *pq[P_QUE_SIZE];
68 XMPane **pq_ptr;
69 } XMWinQue;
70
71
72
73
74 static Bool _XMWinQueIsInit = False;
75 static XMWinQue _XMWinQue;
76
77
78
79
80 int _XMErrorCode = XME_NO_ERROR;
81
82
83
84 char const *const
85 _XMErrorList[XME_CODE_COUNT] = {
86 "No error",
87 "Menu not initialized",
88 "Argument out of bounds",
89 "Pane not found",
90 "Selection not found",
91 "Invalid menu style parameter",
92 "Unable to grab mouse",
93 "Unable to interpret locator",
94 "Unable to calloc memory",
95 "Unable to create XAssocTable",
96 "Unable to store bitmap",
97 "Unable to make tile pixmaps",
98 "Unable to make pixmap",
99 "Unable to create cursor",
100 "Unable to open font",
101 "Unable to create windows",
102 "Unable to create transparencies",
103 };
104
105
106
107
108 int (*_XMEventHandler)(XEvent*) = NULL;
109
110
111
112
113
114
115
116 void
117 _XMWinQueInit(void)
118 {
119
120
121
122 if (!_XMWinQueIsInit) {
123
124
125
126 register int i;
127
128 for (i = 0; i < S_QUE_SIZE; i++)
129 _XMWinQue.sq[i] = 0;
130
131 for (i = 0; i < P_QUE_SIZE; i++)
132 _XMWinQue.pq[i] = 0;
133
134 _XMWinQue.sq_size = _XMWinQue.pq_size = 0;
135
136
137
138
139 _XMWinQue.sq_ptr = _XMWinQue.sq;
140 _XMWinQue.pq_ptr = _XMWinQue.pq;
141 }
142 }
143
144
145
146
147
148
149
150 int
151 _XMWinQueAddPane(register Display *display, register XMenu *menu, register XMPane *p_ptr)
152
153
154
155 {
156
157
158
159 if (_XMWinQue.pq_size == P_QUE_SIZE) {
160 if (_XMWinQueFlush(display, menu, 0, 0) == _FAILURE) return(_FAILURE);
161 }
162
163
164
165
166
167 *_XMWinQue.pq_ptr = p_ptr;
168 _XMWinQue.pq_ptr++;
169 _XMWinQue.pq_size++;
170
171
172
173
174 _XMErrorCode = XME_NO_ERROR;
175 return(_SUCCESS);
176 }
177
178
179
180
181
182
183
184 int
185 _XMWinQueAddSelection(register Display *display, register XMenu *menu, register XMSelect *s_ptr)
186
187
188
189 {
190
191
192
193 if (_XMWinQue.sq_size == S_QUE_SIZE) {
194 if (_XMWinQueFlush(display, menu, 0, 0) == _FAILURE) return(_FAILURE);
195 }
196
197
198
199
200
201 *_XMWinQue.sq_ptr = s_ptr;
202 _XMWinQue.sq_ptr++;
203 _XMWinQue.sq_size++;
204
205
206
207
208 _XMErrorCode = XME_NO_ERROR;
209 return(_SUCCESS);
210 }
211
212
213
214
215
216
217
218 int
219 _XMWinQueFlush(register Display *display, register XMenu *menu, register XMPane *pane, XMSelect *sel)
220
221
222
223 {
224 register int pq_index;
225 register int sq_index;
226 register XMPane *p_ptr;
227 register XMSelect *s_ptr;
228 unsigned long valuemask;
229 XSetWindowAttributes attributes_buf;
230 XSetWindowAttributes *attributes = &attributes_buf;
231
232
233
234
235
236 if (_XMWinQue.pq_size > 0) {
237
238
239
240 valuemask = (CWBackPixmap | CWBorderPixel | CWOverrideRedirect);
241 attributes->border_pixel = menu->p_bdr_color;
242 attributes->background_pixmap = menu->inact_pixmap;
243 attributes->override_redirect = True;
244
245
246
247
248
249
250 for (pq_index = _XMWinQue.pq_size - 1;
251 pq_index >= 0;
252 pq_index--)
253 {
254 p_ptr = _XMWinQue.pq[pq_index];
255 if (p_ptr == pane) break;
256 p_ptr->window = XCreateWindow(display,
257 menu->parent,
258 p_ptr->window_x,
259 p_ptr->window_y,
260 p_ptr->window_w,
261 p_ptr->window_h,
262 menu->p_bdr_width,
263 CopyFromParent,
264 InputOutput,
265 CopyFromParent,
266 valuemask,
267 attributes);
268 XMakeAssoc(display, menu->assoc_tab, p_ptr->window, p_ptr);
269 XSelectInput(display, p_ptr->window, menu->p_events);
270 }
271 for (pq_index = 0;
272 pq_index < _XMWinQue.pq_size;
273 pq_index++)
274 {
275 p_ptr = _XMWinQue.pq[pq_index];
276 p_ptr->window = XCreateWindow(display,
277 menu->parent,
278 p_ptr->window_x,
279 p_ptr->window_y,
280 p_ptr->window_w,
281 p_ptr->window_h,
282 menu->p_bdr_width,
283 CopyFromParent,
284 InputOutput,
285 CopyFromParent,
286 valuemask,
287 attributes);
288 XMakeAssoc(display, menu->assoc_tab, p_ptr->window, p_ptr);
289 XSelectInput(display, p_ptr->window, menu->p_events);
290 if (p_ptr == pane) break;
291 }
292
293
294
295
296 _XMWinQue.pq_size = 0;
297 _XMWinQue.pq_ptr = _XMWinQue.pq;
298 }
299
300
301
302
303
304 if (_XMWinQue.sq_size > 0) {
305
306 for (sq_index = 0; sq_index < _XMWinQue.sq_size; sq_index++) {
307
308
309
310 s_ptr = _XMWinQue.sq[sq_index];
311 s_ptr->window = XCreateWindow(display,
312 s_ptr->parent_p->window,
313 s_ptr->window_x,
314 s_ptr->window_y,
315 s_ptr->window_w,
316 s_ptr->window_h,
317 0,
318 CopyFromParent,
319 InputOnly,
320 CopyFromParent,
321 0,
322 attributes);
323
324
325
326
327
328
329 XMakeAssoc(display, menu->assoc_tab, s_ptr->window, s_ptr);
330 XSelectInput(display, s_ptr->window, menu->s_events);
331 }
332
333
334
335
336 _XMWinQue.sq_size = 0;
337 _XMWinQue.sq_ptr = _XMWinQue.sq;
338 }
339
340
341
342
343 XFlush(display);
344
345
346
347
348 _XMErrorCode = XME_NO_ERROR;
349 return(_SUCCESS);
350 }
351
352
353
354
355
356
357
358 XMPane *
359 _XMGetPanePtr(register XMenu *menu, register int p_num)
360
361
362 {
363 register XMPane *p_ptr;
364 register int i;
365
366
367
368
369 if ((p_num < 0) || (p_num > (menu->p_count - 1))) {
370 _XMErrorCode = XME_P_NOT_FOUND;
371 return(NULL);
372 }
373
374
375
376
377 p_ptr = menu->p_list->next;
378 for (i = 0; i < p_num; i++) p_ptr = p_ptr->next;
379
380
381
382
383 _XMErrorCode = XME_NO_ERROR;
384 return(p_ptr);
385 }
386
387
388
389
390
391
392
393
394 XMSelect *
395 _XMGetSelectionPtr(register XMPane *p_ptr, register int s_num)
396
397
398 {
399 register XMSelect *s_ptr;
400 register int i;
401
402
403
404
405 if ((s_num < 0) || (s_num > (p_ptr->s_count - 1))) {
406 _XMErrorCode = XME_S_NOT_FOUND;
407 return(NULL);
408 }
409
410
411
412
413 s_ptr = p_ptr->s_list->next;
414 for (i = 0; i < s_num; i++) s_ptr = s_ptr->next;
415
416
417
418
419 _XMErrorCode = XME_NO_ERROR;
420 return(s_ptr);
421 }
422
423
424
425
426
427
428
429 void
430 _XMRecomputeGlobals(register Display *display, register XMenu *menu)
431
432
433 {
434 register XMPane *p_ptr;
435 register XMSelect *s_ptr;
436
437 register int max_p_label = 0;
438 register int max_s_label = 0;
439 register int s_count = 0;
440
441 int p_s_pad;
442 int p_s_diff;
443
444 int p_height;
445 int p_width;
446 int s_width;
447
448 int screen;
449
450
451
452
453 for (
454 p_ptr = menu->p_list->next;
455 p_ptr != menu->p_list;
456 p_ptr = p_ptr->next
457 ){
458
459
460
461
462 max_p_label = max(max_p_label, p_ptr->label_width);
463
464
465
466
467 s_count = max(s_count, p_ptr->s_count);
468
469
470
471
472 for (
473 s_ptr = p_ptr->s_list->next;
474 s_ptr != p_ptr->s_list;
475 s_ptr = s_ptr->next
476 ){
477
478
479
480
481 max_s_label = max(max_s_label, s_ptr->label_width);
482 }
483 }
484
485
486
487
488 p_height = (menu->flag_height << 1) + (menu->s_y_off * s_count);
489
490
491
492
493
494 p_s_pad = menu->p_x_off << 1;
495
496
497
498
499
500
501
502
503
504
505
506
507
508 p_width = max_p_label + p_s_pad;
509 s_width = max_s_label + (menu->s_fnt_pad << 1) + (menu->s_bdr_width << 1);
510 p_s_diff = p_width - s_width;
511 if (p_s_diff < p_s_pad) {
512 p_width = s_width + p_s_pad;
513 }
514 else if (p_s_diff > p_s_pad) {
515 s_width = p_width - p_s_pad;
516 }
517
518
519
520
521 menu->s_count = s_count;
522 menu->p_height = p_height;
523 menu->p_width = p_width;
524 menu->s_width = s_width;
525
526
527
528
529
530 screen = DefaultScreen(display);
531 if (menu->x_pos + menu->width > DisplayWidth(display, screen))
532 menu->x_pos = DisplayWidth(display, screen) - menu->width;
533 else if (menu->x_pos < 0) menu->x_pos = 0;
534 if(menu->y_pos + menu->height > DisplayHeight(display, screen))
535 menu->y_pos = DisplayHeight(display, screen) - menu->height;
536 else if (menu->y_pos < 0) menu->y_pos = 0;
537 }
538
539
540
541
542
543
544 int
545 _XMRecomputePane(register Display *display, register XMenu *menu, register XMPane *p_ptr, register int p_num)
546
547
548
549
550 {
551 register int window_x;
552 register int window_y;
553
554 unsigned long change_mask;
555
556 register Bool config_p = False;
557
558
559
560
561 p_ptr->serial = p_num;
562
563
564
565
566 switch (menu->menu_style) {
567 case LEFT:
568 window_x = menu->p_x_off * ((menu->p_count - 1) - p_num);
569 window_y = menu->p_y_off * ((menu->p_count - 1) - p_num);
570 break;
571 case RIGHT:
572 window_x = menu->p_x_off * p_num;
573 window_y = menu->p_y_off * ((menu->p_count - 1) - p_num);
574 break;
575 case CENTER:
576 window_x = 0;
577 window_y = menu->p_y_off * ((menu->p_count - 1) - p_num);
578 break;
579 default:
580
581 _XMErrorCode = XME_STYLE_PARAM;
582 return(_FAILURE);
583 }
584 window_x += menu->x_pos;
585 window_y += menu->y_pos;
586
587
588
589
590
591
592 if (
593 (window_x != p_ptr->window_x) ||
594 (window_y != p_ptr->window_y)
595 ){
596
597
598
599
600 p_ptr->window_x = window_x;
601 p_ptr->window_y = window_y;
602 config_p = True;
603 }
604
605
606
607
608
609 if (
610 (p_ptr->window_w != menu->p_width) ||
611 (p_ptr->window_h != menu->p_height)
612 ){
613
614
615
616
617 p_ptr->window_w = menu->p_width;
618 p_ptr->window_h = menu->p_height;
619 config_p = True;
620 }
621
622
623
624
625 if (config_p == True) {
626
627
628
629
630
631 if (p_ptr->window) {
632 XWindowChanges changes;
633 change_mask = (CWX | CWY | CWWidth | CWHeight);
634 changes.x = p_ptr->window_x;
635 changes.y = p_ptr->window_y;
636 changes.width = p_ptr->window_w;
637 changes.height = p_ptr->window_h;
638
639 XConfigureWindow(
640 display,
641 p_ptr->window,
642 change_mask,
643 &changes
644 );
645 }
646 else {
647 if (_XMWinQueAddPane(display, menu, p_ptr) == _FAILURE) {
648 return(_FAILURE);
649 }
650 }
651 }
652
653
654
655
656 switch (menu->p_style) {
657 case LEFT:
658 p_ptr->label_x = menu->p_x_off + menu->p_fnt_pad;
659 break;
660 case RIGHT:
661 p_ptr->label_x = menu->p_width -
662 (p_ptr->label_width + menu->p_x_off + menu->p_fnt_pad);
663 break;
664 case CENTER:
665 p_ptr->label_x = (menu->p_width - p_ptr->label_width) >> 1;
666 break;
667 default:
668
669 _XMErrorCode = XME_STYLE_PARAM;
670 return(_FAILURE);
671 }
672
673
674
675 p_ptr->label_uy = menu->p_fnt_pad + menu->p_fnt_info->max_bounds.ascent;
676 p_ptr->label_ly = (menu->p_height - menu->p_fnt_pad - menu->p_fnt_info->max_bounds.descent);
677
678
679
680
681 _XMErrorCode = XME_NO_ERROR;
682 return(_SUCCESS);
683 }
684
685
686
687
688
689
690
691 int
692 _XMRecomputeSelection(register Display *display, register XMenu *menu, register XMSelect *s_ptr, register int s_num)
693
694
695
696
697 {
698 register Bool config_s = False;
699 unsigned long change_mask;
700
701
702
703
704
705
706
707
708
709
710 if (s_ptr->serial != s_num) {
711
712
713
714 s_ptr->serial = s_num;
715
716
717
718 s_ptr->window_x = menu->s_x_off;
719 s_ptr->window_y = menu->flag_height + (menu->s_y_off * s_num);
720
721
722
723 config_s = True;
724 }
725
726
727
728
729
730 if (
731 (s_ptr->window_w != menu->s_width) ||
732 (s_ptr->window_h != menu->s_height)
733 ){
734
735
736
737 config_s = True;
738
739
740
741 s_ptr->window_w = menu->s_width;
742 s_ptr->window_h = menu->s_height;
743 }
744
745
746
747
748 if (config_s == True) {
749
750
751
752
753
754 if (s_ptr->window) {
755 XWindowChanges changes;
756 change_mask = (CWX | CWY | CWWidth | CWHeight);
757 changes.x = s_ptr->window_x;
758 changes.y = s_ptr->window_y;
759 changes.width = s_ptr->window_w;
760 changes.height = s_ptr->window_h;
761
762 XConfigureWindow(
763 display,
764 s_ptr->window,
765 change_mask,
766 &changes
767 );
768 }
769 else {
770 if (_XMWinQueAddSelection(display, menu, s_ptr) == _FAILURE) {
771 return(_FAILURE);
772 }
773 }
774 }
775
776
777
778
779 switch (menu->s_style) {
780 case LEFT:
781 s_ptr->label_x = menu->s_bdr_width + menu->s_fnt_pad + s_ptr->window_x;
782 break;
783 case RIGHT:
784 s_ptr->label_x = s_ptr->window_x + menu->s_width -
785 (s_ptr->label_width + menu->s_bdr_width + menu->s_fnt_pad);
786 break;
787 case CENTER:
788 s_ptr->label_x = s_ptr->window_x + ((menu->s_width - s_ptr->label_width) >> 1);
789 break;
790 default:
791
792 _XMErrorCode = XME_STYLE_PARAM;
793 return(_FAILURE);
794 }
795
796
797
798 s_ptr->label_y = s_ptr->window_y + menu->s_fnt_info->max_bounds.ascent + menu->s_fnt_pad + menu->s_bdr_width;
799
800
801
802
803 _XMErrorCode = XME_NO_ERROR;
804 return(_SUCCESS);
805 }
806
807
808
809
810
811
812
813
814
815
816
817
818 void
819 _XMTransToOrigin(Display *display, register XMenu *menu, register XMPane *p_ptr, register XMSelect *s_ptr, int x_pos, int y_pos, int *orig_x, int *orig_y)
820
821
822
823
824
825
826
827
828 {
829 register int l_orig_x;
830 register int l_orig_y;
831
832
833
834
835
836
837
838
839 if (s_ptr == NULL) {
840
841
842
843
844 l_orig_x = x_pos - (menu->p_width >> 1) - menu->p_bdr_width;
845 l_orig_y = y_pos - (menu->flag_height >> 1) - menu->p_bdr_width;
846 }
847 else {
848
849
850
851
852 l_orig_x = x_pos - (menu->s_width >> 1);
853 l_orig_y = y_pos - (menu->s_height >> 1);
854
855
856
857
858 l_orig_x -= (s_ptr->window_x + menu->p_bdr_width);
859 l_orig_y -= (s_ptr->window_y + menu->p_bdr_width);
860 }
861
862
863
864
865 l_orig_x -= (p_ptr->window_x - menu->x_pos);
866 l_orig_y -= (p_ptr->window_y - menu->y_pos);
867
868
869
870
871 *orig_x = l_orig_x;
872 *orig_y = l_orig_y;
873 }
874
875
876
877
878
879 void
880 _XMRefreshPane(register Display *display, register XMenu *menu, register XMPane *pane)
881 {
882 register XMSelect *s_list = pane->s_list;
883 register XMSelect *s_ptr;
884
885
886
887
888 XClearWindow(display, pane->window);
889 if (!pane->activated) {
890 XFillRectangle(display,
891 pane->window,
892 menu->inverse_select_GC,
893 pane->label_x - menu->p_fnt_pad,
894 pane->label_uy - menu->p_fnt_info->max_bounds.ascent - menu->p_fnt_pad,
895 pane->label_width + (menu->p_fnt_pad << 1),
896 menu->flag_height);
897
898 XFillRectangle(display,
899 pane->window,
900 menu->inverse_select_GC,
901 pane->label_x - menu->p_fnt_pad,
902 pane->label_ly - menu->p_fnt_info->max_bounds.ascent - menu->p_fnt_pad,
903 pane->label_width + (menu->p_fnt_pad << 1),
904 menu->flag_height);
905 }
906 if (!pane->active) {
907 XDrawString(display,
908 pane->window,
909 menu->inact_GC,
910 pane->label_x, pane->label_uy,
911 pane->label, pane->label_length);
912 XDrawString(display,
913 pane->window,
914 menu->inact_GC,
915 pane->label_x, pane->label_ly,
916 pane->label, pane->label_length);
917 }
918 else {
919 XDrawString(display,
920 pane->window,
921 menu->pane_GC,
922 pane->label_x, pane->label_uy,
923 pane->label, pane->label_length);
924 XDrawString(display,
925 pane->window,
926 menu->pane_GC,
927 pane->label_x, pane->label_ly,
928 pane->label, pane->label_length);
929
930
931
932
933 if (pane->activated) {
934 for (s_ptr = s_list->next; s_ptr != s_list; s_ptr = s_ptr->next)
935 _XMRefreshSelection(display, menu, s_ptr);
936 }
937 }
938 }
939
940
941
942
943
944
945
946
947 void
948 _XMRefreshSelection(register Display *display, register XMenu *menu, register XMSelect *sel)
949 {
950 register int width = sel->window_w;
951 register int height = sel->window_h;
952 register int bdr_width = menu->s_bdr_width;
953
954 if (sel->type == SEPARATOR) {
955 XDrawLine(display,
956 sel->parent_p->window,
957 menu->normal_select_GC,
958 sel->window_x,
959 sel->window_y + height / 2,
960 sel->window_x + width,
961 sel->window_y + height / 2);
962 }
963 else if (sel->activated) {
964 if (menu->menu_mode == INVERT) {
965 XFillRectangle(display,
966 sel->parent_p->window,
967 menu->normal_select_GC,
968 sel->window_x, sel->window_y,
969 width, height);
970 XDrawString(display,
971 sel->parent_p->window,
972 menu->inverse_select_GC,
973 sel->label_x,
974 sel->label_y,
975 sel->label, sel->label_length);
976 }
977 else {
978
979
980
981
982
983
984
985 XDrawRectangle(display,
986 sel->parent_p->window,
987 menu->normal_select_GC,
988 sel->window_x + (bdr_width >> 1),
989 sel->window_y + (bdr_width >> 1 ),
990 width - bdr_width,
991 height - bdr_width);
992 XDrawString(display,
993 sel->parent_p->window,
994 menu->normal_select_GC,
995 sel->label_x,
996 sel->label_y,
997 sel->label, sel->label_length);
998 }
999 }
1000 else {
1001 XClearArea(display,
1002 sel->parent_p->window,
1003 sel->window_x, sel->window_y,
1004 width, height,
1005 False);
1006 if (sel->active) {
1007 XDrawString(display,
1008 sel->parent_p->window,
1009 menu->normal_select_GC,
1010 sel->label_x,
1011 sel->label_y,
1012 sel->label, sel->label_length);
1013 }
1014 else {
1015 XDrawString(display,
1016 sel->parent_p->window,
1017 menu->inact_GC,
1018 sel->label_x,
1019 sel->label_y,
1020 sel->label, sel->label_length);
1021 }
1022 }
1023 }