Document revision date: 30 March 2001

## DEC Text Processing Utility Reference Manual

Previous | Contents | Index

The parameter specifies the data to supply to the requesting application. If you specify NONE, DECTPU informs the requesting application that no information is available. However, for any case in which a routine omits a WRITE_GLOBAL_SELECT statement, by default DECTPU informs the requesting application that no information is available.

Call WRITE_GLOBAL_SELECT no more than once during the execution of a global selection read routine. DECTPU signals TPU$_INVBUILTININV if you attempt to call this routine more than once.

#### Signaled Errors

TPU$_BUILTININV | WARNING | WRITE_GLOBAL_SELECT was used more than once in the same routine or the built-in is being called outside of a global section read routine.
TPU$_TRUNCATE | WARNING | DECTPU truncated characters from the data written because you specified a buffer or range that contained more than 65535 characters.
TPU$_INVPARAM | ERROR | One of the parameters was specified with data of the wrong type.
TPU$_NORETURNVALUE | ERROR | WRITE_GLOBAL_SELECT cannot return a value.
TPU$_REQUIRESDECW | ERROR | You can use the WRITE_GLOBAL_SELECT built-in only if you are using DECwindows DECTPU.
TPU$_TOOFEW | ERROR | Too few arguments passed to the WRITE_GLOBAL_SELECT built-in.
TPU$_TOOMANY | ERROR | Too many arguments passed to the WRITE_GLOBAL_SELECT built-in.

### Example

> The following example sends the contents of the range this_range to the requesting application:

    WRITE_GLOBAL_SELECT (this_range);

> For an example of a procedure that uses the WRITE_GLOBAL_SELECT built-in procedure, see Example A-6.

## Appendix A
Sample DECwindows DECTPU Procedures

This appendix presents a number of procedures that use DECwindows built-ins.

The following examples demonstrate some of the ways in which you can use DECTPU procedures:

- Creating a mouse pad
- Implementing an EDT-style APPEND command
- Testing and returning a select range
- Handling callbacks from a scroll bar widget
- Reactivating a select range
- Implementing the DECwindows COPY SELECTION operation from EVE to another application

Most of the procedures are drawn from the code implementing the Extensible Versatile Editor (EVE). Some have been modified to make them easier to understand.

You can see all the code used to implement EVE by looking at the files in SYS$EXAMPLES:EVE$*.*.

## A.1 Creating a Mouse Pad

Example A-1 shows how to use the variant of CREATE_WIDGET that calls the Toolkit low-level creation routine. The module in Example A-1 creates a screen that represents a keypad. Instead of pressing a keypad key, you can click on the widget that represents the key.

