Squeak Class Documentation category index | class index  
 
EventSensor
  category: Kernel-Processes
  superclass: InputSensor
  subclasses:

EventSensor is a replacement for InputSensor based on a set of (optional) event primitives. An EventSensor updates its state when events are received so that all state based users of Sensor (e.g., Sensor keyboard, Sensor leftShiftDown, Sensor mouseButtons) will work exactly as before, by moving the current VM mechanisms into EventSensor itself. An optional input semaphore is part of the new design. For platforms that support true asynchronous event notification the semaphore can be signaled to indicate pending events. However, since most platforms do not support asynchronous notifications about events EventSensor still has to poll every now and then.

Instance variables:
mouseButtons <Integer> - mouse button state as replacement for primMouseButtons
mousePosition <Point> - mouse position as replacement for primMousePt
keyboardBuffer <SharedQueue> - keyboard input buffer
interruptKey <Integer> - currently defined interrupt key
interruptSemaphore <Semaphore> - the semaphore signaled when the interruptKey is detected
eventQueue <SharedQueue> - an optional event queue for event driven applications
inputProcess <Process> - the process receiving low-level events
inputSemaphore <Semaphore>- the semaphore signaled by the VM if asynchronous event notification is supported

Class variables:
EventPollFrequency <Integer> - the number of milliseconds to wait between polling for more events

Event format:
The current event format is very simple. Each event is recorded into an 8 element array. All events must provide some SmallInteger ID (the first field in the event buffer) and a time stamp (the second field in the event buffer), so that the difference between the time stamp of an event and the current time can be reported.

Currently, the following events are defined:

Null event
=============
The Null event is returned when the ST side asks for more events but no more events are available.
Structure:
[1] - event type 0
[2-8] - unused

Mouse event structure
==========================
Mouse events are generated when mouse input is detected.
Structure:
[1] - event type 1
[2] - time stamp
[3] - mouse x position
[4] - mouse y position
[5] - button state; bitfield with the following entries:
1 - yellow (e.g., right) button
2 - blue (e.g., middle) button
4 - red (e.g., left) button
[all other bits are currently undefined]
[6] - modifier keys; bitfield with the following entries:
1 - shift key
2 - ctrl key
4 - (Mac specific) option key
8 - Cmd/Alt key
[all other bits are currently undefined]
[7] - reserved.
[8] - reserved.

Keyboard events
====================
Keyboard events are generated when keyboard input is detected.
[1] - event type 2
[2] - time stamp
[3] - character code
For now the character code is in Mac Roman encoding.
[4] - press state; integer with the following meaning
0 - character
1 - key press (down)
2 - key release (up)
[5] - modifier keys (same as in mouse events)
[6] - reserved.
[7] - reserved.
[8] - reserved.

instance methods
  NOTES
  higherPerformanceNotes

  accessing
  eventQueue
eventQueue:
flushEvents
inputProcess
nextEvent
nextEventFromQueue
nextEventSynthesized
peekButtons
peekEvent
peekMousePt
peekPosition

  initialize
  initialize
shutDown
startUp

  keyboard
  primKbdNext
primKbdPeek

  private
  flushNonKbdEvents
isKbdEvent:
primInterruptSemaphore:
primMouseButtons
primMousePt
primSetInterruptKey:

  private-I/O
  ioProcess
mapButtons:modifiers:
primGetNextEvent:
primSetInputSemaphore:
processEvent:
processKeyboardEvent:
processMouseEvent:
queueEvent:

class methods
  class initialization
  initialize
initializeEventSensorConstants
install

  instance creation
  new

instance methods
  NOTES top  
 

higherPerformanceNotes


This is mostly a Mac issue, but may have some effect on other platforms. These changes do not take effect until you set the preference #higherPerformance to true. The impact of setting this pref to true may be higher performance for this Squeak image, but lower performance for other applications/processes that may be running concurrently. Experiment with your particular configuration/desires and decide for yourself.

