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/dpmsstubs-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/Xquartz
|
||||
hw/xquartz/doc/Xquartz.1
|
||||
|
|
|
@ -5,9 +5,13 @@ AM_CPPFLAGS = \
|
|||
x11appdir = $(APPLE_APPLICATIONS_DIR)/X11.app/Contents/MacOS
|
||||
x11app_PROGRAMS = X11
|
||||
|
||||
X11_SOURCES = \
|
||||
dist_X11_SOURCES = \
|
||||
bundle-main.c
|
||||
|
||||
nodist_X11_SOURCES = \
|
||||
mach_startupServer.c \
|
||||
mach_startupUser.c
|
||||
|
||||
X11_LDADD = \
|
||||
$(top_builddir)/hw/xquartz/libXquartz.la \
|
||||
$(top_builddir)/hw/xquartz/xpr/libXquartzXpr.la \
|
||||
|
@ -27,8 +31,28 @@ X11_LDFLAGS = \
|
|||
|
||||
bin_PROGRAMS = Xquartz
|
||||
|
||||
Xquartz_SOURCES = \
|
||||
dist_Xquartz_SOURCES = \
|
||||
stub.c
|
||||
|
||||
nodist_Xquartz_SOURCES = \
|
||||
mach_startupUser.c
|
||||
|
||||
Xquartz_LDFLAGS = \
|
||||
-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 <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.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_STARTX "/usr/X11/bin/startx"
|
||||
#define DEFAULT_SHELL "/bin/sh"
|
||||
|
@ -43,9 +50,143 @@
|
|||
static int execute(const char *command);
|
||||
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);
|
||||
|
||||
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) {
|
||||
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;
|
||||
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 */
|
||||
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
|
||||
|
|
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