summaryrefslogtreecommitdiffstats
path: root/generic/tkWindow.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tkWindow.c')
-rw-r--r--generic/tkWindow.c244
1 files changed, 157 insertions, 87 deletions
diff --git a/generic/tkWindow.c b/generic/tkWindow.c
index 528fc87..b04b95f 100644
--- a/generic/tkWindow.c
+++ b/generic/tkWindow.c
@@ -10,13 +10,13 @@
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
- *
- * RCS: @(#) $Id: tkWindow.c,v 1.114 2010/11/19 14:48:00 nijtmans Exp $
*/
#include "tkInt.h"
-#if !( defined(__WIN32__) || defined(MAC_OSX_TK))
+#ifdef __WIN32__
+#include "tkWinInt.h"
+#elif !defined(MAC_OSX_TK)
#include "tkUnixInt.h"
#endif
@@ -65,14 +65,14 @@ TCL_DECLARE_MUTEX(windowMutex)
* on internal windows: these events are generated internally.
*/
-static XWindowChanges defChanges = {
+static const XWindowChanges defChanges = {
0, 0, 1, 1, 0, 0, Above
};
#define ALL_EVENTS_MASK \
KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask| \
EnterWindowMask|LeaveWindowMask|PointerMotionMask|ExposureMask| \
VisibilityChangeMask|PropertyChangeMask|ColormapChangeMask
-static XSetWindowAttributes defAtts= {
+static const XSetWindowAttributes defAtts= {
None, /* background_pixmap */
0, /* background_pixel */
CopyFromParent, /* border_pixmap */
@@ -94,18 +94,18 @@ static XSetWindowAttributes defAtts= {
* The following structure defines all of the commands supported by Tk, and
* the C functions that execute them.
*/
+
+#define ISSAFE 1
+#define PASSMAINWINDOW 2
+#define NOOBJPROC 4
+#define WINMACONLY 8
+#define USEINITPROC 16
+
typedef int (TkInitProc)(Tcl_Interp *interp, ClientData clientData);
typedef struct {
- const char *name; /* Name of command. */
- Tcl_CmdProc *cmdProc; /* Command's string-based function. */
- Tcl_ObjCmdProc *objProc; /* Command's object-based function. */
- TkInitProc *initProc; /* Command's initialization function */
- int isSafe; /* If !0, this command will be exposed in a
- * safe interpreter. Otherwise it will be
- * hidden in a safe interpreter. */
- int passMainWindow; /* 0 means provide NULL clientData to command
- * function; 1 means pass main window as
- * clientData to command function. */
+ const char *name; /* Name of command. */
+ Tcl_ObjCmdProc *objProc; /* Command's object- (or string-) based function, or initProc. */
+ int flags;
} TkCmd;
static const TkCmd commands[] = {
@@ -113,72 +113,72 @@ static const TkCmd commands[] = {
* Commands that are part of the intrinsics:
*/
- {"bell", NULL, Tk_BellObjCmd, NULL, 0, 1},
- {"bind", NULL, Tk_BindObjCmd, NULL, 1, 1},
- {"bindtags", NULL, Tk_BindtagsObjCmd, NULL, 1, 1},
- {"clipboard", NULL, Tk_ClipboardObjCmd, NULL, 0, 1},
- {"destroy", NULL, Tk_DestroyObjCmd, NULL, 1, 1},
- {"event", NULL, Tk_EventObjCmd, NULL, 1, 1},
- {"focus", NULL, Tk_FocusObjCmd, NULL, 1, 1},
- {"font", NULL, Tk_FontObjCmd, NULL, 1, 1},
- {"grab", NULL, Tk_GrabObjCmd, NULL, 0, 1},
- {"grid", NULL, Tk_GridObjCmd, NULL, 1, 1},
- {"image", NULL, Tk_ImageObjCmd, NULL, 1, 1},
- {"lower", NULL, Tk_LowerObjCmd, NULL, 1, 1},
- {"option", NULL, Tk_OptionObjCmd, NULL, 1, 1},
- {"pack", NULL, Tk_PackObjCmd, NULL, 1, 1},
- {"place", NULL, Tk_PlaceObjCmd, NULL, 1, 1},
- {"raise", NULL, Tk_RaiseObjCmd, NULL, 1, 1},
- {"selection", NULL, Tk_SelectionObjCmd, NULL, 0, 1},
- {"tk", NULL, NULL, TkInitTkCmd, 1, 1},
- {"tkwait", NULL, Tk_TkwaitObjCmd, NULL, 1, 1},
- {"update", NULL, Tk_UpdateObjCmd, NULL, 1, 1},
- {"winfo", NULL, Tk_WinfoObjCmd, NULL, 1, 1},
- {"wm", NULL, Tk_WmObjCmd, NULL, 0, 1},
+ {"bell", Tk_BellObjCmd, PASSMAINWINDOW},
+ {"bind", Tk_BindObjCmd, PASSMAINWINDOW|ISSAFE},
+ {"bindtags", Tk_BindtagsObjCmd, PASSMAINWINDOW|ISSAFE},
+ {"clipboard", Tk_ClipboardObjCmd, PASSMAINWINDOW},
+ {"destroy", Tk_DestroyObjCmd, PASSMAINWINDOW|ISSAFE},
+ {"event", Tk_EventObjCmd, PASSMAINWINDOW|ISSAFE},
+ {"focus", Tk_FocusObjCmd, PASSMAINWINDOW|ISSAFE},
+ {"font", Tk_FontObjCmd, PASSMAINWINDOW|ISSAFE},
+ {"grab", Tk_GrabObjCmd, PASSMAINWINDOW},
+ {"grid", Tk_GridObjCmd, PASSMAINWINDOW|ISSAFE},
+ {"image", Tk_ImageObjCmd, PASSMAINWINDOW|ISSAFE},
+ {"lower", Tk_LowerObjCmd, PASSMAINWINDOW|ISSAFE},
+ {"option", Tk_OptionObjCmd, PASSMAINWINDOW|ISSAFE},
+ {"pack", Tk_PackObjCmd, PASSMAINWINDOW|ISSAFE},
+ {"place", Tk_PlaceObjCmd, PASSMAINWINDOW|ISSAFE},
+ {"raise", Tk_RaiseObjCmd, PASSMAINWINDOW|ISSAFE},
+ {"selection", Tk_SelectionObjCmd, PASSMAINWINDOW},
+ {"tk", (Tcl_ObjCmdProc *) TkInitTkCmd, USEINITPROC|PASSMAINWINDOW|ISSAFE},
+ {"tkwait", Tk_TkwaitObjCmd, PASSMAINWINDOW|ISSAFE},
+ {"update", Tk_UpdateObjCmd, PASSMAINWINDOW|ISSAFE},
+ {"winfo", Tk_WinfoObjCmd, PASSMAINWINDOW|ISSAFE},
+ {"wm", Tk_WmObjCmd, PASSMAINWINDOW},
/*
* Default widget class commands.
*/
- {"button", NULL, Tk_ButtonObjCmd, NULL, 1, 0},
- {"canvas", NULL, Tk_CanvasObjCmd, NULL, 1, 1},
- {"checkbutton", NULL, Tk_CheckbuttonObjCmd, NULL, 1, 0},
- {"entry", NULL, Tk_EntryObjCmd, NULL, 1, 0},
- {"frame", NULL, Tk_FrameObjCmd, NULL, 1, 0},
- {"label", NULL, Tk_LabelObjCmd, NULL, 1, 0},
- {"labelframe", NULL, Tk_LabelframeObjCmd, NULL, 1, 0},
- {"listbox", NULL, Tk_ListboxObjCmd, NULL, 1, 0},
- {"menubutton", NULL, Tk_MenubuttonObjCmd, NULL, 1, 0},
- {"message", NULL, Tk_MessageObjCmd, NULL, 1, 0},
- {"panedwindow", NULL, Tk_PanedWindowObjCmd, NULL, 1, 0},
- {"radiobutton", NULL, Tk_RadiobuttonObjCmd, NULL, 1, 0},
- {"scale", NULL, Tk_ScaleObjCmd, NULL, 1, 0},
- {"scrollbar", Tk_ScrollbarCmd,NULL, NULL, 1, 1},
- {"spinbox", NULL, Tk_SpinboxObjCmd, NULL, 1, 0},
- {"text", NULL, Tk_TextObjCmd, NULL, 1, 1},
- {"toplevel", NULL, Tk_ToplevelObjCmd, NULL, 0, 0},
+ {"button", Tk_ButtonObjCmd, ISSAFE},
+ {"canvas", Tk_CanvasObjCmd, PASSMAINWINDOW|ISSAFE},
+ {"checkbutton", Tk_CheckbuttonObjCmd, ISSAFE},
+ {"entry", Tk_EntryObjCmd, ISSAFE},
+ {"frame", Tk_FrameObjCmd, ISSAFE},
+ {"label", Tk_LabelObjCmd, ISSAFE},
+ {"labelframe", Tk_LabelframeObjCmd, ISSAFE},
+ {"listbox", Tk_ListboxObjCmd, ISSAFE},
+ {"menubutton", Tk_MenubuttonObjCmd, ISSAFE},
+ {"message", Tk_MessageObjCmd, ISSAFE},
+ {"panedwindow", Tk_PanedWindowObjCmd, ISSAFE},
+ {"radiobutton", Tk_RadiobuttonObjCmd, ISSAFE},
+ {"scale", Tk_ScaleObjCmd, ISSAFE},
+ {"scrollbar", (Tcl_ObjCmdProc *) Tk_ScrollbarCmd, NOOBJPROC|PASSMAINWINDOW|ISSAFE},
+ {"spinbox", Tk_SpinboxObjCmd, ISSAFE},
+ {"text", Tk_TextObjCmd, PASSMAINWINDOW|ISSAFE},
+ {"toplevel", Tk_ToplevelObjCmd, 0},
/*
* Classic widget class commands.
*/
- {"::tk::button", NULL, Tk_ButtonObjCmd, NULL, 1, 0},
- {"::tk::canvas", NULL, Tk_CanvasObjCmd, NULL, 1, 1},
- {"::tk::checkbutton",NULL, Tk_CheckbuttonObjCmd, NULL, 1, 0},
- {"::tk::entry", NULL, Tk_EntryObjCmd, NULL, 1, 0},
- {"::tk::frame", NULL, Tk_FrameObjCmd, NULL, 1, 0},
- {"::tk::label", NULL, Tk_LabelObjCmd, NULL, 1, 0},
- {"::tk::labelframe",NULL, Tk_LabelframeObjCmd, NULL, 1, 0},
- {"::tk::listbox", NULL, Tk_ListboxObjCmd, NULL, 1, 0},
- {"::tk::menubutton",NULL, Tk_MenubuttonObjCmd, NULL, 1, 0},
- {"::tk::message", NULL, Tk_MessageObjCmd, NULL, 1, 0},
- {"::tk::panedwindow",NULL, Tk_PanedWindowObjCmd, NULL, 1, 0},
- {"::tk::radiobutton",NULL, Tk_RadiobuttonObjCmd, NULL, 1, 0},
- {"::tk::scale", NULL, Tk_ScaleObjCmd, NULL, 1, 0},
- {"::tk::scrollbar", Tk_ScrollbarCmd,NULL, NULL, 1, 1},
- {"::tk::spinbox", NULL, Tk_SpinboxObjCmd, NULL, 1, 0},
- {"::tk::text", NULL, Tk_TextObjCmd, NULL, 1, 1},
- {"::tk::toplevel", NULL, Tk_ToplevelObjCmd, NULL, 0, 0},
+ {"::tk::button", Tk_ButtonObjCmd, ISSAFE},
+ {"::tk::canvas", Tk_CanvasObjCmd, PASSMAINWINDOW|ISSAFE},
+ {"::tk::checkbutton",Tk_CheckbuttonObjCmd, ISSAFE},
+ {"::tk::entry", Tk_EntryObjCmd, ISSAFE},
+ {"::tk::frame", Tk_FrameObjCmd, ISSAFE},
+ {"::tk::label", Tk_LabelObjCmd, ISSAFE},
+ {"::tk::labelframe",Tk_LabelframeObjCmd, ISSAFE},
+ {"::tk::listbox", Tk_ListboxObjCmd, ISSAFE},
+ {"::tk::menubutton",Tk_MenubuttonObjCmd, ISSAFE},
+ {"::tk::message", Tk_MessageObjCmd, ISSAFE},
+ {"::tk::panedwindow",Tk_PanedWindowObjCmd, ISSAFE},
+ {"::tk::radiobutton",Tk_RadiobuttonObjCmd, ISSAFE},
+ {"::tk::scale", Tk_ScaleObjCmd, ISSAFE},
+ {"::tk::scrollbar", (Tcl_ObjCmdProc *) Tk_ScrollbarCmd, NOOBJPROC|PASSMAINWINDOW|ISSAFE},
+ {"::tk::spinbox", Tk_SpinboxObjCmd, ISSAFE},
+ {"::tk::text", Tk_TextObjCmd, PASSMAINWINDOW|ISSAFE},
+ {"::tk::toplevel", Tk_ToplevelObjCmd, 0},
/*
* Standard dialog support. Note that the Unix/X11 platform implements
@@ -186,11 +186,11 @@ static const TkCmd commands[] = {
*/
#if defined(__WIN32__) || defined(MAC_OSX_TK)
- {"tk_chooseColor", NULL, Tk_ChooseColorObjCmd, NULL, 0, 1},
- {"tk_chooseDirectory", NULL, Tk_ChooseDirectoryObjCmd,NULL, 0,1},
- {"tk_getOpenFile", NULL, Tk_GetOpenFileObjCmd, NULL, 0, 1},
- {"tk_getSaveFile", NULL, Tk_GetSaveFileObjCmd, NULL, 0, 1},
- {"tk_messageBox", NULL, Tk_MessageBoxObjCmd, NULL, 0, 1},
+ {"tk_chooseColor", Tk_ChooseColorObjCmd, PASSMAINWINDOW},
+ {"tk_chooseDirectory", Tk_ChooseDirectoryObjCmd,WINMACONLY|PASSMAINWINDOW},
+ {"tk_getOpenFile", Tk_GetOpenFileObjCmd, WINMACONLY|PASSMAINWINDOW},
+ {"tk_getSaveFile", Tk_GetSaveFileObjCmd, WINMACONLY|PASSMAINWINDOW},
+ {"tk_messageBox", Tk_MessageBoxObjCmd, PASSMAINWINDOW},
#endif
/*
@@ -199,9 +199,9 @@ static const TkCmd commands[] = {
#if defined(MAC_OSX_TK)
{"::tk::unsupported::MacWindowStyle",
- NULL, TkUnsupported1ObjCmd, NULL, 1, 1},
+ TkUnsupported1ObjCmd, PASSMAINWINDOW|ISSAFE},
#endif
- {NULL, NULL, NULL, NULL, 0, 0}
+ {NULL, NULL, 0}
};
/*
@@ -949,26 +949,31 @@ TkCreateMainWindow(
isSafe = Tcl_IsSafe(interp);
for (cmdPtr = commands; cmdPtr->name != NULL; cmdPtr++) {
- if ((cmdPtr->cmdProc == NULL) && (cmdPtr->objProc == NULL)
- && (cmdPtr->initProc == NULL)) {
+ if ((cmdPtr->objProc == NULL)) {
Tcl_Panic("TkCreateMainWindow: builtin command with NULL string and object procs");
}
- if (cmdPtr->passMainWindow) {
+#if defined(__WIN32__) && !defined(STATIC_BUILD)
+ if ((cmdPtr->flags & WINMACONLY) && tclStubsPtr->reserved9) {
+ /* We are running on Cygwin, so don't use the win32 dialogs */
+ continue;
+ }
+#endif
+ if (cmdPtr->flags & PASSMAINWINDOW) {
clientData = tkwin;
} else {
clientData = NULL;
}
- if (cmdPtr->initProc != NULL) {
- cmdPtr->initProc(interp, clientData);
- } else if (cmdPtr->cmdProc != NULL) {
- Tcl_CreateCommand(interp, cmdPtr->name, cmdPtr->cmdProc,
- clientData, NULL);
+ if (cmdPtr->flags & USEINITPROC) {
+ ((TkInitProc *)cmdPtr->objProc)(interp, clientData);
+ } else if (cmdPtr->flags & NOOBJPROC) {
+ Tcl_CreateCommand(interp, cmdPtr->name,
+ (Tcl_CmdProc *) cmdPtr->objProc, clientData, NULL);
} else {
Tcl_CreateObjCommand(interp, cmdPtr->name, cmdPtr->objProc,
clientData, NULL);
}
if (isSafe) {
- if (!(cmdPtr->isSafe)) {
+ if (!(cmdPtr->flags & ISSAFE)) {
Tcl_HideCommand(interp, cmdPtr->name, cmdPtr->name);
}
}
@@ -2828,6 +2833,51 @@ DeleteWindowsExitProc(
tsdPtr->initialized = 0;
}
+#if defined(__WIN32__) && !defined(__WIN64__)
+
+static HMODULE tkcygwindll = NULL;
+
+/*
+ * Run Tk_MainEx from libtk8.?.dll
+ *
+ * This function is only ever called from wish8.4.exe, the cygwin
+ * port of Tcl. This means that the system encoding is utf-8,
+ * so we don't have to do any encoding conversions.
+ */
+int
+TkCygwinMainEx(argc, argv, appInitProc, interp)
+ int argc; /* Number of arguments. */
+ char **argv; /* Array of argument strings. */
+ Tcl_AppInitProc *appInitProc; /* Application-specific initialization
+ * procedure to call after most
+ * initialization but before starting
+ * to execute commands. */
+ Tcl_Interp *interp;
+{
+ TCHAR name[MAX_PATH];
+ int len;
+ void (*sym)(int, char **, Tcl_AppInitProc *, Tcl_Interp *);
+
+ /* construct "<path>/libtk8.?.dll", from "<path>/tk8?.dll" */
+ len = GetModuleFileNameW(Tk_GetHINSTANCE(), name, MAX_PATH);
+ name[len-2] = TEXT('.');
+ name[len-1] = name[len-5];
+ _tcscpy(name+len, TEXT(".dll"));
+ memcpy(name+len-8, TEXT("libtk8"), 6 * sizeof(TCHAR));
+
+ tkcygwindll = LoadLibrary(name);
+ if (!tkcygwindll) {
+ /* dll is not present */
+ return 0;
+ }
+ sym = (void (*)(int, char **, Tcl_AppInitProc *, Tcl_Interp *)) GetProcAddress(tkcygwindll, "Tk_MainEx");
+ if (!sym) {
+ return 0;
+ }
+ sym(argc, argv, appInitProc, interp);
+ return 1;
+}
+#endif
/*
*----------------------------------------------------------------------
*
@@ -2855,6 +2905,16 @@ int
Tk_Init(
Tcl_Interp *interp) /* Interpreter to initialize. */
{
+#if defined(__WIN32__) && !defined(__WIN64__)
+ if (tkcygwindll) {
+ int (*sym)(Tcl_Interp *);
+
+ sym = (int (*)(Tcl_Interp *)) GetProcAddress(tkcygwindll, "Tk_Init");
+ if (sym) {
+ return sym(interp);
+ }
+ }
+#endif
return Initialize(interp);
}
@@ -2918,6 +2978,16 @@ Tk_SafeInit(
* checked at several places to differentiate the two initialisations.
*/
+#if defined(__WIN32__) && !defined(__WIN64__)
+ if (tkcygwindll) {
+ int (*sym)(Tcl_Interp *);
+
+ sym = (int (*)(Tcl_Interp *)) GetProcAddress(tkcygwindll, "Tk_SafeInit");
+ if (sym) {
+ return sym(interp);
+ }
+ }
+#endif
return Initialize(interp);
}