+++ /dev/null
-/* X11Application.m -- subclass of NSApplication to multiplex events
- $Id: X11Application.m,v 1.53 2003/09/13 02:00:46 jharper Exp $
-
- Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
-
- Permission is hereby granted, free of charge, to any person
- obtaining a copy of this software and associated documentation files
- (the "Software"), to deal in the Software without restriction,
- including without limitation the rights to use, copy, modify, merge,
- publish, distribute, sublicense, and/or sell copies of the Software,
- and to permit persons to whom the Software is furnished to do so,
- subject to the following conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
- HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
-
- Except as contained in this notice, the name(s) of the above
- copyright holders shall not be used in advertising or otherwise to
- promote the sale, use or other dealings in this Software without
- prior written authorization. */
-
-#import "X11Application.h"
-#include <Carbon/Carbon.h>
-
-/* ouch! */
-#define BOOL X_BOOL
-# include "Xproto.h"
-#define WindowPtr X_WindowPtr
-#define Cursor X_Cursor
-# include "quartz.h"
-# define _APPLEWM_SERVER_
-# include "applewm.h"
-# include "X.h"
-#undef Cursor
-#undef WindowPtr
-#undef BOOL
-
-#include "xf86Version.h"
-
-#include <mach/mach.h>
-#include <unistd.h>
-#include <pthread.h>
-
-#define DEFAULTS_FILE "/etc/X11/xserver/Xquartz.plist"
-
-int X11EnableKeyEquivalents = TRUE;
-
-X11Application *X11App;
-
-#define ALL_KEY_MASKS (NSShiftKeyMask | NSControlKeyMask \
- | NSAlternateKeyMask | NSCommandKeyMask)
-
-@implementation X11Application
-
-typedef struct message_struct message;
-struct message_struct {
- mach_msg_header_t hdr;
- SEL selector;
- NSObject *arg;
-};
-
-static mach_port_t _port;
-
-static void send_nsevent (NSEventType type, NSEvent *e);
-
-/* avoid header conflict hell */
-extern int RootlessKnowsWindowNumber (int number);
-extern void DarwinEnqueueEvent (const xEvent *e);
-
-static void
-init_ports (void)
-{
- kern_return_t r;
- NSPort *p;
-
- if (_port != MACH_PORT_NULL)
- return;
-
- r = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &_port);
- if (r != KERN_SUCCESS)
- return;
-
- p = [NSMachPort portWithMachPort:_port];
- [p setDelegate:NSApp];
- [p scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
-}
-
-static void
-message_kit_thread (SEL selector, NSObject *arg)
-{
- message msg;
- kern_return_t r;
-
- msg.hdr.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_MAKE_SEND, 0);
- msg.hdr.msgh_size = sizeof (msg);
- msg.hdr.msgh_remote_port = _port;
- msg.hdr.msgh_local_port = MACH_PORT_NULL;
- msg.hdr.msgh_reserved = 0;
- msg.hdr.msgh_id = 0;
-
- msg.selector = selector;
- msg.arg = [arg retain];
-
- r = mach_msg (&msg.hdr, MACH_SEND_MSG, msg.hdr.msgh_size,
- 0, MACH_PORT_NULL, 0, MACH_PORT_NULL);
- if (r != KERN_SUCCESS)
- fprintf (stderr, "%s: mach_msg failed: %x\n", __FUNCTION__, r);
-}
-
-- (void) handleMachMessage:(void *)_msg
-{
- message *msg = _msg;
-
- [self performSelector:msg->selector withObject:msg->arg];
- [msg->arg release];
-}
-
-- (void) set_controller:obj
-{
- if (_controller == nil)
- _controller = [obj retain];
-}
-
-- (void) dealloc
-{
- if (_controller != nil)
- [_controller release];
-
- if (_port != MACH_PORT_NULL)
- mach_port_deallocate (mach_task_self (), _port);
-
- [super dealloc];
-}
-
-- (void) orderFrontStandardAboutPanel: (id) sender
-{
- NSMutableDictionary *dict;
- NSDictionary *infoDict;
- NSString *tem;
-
- dict = [NSMutableDictionary dictionaryWithCapacity:2];
- infoDict = [[NSBundle mainBundle] infoDictionary];
-
- [dict setObject: NSLocalizedString (@"The X Window System", @"About panel")
- forKey:@"ApplicationName"];
-
- tem = [infoDict objectForKey:@"CFBundleShortVersionString"];
-
- [dict setObject:[NSString stringWithFormat:@"X11 %@ - XFree86 %d.%d.%d",
- tem, XF86_VERSION_MAJOR, XF86_VERSION_MINOR,
- XF86_VERSION_PATCH] forKey:@"ApplicationVersion"];
-
- [self orderFrontStandardAboutPanelWithOptions: dict];
-}
-
-- (void) activateX:(BOOL)state
-{
- /* Create a TSM document that supports full Unicode input, and
- have it activated while X is active (unless using the old
- keymapping files) */
- static TSMDocumentID x11_document;
-
- if (state)
- {
- QuartzMessageMainThread (kXquartzActivate, 0);
-
- if (!_x_active)
- {
- if (x11_document == 0 && darwinKeymapFile == NULL)
- {
- OSType types[1];
- types[0] = kUnicodeDocument;
- NewTSMDocument (1, types, &x11_document, 0);
- }
-
- if (x11_document != 0)
- ActivateTSMDocument (x11_document);
- }
- }
- else
- {
- QuartzMessageMainThread (kXquartzDeactivate, 0);
-
- if (_x_active)
- {
- if (x11_document != 0)
- DeactivateTSMDocument (x11_document);
- }
- }
-
- _x_active = state;
-}
-
-- (void) became_key:(NSWindow *)win
-{
- [self activateX:NO];
-}
-
-- (void) sendEvent:(NSEvent *)e
-{
- NSEventType type;
- BOOL for_appkit, for_x;
-
- type = [e type];
-
- /* By default pass down the responder chain and to X. */
- for_appkit = YES;
- for_x = YES;
-
- switch (type)
- {
- case NSLeftMouseDown: case NSRightMouseDown: case NSOtherMouseDown:
- case NSLeftMouseUp: case NSRightMouseUp: case NSOtherMouseUp:
- if ([e window] != nil)
- {
- /* Pointer event has a window. Probably something for the kit. */
-
- for_x = NO;
-
- if (_x_active)
- [self activateX:NO];
- }
- else if ([self modalWindow] == nil)
- {
- /* Must be an X window. Tell appkit it doesn't have focus. */
-
- for_appkit = NO;
-
- if ([self isActive])
- {
- [self deactivate];
-
- if (!_x_active && RootlessKnowsWindowNumber ([e windowNumber]))
- [self activateX:YES];
- }
- }
- break;
-
- case NSKeyDown: case NSKeyUp:
- if (_x_active)
- {
- static int swallow_up;
-
- /* No kit window is focused, so send it to X. */
-
- for_appkit = NO;
-
- if (type == NSKeyDown)
- {
- /* Before that though, see if there are any global
- shortcuts bound to it. */
-
- if (X11EnableKeyEquivalents
- && [[self mainMenu] performKeyEquivalent:e])
- {
- swallow_up = [e keyCode];
- for_x = NO;
- }
- else if (!quartzEnableRootless
- && ([e modifierFlags] & ALL_KEY_MASKS)
- == (NSCommandKeyMask | NSAlternateKeyMask)
- && ([e keyCode] == 0 /*a*/
- || [e keyCode] == 53 /*Esc*/))
- {
- swallow_up = 0;
- for_x = NO;
- QuartzMessageMainThread (kXquartzToggleFullscreen, 0);
- }
- }
- else
- {
- /* If we saw a key equivalent on the down, don't pass
- the up through to X. */
-
- if (swallow_up != 0 && [e keyCode] == swallow_up)
- {
- swallow_up = 0;
- for_x = NO;
- }
- }
- }
- else
- {
- for_x = NO;
- }
- break;
-
- case NSFlagsChanged:
- /* For the l33t X users who remap modifier keys to normal keysyms. */
- if (!_x_active)
- for_x = NO;
- break;
-
- case NSAppKitDefined:
- switch ([e subtype])
- {
- case NSApplicationActivatedEventType:
- for_x = NO;
- if ([self modalWindow] == nil)
- {
- for_appkit = NO;
-
- /* FIXME: hack to avoid having to pass the event to appkit,
- which would cause it to raise one of its windows. */
- _appFlags._active = YES;
-
- [self activateX:YES];
- }
- break;
-
- case 18: /* ApplicationDidReactivate */
- if (quartzHasRoot)
- for_appkit = NO;
- break;
-
- case NSApplicationDeactivatedEventType:
- for_x = NO;
- [self activateX:NO];
- break;
- }
- break;
-
- default: break; /* for gcc */
- }
-
- if (for_appkit)
- {
- [super sendEvent:e];
- }
-
- if (for_x)
- {
- send_nsevent (type, e);
- }
-}
-
-- (void) set_window_menu:(NSArray *)list
-{
- [_controller set_window_menu:list];
-}
-
-- (void) set_window_menu_check:(NSNumber *)n
-{
- [_controller set_window_menu_check:n];
-}
-
-- (void) set_apps_menu:(NSArray *)list
-{
- [_controller set_apps_menu:list];
-}
-
-- (void) set_front_process:unused
-{
- [NSApp activateIgnoringOtherApps:YES];
-
- if ([self modalWindow] == nil)
- [self activateX:YES];
-}
-
-- (void) set_can_quit:(NSNumber *)state
-{
- [_controller set_can_quit:[state boolValue]];
-}
-
-- (void) server_ready:unused
-{
- [_controller server_ready];
-}
-
-- (void) show_hide_menubar:(NSNumber *)state
-{
- if ([state boolValue])
- ShowMenuBar ();
- else
- HideMenuBar ();
-}
-
-\f
-/* user preferences */
-
-/* Note that these functions only work for arrays whose elements
- can be toll-free-bridged between NS and CF worlds. */
-
-static const void *cfretain (CFAllocatorRef a, const void *b) {
- return CFRetain (b);
-}
-static void cfrelease (CFAllocatorRef a, const void *b) {
- CFRelease (b);
-}
-static CFMutableArrayRef
-nsarray_to_cfarray (NSArray *in)
-{
- CFMutableArrayRef out;
- CFArrayCallBacks cb;
- NSObject *ns;
- const CFTypeRef *cf;
- int i, count;
-
- memset (&cb, 0, sizeof (cb));
- cb.version = 0;
- cb.retain = cfretain;
- cb.release = cfrelease;
-
- count = [in count];
- out = CFArrayCreateMutable (NULL, count, &cb);
-
- for (i = 0; i < count; i++)
- {
- ns = [in objectAtIndex:i];
-
- if ([ns isKindOfClass:[NSArray class]])
- cf = (CFTypeRef) nsarray_to_cfarray ((NSArray *) ns);
- else
- cf = CFRetain ((CFTypeRef) ns);
-
- CFArrayAppendValue (out, cf);
- CFRelease (cf);
- }
-
- return out;
-}
-static NSMutableArray *
-cfarray_to_nsarray (CFArrayRef in)
-{
- NSMutableArray *out;
- const CFTypeRef *cf;
- NSObject *ns;
- int i, count;
-
- count = CFArrayGetCount (in);
- out = [[NSMutableArray alloc] initWithCapacity:count];
-
- for (i = 0; i < count; i++)
- {
- cf = CFArrayGetValueAtIndex (in, i);
-
- if (CFGetTypeID (cf) == CFArrayGetTypeID ())
- ns = cfarray_to_nsarray ((CFArrayRef) cf);
- else
- ns = [(id)cf retain];
-
- [out addObject:ns];
- [ns release];
- }
-
- return out;
-}
-
-- (CFPropertyListRef) prefs_get:(NSString *)key
-{
- CFPropertyListRef value;
-
- value = CFPreferencesCopyAppValue ((CFStringRef) key, CFSTR (APP_PREFS));
-
- if (value == NULL)
- {
- static CFDictionaryRef defaults;
-
- if (defaults == NULL)
- {
- CFStringRef error = NULL;
- CFDataRef data;
- CFURLRef url;
- SInt32 error_code;
-
- url = (CFURLCreateFromFileSystemRepresentation
- (NULL, DEFAULTS_FILE, strlen (DEFAULTS_FILE), false));
- if (CFURLCreateDataAndPropertiesFromResource (NULL, url, &data,
- NULL, NULL,
- &error_code))
- {
- defaults = (CFPropertyListCreateFromXMLData
- (NULL, data, kCFPropertyListImmutable, &error));
- if (error != NULL)
- CFRelease (error);
- CFRelease (data);
- }
- CFRelease (url);
- }
-
- if (defaults != NULL)
- value = CFDictionaryGetValue (defaults, key);
-
- if (value != NULL)
- CFRetain (value);
- }
-
- return value;
-}
-
-- (int) prefs_get_integer:(NSString *)key default:(int)def
-{
- CFPropertyListRef value;
- int ret;
-
- value = [self prefs_get:key];
-
- if (value != NULL && CFGetTypeID (value) == CFNumberGetTypeID ())
- CFNumberGetValue (value, kCFNumberIntType, &ret);
- else if (value != NULL && CFGetTypeID (value) == CFStringGetTypeID ())
- ret = CFStringGetIntValue (value);
- else
- ret = def;
-
- if (value != NULL)
- CFRelease (value);
-
- return ret;
-}
-
-- (const char *) prefs_get_string:(NSString *)key default:(const char *)def
-{
- CFPropertyListRef value;
- const char *ret = NULL;
-
- value = [self prefs_get:key];
-
- if (value != NULL && CFGetTypeID (value) == CFStringGetTypeID ())
- {
- NSString *s = (NSString *) value;
-
- ret = [s UTF8String];
- }
-
- if (value != NULL)
- CFRelease (value);
-
- return ret != NULL ? ret : def;
-}
-
-- (float) prefs_get_float:(NSString *)key default:(float)def
-{
- CFPropertyListRef value;
- float ret = def;
-
- value = [self prefs_get:key];
-
- if (value != NULL
- && CFGetTypeID (value) == CFNumberGetTypeID ()
- && CFNumberIsFloatType (value))
- {
- CFNumberGetValue (value, kCFNumberFloatType, &ret);
- }
- else if (value != NULL && CFGetTypeID (value) == CFStringGetTypeID ())
- {
- ret = CFStringGetDoubleValue (value);
- }
-
- if (value != NULL)
- CFRelease (value);
-
- return ret;
-}
-
-- (int) prefs_get_boolean:(NSString *)key default:(int)def
-{
- CFPropertyListRef value;
- int ret = def;
-
- value = [self prefs_get:key];
-
- if (value != NULL)
- {
- if (CFGetTypeID (value) == CFNumberGetTypeID ())
- CFNumberGetValue (value, kCFNumberIntType, &ret);
- else if (CFGetTypeID (value) == CFBooleanGetTypeID ())
- ret = CFBooleanGetValue (value);
- else if (CFGetTypeID (value) == CFStringGetTypeID ())
- {
- const char *tem = [(NSString *) value lossyCString];
- if (strcasecmp (tem, "true") == 0 || strcasecmp (tem, "yes") == 0)
- ret = YES;
- else
- ret = NO;
- }
-
- CFRelease (value);
- }
-
- return ret;
-}
-
-- (NSArray *) prefs_get_array:(NSString *)key
-{
- NSArray *ret = nil;
- CFPropertyListRef value;
-
- value = [self prefs_get:key];
-
- if (value != NULL)
- {
- if (CFGetTypeID (value) == CFArrayGetTypeID ())
- ret = [cfarray_to_nsarray (value) autorelease];
-
- CFRelease (value);
- }
-
- return ret;
-}
-
-- (void) prefs_set_integer:(NSString *)key value:(int)value
-{
- CFNumberRef x;
-
- x = CFNumberCreate (NULL, kCFNumberIntType, &value);
-
- CFPreferencesSetValue ((CFStringRef) key, (CFTypeRef) x, CFSTR (APP_PREFS),
- kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
-
- CFRelease (x);
-}
-
-- (void) prefs_set_float:(NSString *)key value:(float)value
-{
- CFNumberRef x;
-
- x = CFNumberCreate (NULL, kCFNumberFloatType, &value);
-
- CFPreferencesSetValue ((CFStringRef) key, (CFTypeRef) x, CFSTR (APP_PREFS),
- kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
-
- CFRelease (x);
-}
-
-- (void) prefs_set_boolean:(NSString *)key value:(int)value
-{
- CFPreferencesSetValue ((CFStringRef) key,
- (CFTypeRef) value ? kCFBooleanTrue
- : kCFBooleanFalse, CFSTR (APP_PREFS),
- kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
-
-}
-
-- (void) prefs_set_array:(NSString *)key value:(NSArray *)value
-{
- CFArrayRef cfarray;
-
- cfarray = nsarray_to_cfarray (value);
- CFPreferencesSetValue ((CFStringRef) key,
- (CFTypeRef) cfarray,
- CFSTR (APP_PREFS),
- kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
- CFRelease (cfarray);
-}
-
-- (void) prefs_set_string:(NSString *)key value:(NSString *)value
-{
- CFPreferencesSetValue ((CFStringRef) key, (CFTypeRef) value,
- CFSTR (APP_PREFS), kCFPreferencesCurrentUser,
- kCFPreferencesAnyHost);
-}
-
-- (void) prefs_synchronize
-{
- CFPreferencesAppSynchronize (kCFPreferencesCurrentApplication);
-}
-
-- (void) read_defaults
-{
- extern int darwinFakeButtons;
- const char *tem;
-
- quartzUseSysBeep = [self prefs_get_boolean:@PREFS_SYSBEEP
- default:quartzUseSysBeep];
- quartzEnableRootless = [self prefs_get_boolean:@PREFS_ROOTLESS
- default:quartzEnableRootless];
- quartzFullscreenDisableHotkeys = ![self prefs_get_boolean:
- @PREFS_FULLSCREEN_HOTKEYS default:
- !quartzFullscreenDisableHotkeys];
- quartzXpluginOptions = [self prefs_get_integer:@PREFS_XP_OPTIONS
- default:quartzXpluginOptions];
-
- darwinSwapAltMeta = [self prefs_get_boolean:@PREFS_SWAP_ALT_META
- default:darwinSwapAltMeta];
- darwinFakeButtons = [self prefs_get_boolean:@PREFS_FAKEBUTTONS
- default:darwinFakeButtons];
- if (darwinFakeButtons)
- {
- const char *fake2, *fake3;
-
- fake2 = [self prefs_get_string:@PREFS_FAKE_BUTTON2 default:NULL];
- fake3 = [self prefs_get_string:@PREFS_FAKE_BUTTON3 default:NULL];
-
- DarwinSetFakeButtons (fake2, fake3);
- }
-
- X11EnableKeyEquivalents = [self prefs_get_boolean:@PREFS_KEYEQUIVS
- default:X11EnableKeyEquivalents];
-
- darwinSyncKeymap = [self prefs_get_boolean:@PREFS_SYNC_KEYMAP
- default:darwinSyncKeymap];
-
- tem = [self prefs_get_string:@PREFS_KEYMAP_FILE default:NULL];
- if (tem != NULL)
- darwinKeymapFile = strdup (tem);
-
- quartzDesiredDepth = [self prefs_get_integer:@PREFS_DEPTH
- default:quartzDesiredDepth];
-}
-
-/* This will end up at the end of the responder chain. */
-- (void) copy:sender
-{
- QuartzMessageMainThread (kXquartzPasteboardNotify, 1,
- AppleWMCopyToPasteboard);
-}
-
-- (BOOL) x_active
-{
- return _x_active;
-}
-
-@end
-
-static NSArray *
-array_with_strings_and_numbers (int nitems, const char **items,
- const char *numbers)
-{
- NSMutableArray *array, *subarray;
- NSString *string;
- NSString *number;
- int i;
-
- /* (Can't autorelease on the X server thread) */
-
- array = [[NSMutableArray alloc] initWithCapacity:nitems];
-
- for (i = 0; i < nitems; i++)
- {
- subarray = [[NSMutableArray alloc] initWithCapacity:2];
-
- string = [[NSString alloc] initWithUTF8String:items[i]];
- [subarray addObject:string];
- [string release];
-
- if (numbers[i] != 0)
- {
- number = [[NSString alloc] initWithFormat:@"%d", numbers[i]];
- [subarray addObject:number];
- [number release];
- }
- else
- [subarray addObject:@""];
-
- [array addObject:subarray];
- [subarray release];
- }
-
- return array;
-}
-
-void
-X11ApplicationSetWindowMenu (int nitems, const char **items,
- const char *shortcuts)
-{
- NSArray *array;
-
- array = array_with_strings_and_numbers (nitems, items, shortcuts);
-
- /* Send the array of strings over to the appkit thread */
-
- message_kit_thread (@selector (set_window_menu:), array);
- [array release];
-}
-
-void
-X11ApplicationSetWindowMenuCheck (int idx)
-{
- NSNumber *n;
-
- n = [[NSNumber alloc] initWithInt:idx];
-
- message_kit_thread (@selector (set_window_menu_check:), n);
-
- [n release];
-}
-
-void
-X11ApplicationSetFrontProcess (void)
-{
- message_kit_thread (@selector (set_front_process:), nil);
-}
-
-void
-X11ApplicationSetCanQuit (int state)
-{
- NSNumber *n;
-
- n = [[NSNumber alloc] initWithBool:state];
-
- message_kit_thread (@selector (set_can_quit:), n);
-
- [n release];
-}
-
-void
-X11ApplicationServerReady (void)
-{
- message_kit_thread (@selector (server_ready:), nil);
-}
-
-void
-X11ApplicationShowHideMenubar (int state)
-{
- NSNumber *n;
-
- n = [[NSNumber alloc] initWithBool:state];
-
- message_kit_thread (@selector (show_hide_menubar:), n);
-
- [n release];
-}
-
-static void *
-create_thread (void *func, void *arg)
-{
- pthread_attr_t attr;
- pthread_t tid;
-
- pthread_attr_init (&attr);
-
- pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM);
- pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
-
- pthread_create (&tid, &attr, func, arg);
-
- pthread_attr_destroy (&attr);
-
- return (void *) tid;
-}
-
-static void
-check_xinitrc (void)
-{
- char *tem, buf[1024];
- NSString *msg;
-
- if ([X11App prefs_get_boolean:@PREFS_DONE_XINIT_CHECK default:NO])
- return;
-
- tem = getenv ("HOME");
- if (tem == NULL)
- goto done;
-
- snprintf (buf, sizeof (buf), "%s/.xinitrc", tem);
- if (access (buf, F_OK) != 0)
- goto done;
-
- /* FIXME: put localized strings into Resources/English.lproj */
-
- msg = NSLocalizedString (
-@"You have an existing ~/.xinitrc file.\n\n\
-Windows displayed by X11 applications may not have titlebars, or may look \
-different to windows displayed by native applications.\n\n\
-Would you like to move aside the existing file and use the standard X11 \
-environment?", @"");
-
- if (NSRunAlertPanel (nil, msg, NSLocalizedString (@"Yes", @""),
- NSLocalizedString (@"No", @""), nil)
- == NSAlertDefaultReturn)
- {
- char buf2[1024];
- int i = -1;
-
- snprintf (buf2, sizeof (buf2), "%s.old", buf);
-
- for (i = 1; access (buf2, F_OK) == 0; i++)
- snprintf (buf2, sizeof (buf2), "%s.old.%d", buf, i);
-
- rename (buf, buf2);
- }
-
-done:
- [X11App prefs_set_boolean:@PREFS_DONE_XINIT_CHECK value:YES];
- [X11App prefs_synchronize];
-}
-
-void
-X11ApplicationMain (int argc, const char *argv[],
- void (*server_thread) (void *), void *server_arg)
-{
- NSAutoreleasePool *pool;
-
-#ifdef DEBUG
- while (access ("/tmp/x11-block", F_OK) == 0)
- sleep (1);
-#endif
-
- pool = [[NSAutoreleasePool alloc] init];
-
- X11App = (X11Application *) [X11Application sharedApplication];
-
- init_ports ();
-
- [NSApp read_defaults];
-
- [NSBundle loadNibNamed:@"main" owner:NSApp];
-
- [[NSNotificationCenter defaultCenter] addObserver:NSApp
- selector:@selector (became_key:)
- name:NSWindowDidBecomeKeyNotification object:nil];
-
- check_xinitrc ();
-
- if (!create_thread (server_thread, server_arg))
- {
- fprintf (stderr, "can't create secondary thread\n");
- exit (1);
- }
-
- [NSApp run];
-
- /* not reached */
-}
-
-\f
-/* event conversion */
-
-static inline unsigned short
-convert_flags (unsigned int nsflags)
-{
- unsigned int xflags;
-
- if (nsflags == ~0)
- return 0xffff;
-
- xflags = 0;
-
- if (nsflags & NSAlphaShiftKeyMask)
- xflags |= LockMask;
- if (nsflags & NSShiftKeyMask)
- xflags |= ShiftMask;
- if (nsflags & NSControlKeyMask)
- xflags |= ControlMask;
- if (nsflags & NSAlternateKeyMask)
- xflags |= Mod1Mask;
- if (nsflags & NSCommandKeyMask)
- xflags |= Mod2Mask;
- /* FIXME: secondaryfn? */
-
- return xflags;
-}
-
-static void
-send_nsevent (NSEventType type, NSEvent *e)
-{
- static unsigned int button_state = 0;
-
- xEvent xe;
-
- memset (&xe, 0, sizeof (xe));
-
- switch (type)
- {
- NSRect screen;
- NSPoint location;
- NSWindow *window;
- int pointer_x, pointer_y, count;
-
- case NSLeftMouseDown:
- xe.u.u.type = ButtonPress;
- xe.u.u.detail = 1;
- goto do_press_event;
-
- case NSRightMouseDown:
- xe.u.u.type = ButtonPress;
- xe.u.u.detail = 3;
- goto do_press_event;
-
- case NSOtherMouseDown:
- xe.u.u.type = ButtonPress;
- xe.u.u.detail = 2; /* FIXME? */
- goto do_press_event;
-
- do_press_event:
- if (RootlessKnowsWindowNumber ([e windowNumber]) == NULL)
- {
- /* X server doesn't grok this window, drop the event.
-
- Note: theoretically this isn't necessary, but if I click
- on the menubar, we get sent a LeftMouseDown when the
- release happens, but no LeftMouseUp is ever seen! */
-
- break;
- }
- goto do_event;
-
- case NSLeftMouseUp:
- xe.u.u.type = ButtonRelease;
- xe.u.u.detail = 1;
- goto do_release_event;
-
- case NSRightMouseUp:
- xe.u.u.type = ButtonRelease;
- xe.u.u.detail = 3;
- goto do_release_event;
-
- case NSOtherMouseUp:
- xe.u.u.type = ButtonRelease;
- xe.u.u.detail = 2; /* FIXME? */
- goto do_release_event;
-
- do_release_event:
- if ((button_state & (1 << xe.u.u.detail)) == 0)
- {
- /* X didn't see the button press for this release, so skip it */
- break;
- }
- goto do_event;
-
- case NSMouseMoved:
- case NSLeftMouseDragged:
- case NSRightMouseDragged:
- case NSOtherMouseDragged:
- /* convert location to global top-left coordinates */
-
- location = [e locationInWindow];
- window = [e window];
- screen = [[[NSScreen screens] objectAtIndex:0] frame];
-
- if (window != nil)
- {
- NSRect frame = [window frame];
- pointer_x = location.x + frame.origin.x;
- pointer_y = (((screen.origin.y + screen.size.height)
- - location.y) - frame.origin.y);
- }
- else
- {
- pointer_x = location.x;
- pointer_y = (screen.origin.y + screen.size.height) - location.y;
- }
-
- xe.u.keyButtonPointer.rootX = pointer_x;
- xe.u.keyButtonPointer.rootY = pointer_y;
- xe.u.u.type = MotionNotify;
- goto do_event;
-
- case NSKeyDown:
- xe.u.u.type = KeyPress;
- xe.u.u.detail = [e keyCode];
- goto do_event;
-
- case NSKeyUp:
- xe.u.u.type = KeyRelease;
- xe.u.u.detail = [e keyCode];
- goto do_event;
-
- case NSScrollWheel:
- xe.u.keyButtonPointer.state = convert_flags ([e modifierFlags]);
- count = [e deltaY];
- xe.u.u.detail = count > 0 ? 4 : 5;
- for (count = abs (count); count-- > 0;)
- {
- xe.u.u.type = ButtonPress;
- DarwinEnqueueEvent (&xe);
- xe.u.u.type = ButtonRelease;
- DarwinEnqueueEvent (&xe);
- }
- xe.u.u.type = 0;
- break;
-
- case NSFlagsChanged:
- do_event:
- xe.u.keyButtonPointer.state = convert_flags ([e modifierFlags]);
- DarwinEnqueueEvent (&xe);
- break;
-
- default: break; /* for gcc */
- }
-
- if (xe.u.u.type == ButtonPress)
- button_state |= (1 << xe.u.u.detail);
- else if (xe.u.u.type == ButtonRelease)
- button_state &= ~(1 << xe.u.u.detail);
-}