Input: 2.1 Mouse Input: Mouse Events

Up: GEOS SDK TechDocs | Up | Prev: 2 Mouse Input | Next: 2.2 Gaining the Mouse Grab

Each time the user moves the mouse or clicks a mouse button, GEOS generates a mouse event and passes it to the proper object. Mouse events are actually MetaClass messages that any object may intercept. Default handlers for these messages typically do nothing, so if you do not handle a particular event, it will likely be ignored.

GEOS uses three basic types of mouse events: button, pointer, and drag events. Button events indicate when the user has either pressed or released any mouse button (double-clicks are considered Button events). Pointer events indicate that the mouse has been moved. Drag events indicate the user has clicked and dragged the mouse. All of these types pass information about the mouse context and the operations currently in progress.

The Input Manager checks both the button state and the mouse movement before deciding on an event's type. For example, ifthe user clicks twice quickly, the Input Manager decides whether the user intended a double-click or a click-move-click. Objects receiving the events do not have to differentiate between the two; the events automatically contain the required information.

Pointer events are fairly straightforward; when the mouse is moved, the Input Manager generates the proper MSG_META_MOUSE_PTR indicating the move. This message also indicates the state of the mouse buttons and keyboard modifier keys.

Button events are quite a bit more complex. With each button press or release, the Input Manager generates a MSG_META_MOUSE_BUTTON which gets translated into the proper press/release/drag event before being passed on to the application. The final message generated depends on which button was pressed, whether large graphics coordinates are being used, and whether the event is being sent pre-passive or post-passive.

Among Button events, there are two basic types: the press and the release. All press events are of the form MSG_META_START_... , and all release events are of the form MSG_META_END_... . The last portion of the message name is the function of the button pressed or released. The various buttons are referred to by their meaning to the Specific UI, as follows:

SELECT
The button used for making selections. In OSF/Motif and many other Specific UIs, this is the left mouse button.
MOVE_COPY
The button used for quick-copies and quick-moves of data. In OSF/Motif, this is the right mouse button. For single-button mice, a key sequence plus a mouse click is often used.
FEATURES
The button used to bring up a "features" pop-up menu or dialog box. In some Specific UIs, this is the middle or the right mouse button. For single- or two-button mice, a key sequence plus a mouse click is often used.
OTHER
Any button not designated one of the three categories above. This category can also be used to indicate when the user presses more than one button at a time.

A press event indicates the user pressed down on the particular button. A release event indicates the user released the button. If the user presses a button and moves the mouse, a drag event will be sent after the initial press event. If the user double-clicks, a special flag will be sent with a single press event; it is up to the application to handle double-clicks differently.

Drag events are of the form MSG_META_DRAG_... , similar to Button events. Each of the above button types has a corresponding drag message. If the user presses a mouse button and quickly moves the mouse more than a specified distance, or if he holds a particular mouse button down more than a specified time, the Input Manager will send a drag event after the press event. A single release event signifies the user released the mouse button, just as with normal presses.

There is also a complete set of events used for large documents. If an object has large bounds, or if a GenView is set up to display a large content, large mouse events will be generated instead of normal mouse events. Large events take the form MSG_META_LARGE_... . For example, the large version of MSG_META_MOUSE_PTR is MSG_META_LARGE_PTR .

Below are listed all the standard mouse events your objects may be interested in handling. Most objects will be interested in only a small subset of these.

MSG_META_MOUSE_PTR
The standard Pointer event, generated whenever the mouse moves without a button down.
MSG_META_START_SELECT
Generated when the user presses the select button.
MSG_META_END_SELECT
Generated when the user releases the select button.
MSG_META_START_MOVE_COPY
Generated when the user presses the move/copy button.
MSG_META_END_MOVE_COPY
Generated when the user releases the move/copy button.
MSG_META_START_FEATURES
Generated when the user presses the features button.
MSG_META_END_FEATURES
Generated when the user releases the features button.
MSG_META_START_OTHER
Generated when the user presses a button combination not recognized as select, move/copy, or features.
MSG_META_END_OTHER
Generated at the release of the combination that generated the MSG_META_START_OTHER .
MSG_META_DRAG_SELECT
Generated between a press and release of the select button if the user holds the button down or if the user moves the mouse.
MSG_META_DRAG_MOVE_COPY
Generated between a press and release of the move/copy button if the user holds the button down or if the user moves the mouse.
MSG_META_DRAG_FEATURES
Generated between a press and release of the features button if the user holds the button down or if the user moves the mouse.
MSG_META_DRAG_OTHER
Generated between a press and release of a button not specified above if the user holds it down or if the user moves the mouse.

Listed below are the large equivalents of the above messages.

MSG_META_LARGE_PTR
MSG_META_LARGE_START_SELECT
MSG_META_LARGE_END_SELECT
MSG_META_LARGE_START_MOVE_COPY
MSG_META_LARGE_END_MOVE_COPY
MSG_META_LARGE_START_FEATURES
MSG_META_LARGE_END_FEATURES
MSG_META_LARGE_START_OTHER
MSG_META_LARGE_END_OTHER
MSG_META_LARGE_DRAG_SELECT
MSG_META_LARGE_DRAG_MOVE_COPY
MSG_META_LARGE_DRAG_FEATURES
MSG_META_LARGE_DRAG_OTHER