Example A-1 Procedure That Creates a Mouse Pad

    ! SAMPLE.TPU

    !++
    !                                Table of Contents
    !
    !                                   SAMPLE.TPU
    !
    !        Procedure name        Description
    !        --------------        -----------
    !
    !        sample_sample_module_ident   Ident.
    !        sample_sample_module_init    Initializes the module.
    !        eve_mouse_pad                Implements the user command DISPLAY MOUSE PAD.
    !        sample_key_def               Creates a mouse pad "key" push button.
    !        sample_key_dispatch          Handles push button widget callbacks.
    !        sample_row_to_pix            Converts a row number to pixels.
    !        sample_col_to_pix            Converts a column number to pixels.
    !        sample_key_height            Converts y dimension from rows to pixels.
    !        sample_key_width             Converts x dimension from columns to pixels.
    !--
    ! This module layers a "mouse pad" on top of DECTPU.  The mouse pad
    ! is implemented by creating a dialog box widget that is the parent of a group
    ! of push button widgets depicting keypad keys.  The resulting
    ! "mouse pad" is a screen representation of a keypad.  The user can
    ! click on a push button to execute the same function that would be
    ! executed by pressing the corresponding keypad key.  The module uses
    ! the key map list mapped to the current buffer to determine what
    ! code to execute when the user clicks on a given push button.  To
    ! use a different key map, substitute a string naming the desired
    ! key map for the null string assigned to "sample_k_keymap".
    ! This module can be used with the EVE section file
    ! or with a non-EVE section file.
    !
    ! This module uses the variant of CREATE_WIDGET that calls
    ! X Toolkit widget creation routines to create instances
    ! of widgets of specific classes.

    ! Widget class records for the DECwindows widgets for DEFINE_WIDGET built-in.

    CONSTANT
        sample_k_labelwidgetclass      := "xmLabelWidgetClassRec",
        sample_k_dialogwidgetclass     := "xmBulletinBoardClassRec",
        sample_k_pushbuttonwidgetclass := "xmPushButtonClassRec";

    ! Motif Toolkit resource name strings, callback reasons, resource values, or
    ! arguments to the CREATE_WIDGET built-in.

    CONSTANT
        sample_k_cstyle := "dialogStyle",
        sample_k_modeless := 0,  ! = XmDIALOG_MODELESS
        sample_k_nunits := "unitType",
        sample_k_pixelunits := 0,  ! = XmPIXELS
        sample_k_ntitle := "dialogTitle",
        sample_k_nx := "x",
        sample_k_ny := "y",
        sample_k_nautounmanage := "autoUnmanage",
        sample_k_nheight := "height",
        sample_k_nwidth := "width",
        sample_k_nlabel := "labelString",
        sample_k_nactivate_callback := "activateCallback",
        sample_k_nborderwidth := "borderWidth",
        sample_kt_nrecomputeSize := "recomputeSize",
        sample_k_cractivate := 10;

    ! These constants are intended for use only in this sample module
    ! because their values are specific to the mouse pad application.

    CONSTANT
        sample_k_x_pos := 500,            ! Screen position for mouse pad.
        sample_k_y_pos := 500,
        sample_k_keypad_border := 5,      ! Width of border between keys and edge.
        sample_k_key_height := 30,        ! Key dimensions.
        sample_k_key_width := 60,
        sample_k_button_border_frac := 3, ! Determines spacing between keys.

        sample_k_overall_height := (sample_k_key_height * 5)
                                    + ((sample_k_key_height
                                        / sample_k_button_border_frac) * 5)
                                    + sample_k_keypad_border,

        sample_k_overall_width := (sample_k_key_width * 4)
                                   + ((sample_k_key_width
                                       / sample_k_button_border_frac) * 4)
                                   + sample_k_keypad_border,

        sample_k_keymap := '',      ! If this constant has a null string
                                    ! as its value, the program uses the
                                    ! current key map list to determine what
                                    ! code to execute when the user
                                    ! clicks on a given push button.

        sample_k_pad_title := "Sample mouse pad",   ! Title of the mouse pad.
        sample_k_closure := '';                     ! Not currently used.

    PROCEDURE sample_sample_module_ident                ! This procedure returns
    RETURN "V01-001";                                   ! the Ident.
    ENDPROCEDURE;

    PROCEDURE sample_sample_module_init          ! Module initialization.
    ENDPROCEDURE;

    PROCEDURE eve_mouse_pad         ! Implements a user-created command MOUSE PAD
        ! that the user can invoke from within EVE.
    ON_ERROR
        [TPU$_CONTROLC]:
            eve$learn_abort;
            ABORT;
    ENDON_ERROR

    ! Checks whether the dialog box widget class has already been defined.
    ! If not, defines the dialog box widget class and creates a widget
    ! instance to be used as the "container" for the mouse pad.

    IF GET_INFO (sample_x_dialog_class, 'type') <> INTEGER
    THEN
        sample_x_dialog_class
    (1)        : = DEFINE_WIDGET_CLASS (sample_k_dialogwidgetclass,
         "XmCreateBulletinBoardDialog");
        ! Tell TPU about new resource types

        set (WIDGET_RESOURCE_TYPES, "unsigned_char", "dialogStyle", "unitType");
    ENDIF;

    ! Create the dialog box

    (2)sample_x_keypad := CREATE_WIDGET (sample_x_dialog_class, "Keypad", SCREEN,
                                      "MESSAGE('CALLBACK activated')",
                                      "sample_k_closure",
          sample_k_cstyle, sample_k_modeless,
                                      sample_k_nunits, sample_k_pixelunits,
                                      sample_k_ntitle, sample_k_pad_title,
                                      sample_k_nautounmanage, FALSE,
                                      sample_k_nheight, sample_k_overall_height,
                                      sample_k_nwidth, sample_k_overall_width,
                                      sample_k_nx, sample_k_x_pos,
                                      sample_k_ny, sample_k_y_pos);

    ! Checks whether the push button widget class has already been defined
    ! and, if not, defines the class.

    IF GET_INFO (sample_x_pushbutton_class, 'type') <> INTEGER
    THEN
        sample_x_pushbutton_class
            := DEFINE_WIDGET_CLASS (sample_k_pushbuttonwidgetclass,
                                    "XmCreatePushButton");
    ENDIF;

    ! Initializes the array that the program passes repeatedly
    ! to the procedure "sample_key_def".

    sample_x_attributes := CREATE_ARRAY;
    sample_x_attributes {sample_k_nactivate_callback} := 0; ! must be 0 (non-UIL)
    sample_x_attributes {sample_k_nborderwidth} := 2;
    sample_x_pad_program := COMPILE ("sample_key_dispatch");

    ! Creates and manages all the "keys" in the mouse pad.  The procedure
    ! "sample_key_def" returns a variable of type widget, so you can use the
    ! returned value as an argument to the built-in MANAGE_WIDGET.

    (3)MANAGE_WIDGET (sample_key_def ("PF1", 0, 0, 1, 1, sample_x_pad_program),
                   sample_key_def ("PF2", 1, 0, 1, 1, sample_x_pad_program),
                   sample_key_def ("PF3", 2, 0, 1, 1, sample_x_pad_program),
                   sample_key_def ("PF4", 3, 0, 1, 1, sample_x_pad_program),
                   sample_key_def ("KP7", 0, 1, 1, 1, sample_x_pad_program),
                   sample_key_def ("KP8", 1, 1, 1, 1, sample_x_pad_program),
                   sample_key_def ("KP9", 2, 1, 1, 1, sample_x_pad_program),
                   sample_key_def ("-",   3, 1, 1, 1, sample_x_pad_program, "minus"),
                   sample_key_def ("KP4", 0, 2, 1, 1, sample_x_pad_program),
                   sample_key_def ("KP5", 1, 2, 1, 1, sample_x_pad_program),
                   sample_key_def ("KP6", 2, 2, 1, 1, sample_x_pad_program),
                   sample_key_def (",",   3, 2, 1, 1, sample_x_pad_program, "comma"),
                   sample_key_def ("KP1", 0, 3, 1, 1, sample_x_pad_program),
                   sample_key_def ("KP2", 1, 3, 1, 1, sample_x_pad_program),
                   sample_key_def ("KP3", 2, 3, 1, 1, sample_x_pad_program),
                   sample_key_def ("Enter", 3, 3, 2, 1, sample_x_pad_program, "enter"),
                   sample_key_def ("KP0", 0, 4, 1, 2, sample_x_pad_program),
                   sample_key_def (".", 2, 4, 1, 1, sample_x_pad_program, "period"));

    sample_shift_was_last := FALSE;     ! The program starts out assuming that
                                          ! no GOLD key has been pressed.

    (4)MANAGE_WIDGET (sample_x_keypad);      ! This statement displays the
                                          ! resulting mouse pad.

    RETURN (TRUE);
    ENDPROCEDURE ! End of procedure eve_mouse_pad.

    PROCEDURE sample_key_def                ! Creates a mouse pad "key" push button
                                            ! widget.

        (the_legend,             ! What characters to show on the push button label.

         the_row, the_col,       ! Location of the key in relation to the parent
                                 ! widget's upper left corner.

         the_width, the_height,  ! Dimensions of the key.

         the_pgm;                ! Program to use as the callback routine; used
                                 ! as a parameter to the CREATE_WIDGET built-in.

         the_string);            ! The string representation of the name
                                 ! of a key if the key name is not going
                                 ! to be the same as the legend (as in
                                 ! the case of the comma).  Specify the null
                                 ! string if the key name and the legend are
                                 ! the same.

    IF GET_INFO (the_string, 'type') = UNSPECIFIED
    THEN
        the_string := the_legend;     ! Determines whether the optional parameter
                                      ! the_string is provided.
    ENDIF;

    RETURN CREATE_WIDGET (sample_x_pushbutton_class,
            "Key",     ! name
            sample_x_keypad,    ! parent
                          the_pgm,     ! program
                          (sample_k_keymap + ' ' + the_string), ! closure
                           sample_x_attributes,   ! attributes...
                           sample_kt_nrecomputesize, 1,
                           sample_k_nlabel, the_legend,
                          sample_k_nheight, sample_key_height (the_width),
                          sample_k_nwidth, sample_key_width (the_height),
                          sample_k_nx, sample_col_to_pix (the_row),
                          sample_k_ny, sample_row_to_pix (the_col));

    ENDPROCEDURE ! End of the procedure "sample_key_def".

    PROCEDURE sample_key_dispatch  ! Handles push button widget callbacks.

    LOCAL   status,                ! Variable to contain the return value from
                                   ! GET_INFO (WIDGET, "callback_parameters",).

            blank_index,           ! Position of the blank space in the tag string.

            temp_array,            ! Holds callback parameters.

            a_shift_key,           ! The SHIFT key in the current key map list.

            the_key,               ! A string naming a key.

            gold_key;              ! Name of the GOLD key.

    ON_ERROR
        [TPU$_CONTROLC]:
            eve$learn_abort;
            ABORT;
    ENDON_ERROR

    (5)status := GET_INFO (widget, "callback_parameters", temp_array);
    $widget := temp_array {'widget'};
    $widget_tag := temp_array {'closure'};
    $widget_reason := temp_array {'reason_code'};

    (6)the_key := EXECUTE ("RETURN(KEY_NAME (" + $widget_tag + "))");
    gold_key := GET_INFO (eve$current_key_map_list, "shift_key");
    IF the_key = gold_key
    THEN
        sample_shift_was_last := TRUE;      ! User pressed Gold Key
    ELSE
        IF sample_shift_was_last
        THEN
            the_key := KEY_NAME (the_key, SHIFT_KEY);
        ENDIF;
        CASE $widget_reason
            [sample_k_cractivate]:
                EXECUTE (the_key);
            [OTHERWISE]:
                eve_show_key (the_key)
        ENDCASE;
        sample_shift_was_last := FALSE;
    ENDIF;
    RETURN;
    ENDPROCEDURE ! End of the procedure "sample_key_dispatch".

    ! These procedures implement position and
    ! size calculations for the push button widgets.

    PROCEDURE sample_row_to_pix (row)        ! Converts a row number to the
                                             ! pixel-based measuring system.
    RETURN sample_k_keypad_border +
        (row * (sample_k_key_height + (sample_k_key_height
                                        / sample_k_button_border_frac)));
    ENDPROCEDURE ! End of the procedure "sample_row_to_pix".

    PROCEDURE sample_col_to_pix (col)       ! Converts a column number to the
                                            ! pixel-based measuring system.
    RETURN sample_k_keypad_border +
        col * (sample_k_key_width + ( 2* sample_k_button_border_frac) );

    ENDPROCEDURE ! End of the procedure "sample_col_to_pix".

    PROCEDURE sample_key_height (given_height) ! Converts the y dimension
                                               ! from rows to pixels.
    IF given_height = 1
    THEN
        RETURN sample_k_key_height;
    ELSE
        RETURN ((sample_k_key_height * given_height)
                + (sample_k_key_height / sample_k_button_border_frac)
                * (given_height - 1));
    ENDIF;
    ENDPROCEDURE ! End of the procedure "sample_key_height".

    PROCEDURE sample_key_width (given_width)    ! Converts the x dimension
                                                ! from rows to pixels.
    IF given_width = 1
    THEN
        RETURN sample_k_key_width;
    ELSE
        RETURN ((sample_k_key_width * given_width)
                + (sample_k_key_width / sample_k_button_border_frac)
                * (given_width - 1));
    ENDIF;
    ENDPROCEDURE ! End of the procedure "sample_key_width".

