aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/xquartz/pbproxy/x-input.m
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/xquartz/pbproxy/x-input.m')
-rw-r--r--xorg-server/hw/xquartz/pbproxy/x-input.m187
1 files changed, 187 insertions, 0 deletions
diff --git a/xorg-server/hw/xquartz/pbproxy/x-input.m b/xorg-server/hw/xquartz/pbproxy/x-input.m
new file mode 100644
index 000000000..6ba30c610
--- /dev/null
+++ b/xorg-server/hw/xquartz/pbproxy/x-input.m
@@ -0,0 +1,187 @@
+/* x-input.m -- event handling
+ Copyright (c) 2002, 2008 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.
+ */
+
+#include "pbproxy.h"
+#import "x-selection.h"
+
+#include <CoreFoundation/CFSocket.h>
+#include <CoreFoundation/CFRunLoop.h>
+
+#include <X11/Xatom.h>
+#include <X11/keysym.h>
+#include <X11/extensions/applewm.h>
+
+#include <unistd.h>
+
+#include <pthread.h>
+
+static CFRunLoopSourceRef xpbproxy_dpy_source;
+
+#ifdef STANDALONE_XPBPROXY
+BOOL xpbproxy_prefs_reload = NO;
+#endif
+
+static pthread_mutex_t xpbproxy_dpy_rdy_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t xpbproxy_dpy_rdy_cond = PTHREAD_COND_INITIALIZER;
+
+/* 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 - xpbproxy_apple_wm_event_base;
+ int kind = e->kind;
+
+ /* We want to reload prefs even if we're not active */
+ if(type == AppleWMActivationNotify &&
+ kind == AppleWMReloadPreferences)
+ [xpbproxy_selection_object() reload_preferences];
+
+ if(![xpbproxy_selection_object() is_active])
+ return;
+
+ switch (type) {
+ case AppleWMActivationNotify:
+ switch (kind) {
+ case AppleWMIsActive:
+ last_activation_time = e->time;
+ [xpbproxy_selection_object() x_active:e->time];
+ break;
+
+ case AppleWMIsInactive:
+ [xpbproxy_selection_object() x_inactive:e->time];
+ break;
+ }
+ break;
+
+ case AppleWMPasteboardNotify:
+ switch (kind) {
+ case AppleWMCopyToPasteboard:
+ [xpbproxy_selection_object() x_copy:e->time];
+ }
+ break;
+ }
+}
+
+void xpbproxy_input_loop() {
+ pthread_mutex_lock(&xpbproxy_dpy_rdy_lock);
+ while(true) {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ if(pool == nil) {
+ fprintf(stderr, "unable to allocate/init auto release pool!\n");
+ break;
+ }
+
+ while (XPending(xpbproxy_dpy) != 0) {
+ XEvent e;
+
+ pthread_mutex_unlock(&xpbproxy_dpy_rdy_lock);
+ XNextEvent (xpbproxy_dpy, &e);
+
+ switch (e.type) {
+ case SelectionClear:
+ if([xpbproxy_selection_object() is_active])
+ [xpbproxy_selection_object () clear_event:&e.xselectionclear];
+ break;
+
+ case SelectionRequest:
+ [xpbproxy_selection_object () request_event:&e.xselectionrequest];
+ break;
+
+ case SelectionNotify:
+ [xpbproxy_selection_object () notify_event:&e.xselection];
+ break;
+
+ case PropertyNotify:
+ [xpbproxy_selection_object () property_event:&e.xproperty];
+ break;
+
+ default:
+ if(e.type >= xpbproxy_apple_wm_event_base &&
+ e.type < xpbproxy_apple_wm_event_base + AppleWMNumberEvents) {
+ x_event_apple_wm_notify((XAppleWMNotifyEvent *) &e);
+ } else if(e.type == xpbproxy_xfixes_event_base + XFixesSelectionNotify) {
+ [xpbproxy_selection_object() xfixes_selection_notify:(XFixesSelectionNotifyEvent *)&e];
+ }
+ break;
+ }
+
+ XFlush(xpbproxy_dpy);
+ pthread_mutex_lock(&xpbproxy_dpy_rdy_lock);
+ }
+
+ [pool release];
+
+ pthread_cond_wait(&xpbproxy_dpy_rdy_cond, &xpbproxy_dpy_rdy_lock);
+ }
+}
+
+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 (CFRunLoopGetMain (),
+ *cf_source, kCFRunLoopDefaultMode);
+ return TRUE;
+}
+
+static void x_input_callback (CFSocketRef sock, CFSocketCallBackType type,
+ CFDataRef address, const void *data, void *info) {
+
+#ifdef STANDALONE_XPBPROXY
+ if(xpbproxy_prefs_reload) {
+ [xpbproxy_selection_object() reload_preferences];
+ xpbproxy_prefs_reload = NO;
+ }
+#endif
+
+ pthread_mutex_lock(&xpbproxy_dpy_rdy_lock);
+ pthread_cond_broadcast(&xpbproxy_dpy_rdy_cond);
+ pthread_mutex_unlock(&xpbproxy_dpy_rdy_lock);
+}
+
+BOOL xpbproxy_input_register(void) {
+ return add_input_socket(ConnectionNumber(xpbproxy_dpy), kCFSocketReadCallBack,
+ x_input_callback, NULL, &xpbproxy_dpy_source);
+}