GENWiki

Premier IT Outsourcing and Support Services within the UK

User Tools

Site Tools


archive:programming:xwindow

_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
                                  &copyID );
  }
  /* 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) $<

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:

  1. rm *.bak *.o

lint:

lint $(INCLUDE_DIRS) -DSYSV *.c
/data/webs/external/dokuwiki/data/pages/archive/programming/xwindow.txt · Last modified: 2001/11/08 10:27 by 127.0.0.1

Was this page helpful?-11+1

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki