Revision [422]

This is an old revision of ioGetNextEvent made by JohnMcIntosh on 2010-09-12 22:16:23.

 

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:


typedef struct sqMouseEvent
{
int type; unsigned int timeStamp; int x; int y; int buttons; int modifiers; int reserved1; int windowIndex; } 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.

typedef struct sqKeyboardEvent
{
int type; unsigned int timeStamp; int charCode; int pressCode; int modifiers; int utf32Code; int reserved1; int windowIndex; } 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
#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.

typedef struct sqDragDropFilesEvent
{
int type; unsigned int timeStamp; int dragType; int x; int y; int modifiers; int numFiles; int windowIndex; } sqDragDropFilesEvent;

#define DragEnter 1 #define DragMove 2 #define DragLeave 3 #define DragDrop 4 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


typedef struct sqMenuEvent
{
int type; unsigned int timeStamp; int menu; int menuItem; int reserved1; int reserved2; int reserved3; int windowIndex; } 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

typedef struct sqWindowEvent
{
int type; unsigned int timeStamp; int action; int value1; int value2; int value3; int value4; int windowIndex; } sqWindowEvent;

#define WindowEventMetricChange 1 #define WindowEventClose 2 #define WindowEventIconise 3 #define WindowEventActivated 4 #define WindowEventPaint 5 #define WindowEventStinks 6 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

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.


There are no comments on this page.
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki