xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

x-input.m (5480B)


      1 /* x-input.m -- event handling
      2  *
      3  * Copyright (c) 2002-2012 Apple Inc. All rights reserved.
      4  *
      5  * Permission is hereby granted, free of charge, to any person
      6  * obtaining a copy of this software and associated documentation files
      7  * (the "Software"), to deal in the Software without restriction,
      8  * including without limitation the rights to use, copy, modify, merge,
      9  * publish, distribute, sublicense, and/or sell copies of the Software,
     10  * and to permit persons to whom the Software is furnished to do so,
     11  * subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be
     14  * included in all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     19  * NONINFRINGEMENT.  IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
     20  * HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     21  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     23  * DEALINGS IN THE SOFTWARE.
     24  *
     25  * Except as contained in this notice, the name(s) of the above
     26  * copyright holders shall not be used in advertising or otherwise to
     27  * promote the sale, use or other dealings in this Software without
     28  * prior written authorization.
     29  */
     30 
     31 #include "pbproxy.h"
     32 #import "x-selection.h"
     33 
     34 #include <CoreFoundation/CFSocket.h>
     35 #include <CoreFoundation/CFRunLoop.h>
     36 
     37 #include <X11/Xatom.h>
     38 #include <X11/keysym.h>
     39 #include <X11/extensions/applewm.h>
     40 
     41 #include <unistd.h>
     42 
     43 static CFRunLoopSourceRef xpbproxy_dpy_source;
     44 
     45 #ifdef STANDALONE_XPBPROXY
     46 BOOL xpbproxy_prefs_reload = NO;
     47 #endif
     48 
     49 /* Timestamp when the X server last told us it's active */
     50 static Time last_activation_time;
     51 
     52 static void
     53 x_event_apple_wm_notify(XAppleWMNotifyEvent *e)
     54 {
     55     int type = e->type - xpbproxy_apple_wm_event_base;
     56     int kind = e->kind;
     57 
     58     /* We want to reload prefs even if we're not active */
     59     if (type == AppleWMActivationNotify &&
     60         kind == AppleWMReloadPreferences)
     61         [xpbproxy_selection_object ()reload_preferences];
     62 
     63     if (![xpbproxy_selection_object ()is_active])
     64         return;
     65 
     66     switch (type) {
     67     case AppleWMActivationNotify:
     68         switch (kind) {
     69         case AppleWMIsActive:
     70             last_activation_time = e->time;
     71             [xpbproxy_selection_object () x_active:e->time];
     72             break;
     73 
     74         case AppleWMIsInactive:
     75             [xpbproxy_selection_object () x_inactive:e->time];
     76             break;
     77         }
     78         break;
     79 
     80     case AppleWMPasteboardNotify:
     81         switch (kind) {
     82         case AppleWMCopyToPasteboard:
     83             [xpbproxy_selection_object () x_copy:e->time];
     84         }
     85         break;
     86     }
     87 }
     88 
     89 static void
     90 xpbproxy_process_xevents(void)
     91 {
     92     while (XPending(xpbproxy_dpy) != 0) { @autoreleasepool {
     93         XEvent e;
     94 
     95         XNextEvent(xpbproxy_dpy, &e);
     96 
     97         switch (e.type) {
     98         case SelectionClear:
     99             if ([xpbproxy_selection_object ()is_active])
    100                 [xpbproxy_selection_object () clear_event:&e.xselectionclear];
    101             break;
    102 
    103         case SelectionRequest:
    104             [xpbproxy_selection_object () request_event:&e.xselectionrequest];
    105             break;
    106 
    107         case SelectionNotify:
    108             [xpbproxy_selection_object () notify_event:&e.xselection];
    109             break;
    110 
    111         case PropertyNotify:
    112             [xpbproxy_selection_object () property_event:&e.xproperty];
    113             break;
    114 
    115         default:
    116             if (e.type >= xpbproxy_apple_wm_event_base &&
    117                 e.type < xpbproxy_apple_wm_event_base +
    118                 AppleWMNumberEvents) {
    119                 x_event_apple_wm_notify((XAppleWMNotifyEvent *)&e);
    120             }
    121             else if (e.type == xpbproxy_xfixes_event_base +
    122                      XFixesSelectionNotify) {
    123                 [xpbproxy_selection_object () xfixes_selection_notify:(
    124                      XFixesSelectionNotifyEvent *)&e];
    125             }
    126             break;
    127         }
    128 
    129         XFlush(xpbproxy_dpy);
    130     }}
    131 }
    132 
    133 static BOOL
    134 add_input_socket(int sock, CFOptionFlags callback_types,
    135                  CFSocketCallBack callback, const CFSocketContext *ctx,
    136                  CFRunLoopSourceRef *cf_source)
    137 {
    138     CFSocketRef cf_sock;
    139 
    140     cf_sock = CFSocketCreateWithNative(kCFAllocatorDefault, sock,
    141                                        callback_types, callback, ctx);
    142     if (cf_sock == NULL) {
    143         close(sock);
    144         return FALSE;
    145     }
    146 
    147     *cf_source = CFSocketCreateRunLoopSource(kCFAllocatorDefault,
    148                                              cf_sock, 0);
    149     CFRelease(cf_sock);
    150 
    151     if (*cf_source == NULL)
    152         return FALSE;
    153 
    154     CFRunLoopAddSource(CFRunLoopGetCurrent(),
    155                        *cf_source, kCFRunLoopDefaultMode);
    156     return TRUE;
    157 }
    158 
    159 static void
    160 x_input_callback(CFSocketRef sock, CFSocketCallBackType type,
    161                  CFDataRef address, const void *data, void *info)
    162 {
    163 
    164 #ifdef STANDALONE_XPBPROXY
    165     if (xpbproxy_prefs_reload) {
    166         [xpbproxy_selection_object ()reload_preferences];
    167         xpbproxy_prefs_reload = NO;
    168     }
    169 #endif
    170 
    171     xpbproxy_process_xevents();
    172 }
    173 
    174 BOOL
    175 xpbproxy_input_register(void)
    176 {
    177     return add_input_socket(ConnectionNumber(
    178                                 xpbproxy_dpy), kCFSocketReadCallBack,
    179                             x_input_callback, NULL, &xpbproxy_dpy_source);
    180 }