Wiki source for ioGetNextEvent


Show raw source

======**sqInt ioGetNextEvent( sqInputEvent *evt)**======

**Parms**:
Evt is a pointer to an array of words that we populate with event data.

**return**: NONE, fake return of zero
Can set success() to fail, not fail the primitive

**From**: Interpreter
**Why**:
To get FIFO UI event data from the UI

**Responsibility**:
Most VMs have a FIFO queue that contains subclasses of sqInputEvent to record mouse, keyboard, drag/drop, menu and window events.
Most VMs call ioProcessEvents if the queue is empty

**MacIntosh**
//os-9/OSXCarbon//
ioProcessEvents is always called.

//Cocoa://
See iPhone

**iPhone**
Uses proper multi-threaded Queue class for the FIFO queue

Adds a new event type that indicates we have a pending complex data object to return. This data object is to support the
multi-touch UI. The smalltalk event queue processing logic has to make a different call to fetch the data from another queue.
This requires a change to the currently shipping VMMaker to allow us to pass up a smalltalk object, versus just integers.

**Unix**
IF there are no events it calls ioProcessEvents, otherwise return next event on queue. Queue is not locked

**Windows**
IF there are no events it calls ioProcessEvents, otherwise return next event on queue. Queue is not locked

**BUGS**
Most VMs don't consider locking the FIFO queue, are they all thread safe?
Some VMs return true/false, but the return value is ignored.

=====Thoughts on events:=====

/* mouse input event */
typedef struct sqMouseEvent
{
int type; /* EventTypeMouse */
unsigned int timeStamp; /* time stamp */
int x; /* mouse position x */
int y; /* mouse position y */
int buttons; /* combination of xxxButtonBit */
int modifiers; /* combination of xxxKeyBit */
int reserved1; /* reserved for future use */
int windowIndex; /* host window structure */
} sqMouseEvent;

where
timeStamp is the ms clock ioMSecs()
x, y are the mouse location in pixel coordindates local to the window
windowIndex is the index number for the window that posted the mouse event.

To complicate things you have 4 different type of events that can occur button down, button up, mouse move, and mouse wheel event
For the mouse wheel event we translate that into synthetic events for keyboard entry using cursor up/down/left/right based on the mouse wheel geometry and the number of cursor events then map to some unit of measure for the wheel (usually one unit of wheel movement means one cursor movment).

Since mice have 1 or more buttons we support the traditional three Smalltalk buttons (red, yellow, blue), these can be generated by having a mouse with the right physical buttons, or by using a single button mouse with alt/control/cmd/option modifier keys to indicate alternate button down choices.

From wikipedia: "The ground-breaking Xerox Parc Alto and Dorado computers from the mid-1970s used three-button mice, and each button was assigned a color. Red was used for the left (or primary) button, yellow for the middle (secondary), and blue for the right (meta or tertiary). "

We cache the old event and compare to the new event based on button state, mouse point location. If the data is the same we don't forward that to the queue. This is needed on systems that have some sort of polling and would return cursor at x,y, cursor at x,y every 16ms, versus generating a new event only if the state is different.

Please note it is possible then to generate button down at 10,10 followed by mouse moved at 10,10 (with button down), which seems a duplicate, but in one case the button went down, the other it moved.

**MacIntosh**
//os-9/OSXCarbon//

On the macintosh get mouse location, map to local coordinates, we use the info-plist to map the button logic to a desired button logic for running as an application, or running via the browser. In both cases we end up swapping the buttons to first deal with cmd/opt/alt usage, or to deal with cases where the user might have a two or three button mouse.

Events handled are:

{ kEventClassMouse, kEventMouseMoved},
{ kEventClassMouse, kEventMouseWheelMoved},
{ kEventClassMouse, kEventMouseDragged},
{ kEventClassMouse, kEventMouseUp},
{ kEventClassMouse, kEventMouseDown},
{ kEventClassMouse, kEventMouseEntered },
{ kEventClassMouse, kEventMouseExited }

kEventMouseEntered, and kEventMouseExited are not presented as mouse events, they are used to alter the cursor from the default cursor to the cursor set by Squeak when it enters or exits the window.

