[AD] OSX Dead bootstrap fix

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


Please find below a patch to avoid the dead bootstrap issue as discussed on a.cc. It also cleans up the dock notification code, and allows command line apps (with SYSTEM_NONE) to run without the dock being notified at all (resulting in faster start-up times, and avoiding Dock crashes if apps start and terminate very quickly)

Pete
Index: src/macosx/main.m
===================================================================
RCS file: /cvsroot/alleg/allegro/src/macosx/main.m,v
retrieving revision 1.25
diff -u -b -r1.25 main.m
--- src/macosx/main.m   26 Jun 2005 14:50:51 -0000      1.25
+++ src/macosx/main.m   12 Jul 2005 18:18:48 -0000
@@ -37,18 +37,7 @@
 static int refresh_rate = 70;


-/* These are used to warn the dock about the application */
-typedef struct CPSProcessSerNum
-{
-   UInt32 lo;
-   UInt32 hi;
-} CPSProcessSerNum;
-
-extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn);
-extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
-extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn);
-
-
+int osx_bootstrap_ok(void);

 @implementation AllegroAppDelegate

@@ -156,6 +145,13 @@
 }


+/* Call the user main() */
+static void call_user_main(void) {
+   int (*real_main) (int, char*[]) =
+      (int (*) (int, char*[])) _mangled_main_address;
+   exit(real_main(__crt0_argc, __crt0_argv));
+}
+

 /* app_main:
  *  Thread dedicated to the user program; real main() gets called here.
@@ -163,11 +159,7 @@
 + (void)app_main: (id)arg
 {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- int (*real_main) (int, char*[]) = (int (*) (int, char*[])) _mangled_main_address;
-
-   /* Call the user main() */
-   exit(real_main(__crt0_argc, __crt0_argv));
-
+   call_user_main();
    [pool release];
 }

@@ -206,22 +198,15 @@
 {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
AllegroAppDelegate *app_delegate = [[AllegroAppDelegate alloc] init];
-   CPSProcessSerNum psn;
    NSMenu *menu;
    NSMenuItem *menu_item, *temp_item;

    __crt0_argc = argc;
    __crt0_argv = argv;

-   [NSApplication sharedApplication];
+   if (!osx_bootstrap_ok()) /* not safe to use NSApplication */
+      call_user_main();

- /* Tell the dock about us; the origins of this hack are unknown, but it's - * currently the only way to make a Cocoa app to work when started from a
-    * console.
-    */
-   if ((!CPSGetCurrentProcess(&psn)) &&
- (!CPSEnableForegroundOperation(&psn, 0x03, 0x3C, 0x2C, 0x1103)) &&
-       (!CPSSetFrontProcess(&psn)))
       [NSApplication sharedApplication];

    /* Creates a custom application menu */
Index: src/macosx/system.m
===================================================================
RCS file: /cvsroot/alleg/allegro/src/macosx/system.m,v
retrieving revision 1.28
diff -u -b -r1.28 system.m
--- src/macosx/system.m 26 Jun 2005 14:50:51 -0000      1.28
+++ src/macosx/system.m 12 Jul 2005 18:18:51 -0000
@@ -320,7 +320,53 @@
    [pool release];
 }

-
+/* osx_tell_dock:
+ * Tell the dock about us; the origins of this hack are unknown, but it's + * currently the only way to make a Cocoa app to work when started from a
+ * console.
+ * For the future, (10.3 and above) investigate TranformProcessType in the
+ * HIServices framework.
+ */
+static void osx_tell_dock(void)
+{
+  struct CPSProcessSerNum
+    {
+      UInt32 lo;
+      UInt32 hi;
+    } psn;
+  extern OSErr CPSGetCurrentProcess(struct CPSProcessSerNum *psn);
+ extern OSErr CPSEnableForegroundOperation(struct CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
+  extern OSErr CPSSetFrontProcess(struct CPSProcessSerNum *psn);
+
+  if ((!CPSGetCurrentProcess(&psn)) &&
+ (!CPSEnableForegroundOperation(&psn, 0x03, 0x3C, 0x2C, 0x1103)) &&
+      (!CPSSetFrontProcess(&psn)))
+    [NSApplication sharedApplication];
+}
+/* osx_bootstrap_ok:
+ * Check if the current bootstrap context is privilege. If it's not, we can't
+ *  use NSApplication, and instead have to go directly to main.
+ *  Returns 1 if ok, 0 if not.
+ */
+#include <CoreFoundation/CoreFoundation.h>
+#include <mach/mach_port.h>
+#include <servers/bootstrap.h>
+
+
+int osx_bootstrap_ok(void) {
+   static int _ok=-1;
+   mach_port_t bp;
+   kern_return_t ret;
+   CFMachPortRef cfport;
+   /* If have tested once, just return that answer */
+   if (_ok>=0) return _ok;
+   cfport = CFMachPortCreate(NULL, NULL, NULL, NULL);
+   task_get_bootstrap_port(mach_task_self(), &bp);
+   ret = bootstrap_register(bp, "bootstrap-ok-test",
+      CFMachPortGetPort(cfport));
+   _ok= (ret == KERN_SUCCESS) ? 1 : 0;
+   return _ok;
+}

 /* osx_sys_init:
  *  Initalizes the MacOS X system driver.
@@ -331,6 +377,15 @@
    AL_CONST char *exe_name;
    char resource_dir[1024];

+   /* If we're in
+    * the 'dead bootstrap' environment, the Mac
+    * driver won't work
+    */
+
+   if (!osx_bootstrap_ok()) {
+     return -1;
+   }
+
    /* Install emergency-exit signal handlers */
    old_sig_abrt = signal(SIGABRT, osx_signal_handler);
    old_sig_fpe  = signal(SIGFPE,  osx_signal_handler);
@@ -340,6 +395,8 @@
    old_sig_int  = signal(SIGINT,  osx_signal_handler);
    old_sig_quit = signal(SIGQUIT, osx_signal_handler);

+   osx_tell_dock();
+
    /* Get into bundle resource directory if appropriate */
    if (osx_bundle) {
       exe_name = [[osx_bundle executablePath] lossyCString];





Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/