/** NSEvent The event class Copyright (C) 1996 Free Software Foundation, Inc. Author: Scott Christley Author: Ovidiu Predescu Date: 1996 Author: Felipe A. Rodriguez Date: Sept 1998 Updated: Richard Frith-Macdonald Date: June 1999 This file is part of the GNUstep GUI Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #include #include #include #include #include #include #include #include #include "AppKit/NSEvent.h" #include "AppKit/NSApplication.h" #include "AppKit/NSWindow.h" #include "AppKit/NSGraphicsContext.h" #include "AppKit/NSGraphics.h" #include "AppKit/PSOperators.h" #include "GNUstepGUI/GSDisplayServer.h" /* * gstep-base has a faster mechanism to get the current thread. */ #ifndef GNUSTEP_BASE_LIBRARY #define GSCurrentThread() [NSThread currentThread] #define GSCurrentThreadDictionary() [[NSThread currentThread] threadDictionary] #endif @implementation NSEvent /* * Class variables */ static NSString *timerKey = @"NSEventTimersKey"; static Class eventClass; /* * Class methods */ + (void) initialize { if (self == [NSEvent class]) { [self setVersion: 1]; eventClass = [NSEvent class]; } } /* * Creating NSEvent objects */ + (NSEvent*) enterExitEventWithType: (NSEventType)type location: (NSPoint)location modifierFlags: (unsigned int)flags timestamp: (NSTimeInterval)time windowNumber: (int)windowNum context: (NSGraphicsContext*)context eventNumber: (int)eventNum trackingNumber: (int)trackingNum userData: (void *)userData { NSEvent *e; if (type == NSCursorUpdate) RETAIN((id)userData); else if ((type != NSMouseEntered) && (type != NSMouseExited)) [NSException raise: NSInvalidArgumentException format: @"enterExitEvent with wrong type"]; e = (NSEvent*)NSAllocateObject(self, 0, NSDefaultMallocZone()); if (self != eventClass) e = [e init]; AUTORELEASE(e); e->event_type = type; e->location_point = location; e->modifier_flags = flags; e->event_time = time; e->window_num = windowNum; e->event_context = context; e->event_data.tracking.event_num = eventNum; e->event_data.tracking.tracking_num = trackingNum; e->event_data.tracking.user_data = userData; return e; } + (NSEvent*) keyEventWithType: (NSEventType)type location: (NSPoint)location modifierFlags: (unsigned int)flags timestamp: (NSTimeInterval)time windowNumber: (int)windowNum context: (NSGraphicsContext *)context characters: (NSString *)keys charactersIgnoringModifiers: (NSString *)ukeys isARepeat: (BOOL)repeatKey keyCode: (unsigned short)code { NSEvent *e; if (type < NSKeyDown || type > NSFlagsChanged) [NSException raise: NSInvalidArgumentException format: @"keyEvent with wrong type"]; e = (NSEvent*)NSAllocateObject(self, 0, NSDefaultMallocZone()); if (self != eventClass) e = [e init]; AUTORELEASE(e); e->event_type = type; e->location_point = location; e->modifier_flags = flags; e->event_time = time; e->window_num = windowNum; e->event_context = context; RETAIN(keys); e->event_data.key.char_keys = keys; RETAIN(ukeys); e->event_data.key.unmodified_keys = ukeys; e->event_data.key.repeat = repeatKey; e->event_data.key.key_code = code; return e; } + (NSEvent*) mouseEventWithType: (NSEventType)type location: (NSPoint)location modifierFlags: (unsigned int)flags timestamp: (NSTimeInterval)time windowNumber: (int)windowNum context: (NSGraphicsContext*)context eventNumber: (int)eventNum clickCount: (int)clickNum pressure: (float)pressureValue { NSEvent *e; if (type < NSLeftMouseDown || type > NSRightMouseDragged) [NSException raise: NSInvalidArgumentException format: @"mouseEvent with wrong type"]; e = (NSEvent*)NSAllocateObject(self, 0, NSDefaultMallocZone()); if (self != eventClass) e = [e init]; AUTORELEASE(e); e->event_type = type; e->location_point = location; e->modifier_flags = flags; e->event_time = time; e->window_num = windowNum; e->event_context = context; e->event_data.mouse.event_num = eventNum; e->event_data.mouse.click = clickNum; e->event_data.mouse.pressure = pressureValue; return e; } + (NSEvent*) mouseEventWithType: (NSEventType)type location: (NSPoint)location modifierFlags: (unsigned int)flags timestamp: (NSTimeInterval)time windowNumber: (int)windowNum context: (NSGraphicsContext*)context eventNumber: (int)eventNum clickCount: (int)clickNum pressure: (float)pressureValue buttonNumber: (int)buttonNum deltaX: (float)deltaX deltaY: (float)deltaY deltaZ: (float)deltaZ { NSEvent *e; if ((type < NSLeftMouseDown || type > NSRightMouseDragged) && (type != NSScrollWheel)) [NSException raise: NSInvalidArgumentException format: @"mouseEvent with wrong type"]; e = (NSEvent*)NSAllocateObject(self, 0, NSDefaultMallocZone()); if (self != eventClass) e = [e init]; AUTORELEASE(e); e->event_type = type; e->location_point = location; e->modifier_flags = flags; e->event_time = time; e->window_num = windowNum; e->event_context = context; e->event_data.mouse.event_num = eventNum; e->event_data.mouse.click = clickNum; e->event_data.mouse.button = buttonNum; e->event_data.mouse.pressure = pressureValue; e->event_data.mouse.deltaX = deltaX; e->event_data.mouse.deltaY = deltaY; e->event_data.mouse.deltaZ = deltaZ; return e; } /** * Returns the current mouse location. */ + (NSPoint) mouseLocation { return [GSCurrentServer() mouselocation]; } + (NSEvent*) otherEventWithType: (NSEventType)type location: (NSPoint)location modifierFlags: (unsigned int)flags timestamp: (NSTimeInterval)time windowNumber: (int)windowNum context: (NSGraphicsContext*)context subtype: (short)subType data1: (int)data1 data2: (int)data2 { NSEvent *e; if (type < NSAppKitDefined || type > NSPeriodic) [NSException raise: NSInvalidArgumentException format: @"otherEvent with wrong type"]; e = (NSEvent*)NSAllocateObject(self, 0, NSDefaultMallocZone()); if (self != eventClass) e = [e init]; AUTORELEASE(e); e->event_type = type; e->location_point = location; e->modifier_flags = flags; e->event_time = time; e->window_num = windowNum; e->event_context = context; e->event_data.misc.sub_type = subType; e->event_data.misc.data1 = data1; e->event_data.misc.data2 = data2; return e; } /* * Requesting Periodic Events */ + (void) startPeriodicEventsAfterDelay: (NSTimeInterval)delaySeconds withPeriod: (NSTimeInterval)periodSeconds { NSTimer *timer; NSMutableDictionary *dict = GSCurrentThreadDictionary(); NSDebugLLog (@"NSEvent", @"startPeriodicEventsAfterDelay: withPeriod: "); if ([dict objectForKey: timerKey]) [NSException raise: NSInternalInconsistencyException format: @"Periodic events are already being generated for " @"this thread %x", GSCurrentThread()]; /* * Register a timer that will fire in delaySeconds. * This timer will fire the first event and register * a repeat timer that will send the following events */ timer = [NSTimer timerWithTimeInterval: delaySeconds target: self selector: @selector(_registerRealTimer:) userInfo: [NSNumber numberWithDouble: periodSeconds] repeats: NO]; [[NSRunLoop currentRunLoop] addTimer: timer forMode: NSEventTrackingRunLoopMode]; [dict setObject: timer forKey: timerKey]; } + (void) _timerFired: (NSTimer*)timer { NSTimeInterval timeInterval; NSEvent *periodicEvent; timeInterval = [[NSDate date] timeIntervalSinceReferenceDate]; periodicEvent = [self otherEventWithType: NSPeriodic location: NSZeroPoint modifierFlags: 0 timestamp: timeInterval windowNumber: 0 context: [NSApp context] subtype: 0 data1: 0 data2: 0]; NSDebugLLog (@"NSEvent", @"_timerFired: "); [NSApp postEvent: periodicEvent atStart: NO]; } /* * This method provides a means of delaying the start of periodic events */ + (void) _registerRealTimer: (NSTimer*)timer { NSTimer *realTimer; NSMutableDictionary *dict = GSCurrentThreadDictionary(); NSDebugLLog (@"NSEvent", @"_registerRealTimer: "); { NSTimeInterval timeInterval; NSEvent *periodicEvent; timeInterval = [[NSDate date] timeIntervalSinceReferenceDate]; periodicEvent = [self otherEventWithType: NSPeriodic location: NSZeroPoint modifierFlags: 0 timestamp: timeInterval windowNumber: 0 context: [NSApp context] subtype: 0 data1: 0 data2: 0]; [NSApp postEvent: periodicEvent atStart: NO]; } realTimer = [NSTimer timerWithTimeInterval: [[timer userInfo] doubleValue] target: self selector: @selector(_timerFired:) userInfo: nil repeats: YES]; [dict setObject: realTimer forKey: timerKey]; [[NSRunLoop currentRunLoop] addTimer: realTimer forMode: NSEventTrackingRunLoopMode]; } + (void) stopPeriodicEvents { NSTimer *timer; NSMutableDictionary *dict = GSCurrentThreadDictionary(); NSDebugLLog (@"NSEvent", @"stopPeriodicEvents"); timer = [dict objectForKey: timerKey]; [timer invalidate]; [dict removeObjectForKey: timerKey]; } /** * Returns the button number for the mouse button pressed in a mouse * event. Intended primarily for the case where a mouse has three or * more buttons, and you want to know which button an 'other' mouse * event refers to. */ - (int) buttonNumber { if (event_type < NSLeftMouseDown || event_type > NSMouseExited) { [NSException raise: NSInternalInconsistencyException format: @"buttonNumber requested for non-mouse event"]; } return event_data.mouse.button; } /** * Returns the string of characters for a keyboard event. *
Raises an NSInternalInconsistencyException if applied to any * other type of event. */ - (NSString *) characters { if ((event_type != NSKeyUp) && (event_type != NSKeyDown)) { [NSException raise: NSInternalInconsistencyException format: @"characters requested for non-keyboard event"]; } return event_data.key.char_keys; } /** * Returns the string of characters for a keyboard event, as if no modifier * keys had been pressed when the keyboard event occirred. *
Raises an NSInternalInconsistencyException if applied to any * other type of event. */ - (NSString *) charactersIgnoringModifiers { if ((event_type != NSKeyUp) && (event_type != NSKeyDown)) { [NSException raise: NSInternalInconsistencyException format: @"charactersIgnoringModifiers requested for " @"non-keyboard event"]; } return event_data.key.unmodified_keys; } /** * Return the number of clicks associated with the mouse down or up * event. This method is not applicable for any event type other * than a mouse down or mouse up. *
Raises an NSInternalInconsistencyException if applied to any * other type of event. */ - (int) clickCount { /* Make sure it is one of the right event types */ if (event_type < NSLeftMouseDown || event_type > NSRightMouseUp) { [NSException raise: NSInternalInconsistencyException format: @"clickCount requested for non-mouse event"]; } return event_data.mouse.click; } /** * Returns the graphics context for which this event was generated. */ - (NSGraphicsContext*) context { return event_context; } - (id) copyWithZone: (NSZone*)zone { NSEvent *e = (NSEvent*)NSCopyObject (self, 0, zone); if ((event_type == NSKeyUp) || (event_type == NSKeyDown)) { event_data.key.char_keys = [event_data.key.char_keys copyWithZone: zone]; event_data.key.unmodified_keys = [event_data.key.unmodified_keys copyWithZone: zone]; } else if (event_type == NSCursorUpdate) { event_data.tracking.user_data = (void *)[(id)event_data.tracking.user_data copyWithZone: zone]; } return e; } /** * Returns the 'data1' item associated with the event. *
Raises NSInternalInconsistencyException if the event is not * of type NSAppKitDefined, NSSystemDefined, NSApplicationDefined, * or NSPeriodic */ - (int) data1 { if (event_type < NSAppKitDefined || event_type > NSPeriodic) { [NSException raise: NSInternalInconsistencyException format: @"data1 requested for invalid event type"]; } return event_data.misc.data1; } /** * Returns the 'data2' item associated with the event. *
Raises NSInternalInconsistencyException if the event is not * of type NSAppKitDefined, NSSystemDefined, NSApplicationDefined, * or NSPeriodic */ - (int) data2 { if (event_type < NSAppKitDefined || event_type > NSPeriodic) { [NSException raise: NSInternalInconsistencyException format: @"data2 requested for invalid event type"]; } return event_data.misc.data2; } - (void) dealloc { if ((event_type == NSKeyUp) || (event_type == NSKeyDown)) { RELEASE(event_data.key.char_keys); RELEASE(event_data.key.unmodified_keys); } else if (event_type == NSCursorUpdate) { RELEASE((id)event_data.tracking.user_data); } NSDeallocateObject(self); GSNOSUPERDEALLOC; } /**

Returns the movement of the mouse on the X axis.

This method is only valid for NSMouseMoved, NS*MouseDragged and NSScrollWheel events, otherwise it will raise an NSInternalInconsistencyException.

*/ - (float)deltaX { if (event_type != NSScrollWheel && (event_type < NSMouseMoved || event_type > NSRightMouseDragged)) { [NSException raise: NSInternalInconsistencyException format: @"deltaX requested for invalid event type"]; } return event_data.mouse.deltaX; } /**

Returns the movement of the mouse on the Y axis.

This method is only valid for NSMouseMoved, NS*MouseDragged and NSScrollWheel events, otherwise it will raise an NSInternalInconsistencyException.

*/ - (float)deltaY { if (event_type != NSScrollWheel && (event_type < NSMouseMoved || event_type > NSRightMouseDragged)) { [NSException raise: NSInternalInconsistencyException format: @"deltaY requested for invalid event type"]; } return event_data.mouse.deltaY; } /**

Returns the movement of the mouse on the Z axis.

This method is only valid for NSMouseMoved, NS*MouseDragged and NSScrollWheel events, otherwise it will raise an NSInternalInconsistencyException.

The value returned is 0.0 in most cases.

*/ - (float)deltaZ { if (event_type != NSScrollWheel && (event_type < NSMouseMoved || event_type > NSRightMouseDragged)) { [NSException raise: NSInternalInconsistencyException format: @"deltaZ requested for invalid event type"]; } return event_data.mouse.deltaZ; } - (NSString*) description { static const char *eventTypes[] = { "leftMouseDown", "leftMouseUp", "otherMouseDown", "otherMouseUp", "rightMouseDown", "rightMouseUp", "mouseMoved", "leftMouseDragged", "otherMouseDragged", "rightMouseDragged", "mouseEntered", "mouseExited", "keyDown", "keyUp", "flagsChanged", "appKitDefined", "systemDefined", "applicationDefined", "periodic", "cursorUpdate", "scrollWheel" }; switch (event_type) { case NSLeftMouseDown: case NSLeftMouseUp: case NSOtherMouseDown: case NSOtherMouseUp: case NSRightMouseDown: case NSRightMouseUp: return [NSString stringWithFormat: @"NSEvent: eventType = %s, point = { %f, %f }, modifiers = %u," @" time = %f, window = %d, dpsContext = %p," @" event number = %d, click = %d, pressure = %f", eventTypes[event_type], location_point.x, location_point.y, modifier_flags, event_time, window_num, event_context, event_data.mouse.event_num, event_data.mouse.click, event_data.mouse.pressure]; break; case NSMouseEntered: case NSMouseExited: return [NSString stringWithFormat: @"NSEvent: eventType = %s, point = { %f, %f }, modifiers = %u," @" time = %f, window = %d, dpsContext = %p, " @" event number = %d, tracking number = %d, user data = %p", eventTypes[event_type], location_point.x, location_point.y, modifier_flags, event_time, window_num, event_context, event_data.tracking.event_num, event_data.tracking.tracking_num, event_data.tracking.user_data]; break; case NSKeyDown: case NSKeyUp: return [NSString stringWithFormat: @"NSEvent: eventType = %s, point = { %f, %f }, modifiers = %u," @" time = %f, window = %d, dpsContext = %p, " @" repeat = %s, keys = %@, ukeys = %@, keyCode = 0x%x", eventTypes[event_type], location_point.x, location_point.y, modifier_flags, event_time, window_num, event_context, (event_data.key.repeat ? "YES" : "NO"), event_data.key.char_keys, event_data.key.unmodified_keys, event_data.key.key_code]; break; case NSFlagsChanged: case NSPeriodic: case NSCursorUpdate: case NSAppKitDefined: case NSSystemDefined: case NSApplicationDefined: return [NSString stringWithFormat: @"NSEvent: eventType = %s, point = { %f, %f }, modifiers = %u," @" time = %f, window = %d, dpsContext = %p, " @" subtype = %d, data1 = %p, data2 = %p", eventTypes[event_type], location_point.x, location_point.y, modifier_flags, event_time, window_num, event_context, event_data.misc.sub_type, event_data.misc.data1, event_data.misc.data2]; break; case NSScrollWheel: case NSMouseMoved: case NSLeftMouseDragged: case NSOtherMouseDragged: case NSRightMouseDragged: return [NSString stringWithFormat: @"NSEvent: eventType = %s, point = { %f, %f }, modifiers = %u," @" time = %f, window = %d, dpsContext = %p," @" event number = %d, click = %d, pressure = %f" @" button = %d, deltaX = %f, deltaY = %f, deltaZ = %f", eventTypes[event_type], location_point.x, location_point.y, modifier_flags, event_time, window_num, event_context, event_data.mouse.event_num, event_data.mouse.click, event_data.mouse.pressure, event_data.mouse.button, event_data.mouse.deltaX, event_data.mouse.deltaY, event_data.mouse.deltaZ]; break; } return [super description]; } - (void) encodeWithCoder: (NSCoder*)aCoder { [aCoder encodeValueOfObjCType: @encode(NSEventType) at: &event_type]; [aCoder encodePoint: location_point]; [aCoder encodeValueOfObjCType: @encode(unsigned) at: &modifier_flags]; [aCoder encodeValueOfObjCType: @encode(NSTimeInterval) at: &event_time]; [aCoder encodeValueOfObjCType: @encode(unsigned) at: &window_num]; switch (event_type) { case NSLeftMouseDown: case NSLeftMouseUp: case NSOtherMouseDown: case NSOtherMouseUp: case NSRightMouseDown: case NSRightMouseUp: case NSScrollWheel: case NSMouseMoved: case NSLeftMouseDragged: case NSOtherMouseDragged: case NSRightMouseDragged: [aCoder encodeValuesOfObjCTypes: "iififff", &event_data.mouse.event_num, &event_data.mouse.click, &event_data.mouse.pressure, &event_data.mouse.button, &event_data.mouse.deltaX, &event_data.mouse.deltaY, &event_data.mouse.deltaZ]; break; case NSMouseEntered: case NSMouseExited: case NSCursorUpdate: // Can't do anything with the user_data!? [aCoder encodeValuesOfObjCTypes: "ii", &event_data.tracking.event_num, &event_data.tracking.tracking_num]; break; case NSKeyDown: case NSKeyUp: [aCoder encodeValueOfObjCType: @encode(BOOL) at: &event_data.key.repeat]; [aCoder encodeObject: event_data.key.char_keys]; [aCoder encodeObject: event_data.key.unmodified_keys]; [aCoder encodeValueOfObjCType: "S" at: &event_data.key.key_code]; break; case NSFlagsChanged: case NSPeriodic: case NSAppKitDefined: case NSSystemDefined: case NSApplicationDefined: [aCoder encodeValuesOfObjCTypes: "sii", &event_data.misc.sub_type, &event_data.misc.data1, &event_data.misc.data2]; break; } } /** * Returns the event number associated with any mouse event or tracking * event. Event numbers are allocated sequentially when the system * creates these events. *
Raises an NSInternalInconsistencyException if applied to any * other type of event. */ - (int) eventNumber { /* Make sure it is one of the right event types */ if (event_type < NSLeftMouseDown || event_type > NSMouseExited) [NSException raise: NSInternalInconsistencyException format: @"eventNumber requested for non-mouse event"]; if ((event_type == NSMouseEntered) || (event_type == NSMouseExited)) return event_data.tracking.event_num; else return event_data.mouse.event_num; } - (id) initWithCoder: (NSCoder*)aDecoder { [aDecoder decodeValueOfObjCType: @encode(NSEventType) at: &event_type]; location_point = [aDecoder decodePoint]; [aDecoder decodeValueOfObjCType: @encode(unsigned) at: &modifier_flags]; [aDecoder decodeValueOfObjCType: @encode(NSTimeInterval) at: &event_time]; [aDecoder decodeValueOfObjCType: @encode(unsigned) at: &window_num]; // Decode the event date based upon the event type switch (event_type) { case NSLeftMouseDown: case NSLeftMouseUp: case NSOtherMouseDown: case NSOtherMouseUp: case NSRightMouseDown: case NSRightMouseUp: case NSScrollWheel: case NSMouseMoved: case NSLeftMouseDragged: case NSOtherMouseDragged: case NSRightMouseDragged: [aDecoder decodeValuesOfObjCTypes: "iififff", &event_data.mouse.event_num, &event_data.mouse.click, &event_data.mouse.pressure, &event_data.mouse.button, &event_data.mouse.deltaX, &event_data.mouse.deltaY, &event_data.mouse.deltaZ]; break; case NSMouseEntered: case NSMouseExited: case NSCursorUpdate: // Can't do anything with the user_data!? [aDecoder decodeValuesOfObjCTypes: "ii", &event_data.tracking.event_num, &event_data.tracking.tracking_num]; break; case NSKeyDown: case NSKeyUp: [aDecoder decodeValueOfObjCType: @encode(BOOL) at: &event_data.key.repeat]; event_data.key.char_keys = [aDecoder decodeObject]; event_data.key.unmodified_keys = [aDecoder decodeObject]; [aDecoder decodeValueOfObjCType: "S" at: &event_data.key.key_code]; break; case NSFlagsChanged: case NSPeriodic: case NSAppKitDefined: case NSSystemDefined: case NSApplicationDefined: [aDecoder decodeValuesOfObjCTypes: "sii", &event_data.misc.sub_type, &event_data.misc.data1, &event_data.misc.data2]; break; } return self; } /** * Returns a flag to say if this is a keyboard repeat event. *
Raises an NSInternalInconsistencyException if applied to any * other type of event than an NSKeyUp or NSKeyDown. */ - (BOOL) isARepeat { if ((event_type != NSKeyUp) && (event_type != NSKeyDown)) [NSException raise: NSInternalInconsistencyException format: @"isARepeat requested for non-keyboard event"]; return event_data.key.repeat; } /** * Returns the numeric key code of a keyboard event. *
Raises an NSInternalInconsistencyException if applied to any * other type of event than an NSKeyUp or NSKeyDown. */ - (unsigned short) keyCode { if ((event_type != NSKeyUp) && (event_type != NSKeyDown) && (event_type != NSFlagsChanged)) { [NSException raise: NSInternalInconsistencyException format: @"keyCode requested for non-keyboard event"]; } return event_data.key.key_code; } /** * Returns the window location for which this event was generated (in the * base coordinate system of the window). */ - (NSPoint) locationInWindow { return location_point; } /** * Returns the modifier flag bits associated with the event. */ - (unsigned int) modifierFlags { return modifier_flags; } /** * Returns the pressure associated with a mouse event. This is a value * in the range 0.0 to 1.0 and for mormal mouse events should be set to * one of those extremes. This is used by pressure sensitive input devices. *
Raises an NSInternalInconsistencyException if applied to any * other type of event than a mouse event. */ - (float) pressure { /* Make sure it is one of the right event types */ if (event_type < NSLeftMouseDown || event_type > NSRightMouseDragged) { [NSException raise: NSInternalInconsistencyException format: @"pressure requested for non-mouse event"]; } return event_data.mouse.pressure; } /** * Returns the 'subtype' item associated with the event. *
Raises NSInternalInconsistencyException if the event is not * of type NSAppKitDefined, NSSystemDefined, NSApplicationDefined, * or NSPeriodic */ - (short) subtype { if (event_type < NSAppKitDefined || event_type > NSPeriodic) { [NSException raise: NSInternalInconsistencyException format: @"subtype requested for invalid event type"]; } return event_data.misc.sub_type;; } /** * Returns the time interval since system startup at which this * event was generated. */ - (NSTimeInterval) timestamp { return event_time; } /** * Returns a number identifying the tracking rectangle entered or exited. *
Raises an NSInternalInconsistencyException if applied to any * other type of event than a mouse entered or exited event. */ - (int) trackingNumber { if (event_type != NSMouseEntered && event_type != NSMouseExited && event_type != NSCursorUpdate) { [NSException raise: NSInternalInconsistencyException format: @"trackingNumber requested for non-tracking event"]; } return event_data.tracking.tracking_num; } /** * returns the type of this event. */ - (NSEventType) type { return event_type; } /** * Returns usder data associated with a tracking event... the data assigned to * the tracking rectangle concerned when it was created.. *
Raises an NSInternalInconsistencyException if applied to any * other type of event than a mouse entered or exited event. */ - (void *) userData { if (event_type != NSMouseEntered && event_type != NSMouseExited && event_type != NSCursorUpdate) { [NSException raise: NSInternalInconsistencyException format: @"userData requested for non-tracking event"]; } return event_data.tracking.user_data; } /** * Returns the window for which this event was generated.
* Periodic events have no associated window, and you should not call * this method for those events. */ - (NSWindow *) window { return GSWindowWithNumber(window_num); } /** * Returns the window number of the window for which this event was generated. *
Periodic events have no associated window, and you should not call * this method for those events. */ - (int) windowNumber { return window_num; } @end