1
/* sqUnixEvent.c -- support for window system events.
3
* Copyright (C) 1996-2007 by Ian Piumarta and other authors/contributors
4
* listed elsewhere in this file.
7
* This file is part of Unix Squeak.
9
* Permission is hereby granted, free of charge, to any person obtaining a copy
10
* of this software and associated documentation files (the "Software"), to deal
11
* in the Software without restriction, including without limitation the rights
12
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
* copies of the Software, and to permit persons to whom the Software is
14
* furnished to do so, subject to the following conditions:
16
* The above copyright notice and this permission notice shall be included in
17
* all copies or substantial portions of the Software.
19
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
/* Author: Ian Piumarta <ian.piumarta@squeakland.org>
30
* Last edited: 2009-08-15 15:39:46 by piumarta on emilia-2.local
32
* NOTE: this file is included by the window support files that need it.
35
#define IEB_SIZE 64 /* must be power of 2 */
42
SqPoint mousePosition= { 0, 0 }; /* position at last motion event */
43
int swapBtn= 0; /* 1 to swap yellow and blue buttons */
45
sqInputEvent inputEventBuffer[IEB_SIZE];
47
int iebIn= 0; /* next IEB location to write */
48
int iebOut= 0; /* next IEB location to read */
50
#define iebEmptyP() (iebIn == iebOut)
51
#define iebAdvance(P) (P= ((P + 1) & (IEB_SIZE - 1)))
53
int buttonState= 0; /* mouse button state or 0 if not pressed */
54
int modifierState= 0; /* modifier key state or 0 if none pressed */
56
#if defined(DEBUG_EVENTS)
60
static void printKey(int key)
62
printf(" `%c' (%d = 0x%x)", (isgraph(key) ? key : ' '), key, key);
65
static void printButtons(int buttons)
67
if (buttons & RedButtonBit) printf(" red");
68
if (buttons & YellowButtonBit) printf(" yellow");
69
if (buttons & BlueButtonBit) printf(" blue");
72
static void printModifiers(int midofiers)
74
if (midofiers & ShiftKeyBit) printf(" Shift");
75
if (midofiers & CtrlKeyBit) printf(" Control");
76
if (midofiers & CommandKeyBit) printf(" Command");
77
if (midofiers & OptionKeyBit) printf(" Option");
83
static sqInputEvent *allocateInputEvent(int eventType)
85
sqInputEvent *evt= &inputEventBuffer[iebIn];
89
/* overrun: discard oldest event */
93
evt->timeStamp= ioMSecs();
97
#define allocateMouseEvent() ( \
98
(sqMouseEvent *)allocateInputEvent(EventTypeMouse) \
101
#define allocateKeyboardEvent() ( \
102
(sqKeyboardEvent *)allocateInputEvent(EventTypeKeyboard) \
105
#define allocateDragEvent() ( \
106
(sqDragDropFilesEvent *)allocateInputEvent(EventTypeDragDropFiles) \
109
#define allocateWindowEvent() ( \
110
(sqWindowEvent *)allocateInputEvent(EventTypeWindow) \
114
static sqInt getButtonState(void)
116
/* red button honours the modifiers:
117
* red+ctrl = yellow button
118
* red+command = blue button
120
int buttons= buttonState;
121
int modifiers= modifierState;
122
if ((buttons == RedButtonBit) && modifiers)
124
int yellow= swapBtn ? BlueButtonBit : YellowButtonBit;
125
int blue= swapBtn ? YellowButtonBit : BlueButtonBit;
128
case CtrlKeyBit: buttons= yellow; modifiers &= ~CtrlKeyBit; break;
129
case CommandKeyBit: buttons= blue; modifiers &= ~CommandKeyBit; break;
134
printModifiers(modifiers);
135
printButtons(buttons);
138
return buttons | (modifiers << 3);
142
static void signalInputEvent(void)
145
printf("signalInputEvent\n");
147
if (inputEventSemaIndex > 0)
148
signalSemaphoreWithIndex(inputEventSemaIndex);
152
static void recordMouseEvent(void)
154
int state= getButtonState();
155
sqMouseEvent *evt= allocateMouseEvent();
156
evt->x= mousePosition.x;
157
evt->y= mousePosition.y;
158
evt->buttons= (state & 0x7);
159
evt->modifiers= (state >> 3);
164
printf("EVENT: mouse (%d,%d)", mousePosition.x, mousePosition.y);
165
printModifiers(state >> 3);
166
printButtons(state & 7);
172
static void recordKeyboardEvent(int keyCode, int pressCode, int modifiers, int ucs4)
174
sqKeyboardEvent *evt= allocateKeyboardEvent();
175
if (keyCode < 0) keyCode= 0;
176
evt->charCode= keyCode;
177
evt->pressCode= pressCode;
178
evt->modifiers= modifiers;
179
evt->utf32Code= ucs4;
184
printf("EVENT: key");
187
case EventKeyDown: printf(" down "); break;
188
case EventKeyChar: printf(" char "); break;
189
case EventKeyUp: printf(" up "); break;
190
default: printf(" ***UNKNOWN***"); break;
192
printModifiers(modifiers);
194
printf(" ucs4 %d\n", ucs4);
199
static void recordDragEvent(int dragType, int numFiles)
201
int state= getButtonState();
202
sqDragDropFilesEvent *evt= allocateDragEvent();
203
evt->dragType= dragType;
204
evt->x= mousePosition.x;
205
evt->y= mousePosition.y;
206
evt->modifiers= (state >> 3);
207
evt->numFiles= numFiles;
211
printf("EVENT: drag (%d,%d)", mousePosition.x, mousePosition.y);
212
printModifiers(state >> 3);
213
printButtons(state & 7);
219
static void recordWindowEvent(int action, int v1, int v2, int v3, int v4, int windowIndex)
221
sqWindowEvent *evt= allocateWindowEvent();
227
evt->windowIndex= windowIndex;
230
printf("EVENT: window (%d %d %d %d %d %d) ", action, v1, v2, v3, v4, 0);
233
case WindowEventMetricChange: printf("metric change"); break;
234
case WindowEventClose: printf("close"); break;
235
case WindowEventIconise: printf("iconise"); break;
236
case WindowEventActivated: printf("activated"); break;
237
case WindowEventPaint: printf("paint"); break;
238
default: printf("***UNKNOWN***"); break;
245
/* retrieve the next input event from the queue */
247
static sqInt display_ioGetNextEvent(sqInputEvent *evt)
253
*evt= inputEventBuffer[iebOut];
259
/*** the following are deprecated and should really go away. for now
260
we keep them for backwards compatibility with ancient images ***/
263
#define KEYBUF_SIZE 64
265
static int keyBuf[KEYBUF_SIZE]; /* circular buffer */
266
static int keyBufGet= 0; /* index of next item of keyBuf to read */
267
static int keyBufPut= 0; /* index of next item of keyBuf to write */
268
static int keyBufOverflows= 0; /* number of characters dropped */
270
static void recordKeystroke(int keyCode) /* DEPRECATED */
272
if (inputEventSemaIndex == 0)
274
int keystate= keyCode | (modifierState << 8);
276
printf("RECORD keystroke");
277
printModifiers(modifierState);
279
printf(" = %d 0x%x\n", keystate, keystate);
281
if (keystate == getInterruptKeycode())
283
setInterruptPending(true);
284
setInterruptCheckCounter(0);
288
keyBuf[keyBufPut]= keystate;
289
keyBufPut= (keyBufPut + 1) % KEYBUF_SIZE;
290
if (keyBufGet == keyBufPut)
292
/* buffer overflow; drop the last character */
293
keyBufGet= (keyBufGet + 1) % KEYBUF_SIZE;
303
static sqInt display_ioPeekKeystroke(void) /* DEPRECATED */
307
ioProcessEvents(); /* process all pending events */
308
if (keyBufGet == keyBufPut)
309
return -1; /* keystroke buffer is empty */
310
keystate= keyBuf[keyBufGet];
315
static sqInt display_ioGetKeystroke(void) /* DEPRECATED */
319
ioProcessEvents(); /* process all pending events */
320
if (keyBufGet == keyBufPut)
321
return -1; /* keystroke buffer is empty */
322
keystate= keyBuf[keyBufGet];
323
keyBufGet= (keyBufGet + 1) % KEYBUF_SIZE;
328
static sqInt display_ioGetButtonState(void)
330
ioProcessEvents(); /* process all pending events */
331
return getButtonState();
335
static sqInt display_ioMousePoint(void)
337
ioProcessEvents(); /* process all pending events */
338
/* x is high 16 bits; y is low 16 bits */
339
return (mousePosition.x << 16) | (mousePosition.y);