diff options
-rw-r--r-- | doc/canvas.n | 1 | ||||
-rw-r--r-- | library/tk.tcl | 23 | ||||
-rw-r--r-- | sdl/SdlTkInt.h | 3 | ||||
-rw-r--r-- | sdl/SdlTkUtils.c | 5 | ||||
-rw-r--r-- | sdl/SdlTkX.c | 80 | ||||
-rw-r--r-- | sdl/tkAppInit.c | 55 |
6 files changed, 148 insertions, 19 deletions
diff --git a/doc/canvas.n b/doc/canvas.n index 6d22f27..5b65283 100644 --- a/doc/canvas.n +++ b/doc/canvas.n @@ -555,6 +555,7 @@ which may not be the order originally given. Also the coordinates are always returned in screen units with no units (that is, in pixels). So if the original coordinates were specified for instance in centimeters or inches, the returned values will nevertheless be in pixels. +.RE .TP \fIpathName \fBcreate \fItype x y \fR?\fIx y ...\fR? ?\fIoption value ...\fR? .TP diff --git a/library/tk.tcl b/library/tk.tcl index 5d8a670..9f04658 100644 --- a/library/tk.tcl +++ b/library/tk.tcl @@ -492,6 +492,20 @@ switch -exact -- [tk windowingsystem] { } # ---------------------------------------------------------------------- +# Setup flags/vars for SDL, screen dpi, and Android. +# ---------------------------------------------------------------------- + +namespace eval ::tk { + variable sdltk [expr {[info command "sdltk"] eq "sdltk"}] + variable dpi + set dpi [expr int((25.4 * [winfo screenwidth .]) / [winfo screenmmwidth .])] + variable android 0 + if {$sdltk} { + set android [sdltk android] + } +} + +# ---------------------------------------------------------------------- # Read in files that define all of the class bindings. # ---------------------------------------------------------------------- @@ -500,12 +514,7 @@ if {$::tk_library ne ""} { namespace eval :: [list source [file join $::tk_library $file.tcl]] } namespace eval ::tk { - variable sdltk [expr {[info command "sdltk"] eq "sdltk"}] - variable dpi - set dpi [expr int((25.4 * [winfo screenwidth .]) / [winfo screenmmwidth .])] - variable android 0 if {$sdltk} { - set android [sdltk android] if {$dpi < 140} { SourceLibFile icons } elseif {$dpi < 240} { @@ -702,9 +711,9 @@ if {[tk windowingsystem] eq "aqua"} { } } -if {[info command "sdltk"] eq "sdltk"} { +if {$::tk::sdltk} { # Android hardware keyboard handling - if {[sdltk android]} { + if {$::tk::android} { if {[package versions Borg] ne {}} { package require Borg } diff --git a/sdl/SdlTkInt.h b/sdl/SdlTkInt.h index b8f3cb0..941c6be 100644 --- a/sdl/SdlTkInt.h +++ b/sdl/SdlTkInt.h @@ -355,6 +355,9 @@ extern void SdlTkGLXReleaseCurrent(Display *display, Window w, void *ctx); extern void SdlTkGLXSwapBuffers(Display *display, Window w); #endif extern void SdlTkDumpXEvent(XEvent *eventPtr); +#ifdef __APPLE__ +extern void SdlTkEventThread(void); +#endif /* SdlTkAGG.c */ extern void SdlTkGfxDrawArc(Drawable d, GC gc, int x, int y, diff --git a/sdl/SdlTkUtils.c b/sdl/SdlTkUtils.c index bafb3e2..245b92c 100644 --- a/sdl/SdlTkUtils.c +++ b/sdl/SdlTkUtils.c @@ -1100,6 +1100,11 @@ SdlTkFontInit(Tcl_Interp *interp) #ifdef __HAIKU__ "[glob -nocomplain -directory /system/data/fonts" " -types f */*.ttf */*.ttc */*.otf]", +#elif defined(__APPLE__) + "[glob -nocomplain -directory /Library/Fonts" + " -types f *.ttf *.ttc *.otf] " + "[glob -nocomplain -directory /System/Library/Fonts" + " -types f *.ttf *.ttc *.otf]", #else "[glob -nocomplain -directory /usr/share/fonts" " -types f */*.ttf */*.ttc */*.otf] " diff --git a/sdl/SdlTkX.c b/sdl/SdlTkX.c index 6ff519c..39a0657 100644 --- a/sdl/SdlTkX.c +++ b/sdl/SdlTkX.c @@ -99,6 +99,9 @@ static Tcl_Condition xlib_cond; static Tcl_Condition time_cond; static int timer_enabled = 0; static int num_displays = 0; +#ifdef __APPLE__ +struct EventThreadStartup evt_startup = { 0, NULL, NULL }; +#endif static void SdlTkDestroyWindow(Display *display, Window w); static void SdlTkMapWindow(Display *display, Window w); @@ -145,6 +148,12 @@ SdlTkWaitVSync(void) Tcl_ConditionWait(&time_cond, &xlib_lock, NULL); } +static void +SdlTkNotify(void) +{ + Tcl_ConditionNotify(&xlib_cond); +} + /* * Undocumented Xlib internal function */ @@ -621,7 +630,7 @@ XCloseDisplay(Display *display) } xlib_grab = NULL; - Tcl_ConditionNotify(&xlib_cond); + SdlTkNotify(); SdlTkUnlock(display); memset(display, 0, sizeof (Display)); @@ -4500,7 +4509,7 @@ HandlePanZoom(struct PanZoomRequest *pz) done: if (pz->running) { pz->running = 0; - Tcl_ConditionNotify(&xlib_cond); + SdlTkNotify(); } return ret; } @@ -4741,7 +4750,7 @@ HandleRootSize(struct RootSizeRequest *r) done: if (r->running) { r->running = 0; - Tcl_ConditionNotify(&xlib_cond); + SdlTkNotify(); } } @@ -4859,7 +4868,7 @@ HandleWindowFlags(struct WindowFlagsRequest *r) done: if (r->running) { r->running = 0; - Tcl_ConditionNotify(&xlib_cond); + SdlTkNotify(); } } #endif @@ -5387,6 +5396,12 @@ retry: goto fatal; } #ifndef ANDROID +#ifdef __APPLE__ + /* + * Do not create a GL context here, otherwise something internal + * to SDL2 goes terribly wrong that the root remains black. + */ +#else if (!SdlTkX.arg_nogl) { /* check for OpenGL >= 2.x, otherwise fall back to SW renderer */ int glvernum = -1; @@ -5457,6 +5472,7 @@ ctxRetry: SdlTkX.arg_nogl = (glvernum < 1) || !hasFBO; #endif } +#endif if (pfmt->BitsPerPixel == 15) { tfmt = SDL_PIXELFORMAT_RGB555; } else if (pfmt->BitsPerPixel == 16) { @@ -5875,8 +5891,13 @@ ctxRetry: *---------------------------------------------------------------------- */ +#ifdef __APPLE__ +void +SdlTkEventThread(void) +#else static Tcl_ThreadCreateType EventThread(ClientData clientData) +#endif { SDL_Event sdl_event; XEvent event; @@ -5890,16 +5911,28 @@ EventThread(ClientData clientData) Uint16 rate, Uint16 delay); extern int SDL_SendKeyboardText(const char *text); #endif +#ifdef __APPLE__ + struct EventThreadStartup *evs = &evt_startup; +#else struct EventThreadStartup *evs = (struct EventThreadStartup *) clientData; +#endif EVLOG("EventThread start"); #ifdef ANDROID Android_JNI_SetupThread(); #endif SdlTkLock(NULL); +#ifdef __APPLE__ + while (evs->root_width == NULL && evs->root_height == NULL) { + SdlTkWaitLock(); + } +#endif initSuccess = PerformSDLInit(evs->root_width, evs->root_height); evs->init_done = 1; - Tcl_ConditionNotify(&xlib_cond); +#ifdef __APPLE__ + evs->root_width = evs->root_height = NULL; +#endif + SdlTkNotify(); if (!initSuccess) { SdlTkUnlock(NULL); goto eventThreadEnd; @@ -6031,9 +6064,14 @@ EventThread(ClientData clientData) /* tear down font manager/engine */ SdlTkGfxDeinitFC(); eventThreadEnd: +#ifdef __APPLE__ + exit(3); +#else TCL_THREAD_CREATE_RETURN; +#endif } +#ifndef __APPLE__ static void EventThreadExitHandler(ClientData clientData) { @@ -6052,25 +6090,43 @@ EventThreadExitHandler(ClientData clientData) #endif } } +#endif static void OpenVeryFirstDisplay(int *root_width, int *root_height) { - struct EventThreadStartup evs; +#ifdef __APPLE__ + struct EventThreadStartup *evs = &evt_startup; +#else + struct EventThreadStartup evs0, *evs = &evs0; +#endif + evs->init_done = 0; + evs->root_width = root_width; + evs->root_height = root_height; +#ifdef __APPLE__ + /* + * Rendezvous with already running event thread, which + * in MacOSX is the main thread. + */ + + SdlTkNotify(); + while (!evs->init_done) { + SdlTkWaitLock(); + } +#else /* * Run thread to startup SDL, to collect SDL events, * and to perform screen updates. */ - evs.init_done = 0; - evs.root_width = root_width; - evs.root_height = root_height; - Tcl_CreateThread(&SdlTkX.event_tid, EventThread, &evs, + + Tcl_CreateThread(&SdlTkX.event_tid, EventThread, evs, TCL_THREAD_STACK_DEFAULT, TCL_THREAD_NOFLAGS); - while (!evs.init_done) { + while (!evs->init_done) { SdlTkWaitLock(); } Tcl_CreateExitHandler(EventThreadExitHandler, NULL); +#endif } Display * @@ -7307,7 +7363,7 @@ XUngrabServer(Display *display) SdlTkLock(display); display->request++; xlib_grab = NULL; - Tcl_ConditionNotify(&xlib_cond); + SdlTkNotify(); SdlTkUnlock(display); return 0; } diff --git a/sdl/tkAppInit.c b/sdl/tkAppInit.c index 124bbc4..863b2c6 100644 --- a/sdl/tkAppInit.c +++ b/sdl/tkAppInit.c @@ -66,6 +66,13 @@ MODULE_SCOPE int TK_LOCAL_MAIN_HOOK(int *argc, char ***argv); #undef Tcl_ObjSetVar2 #undef Tcl_NewStringObj +#ifdef __APPLE__ +struct ThreadStartup { + int argc; + char **argv; +}; +#endif + /* *---------------------------------------------------------------------- @@ -299,6 +306,28 @@ GetOBBDir(void) } #endif +#ifdef __APPLE__ +/* + *---------------------------------------------------------------------- + * + * TkMainThread -- + * + * This is the thread body of the main program for the application. + * + *---------------------------------------------------------------------- + */ + +static Tcl_ThreadCreateType +TkMainThread(ClientData clientData) +{ + struct ThreadStartup *stPtr = (struct ThreadStartup *) clientData; + + Tk_MainEx(stPtr->argc, stPtr->argv, TK_LOCAL_APPINIT, Tcl_CreateInterp()); + exit(4); + TCL_THREAD_CREATE_RETURN; +} +#endif + /* *---------------------------------------------------------------------- * @@ -324,6 +353,11 @@ main( #if defined(ANDROID) && defined(PLATFORM_SDL) const char *path, *temp; #endif +#ifdef __APPLE__ + Tcl_ThreadId thrId; + struct ThreadStartup startup; + extern void SdlTkEventThread(void); +#endif #ifdef TK_LOCAL_MAIN_HOOK TK_LOCAL_MAIN_HOOK(&argc, &argv); @@ -434,7 +468,28 @@ main( #else Tcl_FindExecutable(argv[0]); #endif +#ifdef __APPLE__ + /* + * We need the SDL event handling run in the main thread, + * which seems to be a Cocoa requirement. Therefore Tk_MainEx() + * is run in a seperate thread which is started now. + */ + + startup.argc = argc; + startup.argv = argv; + if (Tcl_CreateThread(&thrId, TkMainThread, &startup, + TCL_THREAD_STACK_DEFAULT, TCL_THREAD_NOFLAGS) != TCL_OK) { + Tcl_Panic("unable to start Tk main thread"); + } + + /* + * Perform SDL event handling, screen refresh, etc. + */ + + SdlTkEventThread(); +#else Tk_MainEx(argc, argv, TK_LOCAL_APPINIT, Tcl_CreateInterp()); +#endif return 0; /* Needed only to prevent compiler warning. */ } |