Initial import of the CDE 2.1.30 sources from the Open Group.
This commit is contained in:
409
cde/programs/dtpad/ttSaveSupport.c
Normal file
409
cde/programs/dtpad/ttSaveSupport.c
Normal file
@@ -0,0 +1,409 @@
|
||||
/* $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)&_TTKeys[0])
|
||||
#define _TTClientCBKey ((int)&_TTKeys[1])
|
||||
#define _TTClientDataKey ((int)&_TTKeys[2])
|
||||
#define _TTDepositPatKey ((int)&_TTKeys[3])
|
||||
#define _TTJoinInfoKey ((int)&_TTKeys[4])
|
||||
#define _TTContractKey ((int)&_TTKeys[5])
|
||||
#define _TTSubContractKey ((int)&_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 argments 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user