Add code to track 5 valuators for pointing device, in preparation

for supporting tablet input in Xquartz.
(cherry picked from commit 22c8849ea819eb70a14b2e06330b11b22aa63ebc)
This commit is contained in:
Ben Byer 2008-03-28 20:47:44 -07:00 committed by Jeremy Huddleston
parent 6648867d8b
commit a4d0349411
3 changed files with 80 additions and 20 deletions

View File

@ -61,7 +61,7 @@ int X11EnableKeyEquivalents = TRUE;
int quartzHasRoot = FALSE, quartzEnableRootless = TRUE; int quartzHasRoot = FALSE, quartzEnableRootless = TRUE;
extern int darwinFakeButtons, input_check_flag; extern int darwinFakeButtons, input_check_flag;
extern Bool enable_stereo; extern Bool enable_stereo;
extern xEvent *darwinEvents; extern xEvent *darwinEvents;
@ -153,7 +153,7 @@ static void message_kit_thread (SEL selector, NSObject *arg) {
tem = [infoDict objectForKey:@"CFBundleShortVersionString"]; tem = [infoDict objectForKey:@"CFBundleShortVersionString"];
[dict setObject:[NSString stringWithFormat:@"Xquartz %@ - (xorg-server %s)", tem, XSERVER_VERSION] [dict setObject:[NSString stringWithFormat:@"XQuartz %@ - (xorg-server %s)", tem, XSERVER_VERSION]
forKey:@"ApplicationVersion"]; forKey:@"ApplicationVersion"];
[self orderFrontStandardAboutPanelWithOptions: dict]; [self orderFrontStandardAboutPanelWithOptions: dict];
@ -501,7 +501,7 @@ static NSMutableArray * cfarray_to_nsarray (CFArrayRef in) {
if (value != NULL if (value != NULL
&& CFGetTypeID (value) == CFNumberGetTypeID () && CFGetTypeID (value) == CFNumberGetTypeID ()
&& CFNumberIsFloatType (value)) && CFNumberIsFloatType (value))
CFNumberGetValue (value, kCFNumberFloatType, &ret); CFNumberGetValue (value, kCFNumberFloatType, &ret);
else if (value != NULL && CFGetTypeID (value) == CFStringGetTypeID ()) else if (value != NULL && CFGetTypeID (value) == CFStringGetTypeID ())
ret = CFStringGetDoubleValue (value); ret = CFStringGetDoubleValue (value);
@ -862,7 +862,9 @@ static void send_nsevent (NSEventType type, NSEvent *e) {
NSRect screen; NSRect screen;
NSPoint location; NSPoint location;
NSWindow *window; NSWindow *window;
int pointer_x, pointer_y, ev_button, ev_type; int pointer_x, pointer_y, ev_button, ev_type;
float pressure, tilt_x, tilt_y;
// int num_events=0, i=0, state; // int num_events=0, i=0, state;
// xEvent xe; // xEvent xe;
@ -884,6 +886,10 @@ static void send_nsevent (NSEventType type, NSEvent *e) {
pointer_y -= aquaMenuBarHeight; pointer_y -= aquaMenuBarHeight;
// state = convert_flags ([e modifierFlags]); // state = convert_flags ([e modifierFlags]);
pressure = 0; // for tablets
tilt_x = 0;
tilt_y = 0;
switch (type) { switch (type) {
case NSLeftMouseDown: ev_button=1; ev_type=ButtonPress; goto handle_mouse; case NSLeftMouseDown: ev_button=1; ev_type=ButtonPress; goto handle_mouse;
case NSOtherMouseDown: ev_button=2; ev_type=ButtonPress; goto handle_mouse; case NSOtherMouseDown: ev_button=2; ev_type=ButtonPress; goto handle_mouse;
@ -894,6 +900,10 @@ static void send_nsevent (NSEventType type, NSEvent *e) {
case NSLeftMouseDragged: ev_button=1; ev_type=MotionNotify; goto handle_mouse; case NSLeftMouseDragged: ev_button=1; ev_type=MotionNotify; goto handle_mouse;
case NSOtherMouseDragged: ev_button=2; ev_type=MotionNotify; goto handle_mouse; case NSOtherMouseDragged: ev_button=2; ev_type=MotionNotify; goto handle_mouse;
case NSRightMouseDragged: ev_button=3; ev_type=MotionNotify; goto handle_mouse; case NSRightMouseDragged: ev_button=3; ev_type=MotionNotify; goto handle_mouse;
case NSTabletPoint:
pressure = [e pressure];
tilt_x = [e tilt].x;
tilt_y = [e tilt].y; // fall through
case NSMouseMoved: ev_button=0; ev_type=MotionNotify; goto handle_mouse; case NSMouseMoved: ev_button=0; ev_type=MotionNotify; goto handle_mouse;
handle_mouse: handle_mouse:
@ -907,10 +917,14 @@ static void send_nsevent (NSEventType type, NSEvent *e) {
DarwinSendPointerEvents(ev_type, ev_button, pointer_x, pointer_y); DarwinSendPointerEvents(ev_type, ev_button, pointer_x, pointer_y);
} else if (ev_type==ButtonRelease && (button_state & (1 << ev_button)) == 0) break; } else if (ev_type==ButtonRelease && (button_state & (1 << ev_button)) == 0) break;
*/ */
DarwinSendPointerEvents(ev_type, ev_button, pointer_x, pointer_y);
// if ([e subtype] == NSTabletPointEventSubtype) pressure = [e pressure];
DarwinSendPointerEvents(ev_type, ev_button, pointer_x, pointer_y,
pressure, tilt_x, tilt_y);
break; break;
case NSScrollWheel: case NSScrollWheel:
DarwinSendScrollEvents([e deltaY], pointer_x, pointer_y); DarwinSendScrollEvents([e deltaY], pointer_x, pointer_y,
pressure, tilt_x, tilt_y);
break; break;
case NSKeyDown: // do we need to translate these keyCodes? case NSKeyDown: // do we need to translate these keyCodes?

View File

@ -173,6 +173,9 @@ static void DarwinReleaseModifiers(void) {
static void DarwinSimulateMouseClick( static void DarwinSimulateMouseClick(
int pointer_x, int pointer_x,
int pointer_y, int pointer_y,
float pressure,
float tilt_x,
float tilt_y,
int whichButton, // mouse button to be pressed int whichButton, // mouse button to be pressed
int modifierMask) // modifiers used for the fake click int modifierMask) // modifiers used for the fake click
{ {
@ -183,8 +186,10 @@ static void DarwinSimulateMouseClick(
DarwinUpdateModifiers(KeyRelease, modifierMask); DarwinUpdateModifiers(KeyRelease, modifierMask);
// push the mouse button // push the mouse button
DarwinSendPointerEvents(ButtonPress, whichButton, pointer_x, pointer_y); DarwinSendPointerEvents(ButtonPress, whichButton, pointer_x, pointer_y,
DarwinSendPointerEvents(ButtonRelease, whichButton, pointer_x, pointer_y); pressure, tilt_x, tilt_y);
DarwinSendPointerEvents(ButtonRelease, whichButton, pointer_x, pointer_y,
pressure, tilt_x, tilt_y);
// restore old modifiers // restore old modifiers
DarwinUpdateModifiers(KeyPress, modifierMask); DarwinUpdateModifiers(KeyPress, modifierMask);
@ -378,22 +383,39 @@ void DarwinPokeEQ(void) {
write(darwinEventWriteFD, &nullbyte, 1); write(darwinEventWriteFD, &nullbyte, 1);
} }
void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int pointer_y) { void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int pointer_y,
float pressure, float tilt_x, float tilt_y) {
static int darwinFakeMouseButtonDown = 0; static int darwinFakeMouseButtonDown = 0;
static int darwinFakeMouseButtonMask = 0; static int darwinFakeMouseButtonMask = 0;
int i, num_events; int i, num_events;
int valuators[2] = {pointer_x, pointer_y};
/* I can't find a spec for this, but at least GTK expects that tablets are
just like mice, except they have either one or three extra valuators, in this
order:
X coord, Y coord, pressure, X tilt, Y tilt
Pressure and tilt should be represented natively as floats; unfortunately,
we can't do that. Again, GTK seems to record the min/max of each valuator,
and then perform scaling back to float itself using that info. Soo.... */
int valuators[5] = {pointer_x, pointer_y,
pressure * INT32_MAX * 1.0f,
tilt_x * INT32_MAX * 1.0f,
tilt_y * INT32_MAX * 1.0f};
if (ev_type == ButtonPress && darwinFakeButtons && ev_button == 1) { if (ev_type == ButtonPress && darwinFakeButtons && ev_button == 1) {
// Mimic multi-button mouse with modifier-clicks // Mimic multi-button mouse with modifier-clicks
// If both sets of modifiers are pressed, // If both sets of modifiers are pressed,
// button 2 is clicked. // button 2 is clicked.
if ((old_flags & darwinFakeMouse2Mask) == darwinFakeMouse2Mask) { if ((old_flags & darwinFakeMouse2Mask) == darwinFakeMouse2Mask) {
DarwinSimulateMouseClick(pointer_x, pointer_y, 2, darwinFakeMouse2Mask); DarwinSimulateMouseClick(pointer_x, pointer_y, pressure,
tilt_x, tilt_y, 2, darwinFakeMouse2Mask);
darwinFakeMouseButtonDown = 2; darwinFakeMouseButtonDown = 2;
darwinFakeMouseButtonMask = darwinFakeMouse2Mask; darwinFakeMouseButtonMask = darwinFakeMouse2Mask;
return; return;
} else if ((old_flags & darwinFakeMouse3Mask) == darwinFakeMouse3Mask) { } else if ((old_flags & darwinFakeMouse3Mask) == darwinFakeMouse3Mask) {
DarwinSimulateMouseClick(pointer_x, pointer_y, 3, darwinFakeMouse3Mask); DarwinSimulateMouseClick(pointer_x, pointer_y, pressure,
tilt_x, tilt_y, 3, darwinFakeMouse3Mask);
darwinFakeMouseButtonDown = 3; darwinFakeMouseButtonDown = 3;
darwinFakeMouseButtonMask = darwinFakeMouse3Mask; darwinFakeMouseButtonMask = darwinFakeMouse3Mask;
return; return;
@ -412,7 +434,7 @@ void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int poin
} }
num_events = GetPointerEvents(darwinEvents, darwinPointer, ev_type, ev_button, num_events = GetPointerEvents(darwinEvents, darwinPointer, ev_type, ev_button,
POINTER_ABSOLUTE, 0, 2, valuators); POINTER_ABSOLUTE, 0, 5, valuators);
for(i=0; i<num_events; i++) mieqEnqueue (darwinPointer,&darwinEvents[i]); for(i=0; i<num_events; i++) mieqEnqueue (darwinPointer,&darwinEvents[i]);
DarwinPokeEQ(); DarwinPokeEQ();
@ -438,18 +460,38 @@ void DarwinSendKeyboardEvents(int ev_type, int keycode) {
DarwinPokeEQ(); DarwinPokeEQ();
} }
void DarwinSendProximityEvents(int ev_type, int pointer_x, int pointer_y,
float pressure, float tilt_x, float tilt_y) {
int i, num_events;
int valuators[5] = {pointer_x, pointer_y,
pressure * INT32_MAX * 1.0f,
tilt_x * INT32_MAX * 1.0f,
tilt_y * INT32_MAX * 1.0f};
num_events = GetProximityEvents(darwinEvents, darwinPointer, ev_type,
0, 5, valuators);
for(i=0; i<num_events; i++) mieqEnqueue (darwinPointer,&darwinEvents[i]);
DarwinPokeEQ();
}
/* Send the appropriate number of button 4 / 5 clicks to emulate scroll wheel */ /* Send the appropriate number of button 4 / 5 clicks to emulate scroll wheel */
void DarwinSendScrollEvents(float count, int pointer_x, int pointer_y) { void DarwinSendScrollEvents(float count, int pointer_x, int pointer_y,
float pressure, float tilt_x, float tilt_y) {
int i; int i;
int ev_button = count > 0.0f ? 4 : 5; int ev_button = count > 0.0f ? 4 : 5;
int valuators[2] = {pointer_x, pointer_y}; int valuators[5] = {pointer_x, pointer_y,
pressure * INT32_MAX * 1.0f,
tilt_x * INT32_MAX * 1.0f,
tilt_y * INT32_MAX * 1.0f};
for (count = fabs(count); count > 0.0; count = count - 1.0f) { for (count = fabs(count); count > 0.0; count = count - 1.0f) {
int num_events = GetPointerEvents(darwinEvents, darwinPointer, ButtonPress, ev_button, int num_events = GetPointerEvents(darwinEvents, darwinPointer, ButtonPress, ev_button,
POINTER_ABSOLUTE, 0, 2, valuators); POINTER_ABSOLUTE, 0, 5, valuators);
for(i=0; i<num_events; i++) mieqEnqueue(darwinPointer,&darwinEvents[i]); for(i=0; i<num_events; i++) mieqEnqueue(darwinPointer,&darwinEvents[i]);
num_events = GetPointerEvents(darwinEvents, darwinPointer, ButtonRelease, ev_button, num_events = GetPointerEvents(darwinEvents, darwinPointer, ButtonRelease, ev_button,
POINTER_ABSOLUTE, 0, 2, valuators); POINTER_ABSOLUTE, 0, 5, valuators);
for(i=0; i<num_events; i++) mieqEnqueue(darwinPointer,&darwinEvents[i]); for(i=0; i<num_events; i++) mieqEnqueue(darwinPointer,&darwinEvents[i]);
} }
DarwinPokeEQ(); DarwinPokeEQ();

View File

@ -32,9 +32,13 @@ void DarwinEQEnqueue(const xEventPtr e);
void DarwinEQPointerPost(DeviceIntPtr pDev, xEventPtr e); void DarwinEQPointerPost(DeviceIntPtr pDev, xEventPtr e);
void DarwinEQSwitchScreen(ScreenPtr pScreen, Bool fromDIX); void DarwinEQSwitchScreen(ScreenPtr pScreen, Bool fromDIX);
void DarwinPokeEQ(void); void DarwinPokeEQ(void);
void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int pointer_y); void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int pointer_y,
float pressure, float tilt_x, float tilt_y);
void DarwinSendProximityEvents(int ev_type, int pointer_x, int pointer_y,
float pressure, float tilt_x, float tilt_y);
void DarwinSendKeyboardEvents(int ev_type, int keycode); void DarwinSendKeyboardEvents(int ev_type, int keycode);
void DarwinSendScrollEvents(float count, int pointer_x, int pointer_y); void DarwinSendScrollEvents(float count, int pointer_x, int pointer_y,
float pressure, float tilt_x, float tilt_y);
void DarwinUpdateModKeys(int flags); void DarwinUpdateModKeys(int flags);
#endif /* _DARWIN_EVENTS_H */ #endif /* _DARWIN_EVENTS_H */