1706f2543Smrg/* main.m 2706f2543Smrg Copyright (c) 2002, 2008 Apple Computer, Inc. All rights reserved. 3706f2543Smrg 4706f2543Smrg Permission is hereby granted, free of charge, to any person 5706f2543Smrg obtaining a copy of this software and associated documentation files 6706f2543Smrg (the "Software"), to deal in the Software without restriction, 7706f2543Smrg including without limitation the rights to use, copy, modify, merge, 8706f2543Smrg publish, distribute, sublicense, and/or sell copies of the Software, 9706f2543Smrg and to permit persons to whom the Software is furnished to do so, 10706f2543Smrg subject to the following conditions: 11706f2543Smrg 12706f2543Smrg The above copyright notice and this permission notice shall be 13706f2543Smrg included in all copies or substantial portions of the Software. 14706f2543Smrg 15706f2543Smrg THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16706f2543Smrg EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17706f2543Smrg MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18706f2543Smrg NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT 19706f2543Smrg HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20706f2543Smrg WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21706f2543Smrg OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22706f2543Smrg DEALINGS IN THE SOFTWARE. 23706f2543Smrg 24706f2543Smrg Except as contained in this notice, the name(s) of the above 25706f2543Smrg copyright holders shall not be used in advertising or otherwise to 26706f2543Smrg promote the sale, use or other dealings in this Software without 27706f2543Smrg prior written authorization. 28706f2543Smrg */ 29706f2543Smrg 30706f2543Smrg#include "pbproxy.h" 31706f2543Smrg#import "x-selection.h" 32706f2543Smrg 33706f2543Smrg#include <pthread.h> 34706f2543Smrg#include <unistd.h> 35706f2543Smrg#include <X11/extensions/applewm.h> 36706f2543Smrg 37706f2543SmrgDisplay *xpbproxy_dpy; 38706f2543Smrgint xpbproxy_apple_wm_event_base, xpbproxy_apple_wm_error_base; 39706f2543Smrgint xpbproxy_xfixes_event_base, xpbproxy_xfixes_error_base; 40706f2543SmrgBOOL xpbproxy_have_xfixes; 41706f2543Smrg 42706f2543Smrgextern char *display; 43706f2543Smrg 44706f2543Smrg#ifdef STANDALONE_XPBPROXY 45706f2543SmrgBOOL xpbproxy_is_standalone = NO; 46706f2543Smrg#endif 47706f2543Smrg 48706f2543Smrgx_selection *_selection_object; 49706f2543Smrg 50706f2543Smrgextern BOOL serverRunning; 51706f2543Smrgextern pthread_mutex_t serverRunningMutex; 52706f2543Smrgextern pthread_cond_t serverRunningCond; 53706f2543Smrg 54706f2543Smrgstatic inline void wait_for_server_init(void) { 55706f2543Smrg /* If the server hasn't finished initializing, wait for it... */ 56706f2543Smrg if(!serverRunning) { 57706f2543Smrg pthread_mutex_lock(&serverRunningMutex); 58706f2543Smrg while(!serverRunning) 59706f2543Smrg pthread_cond_wait(&serverRunningCond, &serverRunningMutex); 60706f2543Smrg pthread_mutex_unlock(&serverRunningMutex); 61706f2543Smrg } 62706f2543Smrg} 63706f2543Smrg 64706f2543Smrgstatic int x_io_error_handler (Display *dpy) { 65706f2543Smrg /* We lost our connection to the server. */ 66706f2543Smrg 67706f2543Smrg TRACE (); 68706f2543Smrg 69706f2543Smrg /* trigger the thread to restart? 70706f2543Smrg * NO - this would be to a "deeper" problem, and restarts would just 71706f2543Smrg * make things worse... 72706f2543Smrg */ 73706f2543Smrg#ifdef STANDALONE_XPBPROXY 74706f2543Smrg if(xpbproxy_is_standalone) 75706f2543Smrg exit(EXIT_FAILURE); 76706f2543Smrg#endif 77706f2543Smrg 78706f2543Smrg /* Prevent _XIOError from calling exit() */ 79706f2543Smrg pthread_exit(NULL); 80706f2543Smrg return 0; 81706f2543Smrg} 82706f2543Smrg 83706f2543Smrgstatic int x_error_handler (Display *dpy, XErrorEvent *errevent) { 84706f2543Smrg return 0; 85706f2543Smrg} 86706f2543Smrg 87706f2543Smrgint xpbproxy_run (void) { 88706f2543Smrg NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 89706f2543Smrg size_t i; 90706f2543Smrg 91706f2543Smrg wait_for_server_init(); 92706f2543Smrg 93706f2543Smrg for(i=0, xpbproxy_dpy=NULL; !xpbproxy_dpy && i<5; i++) { 94706f2543Smrg xpbproxy_dpy = XOpenDisplay(NULL); 95706f2543Smrg 96706f2543Smrg if(!xpbproxy_dpy && display) { 97706f2543Smrg char _display[32]; 98706f2543Smrg snprintf(_display, sizeof(_display), ":%s", display); 99706f2543Smrg setenv("DISPLAY", _display, TRUE); 100706f2543Smrg 101706f2543Smrg xpbproxy_dpy=XOpenDisplay(_display); 102706f2543Smrg } 103706f2543Smrg if(!xpbproxy_dpy) 104706f2543Smrg sleep(1); 105706f2543Smrg } 106706f2543Smrg 107706f2543Smrg if (xpbproxy_dpy == NULL) { 108706f2543Smrg fprintf (stderr, "xpbproxy: can't open default display\n"); 109706f2543Smrg [pool release]; 110706f2543Smrg return EXIT_FAILURE; 111706f2543Smrg } 112706f2543Smrg 113706f2543Smrg XSetIOErrorHandler (x_io_error_handler); 114706f2543Smrg XSetErrorHandler (x_error_handler); 115706f2543Smrg 116706f2543Smrg if (!XAppleWMQueryExtension (xpbproxy_dpy, &xpbproxy_apple_wm_event_base, 117706f2543Smrg &xpbproxy_apple_wm_error_base)) { 118706f2543Smrg fprintf (stderr, "xpbproxy: can't open AppleWM server extension\n"); 119706f2543Smrg [pool release]; 120706f2543Smrg return EXIT_FAILURE; 121706f2543Smrg } 122706f2543Smrg 123706f2543Smrg xpbproxy_have_xfixes = XFixesQueryExtension(xpbproxy_dpy, &xpbproxy_xfixes_event_base, &xpbproxy_xfixes_error_base); 124706f2543Smrg 125706f2543Smrg XAppleWMSelectInput (xpbproxy_dpy, AppleWMActivationNotifyMask | 126706f2543Smrg AppleWMPasteboardNotifyMask); 127706f2543Smrg 128706f2543Smrg _selection_object = [[x_selection alloc] init]; 129706f2543Smrg 130706f2543Smrg if(!xpbproxy_input_register()) { 131706f2543Smrg [pool release]; 132706f2543Smrg return EXIT_FAILURE; 133706f2543Smrg } 134706f2543Smrg 135706f2543Smrg [pool release]; 136706f2543Smrg 137706f2543Smrg CFRunLoopRun(); 138706f2543Smrg 139706f2543Smrg return EXIT_SUCCESS; 140706f2543Smrg} 141706f2543Smrg 142706f2543Smrgid xpbproxy_selection_object (void) { 143706f2543Smrg return _selection_object; 144706f2543Smrg} 145706f2543Smrg 146706f2543SmrgTime xpbproxy_current_timestamp (void) { 147706f2543Smrg /* FIXME: may want to fetch a timestamp from the server.. */ 148706f2543Smrg return CurrentTime; 149706f2543Smrg} 150706f2543Smrg 151706f2543Smrgvoid debug_printf (const char *fmt, ...) { 152706f2543Smrg static int spew = -1; 153706f2543Smrg 154706f2543Smrg if (spew == -1) { 155706f2543Smrg char *x = getenv ("DEBUG"); 156706f2543Smrg spew = (x != NULL && atoi (x) != 0); 157706f2543Smrg } 158706f2543Smrg 159706f2543Smrg if (spew) { 160706f2543Smrg va_list args; 161706f2543Smrg va_start(args, fmt); 162706f2543Smrg vfprintf (stderr, fmt, args); 163706f2543Smrg va_end(args); 164706f2543Smrg } 165706f2543Smrg} 166