2864 #endif |
2876 #endif |
2865 |
2877 |
2866 fail: ; |
2878 fail: ; |
2867 %} |
2879 %} |
2868 . |
2880 . |
|
2881 ^ false |
|
2882 ! ! |
|
2883 |
|
2884 !XWorkstation methodsFor:'event sending'! |
|
2885 |
|
2886 simulateKeyboardInput:aCharacterOrString inViewId:viewId |
|
2887 "send input to some other view, by simulating keyPress/keyRelease |
|
2888 events. Notice: not all alien views allow this kind of synthetic input; |
|
2889 some simply ignore it." |
|
2890 |
|
2891 |shifted control code state| |
|
2892 |
|
2893 aCharacterOrString isString ifTrue:[ |
|
2894 aCharacterOrString do:[:char | |
|
2895 self simulateKeyboardInput:char inViewId:viewId |
|
2896 ]. |
|
2897 ^ self |
|
2898 ]. |
|
2899 |
|
2900 shifted := false. |
|
2901 control := false. |
|
2902 code := aCharacterOrString asciiValue. |
|
2903 |
|
2904 (aCharacterOrString between:$A and:$Z) ifTrue:[ |
|
2905 "/ shifted |
|
2906 shifted := true |
|
2907 ] ifFalse:[ |
|
2908 (aCharacterOrString between:$a and:$z) ifTrue:[ |
|
2909 "/ unshifted alpha |
|
2910 code := code - $a asciiValue + $A asciiValue |
|
2911 ] |
|
2912 ]. |
|
2913 |
|
2914 shifted ifTrue:[ |
|
2915 state := self shiftMask |
|
2916 ] ifFalse:[ |
|
2917 state := 0 |
|
2918 ]. |
|
2919 control ifTrue:[ |
|
2920 state := state bitOr:(self controlMask) |
|
2921 ]. |
|
2922 |
|
2923 self sendKeyEvent:#keyPress x:0 y:0 key:code state:state toViewId:viewId. |
|
2924 self sendKeyEvent:#keyRelease x:0 y:0 key:code state:state toViewId:viewId |
|
2925 |
|
2926 " |
|
2927 sending input to some (possibly alien) view: |
|
2928 |
|
2929 |point id| |
|
2930 |
|
2931 point := Display pointFromUser. |
|
2932 id := Display viewIdFromPoint:point. |
|
2933 Display simulateKeyboardInput:'hello' inViewId:id |
|
2934 " |
|
2935 ! |
|
2936 |
|
2937 sendKeyEvent:typeSymbol x:xPos y:yPos key:keySymCode state:stateMask toViewId:targetId |
|
2938 "send a keyPress/keyRelease event to some (possibly alien) view. |
|
2939 TypeSymbol must be one of: #keyPress / #keyRelease. |
|
2940 keySymCode can be either a symbol (as listen in X's keySyms or a numeric keysym) |
|
2941 This is the lowlevel entry, where state must include any shift/ctrl information |
|
2942 (not very user friendly)" |
|
2943 |
|
2944 %{ /* NOCONTEXT */ |
|
2945 Display *dpy = myDpy; |
|
2946 int type; |
|
2947 |
|
2948 if (ISCONNECTED |
|
2949 && __isSmallInteger(xPos) && __isSmallInteger(yPos) |
|
2950 && __isSmallInteger(keySymCode) && __isSmallInteger(stateMask) |
|
2951 && (__isExternalAddress(targetId) || __isInteger(targetId))) { |
|
2952 XEvent ev; |
|
2953 Window target; |
|
2954 Status result; |
|
2955 KeySym keySym; |
|
2956 int screen = _intVal(_INST(screen)); |
|
2957 |
|
2958 ev.xkey.x = __intVal(xPos); |
|
2959 ev.xkey.y = __intVal(yPos); |
|
2960 if (__isSymbol(keySymCode)) { |
|
2961 keySym = XStringToKeysym(__stringVal(keySymCode)); |
|
2962 } else { |
|
2963 keySym = (KeySym) __intVal(keySymCode); |
|
2964 } |
|
2965 ev.xkey.keycode = XKeysymToKeycode(dpy, keySym); |
|
2966 ev.xkey.state = __intVal(stateMask); |
|
2967 ev.xkey.time = CurrentTime; |
|
2968 |
|
2969 if (typeSymbol == @symbol(keyPress)) |
|
2970 ev.xkey.type = KeyPress; |
|
2971 else if (typeSymbol == @symbol(keyRelease)) |
|
2972 ev.xkey.type = KeyRelease; |
|
2973 else { |
|
2974 DPRINTF(("invalid sendEvent typeSymbol\n")); |
|
2975 RETURN (false); |
|
2976 } |
|
2977 |
|
2978 if (__isExternalAddress(targetId)) { |
|
2979 target = _WindowVal(targetId); |
|
2980 } else { |
|
2981 target = (Window) __longIntVal(targetId); |
|
2982 } |
|
2983 ev.xkey.window = target; |
|
2984 ev.xkey.same_screen = 1; |
|
2985 ev.xkey.subwindow = 0; |
|
2986 ev.xkey.root = RootWindow(myDpy, screen); |
|
2987 |
|
2988 result = XSendEvent(dpy, target, False, 0 , &ev); |
|
2989 if ((result == BadValue) || (result == BadWindow)) { |
|
2990 DPRINTF(("bad status\n")); |
|
2991 RETURN ( false ) |
|
2992 } |
|
2993 RETURN (true) |
|
2994 } |
|
2995 %}. |
|
2996 self primitiveFailed. |
|
2997 ^ false |
|
2998 ! |
|
2999 |
|
3000 sendButtonEvent:typeSymbol x:xPos y:yPos button:buttonNr state:stateMask toViewId:targetId |
|
3001 "send a buttonPress/buttonRelease event to some (possibly alien) view. |
|
3002 TypeSymbol must be one of: #buttonPress / #buttonRelease. |
|
3003 This is the lowlevel entry, where state must include any shift/ctrl information |
|
3004 (not very user friendly)" |
|
3005 |
|
3006 %{ /* NOCONTEXT */ |
|
3007 Display *dpy = myDpy; |
|
3008 int type; |
|
3009 |
|
3010 if (ISCONNECTED |
|
3011 && __isSmallInteger(xPos) && __isSmallInteger(yPos) |
|
3012 && __isSmallInteger(buttonNr) && __isSmallInteger(stateMask) |
|
3013 && (__isExternalAddress(targetId) || __isInteger(targetId))) { |
|
3014 XEvent ev; |
|
3015 Window target; |
|
3016 Status result; |
|
3017 int screen = _intVal(_INST(screen)); |
|
3018 |
|
3019 ev.xbutton.x = __intVal(xPos); |
|
3020 ev.xbutton.y = __intVal(yPos); |
|
3021 ev.xbutton.button = __intVal(buttonNr); |
|
3022 ev.xbutton.state = __intVal(stateMask); |
|
3023 ev.xbutton.time = CurrentTime; |
|
3024 |
|
3025 if (typeSymbol == @symbol(buttonPress)) |
|
3026 ev.xbutton.type = ButtonPress; |
|
3027 else if (typeSymbol == @symbol(buttonRelease)) |
|
3028 ev.xbutton.type = ButtonRelease; |
|
3029 else { |
|
3030 DPRINTF(("invalid sendEvent typeSymbol\n")); |
|
3031 RETURN (false); |
|
3032 } |
|
3033 |
|
3034 if (__isExternalAddress(targetId)) { |
|
3035 target = _WindowVal(targetId); |
|
3036 } else { |
|
3037 target = (Window) __longIntVal(targetId); |
|
3038 } |
|
3039 ev.xbutton.window = target; |
|
3040 ev.xbutton.same_screen = 1; |
|
3041 ev.xbutton.subwindow = 0; |
|
3042 ev.xbutton.root = RootWindow(myDpy, screen); |
|
3043 |
|
3044 result = XSendEvent(dpy, target, False, 0 , &ev); |
|
3045 if ((result == BadValue) || (result == BadWindow)) { |
|
3046 DPRINTF(("bad status\n")); |
|
3047 RETURN ( false ) |
|
3048 } |
|
3049 RETURN (true) |
|
3050 } |
|
3051 %}. |
|
3052 self primitiveFailed. |
2869 ^ false |
3053 ^ false |
2870 ! ! |
3054 ! ! |
2871 |
3055 |
2872 !XWorkstation methodsFor:'event handling'! |
3056 !XWorkstation methodsFor:'event handling'! |
2873 |
3057 |