1. When you create widgets directly in DECTPU (that is, without using the Resource Manager to manipulate widgets defined in a UID file), you must define each class of widget. For example, a widget can belong to a push button, dialog box, menu, or another similar class of widget. The DEFINE_WIDGET_CLASS built-in procedure tells DECTPU the widget class name and creation entry point for the class of widget. DEFINE_WIDGET_CLASS also returns an ID for that widget class. Define a widget class for each widget only once in a DECTPU session.
2. With CREATE_WIDGET, you can create an instance of a widget for which you have a widget class ID. An instance is one occurrence of a widget of a given class. For example, EVE has many menu widgets, each of which is an instance of a menu widget.
   This example creates a dialog box widget to contain the mouse pad.
3. Each of the keys of the mouse pad is managed. However, they do not become visible until their parent, the dialog box widget in variable SAMPLE_X_KEYPAD, is managed.
4. Managing a widget whose parent is visible causes that widget and all its managed children to become visible.
5. GET_INFO (WIDGET, "callback_parameters", array) returns the callback information in the array parameter. For more information about using this built-in, see the built-in's description in Section 2.1.
6. When each key widget of the mouse pad is created, the closure value for the widget is set to the string that corresponds to the name of the key that the widget represents. This statement uses the EXECUTE built-in to translate the string into a key name.

