home *** CD-ROM | disk | FTP | other *** search
Text File | 1988-08-10 | 58.8 KB | 1,369 lines |
- DV-GLUE v1.00
- -------------
- (c) Copyright 1988 Ralf Brown
- All Rights Reserved.
- [See file -COPYRIT.NOT for full copying permissions/restrictions. It
- basically says that you can use these functions as long as you don't try to
- make money or claim that you wrote them.]
-
- DV-GLUE is a collection of some 230 functions which give your programs access
- to the power of the DESQview[*] and TopView[**] environments. You may use
- them freely provided you do not try to make money off of the programs you
- write using them. Donations are neither required nor expected (unless you're
- trying to make money, see -COPYRIT.NOT), but wouldn't be turned down.
-
- DV-GLUE implements all but five of the functions described in Quarterdeck's
- DV API library flyer, and several dozen additional functions.
-
-
-
-
-
-
-
-
-
- ---
- [*] DESQview (tm) is a trademark of Quarterdeck Office Systems
- [**] TopView (tm) is a trademark of International Business Machines, Inc.
-
- -----------------------------------------------------------------------------
- To use this library in your own programs, add the line
- #include "tvapi.h"
- to the start of each source file using functions from the library. If you
- are using constants for building your own streams, also add the line
- #include "tvstream.h"
- to the start of the module. If you are using any of the UI... functions,
- add the line
- #include "tvui.h"
- Then add TVAPI.LIB to the list of files to compile (if you are using TCC), or
- add TVAPI.LIB to the .PRJ file.
-
- If you have been using version 0.7, see -HIST for details of the massive
- function renamings which have taken place. If you have been using version
- 0.91, there are a few more renamed functions, as well as several functions
- with changed parameters.
- -----------------------------------------------------------------------------
- A number of the functions at the core of this package were originally written
- by John Navas and have since been modified pretty much beyond recognition. The
- original versions of these can be found in the file TVGLUETC.ARC on the Dog
- Lab BBS (415) 594-9806.
-
-
-
-
-
- Ralf Brown
- August 10, 1988
-
- Direct e-mail to:
- ralf@cs.cmu.edu (Arpanet) \
- ralf%cs.cmu.edu@cmuccvma (BITnet) > preferred
- ...!{harvard,ucbvax}!cs.cmu.edu!ralf (UUCP) /
- Ralf Brown 1:129/31 (FIDOnet)
- [No Compu$pend/$ource/GEnie accounts....]
- or post a message to the DESQVIEW or DR_DEBUG echomail areas on FIDOnet
- -----------------------------------------------------------------------------
-
- Setup
- -----
-
- Before you can call any of the functions in this library, you must first
- initialize the library by calling either TVinit() or DVinit(). TVinit()
- will allow you to use the functions which work under both TopView and
- DESQview, while DVinit() will also allow you to use those functions which are
- unique to DESQview.
-
- At the end of the program, before exiting, you must call either TVexit() or
- DVexit(). If you called TVinit() at the beginning, call TVexit() at the end.
- If you called DVinit(), then call DVexit().
-
- int TVinit(void)
- initialize TopView interface and return TopView version as a hex
- number: 0x010A == version 1.10
- void TVexit(void)
- clean up TopView interface before terminating program. This also
- frees a number of mailboxes used as semaphores to prevent
- reentrancy problems. If you don't call it, your "common" memory
- will slowly dwindle with each run of the program until the window
- is closed.
- int DVinit(void)
- initialize DESQview interface and return DESQview version as a hex
- number: 0x0201 == version 2.01
- void DVexit(void)
- clean up DESQview interface before terminating program. Call this
- function if you started your program with DVinit().
-
- Pre-Processor #defines
- ----------------------
-
- The following two predefined symbols are useful to determine whether the
- correct version of DV-GLUE is being used.
-
- DVGLUE_version is the version number times 100
- DVGLUE_versionSTR is a string in the form "n.nn"
-
- Low-Level Primitives
- --------------------
-
- Most of the functions described in later sections call on one or more of the
- functions in this section.
-
- void TVwin_stream(OBJECT window,BYTE *stream)
- send the specified stream to the window. The only restriction on the
- stream is that it may not contain window-stream opcode E6h (create
- new window).
-
- OBJECT TVwin_new(OBJECT window,int rows,int cols)
- create a new window of the specified dimensions which becomes a child
- of the given window, and return its handle.
-
- void TVsendmsg(int message,int modifier,OBJECT object,PARMLIST *params)
- send a message with the parameters specified in "params", returning
- any result values in "params". The PARMLIST type is a struc with
- two fields:
- int num_args ; /* number of parameters sent/returned */
- DWORD arg[9] ; /* up to nine args may be sent or returned */
-
- void TVsendmsg0(int message,int modifier,OBJECT object)
- send a parameterless, non-value-returning message to the specified
- object.
-
- DWORD TVsendmsg1(int message,int modifier,OBJECT object)
- send a parameterless message which returns a single value to the
- specified object.
-
- Windows
- -------
-
- One of the strongest features of the DESQview API is its windowing
- capabilities. DV-GLUE gives you the capability to create, move, resize,
- color, title, and close windows, among other things.
-
- Each window has a logical cursor which need not be in the same place as the
- hardware cursor--after all, the hardware cursor could be in some other
- program's window. There are calls to manipulate the logical cursor and move
- the hardware cursor to the position corresponding to the logical cursor.
-
- OBJECT TVwin_new(OBJECT window,int rows,int cols)
- create a new window which is a child of the given window and is
- "rows" high and "cols" wide. Returns the handle of the new window.
-
- void TVwin_free(OBJECT window)
- close the specified window.
-
- void TVwin_attach(OBJECT window)
- attach the specified window to its parent window, such that when one
- window is moved, the other also moves.
-
- void TVwin_detach(OBJECT window)
- detach the specified window from its parent window, such that each
- window moves independently of the other.
-
- void TVwin_clear(OBJECT window)
- Erase the entire window. Does not affect the logical cursor's
- position.
-
- void TVwin_fill(OBJECT window,char c)
- Fill the entire window with the specified character.
-
- void TVwin_attr(OBJECT window,int attr)
- Set the default output attribute for the given window.
-
- void TVwin_cursor(OBJECT window,int row,int col)
- Move the window's logical cursor to the specified position.
-
- void TVwin_hcur(OBJECT window)
- Move the hardware cursor to where the window's logical cursor is.
-
- void TVwin_repchar(OBJECT window,char c,int count)
- Write the character "c" to the given window "count" times.
-
- void TVwin_repattr(OBJECT window,int attr,int count)
- Change the attribute of the next "count" characters of the given
- window to "attr."
-
- void TVwin_blanks(OBJECT window,int count)
- Write the specified number of blanks to the given window.
-
- void TVwin_lsize(OBJECT window,int rows,int cols)
- Change the logical size (not the displayed size) of the given window
- to be "rows" high by "cols" wide.
-
- void TVwin_origin(OBJECT window,int row,int col)
- Move the upper left corner of the visible portion of the window to
- be at (row,col).
-
- void TVwin_resize(OBJECT window,int rows,int cols)
- Change the size of the given window on the screen to be "rows" high by
- "cols" wide. You need to call TVwin_redraw() to ensure that the
- window's size is updated on the screen.
-
- void TVwin_move(OBJECT window,int row,int col)
- Move the given window such that its upper left corner is at
- (row,col). You need to call TVwin_redraw() to ensure that the
- window's position is updated on the screen.
-
- void TVposwin(OBJECT window,OBJECT parent,int pos,int row_offset,int col_offset)
- Move the given window to a position relative to the parent window.
- The values for "pos" specify both the horizontal and vertical
- position: one of
- PW_HCURR current horizontal position
- PW_HCENTER centered horizontally in parent window
- PW_LEFT at left edge of parent
- PW_RIGHT at right edge of parent
- ORed with one of
- PW_VCURR current vertical position
- PW_VCENTER centered vertically in parent window
- PW_TOP at top edge of parent
- PW_BOTTOM at bottom edge of parent
- optionally ORed with
- PW_NOREDRAW don't refresh the screen
- "row_offset" and "col_offset" are then added to the position selected
- by "pos". These values are signed, so negative values move the window
- up and left.
-
- For this function, NIL specifies the current task's main window if
- given for "window", but specifies the full screen if given for
- "parent".
-
- void TVwin_minsize(OBJECT window,int rows,int columns)
- Keep the user from reducing the window's size below the specified size
-
- void TVwin_maxsize(OBJECT window,int rows,int columns)
- Keep the user from increasing the window's size beyond the specified
- size.
-
- void TVwin_title(OBJECT window,char *title)
- Set the window's title to the given string.
-
- void TVwin_bottom(OBJECT window)
- move the window behind all other windows belonging to the current
- task.
-
- void TVwin_top(OBJECT window)
- move the window in front of all other windows belonging to the current
- task.
-
- void TVwin_topsys(OBJECT window)
- move the window in front of all other windows in the system.
-
- void TVwin_reorder(OBJECT win,unsigned first,unsigned second,...)
- Put the specified window in front, with "first", "second", etc.
- being put behind it. "first", "second", etc. are the OBJSEG of
- the object handle for the respective windows.
-
- void TVwin_redraw(OBJECT window)
- Update the physical screen to accurately reflect the window.
-
- void TVredrawwin(OBJECT window)
- Same as TVwin_redraw(), but uses different method to tell DESQview to
- update the screen image of the window. This method does not make the
- given window active.
-
- void TVwin_scroll(OBJECT window,int top,int left,int height,int width,int dir)
- Scroll the specified region of the window's virtual screen in the
- given direction. The valid directions are
- SCRL_LEFT
- SCRL_RIGHT
- SCRL_UP
- SCRL_DOWN
-
- int TVwin_printf(OBJECT window,char *format, ...)
- Just like printf(), but writes to the specified window. Note that
- \n is not converted to \r\n, so you will have to use \r\n if you
- want the remaining text to continue at the beginning of the next
- line.
-
- void TVwin_swrite(OBJECT window,char *string)
- Write the string to the given window. Note that \n is not converted
- to \r\n.
-
- void TVwin_write(OBJECT window,char *string,int len)
- Write the first "len" characters of the string to the given window.
-
- void TVwin_writeca(OBJECT window,char *chars,char *attr,int len)
- Write the first "len" characters and attributes to the given window
- starting at the current position of the logical cursor.
-
- void TVwin_writea(OBJECT window,char *attr,int len)
- Change the attributes of the first "len" characters from the current
- cursor position to be those specified by "attr".
-
- void TVwin_repattr(OBJECT window,int attr,int count)
- change the attributes of the next "count" characters on the virtual
- screen to "attr"
-
- void TVwin_repchar(OBJECT window,int character,int count)
- write "count" copies of the character to the virtual screen for the
- given window.
-
- int TVwin_read(OBJECT window,void *buffer,int maxsize)
- Read the remainder of the current line in the given window, and copy
- up to "maxsize" characters into the buffer.
-
- int TVwin_nread(OBJECT window,void *buffer,int n)
- Read the next "n" characters or attributes from the given window and
- place them in the buffer.
-
- void TVwin_gotoxy(OBJECT window,int x,int y)
- Position windows cursor at row y and column x.
-
- void TVwin_cursor(OBJECT window,int row,int col)
- Position window's logical cursor at the given row and column.
-
- void TVwin_color(OBJECT window,int logical_attr,int physical_attr)
- Select the physical attribute for the given logical attribute.
-
- void TVwin_frattr(OBJECT window,int attr)
- set the attribute of the given window's frame.
-
- --------------------------
- There are a number of switches available:
-
- void TVwin_atread(OBJECT window,int read_attr)
- If "read_attr" is nonzero, TVwin_nread() gets attributes, if
- "read_attr" is zero, TVwin_nread() gets characters.
-
- void TVwin_ctrl(OBJECT window,int ctrl)
- If "ctrl" is nonzero, output to the given window will interpret
- CR, LF, BS, etc. If "ctrl" is zero, those characters will be
- displayed.
-
- void TVwin_logattr(OBJECT window,int logattr)
- If "logattr" is nonzero, DESQview will translate the attributes used
- for the window, i.e. the attributes become logical. If "logattr" is
- zero, then the attributes written to a window are those displayed on
- the screen, i.e. physical attributes.
-
- void TVwin_leave(OBJECT window,int leave)
- If "leave" is nonzero, then writing to a window will not change the
- attributes in the positions which are overwritten. If "leave" is
- zero, then characters output to the window will be given the currently
- active default attribute.
-
- void TVwin_frame(OBJECT window,int frame)
- If "frame" is nonzero, then the window's frame will be displayed.
- If "frame" is zero, the window will not have a frame.
-
- void TVwin_hide(OBJECT window)
- make the given window invisible
-
- void TVwin_unhide(OBJECT window)
- make the given window visible
-
-
- Query Functions
- ---------------
-
- In addition to setting window characteristics, you can find out the status of
- most anything that you can set.
-
- int TVqry_attr(OBJECT window)
- Returns the current default character attribute for the window.
-
- void TVqry_cursor(OBJECT window,int *row,int *column)
- Returns the position of the window's logical cursor in "row" and
- "column".
-
- void TVqry_position(OBJECT window,int *row,int *column)
- Returns the position of the given window in "row" and "column"
-
- void TVqry_origin(OBJECT window,int *row,int *column)
- Returns the origin of the visible portion of the window in "row" and
- "column".
-
- void TVqry_lsize(OBJECT window,int *rows,int *columns)
- Returns the logical size of the window in "rows" and "columns"
-
- void TVqry_size(OBJECT window,int *rows,int *columns)
- Returns the displayed size of the window in "rows" and "columns"
-
- void TVqry_title(OBJECT window,char *title,int size)
- Returns the first "size" characters of the window's title in "title"
-
- int TVqry_color(OBJECT win,int logical_attr)
- Returns the physical attribute which the given logical attribute is
- mapped to.
-
- int TVqry_frattr(OBJECT window)
- Returns the attribute of the window's frame.
-
- int TVwin_width(OBJECT window)
- Return the width of the virtual screen for the given window.
-
- The switches which may be set can also be read:
-
- int TVqry_atread(OBJECT window)
- returns TRUE if TVwin_nread() gets attributes, FALSE if it gets
- characters.
-
- int TVqry_ctrl(OBJECT window)
- returns TRUE if control characters are interpreted, FALSE if not
-
- int TVqry_logattr(OBJECT window)
- returns TRUE if logical attributes are being used, FALSE if physical
- attributes are used.
-
- int TVqry_leave(OBJECT window)
- returns TRUE if writing to the window will leave the character
- attributes unchanged, and FALSE if the attributes are changed to the
- current default attribute.
-
- int TVqry_frame(OBJECT window)
- returns TRUE if the window has a frame, FALSE otherwise.
-
- int TVqry_hidden(OBJECT window)
- returns TRUE if the window is hidden, FALSE if it is visible.
-
- Keyboard Objects
- ----------------
-
- Keyboard objects let you direct keyboard input to a specified window, to send
- data that another process thinks came from the keyboard, and other things.
-
- OBJECT TVkbd_new(void)
- create a new keyboard object and return its handle.
-
- void TVkbd_free(OBJECT kbd)
- destroy keyboard object. Do not attempt to free the default keyboard!
-
- void TVkbd_open(OBJECT kbd, OBJECT window)
- connect "kbd" to the indicated window
-
- void TVkbd_close(OBJECT kbd)
- disconnect the keyboard from its window
-
- int TVkbd_messages(OBJECT kbd)
- determine how many messages are pending for the keyboard
-
- void TVkbd_clear(OBJECT kbd)
- remove all pending messages from the keyboard
-
- OBJECT TVmykbd(void)
- return the handle of the current task's default keyboard. For the
- functions described in this section, the special handle NIL represents
- the default keyboard.
-
- OBJECT TVkbdof(OBJECT task)
- return the handle for the given task's default keyboard.
-
- int TVkbd_read(OBJECT kbd,char *buffer,int maxsize)
- wait for a keyboard message on "kbd", and then fill "buffer" with up
- to (maxsize-1) characters from the message. Returns the actual size
- of the message read.
-
- If the keyboard is in field mode, then the user can edit the input
- fields at will, and the return contains the contents of all input
- fields in the following format:
-
- BYTE field number
- WORD length of field data
- N BYTES contents of field
-
- This repeats until the field number is zero, which signals the end of
- the data.
-
- int TVkbd_status(OBJECT kbd)
- return status of last message read from "kbd". If the keyboard is in
- field mode, the status will indicate how the entry was terminated.
- 1 = pressed RETURN
- 27 = pressed ESC
-
- void TVkbd_write(OBJECT kbd,char *data,int size,int status)
- write a message of the given size to "kbd", using the given status,
- which may then be checked by the reader with TVkbd_status().
-
- void TVkbd_setflags(OBJECT kbd,int flags)
- set the keyboard behavior flags for "kbd" that correspond to the set
- bits of "flags"
-
- Valid flags (OR together):
- KBD_FIELDMODE put keyboard into field mode
- KBD_ACTIVE keyboard is active in "kbd"s window
- KBD_INSERT keyboard is in "insert" mode
- KBD_CONCURRENT program continues running during input
- KBD_FILTERALL filter all keystrokes through TVkbd_setesc
- handler
-
- void TVkbd_clrflags(OBJECT kbd,int flags)
- clear the keyboard behavior flags for "kbd" that correspond to the set
- bits of "flags". The valid flags are the same as for TVkbd_setflags.
-
- void TVkbd_setesc(OBJECT kbd,void far (*func)(void))
- set a keyboard filtering function. Not yet tested.
-
- Timers
- ------
-
- The timer management functions allow you to create, destroy, set, and read
- timer objects which can provide for delays.
-
- OBJECT TVtimer_new(void)
- create a new timer object and return its handle
-
- OBJECT TVtimer_free(void)
- destroy a timer object and return its memory to the common pool
-
- void TVtimer_begin(OBJECT timer,DWORD length)
- start a timer counting down from "length". The timer will run for
- 10 * length milliseconds (though the timer's resolution is actually
- only 55 milliseconds).
-
- void TVtimer_set(OBJECT timer,int hour,int minute,int second,int hundredths)
- Start a timer counting down such that it finishes at the indicated
- time.
-
- DWORD TVtimer_len(OBJECT timer)
- return the amount of time left on the timer.
-
- DWORD TVtimer_elapsed(OBJECT timer)
- return the amount of time elapsed since the timer was started.
-
- void TVtimer_start(OBJECT timer)
- start the timer counting down
-
- void TVtimer_stop(OBJECT timer)
- stop the timer from counting down
-
- void TVtimer_close(OBJECT timer)
- close the timer object. Also stops the countdown.
-
- DWORD TVtimer_wait(OBJECT timer)
- wait until the timer completes its countdown, and return the time in
- 1/100ths seconds since midnight at the time the counter finished.
-
- int TVtimer_status(OBJECT timer)
- find out whether the timer is running or not.
-
- Pointers
- --------
-
- OBJECT TVptr_new(void)
- creates a new pointer object and returns its handle
-
- void TVptr_free(OBJECT pointer)
- destroy the given pointer object
-
- void TVptr_open(OBJECT pointer, OBJECT window)
- connect the mouse pointer to the given window, where NIL means the
- current task's default window
-
- void TVptr_close(OBJECT pointer)
- disconnect the mouse pointer from its window
-
- void TVptr_icon(OBJECT pointer,char symbol)
- set the character used to represent the mouse pointer.
-
- void TVptr_goto(OBJECT ptr,int row,int col)
- move the mouse pointer to the given position relative to the window's
- upper left corner
-
- void TVptr_setflags(OBJECT pointer,WORD flags)
- set pointer behavior flags. The valid flags (OR together) are:
- PTR_BUTTON only report on button activity (requires a
- previous call to DVenable())
- PTR_RELEASE report on button release as well as press
- PTR_ABSOLUTE pointer coordinate relative to phys screen
- PTR_SLOWCLICK button held 1/2 sec before it "click"s. Used
- to allow chords to be pressed.
- PTR_NOTFORE report even is window is not in foreground
- PTR_NOTTOP report even if window in not topmost
- PTR_HIDDEN mouse pointer is invisible inside window
-
- void TVptr_clrflags(OBJECT pointer,WORD flags)
- clear pointer behavior flags. What the flags are is not yet known.
-
- void TVptr_erase(OBJECT pointer)
- discard all unread pointer messages
-
- int TVptr_messages(OBJECT pointer)
- return the number of unread pointer messages
-
- int TVptr_read(OBJECT window,POINTER_MSG *msg)
- wait for the next pointer message, and put it in "msg"
- Returns 0 on success, -1 on error.
-
- The format of the POINTER_MSG is:
- int row ;
- int column ;
- BYTE button_state
- Valid bits in button_state are:
- BUTTON_PRESS \ only available if pointer flag PTR_RELEASE
- BUTTON_RELEASE / is set
- BUTTON_LEFT
- BUTTON_RIGHT
-
- int TVptr_status(OBJECT pointer)
- return the pointer's status. This value is the same as the
- button_state field of POINTER_MSG (see above).
-
- void TVptr_goto(OBJECT ptr,int row,int col)
- move the mouse pointer to the given position relative to the window's
- upper left corner
-
- void TVptr_setscale(OBJECT pointer,int rows,int cols)
- Set the scaling of the pointer's coordinates such that the window it
- has been connected to with TVptr_open() is considered to be "rows"
- high and "cols" wide.
-
- void TVptr_getscale(OBJECT pointer,int *rows,int *cols)
- returns the scaling factors previously set with TVptr_setscale().
-
- void TVwin_point(OBJECT window,OBJECT pointer)
- move the mouse pointer to the location of the given window's logical
- cursor.
-
- Keyboard Mouse
- --------------
-
- For those systems without a mouse attached, DESQview provides a "keyboard
- mouse" which emulates a mouse using the numeric keypad. There are two
- functions relating to the keyboard mouse:
-
- int TVqry_kmouse(void)
- returns TRUE if DESQview is using a keyboard mouse, FALSE if not
-
- void TVapi_kmouse(int active)
- if "active" is TRUE, turn on the keyboard mouse, if it is FALSE
- turn off the keyboard mouse.
-
- Panel Files
- -----------
-
- I have no idea what the format of panel files is, so I have no way to test
- the panel functions. I do know that TVpanel_new(), TVpanel_free(),
- TVpanel_open(), and TVpanel_close() *appear* to work.
-
- OBJECT TVpanel_new(void)
- create a new panel object and return its handle
-
- void TVpanel_free(OBJECT panel)
- destroy the panel object
-
- void TVpanel_open(OBJECT panel,char *filename)
- associate the panel object with a disk file
-
- void TVpanel_close(OBJECT panel)
- close the panel file on disk
-
- DWORD TVpanel_status(OBJECT panel)
- check whether panel object is associated with a file?
-
- int TVpanel_size(OBJECT panel)
- return the number of panels in the panel file
-
- char far * TVpanel_dir(OBJECT panel, int *num_entries)
- get the directory of panels in the panel file. I have no idea
- what the format of the directory entries is.
-
- void TVpanel_apply(OBJECT panel,char *name,OBJECT window)
- write the named panel from the panel file to the given window. If
- "window" is NIL, then
-
-
-
-
- Object Queues
- -------------
-
- Object queues let you wait for any one of multiple occurrences without
- creating a separate task for each, and without polling for them.
-
- void TVobq_add(OBJECT objectq, OBJECT item)
- add the specified object to the given objectq. Using NIL for the
- objectq will use the current task's objectq.
-
- void TVobq_remove(OBJECT objectq, OBJECT item)
- remove the specified object from the queue.
-
- void TVobq_clear(OBJECT objectq)
- remove ALL objects from the queue.
-
- int TVobq_size(OBJECT objectq)
- return the number of items in the specified queue.
-
- DWORD TVobq_status(OBJECT objectq)
- find out whether or not the object queue is open
-
- void TVobq_open(OBJECT objectq)
- open the given objectq. NIL means the current task's objectq.
-
- void TVobq_close(OBJECT objectq)
- close the given objectq. NIL means the current task's objectq.
-
- OBJECT TVmyobq(void)
- return the handle of the current task's objectq.
-
- OBJECT TVobqof(OBJECT task)
- return the handle of the given task's objectq.
-
- OBJECT TVobq_read(OBJECT objectq)
- wait for any object on the queue to have input, and return the handle
- of the object which has input.
-
- Multiple Threads of Execution
- -----------------------------
-
- The task management functions allow you to create and destroy threads, and
- start, stop, and interrupt other threads.
-
- OBJECT TVtask_new(OBJECT parent,char *title,int row,int col,int rows,int cols,
- char *stack,int stacksize,void (*startaddr)(int),
- int switch_menu)
- create a new thread as a child of "parent", whose window has title
- "title" (or the title of the parent, if title == NULL). The window
- will the at (row,col) and will be "rows" lines high by "cols" columns
- wide. If stack == NULL, a stack of size "stacksize" will be malloc'd,
- otherwise the given stack will be used by the new task. The task will
- begin by executing the function "startaddr", passing in the segment of
- its parent task's handle.
-
- If "rows" is negative, then the window will have the same number of
- rows as the parent window; similarly for "cols". If both "rows"
- and "cols" are zero, no new window will be created.
-
- If "switch_menu" is TRUE, the new task will be placed on the Switch
- Windows menu.
-
- void TVtask_free(OBJECT task)
- kill the given task.
-
- void TVforeonly(OBJECT task,int foreonly)
- Sets whether or not a task will run in the background. If "foreonly"
- if nonzero, the task will be suspended while in the background.
-
- OBJECT TVmytask(void)
- return the handle of the currently executing task
-
- void TVinterrupt(OBJECT task,void far (*func)(void))
-
- void TVtask_stop(OBJECT task)
- suspend the given task. At least in DV 2.00, this call is ignored
- unless the given task is the currently executing one.
-
- void TVtask_start(OBJECT task)
- restart the previously suspended task
-
- void TVtask_post(OBJECT task)
- start the given task and add its handle to the current task's objectq
-
- WARNING: If you use multiple threads, you will have to ensure that library
- routines which are not completely reentrant have a guarded replacement which
- waits until any other threads have exited the function. By default,
- TVAPI.H contains #define's to protect malloc(), calloc(), realloc(), and free().
- Other functions to watch out for are rand(), srand(), ...printf(), and
- ...scanf().
-
- Applications
- ------------
-
- Applications are very similar to threads, except that each application has its
- own code and data within a memory partition, and may contain multiple threads.
- When a thread is started, it inherits the code of its parent; when an
- application is started, it gets new code from an executable on disk.
-
- OBJECT TVapp_new(OBJECT win,int row,int col,int rows,int cols,int switch_menu,
- char *program, char *argv0, char *argv1, ..., NULL )
- Start a new application as a child of the task owning "win". The
- new window will be at (row,col) and will be rows by cols in size.
- Load "program", and start it executing with the remaining arguments as
- command line. If "switch_menu" is TRUE, the program will be listed
- on the Switch Windows menu.
-
- OBJECT DVapp_start(void *pif_file, int pif_size)
- Given the contents of the .PIF or .DVP file, start a new application in
- a completely new memory partition. This function is known to cause
- lockups under DV 2.00 (6-16-87). Use at your own risk (though I would
- appreciate hearing from you which version (and date) you are using and
- whether or not it worked).
-
- void TVapp_free(OBJECT app)
- kill the given application.
-
- void TVapp_goback(OBJECT app)
- force the given application into the background
-
- void TVapp_gofore(OBJECT app)
- force the given application into the foreground
-
- void TVapp_suspend(OBJECT app)
- hide all windows belonging to the given application and suspend it.
-
- void TVapp_hide(OBJECT app)
- hide all windows belonging to the given application. The application
- continues to run.
-
- void TVapp_show(OBJECT app)
- show the windows belonging to the given application.
-
- Mailboxes
- ---------
-
- Mailboxes provide a convenient way for different tasks to communicate.
- Each task gets a mailbox by default, and this is the mailbox to which
- asynchronous notification messages are sent (see a later section).
-
- OBJECT TVmbx_new(void)
- create a new mailbox and return its handle
-
- void TVmbx_open(OBJECT mbx)
- open a mailbox, making it available for messages. A task's default
- mailbox is opened for you.
- void TVmbx_close(OBJECT mbx)
- close a mailbox, making it unavailable.
-
- void TVmbx_free(OBJECT mbx)
- destroy a mailbox object and return its memory to the pool of common
- memory. Do not use this function on a task's default mailbox, as
- the mailbox's memory is part of the task object's memory block.
-
- OBJECT TVmymbx(void)
- return handle for current task's default mailbox. Note that all of
- the functions expecting a mailbox handle will accept NIL for the
- default mailbox.
- OBJECT TVmbxof(OBJECT task)
- return the given task's default mailbox. This is useful for sending
- mail to another task, such as a subtask you have created.
-
- void TVmbx_name(OBJECT mbx,char *name)
- give a mailbox a globally visible name. Using the next function,
- anyone can then find the mailbox knowing only the name.
- OBJECT TVmbx_find(char *name)
- find the mailbox with the given name. Returns NIL if there is no
- mailbox with that name.
-
- void TVmbx_clear(OBJECT mbx)
- discard all pending messages from the mailbox.
-
- int TVmbx_size(OBJECT mbx)
- return the number of pending messages in the mailbox
-
- int TVmbx_status(OBJECT mbx)
- return the status of the last message read
-
- void TVmbx_write(OBJECT mbx,int ref,int status,char *msg,int length)
- send the message "msg" with the given length to the mailbox
- "mbx". The status is set to "status", and the message is passed by
- reference if "ref" is nonzero, and by value (i.e. a copy is made)
- if "ref" is zero.
-
- void TVsendmail(OBJECT mbx,char *msg,int length)
- send the message "msg" with the given length of the mailbox
- "mbx". The status is set to zero, and the message is passed by
- value (i.e. a copy is made).
-
- int TVreadmail(OBJECT mbx,char *buffer,int maxsize)
- wait for a message to arrive in the mailbox, and then fill buffer
- with up to (maxsize-1) characters of the message. Returns the actual
- size of the message read.
-
- There are also two functions which use mailboxes to synchronize access to
- resources, in effect treating the mailbox as a semaphore:
-
- void TVlock(OBJECT mbx)
- request exclusive access to resource. If another task has already
- locked the mailbox, the current task will be halted until the other
- task unlocks the mailbox. It is legal to lock the mailbox multiple
- times, in which case you must unlock it the same number of times that
- you locked it.
- void TVunlock(OBJECT mbx)
- release exclusive access to resource. If this unlocking corresponds
- to the last lock placed on the mailbox, then any other task waiting to
- lock the mailbox may proceed.
-
- Fields
- ------
-
- Fields are used in building a data-input screen which can be filled out by the
- user. After setup, a single call lets the user fill out the entire screen,
- after which the results can be read back.
-
- void TVfld_header(OBJECT win,FT_HEADER header)
- sets the field table header which defines how many fields there are,
- the colors of the current field and selected fields, and the type of the
- screen.
-
- The FT_HEADER structure contains the following fields:
- BYTE numfields the number of fields on the screen
- BYTE type behavior flags, see TVfld_build_header
- BYTE curr_attr attribute of current field during input
- BYTE selected_attr attribute of any selected fields
- int unknown must be zero
-
- void TVfld_entry(OBJECT win,int field,FT_ENTRY entry)
- sets up the specified field, indicating its position and type.
-
- The FT_ENTRY structure contains the following fields
- BYTE upleftrow \ row and column of upper left corner
- BYTE upleftcol /
- BYTE lowrightrow \ row and column of lower right corner
- BYTE lowrightcol /
- BYTE type type of the field, see TVfld_build_entry()
- BYTE modifier type modifier, see TVfld_build_entry()
- BYTE status don't quite know what this does
- BYTE key2 second key of a two-key menu entry
-
- BYTE *TVfld_build_header(int num_fields,int screen_type,
- int curr_attr,int selected_attr)
- begins building a stream for a screen with "num_fields" fields, using
- the given screen type, where the current field will have attribute
- "curr_attr" and any selected fields will have attribute
- "selected_attr". All fields will have attribute "curr_attr" by
- default, but this may be changed with TVfld_build_color() ;
- Use TVfld_build_entry() and TVfld_build_color() to set the field
- sizes and colors, and then use TVwin_stream(window,stream) to
- send the stream to the window for which you want to define fields.
- DO NOT FREE THE STREAM UNTIL AFTER YOU HAVE FINISHED A TVkbd_read()
- ON THE WINDOW.
-
- The following behaviors may be ORed together for the screen type:
- F_NOREAD TVkbd_read() returns no data
- F_READARRAY read returns a packed array of chars
- F_READALL read returns var-length records of all fields
- F_READNEW read returns var-length records of modified
- fields
- the above are mutually exclusive
- F_NOFLAGS menu items returned as ' ' instead of 'Y'/'N'
- F_RIGHTBUTTON right mouse button terminates entry
- F_LEFTBUTTION left mouse button terminates entry
- F_ALLOWKBD menu choices may be made by keystrokes
-
- void TVfld_build_entry(BYTE *stream,int field,int upleftrow,int upleftcol,
- int lowrightrow,int lowrightcol,int type,int modifier,
- int status,int key2)
- Define the given field (numbered from 1 to the number of fields) to
- be the rectangle from (upleftrow,upleftcol) to
- (lowrightrow,lowrightcol). Use the specified type of field (see
- below), with the given modifier and status. "key2" should be zero
- unless this is a menu entry that uses two keystrokes to select.
-
- The legal types of fields are
- F_NONENTRY no entries allowed on this field
- F_MENUECHO place where keystrokes for a two-key menu are put
- F_FILLIN fill-in-the-blank field
- F_MENU menu selection
-
- For type F_FILLIN, the legal modifiers (OR together) are:
- F_BEEP beep when field is full
- F_NEXT move to next field when field is full
- F_NUMBER enter text from right to left, for numbers
- F_UPPER force input to uppercase
- F_CLEAR clear old field contents on first keystroke
- For type F_MENU, the modifier is the first keystroke of the menu
- entry, or 0 if the selection must be made with the mouse.
-
- If the type of the field is F_MENU, then "status" is the attribute
- to use when the mouse pointer is in the field.
-
- void TVfld_build_color(BYTE *stream,int field,int attr)
- given the stream built by TVfld_build_header() and TVfld_build_entry(),
- set the attribute of the given field. Field numbers range from 1 of
- the number of fields given to TVfld_build_header().
-
- void TVfld_clear(OBJECT win,int field)
- clears specified field to all blanks
-
- void TVfld_char(OBJECT win,int field,int c)
- fills the entire field with the specified character.
-
- void TVfld_attr(OBJECT win,int field,int attr)
- sets the display attribute of the specified field.
-
- int TVfld_swrite(OBJECT win,int field,char *s)
- write the characters of the string "s" to the specified field.
- If the string is shorter than the field, the rest of the
- field is padded with blanks. Returns TRUE if the string could
- be written, FALSE otherwise.
-
- int TVfld_write(OBJECT win,int field,char *s)
- write EXACTLY enough characters of the string "s" to the specified
- field in order to fill it. Returns TRUE if the string could be written,
- FALSE otherwise.
-
- void TVfld_cursor(OBJECT win,int field)
- move the cursor to the specified field
-
- void TVfld_scroll(OBJECT window,int field,int direction)
- scroll the given field on the window one position in the specified
- direction. Legal directions are SCRL_UP, SCRL_DOWN, SCRL_LEFT,
- and SCRL_RIGHT.
-
- void TVfld_type(OBJECT window,int field,int type)
- Set the field's type. Legal types are F_NONENTRY, F_MENUECHO,
- F_FILLIN, and F_MENU. See TV_fld_build_entry() above.
-
- void TVfld_reset(OBJECT window)
- Resets selected and modified bits on all field for the window.
-
- void TVfld_marker(OBJECT window,char marker)
- Sets the character to display at the left edge of fields which have
- their "selected" bit set.
-
- void TVfld_altmode(OBJECT keyboard,int altmode)
- If "altmode" is TRUE, set the keyboard into field mode. If "altmode"
- is FALSE, set the keyboard into character mode.
-
- unsigned TVqry_fieldsize(OBJECT window,int field)
- return the size in characters of the specified field on the window.
-
- int TVqry_field(OBJECT window,int field,int buffersize,char *buffer)
- put up to "buffersize" characters of the specified field on the given
- window into the buffer. Return TRUE if the read was successful,
- FALSE if not.
-
- void TVqry_header(OBJECT window,FT_HEADER *header)
- fill in "header" with the field table header, which indicates
- the number of field and other information. See TVfld_header()
- above for the format of the FT_HEADER structure.
-
- void TVqry_entry(OBJECT window,int field,FT_ENTRY *entry)
- fill in "entry" with the specified field table entry. See
- TVfld_entry() above for the format of the FT_ENTRY structure.
-
- int TVqry_type(OBJECT window,int field)
- return the type byte of the specified field on the window. This byte
- is also returned by TVqry_entry() as part of the field table entry.
-
- Asynchronous Notification
- -------------------------
-
- A program running under DESQview may request to be notified when certain
- events occur. When a selected event occurs, the specified handler is
- immediately invoked, and a message is sent to the task's default mailbox
- indicating which event occurred.
-
- void TVwin_async(OBJECT win,void far (*func)(void))
- Defines a notification handler for the window "win". You may share a
- handler among multiple windows, as the events which apply to a single
- window identify which window was affected.
-
- Note: while inside the handler, the task's private stack will be in
- use, and you can't use TVostack() or TVustack() to switch stacks, as
- they mess up DESQview's record of its own stack use. As the stack is
- only 256 bytes, and some of that is used by DESQview, you will very
- quickly run out of space.
-
- This function will not work in huge model at present. A supporting
- function would have to be recoded entirely in assembler to get around
- the huge model function entry code.
-
- void TVwin_notify(OBJECT win,int event)
- Call the notification handler set up with TVwin_async() on the
- specified event. The events are defined in TVSTREAM.H and are:
- TV_HMOVE window was moved left or right
- TV_VMOVE window was moved up or down
- TV_HSIZE window's width changed
- TV_VSIZE window's height changed
- TV_HSCROLL window was scrolled left or right
- TV_VSCROLL window was scrolled up or down
- TV_CLOSE window is requested to close itself
- TV_HIDE window was hidden
- TV_HELP DESQview main menu "Help for Program" selected
- TV_COLORS DESQview "Rearrange" menu "Colors" option
- TV_RAISE window was put in foreground
- TV_LOWER window was put in background
- TV_VIDEOMODE "Rearrange" "Video Options" selected
- TV_SCISSORS_CUT "Scissors" menu "Cut" option selected
- TV_SCISSORS_COPY "Scissors" menu "Copy" option selected
- TV_SCISSORS_PASTE "Scissors" menu "Paste" option selected
- TV_MAINMENU DESQview main menu popped up
- TV_MENU_END DESQview main menu closed
-
- void TVwin_cancel(OBJECT win,int event)
- Turn off notification of given event for the window "win". The events
- are the same as for TVwin_notify().
-
- void TVwin_allow(OBJECT win,int event)
- Allow the specified event to occur on the window "win". The possible
- events are defined in TVSTREAM.H and are
- TV_HMOVE horizontal movement of the window
- TV_VMOVE vertical movement of the window
- TV_HSIZE changing the width of the window
- TV_VSIZE changing the height of the window
- TV_HSCROLL scrolling the window left or right
- TV_VSCROLL scrolling the window up or down
- TV_CLOSE main menu "Close" option
- TV_HIDE allow DESQview "Rearrange" menu "Hide" option
- TV_MARK access to DESQview's "Mark" menu
- TV_SCISSORS access to DESQview's "Scissors" menu
- TV_MAINMENU allow DESQview's main menu to pop up
- TV_SWITCH allow switching to other window
- TV_OPENMENU allow access to DESQview's "Open" menu
- TV_QUIT allow DESQview main menu "Quit" option
-
- void TVwin_disallow(OBJECT win,int event)
- disallow the given event for the window "win". The events are the
- same as for TVwin_allow().
-
- NOTE: if a function is not completely reentrant, you may not use that
- function within a notification handler unless the function cannot be called in
- any code from which the notification may take place. If you are using a
- guarded replacement (for functions such as malloc() and free()), you must
- still follow this restriction, as you may otherwise hang the current process.
-
- In addition, small-model code which assumes SS == DS (which some C library
- functions do) will break, as SS will be different inside the notification
- handler.
-
- Second-Level Interrupts
- -----------------------
-
- WORD TVgetbit(void far (*handler)(void))
- allocate a second-level interrupt, and set it to point to "handler"
- Returns a bitmask with a single bit set, or 0 if no second-level
- interrupt could be allocated.
-
- void TVsetbit(WORD bitmask)
- enqueue all second-level interrupts corresponding to set bits in the
- bitmask.
-
- void TVfreebit(WORD bitmask)
- deallocate all second-level interrupts corresponding to set bits in
- the bitmask.
-
- Memory Allocation
- -----------------
-
- There are a number of functions to allocate and deallocate blocks of common
- memory, and find out how much memory is available.
-
- void DVcommon_mem(WORD *avail, WORD *largest, WORD *total)
- sets "avail" to the total bytes of common memory available
- sets "largest" to the number of bytes in the largest block of common
- memory available
- sets "total" to the total number of bytes of common memory
-
- void DVconv_mem(WORD *avail, WORD *largest, WORD *total)
- sets "avail" to the total kilobytes of conventional memory available
- sets "largest" to the size in K of the largest block of conv memory
- sets "total" to the total size of conventional memory in K
-
- void DVexp_mem(WORD *avail, WORD *largest, WORD *total)
- same as DVconv_mem, except that it reports on expanded memory
-
- void far *TVgetmem(unsigned amt)
- allocate "amt" bytes of system memory and return a pointer to the
- allocated block.
-
- void TVputmem(void far *block)
- return the previously allocated block of system memory to the pool
- of available memory.
-
- Miscellaneous Functions
- -----------------------
-
- void TVpause(void)
- give up rest of timeslice to other tasks/processes
-
- void TVbegincrit(void)
- void TVendcrit(void)
- delimit a "critical section", during which TopView/DESQview will not
- perform task switches.
-
- void TVostack(void)
- switch to task's private stack
- void TVustack(void)
- switch back to user stack
-
- Use extreme caution with these two functions, as they switch the stack
- out from under your C code. You will not be able to access local
- variables after the stack switch, and any code which assumes SS == DS
- will break.
-
- void far *TVshadow(void)
- returns address of shadow buffer for the current task's main window.
- Under DESQview, it also starts shadowing, that is, automatically
- updating the display. Under TopView, you must manually update the
- display with the next function.
- void TVupdate(void far *first, WORD count)
- update the display from the shadow buffer, starting with the character
- pointed to by "first", for "count" contiguous characters
-
- void far *DVshadow_start(int *rows,int *cols)
- similar to TVshadow(), but also returns size of shadow buffer in rows
- and columns. Unlike TVshadow(), it will restart shadowing which has
- been stopped by TVupdate() or DVshadow_stop().
- void DVshadow_stop(void)
- stop automatic updating of screen from shadow buffer. In DESQview 2.0
- and higher, shadowing is also stopped by TVupdate(), but will not be
- restarted by TVshadow().
-
- int DVappnum(void)
- returns the number of the current task as it appears on the "Switch
- Windows" menu.
-
- WORD DVprogname(void)
- returns the offset within DESQVIEW.DVO of the current task's name.
-
- void DVdbgpoke(char c)
- write the character directly to the 25th line of the screen. After
- the character is written, the next call will place the character in
- the next position, wrapping back to the beginning of the 25th line
- if necessary. Note that this function does not heed any windows which
- may be on the screen, nor does it work properly in graphics modes.
-
- void DVenable(void)
- enable DESQview extensions for the current task. I don't yet know
- what the extent of these extensions is.
-
- void DVjustify(int justify)
- if "justify" is nonzero, the viewport origins of windows will shift
- to keep the cursor within the visible portion of the virtual screen.
- If "justify" is zero, no such shifting will take place.
-
- void TVgetbuf(OBJECT window,char far **buffer,int *size,int *flag)
- Get the virtual screen buffer for the given window. On return,
- "buffer" points to the screen buffer, which contains "size" bytes.
- I don't know yet what "flag" is.
-
- void TVsound(int frequency,int duration)
- make a tone with the given frequency in Hertz for the given duration
- in clock ticks (1/18 sec). The function returns immediately, while
- the tone plays to completion. If another tone is already playing, the
- new one is enqueued, up to 32 deep (if the queue is already full, then
- the function waits until the current tone completes before returning).
-
- void TVnosound(void)
- cancel all tones queued up to be played, and turn off the current tone
- (if any).
-
- User Interface Functions
- ------------------------
-
- The functions in this section are all high-level functions, which make use of
- a number of the primitives described in previous sections. If you wish to use
- them, you must include "TVUI.H" *after* "TVAPI.H".
-
- The first two functions allow you to display menus that look like the ones
- DESQview itself uses.
-
- void *UImenu_build(MENU_ITEM *menu_items,MENU_OPTION *menu_options)
- Build a menu stream given the description of the menu in
- "menu_items" and the title and other options in "menu_options".
- Note that the returned stream cannot be used directly because of
- control information which is added to be used by UImenu_show.
- As the memory for the stream is allocated, you should free() the
- returned menu when you are done with it. UImenu_show() does not
- do the free() so that you may reuse the menu without having to
- rebuild it each time.
-
- Format of a menu item:
- typedef struct
- {
- char type ; The item's type, see below
- char *entry ; The string to display for this entry
- char key1 ; The first key to use
- char key2 ; The second key to use, 0 if none
- char selected ; the field starts out selected if nonzero
- } MENU_ITEM ;
-
- Format of the menu options:
- typedef struct
- {
- char *title ; The menu's title
- int row ; Position of menu. Values less than 0 are
- int col ; measured from screen right or bottom
- int left_button ; Can left mouse button terminate entry?
- int right_button ; Can right mouse button terminate entry?
- int allow_kbd ; Can menu items be selected from the kbd?
- char marker ; Marker character for selected menu items
- } MENU_OPTIONS ;
-
- Valid menu item types:
- M_ITEM a menu item. The characters in "key1" and optionally
- "key2" are placed in the "key" position on the menu.
- M_SPECIAL a menu item using a special key. All text after the
- last blank is placed in the "key" position on the
- menu.
- M_TEXT descriptive text, will not allow entry
- M_HTEXT highlighted descriptive text
- M_CENTER centered descriptive text
- M_HCENTER highlighted centered text
- M_SEP separator line. The character in "key1" is replicated
- across the entire width of the menu.
- M_IGNORE this item is completely ignored. Useful for
- on-the-fly addition and deletion of entries.
- M_END indicates the end of the menu description
-
- Error returns: UImenu_build can return three errors, and you should
- check for them before using the returned stream.
- ME_NOMEM unable to allocate memory for the stream
- ME_TOOBIG menu won't fit on the screen
- ME_BADITEM invalid menu item type. This is usually caused by
- forgetting the M_END entry at the end of the menu
- description. It can also be caused by a missing
- string for M_ITEM and a string without blanks for
- M_SPECIAL.
-
- int UImenu_show(void *menu,int reset,int (*test)(OBJECT,int,char *),char *result)
- Displays the previously built menu, resetting the "selected" flags on
- all menu items if "reset" is TRUE. The user then selects a menu item,
- or makes some other keypress. The test function is then called and is
- passed the handle for the menu's window,the status returned by
- DESQview (see below), and a character string indicating the state of
- each menu item. The test function returns a value which tells
- UImenu_show() what to do next. When the input is done, UImenu_show()
- fills in "result" with the same character string which was previously
- passed to the test function, and returns the status that was passed
- to the test function.
-
- Status:
- 0 RETURN pressed, unless a menu item defines RETURN as its
- keypress
- 1 menu item selected by pressing left mouse button, or typing
- the item's keystroke(s).
- 2 entry aborted with the right mouse button
- 27 entry aborted by pressing ESC.
- any other value indicates the extended-ASCII value of function or
- Alt-keys which are not defined as fields and not used by DESQview
- itself.
-
- Valid test function returns. These may be ORed together:
- MA_REDO ask user for input again \ mutually
- MA_DONE return to caller / exclusive
- MA_BEEP 1/4 second beep
- MA_RESET reset "selected" bits for all menu items
- MA_SELECT change "selected" status of all fields to match
- changed values in the string which was passed to the
- test function.
-
- The next function lets the user move and resize a new window by dragging it
- around with the mouse.
-
- OBJECT UIwin_open(OBJECT parent,int minrows,int mincols,
- int maxrows,int maxcols,int defrows,int defcols)
- Prompt the user to use the mouse to position and size a new window,
- which defaults to "defrows" by "defcols" in size, and must be at least
- "minrows" by "mincols", but no more than "maxrows" by "maxcols."
- Returns the handle for the new window.
-
- The last function (for now), is a higher-level version of TVwin_async(),
- which allows a separate handler for each possible event which DESQview can
- notify a program of.
-
- void (*UIsignal(int signal,OBJECT win,void (*handler)()))(NOTIFY_MSG far *)
- Installs a handler for the specified event notification (the valid
- signals are the same as for TVwin_notify() and TVwin_cancel()) and
- returns a pointer to the previous handler. The handler takes a single
- argument, which is a FAR pointer to the notification message provided
- by DESQview, with one exception. The exception is that the first byte
- has already had the MS_NOTIFY offset subtracted from it, so the
- handler can directly compare the first byte to the event numbers
- (for those handlers that take care of multiple events).
-
- The specified event is enabled when "handler" is non-NULL, but not
- automatically disabled when "handler" is NULL. This is because of the
- assumption that you want any event you are trapping to actually occur,
- but don't necessarily want to disable the action when you are no
- longer interested in trapping the event (such as moving the window).
- If you want the action disabled when you remove the handler, you must
- explicitly call TVwin_disallow().
-
- You may define a handler for the same signal for multiple windows, but
- only the last-used handler for a given signal is actually called,
- regardless of which window gets the notification. BEWARE!
-
- DO NOT mix this function with the TVwin_async() function, as that
- will cause unpredictable results.
-