In MacOSX, when drag'n'dropping a document on an SDL app, or double-clicking a
authorRyan C. Gordon
Thu, 11 Aug 2005 00:56:16 +0000
changeset 111339408f59a0f7
parent 1112 6ded3dd929f5
child 1114 242a35a85852
In MacOSX, when drag'n'dropping a document on an SDL app, or double-clicking a
document associated with the app, the document(s) are passed to SDL_main()
as if they were command line arguments. Otherwise, the command line is always
empty and there is no way for the app to recover this information.
src/main/macosx/SDLMain.m
     1.1 --- a/src/main/macosx/SDLMain.m	Wed Aug 10 14:30:53 2005 +0000
     1.2 +++ b/src/main/macosx/SDLMain.m	Thu Aug 11 00:56:16 2005 +0000
     1.3 @@ -32,6 +32,7 @@
     1.4  static int    gArgc;
     1.5  static char  **gArgv;
     1.6  static BOOL   gFinderLaunch;
     1.7 +static BOOL   gCalledAppMainline = FALSE;
     1.8  
     1.9  static NSString *getApplicationName(void)
    1.10  {
    1.11 @@ -226,6 +227,52 @@
    1.12  
    1.13  #endif
    1.14  
    1.15 +
    1.16 +/*
    1.17 + * Catch document open requests...this lets us notice files when the app
    1.18 + *  was launched by double-clicking a document, or when a document was
    1.19 + *  dragged/dropped on the app's icon. You need to have a
    1.20 + *  CFBundleDocumentsType section in your Info.plist to get this message,
    1.21 + *  apparently.
    1.22 + *
    1.23 + * Files are added to gArgv, so to the app, they'll look like command line
    1.24 + *  arguments. Previously, apps launched from the finder had nothing but
    1.25 + *  an argv[0].
    1.26 + *
    1.27 + * This message may be received multiple times to open several docs on launch.
    1.28 + *
    1.29 + * This message is ignored once the app's mainline has been called.
    1.30 + */
    1.31 +- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
    1.32 +{
    1.33 +    if (gCalledAppMainline)  /* app has started, ignore this document. */
    1.34 +        return FALSE;
    1.35 +
    1.36 +    unsigned buflen = [filename lengthOfBytesUsingEncoding:NSUTF8StringEncoding] + 1;
    1.37 +    char *arg = (char *) malloc(buflen);
    1.38 +    if (arg == NULL)
    1.39 +        return FALSE;
    1.40 +
    1.41 +    char **newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2));
    1.42 +    if (newargv == NULL)
    1.43 +    {
    1.44 +        free(arg);
    1.45 +        return FALSE;
    1.46 +    }
    1.47 +    gArgv = newargv;
    1.48 +
    1.49 +    BOOL rc = [filename getCString:arg maxLength:buflen encoding:NSUTF8StringEncoding];
    1.50 +    if (!rc)
    1.51 +        free(arg);
    1.52 +    else
    1.53 +    {
    1.54 +        gArgv[gArgc++] = arg;
    1.55 +        gArgv[gArgc] = NULL;
    1.56 +    }
    1.57 +    return rc;
    1.58 +}
    1.59 +
    1.60 +
    1.61  /* Called when the internal event loop has just started running */
    1.62  - (void) applicationDidFinishLaunching: (NSNotification *) note
    1.63  {
    1.64 @@ -240,6 +287,7 @@
    1.65  #endif
    1.66  
    1.67      /* Hand off to main application code */
    1.68 +    gCalledAppMainline = TRUE;
    1.69      status = SDL_main (gArgc, gArgv);
    1.70  
    1.71      /* We're done, thank you for playing */
    1.72 @@ -300,13 +348,19 @@
    1.73      /* Copy the arguments into a global variable */
    1.74      /* This is passed if we are launched by double-clicking */
    1.75      if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
    1.76 +        gArgv = (char **) malloc(sizeof (char *) * 2);
    1.77 +        gArgv[0] = argv[0];
    1.78 +        gArgv[1] = NULL;
    1.79          gArgc = 1;
    1.80          gFinderLaunch = YES;
    1.81      } else {
    1.82 +        int i;
    1.83          gArgc = argc;
    1.84 +        gArgv = (char **) malloc(sizeof (char *) * (argc+1));
    1.85 +        for (i = 0; i <= argc; i++)
    1.86 +            gArgv[i] = argv[i];
    1.87          gFinderLaunch = NO;
    1.88      }
    1.89 -    gArgv = argv;
    1.90  
    1.91  #if SDL_USE_NIB_FILE
    1.92      [SDLApplication poseAsClass:[NSApplication class]];