XQuartz: Starting to work on the new Mach IPC startup stuff for better launchd, ApplicationServices, and Dock support
(cherry picked from commit 9b67fca9b7
)
This commit is contained in:
parent
e2431ff488
commit
6cb8900736
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -276,6 +276,10 @@ hw/xprint/doc/Xprt.1x
|
||||||
hw/xprint/doc/Xprt.man
|
hw/xprint/doc/Xprt.man
|
||||||
hw/xprint/dpmsstubs-wrapper.c
|
hw/xprint/dpmsstubs-wrapper.c
|
||||||
hw/xprint/miinitext-wrapper.c
|
hw/xprint/miinitext-wrapper.c
|
||||||
|
hw/xquartz/mach-startup/mach_startup.h
|
||||||
|
hw/xquartz/mach-startup/mach_startupServer.c
|
||||||
|
hw/xquartz/mach-startup/mach_startupServer.h
|
||||||
|
hw/xquartz/mach-startup/mach_startupUser.c
|
||||||
hw/xquartz/mach-startup/X11
|
hw/xquartz/mach-startup/X11
|
||||||
hw/xquartz/mach-startup/Xquartz
|
hw/xquartz/mach-startup/Xquartz
|
||||||
hw/xquartz/doc/Xquartz.1
|
hw/xquartz/doc/Xquartz.1
|
||||||
|
|
|
@ -5,9 +5,13 @@ AM_CPPFLAGS = \
|
||||||
x11appdir = $(APPLE_APPLICATIONS_DIR)/X11.app/Contents/MacOS
|
x11appdir = $(APPLE_APPLICATIONS_DIR)/X11.app/Contents/MacOS
|
||||||
x11app_PROGRAMS = X11
|
x11app_PROGRAMS = X11
|
||||||
|
|
||||||
X11_SOURCES = \
|
dist_X11_SOURCES = \
|
||||||
bundle-main.c
|
bundle-main.c
|
||||||
|
|
||||||
|
nodist_X11_SOURCES = \
|
||||||
|
mach_startupServer.c \
|
||||||
|
mach_startupUser.c
|
||||||
|
|
||||||
X11_LDADD = \
|
X11_LDADD = \
|
||||||
$(top_builddir)/hw/xquartz/libXquartz.la \
|
$(top_builddir)/hw/xquartz/libXquartz.la \
|
||||||
$(top_builddir)/hw/xquartz/xpr/libXquartzXpr.la \
|
$(top_builddir)/hw/xquartz/xpr/libXquartzXpr.la \
|
||||||
|
@ -27,8 +31,28 @@ X11_LDFLAGS = \
|
||||||
|
|
||||||
bin_PROGRAMS = Xquartz
|
bin_PROGRAMS = Xquartz
|
||||||
|
|
||||||
Xquartz_SOURCES = \
|
dist_Xquartz_SOURCES = \
|
||||||
stub.c
|
stub.c
|
||||||
|
|
||||||
|
nodist_Xquartz_SOURCES = \
|
||||||
|
mach_startupUser.c
|
||||||
|
|
||||||
Xquartz_LDFLAGS = \
|
Xquartz_LDFLAGS = \
|
||||||
-Wl,-framework,CoreServices
|
-Wl,-framework,CoreServices
|
||||||
|
|
||||||
|
BUILT_SOURCES = \
|
||||||
|
mach_startupServer.c \
|
||||||
|
mach_startupUser.c \
|
||||||
|
mach_startupServer.h \
|
||||||
|
mach_startup.h
|
||||||
|
|
||||||
|
CLEANFILES = \
|
||||||
|
$(BUILT_SOURCES)
|
||||||
|
|
||||||
|
$(BUILT_SOURCES): mach_startup.defs
|
||||||
|
mig -sheader mach_startupServer.h mach_startup.defs
|
||||||
|
|
||||||
|
EXTRA_DIST = \
|
||||||
|
mach_startup.defs \
|
||||||
|
mach_startup_types.h
|
||||||
|
|
||||||
|
|
|
@ -33,9 +33,16 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#include <CoreFoundation/CoreFoundation.h>
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
|
|
||||||
|
#include <mach/mach.h>
|
||||||
|
#include <mach/mach_error.h>
|
||||||
|
#include <servers/bootstrap.h>
|
||||||
|
#include "mach_startup.h"
|
||||||
|
#include "mach_startupServer.h"
|
||||||
|
|
||||||
#define DEFAULT_CLIENT "/usr/X11/bin/xterm"
|
#define DEFAULT_CLIENT "/usr/X11/bin/xterm"
|
||||||
#define DEFAULT_STARTX "/usr/X11/bin/startx"
|
#define DEFAULT_STARTX "/usr/X11/bin/startx"
|
||||||
#define DEFAULT_SHELL "/bin/sh"
|
#define DEFAULT_SHELL "/bin/sh"
|
||||||
|
@ -43,9 +50,143 @@
|
||||||
static int execute(const char *command);
|
static int execute(const char *command);
|
||||||
static char *command_from_prefs(const char *key, const char *default_value);
|
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);
|
int server_main(int argc, char **argv, char **envp);
|
||||||
|
|
||||||
|
struct arg {
|
||||||
|
int argc;
|
||||||
|
char **argv;
|
||||||
|
char **envp;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*** Mach-O IPC Stuffs ***/
|
||||||
|
|
||||||
|
union MaxMsgSize {
|
||||||
|
union __RequestUnion__mach_startup_subsystem req;
|
||||||
|
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) {
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* If we're started by launchd or the old mach_init */
|
||||||
|
kr = bootstrap_check_in(bootstrap_port, bname, &mp);
|
||||||
|
if (kr == KERN_SUCCESS)
|
||||||
|
return mp;
|
||||||
|
|
||||||
|
/* We probably were not started by launchd or the old mach_init */
|
||||||
|
kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &mp);
|
||||||
|
if (kr != KERN_SUCCESS) {
|
||||||
|
fprintf(stderr, "mach_port_allocate(): %s\n", mach_error_string(kr));
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
kr = mach_port_insert_right(mach_task_self(), mp, mp, MACH_MSG_TYPE_MAKE_SEND);
|
||||||
|
if (kr != KERN_SUCCESS) {
|
||||||
|
fprintf(stderr, "mach_port_insert_right(): %s\n", mach_error_string(kr));
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
kr = bootstrap_register(bootstrap_port, bname, mp);
|
||||||
|
if (kr != KERN_SUCCESS) {
|
||||||
|
fprintf(stderr, "bootstrap_register(): %s\n", mach_error_string(kr));
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** Pthread Magics ***/
|
||||||
|
static pthread_t create_thread(void *func, void *arg) {
|
||||||
|
pthread_attr_t attr;
|
||||||
|
pthread_t tid;
|
||||||
|
|
||||||
|
pthread_attr_init (&attr);
|
||||||
|
pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM);
|
||||||
|
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
|
||||||
|
pthread_create (&tid, &attr, func, arg);
|
||||||
|
pthread_attr_destroy (&attr);
|
||||||
|
|
||||||
|
return tid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** Main ***/
|
||||||
|
static int execute(const char *command);
|
||||||
|
static char *command_from_prefs(const char *key, const char *default_value);
|
||||||
|
|
||||||
|
#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);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv, char **envp) {
|
int main(int argc, char **argv, char **envp) {
|
||||||
|
BOOL listenOnly = FALSE;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i=1; i < argc; i++) {
|
||||||
|
if(!strcmp(argv[i], "--listenonly")) {
|
||||||
|
listenOnly = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
FatalError("Could not allocate memory.\n");
|
||||||
|
|
||||||
|
args->argc = argc;
|
||||||
|
args->argv = argv;
|
||||||
|
args->envp = envp;
|
||||||
|
|
||||||
|
create_thread(startup_trigger_thread, args);
|
||||||
|
} else {
|
||||||
|
/* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
mach_msg_size_t mxmsgsz = sizeof(union MaxMsgSize) + MAX_TRAILER_SIZE;
|
||||||
|
mach_port_t mp = checkin_or_register(SERVER_BOOTSTRAP_NAME);
|
||||||
|
kern_return_t kr;
|
||||||
|
|
||||||
|
/* 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));
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int startup_trigger(int argc, char **argv, char **envp) {
|
||||||
|
#else
|
||||||
|
int main(int argc, char **argv, char **envp) {
|
||||||
|
#endif
|
||||||
Display *display;
|
Display *display;
|
||||||
const char *s;
|
const char *s;
|
||||||
|
|
||||||
|
@ -57,7 +198,15 @@ int main(int argc, char **argv, char **envp) {
|
||||||
|
|
||||||
/* Take care of the case where we're called like a normal DDX */
|
/* Take care of the case where we're called like a normal DDX */
|
||||||
if(argc > 1 && argv[1][0] == ':') {
|
if(argc > 1 && argv[1][0] == ':') {
|
||||||
exit(server_main(argc, argv, envp));
|
#ifdef NEW_LAUNCH_METHOD
|
||||||
|
/* We need to count envp */
|
||||||
|
int envpc;
|
||||||
|
for(envpc=0; envp[envpc]; envpc++);
|
||||||
|
|
||||||
|
return start_x11_server(argc, argv, envp, envpc);
|
||||||
|
#else
|
||||||
|
return server_main(argc, argv, envp);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we have a process serial number and it's our only arg, act as if
|
/* If we have a process serial number and it's our only arg, act as if
|
||||||
|
|
41
hw/xquartz/mach-startup/mach_startup.defs
Normal file
41
hw/xquartz/mach-startup/mach_startup.defs
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/* 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 <mach/std_types.defs>
|
||||||
|
#include <mach/mach_types.defs>
|
||||||
|
import "mach_startup_types.h";
|
||||||
|
|
||||||
|
subsystem mach_startup 1000;
|
||||||
|
serverprefix do_;
|
||||||
|
|
||||||
|
type string_array_t = array[] of c_string[1024];
|
||||||
|
|
||||||
|
routine start_x11_server(
|
||||||
|
port : mach_port_t;
|
||||||
|
argv : string_array_t;
|
||||||
|
envp : string_array_t);
|
8
hw/xquartz/mach-startup/mach_startup_types.h
Normal file
8
hw/xquartz/mach-startup/mach_startup_types.h
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef _MACH_STARTUP_TYPES_H_
|
||||||
|
#define _MACH_STARTUP_TYPES_H_
|
||||||
|
|
||||||
|
#define SERVER_BOOTSTRAP_NAME "org.x.X11"
|
||||||
|
|
||||||
|
typedef char ** string_array_t;
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user