## A.2 Implementing an EDT-Style APPEND Command

Example A-2 shows one of the ways an application can use the GET_CLIPBOARD built-in. This procedure is based on the EVE procedure EVE$EDT_APPEND. The original version is in SYS$EXAMPLES:EVE$EDT.TPU.

The procedure EVE$EDT_APPEND appends the currently selected text to the contents of the clipboard if you have activated the clipboard; otherwise, the procedure appends the current selection to the contents of the Insert Here buffer.

This example uses the following global variables and procedures from EVE:

- EVE$MESSAGE---A procedure that translates the specified message code into text and displays the text in the message buffer.
- EVE$$RESTORE_POSITION---A procedure that repositions the editing point to the location indicated by the specified window and marker.
- EVE$LEARN_ABORT---A procedure that aborts a learn sequence.
- EVE$SELECTION---A procedure that returns a range containing the current selection. This can be the select range, the found range, or the text of the global selection.
- EVE$$TEST_IF_MODIFIABLE---A procedure that checks whether a buffer can be modified.
- EVE$X_DECWINDOWS_ACTIVE---A Boolean global variable that is true if DECTPU is using the DECwindows screen updater. If DECTPU is not using DECwindows, the DECwindows features are not available.
- EVE$$X_STATE_ARRAY---A global variable of type array describing various EVE flags and data. This variable is private to EVE and should not be used by user routines.
- EVE$$EDT_APPEND_PASTE---Procedure that appends text to the INSERT HERE buffer.

