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: 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 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);
241 tt_free( default_session );
242 status = tt_pattern_class_add(notice_pattern, TT_NOTICE);
243 if (status != TT_OK) {
244 ToolTalkError(toplevel, errfmt, status);
247 status = tt_pattern_state_add(notice_pattern, TT_SENT);
248 if (status != TT_OK) {
249 ToolTalkError(toplevel, errfmt, status);
252 status = tt_pattern_class_add(request_pattern, TT_REQUEST);
253 if (status != TT_OK) {
254 ToolTalkError(toplevel, errfmt, status);
257 status = tt_pattern_state_add(request_pattern, TT_SENT);
258 if (status != TT_OK) {
259 ToolTalkError(toplevel, errfmt, status);
265 * Ops handled by the notice_pattern
267 status = tt_pattern_op_add(notice_pattern, "DtActivity_Beginning");
268 if (status != TT_OK) {
269 ToolTalkError(toplevel, errfmt, status);
272 status = tt_pattern_op_add(notice_pattern, "DtActivity_Began");
273 if (status != TT_OK) {
274 ToolTalkError(toplevel, errfmt, status);
277 status = tt_pattern_op_add(notice_pattern, "DtTypes_Reloaded");
278 if (status != TT_OK) {
279 ToolTalkError(toplevel, errfmt, status);
284 * Ops handled by the request_pattern
286 status = tt_pattern_op_add(request_pattern, "DtPanel_Restore");
287 if (status != TT_OK) {
288 ToolTalkError(toplevel, errfmt, status);
291 status = tt_pattern_op_add(request_pattern, "DtWorkspace_SetCurrent");
292 if (status != TT_OK) {
293 ToolTalkError(toplevel, errfmt, status);
296 status = tt_pattern_op_add(request_pattern, "DtWorkspace_Title_Set");
297 if (status != TT_OK) {
298 ToolTalkError(toplevel, errfmt, status);
301 status = tt_pattern_op_add(request_pattern, "DtWorkspace_Add");
302 if (status != TT_OK) {
303 ToolTalkError(toplevel, errfmt, status);
306 status = tt_pattern_op_add(request_pattern, "DtWorkspace_Delete");
307 if (status != TT_OK) {
308 ToolTalkError(toplevel, errfmt, status);
311 status = tt_pattern_op_add(request_pattern, "GetWsmClients");
312 if (status != TT_OK) {
313 ToolTalkError(toplevel, errfmt, status);
318 * Register callback for the notice_pattern
320 status = tt_pattern_callback_add(notice_pattern, NoticeMsgCB);
321 if (status != TT_OK) {
322 ToolTalkError(toplevel, errfmt, status);
327 * Register callback for the request_pattern
329 status = tt_pattern_callback_add(request_pattern, RequestMsgCB);
330 if (status != TT_OK) {
331 ToolTalkError(toplevel, errfmt, status);
335 status = tt_pattern_register(notice_pattern);
336 if (status != TT_OK) {
337 ToolTalkError(toplevel, errfmt, status);
340 status = tt_pattern_register(request_pattern);
341 if (status != TT_OK) {
342 ToolTalkError(toplevel, errfmt, status);
346 } /* END OF FUNCTION dtInitializeMessaging */
349 /******************************<->*************************************
355 * Shuts down the messaging mechanism
365 * Should be done before exiting
367 ******************************<->***********************************/
371 } /* END OF FUNCTION dtCloseIPC */
375 /******************************<->*************************************
377 * void dtReadyNotification()
381 * Tells the world that we're up and ready.
391 * Invoked as the fitting culmination of dtwm initialization
393 ******************************<->***********************************/
395 dtReadyNotification( void )
397 SendClientMsg( wmGD.dtSmWindow,
398 (long) wmGD.xa_DT_SM_WM_PROTOCOL,
399 (long) wmGD.xa_DT_WM_READY,
400 CurrentTime, NULL, 0);
402 } /* END OF FUNCTION dtReadyNotification */
405 /******************************<->*************************************
411 * This is called to turn off "system busy" activity
422 * This routine relies on two globals, blinkerPCW and dtSD,
423 * on the major assumptions that:
424 * - there is just one DT Screen, with the front panel enabled
425 * - there is just one dtwmbusy control in that front panel
426 ******************************<->***********************************/
428 WmStopWaiting( void )
433 WmFrontPanelSetBusy (False);
435 #endif /* PANELIST */
436 } /* END OF FUNCTION WmStopWaiting */
440 /******************************<->*************************************
442 * dtSendWorkspaceModifyNotification ()
446 * This is called to announce that the workspace set has been
451 * pSD - pointer to screen data
452 * aWs - id of workspace just modified
453 * iType - type of modification
463 * "MODIFY_WORKSPACE" "<atom_for_wsname>" "<modify_type>"
465 * <modify_type> is one of:
470 ******************************<->***********************************/
472 dtSendWorkspaceModifyNotification(
483 msg = tt_pnotice_create(TT_SESSION, "DtWorkspace_Modified");
484 status = tt_ptr_error(msg);
485 if (status != TT_OK) {
488 sprintf(sNum, "%d", pSD->screen);
489 status = tt_message_arg_add(msg, TT_IN, Tttk_string, sNum);
490 if (status != TT_OK) {
493 sprintf (pch, "%ld", aWs);
494 status = tt_message_arg_add(msg, TT_IN, Tttk_string, pch);
495 if (status != TT_OK) {
498 sprintf (pchType, "%d", iType);
499 status = tt_message_arg_add(msg, TT_IN, Tttk_string, pchType);
500 if (status != TT_OK) {
503 status = tt_message_send(msg);
504 if (status != TT_OK) {
507 tt_message_destroy(msg);
511 /******************************<->*************************************
513 * dtSendMarqueeSelectionNotification ()
517 * This is called to announce marquee selection state
521 * pSD - pointer to screen data
522 * type - id of workspace just modified
523 * x - x position of UL corner of rectangle
524 * y - y position of UL corner of rectangle
525 * width - width of rectangle
526 * heigth - height of rectangle
536 * "MARQUEE_SELECTION" "<type>" "<x>" "<y>" "<width>" "<height>"
538 * <modify_type> is one of:
543 ******************************<->***********************************/
545 dtSendMarqueeSelectionNotification(
557 msg = tt_pnotice_create(TT_SESSION, "DtMarquee_Selection");
558 status = tt_ptr_error(msg);
559 if (status != TT_OK) {
563 sprintf(sNum, "%d", pSD->screen);
564 status = tt_message_arg_add(msg, TT_IN, Tttk_string, sNum);
565 if (status != TT_OK) {
568 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
571 if (tt_message_arg_ival_set(msg, 1, type) != TT_OK) {
574 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
577 if (tt_message_arg_ival_set(msg, 2, x) != TT_OK) {
580 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
583 if (tt_message_arg_ival_set(msg, 3, y) != TT_OK) {
586 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
589 if (tt_message_arg_ival_set(msg, 4, width) != TT_OK) {
592 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
595 if (tt_message_arg_ival_set(msg, 5, height) != TT_OK) {
598 status = tt_message_send(msg);
599 if (status != TT_OK) {
602 tt_message_destroy(msg);
606 /******************************<->*************************************
613 * This is called to handle busy and stopbusy message
617 * m = ToolTalk message
618 * p = ToolTalk pattern
622 * TT_CALLBACK_PROCESSED
623 * TT_CALLBACK_CINTINUE
627 ******************************<->***********************************/
629 NoticeMsgCB(Tt_message m, Tt_pattern p)
634 if (tt_message_state(m) != TT_SENT) {
635 return TT_CALLBACK_CONTINUE;
637 op = tt_message_op(m);
638 status = tt_ptr_error(op);
639 if (status != TT_OK) {
640 return TT_CALLBACK_CONTINUE;
642 if (!strcmp(op, "DtActivity_Began")) {
646 tt_message_destroy(m);
649 else if (!strcmp(op, "DtActivity_Beginning")) {
651 WmFrontPanelSetBusy (True);
655 tt_message_destroy(m);
657 #endif /* PANELIST */
658 else if (!strcmp(op, "DtTypes_Reloaded")) {
660 * Blink busy light during reload.
662 WmFrontPanelSetBusy (True);
665 * Load action definitions from the action database.
669 UpdateFileTypeControlFields();
672 * Turn off busy light.
674 WmFrontPanelSetBusy (False);
677 tt_message_destroy(m);
681 return TT_CALLBACK_PROCESSED;
683 } /* END OF FUNCTION NoticeMsgCB */
686 /******************************<->*************************************
693 * This is called to handle busy and stopbusy message
697 * m = ToolTalk message
698 * p = ToolTalk pattern
702 * TT_CALLBACK_PROCESSED
703 * TT_CALLBACK_CINTINUE
707 ******************************<->***********************************/
709 RequestMsgCB(Tt_message m, Tt_pattern p)
716 WmWorkspaceData *pWS = NULL;
721 if (tt_message_state(m) != TT_SENT) {
722 return TT_CALLBACK_CONTINUE;
724 op = tt_message_op(m);
725 status = tt_ptr_error(op);
726 if (status != TT_OK) {
727 return TT_CALLBACK_CONTINUE;
729 if (!strcmp(op, "DtPanel_Restore")) {
731 tt_message_destroy(m);
735 F_Restart( DTWM_REQP_NO_CONFIRM, NULL, NULL );
737 else if (!strcmp(op, "DtWorkspace_SetCurrent")) {
739 * 1st arg: integer, screen number
740 * 2nd arg: string, atom of workspace name
743 /* get the first arg from the message */
744 tt_message_arg_ival(m, 0, &screen_num);
745 pSD = &wmGD.Screens[screen_num];
747 /* get the second arg from the message */
748 pch = tt_message_arg_val(m, 1);
750 /* retrieve the selected workspace */
751 aWs = strtoul (pch, (char **) NULL, 0);
753 pWS = GetWorkspaceData (pSD, aWs);
756 ChangeToWorkspace (pWS);
760 tt_message_destroy(m);
762 else if (!strcmp(op, "DtWorkspace_Title_Set")) {
764 * 1st arg: integer, screen number
765 * 2nd arg: string, atom of workspace name
766 * 3rd arg: string, new name for the workspace
769 /* get the first arg from the message */
770 tt_message_arg_ival(m, 0, &screen_num);
771 pSD = &wmGD.Screens[screen_num];
773 /* get the second arg from the message */
774 pch = tt_message_arg_val(m, 1);
776 /* retrieve the selected workspace */
777 aWs = strtoul (pch, (char **) NULL, 0);
779 pWS = GetWorkspaceData (pSD, aWs);
781 /* get the third arg from the message */
782 pch = tt_message_arg_val(m, 2);
785 ChangeWorkspaceTitle (pWS, pch);
790 tt_message_destroy(m);
792 else if (!strcmp(op, "DtWorkspace_Add")) {
794 * 1st arg: string, user-visible title of the workspace
796 pch = tt_message_arg_val(m, 0);
798 F_CreateWorkspace( pch, NULL, NULL );
802 tt_message_destroy(m);
804 else if (!strcmp(op, "DtWorkspace_Delete")) {
806 * 1st arg: string, atom of workspace name
808 pch = tt_message_arg_val(m, 0);
810 /* retrieve the selected workspace */
811 aWs = strtoul (pch, (char **) NULL, 0);
813 sName = (String) XmGetAtomName (DISPLAY1, aWs);
815 F_DeleteWorkspace( sName, NULL, NULL );
818 tt_message_destroy(m);
822 else if (!strcmp(op, "GetWsmClients")) {
824 ClientData **clients;
827 if (GetSmClientIdClientList(&clients, &nClients))
829 char *clientIds = (char *)NULL;
830 int *clientWorkspaces = (int *)NULL;
833 SortClientListByWorkspace(clients, nClients);
835 tt_message_arg_ival_set(m, 0, nClients);
843 for (i = 0; i < nClients; i++)
844 clientIdLen += strlen(clients[i]->smClientID) + 1;
847 (char *)XtMalloc(clientIdLen * sizeof(char)))
850 (int *)XtMalloc(nClients * sizeof(int)))
853 if (clientIds != (char *)NULL)
856 /* LATER - Right way to handle errors? */
858 tt_message_destroy(m);
860 return TT_CALLBACK_PROCESSED;
864 for (i = 0, ptr = clientIds;
866 ptr += strlen(pCD->smClientID) + 1, i++)
869 strcpy(ptr, pCD->smClientID);
870 clientWorkspaces[i] =
872 pCD->pWsList[pCD->currentWsc].wsID;
879 tt_message_arg_bval_set(m, 1, (unsigned char *)clientIds,
880 clientIdLen * sizeof(char));
881 tt_message_arg_bval_set(m, 2, (unsigned char *)clientWorkspaces,
882 nClients * sizeof(int));
884 if (clientIds != (char *)NULL)
886 if (clientWorkspaces != (int *)NULL)
887 XtFree((char *)clientWorkspaces);
888 XtFree((char *)clients);
892 tt_message_destroy(m);
895 return TT_CALLBACK_CONTINUE;
899 return TT_CALLBACK_PROCESSED;
901 } /* END OF FUNCTION RequestMsgCB */
905 /******************************<->*************************************
921 ******************************<->***********************************/
922 #define GETXMSTRING(s, m, d) XmStringCreateLocalized(GETMESSAGE(s,m,d))
925 OKCB (Widget dialog, XtPointer client_data, XtPointer call_data)
927 XtUnmanageChild((Widget) client_data);
931 ToolTalkError(Widget parent, char *errfmt, Tt_status status)
934 Widget dialog, dialogShell;
935 char *errmsg, *statmsg, *title;
936 XmString xms_errmsg, xms_ok, xms_title;
939 if (! tt_is_err(status)) return;
941 statmsg = tt_status_message(status);
942 errmsg = XtMalloc(strlen(errfmt) + strlen(statmsg) + 2);
943 sprintf(errmsg, errfmt, statmsg);
945 xms_ok = GETXMSTRING(2, 3, "OK");
946 xms_errmsg = XmStringCreateLocalized(errmsg);
947 xms_title = GETXMSTRING(2, 1, "Dtwm - Error");
950 XtSetArg(args[n], XmNautoUnmanage, False); n++;
951 XtSetArg(args[n], XmNokLabelString, xms_ok); n++;
952 XtSetArg(args[n], XmNdialogTitle, xms_title); n++;
953 XtSetArg(args[n], XmNmessageString, xms_errmsg); n++;
954 XtSetArg(args[n], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); n++;
956 dialog = XmCreateErrorDialog(parent, "IconEditorError", args, n);
957 XtAddCallback(dialog, XmNokCallback, OKCB, (XtPointer) dialog);
958 XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_CANCEL_BUTTON));
959 XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));
962 * Disable the frame menu from dialog since we don't want the user
963 * to be able to close dialogs with the frame menu
965 dialogShell = XtParent(dialog);
967 XtSetArg(args[n], XmNmwmDecorations, MWM_DECOR_BORDER | MWM_DECOR_TITLE); n++;
968 XtSetValues(dialogShell, args, n);
969 XtManageChild(dialog);
970 XtRealizeWidget(dialogShell);
972 _DtSimpleError("Dtwm", DtFatalError, NULL, errmsg);
975 XmStringFree(xms_ok);
976 XmStringFree(xms_errmsg);
977 XmStringFree(xms_title);
979 /**************************** eof ***************************/