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() {