123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431 |
- /*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- /* $XConsortium: ttSaveSupport.c /main/4 1996/05/08 20:09:07 drk $ */
- /**********************************<+>*************************************
- ***************************************************************************
- **
- ** File: ttSaveSupport.c
- **
- ** Project: DT dtpad, a memo maker type editor based on the Dt Editor
- ** widget.
- **
- ** Description:
- ** -----------
- **
- ** Provides support for the ToolTalk "Save" message in a manner analogous
- ** to "Quit" message support provided by the ttdt_message_accept() function.
- **
- *******************************************************************
- ** (c) Copyright Hewlett-Packard Company, 1990, 1991, 1992, 1993.
- ** All rights are
- ** reserved. Copying or other reproduction of this program
- ** except for archival purposes is prohibited without prior
- ** written consent of Hewlett-Packard Company.
- ********************************************************************
- **
- ********************************************************************
- ** (c) Copyright 1993, 1994 Hewlett-Packard Company
- ** (c) Copyright 1993, 1994 International Business Machines Corp.
- ** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
- ** (c) Copyright 1993, 1994 Novell, Inc.
- ********************************************************************
- **
- **
- **************************************************************************
- **********************************<+>*************************************/
- #include "dtpad.h"
- /* definitions from tttk/tttkutils.h */
- char _TTKeys[7];
- #define _TTCBKey ((int)(intptr_t)&_TTKeys[0])
- #define _TTClientCBKey ((int)(intptr_t)&_TTKeys[1])
- #define _TTClientDataKey ((int)(intptr_t)&_TTKeys[2])
- #define _TTDepositPatKey ((int)(intptr_t)&_TTKeys[3])
- #define _TTJoinInfoKey ((int)(intptr_t)&_TTKeys[4])
- #define _TTContractKey ((int)(intptr_t)&_TTKeys[5])
- #define _TTSubContractKey ((int)(intptr_t)&_TTKeys[6])
- extern Editor *pPadList; /* list of Editor instances - declared in main.c */
- /******************************************************************************
- * TTSaveContractCB - callback (setup in ttdt_message_accept()) to handle
- * Save(4) requests. Currently this routine handles one argument:
- *
- * messageID - This must be the message ID the originating Edit
- * request whose contents are to that is to be saved
- * (or deposited if a buffer is being edited).
- *
- * This routine is analogous to TTdt_message_acceptCB() which handles
- * Quit requests. Patterns to handle Quit requests are automatically
- * registered via ttdt_message_accept() whereas patterns to handle Save
- * requests must be explicitly registered (see TTCreateSavePattern()).
- *
- * See dtpad(1) for more details.
- *
- ******************************************************************************/
- Tt_message
- TTSaveContractCB(
- Tt_message m,
- void * clientData,
- Tt_message contract)
- {
- Editor *pPad;
- int silent, force;
- Tt_status status;
- char *messageID;
- int mark = tt_mark();
- char *opString = tt_message_op(m);
- Tttk_op op = tttk_string_op(opString);
- if (op == TTDT_SAVE) {
- /* Search the list of Editor instances for one with a TT media
- * msg id matching the originating media msg id supplied as the
- * 'messageID' (1st) argument of the TTDT_SAVE msg */
- if (messageID = tt_message_arg_val(m, 0)) {
- for (pPad = pPadList; pPad != (Editor *)NULL; pPad = pPad->pNextPad) {
- if (pPad->inUse == True && pPad->ttEditReq.msg_id &&
- strcmp(pPad->ttEditReq.msg_id, messageID) == 0) {
- pPad->ttSaveReq.contract = m; /* process Save msg */
- pPad->ttSaveReq.messageID = strdup(messageID);
- FileSaveCB((Widget) NULL, (caddr_t) pPad, (caddr_t) NULL);
- tt_release(mark);
- return((Tt_message) 0); /* handling Save */
- }
- }
- /* no Edit window matching the messageID */
- tttk_message_fail(m,
- TT_DESKTOP_ECANCELED, /* status */
- (char *) NULL, /* status str */
- 1); /* destroy request */
- } else { /* no messageID - which is required */
- tttk_message_fail(m,
- TT_DESKTOP_ECANCELED, /* status */
- (char *) NULL, /* status str */
- 1); /* destroy request */
- }
- /* We're handling all Save requests. If the request has not been
- * failed already, pPad->ttSaveReq.contract will be non-NULL and
- * the Save message will be responded to or failed later. */
- tt_release(mark);
- return((Tt_message) 0); /* handling Quit */
- } else { /* unsupported message type */
- tt_release(mark);
- return(m); /* didn't handle message */
- }
- }
- /******************************************************************************
- * _TT_pattern_contract - obtains the contracting message from the pattern
- ******************************************************************************/
- Tt_message
- _TT_pattern_contract(
- Tt_pattern pat)
- {
- void *contract = tt_pattern_user(pat, _TTContractKey);
- Tt_status status = tt_ptr_error(contract);
- if (status != TT_OK) {
- return 0;
- }
- return (Tt_message) contract;
- }
- /******************************************************************************
- * _TTpatternCB - Retrieves the client callback and callback arguments from
- * the pattern and calls it (ala tttkpattern.C:_ttDtPatternCB()).
- ******************************************************************************/
- static Tt_callback_action
- _TTpatternCB(
- Tt_message msg,
- Tt_pattern pat)
- {
- Ttdt_contract_cb clientCB;
- void * clientData;
- Tt_status status;
- /* ----> Obtain client callback */
- clientCB = (Ttdt_contract_cb) tt_pattern_user(pat, _TTClientCBKey);
- status = tt_ptr_error(clientCB);
- if (status != TT_OK) {
- return TT_CALLBACK_PROCESSED;
- }
- if (clientCB == 0) {
- return TT_CALLBACK_CONTINUE;
- }
- /* ----> Obtain client data */
- clientData = tt_pattern_user(pat, _TTClientDataKey);
- status = tt_ptr_error(clientData);
- if (status != TT_OK) {
- return TT_CALLBACK_PROCESSED;
- }
- /* -----> Call client callback */
- msg = (*clientCB)(msg, clientData, _TT_pattern_contract(pat));
- status = tt_ptr_error(msg);
- if ((status != TT_OK) || (msg == 0)) {
- return TT_CALLBACK_PROCESSED;
- } else {
- return TT_CALLBACK_CONTINUE;
- }
- }
- /******************************************************************************
- * _TTCreatePattern - creates a pattern for a desktop message
- * (ala cdesrc/lib/tt/lib/tttk/tttkpattern.C:_ttDtPatternCreate())
- ******************************************************************************/
- Tt_pattern
- _TTCreatePattern(
- Tt_category category,
- Tt_scope theScope,
- int addDefaultSess,
- const char * file,
- const char * op_string,
- Ttdt_contract_cb clientCB,
- void * clientData)
- {
- Tt_pattern pat = tt_pattern_create();
- Tt_status status = tt_ptr_error(pat);
- if (status != TT_OK) {
- return pat;
- }
- status = tt_pattern_category_set(pat, category);
- if (status != TT_OK) {
- tt_pattern_destroy(pat);
- return (Tt_pattern)tt_error_pointer(status);
- }
- /* we only observe notices and only handle requests */
- if (category == TT_HANDLE) {
- status = tt_pattern_class_add(pat, TT_REQUEST);
- }
- if (category == TT_OBSERVE) {
- status = tt_pattern_class_add(pat, TT_NOTICE);
- }
- if (status != TT_OK) {
- tt_pattern_destroy(pat);
- return (Tt_pattern)tt_error_pointer(status);
- }
- status = tt_pattern_scope_add(pat, theScope);
- if (status != TT_OK) {
- tt_pattern_destroy(pat);
- return (Tt_pattern)tt_error_pointer(status);
- }
- if (addDefaultSess) {
- char *sess = tt_default_session();
- status = tt_pattern_session_add(pat, sess);
- tt_free(sess);
- if (status != TT_OK) {
- tt_pattern_destroy(pat);
- return (Tt_pattern)tt_error_pointer(status);
- }
- }
- if (file != 0) {
- status = tt_pattern_file_add(pat, file);
- if (status != TT_OK) {
- tt_pattern_destroy(pat);
- return (Tt_pattern)tt_error_pointer(status);
- }
- }
- if (op_string) {
- status = tt_pattern_op_add(pat, op_string);
- if (status != TT_OK) {
- tt_pattern_destroy(pat);
- return (Tt_pattern)tt_error_pointer(status);
- }
- }
- /* -----> Add the general purpose pattern callback (as well as the
- * client callback and client data) as fields to the pattern.
- * When the general purpose pattern callback is called, it
- * obtains the client callback and client data from the pattern
- * and calls the client callback with the appropriate arguments. */
- status = tt_pattern_callback_add( pat, _TTpatternCB );
- if (status != TT_OK) {
- tt_pattern_destroy(pat);
- return (Tt_pattern)tt_error_pointer(status);
- }
- status = tt_pattern_user_set(pat, _TTClientCBKey, (void *) clientCB);
- if (status != TT_OK) {
- tt_pattern_destroy(pat);
- return (Tt_pattern)tt_error_pointer(status);
- }
- status = tt_pattern_user_set(pat, _TTClientDataKey, clientData);
- if (status != TT_OK) {
- tt_pattern_destroy(pat);
- return (Tt_pattern)tt_error_pointer(status);
- }
- return pat;
- }
- /******************************************************************************
- * _TTmessage_id - Returns sender-set message id if any, otherwise the
- * tt_message_id() (ala lib/tt/lib/tttk/tttkmessage.C:_tttk_message_id())
- ******************************************************************************/
- char *
- _TTmessage_id(
- Tt_message msg)
- {
- int i, miss, numArgs = tt_message_args_count( msg );
- Tt_status status = tt_int_error( numArgs );
- char *msgID;
- if (status != TT_OK) {
- return 0;
- }
- for (i = 0; i < numArgs; i++) {
- char *type = tt_message_arg_type(msg, i);
- status = tt_ptr_error(type);
- if (status != TT_OK) {
- return 0;
- }
- if (type == 0) {
- continue;
- }
- miss = strcmp(type, Tttk_message_id);
- tt_free(type);
- if (miss) {
- continue;
- }
- msgID = tt_message_arg_val(msg, i);
- status = tt_ptr_error(type);
- if (status != TT_OK) {
- return 0;
- }
- return msgID;
- }
- return tt_message_id(msg);
- }
- /******************************************************************************
- * TTCreateSavePattern - Creates and (optionally) registers a pattern to handle
- * Save requests (ala cdesrc/lib/tt/lib/tttk/ttdesktop.C:_ttdt_pat() and
- * _ttDesktopPatternFinish())
- ******************************************************************************/
- Tt_pattern
- TTCreateSavePattern(
- Tt_message contract,
- Ttdt_contract_cb clientCB,
- void * clientData,
- int register_it)
- {
- char *msgID;
- /* -----> Create pattern */
- Tt_pattern pat = _TTCreatePattern(
- TT_HANDLE, /* catagory */
- TT_SESSION, /* scope */
- 1, /* add default session to pat */
- 0, /* don't add file to pat */
- "Save", /* desktop message (op) type */
- clientCB,
- clientData);
- Tt_status status = tt_ptr_error( pat );
- if (status != TT_OK) {
- return pat;
- }
- /* -----> Add message id and contracting message to pattern */
- if (contract != 0) {
- char *msgID = _TTmessage_id(contract);
- status = tt_pattern_arg_add(pat, TT_IN, Tttk_message_id, msgID);
- tt_free(msgID);
- if (status != TT_OK) {
- tt_pattern_destroy(pat);
- return (Tt_pattern) tt_error_pointer(status);
- }
- tt_pattern_user_set(pat, _TTContractKey, contract);
- }
- /* -----> Register pattern */
- if (register_it) {
- status = tt_pattern_register(pat);
- if (status != TT_OK) {
- tt_pattern_destroy(pat);
- return (Tt_pattern) tt_error_pointer(status);
- }
- }
- return pat;
- }
- /************************************************************************
- * TTresetSaveArgs - resets TTDT_SAVE arguments set in TTSaveContractCB()
- ************************************************************************/
- void
- TTresetSaveArgs(
- Editor *pPad)
- {
- if (!pPad->ttSaveReq.contract)
- return;
- pPad->ttSaveReq.contract = NULL;
- if (pPad->ttSaveReq.messageID != (char *) NULL) {
- XtFree(pPad->ttSaveReq.messageID);
- pPad->ttSaveReq.messageID = (char *) NULL;
- }
- }
- /************************************************************************
- * TTfailPendingSave - fails any pending Save request
- ************************************************************************/
- void
- TTfailPendingSave(
- Editor *pPad)
- {
- if (pPad->ttSaveReq.contract) {
- tttk_message_fail(pPad->ttSaveReq.contract, /* original Save req */
- TT_DESKTOP_ECANCELED, /* status */
- (char *) NULL, /* status string */
- 1); /* destroy request */
- TTresetSaveArgs(pPad);
- }
- }
|