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 )
434 WmFrontPanelSetBusy (False);
436 #endif /* PANELIST */
437 } /* END OF FUNCTION WmStopWaiting */
441 /******************************<->*************************************
443 * dtSendWorkspaceModifyNotification ()
447 * This is called to announce that the workspace set has been
452 * pSD - pointer to screen data
453 * aWs - id of workspace just modified
454 * iType - type of modification
464 * "MODIFY_WORKSPACE" "<atom_for_wsname>" "<modify_type>"
466 * <modify_type> is one of:
471 ******************************<->***********************************/
473 dtSendWorkspaceModifyNotification(
484 msg = tt_pnotice_create(TT_SESSION, "DtWorkspace_Modified");
485 status = tt_ptr_error(msg);
486 if (status != TT_OK) {
489 sprintf(sNum, "%d", pSD->screen);
490 status = tt_message_arg_add(msg, TT_IN, Tttk_string, sNum);
491 if (status != TT_OK) {
494 sprintf (pch, "%ld", aWs);
495 status = tt_message_arg_add(msg, TT_IN, Tttk_string, pch);
496 if (status != TT_OK) {
499 sprintf (pchType, "%d", iType);
500 status = tt_message_arg_add(msg, TT_IN, Tttk_string, pchType);
501 if (status != TT_OK) {
504 status = tt_message_send(msg);
505 if (status != TT_OK) {
508 tt_message_destroy(msg);
512 /******************************<->*************************************
514 * dtSendMarqueeSelectionNotification ()
518 * This is called to announce marquee selection state
522 * pSD - pointer to screen data
523 * type - id of workspace just modified
524 * x - x position of UL corner of rectangle
525 * y - y position of UL corner of rectangle
526 * width - width of rectangle
527 * heigth - height of rectangle
537 * "MARQUEE_SELECTION" "<type>" "<x>" "<y>" "<width>" "<height>"
539 * <modify_type> is one of:
544 ******************************<->***********************************/
546 dtSendMarqueeSelectionNotification(
558 msg = tt_pnotice_create(TT_SESSION, "DtMarquee_Selection");
559 status = tt_ptr_error(msg);
560 if (status != TT_OK) {
564 sprintf(sNum, "%d", pSD->screen);
565 status = tt_message_arg_add(msg, TT_IN, Tttk_string, sNum);
566 if (status != TT_OK) {
569 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
572 if (tt_message_arg_ival_set(msg, 1, type) != TT_OK) {
575 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
578 if (tt_message_arg_ival_set(msg, 2, x) != TT_OK) {
581 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
584 if (tt_message_arg_ival_set(msg, 3, y) != TT_OK) {
587 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
590 if (tt_message_arg_ival_set(msg, 4, width) != TT_OK) {
593 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
596 if (tt_message_arg_ival_set(msg, 5, height) != TT_OK) {
599 status = tt_message_send(msg);
600 if (status != TT_OK) {
603 tt_message_destroy(msg);
607 /******************************<->*************************************
614 * This is called to handle busy and stopbusy message
618 * m = ToolTalk message
619 * p = ToolTalk pattern
623 * TT_CALLBACK_PROCESSED
624 * TT_CALLBACK_CINTINUE
628 ******************************<->***********************************/
630 NoticeMsgCB(Tt_message m, Tt_pattern p)
635 if (tt_message_state(m) != TT_SENT) {
636 return TT_CALLBACK_CONTINUE;
638 op = tt_message_op(m);
639 status = tt_ptr_error(op);
640 if (status != TT_OK) {
641 return TT_CALLBACK_CONTINUE;
643 if (!strcmp(op, "DtActivity_Began")) {
647 tt_message_destroy(m);
650 else if (!strcmp(op, "DtActivity_Beginning")) {
652 WmFrontPanelSetBusy (True);
656 tt_message_destroy(m);
658 #endif /* PANELIST */
659 else if (!strcmp(op, "DtTypes_Reloaded")) {
661 * Blink busy light during reload.
663 WmFrontPanelSetBusy (True);
666 * Load action definitions from the action database.
670 UpdateFileTypeControlFields();
673 * Turn off busy light.
675 WmFrontPanelSetBusy (False);
678 tt_message_destroy(m);
682 return TT_CALLBACK_PROCESSED;
684 } /* END OF FUNCTION NoticeMsgCB */
687 /******************************<->*************************************
694 * This is called to handle busy and stopbusy message
698 * m = ToolTalk message
699 * p = ToolTalk pattern
703 * TT_CALLBACK_PROCESSED
704 * TT_CALLBACK_CINTINUE
708 ******************************<->***********************************/
710 RequestMsgCB(Tt_message m, Tt_pattern p)
717 WmWorkspaceData *pWS = NULL;
722 if (tt_message_state(m) != TT_SENT) {
723 return TT_CALLBACK_CONTINUE;
725 op = tt_message_op(m);
726 status = tt_ptr_error(op);
727 if (status != TT_OK) {
728 return TT_CALLBACK_CONTINUE;
730 if (!strcmp(op, "DtPanel_Restore")) {
732 tt_message_destroy(m);
736 F_Restart( DTWM_REQP_NO_CONFIRM, NULL, NULL );
738 else if (!strcmp(op, "DtWorkspace_SetCurrent")) {
740 * 1st arg: integer, screen number
741 * 2nd arg: string, atom of workspace name
744 /* get the first arg from the message */
745 tt_message_arg_ival(m, 0, &screen_num);
746 pSD = &wmGD.Screens[screen_num];
748 /* get the second arg from the message */
749 pch = tt_message_arg_val(m, 1);
751 /* retrieve the selected workspace */
752 aWs = strtoul (pch, (char **) NULL, 0);
754 pWS = GetWorkspaceData (pSD, aWs);
757 ChangeToWorkspace (pWS);
761 tt_message_destroy(m);
763 else if (!strcmp(op, "DtWorkspace_Title_Set")) {
765 * 1st arg: integer, screen number
766 * 2nd arg: string, atom of workspace name
767 * 3rd arg: string, new name for the workspace
770 /* get the first arg from the message */
771 tt_message_arg_ival(m, 0, &screen_num);
772 pSD = &wmGD.Screens[screen_num];
774 /* get the second arg from the message */
775 pch = tt_message_arg_val(m, 1);
777 /* retrieve the selected workspace */
778 aWs = strtoul (pch, (char **) NULL, 0);
780 pWS = GetWorkspaceData (pSD, aWs);
782 /* get the third arg from the message */
783 pch = tt_message_arg_val(m, 2);
786 ChangeWorkspaceTitle (pWS, pch);
791 tt_message_destroy(m);
793 else if (!strcmp(op, "DtWorkspace_Add")) {
795 * 1st arg: string, user-visible title of the workspace
797 pch = tt_message_arg_val(m, 0);
799 F_CreateWorkspace( pch, NULL, NULL );
803 tt_message_destroy(m);
805 else if (!strcmp(op, "DtWorkspace_Delete")) {
807 * 1st arg: string, atom of workspace name
809 pch = tt_message_arg_val(m, 0);
811 /* retrieve the selected workspace */
812 aWs = strtoul (pch, (char **) NULL, 0);
814 sName = (String) XmGetAtomName (DISPLAY1, aWs);
816 F_DeleteWorkspace( sName, NULL, NULL );
819 tt_message_destroy(m);
823 else if (!strcmp(op, "GetWsmClients")) {
825 ClientData **clients;
828 if (GetSmClientIdClientList(&clients, &nClients))
830 char *clientIds = (char *)NULL;
831 int *clientWorkspaces = (int *)NULL;
834 SortClientListByWorkspace(clients, nClients);
836 tt_message_arg_ival_set(m, 0, nClients);
844 for (i = 0; i < nClients; i++)
845 clientIdLen += strlen(clients[i]->smClientID) + 1;
848 (char *)XtMalloc(clientIdLen * sizeof(char)))
851 (int *)XtMalloc(nClients * sizeof(int)))
854 if (clientIds != (char *)NULL)
857 /* LATER - Right way to handle errors? */
859 tt_message_destroy(m);
861 return TT_CALLBACK_PROCESSED;
865 for (i = 0, ptr = clientIds;
867 ptr += strlen(pCD->smClientID) + 1, i++)
870 strcpy(ptr, pCD->smClientID);
871 clientWorkspaces[i] =
873 pCD->pWsList[pCD->currentWsc].wsID;
880 tt_message_arg_bval_set(m, 1, (unsigned char *)clientIds,
881 clientIdLen * sizeof(char));
882 tt_message_arg_bval_set(m, 2, (unsigned char *)clientWorkspaces,
883 nClients * sizeof(int));
885 if (clientIds != (char *)NULL)
887 if (clientWorkspaces != (int *)NULL)
888 XtFree((char *)clientWorkspaces);
889 XtFree((char *)clients);
893 tt_message_destroy(m);
896 return TT_CALLBACK_CONTINUE;
900 return TT_CALLBACK_PROCESSED;
902 } /* END OF FUNCTION RequestMsgCB */
906 /******************************<->*************************************
922 ******************************<->***********************************/
923 #define GETXMSTRING(s, m, d) XmStringCreateLocalized(GETMESSAGE(s,m,d))
926 OKCB (Widget dialog, XtPointer client_data, XtPointer call_data)
928 XtUnmanageChild((Widget) client_data);
932 ToolTalkError(Widget parent, char *errfmt, Tt_status status)
935 Widget dialog, dialogShell;
936 char *errmsg, *statmsg, *title;
937 XmString xms_errmsg, xms_ok, xms_title;
940 if (! tt_is_err(status)) return;
942 statmsg = tt_status_message(status);
943 errmsg = XtMalloc(strlen(errfmt) + strlen(statmsg) + 2);
944 sprintf(errmsg, errfmt, statmsg);
946 xms_ok = GETXMSTRING(2, 3, "OK");
947 xms_errmsg = XmStringCreateLocalized(errmsg);
948 xms_title = GETXMSTRING(2, 1, "Dtwm - Error");
951 XtSetArg(args[n], XmNautoUnmanage, False); n++;
952 XtSetArg(args[n], XmNokLabelString, xms_ok); n++;
953 XtSetArg(args[n], XmNdialogTitle, xms_title); n++;
954 XtSetArg(args[n], XmNmessageString, xms_errmsg); n++;
955 XtSetArg(args[n], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); n++;
957 dialog = XmCreateErrorDialog(parent, "IconEditorError", args, n);
958 XtAddCallback(dialog, XmNokCallback, OKCB, (XtPointer) dialog);
959 XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_CANCEL_BUTTON));
960 XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));
963 * Disable the frame menu from dialog since we don't want the user
964 * to be able to close dialogs with the frame menu
966 dialogShell = XtParent(dialog);
968 XtSetArg(args[n], XmNmwmDecorations, MWM_DECOR_BORDER | MWM_DECOR_TITLE); n++;
969 XtSetValues(dialogShell, args, n);
970 XtManageChild(dialog);
971 XtRealizeWidget(dialogShell);
973 _DtSimpleError("Dtwm", DtFatalError, NULL, errmsg);
976 XmStringFree(xms_ok);
977 XmStringFree(xms_errmsg);
978 XmStringFree(xms_title);
980 /**************************** eof ***************************/