89
edits
Line 178: | Line 178: | ||
Plugins should receive all their events from NPP_HandleEvent. We believe that standardizing the event types and payloads based on, for example, DOM events, would be sufficient to provide browser and OS independent events. If not, the goal can be accomplished by possibly extending the set of event types or data on the event structures to convey more information. | Plugins should receive all their events from NPP_HandleEvent. We believe that standardizing the event types and payloads based on, for example, DOM events, would be sufficient to provide browser and OS independent events. If not, the goal can be accomplished by possibly extending the set of event types or data on the event structures to convey more information. | ||
=== | === Events === | ||
Background | |||
All events to an untrusted Pepper module will arrive via NPHandleEvent?(). For the most part, think of this as NPHandleEvent?() as it appears in traditional NPAPI, but instead of recieving a void* package of blind data that must be type cast to an operating system specific event structure, Pepper's version of NPHandleEvent?() will recieve pointers to Pepper's platform independent NPEvent structure. | |||
int16_t NPP_HandleEvent(NPP_Instance instance, const NPEvent *event) | |||
This platform independent event structure will be principally based on WebKit's internal events. Some light translation may need to occur for platform neutrality, and platform specific fields in the WebKit events will be dropped. Also, Pepper is a 'C' style API, so instead of using classes, Pepper's events will be defined as C structures. They will also use specifically sized types (int32_t, int16_t, int8_t, etc.) to avoid sizeof(int) and sizeof(wchar) differences between compilers and machine architectures, and have very strict padding and alignment specifications. | |||
This specification is version 1.0 of events in Pepper. If future events are added, or additional fields are added to existing events, we'll need a way for the Native Client application to query (or negotiate) what version of events are supported by the browser. If significant changes are made to WebKit's event model, we may need to add additional trusted code to maintain backwards compatibility with existing Native Client applications. This applies not only to new fields or changes to the ranges of existing fields, but is also especially important for changes or differences in behaviours across multiple operating systems (for example, are mouse movements reported outside the embedded area while a button is held down and the initial mouse down event occurred within the embedded area) Subsequent versions of Pepper events may need to support gesture & touch based events, such as finger pinching and stretching to support zoom in / zoom out for maps & photo editors. | |||
The Native Client application can use NPN_GetValue() & NPN_SetValue() to query and set future event models. Currently, only version 1.0 model is supported, and it should be safe to assume that version 1.0 model will always be available, and will be the default at startup. | |||
Additional Items | |||
There is no timer event, see NPN_ScheduleTimer() and NPN_UnscheduleTimer() for timer support. There is no quit event during application shutdown, see JavaScript's "onunload" There is no resize event; see NPN_SetWindow(), which will be correctly serialized with respect to event order. | |||
Currently, we are proposing a platform neutral event for focus gained/lost, and a similar event for minimize/background tab. There is also a proposal for NPAPI to support three new NPN functions: NPN_UnfocusInstance(), NPN_LostFocus(), and NPN_GotFocus(). The NPAPI proposal uses NPN functions in leu of events for a few reasons, two of which are: 1) they didn't want to define what the focus event should be for each OS platform, 2) allow the application to explicitly give up focus. Since PEPPER events are platform neutral, the 1st reason doesn't really apply here. The 2nd reason might be good enough to consider using AKH instead of focus events. The downside is that as more events become NPN_* functions, the event model starts to become an inconsistent mix of traditional events and NPN_* functions. https://wiki.mozilla.org/Plugins:AdvancedKeyHandling | |||
Pepper NPAPI Event Structures | |||
It is important that all compilers, on all supported platforms, both trusted and untrusted, preserve structure order, field size, and alignment padding, as these structures might be used as a bit copyable wire format between different processes. These seperate processses could be compiled using different compilers and/or compilier options, while sharing these structures via shared memory. For the definitions below, the byte offset for each field is in square brackets. Unused portions of the event structure should be treated as undefined data. | |||
<pre> | <pre> | ||
enum NPMouseButtons { | |||
// Each value explicitly set, and must match between trusted & untrusted code. | |||
NPMouseButton_None = -1, | |||
NPMouseButton_Left = 0, | |||
NPMouseButton_Middle = 1, | |||
NPMouseButton_Right = 2, | |||
// End of Native Client event specification version 1.0 | |||
// Additional future mouse button enums go here... | |||
}; | |||
enum NPEventTypes { | |||
// Each value explicitly set, and must match between trusted & untrusted code. | |||
NPEventType_Undefined = -1, | |||
// events relevant union to use in NPEvent | |||
NPEventType_MouseDown = 0, // NPMouseEvent struct | |||
NPEventType_MouseUp = 1, // NPMouseEvent struct | |||
NPEventType_MouseMove = 2, // NPMouseEvent struct | |||
NPEventType_MouseEnter = 3, // NPMouseEvent struct | |||
NPEventType_MouseLeave = 4, // NPMouseEvent struct | |||
NPEventType_MouseWheel = 5, // NPMouseWheelEvent struct | |||
NPEventType_RawKeyDown = 6, // NPKeyEvent struct | |||
NPEventType_KeyDown = 7, // NPKeyEvent struct | |||
NPEventType_KeyUp = 8, // NPKeyEvent struct | |||
NPEventType_Char = 9, // NPCharEvent struct | |||
NPEventType_Minimize = 10, // NPMinimizeEvent struct | |||
NPEventType_Focus = 11, // NPFocusEvent struct | |||
NPEventType_Device = 12, // NPDeviceEvent struct | |||
// End of Native Client specific event specification version 1.0 | |||
// Additional future Native Client events go here... | |||
}; | |||
enum NPEventModifiers { | |||
// Each value explicitly set, and must match between trusted & untrusted code. | |||
NPEventModifier_ShiftKey = 1 << 0; // Does not differentiate between left/right keys | |||
NPEventModifier_ControlKey = 1 << 1; // Does not differentiate between left/right keys | |||
NPEventModifier_AltKey = 1 << 2; // Does not differentiate between left/right keys | |||
NPEventModifier_MetaKey = 1 << 3; // Does not differentiate between left/right keys | |||
NPEventModifier_IsKeyPad = 1 << 4; | |||
NPEventModifier_IsAutoRepeat = 1 << 5; | |||
NPEventModifier_LeftButtonDown = 1 << 6; | |||
NPEventModifier_MiddleButtonDown = 1 << 7; | |||
NPEventModifier_RightButtonDown = 1 << 8; | |||
// End of Native Client event specification version 1.0 | |||
// Additional future event modifiers go here... | |||
}; | |||
struct NPKeyEvent { | struct NPKeyEvent { | ||
// | // Structure layout must match between trusted & untrusted code. | ||
uint32_t normalizedKeyCode; | uint32_t modifier; // [0] : NPModifier | ||
uint32_t | uint32_t normalizedKeyCode; // [4] : key codes from Chromium's keyboard_codes_posix.h | ||
}; | |||
struct NPCharacterEvent { | |||
uint32_t modifier; // [0] : NPModifier | |||
uint16_t text[4]; // [4] : 32bit wchar | |||
uint16_t unmodifiedText[4]; // [8] : 32bit wchar | |||
// End of Native Client event specification version 1.0 | |||
// Additional future key event fields go here... | |||
}; | }; | ||
struct NPMouseEvent { | struct NPMouseEvent { | ||
// Structure layout must match between trusted & untrusted code. | |||
uint32_t modifier; // [0] : NPModifier | |||
int32_t | int32_t button; // [4] : NPMouseButtons | ||
int32_t | int32_t x; // [8] : Relative to upper left corner of embedded area, in units of pixels | ||
int32_t | int32_t y; // [12]: Relative to upper left corner of embedded area (+y down) | ||
int32_t | int32_t clickCount; // [16]: Number of button clicks | ||
// End of Native Client event specification version 1.0 | |||
// | // Additional future mouse event fields go here... | ||
}; | }; | ||
struct NPMouseWheelEvent { | struct NPMouseWheelEvent { | ||
float deltaX; | // Structure layout must match between trusted & untrusted code. | ||
float deltaY; | uint32_t modifier; // [0] : NPModifier | ||
float wheelTicksX; | float deltaX; // [4] : Positive deltaX indicate scroll left, in scroll wheel units. | ||
float wheelTicksY; | float deltaY; // [8] : Positive deltaY indicate scroll up, in scroll wheel units. | ||
uint32_t scrollByPage; | // On Windows, one scroll wheel click is a delta of 100.0 | ||
// | float wheelTicksX; // [12]: Positive wheelTicksX indicate scroll left. | ||
float wheelTicksY; // [16]: Positive wheelTicksY indicate scroll up. | |||
// Wheel ticks can be fractional values on certain devices. | |||
uint32_t scrollByPage; // [20]: 0 - scroll by line, 1 - scroll by page | |||
// End of Native Client event specification version 1.0 | |||
// Additional future mouse wheel event fields go here... | |||
}; | }; | ||
struct | struct NPDeviceEvent { | ||
// | // Structure layout must match between trusted & untrusted code. | ||
// This is a generic event type that devices (discovered via NPN_SetWindow) may use | |||
// to deliver events to NPN_HandleEvent(). | |||
// Note: this area is under construction | |||
uint32_t device_uid; // [0] : unique id of device (comes in on PEPPER NPN_SetWindow) | |||
uint32_t subtype; // [4] : device event subtype | |||
uint8_t generic[0]; // [8] : payload is typecast based on device uid & subtype | |||
}; | |||
struct NPMinimizeEvent { | |||
// Structure layout must match between trusted & untrusted code. | |||
// Minimizing may also include becoming a background/foreground tab. | |||
int32_t value; // [0] : New value | |||
// 0 = transitioning out of minimized state | |||
// 1 = transitioning to a minimized state | |||
// End of Native Client event specification version 1.0 | |||
// Additional future minimize event fields go here... | |||
}; | |||
struct NPFocusEvent { | |||
// Structure layout must match between trusted & untrusted code. | |||
// The embedded Native Client area is gaining or losing keyboard focus. | |||
int32_t value; // [0] : New value | |||
// 0 = losing focus | |||
// 1 = gaining focus | |||
// End of Native Client event specification version 1.0 | |||
// Additional future focus event fields go here... | |||
}; | }; | ||
struct NPEvent { | struct NPEvent { | ||
// Structure layout must match between trusted & untrusted code. | |||
uint32_t | int32_t type; // [0] : NPEventTypes | ||
uint32_t size; // [4] : Size in bytes of _this_ event structure. | |||
double timeStampSeconds; | double timeStampSeconds; // [8] : Time of creation; seconds since epoch. | ||
union { | union { | ||
// [16]: Info specific to each event type | |||
NPKeyEvent key; | NPKeyEvent key; | ||
NPCharacterEvent character; | |||
NPMouseEvent mouse; | NPMouseEvent mouse; | ||
NPMouseWheelEvent wheel; | NPMouseWheelEvent wheel; | ||
NPMinimizeEvent minimize; | |||
NPFocusEvent focus; | |||
NPDeviceEvent device; | |||
// End of Native Client event specification version 1.0 | |||
// Additional future event type structures go here... | |||
}; | }; | ||
}; | |||
Keycodes used by NPKeyEvent.normalizedKeyCode (keyboard_codes_posix.h) | |||
enum { | |||
VKEY_BACK = 0x08, | |||
VKEY_TAB = 0x09, | |||
VKEY_CLEAR = 0x0C, | |||
VKEY_RETURN = 0x0D, | |||
VKEY_SHIFT = 0x10, | |||
VKEY_CONTROL = 0x11, | |||
VKEY_MENU = 0x12, | |||
VKEY_PAUSE = 0x13, | |||
VKEY_CAPITAL = 0x14, | |||
VKEY_KANA = 0x15, | |||
VKEY_HANGUL = 0x15, | |||
VKEY_JUNJA = 0x17, | |||
VKEY_FINAL = 0x18, | |||
VKEY_HANJA = 0x19, | |||
VKEY_KANJI = 0x19, | |||
VKEY_ESCAPE = 0x1B, | |||
VKEY_CONVERT = 0x1C, | |||
VKEY_NONCONVERT = 0x1D, | |||
VKEY_ACCEPT = 0x1E, | |||
VKEY_MODECHANGE = 0x1F, | |||
VKEY_SPACE = 0x20, | |||
VKEY_PRIOR = 0x21, | |||
VKEY_NEXT = 0x22, | |||
VKEY_END = 0x23, | |||
VKEY_HOME = 0x24, | |||
VKEY_LEFT = 0x25, | |||
VKEY_UP = 0x26, | |||
VKEY_RIGHT = 0x27, | |||
VKEY_DOWN = 0x28, | |||
VKEY_SELECT = 0x29, | |||
VKEY_PRINT = 0x2A, | |||
VKEY_EXECUTE = 0x2B, | |||
VKEY_SNAPSHOT = 0x2C, | |||
VKEY_INSERT = 0x2D, | |||
VKEY_DELETE = 0x2E, | |||
VKEY_HELP = 0x2F, | |||
VKEY_0 = 0x30, | |||
VKEY_1 = 0x31, | |||
VKEY_2 = 0x32, | |||
VKEY_3 = 0x33, | |||
VKEY_4 = 0x34, | |||
VKEY_5 = 0x35, | |||
VKEY_6 = 0x36, | |||
VKEY_7 = 0x37, | |||
VKEY_8 = 0x38, | |||
VKEY_9 = 0x39, | |||
VKEY_A = 0x41, | |||
VKEY_B = 0x42, | |||
VKEY_C = 0x43, | |||
VKEY_D = 0x44, | |||
VKEY_E = 0x45, | |||
VKEY_F = 0x46, | |||
VKEY_G = 0x47, | |||
VKEY_H = 0x48, | |||
VKEY_I = 0x49, | |||
VKEY_J = 0x4A, | |||
VKEY_K = 0x4B, | |||
VKEY_L = 0x4C, | |||
VKEY_M = 0x4D, | |||
VKEY_N = 0x4E, | |||
VKEY_O = 0x4F, | |||
VKEY_P = 0x50, | |||
VKEY_Q = 0x51, | |||
VKEY_R = 0x52, | |||
VKEY_S = 0x53, | |||
VKEY_T = 0x54, | |||
VKEY_U = 0x55, | |||
VKEY_V = 0x56, | |||
VKEY_W = 0x57, | |||
VKEY_X = 0x58, | |||
VKEY_Y = 0x59, | |||
VKEY_Z = 0x5A, | |||
VKEY_LWIN = 0x5B, | |||
VKEY_RWIN = 0x5C, | |||
VKEY_APPS = 0x5D, | |||
VKEY_SLEEP = 0x5F, | |||
VKEY_NUMPAD0 = 0x60, | |||
VKEY_NUMPAD1 = 0x61, | |||
VKEY_NUMPAD2 = 0x62, | |||
VKEY_NUMPAD3 = 0x63, | |||
VKEY_NUMPAD4 = 0x64, | |||
VKEY_NUMPAD5 = 0x65, | |||
VKEY_NUMPAD6 = 0x66, | |||
VKEY_NUMPAD7 = 0x67, | |||
VKEY_NUMPAD8 = 0x68, | |||
VKEY_NUMPAD9 = 0x69, | |||
VKEY_MULTIPLY = 0x6A, | |||
VKEY_ADD = 0x6B, | |||
VKEY_SEPARATOR = 0x6C, | |||
VKEY_SUBTRACT = 0x6D, | |||
VKEY_DECIMAL = 0x6E, | |||
VKEY_DIVIDE = 0x6F, | |||
VKEY_F1 = 0x70, | |||
VKEY_F2 = 0x71, | |||
VKEY_F3 = 0x72, | |||
VKEY_F4 = 0x73, | |||
VKEY_F5 = 0x74, | |||
VKEY_F6 = 0x75, | |||
VKEY_F7 = 0x76, | |||
VKEY_F8 = 0x77, | |||
VKEY_F9 = 0x78, | |||
VKEY_F10 = 0x79, | |||
VKEY_F11 = 0x7A, | |||
VKEY_F12 = 0x7B, | |||
VKEY_F13 = 0x7C, | |||
VKEY_F14 = 0x7D, | |||
VKEY_F15 = 0x7E, | |||
VKEY_F16 = 0x7F, | |||
VKEY_F17 = 0x80, | |||
VKEY_F18 = 0x81, | |||
VKEY_F19 = 0x82, | |||
VKEY_F20 = 0x83, | |||
VKEY_F21 = 0x84, | |||
VKEY_F22 = 0x85, | |||
VKEY_F23 = 0x86, | |||
VKEY_F24 = 0x87, | |||
VKEY_NUMLOCK = 0x90, | |||
VKEY_SCROLL = 0x91, | |||
VKEY_LSHIFT = 0xA0, | |||
VKEY_RSHIFT = 0xA1, | |||
VKEY_LCONTROL = 0xA2, | |||
VKEY_RCONTROL = 0xA3, | |||
VKEY_LMENU = 0xA4, | |||
VKEY_RMENU = 0xA5, | |||
VKEY_BROWSER_BACK = 0xA6, | |||
VKEY_BROWSER_FORWARD = 0xA7, | |||
VKEY_BROWSER_REFRESH = 0xA8, | |||
VKEY_BROWSER_STOP = 0xA9, | |||
VKEY_BROWSER_SEARCH = 0xAA, | |||
VKEY_BROWSER_FAVORITES = 0xAB, | |||
VKEY_BROWSER_HOME = 0xAC, | |||
VKEY_VOLUME_MUTE = 0xAD, | |||
VKEY_VOLUME_DOWN = 0xAE, | |||
VKEY_VOLUME_UP = 0xAF, | |||
VKEY_MEDIA_NEXT_TRACK = 0xB0, | |||
VKEY_MEDIA_PREV_TRACK = 0xB1, | |||
VKEY_MEDIA_STOP = 0xB2, | |||
VKEY_MEDIA_PLAY_PAUSE = 0xB3, | |||
VKEY_MEDIA_LAUNCH_MAIL = 0xB4, | |||
VKEY_MEDIA_LAUNCH_MEDIA_SELECT = 0xB5, | |||
VKEY_MEDIA_LAUNCH_APP1 = 0xB6, | |||
VKEY_MEDIA_LAUNCH_APP2 = 0xB7, | |||
VKEY_OEM_1 = 0xBA, | |||
VKEY_OEM_PLUS = 0xBB, | |||
VKEY_OEM_COMMA = 0xBC, | |||
VKEY_OEM_MINUS = 0xBD, | |||
VKEY_OEM_PERIOD = 0xBE, | |||
VKEY_OEM_2 = 0xBF, | |||
VKEY_OEM_3 = 0xC0, | |||
VKEY_OEM_4 = 0xDB, | |||
VKEY_OEM_5 = 0xDC, | |||
VKEY_OEM_6 = 0xDD, | |||
VKEY_OEM_7 = 0xDE, | |||
VKEY_OEM_8 = 0xDF, | |||
VKEY_OEM_102 = 0xE2, | |||
VKEY_PROCESSKEY = 0xE5, | |||
VKEY_PACKET = 0xE7, | |||
VKEY_ATTN = 0xF6, | |||
VKEY_CRSEL = 0xF7, | |||
VKEY_EXSEL = 0xF8, | |||
VKEY_EREOF = 0xF9, | |||
VKEY_PLAY = 0xFA, | |||
VKEY_ZOOM = 0xFB, | |||
VKEY_NONAME = 0xFC, | |||
VKEY_PA1 = 0xFD, | |||
VKEY_OEM_CLEAR = 0xFE, | |||
VKEY_UNKNOWN = 0 | |||
}; | }; | ||
</pre> | </pre> |
edits