1 /*
2 * Motif
3 *
4 * Copyright (c) 1987-2012, The Open Group. All rights reserved.
5 *
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
10 * any later version.
11 *
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
16 * details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
22 */
23 /*
24 * HISTORY
25 */
26 #ifdef REV_INFO
27 #ifndef lint
28 static char rcsid[] = "$TOG: wsmStruct.c /main/7 1997/05/02 10:04:46 dbl $"
29 #endif
30 #endif
31 #include <stdio.h>
32 #include <Xm/Xm.h>
33 #include <Xm/AtomMgr.h>
34
35
36 #include "wsm.h"
37 #include "wsmData.h"
38 #include "wsmStruct.h"
39 #include "wsm_cb.h"
40 #include "wsmDebug.h"
41 #include "xrmLib.h"
42 #include "command_ui.h"
43
44
45 extern AtomStruct atoms;
46 extern Space *space_list;
47 extern Space *all_space;
48 extern Space *current_space;
49 extern WorkWindow *work_windows;
50 extern XrmQuark *space_qlist;
51 extern XrmQuark *window_attribq;
52 extern XrmQuark *icon_attribq;
53 extern XrmQuark *global_attribq;
54 extern WSMAttribute *window_attrib_list;
55 extern WSMAttribute *icon_attrib_list;
56 extern WSMAttribute *global_attrib_list;
57 extern int num_window_attrib;
58 extern int num_icon_attrib;
59 extern int num_global_attrib;
60 extern Boolean diffs_allowed;
61 extern Widget shell;
62 extern Display *dsp;
63 extern Boolean connected;
64
65 static char* GetWMName(
66 Window, Boolean
67 );
68 static char* GetWMClient(
69 Window, Boolean
70 );
71 static char* GetWMRole(
72 Window, Boolean
73 );
74 static char* GetWMCount(
75 XrmQuark,XrmQuark
76 );
77 XrmQuarkList GetSpecifierQList(
78 Window, Boolean
79 );
80
81 void AddWindowToSpace(
82 Space*,WorkWindow*
83 );
84
85 char *Get_SM_CLIENT_ID(
86 Display*, Window
87 );
88
89 char *Get_WM_WINDOW_ROLE(
90 Display*, Window
91 );
92
93 Colormap default_cmap = 0;
94
95
96 /**********************************************************************/
97 /* INTERNAL STRUCTURE CODE */
98 /**********************************************************************/
99
100
101
102 /*------------------------------------------------------------------
103 CreateSpace
104
105 ------------------------------------------------------------------*/
106 Space*
CreateSpace(XrmQuark name,char * str)107 CreateSpace(XrmQuark name, char *str)
108 {
109 WorkWindowList *w_list;
110 Space *s, *s2;
111 s = (Space*)XtMalloc(sizeof(Space));
112 s->nameq = name;
113 s->w_list = NULL;
114 if (all_space->w_list != NULL)
115 {
116 w_list = all_space->w_list;
117 while (w_list != NULL)
118 {
119 AddWindowToSpace(s,w_list->work_win);
120 w_list = w_list->next;
121 }
122 }
123 s->next = NULL;
124 strcpy(s->name, str);
125 strcpy(s->background,"None");
126 strcpy(s->pixmap_name,"None");
127 s->pixel = 0;
128 s->pixmap = None;
129 s->pixmap_label = None;
130 if (space_list == NULL)
131 {
132 current_space = s;
133 space_list = s;
134 }
135 else
136 {
137 s2 = space_list;
138 while (s2->next != NULL)
139 s2 = s2->next;
140 s2->next = s;
141 }
142 return s;
143 }
144
145 /*------------------------------------------------------------------
146 SetSpacePixel
147
148 ------------------------------------------------------------------*/
149 Boolean
SetSpacePixel(Space * s,char * name)150 SetSpacePixel(Space *s, char *name)
151 {
152 Boolean retval = True;
153 XColor a_color;
154 XColor def_color;
155
156 if (default_cmap == 0)
157 default_cmap = DefaultColormap(dsp,0);
158 if (XAllocNamedColor(dsp,default_cmap,name,&a_color, &def_color)==0)
159 return False;
160 s->pixel = a_color.pixel;
161 strcpy(s->background,name);
162 s->pixmap = None;
163 return retval;
164 }
165
166
167
168
169
170 /*------------------------------------------------------------------
171 SpacePixelSet
172
173 ------------------------------------------------------------------*/
174 Boolean
SpacePixelSet(Space * s)175 SpacePixelSet(Space *s)
176 {
177 if (strcmp("None",s->background) == 0)
178 return False;
179 if (s->pixmap != None)
180 return False;
181 else return True;
182 }
183
184
185
186 /*------------------------------------------------------------------
187 SetSpacePixmap
188
189 ------------------------------------------------------------------*/
190 Boolean
SetSpacePixmap(Space * s,char * name)191 SetSpacePixmap(Space *s, char *name)
192 {
193 unsigned int width, height;
194 Window root = XRootWindowOfScreen(XtScreen(shell));
195
196 s -> pixmap = XmGetPixmapByDepth(XtScreen(shell), name,
197 BlackPixel(XtDisplay(shell), 0),
198 WhitePixel(XtDisplay(shell), 0),
199 DefaultDepth(dsp, 0));
200 if (s -> pixmap == XmUNSPECIFIED_PIXMAP)
201 {
202 fprintf(stderr, "can't get pixmap for %s\n", name);
203 return False;
204 }
205
206 s->background[0] = '"';
207 s->background[1] = '\0';
208 strcat(s->background,name);
209 PRINT("s->background is %s\n",name);
210 return True;
211 }
212
213
214
215 /*------------------------------------------------------------------
216 SpacePixmapSet
217
218 ------------------------------------------------------------------*/
219 Boolean
SpacePixmapSet(Space * s)220 SpacePixmapSet(Space *s)
221 {
222 if (strcmp("None",s->background) == 0)
223 return False;
224 if (s->pixmap == None)
225 return False;
226 else return True;
227 }
228
229
230
231
232 /*------------------------------------------------------------------
233 SetSpaceLabelPixmap
234
235 ------------------------------------------------------------------*/
236 Boolean
SetSpaceLabelPixmap(Space * s,char * name)237 SetSpaceLabelPixmap(Space *s, char *name)
238 {
239 unsigned int width, height;
240 Pixmap bitmap;
241 int status;
242 GC gc;
243 XGCValues values;
244 Window root = XRootWindowOfScreen(XtScreen(shell));
245
246 PRINT("setting space %s label pixmap to %s\n", s->name,name);
247 if (strcmp(name,"None") == 0 || strcmp(name,"none")== 0)
248 return False;
249 status = XReadBitmapFile(dsp,root,name,&width,&height,&bitmap,
250 (int *)NULL, (int *)NULL);
251
252 if (status == BitmapOpenFailed)
253 {
254 fprintf(stderr, "can't open file %s\n", name);
255 return False;
256 }
257 else if (status == BitmapFileInvalid)
258 {
259 fprintf(stderr, "bad bitmap format file: %s\n", name);
260 return False;
261 }
262 else if (status == BitmapNoMemory)
263 {
264 fprintf(stderr, "insufficient memory for bitmap file: %s\n", name);
265 return False;
266 }
267 values.foreground = BlackPixel(XtDisplay(shell),0);
268 values.background = WhitePixel(XtDisplay(shell),0);
269 gc = XCreateGC(dsp,root,GCForeground|GCBackground,&values);
270 if (s->pixmap_label != None) XFreePixmap(dsp,s->pixmap_label);
271 s->pixmap_label = XCreatePixmap(dsp,root,width,height,
272 (unsigned int)DefaultDepth(dsp,0));
273 XCopyPlane(dsp,bitmap,s->pixmap_label,gc,0,0,width,height,0,0,
274 (unsigned long)1);
275 /* s->pixmap = XCreatePixmapFromBitmapData(dsp,root,name,width,height,
276 BlackPixel(XtDisplay(shell),0),
277 WhitePixel(XtDisplay(shell),0),
278 (unsigned int)
279 DefaultDepth(dsp,
280 DefaultScreen(dsp)));*/
281 strcpy(s->pixmap_name,name);
282 PRINT("s->pixmap_name is %s\n",name);
283 XFreeGC(dsp, gc);
284 return True;
285 }
286
287
288
289 /*------------------------------------------------------------------
290 SpaceLabelPixmapSet
291
292 ------------------------------------------------------------------*/
293 Boolean
SpaceLabelPixmapSet(Space * s)294 SpaceLabelPixmapSet(Space *s)
295 {
296 if (s->pixmap_label == None)
297 return False;
298 else return True;
299 }
300
301
302
303
304 /*------------------------------------------------------------------
305 CreateInternalStructure
306
307 ------------------------------------------------------------------*/
308 Boolean
CreateInternalStructure(WorkWindow * w_window,XrmQuark * rooms_qlist)309 CreateInternalStructure(WorkWindow *w_window,XrmQuark *rooms_qlist)
310 {
311 Space *space;
312 int j;
313 Boolean in_current_space = False;
314 if (w_window->all_workspaces)
315 {
316 /* create internal structures */
317 for (j=0, space = space_list; space !=NULL; space = space->next, j++)
318 {
319 if (space == current_space)
320 in_current_space = True;
321 AddSpaceToWindow(space, w_window);
322 AddWindowToSpace(space, w_window);
323 }
324 }
325 else if (rooms_qlist == NULL)
326 {
327 AddSpaceToWindow(current_space,w_window);
328 AddWindowToSpace(current_space,w_window);
329 in_current_space = True;
330 }
331 else
332 {
333 /* create internal structures */
334 for (j=0; rooms_qlist[j] != NULLQUARK; j++)
335 {
336 space = GetSpace(rooms_qlist[j]);
337 if (space == NULL)
338 space = CreateSpace(rooms_qlist[j], XrmQuarkToString(rooms_qlist[j]));
339 if (space == current_space)
340 in_current_space = True;
341 AddSpaceToWindow(space, w_window);
342 AddWindowToSpace(space, w_window);
343 }
344 }
345
346 if (w_window->all_workspaces)
347 AddWindowToSpace(all_space,w_window);
348 return in_current_space;
349 }
350
351 /*------------------------------------------------------------------
352 CreateWorkWindow
353
354 ------------------------------------------------------------------*/
355 WorkWindow*
CreateWorkWindow(Window window)356 CreateWorkWindow(Window window)
357 {
358 WorkWindow *w, *w2;
359 int i;
360
361 w = GetWorkWindow(window);
362
363 /* if wsm already knows about this window then just
364 set mapped = True and return the window */
365 if (w != NULL)
366 {
367 w->mapped = True;
368 return w;
369 }
370
371 w = (WorkWindow *)XtMalloc(sizeof(WorkWindow));
372 w->window = window;
373 w->used = True;
374
375 switch (_WSMGetConfigFormatType(window))
376 {
377 case WSM_GLOBAL_FMT:
378 w->attrib_qlist = global_attribq;
379 w->attrib_list = global_attrib_list;
380 w->num_attrib_list = num_global_attrib;
381 w->all_workspaces = True;
382 w->specifier_qlist = GetSpecifierQList(0,False);
383 w->name = GetWMName(0,False);
384 break;
385
386 case WSM_WINDOW_FMT:
387 w->attrib_qlist = window_attribq;
388 w->attrib_list = window_attrib_list;
389 w->num_attrib_list = num_window_attrib;
390 w->all_workspaces = False;
391 w->specifier_qlist = GetSpecifierQList(window,False);
392 w->name = GetWMName(window,False);
393 break;
394
395 case WSM_ICON_FMT:
396 w->attrib_qlist = icon_attribq;
397 w->attrib_list = icon_attrib_list;
398 w->num_attrib_list = num_icon_attrib;
399 w->all_workspaces = True;
400 w->specifier_qlist = GetSpecifierQList(window, True);
401 w->name = GetWMName(window,True);
402 break;
403
404 default:
405 break;
406 }
407
408 w->next = NULL;
409 w->prev = NULL;
410 w->last_space = NULL;
411 w->s_list = NULL;
412 w->linked = False;
413 w->mapped = True;
414 w->win_data = (WSMWinData*)XtMalloc(w->num_attrib_list*sizeof(WSMWinData));
415 for (i = 0; i < w->num_attrib_list; i++)
416 {
417 w->win_data[i].nameq = w->attrib_qlist[i];
418 w->win_data[i].type = WSM_NONE;
419 w->win_data[i].data.value = -1;
420 }
421 if (work_windows == NULL)
422 work_windows = w;
423 else
424 {
425 w2 = work_windows;
426 while (w2->next != NULL)
427 w2 = w2->next;
428 w2->next = w;
429 w->prev = w2;
430 }
431
432 if (w->all_workspaces)
433 {
434 CreateInternalStructure(w,NULL);
435 UpdateBothList(all_space);
436 }
437
438 if (_WSMGetConfigFormatType(window) == WSM_WINDOW_FMT)
439 {
440 PRINT("XSelectInput ");
441 print_window(w);
442 XSelectInput(dsp,window,StructureNotifyMask);
443 }
444
445 return w;
446 }
447
448
449
450 /*------------------------------------------------------------------
451 ReCreateWorkWindow
452
453 ------------------------------------------------------------------*/
454 WorkWindow*
ReCreateWorkWindow(Window window)455 ReCreateWorkWindow(Window window)
456 {
457 WorkWindow *w;
458 int i;
459
460 w = GetWorkWindow(window);
461
462 if (w == NULL)
463 return CreateWorkWindow(window);
464
465 switch (_WSMGetConfigFormatType(window))
466 {
467 case WSM_GLOBAL_FMT:
468 w->attrib_qlist = global_attribq;
469 w->attrib_list = global_attrib_list;
470 w->num_attrib_list = num_global_attrib;
471 break;
472
473 case WSM_WINDOW_FMT:
474 w->attrib_qlist = window_attribq;
475 w->attrib_list = window_attrib_list;
476 w->num_attrib_list = num_window_attrib;
477 break;
478
479 case WSM_ICON_FMT:
480 w->attrib_qlist = icon_attribq;
481 w->attrib_list = icon_attrib_list;
482 w->num_attrib_list = num_icon_attrib;
483 break;
484
485 default:
486 break;
487 }
488
489 XtFree((XtPointer)w->win_data);
490 w->win_data = (WSMWinData*)XtMalloc(w->num_attrib_list*sizeof(WSMWinData));
491 for (i = 0; i < w->num_attrib_list; i++)
492 {
493 w->win_data[i].nameq = w->attrib_qlist[i];
494 w->win_data[i].type = WSM_NONE;
495 w->win_data[i].data.value = -1;
496 }
497
498 return w;
499 }
500
501
502
503 /*------------------------------------------------------------------
504 GetSpace
505
506 ------------------------------------------------------------------*/
507 Space*
GetSpace(XrmQuark name)508 GetSpace(XrmQuark name)
509 {
510 Space *s;
511 s = space_list;
512 while (s != NULL)
513 {
514 if (s->nameq == name)
515 return s;
516 s = s->next;
517 }
518 PRINT("returning NULL space\n");
519 return NULL;
520 }
521
522
523
524 /*------------------------------------------------------------------
525 GetSpaceFromName
526
527 ------------------------------------------------------------------*/
528 Space*
GetSpaceFromName(char * name)529 GetSpaceFromName(char *name)
530 {
531 Space *s;
532 s = space_list;
533 while (s != NULL)
534 {
535 if (strcmp(s->name,name)== 0)
536 return s;
537 s = s->next;
538 }
539 PRINT("returning NULL space\n");
540 return NULL;
541 }
542
543
544
545
546 /*------------------------------------------------------------------
547 GetNumberSpaces
548
549 ------------------------------------------------------------------*/
550 int
GetNumberSpaces()551 GetNumberSpaces()
552 {
553 Space *s;
554 int i;
555
556 for (i = 0, s = space_list; s != NULL; s = s->next, i++);
557 return i;
558 }
559
560
561 /*------------------------------------------------------------------
562 GetWorkWindowID
563
564 ------------------------------------------------------------------*/
565 WorkWindow*
GetWorkWindowID(Space * s,int wsm_index)566 GetWorkWindowID(Space *s,int wsm_index)
567 {
568 int j =0;
569 WorkWindowList *w_list = s->w_list;
570
571 while (w_list != NULL)
572 {
573 if (_WSMGetConfigFormatType(w_list->work_win->window) == WSM_WINDOW_FMT)
574 {
575 if (j == wsm_index)
576 return w_list->work_win;
577 j++;
578 }
579 w_list = w_list->next;
580 }
581 return NULL;
582 }
583
584
585
586
587 /*------------------------------------------------------------------
588 GetSpaceFromID
589
590 ------------------------------------------------------------------*/
591 Space*
GetSpaceFromID(int wsm_index)592 GetSpaceFromID(int wsm_index)
593 {
594 int j;
595 Space *s;
596 s = space_list;
597 if (s == NULL) return NULL;
598
599 for (j = 0; j < wsm_index; j++)
600 {
601 if (s == NULL)
602 return NULL;
603 s = s->next;
604 }
605 return s;
606 }
607
608
609
610
611
612 /*------------------------------------------------------------------
613 GetSpaceID
614
615 ------------------------------------------------------------------*/
616 int
GetSpaceID(Space * space)617 GetSpaceID(Space *space)
618 {
619 int j;
620 Space *s;
621
622 for (j = 0, s = space_list; s != NULL; s = s->next, j++)
623 {
624 if (s == space)
625 return j;
626 }
627 return -1;
628 }
629
630
631
632
633 /*------------------------------------------------------------------
634 GetWorkWindow
635
636 ------------------------------------------------------------------*/
637 WorkWindow*
GetWorkWindow(Window window)638 GetWorkWindow(Window window)
639 {
640 WorkWindow *w;
641 w = work_windows;
642 while (w != NULL)
643 {
644 if (w->window == window)
645 return w;
646 w = w->next;
647 }
648 return NULL;
649 }
650
651
652
653
654
655
656 /*------------------------------------------------------------------
657 GetWorkWindowClient
658
659 ------------------------------------------------------------------*/
660 /*
661 Boolean
662 #ifndef _NO_PROTO
663 GetWorkWindowClient(Window window, WorkWindow*** w_windows, int *num_w_windows)
664 #else
665 GetWorkWindowClient(window)
666 Window window;
667 WorkWindow ***w_windows;
668 int *num_w_windows;
669 #endif
670 {
671 WorkWindow *w, *i_window;
672 int num_w = 0;
673 WorkWindow **w_wins;
674 Boolean found = False;
675
676 w = work_windows;
677 while (w != NULL)
678 {
679 if (w->window == window)
680 {
681 main_w = w;
682 found = True;
683 break;
684 }
685 w = w->next;
686 }
687
688 if (!found) return False;
689
690 i_window = GetIconWorkWindow(win);
691
692 if (i_window == NULL)
693 w_wins = (WorkWindow*) XtMalloc(sizeof(WorkWindow*));
694 else
695 w_wins = (WorkWindow*) XtMalloc(2*sizeof(WorkWindow*));
696
697 w_wins[num_w++] = main_w;
698 if (i_window != NULL)
699 w_wins[num_w++] = i_window;
700
701 client_id = main_w->specifier_qlist[0];
702 count = main_w->specifier_qlist[2];
703
704 w = work_windows;
705 while (w != NULL)
706 {
707 if (w->specifier_qlist[0] == client_id && w->specifier_qlist[2] == count)
708 {
709 w_wins = (WorkWidnow*) XtRealloc(w_wins,(num_w+1) * sizeof(WorkWindow*));
710 w_wins[num_w] = w;
711 num_w++;
712 }
713 }
714
715 *w_windows = w_wins;
716 *num_w_windows = num_w;
717 return True;
718 }
719 */
720
721
722
723
724
725 /*------------------------------------------------------------------
726 GetWorkWindowClientIDs
727
728 ------------------------------------------------------------------*/
729
730 Boolean
GetWorkWindowClientIDs(int main_pos,Space * s,int ** w_ids,int * num_wids)731 GetWorkWindowClientIDs(int main_pos, Space *s, int **w_ids, int *num_wids)
732 {
733 WorkWindowList *w_list;
734 int num_w = 0;
735 int *wids;
736 Boolean found = False;
737 int pos;
738 WorkWindow *main_w;
739 XrmQuark client_id, count;
740
741 w_list = s->w_list;
742 pos = 0;
743 while (w_list != NULL)
744 {
745 if (_WSMGetConfigFormatType(w_list->work_win->window) == WSM_WINDOW_FMT)
746 {
747 if (pos == main_pos)
748 {
749 main_w = w_list->work_win;
750 found = True;
751 break;
752 }
753 pos++;
754 }
755 w_list = w_list->next;
756 }
757
758 if (!found) return False;
759
760 wids = (int*) XtMalloc(sizeof(int));
761
762 wids[num_w++] = main_pos;
763
764 client_id = main_w->specifier_qlist[0];
765 count = main_w->specifier_qlist[2];
766
767 w_list = s->w_list;
768 pos = 0;
769 while (w_list != NULL)
770 {
771 if (_WSMGetConfigFormatType(w_list->work_win->window) == WSM_WINDOW_FMT)
772 {
773 if (w_list->work_win->specifier_qlist[0] == client_id
774 && w_list->work_win->specifier_qlist[2] == count
775 && w_list->work_win != main_w)
776 {
777 wids = (int*) XtRealloc((char*)wids,(num_w+1) * sizeof(int));
778 wids[num_w] = pos;
779 num_w++;
780 }
781 pos++;
782 }
783 w_list = w_list->next;
784 }
785
786 *w_ids = wids;
787 *num_wids = num_w;
788
789 return True;
790 }
791
792
793
794
795 /*------------------------------------------------------------------
796 GetIconWorkWindow
797
798 ------------------------------------------------------------------*/
799 WorkWindow*
GetIconWorkWindow(Window window)800 GetIconWorkWindow(Window window)
801 {
802 WorkWindow *w;
803 w = work_windows;
804 while (w != NULL)
805 {
806 if (w->window == (window | ~WIN_MASK))
807 return w;
808 w = w->next;
809 }
810 PRINT("returning NULL icon window\n");
811 return NULL;
812 }
813
814
815 /*------------------------------------------------------------------
816 AddSpaceToWindow
817
818 ------------------------------------------------------------------*/
819 void
AddSpaceToWindow(Space * s,WorkWindow * w_window)820 AddSpaceToWindow(Space *s,
821 WorkWindow *w_window)
822 {
823 SpaceList *s_list, *s_list2;
824
825 s_list = (SpaceList*)XtMalloc(sizeof(SpaceList));
826 s_list->next = NULL;
827 s_list->space = s;
828 if (w_window->s_list == NULL)
829 {
830 w_window->s_list = s_list;
831 }
832 else
833 {
834 s_list2 = w_window->s_list;
835 if (s_list2->space == s)
836 {
837 XtFree((char*)s_list);
838 return;
839 }
840 while (s_list2->next != NULL)
841 {
842 s_list2 = s_list2->next;
843 if (s_list2->space == s)
844 {
845 XtFree((char*)s_list);
846 return;
847 }
848 }
849 s_list2->next = s_list;
850 }
851
852 if ((w_window->s_list != NULL) && (w_window->s_list->next != NULL) &&
853 (w_window->mapped) &&
854 (_WSMGetConfigFormatType(w_window->window) == WSM_WINDOW_FMT))
855 {
856 EnableDeleteCommand(w_window->window);
857 }
858
859 UpdateButtons(w_window);
860 }
861
862
863 /*------------------------------------------------------------------
864 AddWindowToSpace
865
866 ------------------------------------------------------------------*/
867 void
AddWindowToSpace(Space * s,WorkWindow * w_window)868 AddWindowToSpace(Space *s,
869 WorkWindow *w_window)
870 {
871 WorkWindowList *w_list,*w_list2;
872
873 w_list = (WorkWindowList*)XtMalloc(sizeof(WorkWindowList));
874 w_list->next = NULL;
875 w_list->work_win = w_window;
876 w_list->sib_win = NULL;
877 if (s->w_list == NULL)
878 s->w_list = w_list;
879 else
880 {
881 w_list2 = s->w_list;
882 if (w_list2->work_win == w_window)
883 {
884 XtFree((char*)w_list);
885 return;
886 }
887 while (w_list2->next != NULL)
888 {
889 w_list2 = w_list2->next;
890 if (w_list2->work_win == w_window)
891 {
892 XtFree((char*)w_list);
893 return;
894 }
895 }
896 w_list2->next = w_list;
897 }
898 UpdateBothList(s);
899 }
900
901
902 /*------------------------------------------------------------------
903 RemoveWorkWindowFromSpace
904
905 ------------------------------------------------------------------*/
906 void
RemoveWorkWindowFromSpace(Space * s,WorkWindow * w_window)907 RemoveWorkWindowFromSpace(Space *s,
908 WorkWindow *w_window)
909 {
910 WorkWindowList *w_list,*pw_list;
911
912 w_list = s->w_list;
913 pw_list = w_list;
914 while (w_list !=NULL)
915 {
916 if (w_list->work_win == w_window)
917 {
918 if (pw_list == w_list)
919 s->w_list = s->w_list->next;
920 else
921 pw_list->next = w_list->next;
922 XtFree((XtPointer)w_list);
923 UpdateBothList(s);
924 return;
925 }
926 if (w_list->sib_win == w_window)
927 w_list->sib_win = NULL;
928 pw_list = w_list;
929 w_list = w_list->next;
930 }
931 return;
932 }
933
934
935
936
937 /*------------------------------------------------------------------
938 RemoveSpaceFromWindow
939
940 ------------------------------------------------------------------*/
941 void
RemoveSpaceFromWindow(Space * s,WorkWindow * w_window)942 RemoveSpaceFromWindow(Space *s,
943 WorkWindow *w_window)
944 {
945 SpaceList *s_list,*ps_list;
946
947 s_list = w_window->s_list;
948 ps_list = s_list;
949 while (s_list !=NULL)
950 {
951 if (s_list->space == s)
952 {
953 if (ps_list == s_list)
954 w_window->s_list = w_window->s_list->next;
955 else
956 ps_list->next = s_list->next;
957 XtFree((XtPointer)s_list);
958
959 if (w_window->s_list != NULL)
960 if (w_window->s_list->next == NULL)
961 DisableDeleteCommand(w_window->window);
962 return;
963 }
964 ps_list = s_list;
965 s_list = s_list->next;
966 }
967 if (w_window->s_list != NULL)
968 if (w_window->s_list->next == NULL)
969 DisableDeleteCommand(w_window->window);
970
971 UpdateButtons(w_window);
972
973 }
974
975
976 /*------------------------------------------------------------------
977 RemoveWorkWindow
978
979 ------------------------------------------------------------------*/
980 void
RemoveWorkWindow(WorkWindow * w_window,Boolean purge)981 RemoveWorkWindow(WorkWindow *w_window, Boolean purge)
982 {
983 SpaceList *s_list;
984 WorkWindow *pre_window, *post_window;
985 pre_window = w_window->prev;
986 post_window = w_window->next;
987 s_list = w_window->s_list;
988 while (s_list != NULL)
989 {
990 RemoveWorkWindowFromSpace(s_list->space, w_window);
991 s_list = s_list->next;
992 }
993
994 if (w_window->all_workspaces)
995 RemoveWorkWindowFromSpace(all_space,w_window);
996
997 if (work_windows == w_window)
998 work_windows = w_window->next;
999 if (pre_window != NULL)
1000 pre_window->next = post_window;
1001 if (post_window != NULL)
1002 post_window->prev = pre_window;
1003
1004 if (purge)
1005 (void) PurgeAllWindowConfiguration(shell,
1006 w_window->specifier_qlist,
1007 w_window->attrib_qlist);
1008
1009
1010 XtFree((XtPointer)w_window->win_data);
1011 XtFree((XtPointer)w_window);
1012 }
1013
1014 /*------------------------------------------------------------------
1015 RemoveSpace
1016
1017 ------------------------------------------------------------------*/
1018 /* not tested */
1019 void
RemoveSpace(Space * space)1020 RemoveSpace(Space *space)
1021 {
1022 WorkWindowList *w_list, *destroy_list;
1023 Space *s, *p;
1024
1025 w_list = space->w_list;
1026 while (w_list != NULL)
1027 {
1028 RemoveSpaceFromWindow(space,w_list->work_win);
1029 destroy_list = w_list;
1030 w_list = w_list->next;
1031 XtFree((char*)destroy_list);
1032 }
1033
1034 s = space_list;
1035 p = s;
1036 while (s != NULL)
1037 {
1038 if (s == space)
1039 {
1040 if (p == s)
1041 space_list = s->next;
1042 else
1043 p->next = s->next;
1044 }
1045 p = s;
1046 s = s->next;
1047 }
1048
1049 XtFree((XtPointer)space);
1050 }
1051
1052 /*------------------------------------------------------------------
1053 IsWorkWindowInSpace
1054
1055 ------------------------------------------------------------------*/
1056 Boolean
IsWorkWindowInSpace(WorkWindow * w,Space * s)1057 IsWorkWindowInSpace(WorkWindow *w,Space *s)
1058 {
1059 WorkWindowList *w_list;
1060
1061 if (w->all_workspaces && s!= all_space) return True;
1062 w_list = s->w_list;
1063 while (w_list != NULL)
1064 {
1065 if (w_list->work_win == w)
1066 return True;
1067 w_list = w_list->next;
1068 }
1069 return False;
1070 }
1071
1072
1073 /*------------------------------------------------------------------
1074 IsSpaceInWorkWindow
1075
1076 ------------------------------------------------------------------*/
1077 Boolean
IsSpaceInWorkWindow(Space * s,WorkWindow * w)1078 IsSpaceInWorkWindow(Space *s, WorkWindow *w)
1079 {
1080 SpaceList *s_list;
1081
1082 if (w->all_workspaces && s!= all_space) return True;
1083 s_list = w->s_list;
1084 while (s_list !=NULL)
1085 {
1086 if (s_list->space == s)
1087 return True;
1088 s_list = s_list->next;
1089 }
1090 return False;
1091 }
1092
1093
1094 /*------------------------------------------------------------------
1095 InitializeWsm
1096
1097 ------------------------------------------------------------------*/
InitializeWsm()1098 void InitializeWsm()
1099 {
1100 atoms.save_property = XmInternAtom(XtDisplay(shell),"WM_SAVE_YOURSELF",False);
1101 atoms.protocols_property = XmInternAtom(XtDisplay(shell),"WM_PROTOCOLS",False);
1102 atoms.sm_client_id_property = XmInternAtom(XtDisplay(shell),"_MOTIF_SM_CLIENT_ID",False);
1103 atoms.wm_role_property = XmInternAtom(XtDisplay(shell),"_MOTIF_WM_WINDOW_ROLE",False);
1104 atoms.wm_client_leader = XmInternAtom(XtDisplay(shell),"WM_CLIENT_LEADER",False);
1105
1106 all_space = (Space *)XtMalloc(sizeof(Space));
1107 all_space->nameq = XrmStringToQuark("all");
1108 all_space->w_list = NULL;
1109 all_space->next = NULL;
1110
1111 current_space = NULL;
1112 }
1113
1114
1115
1116 /*------------------------------------------------------------------
1117 RestartWsm
1118
1119 ------------------------------------------------------------------*/
1120
CompleteRestartWSM()1121 void CompleteRestartWSM()
1122 {
1123 Space *s;
1124 WorkWindowList *w_list, *destroy_w_list;
1125 WorkWindow *w, *destroy_w;
1126 SpaceList *s_list, *destroy_s_list;
1127
1128 s = space_list;
1129
1130 while (s!= NULL)
1131 {
1132 w_list = s->w_list;
1133 while (w_list != NULL)
1134 {
1135 destroy_w_list = w_list;
1136 w_list = w_list->next;
1137 XtFree((XtPointer)destroy_w_list);
1138 }
1139 s->w_list = NULL;
1140 s = s->next;
1141 }
1142
1143 w_list = all_space->w_list;
1144 while (w_list != NULL)
1145 {
1146 destroy_w_list=w_list;
1147 w_list = w_list->next;
1148 XtFree((XtPointer)destroy_w_list);
1149 }
1150
1151 all_space->w_list = NULL;
1152 all_space->next = NULL;
1153
1154 w = work_windows;
1155 while (w!= NULL)
1156 {
1157 destroy_w = w;
1158 s_list = w->s_list;
1159 while (s_list != NULL)
1160 {
1161 destroy_s_list = s_list;
1162 s_list = s_list->next;
1163 XtFree((XtPointer)destroy_s_list);
1164 }
1165 w = w->next;
1166 XtFree((XtPointer)destroy_w);
1167 }
1168
1169 work_windows = NULL;
1170
1171 PRINT("Restarting WSM\n");
1172
1173 }
1174
1175
RestartWSM()1176 void RestartWSM()
1177 {
1178 WorkWindow *w;
1179
1180 for (w = work_windows; w != NULL; w = w->next)
1181 {
1182 w->used = False;
1183 }
1184 }
1185
FinishRestartWSM()1186 void FinishRestartWSM()
1187 {
1188 WorkWindow *w;
1189
1190 for (w = work_windows; w != NULL; w = w->next)
1191 {
1192 if (w->used == False)
1193 {
1194 RemoveWorkWindow(w,False);
1195 }
1196 }
1197 }
1198 /*------------------------------------------------------------------
1199 GetWSMWindow
1200
1201 ------------------------------------------------------------------*/
1202 Window
GetWSMWindow(WorkWindow * w_window)1203 GetWSMWindow(WorkWindow *w_window)
1204 {
1205
1206 return (w_window->window);
1207
1208 }
1209
1210
1211
1212 /*------------------------------------------------------------------
1213 SetWorkWindowValues
1214
1215 ------------------------------------------------------------------*/
1216 void
SetWorkWindowValues(WorkWindow * w,Boolean all_workspaces,Boolean linked)1217 SetWorkWindowValues(WorkWindow *w, Boolean all_workspaces, Boolean linked)
1218 {
1219 if (all_workspaces && !(w->all_workspaces))
1220 {
1221 AddWindowToSpace(all_space,w);
1222 UpdateBothList(all_space);
1223 UpdateButtons(w);
1224 }
1225 else if (!all_workspaces && w->all_workspaces)
1226 {
1227 RemoveWorkWindowFromSpace(all_space,w);
1228 UpdateBothList(all_space);
1229 UpdateButtons(w);
1230 }
1231 w->all_workspaces = all_workspaces;
1232 w->linked = linked;
1233
1234
1235 }
1236
1237
1238 /*------------------------------------------------------------------
1239 UnmapCurrentSpace
1240
1241 ------------------------------------------------------------------*/
1242 void
UnmapCurrentSpace()1243 UnmapCurrentSpace()
1244 {
1245 WorkWindowList *w_list = current_space->w_list;
1246 while (w_list!= NULL)
1247 {
1248 w_list->work_win->mapped = False;
1249 w_list = w_list->next;
1250 }
1251 }
1252
1253 /*------------------------------------------------------------------
1254 UnmapWorkWindow
1255
1256 ------------------------------------------------------------------*/
1257 void
UnmapWorkWindow(WorkWindow * w_window)1258 UnmapWorkWindow(WorkWindow *w_window)
1259 {
1260 w_window->mapped = False;
1261 }
1262
1263 /*------------------------------------------------------------------
1264 MapWorkWindow
1265
1266 ------------------------------------------------------------------*/
1267 void
MapWorkWindow(WorkWindow * w_window)1268 MapWorkWindow(WorkWindow *w_window)
1269 {
1270 w_window->mapped = True;
1271 }
1272
1273
1274 /**********************************************************************/
1275 /* This is for testing purposes. */
1276 /**********************************************************************/
1277
1278
1279 char*
trimblanks(char * s)1280 trimblanks(char *s)
1281 {
1282 char *p;
1283
1284 p = &s[strlen(s)-1]; /* point to last char */
1285 while((*p <= ' ') && p >= s) p--;
1286 p++;
1287 *p = '\0';
1288
1289 return s;
1290 }
1291
1292
1293 void
translate_for_database(char * s)1294 translate_for_database(char *s)
1295 {
1296 int length = strlen(s);
1297 int i,j;
1298
1299
1300 for (i = 0; i < length; i++)
1301 {
1302 if (s[i] == ':')
1303 {
1304 s[i] = '&';
1305 }
1306 }
1307 }
1308
1309 static char*
GetWMName(Window window,Boolean is_icon)1310 GetWMName(Window window, Boolean is_icon)
1311 {
1312 XTextProperty textProperty;
1313 char *str = NULL;
1314
1315 if (window == 0)
1316 {
1317 str = (char*) XtMalloc((strlen("Global") +1) * sizeof(char));
1318 strcpy(str,"Global");
1319 return str;
1320 }
1321 if(XGetWMName(dsp, (window & WIN_MASK), &textProperty)) {
1322 if (textProperty.encoding == XA_STRING) {
1323 if (textProperty.value) {
1324 str = (String)textProperty.value;
1325 trimblanks(str);
1326 if(str[0])
1327 {
1328 if (is_icon)
1329 {
1330 str = (char*)XtRealloc(str,(strlen(str)+2 )* sizeof(char));
1331 strcat(str,"I");
1332 }
1333 return str;
1334 }
1335 }
1336 }
1337 }
1338
1339 strcpy(str, "");
1340 return str;
1341 }
1342
1343
1344
1345
1346 static char *
GetWMClient(Window window,Boolean is_icon)1347 GetWMClient(Window window, Boolean is_icon)
1348 {
1349 int format;
1350 int status;
1351 unsigned long nitems, after;
1352 Atom type = None;
1353 char *str;
1354
1355 status = XGetWindowProperty(dsp,
1356 (window & WIN_MASK),
1357 atoms.sm_client_id_property,
1358 0L,(long)1000,
1359 False,
1360 XA_STRING,
1361 &type,
1362 &format,
1363 &nitems,
1364 &after,
1365 (unsigned char **)&str);
1366
1367 if (status == Success)
1368 {
1369 if (str == NULL) return (NULL);
1370 translate_for_database(str);
1371 if (is_icon)
1372 {
1373 str = (char*) XtRealloc((char*)str,(strlen(str)+2) * sizeof(char));
1374 strcat(str,"I");
1375 }
1376 return str;
1377 }
1378
1379
1380 /*
1381 * if there's no clientID on this window, then see if it points
1382 * to a client leader that has a clientID.
1383 */
1384 else
1385 {
1386 Window leader;
1387
1388 /* check for CLIENT_LEADER property. */
1389 status = XGetWindowProperty(dsp,
1390 (window & WIN_MASK),
1391 atoms.wm_client_leader,
1392 0L,(long)1000,
1393 False,
1394 XA_WINDOW,
1395 &type,
1396 &format,
1397 &nitems,
1398 &after,
1399 (unsigned char **)&leader);
1400 if (status == Success)
1401 {
1402 if ((leader == None) || (leader == window))
1403 return (NULL);
1404 else
1405 return (GetWMClient(leader, is_icon));
1406 }
1407
1408 else
1409 {
1410 /* Old-style client - no WM_CLIENT_ID property */
1411 return (NULL);
1412 }
1413 }
1414 }
1415
1416
1417
1418
1419
1420 static
1421 char *
GetWMRole(Window window,Boolean is_icon)1422 GetWMRole(Window window, Boolean is_icon)
1423 {
1424 int format;
1425 int status;
1426 unsigned long nitems, after;
1427 Atom type = None;
1428 char *str;
1429
1430 status = XGetWindowProperty(dsp,
1431 (window & WIN_MASK),
1432 atoms.wm_role_property,
1433 0L,(long)1000,
1434 False,
1435 XA_STRING,
1436 &type,
1437 &format,
1438 &nitems,
1439 &after,
1440 (unsigned char **)&str);
1441
1442 if (status == Success)
1443 {
1444 if (str == NULL) return (NULL);
1445 translate_for_database(str);
1446 if (is_icon)
1447 {
1448 str = (char*) XtRealloc((char*)str,(strlen(str)+2) * sizeof(char));
1449 strcat(str,"I");
1450 }
1451 return str;
1452 }
1453
1454 else return (NULL);
1455 }
1456
1457
1458
1459
1460
1461 static
1462 char *
GetWMCount(XrmQuark client,XrmQuark role)1463 GetWMCount(XrmQuark client, XrmQuark role)
1464 {
1465 WorkWindow *w;
1466 char *str;
1467 int count;
1468
1469 count = 0;
1470 for (w = work_windows; w!= NULL; w = w->next)
1471 {
1472 if (w->specifier_qlist[0] == client && w->specifier_qlist[1] == role)
1473 count++;
1474 }
1475 str = (String) XtMalloc(4*sizeof(char));
1476 /* if (count == 0)
1477 strcpy(str,"*");
1478 else*/
1479 sprintf(str,"%d",count);
1480 return str;
1481 }
1482
1483
1484 XrmQuarkList
GetSpecifierQList(Window window,Boolean is_icon)1485 GetSpecifierQList(Window window, Boolean is_icon)
1486 {
1487 XrmQuark *specifier;
1488 char *client;
1489 char *role;
1490 char *count;
1491
1492 specifier = (XrmQuark*)XtMalloc(4*sizeof(XrmQuark));
1493
1494 if (window != 0)
1495 {
1496 client = GetWMClient(window, is_icon);
1497 if (client == NULL)
1498 client = GetWMName(window,is_icon);
1499 role = GetWMRole(window, is_icon);
1500 if (role == NULL)
1501 role = GetWMName(window,is_icon);
1502 specifier[0] = XrmStringToQuark(client);
1503 specifier[1] = XrmStringToQuark(role);
1504 count = GetWMCount(specifier[0],specifier[1]);
1505 specifier[2] = XrmStringToQuark(count);
1506 specifier[3] = NULLQUARK;
1507 XtFree((XtPointer)client);
1508 XtFree((XtPointer)role);
1509 XtFree((XtPointer)count);
1510 }
1511 else
1512 {
1513 specifier[0] = XrmStringToQuark("Global");
1514 specifier[1] = NULLQUARK;
1515 }
1516 return specifier;
1517 }
1518
1519
1520