Code Example D-1 Typical Algorithm of Ttdt_contract_cb
Tt_message
myContractCB(
Tt_message msg,
void *clientdata,
Tt_message contract
)
{
char *opString = tt_message_op( msg );
Tttk_op op = tttk_string_op( opString );
tt_free( opString );
int silent = 0;
int force = 0;
Boolean cancel = False;
Boolean sensitive = True;
char *status, command;
switch (op) {
case TTDT_QUIT:
tt_message_arg_ival( msg, 0, &silent );
tt_message_arg_ival( msg, 1, &force );
if (contract == 0) {
/* Quit entire application */
cancel = ! myQuitWholeApp( silent, force );
} else {
/* Quit just the specified request being worked on */
cancel = ! myCancelThisRequest(contract, silent, force);
}
if (cancel) {
/* User canceled Quit; fail the Quit request */
tttk_message_fail( msg, TT_DESKTOP_ECANCELED, 0, 1 );
} else {
tt_message_reply( msg );
tttk_message_destroy( msg );
}
return 0;
case TTDT_PAUSE:
sensitive = False;
case TTDT_RESUME:
if (contract == 0) {
int already = 1;
if (XtIsSensitive( myTopShell ) != sensitive) {
already = 0;
XtSetSensitive( myTopShell, sensitive );
}
if (already) {
tt_message_status_set(msg,TT_DESKTOP_EALREADY);
}
} else {
if (XtIsSensitive( thisShell ) == sensitive) {
tt_message_status_set(msg,TT_DESKTOP_EALREADY);
} else {
XtSetSensitive( thisShell, sensitive );
}
}
tt_message_reply( msg );
tttk_message_destroy( msg );
return 0;
case TTDT_GET_STATUS:
if (contract == 0) {
status = "Message about status of entire app";
} else {
status = "Message about status of this request";
}
tt_message_arg_val_set( msg, 0, status );
tt_message_reply( msg );
tttk_message_destroy( msg );
return 0;
case TTDT_DO_COMMAND:
if (! haveExtensionLanguage) {
tttk_message_fail( msg, TT_DESKTOP_ENOTSUP, 0, 1 );
return 0;
}
command = tt_message_arg_val( msg, 0 );
result = myEval( command );
tt_free( command );
tt_message_status_set( msg, result );
if (tt_is_err( result )) {
tttk_message_fail( msg, result, 0, 1 );
} else {
tt_message_reply( msg );
tttk_message_destroy( msg );
}
return 0;
}
/* Unrecognized message; do not consume it */
return msg;
}
Code Example D-2 Typical Algorithm of Ttdt_file_cb
Tt_message
myFileCB(
Tt_message msg,
Tttk_op op,
char *pathname,
int trust,
int isMe
)
{
tt_free( pathname );
Tt_status status = TT_OK;
switch (op) {
case TTDT_MODIFIED:
if ((_modifiedByMe) && (! isMe)) {
// Hmm, the other editor either does not know or
// does not care that we are already modifying the
// file, so the last saver will win.
} else {
// Interrogate user if she ever modifies the buffer
_modifiedByOther = 1;
XtAddCallback( myTextWidget, XmNmodifyVerifyCallback,
myTextModifyCB, 0 );
}
break;
case TTDT_GET_MODIFIED:
tt_message_arg_ival_set( msg, 1, _modifiedByMe );
tt_message_reply( msg );
break;
case TTDT_SAVE:
status = mySave( trust );
if (status == TT_OK) {
tt_message_reply( msg );
} else {
tttk_message_fail( msg, status, 0, 0 );
}
break;
case TTDT_REVERT:
status = myRevert( trust );
if (status == TT_OK) {
tt_message_reply( msg );
} else {
tttk_message_fail( msg, status, 0, 0 );
}
break;
case TTDT_REVERTED:
if (! isMe) {
_modifiedByOther = 0;
}
break;
case TTDT_SAVED:
if (! isMe) {
_modifiedByOther = 0;
int choice = myUserChoice( myContext, myBaseFrame,
"Another tool has saved "
"this file.", 2, "Ignore",
"Revert" );
switch (choice) {
case 1:
myRevert( 1 );
break;
}
}
break;
case TTDT_MOVED:
case TTDT_DELETED:
// Do something appropriate
break;
}
tttk_message_destroy( msg );
return 0;
}
Code Example D-3 Typical Algorithm of Ttmedia_load_msg_cb
Tt_message
myLoadMsgCB(
Tt_message msg,
void *clientData,
Tttk_op op,
unsigned char *contents,
int len,
char *file
)
{
if (len > 0) {
// Replace data with len bytes in contents
} else if (file != 0) {
// Replace data with data read from file
}
if (op == TTME_DEPOSIT) {
tt_message_reply( msg );
}
tttk_message_destroy( msg );
return 0;
}
Code Example D-4 Typical Algorithm of Ttmedia_load_pat_cb
Tt_message
myAcmeSheetLoadCB(
Tt_message msg,
void *client_data,
Tttk_op op,
Tt_status diagnosis,
unsigned char *contents,
int len,
char *file,
char *docname
)
{
Tt_status status = TT_OK;
if (diagnosis != TT_OK) {
// toolkit detected an error
if (tt_message_status( msg ) == TT_WRN_START_MESSAGE) {
//
// Error is in start message! We now have no
// reason to live, so tell main() to exit().
//
myAbortCode = 2;
}
// let toolkit handle the error
return msg;
}
if ((op == TTME_COMPOSE) && (file == 0)) {
// open empty new buffer
} else if (len > 0) {
// load contents into new buffer
} else if (file != 0) {
if (ttdt_Get_Modified( msg, file, TT_BOTH, myCntxt, 5000 )) {
switch (myUserChoice( "Save, Revert, Ignore?" )) {
case 0:
ttdt_Save( msg, file, TT_BOTH, myCntxt, 5000 );
break;
case 1:
ttdt_Revert( msg, file, TT_BOTH, myCntxt, 5000);
break;
}
}
// load file into new buffer
} else {
tttk_message_fail( msg, TT_DESKTOP_ENODATA, 0, 1 );
tt_free( contents ); tt_free( file ); tt_free( docname );
return 0;
}
int w, h, x, y = INT_MAX;
ttdt_sender_imprint_on( 0, msg, 0, &w, &h, &x, &y, myCntxt, 5000 );
positionMyWindowRelativeTo( w, h, x, y );
if (maxBuffersAreNowOpen) {
// Un-volunteer to handle future requests until less busy
tt_ptype_undeclare( "Acme_Calc" );
}
if (tt_message_status( msg ) == TT_WRN_START_MESSAGE) {
//
// Join session before accepting start message,
// to prevent unnecessary starts of our ptype
//
ttdt_session_join( 0, myContractCB, myShell, 0, 1 );
}
ttdt_message_accept( msg, myContractCB, myShell, 0, 1, 1 );
tt_free( contents ); tt_free( file ); tt_free( docname );
return 0;
}
Code Example D-5 Example of Media Ptype Signature Layout
ptype Acme_Calc {
start "acalc";
handle:
/*
* Display Acme_Sheet
* Include in tool's ptype if tool can display a document.
*/
session Display( in Acme_Sheet contents ) => start opnum = 1;
session Display( in Acme_Sheet contents,
in messageID counterfoil ) => start opnum = 2;
session Display( in Acme_Sheet contents,
in title docName ) => start opnum = 3;
session Display( in Acme_Sheet contents,
in messageID counterfoil,
in title docName ) => start opnum = 4;
/*
* Edit Acme_Sheet
* Include in tool's ptype if tool can edit a document.
*/
session Edit( inout Acme_Sheet contents ) => start opnum = 101;
session Edit( inout Acme_Sheet contents,
in messageID counterfoil ) => start opnum = 102;
session Edit( inout Acme_Sheet contents,
in title docName ) => start opnum = 103;
session Edit( inout Acme_Sheet contents,
in messageID counterfoil,
in title docName ) => start opnum = 104;
/*
* Compose Acme_Sheet
* Include in tool's ptype if tool can compose a document from scratch.
*/
session Edit( out Acme_Sheet contents ) => start opnum = 201;
session Edit( out Acme_Sheet contents,
in messageID counterfoil ) => start opnum = 202;
session Edit( out Acme_Sheet contents,
in title docName ) => start opnum = 203;
session Edit( out Acme_Sheet contents,
in messageID counterfoil,
in title docName ) => start opnum = 204;
/*
* Mail Acme_Sheet
* Include in tool's ptype if tool can mail a document.
*/
session Mail( in Acme_Sheet contents ) => start opnum = 301;
session Mail( inout Acme_Sheet contents ) => start opnum = 311;
session Mail( inout Acme_Sheet contents,
in title docName ) => start opnum = 313;
session Mail( out Acme_Sheet contents ) => start opnum = 321;
session Mail( out Acme_Sheet contents,
in messageID counterfoil ) => start opnum = 323;
};
Code Example D-6 Xt Input Handler Function Example
int myTtFd;
char *myProcID;
myProcID = ttdt_open( &myTtFd, "WhizzyCalc", "Acme", "1.0", 1 );
/* ... */
/* Process the message that started us, if any */
tttk_Xt_input_handler( myProcID, 0, 0 );
/* ... */
XtAppAddInput( myContext, myTtFd, (XtPointer)XtInputReadMask,
tttk_Xt_input_handler, myProcID );