The macintosh does not have good control over modifier key changes, so on a kEventRawKeyModifiersChanged we fake a mouse move
so that EventSensor caches the state of the modifier keys.

//Cocoa://
See the carbon logic, we still use the info-plist data to map mouse buttons etc...

On the NSView we consider
mouseMoved,mouseDragged,rightMouseDragged,otherMouseDragged,scrollWheel,mouseUp,rightMouseUp,otherMouseUp,mouseDown,rightMouseDown,otherMouseDown

As like for Carbon we also look at mouseEntered mouseExited to set the default cursor.

**iPhone**

There are no mouse events on the iPhone. Rather there are touch event sets which bundle up and give back in ioGetNextEvent. Then code in the EventSensor processes the complex event and dispatches the proper mouse down,move, up events. There is no way to indicate other mouse buttons since there are no modifier. Likely someone has to come up with a gesture that makes sense?

**Unix**

**Windows**
map the buttons correctly depending on if there are 1, 2, or 3 buttons on the mouse
3 button mice RYB
2 button mice RBY
1 button mouse R

**BUGS**
macintosh, if you hold the cmd/opt/control keys down and click we only think you have the control key down for mapping purposes
macintosh, although event logic does have the concept of left/right shift key & command key. some/many flavors of older powerbooks tied shift
and command key lines together so there was no way to determine if the left key or right key went down.

/* keyboard input event */
typedef struct sqKeyboardEvent
{
int type; /* EventTypeKeyboard */
unsigned int timeStamp; /* time stamp */
int charCode; /* character code in Mac Roman encoding */
int pressCode; /* press code; any of EventKeyXXX */
int modifiers; /* combination of xxxKeyBit */
int utf32Code; /* UTF-32 unicode value */
int reserved1; /* reserved for future use */
int windowIndex; /* host window structure */
} sqKeyboardEvent;

where
timeStamp is the ms clock ioMSecs()
charCode is the mac roman character value of the key pressed (key char), or a virtual key code (key up/down)
pressCode is
/* Keypress state for keyboard events. */
#define EventKeyChar 0
#define EventKeyDown 1
#define EventKeyUp 2
modifiers keyboard modifier state
utf32Code unicode 32 value (key char only), zero otherwise
windowIndex which window did the keyboard event go to

To complicate things, Tweak uses virtual key codes, but Squeak uses mac roman or more modern implementations like Sophie use uf32Code
Also due to the sub-standard Windows api utf32Code is only available on EventKeyChar not on key up or down which leads to the fun state where tweak platforms have to map key up virtual codes to the unicode value in order to make sense of what is being pressed.

Note the virtual key code is the concept on windows of having VK_SHIFT or VK_A which are magic numbers and if you know the decoder then well you can say Oh that magic number means "A" in whatever character set you are working with. On the macintosh the virtual key codes are the numbers assigned to keys on a keyboard, see:
http://developer.apple.com/documentation/mac/Text/Text-571.html
So we can say the virtual key code of zero maps on usa keyboards to 'A'

Normally the process is
key down
key char
key up

But for Repeat key, again because of windows limitations the event situation for repeating key is
key down
key char
key down
key char
key up

**MacIntosh**
//os-9/OSXCarbon//
To complicate things we track raw keyboard events and kEventTextInputUnicodeForKeyEvent so that we can report on the keys the
person used, but also then the resulting unicode since a unicode phrase might be generated by numerious keystrokes, or dead keys used
to create accented characters.

This complicated procedure borrowed code from the unix implementation where it records raw key down events, or key repeat events in a keymap, then on a raw key up it generates a EventKeyUp. Usually the key stroke key down, key up would then generate
record raw key down
see kEventTextInputUnicodeForKeyEvent
which would generate a
EventKeyDown using the macintosh virtual key code kEventParamKeyCode
EventKeyChar using the mac roman key value and the unicode value
EventKeyUp (MAYBE) using the macintosh virtual key code if this is a unicode phrase we are seeing due to dead key input logic
finally
the raw key up
would generate a EventKeyUp if it mapped to a recorded raw key down

This leads to the case where dead key input can for example geneate
key up for accent
key down for e
key char for accented e
key up for e

Note for wheel mouse we generate the key down/char/up for cursor keys

