💾 Archived View for spam.works › mirrors › textfiles › programming › xwindow.asc captured on 2023-07-22 at 20:46:33.
View Raw
More Information
⬅️ Previous capture (2023-06-16)
-=-=-=-=-=-=-
_INTRINSICS OF THE X TOOLKIT_
by Todd Lainhart
[LISTING ONE]
!
! Resource specifications for simple text editor
!
- textEdit.rows: 24
- textEdit.columns: 80
- textEdit.resizeWidth: False
- textEdit.resizeHeight: False
- textEdit.translations: #override \n\
Ctrl<Key>Right: forward-word() \n\
Ctrl<Key>Left: backward-word() \n\
Ctrl<Key>a: beginning-of-line() \n\
Ctrl<Key>e: end-of-line() \n\
Ctrl<Key>a, Ctrl<Key>a: beginning-of-file() \n\
Ctrl<Key>e, Ctrl<Key>e: end-of-file()
[LISTING TWO]
/*~PKG*************************************************************************
* Package Name: xm_main.c
* Synopsis: Implements a simple text editor using the Motif toolkit.
* Features Supported: Not much.
* References: Xt Programming and Apps by Doug Young.
* Xm Programming Reference and Guide by OSF.
* Xt Programming Reference and Guide by O'Reilly.
* Usage: Bind this with a couple of other support objs.
* Known Bugs/Deficiencies:
* Modification History: 11/01/90 twl original
*/
/******************************************************************************
* Header files included. */
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <Xm/Xm.h>
#include <Xm/Text.h>
#include <Xm/RowColumn.h>
#include <Xm/PushBG.h>
#include <Xm/FileSB.h>
#include <Xm/SelectioB.h>
#include "xm_callbacks.h"
/******************************************************************************
* Constants and variables local to this package. */
/* These widgets are the popup menu items, externalized here so that
* functions within this package can have access (for the setting/unsetting
* of selectability. */
static Widget CopyMenuItem;
static Widget CutMenuItem;
static Widget PasteMenuItem;
static Widget PasteFileMenuItem;
static Widget WriteFileMenuItem;
static void ExitApp();
/* The actions table for declaring new translations. */
static
XtActionsRec actionTable[] =
{
{ "exit", ExitApp },
};
/******************************************************************************
* Procedure: ExitApp
* Synopsis: Action procedure for exiting application
* Assumptions: None.
* Features Supported:
* Known Bugs/Deficiencies: We're not interested in checking state of the editor before going down.
* Regardless of the circumstances, down we go.
* Modification History: 11/01/90 twl original
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void
ExitApp( Widget parent, XEvent *event, String *actionArgs, Cardinal argNdx )
{
XtCloseDisplay( XtDisplay( parent ) );
exit( 0 );
}
/******************************************************************************
* Procedure: DisplayTextEditMenu
* Synopsis: Event handler to display the text body popup menu.
* Assumptions: The parent is a Text Widget.
* Features Supported:
* Known Bugs/Deficiencies: External resources should be considered.
* Modification History: 11/01/90 twl original
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void
DisplayTextEditMenu( textBody, popupMenu, xEvent )
Widget textBody; /* Owner of the event handler */
Widget popupMenu; /* Data passed by the registering procedure */
XEvent *xEvent; /* Passed to all event handlers */
{
Arg argList[25]; /* Resource argument list */
int argNdx; /* Index into resource list */
int menuButton; /* MENU button assigned to popup */
char *selectedText; /* The text selected for the widget invoking
/* We're assuming that the owning widget of this event handler is of
* type XmCText. If not, get out. */
if ( !XmIsText( textBody ) )
{
printf( "DisplayTextEditMenu: Not Text\n" );
exit( 1 );
}
/* We're also assuming that the the data passed by the event handler
* is a popup menu widget. If not, get out. */
if ( !XmIsRowColumn( popupMenu ) )
{
printf( "DisplayTextEditMenu: Not RowColumn\n" );
exit( 1 );
}
/* Check to see if the button that caused this event is the menu
* button. If not, get out. */
argNdx = 0;
XtSetArg( argList[argNdx], XmNwhichButton, &menuButton ); argNdx++;
XtGetValues( popupMenu, argList, argNdx );
if ( xEvent->xbutton.button != menuButton )
{
return;
}
/* We need to set the selectability of the menu items here. For most menu
* items, that involves checking to see if any text has been selected. */
selectedText = XmTextGetSelection( textBody );
/* The Copy menu item. */
if ( selectedText != NULL )
{
XtSetSensitive( CopyMenuItem, TRUE );
}
else
{
XtSetSensitive( CopyMenuItem, FALSE );
}
/* The Cut menu item. */
if ( selectedText != NULL )
{
XtSetSensitive( CutMenuItem, TRUE );
}
else
{
XtSetSensitive( CutMenuItem, FALSE );
}
/* The Paste menu item. See if there's something in the clipboard,
* and set sensitivity accordingly. */
if ( selectedText == NULL )
{
if ( ClipboardIsEmpty( textBody ) )
{
XtSetSensitive( PasteMenuItem, FALSE );
}
else
{
XtSetSensitive( PasteMenuItem, TRUE );
}
}
else
{
XtSetSensitive( PasteMenuItem, FALSE );
}
/* The PasteFile menu item. Let's say that we can only paste from a file
* if no text has been selected. */
if ( selectedText == NULL )
{
XtSetSensitive( PasteFileMenuItem, TRUE );
}
else
{
XtSetSensitive( PasteFileMenuItem, FALSE );
}
/* The WriteFile menu item. */
if ( selectedText != NULL )
{
XtSetSensitive( WriteFileMenuItem, TRUE );
}
else
{
XtSetSensitive( WriteFileMenuItem, FALSE );
}
XmMenuPosition( popupMenu, xEvent );
XtManageChild( popupMenu );
}
/*~PROC************************************************************************
* Procedure: CreateTextEditPopup
* Synopsis: Creates the Popup menu displayed over the text edit area.
* Callbacks are also defined here.
* Assumptions:
* Features Supported:
* Known Bugs/Deficiencies: External resources should perhaps be considered.
* Modification History: 11/01/90 twl original
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static Widget
CreateTextEditPopup( Widget parent )
{
Widget textPopup; /* Created popup returned */
Arg argList[25]; /* Resource argument list */
int argNdx; /* Index into argument list */
Widget fileDialog; /* File selection dialog box */
Widget promptDialog; /* Text input prompt */
/* We assume a text edit widget as parent. If not, get out. */
if ( !XmIsText( parent ) )
{
printf( "CreateTextEditPopup: Not Text\n" );
exit( 1 );
}
/* Create the popup menu. We'll tell Xt to manage it at the time that
* it needs to be displayed. */
textPopup = XmCreatePopupMenu( parent, "textPopup", NULL, 0 );
/* Add the menu items (buttons). */
argNdx = 0;
XtSetArg( argList[argNdx], XmNlabelString, XmStringCreateLtoR( "Copy", XmSTRING_DEFAULT_CHARSET ) ); argNdx++;
CopyMenuItem = XmCreatePushButtonGadget( textPopup, "copyMenuItem", argList, argNdx );
XtManageChild( CopyMenuItem );
argNdx = 0;
XtSetArg( argList[argNdx], XmNlabelString, XmStringCreateLtoR( "Cut", XmSTRING_DEFAULT_CHARSET ) ); argNdx++;
CutMenuItem = XmCreatePushButtonGadget( textPopup, "cutMenuItem", argList, argNdx );
XtManageChild( CutMenuItem );
argNdx = 0;
XtSetArg( argList[argNdx], XmNlabelString, XmStringCreateLtoR( "Paste", XmSTRING_DEFAULT_CHARSET ) ); argNdx++;
PasteMenuItem = XmCreatePushButtonGadget( textPopup, "pasteMenuItem", argList, argNdx );
XtManageChild( PasteMenuItem );
argNdx = 0;
XtSetArg( argList[argNdx], XmNlabelString, XmStringCreateLtoR( "Paste From File...", XmSTRING_DEFAULT_CHARSET ) ); argNdx++;
PasteFileMenuItem = XmCreatePushButtonGadget( textPopup, "pasteFileMenuItem", argList, argNdx );
XtManageChild( PasteFileMenuItem );
argNdx = 0;
XtSetArg( argList[argNdx], XmNlabelString, XmStringCreateLtoR( "Write To File...", XmSTRING_DEFAULT_CHARSET ) ); argNdx++;
WriteFileMenuItem = XmCreatePushButtonGadget( textPopup, "writeFileMenuItem", argList, argNdx );
XtManageChild( WriteFileMenuItem );
/* Add the File Selection dialog, to be invoked by PasteFileMenu button. */
argNdx = 0;
XtSetArg( argList[argNdx], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL ); argNdx++;
XtSetArg( argList[argNdx], XmNdialogTitle, XmStringCreateLtoR( "Paste From File", XmSTRING_DEFAULT_CHARSET ) ); argNdx++;
XtSetArg( argList[argNdx], XmNselectionLabelString, XmStringCreateLtoR( "Directory", XmSTRING_DEFAULT_CHARSET ) ); argNdx++ ;
XtSetArg( argList[argNdx], XmNautoUnmanage, True ); argNdx++;
fileDialog = XmCreateFileSelectionDialog( parent, "fileDialog", argList, argNdx );
/* Add a selection dialog, to be invoked by the WriteFileMenu button. */
argNdx = 0;
XtSetArg( argList[argNdx], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL ); argNdx++;
XtSetArg( argList[argNdx], XmNdialogTitle, XmStringCreateLtoR( "Write To File", XmSTRING_DEFAULT_CHARSET ) ); argNdx++;
XtSetArg( argList[argNdx], XmNselectionLabelString, XmStringCreateLtoR( "File", XmSTRING_DEFAULT_CHARSET ) ); argNdx++ ;
XtSetArg( argList[argNdx], XmNtextColumns, 32 ); argNdx++;
promptDialog = XmCreatePromptDialog( parent, "promptDialog", argList, argNdx );
/* Add callbacks for the menu buttons. */
XtAddCallback( CopyMenuItem, XmNactivateCallback, CopyCB, parent );
XtAddCallback( CutMenuItem, XmNactivateCallback, CutCB, parent );
XtAddCallback( PasteMenuItem, XmNactivateCallback, PasteCB, parent );
XtAddCallback( PasteFileMenuItem, XmNactivateCallback, PasteFileCB, fileDialog );
XtAddCallback( WriteFileMenuItem, XmNactivateCallback, WriteFileCB, promptDialog );
/* Add callbacks for the dialog box buttons. */
XtAddCallback( fileDialog, XmNokCallback, FileDialogOKCB, parent );
XtAddCallback( fileDialog, XmNcancelCallback, UnMapDialogCB, fileDialog );
XtAddCallback( fileDialog, XmNhelpCallback, UnMapDialogCB, fileDialog );
XtAddCallback( promptDialog, XmNokCallback, PromptDialogOKCB, parent );
XtAddCallback( promptDialog, XmNcancelCallback, UnMapDialogCB, promptDialog );
XtAddCallback( promptDialog, XmNhelpCallback, UnMapDialogCB, promptDialog );
return( textPopup );
}
/*~PROC************************************************************************
* Procedure: main
* Synopsis: Initializes the Intrinsics, creates all of the higher-level widgets
* necessary to make the application happen, and enters the main loop.
* Assumptions:
* Usage: Command-line arguments are ignored (for now).
* Modification History: 11/01/90 twl original
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void
main( int argc, char *argv[] )
{
Widget topShell; /* Top level shell created by the Intrinsics */
Widget textEdit; /* Main edit Text Widget */
Widget textMenu; /* Popup menu associated with the text editor */
Arg argList[25]; /* Resource argument list */
int argNdx; /* Index into resource list */
/* Initialize the Intrinsics. */
topShell = XtInitialize( argv[0], "Editor", NULL, 0, &argc, argv );
/* Create the scrolled Text Widget */
argNdx = 0;
XtSetArg(argList[argNdx], XmNscrollVertical, True ); argNdx++;
XtSetArg(argList[argNdx], XmNscrollHorizontal, True ); argNdx++;
XtSetArg(argList[argNdx], XmNeditMode, XmMULTI_LINE_EDIT ); argNdx++;
textEdit = XmCreateScrolledText( topShell, "textEdit", argList, argNdx );
XtManageChild( textEdit );
/* Create the context-sensitive popup menu for this Widget */
textMenu = CreateTextEditPopup( textEdit );
/* Add the event handler to the Text Widget, invoking the popup menu. */
XtAddEventHandler( textEdit, ButtonPressMask, FALSE, DisplayTextEditMenu, textMenu );
/* Register new actions to be associated with our app. */
XtAddActions( actionTable, XtNumber( actionTable ) );
/* Map the editor, and enter the event dispatch loop. */
XtRealizeWidget( topShell );
XtMainLoop();
}
[LISTING THREE]
/*~PKG*************************************************************************
* Package Name: xm_callbacks.c
* Synopsis: Common text manipulation callbacks.
* Features Supported:
* References: Xt Programming and Apps by Doug Young.
* Xm Programming Reference and Guide by OSF.
* Xt Programming Reference and Guide by O'Reilly.
* Usage: Include "xm_callbacks.h"
* Known Bugs/Deficiencies:
* Modification History: 11/01/90 twl original
*/
/*~HDR*************************************************************************
* Header files included.
*/
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <X11/Xatom.h>
#include <X11/StringDefs.h>
#include <X11/Intrinsic.h>
#include <Xm/Xm.h>
#include <Xm/Text.h>
#include <Xm/FileSB.h>
#include "xm_clipboard.h"
/*~PROC************************************************************************
* Procedure: MapDialogCB
* Synopsis: Maps the referenced dialog box.
* Assumptions: The parent has been realized.
* The widget passed to this callback is a subclass of dialogshell.
* Features Supported:
* Known Bugs/Deficiencies:
* Modification History: 11/01/90 twl original
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void
MapDialogCB( source, dialog, callbackData )
Widget source; /* Source of the callback */
Widget dialog; /* Data passed to the callback by the register procedure */
XmAnyCallbackStruct *callbackData; /* Generic data passed to all callback procedures */
{
XtManageChild( dialog );
}
/*~PROC************************************************************************
* Procedure: UnMapDialogCB
* Synopsis: Unmaps the referenced dialog box.
* Assumptions: The parent has been realized.
* The widget passed to this callback is a subclass of dialogshell.
* Features Supported:
* Known Bugs/Deficiencies:
* Modification History: 11/01/90 twl original
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void
UnMapDialogCB( source, dialog, callbackData )
Widget source; /* Source of the callback */
Widget dialog; /* Data passed to the callback by the register procedure */
XmAnyCallbackStruct *callbackData; /* Generic data passed to all callback procedures */
{
XtUnmanageChild( dialog );
}
/*~PROC************************************************************************
* Procedure: CutCB
* Synopsis: Callback procedure for cutting text from the referenced text
* widget to the clipboard. Callback for the "Cut" menu item.
* Assumptions:
* Features Supported:
* Known Bugs/Deficiencies: Cursor should change to a wait state.
* Modification History: 11/01/90 twl original
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void
CutCB( source, textID, callbackData )
Widget source; /* Source of the callback */
Widget textID; /* Data passed to the callback by the register procedure */
XmAnyCallbackStruct *callbackData; /* Generic data passed to all callback procedures */
{
XClientMessageEvent clientMessage; /* X client message structure */
Time timestamp; /* X Event time */
int clipStat; /* Return status of clipboard call */
/* Get the event timestamp */
timestamp = ((XButtonEvent *)callbackData->event)->time;
/* Copy the selected text to the clipboard. */
clipStat = CopyToClipboard( textID, timestamp );
/* Delete the selected text from the Text Widget */
if ( clipStat == True )
{
clientMessage.type = ClientMessage;
clientMessage.display = XtDisplay( textID );
clientMessage.message_type = XmInternAtom( XtDisplay( textID ), "KILL_SELECTION", FALSE );
clientMessage.window = XtWindow( textID );
clientMessage.format = 32;
clientMessage.data.l[0] = XA_PRIMARY;
XSendEvent( XtDisplay( textID ), clientMessage.window, TRUE, NoEventMask, &clientMessage );
}
}
/*~PROC************************************************************************
* Procedure: CopyCB
* Synopsis: Callback procedure for copying text from the referenced text
* widget to the clipboard. Callback for the "Copy" menu item.
* Assumptions:
* Features Supported:
* Known Bugs/Deficiencies: The cursor should change into a waiting cursor.
* Modification History: 11/01/90 twl original
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void
CopyCB( source, textID, clientData )
Widget source; /* Source of the callback */
Widget textID; /* Data passed to the callback as defined by the registering procedure */
XmAnyCallbackStruct *clientData; /* Generic data passed to all callback procedures */
{
Time eventTime; /* Time stamp for the clipboard */
/* Get the time the event occurred */
eventTime = ((XButtonEvent *)clientData->event)->time;
/* Copy the selected text (if any) to the clipboard */
CopyToClipboard( textID, eventTime );
}
/*~PROC************************************************************************
* Procedure: PasteCB
* Synopsis: Callback procedure for pasting text from the referenced text widget
* to the clipboard. Callback for the "Paste" menu item.
* Assumptions:
* Features Supported:
* Known Bugs/Deficiencies: External resources should be considered.
* Modification History: 11/01/90 twl original
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void
PasteCB( source, textID, callbackData )
Widget source; /* Owner of the callback */
Widget textID; /* Data passed to the callback routine by */
/* the registering procedure */
XmAnyCallbackStruct *callbackData; /* Data passed to all callbacks */
{
char *pasteText; /* That text which is to be retrieved from the paste buffer */
Time eventTime; /* Time stamp for the clipboard routines */
Arg argList[25]; /* Resource retrieval array */
int argNdx; /* Index into resource array */
XmTextPosition textCursorPos; /* Position of Text Widget insertion cursor */
/* Get the time the event occurred (for transaction timestamping) */
eventTime = ((XButtonEvent *)callbackData->event)->time;
/* Get the latest text from the clipboard. */
pasteText = RetrieveFromClipboard( textID, eventTime );
/* See if we have a hit. If not, get out. */
if ( pasteText == NULL )
{
return;
}
/* Get the insertion point of the text Widget */
argNdx = 0;
XtSetArg( argList[argNdx], XmNcursorPosition, &textCursorPos ); argNdx++;
XtGetValues( textID, argList, argNdx );
/* ...and insert the text */
XmTextReplace( textID, textCursorPos, textCursorPos, pasteText );
XtFree( pasteText );
}
/*~PROC************************************************************************
* Procedure: PasteFileCB
* Synopsis: Callback procedure for the Paste from File... menu item.
* Currently, just the dialog box is displayed.
* Assumptions:
* Features Supported:
* Known Bugs/Deficiencies: External resources should be considered.
* Modification History: 11/01/90 twl original
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void
PasteFileCB( source, dialog, callbackData )
Widget source; /* Owner of the callback */
Widget dialog; /* Data passed to the callback routine by */
/* the registering procedure */
XmAnyCallbackStruct *callbackData; /* Data passed to all callbacks */
{
XtManageChild( dialog );
}
/*~PROC************************************************************************
* Procedure: WriteFileCB
* Synopsis: Callback procedure for the Write to File... menu item.
* Currently, just the dialog box is displayed.
* Assumptions:
* Features Supported:
* Known Bugs/Deficiencies: External resources should be considered.
* Modification History: 11/01/90 twl original
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void
WriteFileCB( source, dialog, callbackData )
Widget source; /* Owner of the callback */
Widget dialog; /* Data passed to the callback routine by */
/* the registering procedure */
XmAnyCallbackStruct *callbackData; /* Data passed to all callbacks */
{
XtManageChild( dialog );
}
/*~PROC************************************************************************
* Procedure: FileDialogOKCB
* Synopsis: Callback procedure for the activation of the OK button on the file selection
* dialog box.
* Assumptions: The file to be pasted is ASCII.
* The source of the callback is a file selection dialog box.
* Features Supported:
* Known Bugs/Deficiencies: External resources should be considered.
* The file to be pasted is not checked for type (should be ASCII).
* Modification History: 11/01/90 twl original
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void
FileDialogOKCB( source, textID, callbackData )
Widget source; /* Owner of the callback */
Widget textID; /* Data passed to the callback routine */
XmFileSelectionBoxCallbackStruct *callbackData; /* Data passed to all file selection callbacks */
{
char *pasteFile; /* Filename returned from the dialog */
int pasteFileLen; /* Length of referenced file */
char *pasteText; /* Contents of reference file */
struct stat statBuf; /* Buffer for stat() results */
FILE *fileDesc; /* UNIX file descriptor */
Arg argList[25]; /* Resource retrieval array */
int argNdx; /* Index into resource array */
XmTextPosition textCursorPos; /* Position of Text Widget insertion cursor */
if ( !XmIsText( textID ) )
{
printf( "FileDialogOKCB: Not Text Widget\n" );
exit( 1 );
}
if ( !XmIsFileSelectionBox( source ) )
{
printf( "FileDialogOKCB: Not dialog box\n" );
exit( 1 );
}
/* Get the filename */
XmStringGetLtoR( callbackData->value, XmSTRING_DEFAULT_CHARSET, &pasteFile );
/* Open the file */
fileDesc = fopen( pasteFile, "r" );
if ( fileDesc == NULL )
{
/* Display an error prompt, and get out */
printf( "FileDialogOKCB: File not available for read\n" );
exit( 1 );
}
/* Get its length, read the contents, and close it up. */
stat( pasteFile, &statBuf );
pasteFileLen = statBuf.st_size;
pasteText = XtMalloc( pasteFileLen );
fread( pasteText, sizeof( char ), pasteFileLen, fileDesc );
fclose( fileDesc );
/* Paste the contents at the current insertion point. */
argNdx = 0;
XtSetArg( argList[argNdx], XmNcursorPosition, &textCursorPos ); argNdx++;
XtGetValues( textID, argList, argNdx );
XmTextReplace( textID, textCursorPos, textCursorPos, pasteText );
/* Free up resources */
XtFree( pasteFile );
XtFree( pasteText );
/* Bring down the dialog box */
XtUnmanageChild( source );
}
/*~PROC************************************************************************
* Procedure: PromptDialogOKCB
* Synopsis: Callback procedure for the activation of the OK button on the prompt
* dialog box.
* Assumptions:
* Features Supported:
* Known Bugs/Deficiencies: External resources should be considered.
* Minimal error checking on file creation and write.
* Modification History: 08/20/90 twl original
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void
PromptDialogOKCB( source, textID, callbackData )
Widget source; /* Owner of the callback */
Widget textID; /* Data passed to the callback routine */
XmSelectionBoxCallbackStruct *callbackData; /* Data passed to all selection callbacks */
{
char *writeFile; /* Filename returned from the dialog */
int writeFileLen; /* Length of referenced file */
char *writeText; /* Contents of reference file */
struct stat statBuf; /* Buffer for stat() results */
FILE *fileDesc; /* UNIX file descriptor */
char *selectedText; /* That text which is marked as selected in textID */
if ( !XmIsText( textID ) )
{
printf( "PromptDialogOKCB: Not Text Widget\n" );
exit( 1 );
}
/* If no text selected, we can leave. */
selectedText = XmTextGetSelection( textID );
if ( selectedText == NULL )
{
return;
}
/* Get the filename */
XmStringGetLtoR( callbackData->value, XmSTRING_DEFAULT_CHARSET, &writeFile );
/* Open the file */
fileDesc = fopen( writeFile, "w" );
if ( fileDesc == NULL )
{
/* Display an error, and get out */
printf( "PromptDialogOKCB: Error on file creation\n" );
exit( 1 );
}
/* Write the file, and close it up */
fwrite( selectedText, sizeof( char ), strlen( selectedText ), fileDesc );
if ( fclose( fileDesc ) != NULL )
{
/* Display an error, and get out */
printf( "PromptDialogOKCB: Error on file close\n" );
exit( 1 );
}
}
[LISTING FOUR]
/*~PKG*************************************************************************
* Package Name: xm_clipboard.c
* Synopsis: Implements clipboard store and retrieve procedures.
* Features Supported:
* References: Xt Programming and Apps by Doug Young.
* Xm Programming Reference and Guide by OSF.
* Xt Programming Reference and Guide by O'Reilly.
* Usage: Include "xm_clipboard.h"
* Known Bugs/Deficiencies:
* Modification History: 11/01/90 twl original
*/
/*~HDR*************************************************************************
* Header files included. */
#include <X11/StringDefs.h>
#include <X11/Intrinsic.h>
#include <Xm/Xm.h>
#include <Xm/Text.h>
#include <Xm/CutPaste.h>
/*~LOC*DATA********************************************************************
* Constants and variables local to this package. */
#define CBLABEL "TextEdit"
/*~PROC************************************************************************
* Procedure: CopyToClipboard
* Synopsis: Retrieve selected text from reference textID, and copy it to the system
* clipboard. Returns True if successful, False if not.
* Assumptions:
* Features Supported:
* Known Bugs/Deficiencies: Text only supported.
* Modification History: 11/01/90 twl original
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int
CopyToClipboard( Widget textID, Time timestamp )
{
char *selectedText; /* That text which is marked as selected in textID */
int clipStat; /* Return value from XmClipboard routines */
XmString clipLabel; /* The label used to identify the clipboard string */
long clipID, copyID; /* The handles used in identifying clipboard transactions */
/* Sanity check. */
if ( !XmIsText( textID ) )
{
printf( "CopyToClipboard: Not Text Widget\n" );
exit( 1 );
}
/* If no text selected, we can leave. */
selectedText = XmTextGetSelection( textID );
if ( selectedText == NULL )
{
return( False );
}
/* Create the label that appears in the clipboard. */
clipLabel = XmStringCreateLtoR( CBLABEL, XmSTRING_DEFAULT_CHARSET );
/* Poll the clipboard, asking for permission to start. */
clipStat = ClipboardLocked;
while( clipStat == ClipboardLocked )
{
clipStat = XmClipboardStartCopy( XtDisplay( textID ), XtWindow( textID ),
clipLabel, timestamp, textID, NULL,
&clipID );
}
/* Copy the data to the clipboard until successful. */
clipStat = ClipboardLocked;
while( clipStat == ClipboardLocked )
{
clipStat = XmClipboardCopy( XtDisplay( textID ), XtWindow( textID ), clipID,
XtRString, selectedText, (long)strlen( selectedText ), 0
©ID );
}
/* End the transaction... */
clipStat = ClipboardLocked;
while( clipStat == ClipboardLocked )
{
clipStat = XmClipboardEndCopy( XtDisplay( textID ), XtWindow( textID ), clipID );
}
/* ... cleanup, and leave. */
XtFree( selectedText );
XmStringFree( clipLabel );
return( True );
}
/*~PROC************************************************************************
* Procedure: RetrieveFromClipboard
* Synopsis: Return text from the clipboard.
* Assumptions: The caller assumes responsibility for freeing returned string.
* Features Supported:
* Known Bugs/Deficiencies: Text only supported.
* Modification History: 11/01/90 twl original
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
char *
RetrieveFromClipboard( Widget textID, Time timestamp )
{
char *pasteText; /* That text which is to be retrieved from the paste buffer */
int pasteTextLen; /* Length of text in clipboard */
int clipStat; /* Return value from XmClipboard routines */
XmString clipLabel; /* The label used to identify the clipboard string */
long clipID, privateID; /* The handles used in identifying clipboard transactions */
long outlen; /* Length of data retrieved from clipboard */
/* Check to be sure that we have a text Widget */
if ( !XmIsText( textID ) )
{
printf( "RetrieveFromClipboard: Widget not Text\n" );
exit( 1 );
}
/* Start our clipboard transaction */
clipStat = ClipboardLocked;
while( clipStat == ClipboardLocked )
{
clipStat = XmClipboardStartRetrieve( XtDisplay( textID ), XtWindow( textID ),
timestamp );
}
/* Get the length of the clipboard contents */
clipStat = ClipboardLocked;
pasteTextLen = 0;
while( clipStat == ClipboardLocked )
{
clipStat = XmClipboardInquireLength( XtDisplay( textID ), XtWindow( textID ),
XmRString, &pasteTextLen );
if ( clipStat == ClipboardNoData )
{
return( NULL );
}
}
/* Retrieve the data (allocating a string buffer) */
pasteText = XtMalloc( pasteTextLen + 1 );
clipStat = ClipboardLocked;
while( clipStat == ClipboardLocked )
{
clipStat = XmClipboardRetrieve( XtDisplay( textID ), XtWindow( textID ),
XmRString, pasteText, pasteTextLen,
&outlen, &privateID );
}
/* End the clipboard session... */
clipStat = ClipboardLocked;
while( clipStat == ClipboardLocked )
{
clipStat = XmClipboardEndRetrieve( XtDisplay( textID ), XtWindow( textID ) );
}
/* ... and return the clipboard contents. */
return( pasteText );
}
/*~PROC************************************************************************
* Procedure: ClipboardIsEmpty
* Synopsis: Returns FALSE, if no items in the clipboard.
* Assumptions:
* Features Supported:
* Known Bugs/Deficiencies: Text only supported. Returns False (no data) if clipboard is locked.
* Modification History: 11/01/90 twl original
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int
ClipboardIsEmpty( Widget w )
{
int clipStat; /* Clipboard status value */
int textLength; /* Length of text in clipboard */
clipStat = XmClipboardInquireLength( XtDisplay( w ), XtWindow( w ), XmRString,
&textLength );
if ( clipStat == ClipboardSuccess )
{
return( False );
}
else
{
return( True );
}
}
[LISTING FIVE]
#ifndef XM_CALLBACKS_H
#define XM_CALLBACKS_H
/*****************************************************************************
* Include File Name: xm_callbacks.h
* Contents: Interface to the callbacks package.
* This include file is dependent on the following include file(s):
* None.
* Modification History: 11/01/90 twl original
*/
/*~EXP*PROC********************************************************************
* Procedures and functions exported by this package. */
extern void
MapDialogCB( Widget source, Widget dialog, XmAnyCallbackStruct *callbackData );
extern void
UnMapDialogCB( Widget source, Widget dialog, XmAnyCallbackStruct *callbackData );
extern void
CutCB( Widget source, Widget textID, XmAnyCallbackStruct *callbackData );
extern void
CopyCB( Widget source, Widget textID, XmAnyCallbackStruct *callbackData );
extern void
PasteCB( Widget source, Widget textID, XmAnyCallbackStruct *callbackData );
extern void
PasteFileCB( Widget source, Widget textID, XmAnyCallbackStruct *callbackData );
extern void
WriteFileCB( Widget source, Widget textID, XmAnyCallbackStruct *callbackData );
extern void
FileDialogOKCB( Widget source, Widget textID, XmFileSelectionBoxCallbackStruct *callbackData );
extern void
PromptDialogOKCB( Widget source, Widget textID, XmSelectionBoxCallbackStruct *callbackData );
#endif
[LISTING SIX]
#ifndef XM_CLIPBOARD_H
#define XM_CLIPBOARD_H
/*****************************************************************************
*
* Include File Name: xm_clipboard.h
*
* Contents:
* Interface to the Clipboard package.
*
* This include file is dependent on the following include file(s):
* None.
*
* Modification History:
* 11/01/90 twl original
*/
/*~EXP*PROC********************************************************************
*
* Procedures and functions exported by this package.
*/
extern int
CopyToClipboard( Widget textID, Time timestamp );
extern char *
RetrieveFromClipboard( Widget textID, Time timestamp );
extern int
ClipboardIsEmpty( Widget w );
#endif
[LISTING SEVEN]
#
# Makefile to build textedit
#
#
# Macros
#
CC=/bin/cc
DEBUG=-g
INCLUDE_DIRS=-I /usr/include/Xm -I /usr/include/X11
SYS_DEFS=$(SYS_T) $(RUN_T) -DSYSV
CC_SWITCHES= -c $(SYS_DEFS) $(INCLUDE_DIRS) $(DEBUG)
LD=/bin/ld
LIBDIRS=-L/usr/X11/lib
LIBS=-lXm -lXtm -lXaw -lX11
LD_SWITCHES=$(LIBDIRS) $(LIBS)
#
# Inference rules
#
.SUFFIXES: .c .o .ln
.c.o:
$(CC) $(CC_SWITCHES) {body}lt;
OBJS=\
xm_main.o\
xm_clipboard.o\
xm_callbacks.o
#
# Targets
#
all: textedit
textedit: $(OBJS)
$(LD) -o $@ $(OBJS) $(LD_SWITCHES)
xm_main.o: xm_callbacks.h
xm_callbacks.o: xm_clipboard.h
#-------------------------
# Misc targets
#-------------------------
clean:
-rm *.bak *.o
lint:
lint $(INCLUDE_DIRS) -DSYSV *.c