5da0840e2e5d138d2f2bc5c40369c781b612308a
[reactos.git] / reactos / 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: bitmap.c,v 1.4 2002/09/08 10:23:11 chorns Exp $
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 <windows.h>
32 #include <user32.h>
33 #include <debug.h>
34
35 /* FUNCTIONS *****************************************************************/
36
37 HANDLE STDCALL
38 LoadImageA(HINSTANCE hinst,
39 LPCSTR lpszName,
40 UINT uType,
41 int cxDesired,
42 int cyDesired,
43 UINT fuLoad)
44 {
45 LPWSTR lpszWName;
46 HANDLE Handle;
47
48 if (HIWORD(lpszName))
49 {
50 lpszWName = User32ConvertString(lpszName);
51 Handle = LoadImageW(hinst, lpszWName, uType, cxDesired,
52 cyDesired, fuLoad);
53 User32FreeString(lpszWName);
54 }
55 else
56 {
57 Handle = LoadImageW(hinst, lpszWName, uType, cxDesired,
58 cyDesired, fuLoad);
59 }
60 return(Handle);
61 }
62
63 HANDLE STATIC
64 LoadBitmapImage(HINSTANCE hInstance, LPCWSTR lpszName, UINT fuLoad)
65 {
66 HANDLE hResource;
67 HANDLE hFile;
68 HANDLE hSection;
69 BITMAPINFO* BitmapInfo;
70 BITMAPINFO* PrivateInfo;
71 HDC hScreenDc;
72 HANDLE hBitmap;
73 ULONG HeaderSize;
74 ULONG ColourCount;
75 PVOID Data;
76
77 if (!(fuLoad & LR_LOADFROMFILE))
78 {
79 if (hInstance == NULL)
80 {
81 hInstance = GetModuleHandle(L"USER32");
82 }
83 hResource = FindResourceW(hInstance, lpszName, RT_BITMAP);
84 if (hResource == NULL)
85 {
86 return(NULL);
87 }
88 hResource = LoadResource(hInstance, hResource);
89 if (hResource == NULL)
90 {
91 return(NULL);
92 }
93 BitmapInfo = LockResource(hResource);
94 if (BitmapInfo == NULL)
95 {
96 return(NULL);
97 }
98 }
99 else
100 {
101 hFile = CreateFile(lpszName,
102 GENERIC_READ,
103 FILE_SHARE_READ,
104 NULL,
105 OPEN_EXISTING,
106 0,
107 NULL);
108 if (hFile == NULL)
109 {
110 return(NULL);
111 }
112 hSection = CreateFileMapping(hFile,
113 NULL,
114 PAGE_READONLY,
115 0,
116 0,
117 NULL);
118 CloseHandle(hFile);
119 if (hSection == NULL)
120 {
121 return(NULL);
122 }
123 BitmapInfo = MapViewOfFile(hSection,
124 FILE_MAP_READ,
125 0,
126 0,
127 0);
128 CloseHandle(hSection);
129 if (BitmapInfo == NULL)
130 {
131 return(NULL);
132 }
133 }
134
135 if (BitmapInfo->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
136 {
137 BITMAPCOREHEADER* Core = (BITMAPCOREHEADER*)BitmapInfo;
138 ColourCount = (Core->bcBitCount <= 8) ? (1 << Core->bcBitCount) : 0;
139 HeaderSize = sizeof(BITMAPCOREHEADER) + ColourCount * sizeof(RGBTRIPLE);
140 }
141 else
142 {
143 ColourCount = BitmapInfo->bmiHeader.biClrUsed;
144 if (ColourCount == 0 && BitmapInfo->bmiHeader.biBitCount <= 8)
145 {
146 ColourCount = 1 << BitmapInfo->bmiHeader.biBitCount;
147 }
148 HeaderSize = sizeof(BITMAPINFOHEADER) + ColourCount * sizeof(RGBQUAD);
149 }
150 Data = (PVOID)BitmapInfo + HeaderSize;
151
152 PrivateInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, HeaderSize);
153 if (PrivateInfo == NULL)
154 {
155 if (fuLoad & LR_LOADFROMFILE)
156 {
157 UnmapViewOfFile(BitmapInfo);
158 }
159 return(NULL);
160 }
161 memcpy(PrivateInfo, BitmapInfo, HeaderSize);
162
163 /* FIXME: Handle colour conversion and transparency. */
164
165 hScreenDc = CreateDCW(L"DISPLAY", NULL, NULL, NULL);
166 if (hScreenDc == NULL)
167 {
168 if (fuLoad & LR_LOADFROMFILE)
169 {
170 UnmapViewOfFile(BitmapInfo);
171 }
172 return(NULL);
173 }
174
175 if (fuLoad & LR_CREATEDIBSECTION)
176 {
177 DIBSECTION Dib;
178
179 hBitmap = CreateDIBSection(hScreenDc, PrivateInfo, DIB_RGB_COLORS, NULL,
180 0, 0);
181 GetObjectA(hBitmap, sizeof(DIBSECTION), &Dib);
182 SetDIBits(hScreenDc, hBitmap, 0, Dib.dsBm.bmHeight, Data, BitmapInfo,
183 DIB_RGB_COLORS);
184 }
185 else
186 {
187 hBitmap = CreateDIBitmap(hScreenDc, &PrivateInfo->bmiHeader, CBM_INIT,
188 Data, PrivateInfo, DIB_RGB_COLORS);
189 }
190
191 RtlFreeHeap(RtlGetProcessHeap(), 0, PrivateInfo);
192 /*DeleteDC(hScreenDc);*/
193 if (fuLoad & LR_LOADFROMFILE)
194 {
195 UnmapViewOfFile(BitmapInfo);
196 }
197 return(hBitmap);
198 }
199
200 HANDLE STDCALL
201 LoadImageW(HINSTANCE hinst,
202 LPCWSTR lpszName,
203 UINT uType,
204 int cxDesired,
205 int cyDesired,
206 UINT fuLoad)
207 {
208 if (fuLoad & LR_DEFAULTSIZE)
209 {
210 if (uType == IMAGE_ICON)
211 {
212 if (cxDesired == 0)
213 {
214 cxDesired = GetSystemMetrics(SM_CXICON);
215 }
216 if (cyDesired == 0)
217 {
218 cyDesired = GetSystemMetrics(SM_CYICON);
219 }
220 }
221 else if (uType == IMAGE_CURSOR)
222 {
223 if (cxDesired == 0)
224 {
225 cxDesired = GetSystemMetrics(SM_CXCURSOR);
226 }
227 if (cyDesired == 0)
228 {
229 cyDesired = GetSystemMetrics(SM_CYCURSOR);
230 }
231 }
232 }
233
234 switch (uType)
235 {
236 case IMAGE_BITMAP:
237 {
238 return(LoadBitmapImage(hinst, lpszName, fuLoad));
239 }
240 case IMAGE_CURSOR:
241 {
242 DbgPrint("FIXME: Need support for loading cursors.\n");
243 return(NULL);
244 }
245 default:
246 DbgBreakPoint();
247 break;
248 }
249 return(NULL);
250 }
251
252
253 HBITMAP STDCALL
254 LoadBitmapA(HINSTANCE hInstance, LPCSTR lpBitmapName)
255 {
256 return(LoadImageA(hInstance, lpBitmapName, IMAGE_BITMAP, 0, 0, 0));
257 }
258
259 HBITMAP STDCALL
260 LoadBitmapW(HINSTANCE hInstance, LPCWSTR lpBitmapName)
261 {
262 return(LoadImageW(hInstance, lpBitmapName, IMAGE_BITMAP, 0, 0, 0));
263 }