Example A-2 EVE Procedure That Implements a Variant of the EDT APPEND Command

    PROCEDURE eve$edt_append        ! Implements EVE's version of
                                    ! the EDT APPEND command.

    LOCAL   saved_mark,             ! Marks the editing point at the
                                    ! beginning of the procedure.

            remove_range,           ! Stores the currently selected text.

            old_string,             ! Stores the text that was in the clipboard.

            new_string,             ! Stores the old contents of the clipboard
                                    ! plus the currently selected text.

            remove_status;          ! Indicates whether the selected text
                                    ! should be removed.

    ON_ERROR
        [TPU$_CLIPBOARDNODATA]:
            eve$message (EVE$_NOINSUSESEL);
            eve$$restore_position (saved_mark);
            eve$learn_abort;
            RETURN (FALSE);
        [TPU$_CLIPBOARDLOCKED]:
            eve$message (EVE$_CLIPBDREADLOCK);
            eve$$restore_position (saved_mark);
            eve$learn_abort;
            RETURN (FALSE);

        [TPU$_CONTROLC]:
            eve$$restore_position (saved_mark);
            eve$learn_abort;
            ABORT;
        [OTHERWISE]:        eve$$restore_position (saved_mark);
            eve$learn_abort;
    ENDON_ERROR;

    remove_range := eve$selection (TRUE,,, eve$x_select_remove_flag);
    IF remove_range <> 0
    THEN
        saved_mark := MARK (NONE);
        remove_status := eve$test_if_modifiable (GET_INFO (saved_mark, "buffer"));
        IF eve$x_decwindows_active
        THEN
            IF eve$$x_state_array {eve$$k_clipboard}
            THEN

    (1)            old_string := GET_CLIPBOARD;
                new_string := old_string + str (remove_range);
    (2)            WRITE_CLIPBOARD ("", new_string);

                IF remove_status
                THEN
                    ERASE (remove_range);
                    eve$message (EVE$_REMCLIPBOARD);
                ENDIF;
            ELSE
                eve$$edt_append_paste (remove_range, remove_status);
            ENDIF;
        ELSE
            eve$$edt_append_paste (remove_range, remove_status);
        ENDIF;

        POSITION (saved_mark);
        remove_range := 0;
        RETURN (TRUE);
    ENDIF;

    eve$learn_abort;
    RETURN (FALSE);

    ENDPROCEDURE;

