Added ReleaseDC function to the USER driver interface.
[wine] / dlls / user / user16.c
1 /*
2  * Misc 16-bit USER functions
3  *
4  * Copyright 2002 Patrik Stridvall
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "wine/winuser16.h"
22 #include "winbase.h"
23 #include "wownt32.h"
24 #include "user.h"
25 #include "win.h"
26
27 /* handle to handle 16 conversions */
28 #define HANDLE_16(h32)          (LOWORD(h32))
29
30 /* handle16 to handle conversions */
31 #define HANDLE_32(h16)          ((HANDLE)(ULONG_PTR)(h16))
32 #define HINSTANCE_32(h16)       ((HINSTANCE)(ULONG_PTR)(h16))
33
34 WORD WINAPI DestroyIcon32(HGLOBAL16, UINT16);
35
36
37 /***********************************************************************
38  *              SetCursor (USER.69)
39  */
40 HCURSOR16 WINAPI SetCursor16(HCURSOR16 hCursor)
41 {
42   return HCURSOR_16(SetCursor(HCURSOR_32(hCursor)));
43 }
44
45 /***********************************************************************
46  *              ShowCursor (USER.71)
47  */
48 INT16 WINAPI ShowCursor16(BOOL16 bShow)
49 {
50   return ShowCursor(bShow);
51 }
52
53 /***********************************************************************
54  *              DrawIcon (USER.84)
55  */
56 BOOL16 WINAPI DrawIcon16(HDC16 hdc, INT16 x, INT16 y, HICON16 hIcon)
57 {
58   return DrawIcon(HDC_32(hdc), x, y, HICON_32(hIcon));
59 }
60
61 /***********************************************************************
62  *              IconSize (USER.86)
63  *
64  * See "Undocumented Windows". Used by W2.0 paint.exe.
65  */
66 DWORD WINAPI IconSize16(void)
67 {
68   return MAKELONG(GetSystemMetrics(SM_CYICON), GetSystemMetrics(SM_CXICON));
69 }
70
71 /***********************************************************************
72  *              LoadCursor (USER.173)
73  */
74 HCURSOR16 WINAPI LoadCursor16(HINSTANCE16 hInstance, LPCSTR name)
75 {
76   return HCURSOR_16(LoadCursorA(HINSTANCE_32(hInstance), name));
77 }
78
79
80 /***********************************************************************
81  *              LoadIcon (USER.174)
82  */
83 HICON16 WINAPI LoadIcon16(HINSTANCE16 hInstance, LPCSTR name)
84 {
85   return HICON_16(LoadIconA(HINSTANCE_32(hInstance), name));
86 }
87
88 /**********************************************************************
89  *              LoadBitmap (USER.175)
90  */
91 HBITMAP16 WINAPI LoadBitmap16(HINSTANCE16 hInstance, LPCSTR name)
92 {
93   return HBITMAP_16(LoadBitmapA(HINSTANCE_32(hInstance), name));
94 }
95
96 /*************************************************************************
97  *              ScrollDC (USER.221)
98  */
99 BOOL16 WINAPI ScrollDC16( HDC16 hdc, INT16 dx, INT16 dy, const RECT16 *rect,
100                           const RECT16 *cliprc, HRGN16 hrgnUpdate,
101                           LPRECT16 rcUpdate )
102 {
103     RECT rect32, clipRect32, rcUpdate32;
104     BOOL16 ret;
105
106     if (rect) CONV_RECT16TO32( rect, &rect32 );
107     if (cliprc) CONV_RECT16TO32( cliprc, &clipRect32 );
108     ret = ScrollDC( HDC_32(hdc), dx, dy, rect ? &rect32 : NULL,
109                     cliprc ? &clipRect32 : NULL, HRGN_32(hrgnUpdate),
110                     &rcUpdate32 );
111     if (rcUpdate) CONV_RECT32TO16( &rcUpdate32, rcUpdate );
112     return ret;
113 }
114
115 /***********************************************************************
116  *              GetCursor (USER.247)
117  */
118 HCURSOR16 WINAPI GetCursor16(void)
119 {
120   return HCURSOR_16(GetCursor());
121 }
122
123 /***********************************************************************
124  *              GlobalAddAtom (USER.268)
125  */
126 ATOM WINAPI GlobalAddAtom16(LPCSTR lpString)
127 {
128   return GlobalAddAtomA(lpString);
129 }
130
131 /***********************************************************************
132  *              GlobalDeleteAtom (USER.269)
133  */
134 ATOM WINAPI GlobalDeleteAtom16(ATOM nAtom)
135 {
136   return GlobalDeleteAtom(nAtom);
137 }
138
139 /***********************************************************************
140  *              GlobalFindAtom (USER.270)
141  */
142 ATOM WINAPI GlobalFindAtom16(LPCSTR lpString)
143 {
144   return GlobalFindAtomA(lpString);
145 }
146
147 /***********************************************************************
148  *              GlobalGetAtomName (USER.271)
149  */
150 UINT16 WINAPI GlobalGetAtomName16(ATOM nAtom, LPSTR lpBuffer, INT16 nSize)
151 {
152   return GlobalGetAtomNameA(nAtom, lpBuffer, nSize);
153 }
154
155 /***********************************************************************
156  *              SelectPalette (USER.282)
157  */
158 HPALETTE16 WINAPI SelectPalette16( HDC16 hdc, HPALETTE16 hpal, BOOL16 bForceBackground )
159 {
160     return HPALETTE_16( SelectPalette( HDC_32(hdc), HPALETTE_32(hpal), bForceBackground ));
161 }
162
163 /***********************************************************************
164  *              RealizePalette (USER.283)
165  */
166 UINT16 WINAPI RealizePalette16( HDC16 hdc )
167 {
168     return UserRealizePalette( HDC_32(hdc) );
169 }
170
171 /***********************************************************************
172  *              LoadImage (USER.389)
173  *
174  */
175 HANDLE16 WINAPI LoadImage16(HINSTANCE16 hinst, LPCSTR name, UINT16 type,
176                             INT16 desiredx, INT16 desiredy, UINT16 loadflags)
177 {
178   return HANDLE_16(LoadImageA(HINSTANCE_32(hinst), name, type, desiredx,
179                               desiredy, loadflags));
180 }
181
182 /******************************************************************************
183  *              CopyImage (USER.390) Creates new image and copies attributes to it
184  *
185  */
186 HICON16 WINAPI CopyImage16(HANDLE16 hnd, UINT16 type, INT16 desiredx,
187                            INT16 desiredy, UINT16 flags)
188 {
189   return HICON_16(CopyImage(HANDLE_32(hnd), (UINT)type, (INT)desiredx,
190                             (INT)desiredy, (UINT)flags));
191 }
192
193 /**********************************************************************
194  *              DrawIconEx (USER.394)
195  */
196 BOOL16 WINAPI DrawIconEx16(HDC16 hdc, INT16 xLeft, INT16 yTop, HICON16 hIcon,
197                            INT16 cxWidth, INT16 cyWidth, UINT16 istep,
198                            HBRUSH16 hbr, UINT16 flags)
199 {
200   return DrawIconEx(HDC_32(hdc), xLeft, yTop, HICON_32(hIcon), cxWidth, cyWidth,
201                     istep, HBRUSH_32(hbr), flags);
202 }
203
204 /**********************************************************************
205  *              GetIconInfo (USER.395)
206  */
207 BOOL16 WINAPI GetIconInfo16(HICON16 hIcon, LPICONINFO16 iconinfo)
208 {
209   ICONINFO ii32;
210   BOOL16 ret = GetIconInfo(HICON_32(hIcon), &ii32);
211
212   iconinfo->fIcon = ii32.fIcon;
213   iconinfo->xHotspot = ii32.xHotspot;
214   iconinfo->yHotspot = ii32.yHotspot;
215   iconinfo->hbmMask  = HBITMAP_16(ii32.hbmMask);
216   iconinfo->hbmColor = HBITMAP_16(ii32.hbmColor);
217   return ret;
218 }
219
220 /***********************************************************************
221  *              CreateCursor (USER.406)
222  */
223 HCURSOR16 WINAPI CreateCursor16(HINSTANCE16 hInstance,
224                                 INT16 xHotSpot, INT16 yHotSpot,
225                                 INT16 nWidth, INT16 nHeight,
226                                 LPCVOID lpANDbits, LPCVOID lpXORbits)
227 {
228   CURSORICONINFO info;
229
230   info.ptHotSpot.x = xHotSpot;
231   info.ptHotSpot.y = yHotSpot;
232   info.nWidth = nWidth;
233   info.nHeight = nHeight;
234   info.nWidthBytes = 0;
235   info.bPlanes = 1;
236   info.bBitsPerPixel = 1;
237
238   return CreateCursorIconIndirect16(hInstance, &info, lpANDbits, lpXORbits);
239 }
240
241 /**********************************************************************
242  *              CreateIconFromResourceEx (USER.450)
243  *
244  * FIXME: not sure about exact parameter types
245  */
246 HICON16 WINAPI CreateIconFromResourceEx16(LPBYTE bits, UINT16 cbSize,
247                                           BOOL16 bIcon, DWORD dwVersion,
248                                           INT16 width, INT16 height,
249                                           UINT16 cFlag)
250 {
251   return HICON_16(CreateIconFromResourceEx(bits, cbSize, bIcon, dwVersion,
252                                            width, height, cFlag));
253 }
254
255 /***********************************************************************
256  *              DestroyIcon (USER.457)
257  */
258 BOOL16 WINAPI DestroyIcon16(HICON16 hIcon)
259 {
260   return DestroyIcon32(hIcon, 0);
261 }
262
263 /***********************************************************************
264  *              DestroyCursor (USER.458)
265  */
266 BOOL16 WINAPI DestroyCursor16(HCURSOR16 hCursor)
267 {
268   return DestroyIcon32(hCursor, 0);
269 }
270
271 /*******************************************************************
272  *                      DRAG_QueryUpdate16
273  *
274  * Recursively find a child that contains spDragInfo->pt point
275  * and send WM_QUERYDROPOBJECT. Helper for DragObject16.
276  */
277 static BOOL DRAG_QueryUpdate16( HWND hQueryWnd, SEGPTR spDragInfo )
278 {
279     BOOL bResult = 0;
280     WPARAM wParam;
281     POINT pt, old_pt;
282     LPDRAGINFO16 ptrDragInfo = MapSL(spDragInfo);
283     RECT tempRect;
284     HWND child;
285
286     if (!IsWindowEnabled(hQueryWnd)) return FALSE;
287
288     old_pt.x = ptrDragInfo->pt.x;
289     old_pt.y = ptrDragInfo->pt.y;
290     pt = old_pt;
291     ScreenToClient( hQueryWnd, &pt );
292     child = ChildWindowFromPointEx( hQueryWnd, pt, CWP_SKIPINVISIBLE );
293     if (!child) return FALSE;
294
295     if (child != hQueryWnd)
296     {
297         wParam = 0;
298         if (DRAG_QueryUpdate16( child, spDragInfo )) return TRUE;
299     }
300     else
301     {
302         GetClientRect( hQueryWnd, &tempRect );
303         wParam = !PtInRect( &tempRect, pt );
304     }
305
306     ptrDragInfo->pt.x = pt.x;
307     ptrDragInfo->pt.y = pt.y;
308     ptrDragInfo->hScope = HWND_16(hQueryWnd);
309
310     bResult = SendMessage16( HWND_16(hQueryWnd), WM_QUERYDROPOBJECT, wParam, spDragInfo );
311
312     if (!bResult)
313     {
314         ptrDragInfo->pt.x = old_pt.x;
315         ptrDragInfo->pt.y = old_pt.y;
316     }
317     return bResult;
318 }
319
320
321 /******************************************************************************
322  *              DragObject (USER.464)
323  */
324 DWORD WINAPI DragObject16( HWND16 hwndScope, HWND16 hWnd, UINT16 wObj,
325                            HANDLE16 hOfStruct, WORD szList, HCURSOR16 hCursor )
326 {
327     MSG msg;
328     LPDRAGINFO16 lpDragInfo;
329     SEGPTR      spDragInfo;
330     HCURSOR     hOldCursor=0, hBummer=0;
331     HGLOBAL16   hDragInfo  = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO16));
332     HCURSOR     hCurrentCursor = 0;
333     HWND16      hCurrentWnd = 0;
334
335     lpDragInfo = (LPDRAGINFO16) GlobalLock16(hDragInfo);
336     spDragInfo = K32WOWGlobalLock16(hDragInfo);
337
338     if( !lpDragInfo || !spDragInfo ) return 0L;
339
340     if (!(hBummer = LoadCursorA(0, MAKEINTRESOURCEA(OCR_NO))))
341     {
342         GlobalFree16(hDragInfo);
343         return 0L;
344     }
345
346     if(hCursor) hOldCursor = SetCursor(HCURSOR_32(hCursor));
347
348     lpDragInfo->hWnd   = hWnd;
349     lpDragInfo->hScope = 0;
350     lpDragInfo->wFlags = wObj;
351     lpDragInfo->hList  = szList; /* near pointer! */
352     lpDragInfo->hOfStruct = hOfStruct;
353     lpDragInfo->l = 0L;
354
355     SetCapture( HWND_32(hWnd) );
356     ShowCursor( TRUE );
357
358     do
359     {
360         GetMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST );
361
362        *(lpDragInfo+1) = *lpDragInfo;
363
364         lpDragInfo->pt.x = msg.pt.x;
365         lpDragInfo->pt.y = msg.pt.y;
366
367         /* update DRAGINFO struct */
368         if( DRAG_QueryUpdate16(WIN_Handle32(hwndScope), spDragInfo) > 0 )
369             hCurrentCursor = HCURSOR_32(hCursor);
370         else
371         {
372             hCurrentCursor = hBummer;
373             lpDragInfo->hScope = 0;
374         }
375         if( hCurrentCursor )
376             SetCursor(hCurrentCursor);
377
378         /* send WM_DRAGLOOP */
379         SendMessage16( hWnd, WM_DRAGLOOP, (WPARAM16)(hCurrentCursor != hBummer),
380                                           (LPARAM) spDragInfo );
381         /* send WM_DRAGSELECT or WM_DRAGMOVE */
382         if( hCurrentWnd != lpDragInfo->hScope )
383         {
384             if( hCurrentWnd )
385                 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0,
386                        (LPARAM)MAKELONG(LOWORD(spDragInfo)+sizeof(DRAGINFO16),
387                                         HIWORD(spDragInfo)) );
388             hCurrentWnd = lpDragInfo->hScope;
389             if( hCurrentWnd )
390                 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo);
391         }
392         else
393             if( hCurrentWnd )
394                 SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
395
396     } while( msg.message != WM_LBUTTONUP && msg.message != WM_NCLBUTTONUP );
397
398     ReleaseCapture();
399     ShowCursor( FALSE );
400
401     if( hCursor ) SetCursor(hOldCursor);
402
403     if( hCurrentCursor != hBummer )
404         msg.lParam = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT,
405                                    (WPARAM16)hWnd, (LPARAM)spDragInfo );
406     else
407         msg.lParam = 0;
408     GlobalFree16(hDragInfo);
409
410     return (DWORD)(msg.lParam);
411 }
412
413
414 /**********************************************************************
415  *          DrawFrameControl  (USER.656)
416  */
417 BOOL16 WINAPI DrawFrameControl16( HDC16 hdc, LPRECT16 rc, UINT16 uType, UINT16 uState )
418 {
419     RECT rect32;
420     BOOL ret;
421
422     CONV_RECT16TO32( rc, &rect32 );
423     ret = DrawFrameControl( HDC_32(hdc), &rect32, uType, uState );
424     CONV_RECT32TO16( &rect32, rc );
425     return ret;
426 }
427
428 /**********************************************************************
429  *          DrawEdge   (USER.659)
430  */
431 BOOL16 WINAPI DrawEdge16( HDC16 hdc, LPRECT16 rc, UINT16 edge, UINT16 flags )
432 {
433     RECT rect32;
434     BOOL ret;
435
436     CONV_RECT16TO32( rc, &rect32 );
437     ret = DrawEdge( HDC_32(hdc), &rect32, edge, flags );
438     CONV_RECT32TO16( &rect32, rc );
439     return ret;
440 }
441
442 /**********************************************************************
443  *              WinHelp (USER.171)
444  */
445 BOOL16 WINAPI WinHelp16( HWND16 hWnd, LPCSTR lpHelpFile, UINT16 wCommand,
446                          DWORD dwData )
447 {
448     BOOL ret;
449     DWORD mutex_count;
450
451     /* We might call WinExec() */
452     ReleaseThunkLock(&mutex_count);
453
454     ret = WinHelpA(WIN_Handle32(hWnd), lpHelpFile, wCommand, (DWORD)MapSL(dwData));
455
456     RestoreThunkLock(mutex_count);
457     return ret;
458 }