/[dtapublic]/projs/trunk/shared_source/tk_base/tkwinwindow.c
ViewVC logotype

Contents of /projs/trunk/shared_source/tk_base/tkwinwindow.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 42 - (show annotations) (download)
Fri Oct 14 01:50:00 2016 UTC (7 years, 5 months ago) by dashley
File MIME type: text/plain
File size: 20373 byte(s)
Move shared source code to commonize.
1 /* $Header: /cvsroot/esrg/sfesrg/esrgpcpj/shared/tk_base/tkwinwindow.c,v 1.1.1.1 2001/06/13 05:14:28 dtashley Exp $ */
2
3 /*
4 * tkWinWindow.c --
5 *
6 * Xlib emulation routines for Windows related to creating,
7 * displaying and destroying windows.
8 *
9 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
10 *
11 * See the file "license.terms" for information on usage and redistribution
12 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13 *
14 * RCS: @(#) $Id: tkwinwindow.c,v 1.1.1.1 2001/06/13 05:14:28 dtashley Exp $
15 */
16
17 #include "tkWinInt.h"
18
19 typedef struct ThreadSpecificData {
20 int initialized; /* 0 means table below needs initializing. */
21 Tcl_HashTable windowTable; /* The windowTable maps from HWND to
22 * Tk_Window handles. */
23 } ThreadSpecificData;
24 static Tcl_ThreadDataKey dataKey;
25
26 /*
27 * Forward declarations for procedures defined in this file:
28 */
29
30 static void NotifyVisibility _ANSI_ARGS_((XEvent *eventPtr,
31 TkWindow *winPtr));
32 static void StackWindow _ANSI_ARGS_((Window w, Window sibling,
33 int stack_mode));
34
35 /*
36 *----------------------------------------------------------------------
37 *
38 * Tk_AttachHWND --
39 *
40 * This function binds an HWND and a reflection procedure to
41 * the specified Tk_Window.
42 *
43 * Results:
44 * Returns an X Window that encapsulates the HWND.
45 *
46 * Side effects:
47 * May allocate a new X Window. Also enters the HWND into the
48 * global window table.
49 *
50 *----------------------------------------------------------------------
51 */
52
53 Window
54 Tk_AttachHWND(tkwin, hwnd)
55 Tk_Window tkwin;
56 HWND hwnd;
57 {
58 int new;
59 Tcl_HashEntry *entryPtr;
60 TkWinDrawable *twdPtr = (TkWinDrawable *) Tk_WindowId(tkwin);
61 ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
62 Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
63
64 if (!tsdPtr->initialized) {
65 Tcl_InitHashTable(&tsdPtr->windowTable, TCL_ONE_WORD_KEYS);
66 tsdPtr->initialized = 1;
67 }
68
69 /*
70 * Allocate a new drawable if necessary. Otherwise, remove the
71 * previous HWND from from the window table.
72 */
73
74 if (twdPtr == NULL) {
75 twdPtr = (TkWinDrawable*) ckalloc(sizeof(TkWinDrawable));
76 twdPtr->type = TWD_WINDOW;
77 twdPtr->window.winPtr = (TkWindow *) tkwin;
78 } else if (twdPtr->window.handle != NULL) {
79 entryPtr = Tcl_FindHashEntry(&tsdPtr->windowTable,
80 (char *)twdPtr->window.handle);
81 Tcl_DeleteHashEntry(entryPtr);
82 }
83
84 /*
85 * Insert the new HWND into the window table.
86 */
87
88 twdPtr->window.handle = hwnd;
89 entryPtr = Tcl_CreateHashEntry(&tsdPtr->windowTable, (char *)hwnd, &new);
90 Tcl_SetHashValue(entryPtr, (ClientData)tkwin);
91
92 return (Window)twdPtr;
93 }
94
95 /*
96 *----------------------------------------------------------------------
97 *
98 * Tk_HWNDToWindow --
99 *
100 * This function retrieves a Tk_Window from the window table
101 * given an HWND.
102 *
103 * Results:
104 * Returns the matching Tk_Window.
105 *
106 * Side effects:
107 * None.
108 *
109 *----------------------------------------------------------------------
110 */
111
112 Tk_Window
113 Tk_HWNDToWindow(hwnd)
114 HWND hwnd;
115 {
116 Tcl_HashEntry *entryPtr;
117 ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
118 Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
119
120 if (!tsdPtr->initialized) {
121 Tcl_InitHashTable(&tsdPtr->windowTable, TCL_ONE_WORD_KEYS);
122 tsdPtr->initialized = 1;
123 }
124 entryPtr = Tcl_FindHashEntry(&tsdPtr->windowTable, (char*)hwnd);
125 if (entryPtr != NULL) {
126 return (Tk_Window) Tcl_GetHashValue(entryPtr);
127 }
128 return NULL;
129 }
130
131 /*
132 *----------------------------------------------------------------------
133 *
134 * Tk_GetHWND --
135 *
136 * This function extracts the HWND from an X Window.
137 *
138 * Results:
139 * Returns the HWND associated with the Window.
140 *
141 * Side effects:
142 * None.
143 *
144 *----------------------------------------------------------------------
145 */
146
147 HWND
148 Tk_GetHWND(window)
149 Window window;
150 {
151 TkWinDrawable *twdPtr = (TkWinDrawable *) window;
152 return twdPtr->window.handle;
153 }
154
155 /*
156 *----------------------------------------------------------------------
157 *
158 * TkpPrintWindowId --
159 *
160 * This routine stores the string representation of the
161 * platform dependent window handle for an X Window in the
162 * given buffer.
163 *
164 * Results:
165 * Returns the result in the specified buffer.
166 *
167 * Side effects:
168 * None.
169 *
170 *----------------------------------------------------------------------
171 */
172
173 void
174 TkpPrintWindowId(buf, window)
175 char *buf; /* Pointer to string large enough to hold
176 * the hex representation of a pointer. */
177 Window window; /* Window to be printed into buffer. */
178 {
179 HWND hwnd = (window) ? Tk_GetHWND(window) : 0;
180 sprintf(buf, "0x%x", (unsigned int) hwnd);
181 }
182
183 /*
184 *----------------------------------------------------------------------
185 *
186 * TkpScanWindowId --
187 *
188 * Given a string which represents the platform dependent window
189 * handle, produce the X Window id for the window.
190 *
191 * Results:
192 * The return value is normally TCL_OK; in this case *idPtr
193 * will be set to the X Window id equivalent to string. If
194 * string is improperly formed then TCL_ERROR is returned and
195 * an error message will be left in the interp's result. If the
196 * number does not correspond to a Tk Window, then *idPtr will
197 * be set to None.
198 *
199 * Side effects:
200 * None.
201 *
202 *----------------------------------------------------------------------
203 */
204
205 int
206 TkpScanWindowId(interp, string, idPtr)
207 Tcl_Interp *interp; /* Interpreter to use for error reporting. */
208 char *string; /* String containing a (possibly signed)
209 * integer in a form acceptable to strtol. */
210 int *idPtr; /* Place to store converted result. */
211 {
212 int number;
213 Tk_Window tkwin;
214
215 if (Tcl_GetInt(interp, string, &number) != TCL_OK) {
216 return TCL_ERROR;
217 }
218 tkwin = Tk_HWNDToWindow((HWND)number);
219 if (tkwin) {
220 *idPtr = Tk_WindowId(tkwin);
221 } else {
222 *idPtr = None;
223 }
224 return TCL_OK;
225 }
226
227 /*
228 *----------------------------------------------------------------------
229 *
230 * TkpMakeWindow --
231 *
232 * Creates a Windows window object based on the current attributes
233 * of the specified TkWindow.
234 *
235 * Results:
236 * Returns a pointer to a new TkWinDrawable cast to a Window.
237 *
238 * Side effects:
239 * Creates a new window.
240 *
241 *----------------------------------------------------------------------
242 */
243
244 Window
245 TkpMakeWindow(winPtr, parent)
246 TkWindow *winPtr;
247 Window parent;
248 {
249 HWND parentWin;
250 int style;
251 HWND hwnd;
252
253 if (parent != None) {
254 parentWin = Tk_GetHWND(parent);
255 style = WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
256 } else {
257 parentWin = NULL;
258 style = WS_POPUP | WS_CLIPCHILDREN;
259 }
260
261 /*
262 * Create the window, then ensure that it is at the top of the
263 * stacking order.
264 */
265
266 hwnd = CreateWindowEx(WS_EX_NOPARENTNOTIFY, TK_WIN_CHILD_CLASS_NAME, NULL,
267 style, Tk_X(winPtr), Tk_Y(winPtr), Tk_Width(winPtr),
268 Tk_Height(winPtr), parentWin, NULL, Tk_GetHINSTANCE(), NULL);
269 SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0,
270 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
271 return Tk_AttachHWND((Tk_Window)winPtr, hwnd);
272 }
273
274 /*
275 *----------------------------------------------------------------------
276 *
277 * XDestroyWindow --
278 *
279 * Destroys the given window.
280 *
281 * Results:
282 * None.
283 *
284 * Side effects:
285 * Sends the WM_DESTROY message to the window and then destroys
286 * it the Win32 resources associated with the window.
287 *
288 *----------------------------------------------------------------------
289 */
290
291 void
292 XDestroyWindow(display, w)
293 Display* display;
294 Window w;
295 {
296 Tcl_HashEntry *entryPtr;
297 TkWinDrawable *twdPtr = (TkWinDrawable *)w;
298 TkWindow *winPtr = TkWinGetWinPtr(w);
299 HWND hwnd = Tk_GetHWND(w);
300 ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
301 Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
302
303 display->request++;
304
305 /*
306 * Remove references to the window in the pointer module then
307 * release the drawable.
308 */
309
310 TkPointerDeadWindow(winPtr);
311
312 entryPtr = Tcl_FindHashEntry(&tsdPtr->windowTable, (char*)hwnd);
313 if (entryPtr != NULL) {
314 Tcl_DeleteHashEntry(entryPtr);
315 }
316
317 ckfree((char *)twdPtr);
318
319 /*
320 * Don't bother destroying the window if we are going to destroy
321 * the parent later.
322 */
323
324 if (hwnd != NULL && !(winPtr->flags & TK_DONT_DESTROY_WINDOW)) {
325 DestroyWindow(hwnd);
326 }
327 }
328
329 /*
330 *----------------------------------------------------------------------
331 *
332 * XMapWindow --
333 *
334 * Cause the given window to become visible.
335 *
336 * Results:
337 * None
338 *
339 * Side effects:
340 * Causes the window state to change, and generates a MapNotify
341 * event.
342 *
343 *----------------------------------------------------------------------
344 */
345
346 void
347 XMapWindow(display, w)
348 Display* display;
349 Window w;
350 {
351 XEvent event;
352 TkWindow *parentPtr;
353 TkWindow *winPtr = TkWinGetWinPtr(w);
354
355 display->request++;
356
357 ShowWindow(TkWinGetHWND(w), SW_SHOWNORMAL);
358 winPtr->flags |= TK_MAPPED;
359
360 /*
361 * Check to see if this window is visible now. If all of the parent
362 * windows up to the first toplevel are mapped, then this window and
363 * its mapped children have just become visible.
364 */
365
366 if (!(winPtr->flags & TK_TOP_LEVEL)) {
367 for (parentPtr = winPtr->parentPtr; ;
368 parentPtr = parentPtr->parentPtr) {
369 if ((parentPtr == NULL) || !(parentPtr->flags & TK_MAPPED)) {
370 return;
371 }
372 if (parentPtr->flags & TK_TOP_LEVEL) {
373 break;
374 }
375 }
376 } else {
377 event.type = MapNotify;
378 event.xmap.serial = display->request;
379 event.xmap.send_event = False;
380 event.xmap.display = display;
381 event.xmap.event = winPtr->window;
382 event.xmap.window = winPtr->window;
383 event.xmap.override_redirect = winPtr->atts.override_redirect;
384 Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
385 }
386
387 /*
388 * Generate VisibilityNotify events for this window and its mapped
389 * children.
390 */
391
392 event.type = VisibilityNotify;
393 event.xvisibility.serial = display->request;
394 event.xvisibility.send_event = False;
395 event.xvisibility.display = display;
396 event.xvisibility.window = winPtr->window;
397 event.xvisibility.state = VisibilityUnobscured;
398 NotifyVisibility(&event, winPtr);
399 }
400
401 /*
402 *----------------------------------------------------------------------
403 *
404 * NotifyVisibility --
405 *
406 * This function recursively notifies the mapped children of the
407 * specified window of a change in visibility. Note that we don't
408 * properly report the visibility state, since Windows does not
409 * provide that info. The eventPtr argument must point to an event
410 * that has been completely initialized except for the window slot.
411 *
412 * Results:
413 * None.
414 *
415 * Side effects:
416 * Generates lots of events.
417 *
418 *----------------------------------------------------------------------
419 */
420
421 static void
422 NotifyVisibility(eventPtr, winPtr)
423 XEvent *eventPtr; /* Initialized VisibilityNotify event. */
424 TkWindow *winPtr; /* Window to notify. */
425 {
426 if (winPtr->atts.event_mask & VisibilityChangeMask) {
427 eventPtr->xvisibility.window = winPtr->window;
428 Tk_QueueWindowEvent(eventPtr, TCL_QUEUE_TAIL);
429 }
430 for (winPtr = winPtr->childList; winPtr != NULL;
431 winPtr = winPtr->nextPtr) {
432 if (winPtr->flags & TK_MAPPED) {
433 NotifyVisibility(eventPtr, winPtr);
434 }
435 }
436 }
437
438 /*
439 *----------------------------------------------------------------------
440 *
441 * XUnmapWindow --
442 *
443 * Cause the given window to become invisible.
444 *
445 * Results:
446 * None
447 *
448 * Side effects:
449 * Causes the window state to change, and generates an UnmapNotify
450 * event.
451 *
452 *----------------------------------------------------------------------
453 */
454
455 void
456 XUnmapWindow(display, w)
457 Display* display;
458 Window w;
459 {
460 XEvent event;
461 TkWindow *winPtr = TkWinGetWinPtr(w);
462
463 display->request++;
464
465 /*
466 * Bug fix: Don't short circuit this routine based on TK_MAPPED because
467 * it will be cleared before XUnmapWindow is called.
468 */
469
470 ShowWindow(TkWinGetHWND(w), SW_HIDE);
471 winPtr->flags &= ~TK_MAPPED;
472
473 if (winPtr->flags & TK_TOP_LEVEL) {
474 event.type = UnmapNotify;
475 event.xunmap.serial = display->request;
476 event.xunmap.send_event = False;
477 event.xunmap.display = display;
478 event.xunmap.event = winPtr->window;
479 event.xunmap.window = winPtr->window;
480 event.xunmap.from_configure = False;
481 Tk_HandleEvent(&event);
482 }
483 }
484
485 /*
486 *----------------------------------------------------------------------
487 *
488 * XMoveResizeWindow --
489 *
490 * Move and resize a window relative to its parent.
491 *
492 * Results:
493 * None.
494 *
495 * Side effects:
496 * Repositions and resizes the specified window.
497 *
498 *----------------------------------------------------------------------
499 */
500
501 void
502 XMoveResizeWindow(display, w, x, y, width, height)
503 Display* display;
504 Window w;
505 int x; /* Position relative to parent. */
506 int y;
507 unsigned int width;
508 unsigned int height;
509 {
510 display->request++;
511 MoveWindow(TkWinGetHWND(w), x, y, width, height, TRUE);
512 }
513
514 /*
515 *----------------------------------------------------------------------
516 *
517 * XMoveWindow --
518 *
519 * Move a window relative to its parent.
520 *
521 * Results:
522 * None.
523 *
524 * Side effects:
525 * Repositions the specified window.
526 *
527 *----------------------------------------------------------------------
528 */
529
530 void
531 XMoveWindow(display, w, x, y)
532 Display* display;
533 Window w;
534 int x;
535 int y;
536 {
537 TkWindow *winPtr = TkWinGetWinPtr(w);
538
539 display->request++;
540
541 MoveWindow(TkWinGetHWND(w), x, y, winPtr->changes.width,
542 winPtr->changes.height, TRUE);
543 }
544
545 /*
546 *----------------------------------------------------------------------
547 *
548 * XResizeWindow --
549 *
550 * Resize a window.
551 *
552 * Results:
553 * None.
554 *
555 * Side effects:
556 * Resizes the specified window.
557 *
558 *----------------------------------------------------------------------
559 */
560
561 void
562 XResizeWindow(display, w, width, height)
563 Display* display;
564 Window w;
565 unsigned int width;
566 unsigned int height;
567 {
568 TkWindow *winPtr = TkWinGetWinPtr(w);
569
570 display->request++;
571
572 MoveWindow(TkWinGetHWND(w), winPtr->changes.x, winPtr->changes.y, width,
573 height, TRUE);
574 }
575
576 /*
577 *----------------------------------------------------------------------
578 *
579 * XRaiseWindow --
580 *
581 * Change the stacking order of a window.
582 *
583 * Results:
584 * None.
585 *
586 * Side effects:
587 * Changes the stacking order of the specified window.
588 *
589 *----------------------------------------------------------------------
590 */
591
592 void
593 XRaiseWindow(display, w)
594 Display* display;
595 Window w;
596 {
597 HWND window = TkWinGetHWND(w);
598
599 display->request++;
600 SetWindowPos(window, HWND_TOPMOST, 0, 0, 0, 0,
601 SWP_NOMOVE | SWP_NOSIZE);
602 }
603
604 /*
605 *----------------------------------------------------------------------
606 *
607 * XConfigureWindow --
608 *
609 * Change the size, position, stacking, or border of the specified
610 * window.
611 *
612 * Results:
613 * None.
614 *
615 * Side effects:
616 * Changes the attributes of the specified window. Note that we
617 * ignore the passed in values and use the values stored in the
618 * TkWindow data structure.
619 *
620 *----------------------------------------------------------------------
621 */
622
623 void
624 XConfigureWindow(display, w, value_mask, values)
625 Display* display;
626 Window w;
627 unsigned int value_mask;
628 XWindowChanges* values;
629 {
630 TkWindow *winPtr = TkWinGetWinPtr(w);
631 HWND hwnd = TkWinGetHWND(w);
632
633 display->request++;
634
635 /*
636 * Change the shape and/or position of the window.
637 */
638
639 if (value_mask & (CWX|CWY|CWWidth|CWHeight)) {
640 MoveWindow(hwnd, winPtr->changes.x, winPtr->changes.y,
641 winPtr->changes.width, winPtr->changes.height, TRUE);
642 }
643
644 /*
645 * Change the stacking order of the window.
646 */
647
648 if (value_mask & CWStackMode) {
649 HWND sibling;
650 if ((value_mask & CWSibling) && (values->sibling != None)) {
651 sibling = Tk_GetHWND(values->sibling);
652 } else {
653 sibling = NULL;
654 }
655 TkWinSetWindowPos(hwnd, sibling, values->stack_mode);
656 }
657 }
658
659 /*
660 *----------------------------------------------------------------------
661 *
662 * XClearWindow --
663 *
664 * Clears the entire window to the current background color.
665 *
666 * Results:
667 * None.
668 *
669 * Side effects:
670 * Erases the current contents of the window.
671 *
672 *----------------------------------------------------------------------
673 */
674
675 void
676 XClearWindow(display, w)
677 Display* display;
678 Window w;
679 {
680 RECT rc;
681 HBRUSH brush;
682 HPALETTE oldPalette, palette;
683 TkWindow *winPtr;
684 HWND hwnd = TkWinGetHWND(w);
685 HDC dc = GetDC(hwnd);
686
687 palette = TkWinGetPalette(display->screens[0].cmap);
688 oldPalette = SelectPalette(dc, palette, FALSE);
689
690 display->request++;
691
692 winPtr = TkWinGetWinPtr(w);
693 brush = CreateSolidBrush(winPtr->atts.background_pixel);
694 GetWindowRect(hwnd, &rc);
695 rc.right = rc.right - rc.left;
696 rc.bottom = rc.bottom - rc.top;
697 rc.left = rc.top = 0;
698 FillRect(dc, &rc, brush);
699
700 DeleteObject(brush);
701 SelectPalette(dc, oldPalette, TRUE);
702 ReleaseDC(hwnd, dc);
703 }
704
705 /*
706 *----------------------------------------------------------------------
707 *
708 * XChangeWindowAttributes --
709 *
710 * This function is called when the attributes on a window are
711 * updated. Since Tk maintains all of the window state, the only
712 * relevant value is the cursor.
713 *
714 * Results:
715 * None.
716 *
717 * Side effects:
718 * May cause the mouse position to be updated.
719 *
720 *----------------------------------------------------------------------
721 */
722
723 void
724 XChangeWindowAttributes(display, w, valueMask, attributes)
725 Display* display;
726 Window w;
727 unsigned long valueMask;
728 XSetWindowAttributes* attributes;
729 {
730 if (valueMask & CWCursor) {
731 XDefineCursor(display, w, attributes->cursor);
732 }
733 }
734
735 /*
736 *----------------------------------------------------------------------
737 *
738 * TkWinSetWindowPos --
739 *
740 * Adjust the stacking order of a window relative to a second
741 * window (or NULL).
742 *
743 * Results:
744 * None.
745 *
746 * Side effects:
747 * Moves the specified window in the stacking order.
748 *
749 *----------------------------------------------------------------------
750 */
751
752 void
753 TkWinSetWindowPos(hwnd, siblingHwnd, pos)
754 HWND hwnd; /* Window to restack. */
755 HWND siblingHwnd; /* Sibling window. */
756 int pos; /* One of Above or Below. */
757 {
758 HWND temp;
759
760 /*
761 * Since Windows does not support Above mode, we place the
762 * specified window below the sibling and then swap them.
763 */
764
765 if (siblingHwnd) {
766 if (pos == Above) {
767 SetWindowPos(hwnd, siblingHwnd, 0, 0, 0, 0,
768 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
769 temp = hwnd;
770 hwnd = siblingHwnd;
771 siblingHwnd = temp;
772 }
773 } else {
774 siblingHwnd = (pos == Above) ? HWND_TOP : HWND_BOTTOM;
775 }
776
777 SetWindowPos(hwnd, siblingHwnd, 0, 0, 0, 0,
778 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
779 }
780
781 /*
782 *----------------------------------------------------------------------
783 *
784 * TkpWindowWasRecentlyDeleted --
785 *
786 * Determines whether we know if the window given as argument was
787 * recently deleted. Called by the generic code error handler to
788 * handle BadWindow events.
789 *
790 * Results:
791 * Always 0. We do not keep this information on Windows.
792 *
793 * Side effects:
794 * None.
795 *
796 *----------------------------------------------------------------------
797 */
798
799 int
800 TkpWindowWasRecentlyDeleted(win, dispPtr)
801 Window win;
802 TkDisplay *dispPtr;
803 {
804 return 0;
805 }
806
807
808 /* $History: tkWinWindow.c $
809 *
810 * ***************** Version 1 *****************
811 * User: Dtashley Date: 1/02/01 Time: 3:18a
812 * Created in $/IjuScripter, IjuConsole/Source/Tk Base
813 * Initial check-in.
814 */
815
816 /* End of TKWINWINDOW.C */

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25