summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/canvas.n1
-rw-r--r--library/tk.tcl23
-rw-r--r--sdl/SdlTkInt.h3
-rw-r--r--sdl/SdlTkUtils.c5
-rw-r--r--sdl/SdlTkX.c80
-rw-r--r--sdl/tkAppInit.c55
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. */
}