jbeuhler-flexelint-bugs-found-20031128
[openafs.git] / src / WINNT / afsapplib / al_pump.cpp
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 extern "C" {
11 #include <afs/param.h>
12 #include <afs/stds.h>
13 }
14
15 #include <WINNT/afsapplib.h>
16
17
18 /*
19  * DEFINITIONS ________________________________________________________________
20  *
21  */
22
23 #define cREALLOC_MODELESS 16
24 #define cREALLOC_WINDOWDATA_FIELDS 4
25 #define cREALLOC_WINDOWDATA_WINDOWS 16
26 #define cREALLOC_WINDOWDATA_DATA 8
27
28 #define GWD_IS_MODELESS  TEXT("afsapplib/al_pump.cpp - is window modeless?")
29
30
31 /*
32  * VARIABLES __________________________________________________________________
33  *
34  */
35
36          // Modeless-dialog support
37          //
38 static HWND  *aModeless = NULL;
39 static size_t cModeless = 0;
40 static LPCRITICAL_SECTION pcsPump = NULL;
41
42 static void (*g_fnPump)(MSG *lpm) = NULL;
43
44          // Window-data support
45          //
46 static struct
47    {
48    TCHAR szField[ cchNAME ];
49    } *aFields = NULL;
50 static size_t cFields = 0;
51
52 static struct
53    {
54    HWND hWnd;
55    DWORD *adwData;
56    size_t cdwData;
57    } *aWindows = NULL;
58 static size_t cWindows = 0;
59 static LPCRITICAL_SECTION pcsData = NULL;
60
61
62 /*
63  * DIALOG ROUTINES ____________________________________________________________
64  *
65  */
66
67 BOOL CALLBACK Modeless_HookProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
68 {
69    PVOID oldProc = Subclass_FindNextHook (hDlg, Modeless_HookProc);
70
71    if (msg == WM_DESTROY)
72       {
73       EnterCriticalSection (pcsPump);
74       for (size_t ii = 0; ii < cModeless; ++ii)
75          {
76          if (aModeless[ ii ] == hDlg)
77             aModeless[ ii ] = 0;
78          }
79       LeaveCriticalSection (pcsPump);
80       Subclass_RemoveHook (hDlg, Modeless_HookProc);
81       }
82
83    if (oldProc)
84       return CallWindowProc ((WNDPROC)oldProc, hDlg, msg, wp, lp);
85    else
86       return DefWindowProc (hDlg, msg, wp, lp);
87 }
88
89
90 BOOL AfsAppLib_IsModelessDialogMessage (MSG *lpm)
91 {
92    BOOL rc = FALSE;
93
94    if (pcsPump)
95       {
96       EnterCriticalSection (pcsPump);
97
98       for (size_t ii = 0; (!rc) && (ii < cModeless); ++ii)
99          {
100          if (aModeless[ ii ] != 0)
101             {
102             if (IsPropSheet (aModeless[ ii ]))
103                {
104                if (!PropSheet_GetCurrentPageHwnd(aModeless[ ii ]))
105                   DestroyWindow (aModeless[ ii ]);
106                if (PropSheet_IsDialogMessage(aModeless[ ii ], lpm))
107                   rc = TRUE;
108                }
109             else
110                {
111                if (IsDialogMessage (aModeless[ ii ], lpm))
112                   rc = TRUE;
113                }
114             }
115          }
116
117       LeaveCriticalSection (pcsPump);
118       }
119
120    return rc;
121 }
122
123
124 void AfsAppLib_RegisterModelessDialog (HWND hDlg)
125 {
126    if (pcsPump == NULL)
127       {
128       pcsPump = New (CRITICAL_SECTION);
129       InitializeCriticalSection (pcsPump);
130       }
131
132    EnterCriticalSection (pcsPump);
133
134    for (size_t ii = 0; ii < cModeless; ++ii)
135       {
136       if (aModeless[ ii ] == hDlg)
137          break;
138       }
139    if (ii == cModeless)
140       {
141       for (ii = 0; ii < cModeless; ++ii)
142          {
143          if (aModeless[ ii ] == 0)
144             break;
145          }
146       if (ii == cModeless)
147          {
148          (void)REALLOC (aModeless, cModeless, 1+ii, cREALLOC_MODELESS);
149          }
150       if (ii < cModeless)
151          {
152          aModeless[ ii ] = hDlg;
153          Subclass_AddHook (hDlg, Modeless_HookProc);
154          }
155       }
156
157    LeaveCriticalSection (pcsPump);
158 }
159
160
161 void AfsAppLib_SetPumpRoutine (void (*fnPump)(MSG *lpm))
162 {
163    g_fnPump = fnPump;
164 }
165
166
167 void AfsAppLib_MainPump (void)
168 {
169    MSG msg;
170
171    while (GetMessage (&msg, NULL, 0, 0))
172       {
173       if (AfsAppLib_IsModelessDialogMessage (&msg))
174          continue;
175
176       if (g_fnPump)
177          (*g_fnPump)(&msg);
178       else
179          {
180          TranslateMessage (&msg);
181          DispatchMessage (&msg);
182          }
183       }
184 }
185
186
187 /*
188  * WINDOW-DATA ________________________________________________________________
189  *
190  */
191
192 BOOL CALLBACK WindowData_HookProc (HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
193 {
194    PVOID oldProc = Subclass_FindNextHook (hWnd, WindowData_HookProc);
195
196    if (msg == WM_DESTROY)
197       {
198       EnterCriticalSection (pcsData);
199       for (size_t ii = 0; ii < cWindows; ++ii)
200          {
201          if (aWindows[ ii ].hWnd == hWnd)
202             {
203             if (aWindows[ ii ].adwData)
204                Free (aWindows[ ii ].adwData);
205             memset (&aWindows[ii], 0x00, sizeof(aWindows[ii]));
206             }
207          }
208       LeaveCriticalSection (pcsData);
209       Subclass_RemoveHook (hWnd, WindowData_HookProc);
210       }
211
212    if (oldProc)
213       return CallWindowProc ((WNDPROC)oldProc, hWnd, msg, wp, lp);
214    else
215       return DefWindowProc (hWnd, msg, wp, lp);
216 }
217
218
219 size_t GetWindowDataField (LPTSTR pszField)
220 {
221    size_t rc = (size_t)-1;
222
223    if (pcsData == NULL)
224       {
225       pcsData = New (CRITICAL_SECTION);
226       InitializeCriticalSection (pcsData);
227       }
228    EnterCriticalSection (pcsData);
229
230    for (size_t ii = 0; ii < cFields; ++ii)
231       {
232       if (!lstrcmpi (aFields[ ii ].szField, pszField))
233          break;
234       }
235    if (ii == cFields)
236       {
237       for (ii = 0; ii < cFields; ++ii)
238          {
239          if (aFields[ ii ].szField[0] == TEXT('\0'))
240             break;
241          }
242       if (ii == cFields)
243          {
244          (void)REALLOC (aFields, cFields, 1+ii, cREALLOC_WINDOWDATA_FIELDS);
245          }
246       if (ii < cFields)
247          {
248          lstrcpy (aFields[ ii ].szField, pszField);
249          }
250       }
251    if (ii < cFields)
252       {
253       rc = ii;
254       }
255
256    LeaveCriticalSection (pcsData);
257    return rc;
258 }
259
260
261 DWORD GetWindowData (HWND hWnd, LPTSTR pszField)
262 {
263    DWORD rc = 0;
264
265    if (pcsData == NULL)
266       {
267       pcsData = New (CRITICAL_SECTION);
268       InitializeCriticalSection (pcsData);
269       }
270    EnterCriticalSection (pcsData);
271
272    size_t iField;
273    if ((iField = GetWindowDataField (pszField)) != (size_t)-1)
274       {
275       for (size_t ii = 0; ii < cWindows; ++ii)
276          {
277          if (aWindows[ ii ].hWnd == hWnd)
278             {
279             if (iField < aWindows[ ii ].cdwData)
280                rc = aWindows[ ii ].adwData[ iField ];
281             break;
282             }
283          }
284       }
285
286    LeaveCriticalSection (pcsData);
287    return rc;
288 }
289
290
291 DWORD SetWindowData (HWND hWnd, LPTSTR pszField, DWORD dwNewData)
292 {
293    DWORD rc = 0;
294
295    if (pcsData == NULL)
296       {
297       pcsData = New (CRITICAL_SECTION);
298       InitializeCriticalSection (pcsData);
299       }
300    EnterCriticalSection (pcsData);
301
302    size_t iField;
303    if ((iField = GetWindowDataField (pszField)) != (size_t)-1)
304       {
305       for (size_t ii = 0; ii < cWindows; ++ii)
306          {
307          if (aWindows[ ii ].hWnd == hWnd)
308             {
309             if (iField < aWindows[ ii ].cdwData)
310                rc = aWindows[ ii ].adwData[ iField ];
311             break;
312             }
313          }
314       if (ii == cWindows)
315          {
316          for (ii = 0; ii < cWindows; ++ii)
317             {
318             if (aWindows[ ii ].hWnd == 0)
319                break;
320             }
321          if (ii == cWindows)
322             {
323             (void)REALLOC (aWindows, cWindows, 1+ii, cREALLOC_WINDOWDATA_WINDOWS);
324             }
325          }
326       if (ii < cWindows)
327          {
328          if (aWindows[ ii ].hWnd == 0)
329             {
330             aWindows[ ii ].hWnd = hWnd;
331             Subclass_AddHook (hWnd, WindowData_HookProc);
332             }
333          if ((dwNewData) && (iField >= aWindows[ ii ].cdwData))
334             {
335             (void)REALLOC (aWindows[ ii ].adwData, aWindows[ ii ].cdwData, 1+iField, cREALLOC_WINDOWDATA_DATA);
336             }
337          if (iField < aWindows[ ii ].cdwData)
338             {
339             aWindows[ ii ].adwData[ iField ] = dwNewData;
340             }
341          }
342       }
343
344    LeaveCriticalSection (pcsData);
345    return rc;
346 }
347