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 libraries 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: WmIPC.c /main/11 1999/09/20 15:17:25 mgreess $ */
25 * (c) Copyright 1997, The Open Group
28 * (c) Copyright 1987, 1988, 1989, 1990, 1992, 1993 HEWLETT-PACKARD COMPANY
33 static char rcsid[] = ""
41 #include "WmProtocol.h"
45 #include <Dt/Action.h>
47 #include <Dt/IndicatorM.h>
48 #include <Dt/UserMsg.h>
51 #include "WmBackdrop.h"
53 #include "WmFunction.h"
54 #include "WmWrkspace.h"
58 #include "DataBaseLoad.h"
62 * include extern functions and definitions
65 extern void UpdateFileTypeControlFields ( void );
66 extern WmScreenData * GetScreenForWindow (Window);
68 static void ToolTalkError(Widget, char*, Tt_status);
72 * data for the "DT screen"
79 Const char *szWM_TOOL_CLASS = DtWM_TOOL_CLASS;
83 /******************************<->*************************************
85 * dtInitialize (char * program_name, XtAppContext appContext)
89 * Initialize the messaging mechanism
93 * program_name - argv[0]
94 * appContext - used throughout the WM
102 ******************************<->***********************************/
106 XtAppContext appContext )
109 (void) DtAppInitialize(appContext, DISPLAY1, wmGD.topLevelW1,
110 program_name, (char *)szWM_TOOL_CLASS);
113 * Load action definitions from the action database.
115 #ifdef DT_PERFORMANCE
116 _DtPerfChkpntMsgSend("Begin action database load");
121 #ifdef DT_PERFORMANCE
122 _DtPerfChkpntMsgSend("End action database load");
125 } /* END OF FUNCTION dtInitialize */
127 /******************************<->*************************************
129 * dtInitializeMessaging (Widget)
133 * Initialize the messaging mechanisms
144 ******************************<->***********************************/
147 dtInitializeMessaging(Widget toplevel)
154 Tt_pattern notice_pattern, request_pattern;
155 char *default_session;
161 Tt_callback_action NoticeMsgCB(
164 Tt_callback_action RequestMsgCB(
169 * Makef sure we have a ToolTalk connection
172 status = tt_ptr_error(procId);
173 if (status != TT_OK) {
175 GETMESSAGE(2, 2, "Could not connect to ToolTalk:\n%s\n");
176 ToolTalkError(toplevel, errfmt, status);
180 status = tt_int_error(fd);
181 if (status == TT_OK) {
182 XtAppAddInput(XtWidgetToApplicationContext(wmGD.topLevelW), fd,
183 (XtPointer)XtInputReadMask, tttk_Xt_input_handler, procId);
185 ToolTalkError(toplevel, "tt_fd()", status);
189 default_session = tt_default_session();
190 status = tt_ptr_error(default_session);
191 if (status != TT_OK) {
192 errfmt = GETMESSAGE(2, 4, "Could not get default ToolTalk session:\n%s\n");
193 ToolTalkError(toplevel, errfmt, status);
197 errfmt = GETMESSAGE(2, 5, "Error constructing ToolTalk pattern:\n%s\n");
198 notice_pattern = tt_pattern_create();
199 status = tt_ptr_error(notice_pattern);
200 if (status != TT_OK) {
201 ToolTalkError(toplevel, errfmt, status);
204 request_pattern = tt_pattern_create();
205 status = tt_ptr_error(request_pattern);
206 if (status != TT_OK) {
207 ToolTalkError(toplevel, errfmt, status);
211 status = tt_pattern_category_set(notice_pattern, TT_OBSERVE);
212 if (status != TT_OK) {
213 ToolTalkError(toplevel, errfmt, status);
216 status = tt_pattern_category_set(request_pattern, TT_HANDLE);
217 if (status != TT_OK) {
218 ToolTalkError(toplevel, errfmt, status);
221 status = tt_pattern_scope_add(notice_pattern, TT_SESSION);
222 if (status != TT_OK) {
223 ToolTalkError(toplevel, errfmt, status);
226 status = tt_pattern_scope_add(request_pattern, TT_SESSION);
227 if (status != TT_OK) {
228 ToolTalkError(toplevel, errfmt, status);
231 status = tt_pattern_session_add(notice_pattern, default_session);
232 if (status != TT_OK) {
233 ToolTalkError(toplevel, errfmt, status);
236 status = tt_pattern_session_add(request_pattern, default_session);
237 if (status != TT_OK) {
238 ToolTalkError(toplevel, errfmt, status);
242 tt_free( default_session );
243 status = tt_pattern_class_add(notice_pattern, TT_NOTICE);
244 if (status != TT_OK) {
245 ToolTalkError(toplevel, errfmt, status);
248 status = tt_pattern_state_add(notice_pattern, TT_SENT);
249 if (status != TT_OK) {
250 ToolTalkError(toplevel, errfmt, status);
253 status = tt_pattern_class_add(request_pattern, TT_REQUEST);
254 if (status != TT_OK) {
255 ToolTalkError(toplevel, errfmt, status);
258 status = tt_pattern_state_add(request_pattern, TT_SENT);
259 if (status != TT_OK) {
260 ToolTalkError(toplevel, errfmt, status);
266 * Ops handled by the notice_pattern
268 status = tt_pattern_op_add(notice_pattern, "DtActivity_Beginning");
269 if (status != TT_OK) {
270 ToolTalkError(toplevel, errfmt, status);
273 status = tt_pattern_op_add(notice_pattern, "DtActivity_Began");
274 if (status != TT_OK) {
275 ToolTalkError(toplevel, errfmt, status);
278 status = tt_pattern_op_add(notice_pattern, "DtTypes_Reloaded");
279 if (status != TT_OK) {
280 ToolTalkError(toplevel, errfmt, status);
285 * Ops handled by the request_pattern
287 status = tt_pattern_op_add(request_pattern, "DtPanel_Restore");
288 if (status != TT_OK) {
289 ToolTalkError(toplevel, errfmt, status);
292 status = tt_pattern_op_add(request_pattern, "DtWorkspace_SetCurrent");
293 if (status != TT_OK) {
294 ToolTalkError(toplevel, errfmt, status);
297 status = tt_pattern_op_add(request_pattern, "DtWorkspace_Title_Set");
298 if (status != TT_OK) {
299 ToolTalkError(toplevel, errfmt, status);
302 status = tt_pattern_op_add(request_pattern, "DtWorkspace_Add");
303 if (status != TT_OK) {
304 ToolTalkError(toplevel, errfmt, status);
307 status = tt_pattern_op_add(request_pattern, "DtWorkspace_Delete");
308 if (status != TT_OK) {
309 ToolTalkError(toplevel, errfmt, status);
312 status = tt_pattern_op_add(request_pattern, "GetWsmClients");
313 if (status != TT_OK) {
314 ToolTalkError(toplevel, errfmt, status);
319 * Register callback for the notice_pattern
321 status = tt_pattern_callback_add(notice_pattern, NoticeMsgCB);
322 if (status != TT_OK) {
323 ToolTalkError(toplevel, errfmt, status);
328 * Register callback for the request_pattern
330 status = tt_pattern_callback_add(request_pattern, RequestMsgCB);
331 if (status != TT_OK) {
332 ToolTalkError(toplevel, errfmt, status);
336 status = tt_pattern_register(notice_pattern);
337 if (status != TT_OK) {
338 ToolTalkError(toplevel, errfmt, status);
341 status = tt_pattern_register(request_pattern);
342 if (status != TT_OK) {
343 ToolTalkError(toplevel, errfmt, status);
347 } /* END OF FUNCTION dtInitializeMessaging */
350 /******************************<->*************************************
356 * Shuts down the messaging mechanism
366 * Should be done before exiting
368 ******************************<->***********************************/
372 } /* END OF FUNCTION dtCloseIPC */
376 /******************************<->*************************************
378 * void dtReadyNotification()
382 * Tells the world that we're up and ready.
392 * Invoked as the fitting culmination of dtwm initialization
394 ******************************<->***********************************/
396 dtReadyNotification( void )
398 SendClientMsg( wmGD.dtSmWindow,
399 (long) wmGD.xa_DT_SM_WM_PROTOCOL,
400 (long) wmGD.xa_DT_WM_READY,
401 CurrentTime, NULL, 0);
403 } /* END OF FUNCTION dtReadyNotification */
406 /******************************<->*************************************
412 * This is called to turn off "system busy" activity
423 * This routine relies on two globals, blinkerPCW and dtSD,
424 * on the major assumptions that:
425 * - there is just one DT Screen, with the front panel enabled
426 * - there is just one dtwmbusy control in that front panel
427 ******************************<->***********************************/
429 WmStopWaiting( void )
433 WmFrontPanelSetBusy (False);
435 } /* END OF FUNCTION WmStopWaiting */
439 /******************************<->*************************************
441 * dtSendWorkspaceModifyNotification ()
445 * This is called to announce that the workspace set has been
450 * pSD - pointer to screen data
451 * aWs - id of workspace just modified
452 * iType - type of modification
462 * "MODIFY_WORKSPACE" "<atom_for_wsname>" "<modify_type>"
464 * <modify_type> is one of:
469 ******************************<->***********************************/
471 dtSendWorkspaceModifyNotification(
482 msg = tt_pnotice_create(TT_SESSION, "DtWorkspace_Modified");
483 status = tt_ptr_error(msg);
484 if (status != TT_OK) {
487 sprintf(sNum, "%d", pSD->screen);
488 status = tt_message_arg_add(msg, TT_IN, Tttk_string, sNum);
489 if (status != TT_OK) {
492 sprintf (pch, "%ld", aWs);
493 status = tt_message_arg_add(msg, TT_IN, Tttk_string, pch);
494 if (status != TT_OK) {
497 sprintf (pchType, "%d", iType);
498 status = tt_message_arg_add(msg, TT_IN, Tttk_string, pchType);
499 if (status != TT_OK) {
502 status = tt_message_send(msg);
503 if (status != TT_OK) {
506 tt_message_destroy(msg);
510 /******************************<->*************************************
512 * dtSendMarqueeSelectionNotification ()
516 * This is called to announce marquee selection state
520 * pSD - pointer to screen data
521 * type - id of workspace just modified
522 * x - x position of UL corner of rectangle
523 * y - y position of UL corner of rectangle
524 * width - width of rectangle
525 * height - height of rectangle
535 * "MARQUEE_SELECTION" "<type>" "<x>" "<y>" "<width>" "<height>"
537 * <modify_type> is one of:
542 ******************************<->***********************************/
544 dtSendMarqueeSelectionNotification(
556 msg = tt_pnotice_create(TT_SESSION, "DtMarquee_Selection");
557 status = tt_ptr_error(msg);
558 if (status != TT_OK) {
562 sprintf(sNum, "%d", pSD->screen);
563 status = tt_message_arg_add(msg, TT_IN, Tttk_string, sNum);
564 if (status != TT_OK) {
567 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
570 if (tt_message_arg_ival_set(msg, 1, type) != TT_OK) {
573 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
576 if (tt_message_arg_ival_set(msg, 2, x) != TT_OK) {
579 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
582 if (tt_message_arg_ival_set(msg, 3, y) != TT_OK) {
585 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
588 if (tt_message_arg_ival_set(msg, 4, width) != TT_OK) {
591 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
594 if (tt_message_arg_ival_set(msg, 5, height) != TT_OK) {
597 status = tt_message_send(msg);
598 if (status != TT_OK) {
601 tt_message_destroy(msg);
605 /******************************<->*************************************
612 * This is called to handle busy and stopbusy message
616 * m = ToolTalk message
617 * p = ToolTalk pattern
621 * TT_CALLBACK_PROCESSED
622 * TT_CALLBACK_CINTINUE
626 ******************************<->***********************************/
628 NoticeMsgCB(Tt_message m, Tt_pattern p)
633 if (tt_message_state(m) != TT_SENT) {
634 return TT_CALLBACK_CONTINUE;
636 op = tt_message_op(m);
637 status = tt_ptr_error(op);
638 if (status != TT_OK) {
639 return TT_CALLBACK_CONTINUE;
641 if (!strcmp(op, "DtActivity_Began")) {
645 tt_message_destroy(m);
647 else if (!strcmp(op, "DtActivity_Beginning")) {
649 WmFrontPanelSetBusy (True);
653 tt_message_destroy(m);
655 else if (!strcmp(op, "DtTypes_Reloaded")) {
657 * Blink busy light during reload.
659 WmFrontPanelSetBusy (True);
662 * Load action definitions from the action database.
666 UpdateFileTypeControlFields();
669 * Turn off busy light.
671 WmFrontPanelSetBusy (False);
674 tt_message_destroy(m);
678 return TT_CALLBACK_PROCESSED;
680 } /* END OF FUNCTION NoticeMsgCB */
683 /******************************<->*************************************
690 * This is called to handle busy and stopbusy message
694 * m = ToolTalk message
695 * p = ToolTalk pattern
699 * TT_CALLBACK_PROCESSED
700 * TT_CALLBACK_CINTINUE
704 ******************************<->***********************************/
706 RequestMsgCB(Tt_message m, Tt_pattern p)
713 WmWorkspaceData *pWS = NULL;
718 if (tt_message_state(m) != TT_SENT) {
719 return TT_CALLBACK_CONTINUE;
721 op = tt_message_op(m);
722 status = tt_ptr_error(op);
723 if (status != TT_OK) {
724 return TT_CALLBACK_CONTINUE;
726 if (!strcmp(op, "DtPanel_Restore")) {
728 tt_message_destroy(m);
732 F_Restart( DTWM_REQP_NO_CONFIRM, NULL, NULL );
734 else if (!strcmp(op, "DtWorkspace_SetCurrent")) {
736 * 1st arg: integer, screen number
737 * 2nd arg: string, atom of workspace name
740 /* get the first arg from the message */
741 tt_message_arg_ival(m, 0, &screen_num);
742 pSD = &wmGD.Screens[screen_num];
744 /* get the second arg from the message */
745 pch = tt_message_arg_val(m, 1);
747 /* retrieve the selected workspace */
748 aWs = strtoul (pch, (char **) NULL, 0);
750 pWS = GetWorkspaceData (pSD, aWs);
753 ChangeToWorkspace (pWS);
757 tt_message_destroy(m);
759 else if (!strcmp(op, "DtWorkspace_Title_Set")) {
761 * 1st arg: integer, screen number
762 * 2nd arg: string, atom of workspace name
763 * 3rd arg: string, new name for the workspace
766 /* get the first arg from the message */
767 tt_message_arg_ival(m, 0, &screen_num);
768 pSD = &wmGD.Screens[screen_num];
770 /* get the second arg from the message */
771 pch = tt_message_arg_val(m, 1);
773 /* retrieve the selected workspace */
774 aWs = strtoul (pch, (char **) NULL, 0);
776 pWS = GetWorkspaceData (pSD, aWs);
778 /* get the third arg from the message */
779 pch = tt_message_arg_val(m, 2);
782 ChangeWorkspaceTitle (pWS, pch);
787 tt_message_destroy(m);
789 else if (!strcmp(op, "DtWorkspace_Add")) {
791 * 1st arg: string, user-visible title of the workspace
793 pch = tt_message_arg_val(m, 0);
795 F_CreateWorkspace( pch, NULL, NULL );
799 tt_message_destroy(m);
801 else if (!strcmp(op, "DtWorkspace_Delete")) {
803 * 1st arg: string, atom of workspace name
805 pch = tt_message_arg_val(m, 0);
807 /* retrieve the selected workspace */
808 aWs = strtoul (pch, (char **) NULL, 0);
810 sName = (String) XmGetAtomName (DISPLAY1, aWs);
812 F_DeleteWorkspace( sName, NULL, NULL );
815 tt_message_destroy(m);
819 else if (!strcmp(op, "GetWsmClients")) {
821 ClientData **clients;
824 if (GetSmClientIdClientList(&clients, &nClients))
826 char *clientIds = (char *)NULL;
827 int *clientWorkspaces = (int *)NULL;
830 SortClientListByWorkspace(clients, nClients);
832 tt_message_arg_ival_set(m, 0, nClients);
840 for (i = 0; i < nClients; i++)
841 clientIdLen += strlen(clients[i]->smClientID) + 1;
844 (char *)XtMalloc(clientIdLen * sizeof(char)))
847 (int *)XtMalloc(nClients * sizeof(int)))
850 if (clientIds != (char *)NULL)
853 /* LATER - Right way to handle errors? */
855 tt_message_destroy(m);
857 return TT_CALLBACK_PROCESSED;
861 for (i = 0, ptr = clientIds;
863 ptr += strlen(pCD->smClientID) + 1, i++)
866 strcpy(ptr, pCD->smClientID);
867 clientWorkspaces[i] =
869 pCD->pWsList[pCD->currentWsc].wsID;
876 tt_message_arg_bval_set(m, 1, (unsigned char *)clientIds,
877 clientIdLen * sizeof(char));
878 tt_message_arg_bval_set(m, 2, (unsigned char *)clientWorkspaces,
879 nClients * sizeof(int));
881 if (clientIds != (char *)NULL)
883 if (clientWorkspaces != (int *)NULL)
884 XtFree((char *)clientWorkspaces);
885 XtFree((char *)clients);
889 tt_message_destroy(m);
892 return TT_CALLBACK_CONTINUE;
896 return TT_CALLBACK_PROCESSED;
898 } /* END OF FUNCTION RequestMsgCB */
902 /******************************<->*************************************
918 ******************************<->***********************************/
919 #define GETXMSTRING(s, m, d) XmStringCreateLocalized(GETMESSAGE(s,m,d))
922 OKCB (Widget dialog, XtPointer client_data, XtPointer call_data)
924 XtUnmanageChild((Widget) client_data);
928 ToolTalkError(Widget parent, char *errfmt, Tt_status status)
931 Widget dialog, dialogShell;
932 char *errmsg, *statmsg, *title;
933 XmString xms_errmsg, xms_ok, xms_title;
936 if (! tt_is_err(status)) return;
938 statmsg = tt_status_message(status);
939 errmsg = XtMalloc(strlen(errfmt) + strlen(statmsg) + 2);
940 sprintf(errmsg, errfmt, statmsg);
942 xms_ok = GETXMSTRING(2, 3, "OK");
943 xms_errmsg = XmStringCreateLocalized(errmsg);
944 xms_title = GETXMSTRING(2, 1, "Dtwm - Error");
947 XtSetArg(args[n], XmNautoUnmanage, False); n++;
948 XtSetArg(args[n], XmNokLabelString, xms_ok); n++;
949 XtSetArg(args[n], XmNdialogTitle, xms_title); n++;
950 XtSetArg(args[n], XmNmessageString, xms_errmsg); n++;
951 XtSetArg(args[n], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); n++;
953 dialog = XmCreateErrorDialog(parent, "IconEditorError", args, n);
954 XtAddCallback(dialog, XmNokCallback, OKCB, (XtPointer) dialog);
955 XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_CANCEL_BUTTON));
956 XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));
959 * Disable the frame menu from dialog since we don't want the user
960 * to be able to close dialogs with the frame menu
962 dialogShell = XtParent(dialog);
964 XtSetArg(args[n], XmNmwmDecorations, MWM_DECOR_BORDER | MWM_DECOR_TITLE); n++;
965 XtSetValues(dialogShell, args, n);
966 XtManageChild(dialog);
967 XtRealizeWidget(dialogShell);
969 _DtSimpleError("Dtwm", DtFatalError, NULL, errmsg);
972 XmStringFree(xms_ok);
973 XmStringFree(xms_errmsg);
974 XmStringFree(xms_title);
976 /**************************** eof ***************************/