diff options
Diffstat (limited to 'generic/tkWindow.c')
-rw-r--r-- | generic/tkWindow.c | 244 |
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); } |