Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / programs / dtsession / SmCommun.c
1 /* $TOG: SmCommun.c /main/14 1999/09/20 13:47:25 mgreess $ */
2 /* 
3  * (c) Copyright 1997, The Open Group 
4  */
5 /*************************************<+>*************************************
6  *****************************************************************************
7  **
8  **  File:        SmCommun.c
9  **
10  **  Project:     HP DT Session Manager (dtsession)
11  **
12  **  Description:
13  **  -----------
14  **  This file contains functionality needed to communicate with the
15  **  other DT components.  This includes initialization and callback code.
16  **
17  *****************************************************************************
18  *************************************<+>*************************************/
19 /*                                                               
20  * (c) Copyright 1996 Digital Equipment Corporation.
21  * (c) Copyright 1990, 1993, 1994, 1996 Hewlett-Packard Company        
22  * (c) Copyright 1993, 1994, 1996 International Business Machines Corp.       
23  * (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc.                      
24  * (c) Copyright 1993, 1994, 1996 Novell, Inc.                                
25  * (c) Copyright 1996 FUJITSU LIMITED.
26  * (c) Copyright 1996 Hitachi.
27  */
28
29 #include <stdio.h>
30 #ifdef _SUN_OS /* for the strtok calls */
31 #include <string.h>
32 #endif
33 #include <X11/Intrinsic.h>
34 #include <X11/StringDefs.h>
35 #if defined (USE_X11SSEXT)
36 #include <X11/extensions/scrnsaver.h>
37 #endif /* USE_X11SSEXT */
38 #include <Xm/Xm.h>
39 #include <Dt/DtP.h>
40 #include <Dt/Action.h>
41 #include <Dt/SessionM.h>
42 #include <Dt/UserMsg.h>
43 #include <Dt/Indicator.h>
44 #include <Dt/MsgLog.h>
45 #include <Tt/tttk.h>
46 #include "Sm.h"
47 #include "SmError.h"
48 #include "SmLock.h"
49 #include "SmCommun.h"
50 #include "SmRestore.h"
51 #include "SmSave.h"
52 #include "SmUI.h"
53 #include "SmProtocol.h"
54 #include "SmGlobals.h"
55 #include "SmXSMP.h"
56
57 /*
58  * Pulic var declarations
59  */
60 extern int  clientRunning; /* from SmConMgmt.c */
61 extern char **smExecArray;
62
63 /*
64  * Defines for this file only
65  */
66 #define SS_ON           0
67 #define SS_OFF          1
68 #define SS_DRAW         2
69
70 /*
71  * Constants for the Save_Session ToolTalk message
72  */
73 static const char *SAVE_TYPE            = "save_type";
74 static const char *SHUTDOWN             = "shutdown";
75 static const char *INTERACT_STYLE       = "interact_style";
76 static const char *FAST                 = "fast";
77 static const char *GLOBAL               = "global";
78 static const char *NUM_BACKUPS          = "num_sessions_backedup";
79 static const char *SAVE_LOCAL           = "Local";
80 static const char *SAVE_GLOBAL          = "Global";
81 static const char *SAVE_BOTH            = "Both";
82 static const char *INTERACT_NONE        = "None";
83 static const char *INTERACT_ERRORS      = "Errors";
84 static const char *TRUE_STR             = "True";
85 static const char *FALSE_STR            = "False";
86
87 /*
88  * Local function definitions
89  */
90
91 static void DtwmStarted(void);
92
93 static void
94 ProcessSaveSessionMessage (
95         Tt_message              saveMsg )
96 {
97         int                     i;
98
99         int                     saveType = -1;
100         Boolean                 shutdown = DEFAULT_SHUTDOWN;
101         int                     interactStyle = DEFAULT_INTERACT_STYLE;
102         Boolean                 fast = DEFAULT_FAST;
103         Boolean                 global = DEFAULT_GLOBAL;
104         int                     numSessionsBackedup;
105
106         char                    * type;
107         char                    * value;
108         int                     num_args = tt_message_args_count (saveMsg);
109
110         Tt_message              tmpMsg;
111         Tt_status               status;
112
113         for (i = 0; i < num_args; i++) {
114
115                 type  = tt_message_arg_type  (saveMsg, i);
116                 status = tt_ptr_error (type);
117                 if (status != TT_OK || type == NULL)
118                         continue;
119
120                 value = tt_message_arg_val (saveMsg, i);
121                 status = tt_ptr_error (value);
122                 if (status != TT_OK || value == NULL)
123                         continue;
124
125                 if (!strcmp (type, SAVE_TYPE)) {
126                         if (!strcmp (value, SAVE_LOCAL))
127                                 saveType = SmSaveLocal;
128                         else if (!strcmp (value, SAVE_GLOBAL))
129                                 saveType = SmSaveGlobal;
130                         else if (!strcmp (value, SAVE_BOTH))
131                                 saveType = SmSaveBoth;
132                         else  {
133                                 tt_free (type);
134                                 tt_free (value);
135                                 break;
136                         }
137                 }
138                 else if (!strcmp (type, SHUTDOWN)) {
139                         if (!strcmp (value, TRUE_STR))
140                                  shutdown = True;
141                         else if (!strcmp (value, FALSE_STR))
142                                  shutdown = False;
143                 }
144                 else if (!strcmp (type, INTERACT_STYLE)){
145                         if (!strcmp (value, INTERACT_NONE))
146                                 interactStyle = SmInteractStyleNone;
147                         else if (!strcmp (value, INTERACT_ERRORS))
148                                 interactStyle = SmInteractStyleErrors;
149                 }
150                 else if (!strcmp (type, FAST)) {
151                         if (!strcmp (value, TRUE_STR))
152                                  fast = True;
153                         else if (!strcmp (value, FALSE_STR))
154                                  fast = False;
155                 }
156                 else if (!strcmp (type, GLOBAL)) {
157                         if (!strcmp (value, TRUE_STR))
158                                  global = True;
159                         else if (!strcmp (value, FALSE_STR))
160                                  global = False;
161                 }
162                 else if (!strcmp (type, NUM_BACKUPS)) {
163                         numSessionsBackedup = atoi (value);
164                         if (numSessionsBackedup > 0)
165                                 smRes.numSessionsBackedup = numSessionsBackedup;
166                 }
167                 else {
168                         char            *pch1;
169                         char            *pch2;
170
171                         pch1 = strdup ((char *) GETMESSAGE (40, 16,
172                                 "The Save_Session message contains the unrecognized argument '%s'."));
173                         if (pch1) {
174                                 pch2 = XtMalloc (strlen (pch1)+strlen (type)+3);
175                                 if (pch2) {
176                                         (void) sprintf (pch2, pch1, type);
177                                         DtMsgLogMessage (smGD.programName, 
178                                                 DtMsgLogWarning, pch2);
179                                         free (pch1); free (pch2);
180                                 }
181                                 else {
182                                         free (pch1);
183                                 }
184                         }
185                 }
186
187                 tt_free (type);
188                 tt_free (value);
189         }
190
191         if (saveType == -1) {
192                 PostSaveSessionErrorDialog ();
193                 return;
194         }
195
196         smGD.smState = IN_PROCESS;
197         tmpMsg = tttk_message_create (0, TT_NOTICE, TT_SESSION, 0,
198                                    "DtActivity_Beginning", 0);
199         tt_message_send (tmpMsg);
200         tt_message_destroy (tmpMsg);
201
202         SaveState ((smGD.sessionType == HOME_SESSION), 
203                         smSettings.startState, saveType, shutdown,
204                         interactStyle, fast, global);
205
206         tmpMsg = tttk_message_create (0, TT_NOTICE, TT_SESSION, 0,
207                                    "DtActivity_Began", 0);
208         tt_message_send (tmpMsg);
209         tt_message_destroy (tmpMsg);
210
211         SetSystemReady ();
212 }
213
214 \f
215 /*************************************<->*************************************
216  *
217  *  handleSessionMgrRequest ()
218  *
219  *
220  *  Description:
221  *  -----------
222  *  Handle ToolTalk requests for which the session manager is responsible.
223  *
224  *
225  *  Inputs:
226  *  ------
227  *  Incoming request, and the pattern it matched.
228  *
229  * 
230  *  Outputs:
231  *  -------
232  *  Whether the message has been consumed.
233  *
234  *
235  *  Comments:
236  *  --------
237  * 
238  *************************************<->***********************************/
239 Tt_callback_action
240 handleSessionMgrRequest(
241         Tt_message msg,
242         Tt_pattern pat
243 )
244 {
245   char *op;
246   Tt_status status;
247   Tt_callback_action rc;
248   Boolean destroyMsg;
249
250   if (tt_message_state( msg ) != TT_SENT) 
251   {
252     /* msg is a reply to ourself */
253     return TT_CALLBACK_CONTINUE;
254   }
255
256   op = tt_message_op( msg );
257   status = tt_ptr_error( op );
258   if ((status != TT_OK) || (op == 0)) 
259   {
260     /* Let tttk_Xt_input_handler() Do The Right Thing */
261     return TT_CALLBACK_CONTINUE;
262   }
263     
264   destroyMsg = True;
265   if (strcmp( op, SM_DISPLAY_LOCK ) == 0) 
266   {
267     if(smGD.smState == READY) 
268     {
269       smGD.smState = IN_PROCESS;
270       LockDisplay(True);
271     }
272     rc = TT_CALLBACK_PROCESSED;
273   }
274   else if (strcmp( op, SM_XSESSION_EXIT ) == 0) 
275   {
276     if(smGD.smState == READY) 
277     {
278       smGD.smState = IN_PROCESS;
279       ExitSession( msg );
280       /*
281        * The session may have been canceled so set the smState
282        * back to ready.
283        */
284       smGD.smState = READY;
285       destroyMsg = False; /* done in SmUI.c */
286     }
287     rc = TT_CALLBACK_PROCESSED;
288   } 
289   else if (strcmp( op, SM_RESOURCES_RELOAD ) == 0) 
290   {
291     if(smGD.smState == READY) 
292     {
293       smGD.smState = IN_PROCESS;
294       ReloadResources();
295     }
296     rc = TT_CALLBACK_PROCESSED;
297   } 
298   else if (strcmp( op, SM_SAVE_SESSION ) == 0) 
299   {
300     if(smGD.smState == READY) 
301     {
302       smGD.smState = IN_PROCESS;
303       ProcessSaveSessionMessage (msg);
304     }
305     rc = TT_CALLBACK_PROCESSED;
306   } 
307   else 
308   {
309     rc = TT_CALLBACK_CONTINUE;
310     destroyMsg = False;
311   }
312
313   if (destroyMsg == True)
314   {
315     tt_message_reply( msg );
316     tt_message_destroy( msg );
317   }
318         
319   tt_free( op );
320   return (rc);
321 }
322
323 \f
324 /*************************************<->*************************************
325  *
326  *  StartMsgServer ()
327  *
328  *
329  *  Description:
330  *  -----------
331  *  Initialize the BMS and register the session manager with it.  Then
332  *  register all requests and notifications that the session manager is
333  *  interested in.
334  *
335  *
336  *  Inputs:
337  *  ------
338  *  app = Application context for dtsession
339  *
340  * 
341  *  Outputs:
342  *  -------
343  *
344  *
345  *  Comments:
346  *  --------
347  * 
348  *************************************<->***********************************/
349 void 
350 StartMsgServer(void)
351 {
352     Boolean     makeConnect;
353     String      tmpString;
354     char *      sessId;
355     char *      procId;
356     int         fd;
357     Tt_status   status;
358     
359     /*
360      * Before we start anything - initialize the customize data structure
361      */
362     smCust.screenSavChange = False;
363     smCust.audioChange = False;
364     smCust.keyboardChange = False;
365     smCust.fontChange = False;
366     smCust.pointerChange = False;
367     smCust.dClickChange = False;
368     smCust.preeditChange = False;
369     
370     makeConnect = DtAppInitialize(smGD.appCon, smGD.display, smGD.topLevelWid,
371                                   SM_RESOURCE_NAME,
372                                   DtSM_TOOL_CLASS);
373
374     smDD.okString = XmStringCreateLocalized(((char *)GETMESSAGE(18, 39, "OK")));
375     smDD.okLogoutString = XmStringCreateLocalized(((char *)GETMESSAGE(18, 39, "OK")));
376     smDD.cancelLogoutString = XmStringCreateLocalized(((char *)GETMESSAGE(18,40, "Cancel")));
377     smDD.helpString = XmStringCreateLocalized(((char *)GETMESSAGE(18, 41, "Help")));
378
379     if(makeConnect == False)
380     {
381         smGD.bmsDead = True;
382     }
383     else
384     {
385         smGD.bmsDead = False;
386     }
387
388     procId = tt_open();
389     status = tt_ptr_error( procId );
390     if (status == TT_OK) {
391         fd = tt_fd();
392         status = tt_int_error( fd );
393         if (status == TT_OK) {
394             XtAppAddInput( smGD.appCon, fd, (XtPointer)XtInputReadMask,
395                            tttk_Xt_input_handler, procId );
396         }
397     }
398     if (status != TT_OK) {
399         smGD.bmsDead = True;
400     }
401
402     smGD.requests2Handle = 0;
403     if (status == TT_OK) {
404         smGD.requests2Handle = tt_pattern_create();
405         tt_pattern_category_set( smGD.requests2Handle, TT_HANDLE );
406         tt_pattern_class_add( smGD.requests2Handle, TT_REQUEST );
407         tt_pattern_scope_add( smGD.requests2Handle, TT_SESSION );
408         sessId = tt_default_session();
409         tt_pattern_session_add( smGD.requests2Handle, sessId );
410         tt_free( sessId );
411         tt_pattern_op_add( smGD.requests2Handle, SM_DISPLAY_LOCK );
412         tt_pattern_op_add( smGD.requests2Handle, SM_XSESSION_EXIT );
413         tt_pattern_op_add( smGD.requests2Handle, SM_RESOURCES_RELOAD );
414         tt_pattern_op_add( smGD.requests2Handle, SM_SAVE_SESSION );
415         tt_pattern_callback_add( smGD.requests2Handle,
416                                  handleSessionMgrRequest );
417         status = tt_pattern_register( smGD.requests2Handle );
418         if (status != TT_OK) {
419             smGD.bmsDead = True;
420         }
421     }
422
423     if (smGD.bmsDead) {
424         char    *errfmt, *errmsg, *statmsg;
425
426         errfmt = SmNewString((char *) GETMESSAGE (6, 1, 
427           "Could not connect to ToolTalk message server:\n%sExiting ...\n"));
428         statmsg = tt_status_message(status);
429         errmsg = XtMalloc(strlen(errfmt) + strlen(statmsg) + 2);
430         sprintf(errmsg, errfmt, statmsg);
431
432         PrintError(DtError, errmsg);
433         SM_FREE(errfmt);
434         XtFree(errmsg);
435         WarnNoStartup();
436     }
437 } /* END OF FUNCTION StartMsgServer  */
438
439 \f
440 /*************************************<->*************************************
441  *
442  *  DtwmStarted (fields, client_data, num_words)
443  *
444  *
445  *  Description:
446  *  -----------
447  *
448  *  Inputs:
449  *  ------
450  *
451  * 
452  *  Outputs:
453  *  -------
454  *
455  *
456  *  Comments:
457  *  --------
458  * 
459  *************************************<->***********************************/
460 static void 
461 DtwmStarted()
462 {
463     smGD.dtwmRunning = True;
464 } /* END OF FUNCTION  DtwmStarted */
465
466 \f
467 /*************************************<->*************************************
468  *
469  *  RestoreDefaults ()
470  *
471  *
472  *  Description:
473  *  -----------
474  *  A request has come in (usually from the customizer) to restore one of
475  *  the settings to their default states
476  *
477  *  Inputs:
478  *  ------
479  *
480  * 
481  *  Outputs:
482  *  -------
483  *  smToSet = (global) turns off flag of setting no longer set
484  *
485  *
486  *  Comments:
487  *  --------
488  * 
489  *************************************<->***********************************/
490 void 
491 RestoreDefaults(
492                 Atom toRestore)
493 {
494
495   if(toRestore == XaDtSmScreenInfo)
496   {
497     smToSet.screenSavChange = False;
498   }
499   else if(toRestore == XaDtSmAudioInfo)
500   {
501     smToSet.audioChange = False;
502   }
503   else if(toRestore == XaDtSmKeyboardInfo)
504   {
505     smToSet.keyboardChange = False;
506   }
507   else if(toRestore == XaDtSmPointerInfo)
508   {
509     smToSet.pointerChange = False;
510     smToSet.pointerMapChange = False;
511   }
512 } /* END OF FUNCTION RestoreDefaults  */
513
514 \f
515 /*************************************<->*************************************
516  *
517  *  ProcessPropertyNotify ()
518  *
519  *
520  *  Description:
521  *  -----------
522  *  The customizer has changed one of the properties on the sm top level
523  *  window.  This fact is remembered, so that at shutdown the information
524  *  can be saved
525  *
526  *  Inputs:
527  *  ------
528  *
529  * 
530  *  Outputs:
531  *  -------
532  *  smToSet = (global) turns on flag of setting being set
533  *
534  *
535  *  Comments:
536  *  --------
537  * 
538  *************************************<->***********************************/
539 void 
540 ProcessPropertyNotify(
541         XEvent *next)
542 {
543   XPropertyEvent *pEvent = (XPropertyEvent *) next;
544
545   if (pEvent->state != PropertyNewValue)
546   {
547     return;
548   }
549
550   if(pEvent->atom == XaDtSmScreenInfo)
551   {
552     smToSet.screenSavChange = True;
553     smCust.screenSavChange = True;
554   }
555   else if(pEvent->atom == XaDtSmAudioInfo)
556   {
557     smToSet.audioChange = True;
558     smCust.audioChange = True;
559   }
560   else if(pEvent->atom == XaDtSmKeyboardInfo)
561   {
562     smToSet.keyboardChange = True;
563     smCust.keyboardChange = True;
564   }
565   else if(pEvent->atom == XaDtSmFontInfo)
566   {
567     smCust.fontChange = True;
568   }
569   else if(pEvent->atom == XaDtSmPreeditInfo)
570   {
571     smCust.preeditChange = True;
572   }
573   else if(pEvent->atom == XaDtSmPointerInfo)
574   {
575     smToSet.pointerChange = True;
576     smCust.pointerChange = True;
577     smToSet.pointerMapChange = True;
578     smCust.dClickChange = True;
579   }
580 } /* END OF FUNCTION RecordChanges   */
581
582
583 \f
584 /*************************************<->*************************************
585  *
586  *  ProcessClientMessage(next)
587  *
588  *
589  *  Description:
590  *  -----------
591  *  A client message has come from somewhere.  Process it if we know how.
592  *
593  *  Inputs:
594  *  ------
595  *  next - the client message event
596  *
597  * 
598  *  Outputs:
599  *  -------
600  *
601  *
602  *  Comments:
603  *  --------
604  * 
605  *************************************<->***********************************/
606 void 
607 ProcessClientMessage(
608                      XEvent *next)
609 {
610   XClientMessageEvent   *cEvent = (XClientMessageEvent *) next;
611
612  /*
613   * If this event came from the style manager - process it
614   */
615   if(cEvent->message_type == XaDtSmStmProtocol)
616   {
617     if(cEvent->data.l[0] == XaDtSmSaveToHome)
618     {
619      /*
620       * The style manager is asking for a save home session
621       */
622       if(smGD.smState == READY)
623       {
624         int startStateOrig;
625         int confirmModeOrig;
626         Tt_message msg;
627
628         smGD.smState = IN_PROCESS;
629         msg = tttk_message_create( 0, TT_NOTICE, TT_SESSION, 0,
630                                    "DtActivity_Beginning", 0 );
631         tt_message_send( msg );
632         tt_message_destroy( msg );
633
634         startStateOrig = smSettings.startState;
635         confirmModeOrig = smSettings.confirmMode;
636
637         smSettings.startState = cEvent->data.l[1];
638         smSettings.confirmMode = cEvent->data.l[2];;
639                 
640         smGD.homeSave = True;
641         SaveState(True, smSettings.startState, SmSaveLocal,
642                         DEFAULT_SHUTDOWN, SmInteractStyleNone,
643                         DEFAULT_FAST, DEFAULT_GLOBAL);
644         smGD.homeSave = False;
645
646         smSettings.startState = startStateOrig;
647         smSettings.confirmMode = confirmModeOrig;
648
649         msg = tttk_message_create( 0, TT_NOTICE, TT_SESSION, 0,
650                                    "DtActivity_Began", 0 );
651         tt_message_send( msg );
652         tt_message_destroy( msg );
653         SetSystemReady();
654       }
655     }
656     else if (cEvent->data.l[0] == XaDtSmRestoreDefault)
657     {
658       RestoreDefaults((Atom) cEvent->data.l[1]);
659     }
660   }
661   else if(cEvent->message_type == XaSmWmProtocol)
662   {
663    /*
664     * If this event came from the ws manager - process it
665     */
666     if(cEvent->data.l[0] == XaWmExitSession)
667     {
668      /*
669       * The ws manager is sending an exit session message
670       */
671       if(smGD.smState == READY)
672       {
673         smGD.smState = IN_PROCESS;
674         ExitSession(0);
675       }
676     }
677     else if(cEvent->data.l[0] == XaWmLockDisplay)
678     {
679      /*
680       * The ws manager is sending an lock display message
681       */
682       if(smGD.smState == READY)
683       {
684         smGD.smState = IN_PROCESS;
685         LockDisplay(True);
686       }
687     }
688     else if(cEvent->data.l[0] == XaWmWindowAck)
689     {
690      /*
691       * The ws manager is sending a "client has been managed"
692       */
693       clientRunning = True;
694     }
695     else if(cEvent->data.l[0] == XaWmReady)
696     {
697      /*
698       * The ws manager is sending a "ready for clients"
699       */
700       smGD.dtwmRunning = True;
701     }
702   }
703   else if (cEvent->message_type == XaDtSmStateInfo)
704   {
705     SmStateInfo state;
706     int flags = (int)cEvent->data.l[0];
707
708    /*
709     * Session state has been changed. Get new values.
710     */
711     if(_DtGetSmState(smGD.display, smGD.topLevelWindow, &state) == Success)
712     {
713       char *newRes = malloc(BUFSIZ);
714
715      /*
716       * Copy selected changes to data areas.
717       */
718       if (flags & SM_STATE_START)
719       {
720         smSettings.startState = state.smStartState;
721       }
722
723       if (flags & SM_STATE_CONFIRM)
724       {
725         smSettings.confirmMode = state.smConfirmMode;
726       }
727
728       newRes[0] = '\0';
729       if (flags & SM_STATE_CYCLETIMEOUT)
730       {
731         smSaverRes.cycleTimeout = state.smCycleTimeout;
732         sprintf(newRes+strlen(newRes), "dtsession*%scycleTimeout: %d\n",
733                 smGD.extensionSpec,
734                 smSaverRes.cycleTimeout/60);
735       }
736
737       if (flags & SM_STATE_LOCKTIMEOUT)
738       {
739         smSaverRes.lockTimeout = state.smLockTimeout;
740         sprintf(newRes+strlen(newRes), "dtsession*%slockTimeout: %d\n",
741                 smGD.extensionSpec,
742                 smSaverRes.lockTimeout/60);
743       }
744
745       if (flags & SM_STATE_SAVERTIMEOUT)
746       {
747         smSaverRes.saverTimeout = state.smSaverTimeout;
748         sprintf(newRes+strlen(newRes), "dtsession*%ssaverTimeout: %d\n",
749                 smGD.extensionSpec,
750                 smSaverRes.saverTimeout/60);
751       }
752
753       if (flags & SM_STATE_RANDOM)
754       {
755         smSaverRes.random = state.smRandom;
756         sprintf(newRes+strlen(newRes), "dtsession*%srandom: %s\n",
757                 smGD.extensionSpec,
758                 smSaverRes.random ? "True\n" : "False\n");
759       }
760
761       if (newRes[0] != '\0')
762       {
763         _DtAddToResource(smGD.display, newRes);
764       }
765
766       if (NULL != newRes) free(newRes);
767     }
768   }
769   else if (cEvent->message_type == XaDtSmSaverInfo)
770   {
771     SmSaverInfo saver;
772
773    /*
774     * Session screen saver list has been changed. Get new values.
775     */
776     if(_DtGetSmSaver(smGD.display, smGD.topLevelWindow, &saver) == Success)
777     {
778       char *pRes;
779
780       SM_FREE(smGD.saverList);
781       smGD.saverList = SmNewString(saver.saverList);
782       SM_FREE(saver.saverList);
783
784       pRes = malloc(strlen("dtsession*saverList: ") +
785                     strlen(smGD.saverList) +
786                     strlen(smGD.extensionSpec) +
787                     2); /* for the '/n' and '/0' */
788       if (pRes)
789       {
790         sprintf(pRes, "dtsession*%ssaverList: %s\n",
791                smGD.extensionSpec,
792                smGD.saverList);
793         _DtAddToResource(smGD.display, pRes);
794         free(pRes);
795       }
796
797       if (smGD.saverListParse)
798       {
799         SM_FREE(smGD.saverListParse);
800         smGD.saverListParse = NULL; 
801       }
802     }
803   }
804 #if defined (USE_HPSSEXT)
805   else if(cEvent->message_type == XaSmScreenSaveRet)
806   {
807     if(cEvent->data.l[0] == SS_ON)
808     {
809       if (smSaverRes.saverTimeout + smSaverRes.lockTimeout > 0 &&
810           smGD.smState == READY)
811       {
812         smGD.smState = IN_PROCESS;
813         LockDisplay(False);
814       }
815     }
816   }
817 #endif /* USE_HPSSEXT */
818
819   return;
820
821 } /* END OF FUNCTION ProcessClientMessage  */
822
823 /*************************************<->*************************************
824  *
825  *  ProcessScreenSaverMessage(next)
826  *
827  *
828  *  Description:
829  *  -----------
830  *  A screen saver message has come from the server.  Process it if we know how.
831  *
832  *  Inputs:
833  *  ------
834  *  next - the client message event
835  *
836  *
837  *  Outputs:
838  *  -------
839  *
840  *
841  *  Comments:
842  *  --------
843  *
844  *************************************<->***********************************/
845 #if defined (USE_X11SSEXT)
846
847 void
848 ProcessScreenSaverMessage(
849                      XEvent *next)
850 {
851   XScreenSaverNotifyEvent *ssEvent =  (XScreenSaverNotifyEvent *) next;
852   static int          ssCount = 0;
853
854   if (ssEvent->state == ScreenSaverOn)
855   { 
856    /*
857     * Screen saver activated. 
858     */
859     if (smSaverRes.saverTimeout + smSaverRes.lockTimeout > 0 &&
860         smGD.smState == READY)
861     {
862      /*
863       * Resource says to lock the display and SM is ready, so lock it.
864       */
865       smGD.smState = IN_PROCESS;
866       LockDisplay(False);
867     }
868   }
869 }
870 #endif /* USE_X11SSEXT */
871
872 /*************************************<->*************************************
873  *
874  *  ProcessReloadActionsDatabase(void)
875  *
876  *
877  *  Description:
878  *  -----------
879  *  Register for notification of action database changes and load the action
880  *  database into our address space. This function can be called directly
881  *  by session mgr code, or called as a callback by the actions database.
882  *
883  *  Inputs:
884  *  ------
885  *
886  *  Outputs:
887  *  -------
888  *
889  *  Comments:
890  *  --------
891  *  The first time in, this call registers itself as a callback routine with
892  *  the actions database. The first and subsequent times in, this call will
893  *  load the actions database into the session mgr address space.
894  *
895  *************************************<->***********************************/
896
897 void
898 ProcessReloadActionsDatabase(void)
899 {
900   static int needtoregister = 1;
901
902   if (needtoregister)
903   {
904    /*
905     * Have not yet registered with the actions database to call this
906     * callback when the database changes. Do so.
907     */
908     DtDbReloadNotify((DtDbReloadCallbackProc) ProcessReloadActionsDatabase,
909                         (XtPointer) NULL);
910     needtoregister = 0;
911   }
912
913  /*
914   * Our copy of the actions database must be out of date. Reload.
915   */
916   DtDbLoad();  
917 }
918
919 void
920 ProcessEvent(w, client_data, event, continue_to_dispatch)
921   Widget w;
922   XtPointer client_data;
923   XEvent *event;
924   Boolean *continue_to_dispatch;
925 {
926   switch(event->type)
927   {
928     case ClientMessage:
929       ProcessClientMessage(event);
930       break;
931     case PropertyNotify:
932       ProcessPropertyNotify(event);
933       break;
934     default:
935 #if defined (USE_X11SSEXT)
936       if (event->type == smGD.ssEventType)
937         ProcessScreenSaverMessage(event);
938 #endif
939       break;
940   }
941 }