14642e01fSmrg/* main.m
235c4bbdfSmrg *
335c4bbdfSmrg * Copyright (c) 2002-2012 Apple Inc. All rights reserved.
435c4bbdfSmrg *
535c4bbdfSmrg * Permission is hereby granted, free of charge, to any person
635c4bbdfSmrg * obtaining a copy of this software and associated documentation files
735c4bbdfSmrg * (the "Software"), to deal in the Software without restriction,
835c4bbdfSmrg * including without limitation the rights to use, copy, modify, merge,
935c4bbdfSmrg * publish, distribute, sublicense, and/or sell copies of the Software,
1035c4bbdfSmrg * and to permit persons to whom the Software is furnished to do so,
1135c4bbdfSmrg * subject to the following conditions:
1235c4bbdfSmrg *
1335c4bbdfSmrg * The above copyright notice and this permission notice shall be
1435c4bbdfSmrg * included in all copies or substantial portions of the Software.
1535c4bbdfSmrg *
1635c4bbdfSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1735c4bbdfSmrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1835c4bbdfSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1935c4bbdfSmrg * NONINFRINGEMENT.  IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
2035c4bbdfSmrg * HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
2135c4bbdfSmrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2235c4bbdfSmrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2335c4bbdfSmrg * DEALINGS IN THE SOFTWARE.
2435c4bbdfSmrg *
2535c4bbdfSmrg * Except as contained in this notice, the name(s) of the above
2635c4bbdfSmrg * copyright holders shall not be used in advertising or otherwise to
2735c4bbdfSmrg * promote the sale, use or other dealings in this Software without
2835c4bbdfSmrg * prior written authorization.
294642e01fSmrg */
304642e01fSmrg
314642e01fSmrg#include "pbproxy.h"
324642e01fSmrg#import "x-selection.h"
334642e01fSmrg
344642e01fSmrg#include <pthread.h>
354642e01fSmrg#include <unistd.h>
364642e01fSmrg#include <X11/extensions/applewm.h>
374642e01fSmrg
384642e01fSmrgDisplay *xpbproxy_dpy;
394642e01fSmrgint xpbproxy_apple_wm_event_base, xpbproxy_apple_wm_error_base;
404642e01fSmrgint xpbproxy_xfixes_event_base, xpbproxy_xfixes_error_base;
414642e01fSmrgBOOL xpbproxy_have_xfixes;
424642e01fSmrg
434642e01fSmrgextern char *display;
444642e01fSmrg
454642e01fSmrg#ifdef STANDALONE_XPBPROXY
464642e01fSmrgBOOL xpbproxy_is_standalone = NO;
474642e01fSmrg#endif
484642e01fSmrg
494642e01fSmrgx_selection *_selection_object;
504642e01fSmrg
5135c4bbdfSmrgstatic int
5235c4bbdfSmrgx_io_error_handler(Display *dpy)
5335c4bbdfSmrg{
544642e01fSmrg    /* We lost our connection to the server. */
5535c4bbdfSmrg
5635c4bbdfSmrg    TRACE();
574642e01fSmrg
584642e01fSmrg    /* trigger the thread to restart?
594642e01fSmrg     *   NO - this would be to a "deeper" problem, and restarts would just
604642e01fSmrg     *        make things worse...
614642e01fSmrg     */
624642e01fSmrg#ifdef STANDALONE_XPBPROXY
6335c4bbdfSmrg    if (xpbproxy_is_standalone)
644642e01fSmrg        exit(EXIT_FAILURE);
654642e01fSmrg#endif
664642e01fSmrg
676747b715Smrg    /* Prevent _XIOError from calling exit() */
686747b715Smrg    pthread_exit(NULL);
694642e01fSmrg    return 0;
704642e01fSmrg}
714642e01fSmrg
7235c4bbdfSmrgstatic int
7335c4bbdfSmrgx_error_handler(Display *dpy, XErrorEvent *errevent)
7435c4bbdfSmrg{
754642e01fSmrg    return 0;
764642e01fSmrg}
774642e01fSmrg
7835c4bbdfSmrgint
7935c4bbdfSmrgxpbproxy_run(void)
8035c4bbdfSmrg{
81c8548ba8Smrg    @autoreleasepool {
82c8548ba8Smrg        size_t i;
8335c4bbdfSmrg
84c8548ba8Smrg        for (i = 0, xpbproxy_dpy = NULL; !xpbproxy_dpy && i < 5; i++) {
85c8548ba8Smrg            xpbproxy_dpy = XOpenDisplay(NULL);
8635c4bbdfSmrg
87c8548ba8Smrg            if (!xpbproxy_dpy && display) {
88c8548ba8Smrg                char _display[32];
89c8548ba8Smrg                snprintf(_display, sizeof(_display), ":%s", display);
90c8548ba8Smrg                setenv("DISPLAY", _display, TRUE);
9135c4bbdfSmrg
92c8548ba8Smrg                xpbproxy_dpy = XOpenDisplay(_display);
93c8548ba8Smrg            }
94c8548ba8Smrg            if (!xpbproxy_dpy)
95c8548ba8Smrg                sleep(1);
964642e01fSmrg        }
9735c4bbdfSmrg
98c8548ba8Smrg        if (xpbproxy_dpy == NULL) {
99c8548ba8Smrg            ErrorF("xpbproxy: can't open default display\n");
100c8548ba8Smrg            return EXIT_FAILURE;
101c8548ba8Smrg        }
10235c4bbdfSmrg
103c8548ba8Smrg        XSetIOErrorHandler(x_io_error_handler);
104c8548ba8Smrg        XSetErrorHandler(x_error_handler);
10535c4bbdfSmrg
106c8548ba8Smrg        if (!XAppleWMQueryExtension(xpbproxy_dpy, &xpbproxy_apple_wm_event_base,
107c8548ba8Smrg                                    &xpbproxy_apple_wm_error_base)) {
108c8548ba8Smrg            ErrorF("xpbproxy: can't open AppleWM server extension\n");
109c8548ba8Smrg            return EXIT_FAILURE;
110c8548ba8Smrg        }
1116747b715Smrg
112c8548ba8Smrg        xpbproxy_have_xfixes = XFixesQueryExtension(xpbproxy_dpy, &xpbproxy_xfixes_event_base,
113c8548ba8Smrg                                                    &xpbproxy_xfixes_error_base);
11435c4bbdfSmrg
115c8548ba8Smrg        XAppleWMSelectInput(xpbproxy_dpy, AppleWMActivationNotifyMask | AppleWMPasteboardNotifyMask);
1166747b715Smrg
117c8548ba8Smrg        _selection_object = [x_selection new];
11835c4bbdfSmrg
119c8548ba8Smrg        if (!xpbproxy_input_register()) {
120c8548ba8Smrg            return EXIT_FAILURE;
121c8548ba8Smrg        }
1224642e01fSmrg    }
12335c4bbdfSmrg
1246747b715Smrg    CFRunLoopRun();
1254642e01fSmrg
1266747b715Smrg    return EXIT_SUCCESS;
1274642e01fSmrg}
1284642e01fSmrg
12935c4bbdfSmrgid
13035c4bbdfSmrgxpbproxy_selection_object(void)
13135c4bbdfSmrg{
1324642e01fSmrg    return _selection_object;
1334642e01fSmrg}
1344642e01fSmrg
13535c4bbdfSmrgTime
13635c4bbdfSmrgxpbproxy_current_timestamp(void)
13735c4bbdfSmrg{
1384642e01fSmrg    /* FIXME: may want to fetch a timestamp from the server.. */
1394642e01fSmrg    return CurrentTime;
1404642e01fSmrg}
141