2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
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
23 /* $TOG: SmCommun.c /main/14 1999/09/20 13:47:25 mgreess $ */
25 * (c) Copyright 1997, The Open Group
27 /*************************************<+>*************************************
28 *****************************************************************************
32 ** Project: HP DT Session Manager (dtsession)
36 ** This file contains functionality needed to communicate with the
37 ** other DT components. This includes initialization and callback code.
39 *****************************************************************************
40 *************************************<+>*************************************/
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.
52 #ifdef _SUN_OS /* for the strtok calls */
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 */
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>
72 #include "SmRestore.h"
75 #include "SmProtocol.h"
76 #include "SmGlobals.h"
80 * Pulic var declarations
82 extern int clientRunning; /* from SmConMgmt.c */
83 extern char **smExecArray;
86 * Defines for this file only
93 * Constants for the Save_Session ToolTalk message
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";
110 * Local function definitions
113 static void DtwmStarted(void);
116 ProcessSaveSessionMessage (
122 Boolean shutdown = DEFAULT_SHUTDOWN;
123 int interactStyle = DEFAULT_INTERACT_STYLE;
124 Boolean fast = DEFAULT_FAST;
125 Boolean global = DEFAULT_GLOBAL;
126 int numSessionsBackedup;
130 int num_args = tt_message_args_count (saveMsg);
135 for (i = 0; i < num_args; i++) {
137 type = tt_message_arg_type (saveMsg, i);
138 status = tt_ptr_error (type);
139 if (status != TT_OK || type == NULL)
142 value = tt_message_arg_val (saveMsg, i);
143 status = tt_ptr_error (value);
144 if (status != TT_OK || value == NULL)
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;
160 else if (!strcmp (type, SHUTDOWN)) {
161 if (!strcmp (value, TRUE_STR))
163 else if (!strcmp (value, FALSE_STR))
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;
172 else if (!strcmp (type, FAST)) {
173 if (!strcmp (value, TRUE_STR))
175 else if (!strcmp (value, FALSE_STR))
178 else if (!strcmp (type, GLOBAL)) {
179 if (!strcmp (value, TRUE_STR))
181 else if (!strcmp (value, FALSE_STR))
184 else if (!strcmp (type, NUM_BACKUPS)) {
185 numSessionsBackedup = atoi (value);
186 if (numSessionsBackedup > 0)
187 smRes.numSessionsBackedup = numSessionsBackedup;
193 pch1 = strdup ((char *) GETMESSAGE (40, 16,
194 "The Save_Session message contains the unrecognized argument '%s'."));
196 pch2 = XtMalloc (strlen (pch1)+strlen (type)+3);
198 (void) sprintf (pch2, pch1, type);
199 DtMsgLogMessage (smGD.programName,
200 DtMsgLogWarning, pch2);
201 free (pch1); free (pch2);
213 if (saveType == -1) {
214 PostSaveSessionErrorDialog ();
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);
224 SaveState ((smGD.sessionType == HOME_SESSION),
225 smSettings.startState, saveType, shutdown,
226 interactStyle, fast, global);
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);
237 /*************************************<->*************************************
239 * handleSessionMgrRequest ()
244 * Handle ToolTalk requests for which the session manager is responsible.
249 * Incoming request, and the pattern it matched.
254 * Whether the message has been consumed.
260 *************************************<->***********************************/
262 handleSessionMgrRequest(
269 Tt_callback_action rc;
272 if (tt_message_state( msg ) != TT_SENT)
274 /* msg is a reply to ourself */
275 return TT_CALLBACK_CONTINUE;
278 op = tt_message_op( msg );
279 status = tt_ptr_error( op );
280 if ((status != TT_OK) || (op == 0))
282 /* Let tttk_Xt_input_handler() Do The Right Thing */
283 return TT_CALLBACK_CONTINUE;
287 if (strcmp( op, SM_DISPLAY_LOCK ) == 0)
289 if(smGD.smState == READY)
291 smGD.smState = IN_PROCESS;
294 rc = TT_CALLBACK_PROCESSED;
296 else if (strcmp( op, SM_XSESSION_EXIT ) == 0)
298 if(smGD.smState == READY)
300 smGD.smState = IN_PROCESS;
303 * The session may have been canceled so set the smState
306 smGD.smState = READY;
307 destroyMsg = False; /* done in SmUI.c */
309 rc = TT_CALLBACK_PROCESSED;
311 else if (strcmp( op, SM_RESOURCES_RELOAD ) == 0)
313 if(smGD.smState == READY)
315 smGD.smState = IN_PROCESS;
318 rc = TT_CALLBACK_PROCESSED;
320 else if (strcmp( op, SM_SAVE_SESSION ) == 0)
322 if(smGD.smState == READY)
324 smGD.smState = IN_PROCESS;
325 ProcessSaveSessionMessage (msg);
327 rc = TT_CALLBACK_PROCESSED;
331 rc = TT_CALLBACK_CONTINUE;
335 if (destroyMsg == True)
337 tt_message_reply( msg );
338 tt_message_destroy( msg );
346 /*************************************<->*************************************
353 * Initialize the BMS and register the session manager with it. Then
354 * register all requests and notifications that the session manager is
360 * app = Application context for dtsession
370 *************************************<->***********************************/
382 * Before we start anything - initialize the customize data structure
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;
392 makeConnect = DtAppInitialize(smGD.appCon, smGD.display, smGD.topLevelWid,
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")));
401 if(makeConnect == False)
407 smGD.bmsDead = False;
411 status = tt_ptr_error( procId );
412 if (status == TT_OK) {
414 status = tt_int_error( fd );
415 if (status == TT_OK) {
416 XtAppAddInput( smGD.appCon, fd, (XtPointer)XtInputReadMask,
417 tttk_Xt_input_handler, procId );
420 if (status != TT_OK) {
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 );
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) {
446 char *errfmt, *errmsg, *statmsg;
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);
454 PrintError(DtError, errmsg);
459 } /* END OF FUNCTION StartMsgServer */
462 /*************************************<->*************************************
464 * DtwmStarted (fields, client_data, num_words)
481 *************************************<->***********************************/
485 smGD.dtwmRunning = True;
486 } /* END OF FUNCTION DtwmStarted */
489 /*************************************<->*************************************
496 * A request has come in (usually from the customizer) to restore one of
497 * the settings to their default states
505 * smToSet = (global) turns off flag of setting no longer set
511 *************************************<->***********************************/
517 if(toRestore == XaDtSmScreenInfo)
519 smToSet.screenSavChange = False;
521 else if(toRestore == XaDtSmAudioInfo)
523 smToSet.audioChange = False;
525 else if(toRestore == XaDtSmKeyboardInfo)
527 smToSet.keyboardChange = False;
529 else if(toRestore == XaDtSmPointerInfo)
531 smToSet.pointerChange = False;
532 smToSet.pointerMapChange = False;
534 } /* END OF FUNCTION RestoreDefaults */
537 /*************************************<->*************************************
539 * ProcessPropertyNotify ()
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
554 * smToSet = (global) turns on flag of setting being set
560 *************************************<->***********************************/
562 ProcessPropertyNotify(
565 XPropertyEvent *pEvent = (XPropertyEvent *) next;
567 if (pEvent->state != PropertyNewValue)
572 if(pEvent->atom == XaDtSmScreenInfo)
574 smToSet.screenSavChange = True;
575 smCust.screenSavChange = True;
577 else if(pEvent->atom == XaDtSmAudioInfo)
579 smToSet.audioChange = True;
580 smCust.audioChange = True;
582 else if(pEvent->atom == XaDtSmKeyboardInfo)
584 smToSet.keyboardChange = True;
585 smCust.keyboardChange = True;
587 else if(pEvent->atom == XaDtSmFontInfo)
589 smCust.fontChange = True;
591 else if(pEvent->atom == XaDtSmPreeditInfo)
593 smCust.preeditChange = True;
595 else if(pEvent->atom == XaDtSmPointerInfo)
597 smToSet.pointerChange = True;
598 smCust.pointerChange = True;
599 smToSet.pointerMapChange = True;
600 smCust.dClickChange = True;
602 } /* END OF FUNCTION RecordChanges */
606 /*************************************<->*************************************
608 * ProcessClientMessage(next)
613 * A client message has come from somewhere. Process it if we know how.
617 * next - the client message event
627 *************************************<->***********************************/
629 ProcessClientMessage(
632 XClientMessageEvent *cEvent = (XClientMessageEvent *) next;
635 * If this event came from the style manager - process it
637 if(cEvent->message_type == XaDtSmStmProtocol)
639 if(cEvent->data.l[0] == XaDtSmSaveToHome)
642 * The style manager is asking for a save home session
644 if(smGD.smState == READY)
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 );
656 startStateOrig = smSettings.startState;
657 confirmModeOrig = smSettings.confirmMode;
659 smSettings.startState = cEvent->data.l[1];
660 smSettings.confirmMode = cEvent->data.l[2];;
662 smGD.homeSave = True;
663 SaveState(True, smSettings.startState, SmSaveLocal,
664 DEFAULT_SHUTDOWN, SmInteractStyleNone,
665 DEFAULT_FAST, DEFAULT_GLOBAL);
666 smGD.homeSave = False;
668 smSettings.startState = startStateOrig;
669 smSettings.confirmMode = confirmModeOrig;
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 );
678 else if (cEvent->data.l[0] == XaDtSmRestoreDefault)
680 RestoreDefaults((Atom) cEvent->data.l[1]);
683 else if(cEvent->message_type == XaSmWmProtocol)
686 * If this event came from the ws manager - process it
688 if(cEvent->data.l[0] == XaWmExitSession)
691 * The ws manager is sending an exit session message
693 if(smGD.smState == READY)
695 smGD.smState = IN_PROCESS;
699 else if(cEvent->data.l[0] == XaWmLockDisplay)
702 * The ws manager is sending an lock display message
704 if(smGD.smState == READY)
706 smGD.smState = IN_PROCESS;
710 else if(cEvent->data.l[0] == XaWmWindowAck)
713 * The ws manager is sending a "client has been managed"
715 clientRunning = True;
717 else if(cEvent->data.l[0] == XaWmReady)
720 * The ws manager is sending a "ready for clients"
722 smGD.dtwmRunning = True;
725 else if (cEvent->message_type == XaDtSmStateInfo)
728 int flags = (int)cEvent->data.l[0];
731 * Session state has been changed. Get new values.
733 if(_DtGetSmState(smGD.display, smGD.topLevelWindow, &state) == Success)
735 char *newRes = malloc(BUFSIZ);
738 * Copy selected changes to data areas.
740 if (flags & SM_STATE_START)
742 smSettings.startState = state.smStartState;
745 if (flags & SM_STATE_CONFIRM)
747 smSettings.confirmMode = state.smConfirmMode;
751 if (flags & SM_STATE_CYCLETIMEOUT)
753 smSaverRes.cycleTimeout = state.smCycleTimeout;
754 sprintf(newRes+strlen(newRes), "dtsession*%scycleTimeout: %d\n",
756 smSaverRes.cycleTimeout/60);
759 if (flags & SM_STATE_LOCKTIMEOUT)
761 smSaverRes.lockTimeout = state.smLockTimeout;
762 sprintf(newRes+strlen(newRes), "dtsession*%slockTimeout: %d\n",
764 smSaverRes.lockTimeout/60);
767 if (flags & SM_STATE_SAVERTIMEOUT)
769 smSaverRes.saverTimeout = state.smSaverTimeout;
770 sprintf(newRes+strlen(newRes), "dtsession*%ssaverTimeout: %d\n",
772 smSaverRes.saverTimeout/60);
775 if (flags & SM_STATE_RANDOM)
777 smSaverRes.random = state.smRandom;
778 sprintf(newRes+strlen(newRes), "dtsession*%srandom: %s\n",
780 smSaverRes.random ? "True\n" : "False\n");
783 if (newRes[0] != '\0')
785 _DtAddToResource(smGD.display, newRes);
788 if (NULL != newRes) free(newRes);
791 else if (cEvent->message_type == XaDtSmSaverInfo)
796 * Session screen saver list has been changed. Get new values.
798 if(_DtGetSmSaver(smGD.display, smGD.topLevelWindow, &saver) == Success)
802 SM_FREE(smGD.saverList);
803 smGD.saverList = SmNewString(saver.saverList);
804 SM_FREE(saver.saverList);
806 pRes = malloc(strlen("dtsession*saverList: ") +
807 strlen(smGD.saverList) +
808 strlen(smGD.extensionSpec) +
809 2); /* for the '/n' and '/0' */
812 sprintf(pRes, "dtsession*%ssaverList: %s\n",
815 _DtAddToResource(smGD.display, pRes);
819 if (smGD.saverListParse)
821 SM_FREE(smGD.saverListParse);
822 smGD.saverListParse = NULL;
826 #if defined (USE_HPSSEXT)
827 else if(cEvent->message_type == XaSmScreenSaveRet)
829 if(cEvent->data.l[0] == SS_ON)
831 if (smSaverRes.saverTimeout + smSaverRes.lockTimeout > 0 &&
832 smGD.smState == READY)
834 smGD.smState = IN_PROCESS;
839 #endif /* USE_HPSSEXT */
843 } /* END OF FUNCTION ProcessClientMessage */
845 /*************************************<->*************************************
847 * ProcessScreenSaverMessage(next)
852 * A screen saver message has come from the server. Process it if we know how.
856 * next - the client message event
866 *************************************<->***********************************/
867 #if defined (USE_X11SSEXT)
870 ProcessScreenSaverMessage(
873 XScreenSaverNotifyEvent *ssEvent = (XScreenSaverNotifyEvent *) next;
874 static int ssCount = 0;
876 if (ssEvent->state == ScreenSaverOn)
879 * Screen saver activated.
881 if (smSaverRes.saverTimeout + smSaverRes.lockTimeout > 0 &&
882 smGD.smState == READY)
885 * Resource says to lock the display and SM is ready, so lock it.
887 smGD.smState = IN_PROCESS;
892 #endif /* USE_X11SSEXT */
894 /*************************************<->*************************************
896 * ProcessReloadActionsDatabase(void)
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.
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.
917 *************************************<->***********************************/
920 ProcessReloadActionsDatabase(void)
922 static int needtoregister = 1;
927 * Have not yet registered with the actions database to call this
928 * callback when the database changes. Do so.
930 DtDbReloadNotify((DtDbReloadCallbackProc) ProcessReloadActionsDatabase,
936 * Our copy of the actions database must be out of date. Reload.
942 ProcessEvent(w, client_data, event, continue_to_dispatch)
944 XtPointer client_data;
946 Boolean *continue_to_dispatch;
951 ProcessClientMessage(event);
954 ProcessPropertyNotify(event);
957 #if defined (USE_X11SSEXT)
958 if (event->type == smGD.ssEventType)
959 ProcessScreenSaverMessage(event);