cdesktopenv/cde/programs/dtpad/ttSaveSupport.c

432 lines
13 KiB
C

/*
* 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);
}
}