Release 970928
[wine] / windows / focus.c
1 /*
2  * Focus functions
3  *
4  * Copyright 1993 David Metcalfe
5  *           1994 Alexandre Julliard
6  *           1995 Alex Korobka
7  *
8  */
9
10 #include "win.h"
11 #include "winpos.h"
12 #include "hook.h"
13 #include "color.h"
14 #include "message.h"
15 #include "options.h"
16
17 static HWND32 hwndFocus = 0;
18
19 /*****************************************************************
20  *               FOCUS_SetXFocus
21  *
22  * Set the X focus.
23  * Explicit colormap management seems to work only with OLVWM.
24  */
25 void FOCUS_SetXFocus( HWND32 hwnd )
26 {
27     XWindowAttributes win_attr;
28     Window win;
29
30     /* Only mess with the X focus if there's */
31     /* no desktop window and no window manager. */
32     if ((rootWindow != DefaultRootWindow(display)) || Options.managed) return;
33
34     if (!hwnd)  /* If setting the focus to 0, uninstall the colormap */
35     {
36         if (COLOR_GetSystemPaletteFlags() & COLOR_PRIVATE)
37             XUninstallColormap( display, COLOR_GetColormap() );
38         return;
39     }
40
41       /* Set X focus and install colormap */
42
43     if (!(win = WIN_GetXWindow( hwnd ))) return;
44     if (!XGetWindowAttributes( display, win, &win_attr ) ||
45         (win_attr.map_state != IsViewable))
46         return;  /* If window is not viewable, don't change anything */
47
48     XSetInputFocus( display, win, RevertToParent, CurrentTime );
49     if (COLOR_GetSystemPaletteFlags() & COLOR_PRIVATE)
50         XInstallColormap( display, COLOR_GetColormap() );
51
52     EVENT_Synchronize();
53 }
54
55 /*****************************************************************
56  *               FOCUS_SwitchFocus 
57  */
58 void FOCUS_SwitchFocus( HWND32 hFocusFrom, HWND32 hFocusTo )
59 {
60     hwndFocus = hFocusTo;
61
62 #if 0
63     if (hFocusFrom) SendMessage32A( hFocusFrom, WM_KILLFOCUS, hFocusTo, 0 );
64 #else
65     /* FIXME: must be SendMessage16() because 32A doesn't do
66      * intertask at this time */
67     if (hFocusFrom) SendMessage16( hFocusFrom, WM_KILLFOCUS, hFocusTo, 0 );
68 #endif
69     if( !hFocusTo || hFocusTo != hwndFocus )
70         return;
71
72 #if 0
73     SendMessage32A( hFocusTo, WM_SETFOCUS, hFocusFrom, 0 );
74 #else
75     SendMessage16( hFocusTo, WM_SETFOCUS, hFocusFrom, 0 );
76 #endif
77     FOCUS_SetXFocus( hFocusTo );
78 }
79
80
81 /*****************************************************************
82  *               SetFocus16   (USER.22)
83  */
84 HWND16 WINAPI SetFocus16( HWND16 hwnd )
85 {
86     return (HWND16)SetFocus32( hwnd );
87 }
88
89
90 /*****************************************************************
91  *               SetFocus32   (USER32.480)
92  */
93 HWND32 WINAPI SetFocus32( HWND32 hwnd )
94 {
95     HWND32 hWndPrevFocus, hwndTop = hwnd;
96     WND *wndPtr = WIN_FindWndPtr( hwnd );
97
98     if (wndPtr)
99     {
100           /* Check if we can set the focus to this window */
101
102         while ( (wndPtr->dwStyle & (WS_CHILD | WS_POPUP)) == WS_CHILD  )
103         {
104             if ( wndPtr->dwStyle & ( WS_MINIMIZE | WS_DISABLED) )
105                  return 0;
106             if (!(wndPtr = wndPtr->parent)) return 0;
107             hwndTop = wndPtr->hwndSelf;
108         }
109
110         if( hwnd == hwndFocus ) return hwnd;
111
112         /* call hooks */
113         if( HOOK_CallHooks16( WH_CBT, HCBT_SETFOCUS, (WPARAM16)hwnd,
114                               (LPARAM)hwndFocus) )
115             return 0;
116
117         /* activate hwndTop if needed. */
118         if (hwndTop != GetActiveWindow32())
119         {
120             if (!WINPOS_SetActiveWindow(hwndTop, 0, 0)) return 0;
121
122             if (!IsWindow32( hwnd )) return 0;  /* Abort if window destroyed */
123         }
124     }
125     else if( HOOK_CallHooks16( WH_CBT, HCBT_SETFOCUS, 0, (LPARAM)hwndFocus ) )
126              return 0;
127
128       /* Change focus and send messages */
129     hWndPrevFocus = hwndFocus;
130
131     FOCUS_SwitchFocus( hwndFocus , hwnd );
132
133     return hWndPrevFocus;
134 }
135
136
137 /*****************************************************************
138  *               GetFocus16   (USER.23)
139  */
140 HWND16 WINAPI GetFocus16(void)
141 {
142     return (HWND16)hwndFocus;
143 }
144
145
146 /*****************************************************************
147  *               GetFocus32   (USER32.239)
148  */
149 HWND32 WINAPI GetFocus32(void)
150 {
151     return hwndFocus;
152 }