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: ttMsgSupport.c /main/7 1999/09/15 14:23:02 mgreess $ */
24 /**********************************<+>*************************************
25 ***************************************************************************
27 ** File: ttMsgSupport.c
29 ** Project: DT dtpad, a memo maker type editor based on the Dt Editor
35 ** Provides support for the Tool Talk "Desktop" and "Document and Media
36 ** Exchange" message sets.
38 ** XXX - Need to use mesage catalogs for error messages and not write to
41 *******************************************************************
42 ** (c) Copyright Hewlett-Packard Company, 1990, 1991, 1992, 1993.
44 ** reserved. Copying or other reproduction of this program
45 ** except for archival purposes is prohibited without prior
46 ** written consent of Hewlett-Packard Company.
47 ********************************************************************
49 ********************************************************************
50 ** (c) Copyright 1993, 1994 Hewlett-Packard Company
51 ** (c) Copyright 1993, 1994 International Business Machines Corp.
52 ** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
53 ** (c) Copyright 1993, 1994 Novell, Inc.
54 ********************************************************************
57 **************************************************************************
58 **********************************<+>*************************************/
61 #include <Dt/DtpadM.h>
63 #define TIMEOUT_FACTOR 1000
65 XtInputId ProcessToolTalkInputId = 0;
67 extern Editor *pPadList; /* list of Editor instances - declared in main.c */
68 extern char *initialServerGeometry; /* declared in main.c */
69 extern Tt_message TTSaveContractCB( /* declared in ttSaveSupport.c */
73 extern Tt_pattern TTCreateSavePattern( /* declared in ttSaveSupport.c */
75 Ttdt_contract_cb clientCB,
80 /************************************************************************
81 * TTdisplayError - posts a ToolTalk error dialog containing the specified
82 * error message followed by the related ToolTalk status message.
83 ************************************************************************/
90 char *statusMsg = tt_status_message(status);
93 if (errorMsg != (char *) NULL) {
94 sprintf(buf, "%s\n(%d: %s)", errorMsg, status, statusMsg);
96 sprintf(buf, "(%d: %s)", status, statusMsg);
99 Warning(pPad, buf, XmDIALOG_ERROR);
103 /******************************************************************************
104 * TTdt_session_joinCB - Callback passed to ttdt_session_join() to handle
105 * standard "Desktop" messages.
107 * In our case, this only deals with the standard Desktop Quit message with
110 * Quit(in boolean silent, in boolean force, in messageID operation2Quit)
112 * XXX - This routine was setup by SUN but currently does nothing since:
113 * Requests to quit a specific Media Edit/Display request are handled in
114 * TTdt_message_acceptCB() (which is registered in TTmedia_ptype_declareCB()
115 * when the Media Edit/Display request is first accepted).
116 ******************************************************************************/
123 /* should never get here, if we do, notify sender with a fail */
125 TT_DESKTOP_ENOTSUP, /* status */
126 (char *) NULL, /* status str */
127 1); /* destroy request */
129 return((Tt_message) 0); /* we handled this message */
134 /******************************************************************************
135 * TTdt_message_acceptCB - callback (setup in ttdt_message_accept()) to handle
136 * TT_HANDLER-addressed messages. Currently this routine handles:
138 * Quit(4) request which can contain the following arguments:
140 * silent - controls whether or not the user is notified
141 * when there are unsaved changes
142 * force - controls whether or not the Quit is aborted
143 * when there are unsaved changes
144 * operation2Quit - controls whether all edit window(s) are closed or
145 * whether a specific edit window is closed
147 * This routine is analogous to TTSaveContractCB() which handles
148 * Save requests. Patterns to handle Quit requests are automatically
149 * registered via ttdt_message_accept() whereas patterns to handle Save
150 * requests must be explicitly registered (see TTCreateSavePattern()).
152 * See dtpad(1) for more details.
154 ******************************************************************************/
156 TTdt_message_acceptCB(
164 char *operation2Quit;
165 int mark = tt_mark();
167 char *opString = tt_message_op(m);
168 Tttk_op op = tttk_string_op(opString);
170 if (op == TTDT_QUIT) {
172 /* Search the list of Editor instances for one with a TT media
173 * msg id matching the originating media msg id supplied as the
174 * 'operation2Quit' (3rd) argument of the TTDT_QUIT msg */
175 if (operation2Quit = tt_message_arg_val(m, 2)) {
176 for (pPad = pPadList; pPad != (Editor *)NULL; pPad = pPad->pNextPad) {
177 if (pPad->inUse == True && pPad->ttEditReq.msg_id &&
178 strcmp(pPad->ttEditReq.msg_id, operation2Quit) == 0) {
179 pPad->ttQuitReq.contract = m; /* process Quit msg */
180 status = tt_message_arg_ival(m, 0, &silent);
181 status = tt_message_arg_ival(m, 1, &force);
182 pPad->ttQuitReq.silent = (Boolean) silent;
183 pPad->ttQuitReq.force = (Boolean) force;
184 pPad->ttQuitReq.operation2Quit = strdup(operation2Quit);
185 FileExitCB( (Widget) NULL, (caddr_t) pPad, (caddr_t) NULL);
187 return((Tt_message) 0); /* handling Quit */
190 /* no Edit window matching the operation2Quit */
192 TT_DESKTOP_ENOMSG, /* status */
193 (char *) NULL, /* status str */
194 1); /* destroy request */
196 } else { /* no operation2Quit - quit all Edit windows */
197 /* XXX - not currently processing this type of Quit */
199 TT_DESKTOP_ENOTSUP, /* status */
200 (char *) NULL, /* status str */
201 1); /* destroy request */
204 /* We're handling all Quit requests. If the request has not been
205 * failed already, pPad->ttQuitReq.contract will be non-NULL and
206 * the Quit message will be responded to or failed later. */
208 return((Tt_message) 0); /* handling Quit */
210 } else { /* unsupported message type */
213 return(m); /* didn't handle message */
221 /******************************************************************************
222 * TTmedia_ptype_declareCB - callback (set up in ttmedia_ptype_declare()) to
223 * handle the standard ToolTalk Instantiate/Edit/Display media messages
224 * from a "requestor" dtpad or from other applications.
226 * It sets up TTdt_message_acceptCB() when it "accepts" the message which
227 * handles Quit messages relating to the accepted Instantiate/Edit/Display
230 * Returns: 0 if the message is handled; otherwise, returns Tt_message.
231 ******************************************************************************/
233 TTmedia_ptype_declareCB(
238 unsigned char * contents,
245 Tt_message TTdt_message_acceptCB(), incoming;
247 DtEditorContentRec contentRec;
248 DtEditorErrorCode errorCode;
249 Boolean foundPad = False;
250 char *context = (char *)NULL;
251 char *oldFileName = (char *)NULL;
252 Boolean isCurrentlyVisible = False;
253 int mark = tt_mark();
254 char *localPath = tt_message_file(m);
257 && !(op == TTME_INSTANTIATE && diag == TT_DESKTOP_ENODATA)) { /* TTT - workaround for tttk bug */
259 "Ignored Media request with ToolTalk detected error: %s\n",
260 tt_status_message(diag));
263 if (op != TTME_EDIT && op != TTME_DISPLAY && op != TTME_INSTANTIATE) {
264 return(m); /* Message not handled by this routine. */
267 /* if editing a file, make sure we can read it first,
268 * if not, fail the request immediately
273 if (MbStrrchr(localPath, '/') != (char *)NULL) {
274 char *dir; DIR *pDir;
276 dir = (char *) XtMalloc(strlen(localPath) + 1);
277 strcpy(dir, localPath);
278 pathEnd = MbStrrchr(dir, '/');
279 if (pathEnd == dir) {
280 /* file is in the root directory
284 *pathEnd = (char)'\0';
285 if ((pDir = opendir(dir)) != (DIR *)NULL) {
290 localPath = (char *) NULL;
293 TT_DESKTOP_ENOENT, /* status */
294 (char *) NULL, /* status str */
295 1); /* destroy request */
297 return((Tt_message) 0); /* Message handled by this routine. */
303 * Create an Editor "instance" and manage/realize it.
304 * This involves creating its GUI components, setting it resources,
305 * mapping its windows and, if specified, loading the file to be edited.
307 if (foundPad == False)
308 foundPad = FindOrCreatePad(&pPad); /* returns new Editor in pPad */
311 * If this message is from a dtpad requestor then replace selective
312 * server resources with requestor resources shipped to the dtpad server
313 * in the message context fields
315 if (tt_message_contexts_count(m)) {
317 /*----> a session file, want to restore a session */
318 if (*(context = tt_message_context_val(m, "SESSION"))) {
319 pPad->xrdb.session = strdup(context);
322 /* -----> non text editor specific resource */
323 if (*(context = tt_message_context_val(m, "GEOMETRY"))) {
324 pPad->geometry = strdup(context);
327 /* -----> basic options */
328 if (context = tt_message_context_val(m, "STATUSLINE")) {
330 pPad->xrdb.statusLine = True;
332 pPad->xrdb.statusLine = False;
335 if (context = tt_message_context_val(m, "WINDOWWORDWRAP")) {
337 pPad->xrdb.wordWrap = True;
339 pPad->xrdb.wordWrap = False;
342 if (context = tt_message_context_val(m, "OVERSTRIKE")) {
344 pPad->xrdb.overstrike = True;
346 pPad->xrdb.overstrike = False;
349 if (context = tt_message_context_val(m, "SAVEONCLOSE")) {
351 pPad->xrdb.saveOnClose = True;
353 pPad->xrdb.saveOnClose = False;
356 if (context = tt_message_context_val(m, "MISSINGFILEWARNING")) {
358 pPad->xrdb.missingFileWarning = True;
360 pPad->xrdb.missingFileWarning = False;
363 if (context = tt_message_context_val(m, "NOREADONLYWARNING")) {
365 pPad->xrdb.readOnlyWarning = True;
367 pPad->xrdb.readOnlyWarning = False;
370 if (context = tt_message_context_val(m, "NONAMECHANGE")) {
372 pPad->xrdb.nameChange = True;
374 pPad->xrdb.nameChange = False;
377 if (context = tt_message_context_val(m, "VIEWONLY")) {
379 pPad->xrdb.viewOnly = True;
381 pPad->xrdb.viewOnly = False;
384 if (context = tt_message_context_val(m, "WORKSPACELIST")) {
385 pPad->xrdb.workspaceList = strdup(context);
388 /* -----> client/server control options */
389 if (*(context = tt_message_context_val(m, "BLOCKING"))) {
390 pPad->xrdb.blocking = True;
391 pPad->blockChannel = strdup(context);
396 pPad->ttEditReq.contract = m;
397 pPad->ttEditReq.msg_id = strdup(tt_message_id(m));
398 pPad->ttEditReq.op = op;
400 if (op == TTME_INSTANTIATE) {
401 pPad->ttEditReq.contents = False;
402 pPad->ttEditReq.returnBufContents = False;
404 } else { /* TTME_EDIT or TTME_DISPLAY */
407 /* the mediaType of the first arg (contents) applies to either
408 * contents or a file */
409 pPad->ttEditReq.vtype = strdup(tt_message_arg_type(m, 0));
410 pPad->ttEditReq.contents = False; /* editing a file */
411 pPad->ttEditReq.fileName = strdup(localPath);
412 pPad->fileStuff.fileName = XtNewString(pPad->ttEditReq.fileName);
414 pPad->ttEditReq.contents = True; /* editing a buffer */
415 pPad->xrdb.nameChange = False; /* disallow switching to another
417 pPad->ttEditReq.returnBufContents = True;
420 pPad->ttEditReq.docName = strdup(docname);
422 pPad->ttEditReq.docName = (char *) NULL;
424 if (op == TTME_DISPLAY)
425 pPad->xrdb.viewOnly = True;
428 /* -----> Create GUI components of Editor instance, set resouces,
429 * map window and load file (if specified). */
431 if (oldFileName != (char *)NULL)
434 RealizeNewPad(pPad); /* pPad->mainWindow is created here */
436 if (oldFileName != (char *)NULL)
438 ManageOldPad(pPad, isCurrentlyVisible);
441 /* -----> Accept the message.
443 * Registers patterns in the default session to handle TT_HANDLER-addressed
444 * requests (created by specifying the "handler" argument in
445 * tttk_message_create) in the following manner (based on the shell and
446 * Ttdt_contract_cb args):
448 * type requests handled notes
449 * ---- -------------------- ---------------------------- -----
450 * (1) Get|Set_Geometry, transparently (a)
455 * (2) Pause, Resume passed to Ttdt_contract_cb (b)
456 * (3) Quit, Get_Status passed to Ttdt_contract_cb (c)
459 * (a) type (1) requests are handled transparently because the shell
460 * arg is specified (that is, a pattern is registered to handle
461 * these requests via an internal TT callback)
462 * (b) type (2) requests are handled like type (3) because
463 * Ttdt_contract_cb is specified; otherwise they would be
464 * handled transparently
465 * (c) type (3) request are handled in Ttdt_contract_cb because it
466 * was specified; otherwise they fail with TT_DESKTOP_ENOTSUP
467 * (that is, Ttdt_contract_cb is the pattern callback registered
468 * in the pattern to handle these requests).
470 ttrc = ttdt_message_accept(
472 TTdt_message_acceptCB, /* Ttdt_contract_cb */
473 pPad->app_shell, /* shell widget */
474 pPad->mainWindow, /* client data */
475 1, /* call tt_message_accept() */
476 1); /* send STATUS notice to requestor */
477 if (tt_ptr_error((void *) ttrc) != TT_OK) {
479 "Could not ttdt_message_accept the edit request: %s\n",
480 tt_status_message((tt_ptr_error((void *) ttrc))));
483 /* -----> Create pattern to handle "Save" requests in a manner analogous
484 * to "Quit" requests.
485 * NOTE: This pattern (unlike the Quit pattern automatically registered
486 * via ttdt_message_accept()) is *not* automatically destroyed
487 * when the original Edit request is destroyed. */
488 pPad->ttEditReq.savePattern = TTCreateSavePattern(
490 TTSaveContractCB, /* Ttdt_contract_cb */
491 pPad->mainWindow, /* client data - not currently used */
492 1); /* register it */
494 /* -----> Set the DtEditor widget contents. */
495 if (pPad->ttEditReq.contents) {
496 contentRec.type = DtEDITOR_TEXT;
497 contentRec.value.string = (char *) contents;
498 errorCode = DtEditorSetContents(pPad->editor, &contentRec);
500 /* [SuG 5/18/95] Done
501 The NOT_SAMPLE warnings/errors need to be added to the message
502 catalog. Removed ifdefs.*/
505 case DtEDITOR_NO_ERRORS:
507 case DtEDITOR_NULLS_REMOVED:
508 Warning(pPad, (char *) GETMESSAGE(6, 6,
509 "Embedded Nulls stripped from file."),
512 case DtEDITOR_INSUFFICIENT_MEMORY:
513 Warning(pPad, (char*) GETMESSAGE(6, 7,
514 "Unable to load file (insufficient memory)."),
518 Warning(pPad, (char *) GETMESSAGE(6, 12,
519 "Unable to read from the file (unknown reason)."),
526 return((Tt_message) 0); /* Message handled by this routine. */
530 /********************** Exported Functions (via dtpad.h) **********************/
532 /******************************************************************************
533 * TTstartDesktopMediaExchange - Initializes Took Talk for handling the
534 * "Desktop" and "Document & Media Exchange" message sets.
536 * Returns: True if successful; 0 if failure.
537 ******************************************************************************/
539 TTstartDesktopMediaExchange(
540 Widget topLevelWithWmCommand,
543 char *my_procid = NULL;
545 Tt_pattern *tt_pat = NULL;
546 Tt_status status = TT_OK;
547 int mark = tt_mark();
552 * Open a connection to the ToolTalk service
553 * and send a Started notice so other applications know we're up.
556 sess = (char *)getenv("TT_SESSION");
557 if (!sess || (*sess == '\0')) {
558 sess = getenv("_SUN_TT_SESSION");
560 if (!sess || (*sess == '\0')) {
561 tt_default_session_set(
562 tt_X_session(XDisplayString(XtDisplay(topLevelWithWmCommand))) );
565 status = TTdesktopOpen( &my_ttfd, pPad, (int) pPad->xrdb.server);
569 if (pPad->xrdb.server == True) {
571 * Declare we will handle messages defined under our ptype
572 * which in this case currently consist of the Instantialte, Display
573 * and Edit messages from the Media set, as defined in dtpad.ptypes.
574 * This will enable auto start of dtpad if any of the messages in the
575 * ptype are received.
577 if ((status = ttmedia_ptype_declare(
578 DTPAD_TOOL_CLASS, /* ptype */
580 TTmedia_ptype_declareCB,/* Ttmedia_load_pat_cb */
581 (void *) pPadList, /* client data */
582 1)) /* call tt_ptype_declare() */
585 "Could not register as %s tool class handler: %s\n",
587 tt_status_message(status)) ;
592 * Join the default sesssion,
593 * and register to deal with standard Desktop requests in the following
594 * manner (controlled by the Ttdt_contract_cb and shell arguments):
596 * type requests handled notes
597 * ---- -------------------- ---------------------------- -----
598 * (1) Get|Set_Environment, transparently
601 * Signal, Get_Sysinfo
602 * (2) Get|Set_Geometry, fail with TT_DESKTOP_ENOTSUP (b)
607 * Get_Xinfo transparently
608 * (3) Pause, Resume, Quit passed to Ttdt_contract_cb (c)
609 * (4) Get_Status, Do_Command passed to Ttdt_contract_cb
612 * (b) type (2) requests (except Get_Xinfo) fail because the shell
613 * arg is not a "realized mappedWhenManaged applicationShellWidget"
614 * (c) type (3) requests are not handled transparently because
615 * Ttdt_contract_cb is specified
617 tt_pat = ttdt_session_join(
618 (const char *) 0, /* join default session */
619 TTdt_session_joinCB, /* Ttdt_contract_cb */
620 topLevelWithWmCommand, /* shell widget */
621 (void *) 0, /* client data */
622 1); /* really join the session */
623 if ((status = tt_ptr_error(tt_pat)) != TT_OK) {
625 "Could not join default ToolTalk session: %s\n",
626 tt_status_message(tt_ptr_error(tt_pat)));
634 * Have Xt monitor the connection to the ToolTalk service.
635 * tttk_Xt_input_handler() will ultimately call tt_message_receive(),
636 * which will invoke the callbacks we've registered.
638 XtAppAddInput(XtWidgetToApplicationContext(topLevelWithWmCommand),
639 my_ttfd, (XtPointer) XtInputReadMask, tttk_Xt_input_handler,
646 /************************************************************************
647 * TTmediaDepositContents - sends a ToolTalk Deposit request (containing
648 * the current contents of the DtEditor widget) directly to the
649 * sender of the original media request.
651 * Returns: 0 if successful; !0 if failure.
652 ************************************************************************/
654 TTmediaDepositContents(
657 DtEditorErrorCode errorCode;
658 DtEditorContentRec contentRec;
659 Boolean addNewlines = pPad->xrdb.wordWrap == True &&
660 pPad->fileStuff.saveWithNewlines == True;
663 _DtTurnOnHourGlass(pPad->app_shell);
665 contentRec.type = DtEDITOR_TEXT;
666 errorCode = DtEditorGetContents(
670 False); /* don't mark contents as saved yet */
671 if (errorCode != DtEDITOR_NO_ERRORS) {
673 "Internal Error: Unable to get contents from Editor Widget.",
678 status = ttmedia_Deposit(
679 pPad->ttEditReq.contract, /* original request */
680 (char *) NULL, /* send directly to requestor */
681 pPad->ttEditReq.vtype, /* media type */
682 (unsigned char *) contentRec.value.string, /*new contents */
683 strlen(contentRec.value.string),
684 (char *) NULL, /* don't use temp file for xfer */
685 pPad->app_context, /* we're the blocking application */
686 10 * TIMEOUT_FACTOR); /* milliseconds to block for reply */
688 if (status == TT_OK) {
689 /* XXX - an inefficient way of marking contents as saved -
690 * need to use a global to keep track of unsaved changes
691 * and replace DtEditorCheckForUnsavedChanges() */
692 errorCode = DtEditorGetContents(
696 True); /* mark contents as saved */
697 _DtTurnOffHourGlass(pPad->app_shell);
699 _DtTurnOffHourGlass(pPad->app_shell);
701 (char *) GETMESSAGE(13, 1, "Checkpoint save failed."),
709 /************************************************************************
710 * TTmediaReply - replies to (and closes) a ToolTalk media request.
712 * If a file is being edited, it is assumed at this point that it
713 * has already been updated with the current contents.
715 * If a buffer is being edited, the current text is included in the
716 * reply only if pPad->ttEditReq.returnBufContents is True.
718 * Returns: 0 if successful; !0 if failure.
719 ************************************************************************/
724 DtEditorErrorCode errorCode;
725 DtEditorContentRec contentRec;
727 Boolean addNewlines = pPad->xrdb.wordWrap == True &&
728 pPad->fileStuff.saveWithNewlines == True;
730 _DtTurnOnHourGlass(pPad->app_shell);
732 if (! pPad->ttEditReq.contract) {
736 /* ----> Not editing a buffer */
737 if (! pPad->ttEditReq.contents) {
738 status = ttmedia_load_reply(
739 pPad->ttEditReq.contract, /* original request */
740 (unsigned char *) 0, /* new contents */
741 0, /* contents length */
742 True); /* destroy message after reply */
743 _DtTurnOffHourGlass(pPad->app_shell);
744 if (status == TT_OK) {
745 pPad->ttEditReq.contract = 0; /* request has been closed */
749 (char *) GETMESSAGE(13, 2, "Checkpoint reply failed."),
755 /* ----> Editing a buffer */
756 if (pPad->ttEditReq.returnBufContents) {
757 /* -----> Include the contents in the reply */
758 contentRec.type = DtEDITOR_TEXT;
759 errorCode = DtEditorGetContents(
763 False); /* don't mark contents as saved yet */
764 if (errorCode != DtEDITOR_NO_ERRORS) {
766 "Internal Error: Unable to get contents from Editor Widget.",
768 tttk_message_fail(pPad->ttEditReq.contract,
769 TT_DESKTOP_ENODATA, /* status */
770 (char *) NULL, /* status str */
771 1); /* destroy request */
775 status = ttmedia_load_reply(
776 pPad->ttEditReq.contract, /* original request */
777 (unsigned char *) contentRec.value.string, /* new contents */
778 strlen(contentRec.value.string),
779 True); /* destroy message after reply */
780 if (status == TT_OK) {
781 /* XXX - an inefficient way of marking contents as saved -
782 * need to use a global to keep track of unsaved changes
783 * and replace DtEditorCheckForUnsavedChanges() */
784 errorCode = DtEditorGetContents(
788 True); /* mark contents as saved */
789 _DtTurnOffHourGlass(pPad->app_shell);
790 pPad->ttEditReq.contract = NULL; /* request has been closed */
792 _DtTurnOffHourGlass(pPad->app_shell);
794 (char *) GETMESSAGE(13, 2, "Checkpoint reply failed."),
800 /* -----> Don't include anything in the buffer reply (e.g.
801 * when the user responds "no" to saving unsaved contents).
803 * NOTE: TT_DESKTOP_ECANCELED changes the "failure" into a "reply".
805 status = tttk_message_fail(
806 pPad->ttEditReq.contract, /* original request */
807 TT_DESKTOP_ECANCELED, /* status */
808 (char *) NULL, /* status str */
809 1); /* destroy request */
810 _DtTurnOffHourGlass(pPad->app_shell);
811 if (status == TT_OK) {
812 pPad->ttEditReq.contract = NULL; /* request has been closed */
815 (char *) GETMESSAGE(13, 2, "Checkpoint reply failed."),
824 /************************************************************************
825 * TTresetQuitArgs - resets TTDT_QUIT argments set in TTdt_message_acceptCB()
826 ************************************************************************/
831 if (!pPad->ttQuitReq.contract)
833 pPad->ttQuitReq.contract = NULL;
834 if (pPad->ttQuitReq.operation2Quit != (char *) NULL) {
835 XtFree(pPad->ttQuitReq.operation2Quit);
836 pPad->ttQuitReq.operation2Quit = (char *) NULL;
838 pPad->ttQuitReq.silent = 0;
839 pPad->ttQuitReq.force = 0;
843 /************************************************************************
844 * TTfailPendingQuit - fails any pending Quit request - even if 'force' is
846 ************************************************************************/
851 if (pPad->ttQuitReq.contract) {
852 tttk_message_fail(pPad->ttQuitReq.contract, /* original Quit req */
853 TT_DESKTOP_ECANCELED, /* status */
854 (char *) NULL, /* status string */
855 1); /* destroy request */
856 TTresetQuitArgs(pPad);
860 /************************************************************************
861 * TTdesktopOpen - This procedure just opens a connection to
862 * ToolTalk so a simple message can be sent.
863 ************************************************************************/
865 TTdesktopOpen( int *ttFd, Editor *pPad, Boolean sendStarted )
872 vendor = "Sun Microsystems";
878 vendor = "Hewlett-Packard";
885 procId = ttdt_open( ttFd, "dtpad", vendor, "2.1", sendStarted );
886 if ( (status = tt_ptr_error( procId )) != TT_OK )
888 ttdt_close( NULL, NULL, sendStarted );
892 ProcessToolTalkInputId =
893 XtAppAddInput( pPad->app_context,
894 *ttFd, (XtPointer)XtInputReadMask,
895 tttk_Xt_input_handler, procId );
899 /************************************************************************
900 * TTwarning - This procedure displays a message dialog and exits.
901 ************************************************************************/
904 okCB(Widget w, XtPointer clientData, XtPointer callData)
906 *((int*) clientData) = 1;
910 TTwarning( Editor *pPad, Tt_status status, char *errsuff )
912 FileWidgets *pFileWidgets;
918 if (TT_OK == status || NULL == pPad) return;
921 GETMESSAGE(7, 13, "Could not connect to ToolTalk service:\n%s\n%s\n");
922 statmsg = tt_status_message(status);
923 errmsg = XtMalloc(strlen(errfmt) + strlen(statmsg) + strlen(errsuff) + 2);
925 if (NULL == errsuff) errsuff = "";
926 fprintf(stderr, errfmt, statmsg, errsuff);
927 sprintf(errmsg, errfmt, statmsg, errsuff);
928 Warning(pPad, errmsg, XmDIALOG_ERROR);
930 pFileWidgets = &pPad->fileStuff.fileWidgets;
931 XtAddCallback(pFileWidgets->gen_warning, XmNokCallback,
932 (XtCallbackProc) okCB, (XtPointer) &done);
933 XFlush(pPad->display);
934 XSync(pPad->display, False);
939 XtWidgetToApplicationContext(pFileWidgets->gen_warning),