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[] = ""
43 #include <Dt/Action.h>
45 #include <Dt/IndicatorM.h>
46 #include <Dt/UserMsg.h>
49 #include "WmBackdrop.h"
51 #include "WmFunction.h"
52 #include "WmWrkspace.h"
54 #include "DataBaseLoad.h"
58 * include extern functions and definitions
61 extern void UpdateFileTypeControlFields ( void );
62 extern WmScreenData * GetScreenForWindow (Window);
64 static void ToolTalkError(Widget, char*, Tt_status);
68 * data for the "DT screen"
75 Const char *szWM_TOOL_CLASS = DtWM_TOOL_CLASS;
79 /******************************<->*************************************
81 * dtInitialize (char * program_name, XtAppContext appContext)
85 * Initialize the messaging mechanism
89 * program_name - argv[0]
90 * appContext - used throughout the WM
98 ******************************<->***********************************/
102 XtAppContext appContext )
105 (void) DtAppInitialize(appContext, DISPLAY1, wmGD.topLevelW1,
106 program_name, (char *)szWM_TOOL_CLASS);
109 * Load action definitions from the action database.
111 #ifdef DT_PERFORMANCE
112 _DtPerfChkpntMsgSend("Begin action database load");
117 #ifdef DT_PERFORMANCE
118 _DtPerfChkpntMsgSend("End action database load");
121 } /* END OF FUNCTION dtInitialize */
123 /******************************<->*************************************
125 * dtInitializeMessaging (Widget)
129 * Initialize the messaging mechanisms
140 ******************************<->***********************************/
143 dtInitializeMessaging(Widget toplevel)
150 Tt_pattern notice_pattern, request_pattern;
151 char *default_session;
157 Tt_callback_action NoticeMsgCB(
160 Tt_callback_action RequestMsgCB(
165 * Makef sure we have a ToolTalk connection
168 status = tt_ptr_error(procId);
169 if (status != TT_OK) {
171 GETMESSAGE(2, 2, "Could not connect to ToolTalk:\n%s\n");
172 ToolTalkError(toplevel, errfmt, status);
176 status = tt_int_error(fd);
177 if (status == TT_OK) {
178 XtAppAddInput(XtWidgetToApplicationContext(wmGD.topLevelW), fd,
179 (XtPointer)XtInputReadMask, tttk_Xt_input_handler, procId);
181 ToolTalkError(toplevel, "tt_fd()", status);
185 default_session = tt_default_session();
186 status = tt_ptr_error(default_session);
187 if (status != TT_OK) {
188 GETMESSAGE(2, 4, "Could not get default ToolTalk session:\n%s\n");
189 ToolTalkError(toplevel, errfmt, status);
193 errfmt = GETMESSAGE(2, 5, "Error constructing ToolTalk pattern:\n%s\n");
194 notice_pattern = tt_pattern_create();
195 status = tt_ptr_error(notice_pattern);
196 if (status != TT_OK) {
197 ToolTalkError(toplevel, errfmt, status);
200 request_pattern = tt_pattern_create();
201 status = tt_ptr_error(request_pattern);
202 if (status != TT_OK) {
203 ToolTalkError(toplevel, errfmt, status);
207 status = tt_pattern_category_set(notice_pattern, TT_OBSERVE);
208 if (status != TT_OK) {
209 ToolTalkError(toplevel, errfmt, status);
212 status = tt_pattern_category_set(request_pattern, TT_HANDLE);
213 if (status != TT_OK) {
214 ToolTalkError(toplevel, errfmt, status);
217 status = tt_pattern_scope_add(notice_pattern, TT_SESSION);
218 if (status != TT_OK) {
219 ToolTalkError(toplevel, errfmt, status);
222 status = tt_pattern_scope_add(request_pattern, TT_SESSION);
223 if (status != TT_OK) {
224 ToolTalkError(toplevel, errfmt, status);
227 status = tt_pattern_session_add(notice_pattern, default_session);
228 if (status != TT_OK) {
229 ToolTalkError(toplevel, errfmt, status);
232 status = tt_pattern_session_add(request_pattern, default_session);
233 if (status != TT_OK) {
234 ToolTalkError(toplevel, errfmt, status);
237 tt_free( default_session );
238 status = tt_pattern_class_add(notice_pattern, TT_NOTICE);
239 if (status != TT_OK) {
240 ToolTalkError(toplevel, errfmt, status);
243 status = tt_pattern_state_add(notice_pattern, TT_SENT);
244 if (status != TT_OK) {
245 ToolTalkError(toplevel, errfmt, status);
248 status = tt_pattern_class_add(request_pattern, TT_REQUEST);
249 if (status != TT_OK) {
250 ToolTalkError(toplevel, errfmt, status);
253 status = tt_pattern_state_add(request_pattern, TT_SENT);
254 if (status != TT_OK) {
255 ToolTalkError(toplevel, errfmt, status);
261 * Ops handled by the notice_pattern
263 status = tt_pattern_op_add(notice_pattern, "DtActivity_Beginning");
264 if (status != TT_OK) {
265 ToolTalkError(toplevel, errfmt, status);
268 status = tt_pattern_op_add(notice_pattern, "DtActivity_Began");
269 if (status != TT_OK) {
270 ToolTalkError(toplevel, errfmt, status);
273 status = tt_pattern_op_add(notice_pattern, "DtTypes_Reloaded");
274 if (status != TT_OK) {
275 ToolTalkError(toplevel, errfmt, status);
280 * Ops handled by the request_pattern
282 status = tt_pattern_op_add(request_pattern, "DtPanel_Restore");
283 if (status != TT_OK) {
284 ToolTalkError(toplevel, errfmt, status);
287 status = tt_pattern_op_add(request_pattern, "DtWorkspace_SetCurrent");
288 if (status != TT_OK) {
289 ToolTalkError(toplevel, errfmt, status);
292 status = tt_pattern_op_add(request_pattern, "DtWorkspace_Title_Set");
293 if (status != TT_OK) {
294 ToolTalkError(toplevel, errfmt, status);
297 status = tt_pattern_op_add(request_pattern, "DtWorkspace_Add");
298 if (status != TT_OK) {
299 ToolTalkError(toplevel, errfmt, status);
302 status = tt_pattern_op_add(request_pattern, "DtWorkspace_Delete");
303 if (status != TT_OK) {
304 ToolTalkError(toplevel, errfmt, status);
307 status = tt_pattern_op_add(request_pattern, "GetWsmClients");
308 if (status != TT_OK) {
309 ToolTalkError(toplevel, errfmt, status);
314 * Register callback for the notice_pattern
316 status = tt_pattern_callback_add(notice_pattern, NoticeMsgCB);
317 if (status != TT_OK) {
318 ToolTalkError(toplevel, errfmt, status);
323 * Register callback for the request_pattern
325 status = tt_pattern_callback_add(request_pattern, RequestMsgCB);
326 if (status != TT_OK) {
327 ToolTalkError(toplevel, errfmt, status);
331 status = tt_pattern_register(notice_pattern);
332 if (status != TT_OK) {
333 ToolTalkError(toplevel, errfmt, status);
336 status = tt_pattern_register(request_pattern);
337 if (status != TT_OK) {
338 ToolTalkError(toplevel, errfmt, status);
342 } /* END OF FUNCTION dtInitializeMessaging */
345 /******************************<->*************************************
351 * Shuts down the messaging mechanism
361 * Should be done before exiting
363 ******************************<->***********************************/
367 } /* END OF FUNCTION dtCloseIPC */
371 /******************************<->*************************************
373 * void dtReadyNotification()
377 * Tells the world that we're up and ready.
387 * Invoked as the fitting culmination of dtwm initialization
389 ******************************<->***********************************/
391 dtReadyNotification( void )
393 SendClientMsg( wmGD.dtSmWindow,
394 (long) wmGD.xa_DT_SM_WM_PROTOCOL,
395 (long) wmGD.xa_DT_WM_READY,
396 CurrentTime, NULL, 0);
398 } /* END OF FUNCTION dtReadyNotification */
401 /******************************<->*************************************
407 * This is called to turn off "system busy" activity
418 * This routine relies on two globals, blinkerPCW and dtSD,
419 * on the major assumptions that:
420 * - there is just one DT Screen, with the front panel enabled
421 * - there is just one dtwmbusy control in that front panel
422 ******************************<->***********************************/
424 WmStopWaiting( void )
429 WmFrontPanelSetBusy (False);
431 #endif /* PANELIST */
432 } /* END OF FUNCTION WmStopWaiting */
436 /******************************<->*************************************
438 * dtSendWorkspaceModifyNotification ()
442 * This is called to announce that the workspace set has been
447 * pSD - pointer to screen data
448 * aWs - id of workspace just modified
449 * iType - type of modification
459 * "MODIFY_WORKSPACE" "<atom_for_wsname>" "<modify_type>"
461 * <modify_type> is one of:
466 ******************************<->***********************************/
468 dtSendWorkspaceModifyNotification(
479 msg = tt_pnotice_create(TT_SESSION, "DtWorkspace_Modified");
480 status = tt_ptr_error(msg);
481 if (status != TT_OK) {
484 sprintf(sNum, "%d", pSD->screen);
485 status = tt_message_arg_add(msg, TT_IN, Tttk_string, sNum);
486 if (status != TT_OK) {
489 sprintf (pch, "%ld", aWs);
490 status = tt_message_arg_add(msg, TT_IN, Tttk_string, pch);
491 if (status != TT_OK) {
494 sprintf (pchType, "%d", iType);
495 status = tt_message_arg_add(msg, TT_IN, Tttk_string, pchType);
496 if (status != TT_OK) {
499 status = tt_message_send(msg);
500 if (status != TT_OK) {
503 tt_message_destroy(msg);
507 /******************************<->*************************************
509 * dtSendMarqueeSelectionNotification ()
513 * This is called to announce marquee selection state
517 * pSD - pointer to screen data
518 * type - id of workspace just modified
519 * x - x position of UL corner of rectangle
520 * y - y position of UL corner of rectangle
521 * width - width of rectangle
522 * heigth - height of rectangle
532 * "MARQUEE_SELECTION" "<type>" "<x>" "<y>" "<width>" "<height>"
534 * <modify_type> is one of:
539 ******************************<->***********************************/
541 dtSendMarqueeSelectionNotification(
553 msg = tt_pnotice_create(TT_SESSION, "DtMarquee_Selection");
554 status = tt_ptr_error(msg);
555 if (status != TT_OK) {
559 sprintf(sNum, "%d", pSD->screen);
560 status = tt_message_arg_add(msg, TT_IN, Tttk_string, sNum);
561 if (status != TT_OK) {
564 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
567 if (tt_message_arg_ival_set(msg, 1, type) != TT_OK) {
570 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
573 if (tt_message_arg_ival_set(msg, 2, x) != TT_OK) {
576 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
579 if (tt_message_arg_ival_set(msg, 3, y) != TT_OK) {
582 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
585 if (tt_message_arg_ival_set(msg, 4, width) != TT_OK) {
588 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
591 if (tt_message_arg_ival_set(msg, 5, height) != TT_OK) {
594 status = tt_message_send(msg);
595 if (status != TT_OK) {
598 tt_message_destroy(msg);
602 /******************************<->*************************************
609 * This is called to handle busy and stopbusy message
613 * m = ToolTalk message
614 * p = ToolTalk pattern
618 * TT_CALLBACK_PROCESSED
619 * TT_CALLBACK_CINTINUE
623 ******************************<->***********************************/
625 NoticeMsgCB(Tt_message m, Tt_pattern p)
630 if (tt_message_state(m) != TT_SENT) {
631 return TT_CALLBACK_CONTINUE;
633 op = tt_message_op(m);
634 status = tt_ptr_error(op);
635 if (status != TT_OK) {
636 return TT_CALLBACK_CONTINUE;
638 if (!strcmp(op, "DtActivity_Began")) {
642 tt_message_destroy(m);
645 else if (!strcmp(op, "DtActivity_Beginning")) {
647 WmFrontPanelSetBusy (True);
651 tt_message_destroy(m);
653 #endif /* PANELIST */
654 else if (!strcmp(op, "DtTypes_Reloaded")) {
656 * Blink busy light during reload.
658 WmFrontPanelSetBusy (True);
661 * Load action definitions from the action database.
665 UpdateFileTypeControlFields();
668 * Turn off busy light.
670 WmFrontPanelSetBusy (False);
673 tt_message_destroy(m);
677 return TT_CALLBACK_PROCESSED;
679 } /* END OF FUNCTION NoticeMsgCB */
682 /******************************<->*************************************
689 * This is called to handle busy and stopbusy message
693 * m = ToolTalk message
694 * p = ToolTalk pattern
698 * TT_CALLBACK_PROCESSED
699 * TT_CALLBACK_CINTINUE
703 ******************************<->***********************************/
705 RequestMsgCB(Tt_message m, Tt_pattern p)
712 WmWorkspaceData *pWS = NULL;
717 if (tt_message_state(m) != TT_SENT) {
718 return TT_CALLBACK_CONTINUE;
720 op = tt_message_op(m);
721 status = tt_ptr_error(op);
722 if (status != TT_OK) {
723 return TT_CALLBACK_CONTINUE;
725 if (!strcmp(op, "DtPanel_Restore")) {
727 tt_message_destroy(m);
731 F_Restart( DTWM_REQP_NO_CONFIRM, NULL, NULL );
733 else if (!strcmp(op, "DtWorkspace_SetCurrent")) {
735 * 1st arg: integer, screen number
736 * 2nd arg: string, atom of workspace name
739 /* get the first arg from the message */
740 tt_message_arg_ival(m, 0, &screen_num);
741 pSD = &wmGD.Screens[screen_num];
743 /* get the second arg from the message */
744 pch = tt_message_arg_val(m, 1);
746 /* retrieve the selected workspace */
747 aWs = strtoul (pch, (char **) NULL, 0);
749 pWS = GetWorkspaceData (pSD, aWs);
752 ChangeToWorkspace (pWS);
756 tt_message_destroy(m);
758 else if (!strcmp(op, "DtWorkspace_Title_Set")) {
760 * 1st arg: integer, screen number
761 * 2nd arg: string, atom of workspace name
762 * 3rd arg: string, new name for the workspace
765 /* get the first arg from the message */
766 tt_message_arg_ival(m, 0, &screen_num);
767 pSD = &wmGD.Screens[screen_num];
769 /* get the second arg from the message */
770 pch = tt_message_arg_val(m, 1);
772 /* retrieve the selected workspace */
773 aWs = strtoul (pch, (char **) NULL, 0);
775 pWS = GetWorkspaceData (pSD, aWs);
777 /* get the third arg from the message */
778 pch = tt_message_arg_val(m, 2);
781 ChangeWorkspaceTitle (pWS, pch);
786 tt_message_destroy(m);
788 else if (!strcmp(op, "DtWorkspace_Add")) {
790 * 1st arg: string, user-visible title of the workspace
792 pch = tt_message_arg_val(m, 0);
794 F_CreateWorkspace( pch, NULL, NULL );
798 tt_message_destroy(m);
800 else if (!strcmp(op, "DtWorkspace_Delete")) {
802 * 1st arg: string, atom of workspace name
804 pch = tt_message_arg_val(m, 0);
806 /* retrieve the selected workspace */
807 aWs = strtoul (pch, (char **) NULL, 0);
809 sName = (String) XmGetAtomName (DISPLAY1, aWs);
811 F_DeleteWorkspace( sName, NULL, NULL );
814 tt_message_destroy(m);
818 else if (!strcmp(op, "GetWsmClients")) {
820 ClientData **clients;
823 if (GetSmClientIdClientList(&clients, &nClients))
825 char *clientIds = (char *)NULL;
826 int *clientWorkspaces = (int *)NULL;
829 SortClientListByWorkspace(clients, nClients);
831 tt_message_arg_ival_set(m, 0, nClients);
839 for (i = 0; i < nClients; i++)
840 clientIdLen += strlen(clients[i]->smClientID) + 1;
843 (char *)XtMalloc(clientIdLen * sizeof(char)))
846 (int *)XtMalloc(nClients * sizeof(int)))
849 if (clientIds != (char *)NULL)
852 /* LATER - Right way to handle errors? */
854 tt_message_destroy(m);
856 return TT_CALLBACK_PROCESSED;
860 for (i = 0, ptr = clientIds;
862 ptr += strlen(pCD->smClientID) + 1, i++)
865 strcpy(ptr, pCD->smClientID);
866 clientWorkspaces[i] =
868 pCD->pWsList[pCD->currentWsc].wsID;
875 tt_message_arg_bval_set(m, 1, (unsigned char *)clientIds,
876 clientIdLen * sizeof(char));
877 tt_message_arg_bval_set(m, 2, (unsigned char *)clientWorkspaces,
878 nClients * sizeof(int));
880 if (clientIds != (char *)NULL)
882 if (clientWorkspaces != (int *)NULL)
883 XtFree((char *)clientWorkspaces);
884 XtFree((char *)clients);
888 tt_message_destroy(m);
891 return TT_CALLBACK_CONTINUE;
895 return TT_CALLBACK_PROCESSED;
897 } /* END OF FUNCTION RequestMsgCB */
901 /******************************<->*************************************
917 ******************************<->***********************************/
918 #define GETXMSTRING(s, m, d) XmStringCreateLocalized(GETMESSAGE(s,m,d))
921 OKCB (Widget dialog, XtPointer client_data, XtPointer call_data)
923 XtUnmanageChild((Widget) client_data);
927 ToolTalkError(Widget parent, char *errfmt, Tt_status status)
930 Widget dialog, dialogShell;
931 char *errmsg, *statmsg, *title;
932 XmString xms_errmsg, xms_ok, xms_title;
935 if (! tt_is_err(status)) return;
937 statmsg = tt_status_message(status);
938 errmsg = XtMalloc(strlen(errfmt) + strlen(statmsg) + 2);
939 sprintf(errmsg, errfmt, statmsg);
941 xms_ok = GETXMSTRING(2, 3, "OK");
942 xms_errmsg = XmStringCreateLocalized(errmsg);
943 xms_title = GETXMSTRING(2, 1, "Dtwm - Error");
946 XtSetArg(args[n], XmNautoUnmanage, False); n++;
947 XtSetArg(args[n], XmNokLabelString, xms_ok); n++;
948 XtSetArg(args[n], XmNdialogTitle, xms_title); n++;
949 XtSetArg(args[n], XmNmessageString, xms_errmsg); n++;
950 XtSetArg(args[n], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); n++;
952 dialog = XmCreateErrorDialog(parent, "IconEditorError", args, n);
953 XtAddCallback(dialog, XmNokCallback, OKCB, (XtPointer) dialog);
954 XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_CANCEL_BUTTON));
955 XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));
958 * Disable the frame menu from dialog since we don't want the user
959 * to be able to close dialogs with the frame menu
961 dialogShell = XtParent(dialog);
963 XtSetArg(args[n], XmNmwmDecorations, MWM_DECOR_BORDER | MWM_DECOR_TITLE); n++;
964 XtSetValues(dialogShell, args, n);
965 XtManageChild(dialog);
966 XtRealizeWidget(dialogShell);
968 _DtSimpleError("Dtwm", DtFatalError, NULL, errmsg);
971 XmStringFree(xms_ok);
972 XmStringFree(xms_errmsg);
973 XmStringFree(xms_title);
975 /**************************** eof ***************************/