~vcs-imports/qemu/git

« back to all changes in this revision

Viewing changes to cocoa.m

  • Committer: bellard
  • Date: 2005-10-30 18:24:49 UTC
  • Revision ID: git-v1:87f48e6a1afbaf14bed8a5c253c874ec4f15edfb
fixed/full keyboard input - full mouse support - support for qemu console (Mike Kronenberg)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1582 c046a42c-6fe2-441c-8c8c-71466251a162

Show diffs side-by-side

added added

removed removed

Lines of Context:
47
47
char **gArgv;
48
48
DisplayState current_ds;
49
49
 
 
50
int grab = 0;
 
51
int modifiers_state[256];
 
52
 
50
53
/* main defined in qemu/vl.c */
51
54
int qemu_main(int argc, char **argv);
52
55
 
171
174
 ------------------------------------------------------
172
175
*/
173
176
 
174
 
static int keymap[] =
 
177
int keymap[] =
175
178
{
176
 
    30, //'a' 0x0
177
 
    31,  //'s'
178
 
    32,  //'d'
179
 
    33,  //'f'
180
 
    35,  //'h'
181
 
    34,  //'g'
182
 
    44,  //'z'
183
 
    45,  //'x'
184
 
    46,  //'c'
185
 
    47,  //'v'
186
 
    0,   // 0  0x0a
187
 
    48,  //'b'
188
 
    16,  //'q'
189
 
    17,  //'w'
190
 
    18,  //'e'
191
 
    19,  //'r' 
192
 
    21,  //'y' 0x10
193
 
    20,  //'t'
194
 
    2,  //'1'
195
 
    3,  //'2'
196
 
    4,  //'3'
197
 
    5,  //'4'
198
 
    7,  //'6'
199
 
    6,  //'5'
200
 
    0,  //'='
201
 
    10,  //'9'
202
 
    8,  //'7' 0x1A
203
 
    0,  //'-' 
204
 
    9,  //'8' 
205
 
    11,  //'0' 
206
 
    27,  //']' 
207
 
    24,  //'o' 
208
 
    22,  //'u' 0x20
209
 
    26,  //'['
210
 
    23,  //'i'
211
 
    25,  //'p'
212
 
    28,  //'\n'
213
 
    38,  //'l'
214
 
    36,  //'j'
215
 
    40,  //'"'
216
 
    37,  //'k'
217
 
    39,  //';'
218
 
    15,  //'\t' 0x30
219
 
    0,  //' '
220
 
    0,  //'`'
221
 
    14,  //'<backspace>'
222
 
    0,  //'' 0x34
223
 
    0,  //'<esc>'
224
 
    0,  //'<esc>'
225
 
    /* Not completed to finish see http://www.libsdl.org/cgi/cvsweb.cgi/SDL12/src/video/quartz/SDL_QuartzKeys.h?rev=1.6&content-type=text/x-cvsweb-markup */
 
179
//  SdlI    macI    macH    SdlH    104xtH  104xtC  sdl
 
180
    30, //  0       0x00    0x1e            A       QZ_a
 
181
    31, //  1       0x01    0x1f            S       QZ_s
 
182
    32, //  2       0x02    0x20            D       QZ_d
 
183
    33, //  3       0x03    0x21            F       QZ_f
 
184
    35, //  4       0x04    0x23            H       QZ_h
 
185
    34, //  5       0x05    0x22            G       QZ_g
 
186
    44, //  6       0x06    0x2c            Z       QZ_z
 
187
    45, //  7       0x07    0x2d            X       QZ_x
 
188
    46, //  8       0x08    0x2e            C       QZ_c
 
189
    47, //  9       0x09    0x2f            V       QZ_v
 
190
    0,  //  10      0x0A    Undefined
 
191
    48, //  11      0x0B    0x30            B       QZ_b
 
192
    16, //  12      0x0C    0x10            Q       QZ_q
 
193
    17, //  13      0x0D    0x11            W       QZ_w
 
194
    18, //  14      0x0E    0x12            E       QZ_e
 
195
    19, //  15      0x0F    0x13            R       QZ_r
 
196
    21, //  16      0x10    0x15            Y       QZ_y
 
197
    20, //  17      0x11    0x14            T       QZ_t
 
198
    2,  //  18      0x12    0x02            1       QZ_1
 
199
    3,  //  19      0x13    0x03            2       QZ_2
 
200
    4,  //  20      0x14    0x04            3       QZ_3
 
201
    5,  //  21      0x15    0x05            4       QZ_4
 
202
    7,  //  22      0x16    0x07            6       QZ_6
 
203
    6,  //  23      0x17    0x06            5       QZ_5
 
204
    13, //  24      0x18    0x0d            =       QZ_EQUALS
 
205
    10, //  25      0x19    0x0a            9       QZ_9
 
206
    8,  //  26      0x1A    0x08            7       QZ_7
 
207
    12, //  27      0x1B    0x0c            -       QZ_MINUS
 
208
    9,  //  28      0x1C    0x09            8       QZ_8
 
209
    11, //  29      0x1D    0x0b            0       QZ_0
 
210
    27, //  30      0x1E    0x1b            ]       QZ_RIGHTBRACKET
 
211
    24, //  31      0x1F    0x18            O       QZ_o
 
212
    22, //  32      0x20    0x16            U       QZ_u
 
213
    26, //  33      0x21    0x1a            [       QZ_LEFTBRACKET
 
214
    23, //  34      0x22    0x17            I       QZ_i
 
215
    25, //  35      0x23    0x19            P       QZ_p
 
216
    28, //  36      0x24    0x1c            ENTER   QZ_RETURN
 
217
    38, //  37      0x25    0x26            L       QZ_l
 
218
    36, //  38      0x26    0x24            J       QZ_j
 
219
    40, //  39      0x27    0x28            '       QZ_QUOTE
 
220
    37, //  40      0x28    0x25            K       QZ_k
 
221
    39, //  41      0x29    0x27            ;       QZ_SEMICOLON
 
222
    43, //  42      0x2A    0x2b            \       QZ_BACKSLASH
 
223
    51, //  43      0x2B    0x33            ,       QZ_COMMA
 
224
    53, //  44      0x2C    0x35            /       QZ_SLASH
 
225
    49, //  45      0x2D    0x31            N       QZ_n
 
226
    50, //  46      0x2E    0x32            M       QZ_m
 
227
    52, //  47      0x2F    0x34            .       QZ_PERIOD
 
228
    15, //  48      0x30    0x0f            TAB     QZ_TAB
 
229
    57, //  49      0x31    0x39            SPACE   QZ_SPACE
 
230
    41, //  50      0x32    0x29            `       QZ_BACKQUOTE
 
231
    14, //  51      0x33    0x0e            BKSP    QZ_BACKSPACE
 
232
    0,  //  52      0x34    Undefined
 
233
    1,  //  53      0x35    0x01            ESC     QZ_ESCAPE
 
234
    0,  //  54      0x36                            QZ_RMETA
 
235
    0,  //  55      0x37                            QZ_LMETA
 
236
    42, //  56      0x38    0x2a            L SHFT  QZ_LSHIFT
 
237
    58, //  57      0x39    0x3a            CAPS    QZ_CAPSLOCK
 
238
    56, //  58      0x3A    0x38            L ALT   QZ_LALT
 
239
    29, //  59      0x3B    0x1d            L CTRL  QZ_LCTRL
 
240
    54, //  60      0x3C    0x36            R SHFT  QZ_RSHIFT
 
241
    184,//  61      0x3D    0xb8    E0,38   R ALT   QZ_RALT
 
242
    157,//  62      0x3E    0x9d    E0,1D   R CTRL  QZ_RCTRL
 
243
    0,  //  63      0x3F    Undefined
 
244
    0,  //  64      0x40    Undefined
 
245
    0,  //  65      0x41    Undefined
 
246
    0,  //  66      0x42    Undefined
 
247
    55, //  67      0x43    0x37            KP *    QZ_KP_MULTIPLY
 
248
    0,  //  68      0x44    Undefined
 
249
    78, //  69      0x45    0x4e            KP +    QZ_KP_PLUS
 
250
    0,  //  70      0x46    Undefined
 
251
    69, //  71      0x47    0x45            NUM     QZ_NUMLOCK
 
252
    0,  //  72      0x48    Undefined
 
253
    0,  //  73      0x49    Undefined
 
254
    0,  //  74      0x4A    Undefined
 
255
    181,//  75      0x4B    0xb5    E0,35   KP /    QZ_KP_DIVIDE
 
256
    152,//  76      0x4C    0x9c    E0,1C   KP EN   QZ_KP_ENTER
 
257
    0,  //  77      0x4D    undefined
 
258
    74, //  78      0x4E    0x4a            KP -    QZ_KP_MINUS
 
259
    0,  //  79      0x4F    Undefined
 
260
    0,  //  80      0x50    Undefined
 
261
    0,  //  81      0x51                            QZ_KP_EQUALS
 
262
    82, //  82      0x52    0x52            KP 0    QZ_KP0
 
263
    79, //  83      0x53    0x4f            KP 1    QZ_KP1
 
264
    80, //  84      0x54    0x50            KP 2    QZ_KP2
 
265
    81, //  85      0x55    0x51            KP 3    QZ_KP3
 
266
    75, //  86      0x56    0x4b            KP 4    QZ_KP4
 
267
    76, //  87      0x57    0x4c            KP 5    QZ_KP5
 
268
    77, //  88      0x58    0x4d            KP 6    QZ_KP6
 
269
    71, //  89      0x59    0x47            KP 7    QZ_KP7
 
270
    0,  //  90      0x5A    Undefined
 
271
    72, //  91      0x5B    0x48            KP 8    QZ_KP8
 
272
    73, //  92      0x5C    0x49            KP 9    QZ_KP9
 
273
    0,  //  93      0x5D    Undefined
 
274
    0,  //  94      0x5E    Undefined
 
275
    0,  //  95      0x5F    Undefined
 
276
    63, //  96      0x60    0x3f            F5      QZ_F5
 
277
    64, //  97      0x61    0x40            F6      QZ_F6
 
278
    65, //  98      0x62    0x41            F7      QZ_F7
 
279
    61, //  99      0x63    0x3d            F3      QZ_F3
 
280
    66, //  100     0x64    0x42            F8      QZ_F8
 
281
    67, //  101     0x65    0x43            F9      QZ_F9
 
282
    0,  //  102     0x66    Undefined
 
283
    87, //  103     0x67    0x57            F11     QZ_F11
 
284
    0,  //  104     0x68    Undefined
 
285
    183,//  105     0x69    0xb7            QZ_PRINT
 
286
    0,  //  106     0x6A    Undefined
 
287
    70, //  107     0x6B    0x46            SCROLL  QZ_SCROLLOCK
 
288
    0,  //  108     0x6C    Undefined
 
289
    68, //  109     0x6D    0x44            F10     QZ_F10
 
290
    0,  //  110     0x6E    Undefined
 
291
    88, //  111     0x6F    0x58            F12     QZ_F12
 
292
    0,  //  112     0x70    Undefined
 
293
    110,//  113     0x71    0x0                     QZ_PAUSE
 
294
    210,//  114     0x72    0xd2    E0,52   INSERT  QZ_INSERT
 
295
    199,//  115     0x73    0xc7    E0,47   HOME    QZ_HOME
 
296
    201,//  116     0x74    0xc9    E0,49   PG UP   QZ_PAGEUP
 
297
    211,//  117     0x75    0xd3    E0,53   DELETE  QZ_DELETE
 
298
    62, //  118     0x76    0x3e            F4      QZ_F4
 
299
    207,//  119     0x77    0xcf    E0,4f   END     QZ_END
 
300
    60, //  120     0x78    0x3c            F2      QZ_F2
 
301
    209,//  121     0x79    0xd1    E0,51   PG DN   QZ_PAGEDOWN
 
302
    59, //  122     0x7A    0x3b            F1      QZ_F1
 
303
    203,//  123     0x7B    0xcb    e0,4B   L ARROW QZ_LEFT
 
304
    205,//  124     0x7C    0xcd    e0,4D   R ARROW QZ_RIGHT
 
305
    208,//  125     0x7D    0xd0    E0,50   D ARROW QZ_DOWN
 
306
    200,//  126     0x7E    0xc8    E0,48   U ARROW QZ_UP
 
307
/* completed according to http://www.libsdl.org/cgi/cvsweb.cgi/SDL12/src/video/quartz/SDL_QuartzKeys.h?rev=1.6&content-type=text/x-cvsweb-markup */
 
308
  
 
309
/* Aditional 104 Key XP-Keyboard Scancodes from http://www.computer-engineering.org/ps2keyboard/scancodes1.html */
 
310
/*
 
311
    219 //          0xdb            e0,5b   L GUI   
 
312
    220 //          0xdc            e0,5c   R GUI   
 
313
    221 //          0xdd            e0,5d   APPS    
 
314
        //              E0,2A,E0,37         PRNT SCRN   
 
315
        //              E1,1D,45,E1,9D,C5   PAUSE   
 
316
    83  //          0x53    0x53            KP .    
 
317
// ACPI Scan Codes                              
 
318
    222 //          0xde            E0, 5E  Power   
 
319
    223 //          0xdf            E0, 5F  Sleep   
 
320
    227 //          0xe3            E0, 63  Wake    
 
321
// Windows Multimedia Scan Codes                                
 
322
    153 //          0x99            E0, 19  Next Track  
 
323
    144 //          0x90            E0, 10  Previous Track  
 
324
    164 //          0xa4            E0, 24  Stop    
 
325
    162 //          0xa2            E0, 22  Play/Pause  
 
326
    160 //          0xa0            E0, 20  Mute    
 
327
    176 //          0xb0            E0, 30  Volume Up   
 
328
    174 //          0xae            E0, 2E  Volume Down 
 
329
    237 //          0xed            E0, 6D  Media Select    
 
330
    236 //          0xec            E0, 6C  E-Mail  
 
331
    161 //          0xa1            E0, 21  Calculator  
 
332
    235 //          0xeb            E0, 6B  My Computer 
 
333
    229 //          0xe5            E0, 65  WWW Search  
 
334
    178 //          0xb2            E0, 32  WWW Home    
 
335
    234 //          0xea            E0, 6A  WWW Back    
 
336
    233 //          0xe9            E0, 69  WWW Forward 
 
337
    232 //          0xe8            E0, 68  WWW Stop    
 
338
    231 //          0xe7            E0, 67  WWW Refresh 
 
339
    230 //          0xe6            E0, 66  WWW Favorites   
 
340
*/
226
341
};
227
342
 
