~drgeo-developers/drgeo/trunk

« back to all changes in this revision

Viewing changes to VMs/iPad/source/unix/vm/sqUnixEvent.c

  • Committer: Hilaire Fernandes
  • Date: 2012-01-27 21:15:40 UTC
  • Revision ID: hilaire.fernandes@gmail.com-20120127211540-912spf97bhpx6mve
Initial additions

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* sqUnixEvent.c -- support for window system events.
 
2
 * 
 
3
 *   Copyright (C) 1996-2007 by Ian Piumarta and other authors/contributors
 
4
 *                              listed elsewhere in this file.
 
5
 *   All rights reserved.
 
6
 *   
 
7
 *   This file is part of Unix Squeak.
 
8
 * 
 
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:
 
15
 * 
 
16
 *   The above copyright notice and this permission notice shall be included in
 
17
 *   all copies or substantial portions of the Software.
 
18
 * 
 
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
 
25
 *   SOFTWARE.
 
26
 */
 
27
 
 
28
/* Author: Ian Piumarta <ian.piumarta@squeakland.org>
 
29
 *
 
30
 * Last edited: 2009-08-15 15:39:46 by piumarta on emilia-2.local
 
31
 *
 
32
 * NOTE: this file is included by the window support files that need it.
 
33
 */
 
34
 
 
35
#define IEB_SIZE         64     /* must be power of 2 */
 
36
 
 
37
typedef struct
 
38
{
 
39
  int x, y;
 
40
} SqPoint;
 
41
 
 
42
SqPoint mousePosition= { 0, 0 };        /* position at last motion event */
 
43
int     swapBtn= 0;                     /* 1 to swap yellow and blue buttons */
 
44
 
 
45
sqInputEvent inputEventBuffer[IEB_SIZE];
 
46
 
 
47
int iebIn=  0;  /* next IEB location to write */
 
48
int iebOut= 0;  /* next IEB location to read  */
 
49
 
 
50
#define iebEmptyP()     (iebIn == iebOut)
 
51
#define iebAdvance(P)   (P= ((P + 1) & (IEB_SIZE - 1)))
 
52
 
 
53
int buttonState= 0;             /* mouse button state or 0 if not pressed */
 
54
int modifierState= 0;           /* modifier key state or 0 if none pressed */
 
55
 
 
56
#if defined(DEBUG_EVENTS)
 
57
 
 
58
#include <ctype.h>
 
59
 
 
60
static void printKey(int key)
 
61
{
 
62
  printf(" `%c' (%d = 0x%x)", (isgraph(key) ? key : ' '), key, key);
 
63
}
 
64
 
 
65
static void printButtons(int buttons)
 
66
{
 
67
  if (buttons & RedButtonBit)    printf(" red");
 
68
  if (buttons & YellowButtonBit) printf(" yellow");
 
69
  if (buttons & BlueButtonBit)   printf(" blue");
 
70
}
 
71
 
 
72
static void printModifiers(int midofiers)
 
73
{
 
74
  if (midofiers & ShiftKeyBit)   printf(" Shift");
 
75
  if (midofiers & CtrlKeyBit)    printf(" Control");
 
76
  if (midofiers & CommandKeyBit) printf(" Command");
 
77
  if (midofiers & OptionKeyBit)  printf(" Option");
 
78
}
 
79
 
 
80
#endif
 
81
 
 
82
 
 
83
static sqInputEvent *allocateInputEvent(int eventType)
 
84
{
 
85
  sqInputEvent *evt= &inputEventBuffer[iebIn];
 
86
  iebAdvance(iebIn);
 
87
  if (iebEmptyP())
 
88
    {
 
89
      /* overrun: discard oldest event */
 
90
      iebAdvance(iebOut);
 
91
    }
 
92
  evt->type= eventType;
 
93
  evt->timeStamp= ioMSecs();
 
94
  return evt;
 
95
}
 
96
 
 
97
#define allocateMouseEvent() ( \
 
98
  (sqMouseEvent *)allocateInputEvent(EventTypeMouse) \
 
