\begindata{text,538321152} \textdsversion{12} \template{default} \define{itemize } \define{fixedtext menu:[Region~4,Fixedtext] attr:[Justification LeftJustified Point 0] attr:[FontFace FixedFace Int Set] attr:[FontFamily AndyType Int 0] attr:[FontSize ConstantFontSize Point 10]} \define{fixedindent menu:[Region~4,Fixedindent] attr:[LeftMargin LeftMargin Cm 83230] attr:[Justification LeftJustified Point 0] attr:[FontFace FixedFace Int Set] attr:[FontFamily AndyType Int 0] attr:[FontSize ConstantFontSize Point 10]} \define{paramname menu:[Font~1,Paramname] attr:[FontFace Italic Int Set]} \formatnote{\chapter{Interaction Manager}}\indexi{Interaction Manager} The interaction manager handles all the "administrative" duties in the event-driven Andrew Toolkit system. It determines what functions need to be called when and then calls those functions. It also controls some aspects of window appearance. Parameters for rectangles, as well as menu lists, key maps and key states, and cursors,etc. as usually passed up to the interaction manager (via \italic{InsertGraphic}, \italic{PostKeyState}, \italic{PostCursor}, etc.) where the interaction manager decides if the information is acceptable. In some cases, e.g. WantInputFocus, the interaction manager calls back down to the requesting object, letting it know that its request has been "approved". \section{Quick reference list for Im} \fixedtext{boolean \bold{im_}AddCanOutHandler }\fixedindent{(FILE *\paramname{file}, procedure \paramname{proc}, char *\paramname{procdata}, long \paramname{priority});} \fixedtext{boolean \bold{im_}AddFileHandler }\fixedindent{(FILE *\paramname{file}, procedure \paramname{proc}, char *\paramname{procdata}, long \paramname{priority});} \fixedtext{void \bold{im_}AddZombieHandler }\fixedindent{(int \paramname{pid}, procedure \paramname{function}, long \paramname{functionData});} \fixedtext{long \bold{im_}AllocLastCmd }\fixedindent{();} \fixedtext{void \bold{im_}AppendToCutBuffer }\fixedindent{(struct im *\paramname{im}, FILE *\paramname{writeFile});} \fixedtext{boolean \bold{im_}ArgProvided }\fixedindent{(struct im *\paramname{im});} \fixedtext{long \bold{im_}Argument }\fixedindent{(struct im *\paramname{im});} \fixedtext{void \bold{im_}CancelInteractionEvent }\fixedindent{(struct im *\paramname{im}, struct event *\paramname{event});} \fixedtext{long \bold{im_}ChangeDirectory }\fixedindent{(char *\paramname{dirName});} \fixedtext{boolean \bold{im_}CheckForInterrupt }\fixedindent{();} \fixedtext{void \bold{im_}ClearArg }\fixedindent{(struct im *\paramname{im});} \fixedtext{void \bold{im_}ClearCursorList }\fixedindent{(struct im *\paramname{im});} \fixedtext{void \bold{im_}ClearCursors }\fixedindent{(struct im *\paramname{im}, struct cursor *\paramname{C});} \fixedtext{void \bold{im_}CloseFromCutBuffer }\fixedindent{(struct im *\paramname{im}, FILE *\paramname{readFile});} \fixedtext{void \bold{im_}CloseToCutBuffer }\fixedindent{(struct im *\paramname{im}, FILE *\paramname{writeFile});} \fixedtext{boolean \bold{im_}CreateWindow }\fixedindent{(struct im *\paramname{im}, char *\paramname{host});} \fixedtext{\fixedtext{boolean \bold{im}_CreateTransientWindow \fixedindent{(struct im *\paramname{other})} returns boolean; boolean \bold{im}_CreateOverrideWindow \fixedindent{(struct im *\paramname{other})} returns boolean; }struct im *\bold{im_}Create }\fixedindent{(char *\paramname{host});} \fixedtext{void \bold{im_}DeliverSignals }\fixedindent{();} \fixedtext{void \bold{im_}DispatchPendingInteractionEvents }\fixedindent{(struct im *\paramname{im});} \fixedtext{void \bold{im_}DoKeySequence }\fixedindent{(struct im *\paramname{im}, unsigned char *\paramname{keys});} \fixedtext{struct im *\bold{im_}DoKey }\fixedindent{(struct im *\paramname{im}, long \paramname{key});} \fixedtext{void \bold{im_}DoMacro }\fixedindent{(struct im *\paramname{im});} \fixedtext{void \bold{im_}DoMenu }\fixedindent{(struct im *\paramname{im}, unsigned char *\paramname{itemname});} \fixedtext{struct event *\bold{im_}EnqueueEvent }\fixedindent{(procedure \paramname{proc}, char *\paramname{procdata}, long \paramname{timeIncrement});} \fixedtext{void \bold{im_}ExposeWindow }\fixedindent{(struct im *\paramname{im});} \fixedtext{void \bold{im_}FinalizeObject }\fixedindent{(struct im *\paramname{self});} \fixedtext{void \bold{im_}ForceUpdate }\fixedindent{();} \fixedtext{FILE *\bold{im_}FromCutBuffer }\fixedindent{(struct im *\paramname{im});} \fixedtext{struct im_ArgState *\bold{im_}GetArgState }\fixedindent{(struct im *\paramname{im});} \fixedtext{int \bold{im_}GetCharacter }\fixedindent{(struct im *\paramname{im});} \fixedtext{struct cursor *\bold{im_}GetCursor }\fixedindent{();} \fixedtext{char *\bold{im_}GetDirectory }\fixedindent{(char *\paramname{outputString});} \fixedtext{struct fontdesc *\bold{im_}GetFontdesc }\fixedindent{();} \fixedtext{struct im_GlobalDataType *\bold{im_}GetGlobalData }\fixedindent{();} \fixedtext{struct init *\bold{im_}GetGlobalInit }\fixedindent{();} \fixedtext{struct graphic *\bold{im_}GetGraphic }\fixedindent{();} \fixedtext{\bold{im_}GetInputFocus }\fixedindent{(\paramname{self});} \fixedtext{long \bold{im_}GetLastCmd }\fixedindent{(struct im *\paramname{im});} \fixedtext{struct im *\bold{im_}GetLastUsed }\fixedindent{();} \fixedtext{void \bold{im_}GetManyParameters }\fixedindent{(struct im *\paramname{im}, struct resourceList *\paramname{resources}, struct atomlist *\paramname{name}, struct atomlist *\paramname{className});} \fixedtext{void \bold{im_}GetPreferedDimensions }\fixedindent{(long *\paramname{top}, long *\paramname{left}, long *\paramname{width}, long *\paramname{height});} \fixedtext{struct cursor *\bold{im_}GetProcessCursor }\fixedindent{();} \fixedtext{char *\bold{im_}GetProgramName }\fixedindent{();} \fixedtext{short \bold{im_}GetResource }\fixedindent{(struct im *\paramname{im}, struct atomlist *\paramname{name}, struct atomlist *\paramname{className}, struct atom *\paramname{type}, long *\paramname{data});} \fixedtext{char *\bold{im_}GetTitle }\fixedindent{(struct im *\paramname{im});} \fixedtext{struct windowsystem *\bold{im_}GetWindowSystem }\fixedindent{();} \fixedtext{long \bold{im_}GetWriteID }\fixedindent{();} \fixedtext{struct im *\bold{im_}HandleMenu }\fixedindent{(struct im *\paramname{im}, struct proctable_Entry *\paramname{procTableEntry}, struct basicobject *\paramname{object}, long \paramname{rock});} \fixedtext{struct im *\bold{im_}HandleMouse }\fixedindent{(struct im *\paramname{im}, enum view_MouseAction \paramname{action}, long \paramname{x}, long \paramname{y}, long \paramname{newButtonState});} \fixedtext{void \bold{im_}HandleRedraw }\fixedindent{(struct im *\paramname{im});} \fixedtext{void \bold{im_}HideWindow }\fixedindent{(struct im *\paramname{im});} \fixedtext{boolean \bold{im_}InitializeClass }\fixedindent{();} \fixedtext{boolean \bold{im_}InitializeObject }\fixedindent{(struct im *\paramname{self});} \fixedtext{boolean \bold{im_}Interact }\fixedindent{(boolean \paramname{mayBlock});} \fixedtext{void \bold{im_}IOMGRCancel }\fixedindent{(char *\paramname{imPid});} \fixedtext{boolean \bold{im_}IOMGRSelect }\fixedindent{(long \paramname{maxnum}, long *\paramname{rmask}, long *\paramname{wmask}, long \paramname{wantTime}, struct timeval *\paramname{retTime});} \fixedtext{void \bold{im_}IOMGRSoftSig }\fixedindent{(long \paramname{unknown1}, long \paramname{unknown2});} \fixedtext{boolean \bold{im_}IsPlaying }\fixedindent{();} \fixedtext{void \bold{im_}KeyboardExit }\fixedindent{();} \fixedtext{long \bold{im_}KeyboardLevel }\fixedindent{();} \fixedtext{void \bold{im_}KeyboardProcessor }\fixedindent{();} \fixedtext{long \bold{im_}LWPCurrentProcess }\fixedindent{(char *\paramname{curProcessID});} \fixedtext{void \bold{im_}plumber }\fixedindent{(FILE *\paramname{reportFile});} \fixedtext{void \bold{im_}PostCursor }\fixedindent{(struct im *\paramname{im}, struct rectangle *\paramname{rec}, struct cursor *\paramname{cursor});} \fixedtext{void \bold{im_}PostDefaultHandler }\fixedindent{(struct im *\paramname{im}, char *\paramname{handlerName}, struct basicobject *\paramname{handler});} \fixedtext{void \bold{im_}PostKeyState }\fixedindent{(struct im *\paramname{im}, struct keystate *\paramname{keystate});} \fixedtext{void \bold{im_}PostMenus }\fixedindent{(struct im *\paramname{im}, struct menulist *\paramname{menulist});} \fixedtext{void \bold{im_}PostResource }\fixedindent{(struct im *\paramname{im}, struct atomlist *\paramname{path}, struct atom *\paramname{type}, long \paramname{data});} \fixedtext{void \bold{im_}ProvideArg }\fixedindent{(struct im *\paramname{im}, long \paramname{arg});} \fixedtext{void \bold{im_}RedrawChangedWindows }\fixedindent{();} \fixedtext{void \bold{im_}RedrawWindow }\fixedindent{(struct im *\paramname{im});} \fixedtext{void \bold{im_}RemoveCanOutHandler }\fixedindent{(FILE *\paramname{file});} \fixedtext{void \bold{im_}RemoveFileHandler }\fixedindent{(FILE *\paramname{file});} \fixedtext{void \bold{im_}RemoveZombieHandler }\fixedindent{(int \paramname{pid});} \fixedtext{void \bold{im_}RetractCursor }\fixedindent{(struct im *\paramname{im}, struct cursor *\paramname{cursor});} \fixedtext{void \bold{im_}RetractViewCursors }\fixedindent{(struct im *\paramname{im}, struct view *\paramname{requestor});} \fixedtext{void \bold{im_}RotateCutBuffers }\fixedindent{(struct im *\paramname{im}, long \paramname{count});} \fixedtext{void \bold{im_}SetCleanUpZombies }\fixedindent{(boolean \paramname{value});} \fixedtext{void \bold{im_}SetDefaultServerHost }\fixedindent{(char *\paramname{name});} \fixedtext{void \bold{im_}SetGeometrySpec }\fixedindent{(char \paramname{value});} \fixedtext{void \bold{im_}SetGlobalInit }\fixedindent{(struct init *\paramname{init});} \fixedtext{struct event *\bold{im_}SetInteractionEvent }\fixedindent{(struct im *\paramname{im}, procedure \paramname{function}, long \paramname{functionData}, long \paramname{time});} \fixedtext{void \bold{im_}SetLastCmd }\fixedindent{(struct im *\paramname{im}, long \paramname{cmd});} \fixedtext{void \bold{im_}SetLastUsed }\fixedindent{(struct im *\paramname{used});} \fixedtext{void \bold{im_}SetPreferedDimensions }\fixedindent{(long \paramname{top}, long \paramname{left}, long \paramname{width}, long \paramname{height});} \fixedtext{void \bold{im_}SetProcessCursor }\fixedindent{(struct cursor *\paramname{cursor});} \fixedtext{void \bold{im_}SetProgramName }\fixedindent{(char *\paramname{nameString});} \fixedtext{void \bold{im_}SetTitle }\fixedindent{(struct im *\paramname{im}, char *\paramname{titleString});} \fixedtext{void \bold{im_}SetView }\fixedindent{(struct im *\paramname{im}, struct view *\paramname{toplevel});} \fixedtext{void \bold{im_}SetWindowCursor }\fixedindent{(struct im *\paramname{im}, struct cursor *\paramname{cursor});} \fixedtext{void \bold{im_}SetWMFocus }\fixedindent{(struct im *\paramname{im});} \fixedtext{void \bold{im_}SignalHandler }\fixedindent{(long \paramname{signalNumber}, procedure \paramname{proc}, char *\paramname{procdata});} \fixedtext{FILE *\bold{im_}ToCutBuffer }\fixedindent{(struct im *\paramname{im});} \fixedtext{void \bold{im_}UnlinkNotification }\fixedindent{(struct im *\paramname{im}, struct view *\paramname{unlinkedTree});} \fixedtext{void \bold{im_}UpdateCursors }\fixedindent{(struct im *\paramname{im});} \fixedtext{void \bold{im_}VanishWindow }\fixedindent{(struct im *\paramname{im});} \fixedtext{void \bold{im_}vfilecleanup }\fixedindent{();} \fixedtext{void \bold{im_}vfileclose }\fixedindent{(FILE *\paramname{f}, struct expandstring *\paramname{buffer});} \fixedtext{FILE *\bold{im_}vfileopen }\fixedindent{(char *\paramname{mode}, struct expandstring *\paramname{buffer});} \fixedtext{struct basicobject *\bold{im_}WantHandler }\fixedindent{(struct im *\paramname{im}, char *\paramname{handlerName});} \fixedtext{char *\bold{im_}WantInformation }\fixedindent{(struct im *\paramname{im}, char *\paramname{key});} \fixedtext{void \bold{im_}WantInputFocus }\fixedindent{(struct im *\paramname{im}, struct view *\paramname{requestor});} \fixedtext{void \bold{im_}WantNewSize }\fixedindent{(struct im *\paramname{im}, struct view *\paramname{requestor});} \fixedtext{void \bold{im_}WantUpdate }\fixedindent{(struct im *\paramname{im}, struct view *\paramname{requestor});} \fixedtext{unsigned char *\bold{im_}WhichWS }\fixedindent{(struct im *\paramname{im});} \section{Overview of interaction manager} The interaction manager is the top-level view in an X window. It represents the interface between the window manager software (such as X or wm) and Toolkit. It includes many functions required for interfacing with the Unix operating system, since so many interact with the delivery of mouse, menu and keyboard events from the window manager. Note that in general, people do not subclass the interaction manager. \section{Working with interaction managers} \subsection{Creating interaction managers} \paragraph{Creating an instance of an interaction manager}\indexi{Interaction Manager++Creating} \indexi{ \italic{im_Create}} \example{struct im *im_Create( host) char *host;} \leftindent{\bold{Class procedure description. } \italic{im_Create }creates a new instance of an interaction manager. \bold{Return value.} Returns a pointer to the newly created instance. \bold{Side effects.} A new window appears on host \italic{host}, and this window is associated with the returned \italic{im} object. When a view is inserted into the view, using \italic{im_SetView}, that view will appear in the window associated with this \italic{im}. \bold{Usage.} One calls im_Create in order to create a new window from an application. One generally next causes a view to appear in this newlycreated window by calling \italic{im_SetView} with the desired view. } Creating and associating a temporary interaction manager with an existing one struct im *im_CreateTransient(struct im *other); struct im *other; \bold{Method Description.} Creates a top level im window that is a transient for the named im 'other'. The geometry of this new im is relative to the position of 'other' with one non-obvious, but highly useful aspect: If you set desired position to (0,0) the given desired height and width will be used to produce an im which appears in the middle of the 'other' im. The transient window is autonomous and separately manageable by the window manager in the same way that other top level im's are. The reason for the existance of this function was to be able to create a window from inside an application and to set the geometry precisely. Some window managers may group the transient window with the top level window and iconify both at the same time when the 'other' window is. struct im *im_CreateOverride(struct im *other) struct im *other; \bold{Method Description. }Creates a child window of 'other' following the same geometry setting conventions as a transient window. All keystrokes go to the override window for as long as it is visible. Mouse events outside the override window are discarded for as long as the override is visible. Since the override is a child of 'other' it is clipped to the bounds of 'other'. (An attempt was made to relax this restriction but it proved too hard to write with the current X ICCCM. (There are missing conventions for stacking notifications from a window manager.)) The override window is not managed by the window manager. It is considered part of the 'other' im's window hierarchy. It is guaranteed to stack in the right order, to iconify and de-iconify when 'other' does, and to move when 'other' does. The purpose of this function is allow creation of pop-up messages that are full im's. To make it easy for people to code using the new functions, the im object defines the CreateOverride and CreateTransient functions but will return regular top level im's if the window specific server does not actually support the kind of window being asked for. (For example, supporting overlapping windows with the wm window server is very hard.) im_SupportsTransients(); \bold{Macro Description.} Returns TRUE if the im_CreateOverride function really will create a transient. im_SupportsOverrides(); \bold{Macro Description.} Returns TRUE if the im_CreateOverride function really will create a pop-up. The im object defines these macros to be FALSE, and allows specific im subclasses (such as xim) to override the macros. The idea behind the existance of these predicates is to be able to, in the future, modify frame to use override windows for dialogue boxes under window servers that support overrides. \paragraph{Associating a view with an interaction manager window}\indexi{Interaction manager++Linking to a view} \indexi{ \italic{im_SetView}} \example{ void im_SetView (im, topLevel) struct im *im; struct view *topLevel;} \leftindent{\bold{Method description. } \italic{im_SetView} associates the top-level view in a window with that window. In addition, it calls \italic{im_ForceFullUpdate}, causing the view tree to be sized and linked up. } \paragraph{An interaction loop procedure}\indexi{Interaction Manager++Interaction loop} \indexi{ \italic{im_Interact}} \example{boolean im_Interact(mayBlock) boolean mayBlock;} \leftindent{\bold{Class procedure description. } \italic{im_Interact} is an interaction procedure that performs one of the following "userinteractions" and then returns. \itemize{ \indent{Performs one character event of a keyboard macro. Handles a redraw request from the Andrew system window manager, Reads a character from a window manager window and calls the appropriate procedures, depending upon whether the character represents keyboard input or a mouse hit. Handles input available from an arbitrary file descriptor. Executes an event from the timer event queue. } } \bold{Return Value.} The procedure returns a boolean. This boolean is always TRUE if mayBlock is TRUE. If mayBlock is false, then im_Interact returns TRUE if there is more data to be read, and FALSE if there are no pending events. \bold{Usage.} Since the procedure returns after performing a single operation, it must be called from a while loop in order to accomplish what in Unix/Emacs terms is called a recursive edit. \bold{Example.} The following procedure allows a user to edit in any window Toolkit is managing, until some procedure, perhaps bound via the keymap package to a simple command sequence, sets the global variable AllDone to TRUE. \example{while (!AllDone) im_Interact(TRUE); }The following code fragment allows any already-typed commands to be executed, but does not wait for more input. \example{while (im_Interact(FALSE)); }Note that in this last example, \italic{im_Interact} is called with its mayBlock parameter being false, indicating that im_Interact should not wait for any input. } \begindata{bp,538928456} \enddata{bp,538928456} \view{bpv,538928456,1254,0,0} \paragraph{Providing an exit for the interaction loop}\indexi{Interaction manager++Exiting the interaction loop} \indexi{ \italic{im_KeyboardProcessor}} \example{void im_KeyboardProcessor() } \leftindent{\bold{Class procedure description. } \italic{im_KeyboardProcessor} loops calling \italic{im_Interact} repeatedly, returning only when the \italic{keyboardExitFlag} becomes true. See the description of \italic{im_KeyboardExit} for details on how to set this flag. \bold{Usage.} This routine enters a recursive edit loop. In other words, a command may pause and let a user edit for a while by calling this routine. A command to terminate this phase of the command's execution is generally bound to a function that eventually invokes \italic{im_KeyboardExit}. Executing this command then terminates the call to \italic{im_KeyboardProcessor}, and the command containing the recursive edit then continues its execution. } \subsection{Interaction events} \paragraph{Queuing up an event}\indexi{Interaction manager++Queuing an event} \indexi{ \italic{im_EnqueueEvent}} \example{struct event *im_EnqueueEvent( proc, procdata, timeIncrement) int (*proc) (); char *procdata; long timeIncrement;} \leftindent{\bold{Class procedure description. } \italic{im_EnqueueEvent} is used to queue up an event. The procedure \italic{proc} will be called with \italic{procdata} and the current time (a long representing the time in seconds in the same form as return by the \italic{time} subroutine call) \italic{timeIncrement} seconds from now. \bold{Usage.} the future. This routine is used to perform an operation some time in } \begindata{bp,538928520} \enddata{bp,538928520} \view{bpv,538928520,1255,0,0} \paragraph{Setting an interaction event}\indexi{Interaction manager++Setting an interaction event} \indexi{ \italic{im_SetInteractionEvent}} \example{struct event *im_SetInteractionEvent (im, interactionFunction, interactionData, timeIncrement) struct im *im; int (*interactionFunction)(); long interactionData; long timeIncrement;} \leftindent{\bold{Method description. } \italic{im_SetInteractionEvent } sets up an interaction event. After a delay of timeIncrement seconds, the interactionFunction will be called with the parameter interactionData when the next user interaction (mouse hit, key-stroke or menu selection) occurs. \bold{Usage.} Be careful with this function. Because Toolkit objects are do not have reference counts, it is quite possible for an object referred to by interactionData to be freed before the interaction event occurs. In order to avoid this problem, you must be sure to cancel any interaction event when you invalidate its interactionData parameter. This has ramifications on the choice of your interactionData parameter. Also, note that there is only one interaction event per window (im). \bold{Example.} The frame view uses this function to clear out the message line's contents on the next interaction. Essentially, it invokes message_DisplayString(view, "") in the interactionFunction. } \paragraph{Canceling an interaction event}\indexi{Interaction manager++Canceling an interaction event} \indexi{ \italic{im_CancelInteractionEvent}} \example{void im_CancelInteractionEvent(im) struct im *im;} \leftindent{\bold{Method description. } \italic{im_CancelInteractionEvent} cancels an interaction event. Note that since there is only one interaction event per window allowed, the only parameter to this function is the interaction manager, im. \bold{Usage.} See im_SetInteractionEvent. } \begindata{bp,538929224} \enddata{bp,538929224} \view{bpv,538929224,1256,0,0} \subsection{Managing windows and the window manager} \paragraph{Updating the windows}\indexi{Interaction manager++Updating windows} \indexi{ \italic{im_ForceUpdate}} \example{void im_ForceUpdate () } \leftindent{\bold{Class procedure description. } \italic{im_ForceUpdate} forces an update on all the windows and interfaces that have requested they be redrawn via \italic{view_WantUpdate}, by calling the procedure\italic{ view_Update}. \bold{Usage.} Normally, the views that have requested updates are not actually drawn until the next call to im_Interact. To force these redraws at an earlier time, you can call this routine. A programmer can use this function to let the user see the screen representation of a view state in the middle of the execution of a command. For example, a command performing an animation might use this function to display an individual animation frame. } \paragraph{Exposing a window manager window}\indexi{Interaction manager++Exposing a window manager} \indexi{ \italic{im_ExposeWindow}} \example{void im_ExposeWindow(im) struct im *im;} \leftindent{\bold{Method description. } This function exposes the window manager window associated with the specified im, if was previously hidden.} \paragraph{Hiding a window}\indexi{Interaction manager++Hiding a window} \indexi{ \italic{im_HideWindow}} \example{void im_HideWindow(im) struct im *im;} \leftindent{\bold{Method description. } This method directs the window manager to iconize the window associated with the specified interaction manager. } \paragraph{Getting the window system }\indexi{Interaction manager++Getting the window system} \indexi{ \italic{im_GetWindowSystem}} \example{struct windowsystem *im_GetWindowSystem() } \leftindent{\bold{Class procedure description. } This function allows a program to determine which window system it is running under, e.g. X or the Andrew window manager. \bold{Return value.} The current window system structure. } \paragraph{Setting the window manager focus}\indexi{Interaction manager++Setting window manager focus} \indexi{ \italic{im_SetWmFocus}} \example{void im_SetWMFocus(im) struct im *im;} \leftindent{\bold{Method description. } This function moves the window manager's input focus to the window associated with the specified im. When possible, the cursor will move to the titlebar of the associated window. \bold{Example. this function. }The ez next-window and previous window commands use } \begindata{bp,538929032} \enddata{bp,538929032} \view{bpv,538929032,1257,0,0} \subsection{Cursors} \paragraph{Setting a cursor for a window}\indexi{Interaction manager++Window cursors} \indexi{ \italic{im_SetWindowCursor}} \example{im_SetWindowCursor (im, cursor) struct im *im; struct cursor *cursor;} \leftindent{\bold{Method description. sets the cursor for the window associated } \italic{im_SetWindowCursor} with the passed im. This cursor will temporarily override all of the locally set cursors. Calling this function with a NULL cursor pointer will deactivate the currently set window cursor and restore the local ones. \bold{Usage.} To deactivate a cursor, set cursor to NULL. } \paragraph{Setting a cursor for all windows controlled by a process}\indexi{Interaction manager++Setting a process cursor} \indexi{ \italic{im_SetProcessCursor}} \example{im_SetProcessCursor (cursor) struct cursor *cursor;} \leftindent{\bold{Class procedure description. } \italic{im_SetProcessCursor} sets the cursor for all windows controlled by the current process. The process cursor will override (but not reset) the window cursors. This is a class procedure, and requires no im pointer. Calling this function with a NULL cursor pointer will deactivate the currently set process cursor. If a given window has a window cursor, it will be restored, otherwise the window's local cursors will be restored. \begindata{bp,538929736} \enddata{bp,538929736} \view{bpv,538929736,1258,0,0}} \subsection{Directories} \paragraph{Changing the working directory}\indexi{Interaction manager++Changing the working directory} \indexi{ \italic{im_ChangeDirectory}} \example{long im_ChangeDirectory(dirName) char *dirName;} \leftindent{\bold{Class procedure description. } \italic{im_ChangeDirectory} changes the working directory to the specified directory. \bold{Return value.} The function returns 0 if the operation succeeded. \bold{Side effects.} The working directory for the process is changed. \bold{Usage.} You must use this command to change your process's working directory in Toolkit, since this allowed the Toolkit to cache the working directory information in memory. Since the Toolkit often needs to know the current working directory, this in-memory cache allows many Toolkit functions to run considerably faster than would be otherwise possible. } \begindata{bp,538928584} \enddata{bp,538928584} \view{bpv,538928584,1259,0,0} \paragraph{Getting a directory}\indexi{Interaction manager++Getting the current directory} \indexi{ \italic{im_GetDirectory}} \example{char *im_GetDirectory(outputString) char *outputString;} \leftindent{\bold{Class procedure description. } \italic{im_GetDirectory} gets a named directory. \bold{Return value.} This function returns a static pointer to the name of the current working directory. \bold{Usage.} Call this function to get the value of the current working directory. It is considerably faster than calling the Unix system's \italic{getwd} subroutine. \begindata{bp,538927560} \enddata{bp,538927560} \view{bpv,538927560,1260,0,0}} \subsection{Keyboard and user interaction} \paragraph{Giving the keyboard level value}\indexi{Interaction manager++Keyboard level value} \indexi{ \italic{im_KeyboardLevel}} \example{long im_KeyboardLevel() } \leftindent{\bold{Class procedure description. } \italic{im_KeyboardLevel} returns the current keyboard level, that is, the number of calls made to im_Interact (or, equivalently, im_KeyboardProcessor) that are currently on the C stack. Most commands, run from an application's top-level interact loop, would obtain a value of 1 from calling this function. \bold{Return value.} on the stack. The number of calls to im_Interact currently active \bold{Usage. } The primary use for this function is for determining whether exiting the current interact loop (that is, the current call to im_KeyboardProcessor) would result in the entire application exiting. Thus, for example, the "exit" command uses this function to see if you are exiting the editor, or just exiting from a recursive edit. If you are exiting the entire editor, the exit command checks to see if there are any modified buffers, and asks for confirmation before exiting. } \paragraph{Setting the keyboard exit flag}\indexi{Interaction manager++Setting the keyboard flag} \indexi{ \italic{im_KeyboardExit}} \example{void im_KeyboardExit() } \leftindent{\bold{Class procedure description. } \italic{im_KeyboardExit} sets\italic{ keyboardExitFlag} to TRUE. \bold{Side effects.} The next loop through the the loop in \italic{im_KeyboardProcessor}, \italic{im_KeyboardProcessor} will exit rather than interact again. \bold{Usage.} This function is used to terminate a call to \italic{im_KeyboardProcessor}. This will result in the termination of the top-level interact loop, if not in a recursive edit, and in the termination of the recursive edit, if one is active. } \paragraph{Getting the argument state}\indexi{Interaction manager++Getting an argument state} \indexi{ \italic{im_ArgState}} \example{struct im_ArgState *im_GetArgState(im) struct im *im;} \leftindent{\bold{Method description. } \italic{im_GetArgState} get the so-called "argument state" associated with a particular interaction manager. It returns \italic{struct im_ArgState *}. \bold{Return value.} the im. A pointer to the im_ArgState structure contained in \bold{Usage.} The "argument" im functions are used for handling the communication between various keyboard commands required to handle processing of numeric arguments to keyboard commands. For example, under the standard key bindings, the command ^U is bound to a function whose semantics are to perform the next command 4 times. This is implemented by having the ^U command set the im_ArgState structure to indicate that an argument has been provided, and that the argument's value is 4. Many commands interrogate the im_ArgState structure and perform different functions depending upon its value. The user interface guide specifies that this function should intuitively correspond to performing the particular function the appropriate number of times. This function is provided to allow callers to get handles on those fields in the im_ArgState structure for which there are no access methods. \bold{Example.} See the digit commands, ^U command and ^F command in the textview object for an example of how the im_ArgState structure is used for communication between commands. } \paragraph{Clearing an Argument}\indexi{Interaction manager++Clearing an argument} \indexi{ \italic{im_ClearArg}} \example{void im_ClearArg(im) struct im *im;} \leftindent{\bold{Method description. } \italic{im_ClearArg} the value of the argument to its default value of 1. clears \bold{Usage.} This function should probably not exist; it does the same thing as im__ProvideArg(im, 1). } \begindata{bp,538928712} \enddata{bp,538928712} \view{bpv,538928712,1261,0,0} \paragraph{Finding if an argument has been provided}\indexi{Interaction manager++Finding if an argument was provided} \indexi{ \italic{im_ArgProvided}} \example{boolean im_ArgProvided(im) struct im *im;} \leftindent{\bold{Method description. } \italic{im_ArgProvided} to see if an argument has been provided for a manager. checks \bold{Return value.} The function returns TRUE if an argument has been provided to this function, and false otherwise. \bold{Usage.} Many commands perform different when they are provided with an argument, versus when they are invoked normally. For example, the digit commands (keystrokes "0" through "9") are self-inserting when not provided an argument, but actually specify part of the argument if they are provided with one (consider ^U13^F for example, which means "move forward 13 characters"). } \paragraph{Finding the state of an argument}\indexi{Interaction manager++Finding the argument state} \indexi{ \italic{im_Argument}} \example{long im_Argument(im) struct im *im;} \leftindent{\bold{Method description. } \italic{im_Argument}, when called, returns the effective argument passed to a command. If no argument was provided to the command, this function returns 1, otherwise it returns the argument value provided to the command. \bold{Usage.} Most commands are not interested in whether an argument has been explicitly provided, or whether instead they've been invoked normally. Thus just need to know how many times to perform their basic functionality. This function returns that value. \bold{Example.} The "move forward one character" textview command uses this function to compute how many characters to move forward. } \paragraph{Providing an argument}\indexi{Interaction manager++Providing an argument} \indexi{ \italic{im_ProvideArg}} \example{void im_ProvideArg(im, arg) struct im *im; long arg;} \leftindent{\bold{Method description. } \italic{im_ProvideArg} to create or provide an argument for the next command. \bold{Usage.} the next command. is used Certain commands' function is to provide an argument to They invoke this function to set the argument value. \bold{Example.} The ^U command, for instance, sets the argument to 4 times its previous value (if an argument was provided to the ^U command), and otherwise sets the argument value to 4. } \begindata{bp,538929288} \enddata{bp,538929288} \view{bpv,538929288,1262,0,0} \paragraph{Getting a character}\indexi{Interaction manager++Getting a character} \indexi{ \italic{im_GetCharacter}} \example{int im_GetCharacter(im) struct im *im;} \leftindent{\bold{Method description. } \italic{im_GetCharacter} returns the next character typed to the window corresponding to the passed-in interaction manager. \bold{Usage.} It is convenient for certain commands to be able to read a character of input without having to build a keymap to install. For example, the ^X^Q (quote the next character and insert it into the text buffer) is much simpler when written using im_GetCharacter to get the next character typed than it is when written using keymaps to intercept the next typed character. } \begindata{bp,538928968} \enddata{bp,538928968} \view{bpv,538928968,1263,0,0} \paragraph{Asking if the user has Interrupted}\indexi{Interaction manager++Getting a character} \italic{\indexi{im_CheckForInterrupt}} \example{boolean im_CheckForInterrupt(im) struct im *im;} \leftindent{\bold{Method description. } \italic{im_CheckForInterrupt} checks the keyboard queue to determine if the user has typed a control-G. If so, all prior user interactions are discarded and the function returns True; otherwise it returns False. The function does not wait for the next user action if none is pending. \bold{Usage.} When an application is performing a lengthy, possibly erroneous, operation it can check occasionally to see if the user has typed control-G. If so, the operation can terminate itself gracefully. Example: when pasting under X, it may be that the partner process fails to respond, leaving this process in limbo. The operation is implemented to respond to control-G by terminating the paste. } \paragraph{Simulating typing in a window}\indexi{Interaction manager++Typing simulation} \indexi{ \italic{im_DoKey}} \example{void im_DoKey(im, key) struct im *im; long key;} \leftindent{\bold{Method description. typing of the key in a window. } \italic{im_DoKey} simulates \bold{Usage.} This function is used whenever an application wants to simulate the typing of a key to a window. \bold{Example.} Certain commands read input from the keyboard and treat exceptional characters as a directive to exit and execute the exceptional character as a command. By using this command, for example, the incremental search command can terminate execution whenever you type a nonalphanumeric key, and then execute the key as a normal command. } \subsection{Files and buffers} \paragraph{Getting the write ID}\indexi{Interaction manager++Getting the write ID} \indexi{ \italic{im_GetWriteID}} \example{long im_GetWriteID() } \leftindent{\bold{Class procedure description. } \italic{im_GetWriteID} gets a new unique write ID number which can be used by any command that writes a new file containing the representation of one or more data objects. \bold{Return value.} The write ID number. \bold{Usage.} When writing a data object out to a, a write ID must be passed to all of the \italic{dataobject_Write} routines. When an object writes out a sub-object, it passes through the \italic{writeID} parameter passed to its \italic{dataobject_Write} routine. Of course, there must be a root to this tree of dataobject_Write calls; this root call's \italic{writeID} is generated by \italic{im_GetWriteID}. } \begindata{bp,538929416} \enddata{bp,538929416} \view{bpv,538929416,1264,0,0} \paragraph{Setting a program name}\indexi{Interaction manager++Setting a program name} \indexi{ \italic{im_SetProgramName}} \example{void im_SetProgramName(name) char *name;} \leftindent{\bold{Class procedure description. } \italic{im_SetProgramName} sets the program name label associated with all windows associated with the process. \bold{Usage.} The programmer calls this function to set the "program name" label for all of the particular program's windows. } \paragraph{Getting a program name}\indexi{Interaction manager++Getting the program name} \indexi{ \italic{im_GetProgramName}} \example{char *im_GetProgramName() } \leftindent{\bold{Class procedure description. }\italic{im_GetProgramName} returns a pointer to a static character string containing the last program name set, or the one set during initialization. \bold{Return value.} A program name (of type (char *)). } \paragraph{Getting a cut buffer file}\indexi{Interaction manager++Getting a cut buffer} \indexi{ \italic{im_FromCutBuffer}} \example{FILE *im_FromCutBuffer(im) struct im *im;} \leftindent{\bold{Method description. } \italic{im_FromCutBuffer} returns a FILE * that, when read, returns the contents of the cut buffer. \bold{Return value.} The cut buffer file. \bold{Usage.} In order to do a paste operation, you obtain a FILE * from this function, read the contents and insert them into your object. When done, you close the file with im_CloseFromCutBuffer. } \paragraph{Writing to a cut buffer file}\indexi{Interaction manager++Writing to a cut buffer} \indexi{ \italic{im_ToCutBuffer}} \example{FILE *im_ToCutBuffer(im) struct im *im;} \leftindent{\bold{Method description. } \italic{im_ToCutBuffer} returns a FILE * to which one can write to place data in the cut buffer. The data will either create a new cut buffer, or be appended to the current cut buffer, depending upon whether the FILE * is closed using im_CloseToCutBuffer or im_AppendToCutBuffer. \bold{Usage.} This function is used by various cut routine to place data into the cut buffer. } \begindata{bp,538929160} \enddata{bp,538929160} \view{bpv,538929160,1265,0,0} \paragraph{Closing from the cut buffer}\indexi{Interaction manager++Closing a file from the cut buffer} \indexi{ \italic{im_CloseFromCutBuffer}} \example{void im_CloseFromCutBuffer(im, readFile) struct im *im; FILE *readFile;} \leftindent{\bold{Method description. stops reading a file from the cut buffer. } \italic{im_CloseFromCutBuffer} \bold{Usage.} This function is used to close a FILE * returned from im_FromCutBuffer. } \paragraph{Closing the cut buffer}\indexi{Interaction manager++Closing a buffer} \indexi{ \italic{im_CloseToCutBuffer}} \example{void im_CloseToCutBuffer(im, writeFile) struct im *im; FILE *writeFile;} \leftindent{\bold{Method description. } \italic{im_CloseToCutBuffer} closes a cut buffer FILE *, marking the cut as one starting out from an empty cut buffer. \bold{Usage.} When this function is used to close a file obtained from im_ToCutBuffer, it results in the new contents of the cut buffer becoming the current cut buffer. } \paragraph{Rotating the cut buffers}\indexi{Interaction manager++Rotating cut buffers} \indexi{ \italic{im_RotateCutBuffers}} \example{void im_RotateCutBuffers(im, count) struct im *im; long count;} \leftindent{\bold{Method description. } \italic{im_RotateCutBuffers} rotates the cut buffer stack the specified number of times. \bold{Usage.} The interaction manager maintains a stack of cut buffers, and when a new cut buffer is written, it is pushed on top of the stack. However, other cut buffers can still be accessed: this function pops the top cut buffer from the stack and places it at the bottom of the stack. Future pastes will then read the contents of the newly-exposed top-of-stack cut buffer. } \paragraph{Appending to a cut buffer}\indexi{Interaction manager++Appending to a cut buffer} \indexi{ \italic{im_AppendToCutBuffer}} \example{void im_AppendToCutBuffer(im, writeFile) struct im *im; FILE *writeFile;} \leftindent{\bold{Method description. appends a file to a cut buffer. } \italic{im_AppendToCutBuffer} \bold{Usage.} When this function is used to close a cut buffer write, then im, instead of creating a new cut buffer and pushing it on the top of the cut buffer stack, appends the new text to the text already in the top cutbuffer. \bold{Example.} The textview ^K command uses this function to append text from a series of ^K commands to the cut buffer. } \begindata{bp,538928776} \enddata{bp,538928776} \view{bpv,538928776,1266,0,0} \subsection{Attributes} \paragraph{Setting the global initialization}\indexi{Interaction manager++Setting global initialization} \indexi{ \italic{im_SetGlobalInit}} \example{void im_SetGlobalInit(init) struct init *init;} \leftindent{\bold{Class procedure description. } \italic{im_SetGlobalInit} sets the global initialization. \bold{Usage.} files, When using the \italic{init} package for reading init the programmer passes the parsed init file to the interaction manager using this procedure. See the \italic{init} package documentation for more details. }\paragraph{Getting the global initialization}\indexi{Interaction manager++Getting global initialization} \indexi{ \italic{im_GetGlobalInit}} \example{struct init *im_GetGlobalInit() } \leftindent{\bold{Class procedure description. }\italic{im_GetGlobalInit} gets the value last set by \italic{im_SetGlobalInit}. \bold{Return value.} \bold{Usage.} A pointer to a initialization file. Retrieve the value last set by \italic{im_SetGlobalInit}. } \paragraph{Setting the preferred dimensions}\indexi{Interaction manager++Setting preferred dimensions} \indexi{ \italic{im_SetPreferedDimensions}} \example{void im_SetPreferedDimensions(top, left, width, height) long top, left, width, height;} \leftindent{\bold{Class procedure description. }\italic{im_SetPreferedDimensions} sets dimension values. \bold{Usage.} process. } This function sets the desired size for all windows in the \paragraph{Getting dimension values}\indexi{Interaction manager++Getting the current dimensions} \indexi{ \italic{im_GetPreferedDimensions}} \example{void im_GetPreferedDimensions( top, left, width, height) long *top, *left, *width, *height;} \leftindent{\bold{Class procedure description. } \italic{im_GetPreferedDimensions} gets the dimensions sets by \italic{im_SetPreferedDimensions}. \bold{Usage.} Find out what values you passed to the last im_SetPreferedDimensions call. } \begindata{bp,538929352} \enddata{bp,538929352} \view{bpv,538929352,1267,0,0} \paragraph{Setting the last used interaction manager}\indexi{Interaction manager++Setting the last used manager} \indexi{ \italic{im_SetLastUsed}} \example{void im_SetLastUsed(used) struct im *used;} \leftindent{\bold{Class procedure description. } Generally called internal to the interaction manager to keep track of the interaction manager (and associated window) from which the last user-interaction originated. Allows im_GetLastUsed to work. } \paragraph{Getting the last used interaction manager}\indexi{Interaction manager++Getting the last used manager} \indexi{ \italic{im_GetLastUsed}} \example{struct im *im_GetLastUsed() } \leftindent{\bold{Class procedure description. } The last used interaction manager (and associated window) can be used for such things as putting up a dialog box in the window from which a particular interaction originated. Most of the time, a programmer has a view in hand whose interaction manager can be obtained via view_GetIM, but on occasion a timer-based interaction will occur (such as checkpointing all files) resulting in output to be displayed on a "useful" window. The last-used window is as good an approximation as any to a "useful" window. \bold{Return value.} The interaction manager from which the last user interaction (mouse, keyboard or menu selection) took place. } \paragraph{Getting the global last command value}\indexi{Interaction manager++Getting the global last command} \indexi{ \italic{im_GetLastCmd}} \example{long im_GetLastCmd(im) struct im *im;} \leftindent{\bold{Method description. global last command value. } \italic{im_GetLastCmd} gets the \bold{Usage.} The last command variable is organized as a 32-bit bit mask, where each bit indicates a different class of command. The variable represents a description of the type of the last command handled by the im. An unused bit may be allocated using the im_AllocLastCmd function. A command may then set a bit-mask representing all of the properties that describe it. \bold{Example.} The ^K command, for instance, sets the bit indicating that the last command typed was a text-killing command. This bit is interpreted by successive ^K commands as indicating that text should be appended to the cut buffer, rather than clearing the cut buffer first, as would otherwise occur. } \paragraph{Setting the global last command value.}\indexi{Interaction manager++Setting the global last command} \indexi{ \italic{im_SetLastCmd}} \example{void im_SetLastCmd(im, cmd) struct im *im; long cmd;} \leftindent{\bold{Method description. global last command value to \italic{cmd}. \bold{Usage.} } \italic{im_SetLastCmd} the See im_GetLastCmd and im_AllocLastCmd.} \begindata{bp,538929096} \enddata{bp,538929096} \view{bpv,538929096,1268,0,0} \paragraph{Setting the title}\indexi{Interaction manager++Allocate the last command} \indexi{ \italic{im_SetTitle}} \example{void im_SetTitle(im, title) struct im *im; char *title;} \leftindent{\bold{Method description. } \italic{im_SetTitle} sets the title in the window manager's window, if any exists. \bold{Usage.} Many programs use this to display an indication of which application is controlling a particular window.} \paragraph{Getting the title}\indexi{Interaction manager++Getting the title from a window manager} \indexi{ \italic{im_GetTitle}} \example{char *im_GetTitle(im) struct im *im;} \leftindent{\bold{Method description. title. } \italic{im_GetTitle} gets the \bold{Usage.} This routine is used to return the value displayed in the window manager title area. } \subsection{Working with interaction manger handles} \paragraph{Allocating the last command}\indexi{Interaction manager++Allocating the last command handle} \indexi{ \italic{im_AllocLastCmd}} \example{long im_AllocLastCmd() } \leftindent{\bold{Class procedure description. } \italic{im_AllocLastCmd} is used to allocate a "last command handle" for use by the keymap routines. \bold{Return value.} command. A new handle, representing a new type of keyboard \bold{Side effects.} allocated. More of the "last command" address space is \bold{Usage.} If you are writing keyboard commands whose function depends upon the previous commands executed, you you may use this function to allocate a new "type" of command. For example, the ^K (kill text to end of line) command appends text to the cut buffer, rather than clearing out the previous cut buffer contents, if the previous command was a "text-killing" command. In this example, "text-killing" command is a "type" of command. You, as a Toolkit programmer, may need to allocate a new command "type" for your own commands. This function allocates a command type that can be used with the routines in the keymap package to easily tell if the previously-executed command was of your new particular command type. } \begindata{bp,538928840} \enddata{bp,538928840} \view{bpv,538928840,1269,0,0} \paragraph{Adding an arbitrary file handler}\indexi{Interaction manager++Adding a file handle} \indexi{ \italic{im_AddFileHandler}} \example{boolean im_AddFileHandler (file, proc, procdata, priority) FILE *file; int (*proc)(); char *procdata; int priority;} \leftindent{\bold{Class procedure description. } One of the operations that \italic{im_Interact } can perform is calling an input handler for a file descriptor from which input is sought. Such an operation is enabled by calling \italic{im_AddFileHandler}, which associates a function to be called with the file descriptor when input is available. The parameter\italic{ file }is the pointer to a file in which the caller is interested. \italic{proc }is the address of a procedure to call when input appears from the file descriptor. \italic{ procdata} will be passed to the procedure provided by \italic{proc}, when it is called. The last parameter is a priority. Toolkit can only remember a fixed number of handlers, and the ones that it keeps are those associated with the smallest-numbered \italic{priority}. \bold{Return Value.} Returns a boolean -- TRUE if the procedure was successful in associating a function to be called with the file descriptor, FALSE otherwise. \bold{Side effects.} The internal Toolkit file table is modified to keep track of this file entry. \bold{Usage.} In general, one calls this entry point whenever you must wait for input to become available from a file descriptor. If the programmer, instead of calling this function, simply called the read function on the appropriate file descriptor, the Toolkit would block until input arrived. When using this function, the Toolkit can continue to process mouse events, keyboard events and menu-driven events until the very moment when the input actually arrives from the specified file descriptor. Clearly, this function is of little use when reading from a disk file, where input always immediately available if it is present at all, but can be very useful when, for instance, waiting for data from a network connection, or from another terminal. } \paragraph{Removing a file handler}\indexi{Interaction manager++Removing a file handle} \indexi{ \italic{im_RemoveFileHandler}} \example{void im_RemoveFileHandler (file) FILE *file;} \leftindent{\bold{Class procedure description. } \italic{im_RemoveFileHandler} removes one handler for the named file descriptor from the list of handled file descriptors. The parameter\italic{ file} is a pointer to the file descriptor. \bold{Side effects.} The Toolkit file information associated with the file descriptor is removed. \bold{Usage.} Sometime after having called im_AddFileHandler, your program may no longer be interested in input from this particular device. Use this routine to stop the notification calls from im_AddFileHandler. } \begindata{bp,538928648} \enddata{bp,538928648} \view{bpv,538928648,1270,0,0} \paragraph{Adding a "can-out" handler}\indexi{Interaction manager++Adding a file handle} \indexi{ \italic{im_AddCanOutHandler}} \example{boolean im_AddCanOutHandler ( file, proc, procdata, priority) FILE *file; int (*proc)(); char *procdata; int priority; } \leftindent{\bold{Class procedure description. } \italic{im_AddCanOutHandler} adds a can-out handler which is a function called whenever the manager is able to output characters onto a file. \bold{Side effects. } state. Modifies the Toolkit's internal file handling \bold{Usage.} This routine is analogous to im_AddFileHandler. Instead of calling the \italic{proc} procedure when input is available from the specified file descriptor however, the procedure \italic{proc} is instead invoked when room is again available for output on the specified output file descriptor. For example, the \italic{typescript} program uses this function to determine when it is permitted to send more user type-ahead (lines the user typed before the program was ready for more input) to the shell. } \paragraph{Removing a can-out handler}\indexi{Interaction manager++Removing a handle} \indexi{ \italic{im_RemoveCanOutHandler}} \example{void im_RemoveCanOutHandler (file) FILE *file;} \leftindent{\bold{Class procedure description. } \italic{im_RemoveCanOutHandler} deletes a can-out handler when it is no longer needed. \bold{Usage.} This function is analogous to im_RemoveFileHandler, and is used to remove an output file handler when the program is no longer interested in when the file descriptor may be sent new output. } \paragraph{Specifying a signal handler}\indexi{Interaction manager++Specifying a signal handle} \indexi{ \italic{im_SignalHandler}} \example{void im_SignalHandler(signalNumber, proc, procdata) long signalNumber; int (*proc)(); char *procdata;} \leftindent{\bold{Class procedure description. } \italic{im_SignalHandler} creates a signal handler. This function associates a C procedure \italic{proc} with the Unix signal \italic{signalNumber}. When the particular signal arrives, the proc will be called by the interaction manager. \bold{Side effects.} Im's internal state is modified. \bold{Usage. }The advantage of using im_SignalHandler instead of the normal Unix \italic{signal} subroutine is that the SignalHandler procedure is invoked by the interaction manager at the next interaction, not at the time the signal actually arrives. While this introduces a slight delay, it also makes it much simpler to write a signal procedure, since it is no longer being executed at "interrupt level." For example, normally you are not allowed to call \italic{malloc} from a signal handler, since you may have been executing in \italic{malloc} or \italic{free} when the signal hit. However, since your \italic{proc} procedure will not be executed until the next call to \italic{im_Interact}, you can be sure that you won't be in the middle of executing any non-reentrant code (like \italic{malloc} or \italic{free}) when your \italic{proc} routine is called. } \begindata{bp,537558784} \enddata{bp,537558784} \view{bpv,537558784,1272,0,0} Copyright 1992 Carnegie Mellon University and IBM. All rights reserved. \smaller{\smaller{$Disclaimer: Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of IBM not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ANY COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. $ }}\enddata{text,538321152}