//Cocoa://
The whole keyboard interaction on Cocoa is complex. First you have modifier key events, then keyDown: and KeyUp: but also since we are emulating a text entry view we get insertText: or insertText:replacementRange: messages, plus then about 50 other messages that are given when you use the cursor or other meta-keys in conjunction with modifer keys. Oh say moveToBeginningOfDocument (plus 50 others), or of course more if you use the Function Keys, along with more exceptions for OpenStep keyboard means. In general an attempt is made then to translate the NSTextInputClient & OpenStep key encoding message back into a macintosh keycode, macroman & unicode value with modifiers.

Likely 3/4 of the code for the sqSqueakOSXNSView relates to keyboard handling.

**iPhone**
in 3.2 we enable UIKeyInput on the view. So if you make the SqueakUIView a first responder then the keyboard comes up.
Unlike the Cocoa NSTextInputClient, UIKeyInput only has insertText: & deleteBackward
We then take the unicode char and do NSMacOSRomanStringEncoding, then we have a hard coded unicodeToKeyCode table
This table was built from some os-9 implementation and tested by Scratch.app, plus now used by eToys.app on the iPad.


**Unix**
very straight forward and from what people say doesn't work well with unicode

**Windows**
record WM_KEYDOWN, WMSYSKEYDOWN, WM_KEYUP,WMSYSKEYUP, WM_CHAR, WM_SYSCHAR
watch out for CR
very straight forward and from what people say doesn't work well with non-english keyboards attempting magic dead key entries.

**BUGS**
Unclear if unix or windows platforms offer good unicode & dead key support.

/* drop files event */
typedef struct sqDragDropFilesEvent
{
int type; /* EventTypeDropFiles */
unsigned int timeStamp; /* time stamp */
int dragType; /* one of DragXXX (see below) */
int x; /* mouse position x */
int y; /* mouse position y */
int modifiers; /* combination of xxxKeyBit */
int numFiles; /* number of files in transaction */
int windowIndex; /* host window structure */
} sqDragDropFilesEvent;

#define DragEnter 1 /* drag operation from OS entered Squeak window */
#define DragMove 2 /* drag operation from OS moved within Squeak window */
#define DragLeave 3 /* drag operation from OS left Squeak window */
#define DragDrop 4 /* drag operation dropped contents onto Squeak. */

timeStamp is the ms clock ioMSecs()
dragType is DragXXX
x, y are local mouse positions
modifer is keyboard mod bits
numFiles is number of files in event
windowIndex is window index that drop occurred in.

This event type is optional, it depends on if the operating system allows drag and drop of files from the filing system to a window.

**MacIntosh**
//os-9/OSXCarbon//
We support this using the old carbon interface.
We also abuse this interface to support the drag and drop of files or double-click of files to open squeak.
When a macintosh carbon vm starts up it may receive one or more apple events for document open. These are examined and a decision is made to pick the first image file it finds. For example you can drag an image and 5 jpgs to a squeak VM then you expect to open the image and then open the 5 jpgs.
Also because this is using the multi-document feature of the operating system, we also get an open document request when squeak is running. Because we don't support opening two images at the same time, we are forced then to either (a) present the image file as a binary file to be read, or (b) we launch a new process using the same VM binary and ask it to open the image file.

Issues, at startup time it doesn't see the squeak document you double-clicked on? Why? This is a bug in the Squeak image, from time to time some clever programmer decides to flush the queued events so that he can ignore keyboard or mouse events at startup time. However he ignores the flush but retain DnD method and goes for the flush everything. That then flushs the pending squeak document open. Other operating systems may instead pass the document as parms to the application at startup time, but that is not how launch services works on the macintosh.

//Cocoa://
We support the cocoa drag api. That said.
You can get a DragEnter, DragMove, DrageLeave, DragDrop.

First we determine if you are dragging one or more squeak images because we need to handle them differently.
For the non squeak images you are dragging we map the cocoa drag events to the squeak drag events.

For the squeak images we use LSOpenFromURLSpec to ask launch services to open them.

Note on NSApp application:openFile: we also use LSOpenFromURLSpec to open other images, this is to handle the case where you drag image files to the squeak app to launch it.

**iPhone**
No such feature

**Unix**
Supported

