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