6419 %{ |
6420 %{ |
6420 int type; |
6421 int type; |
6421 int state; |
6422 int state; |
6422 |
6423 |
6423 if (__isSmallInteger(stateMask)) { |
6424 if (__isSmallInteger(stateMask)) { |
6424 state = __intVal(stateMask); |
6425 state = __intVal(stateMask); |
6425 } else { |
6426 } else { |
6426 state = 0; |
6427 state = 0; |
6427 } |
6428 } |
6428 |
6429 |
6429 if (ISCONNECTED |
6430 if (ISCONNECTED |
6430 && __isSmallInteger(xPos) && __isSmallInteger(yPos) |
6431 && __isSmallInteger(xPos) && __isSmallInteger(yPos) |
6431 && (__isSmallInteger(keySymCodeOrButtonNr) || __isStringLike(keySymCodeOrButtonNr)) |
6432 && (__isSmallInteger(keySymCodeOrButtonNr) || __isStringLike(keySymCodeOrButtonNr)) |
6432 && (__isExternalAddress(targetId) || __isInteger(targetId))) { |
6433 && (__isExternalAddress(targetId) || __isInteger(targetId))) { |
6433 Display *dpy = myDpy; |
6434 Display *dpy = myDpy; |
6434 |
6435 |
6435 XEvent ev; |
6436 XEvent ev; |
6436 Window target; |
6437 Window target; |
6437 Status result; |
6438 Status result; |
6438 KeySym keySym, *syms; |
6439 KeySym keySym, *syms; |
6439 int screen = __intVal(__INST(screen)); |
6440 int screen = __intVal(__INST(screen)); |
6440 char s[2]; |
6441 int nSyms; |
6441 int nSyms; |
6442 |
6442 |
6443 if ((typeSymbol == @symbol(keyPress)) |
6443 if ((typeSymbol == @symbol(keyPress)) |
6444 || (typeSymbol == @symbol(keyRelease))) { |
6444 || (typeSymbol == @symbol(keyRelease))) { |
6445 if (__isStringLike(keySymCodeOrButtonNr)) { |
6445 if (__isStringLike(keySymCodeOrButtonNr)) { |
6446 keySym = XStringToKeysym(__stringVal(keySymCodeOrButtonNr)); |
6446 keySym = XStringToKeysym(__stringVal(keySymCodeOrButtonNr)); |
6447 } else { |
6447 } else { |
6448 if (__isCharacter(keySymCodeOrButtonNr)) { |
6448 if (__isCharacter(keySymCodeOrButtonNr)) { |
6449 char s[2]; |
6449 s[0] = __intVal(__characterVal(keySymCodeOrButtonNr)); |
6450 s[0] = __intVal(__characterVal(keySymCodeOrButtonNr)); |
6450 s[1] = '\0'; |
6451 s[1] = '\0'; |
6451 keySym = XStringToKeysym(s); |
6452 keySym = XStringToKeysym(s); |
6452 } else { |
6453 } else { |
6453 keySym = (KeySym) __intVal(keySymCodeOrButtonNr); |
6454 if (__isSmallInteger(keySymCodeOrButtonNr)) { |
6454 } |
6455 keySym = (KeySym) __intVal(keySymCodeOrButtonNr); |
6455 } |
6456 } else { |
6456 ev.xkey.keycode = XKeysymToKeycode(dpy, keySym); |
6457 goto notOk; |
6457 |
6458 } |
6458 if (stateMask == nil) { |
6459 } |
6459 /* |
6460 } |
6460 * get the modifier from the keySym |
6461 ev.xkey.keycode = XKeysymToKeycode(dpy, keySym); |
6461 */ |
6462 |
6462 nSyms = 0; |
6463 if (stateMask == nil) { |
6463 syms = XGetKeyboardMapping(dpy, ev.xkey.keycode, 1, &nSyms); |
6464 /* |
6464 if (syms) { |
6465 * get the modifier from the keySym |
6465 int i; |
6466 */ |
6466 |
6467 nSyms = 0; |
6467 for (i=0; i<nSyms; i++) { |
6468 syms = XGetKeyboardMapping(dpy, ev.xkey.keycode, 1, &nSyms); |
6468 if (syms[i] == keySym) { |
6469 if (syms) { |
|
6470 int i; |
|
6471 |
|
6472 for (i=0; i<nSyms; i++) { |
|
6473 if (syms[i] == keySym) { |
6469 #ifdef MODIFIERDEBUG |
6474 #ifdef MODIFIERDEBUG |
6470 console_printf("modifier-index is %d\n", i); |
6475 console_printf("modifier-index is %d\n", i); |
6471 #endif |
6476 #endif |
6472 if (i) state = (1 << (i-1)); |
6477 if (i) state = (1 << (i-1)); |
6473 break; |
6478 break; |
6474 } |
6479 } |
6475 } |
6480 } |
6476 XFree(syms); |
6481 XFree(syms); |
6477 } |
6482 } |
6478 } |
6483 } |
6479 } else { |
6484 } else { |
6480 if ((typeSymbol == @symbol(buttonPress)) |
6485 if ((typeSymbol == @symbol(buttonPress)) |
6481 || (typeSymbol == @symbol(buttonRelease))) { |
6486 || (typeSymbol == @symbol(buttonRelease))) { |
6482 if (__isSmallInteger(keySymCodeOrButtonNr)) { |
6487 if (__isSmallInteger(keySymCodeOrButtonNr)) { |
6483 ev.xbutton.button = __intVal(keySymCodeOrButtonNr); |
6488 ev.xbutton.button = __intVal(keySymCodeOrButtonNr); |
6484 } else { |
6489 } else { |
6485 ev.xbutton.button = 1; |
6490 ev.xbutton.button = 1; |
6486 } |
6491 } |
6487 } else { |
6492 } else { |
6488 DPRINTF(("invalid sendEvent typeSymbol\n")); |
6493 DPRINTF(("invalid sendEvent typeSymbol\n")); |
6489 RETURN (false); |
6494 RETURN (false); |
6490 } |
6495 } |
6491 } |
6496 } |
6492 |
6497 |
6493 if (typeSymbol == @symbol(keyPress)) |
6498 if (typeSymbol == @symbol(keyPress)) |
6494 ev.xany.type = KeyPress; |
6499 ev.xany.type = KeyPress; |
6495 else if (typeSymbol == @symbol(keyRelease)) |
6500 else if (typeSymbol == @symbol(keyRelease)) |
6496 ev.xany.type = KeyRelease; |
6501 ev.xany.type = KeyRelease; |
6497 else if (typeSymbol == @symbol(buttonPress)) |
6502 else if (typeSymbol == @symbol(buttonPress)) |
6498 ev.xany.type = ButtonPress; |
6503 ev.xany.type = ButtonPress; |
6499 else if (typeSymbol == @symbol(buttonRelease)) |
6504 else if (typeSymbol == @symbol(buttonRelease)) |
6500 ev.xany.type = ButtonRelease; |
6505 ev.xany.type = ButtonRelease; |
6501 |
6506 |
6502 if (__isExternalAddress(targetId)) { |
6507 if (__isExternalAddress(targetId)) { |
6503 target = __WindowVal(targetId); |
6508 target = __WindowVal(targetId); |
6504 } else { |
6509 } else { |
6505 target = (Window) __longIntVal(targetId); |
6510 target = (Window) __longIntVal(targetId); |
6506 } |
6511 } |
6507 ev.xkey.window = target; |
6512 ev.xkey.window = target; |
6508 ev.xkey.same_screen = 1; |
6513 ev.xkey.same_screen = 1; |
6509 ev.xkey.subwindow = 0; |
6514 ev.xkey.subwindow = 0; |
6510 ev.xkey.root = RootWindow(dpy, screen); |
6515 ev.xkey.root = RootWindow(dpy, screen); |
6511 ev.xkey.x = __intVal(xPos); |
6516 ev.xkey.x = __intVal(xPos); |
6512 ev.xkey.y = __intVal(yPos); |
6517 ev.xkey.y = __intVal(yPos); |
6513 ev.xkey.state = state; |
6518 ev.xkey.state = state; |
6514 ev.xkey.time = CurrentTime; |
6519 ev.xkey.time = CurrentTime; |
6515 |
6520 |
6516 ENTER_XLIB(); |
6521 ENTER_XLIB(); |
6517 result = XSendEvent(dpy, target, False, 0 , &ev); |
6522 result = XSendEvent(dpy, target, False, 0 , &ev); |
6518 LEAVE_XLIB(); |
6523 LEAVE_XLIB(); |
6519 if ((result == BadValue) || (result == BadWindow)) { |
6524 if ((result == BadValue) || (result == BadWindow)) { |
6520 DPRINTF(("bad status\n")); |
6525 DPRINTF(("bad status\n")); |
6521 RETURN ( false ) |
6526 RETURN ( false ) |
6522 } |
6527 } |
6523 RETURN (true) |
6528 RETURN (true) |
6524 } |
6529 } |
|
6530 notOk: ; |
6525 %}. |
6531 %}. |
6526 self primitiveFailedOrClosedConnection. |
6532 self primitiveFailedOrClosedConnection. |
6527 ^ false |
6533 ^ false |
6528 |
6534 |
6529 "<<END |
6535 "<<END |
6533 v contents:'Hello world'. |
6539 v contents:'Hello world'. |
6534 v openAndWait. |
6540 v openAndWait. |
6535 v selectFromCharacterPosition:1 to:5. |
6541 v selectFromCharacterPosition:1 to:5. |
6536 |
6542 |
6537 "/ CTRL-c |
6543 "/ CTRL-c |
6538 v device |
6544 v device |
6539 sendKeyOrButtonEvent:#keyPress |
6545 sendKeyOrButtonEvent:#keyPress |
6540 x:10 y:10 |
6546 x:10 y:10 |
6541 keyOrButton:#'Control' |
6547 keyOrButton:#'Control' |
6542 state:(v device ctrlModifierMask) |
6548 state:(v device ctrlModifierMask) |
6543 toViewId: v id. |
6549 toViewId: v id. |
6544 |
6550 |
6545 v device |
6551 v device |
6546 sendKeyOrButtonEvent:#keyPress |
6552 sendKeyOrButtonEvent:#keyPress |
6547 x:10 y:10 |
6553 x:10 y:10 |
6548 keyOrButton:'c' |
6554 keyOrButton:'c' |
6549 state:(v device ctrlModifierMask) |
6555 state:(v device ctrlModifierMask) |
6550 toViewId: v id. |
6556 toViewId: v id. |
6551 |
6557 |
6552 v device |
6558 v device |
6553 sendKeyOrButtonEvent:#keyRelease |
6559 sendKeyOrButtonEvent:#keyRelease |
6554 x:10 y:10 |
6560 x:10 y:10 |
6555 keyOrButton:'c' |
6561 keyOrButton:'c' |
6556 state:(v device ctrlModifierMask) |
6562 state:(v device ctrlModifierMask) |
6557 toViewId: v id. |
6563 toViewId: v id. |
6558 |
6564 |
6559 v device |
6565 v device |
6560 sendKeyOrButtonEvent:#keyRelease |
6566 sendKeyOrButtonEvent:#keyRelease |
6561 x:10 y:10 |
6567 x:10 y:10 |
6562 keyOrButton:#'Control' |
6568 keyOrButton:#'Control' |
6563 state:0 |
6569 state:0 |
6564 toViewId: v id. |
6570 toViewId: v id. |
6565 |
6571 |
6566 "/ CTRL-v |
6572 "/ CTRL-v |
6567 |
6573 |
6568 v device |
6574 v device |
6569 sendKeyOrButtonEvent:#keyPress |
6575 sendKeyOrButtonEvent:#keyPress |
6570 x:10 y:10 |
6576 x:10 y:10 |
6571 keyOrButton:#'Control' |
6577 keyOrButton:#'Control' |
6572 state:(v device ctrlModifierMask) |
6578 state:(v device ctrlModifierMask) |
6573 toViewId: v id. |
6579 toViewId: v id. |
6574 |
6580 |
6575 v device |
6581 v device |
6576 sendKeyOrButtonEvent:#keyPress |
6582 sendKeyOrButtonEvent:#keyPress |
6577 x:10 y:10 |
6583 x:10 y:10 |
6578 keyOrButton:'v' |
6584 keyOrButton:'v' |
6579 state:(v device ctrlModifierMask) |
6585 state:(v device ctrlModifierMask) |
6580 toViewId: v id. |
6586 toViewId: v id. |
6581 |
6587 |
6582 v device |
6588 v device |
6583 sendKeyOrButtonEvent:#keyRelease |
6589 sendKeyOrButtonEvent:#keyRelease |
6584 x:10 y:10 |
6590 x:10 y:10 |
6585 keyOrButton:'v' |
6591 keyOrButton:'v' |
6586 state:(v device ctrlModifierMask) |
6592 state:(v device ctrlModifierMask) |
6587 toViewId: v id. |
6593 toViewId: v id. |
6588 |
6594 |
6589 v device |
6595 v device |
6590 sendKeyOrButtonEvent:#keyRelease |
6596 sendKeyOrButtonEvent:#keyRelease |
6591 x:10 y:10 |
6597 x:10 y:10 |
6592 keyOrButton:#'Control' |
6598 keyOrButton:#'Control' |
6593 state:0 |
6599 state:0 |
6594 toViewId: v id. |
6600 toViewId: v id. |
6595 END" |
6601 END" |
6596 ! ! |
6602 ! ! |
6597 |
6603 |
6598 !XWorkstation methodsFor:'font stuff'! |
6604 !XWorkstation methodsFor:'font stuff'! |
6599 |
6605 |
7546 FontDescription." |
7552 FontDescription." |
7547 |
7553 |
7548 |names| |
7554 |names| |
7549 |
7555 |
7550 listOfXFonts isNil ifTrue:[ |
7556 listOfXFonts isNil ifTrue:[ |
7551 names := self getAvailableFontsMatching:'*'. |
7557 names := self getAvailableFontsMatching:'*'. |
7552 names isNil ifTrue:[ |
7558 names isNil ifTrue:[ |
7553 "no names returned ..." |
7559 "no names returned ..." |
7554 ^ nil |
7560 ^ nil |
7555 ]. |
7561 ]. |
7556 listOfXFonts := names collect:[:aName | self fontDescriptionFromXFontName:aName]. |
7562 listOfXFonts := names collect:[:aName | self fontDescriptionFromXFontName:aName]. |
7557 listOfXFonts := FontDescription genericFonts, listOfXFonts. |
7563 listOfXFonts := FontDescription genericFonts, listOfXFonts. |
7558 ]. |
7564 ]. |
7559 |
7565 |
7560 (XftFontDescription notNil |
7566 (XftFontDescription notNil |
7561 and:[ XftFontDescription isLoaded |
7567 and:[ XftFontDescription isLoaded |
7562 and:[ self supportsXFTFonts ]] |
7568 and:[ self supportsXFTFonts ]] |
7563 ) ifTrue:[ |
7569 ) ifTrue:[ |
7564 UserPreferences current useXftFontsOnly ifTrue:[ |
7570 UserPreferences current useXftFontsOnly ifTrue:[ |
7565 ^ (XftFontDescription listOfAvailableFonts) |
7571 ^ (XftFontDescription listOfAvailableFonts) |
7566 ]. |
7572 ]. |
7567 ^ listOfXFonts , (XftFontDescription listOfAvailableFonts). |
7573 ^ listOfXFonts , (XftFontDescription listOfAvailableFonts). |
7568 ]. |
7574 ]. |
7569 ^ listOfXFonts |
7575 ^ listOfXFonts |
7570 |
7576 |
7571 " |
7577 " |
7572 Display flushListOfAvailableFonts. |
7578 Display flushListOfAvailableFonts. |
7856 #undef NLOCALBUFFER |
7862 #undef NLOCALBUFFER |
7857 fail: ; |
7863 fail: ; |
7858 %}. |
7864 %}. |
7859 self primitiveFailedOrClosedConnection. |
7865 self primitiveFailedOrClosedConnection. |
7860 ^ 0 |
7866 ^ 0 |
|
7867 ! ! |
|
7868 |
|
7869 !XWorkstation methodsFor:'grabbing-keys'! |
|
7870 |
|
7871 grabKey:keySymCodeOrChar modifier:modifierMaskOrNil window:aWindowIdOrNil |
|
7872 "grab a single key either for an individual window |
|
7873 or the whole screen (if aWindowIdOrNil is nil). |
|
7874 The keySymCodeOrChar argument may be a keySym (name of a key) or an integer (the keySymCode) |
|
7875 or a character. |
|
7876 The modifierMaskOrNil is as mask as returned by altModifierMask, ctrlModifierMask, etc. |
|
7877 if nil, the key is grabbed with AnyModifier. |
|
7878 Only the key is passed to myself - no permanent grab is installed. |
|
7879 (GrabModeAsync)" |
|
7880 |
|
7881 ^ sekf |
|
7882 grabKey:keySymCodeOrChar |
|
7883 modifier:modifierMaskOrNil |
|
7884 grabModeKeyboard:#GrabModeAsync |
|
7885 grabModePointer:#GrabModeAsync |
|
7886 window:aWindowIdOrNil |
|
7887 ! |
|
7888 |
|
7889 grabKey:keySymCodeOrChar modifier:modifierMaskOrNil grabModeKeyboard:modeKbd grabModePointer:modePtr window:aWindowIdOrNil |
|
7890 "internal basic entry to grab a single key either for an individual window |
|
7891 or the whole screen (if aWindowIdOrNil is nil). |
|
7892 The keySymCodeOrChar argument may be a keySym (name of a key) or an integer (the keySymCode) |
|
7893 or a character. |
|
7894 The modifierMaskOrNil is as mask as returned by altModifierMask, ctrlModifierMask, etc. |
|
7895 if nil, the key is grabbed with AnyModifier. |
|
7896 ModeKbd and modePtr are symbols GrabModeAsync or GrabModeSync. |
|
7897 |
|
7898 After that, this key-event will no longer be sent to the window/screen. |
|
7899 |
|
7900 Use with care: the only useful application is to define a special hotKey |
|
7901 to start/stop event recorders without a need for a click or focus change. |
|
7902 Once grabbed, those key events will be exclusively reported to me. |
|
7903 |
|
7904 Use GrabModeSync with big care - you can easily lock up your Xserver, |
|
7905 and have to kill ST/X or force an ungrab from a remote login if you have. |
|
7906 " |
|
7907 |
|
7908 %{ |
|
7909 int modifierMask = AnyModifier; |
|
7910 KeySym keySym, *syms; |
|
7911 |
|
7912 if (__isStringLike(keySymCodeOrChar)) { |
|
7913 keySym = XStringToKeysym(__stringVal(keySymCodeOrChar)); |
|
7914 } else { |
|
7915 if (__isCharacter(keySymCodeOrChar)) { |
|
7916 char s[2]; |
|
7917 |
|
7918 s[0] = __intVal(__characterVal(keySymCodeOrChar)); |
|
7919 s[1] = '\0'; |
|
7920 keySym = XStringToKeysym(s); |
|
7921 } else { |
|
7922 if (__isSmallInteger(keySymCodeOrChar)) { |
|
7923 keySym = (KeySym) __intVal(keySymCodeOrChar); |
|
7924 } else { |
|
7925 goto notOK; |
|
7926 } |
|
7927 } |
|
7928 } |
|
7929 |
|
7930 if (modifierMaskOrNil != nil) { |
|
7931 if (__isSmallInteger(modifierMaskOrNil)) { |
|
7932 modifierMask = __intVal(modifierMaskOrNil); |
|
7933 } else { |
|
7934 goto notOK; |
|
7935 } |
|
7936 } |
|
7937 |
|
7938 if (ISCONNECTED) { |
|
7939 Display *dpy; |
|
7940 Window window; |
|
7941 int keyCode; |
|
7942 int result; |
|
7943 int mKbd, mPtr; |
|
7944 |
|
7945 mKbd = modeKbd == @symbol(GrabModeAsync) ? GrabModeAsync :GrabModeSync; |
|
7946 mPtr = modePtr == @symbol(GrabModeAsync) ? GrabModeAsync :GrabModeSync; |
|
7947 |
|
7948 dpy = myDpy; |
|
7949 keyCode = XKeysymToKeycode(dpy, keySym); |
|
7950 if (__isExternalAddress(aWindowIdOrNil)) { |
|
7951 window = __WindowVal(aWindowIdOrNil); |
|
7952 } else { |
|
7953 int screen; |
|
7954 |
|
7955 screen = DefaultScreen(dpy); |
|
7956 window = RootWindow(dpy, screen); |
|
7957 } |
|
7958 ENTER_XLIB(); |
|
7959 |
|
7960 result = XGrabKey (dpy, |
|
7961 keyCode, modifierMask, window, |
|
7962 False, mKbd, mPtr ); |
|
7963 |
|
7964 XSync(dpy, True); |
|
7965 XFlush(dpy); |
|
7966 |
|
7967 LEAVE_XLIB(); |
|
7968 |
|
7969 if (result != Success) { |
|
7970 if (result == BadAccess) { |
|
7971 __INST(lastError) = @symbol(badAccess); |
|
7972 } else { |
|
7973 __INST(lastError) = @symbol(other); |
|
7974 } |
|
7975 RETURN (false); |
|
7976 } |
|
7977 RETURN (true); |
|
7978 } |
|
7979 notOK: ; |
|
7980 %}. |
|
7981 self primitiveFailedOrClosedConnection |
|
7982 ! |
|
7983 |
|
7984 ungrabKey:keySymCodeOrChar modifier:modifierMaskOrNil window:aWindowIdOrNil |
|
7985 "ungrab a single key as previously grabbed via grabKey: |
|
7986 Read the comment there." |
|
7987 |
|
7988 %{ |
|
7989 int modifierMask = AnyModifier; |
|
7990 KeySym keySym, *syms; |
|
7991 |
|
7992 if (__isStringLike(keySymCodeOrChar)) { |
|
7993 keySym = XStringToKeysym(__stringVal(keySymCodeOrChar)); |
|
7994 } else { |
|
7995 if (__isCharacter(keySymCodeOrChar)) { |
|
7996 char s[2]; |
|
7997 |
|
7998 s[0] = __intVal(__characterVal(keySymCodeOrChar)); |
|
7999 s[1] = '\0'; |
|
8000 keySym = XStringToKeysym(s); |
|
8001 } else { |
|
8002 if (__isSmallInteger(keySymCodeOrChar)) { |
|
8003 keySym = (KeySym) __intVal(keySymCodeOrChar); |
|
8004 } else { |
|
8005 goto notOK; |
|
8006 } |
|
8007 } |
|
8008 } |
|
8009 |
|
8010 if (modifierMaskOrNil != nil) { |
|
8011 if (__isSmallInteger(modifierMaskOrNil)) { |
|
8012 modifierMask = __intVal(modifierMaskOrNil); |
|
8013 } else { |
|
8014 goto notOK; |
|
8015 } |
|
8016 } |
|
8017 |
|
8018 if (ISCONNECTED) { |
|
8019 Display *dpy; |
|
8020 Window window; |
|
8021 int keyCode; |
|
8022 int result; |
|
8023 |
|
8024 dpy = myDpy; |
|
8025 if (__isExternalAddress(aWindowIdOrNil)) { |
|
8026 window = __WindowVal(aWindowIdOrNil); |
|
8027 } else { |
|
8028 int screen; |
|
8029 |
|
8030 screen = DefaultScreen(dpy); |
|
8031 window = RootWindow(dpy, screen); |
|
8032 } |
|
8033 keyCode = XKeysymToKeycode(dpy, keySym); |
|
8034 |
|
8035 ENTER_XLIB(); |
|
8036 |
|
8037 result = XUngrabKey (dpy, keyCode, modifierMask, window); |
|
8038 |
|
8039 XSync(dpy, True); |
|
8040 XFlush(dpy); |
|
8041 |
|
8042 LEAVE_XLIB(); |
|
8043 |
|
8044 if (result != Success) { |
|
8045 if (result == BadAccess) { |
|
8046 __INST(lastError) = @symbol(badAccess); |
|
8047 } else { |
|
8048 __INST(lastError) = @symbol(other); |
|
8049 } |
|
8050 RETURN (false); |
|
8051 } |
|
8052 RETURN (true); |
|
8053 } |
|
8054 notOK: ; |
|
8055 %}. |
|
8056 self primitiveFailedOrClosedConnection |
7861 ! ! |
8057 ! ! |
7862 |
8058 |
7863 !XWorkstation methodsFor:'grabbing'! |
8059 !XWorkstation methodsFor:'grabbing'! |
7864 |
8060 |
7865 allowEvents:mode |
8061 allowEvents:mode |