aboutsummaryrefslogtreecommitdiff
path: root/generic/Window.c
diff options
context:
space:
mode:
authorlemort2008-01-21 09:43:40 +0000
committerlemort2008-01-21 09:43:40 +0000
commitf897309da7f5d145e504ccf427e8821cbda7c1e6 (patch)
tree0befe1142d2310ad123ec9ca2b3057e2c65940c7 /generic/Window.c
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)
Diffstat (limited to 'generic/Window.c')
-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);
}