xserver: Branch 'xorg-server-1.4-apple' - 5 commits

Jeremy Huddleston jeremyhu at kemper.freedesktop.org
Sat May 17 14:51:17 PDT 2008


 hw/xquartz/Makefile.am                    |    1 
 hw/xquartz/X11Application.m               |   27 ++-
 hw/xquartz/darwinEvents.c                 |   43 +++--
 hw/xquartz/darwinEvents.h                 |    2 
 hw/xquartz/mach-startup/Makefile.am       |   15 +
 hw/xquartz/mach-startup/bundle-main.c     |  250 ++++++++++++++++++------------
 hw/xquartz/mach-startup/launchd_fd.c      |   82 +++++++++
 hw/xquartz/mach-startup/launchd_fd.h      |   36 ++++
 hw/xquartz/mach-startup/mach_startup.defs |    7 
 hw/xquartz/mach-startup/stub.c            |   19 +-
 hw/xquartz/quartzKeyboard.c               |    4 
 include/os.h                              |    4 
 os/connection.c                           |   64 +++++++
 13 files changed, 427 insertions(+), 127 deletions(-)

New commits:
commit 301262b07024ad960f22d99a1267fe137f5c3fce
Author: Jeremy Huddleston <jeremyhu at freedesktop.org>
Date:   Sat May 17 14:51:09 2008 -0700

    XQuartz: Ok, pass XQUARTZ_USE_XKB since it breaks worse without it... but we have issues when we have the keyboard configs installed... need to figure out what to do there...

diff --git a/hw/xquartz/quartzKeyboard.c b/hw/xquartz/quartzKeyboard.c
index b9d45cb..c75cd1d 100644
--- a/hw/xquartz/quartzKeyboard.c
+++ b/hw/xquartz/quartzKeyboard.c
@@ -43,10 +43,7 @@
 // Define this to get a diagnostic output to stderr which is helpful
 // in determining how the X server is interpreting the Darwin keymap.
 #define DUMP_DARWIN_KEYMAP
-
-// This breaks when we actually install xkeyboard-config files to start using it
-// We need to serup keymaps in the configs or something...
-// #define XQUARTZ_USE_XKB 
+#define XQUARTZ_USE_XKB 
 #define HACK_MISSING 1
 #define HACK_KEYPAD 1
 
commit 27fbfeacfa16d620801ac3492b25c1e50aec8588
Author: Jeremy Huddleston <jeremyhu at freedesktop.org>
Date:   Thu May 15 12:26:32 2008 -0700

    XQuartz: More work towards Mach-IPC startup... started working on FD passing

diff --git a/hw/xquartz/Makefile.am b/hw/xquartz/Makefile.am
index 77d662f..cc39c9d 100644
--- a/hw/xquartz/Makefile.am
+++ b/hw/xquartz/Makefile.am
@@ -8,6 +8,7 @@ AM_CPPFLAGS = \
 	-DUSE_NEW_CLUT \
 	-DXFree86Server \
 	-I$(top_srcdir)/miext/rootless
+#	-DNEW_LAUNCH_METHOD
 
 SUBDIRS = bundle . GL xpr mach-startup doc
 
diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m
index 972187c..c2d3e6d 100644
--- a/hw/xquartz/X11Application.m
+++ b/hw/xquartz/X11Application.m
@@ -789,7 +789,6 @@ 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);
@@ -820,9 +819,9 @@ void X11ApplicationMain (int argc, char **argv, char **envp) {
     
 #ifndef NEW_LAUNCH_METHOD
     /* Start listening on the launchd fd */
-    launchd_fd = launchd_display_fd();
+    int launchd_fd = launchd_display_fd();
     if(launchd_fd != -1) {
-        DarwinSendDDXEvent(kXquartzListenOnOpenFD, 1, launchd_fd);
+        DarwinListenOnOpenFD(launchd_fd);
     }
 #endif
 
diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c
index 06c5df0..9ecebe4 100644
--- a/hw/xquartz/darwinEvents.c
+++ b/hw/xquartz/darwinEvents.c
@@ -551,6 +551,9 @@ void DarwinUpdateModKeys(int flags) {
 	old_flags = flags;
 }
 
+void DarwinListenOnOpenFD(int fd) {
+    DarwinSendDDXEvent(kXquartzListenOnOpenFD, 1, fd);
+}
 
 /*
  * DarwinSendDDXEvent
diff --git a/hw/xquartz/darwinEvents.h b/hw/xquartz/darwinEvents.h
index 58817fb..7a1e8ca 100644
--- a/hw/xquartz/darwinEvents.h
+++ b/hw/xquartz/darwinEvents.h
@@ -39,6 +39,7 @@ void DarwinSendKeyboardEvents(int ev_type, int keycode);
 void DarwinSendScrollEvents(float count_x, float count_y, int pointer_x, int pointer_y,
 			    float pressure, float tilt_x, float tilt_y);
 void DarwinUpdateModKeys(int flags);
+void DarwinListenOnOpenFD(int fd);
 
 /*
  * Special ddx events understood by the X server
diff --git a/hw/xquartz/mach-startup/Makefile.am b/hw/xquartz/mach-startup/Makefile.am
index 3ed1c1a..11f6ba6 100644
--- a/hw/xquartz/mach-startup/Makefile.am
+++ b/hw/xquartz/mach-startup/Makefile.am
@@ -10,9 +10,9 @@ dist_X11_SOURCES = \
 	bundle-main.c \
 	launchd_fd.c
 
-nodist_X11_SOURCES = \
-	mach_startupServer.c \
-	mach_startupUser.c
+#nodist_X11_SOURCES = \
+#	mach_startupServer.c \
+#	mach_startupUser.c
 
 X11_LDADD = \
 	$(top_builddir)/hw/xquartz/libXquartz.la \
@@ -34,11 +34,11 @@ X11_LDFLAGS =  \
 bin_PROGRAMS = Xquartz
 
 dist_Xquartz_SOURCES = \
-	stub.c \
-	launchd_fd.c
+	stub.c
+#	launchd_fd.c
 
-nodist_Xquartz_SOURCES = \
-	mach_startupUser.c
+#nodist_Xquartz_SOURCES = \
+#	mach_startupUser.c
 
 Xquartz_LDFLAGS =  \
 	-Wl,-framework,CoreServices
diff --git a/hw/xquartz/mach-startup/bundle-main.c b/hw/xquartz/mach-startup/bundle-main.c
index dd75f02..4ddd82f 100644
--- a/hw/xquartz/mach-startup/bundle-main.c
+++ b/hw/xquartz/mach-startup/bundle-main.c
@@ -28,6 +28,8 @@
  promote the sale, use or other dealings in this Software without
  prior written authorization. */
 
+#include <CoreFoundation/CoreFoundation.h>
+
 #include <X11/Xlib.h>
 #include <unistd.h>
 #include <stdio.h>
@@ -35,10 +37,8 @@
 #include <stdlib.h>
 #include <pthread.h>
 #include <stdbool.h>
-
-#include <CoreFoundation/CoreFoundation.h>
-
-#include <asl.h>
+#include <sys/socket.h>
+#include <sys/un.h>
 
 #include <mach/mach.h>
 #include <mach/mach_error.h>
@@ -56,6 +56,11 @@ static char *command_from_prefs(const char *key, const char *default_value);
 /* This is in quartzStartup.c */
 int server_main(int argc, char **argv, char **envp);
 
+static int execute(const char *command);
+static char *command_from_prefs(const char *key, const char *default_value);
+
+#ifdef NEW_LAUNCH_METHOD
+
 struct arg {
     int argc;
     char **argv;
@@ -69,39 +74,6 @@ union MaxMsgSize {
 	union __ReplyUnion__mach_startup_subsystem rep; 
 };
 
-kern_return_t do_start_x11_server(mach_port_t port, string_array_t argv,
-                                  mach_msg_type_number_t argvCnt,
-                                  string_array_t envp,
-                                  mach_msg_type_number_t envpCnt) {
-    /* And now back to char ** */
-    char **_argv = alloca((argvCnt + 1) * sizeof(char *));
-    char **_envp = alloca((envpCnt + 1) * sizeof(char *));
-    size_t i;
-
-    if(!_argv || !_envp) {
-        return KERN_FAILURE;
-    }
-
-    for(i=0; i < argvCnt; i++) {
-        _argv[i] = argv[i];
-    }
-    _argv[argvCnt] = NULL;
-
-    for(i=0; i < envpCnt; i++) {
-        _envp[i] = envp[i];
-    }
-    _envp[envpCnt] = NULL;
-    
-    if(server_main(argvCnt, _argv, _envp) == 0)
-        return KERN_SUCCESS;
-    else
-        return KERN_FAILURE;
-}
-
-kern_return_t do_exit(mach_port_t port, int value) {
-    exit(value);
-}
-
 static mach_port_t checkin_or_register(char *bname) {
     kern_return_t kr;
     mach_port_t mp;
@@ -147,71 +119,99 @@ static pthread_t create_thread(void *func, void *arg) {
     return tid;
 }
 
-/*** Main ***/
-static int execute(const char *command);
-static char *command_from_prefs(const char *key, const char *default_value);
+/*** $DISPLAY handoff ***/
+static char display_handoff_socket[PATH_MAX + 1];
 
-#ifdef NEW_LAUNCH_METHOD
-static void startup_trigger_thread(void *arg) {
-    struct arg args = *((struct arg *)arg);
-    free(arg);
-    startup_trigger(args.argc, args.argv, args.envp);
+kern_return_t do_get_display_handoff_socket(mach_port_t port, string_t filename) {
+    strlcpy(filename, display_handoff_socket, STRING_T_SIZE);
+    fprintf(stderr, "Telling him the filename is %s = %s\n", filename, display_handoff_socket);
+    return KERN_SUCCESS;
 }
 
-int main(int argc, char **argv, char **envp) {
-    Bool listen, listenOnly = FALSE;
-    int i;
-    mach_msg_size_t mxmsgsz = sizeof(union MaxMsgSize) + MAX_TRAILER_SIZE;
-    mach_port_t mp;
-    kern_return_t kr;
+/* From darwinEvents.c ... but don't want to pull in all the server cruft */
+void DarwinListenOnOpenFD(int fd);
 
-    fprintf(stderr, "X11.app: main(): argc=%d\n", argc);
-    for(i=1; i < argc; i++) {
-        fprintf(stderr, "\targv[%u] = %s\n", (unsigned)i, argv[i]);
-        if(!strcmp(argv[i], "--listenonly")) {
-            listenOnly = TRUE;
-        }
-    }
+static void accept_fd_handoff(int connectedSocket) {
+    int fd;
+    return;
+    DarwinListenOnOpenFD(fd);
+}
 
-    /* TODO: This should be unconditional once we figure out fd passing */
-    listen = (argc > 1 && argv[1][0] == ':') || listenOnly;
-    if(listen) {
-        mp = checkin_or_register(SERVER_BOOTSTRAP_NAME);
+/* This thread loops accepting incoming connections and handing off the file
+ * descriptor for the new connection to accept_fd_handoff()
+ */
+static void socket_handoff_thread(void *arg) {
+    struct sockaddr_un servaddr_un;
+    struct sockaddr *servaddr;
+    int handoff_fd;
+    int servaddr_len;
+    
+    /* Wipe ourselves clean */
+    memset (&servaddr_un, 0, sizeof (struct sockaddr_un));
+    
+    servaddr_un.sun_family  = AF_UNIX;
+    strcpy(servaddr_un.sun_path, display_handoff_socket);
+    servaddr = (struct sockaddr *) &servaddr_un;
+    servaddr_len = sizeof(struct sockaddr_un) - sizeof(servaddr_un.sun_path) + strlen(display_handoff_socket);
+    
+    handoff_fd = socket(AF_UNIX, SOCK_STREAM, 0);
+    if(handoff_fd == 0) {
+        fprintf(stderr, "Failed to create socket: %s - %s\n", display_handoff_socket, strerror(errno));
+        return;
+        exit(EXIT_FAILURE);
     }
-
-    /* Check if we need to do something other than listen, and make another
-     * thread handle it.
-     */
-    if(!listenOnly) {
-        struct arg *args = (struct arg*)malloc(sizeof(struct arg));
-        if(!args) {
-            fprintf(stderr, "Memory allocation error.\n");
-            return EXIT_FAILURE;
-        }
-
-        args->argc = argc;
-        args->argv = argv;
-        args->envp = envp;
-
-        create_thread(startup_trigger_thread, args);
+    
+    if(bind(handoff_fd, servaddr, servaddr_len) != 0) {
+        fprintf(stderr, "Failed to bind socket: %s - %s\n", display_handoff_socket, strerror(errno));
+        return;
+        exit(EXIT_FAILURE);
     }
-
-    /* TODO: This should actually fall through rather than be the else
-     *       case once we figure out how to get the stub to pass the
-     *       file descriptor.  For now, we only listen if we are explicitly
-     *       told to.
-     */
-    if(listen) {
-        /* Main event loop */
-        kr = mach_msg_server(mach_startup_server, mxmsgsz, mp, 0);
-        if (kr != KERN_SUCCESS) {
-            asl_log(NULL, NULL, ASL_LEVEL_ERR,
-                    "org.x.X11(mp): %s\n", mach_error_string(kr));
-            return EXIT_FAILURE;
+    
+    if(listen(handoff_fd, 10) != 0) {
+        fprintf(stderr, "Failed to listen to socket: %s - %s\n", display_handoff_socket, strerror(errno));
+        return;
+        exit(EXIT_FAILURE);
+    }
+    
+    while(true) {
+        int connectedSocket = accept(handoff_fd, NULL, NULL);
+        
+        if(connectedSocket == -1) {
+            fprintf(stderr, "Failed to accept incoming connection on socket: %s - %s\n", display_handoff_socket, strerror(errno));
+            continue;
         }
+        accept_fd_handoff(connectedSocket);    
     }
+}
 
-    return EXIT_SUCCESS;
+/*** Server Startup ***/
+kern_return_t do_start_x11_server(mach_port_t port, string_array_t argv,
+                                  mach_msg_type_number_t argvCnt,
+                                  string_array_t envp,
+                                  mach_msg_type_number_t envpCnt) {
+    /* And now back to char ** */
+    char **_argv = alloca((argvCnt + 1) * sizeof(char *));
+    char **_envp = alloca((envpCnt + 1) * sizeof(char *));
+    size_t i;
+    
+    if(!_argv || !_envp) {
+        return KERN_FAILURE;
+    }
+    
+    for(i=0; i < argvCnt; i++) {
+        _argv[i] = argv[i];
+    }
+    _argv[argvCnt] = NULL;
+    
+    for(i=0; i < envpCnt; i++) {
+        _envp[i] = envp[i];
+    }
+    _envp[envpCnt] = NULL;
+    
+    if(server_main(argvCnt, _argv, _envp) == 0)
+        return KERN_SUCCESS;
+    else
+        return KERN_FAILURE;
 }
 
 int startup_trigger(int argc, char **argv, char **envp) {
@@ -305,6 +305,72 @@ int main(int argc, char **argv, char **envp) {
     return execute(command_from_prefs("startx_script", DEFAULT_STARTX));
 }
 
+#ifdef NEW_LAUNCH_METHOD
+static void startup_trigger_thread(void *arg) {
+    struct arg args = *((struct arg *)arg);
+    free(arg);
+    startup_trigger(args.argc, args.argv, args.envp);
+}
+
+/*** Main ***/
+int main(int argc, char **argv, char **envp) {
+    Bool listenOnly = FALSE;
+    int i;
+    mach_msg_size_t mxmsgsz = sizeof(union MaxMsgSize) + MAX_TRAILER_SIZE;
+    mach_port_t mp;
+    kern_return_t kr;
+    
+    fprintf(stderr, "X11.app: main(): argc=%d\n", argc);
+    for(i=1; i < argc; i++) {
+        fprintf(stderr, "\targv[%u] = %s\n", (unsigned)i, argv[i]);
+        if(!strcmp(argv[i], "--listenonly")) {
+            listenOnly = TRUE;
+        }
+    }
+    
+    mp = checkin_or_register(SERVER_BOOTSTRAP_NAME);
+    if(mp == MACH_PORT_NULL) {
+        fprintf(stderr, "NULL mach service: %s", SERVER_BOOTSTRAP_NAME);
+        return EXIT_FAILURE;
+    }
+    
+    /* Figure out what our handoff socket will be
+     * TODO: cleanup on exit.
+     */
+    tmpnam(display_handoff_socket);
+    create_thread(socket_handoff_thread, NULL);
+    
+    fprintf(stderr, "Hi\n");
+    
+    /* Check if we need to do something other than listen, and make another
+     * thread handle it.
+     */
+    if(!listenOnly) {
+        struct arg *args = (struct arg*)malloc(sizeof(struct arg));
+        if(!args) {
+            fprintf(stderr, "Memory allocation error.\n");
+            return EXIT_FAILURE;
+        }
+        
+        args->argc = argc;
+        args->argv = argv;
+        args->envp = envp;
+        
+        create_thread(startup_trigger_thread, args);
+    }
+    
+    /* Main event loop */
+    fprintf(stderr, "Statrup coming...\n");
+    kr = mach_msg_server(mach_startup_server, mxmsgsz, mp, 0);
+    if (kr != KERN_SUCCESS) {
+        fprintf(stderr, "org.x.X11(mp): %s\n", mach_error_string(kr));
+        return EXIT_FAILURE;
+    }
+    
+    return EXIT_SUCCESS;
+}
+#endif
+    
 static int execute(const char *command) {
     const char *newargv[7];
     const char **s;
diff --git a/hw/xquartz/mach-startup/mach_startup.defs b/hw/xquartz/mach-startup/mach_startup.defs
index 83b31b7..05bdf56 100644
--- a/hw/xquartz/mach-startup/mach_startup.defs
+++ b/hw/xquartz/mach-startup/mach_startup.defs
@@ -33,9 +33,14 @@ import "mach_startup_types.h";
 subsystem mach_startup 1000;
 serverprefix do_;
 
-type string_array_t = array[] of c_string[1024];
+type string_t = c_string[1024];
+type string_array_t = array[] of string_t;
 
 routine start_x11_server(
 	port  : mach_port_t;
     argv  : string_array_t;
     envp  : string_array_t);
+
+routine get_display_handoff_socket(
+	port  : mach_port_t;
+    filename  : string_t);
diff --git a/hw/xquartz/mach-startup/stub.c b/hw/xquartz/mach-startup/stub.c
index c53ed53..5fdbad8 100644
--- a/hw/xquartz/mach-startup/stub.c
+++ b/hw/xquartz/mach-startup/stub.c
@@ -45,6 +45,8 @@
 #include <servers/bootstrap.h>
 #include "mach_startup.h"
 
+#include "launchd_fd.h"
+
 static char x11_path[PATH_MAX + 1];
 
 static void set_x11_path() {
@@ -109,13 +111,15 @@ static void set_x11_path() {
 #endif
 
 int main(int argc, char **argv, char **envp) {
-#ifdef NEW_LAUNCH_METHOD_2
+#ifdef NEW_LAUNCH_METHOD
     int envpc;
     kern_return_t kr;
     mach_port_t mp;
     string_array_t newenvp;
     string_array_t newargv;
     size_t i;
+    int launchd_fd;
+    string_t handoff_socket;
 #endif
 
     if(argc == 2 && !strcmp(argv[1], "-version")) {
@@ -125,7 +129,10 @@ int main(int argc, char **argv, char **envp) {
         return EXIT_SUCCESS;
     }
 
-#ifdef NEW_LAUNCH_METHOD_2
+#ifdef NEW_LAUNCH_METHOD
+    /* Get the $DISPLAY FD */
+    launchd_fd = launchd_display_fd();
+
     kr = bootstrap_look_up(bootstrap_port, SERVER_BOOTSTRAP_NAME, &mp);
     if(kr != KERN_SUCCESS) {
         set_x11_path();
@@ -147,7 +154,7 @@ int main(int argc, char **argv, char **envp) {
         }
 
         /* Try connecting for 10 seconds */
-        for(i=0; i < 40; i++) {
+        for(i=0; i < 80; i++) {
             usleep(250000);
             kr = bootstrap_look_up(bootstrap_port, SERVER_BOOTSTRAP_NAME, &mp);
             if(kr == KERN_SUCCESS)
@@ -159,6 +166,12 @@ int main(int argc, char **argv, char **envp) {
             return EXIT_FAILURE;
         }
     }
+    
+    /* Handoff the $DISPLAY FD */
+    if(launchd_fd != -1) {
+        get_display_handoff_socket(mp, handoff_socket);
+        fprintf(stderr, "Handoff socket: %s %d\n", handoff_socket, launchd_fd);
+    }
 
     /* Count envp */
     for(envpc=0; envp[envpc]; envpc++);
commit 543c2cd68d1ffef65d4644b860faad7191c6b9da
Author: Jeremy Huddleston <jeremyhu at freedesktop.org>
Date:   Thu May 15 09:55:17 2008 -0700

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

diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m
index 546ea0c..972187c 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 <mach/mach.h>
 #include <unistd.h>
@@ -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 7376c57..06c5df0 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<nevents; i++) {
+        //sleep(20);
+        ListenOnOpenFD(xe[i].u.clientMessage.u.l.longs0);
+    }
+}
+
 /* Generic handler for Xquartz-specifc events.  When possible, these should
    be moved into their own individual functions and set as handlers using
    mieqSetHandler. */
@@ -319,7 +330,8 @@ Bool DarwinEQInit(void) {
     mieqSetHandler(kXquartzControllerNotify, DarwinEventHandler);
     mieqSetHandler(kXquartzPasteboardNotify, DarwinEventHandler);
     mieqSetHandler(kXquartzDisplayChanged, QuartzDisplayChangedHandler);
-
+    mieqSetHandler(kXquartzListenOnOpenFD, kXquartzListenOnOpenFDHandler);
+    
     QuartzModeEQInit();
 
     if (!darwinEvents)
diff --git a/hw/xquartz/darwinEvents.h b/hw/xquartz/darwinEvents.h
index a676aeb..58817fb 100644
--- a/hw/xquartz/darwinEvents.h
+++ b/hw/xquartz/darwinEvents.h
@@ -56,6 +56,7 @@ enum {
     kXquartzToggleFullscreen, // Enable/Disable fullscreen mode
     kXquartzSetRootless,      // Set rootless mode
     kXquartzSpaceChanged,     // Spaces changed
+    kXquartzListenOnOpenFD,   // Listen to the launchd fd (passed as arg)
     /*
      * AppleWM events
      */
diff --git a/hw/xquartz/mach-startup/Makefile.am b/hw/xquartz/mach-startup/Makefile.am
index d81caa9..3ed1c1a 100644
--- a/hw/xquartz/mach-startup/Makefile.am
+++ b/hw/xquartz/mach-startup/Makefile.am
@@ -7,7 +7,8 @@ x11appdir = $(APPLE_APPLICATIONS_DIR)/X11.app/Contents/MacOS
 x11app_PROGRAMS = X11
 
 dist_X11_SOURCES = \
-	bundle-main.c
+	bundle-main.c \
+	launchd_fd.c
 
 nodist_X11_SOURCES = \
 	mach_startupServer.c \
@@ -33,7 +34,8 @@ X11_LDFLAGS =  \
 bin_PROGRAMS = Xquartz
 
 dist_Xquartz_SOURCES = \
-	stub.c
+	stub.c \
+	launchd_fd.c
 
 nodist_Xquartz_SOURCES = \
 	mach_startupUser.c
@@ -54,6 +56,7 @@ $(BUILT_SOURCES): mach_startup.defs
 	mig -sheader mach_startupServer.h mach_startup.defs
 
 EXTRA_DIST = \
+	launchd_fd.h \
 	mach_startup.defs \
 	mach_startup_types.h
 
diff --git a/hw/xquartz/mach-startup/launchd_fd.c b/hw/xquartz/mach-startup/launchd_fd.c
new file mode 100644
index 0000000..44a243a
--- /dev/null
+++ b/hw/xquartz/mach-startup/launchd_fd.c
@@ -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);
+}
diff --git a/hw/xquartz/mach-startup/launchd_fd.h b/hw/xquartz/mach-startup/launchd_fd.h
new file mode 100644
index 0000000..5083fae
--- /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 cc0c889..b9d45cb 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 3d68947..b6f7553 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 bd98f74..d34cddd 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
commit c28fecc621b1803a4d4536afbc724d141de9e6ee
Author: Jeremy Huddleston <jeremyhu at freedesktop.org>
Date:   Thu May 15 07:08:21 2008 -0700

    XQuartz: Disable xkb since it doesn't work after getting xkeyboard-config installed
    
    Need to setup configs for the quartz keyboard

diff --git a/hw/xquartz/quartzKeyboard.c b/hw/xquartz/quartzKeyboard.c
index 698f39a..cc0c889 100644
--- a/hw/xquartz/quartzKeyboard.c
+++ b/hw/xquartz/quartzKeyboard.c
@@ -43,7 +43,10 @@
 // Define this to get a diagnostic output to stderr which is helpful
 // in determining how the X server is interpreting the Darwin keymap.
 #define DUMP_DARWIN_KEYMAP
-#define XQUARTZ_USE_XKB
+
+// This breaks when we actually install xkeyboard-config files to start using it
+// We need to serup keymaps in the configs or something...
+// #define XQUARTZ_USE_XKB 
 #define HACK_MISSING 1
 #define HACK_KEYPAD 1
 
commit 5626b0949b1a6bdd2fa3ec2ef53a688084349b87
Author: Jeremy Huddleston <jeremyhu at freedesktop.org>
Date:   Thu May 15 05:49:43 2008 -0700

    XQuartz: Made DarwinSendDDXEvent a little more robust to context switching diring server init.

diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m
index 36b73cd..546ea0c 100644
--- a/hw/xquartz/X11Application.m
+++ b/hw/xquartz/X11Application.m
@@ -59,11 +59,9 @@
 int X11EnableKeyEquivalents = TRUE;
 int quartzHasRoot = FALSE, quartzEnableRootless = TRUE;
 
-extern int darwinFakeButtons, input_check_flag;
+extern int darwinFakeButtons;
 extern Bool enable_stereo;
 
-extern xEvent *darwinEvents;
-
 X11Application *X11App;
 
 #define ALL_KEY_MASKS (NSShiftKeyMask | NSControlKeyMask | NSAlternateKeyMask | NSCommandKeyMask)
diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c
index 1547094..7376c57 100644
--- a/hw/xquartz/darwinEvents.c
+++ b/hw/xquartz/darwinEvents.c
@@ -76,12 +76,10 @@ in this Software without prior written authorization from The Open Group.
 /* FIXME: Abstract this better */
 void QuartzModeEQInit(void);
 
-int input_check_zero, input_check_flag;
-
 static int old_flags = 0;  // last known modifier state
 
-xEvent *darwinEvents = NULL;
-pthread_mutex_t darwinEvents_mutex = PTHREAD_MUTEX_INITIALIZER;
+static xEvent *darwinEvents = NULL;
+static pthread_mutex_t darwinEvents_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 static inline void darwinEvents_lock(void) {
     int err;
@@ -307,11 +305,6 @@ static void DarwinEventHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, in
 }
 
 Bool DarwinEQInit(void) { 
-    if (!darwinEvents)
-        darwinEvents = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum());
-    if (!darwinEvents)
-        FatalError("Couldn't allocate event buffer\n");
-
     mieqInit();
     mieqSetHandler(kXquartzReloadKeymap, DarwinKeyboardReloadHandler);
     mieqSetHandler(kXquartzActivate, DarwinEventHandler);
@@ -328,6 +321,11 @@ Bool DarwinEQInit(void) {
     mieqSetHandler(kXquartzDisplayChanged, QuartzDisplayChangedHandler);
 
     QuartzModeEQInit();
+
+    if (!darwinEvents)
+        darwinEvents = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum());
+    if (!darwinEvents)
+        FatalError("Couldn't allocate event buffer\n");
     
     return TRUE;
 }
@@ -354,7 +352,6 @@ void ProcessInputEvents(void) {
    Dispatch() event loop to check out event queue */
 static void DarwinPokeEQ(void) {
 	char nullbyte=0;
-	input_check_flag++;
 	//  <daniels> oh, i ... er ... christ.
 	write(darwinEventWriteFD, &nullbyte, 1);
 }
@@ -567,8 +564,13 @@ void DarwinSendDDXEvent(int type, int argc, ...) {
         va_end (args);
     }
 
-    darwinEvents_lock();
+    /* If we're called from something other than the X server thread, we need
+     * to wait for the X server to setup darwinEvents.
+     */
+    while(darwinEvents == NULL) {
+        usleep(250000);
+    }
+
     mieqEnqueue(darwinPointer, &xe);
     DarwinPokeEQ();
-    darwinEvents_unlock();
 }


More information about the xorg-commit mailing list