aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlemort2008-01-21 09:43:40 +0000
committerlemort2008-01-21 09:43:40 +0000
commitf897309da7f5d145e504ccf427e8821cbda7c1e6 (patch)
tree0befe1142d2310ad123ec9ca2b3057e2c65940c7
parent3b4a6244a556319d469fc6b396a601451b20fdff (diff)
downloadtkzinc-f897309da7f5d145e504ccf427e8821cbda7c1e6.zip
tkzinc-f897309da7f5d145e504ccf427e8821cbda7c1e6.tar.gz
tkzinc-f897309da7f5d145e504ccf427e8821cbda7c1e6.tar.bz2
tkzinc-f897309da7f5d145e504ccf427e8821cbda7c1e6.tar.xz
Ajout d'une propriete -windowtitle qui permet de specifier le nom (ou un pattern) de la fenetre a reparenter dans l'item window
Cette propriete vient en complement de la propriete -window qui permet de reparenter des widgets Tk La propriete peut prendre comme valeur le nom de la fenetre (Google -Moxilla Firefox par exemple) ou un pattern fonctionnant avec Tcl_String (* - Mozilla Firefox par exemple) Cette gestion du reparentage de fenetre eterne fonctionne sous Linux, Windows et un peu sous Mac (pour l'instant le support Mac est limite aux applications X11)
-rw-r--r--generic/Window.c233
1 files changed, 231 insertions, 2 deletions
diff --git a/generic/Window.c b/generic/Window.c
index 9dac5c7..0b6459f 100644
--- a/generic/Window.c
+++ b/generic/Window.c
@@ -20,6 +20,14 @@
#include "WidgetInfo.h"
#include "tkZinc.h"
+#include <stdio.h>
+#include "WindowUtils.h"
+
+/* We need to include tkPlatDecls to use Tk_GetHWND */
+#if defined(_WIN32) && defined(PTK) && !defined(PTK_800)
+#include <tkPlatDecls.m>
+#endif
+
static const char rcsid[] = "$Id$";
static const char compile_id[] = "$Compile: " __FILE__ " " __DATE__ " " __TIME__ " $";
@@ -41,11 +49,20 @@ typedef struct _WindowItemStruct {
Tk_Window win;
int width;
int height;
+ char *windowtitle;
/* Private data */
ZnPoint pos_dev;
int real_width;
int real_height;
+
+#ifdef _WIN32
+ HWND externalwindow;
+ LONG externalwindowstyle;
+#else
+ Window externalwindow;
+#endif /* ifdef _WIN32 */
+
} WindowItemStruct, *WindowItem;
@@ -89,6 +106,9 @@ static ZnAttrConfig wind_attrs[] = {
{ ZN_CONFIG_WINDOW, "-window", NULL,
Tk_Offset(WindowItemStruct, win), 0,
ZN_COORDS_FLAG|ZN_WINDOW_FLAG, False },
+ { ZN_CONFIG_STRING, "-windowtitle", NULL,
+ Tk_Offset(WindowItemStruct, windowtitle), 0,
+ ZN_COORDS_FLAG|ZN_WINDOW_FLAG, False },
{ ZN_CONFIG_END, NULL, NULL, 0, 0, 0, False }
};
@@ -123,6 +143,7 @@ WindowDeleted(ClientData client_data,
**********************************************************************************
*/
+
/*
* A managed window changes requested dimensions.
*/
@@ -162,6 +183,178 @@ static Tk_GeomMgr wind_geom_type = {
};
+
+/*
+ **********************************************************************************
+ *
+ * Manage external Window -- Reparent, Unparent, Resize
+ *
+ **********************************************************************************
+ */
+
+/*
+ * Create a Tk_Window
+ */
+ static int WINDOW_PRIVATE_TK_WINDOW_COUNTER = 0;
+
+ static void
+ WindowCreateTkWindow(ZnItem item)
+ {
+ ZnWInfo *wi = item->wi;
+ WindowItem wind = (WindowItem) item;
+ char buffer[32];
+
+ if (wind->win == 0) {
+ /* create a unique name */
+ sprintf(buffer, "_private_tkwindow_%d", WINDOW_PRIVATE_TK_WINDOW_COUNTER);
+ WINDOW_PRIVATE_TK_WINDOW_COUNTER++;
+
+ /* create a new Tk_Window */
+ wind->win = Tk_CreateWindow(wi->interp, wi->win, buffer, NULL);
+ }
+ }
+
+
+ /*
+ * Resize an external window
+ */
+static void
+WindowResizeExternalWindow(ZnItem item, int width, int height)
+{
+ ZnWInfo *wi = item->wi;
+ WindowItem wind = (WindowItem) item;
+
+ /* Our window (wi->win) must exists before doing anything */
+ Tk_MakeWindowExist(wi->win);
+ Tk_MakeWindowExist(wind->win);
+
+#ifdef _WIN32
+ /* Resize our external window if needed */
+ if (wind->externalwindow != 0) {
+ MoveWindow(wind->externalwindow, 0, 0, width, height, TRUE);
+ }
+
+#else
+ /* Resize our external window if needed */
+ if (wind->externalwindow != 0) {
+ XResizeWindow(wi->dpy, wind->externalwindow, width, height);
+ XFlush(wi->dpy);
+ }
+
+#endif /* ifdef _WIN32 */
+}
+
+
+/*
+ * Reparent/capture an external window
+ */
+static void
+WindowCaptureExternalWindow(ZnItem item)
+{
+ ZnWInfo *wi = item->wi;
+ WindowItem wind = (WindowItem) item;
+
+#ifdef _WIN32
+ /* Try to find a window matching windowtitle */
+ HWND externalWindow = SearchWindowByTitle(wind->windowtitle, wi->dpy, NULL, 0);
+
+ /* Test if we can reparent our window */
+ if ((externalWindow != 0) && (wi->win != 0)) {
+ /* Save external window */
+ wind->externalwindow = externalWindow;
+
+ /* Test if we must create a window */
+ if (wind->win == NULL) {
+ /* Create a new window */
+ WindowCreateTkWindow(item);
+ }
+
+ /* Our window must exists before we try to reparent an external window */
+ Tk_MakeWindowExist(wi->win);
+ Tk_MakeWindowExist(wind->win);
+
+ /* remove window decoration */
+ wind->externalwindowstyle = removeWindowDecoration(externalWindow);
+ ShowWindow(externalWindow, SW_SHOW);
+
+ /* Reparent our external window */
+ SetParent(externalWindow, Tk_GetHWND(Tk_WindowId(wind->win)));
+ ShowWindow(externalWindow, SW_SHOW);
+
+ /* Windows only: we must resize our external window */
+ WindowResizeExternalWindow(item, wind->real_width, wind->real_height);
+ }
+
+#else
+ /* Try to find a window matching windowtitle */
+ Window externalWindow = SearchWindowByTitle(wind->windowtitle, wi->dpy, RootWindowOfScreen(wi->screen), 0);
+
+ /* Test if we can reparent our window */
+ if ((externalWindow != 0) && (wi->win != 0)) {
+ /* Save external window */
+ wind->externalwindow = externalWindow;
+
+ /* Test if we must create a window */
+ if (wind->win == NULL) {
+ /* Create a new window */
+ WindowCreateTkWindow(item);
+ }
+
+ /* Our window must exists before we try to reparent an external window */
+ Tk_MakeWindowExist(wi->win);
+ Tk_MakeWindowExist(wind->win);
+
+ /* Withdraw our external window from desktop */
+ withdrawWindowFromDesktop (wi->dpy, externalWindow, Tk_ScreenNumber(wi->win));
+
+ /* Reparent our external window */
+ XAddToSaveSet (wi->dpy, externalWindow);
+ XReparentWindow(wi->dpy, externalWindow, Tk_WindowId(wind->win), 0, 0);
+ XMapWindow(wi->dpy, externalWindow);
+ XFlush(wi->dpy);
+ }
+
+#endif /* ifdef _WIN32 */
+}
+
+
+/*
+ * Unparent/release an external window
+ */
+static void
+WindowReleaseExternalWindow(ZnItem item)
+{
+ ZnWInfo *wi = item->wi;
+ WindowItem wind = (WindowItem) item;
+
+#ifdef _WIN32
+ /* Test if we must release an external window */
+ if (wind->externalwindow != 0) {
+ /* restore window style */
+ restoreWindowStyle(wind->externalwindow, wind->externalwindowstyle);
+ wind->externalwindowstyle = 0;
+
+ /* Reparent our external window (new parent is the main root window) */
+ SetParent(wind->externalwindow, NULL);
+ }
+
+#else
+ /* Test if we must release an external window */
+ if (wind->externalwindow != 0) {
+ /* Reparent our external window (new parent is the main root window) */
+ XReparentWindow(wi->dpy, wind->externalwindow, XRootWindow(wi->dpy, Tk_ScreenNumber(wi->win)), 0, 0);
+ XMapWindow(wi->dpy, wind->externalwindow);
+ XFlush(wi->dpy);
+ XRemoveFromSaveSet(wi->dpy, wind->externalwindow);
+ }
+#endif /* ifdef _WIN32 */
+
+ /* Reset externalwindow */
+ wind->externalwindow = NULL;
+}
+
+
+
/*
**********************************************************************************
*
@@ -190,6 +383,8 @@ Init(ZnItem item,
wind->anchor = TK_ANCHOR_NW;
wind->connection_anchor = TK_ANCHOR_SW;
wind->win = NULL;
+ wind->windowtitle = NULL;
+ wind->externalwindow = NULL;
return TCL_OK;
}
@@ -211,6 +406,8 @@ Clone(ZnItem item)
* The same Tk widget can't be shared by to Window items.
*/
wind->win = NULL;
+ wind->windowtitle = NULL;
+ wind->externalwindow = NULL;
}
@@ -227,6 +424,17 @@ Destroy(ZnItem item)
ZnWInfo *wi = item->wi;
WindowItem wind = (WindowItem) item;
+
+ /*
+ * Unmanage external window if needed
+ */
+ if (wind->externalwindow != 0) {
+ WindowReleaseExternalWindow(item);
+ }
+ if (wind->windowtitle) {
+ ZnFree(wind->windowtitle);
+ }
+
/*
* Unmanage the widget.
*/
@@ -259,9 +467,11 @@ Configure(ZnItem item,
ZnWInfo *wi = item->wi;
ZnItem old_connected;
Tk_Window old_win;
+ const char *old_windowtitle = wind->windowtitle;
old_connected = item->connected_item;
old_win = wind->win;
+
if (ZnConfigureAttributes(wi, item, item, wind_attrs, argc, argv, flags) == TCL_ERROR) {
item->connected_item = old_connected;
return TCL_ERROR;
@@ -290,6 +500,24 @@ Configure(ZnItem item,
Tk_UnmaintainGeometry(old_win, wi->win);
Tk_UnmapWindow(old_win);
}
+
+ if (wind->windowtitle != NULL) {
+ if (old_windowtitle == 0) {
+ /* It's a new capture */
+ WindowCaptureExternalWindow(item);
+
+ } else {
+ /* Test if we must capture a new window */
+ if (strcmp(old_windowtitle, (const char *)(wind->windowtitle)) != 0) {
+ /* release previous external window */
+ WindowReleaseExternalWindow(item);
+
+ /* Capture a new window */
+ WindowCaptureExternalWindow(item);
+ }
+ }
+ }
+
if (wind->win != NULL) {
Tk_CreateEventHandler(wind->win, StructureNotifyMask,
WindowDeleted, (ClientData) item);
@@ -300,7 +528,7 @@ Configure(ZnItem item,
if ((wind->win != NULL) &&
ISSET(*flags, ZN_VIS_FLAG) &&
ISCLEAR(item->flags, ZN_VISIBLE_BIT)) {
- Tk_UnmapWindow(wind->win);
+ Tk_UnmapWindow(wind->win);
}
return TCL_OK;
@@ -392,7 +620,7 @@ ComputeCoordinates(ZnItem item,
ZnTransfo *t;
ZnResetBBox(&item->item_bounding_box);
-
+
if (wind->win == NULL) {
return;
}
@@ -516,6 +744,7 @@ Draw(ZnItem item)
wind->real_width, wind->real_height);
}
+ WindowResizeExternalWindow(item, wind->real_width, wind->real_height);
}