:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / lib / user32 / windows / bitmap.c
1 /*
2  *  ReactOS kernel
3  *  Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 /* $Id$
20  *
21  * PROJECT:         ReactOS user32.dll
22  * FILE:            lib/user32/windows/input.c
23  * PURPOSE:         Input
24  * PROGRAMMER:      Casper S. Hornstrup (chorns@users.sourceforge.net)
25  * UPDATE HISTORY:
26  *      09-05-2001  CSH  Created
27  */
28
29 /* INCLUDES ******************************************************************/
30
31 #include <string.h>
32 #include <windows.h>
33 #include <user32.h>
34 #include <debug.h>
35
36 /* FUNCTIONS *****************************************************************/
37
38 HANDLE STDCALL
39 LoadImageA(HINSTANCE hinst,
40            LPCSTR lpszName,
41            UINT uType,
42            int cxDesired,
43            int cyDesired,
44            UINT fuLoad)
45 {
46   LPWSTR lpszWName;
47   HANDLE Handle;
48   UNICODE_STRING NameString;
49
50   if (HIWORD(lpszName))
51     {      
52       RtlCreateUnicodeStringFromAsciiz(&NameString, (LPSTR)lpszName);
53       lpszWName = NameString.Buffer;
54       Handle = LoadImageW(hinst, lpszWName, uType, cxDesired,
55                           cyDesired, fuLoad);
56       RtlFreeUnicodeString(&NameString);
57     }
58   else
59     {
60       Handle = LoadImageW(hinst, lpszWName, uType, cxDesired,
61                           cyDesired, fuLoad);
62     }
63   return(Handle);
64 }
65
66 HANDLE STATIC
67 LoadBitmapImage(HINSTANCE hInstance, LPCWSTR lpszName, UINT fuLoad)
68 {
69   HANDLE hResource;
70   HANDLE hFile;
71   HANDLE hSection;
72   BITMAPINFO* BitmapInfo;
73   BITMAPINFO* PrivateInfo;
74   HDC hScreenDc;
75   HANDLE hBitmap;
76   ULONG HeaderSize;
77   ULONG ColourCount;
78   PVOID Data;
79
80   if (!(fuLoad & LR_LOADFROMFILE))
81     {
82       if (hInstance == NULL)
83         {
84           hInstance = GetModuleHandle(L"USER32");               
85         }
86       hResource = FindResourceW(hInstance, lpszName, RT_BITMAP);
87       if (hResource == NULL)
88         {
89           return(NULL);
90         }
91       hResource = LoadResource(hInstance, hResource);
92       if (hResource == NULL)
93         {
94           return(NULL);
95         }
96       BitmapInfo = LockResource(hResource);
97       if (BitmapInfo == NULL)
98         {
99           return(NULL);
100         }
101     }
102   else
103     {
104       hFile = CreateFile(lpszName,
105                          GENERIC_READ,
106                          FILE_SHARE_READ,
107                          NULL,
108                          OPEN_EXISTING,
109                          0,
110                          NULL);
111       if (hFile == NULL)
112         {
113           return(NULL);
114         }
115       hSection = CreateFileMapping(hFile,
116                                    NULL,
117                                    PAGE_READONLY,
118                                    0,
119                                    0,
120                                    NULL);
121       CloseHandle(hFile);
122       if (hSection == NULL)
123         {               
124           return(NULL);
125         }
126       BitmapInfo = MapViewOfFile(hSection, 
127                                  FILE_MAP_READ,
128                                  0, 
129                                  0,
130                                  0);
131       CloseHandle(hSection);
132       if (BitmapInfo == NULL)
133         {
134           return(NULL);
135         }
136     }
137
138   if (BitmapInfo->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
139     {
140       BITMAPCOREHEADER* Core = (BITMAPCOREHEADER*)BitmapInfo;
141       ColourCount = (Core->bcBitCount <= 8) ? (1 << Core->bcBitCount) : 0;
142       HeaderSize = sizeof(BITMAPCOREHEADER) + ColourCount * sizeof(RGBTRIPLE);
143     }
144   else
145     {
146       ColourCount = BitmapInfo->bmiHeader.biClrUsed;
147       if (ColourCount == 0 && BitmapInfo->bmiHeader.biBitCount <= 8)
148         {
149           ColourCount = 1 << BitmapInfo->bmiHeader.biBitCount;
150         }
151       HeaderSize = sizeof(BITMAPINFOHEADER) + ColourCount * sizeof(RGBQUAD);
152     }
153   Data = (PVOID)BitmapInfo + HeaderSize;
154
155   PrivateInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, HeaderSize);
156   if (PrivateInfo == NULL)
157     {
158       if (fuLoad & LR_LOADFROMFILE)
159         {
160           UnmapViewOfFile(BitmapInfo);
161         }
162       return(NULL);
163     }
164   memcpy(PrivateInfo, BitmapInfo, HeaderSize);
165
166   /* FIXME: Handle colour conversion and transparency. */
167
168   hScreenDc = CreateDCW(L"DISPLAY", NULL, NULL, NULL);
169   if (hScreenDc == NULL)
170     {
171       if (fuLoad & LR_LOADFROMFILE)
172         {
173           UnmapViewOfFile(BitmapInfo);
174         }
175       return(NULL);
176     }
177
178   if (fuLoad & LR_CREATEDIBSECTION)
179     {
180       DIBSECTION Dib;
181
182       hBitmap = CreateDIBSection(hScreenDc, PrivateInfo, DIB_RGB_COLORS, NULL, 
183                                  0, 0);
184       GetObjectA(hBitmap, sizeof(DIBSECTION), &Dib);
185       SetDIBits(hScreenDc, hBitmap, 0, Dib.dsBm.bmHeight, Data, BitmapInfo,
186                 DIB_RGB_COLORS);
187     }
188   else
189     {
190       hBitmap = CreateDIBitmap(hScreenDc, &PrivateInfo->bmiHeader, CBM_INIT,
191                                Data, PrivateInfo, DIB_RGB_COLORS);
192     }
193
194   RtlFreeHeap(RtlGetProcessHeap(), 0, PrivateInfo);
195   /*DeleteDC(hScreenDc);*/
196   if (fuLoad & LR_LOADFROMFILE)
197     {
198       UnmapViewOfFile(BitmapInfo);
199     }
200   return(hBitmap);
201 }
202
203 HANDLE STDCALL
204 LoadImageW(HINSTANCE hinst,
205            LPCWSTR lpszName,
206            UINT uType,
207            int cxDesired,
208            int cyDesired,
209            UINT fuLoad)
210 {  
211   if (fuLoad & LR_DEFAULTSIZE)
212     {
213       if (uType == IMAGE_ICON)
214         {
215           if (cxDesired == 0)
216             {
217               cxDesired = GetSystemMetrics(SM_CXICON);
218             }
219           if (cyDesired == 0)
220             {
221               cyDesired = GetSystemMetrics(SM_CYICON);
222             }
223         }
224       else if (uType == IMAGE_CURSOR)
225         {
226           if (cxDesired == 0)
227             {
228               cxDesired = GetSystemMetrics(SM_CXCURSOR);
229             }
230           if (cyDesired == 0)
231             {
232               cyDesired = GetSystemMetrics(SM_CYCURSOR);
233             }
234         }
235     }
236
237   switch (uType)
238     {
239     case IMAGE_BITMAP:
240       {
241         return(LoadBitmapImage(hinst, lpszName, fuLoad));
242       }
243     case IMAGE_CURSOR:
244       {
245         DbgPrint("FIXME: Need support for loading cursors.\n");
246         return(NULL);
247       }
248     default:
249       DbgBreakPoint();
250       break;
251     }
252   return(NULL);
253 }
254
255
256 HBITMAP STDCALL
257 LoadBitmapA(HINSTANCE hInstance, LPCSTR lpBitmapName)
258 {
259   return(LoadImageA(hInstance, lpBitmapName, IMAGE_BITMAP, 0, 0, 0));
260 }
261
262 HBITMAP STDCALL
263 LoadBitmapW(HINSTANCE hInstance, LPCWSTR lpBitmapName)
264 {
265   return(LoadImageW(hInstance, lpBitmapName, IMAGE_BITMAP, 0, 0, 0));
266 }