1 /* $TOG: SmCommun.c /main/14 1999/09/20 13:47:25 mgreess $ */
3 * (c) Copyright 1997, The Open Group
5 /*************************************<+>*************************************
6 *****************************************************************************
10 ** Project: HP DT Session Manager (dtsession)
14 ** This file contains functionality needed to communicate with the
15 ** other DT components. This includes initialization and callback code.
17 *****************************************************************************
18 *************************************<+>*************************************/
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.
30 #ifdef _SUN_OS /* for the strtok calls */
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 */
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>
50 #include "SmRestore.h"
53 #include "SmProtocol.h"
54 #include "SmGlobals.h"
58 * Pulic var declarations
60 extern int clientRunning; /* from SmConMgmt.c */
61 extern char **smExecArray;
64 * Defines for this file only
71 * Constants for the Save_Session ToolTalk message
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";
88 * Local function definitions
91 static void DtwmStarted(void);
94 ProcessSaveSessionMessage (
100 Boolean shutdown = DEFAULT_SHUTDOWN;
101 int interactStyle = DEFAULT_INTERACT_STYLE;
102 Boolean fast = DEFAULT_FAST;
103 Boolean global = DEFAULT_GLOBAL;
104 int numSessionsBackedup;
108 int num_args = tt_message_args_count (saveMsg);
113 for (i = 0; i < num_args; i++) {
115 type = tt_message_arg_type (saveMsg, i);
116 status = tt_ptr_error (type);
117 if (status != TT_OK || type == NULL)
120 value = tt_message_arg_val (saveMsg, i);
121 status = tt_ptr_error (value);
122 if (status != TT_OK || value == NULL)
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;
138 else if (!strcmp (type, SHUTDOWN)) {
139 if (!strcmp (value, TRUE_STR))
141 else if (!strcmp (value, FALSE_STR))
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;
150 else if (!strcmp (type, FAST)) {
151 if (!strcmp (value, TRUE_STR))
153 else if (!strcmp (value, FALSE_STR))
156 else if (!strcmp (type, GLOBAL)) {
157 if (!strcmp (value, TRUE_STR))
159 else if (!strcmp (value, FALSE_STR))
162 else if (!strcmp (type, NUM_BACKUPS)) {
163 numSessionsBackedup = atoi (value);
164 if (numSessionsBackedup > 0)
165 smRes.numSessionsBackedup = numSessionsBackedup;
171 pch1 = strdup ((char *) GETMESSAGE (40, 16,
172 "The Save_Session message contains the unrecognized argument '%s'."));
174 pch2 = XtMalloc (strlen (pch1)+strlen (type)+3);
176 (void) sprintf (pch2, pch1, type);
177 DtMsgLogMessage (smGD.programName,
178 DtMsgLogWarning, pch2);
179 free (pch1); free (pch2);
191 if (saveType == -1) {
192 PostSaveSessionErrorDialog ();
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);
202 SaveState ((smGD.sessionType == HOME_SESSION),
203 smSettings.startState, saveType, shutdown,
204 interactStyle, fast, global);
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);
215 /*************************************<->*************************************
217 * handleSessionMgrRequest ()
222 * Handle ToolTalk requests for which the session manager is responsible.
227 * Incoming request, and the pattern it matched.
232 * Whether the message has been consumed.
238 *************************************<->***********************************/
240 handleSessionMgrRequest(
247 Tt_callback_action rc;
250 if (tt_message_state( msg ) != TT_SENT)
252 /* msg is a reply to ourself */
253 return TT_CALLBACK_CONTINUE;
256 op = tt_message_op( msg );
257 status = tt_ptr_error( op );
258 if ((status != TT_OK) || (op == 0))
260 /* Let tttk_Xt_input_handler() Do The Right Thing */
261 return TT_CALLBACK_CONTINUE;
265 if (strcmp( op, SM_DISPLAY_LOCK ) == 0)
267 if(smGD.smState == READY)
269 smGD.smState = IN_PROCESS;
272 rc = TT_CALLBACK_PROCESSED;
274 else if (strcmp( op, SM_XSESSION_EXIT ) == 0)
276 if(smGD.smState == READY)
278 smGD.smState = IN_PROCESS;
281 * The session may have been canceled so set the smState
284 smGD.smState = READY;
285 destroyMsg = False; /* done in SmUI.c */
287 rc = TT_CALLBACK_PROCESSED;
289 else if (strcmp( op, SM_RESOURCES_RELOAD ) == 0)
291 if(smGD.smState == READY)
293 smGD.smState = IN_PROCESS;
296 rc = TT_CALLBACK_PROCESSED;
298 else if (strcmp( op, SM_SAVE_SESSION ) == 0)
300 if(smGD.smState == READY)
302 smGD.smState = IN_PROCESS;
303 ProcessSaveSessionMessage (msg);
305 rc = TT_CALLBACK_PROCESSED;
309 rc = TT_CALLBACK_CONTINUE;
313 if (destroyMsg == True)
315 tt_message_reply( msg );
316 tt_message_destroy( msg );
324 /*************************************<->*************************************
331 * Initialize the BMS and register the session manager with it. Then
332 * register all requests and notifications that the session manager is
338 * app = Application context for dtsession
348 *************************************<->***********************************/
360 * Before we start anything - initialize the customize data structure
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;
370 makeConnect = DtAppInitialize(smGD.appCon, smGD.display, smGD.topLevelWid,
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")));
379 if(makeConnect == False)
385 smGD.bmsDead = False;
389 status = tt_ptr_error( procId );
390 if (status == TT_OK) {
392 status = tt_int_error( fd );
393 if (status == TT_OK) {
394 XtAppAddInput( smGD.appCon, fd, (XtPointer)XtInputReadMask,
395 tttk_Xt_input_handler, procId );
398 if (status != TT_OK) {
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 );
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) {
424 char *errfmt, *errmsg, *statmsg;
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);
432 PrintError(DtError, errmsg);
437 } /* END OF FUNCTION StartMsgServer */
440 /*************************************<->*************************************
442 * DtwmStarted (fields, client_data, num_words)
459 *************************************<->***********************************/
463 smGD.dtwmRunning = True;
464 } /* END OF FUNCTION DtwmStarted */
467 /*************************************<->*************************************
474 * A request has come in (usually from the customizer) to restore one of
475 * the settings to their default states
483 * smToSet = (global) turns off flag of setting no longer set
489 *************************************<->***********************************/
495 if(toRestore == XaDtSmScreenInfo)
497 smToSet.screenSavChange = False;
499 else if(toRestore == XaDtSmAudioInfo)
501 smToSet.audioChange = False;
503 else if(toRestore == XaDtSmKeyboardInfo)
505 smToSet.keyboardChange = False;
507 else if(toRestore == XaDtSmPointerInfo)
509 smToSet.pointerChange = False;
510 smToSet.pointerMapChange = False;
512 } /* END OF FUNCTION RestoreDefaults */
515 /*************************************<->*************************************
517 * ProcessPropertyNotify ()
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
532 * smToSet = (global) turns on flag of setting being set
538 *************************************<->***********************************/
540 ProcessPropertyNotify(
543 XPropertyEvent *pEvent = (XPropertyEvent *) next;
545 if (pEvent->state != PropertyNewValue)
550 if(pEvent->atom == XaDtSmScreenInfo)
552 smToSet.screenSavChange = True;
553 smCust.screenSavChange = True;
555 else if(pEvent->atom == XaDtSmAudioInfo)
557 smToSet.audioChange = True;
558 smCust.audioChange = True;
560 else if(pEvent->atom == XaDtSmKeyboardInfo)
562 smToSet.keyboardChange = True;
563 smCust.keyboardChange = True;
565 else if(pEvent->atom == XaDtSmFontInfo)
567 smCust.fontChange = True;
569 else if(pEvent->atom == XaDtSmPreeditInfo)
571 smCust.preeditChange = True;
573 else if(pEvent->atom == XaDtSmPointerInfo)
575 smToSet.pointerChange = True;
576 smCust.pointerChange = True;
577 smToSet.pointerMapChange = True;
578 smCust.dClickChange = True;
580 } /* END OF FUNCTION RecordChanges */
584 /*************************************<->*************************************
586 * ProcessClientMessage(next)
591 * A client message has come from somewhere. Process it if we know how.
595 * next - the client message event
605 *************************************<->***********************************/
607 ProcessClientMessage(
610 XClientMessageEvent *cEvent = (XClientMessageEvent *) next;
613 * If this event came from the style manager - process it
615 if(cEvent->message_type == XaDtSmStmProtocol)
617 if(cEvent->data.l[0] == XaDtSmSaveToHome)
620 * The style manager is asking for a save home session
622 if(smGD.smState == READY)
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 );
634 startStateOrig = smSettings.startState;
635 confirmModeOrig = smSettings.confirmMode;
637 smSettings.startState = cEvent->data.l[1];
638 smSettings.confirmMode = cEvent->data.l[2];;
640 smGD.homeSave = True;
641 SaveState(True, smSettings.startState, SmSaveLocal,
642 DEFAULT_SHUTDOWN, SmInteractStyleNone,
643 DEFAULT_FAST, DEFAULT_GLOBAL);
644 smGD.homeSave = False;
646 smSettings.startState = startStateOrig;
647 smSettings.confirmMode = confirmModeOrig;
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 );
656 else if (cEvent->data.l[0] == XaDtSmRestoreDefault)
658 RestoreDefaults((Atom) cEvent->data.l[1]);
661 else if(cEvent->message_type == XaSmWmProtocol)
664 * If this event came from the ws manager - process it
666 if(cEvent->data.l[0] == XaWmExitSession)
669 * The ws manager is sending an exit session message
671 if(smGD.smState == READY)
673 smGD.smState = IN_PROCESS;
677 else if(cEvent->data.l[0] == XaWmLockDisplay)
680 * The ws manager is sending an lock display message
682 if(smGD.smState == READY)
684 smGD.smState = IN_PROCESS;
688 else if(cEvent->data.l[0] == XaWmWindowAck)
691 * The ws manager is sending a "client has been managed"
693 clientRunning = True;
695 else if(cEvent->data.l[0] == XaWmReady)
698 * The ws manager is sending a "ready for clients"
700 smGD.dtwmRunning = True;
703 else if (cEvent->message_type == XaDtSmStateInfo)
706 int flags = (int)cEvent->data.l[0];
709 * Session state has been changed. Get new values.
711 if(_DtGetSmState(smGD.display, smGD.topLevelWindow, &state) == Success)
713 char *newRes = malloc(BUFSIZ);
716 * Copy selected changes to data areas.
718 if (flags & SM_STATE_START)
720 smSettings.startState = state.smStartState;
723 if (flags & SM_STATE_CONFIRM)
725 smSettings.confirmMode = state.smConfirmMode;
729 if (flags & SM_STATE_CYCLETIMEOUT)
731 smSaverRes.cycleTimeout = state.smCycleTimeout;
732 sprintf(newRes+strlen(newRes), "dtsession*%scycleTimeout: %d\n",
734 smSaverRes.cycleTimeout/60);
737 if (flags & SM_STATE_LOCKTIMEOUT)
739 smSaverRes.lockTimeout = state.smLockTimeout;
740 sprintf(newRes+strlen(newRes), "dtsession*%slockTimeout: %d\n",
742 smSaverRes.lockTimeout/60);
745 if (flags & SM_STATE_SAVERTIMEOUT)
747 smSaverRes.saverTimeout = state.smSaverTimeout;
748 sprintf(newRes+strlen(newRes), "dtsession*%ssaverTimeout: %d\n",
750 smSaverRes.saverTimeout/60);
753 if (flags & SM_STATE_RANDOM)
755 smSaverRes.random = state.smRandom;
756 sprintf(newRes+strlen(newRes), "dtsession*%srandom: %s\n",
758 smSaverRes.random ? "True\n" : "False\n");
761 if (newRes[0] != '\0')
763 _DtAddToResource(smGD.display, newRes);
766 if (NULL != newRes) free(newRes);
769 else if (cEvent->message_type == XaDtSmSaverInfo)
774 * Session screen saver list has been changed. Get new values.
776 if(_DtGetSmSaver(smGD.display, smGD.topLevelWindow, &saver) == Success)
780 SM_FREE(smGD.saverList);
781 smGD.saverList = SmNewString(saver.saverList);
782 SM_FREE(saver.saverList);
784 pRes = malloc(strlen("dtsession*saverList: ") +
785 strlen(smGD.saverList) +
786 strlen(smGD.extensionSpec) +
787 2); /* for the '/n' and '/0' */
790 sprintf(pRes, "dtsession*%ssaverList: %s\n",
793 _DtAddToResource(smGD.display, pRes);
797 if (smGD.saverListParse)
799 SM_FREE(smGD.saverListParse);
800 smGD.saverListParse = NULL;
804 #if defined (USE_HPSSEXT)
805 else if(cEvent->message_type == XaSmScreenSaveRet)
807 if(cEvent->data.l[0] == SS_ON)
809 if (smSaverRes.saverTimeout + smSaverRes.lockTimeout > 0 &&
810 smGD.smState == READY)
812 smGD.smState = IN_PROCESS;
817 #endif /* USE_HPSSEXT */
821 } /* END OF FUNCTION ProcessClientMessage */
823 /*************************************<->*************************************
825 * ProcessScreenSaverMessage(next)
830 * A screen saver message has come from the server. Process it if we know how.
834 * next - the client message event
844 *************************************<->***********************************/
845 #if defined (USE_X11SSEXT)
848 ProcessScreenSaverMessage(
851 XScreenSaverNotifyEvent *ssEvent = (XScreenSaverNotifyEvent *) next;
852 static int ssCount = 0;
854 if (ssEvent->state == ScreenSaverOn)
857 * Screen saver activated.
859 if (smSaverRes.saverTimeout + smSaverRes.lockTimeout > 0 &&
860 smGD.smState == READY)
863 * Resource says to lock the display and SM is ready, so lock it.
865 smGD.smState = IN_PROCESS;
870 #endif /* USE_X11SSEXT */
872 /*************************************<->*************************************
874 * ProcessReloadActionsDatabase(void)
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.
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.
895 *************************************<->***********************************/
898 ProcessReloadActionsDatabase(void)
900 static int needtoregister = 1;
905 * Have not yet registered with the actions database to call this
906 * callback when the database changes. Do so.
908 DtDbReloadNotify((DtDbReloadCallbackProc) ProcessReloadActionsDatabase,
914 * Our copy of the actions database must be out of date. Reload.
920 ProcessEvent(w, client_data, event, continue_to_dispatch)
922 XtPointer client_data;
924 Boolean *continue_to_dispatch;
929 ProcessClientMessage(event);
932 ProcessPropertyNotify(event);
935 #if defined (USE_X11SSEXT)
936 if (event->type == smGD.ssEventType)
937 ProcessScreenSaverMessage(event);