-- 10 Feb 2001 -- removed item #1 since other changes in event handling made it moot --
1. In order to reduce the amount of time lost (perhaps 20 to 30% in some cases) to background applications on the Mac, change the strategy used to poll for UI events. Every time we poll the OS for UI events, increase the delay until the next check. Every time Squeak actually requests an event from EventSensor, reset the delay to its normal value (20 ms). This means that a long-running evaluation started in the UI process will receive less competition from background apps (and less overhead even if it is the only app), but normal UI-intensive operations will happen as they do now. What is lost by this change is some sensitivity to mouse events that occur while Squeak is busy over long periods. My thought is that if Squeak is so occupied for a period of seconds, these events are much less useful and perhaps even harmful.

2. Reduce the minimum morphic cycle time (MinCycleLapse) so that the frame rate (and, hence, running of #step methods) can proceed at greater than 50 frames per second. This can be quite beneficial to things like simulations that are run via #step.


  accessing top  
 

eventQueue

Return the current event queue


 

eventQueue:

Install a new queue for events.
If an eventQueue is present all events will be queued up there.
It is assumed that a client installing an event queue will actually
read data from it, otherwise the system will overflow.


 

flushEvents

Do nothing


 

inputProcess

For non-event image compatibility


 

nextEvent

Return the next event from the receiver.


 

nextEventFromQueue

Return the next event from the receiver.


 

nextEventSynthesized

Return a synthesized event. This method is called if an event driven client wants to receive events but the primary user interface is not event-driven (e.g., the receiver does not have an event queue but only updates its state). This can, for instance, happen if a Morphic World is run in an MVC window. To simplify the clients work this method will always return all available keyboard events first, and then (repeatedly) the mouse events. Since mouse events come last, the client can assume that after one mouse event has been received there are no more to come. Note that it is impossible for EventSensor to determine if a mouse event has been issued before so the client must be aware of the possible problem of getting repeatedly the same mouse events. See HandMorph>>processEvents for an example on how to deal with this.


 

peekButtons


 

peekEvent

Look ahead at the next event.


 

peekMousePt


 

peekPosition


  initialize top  
 

initialize

Initialize the receiver


 

shutDown


 

startUp

Run the I/O process


  keyboard top  
 

primKbdNext

Allows for use of old Sensor protocol to get at the keyboard,
as when running kbdTest or the InterpreterSimulator in Morphic


 

primKbdPeek

Allows for use of old Sensor protocol to get at the keyboard,
as when running kbdTest or the InterpreterSimulator in Morphic


  private top  
 

flushNonKbdEvents


 

isKbdEvent:


 

primInterruptSemaphore:

Primitive. Install the argument as the semaphore to be signalled whenever the user presses the interrupt key. The semaphore will be signaled once each time the interrupt key is pressed.


 

primMouseButtons


 

primMousePt

Primitive. Poll the mouse to find out its position. Return a Point. Fail if
event-driven tracking is used instead of polling. Optional. See Object
documentation whatIsAPrimitive.


 

primSetInterruptKey:

Primitive. Register the given keycode as the user interrupt key. The low byte of the keycode is the ISO character and its next four bits are the Smalltalk modifer bits <cmd><opt><ctrl><shift>.


  private-I/O top  
 

ioProcess

Run the i/o process


 

mapButtons:modifiers:

Map the buttons to yellow or blue based on the given modifiers.
If only the red button is pressed, then map
Ctrl-RedButton -> BlueButton.
Cmd-RedButton -> YellowButton.


 

primGetNextEvent:

Store the next OS event available into the provided array.
Essential. If the VM is not event driven the ST code will fall
back to the old-style mechanism and use the state based
primitives instead.


 

primSetInputSemaphore:

Set the input semaphore the VM should use for asynchronously signaling the availability of events. Primitive. Optional.


 

processEvent:

Process a single event. This method is run at high priority.


 

processKeyboardEvent:

process a keyboard event, updating InputSensor state


 

processMouseEvent:

process a mouse event, updating InputSensor state


 

queueEvent:

Queue the given event in the event queue (if any).
Note that the event buffer must be copied since it
will be reused later on.


class methods
  class initialization top  
 

initialize

EventSensor initialize


 

initializeEventSensorConstants

EventSensor initialize


 

install

EventSensor install


  instance creation top  
 

new

Answer a new instance of the receiver (which is a class) with no indexable variables. Fail if the class is indexable.