/[dtapublic]/projs/dtats/trunk/shared_source/c_tk_base_7_5_w_mods/tkwinembed.c
ViewVC logotype

Diff of /projs/dtats/trunk/shared_source/c_tk_base_7_5_w_mods/tkwinembed.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 69 by dashley, Sat Nov 5 10:54:17 2016 UTC revision 71 by dashley, Sat Nov 5 11:07:06 2016 UTC
# Line 1  Line 1 
1  /* $Header$ */  /* $Header$ */
2    
3  /*  /*
4   * tkWinEmbed.c --   * tkWinEmbed.c --
5   *   *
6   *      This file contains platform specific procedures for Windows platforms   *      This file contains platform specific procedures for Windows platforms
7   *      to provide basic operations needed for application embedding (where   *      to provide basic operations needed for application embedding (where
8   *      one application can use as its main window an internal window from   *      one application can use as its main window an internal window from
9   *      another application).   *      another application).
10   *   *
11   * Copyright (c) 1996-1997 Sun Microsystems, Inc.   * Copyright (c) 1996-1997 Sun Microsystems, Inc.
12   *   *
13   * See the file "license.terms" for information on usage and redistribution   * See the file "license.terms" for information on usage and redistribution
14   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
15   *   *
16   * RCS: @(#) $Id: tkwinembed.c,v 1.1.1.1 2001/06/13 05:13:10 dtashley Exp $   * RCS: @(#) $Id: tkwinembed.c,v 1.1.1.1 2001/06/13 05:13:10 dtashley Exp $
17   */   */
18    
19  #include "tkWinInt.h"  #include "tkWinInt.h"
20    
21    
22  /*  /*
23   * One of the following structures exists for each container in this   * One of the following structures exists for each container in this
24   * application.  It keeps track of the container window and its   * application.  It keeps track of the container window and its
25   * associated embedded window.   * associated embedded window.
26   */   */
27    
28  typedef struct Container {  typedef struct Container {
29      HWND parentHWnd;                    /* Windows HWND to the parent window */      HWND parentHWnd;                    /* Windows HWND to the parent window */
30      TkWindow *parentPtr;                /* Tk's information about the container      TkWindow *parentPtr;                /* Tk's information about the container
31                                           * or NULL if the container isn't                                           * or NULL if the container isn't
32                                           * in this process. */                                           * in this process. */
33      HWND embeddedHWnd;                  /* Windows HWND to the embedded window      HWND embeddedHWnd;                  /* Windows HWND to the embedded window
34                                           */                                           */
35      TkWindow *embeddedPtr;              /* Tk's information about the embedded      TkWindow *embeddedPtr;              /* Tk's information about the embedded
36                                           * window, or NULL if the                                           * window, or NULL if the
37                                           * embedded application isn't in                                           * embedded application isn't in
38                                           * this process. */                                           * this process. */
39      struct Container *nextPtr;          /* Next in list of all containers in      struct Container *nextPtr;          /* Next in list of all containers in
40                                           * this process. */                                           * this process. */
41  } Container;  } Container;
42    
43  typedef struct ThreadSpecificData {  typedef struct ThreadSpecificData {
44      Container *firstContainerPtr;       /* First in list of all containers      Container *firstContainerPtr;       /* First in list of all containers
45                                           * managed by this process.  */                                           * managed by this process.  */
46  } ThreadSpecificData;  } ThreadSpecificData;
47  static Tcl_ThreadDataKey dataKey;  static Tcl_ThreadDataKey dataKey;
48    
49  static void             CleanupContainerList _ANSI_ARGS_((  static void             CleanupContainerList _ANSI_ARGS_((
50                              ClientData clientData));                              ClientData clientData));
51  static void             ContainerEventProc _ANSI_ARGS_((ClientData clientData,  static void             ContainerEventProc _ANSI_ARGS_((ClientData clientData,
52                              XEvent *eventPtr));                              XEvent *eventPtr));
53  static void             EmbeddedEventProc _ANSI_ARGS_((  static void             EmbeddedEventProc _ANSI_ARGS_((
54                              ClientData clientData, XEvent *eventPtr));                              ClientData clientData, XEvent *eventPtr));
55  static void             EmbedGeometryRequest _ANSI_ARGS_((  static void             EmbedGeometryRequest _ANSI_ARGS_((
56                              Container*containerPtr, int width, int height));                              Container*containerPtr, int width, int height));
57  static void             EmbedWindowDeleted _ANSI_ARGS_((TkWindow *winPtr));  static void             EmbedWindowDeleted _ANSI_ARGS_((TkWindow *winPtr));
58    
59  /*  /*
60   *----------------------------------------------------------------------   *----------------------------------------------------------------------
61   *   *
62   * CleanupContainerList --   * CleanupContainerList --
63   *   *
64   *      Finalizes the list of containers.   *      Finalizes the list of containers.
65   *   *
66   * Results:   * Results:
67   *      None.   *      None.
68   *   *
69   * Side effects:   * Side effects:
70   *      Releases memory occupied by containers of embedded windows.   *      Releases memory occupied by containers of embedded windows.
71   *   *
72   *----------------------------------------------------------------------   *----------------------------------------------------------------------
73   */   */
74    
75          /* ARGSUSED */          /* ARGSUSED */
76  static void  static void
77  CleanupContainerList(clientData)  CleanupContainerList(clientData)
78      ClientData clientData;      ClientData clientData;
79  {  {
80      Container *nextPtr;      Container *nextPtr;
81      ThreadSpecificData *tsdPtr = (ThreadSpecificData *)      ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
82              Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));              Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
83            
84      for (;      for (;
85          tsdPtr->firstContainerPtr != (Container *) NULL;          tsdPtr->firstContainerPtr != (Container *) NULL;
86          tsdPtr->firstContainerPtr = nextPtr) {          tsdPtr->firstContainerPtr = nextPtr) {
87          nextPtr = tsdPtr->firstContainerPtr->nextPtr;          nextPtr = tsdPtr->firstContainerPtr->nextPtr;
88          ckfree((char *) tsdPtr->firstContainerPtr);          ckfree((char *) tsdPtr->firstContainerPtr);
89      }      }
90      tsdPtr->firstContainerPtr = (Container *) NULL;      tsdPtr->firstContainerPtr = (Container *) NULL;
91  }  }
92    
93  /*  /*
94   *----------------------------------------------------------------------   *----------------------------------------------------------------------
95   *   *
96   * TkpTestembedCmd --   * TkpTestembedCmd --
97   *   *
98   *      Test command for the embedding facility.   *      Test command for the embedding facility.
99   *   *
100   * Results:   * Results:
101   *      Always returns TCL_OK.   *      Always returns TCL_OK.
102   *   *
103   * Side effects:   * Side effects:
104   *      Currently it does not do anything.   *      Currently it does not do anything.
105   *   *
106   *----------------------------------------------------------------------   *----------------------------------------------------------------------
107   */   */
108    
109          /* ARGSUSED */          /* ARGSUSED */
110  int  int
111  TkpTestembedCmd(clientData, interp, argc, argv)  TkpTestembedCmd(clientData, interp, argc, argv)
112      ClientData clientData;      ClientData clientData;
113      Tcl_Interp *interp;      Tcl_Interp *interp;
114      int argc;      int argc;
115      char **argv;      char **argv;
116  {  {
117      return TCL_OK;      return TCL_OK;
118  }  }
119    
120  /*  /*
121   *----------------------------------------------------------------------   *----------------------------------------------------------------------
122   *   *
123   * TkpUseWindow --   * TkpUseWindow --
124   *   *
125   *      This procedure causes a Tk window to use a given Windows handle   *      This procedure causes a Tk window to use a given Windows handle
126   *      for a window as its underlying window, rather than a new Windows   *      for a window as its underlying window, rather than a new Windows
127   *      window being created automatically. It is invoked by an embedded   *      window being created automatically. It is invoked by an embedded
128   *      application to specify the window in which the application is   *      application to specify the window in which the application is
129   *      embedded.   *      embedded.
130   *   *
131   * Results:   * Results:
132   *      The return value is normally TCL_OK. If an error occurred (such as   *      The return value is normally TCL_OK. If an error occurred (such as
133   *      if the argument does not identify a legal Windows window handle),   *      if the argument does not identify a legal Windows window handle),
134   *      the return value is TCL_ERROR and an error message is left in the   *      the return value is TCL_ERROR and an error message is left in the
135   *      the interp's result if interp is not NULL.   *      the interp's result if interp is not NULL.
136   *   *
137   * Side effects:   * Side effects:
138   *      None.   *      None.
139   *   *
140   *----------------------------------------------------------------------   *----------------------------------------------------------------------
141   */   */
142    
143  int  int
144  TkpUseWindow(interp, tkwin, string)  TkpUseWindow(interp, tkwin, string)
145      Tcl_Interp *interp;         /* If not NULL, used for error reporting      Tcl_Interp *interp;         /* If not NULL, used for error reporting
146                                   * if string is bogus. */                                   * if string is bogus. */
147      Tk_Window tkwin;            /* Tk window that does not yet have an      Tk_Window tkwin;            /* Tk window that does not yet have an
148                                   * associated X window. */                                   * associated X window. */
149      char *string;               /* String identifying an X window to use      char *string;               /* String identifying an X window to use
150                                   * for tkwin;  must be an integer value. */                                   * for tkwin;  must be an integer value. */
151  {  {
152      TkWindow *winPtr = (TkWindow *) tkwin;      TkWindow *winPtr = (TkWindow *) tkwin;
153      int id;      int id;
154      HWND hwnd;      HWND hwnd;
155      Container *containerPtr;      Container *containerPtr;
156      ThreadSpecificData *tsdPtr = (ThreadSpecificData *)      ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
157              Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));              Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
158    
159      if (winPtr->window != None) {      if (winPtr->window != None) {
160          panic("TkpUseWindow: Already assigned a window");          panic("TkpUseWindow: Already assigned a window");
161      }      }
162    
163      if (Tcl_GetInt(interp, string, &id) != TCL_OK) {      if (Tcl_GetInt(interp, string, &id) != TCL_OK) {
164          return TCL_ERROR;          return TCL_ERROR;
165      }      }
166      hwnd = (HWND) id;      hwnd = (HWND) id;
167    
168      /*      /*
169       * Check if the window is a valid handle. If it is invalid, return       * Check if the window is a valid handle. If it is invalid, return
170       * TCL_ERROR and potentially leave an error message in the interp's       * TCL_ERROR and potentially leave an error message in the interp's
171       * result.       * result.
172       */       */
173    
174      if (!IsWindow(hwnd)) {      if (!IsWindow(hwnd)) {
175          if (interp != (Tcl_Interp *) NULL) {          if (interp != (Tcl_Interp *) NULL) {
176              Tcl_AppendResult(interp, "window \"", string,              Tcl_AppendResult(interp, "window \"", string,
177                      "\" doesn't exist", (char *) NULL);                      "\" doesn't exist", (char *) NULL);
178          }          }
179          return TCL_ERROR;          return TCL_ERROR;
180      }      }
181    
182      /*      /*
183       * Store the parent window in the platform private data slot so       * Store the parent window in the platform private data slot so
184       * TkWmMapWindow can use it when creating the wrapper window.       * TkWmMapWindow can use it when creating the wrapper window.
185       */       */
186    
187      winPtr->privatePtr = (struct TkWindowPrivate*) hwnd;      winPtr->privatePtr = (struct TkWindowPrivate*) hwnd;
188    
189      /*      /*
190       * Create an event handler to clean up the Container structure when       * Create an event handler to clean up the Container structure when
191       * tkwin is eventually deleted.       * tkwin is eventually deleted.
192       */       */
193    
194      Tk_CreateEventHandler(tkwin, StructureNotifyMask, EmbeddedEventProc,      Tk_CreateEventHandler(tkwin, StructureNotifyMask, EmbeddedEventProc,
195              (ClientData) winPtr);              (ClientData) winPtr);
196    
197      /*      /*
198       * If this is the first container, register an exit handler so that       * If this is the first container, register an exit handler so that
199       * things will get cleaned up at finalization.       * things will get cleaned up at finalization.
200       */       */
201    
202      if (tsdPtr->firstContainerPtr == (Container *) NULL) {      if (tsdPtr->firstContainerPtr == (Container *) NULL) {
203          Tcl_CreateExitHandler(CleanupContainerList, (ClientData) NULL);          Tcl_CreateExitHandler(CleanupContainerList, (ClientData) NULL);
204      }      }
205            
206      /*      /*
207       * Save information about the container and the embedded window       * Save information about the container and the embedded window
208       * in a Container structure.  If there is already an existing       * in a Container structure.  If there is already an existing
209       * Container structure, it means that both container and embedded       * Container structure, it means that both container and embedded
210       * app. are in the same process.       * app. are in the same process.
211       */       */
212    
213      for (containerPtr = tsdPtr->firstContainerPtr;      for (containerPtr = tsdPtr->firstContainerPtr;
214              containerPtr != NULL; containerPtr = containerPtr->nextPtr) {              containerPtr != NULL; containerPtr = containerPtr->nextPtr) {
215          if (containerPtr->parentHWnd == hwnd) {          if (containerPtr->parentHWnd == hwnd) {
216              winPtr->flags |= TK_BOTH_HALVES;              winPtr->flags |= TK_BOTH_HALVES;
217              containerPtr->parentPtr->flags |= TK_BOTH_HALVES;              containerPtr->parentPtr->flags |= TK_BOTH_HALVES;
218              break;              break;
219          }          }
220      }      }
221      if (containerPtr == NULL) {      if (containerPtr == NULL) {
222          containerPtr = (Container *) ckalloc(sizeof(Container));          containerPtr = (Container *) ckalloc(sizeof(Container));
223          containerPtr->parentPtr = NULL;          containerPtr->parentPtr = NULL;
224          containerPtr->parentHWnd = hwnd;          containerPtr->parentHWnd = hwnd;
225          containerPtr->nextPtr = tsdPtr->firstContainerPtr;          containerPtr->nextPtr = tsdPtr->firstContainerPtr;
226          tsdPtr->firstContainerPtr = containerPtr;          tsdPtr->firstContainerPtr = containerPtr;
227      }      }
228    
229      /*      /*
230       * embeddedHWnd is not created yet. It will be created by TkWmMapWindow(),       * embeddedHWnd is not created yet. It will be created by TkWmMapWindow(),
231       * which will send a TK_ATTACHWINDOW to the container window.       * which will send a TK_ATTACHWINDOW to the container window.
232       * TkWinEmbeddedEventProc will process this message and set the embeddedHWnd       * TkWinEmbeddedEventProc will process this message and set the embeddedHWnd
233       * variable       * variable
234       */       */
235    
236      containerPtr->embeddedPtr = winPtr;      containerPtr->embeddedPtr = winPtr;
237      containerPtr->embeddedHWnd = NULL;      containerPtr->embeddedHWnd = NULL;
238    
239      winPtr->flags |= TK_EMBEDDED;      winPtr->flags |= TK_EMBEDDED;
240      winPtr->flags &= (~(TK_MAPPED));      winPtr->flags &= (~(TK_MAPPED));
241    
242      return TCL_OK;      return TCL_OK;
243  }  }
244    
245  /*  /*
246   *----------------------------------------------------------------------   *----------------------------------------------------------------------
247   *   *
248   * TkpMakeContainer --   * TkpMakeContainer --
249   *   *
250   *      This procedure is called to indicate that a particular window will   *      This procedure is called to indicate that a particular window will
251   *      be a container for an embedded application. This changes certain   *      be a container for an embedded application. This changes certain
252   *      aspects of the window's behavior, such as whether it will receive   *      aspects of the window's behavior, such as whether it will receive
253   *      events anymore.   *      events anymore.
254   *   *
255   * Results:   * Results:
256   *      None.   *      None.
257   *   *
258   * Side effects:   * Side effects:
259   *      None.   *      None.
260   *   *
261   *----------------------------------------------------------------------   *----------------------------------------------------------------------
262   */   */
263    
264  void  void
265  TkpMakeContainer(tkwin)  TkpMakeContainer(tkwin)
266      Tk_Window tkwin;      Tk_Window tkwin;
267  {  {
268      TkWindow *winPtr = (TkWindow *) tkwin;      TkWindow *winPtr = (TkWindow *) tkwin;
269      Container *containerPtr;      Container *containerPtr;
270      ThreadSpecificData *tsdPtr = (ThreadSpecificData *)      ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
271              Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));              Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
272    
273      /*      /*
274       * If this is the first container, register an exit handler so that       * If this is the first container, register an exit handler so that
275       * things will get cleaned up at finalization.       * things will get cleaned up at finalization.
276       */       */
277    
278      if (tsdPtr->firstContainerPtr == (Container *) NULL) {      if (tsdPtr->firstContainerPtr == (Container *) NULL) {
279          Tcl_CreateExitHandler(CleanupContainerList, (ClientData) NULL);          Tcl_CreateExitHandler(CleanupContainerList, (ClientData) NULL);
280      }      }
281            
282      /*      /*
283       * Register the window as a container so that, for example, we can       * Register the window as a container so that, for example, we can
284       * find out later if the embedded app. is in the same process.       * find out later if the embedded app. is in the same process.
285       */       */
286    
287      Tk_MakeWindowExist(tkwin);      Tk_MakeWindowExist(tkwin);
288      containerPtr = (Container *) ckalloc(sizeof(Container));      containerPtr = (Container *) ckalloc(sizeof(Container));
289      containerPtr->parentPtr = winPtr;      containerPtr->parentPtr = winPtr;
290      containerPtr->parentHWnd = Tk_GetHWND(Tk_WindowId(tkwin));      containerPtr->parentHWnd = Tk_GetHWND(Tk_WindowId(tkwin));
291      containerPtr->embeddedHWnd = NULL;      containerPtr->embeddedHWnd = NULL;
292      containerPtr->embeddedPtr = NULL;      containerPtr->embeddedPtr = NULL;
293      containerPtr->nextPtr = tsdPtr->firstContainerPtr;      containerPtr->nextPtr = tsdPtr->firstContainerPtr;
294      tsdPtr->firstContainerPtr = containerPtr;      tsdPtr->firstContainerPtr = containerPtr;
295      winPtr->flags |= TK_CONTAINER;      winPtr->flags |= TK_CONTAINER;
296    
297      /*      /*
298       * Unlike in tkUnixEmbed.c, we don't make any requests for events       * Unlike in tkUnixEmbed.c, we don't make any requests for events
299       * in the embedded window here.  Now we just allow the embedding       * in the embedded window here.  Now we just allow the embedding
300       * of another TK application into TK windows. When the embedded       * of another TK application into TK windows. When the embedded
301       * window makes a request, that will be done by sending to the       * window makes a request, that will be done by sending to the
302       * container window a WM_USER message, which will be intercepted       * container window a WM_USER message, which will be intercepted
303       * by TkWinContainerProc.       * by TkWinContainerProc.
304       *       *
305       * We need to get structure events of the container itself, though.       * We need to get structure events of the container itself, though.
306       */       */
307    
308      Tk_CreateEventHandler(tkwin, StructureNotifyMask,      Tk_CreateEventHandler(tkwin, StructureNotifyMask,
309          ContainerEventProc, (ClientData) containerPtr);          ContainerEventProc, (ClientData) containerPtr);
310  }  }
311    
312  /*  /*
313   *----------------------------------------------------------------------   *----------------------------------------------------------------------
314   *   *
315   * EmbeddedEventProc --   * EmbeddedEventProc --
316   *   *
317   *      This procedure is invoked by the Tk event dispatcher when various   *      This procedure is invoked by the Tk event dispatcher when various
318   *      useful events are received for a window that is embedded in   *      useful events are received for a window that is embedded in
319   *      another application.   *      another application.
320   *   *
321   * Results:   * Results:
322   *      None.   *      None.
323   *   *
324   * Side effects:   * Side effects:
325   *      Our internal state gets cleaned up when an embedded window is   *      Our internal state gets cleaned up when an embedded window is
326   *      destroyed.   *      destroyed.
327   *   *
328   *----------------------------------------------------------------------   *----------------------------------------------------------------------
329   */   */
330    
331  static void  static void
332  EmbeddedEventProc(clientData, eventPtr)  EmbeddedEventProc(clientData, eventPtr)
333      ClientData clientData;              /* Token for container window. */      ClientData clientData;              /* Token for container window. */
334      XEvent *eventPtr;                   /* ResizeRequest event. */      XEvent *eventPtr;                   /* ResizeRequest event. */
335  {  {
336      TkWindow *winPtr = (TkWindow *) clientData;      TkWindow *winPtr = (TkWindow *) clientData;
337    
338      if (eventPtr->type == DestroyNotify) {      if (eventPtr->type == DestroyNotify) {
339          EmbedWindowDeleted(winPtr);          EmbedWindowDeleted(winPtr);
340      }      }
341  }  }
342    
343  /*  /*
344   *----------------------------------------------------------------------   *----------------------------------------------------------------------
345   *   *
346   * TkWinEmbeddedEventProc --   * TkWinEmbeddedEventProc --
347   *   *
348   *      This procedure is invoked by the Tk event dispatcher when   *      This procedure is invoked by the Tk event dispatcher when
349   *      various useful events are received for the *children* of a   *      various useful events are received for the *children* of a
350   *      container window. It forwards relevant information, such as   *      container window. It forwards relevant information, such as
351   *      geometry requests, from the events into the container's   *      geometry requests, from the events into the container's
352   *      application.   *      application.
353   *   *
354   * Results:   * Results:
355   *      None.   *      None.
356   *   *
357   * Side effects:   * Side effects:
358   *      Depends on the event.  For example, when ConfigureRequest events   *      Depends on the event.  For example, when ConfigureRequest events
359   *      occur, geometry information gets set for the container window.   *      occur, geometry information gets set for the container window.
360   *   *
361   *----------------------------------------------------------------------   *----------------------------------------------------------------------
362   */   */
363    
364  LRESULT  LRESULT
365  TkWinEmbeddedEventProc(hwnd, message, wParam, lParam)  TkWinEmbeddedEventProc(hwnd, message, wParam, lParam)
366      HWND hwnd;      HWND hwnd;
367      UINT message;      UINT message;
368      WPARAM wParam;      WPARAM wParam;
369      LPARAM lParam;      LPARAM lParam;
370  {  {
371      Container *containerPtr;      Container *containerPtr;
372      ThreadSpecificData *tsdPtr = (ThreadSpecificData *)      ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
373              Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));              Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
374    
375      /*      /*
376       * Find the Container structure associated with the parent window.       * Find the Container structure associated with the parent window.
377       */       */
378    
379      for (containerPtr = tsdPtr->firstContainerPtr;      for (containerPtr = tsdPtr->firstContainerPtr;
380              containerPtr->parentHWnd != hwnd;              containerPtr->parentHWnd != hwnd;
381              containerPtr = containerPtr->nextPtr) {              containerPtr = containerPtr->nextPtr) {
382          if (containerPtr == NULL) {          if (containerPtr == NULL) {
383              panic("TkWinContainerProc couldn't find Container record");              panic("TkWinContainerProc couldn't find Container record");
384          }          }
385      }      }
386    
387      switch (message) {      switch (message) {
388        case TK_ATTACHWINDOW:        case TK_ATTACHWINDOW:
389          /* An embedded window (either from this application or from          /* An embedded window (either from this application or from
390           * another application) is trying to attach to this container.           * another application) is trying to attach to this container.
391           * We attach it only if this container is not yet containing any           * We attach it only if this container is not yet containing any
392           * window.           * window.
393           */           */
394          if (containerPtr->embeddedHWnd == NULL) {          if (containerPtr->embeddedHWnd == NULL) {
395              containerPtr->embeddedHWnd = (HWND)wParam;              containerPtr->embeddedHWnd = (HWND)wParam;
396          } else {          } else {
397              return 0;              return 0;
398          }          }
399    
400          break;          break;
401        case TK_GEOMETRYREQ:        case TK_GEOMETRYREQ:
402          EmbedGeometryRequest(containerPtr, wParam, lParam);          EmbedGeometryRequest(containerPtr, wParam, lParam);
403          break;          break;
404      }      }
405      return 1;      return 1;
406  }  }
407    
408  /*  /*
409   *----------------------------------------------------------------------   *----------------------------------------------------------------------
410   *   *
411   * EmbedGeometryRequest --   * EmbedGeometryRequest --
412   *   *
413   *      This procedure is invoked when an embedded application requests   *      This procedure is invoked when an embedded application requests
414   *      a particular size.  It processes the request (which may or may   *      a particular size.  It processes the request (which may or may
415   *      not actually resize the window) and reflects the results back   *      not actually resize the window) and reflects the results back
416   *      to the embedded application.   *      to the embedded application.
417   *   *
418   * Results:   * Results:
419   *      None.   *      None.
420   *   *
421   * Side effects:   * Side effects:
422   *      If we deny the child's size change request, a Configure event   *      If we deny the child's size change request, a Configure event
423   *      is synthesized to let the child know that the size is the same   *      is synthesized to let the child know that the size is the same
424   *      as it used to be.  Events get processed while we're waiting for   *      as it used to be.  Events get processed while we're waiting for
425   *      the geometry managers to do their thing.   *      the geometry managers to do their thing.
426   *   *
427   *----------------------------------------------------------------------   *----------------------------------------------------------------------
428   */   */
429    
430  void  void
431  EmbedGeometryRequest(containerPtr, width, height)  EmbedGeometryRequest(containerPtr, width, height)
432      Container *containerPtr;    /* Information about the container window. */      Container *containerPtr;    /* Information about the container window. */
433      int width, height;          /* Size that the child has requested. */      int width, height;          /* Size that the child has requested. */
434  {  {
435      TkWindow * winPtr = containerPtr->parentPtr;      TkWindow * winPtr = containerPtr->parentPtr;
436            
437      /*      /*
438       * Forward the requested size into our geometry management hierarchy       * Forward the requested size into our geometry management hierarchy
439       * via the container window.  We need to send a Configure event back       * via the container window.  We need to send a Configure event back
440       * to the embedded application even if we decide not to resize       * to the embedded application even if we decide not to resize
441       * the window;  to make this happen, process all idle event handlers       * the window;  to make this happen, process all idle event handlers
442       * synchronously here (so that the geometry managers have had a       * synchronously here (so that the geometry managers have had a
443       * chance to do whatever they want to do), and if the window's size       * chance to do whatever they want to do), and if the window's size
444       * didn't change then generate a configure event.       * didn't change then generate a configure event.
445       */       */
446      Tk_GeometryRequest((Tk_Window)winPtr, width, height);      Tk_GeometryRequest((Tk_Window)winPtr, width, height);
447    
448      if (containerPtr->embeddedHWnd != NULL) {      if (containerPtr->embeddedHWnd != NULL) {
449          while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {          while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {
450              /* Empty loop body. */              /* Empty loop body. */
451          }          }
452    
453          SetWindowPos(containerPtr->embeddedHWnd, NULL,          SetWindowPos(containerPtr->embeddedHWnd, NULL,
454              0, 0, winPtr->changes.width, winPtr->changes.height, SWP_NOZORDER);              0, 0, winPtr->changes.width, winPtr->changes.height, SWP_NOZORDER);
455      }      }
456  }  }
457    
458  /*  /*
459   *----------------------------------------------------------------------   *----------------------------------------------------------------------
460   *   *
461   * ContainerEventProc --   * ContainerEventProc --
462   *   *
463   *      This procedure is invoked by the Tk event dispatcher when   *      This procedure is invoked by the Tk event dispatcher when
464   *      various useful events are received for the container window.   *      various useful events are received for the container window.
465   *   *
466   * Results:   * Results:
467   *      None.   *      None.
468   *   *
469   * Side effects:   * Side effects:
470   *      Depends on the event.  For example, when ConfigureRequest events   *      Depends on the event.  For example, when ConfigureRequest events
471   *      occur, geometry information gets set for the container window.   *      occur, geometry information gets set for the container window.
472   *   *
473   *----------------------------------------------------------------------   *----------------------------------------------------------------------
474   */   */
475    
476  static void  static void
477  ContainerEventProc(clientData, eventPtr)  ContainerEventProc(clientData, eventPtr)
478      ClientData clientData;              /* Token for container window. */      ClientData clientData;              /* Token for container window. */
479      XEvent *eventPtr;                   /* ResizeRequest event. */      XEvent *eventPtr;                   /* ResizeRequest event. */
480  {  {
481      Container *containerPtr = (Container *)clientData;      Container *containerPtr = (Container *)clientData;
482      Tk_Window tkwin = (Tk_Window)containerPtr->parentPtr;      Tk_Window tkwin = (Tk_Window)containerPtr->parentPtr;
483    
484      if (eventPtr->type == ConfigureNotify) {      if (eventPtr->type == ConfigureNotify) {
485          if (containerPtr->embeddedPtr == NULL) {          if (containerPtr->embeddedPtr == NULL) {
486              return;              return;
487          }          }
488          /* Resize the embedded window, if there is any */          /* Resize the embedded window, if there is any */
489          if (containerPtr->embeddedHWnd) {          if (containerPtr->embeddedHWnd) {
490              SetWindowPos(containerPtr->embeddedHWnd, NULL,              SetWindowPos(containerPtr->embeddedHWnd, NULL,
491                  0, 0, Tk_Width(tkwin), Tk_Height(tkwin), SWP_NOZORDER);                  0, 0, Tk_Width(tkwin), Tk_Height(tkwin), SWP_NOZORDER);
492          }          }
493      } else if (eventPtr->type == DestroyNotify) {      } else if (eventPtr->type == DestroyNotify) {
494          /* The container is gone, remove it from the list */          /* The container is gone, remove it from the list */
495          EmbedWindowDeleted(containerPtr->parentPtr);          EmbedWindowDeleted(containerPtr->parentPtr);
496      }      }
497  }  }
498    
499  /*  /*
500   *----------------------------------------------------------------------   *----------------------------------------------------------------------
501   *   *
502   * TkpGetOtherWindow --   * TkpGetOtherWindow --
503   *   *
504   *      If both the container and embedded window are in the same   *      If both the container and embedded window are in the same
505   *      process, this procedure will return either one, given the other.   *      process, this procedure will return either one, given the other.
506   *   *
507   * Results:   * Results:
508   *      If winPtr is a container, the return value is the token for the   *      If winPtr is a container, the return value is the token for the
509   *      embedded window, and vice versa.  If the "other" window isn't in   *      embedded window, and vice versa.  If the "other" window isn't in
510   *      this process, NULL is returned.   *      this process, NULL is returned.
511   *   *
512   * Side effects:   * Side effects:
513   *      None.   *      None.
514   *   *
515   *----------------------------------------------------------------------   *----------------------------------------------------------------------
516   */   */
517    
518  TkWindow *  TkWindow *
519  TkpGetOtherWindow(winPtr)  TkpGetOtherWindow(winPtr)
520      TkWindow *winPtr;           /* Tk's structure for a container or      TkWindow *winPtr;           /* Tk's structure for a container or
521                                   * embedded window. */                                   * embedded window. */
522  {  {
523      Container *containerPtr;      Container *containerPtr;
524      ThreadSpecificData *tsdPtr = (ThreadSpecificData *)      ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
525              Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));              Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
526    
527      for (containerPtr = tsdPtr->firstContainerPtr; containerPtr != NULL;      for (containerPtr = tsdPtr->firstContainerPtr; containerPtr != NULL;
528              containerPtr = containerPtr->nextPtr) {              containerPtr = containerPtr->nextPtr) {
529          if (containerPtr->embeddedPtr == winPtr) {          if (containerPtr->embeddedPtr == winPtr) {
530              return containerPtr->parentPtr;              return containerPtr->parentPtr;
531          } else if (containerPtr->parentPtr == winPtr) {          } else if (containerPtr->parentPtr == winPtr) {
532              return containerPtr->embeddedPtr;              return containerPtr->embeddedPtr;
533          }          }
534      }      }
535      panic("TkpGetOtherWindow couldn't find window");      panic("TkpGetOtherWindow couldn't find window");
536      return NULL;      return NULL;
537  }  }
538    
539  /*  /*
540   *----------------------------------------------------------------------   *----------------------------------------------------------------------
541   *   *
542   * TkpClaimFocus --   * TkpClaimFocus --
543   *   *
544   *      This procedure is invoked when someone asks or the input focus   *      This procedure is invoked when someone asks or the input focus
545   *      to be put on a window in an embedded application, but the   *      to be put on a window in an embedded application, but the
546   *      application doesn't currently have the focus.  It requests the   *      application doesn't currently have the focus.  It requests the
547   *      input focus from the container application.   *      input focus from the container application.
548   *   *
549   * Results:   * Results:
550   *      None.   *      None.
551   *   *
552   * Side effects:   * Side effects:
553   *      The input focus may change.   *      The input focus may change.
554   *   *
555   *----------------------------------------------------------------------   *----------------------------------------------------------------------
556   */   */
557    
558  void  void
559  TkpClaimFocus(topLevelPtr, force)  TkpClaimFocus(topLevelPtr, force)
560      TkWindow *topLevelPtr;              /* Top-level window containing desired      TkWindow *topLevelPtr;              /* Top-level window containing desired
561                                           * focus window; should be embedded. */                                           * focus window; should be embedded. */
562      int force;                          /* One means that the container should      int force;                          /* One means that the container should
563                                           * claim the focus if it doesn't                                           * claim the focus if it doesn't
564                                           * currently have it. */                                           * currently have it. */
565  {  {
566      HWND hwnd = GetParent(Tk_GetHWND(topLevelPtr->window));      HWND hwnd = GetParent(Tk_GetHWND(topLevelPtr->window));
567      SendMessage(hwnd, TK_CLAIMFOCUS, (WPARAM) force, 0);      SendMessage(hwnd, TK_CLAIMFOCUS, (WPARAM) force, 0);
568  }  }
569    
570  /*  /*
571   *----------------------------------------------------------------------   *----------------------------------------------------------------------
572   *   *
573   * TkpRedirectKeyEvent --   * TkpRedirectKeyEvent --
574   *   *
575   *      This procedure is invoked when a key press or release event   *      This procedure is invoked when a key press or release event
576   *      arrives for an application that does not believe it owns the   *      arrives for an application that does not believe it owns the
577   *      input focus.  This can happen because of embedding; for example,   *      input focus.  This can happen because of embedding; for example,
578   *      X can send an event to an embedded application when the real   *      X can send an event to an embedded application when the real
579   *      focus window is in the container application and is an ancestor   *      focus window is in the container application and is an ancestor
580   *      of the container.  This procedure's job is to forward the event   *      of the container.  This procedure's job is to forward the event
581   *      back to the application where it really belongs.   *      back to the application where it really belongs.
582   *   *
583   * Results:   * Results:
584   *      None.   *      None.
585   *   *
586   * Side effects:   * Side effects:
587   *      The event may get sent to a different application.   *      The event may get sent to a different application.
588   *   *
589   *----------------------------------------------------------------------   *----------------------------------------------------------------------
590   */   */
591    
592  void  void
593  TkpRedirectKeyEvent(winPtr, eventPtr)  TkpRedirectKeyEvent(winPtr, eventPtr)
594      TkWindow *winPtr;           /* Window to which the event was originally      TkWindow *winPtr;           /* Window to which the event was originally
595                                   * reported. */                                   * reported. */
596      XEvent *eventPtr;           /* X event to redirect (should be KeyPress      XEvent *eventPtr;           /* X event to redirect (should be KeyPress
597                                   * or KeyRelease). */                                   * or KeyRelease). */
598  {  {
599      /* not implemented */      /* not implemented */
600  }  }
601    
602  /*  /*
603   *----------------------------------------------------------------------   *----------------------------------------------------------------------
604   *   *
605   * EmbedWindowDeleted --   * EmbedWindowDeleted --
606   *   *
607   *      This procedure is invoked when a window involved in embedding   *      This procedure is invoked when a window involved in embedding
608   *      (as either the container or the embedded application) is   *      (as either the container or the embedded application) is
609   *      destroyed.  It cleans up the Container structure for the window.   *      destroyed.  It cleans up the Container structure for the window.
610   *   *
611   * Results:   * Results:
612   *      None.   *      None.
613   *   *
614   * Side effects:   * Side effects:
615   *      A Container structure may be freed.   *      A Container structure may be freed.
616   *   *
617   *----------------------------------------------------------------------   *----------------------------------------------------------------------
618   */   */
619    
620  static void  static void
621  EmbedWindowDeleted(winPtr)  EmbedWindowDeleted(winPtr)
622      TkWindow *winPtr;           /* Tk's information about window that      TkWindow *winPtr;           /* Tk's information about window that
623                                   * was deleted. */                                   * was deleted. */
624  {  {
625      Container *containerPtr, *prevPtr;      Container *containerPtr, *prevPtr;
626      ThreadSpecificData *tsdPtr = (ThreadSpecificData *)      ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
627              Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));              Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
628    
629      /*      /*
630       * Find the Container structure for this window work.  Delete the       * Find the Container structure for this window work.  Delete the
631       * information about the embedded application and free the container's       * information about the embedded application and free the container's
632       * record.       * record.
633       */       */
634    
635      prevPtr = NULL;      prevPtr = NULL;
636      containerPtr = tsdPtr->firstContainerPtr;      containerPtr = tsdPtr->firstContainerPtr;
637      while (1) {      while (1) {
638          if (containerPtr->embeddedPtr == winPtr) {          if (containerPtr->embeddedPtr == winPtr) {
639              containerPtr->embeddedHWnd = NULL;              containerPtr->embeddedHWnd = NULL;
640              containerPtr->embeddedPtr = NULL;              containerPtr->embeddedPtr = NULL;
641              break;              break;
642          }          }
643          if (containerPtr->parentPtr == winPtr) {          if (containerPtr->parentPtr == winPtr) {
644              containerPtr->parentPtr = NULL;              containerPtr->parentPtr = NULL;
645              break;              break;
646          }          }
647          prevPtr = containerPtr;          prevPtr = containerPtr;
648          containerPtr = containerPtr->nextPtr;          containerPtr = containerPtr->nextPtr;
649          if (containerPtr == NULL) {          if (containerPtr == NULL) {
650              panic("EmbedWindowDeleted couldn't find window");              panic("EmbedWindowDeleted couldn't find window");
651          }          }
652      }      }
653      if ((containerPtr->embeddedPtr == NULL)      if ((containerPtr->embeddedPtr == NULL)
654              && (containerPtr->parentPtr == NULL)) {              && (containerPtr->parentPtr == NULL)) {
655          if (prevPtr == NULL) {          if (prevPtr == NULL) {
656              tsdPtr->firstContainerPtr = containerPtr->nextPtr;              tsdPtr->firstContainerPtr = containerPtr->nextPtr;
657          } else {          } else {
658              prevPtr->nextPtr = containerPtr->nextPtr;              prevPtr->nextPtr = containerPtr->nextPtr;
659          }          }
660          ckfree((char *) containerPtr);          ckfree((char *) containerPtr);
661      }      }
662  }  }
663    
664  /* End of tkwinembed.c */  /* End of tkwinembed.c */

Legend:
Removed from v.69  
changed lines
  Added in v.71

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25