All the normal (as opposed to large) mouse events pass and return the same values. Each event differs based on the message itself; an object knows that MSG_META_START_SELECT is inherently different from MSG_META_START_MOVE_COPY , even though they may pass the exact same values.

Structure of Mouse Events

Each mouse event passes three items of data and one pointer to a return structure. The three parameters are listed below; the fourth, the return structure, is detailed in the next section.

xPosition
The horizontal position of the pointer in document coordinates in the window when the event was generated.
yPosition
The vertical position of the pointer in document coordinates in the window when the event was generated.
inputState
A word of flags indicating the state of the mouse buttons and the UI functions (such as quick-transfer) that were active when the event was generated.

The first two indicate the position of the mouse in the document. The third, inputState , consists of two bytes of flags. The first byte indicates the type of Button event and the state of the mouse buttons during the event. It is a record of type ButtonInfo and has seven flags:

BI_PRESS
Set if this is a press event rather than a release or drag.
BI_DOUBLE_PRESS
Set if this is actually a double-press (GEOS automatically detects double presses).
BI_B3_DOWN
Set if button number three is being held down.
BI_B2_DOWN
Set if button number two is being held down.
BI_B1_DOWN
Set if button number one is being held down.
BI_B0_DOWN
Set if button number zero is being held down.
BI_BUTTON
Set if this is a Button event, clear if a Pointer event.

The second byte of inputState is a record of UIFunctionsActive , which describes which of several UI functions are currently underway. The flags set in this byte are used primarily by the UI, and you will probably not have to check them. The flags allowed, however, are listed below.

UIFA_SELECT
Set if the basic mouse function is underway.
UIFA_MOVE_COPY
Set if a move/copy (quick-transfer) operation is underway.
UIFA_FEATURES
Set if the features popup menu or dialog is open.
UIFA_CONSTRAIN
Set if a modifier key set as a "constraint" key is pressed (e.g., the user holds the Shift key while grabbing an object control point).
UIFA_ADJUST
This is the same bit as UIFA_MOVE and UIFA_POPUP, below. When UIFA_SELECT is also set, this flag indicates that the select event should act as a toggle event.
UIFA_EXTEND
This is the same bit as UIFA_COPY and UIFA_PAN, below. When UIFA_SELECT is also set, this flag indicates that the select event should extend any selection already made (add the area/objects to the current selection).
UIFA_MOVE
This is the same bit as UIFA_ADJUST and UIFA_POPUP. When UIFA_MOVE_COPY is also set, this flag indicates that the operation should be considered a move rather than a copy.
UIFA_COPY
This is the same bit as UIFA_EXTEND and UIFA_PAN. When UIFA_MOVE_COPY is also set, this flag indicates the operation should be considered a copy rather than a move.
UIFA_POPUP
This is the same bit as UIFA_ADJUST and UIFA_MOVE, above. When UIFA_FEATURES is also set, this flag indicates the "features" button brings up a popup menu or dialog box.
UIFA_PAN
This is the same bit as UIFA_EXTEND and UIFA_COPY, above. When UIFA_FEATURES is also set, this flag indicates the "features" button has initiated pan-style scrolling.

Return Values for Mouse Events

One of the parameters of every mouse event is a pointer to a MouseReturnParams structure. This structure is passed empty; it is up to the event handler to fill it with the proper return values. The MouseReturnParams structure's definition is given below:

typedef struct {
    word                unused;  /* for alignment */
    MouseReturnFlags    flags;
    optr                ptrImage;
} MouseReturnParams;

Every time you handle a mouse event, you must fill in the flags field. This describes how the event was handled so the UI knows whether to pass it on to another object, change the pointer image, or treat the event as having been handled. The flags you can return are

MRF_PROCESSED
The event was handled. If you do not set this flag upon return, the window will think the event was not handled and may pass it on to another child.
MRF_REPLAY
The event may or may not have been handled, but it should be rebroadcast as if it had not been. This is used primarily when an object gives up the mouse grab because the mouse has strayed outside its bounds.
MRF_PREVENT_PASS_THROUGH
The event should not be passed through to the active or implied grab object. This is set only by pre-passive handlers which want to filter the event and keep the active or implied grabs from receiving it.
MRF_SET_POINTER_IMAGE
The pointer should be set to a new image. If this flag is returned, you must also return an optr in the ptrImage field (see below).
MRF_CLEAR_POINTER_IMAGE
The pointer image will be reset to the default. See Setting the Pointer Image .

If you return MRF_SET_POINTER_IMAGE, you must specify the new image to be set. An object may want to set the pointer to a new image when it is over the object's bounds or during a drag operation. For example, if the user selects a drawing tool, the tool might set the pointer to cross-hairs instead of the default arrow.

To set the pointer's image, you must return the handle and chunk handle of a chunk containing a PointerDef structure. Return it in the form of an optr in the ptrImage field of the return structure. For full information on PointerDef and defining pointer images, see Setting the Pointer Image .

If you are not setting the pointer image, return a NullOptr in ptrImage . You do not have to return anything in the unused field.


Up: GEOS SDK TechDocs | Up | Prev: 2 Mouse Input | Next: 2.2 Gaining the Mouse Grab