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
24 * (c) Copyright 1997, The Open Group
27 * (c) Copyright 1987, 1988, 1989, 1990, 1992, 1993 HEWLETT-PACKARD COMPANY
35 #include "WmProtocol.h"
39 #include <Dt/Action.h>
41 #include <Dt/IndicatorM.h>
42 #include <Dt/UserMsg.h>
45 #include "WmBackdrop.h"
47 #include "WmFunction.h"
48 #include "WmWrkspace.h"
52 #include "DataBaseLoad.h"
56 * include extern functions and definitions
59 extern void UpdateFileTypeControlFields ( void );
60 extern WmScreenData * GetScreenForWindow (Window);
62 static void ToolTalkError(Widget, char*, Tt_status);
66 * data for the "DT screen"
73 Const char *szWM_TOOL_CLASS = DtWM_TOOL_CLASS;
77 /******************************<->*************************************
79 * dtInitialize (char * program_name, XtAppContext appContext)
83 * Initialize the messaging mechanism
87 * program_name - argv[0]
88 * appContext - used throughout the WM
96 ******************************<->***********************************/
100 XtAppContext appContext )
103 (void) DtAppInitialize(appContext, DISPLAY1, wmGD.topLevelW1,
104 program_name, (char *)szWM_TOOL_CLASS);
107 * Load action definitions from the action database.
109 #ifdef DT_PERFORMANCE
110 _DtPerfChkpntMsgSend("Begin action database load");
115 #ifdef DT_PERFORMANCE
116 _DtPerfChkpntMsgSend("End action database load");
119 } /* END OF FUNCTION dtInitialize */
121 /******************************<->*************************************
123 * dtInitializeMessaging (Widget)
127 * Initialize the messaging mechanisms
138 ******************************<->***********************************/
141 dtInitializeMessaging(Widget toplevel)
148 Tt_pattern notice_pattern, request_pattern;
149 char *default_session;
155 Tt_callback_action NoticeMsgCB(
158 Tt_callback_action RequestMsgCB(
163 * Makef sure we have a ToolTalk connection
166 status = tt_ptr_error(procId);
167 if (status != TT_OK) {
169 GETMESSAGE(2, 2, "Could not connect to ToolTalk:\n%s\n");
170 ToolTalkError(toplevel, errfmt, status);
174 status = tt_int_error(fd);
175 if (status == TT_OK) {
176 XtAppAddInput(XtWidgetToApplicationContext(wmGD.topLevelW), fd,
177 (XtPointer)XtInputReadMask, tttk_Xt_input_handler, procId);
179 ToolTalkError(toplevel, "tt_fd()", status);
183 default_session = tt_default_session();
184 status = tt_ptr_error(default_session);
185 if (status != TT_OK) {
186 errfmt = GETMESSAGE(2, 4, "Could not get default ToolTalk session:\n%s\n");
187 ToolTalkError(toplevel, errfmt, status);
191 errfmt = GETMESSAGE(2, 5, "Error constructing ToolTalk pattern:\n%s\n");
192 notice_pattern = tt_pattern_create();
193 status = tt_ptr_error(notice_pattern);
194 if (status != TT_OK) {
195 ToolTalkError(toplevel, errfmt, status);
198 request_pattern = tt_pattern_create();
199 status = tt_ptr_error(request_pattern);
200 if (status != TT_OK) {
201 ToolTalkError(toplevel, errfmt, status);
205 status = tt_pattern_category_set(notice_pattern, TT_OBSERVE);
206 if (status != TT_OK) {
207 ToolTalkError(toplevel, errfmt, status);
210 status = tt_pattern_category_set(request_pattern, TT_HANDLE);
211 if (status != TT_OK) {
212 ToolTalkError(toplevel, errfmt, status);
215 status = tt_pattern_scope_add(notice_pattern, TT_SESSION);
216 if (status != TT_OK) {
217 ToolTalkError(toplevel, errfmt, status);
220 status = tt_pattern_scope_add(request_pattern, TT_SESSION);
221 if (status != TT_OK) {
222 ToolTalkError(toplevel, errfmt, status);
225 status = tt_pattern_session_add(notice_pattern, default_session);
226 if (status != TT_OK) {
227 ToolTalkError(toplevel, errfmt, status);
230 status = tt_pattern_session_add(request_pattern, default_session);
231 if (status != TT_OK) {
232 ToolTalkError(toplevel, errfmt, status);
236 tt_free( default_session );
237 status = tt_pattern_class_add(notice_pattern, TT_NOTICE);
238 if (status != TT_OK) {
239 ToolTalkError(toplevel, errfmt, status);
242 status = tt_pattern_state_add(notice_pattern, TT_SENT);
243 if (status != TT_OK) {
244 ToolTalkError(toplevel, errfmt, status);
247 status = tt_pattern_class_add(request_pattern, TT_REQUEST);
248 if (status != TT_OK) {
249 ToolTalkError(toplevel, errfmt, status);
252 status = tt_pattern_state_add(request_pattern, TT_SENT);
253 if (status != TT_OK) {
254 ToolTalkError(toplevel, errfmt, status);
260 * Ops handled by the notice_pattern
262 status = tt_pattern_op_add(notice_pattern, "DtActivity_Beginning");
263 if (status != TT_OK) {
264 ToolTalkError(toplevel, errfmt, status);
267 status = tt_pattern_op_add(notice_pattern, "DtActivity_Began");
268 if (status != TT_OK) {
269 ToolTalkError(toplevel, errfmt, status);
272 status = tt_pattern_op_add(notice_pattern, "DtTypes_Reloaded");
273 if (status != TT_OK) {
274 ToolTalkError(toplevel, errfmt, status);
279 * Ops handled by the request_pattern
281 status = tt_pattern_op_add(request_pattern, "DtPanel_Restore");
282 if (status != TT_OK) {
283 ToolTalkError(toplevel, errfmt, status);
286 status = tt_pattern_op_add(request_pattern, "DtWorkspace_SetCurrent");
287 if (status != TT_OK) {
288 ToolTalkError(toplevel, errfmt, status);
291 status = tt_pattern_op_add(request_pattern, "DtWorkspace_Title_Set");
292 if (status != TT_OK) {
293 ToolTalkError(toplevel, errfmt, status);
296 status = tt_pattern_op_add(request_pattern, "DtWorkspace_Add");
297 if (status != TT_OK) {
298 ToolTalkError(toplevel, errfmt, status);
301 status = tt_pattern_op_add(request_pattern, "DtWorkspace_Delete");
302 if (status != TT_OK) {
303 ToolTalkError(toplevel, errfmt, status);
306 status = tt_pattern_op_add(request_pattern, "GetWsmClients");
307 if (status != TT_OK) {
308 ToolTalkError(toplevel, errfmt, status);
313 * Register callback for the notice_pattern
315 status = tt_pattern_callback_add(notice_pattern, NoticeMsgCB);
316 if (status != TT_OK) {
317 ToolTalkError(toplevel, errfmt, status);
322 * Register callback for the request_pattern
324 status = tt_pattern_callback_add(request_pattern, RequestMsgCB);
325 if (status != TT_OK) {
326 ToolTalkError(toplevel, errfmt, status);
330 status = tt_pattern_register(notice_pattern);
331 if (status != TT_OK) {
332 ToolTalkError(toplevel, errfmt, status);
335 status = tt_pattern_register(request_pattern);
336 if (status != TT_OK) {
337 ToolTalkError(toplevel, errfmt, status);
341 } /* END OF FUNCTION dtInitializeMessaging */
344 /******************************<->*************************************
350 * Shuts down the messaging mechanism
360 * Should be done before exiting
362 ******************************<->***********************************/
366 } /* END OF FUNCTION dtCloseIPC */
370 /******************************<->*************************************
372 * void dtReadyNotification()
376 * Tells the world that we're up and ready.
386 * Invoked as the fitting culmination of dtwm initialization
388 ******************************<->***********************************/
390 dtReadyNotification( void )
392 SendClientMsg( wmGD.dtSmWindow,
393 (long) wmGD.xa_DT_SM_WM_PROTOCOL,
394 (long) wmGD.xa_DT_WM_READY,
395 CurrentTime, NULL, 0);
397 } /* END OF FUNCTION dtReadyNotification */
400 /******************************<->*************************************
406 * This is called to turn off "system busy" activity
417 * This routine relies on two globals, blinkerPCW and dtSD,
418 * on the major assumptions that:
419 * - there is just one DT Screen, with the front panel enabled
420 * - there is just one dtwmbusy control in that front panel
421 ******************************<->***********************************/
423 WmStopWaiting( void )
427 WmFrontPanelSetBusy (False);
429 } /* END OF FUNCTION WmStopWaiting */
433 /******************************<->*************************************
435 * dtSendWorkspaceModifyNotification ()
439 * This is called to announce that the workspace set has been
444 * pSD - pointer to screen data
445 * aWs - id of workspace just modified
446 * iType - type of modification
456 * "MODIFY_WORKSPACE" "<atom_for_wsname>" "<modify_type>"
458 * <modify_type> is one of:
463 ******************************<->***********************************/
465 dtSendWorkspaceModifyNotification(
476 msg = tt_pnotice_create(TT_SESSION, "DtWorkspace_Modified");
477 status = tt_ptr_error(msg);
478 if (status != TT_OK) {
481 sprintf(sNum, "%d", pSD->screen);
482 status = tt_message_arg_add(msg, TT_IN, Tttk_string, sNum);
483 if (status != TT_OK) {
486 sprintf (pch, "%ld", aWs);
487 status = tt_message_arg_add(msg, TT_IN, Tttk_string, pch);
488 if (status != TT_OK) {
491 sprintf (pchType, "%d", iType);
492 status = tt_message_arg_add(msg, TT_IN, Tttk_string, pchType);
493 if (status != TT_OK) {
496 status = tt_message_send(msg);
497 if (status != TT_OK) {
500 tt_message_destroy(msg);
504 /******************************<->*************************************
506 * dtSendMarqueeSelectionNotification ()
510 * This is called to announce marquee selection state
514 * pSD - pointer to screen data
515 * type - id of workspace just modified
516 * x - x position of UL corner of rectangle
517 * y - y position of UL corner of rectangle
518 * width - width of rectangle
519 * height - height of rectangle
529 * "MARQUEE_SELECTION" "<type>" "<x>" "<y>" "<width>" "<height>"
531 * <modify_type> is one of:
536 ******************************<->***********************************/
538 dtSendMarqueeSelectionNotification(
550 msg = tt_pnotice_create(TT_SESSION, "DtMarquee_Selection");
551 status = tt_ptr_error(msg);
552 if (status != TT_OK) {
556 sprintf(sNum, "%d", pSD->screen);
557 status = tt_message_arg_add(msg, TT_IN, Tttk_string, sNum);
558 if (status != TT_OK) {
561 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
564 if (tt_message_arg_ival_set(msg, 1, type) != TT_OK) {
567 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
570 if (tt_message_arg_ival_set(msg, 2, x) != TT_OK) {
573 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
576 if (tt_message_arg_ival_set(msg, 3, y) != TT_OK) {
579 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
582 if (tt_message_arg_ival_set(msg, 4, width) != TT_OK) {
585 if (tt_message_arg_add(msg, TT_IN, "integer", NULL) != TT_OK) {
588 if (tt_message_arg_ival_set(msg, 5, height) != TT_OK) {
591 status = tt_message_send(msg);
592 if (status != TT_OK) {
595 tt_message_destroy(msg);
599 /******************************<->*************************************
606 * This is called to handle busy and stopbusy message
610 * m = ToolTalk message
611 * p = ToolTalk pattern
615 * TT_CALLBACK_PROCESSED
616 * TT_CALLBACK_CINTINUE
620 ******************************<->***********************************/
622 NoticeMsgCB(Tt_message m, Tt_pattern p)
627 if (tt_message_state(m) != TT_SENT) {
628 return TT_CALLBACK_CONTINUE;
630 op = tt_message_op(m);
631 status = tt_ptr_error(op);
632 if (status != TT_OK) {
633 return TT_CALLBACK_CONTINUE;
635 if (!strcmp(op, "DtActivity_Began")) {
639 tt_message_destroy(m);
641 else if (!strcmp(op, "DtActivity_Beginning")) {
643 WmFrontPanelSetBusy (True);
647 tt_message_destroy(m);
649 else if (!strcmp(op, "DtTypes_Reloaded")) {
651 * Blink busy light during reload.
653 WmFrontPanelSetBusy (True);
656 * Load action definitions from the action database.
660 UpdateFileTypeControlFields();
663 * Turn off busy light.
665 WmFrontPanelSetBusy (False);
668 tt_message_destroy(m);
672 return TT_CALLBACK_PROCESSED;
674 } /* END OF FUNCTION NoticeMsgCB */
677 /******************************<->*************************************
684 * This is called to handle busy and stopbusy message
688 * m = ToolTalk message
689 * p = ToolTalk pattern
693 * TT_CALLBACK_PROCESSED
694 * TT_CALLBACK_CINTINUE
698 ******************************<->***********************************/
700 RequestMsgCB(Tt_message m, Tt_pattern p)
707 WmWorkspaceData *pWS = NULL;
712 if (tt_message_state(m) != TT_SENT) {
713 return TT_CALLBACK_CONTINUE;
715 op = tt_message_op(m);
716 status = tt_ptr_error(op);
717 if (status != TT_OK) {
718 return TT_CALLBACK_CONTINUE;
720 if (!strcmp(op, "DtPanel_Restore")) {
722 tt_message_destroy(m);
726 F_Restart( DTWM_REQP_NO_CONFIRM, NULL, NULL );
728 else if (!strcmp(op, "DtWorkspace_SetCurrent")) {
730 * 1st arg: integer, screen number
731 * 2nd arg: string, atom of workspace name
734 /* get the first arg from the message */
735 tt_message_arg_ival(m, 0, &screen_num);
736 pSD = &wmGD.Screens[screen_num];
738 /* get the second arg from the message */
739 pch = tt_message_arg_val(m, 1);
741 /* retrieve the selected workspace */
742 aWs = strtoul (pch, (char **) NULL, 0);
744 pWS = GetWorkspaceData (pSD, aWs);
747 ChangeToWorkspace (pWS);
751 tt_message_destroy(m);
753 else if (!strcmp(op, "DtWorkspace_Title_Set")) {
755 * 1st arg: integer, screen number
756 * 2nd arg: string, atom of workspace name
757 * 3rd arg: string, new name for the workspace
760 /* get the first arg from the message */
761 tt_message_arg_ival(m, 0, &screen_num);
762 pSD = &wmGD.Screens[screen_num];
764 /* get the second arg from the message */
765 pch = tt_message_arg_val(m, 1);
767 /* retrieve the selected workspace */
768 aWs = strtoul (pch, (char **) NULL, 0);
770 pWS = GetWorkspaceData (pSD, aWs);
772 /* get the third arg from the message */
773 pch = tt_message_arg_val(m, 2);
776 ChangeWorkspaceTitle (pWS, pch);
781 tt_message_destroy(m);
783 else if (!strcmp(op, "DtWorkspace_Add")) {
785 * 1st arg: string, user-visible title of the workspace
787 pch = tt_message_arg_val(m, 0);
789 F_CreateWorkspace( pch, NULL, NULL );
793 tt_message_destroy(m);
795 else if (!strcmp(op, "DtWorkspace_Delete")) {
797 * 1st arg: string, atom of workspace name
799 pch = tt_message_arg_val(m, 0);
801 /* retrieve the selected workspace */
802 aWs = strtoul (pch, (char **) NULL, 0);
804 sName = (String) XmGetAtomName (DISPLAY1, aWs);
806 F_DeleteWorkspace( sName, NULL, NULL );
809 tt_message_destroy(m);
813 else if (!strcmp(op, "GetWsmClients")) {
815 ClientData **clients;
818 if (GetSmClientIdClientList(&clients, &nClients))
820 char *clientIds = (char *)NULL;
821 int *clientWorkspaces = (int *)NULL;
824 SortClientListByWorkspace(clients, nClients);
826 tt_message_arg_ival_set(m, 0, nClients);
834 for (i = 0; i < nClients; i++)
835 clientIdLen += strlen(clients[i]->smClientID) + 1;
838 (char *)XtMalloc(clientIdLen * sizeof(char)))
841 (int *)XtMalloc(nClients * sizeof(int)))
844 if (clientIds != (char *)NULL)
847 /* LATER - Right way to handle errors? */
849 tt_message_destroy(m);
851 return TT_CALLBACK_PROCESSED;
855 for (i = 0, ptr = clientIds;
857 ptr += strlen(pCD->smClientID) + 1, i++)
860 strcpy(ptr, pCD->smClientID);
861 clientWorkspaces[i] =
862 pCD->pWsList[pCD->currentWsc].wsID;
866 tt_message_arg_bval_set(m, 1, (unsigned char *)clientIds,
867 clientIdLen * sizeof(char));
868 tt_message_arg_bval_set(m, 2, (unsigned char *)clientWorkspaces,
869 nClients * sizeof(int));
871 if (clientIds != (char *)NULL)
873 if (clientWorkspaces != (int *)NULL)
874 XtFree((char *)clientWorkspaces);
875 XtFree((char *)clients);
879 tt_message_destroy(m);
882 return TT_CALLBACK_CONTINUE;
886 return TT_CALLBACK_PROCESSED;
888 } /* END OF FUNCTION RequestMsgCB */
892 /******************************<->*************************************
908 ******************************<->***********************************/
909 #define GETXMSTRING(s, m, d) XmStringCreateLocalized(GETMESSAGE(s,m,d))
912 OKCB (Widget dialog, XtPointer client_data, XtPointer call_data)
914 XtUnmanageChild((Widget) client_data);
918 ToolTalkError(Widget parent, char *errfmt, Tt_status status)
921 Widget dialog, dialogShell;
922 char *errmsg, *statmsg, *title;
923 XmString xms_errmsg, xms_ok, xms_title;
926 if (! tt_is_err(status)) return;
928 statmsg = tt_status_message(status);
929 errmsg = XtMalloc(strlen(errfmt) + strlen(statmsg) + 2);
930 sprintf(errmsg, errfmt, statmsg);
932 xms_ok = GETXMSTRING(2, 3, "OK");
933 xms_errmsg = XmStringCreateLocalized(errmsg);
934 xms_title = GETXMSTRING(2, 1, "Dtwm - Error");
937 XtSetArg(args[n], XmNautoUnmanage, False); n++;
938 XtSetArg(args[n], XmNokLabelString, xms_ok); n++;
939 XtSetArg(args[n], XmNdialogTitle, xms_title); n++;
940 XtSetArg(args[n], XmNmessageString, xms_errmsg); n++;
941 XtSetArg(args[n], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); n++;
943 dialog = XmCreateErrorDialog(parent, "IconEditorError", args, n);
944 XtAddCallback(dialog, XmNokCallback, OKCB, (XtPointer) dialog);
945 XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_CANCEL_BUTTON));
946 XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));
949 * Disable the frame menu from dialog since we don't want the user
950 * to be able to close dialogs with the frame menu
952 dialogShell = XtParent(dialog);
954 XtSetArg(args[n], XmNmwmDecorations, MWM_DECOR_BORDER | MWM_DECOR_TITLE); n++;
955 XtSetValues(dialogShell, args, n);
956 XtManageChild(dialog);
957 XtRealizeWidget(dialogShell);
959 _DtSimpleError("Dtwm", DtFatalError, NULL, errmsg);
962 XmStringFree(xms_ok);
963 XmStringFree(xms_errmsg);
964 XmStringFree(xms_title);
966 /**************************** eof ***************************/