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