/* x-input.m -- event handling $Id: x-input.m,v 1.26 2007-04-07 20:39:03 jharper Exp $ Copyright (c) 2002, 2008 Apple Computer, Inc. All rights reserved. */ #include "pbproxy.h" #import "x-selection.h" #include #include #include #include #include #include static CFRunLoopSourceRef x_dpy_source; /* Timestamp when the X server last told us it's active */ static Time last_activation_time; static void x_event_apple_wm_notify(XAppleWMNotifyEvent *e) { int type = e->type - x_apple_wm_event_base; int kind = e->kind; /* We want to reload prefs even if we're not active */ if(type == AppleWMActivationNotify && kind == AppleWMReloadPreferences) [x_selection_object() reload_preferences]; if(![x_selection_object() is_active]) return; switch (type) { case AppleWMActivationNotify: switch (kind) { case AppleWMIsActive: last_activation_time = e->time; [x_selection_object() x_active:e->time]; break; case AppleWMIsInactive: [x_selection_object() x_inactive:e->time]; break; } break; case AppleWMPasteboardNotify: switch (kind) { case AppleWMCopyToPasteboard: [x_selection_object() x_copy:e->time]; } break; } } void x_input_run (void) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; if (nil == pool) { fprintf(stderr, "unable to allocate/init auto release pool!\n"); return; } while (XPending (x_dpy) != 0) { XEvent e; XNextEvent (x_dpy, &e); switch (e.type) { case SelectionClear: if([x_selection_object() is_active]) [x_selection_object () clear_event:&e.xselectionclear]; break; case SelectionRequest: [x_selection_object () request_event:&e.xselectionrequest]; break; case SelectionNotify: [x_selection_object () notify_event:&e.xselection]; break; case PropertyNotify: [x_selection_object () property_event:&e.xproperty]; break; default: if(e.type >= x_apple_wm_event_base && e.type < x_apple_wm_event_base + AppleWMNumberEvents) { x_event_apple_wm_notify((XAppleWMNotifyEvent *) &e); } else if(e.type == x_xfixes_event_base + XFixesSelectionNotify) { [x_selection_object() xfixes_selection_notify:(XFixesSelectionNotifyEvent *)&e]; } break; } XFlush(x_dpy); } [pool release]; } static BOOL add_input_socket (int sock, CFOptionFlags callback_types, CFSocketCallBack callback, const CFSocketContext *ctx, CFRunLoopSourceRef *cf_source) { CFSocketRef cf_sock; cf_sock = CFSocketCreateWithNative (kCFAllocatorDefault, sock, callback_types, callback, ctx); if (cf_sock == NULL) { close (sock); return FALSE; } *cf_source = CFSocketCreateRunLoopSource (kCFAllocatorDefault, cf_sock, 0); CFRelease (cf_sock); if (*cf_source == NULL) return FALSE; CFRunLoopAddSource (CFRunLoopGetCurrent (), *cf_source, kCFRunLoopDefaultMode); return TRUE; } static void x_input_callback (CFSocketRef sock, CFSocketCallBackType type, CFDataRef address, const void *data, void *info) { #ifndef INTEGRATED_XPBPROXY if(prefs_reload) { [x_selection_object() reload_preferences]; prefs_reload = NO; } #endif x_input_run(); } BOOL x_input_register(void) { return add_input_socket(ConnectionNumber(x_dpy), kCFSocketReadCallBack, x_input_callback, NULL, &x_dpy_source); }