99
)
 
100
 
 
101
#define allocateKeyboardEvent() ( \
 
102
  (sqKeyboardEvent *)allocateInputEvent(EventTypeKeyboard) \
 
103
)
 
104
 
 
105
#define allocateDragEvent() ( \
 
106
  (sqDragDropFilesEvent *)allocateInputEvent(EventTypeDragDropFiles) \
 
107
)
 
108
 
 
109
#define allocateWindowEvent() ( \
 
110
  (sqWindowEvent *)allocateInputEvent(EventTypeWindow) \
 
111
)
 
112
 
 
113
 
 
114
static sqInt getButtonState(void)
 
115
{
 
116
  /* red button honours the modifiers:
 
117
   *    red+ctrl    = yellow button
 
118
   *    red+command = blue button
 
119
   */
 
120
  int buttons= buttonState;
 
121
  int modifiers= modifierState;
 
122
  if ((buttons == RedButtonBit) && modifiers)
 
123
    {
 
124
      int yellow= swapBtn ? BlueButtonBit   : YellowButtonBit;
 
125
      int blue=   swapBtn ? YellowButtonBit : BlueButtonBit;
 
126
      switch (modifiers)
 
127
        {
 
128
        case CtrlKeyBit:    buttons= yellow; modifiers &= ~CtrlKeyBit;    break;
 
129
        case CommandKeyBit: buttons= blue;   modifiers &= ~CommandKeyBit; break;
 
130
        }
 
131
    }
 
132
#ifdef DEBUG_EVENTS
 
133
  printf("BUTTONS");
 
134
  printModifiers(modifiers);
 
135
  printButtons(buttons);
 
136
  printf("\n");
 
137
#endif
 
138
  return buttons | (modifiers << 3);
 
139
}
 
140
 
 
141
 
 
142
static void signalInputEvent(void)
 
143
{
 
144
#ifdef DEBUG_EVENTS
 
145
  printf("signalInputEvent\n");
 
146
#endif
 
147
  if (inputEventSemaIndex > 0)
 
148
    signalSemaphoreWithIndex(inputEventSemaIndex);
 
149
}
 
150
 
 
151
 
 
152
static void recordMouseEvent(void)
 
153
{
 
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);
 
160
  evt->reserved1=
 
161
    evt->windowIndex= 0;
 
162
  signalInputEvent();
 
163
#ifdef DEBUG_EVENTS
 
164
  printf("EVENT: mouse (%d,%d)", mousePosition.x, mousePosition.y);
 
165
  printModifiers(state >> 3);
 
166
  printButtons(state & 7);
 
167
  printf("\n");
 
168
#endif
 
169
}
 
170
 
 
171
 
 
172
static void recordKeyboardEvent(int keyCode, int pressCode, int modifiers, int ucs4)
 
173
{
 
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;
 
180
  evt->reserved1=
 
181
    evt->windowIndex= 0;
 
182
  signalInputEvent();
 
183
#ifdef DEBUG_EVENTS
 
184
  printf("EVENT: key");
 
185
  switch (pressCode)
 
186
    {
 
187
    case EventKeyDown: printf(" down "); break;
 
188
    case EventKeyChar: printf(" char "); break;
 
189
    case EventKeyUp:   printf(" up   "); break;
 
190
    default:           printf(" ***UNKNOWN***"); break;
 
191
    }
 
192
  printModifiers(modifiers);
 
193
  printKey(keyCode);
 
194
  printf(" ucs4 %d\n", ucs4);
 
195
#endif
 
196
}
 
197
 
 
198
 
 
199
static void recordDragEvent(int dragType, int numFiles)
 
200
{
 
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;
 
208
  evt->windowIndex= 0;
 
209
  signalInputEvent();
 
210
#ifdef DEBUG_EVENTS
 
211
  printf("EVENT: drag (%d,%d)", mousePosition.x, mousePosition.y);
 
212
  printModifiers(state >> 3);
 
213
  printButtons(state & 7);
 
214
  printf("\n");
 
215
#endif
 
216
}
 
