1 /* $TOG: WmIPC.c /main/11 1999/09/20 15:17:25 mgreess $ */
3 * (c) Copyright 1997, The Open Group
6 * (c) Copyright 1987, 1988, 1989, 1990, 1992, 1993 HEWLETT-PACKARD COMPANY
11 static char rcsid[] = ""
21 #include <Dt/Action.h>
23 #include <Dt/IndicatorM.h>
24 #include <Dt/UserMsg.h>
27 #include "WmBackdrop.h"
29 #include "WmFunction.h"
30 #include "WmWrkspace.h"
32 #include "DataBaseLoad.h"
36 * include extern functions and definitions
39 extern void UpdateFileTypeControlFields ( void );
40 extern WmScreenData * GetScreenForWindow (Window);
42 static void ToolTalkError(Widget, char*, Tt_status);
46 * data for the "DT screen"
53 Const char *szWM_TOOL_CLASS = DtWM_TOOL_CLASS;
57 /******************************<->*************************************
59 * dtInitialize (char * program_name, XtAppContext appContext)
63 * Initialize the messaging mechanism
67 * program_name - argv[0]
68 * appContext - used throughout the WM
76 ******************************<->***********************************/
80 XtAppContext appContext )
83 (void) DtAppInitialize(appContext, DISPLAY1, wmGD.topLevelW1,
84 program_name, (char *)szWM_TOOL_CLASS);
87 * Load action definitions from the action database.
90 _DtPerfChkpntMsgSend("Begin action database load");
96 _DtPerfChkpntMsgSend("End action database load");
99 } /* END OF FUNCTION dtInitialize */
101 /******************************<->*************************************
103 * dtInitializeMessaging (Widget)
107 * Initialize the messaging mechanisms
118 ******************************<->***********************************/
121 dtInitializeMessaging(Widget toplevel)
128 Tt_pattern notice_pattern, request_pattern;
129 char *default_session;
135 Tt_callback_action NoticeMsgCB(
138 Tt_callback_action RequestMsgCB(
143 * Makef sure we have a ToolTalk connection
146 status = tt_ptr_error(procId);
147 if (status != TT_OK) {
149 GETMESSAGE(2, 2, "Could not connect to ToolTalk:\n%s\n");
150 ToolTalkError(toplevel, errfmt, status);
154 status = tt_int_error(fd);
155 if (status == TT_OK) {
156 XtAppAddInput(XtWidgetToApplicationContext(wmGD.topLevelW), fd,
157 (XtPointer)XtInputReadMask, tttk_Xt_input_handler, procId);
159 ToolTalkError(toplevel, "tt_fd()", status);
163 default_session = tt_default_session();
164 status = tt_ptr_error(default_session);
165 if (status != TT_OK) {
166 GETMESSAGE(2, 4, "Could not get default ToolTalk session:\n%s\n");
167 ToolTalkError(toplevel, errfmt, status);
171 errfmt = GETMESSAGE(2, 5, "Error constructing ToolTalk pattern:\n%s\n");
172 notice_pattern = tt_pattern_create();
173 status = tt_ptr_error(notice_pattern);
174 if (status != TT_OK) {
175 ToolTalkError(toplevel, errfmt, status);
178 request_pattern = tt_pattern_create();
179 status = tt_ptr_error(request_pattern);
180 if (status != TT_OK) {
181 ToolTalkError(toplevel, errfmt, status);
185 status = tt_pattern_category_set(notice_pattern, TT_OBSERVE);
186 if (status != TT_OK) {
187 ToolTalkError(toplevel, errfmt, status);
190 status = tt_pattern_category_set(request_pattern, TT_HANDLE);
191 if (status != TT_OK) {
192 ToolTalkError(toplevel, errfmt, status);
195 status = tt_pattern_scope_add(notice_pattern, TT_SESSION);
196 if (status != TT_OK) {
197 ToolTalkError(toplevel, errfmt, status);
200 status = tt_pattern_scope_add(request_pattern, TT_SESSION);
201 if (status != TT_OK) {
202 ToolTalkError(toplevel, errfmt, status);
205 status = tt_pattern_session_add(notice_pattern, default_session);
206 if (status != TT_OK) {
207 ToolTalkError(toplevel, errfmt, status);
210 status = tt_pattern_session_add(request_pattern, default_session);
211 if (status != TT_OK) {
212 ToolTalkError(toplevel, errfmt, status);
215 tt_free( default_session );
216 status = tt_pattern_class_add(notice_pattern, TT_NOTICE);
217 if (status != TT_OK) {
218 ToolTalkError(toplevel, errfmt, status);
221 status = tt_pattern_state_add(notice_pattern, TT_SENT);
222 if (status != TT_OK) {
223 ToolTalkError(toplevel, errfmt, status);
226 status = tt_pattern_class_add(request_pattern, TT_REQUEST);
227 if (status != TT_OK) {
228 ToolTalkError(toplevel, errfmt, status);
231 status = tt_pattern_state_add(request_pattern, TT_SENT);
232 if (status != TT_OK) {
233 ToolTalkError(toplevel, errfmt, status);
239 * Ops handled by the notice_pattern
241 status = tt_pattern_op_add(notice_pattern, "DtActivity_Beginning");
242 if (status != TT_OK) {
243 ToolTalkError(toplevel, errfmt, status);
246 status = tt_pattern_op_add(notice_pattern, "DtActivity_Began");
247 if (status != TT_OK) {
248 ToolTalkError(toplevel, errfmt, status);
251 status = tt_pattern_op_add(notice_pattern, "DtTypes_Reloaded");
252 if (status != TT_OK) {
253 ToolTalkError(toplevel, errfmt, status);
258 * Ops handled by the request_pattern
260 status = tt_pattern_op_add(request_pattern, "DtPanel_Restore");
261 if (status != TT_OK) {
262 ToolTalkError(toplevel, errfmt, status);
265 status = tt_pattern_op_add(request_pattern, "DtWorkspace_SetCurrent");
266 if (status != TT_OK) {
267 ToolTalkError(toplevel, errfmt, status);
270 status = tt_pattern_op_add(request_pattern, "DtWorkspace_Title_Set");
271 if (status != TT_OK) {
272 ToolTalkError(toplevel, errfmt, status);
275 status = tt_pattern_op_add(request_pattern, "DtWorkspace_Add");
276 if (status != TT_OK) {
277 ToolTalkError(toplevel, errfmt, status);
280 status = tt_pattern_op_add(request_pattern, "DtWorkspace_Delete");
281 if (status != TT_OK) {
282 ToolTalkError(toplevel, errfmt, status);
285 status = tt_pattern_op_add(request_pattern, "GetWsmClients");
286 if (status != TT_OK) {
287 ToolTalkError(toplevel, errfmt, status);
292 * Register callback for the notice_pattern
294 status = tt_pattern_callback_add(notice_pattern, NoticeMsgCB);
295 if (status != TT_OK) {
296 ToolTalkError(toplevel, errfmt, status);
301 * Register callback for the request_pattern
303 status = tt_pattern_callback_add(request_pattern, RequestMsgCB);
304 if (status != TT_OK) {
305 ToolTalkError(toplevel, errfmt, status);
309 status = tt_pattern_register(notice_pattern);
310 if (status != TT_OK) {
311 ToolTalkError(toplevel, errfmt, status);
314 status = tt_pattern_register(request_pattern);
315 if (status != TT_OK) {
316 ToolTalkError(toplevel, errfmt, status);
320 } /* END OF FUNCTION dtInitializeMessaging */
323 /******************************<->*************************************
329 * Shuts down the messaging mechanism
339 * Should be done before exiting
341 ******************************<->***********************************/
345 } /* END OF FUNCTION dtCloseIPC */
349 /******************************<->*************************************
351 * void dtReadyNotification()
355 * Tells the world that we're up and ready.
365 * Invoked as the fitting culmination of dtwm initialization
367 ******************************<->***********************************/
369 dtReadyNotification( void )
371 SendClientMsg( wmGD.dtSmWindow,
372 (long) wmGD.xa_DT_SM_WM_PROTOCOL,
373 (long) wmGD.xa_DT_WM_READY,
374 CurrentTime, NULL, 0);
376 } /* END OF FUNCTION dtReadyNotification */
379 /******************************<->*************************************
385 * This is called to turn off "system busy" activity
396 * This routine relies on two globals, blinkerPCW and dtSD,
397 * on the major assumptions that:
398 * - there is just one DT Screen, with the front panel enabled
399 * - there is just one dtwmbusy control in that front panel
400 ******************************<->***********************************/
402 WmStopWaiting( void )
407 WmFrontPanelSetBusy (False);
409 #endif /* PANELIST */
410 } /* END OF FUNCTION WmStopWaiting */
414 /******************************<->*************************************
416 * dtSendWorkspaceModifyNotification ()
420 * This is called to announce that the workspace set has been
425 * pSD - pointer to screen data
426 * aWs - id of workspace just modified
427 * iType - type of modification
437 * "MODIFY_WORKSPACE" "<atom_for_wsname>" "<modify_type>"
439 * <modify_type> is one of:
444 ******************************<->***********************************/
446 dtSendWorkspaceModifyNotification(
457 msg = tt_pnotice_create(TT_SESSION, "DtWorkspace_Modified");
458 status = tt_ptr_error(msg);
459 if (status != TT_OK) {
462 sprintf(sNum, "%d", pSD->screen);
463 status = tt_message_arg_add(msg, TT_IN, Tttk_string, sNum);
464 if (status != TT_OK) {
467 sprintf (pch, "%ld", aWs);
468 status = tt_message_arg_add(msg, TT_IN, Tttk_string, pch);
469 if (status != TT_OK) {
472 sprintf (pchType, "%d", iType);
473 status = tt_message_arg_add(msg, TT_IN, Tttk_string, pchType);
474 if (status != TT_OK) {
477 status = tt_message_send(msg);
478 if (status != TT_OK) {
481 tt_message_destroy(msg);
485 /******************************<->*************************************
487 * dtSendMarqueeSelectionNotification ()
491 * This is called to announce marquee selection state
495 * pSD - pointer to screen data
496 * type - id of workspace just modified
497 * x - x position of UL corner of rectangle
498 * y - y position of UL corner of rectangle
499 * width - width of rectangle
500 * heigth - height of rectangle
510 * "MARQUEE_SELECTION" "<type>" "<x>" "<y>" "<width>" "<height>"
512 * <modify_type> is one of:
517 ******************************<->***********************************/
519 dtSendMarqueeSelectionNotification(
531 msg = tt_pnotice_create(TT_SESSION, "DtMarquee_Selection");
532 status = tt_ptr_error(msg);
533 if (status != TT_OK) {
537 sprintf(sNum, "%d", pSD->screen);
538 status = tt_message_arg_add(msg, TT_IN, Tttk_string, sNum);
539 if (status != TT_OK) {
542 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
545 if (tt_message_arg_ival_set(msg, 1, type) != TT_OK) {
548 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
551 if (tt_message_arg_ival_set(msg, 2, x) != TT_OK) {
554 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
557 if (tt_message_arg_ival_set(msg, 3, y) != TT_OK) {
560 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
563 if (tt_message_arg_ival_set(msg, 4, width) != TT_OK) {
566 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
569 if (tt_message_arg_ival_set(msg, 5, height) != TT_OK) {
572 status = tt_message_send(msg);
573 if (status != TT_OK) {
576 tt_message_destroy(msg);
580 /******************************<->*************************************
587 * This is called to handle busy and stopbusy message
591 * m = ToolTalk message
592 * p = ToolTalk pattern
596 * TT_CALLBACK_PROCESSED
597 * TT_CALLBACK_CINTINUE
601 ******************************<->***********************************/
603 NoticeMsgCB(Tt_message m, Tt_pattern p)
608 if (tt_message_state(m) != TT_SENT) {
609 return TT_CALLBACK_CONTINUE;
611 op = tt_message_op(m);
612 status = tt_ptr_error(op);
613 if (status != TT_OK) {
614 return TT_CALLBACK_CONTINUE;
616 if (!strcmp(op, "DtActivity_Began")) {
620 tt_message_destroy(m);
623 else if (!strcmp(op, "DtActivity_Beginning")) {
625 WmFrontPanelSetBusy (True);
629 tt_message_destroy(m);
631 #endif /* PANELIST */
632 else if (!strcmp(op, "DtTypes_Reloaded")) {
634 * Blink busy light during reload.
636 WmFrontPanelSetBusy (True);
639 * Load action definitions from the action database.
643 UpdateFileTypeControlFields();
646 * Turn off busy light.
648 WmFrontPanelSetBusy (False);
651 tt_message_destroy(m);
655 return TT_CALLBACK_PROCESSED;
657 } /* END OF FUNCTION NoticeMsgCB */
660 /******************************<->*************************************
667 * This is called to handle busy and stopbusy message
671 * m = ToolTalk message
672 * p = ToolTalk pattern
676 * TT_CALLBACK_PROCESSED
677 * TT_CALLBACK_CINTINUE
681 ******************************<->***********************************/
683 RequestMsgCB(Tt_message m, Tt_pattern p)
690 WmWorkspaceData *pWS = NULL;
695 if (tt_message_state(m) != TT_SENT) {
696 return TT_CALLBACK_CONTINUE;
698 op = tt_message_op(m);
699 status = tt_ptr_error(op);
700 if (status != TT_OK) {
701 return TT_CALLBACK_CONTINUE;
703 if (!strcmp(op, "DtPanel_Restore")) {
705 tt_message_destroy(m);
709 F_Restart( DTWM_REQP_NO_CONFIRM, NULL, NULL );
711 else if (!strcmp(op, "DtWorkspace_SetCurrent")) {
713 * 1st arg: integer, screen number
714 * 2nd arg: string, atom of workspace name
717 /* get the first arg from the message */
718 tt_message_arg_ival(m, 0, &screen_num);
719 pSD = &wmGD.Screens[screen_num];
721 /* get the second arg from the message */
722 pch = tt_message_arg_val(m, 1);
724 /* retrieve the selected workspace */
725 aWs = strtoul (pch, (char **) NULL, 0);
727 pWS = GetWorkspaceData (pSD, aWs);
730 ChangeToWorkspace (pWS);
734 tt_message_destroy(m);
736 else if (!strcmp(op, "DtWorkspace_Title_Set")) {
738 * 1st arg: integer, screen number
739 * 2nd arg: string, atom of workspace name
740 * 3rd arg: string, new name for the workspace
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);
755 /* get the third arg from the message */
756 pch = tt_message_arg_val(m, 2);
759 ChangeWorkspaceTitle (pWS, pch);
764 tt_message_destroy(m);
766 else if (!strcmp(op, "DtWorkspace_Add")) {
768 * 1st arg: string, user-visible title of the workspace
770 pch = tt_message_arg_val(m, 0);
772 F_CreateWorkspace( pch, NULL, NULL );
776 tt_message_destroy(m);
778 else if (!strcmp(op, "DtWorkspace_Delete")) {
780 * 1st arg: string, atom of workspace name
782 pch = tt_message_arg_val(m, 0);
784 /* retrieve the selected workspace */
785 aWs = strtoul (pch, (char **) NULL, 0);
787 sName = (String) XmGetAtomName (DISPLAY1, aWs);
789 F_DeleteWorkspace( sName, NULL, NULL );
792 tt_message_destroy(m);
796 else if (!strcmp(op, "GetWsmClients")) {
798 ClientData **clients;
801 if (GetSmClientIdClientList(&clients, &nClients))
803 char *clientIds = (char *)NULL;
804 int *clientWorkspaces = (int *)NULL;
807 SortClientListByWorkspace(clients, nClients);
809 tt_message_arg_ival_set(m, 0, nClients);
817 for (i = 0; i < nClients; i++)
818 clientIdLen += strlen(clients[i]->smClientID) + 1;
821 (char *)XtMalloc(clientIdLen * sizeof(char)))
824 (int *)XtMalloc(nClients * sizeof(int)))
827 if (clientIds != (char *)NULL)
830 /* LATER - Right way to handle errors? */
832 tt_message_destroy(m);
834 return TT_CALLBACK_PROCESSED;
838 for (i = 0, ptr = clientIds;
840 ptr += strlen(pCD->smClientID) + 1, i++)
843 strcpy(ptr, pCD->smClientID);
844 clientWorkspaces[i] =
846 pCD->pWsList[pCD->currentWsc].wsID;
853 tt_message_arg_bval_set(m, 1, (unsigned char *)clientIds,
854 clientIdLen * sizeof(char));
855 tt_message_arg_bval_set(m, 2, (unsigned char *)clientWorkspaces,
856 nClients * sizeof(int));
858 if (clientIds != (char *)NULL)
860 if (clientWorkspaces != (int *)NULL)
861 XtFree((char *)clientWorkspaces);
862 XtFree((char *)clients);
866 tt_message_destroy(m);
869 return TT_CALLBACK_CONTINUE;
873 return TT_CALLBACK_PROCESSED;
875 } /* END OF FUNCTION RequestMsgCB */
879 /******************************<->*************************************
895 ******************************<->***********************************/
896 #define GETXMSTRING(s, m, d) XmStringCreateLocalized(GETMESSAGE(s,m,d))
899 OKCB (Widget dialog, XtPointer client_data, XtPointer call_data)
901 XtUnmanageChild((Widget) client_data);
905 ToolTalkError(Widget parent, char *errfmt, Tt_status status)
908 Widget dialog, dialogShell;
909 char *errmsg, *statmsg, *title;
910 XmString xms_errmsg, xms_ok, xms_title;
913 if (! tt_is_err(status)) return;
915 statmsg = tt_status_message(status);
916 errmsg = XtMalloc(strlen(errfmt) + strlen(statmsg) + 2);
917 sprintf(errmsg, errfmt, statmsg);
919 xms_ok = GETXMSTRING(2, 3, "OK");
920 xms_errmsg = XmStringCreateLocalized(errmsg);
921 xms_title = GETXMSTRING(2, 1, "Dtwm - Error");
924 XtSetArg(args[n], XmNautoUnmanage, False); n++;
925 XtSetArg(args[n], XmNokLabelString, xms_ok); n++;
926 XtSetArg(args[n], XmNdialogTitle, xms_title); n++;
927 XtSetArg(args[n], XmNmessageString, xms_errmsg); n++;
928 XtSetArg(args[n], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); n++;
930 dialog = XmCreateErrorDialog(parent, "IconEditorError", args, n);
931 XtAddCallback(dialog, XmNokCallback, OKCB, (XtPointer) dialog);
932 XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_CANCEL_BUTTON));
933 XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));
936 * Disable the frame menu from dialog since we don't want the user
937 * to be able to close dialogs with the frame menu
939 dialogShell = XtParent(dialog);
941 XtSetArg(args[n], XmNmwmDecorations, MWM_DECOR_BORDER | MWM_DECOR_TITLE); n++;
942 XtSetValues(dialogShell, args, n);
943 XtManageChild(dialog);
944 XtRealizeWidget(dialogShell);
946 _DtSimpleError("Dtwm", DtFatalError, NULL, errmsg);
949 XmStringFree(xms_ok);
950 XmStringFree(xms_errmsg);
951 XmStringFree(xms_title);
953 /**************************** eof ***************************/