Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
Make Cocoa_ShowMessageBox work in background threads.
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgenpt committed Apr 23, 2013
1 parent babe495 commit 25a7838
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 35 deletions.
48 changes: 42 additions & 6 deletions src/video/cocoa/SDL_cocoamessagebox.m
Expand Up @@ -32,6 +32,29 @@
#include "SDL_messagebox.h"
#include "SDL_cocoavideo.h"

@interface SDLMessageBoxPresenter : NSObject {
@public
NSInteger clicked;
}
@end

@implementation SDLMessageBoxPresenter
- (id)init
{
self = [super init];
if (self) {
clicked = -1;
}

return self;
}

- (void)showAlert:(NSAlert*)alert
{
clicked = [alert runModal];
}
@end


/* Display a Cocoa message box */
int
Expand All @@ -41,7 +64,7 @@

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

NSAlert* alert = [[NSAlert alloc] init];
NSAlert* alert = [[[NSAlert alloc] init] autorelease];

if (messageboxdata->flags & SDL_MESSAGEBOX_ERROR) {
[alert setAlertStyle:NSCriticalAlertStyle];
Expand All @@ -67,14 +90,27 @@
}
}

NSInteger clicked = [alert runModal];
clicked -= NSAlertFirstButtonReturn;
*buttonid = buttons[clicked].buttonid;
[alert release];
SDLMessageBoxPresenter* presenter = [[[SDLMessageBoxPresenter alloc] init] autorelease];

[presenter performSelectorOnMainThread:@selector(showAlert:)
withObject:alert
waitUntilDone:YES];

int returnValue = 0;
NSInteger clicked = presenter->clicked;
if (clicked >= NSAlertFirstButtonReturn)
{
clicked -= NSAlertFirstButtonReturn;
*buttonid = buttons[clicked].buttonid;
}
else
{
returnValue = SDL_SetError("Did not get a valid `clicked button' id: %d", clicked);
}

[pool release];

return 0;
return returnValue;
}

#endif /* SDL_VIDEO_DRIVER_COCOA */
Expand Down
103 changes: 74 additions & 29 deletions test/testmessage.c
Expand Up @@ -29,13 +29,67 @@ quit(int rc)
exit(rc);
}

static int
button_messagebox(void *eventNumber)
{
const SDL_MessageBoxButtonData buttons[] = {
{
SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT,
0,
"OK"
},{
SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT,
1,
"Cancel"
},
};

SDL_MessageBoxData data = {
SDL_MESSAGEBOX_INFORMATION,
NULL, // no parent window
"Custom MessageBox",
"This is a custom messagebox",
2,
buttons,
NULL // Default color scheme
};

int button = -1;
int success = 0;
if (eventNumber) {
data.message = "This is a custom messagebox from a background thread.";
}

success =SDL_ShowMessageBox(&data, &button);
if (success == -1) {
printf("Error Presenting MessageBox: %s\n", SDL_GetError());
if (eventNumber) {
SDL_UserEvent event;
event.type = (intptr_t)eventNumber;
SDL_PushEvent((SDL_Event*)&event);
return 1;
} else {
quit(2);
}
}
printf("Pressed button: %d, %s\n", button, button == 1 ? "Cancel" : "OK");

if (eventNumber) {
SDL_UserEvent event;
event.type = (intptr_t)eventNumber;
SDL_PushEvent((SDL_Event*)&event);
}

return 0;
}

int
main(int argc, char *argv[])
{
int success;

/* Load the SDL library */
if (SDL_Init(0) < 0) {
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
return (1);
}
Expand Down Expand Up @@ -78,36 +132,27 @@ main(int argc, char *argv[])
quit(1);
}

button_messagebox(NULL);

/* Technically this isn't a supported operation for the API, but it doesn't
* hurt for it to work.
*/
{
const SDL_MessageBoxButtonData buttons[] = {
{
SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT,
0,
"OK"
},{
SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT,
1,
"Cancel"
},
};

SDL_MessageBoxData data = {
SDL_MESSAGEBOX_INFORMATION,
NULL, // no parent window
"Custom MessageBox",
"This is a custom messagebox",
2,
buttons,
NULL // Default color scheme
};

int button = -1;
success = SDL_ShowMessageBox(&data, &button);
if (success == -1) {
printf("Error Presenting MessageBox: %s\n", SDL_GetError());
quit(2);
int status = 0;
SDL_Event event;
intptr_t eventNumber = SDL_RegisterEvents(1);
SDL_Thread* thread = SDL_CreateThread(&button_messagebox, "MessageBox", (void*)eventNumber);

while (SDL_WaitEvent(&event))
{
if (event.type == eventNumber) {
break;
}
}
printf("Pressed button: %d, %s\n", button, button == 1 ? "Cancel" : "OK");

SDL_WaitThread(thread, &status);

printf("Message box thread return %i\n", status);
}

SDL_Quit();
Expand Down

0 comments on commit 25a7838

Please sign in to comment.