217
 
 
218
 
 
219
static void recordWindowEvent(int action, int v1, int v2, int v3, int v4, int windowIndex)
 
220
{
 
221
  sqWindowEvent *evt= allocateWindowEvent();
 
222
  evt->action= action;
 
223
  evt->value1= v1;
 
224
  evt->value2= v2;
 
225
  evt->value3= v3;
 
226
  evt->value4= v4;
 
227
  evt->windowIndex= windowIndex;
 
228
  signalInputEvent();
 
229
#ifdef DEBUG_EVENTS
 
230
  printf("EVENT: window (%d %d %d %d %d %d) ", action, v1, v2, v3, v4, 0);
 
231
  switch (action)
 
232
    {
 
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;
 
239
    }
 
240
  printf("\n");
 
241
#endif
 
242
}
 
243
 
 
244
 
 
245
/* retrieve the next input event from the queue */
 
246
 
 
247
static sqInt display_ioGetNextEvent(sqInputEvent *evt)
 
248
{
 
249
  if (iebEmptyP())
 
250
    ioProcessEvents();
 
251
  if (iebEmptyP())
 
252
    return false;
 
253
  *evt= inputEventBuffer[iebOut];
 
254
  iebAdvance(iebOut);
 
255
  return true;
 
256
}
 
257
 
 
258
 
 
259
/*** the following are deprecated and should really go away.  for now
 
260
     we keep them for backwards compatibility with ancient images        ***/
 
261
 
 
262
 
 
263
#define KEYBUF_SIZE 64
 
264
 
 
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 */
 
269
 
 
270
static void recordKeystroke(int keyCode)                        /* DEPRECATED */
 
271
{
 
272
  if (inputEventSemaIndex == 0)
 
273
    {
 
274
      int keystate= keyCode | (modifierState << 8);
 
275
#    ifdef DEBUG_EVENTS
 
276
      printf("RECORD keystroke");
 
277
      printModifiers(modifierState);
 
278
      printKey(keyCode);
 
279
      printf(" = %d 0x%x\n", keystate, keystate);
 
280
#    endif
 
281
      if (keystate == getInterruptKeycode())
 
282
        {
 
283
          setInterruptPending(true);
 
284
          setInterruptCheckCounter(0);
 
285
        }
 
286
      else
 
287
        {
 
288
          keyBuf[keyBufPut]= keystate;
 
289
          keyBufPut= (keyBufPut + 1) % KEYBUF_SIZE;
 
290
          if (keyBufGet == keyBufPut)
 
291
            {
 
292
              /* buffer overflow; drop the last character */
 
293
              keyBufGet= (keyBufGet + 1) % KEYBUF_SIZE;
 
294
              keyBufOverflows++;
 
295
            }
 
296
        }
 
297
    }
 
298
}
 
299
 
 
300
 
 
301
 
 
302
 
 
303
static sqInt display_ioPeekKeystroke(void)                      /* DEPRECATED */
 
304
{
 
305
  int keystate;
 
306
 
 
307
  ioProcessEvents();  /* process all pending events */
 
308
  if (keyBufGet == keyBufPut)
 
309
    return -1;  /* keystroke buffer is empty */
 
310
  keystate= keyBuf[keyBufGet];
 
311
  return keystate;
 
312
}
 
313
 
 
314
 
 
315
static sqInt display_ioGetKeystroke(void)                       /* DEPRECATED */
 
316
{
 
317
  int keystate;
 
318
 
 
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;
 
324
  return keystate;
 
325
}
 
326
 
 
327
 
 
328
static sqInt display_ioGetButtonState(void)
 
329
{
 
330
  ioProcessEvents();  /* process all pending events */
 
331
  return getButtonState();
 
332
}
 
333
 
 
334
 
 
335
static sqInt display_ioMousePoint(void)
 
336
{
 
337
  ioProcessEvents();  /* process all pending events */
 
338
  /* x is high 16 bits; y is low 16 bits */
 
339
  return (mousePosition.x << 16) | (mousePosition.y);
 
340
}