1. The GET_CLIPBOARD built-in procedure returns a copy of the text stored in the clipboard. Only data of type string can be retrieved from the clipboard. Any other data type causes DECTPU to signal an error.
2. The WRITE_CLIPBOARD built-in procedure stores data in the clipboard. The first parameter lets you specify the label for this data. However, the clipboard currently supports only one entry at a time, so you can use any string for the first parameter.

## A.3 Testing and Returning a Select Range

The code fragment in Example A-3 shows how a layered application can use GET_GLOBAL_SELECT. This code fragment is based on the EVE procedure EVE$SELECTION. The original version is in SYS$EXAMPLES:EVE$CORE.TPU.

The procedure EVE$SELECTION returns a select range, found range, or global selection for use with EVE commands that operate on the select range.

This example uses the following global variables and procedures from EVE:

- EVE$MESSAGE---A procedure that translates the specified message code into text and displays the text in the message buffer.
- EVE$LEARN_ABORT---A procedure that aborts a learn sequence.
- EVE$X_DECWINDOWS_ACTIVE---A Boolean global variable that is true if DECTPU is using DECwindows. If DECTPU is not using DECwindows, the DECwindows features are not available.

Example A-3 EVE Procedure That Returns a Select Range

    PROCEDURE eve$selection (
                             do_messages;           ! Display error messages?
                             found_range_arg,       ! Use found range? (D=TRUE).
                             global_arg,            ! Use global select? (D=FALSE).
                             null_range_arg,        ! Extend null ranges? (D=TRUE).
                             cancel_arg)            ! Cancel selection? (D=TRUE).

    ! Return Values:        range           The selected range.
    !                       0               There was no select range.
    !                       NONE            There was a null range and
    !                                        null_range_arg is FALSE.
    !                       string          Text of the global selection
    !                                        if "global_arg" is TRUE.

    LOCAL   possible_selection,
            use_found_range,
            use_global,
            extend_null_range,
            cancel_range;

    ON_ERROR
        [TPU$_SELRANGEZERO]:
        [TPU$_GBLSELOWNER]:
            eve$message (EVE$_NOSELECT);
            eve$learn_abort;
            RETURN (FALSE);
        [OTHERWISE]:
    ENDON_ERROR;

                                    ! The procedure first tests whether it
                                    ! has received a parameter directing
                                    ! it to return a found range or global
                                    ! selection if no select range has been
                                    ! created by the user.

    IF GET_INFO (found_range_arg, "type") = INTEGER
    THEN
        use_found_range := found_range_arg;
    ELSE
        use_found_range := TRUE;
    ENDIF;

    IF GET_INFO (global_arg, "type") = INTEGER
    THEN
        use_global := global_arg;
    ELSE
        use_global := FALSE;
    ENDIF;

    !  .
    !  .
    !  .

                                          ! In the code omitted from this example,
                                          ! eve$selection returns the appropriate
                                          ! range if the calling procedure has
                                          ! requested the user's select range
                                          ! or a found range.

    !  .
    !  .
    !  .

                                          ! If there is no found range or select
                                          ! range, the procedure returns
                                          ! the primary global selection
                                          ! if it exists.

    IF use_global and eve$x_decwindows_active
    THEN
    (1)    possible_selection := GET_GLOBAL_SELECT (PRIMARY,
                                                 "STRING");

        IF GET_INFO (possible_selection, "type") = STRING
        THEN
            RETURN (possible_selection);
        ENDIF;
    ENDIF;
      .
      .
      .
    RETURN (0);                    ! Indicates failure.

    ENDPROCEDURE;

Previous | Next | Contents | Index

| privacy and legal statement |
6020PRO_039.HTML