**Windows**
Supported

**BUGS**
Drag Enter, Move, Leave usually were not used by any images so no-one complained if it worked or not.
On the macintosh there was a problem when a drag event occurred and it was being serviced by the image and another drag occured it would
overrite information about how many items were newly dragged versus being processed. This led to a lock where we lock the drag queue
until the has processed the drag request. This does then lead to a hung image if processing the drag request fails in an walkback.

Not sure if this problem affects other platforms, since the macintosh process the incoming drag event on another thread so it's possible to have race conditions.

macintosh, not sure about modifiers on drag/drop after all click hold and click-hold with cmd key have different meanings in the Finder I doubt you should think that drag with shift, or drag with option key down might give different results, it might not be possible to do


/* menu event */
typedef struct sqMenuEvent
{
int type; /* type of event; EventTypeMenu */
unsigned int timeStamp; /* time stamp */
/* the interpretation of the following fields depend on the type of the event */
int menu; /* platform-dependent to indicate which menu was picked */
int menuItem; /* given a menu having 1 to N items this maps to the menu item number */
int reserved1; /* reserved for future use */
int reserved2; /* reserved for future use */
int reserved3; /* reserved for future use */
int windowIndex; /* host window structure */
} sqMenuEvent;

timeStamp is the ms clock ioMSecs()
menu is a magic number to identify the menu
menuItem is a magic number to identify the menu item that was invoked.
windowIndex menu event could be related to a specific menu

This event type is optional, it depends on if the operating system supports some sort of menuing system on the window outside of any squeak implementation, or like the menu bar on the macintosh


**MacIntosh**
//os-9/OSXCarbon//
Supported with optional image code, see Sophie or Scratch
In general when the user picks a menu item out of a menu we create a menu event that points to the menu handle, and set menuItem to the menu item choosen. For menu items which are state away (ticks) then code is required in the image to either cache or know the tick state. In general this event type is the easiest to implment but the support code to make the menus via FFI or primitives is *harder*

//Cocoa://
2010 this is being written (someday)

**iPhone**
Not supported

**Unix**
Not supported

**Windows**
Not supported

**BUGS**
general lack of interest

/* window action event */
typedef struct sqWindowEvent
{
int type; /* type of event; EventTypeWindow */
unsigned int timeStamp; /* time stamp */
/* the interpretation of the following fields depend on the type of the event */
int action; /* one of WindowEventXXX (see below) */
int value1; /* used for rectangle edges */
int value2; /* used for rectangle edges */
int value3; /* used for rectangle edges */
int value4; /* used for rectangle edges */
int windowIndex; /* host window structure */
} sqWindowEvent;

#define WindowEventMetricChange 1 /* size or position of window changed - value1-4 are left/top/right/bottom values */
#define WindowEventClose 2 /* window close icon pressed */
#define WindowEventIconise 3 /* window iconised or hidden etc */
#define WindowEventActivated 4 /* window made active - some platforms only - do not rely upon this */
#define WindowEventPaint 5 /* window area (in value1-4) needs updating. Some platforms do not need to send this, do not rely on it in image */
#define WindowEventStinks 6 /* this window stinks (just to see if people read this stuff) */

When the Sophie team started work on Sophie, the funders insisted/demanded that Squeak support multiple windows. This led to a multi-month effort by John M McIntosh and Tim Rowledge to make Squeak understand windows. Because interaction with windows can generate async events we have this event type to handle resizing, iconising, activate, updating and closing. See Areithfa Ffenestri http://wiki.squeak.org/squeak/3862

Note this does allow things like the ability to close the main squeak window (if the window is opened with a close box)
**MacIntosh**
//os-9/OSXCarbon//
Fully supported

//Cocoa://
2010 this is being written
But we do support the window close logic which is also triggered on application quit or dock quit item.
Most *modern* play nice smalltalk images now look for the window close event and put up a morphic dialog asking what to do.

**iPhone**
not supported

**Unix**

**Windows**
Fully supported

**BUGS**
general lack of interest, although from time to time people are prodded to remember they could use these events and Areithfa Ffenestri to solve some issues, like notification when the main window is closed.




Valid XHTML :: Valid CSS: :: Powered by WikkaWiki