228
 
static int cocoa_keycode_to_qemu(int keycode)
 
343
int cocoa_keycode_to_qemu(int keycode)
229
344
{
230
 
    if(sizeof(keymap) <= keycode)
 
345
    if((sizeof(keymap)/sizeof(int)) <= keycode)
231
346
    {
232
347
        printf("(cocoa) warning unknow keycode 0x%x\n", keycode);
233
348
        return 0;
246
361
    NSDate *distantPast;
247
362
    NSEvent *event;
248
363
    NSAutoreleasePool *pool;
249
 
    int grab = 1;
250
364
    
251
365
    pool = [ [ NSAutoreleasePool alloc ] init ];
252
366
    distantPast = [ NSDate distantPast ];
258
372
                        inMode: NSDefaultRunLoopMode dequeue:YES ];
259
373
        if (event != nil) {
260
374
            switch ([event type]) {
 
375
                case NSFlagsChanged:
 
376
                    {
 
377
                        int keycode = cocoa_keycode_to_qemu([event keyCode]);
 
378
                        modifiers_state[keycode] = (modifiers_state[keycode] == 0) ? 1 : 0;
 
379
                        
 
380
                        if ( modifiers_state[keycode] ) { /* Keydown */
 
381
                            if (keycode & 0x80)
 
382
                                kbd_put_keycode(0xe0);
 
383
                            kbd_put_keycode(keycode & 0x7f);
 
384
                        } else { /* Keyup */
 
385
                            if (keycode & 0x80)
 
386
                                kbd_put_keycode(0xe0);
 
387
                            kbd_put_keycode(keycode | 0x80);
 
388
                        }
 
389
                        
 
390
                        /* emulate caps lock and num lock keyup */
 
391
                        if ((keycode == 58) || (keycode == 69))
 
392
                        {
 
393
                            modifiers_state[keycode] = 0;
 
394
                            if (keycode & 0x80)
 
395
                                kbd_put_keycode(0xe0);
 
396
                            kbd_put_keycode(keycode | 0x80);
 
397
                        }
 
398
                            
 
399
                        /* release Mouse grab when pressing ctrl+alt */
 
400
                        if (([event modifierFlags] & NSControlKeyMask) && ([event modifierFlags] & NSAlternateKeyMask))
 
401
                            [window setTitle: @"QEMU"];
 
402
                            [NSCursor unhide];
 
403
                            CGAssociateMouseAndMouseCursorPosition ( TRUE );
 
404
                            grab = 0;
 
405
                    }
 
406
                    break;
 
407
                    
261
408
                case NSKeyDown:
262
 
                    if(grab)
263
409
                    {
264
 
                        int keycode = cocoa_keycode_to_qemu([event keyCode]);
265
 
                        
266
 
                        if (keycode & 0x80)
267
 
                            kbd_put_keycode(0xe0);
268
 
                        kbd_put_keycode(keycode & 0x7f);
 
410
                        int keycode = cocoa_keycode_to_qemu([event keyCode]);               
 
411
                        
 
412
                        /* handle command Key Combos */
 
413
                        if ([event modifierFlags] & NSCommandKeyMask) {
 
414
                            switch ([event keyCode]) {
 
415
                                /* quit */
 
416
                                case 12: /* q key */
 
417
                                    /* switch to windowed View */
 
418
                                    exit(0);
 
419
                                    return;
 
420
                            }
 
421
                        }
 
422
                        
 
423
                        /* handle control + alt Key Combos */
 
424
                        if (([event modifierFlags] & NSControlKeyMask) && ([event modifierFlags] & NSAlternateKeyMask)) {
 
425
                            switch (keycode) {
 
426
                                /* toggle Monitor */
 
427
                                case 0x02 ... 0x0a: /* '1' to '9' keys */
 
428
                                    console_select(keycode - 0x02);
 
429
                                    if (is_active_console(vga_console)) {
 
430
                                        /* tell the vga console to redisplay itself */
 
431
                                        vga_invalidate_display();
 
432
                                    break;
 
433
                                }
 
434
                            }
 
435
                        } else {
 
436
                            /* handle standard key events */
 
437
                            if (is_active_console(vga_console)) {
 
438
                                if (keycode & 0x80) //check bit for e0 in front
 
439
                                    kbd_put_keycode(0xe0);
 
440
                                kbd_put_keycode(keycode & 0x7f); //remove e0 bit in front
 
441
                            /* handle monitor key events */
 
442
                            } else {
 
443
                                switch([event keyCode]) {
 
444
                                    case 123:
 
445
                                        kbd_put_keysym(QEMU_KEY_LEFT);
 
446
                                        break;
 
447
                                    case 124:
 
448
                                        kbd_put_keysym(QEMU_KEY_RIGHT);
 
449
                                        break;
 
450
                                    case 125:
 
451
                                        kbd_put_keysym(QEMU_KEY_DOWN);
 
452
                                        break;
 
453
                                    case 126:
 
454
                                        kbd_put_keysym(QEMU_KEY_UP);
 
455
                                        break;
 
456
                                    default:
 
457
                                        kbd_put_keysym([[event characters] characterAtIndex:0]);
 
458
                                        break;
 
459
                                }
 
460
                            }
 
461
                        }
269
462
                    }
270
463
                    break;
 
464
                    
271
465
                case NSKeyUp:
272
 
                    if(grab)
273
466
                    {
274
 
                        int keycode = cocoa_keycode_to_qemu([event keyCode]);
275
 
 
276
 
                        if (keycode & 0x80)
277
 
                            kbd_put_keycode(0xe0);
278
 
                        kbd_put_keycode(keycode | 0x80);
279
 
                    }
280
 
                    break;
281
 
                case NSScrollWheel:
282
 
                
 
467
                        int keycode = cocoa_keycode_to_qemu([event keyCode]);   
 
468
                        if (is_active_console(vga_console)) {
 
469
                            if (keycode & 0x80)
 
470
                                kbd_put_keycode(0xe0);
 
471
                            kbd_put_keycode(keycode | 0x80); //add 128 to signal release of key
 
472
                        }
 
473
                    }
 
474
                    break;
 
475
                    
 
476
                case NSMouseMoved:
 
477
                    if (grab) {
 
478
                        int dx = [event deltaX];
 
479
                        int dy = [event deltaY];
 
480
                        int dz = [event deltaZ];
 
481
                        int buttons = 0;
 
482
                        kbd_mouse_event(dx, dy, dz, buttons);
 
483
                    }
 
484
                    break;
 
485
                        
283
486
                case NSLeftMouseDown:
 
487
                    if (grab) {
 
488
                        int buttons = 0;
 
489
                        
 
490
                        /* leftclick+command simulates rightclick */
 
491
                        if ([event modifierFlags] & NSCommandKeyMask) {
 
492
                            buttons |= MOUSE_EVENT_RBUTTON;
 
493
                        } else {
 
494
                            buttons |= MOUSE_EVENT_LBUTTON;
 
495
                        }
 
496
                        kbd_mouse_event(0, 0, 0, buttons);
 
497
                    } else {
 
498
                        [NSApp sendEvent: event];
 
499
                    }
 
500
                    break;
 
501
                        
 
502
                case NSLeftMouseDragged:
 
503
                    if (grab) {
 
504
                        int dx = [event deltaX];
 
505
                        int dy = [event deltaY];
 
506
                        int dz = [event deltaZ];
 
507
                        int buttons = 0;
 
508
                        if ([[NSApp currentEvent] modifierFlags] & NSCommandKeyMask) { //leftclick+command simulates rightclick
 
509
                            buttons |= MOUSE_EVENT_RBUTTON;
 
510
                        } else {
 
511
                            buttons |= MOUSE_EVENT_LBUTTON;
 
512
                        }
 
513
                        kbd_mouse_event(dx, dy, dz, buttons);
 
514
                    }
 
515
                    break;
 
516
                        
284
517
                case NSLeftMouseUp:
285
 
                
286
 
                case NSOtherMouseDown:
 
518
                    if (grab) {
 
519
                        kbd_mouse_event(0, 0, 0, 0);
 
520
                    } else {
 
521
                        [window setTitle: @"QEMU (Press ctrl + alt to release Mouse)"];
 
522
                        [NSCursor hide];
 
523
                        CGAssociateMouseAndMouseCursorPosition ( FALSE );
 
524
                        grab = 1;
 
525
                        //[NSApp sendEvent: event];
 
526
                    }
 
527
                    break;
 
528
                        
287
529
                case NSRightMouseDown:
288
 
                
289
 
                case NSOtherMouseUp:
 
530
                    if (grab) {
 
531
                        int buttons = 0;
 
532
                        
 
533
                        buttons |= MOUSE_EVENT_RBUTTON;
 
534
                        kbd_mouse_event(0, 0, 0, buttons);
 
535
                    } else {
 
536
                        [NSApp sendEvent: event];
 
537
                    }
 
538
                    break;
 
539
                    
 
540
                case NSRightMouseDragged:
 
541
                    if (grab) {
 
542
                        int dx = [event deltaX];
 
543
                        int dy = [event deltaY];
 
544
                        int dz = [event deltaZ];
 
545
                        int buttons = 0;
 
546
                        buttons |= MOUSE_EVENT_RBUTTON;
 
547
                        kbd_mouse_event(dx, dy, dz, buttons);
 
548
                    }
 
549
                    break;
 
550
                    
290
551
                case NSRightMouseUp:
291
 
                
292
 
                case NSMouseMoved:
 
552
                    if (grab) {
 
553
                        kbd_mouse_event(0, 0, 0, 0);
 
554
                    } else {
 
555
                        [NSApp sendEvent: event];
 
556
                    }
 
557
                    break;
 
558
                        
293
559
                case NSOtherMouseDragged:
294
 
                case NSRightMouseDragged:
295
 
                case NSLeftMouseDragged:
 
560
                    if (grab) {
 
561
                        int dx = [event deltaX];
 
562
                        int dy = [event deltaY];
 
563
                        int dz = [event deltaZ];
 
564
                        int buttons = 0;
 
565
                        buttons |= MOUSE_EVENT_MBUTTON;
 
566
                        kbd_mouse_event(dx, dy, dz, buttons);
 
567
                    }
 
568
                    break;
 
569
                    
 
570
                case NSOtherMouseDown:
 
571
                    if (grab) {
 
572
                        int buttons = 0;
 
573
                        buttons |= MOUSE_EVENT_MBUTTON;
 
574
                        kbd_mouse_event(0, 0, 0, buttons);
 
575
                    } else {
 
576
                        [NSApp sendEvent:event];
 
577
                    }
 
578
                    break;
 
579
                        
 
580
                case NSOtherMouseUp:
 
581
                    if (grab) {
 
582
                        kbd_mouse_event(0, 0, 0, 0);
 
583
                    } else {
 
584
                        [NSApp sendEvent: event];
 
585
                    }
 
586
                    break;
 
587
                        
 
588
                case NSScrollWheel:
 
589
                    if (grab) {
 
590
                        int dz = [event deltaY];
 
591
                        kbd_mouse_event(0, 0, -dz, 0);
 
592
                    }
 
593
                    break;
296
594
                
297
595
                default: [NSApp sendEvent:event];
298
596
            }