From 543c2cd68d1ffef65d4644b860faad7191c6b9da Mon Sep 17 00:00:00 2001 From: Jeremy Huddleston Date: Thu, 15 May 2008 09:55:17 -0700 Subject: XQuartz: Added functionality to add a file descriptor to the connection list after the server is already running. --- hw/xquartz/X11Application.m | 24 ++++++++--- hw/xquartz/darwinEvents.c | 14 +++++- hw/xquartz/darwinEvents.h | 1 + hw/xquartz/mach-startup/Makefile.am | 7 ++- hw/xquartz/mach-startup/launchd_fd.c | 82 ++++++++++++++++++++++++++++++++++++ hw/xquartz/mach-startup/launchd_fd.h | 36 ++++++++++++++++ hw/xquartz/quartzKeyboard.c | 2 - include/os.h | 4 ++ os/connection.c | 64 ++++++++++++++++++++++++++++ 9 files changed, 223 insertions(+), 11 deletions(-) create mode 100644 hw/xquartz/mach-startup/launchd_fd.c create mode 100644 hw/xquartz/mach-startup/launchd_fd.h diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m index 546ea0cb1..972187cd3 100644 --- a/hw/xquartz/X11Application.m +++ b/hw/xquartz/X11Application.m @@ -37,12 +37,15 @@ #import "X11Application.h" -# include "darwin.h" -# include "darwinEvents.h" -# include "quartz.h" -# define _APPLEWM_SERVER_ -# include "X11/extensions/applewm.h" -# include "micmap.h" +#include "darwin.h" +#include "darwinEvents.h" +#include "quartz.h" +#define _APPLEWM_SERVER_ +#include "X11/extensions/applewm.h" +#include "micmap.h" + +#include "os.h" +#include "mach-startup/launchd_fd.h" #include #include @@ -786,6 +789,7 @@ environment?", @"Startup xinitrc dialog"); void X11ApplicationMain (int argc, char **argv, char **envp) { NSAutoreleasePool *pool; + int launchd_fd; #ifdef DEBUG while (access ("/tmp/x11-block", F_OK) == 0) sleep (1); @@ -813,6 +817,14 @@ void X11ApplicationMain (int argc, char **argv, char **envp) { /* Tell the server thread that it can proceed */ QuartzInitServer(argc, argv, envp); + +#ifndef NEW_LAUNCH_METHOD + /* Start listening on the launchd fd */ + launchd_fd = launchd_display_fd(); + if(launchd_fd != -1) { + DarwinSendDDXEvent(kXquartzListenOnOpenFD, 1, launchd_fd); + } +#endif [NSApp run]; /* not reached */ diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index 7376c5796..06c5df048 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -45,6 +45,7 @@ in this Software without prior written authorization from The Open Group. #include "mi.h" #include "scrnintstr.h" #include "mipointer.h" +#include "os.h" #include "darwin.h" #include "quartz.h" @@ -214,6 +215,16 @@ static void DarwinSimulateMouseClick( DarwinUpdateModifiers(KeyPress, modifierMask); } +static void kXquartzListenOnOpenFDHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents) { + size_t i; + TA_SERVER(); + + for (i=0; i +#include +#include + +#include "launchd_fd.h" + +int launchd_display_fd() { + launch_data_t sockets_dict, checkin_request, checkin_response; + launch_data_t listening_fd_array, listening_fd; + + /* Get launchd fd */ + if ((checkin_request = launch_data_new_string(LAUNCH_KEY_CHECKIN)) == NULL) { + fprintf(stderr,"launch_data_new_string(\"" LAUNCH_KEY_CHECKIN "\") Unable to create string.\n"); + return ERROR_FD; + } + + if ((checkin_response = launch_msg(checkin_request)) == NULL) { + fprintf(stderr,"launch_msg(\"" LAUNCH_KEY_CHECKIN "\") IPC failure: %s\n",strerror(errno)); + return ERROR_FD; + } + + if (LAUNCH_DATA_ERRNO == launch_data_get_type(checkin_response)) { + // ignore EACCES, which is common if we weren't started by launchd + if (launch_data_get_errno(checkin_response) != EACCES) + fprintf(stderr,"launchd check-in failed: %s\n", strerror(launch_data_get_errno(checkin_response))); + return ERROR_FD; + } + + sockets_dict = launch_data_dict_lookup(checkin_response, LAUNCH_JOBKEY_SOCKETS); + if (NULL == sockets_dict) { + fprintf(stderr,"launchd check-in: no sockets found to answer requests on!\n"); + return ERROR_FD; + } + + if (launch_data_dict_get_count(sockets_dict) > 1) { + fprintf(stderr,"launchd check-in: some sockets will be ignored!\n"); + return ERROR_FD; + } + + listening_fd_array = launch_data_dict_lookup(sockets_dict, ":0"); + if (NULL == listening_fd_array) { + fprintf(stderr,"launchd check-in: No known sockets found to answer requests on!\n"); + return ERROR_FD; + } + + if (launch_data_array_get_count(listening_fd_array)!=1) { + fprintf(stderr,"launchd check-in: Expected 1 socket from launchd, got %u)\n", + (unsigned)launch_data_array_get_count(listening_fd_array)); + return ERROR_FD; + } + + listening_fd=launch_data_array_get_index(listening_fd_array, 0); + return launch_data_get_fd(listening_fd); +} diff --git a/hw/xquartz/mach-startup/launchd_fd.h b/hw/xquartz/mach-startup/launchd_fd.h new file mode 100644 index 000000000..5083fae21 --- /dev/null +++ b/hw/xquartz/mach-startup/launchd_fd.h @@ -0,0 +1,36 @@ +/* Copyright (c) 2008 Apple Inc. + * + * 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. + */ + +#ifndef _XQUARTZ_LAUNCHD_FD_H_ +#define _XQUARTZ_LAUNCHD_FD_H_ + +#define ERROR_FD -1 + +int launchd_display_fd(void); + +#endif /* _XQUARTZ_LAUNCHD_FD_H_ */ \ No newline at end of file diff --git a/hw/xquartz/quartzKeyboard.c b/hw/xquartz/quartzKeyboard.c index cc0c88959..b9d45cb21 100644 --- a/hw/xquartz/quartzKeyboard.c +++ b/hw/xquartz/quartzKeyboard.c @@ -904,7 +904,6 @@ void DarwinKeyboardInit(DeviceIntPtr pDev) { QuartzXkbUpdate(pDev); #else -#error FAIL assert( InitKeyboardDeviceStruct( (DevicePtr)pDev, &keySyms, keyInfo.modMap, QuartzBell, DarwinChangeKeyboardControl )); @@ -921,7 +920,6 @@ void DarwinKeyboardReloadHandler(int screenNum, xEventPtr xe, DeviceIntPtr pDev, #ifdef XQUARTZ_USE_XKB QuartzXkbUpdate(pDev); #else -#error FAIL if (pDev->key) { if (pDev->key->curKeySyms.map) xfree(pDev->key->curKeySyms.map); if (pDev->key->modifierKeyMap) xfree(pDev->key->modifierKeyMap); diff --git a/include/os.h b/include/os.h index 3d689478e..b6f7553f6 100644 --- a/include/os.h +++ b/include/os.h @@ -167,6 +167,10 @@ extern void MakeClientGrabImpervious(ClientPtr /*client*/); extern void MakeClientGrabPervious(ClientPtr /*client*/); +#ifdef XQUARTZ +extern void ListenOnOpenFD(int /* fd */); +#endif + extern void AvailableClientInput(ClientPtr /* client */); extern CARD32 GetTimeInMillis(void); diff --git a/os/connection.c b/os/connection.c index bd98f7416..d34cddd1e 100644 --- a/os/connection.c +++ b/os/connection.c @@ -1262,3 +1262,67 @@ MakeClientGrabPervious(ClientPtr client) } } +#ifdef XQUARTZ +/* Add a fd (from launchd) to our listeners */ +_X_EXPORT void ListenOnOpenFD(int fd) { + char port[20]; + XtransConnInfo ciptr, *ciptr2, *ciptr3; + int *iptr, *iptr2; + + /* Sigh for inconsistencies. */ + sprintf (port, ":%d", atoi(display)); + + /* Make our XtransConnInfo + * TRANS_SOCKET_LOCAL_INDEX = 5 from Xtrans.c + */ + ciptr = _XSERVTransReopenCOTSServer(5, fd, port); + if(ciptr == NULL) { + fprintf(stderr, "Got NULL while trying to Reopen launchd port.\n"); + return; + } + + /* Allocate space to store it */ + iptr = (int *) realloc(ListenTransFds, (ListenTransCount + 1) * sizeof (int)); + + if(!iptr) { + fprintf(stderr, "Memory allocation error"); + return; + } + + ciptr2 = (XtransConnInfo *) realloc(ListenTransConns, (ListenTransCount + 1) * sizeof (XtransConnInfo)); + if(!ciptr2) { + fprintf(stderr, "Memory allocation error"); + if(iptr != ListenTransFds) + free(ListenTransFds); + return; + } + + if(iptr != ListenTransFds) { + iptr2 = ListenTransFds; + ListenTransFds = iptr; + free(iptr2); + } + + if(ciptr2 != ListenTransConns) { + ciptr3 = ListenTransConns; + ListenTransConns = ciptr2; + free(ciptr3); + } + + /* Store it */ + ListenTransConns[ListenTransCount] = ciptr; + ListenTransFds[ListenTransCount] = fd; + + FD_SET(fd, &WellKnownConnections); + + /* It is always local + if (!_XSERVTransIsLocal(ciptr)) { + // DefineSelf (fd); + } + */ + + /* Increment the count */ + ListenTransCount++; +} + +#endif -- cgit v1.2.3