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