XQuartz: Added functionality to add a file descriptor to the connection list after the server is already running.

(cherry picked from commit 543c2cd68d1ffef65d4644b860faad7191c6b9da)
This commit is contained in:
Jeremy Huddleston 2008-05-17 14:56:53 -07:00
parent 01612fe612
commit 2408303d79
9 changed files with 224 additions and 11 deletions

View File

@ -38,12 +38,16 @@
#import "X11Application.h" #import "X11Application.h"
# include "darwin.h" #include "darwin.h"
# include "darwinEvents.h" #include "darwinEvents.h"
# include "quartz.h" #include "quartz.h"
# define _APPLEWM_SERVER_ #define _APPLEWM_SERVER_
# include "X11/extensions/applewm.h" #include "X11/extensions/applewm.h"
# include "micmap.h" #include "micmap.h"
#include "os.h"
#include "mach-startup/launchd_fd.h"
#include <mach/mach.h> #include <mach/mach.h>
#include <unistd.h> #include <unistd.h>
@ -783,6 +787,7 @@ environment?", @"Startup xinitrc dialog");
void X11ApplicationMain (int argc, char **argv, char **envp) { void X11ApplicationMain (int argc, char **argv, char **envp) {
NSAutoreleasePool *pool; NSAutoreleasePool *pool;
int launchd_fd;
#ifdef DEBUG #ifdef DEBUG
while (access ("/tmp/x11-block", F_OK) == 0) sleep (1); while (access ("/tmp/x11-block", F_OK) == 0) sleep (1);
@ -811,6 +816,14 @@ void X11ApplicationMain (int argc, char **argv, char **envp) {
/* Tell the server thread that it can proceed */ /* Tell the server thread that it can proceed */
QuartzInitServer(argc, argv, envp); 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]; [NSApp run];
/* not reached */ /* not reached */
} }

View File

@ -45,6 +45,7 @@ in this Software without prior written authorization from The Open Group.
#include "mi.h" #include "mi.h"
#include "scrnintstr.h" #include "scrnintstr.h"
#include "mipointer.h" #include "mipointer.h"
#include "os.h"
#include "darwin.h" #include "darwin.h"
#include "quartz.h" #include "quartz.h"
@ -214,6 +215,16 @@ static void DarwinSimulateMouseClick(
DarwinUpdateModifiers(KeyPress, modifierMask); DarwinUpdateModifiers(KeyPress, modifierMask);
} }
static void kXquartzListenOnOpenFDHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents) {
size_t i;
TA_SERVER();
for (i=0; i<nevents; i++) {
//sleep(20);
ListenOnOpenFD(xe[i].u.clientMessage.u.l.longs0);
}
}
/* Generic handler for Xquartz-specifc events. When possible, these should /* Generic handler for Xquartz-specifc events. When possible, these should
be moved into their own individual functions and set as handlers using be moved into their own individual functions and set as handlers using
mieqSetHandler. */ mieqSetHandler. */
@ -319,6 +330,7 @@ Bool DarwinEQInit(void) {
mieqSetHandler(kXquartzControllerNotify, DarwinEventHandler); mieqSetHandler(kXquartzControllerNotify, DarwinEventHandler);
mieqSetHandler(kXquartzPasteboardNotify, DarwinEventHandler); mieqSetHandler(kXquartzPasteboardNotify, DarwinEventHandler);
mieqSetHandler(kXquartzDisplayChanged, QuartzDisplayChangedHandler); mieqSetHandler(kXquartzDisplayChanged, QuartzDisplayChangedHandler);
mieqSetHandler(kXquartzListenOnOpenFD, kXquartzListenOnOpenFDHandler);
QuartzModeEQInit(); QuartzModeEQInit();

View File

@ -56,6 +56,7 @@ enum {
kXquartzToggleFullscreen, // Enable/Disable fullscreen mode kXquartzToggleFullscreen, // Enable/Disable fullscreen mode
kXquartzSetRootless, // Set rootless mode kXquartzSetRootless, // Set rootless mode
kXquartzSpaceChanged, // Spaces changed kXquartzSpaceChanged, // Spaces changed
kXquartzListenOnOpenFD, // Listen to the launchd fd (passed as arg)
/* /*
* AppleWM events * AppleWM events
*/ */

View File

@ -7,7 +7,8 @@ x11appdir = $(APPLE_APPLICATIONS_DIR)/X11.app/Contents/MacOS
x11app_PROGRAMS = X11 x11app_PROGRAMS = X11
dist_X11_SOURCES = \ dist_X11_SOURCES = \
bundle-main.c bundle-main.c \
launchd_fd.c
nodist_X11_SOURCES = \ nodist_X11_SOURCES = \
mach_startupServer.c \ mach_startupServer.c \
@ -33,7 +34,8 @@ X11_LDFLAGS = \
bin_PROGRAMS = Xquartz bin_PROGRAMS = Xquartz
dist_Xquartz_SOURCES = \ dist_Xquartz_SOURCES = \
stub.c stub.c \
launchd_fd.c
nodist_Xquartz_SOURCES = \ nodist_Xquartz_SOURCES = \
mach_startupUser.c mach_startupUser.c
@ -54,6 +56,7 @@ $(BUILT_SOURCES): mach_startup.defs
mig -sheader mach_startupServer.h mach_startup.defs mig -sheader mach_startupServer.h mach_startup.defs
EXTRA_DIST = \ EXTRA_DIST = \
launchd_fd.h \
mach_startup.defs \ mach_startup.defs \
mach_startup_types.h mach_startup_types.h

View File

@ -0,0 +1,82 @@
/* 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.
*/
#include <launch.h>
#include <stdio.h>
#include <errno.h>
#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);
}

View File

@ -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_ */

View File

@ -904,7 +904,6 @@ void DarwinKeyboardInit(DeviceIntPtr pDev) {
QuartzXkbUpdate(pDev); QuartzXkbUpdate(pDev);
#else #else
#error FAIL
assert( InitKeyboardDeviceStruct( (DevicePtr)pDev, &keySyms, assert( InitKeyboardDeviceStruct( (DevicePtr)pDev, &keySyms,
keyInfo.modMap, QuartzBell, keyInfo.modMap, QuartzBell,
DarwinChangeKeyboardControl )); DarwinChangeKeyboardControl ));
@ -921,7 +920,6 @@ void DarwinKeyboardReloadHandler(int screenNum, xEventPtr xe, DeviceIntPtr pDev,
#ifdef XQUARTZ_USE_XKB #ifdef XQUARTZ_USE_XKB
QuartzXkbUpdate(pDev); QuartzXkbUpdate(pDev);
#else #else
#error FAIL
if (pDev->key) { if (pDev->key) {
if (pDev->key->curKeySyms.map) xfree(pDev->key->curKeySyms.map); if (pDev->key->curKeySyms.map) xfree(pDev->key->curKeySyms.map);
if (pDev->key->modifierKeyMap) xfree(pDev->key->modifierKeyMap); if (pDev->key->modifierKeyMap) xfree(pDev->key->modifierKeyMap);

View File

@ -166,6 +166,10 @@ extern void MakeClientGrabImpervious(ClientPtr /*client*/);
extern void MakeClientGrabPervious(ClientPtr /*client*/); extern void MakeClientGrabPervious(ClientPtr /*client*/);
#ifdef XQUARTZ
extern void ListenOnOpenFD(int /* fd */);
#endif
extern void AvailableClientInput(ClientPtr /* client */); extern void AvailableClientInput(ClientPtr /* client */);
extern CARD32 GetTimeInMillis(void); extern CARD32 GetTimeInMillis(void);

View File

@ -1297,3 +1297,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