Mercurial > projects > dynamin
comparison dynamin/gui/x_window.d @ 24:43a88caead16
Implement keyDown and keyUp events with X.
author | Jordan Miner <jminer7@gmail.com> |
---|---|
date | Sat, 25 Jul 2009 15:01:46 -0500 |
parents | d55b5b998412 |
children | 0577e8738dc8 |
comparison
equal
deleted
inserted
replaced
23:d55b5b998412 | 24:43a88caead16 |
---|---|
27 | 27 |
28 public import dynamin.core.string; | 28 public import dynamin.core.string; |
29 public import dynamin.core.global; | 29 public import dynamin.core.global; |
30 public import dynamin.core.math; | 30 public import dynamin.core.math; |
31 public import dynamin.gui.window; | 31 public import dynamin.gui.window; |
32 public import dynamin.gui.key; | |
32 public import dynamin.c.xlib; | 33 public import dynamin.c.xlib; |
33 public import dynamin.c.xlib : XWindow = Window; | 34 public import dynamin.c.xlib : XWindow = Window; |
34 public import dynamin.c.xmu; | 35 public import dynamin.c.xmu; |
35 public import dynamin.c.cairo; | 36 public import dynamin.c.cairo; |
36 public import dynamin.c.cairo_xlib; | 37 public import dynamin.c.cairo_xlib; |
207 int x2, int y2, int width2, int height2) { | 208 int x2, int y2, int width2, int height2) { |
208 } | 209 } |
209 void compress() { | 210 void compress() { |
210 } | 211 } |
211 }+/ | 212 }+/ |
213 | |
214 Key prevKey = Key.None; | |
212 | 215 |
213 //{{{ ApplicationBackend | 216 //{{{ ApplicationBackend |
214 template ApplicationBackend() { | 217 template ApplicationBackend() { |
215 void backend_run(Window w) { | 218 void backend_run(Window w) { |
216 bool isWindowVisible() { | 219 bool isWindowVisible() { |
263 default: return; | 266 default: return; |
264 } | 267 } |
265 scope args = new MouseEventArgs(buttonEv.x+c._borderSize.left, buttonEv.y+c._borderSize.top, button); | 268 scope args = new MouseEventArgs(buttonEv.x+c._borderSize.left, buttonEv.y+c._borderSize.top, button); |
266 func(args); | 269 func(args); |
267 } | 270 } |
271 bool isKeyDown(uint keycode) { | |
272 ubyte[32] keys; | |
273 XQueryKeymap(display, keys.ptr); | |
274 return cast(bool)( (keys[keycode / 8] >> (keycode % 8)) & 1 ); | |
275 } | |
268 //}}} | 276 //}}} |
269 switch(ev.type) { | 277 switch(ev.type) { |
270 case MapNotify: | 278 case MapNotify: |
271 c.mapped = true; | 279 c.mapped = true; |
272 break; | 280 break; |
293 XDestroyWindow(evDisplay, evWindow); | 301 XDestroyWindow(evDisplay, evWindow); |
294 return; // TODO: check event, and figure out what to do | 302 return; // TODO: check event, and figure out what to do |
295 } | 303 } |
296 break; | 304 break; |
297 case KeyPress: | 305 case KeyPress: |
306 auto sym = XLookupKeysym(&ev.xkey, 0); | |
307 if(sym == NoSymbol) | |
308 break; | |
309 // Since X gives no way to tell if a KeyPress is generated by | |
310 // auto-repeat, prevKey is used here to tell. | |
311 auto k = KeysymToKey(sym); | |
312 scope args = new KeyEventArgs(k, k == prevKey); | |
313 prevKey = k; | |
314 Control focused = c.focusedControl ? c.focusedControl : c; | |
315 focused.keyDown(args); | |
298 break; | 316 break; |
299 case KeyRelease: | 317 case KeyRelease: |
318 // When X does auto-repeat for a held down key, it sends | |
319 // a KeyPress and KeyRelease every time, even though the key is | |
320 // down constantly. Here we check if the key is down, and if so, | |
321 // not send a keyUp event. | |
322 if(isKeyDown(ev.xkey.keycode)) | |
323 break; | |
324 auto sym = XLookupKeysym(&ev.xkey, 0); | |
325 if(sym == NoSymbol) | |
326 break; | |
327 auto k = KeysymToKey(sym); | |
328 if(k == prevKey) | |
329 prevKey = Key.None; // can't repeat after released | |
330 scope args = new KeyEventArgs(k, false); | |
331 Control focused = c.focusedControl ? c.focusedControl : c; | |
332 focused.keyUp(args); | |
300 break; | 333 break; |
301 case ButtonPress: | 334 case ButtonPress: |
302 //Button4 is wheel scroll up | 335 //Button4 is wheel scroll up |
303 //Button5 is wheel scroll down | 336 //Button5 is wheel scroll down |
304 createMouseEvent((MouseEventArgs args) { c.mouseDown(args); }); | 337 createMouseEvent((MouseEventArgs args) { c.mouseDown(args); }); |
429 } | 462 } |
430 XChangeProperty(display, selEv.requestor, selEv.property, | 463 XChangeProperty(display, selEv.requestor, selEv.property, |
431 data.target, 8, PropModeReplace, data.data, data.length); | 464 data.target, 8, PropModeReplace, data.data, data.length); |
432 XSendEvent(display, selEv.requestor, false, 0, &fullEv); | 465 XSendEvent(display, selEv.requestor, false, 0, &fullEv); |
433 break; | 466 break; |
467 case MappingNotify: | |
468 XRefreshKeyboardMapping(&ev.xmapping); | |
469 break; | |
434 default: | 470 default: |
435 break; | 471 break; |
436 } | 472 } |
437 } | 473 } |
438 } | 474 } |
441 } | 477 } |
442 void backend_invokeNow(void delegate() dg) { | 478 void backend_invokeNow(void delegate() dg) { |
443 // TODO: | 479 // TODO: |
444 } | 480 } |
445 | 481 |
482 } | |
483 //}}} | |
484 | |
485 //{{{ KeysymToKey() | |
486 Key KeysymToKey(int sym) { | |
487 switch(sym) { | |
488 case XK_parenright: | |
489 case XK_0: return Key.D0; | |
490 case XK_exclam: | |
491 case XK_1: return Key.D1; | |
492 case XK_at: | |
493 case XK_2: return Key.D2; | |
494 case XK_numbersign: | |
495 case XK_3: return Key.D3; | |
496 case XK_dollar: | |
497 case XK_4: return Key.D4; | |
498 case XK_percent: | |
499 case XK_5: return Key.D5; | |
500 case XK_asciicircum: | |
501 case XK_6: return Key.D6; | |
502 case XK_ampersand: | |
503 case XK_7: return Key.D7; | |
504 case XK_asterisk: | |
505 case XK_8: return Key.D8; | |
506 case XK_parenleft: | |
507 case XK_9: return Key.D9; | |
508 | |
509 case XK_F1: return Key.F1; | |
510 case XK_F2: return Key.F2; | |
511 case XK_F3: return Key.F3; | |
512 case XK_F4: return Key.F4; | |
513 case XK_F5: return Key.F5; | |
514 case XK_F6: return Key.F6; | |
515 case XK_F7: return Key.F7; | |
516 case XK_F8: return Key.F8; | |
517 case XK_F9: return Key.F9; | |
518 case XK_F10: return Key.F10; | |
519 case XK_F11: return Key.F11; | |
520 case XK_F12: return Key.F12; | |
521 | |
522 case XK_Escape: return Key.Escape; | |
523 case XK_Tab: return Key.Tab; | |
524 case XK_BackSpace: return Key.Backspace; | |
525 case XK_Return: return Key.Enter; | |
526 case XK_KP_Enter: return Key.Enter; | |
527 case XK_space: return Key.Space; | |
528 | |
529 case XK_KP_Left: | |
530 case XK_Left: return Key.Left; | |
531 case XK_KP_Right: | |
532 case XK_Right: return Key.Right; | |
533 case XK_KP_Up: | |
534 case XK_Up: return Key.Up; | |
535 case XK_KP_Down: | |
536 case XK_Down: return Key.Down; | |
537 | |
538 case XK_KP_Insert: | |
539 case XK_Insert: return Key.Insert; | |
540 case XK_KP_Delete: | |
541 case XK_Delete: return Key.Delete; | |
542 case XK_KP_Home: | |
543 case XK_Home: return Key.Home; | |
544 case XK_KP_End: | |
545 case XK_End: return Key.End; | |
546 case XK_KP_Prior: | |
547 case XK_Prior: return Key.PageUp; | |
548 case XK_KP_Next: | |
549 case XK_Next: return Key.PageDown; | |
550 | |
551 case XK_Print: | |
552 case XK_Sys_Req: return Key.PrintScreen; | |
553 case XK_Pause: | |
554 case XK_Break: return Key.Pause; | |
555 | |
556 case XK_Caps_Lock: return Key.CapsLock; | |
557 case XK_Num_Lock: return Key.NumLock; | |
558 case XK_Scroll_Lock: return Key.ScrollLock; | |
559 | |
560 case XK_KP_0: return Key.NumPad0; | |
561 case XK_KP_1: return Key.NumPad1; | |
562 case XK_KP_2: return Key.NumPad2; | |
563 case XK_KP_3: return Key.NumPad3; | |
564 case XK_KP_4: return Key.NumPad4; | |
565 case XK_KP_5: return Key.NumPad5; | |
566 case XK_KP_6: return Key.NumPad6; | |
567 case XK_KP_7: return Key.NumPad7; | |
568 case XK_KP_8: return Key.NumPad8; | |
569 case XK_KP_9: return Key.NumPad9; | |
570 case XK_KP_Divide: return Key.NumPadDivide; | |
571 case XK_KP_Multiply: return Key.NumPadMultiply; | |
572 case XK_KP_Subtract: return Key.NumPadSubtract; | |
573 case XK_KP_Add: return Key.NumPadAdd; | |
574 case XK_KP_Decimal: return Key.NumPadDecimal; | |
575 | |
576 case XK_grave: | |
577 case XK_asciitilde: return Key.Backquote; | |
578 case XK_minus: | |
579 case XK_underscore: return Key.Minus; | |
580 case XK_equal: | |
581 case XK_plus: return Key.Equals; | |
582 case XK_bracketleft: | |
583 case XK_braceleft: return Key.OpenBracket; | |
584 case XK_bracketright: | |
585 case XK_braceright: return Key.CloseBracket; | |
586 case XK_backslash: | |
587 case XK_bar: return Key.Backslash; | |
588 case XK_semicolon: | |
589 case XK_colon: return Key.Semicolon; | |
590 case XK_apostrophe: | |
591 case XK_quotedbl: return Key.Quote; | |
592 case XK_comma: | |
593 case XK_less: return Key.Comma; | |
594 case XK_period: | |
595 case XK_greater: return Key.Period; | |
596 case XK_slash: | |
597 case XK_question: return Key.Slash; | |
598 | |
599 //case XK_Menu: return Key.Menu; | |
600 | |
601 case XK_Shift_L: | |
602 case XK_Shift_R: return Key.Shift; | |
603 case XK_Control_L: | |
604 case XK_Control_R: return Key.Control; | |
605 case XK_Alt_L: | |
606 case XK_Alt_R: return Key.Alt; | |
607 | |
608 //case XK_: return Key.; | |
609 default: | |
610 if(sym >= 0x41 && sym <= 0x5A) // Key.A - Key.Z | |
611 return cast(Key)sym; | |
612 if(sym >= 0x61 && sym <= 0x7A) // Key.A - Key.Z | |
613 return cast(Key)(sym-32); | |
614 return cast(Key)0; | |
615 } | |
446 } | 616 } |
447 //}}} | 617 //}}} |
448 | 618 |
449 public import tango.stdc.time; | 619 public import tango.stdc.time; |
450 template WindowBackend() { | 620 template WindowBackend() { |