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: wsm.c /main/8 1997/05/02 10:08:35 dbl $"
29 #endif
30 #endif
31 
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <signal.h>
35 #include <Xm/Xm.h>
36 
37 #include "wsmSend.h"
38 #include "wsm.h"
39 #include "wsm_ui.h"
40 #include "wsmStruct.h"
41 #include "xrmLib.h"
42 #include "wsmDebug.h"
43 #include "wsmData.h"
44 #include "wsm_cb.h"
45 #include "wsm_create.h"
46 #include "command_ui.h"
47 #include "Wsm/utm_send.h"
48 
49 #include <Xm/DrawingA.h>
50 #include <Xm/PushB.h>
51 #include <Xm/RowColumn.h>
52 #include <Xm/Text.h>
53 #include <Xm/PanedW.h>
54 #include <Xm/TransferP.h>
55 
56 extern Atom WM_S0;
57 extern Atom _MOTIF_WM_INVOKE_COMMAND;
58 
59 extern Time GetTimestamp (Display *dpy);
60 
61 
62 /* globals */
63 
64 Widget utmShell;
65 AtomStruct atoms;
66 WSM_UI* wsm_ui;
67 Boolean mwm_gone =False;
68 Boolean mwm_reconnect = False;
69 Boolean diffs_allowed = False;
70 Widget shell;
71 Widget shell_ui;
72 Display *dsp;
73 Space * current_space = NULL;
74 Space *all_space;
75 Space *space_list = NULL;
76 WSMConfigFormatReply *config_format_reply = NULL;
77 XrmQuark *space_qlist;
78 WorkWindow *work_windows;
79 Window mwm_window;
80 IndexStruct wsm_index;
81 int num_window_attrib;
82 int num_icon_attrib;
83 int num_global_attrib;
84 XrmQuark *window_attribq;
85 XrmQuark *icon_attribq;
86 XrmQuark *global_attribq;
87 WSMAttribute *window_attrib_list;
88 WSMAttribute *icon_attrib_list;
89 WSMAttribute *global_attrib_list;
90 Boolean connected = False;
91 
92 char *file_name;
93 Space *from_space;
94 Space *to_space;
95 Boolean wsm_shown;
96 
97 
98 typedef struct {
99   String file_name;
100   String *workspace_list;
101   String *background_list;
102   String *label_pixmap_list;
103   String current_workspace;
104   Boolean show_dialog;
105   Boolean show_menu;
106 } AppData;
107 
108 
109 typedef struct {
110   Window window;
111   Space *from_space;
112   Space *to_space;
113 } CopyStruct;
114 
115 AppData app_data;
116 
117 static String fallbacks[] = {
118     "*title: WSM",
119     "*nameShell.title:			Workspace Name",
120     "*backgroundShell.title:		Workspace Background",
121     "*deleteShell.title:		Delete Workspace",
122     "*configureShell.title:		Configure Workspace",
123     "*saveAsShell.title:		Save As",
124     "*occupyShell.title:		Occupy",
125 
126     "*newButton.labelString:		New Workspace",
127     "*nameButton.labelString:		Rename Workspaces...",
128     "*configureButton.labelString:	Configure Workspaces...",
129     "*deleteButton.labelString:		Delete Workspaces...",
130     "*hideButton.labelString:		Hide Workspace Manager",
131     "*saveButton.labelString:		Save",
132     "*saveAsButton.labelString:		Save As...",
133     "*exitButton.labelString:		Exit",
134     "*backgroundButton.labelString:	Set Background...",
135     "*fileCascade.labelString:		File",
136     "*fileCascade.mnemonic:		F",
137     "*workspaceCascade.labelString:	Workspace",
138     "*workspaceCascade.mnemonic:	W",
139     "*viewCascade.labelString:		View",
140     "*viewCascade.mnemonic:		V",
141     "*saveButton.mnemonic:		S",
142     "*saveAsButton.mnemonic:		A",
143     "*exitButton.mnemonic:		x",
144     "*backgroundButton.mnemonic:	B",
145     "*newButton.mnemonic:		N",
146     "*nameButton.mnemonic:		R",
147     "*configureButton.mnemonic:		C",
148     "*deleteButton.mnemonic:		D",
149     "*hideButton.mnemonic:		H",
150 
151     "*applyButton.labelString:		Apply",
152     "*dismissButton.labelString:	Dismiss",
153     "*cancelButton.labelString:		Cancel",
154     "*okButton.labelString:	Ok",
155     "*cancelButton.labelString:	Cancel",
156 
157     "*configureShell*titleLabel.labelString:	Configure Workspace",
158     "*configureShell*copyButton.labelString:	Copy",
159     "*configureShell*linkButton.labelString:	Link",
160     "*configureShell*occupyButton.labelString:  >> Occupy >>",
161     "*configureShell*moveButton.labelString:	>> Move >>",
162     "*configureShell*deleteButton.labelString:	Remove",
163     "*configureShell*clientButton.labelString:	Window",
164     "*configureShell*windowButton.labelString:	Client",
165     "*configureShell.height:			400",
166     "*configureShell.width:			550",
167     "*configureShell*fromForm.leftOffset:	10",
168     "*configureShell*fromForm.rightOffset:	10",
169     "*configureShell*toForm.leftOffset:		10",
170     "*configureShell*toForm.rightOffset:	10",
171     "*configureShell*buttonForm.leftOffset:	-75",
172     "*configureShell*toggleRow.topOffset:	50",
173     "*configureShell*separator2.bottomOffset:	5",
174     "*configureShell*dismissButton.bottomOffset:5",
175 
176     "*nameShell*nameTitleLabel.labelString:	Workspace Name",
177     "*nameShell*nameLabel.labelString:		Workspace Name",
178     "*nameShell*pixmapLabel.labelString:	Label Pixmap",
179     "*nameShell*nameList.height:		200",
180     "*nameShell*applyButton.leftPosition:		25",
181     "*nameShell*dismissButton.leftPosition:		55",
182     "*nameShell*nameTitleLabel.topOffset:			5",
183     "*nameShell*nameWindow.leftOffset:			5",
184     "*nameShell*nameWindow.rightOffset:		5",
185     "*nameShell*nameWindow.topOffset:			5",
186     "*nameShell*nameWindow.bottomOffset:		5",
187     "*nameShell*wnameForm.leftOffset:		5",
188     "*nameShell*wnameForm.rightOffset:		5",
189     "*nameShell*pixForm.leftOffset:		5",
190     "*nameShell*pixForm.rightOffset:		5",
191 
192     "*backgroundShell*backgroundTitleLabel.labelString:	Workspace Background",
193     "*backgroundShell*backgroundLabel.labelString:	Workspace Background",
194     "*backgroundShell*backgroundList.height:		200",
195     "*backgroundShell*applyButton.leftPosition:		25",
196     "*backgroundShell*dismissButton.leftPosition:		55",
197     "*backgroundShell*backgroundTitleLabel.topOffset:			5",
198     "*backgroundShell*backgroundWindow.leftOffset:			5",
199     "*backgroundShell*backgroundWindow.rightOffset:		5",
200     "*backgroundShell*backgroundWindow.topOffset:			5",
201     "*backgroundShell*backgroundWindow.bottomOffset:		5",
202     "*backgroundShell*backgroundForm.leftOffset:		5",
203     "*backgroundShell*backgroundForm.rightOffset:		5",
204 
205     "*deleteShell*deleteTitleLabel.labelString:	Delete Workspace",
206     "*deleteShell*deleteList.height:		200",
207     "*deleteShell*applyButton.leftPosition:		0",
208     "*deleteShell*dismissButton.leftPosition:		45",
209     "*deleteShell*deleteTitleLabel.topOffset:			5",
210     "*deleteShell*deleteWindow.leftOffset:			5",
211     "*deleteShell*deleteWindow.rightOffset:		5",
212     "*deleteShell*deleteWindow.topOffset:			5",
213     "*deleteShell*deleteWindow.bottomOffset:		5",
214 
215     "*saveAsShell*saveAsTitleLabel.labelString:	Save As",
216     "*saveAsShell*saveAsLabel.labelString:	Database Name",
217     "*saveAsShell*okButton.leftPosition:		20",
218     "*saveAsShell*cancelButton.leftPosition:		50",
219     "*saveAsShell*saveAsTitleLabel.topOffset:			5",
220     "*saveAsShell*dbForm.leftOffset:			5",
221     "*saveAsShell*dbForm.rightOffset:		5",
222     "*saveAsShell*dbForm.topOffset:			5",
223     "*saveAsShell*dbForm.bottomOffset:		5",
224 
225     "*occupyShell*occupyTitleLabel.labelString:	Occupy Workspace",
226     "*occupyShell*copyButton.labelString:	Copy",
227     "*occupyShell*linkButton.labelString:	Link",
228     "*occupyShell*okButton.leftPosition:		20",
229     "*occupyShell*cancelButton.leftPosition:		50",
230     "*occupyShell*occupyList.width:			175",
231     "*occupyShell*occupyList.height:			200",
232     "*occupyShell*occupyTitleLabel.topOffset:	5",
233     "*occupyShell*occupyTitleLabel.leftOffset:	5",
234     "*occupyShell*occupyTitleLabel.rightOffset:	5",
235     "*occupyShell*occupyWindow.topOffset:		5",
236     "*occupyShell*occupyWindow.leftOffset:		5",
237     "*occupyShell*occupyWindow.rightOffset:		5",
238     "*occupyShell*toggleRow.topOffset:		5",
239     "*occupyShell*toggleRow.leftOffset:		30",
240 
241     NULL,
242 };
243 
244 static XtResource resources[] = {
245   {
246     "fileName",
247     "FileName",
248     XtRString,
249     sizeof(String),
250     XtOffsetOf(AppData, file_name),
251     XtRString,
252     (XtPointer) NULL,
253     },
254   {
255     "workspaceList",
256     "WorkspaceList",
257     XtRStringTable,
258     sizeof(XtRStringTable),
259     XtOffsetOf(AppData, workspace_list),
260     XtRString,
261     (XtPointer) NULL,
262     },
263   {
264     "backgroundList",
265     "BackgroundList",
266     XtRStringTable,
267     sizeof(XtRStringTable),
268     XtOffsetOf(AppData, background_list),
269     XtRString,
270     (XtPointer) NULL,
271     },
272   {
273     "labelPixmapList",
274     "LabelPixmapList",
275     XtRStringTable,
276     sizeof(XtRStringTable),
277     XtOffsetOf(AppData, label_pixmap_list),
278     XtRString,
279     (XtPointer) NULL,
280     },
281   {
282     "currentWorkspace",
283     "CurrentWorkspace",
284     XtRString,
285     sizeof(XtRString),
286     XtOffsetOf(AppData, current_workspace),
287     XtRString,
288     (XtPointer) NULL,
289     },
290   {
291     "showWSDialog",
292     "ShowWSDialog",
293     XtRBoolean,
294     sizeof(Boolean),
295     XtOffsetOf(AppData, show_dialog),
296     XtRImmediate,
297     (XtPointer) True,
298     },
299   {
300     "useMenuBar",
301     "UseMenuBar",
302     XtRBoolean,
303     sizeof(Boolean),
304     XtOffsetOf(AppData, show_menu),
305     XtRImmediate,
306     (XtPointer) True,
307     },
308 };
309 
310 static XrmOptionDescRec options[] = {
311   {"-fileName",	"*fileName", XrmoptionSepArg, NULL},
312   {"-file",	"*fileName", XrmoptionSepArg, NULL},
313   {"-f",	"*fileName", XrmoptionSepArg, NULL},
314   {"-workspaceList", "*workspaceList", XrmoptionSepArg, NULL},
315   {"-wL", "*workspaceList", XrmoptionSepArg, NULL},
316   {"-backgroundList", "*backgroundList", XrmoptionSepArg, NULL},
317   {"-bL", "*backgroundList", XrmoptionSepArg, NULL},
318  {"-labelPixmapList", "*labelPixmapList", XrmoptionSepArg, NULL},
319   {"-labelPL", "*labelPixmapList", XrmoptionSepArg, NULL},
320   {"-currentWorkspace", "*currentWorkspace", XrmoptionSepArg, NULL},
321   {"-cW", "*currentWorkspace", XrmoptionSepArg, NULL},
322   {"-showWSDialog", "showWSDialog", XrmoptionSepArg, NULL},
323   {"-s", "*showWSDialog", XrmoptionSepArg, NULL},
324 };
325 
326 Widget text;
327 
328 static void UTMConvertProc(
329 Widget w, XtPointer clientData, XtPointer callData
330 );
331 
332 static Boolean WsmConvertProc(
333 Widget, Atom *, Atom *, XtPointer, unsigned long,
334 int, Atom *, XtPointer *, unsigned long *, int *
335 );
336 
337 static void SetupWsmSignalHandlers(
338 int
339 );
340 
341 static void QuitWsmSignalHandler(
342 int
343 );
344 
345 void
GetFileName(char ** name)346 GetFileName(char **name)
347 {
348   /* get dbase file name */
349 
350   char *home_name = getenv("HOME");
351 
352   if (app_data.file_name != NULL)
353     {
354       if (app_data.file_name[0] != '/')
355 	{
356 	  *name = XtMalloc(sizeof(char)*(strlen(home_name)+ 1
357 					 + strlen(app_data.file_name)+ 2));
358 	  strcpy(*name,home_name);
359 	  strcat(*name, "/");
360 	  strcat(*name,app_data.file_name);
361 	}
362       else
363 	{
364 	  *name = XtMalloc(sizeof(char) *(strlen(app_data.file_name) +1));
365 	  strcpy(*name,app_data.file_name);
366 	}
367     }
368   else
369     {
370       *name = XtMalloc(sizeof(char) *(strlen(home_name) + 9));
371       strcpy(*name,home_name);
372       strcat(*name, "/.wsmdb");
373     }
374 }
375 
376 
377 void
GetWorkspaces(String * str_table)378 GetWorkspaces(String *str_table)
379 {
380   char *str, strq[20];
381   int i;
382   /* get workspaces from resources or from dbase file or default to 4 rooms */
383 
384   if (app_data.workspace_list != NULL)
385     {
386       for (i = 0; app_data.workspace_list[i] != NULL; i++)
387 	{
388 	  sprintf(strq,"Room%d",i+1);
389 	  str = (char*) XtMalloc((strlen(app_data.workspace_list[i]) +1)
390 				 * sizeof(char));
391 	  strcpy(str, app_data.workspace_list[i]);
392 	  CreateSpace(XrmStringToQuark(strq),str);
393 	  XtFree(str);
394 	}
395     }
396   else if (str_table != NULL)
397     {
398       for (i = 0; str_table[i] != NULL; i++)
399 	{
400 	  sprintf(strq,"Room%d",i+1);
401 	  str = (char*) XtMalloc((strlen(str_table[i]) +1) * sizeof(char));
402 	  strcpy(str, str_table[i]);
403 	  CreateSpace(XrmStringToQuark(strq),str);
404 	  XtFree(str);
405 	}
406     }
407   else
408     {
409       str = (char*) XtMalloc( 8* sizeof(char));
410       for (i = 1; i < 5; i++)
411 	{
412 	  sprintf(str,"Room%d",i);
413 	  CreateSpace(XrmStringToQuark(str), str);
414 	}
415       XtFree(str);
416     }
417 }
418 
419 
420 
421 void
GetBackgrounds(String * str_table)422 GetBackgrounds(String *str_table)
423 {
424   int i;
425   Space *space;
426   char *cptr;
427 
428   /* get backgrounds from resources or from dbase file or default to None */
429   if (app_data.background_list != NULL)
430     {
431       for (i = 0; app_data.background_list[i] != NULL; i++)
432 	{
433 	  space = GetSpaceFromID(i);
434 	  if (space != NULL)
435 	    {
436 	      if (app_data.background_list[i][0] == '"')
437 		{
438 		  cptr = app_data.background_list[i]+1;
439 		  SetSpacePixmap(space, cptr);
440 		}
441 	      else
442 		SetSpacePixel(space,app_data.background_list[i]);
443 	    }
444 	}
445      }
446   else if (str_table != NULL)
447     {
448       for (i = 0; str_table[i] != NULL; i++)
449 	{
450 	  space = GetSpaceFromID(i);
451 	  if (space != NULL)
452 	    {
453 	      if (str_table[i][0] == '"')
454 		{
455 		  cptr = str_table[i] +1;
456 		  SetSpacePixmap(space,cptr);
457 		}
458 	      else
459 		SetSpacePixel(space,str_table[i]);
460 	    }
461 	  XtFree((XtPointer)str_table[i]);
462 	}
463     }
464 }
465 
466 
467 void
GetPixmaps(String * str_table)468 GetPixmaps(String *str_table)
469 {
470   int i;
471   Space *space;
472   /* get pixmap labels from resources or from dbase file or default to None */
473   if (app_data.label_pixmap_list != NULL)
474     {
475       for (i = 0; app_data.label_pixmap_list[i] != NULL; i++)
476 	{
477 	  space = GetSpaceFromID(i);
478 	  if (space != NULL)
479 	    {
480 	      SetSpaceLabelPixmap(space,app_data.label_pixmap_list[i]);
481 	    }
482 	}
483     }
484   else if (str_table != NULL)
485     {
486       for (i = 0; str_table[i] != NULL; i++)
487 	{
488 	  space = GetSpaceFromID(i);
489 	  if (space != NULL)
490 	    {
491 	      SetSpaceLabelPixmap(space,str_table[i]);
492 	    }
493 	  XtFree((XtPointer)str_table[i]);
494 	}
495       XtFree((XtPointer)str_table);
496     }
497 }
498 
499 
500 
501 
502 void
GetCurrentSpace(String str)503 GetCurrentSpace(String str)
504 {
505   Space *s;
506   PRINT("getting current space\n");
507   /* get current space from resources or from dbase file */
508   if (app_data.current_workspace != NULL)
509     {
510       PRINT("from app_data\n");
511       s = GetSpaceFromName(app_data.current_workspace);
512       if (s == NULL) s = GetSpace(XrmStringToQuark(app_data.current_workspace));
513       if (s != NULL) current_space = s;
514     }
515   else if (str != NULL)
516     {
517       PRINT("from str\n");
518       s = GetSpaceFromName(str);
519       if (s == NULL) s = GetSpace(XrmStringToQuark(str));
520       if (s != NULL) current_space = s;
521     }
522   PRINT("Current space %s\n", current_space->name);
523 }
524 
525 
526 void
GetShowWSDialog(Boolean * s_dialog)527 GetShowWSDialog(Boolean *s_dialog)
528 {
529   /* get dbase file name */
530 
531 
532   if (app_data.show_dialog == False)
533     {
534       *s_dialog = False;
535     }
536 }
537 
538 
539 #ifdef _ERROR_HANDLERS
540 int
MyXErrorHandler(Display * display,XErrorEvent * event)541 MyXErrorHandler(Display *display, XErrorEvent *event)
542 {
543   PRINT("Called MyXErrorHandler XXXXXXXXXXXXXXXXXXXXXXX\n");
544   return(0);
545 }
546 
547 void
MyXtErrorHandler(char * err)548 MyXtErrorHandler(char *err)
549 {
550   PRINT("Called MyXtErrorHandler Xt Xt Xt Xt Xt Xt Xt Xt Xt\n");
551   return;
552 }
553 
554 #endif
main(argc,argv)555 int main(argc, argv)
556     int argc;
557     char **argv;
558 {
559   XtAppContext app_con;
560   Widget rc;
561   Arg args[20];
562   Atom wsm_0_atom;
563   Cardinal num_args = 0;
564   XEvent event;
565   Widget Shell001;
566   Widget Shell001a;
567   Widget Shell002;
568   Widget Shell003;
569   Widget Shell004;
570   Widget Shell005;
571   Time time;
572   int argcnt;
573   String *str_table,*b_str_table,*lp_str_table;
574   String current_space_str;
575   Boolean show_dialog = True;
576 
577   shell = XtAppInitialize(&app_con, "WSM", options, XtNumber(options),
578 			  &argc, argv, fallbacks, args, num_args);
579   XtRealizeWidget(shell);
580 
581   utmShell = XtVaCreateManagedWidget("utmShell", xmDrawingAreaWidgetClass,
582 				     shell, NULL);
583   XtAddCallback(utmShell, XmNconvertCallback, UTMConvertProc, NULL);
584 
585 #ifdef NO_TIMERS
586   XtSetSelectionTimeout(5000000);
587 #endif
588 
589 
590 #ifdef _ERROR_HANDLERS
591   XSetErrorHandler(MyXErrorHandler);
592   XtAppSetErrorHandler(app_con,MyXtErrorHandler);
593 #endif
594   dsp = XtDisplay(shell);
595 
596   XtVaSetValues(shell,XmNallowShellResize,True,NULL);
597 
598   app_data.show_dialog = show_dialog;
599   XtVaGetApplicationResources(shell,
600 			      &app_data,
601 			      resources,
602 			      XtNumber(resources),
603 			      NULL);
604 
605 
606   InitializeWsm();
607 
608   GetFileName(&file_name);
609   PRINT("FILE NAME %s\n", file_name);
610   InitializeXrm(file_name);
611 
612   GetSpaceListResources(shell,
613 			&str_table,
614 			&b_str_table,
615 			&lp_str_table,
616 			&current_space_str,
617 			&show_dialog);
618 
619   GetWorkspaces(str_table);
620   GetBackgrounds(b_str_table);
621   GetPixmaps(lp_str_table);
622   GetCurrentSpace(current_space_str);
623   GetShowWSDialog(&show_dialog);
624   PrintAllSpaces();
625 
626   wsm_shown = show_dialog;
627   wsm_ui = (WSM_UI*)XtMalloc(sizeof(WSM_UI));
628   wsm_0_atom = XInternAtom(XtDisplay(shell), "WSM_S0", False);
629   InitializeInterface(wsm_ui);
630 
631   if (XGetSelectionOwner(XtDisplay(shell), wsm_0_atom) != None) {
632     fprintf(stderr, "Someone owms the WSM selection on screen 0.\n");
633     exit(1);
634   }
635 
636   rc = CreateWorkspacePanel(shell, wsm_ui, app_data.show_menu);
637   XtAddCallback(shell, XmNpopdownCallback, QuitCB, (XtPointer)NULL);
638 
639 
640   /* This arglist is used for all of the dialogs created below */
641   argcnt = 0;
642   XtSetArg(args[argcnt], XmNdeleteResponse, XmUNMAP); argcnt++;
643 
644   Shell001 = XtCreatePopupShell("nameShell", topLevelShellWidgetClass,
645 				shell, args, argcnt);
646   CreateNameWorkspace(Shell001, wsm_ui);
647 
648 
649   Shell001a = XtCreatePopupShell("backgroundShell", topLevelShellWidgetClass,
650 				 shell, args, argcnt);
651   CreateBackgroundWorkspace(Shell001a, wsm_ui);
652 
653 
654   Shell002 = XtCreatePopupShell("deleteShell", topLevelShellWidgetClass,
655 				shell, args, argcnt);
656   CreateDeleteWorkspace(Shell002, wsm_ui);
657 
658 
659   Shell003 = XtCreatePopupShell("configureShell", topLevelShellWidgetClass,
660 				shell, args, argcnt);
661   CreateConfigureWorkspace(Shell003, wsm_ui);
662 
663 
664   Shell004 = XtCreatePopupShell("saveAsShell", topLevelShellWidgetClass,
665 				shell, args, argcnt);
666   CreateSaveAs(Shell004, wsm_ui);
667 
668 #ifndef _NO_OCCUPY_DIALOG
669 
670   Shell005 = XtCreatePopupShell("occupyShell", topLevelShellWidgetClass,
671 				shell, args, argcnt);
672   CreateOccupyWorkspace(Shell005, wsm_ui);
673 #endif
674 
675   XtManageChild(rc);
676 
677   SetSpaceBackground(current_space);
678 
679   InternStuff(dsp);
680 
681   atoms.own_selection = _WSMGetSelectionAtom
682          (dsp, XScreenNumberOfScreen(XtScreen(shell)), WSM_WORKSPACE_MANAGER);
683 
684   PRINT("own selection: %s\n",XGetAtomName(dsp,atoms.own_selection));
685   if (XGetSelectionOwner(dsp, atoms.own_selection) != None)
686     {
687       fprintf(stderr,
688 	      "Error - Someone out there already owns this selection.\n");
689       exit(1);
690     }
691 
692   WSMRegisterRequestCallback(dsp,
693 			     XScreenNumberOfScreen(XtScreen(shell)),
694 			     RequestReceived,NULL);
695 
696   /*
697    * Setup destination proc - use UTMDestinationProc from  utm_send.c module.
698    * Any requests made MUST then use UTMSendMesage.
699    * Also setup own convert proc.
700    *
701    * Note - convertProc was setup when utmShell was created.
702    */
703   XtAddCallback(utmShell, XmNdestinationCallback, UTMDestinationProc, NULL);
704 
705   time = GetTimestamp(dsp);
706   XmeNamedSource(utmShell, atoms.own_selection, time);
707 
708   SendConnect(utmShell);
709 
710   if (!show_dialog)
711     XtUnmapWidget(shell);
712 
713   SetupWsmSignalHandlers(0);
714 
715   for (;;)
716     {
717       XtAppNextEvent(app_con, &event);
718       if (event.type == ClientMessage)
719 	{
720 	  DealWithClientMessage(rc,(XClientMessageEvent *)&event);
721 	}
722       if(event.type == DestroyNotify)
723 	{
724 	  DealWithDestroyNotify(rc,(XDestroyWindowEvent *) &event);
725 	}
726       if(event.type == MapNotify)
727 	{
728 	  DealWithMapNotify(rc,(XMapEvent *) &event);
729 	}
730       if(event.type == UnmapNotify)
731 	{
732 	  DealWithUnmapNotify(rc,(XUnmapEvent *) &event);
733 	}
734       if(XtDispatchEvent(&event))
735 	continue;
736     }
737   return 0;
738 }
739 
740 
741 /*	Function Name: UTMConvertProc
742  *	Description: This is the UTM conversion proc called when a request
743  *                   comes in that we need to process.
744  *	Arguments: w - The widget making the request.
745  *                 clientData - not used.
746  *                 callData - the UTM convert callback structure.
747  */
748 
749 static void
UTMConvertProc(Widget w,XtPointer clientData,XtPointer callData)750 UTMConvertProc(Widget w, XtPointer clientData, XtPointer callData)
751 {
752   int scr = XScreenNumberOfScreen(XtScreen(w));
753   Display *dsp = XtDisplay(w);
754   XmConvertCallbackStruct *ccs = (XmConvertCallbackStruct *)callData;
755   Atom lose_sel = XInternAtom(dsp, "_MOTIF_LOSE_SELECTION", False);
756   Atom wm_sel = _WSMGetSelectionAtom(dsp, scr, WSM_WINDOW_MANAGER);
757   Atom wsm_sel = _WSMGetSelectionAtom(dsp, scr, WSM_WORKSPACE_MANAGER);
758 
759   /*
760    * Check if the callback was invoked for the right reason.
761    * The reason field is not set to anything interresting by the transfer
762    * code, so check the selection.
763    */
764   if ((!ccs) || ((ccs->selection != wm_sel) && (ccs->selection != wsm_sel)))
765     return;
766 
767   if (ccs->target == lose_sel)
768     {
769       /* Done with the conversion - free any data used. */
770     }
771 
772   /*
773    * Handle a conversion request with parameter data.
774    */
775   else
776     {
777       WsmConvertProc (w, &(ccs->selection), &(ccs->target),
778 		     ccs->parm, ccs->parm_length, ccs->parm_format,
779 		     &(ccs->type), &(ccs->value), &(ccs->length),
780 		     &(ccs->format));
781     }
782 }
783 
784 static Boolean
WsmConvertProc(Widget w,Atom * selection,Atom * target,XtPointer input,unsigned long input_len,int input_fmt,Atom * return_type,XtPointer * output,unsigned long * output_len,int * output_fmt)785 WsmConvertProc(Widget w, Atom *selection, Atom *target,
786 	      XtPointer input, unsigned long input_len, int input_fmt,
787 	      Atom *return_type, XtPointer *output, unsigned long *output_len,
788 	      int *output_fmt)
789 {
790   WSMDispInfo   *disp_info;
791 
792   PRINT("WsmConvertProc target is %s\n",XGetAtomName(dsp,*target));
793   disp_info = _WSMGetDispInfo(XtDisplay(w));
794 
795   if (*target == disp_info->targets) {
796     *return_type = XA_STRING;
797     *output = (XtPointer) (long) WSMGetTargetList(w, TRUE, output_len);
798     *output_fmt = 32;
799     return(True);
800   }
801 
802   /*
803    * The only target this handles not included in the
804    * WSM Protocol is INVOKE_COMMAND. Check for this here.
805    * If new targets are added later, they may be added here.
806    */
807   if (*target == _MOTIF_WM_INVOKE_COMMAND)
808     {
809       /* ||| CARD8 type? */
810       InvokeCommand(w, *target, (CARD8*)input, input_len, input_fmt);
811       return (TRUE);
812     }
813 
814   if (!WSMIsKnownTarget(w, *target))
815     {
816       PRINT("isn't known target\n");
817       return (False);
818     }
819   else
820     {
821       PRINT ("is known target \n");
822       if (WSMProcessProtoTarget(w, *target, input, input_len, input_fmt,
823 				return_type, output, output_len, output_fmt))
824 	return(TRUE);
825     }
826   return(False);
827 }
828 
829 
830 void
SendExtensionsProc(XtPointer client_data,XtIntervalId * int_id)831 SendExtensionsProc(XtPointer client_data, XtIntervalId *int_id)
832 {
833   Widget w = (Widget)client_data;
834   SendExtensionCB(w,NULL,NULL);
835 
836 }
837 
838 /*ARGSUSED*/
839 void
RequestReceived(Widget w,XtPointer textp,WSMRequest * request,WSMReply * reply)840 RequestReceived(Widget w, XtPointer textp,
841 		WSMRequest *request, WSMReply *reply)
842 {
843   Boolean version_found = False;
844   int i;
845 
846   PRINT("RequestReceived\n");
847   reply->any.allocated = True;
848   switch (reply->any.type = request->any.type) {
849   case WSM_CONNECT:
850     {
851       /* send versions in decending order */
852       for (i = 0; i < request->connect.num_versions; i++)
853 	if (request->connect.known_versions[i] == 1 ||
854 	    request->connect.known_versions[i] == 2 ||
855 	    request->connect.known_versions[i] == 3)
856 	  {
857 	    reply->connect.version = request->connect.known_versions[i];
858 	    version_found = True;
859 	    break;
860 	  }
861       if (!version_found) reply->connect.version = 0;
862       if (connected)
863 	{
864 	  RestartWSM();
865 	  connected = False;
866 	}
867       mwm_reconnect = True;
868       SendExtensionCB(w,NULL,NULL);
869     }
870     break;
871 
872   case WSM_REG_WINDOW:
873     {
874       PRINT("wsm: get Register reply\n");
875       if (connected)
876 	{
877 	  GetRegisterWindowReply(request->register_window.window,reply);
878 	  print_reply(reply);
879 	}
880       else
881 	{
882 	  reply->register_window.allocated = False;
883 	  reply->register_window.num_window_data = 0;
884 	  reply->register_window.window_data = NULL;
885 	}
886       PRINT("    got it\n");
887     }
888     break;
889   case WSM_EXTENSIONS:
890   case WSM_CONFIG_FMT:
891   case WSM_GET_STATE:
892   case WSM_SET_STATE:
893   case WSM_WM_GET_BACKGROUND_WINDOW:
894   case WSM_WM_SET_BACKGROUND_WINDOW:
895   case WSM_WM_WINDOWS:
896   case WSM_WM_FOCUS:
897   case WSM_WM_POINTER:
898   case WSM_UNKNOWN:
899     /* Not handled cases */
900     break;
901   }
902 
903   /*
904    * If we had allocated any data here we need to ask the
905    * library to free it, see comments in WSMDefaultOwnSelection for
906    * details.
907    */
908 
909 }
910 
911 
912 
913 void
SendConnect(Widget w)914 SendConnect(Widget w)
915 {
916   WSMRequest request;
917   static short versions[] = { 3,2,1 };
918   Display *dsp = XtDisplay(w);
919   int scr = XScreenNumberOfScreen(XtScreen(shell));
920   Atom wm_selection = _WSMGetSelectionAtom(dsp, scr, WSM_WINDOW_MANAGER);
921 
922 
923   if (XGetSelectionOwner(dsp, wm_selection) == None)
924     return;
925 
926   PRINT("send connect\n");
927   if (connected == False)
928     {
929       request.any.type = WSM_CONNECT;
930       request.connect.allocated = False;
931       request.connect.known_versions = versions;
932       request.connect.num_versions = XtNumber(versions);
933       WSMSendMessage(utmShell, WSM_WINDOW_MANAGER, &request,
934 		     ReceiveConnectRCB, NULL);
935     }
936 }
937 
938 void
ReceiveConnectRCB(Widget w,XtPointer call,WSMReply * reply,WSMErrorCode error)939 ReceiveConnectRCB(Widget w, XtPointer call,
940 		  WSMReply *reply, WSMErrorCode error)
941 {
942   PRINT("receive connect\n");
943   if (reply != NULL)
944     {
945       SendExtensionCB(w,call,call);
946     }
947   else
948     PRINT("receive connect == NULL\n");
949 }
950 
951 
952 void
SendExtensionCB(Widget w,XtPointer client,XtPointer call)953 SendExtensionCB(Widget w, XtPointer client,XtPointer call)
954 {
955 
956   WSMRequest request;
957   static String extensions[] = { "Test",
958 				   "Extension #1", "Extension #123" };
959 
960   request.any.type = WSM_EXTENSIONS;
961   request.extensions.extension_suggestions = extensions;
962   request.extensions.num_extensions = 3;
963   request.extensions.allocated = False;
964   WSMSendMessage(utmShell, WSM_WINDOW_MANAGER, &request,
965 		 ReceiveExtensionsRCB, call);
966 
967 }
968 
969 void
ReceiveExtensionsRCB(Widget w,XtPointer client,WSMReply * reply,WSMErrorCode error)970 ReceiveExtensionsRCB(Widget w, XtPointer client,
971 		     WSMReply *reply, WSMErrorCode error)
972 {
973   if (reply != NULL )
974     {
975       SendConfigCB(w,client, client);
976     }
977   else
978     {
979       PRINT(" extension reply == NULL\n");
980       SendConfigCB(w,client,client);
981     }
982 }
983 
984 
985 void
SendConfigCB(Widget w,XtPointer client,XtPointer call)986 SendConfigCB(Widget w, XtPointer client, XtPointer call)
987 {
988   WSMRequest request;
989   request.any.type = WSM_CONFIG_FMT;
990   WSMSendMessage(utmShell, WSM_WINDOW_MANAGER, &request,
991 		 ReceiveConfigRCB, call);
992 }
993 
994 Boolean
find_format(XrmQuark nameq,XrmQuark * nameq_list,int num_list)995 find_format(XrmQuark nameq, XrmQuark *nameq_list, int num_list)
996 {
997   int i;
998   for (i = 0; i < num_list; i++)
999     {
1000       if (nameq == nameq_list[i])
1001 	return True;
1002     }
1003   return False;
1004 }
1005 
1006 void
ReceiveConfigRCB(Widget w,XtPointer call,WSMReply * reply,WSMErrorCode error)1007 ReceiveConfigRCB(Widget w, XtPointer call,
1008 	     WSMReply *reply, WSMErrorCode error)
1009 {
1010   int i,j;
1011   XrmQuark hideq = XrmStringToQuark("hidden");
1012   XrmQuark iconicq = XrmStringToQuark("iconic");
1013 
1014   if (mwm_reconnect)
1015   {
1016       if (num_global_attrib != reply->config_format.num_global_formats)
1017 	  mwm_reconnect = False;
1018       for (i = 0; i < reply->config_format.num_global_formats && mwm_reconnect; i++)
1019 	{
1020 	  if (global_attribq[i] != reply->config_format.global_formats[i].nameq ||
1021 	      global_attrib_list[i].size !=
1022 	      reply->config_format.global_formats[i].size ||
1023 	      global_attrib_list[i].is_list !=
1024 	      reply->config_format.global_formats[i].is_list)
1025 	      mwm_reconnect = False;
1026 	}
1027       if (num_window_attrib != reply->config_format.num_window_formats)
1028 	  mwm_reconnect = False;
1029       for (i = 0; i < reply->config_format.num_window_formats && mwm_reconnect; i++)
1030 	{
1031 	  if (window_attribq[i] != reply->config_format.window_formats[i].nameq ||
1032 	      window_attrib_list[i].size !=
1033 	      reply->config_format.window_formats[i].size ||
1034 	      window_attrib_list[i].is_list !=
1035 	      reply->config_format.window_formats[i].is_list)
1036 	      mwm_reconnect = False;
1037 	}
1038       for (i = 0; i < reply->config_format.num_icon_formats && mwm_reconnect; i++)
1039       {
1040 	  if ( icon_attribq[i] != reply->config_format.icon_formats[i].nameq ||
1041 	      icon_attrib_list[i].size != reply->config_format.icon_formats[i].size ||
1042 	      icon_attrib_list[i].is_list !=
1043 	      reply->config_format.icon_formats[i].is_list)
1044 	      mwm_reconnect = False;
1045       }
1046       if (!mwm_reconnect)
1047 	  CompleteRestartWSM();
1048   }
1049   if (reply != NULL && !mwm_reconnect)
1050     {
1051       diffs_allowed =reply->config_format.accepts_diffs;
1052 
1053       global_attrib_list=
1054 	(WSMAttribute*)	XtMalloc(reply->config_format.num_global_formats *
1055 				 sizeof(WSMAttribute));
1056       global_attribq =
1057 	(XrmQuark*)XtMalloc((1+reply->config_format.num_global_formats) *
1058 			    sizeof(XrmQuark));
1059       window_attrib_list =
1060 	(WSMAttribute*)XtMalloc(reply->config_format.num_window_formats *
1061 				sizeof(WSMAttribute));
1062       window_attribq =
1063 	(XrmQuark*)XtMalloc((1+reply->config_format.num_window_formats) *
1064 			    sizeof(XrmQuark));
1065       icon_attrib_list =
1066 	(WSMAttribute*)XtMalloc(reply->config_format.num_icon_formats *
1067 				sizeof(WSMAttribute));
1068       icon_attribq =
1069 	(XrmQuark*)XtMalloc((1+reply->config_format.num_icon_formats) *
1070 			    sizeof(XrmQuark));
1071       wsm_index.hide = -1;
1072       wsm_index.iconic = -1;
1073       for (i = 0; i < reply->config_format.num_global_formats; i++)
1074 	{
1075 	  global_attrib_list[i].nameq = global_attribq[i] =
1076 	    reply->config_format.global_formats[i].nameq;
1077 	  global_attrib_list[i].size =
1078 	    reply->config_format.global_formats[i].size;
1079 	  global_attrib_list[i].is_list =
1080 	    reply->config_format.global_formats[i].is_list;
1081 	}
1082       global_attribq[i] = NULLQUARK;
1083       num_global_attrib = i;
1084       for (i = 0; i < reply->config_format.num_window_formats; i++)
1085 	{
1086 	  if (reply->config_format.window_formats[i].nameq == hideq)
1087 	    wsm_index.hide = i;
1088 	  if (reply->config_format.window_formats[i].nameq == iconicq)
1089 	    wsm_index.iconic = i;
1090 	  window_attrib_list[i].nameq = window_attribq[i] =
1091 	    reply->config_format.window_formats[i].nameq;
1092 	  window_attrib_list[i].size =
1093 	    reply->config_format.window_formats[i].size;
1094 	  window_attrib_list[i].is_list =
1095 	    reply->config_format.window_formats[i].is_list;
1096 	}
1097       window_attribq[i] = NULLQUARK;
1098       num_window_attrib = i;
1099       for (i = 0; i < reply->config_format.num_icon_formats; i++)
1100 	{
1101 	  icon_attrib_list[i].nameq = icon_attribq[i] =
1102 	    reply->config_format.icon_formats[i].nameq;
1103 	  icon_attrib_list[i].size = reply->config_format.icon_formats[i].size;
1104 	  icon_attrib_list[i].is_list =
1105 	    reply->config_format.icon_formats[i].is_list;
1106 	}
1107       icon_attribq[i] = NULLQUARK;
1108       num_icon_attrib = i;
1109       config_format_reply = &(reply->config_format);
1110     }
1111   if (reply != NULL)
1112     {
1113       SendStartGetStateCB(w,call,call);
1114     }
1115 
1116 }
1117 
1118 
1119 void
SendStartGetStateCB(Widget w,XtPointer call,XtPointer client)1120 SendStartGetStateCB(Widget w, XtPointer call, XtPointer client)
1121 {
1122   WSMRequest request;
1123   PRINT("wsm: send start get state\n");
1124   request.get_state.window = (Window)0;
1125   request.get_state.diffs_allowed = False;
1126   request.any.type = WSM_GET_STATE;
1127   WSMSendMessage(utmShell, WSM_WINDOW_MANAGER, &request, SendStartSetStateRCB,
1128 		 call);
1129 }
1130 
1131 void
SendStartSetStateRCB(Widget w,XtPointer call,WSMReply * reply,WSMErrorCode error)1132 SendStartSetStateRCB(Widget w, XtPointer call,
1133 		     WSMReply *reply, WSMErrorCode error)
1134 {
1135   WSMRequest request;
1136   if (reply != NULL)
1137   {
1138     if (reply->any.type == WSM_GET_STATE && config_format_reply != NULL)
1139       {
1140 	CreateStartStateRequest(&(reply->get_state),
1141 				&request);
1142 	WSMSendMessage(utmShell, WSM_WINDOW_MANAGER, &request,
1143 		       ReceiveSetStateRCB, call);
1144       }
1145   }
1146 }
1147 
1148 
1149 void
ReceiveSetStateRCB(Widget w,XtPointer call,WSMReply * reply,WSMErrorCode error)1150 ReceiveSetStateRCB(Widget w, XtPointer call,
1151 		     WSMReply *reply, WSMErrorCode error)
1152 {
1153   Atom mwm_selection;
1154   WorkWindow *w_window;
1155 
1156   SetInitialCommands();
1157   w_window = work_windows;
1158   for (w_window = work_windows; w_window != NULL; w_window = w_window->next)
1159     if (w_window->s_list != NULL)
1160       if (w_window->s_list->next == NULL)
1161 	DisableDeleteCommand(w_window->window);
1162 
1163   connected = True;
1164   mwm_gone = False;
1165   mwm_reconnect = False;
1166   mwm_selection = _WSMGetSelectionAtom(dsp,
1167                   XScreenNumberOfScreen(XtScreen(shell)),WSM_WINDOW_MANAGER);
1168   mwm_window = XGetSelectionOwner(dsp, mwm_selection);
1169   if ( mwm_window != None)
1170     {
1171       XSelectInput(dsp,mwm_window,StructureNotifyMask);
1172     }
1173   PRINT("CONNECTED!\n");
1174 }
1175 
1176 
1177 
1178 
1179 void
SendSaveWsm(char * file_name)1180 SendSaveWsm(char *file_name)
1181 {
1182   WSMRequest request;
1183   request.get_state.window = 0;
1184   request.get_state.diffs_allowed = False;
1185   request.any.type = WSM_GET_STATE;
1186   PRINT("wsm:  WSMSendMessage WSM_GET_STATE %s\n", file_name);
1187   WSMSendMessage(utmShell, WSM_WINDOW_MANAGER, &request, ReceiveSaveWsmRCB,
1188 		 (XtPointer)file_name);
1189 }
1190 
1191 
1192 
1193 void
SendLeaveRoom(Space * s)1194 SendLeaveRoom(Space *s)
1195 {
1196   WSMRequest request;
1197   request.get_state.window = 0;
1198   request.get_state.diffs_allowed = False;
1199   request.any.type = WSM_GET_STATE;
1200   PRINT("wsm:  WSMSendMessage WSM_GET_STATE\n");
1201   WSMSendMessage(utmShell, WSM_WINDOW_MANAGER, &request, ReceiveLeaveRoomRCB,
1202 		 (XtPointer)s);
1203 }
1204 
1205 
1206 void
ReceiveSaveWsmRCB(Widget w,XtPointer client,WSMReply * reply,WSMErrorCode error)1207 ReceiveSaveWsmRCB(Widget w, XtPointer client,
1208 	     WSMReply *reply, WSMErrorCode error)
1209 {
1210   char *file_name = (char*) client;
1211   if (reply != NULL)
1212     {
1213       if (reply->any.type == WSM_GET_STATE)
1214 	{
1215 	  PRINT("wsm: save\n");
1216 	  SaveState(&(reply->get_state),False);
1217 	  PRINT("wsm:        done\n\n");
1218 	}
1219     }
1220   UpdateXrm();
1221   SaveWsmToFile(file_name);
1222 }
1223 
1224 
1225 
1226 void
ReceiveLeaveRoomRCB(Widget w,XtPointer client,WSMReply * reply,WSMErrorCode error)1227 ReceiveLeaveRoomRCB(Widget w, XtPointer client,
1228 	     WSMReply *reply, WSMErrorCode error)
1229 {
1230   if (reply != NULL)
1231     {
1232       if (reply->any.type == WSM_GET_STATE)
1233 	{
1234 	  PRINT("wsm: save\n");
1235 	  SaveState(&(reply->get_state),False);
1236 	  PRINT("wsm:        done\n\n");
1237 	    ChangeRoomCB(w,client,NULL);
1238 	}
1239     }
1240 }
1241 
1242 void
ReceiveEnterRoomRCB(Widget w,XtPointer client,WSMReply * reply,WSMErrorCode error)1243 ReceiveEnterRoomRCB(Widget w, XtPointer client,
1244 	     WSMReply *reply, WSMErrorCode error)
1245 {
1246   PRINT("finished entering room\n");
1247 }
1248 
1249 void
ChangeRoomCB(Widget w,XtPointer client,XtPointer call)1250 ChangeRoomCB(Widget w, XtPointer client, XtPointer call)
1251 {
1252   WSMRequest request;
1253   Space *space = (Space*)client;
1254 
1255   PRINT("wsm: Get SET_STATE request\n");
1256 
1257   if (space != NULL)
1258     {
1259       GetChangeSpaceRequest(space,&request);
1260       WSMSendMessage(utmShell, WSM_WINDOW_MANAGER, &request,
1261 		     ReceiveEnterRoomRCB, NULL);
1262       SetSpaceBackground(space);
1263     }
1264 
1265 }
1266 
1267 void
ReceiveCopyMoveRCB(Widget w,XtPointer client,WSMReply * reply,WSMErrorCode error)1268 ReceiveCopyMoveRCB(Widget w, XtPointer client,
1269 	     WSMReply *reply, WSMErrorCode error)
1270 {
1271  PRINT("receive copy/move\n");
1272 }
1273 
1274 void
CopyWindow(WorkWindow * w_window,Space * from_s,Space * to_s)1275 CopyWindow(WorkWindow *w_window, Space *from_s, Space* to_s)
1276 {
1277   WSMRequest request;
1278   CopyStruct *copy_struct;
1279 
1280   from_space = from_s;
1281   to_space = to_s;
1282   PrintAllSpaces();
1283   if (w_window != NULL)
1284     {
1285       print_window(w_window);
1286       if (from_space == current_space && w_window->mapped)
1287 	{
1288 	  copy_struct = (CopyStruct *)XtMalloc(sizeof(CopyStruct));
1289 	  copy_struct->window = w_window->window;
1290 	  copy_struct->to_space = to_s;
1291 	  copy_struct->from_space = from_s;
1292 	  request.get_state.window = w_window->window;
1293 	  request.get_state.diffs_allowed = True;
1294 	  request.any.type = WSM_GET_STATE;
1295 	  PRINT("Sending Get State \n");
1296 	  WSMSendMessage(utmShell, WSM_WINDOW_MANAGER, &request, CopyRCB,
1297 			 (XtPointer)copy_struct);
1298 	}
1299       else if (GetCopyWindowRequest(w_window->window, from_space, to_space,
1300 				    &request))
1301 	WSMSendMessage(utmShell, WSM_WINDOW_MANAGER, &request,
1302 		       ReceiveCopyMoveRCB, NULL);
1303     }
1304   else PRINT("copy null window\n");
1305 }
1306 
1307 
1308 void
CopyRCB(Widget w,XtPointer client,WSMReply * reply,WSMErrorCode error)1309 CopyRCB(Widget w, XtPointer client,
1310 	     WSMReply *reply, WSMErrorCode error)
1311 {
1312   WSMRequest request;
1313   CopyStruct *copy_struct = (CopyStruct*)client;
1314   PRINT("Received get state\n");
1315   if (reply != NULL)
1316     {
1317       if (reply->any.type == WSM_GET_STATE)
1318 	{
1319 	  PRINT("calling SaveState\n");
1320 	  SaveState(&(reply->get_state), True);
1321 	}
1322       if (GetCopyWindowRequest(copy_struct->window, copy_struct->from_space,
1323 			       copy_struct->to_space, &request))
1324 	WSMSendMessage(utmShell, WSM_WINDOW_MANAGER, &request,
1325 		       ReceiveCopyMoveRCB, NULL);
1326     }
1327   XtFree((XtPointer)copy_struct);
1328 }
1329 
1330 void
MoveWindow(WorkWindow * w_window,Space * from_s,Space * to_s)1331 MoveWindow(WorkWindow *w_window, Space *from_s, Space* to_s)
1332 {
1333   WSMRequest request;
1334 
1335   from_space = from_s;
1336   to_space = to_s;
1337 
1338   if (w_window != NULL)
1339     {
1340       if (from_space == current_space)
1341 	{
1342 	  request.get_state.window = w_window->window;
1343 	  request.get_state.diffs_allowed = True;
1344 	  request.any.type = WSM_GET_STATE;
1345 	  WSMSendMessage(utmShell, WSM_WINDOW_MANAGER, &request, MoveRCB,
1346 			 (XtPointer)w_window->window);
1347 	}
1348       else if (GetMoveWindowRequest(w_window->window, from_space, to_space,
1349 				    &request))
1350 	WSMSendMessage(utmShell, WSM_WINDOW_MANAGER, &request,
1351 		       ReceiveCopyMoveRCB, NULL);
1352     }
1353 }
1354 
1355 void
MoveRCB(Widget w,XtPointer client,WSMReply * reply,WSMErrorCode error)1356 MoveRCB(Widget w, XtPointer client,
1357 	     WSMReply *reply, WSMErrorCode error)
1358 {
1359     WSMRequest request;
1360 
1361     if (reply != NULL)
1362     {
1363 	SaveState(&(reply->get_state), True);
1364 	if (GetMoveWindowRequest((Window)client, from_space, to_space,
1365 				 &request))
1366 	{
1367 	    WSMSendMessage(utmShell, WSM_WINDOW_MANAGER, &request,
1368 			   ReceiveCopyMoveRCB, NULL);
1369 	}
1370     }
1371 }
1372 
1373 
1374 
1375 
1376 void
DeleteWindow(WorkWindow * w_window,Space * from_s)1377 DeleteWindow(WorkWindow *w_window, Space *from_s)
1378 {
1379   WSMRequest request;
1380 
1381   from_space = from_s;
1382 
1383   if (w_window != NULL)
1384     {
1385       if (GetDeleteWindowRequest(w_window->window, from_space,&request))
1386 	WSMSendMessage(utmShell, WSM_WINDOW_MANAGER, &request,
1387 		       ReceiveCopyMoveRCB, NULL);
1388     }
1389 
1390 }
1391 
1392 void
LinkWindow(WorkWindow * w_window,Space * from_s,Space * to_s)1393 LinkWindow(WorkWindow *w_window, Space *from_s, Space *to_s)
1394 {
1395   WSMRequest request;
1396   CopyStruct *copy_struct;
1397   from_space = from_s;
1398   to_space = to_s;
1399 
1400   if (w_window != NULL)
1401     {
1402       if (from_space == current_space)
1403 	{
1404 	  copy_struct = (CopyStruct *)XtMalloc(sizeof(CopyStruct));
1405 	  copy_struct->window = w_window->window;
1406 	  copy_struct->to_space = to_s;
1407 	  copy_struct->from_space = from_s;
1408 	  request.get_state.window = w_window->window;
1409 	  request.get_state.diffs_allowed = True;
1410 	  request.any.type = WSM_GET_STATE;
1411 	  WSMSendMessage(utmShell, WSM_WINDOW_MANAGER, &request, LinkRCB,
1412 			 (XtPointer)copy_struct);
1413 	}
1414       else if (GetLinkWindowRequest(w_window->window, from_space, to_space,
1415 				    &request))
1416 	WSMSendMessage(utmShell, WSM_WINDOW_MANAGER, &request,
1417 		       ReceiveCopyMoveRCB, NULL);
1418     }
1419   else PRINT("copy null window\n");
1420 }
1421 
1422 
1423 void
LinkRCB(Widget w,XtPointer client,WSMReply * reply,WSMErrorCode error)1424 LinkRCB(Widget w, XtPointer client,
1425 	     WSMReply *reply, WSMErrorCode error)
1426 {
1427   WSMRequest request;
1428   CopyStruct *copy_struct = (CopyStruct*)client;
1429 
1430   if (reply != NULL)
1431   {
1432       SaveState(&(reply->get_state),True);
1433       if (GetLinkWindowRequest(copy_struct->window, copy_struct->from_space,
1434 			       copy_struct->to_space, &request))
1435 	  WSMSendMessage(utmShell, WSM_WINDOW_MANAGER, &request,
1436 			 ReceiveCopyMoveRCB, NULL);
1437   }
1438   XtFree((XtPointer)copy_struct);
1439 }
1440 
1441 /* This function doesn't appear to be used anywhere */
1442 #ifdef notdef
1443 void
BackgroundRCB(Widget w,XtPointer client,WSMReply * reply,WSMErrorCode error)1444 BackgroundRCB(Widget w, XtPointer client,
1445 	     WSMReply *reply, WSMErrorCode error)
1446 {
1447   Window windowID = reply->get_background.window;
1448   GC gc;
1449   unsigned int root_width, root_height;
1450   XGCValues values;
1451   Window rootWindow = XRootWindowOfScreen(XtScreen(shell));
1452   gc = XCreateGC(dsp,rootWindow,0,&values);
1453   XSetBackground(dsp,gc,WhitePixel(dsp,0));
1454   PRINT("background reply returned. %d %d\n", windowID, rootWindow);
1455   XFillRectangle(dsp,rootWindow,gc,0,0,root_width,root_height);
1456 }
1457 #endif
1458 
1459 
1460 void
SetSpaceBackground(Space * space)1461 SetSpaceBackground(Space *space)
1462 {
1463   if (SpacePixelSet(space))
1464     {
1465       PRINT("setting background color\n");
1466       XSetWindowBackground(dsp, XRootWindowOfScreen(XtScreen(shell)),
1467 			   space->pixel);
1468       XClearWindow(dsp,XRootWindowOfScreen(XtScreen(shell)));
1469     }
1470   else if (SpacePixmapSet(space))
1471     {
1472       PRINT("setting background pixmap\n");
1473       XSetWindowBackgroundPixmap(dsp,XRootWindowOfScreen(XtScreen(shell)),
1474 				 space->pixmap);
1475       XClearWindow(dsp,XRootWindowOfScreen(XtScreen(shell)));
1476     }
1477 
1478 }
1479 void
QuitCB(Widget w,XtPointer client,XtPointer call)1480 QuitCB(Widget w, XtPointer client, XtPointer call)
1481 {
1482   PRINT("QUITCB\n");
1483   ManageAllWindowsAndExit();
1484 }
1485 
1486 void
ManageAllWindowsAndExit()1487 ManageAllWindowsAndExit()
1488 {
1489   WSMRequest request;
1490   PRINT("ManageAllWindowsAndExit()\n");
1491   if (!mwm_gone)
1492     {
1493       if (GetManageAllWindowsRequest(&request))
1494 	WSMSendMessage(utmShell, WSM_WINDOW_MANAGER, &request, ExitRCB, NULL);
1495       else
1496 	CleanUpAndExit();
1497     }
1498   else exit(0);
1499 }
1500 
1501 
1502 void
ExitRCB(Widget w,XtPointer client,WSMReply * reply,WSMErrorCode error)1503 ExitRCB(Widget w, XtPointer client,
1504 	     WSMReply *reply, WSMErrorCode error)
1505 {
1506     CleanUpAndExit();
1507 }
1508 
CleanUpAndExit()1509 void CleanUpAndExit()
1510 {
1511     if (!mwm_gone)
1512 	RemoveAllCommandsAndExit();
1513 }
1514 
1515 /*************************************<->*************************************
1516  *
1517  *  SetupWsmSignalHandlers ()
1518  *
1519  *
1520  *  Description:
1521  *  -----------
1522  *  This function sets up the signal handlers for the workspace manager.
1523  *
1524  *************************************<->***********************************/
1525 
1526 /*ARGSUSED*/
SetupWsmSignalHandlers(int dummy)1527 static void SetupWsmSignalHandlers (int dummy)
1528 {
1529     void (*signalHandler) ();
1530 
1531 
1532     signalHandler = (void (*)())signal (SIGINT, SIG_IGN);
1533     if (signalHandler != (void (*)())SIG_IGN)
1534     {
1535 	signal (SIGINT, QuitWsmSignalHandler);
1536     }
1537 
1538     signalHandler = (void (*)())signal (SIGHUP, SIG_IGN);
1539     if (signalHandler != (void (*)())SIG_IGN)
1540     {
1541 	signal (SIGHUP, QuitWsmSignalHandler);
1542     }
1543 
1544     signal (SIGQUIT, QuitWsmSignalHandler);
1545 
1546     signal (SIGTERM, QuitWsmSignalHandler);
1547 
1548 
1549 } /* END OF FUNCTION SetupWsmSignalHandlers */
1550 
1551 
1552 /*************************************<->*************************************
1553  *
1554  *  QuitWsmSignalHandler ()
1555  *
1556  *
1557  *  Description:
1558  *  -----------
1559  *  This function is called on receipt of a signal that is to terminate the
1560  *  workspace manager.
1561  *
1562  *************************************<->***********************************/
1563 
1564 /*ARGSUSED*/
QuitWsmSignalHandler(int dummy)1565 static void QuitWsmSignalHandler (int dummy)
1566 {
1567     ManageAllWindowsAndExit();
1568     XFlush(dsp);
1569 } /* END OF FUNCTION QuitWsmSignalHandler */
1570