kernel32/tests: Add a test to check some fields in fake dlls.
[wine.git] / dlls / cards / cards.c
blob9bec96650e6b34da64782e14fce488b72c04bbbe
1 /*
2 * Cards dll implementation
4 * Copyright (C) 2004 Sami Nopanen
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.
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.
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "config.h"
23 #include <stdarg.h>
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winuser.h"
28 #include "wingdi.h"
30 #include "cards.h"
31 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(cards);
36 void WINAPI cdtTerm(void);
39 static HINSTANCE hInst;
40 static int cardWidth;
41 static int cardHeight;
42 static HBITMAP cardBitmaps[CARD_MAX + 1];
45 /***********************************************************************
46 * Initializes the cards.dll library. Loads the card bitmaps from the
47 * resources, and initializes the card size variables.
49 BOOL WINAPI cdtInit(int *width, int *height)
51 BITMAP bm;
52 int i;
54 TRACE("(%p, %p)\n", width, height);
56 for(i = 0; i <= CARD_MAX; i++)
57 cardBitmaps[i] = 0;
59 for(i = 0; i <= CARD_MAX; i++)
61 cardBitmaps[i] = LoadBitmapA(hInst, MAKEINTRESOURCEA(i));
62 if(cardBitmaps[i] == 0)
64 cdtTerm();
65 return FALSE;
69 GetObjectA(cardBitmaps[0], sizeof(BITMAP), &bm);
70 *width = cardWidth = bm.bmWidth;
71 *height = cardHeight = bm.bmHeight;
72 return TRUE;
75 static DWORD do_blt(HDC hdc, int x, int y, int dx, int dy, HDC hMemoryDC, DWORD rasterOp )
77 if((cardWidth == dx) && (cardHeight == dy))
78 return BitBlt(hdc, x, y, cardWidth, cardHeight, hMemoryDC, 0, 0, rasterOp);
79 return StretchBlt(hdc, x, y, dx, dy, hMemoryDC, 0, 0, cardWidth, cardHeight, rasterOp);
82 /***********************************************************************
83 * Draw a card. Unlike cdtDrawCard, this version allows you to stretch
84 * card bitmaps to the size you specify (dx, dy). See cdtDraw for info
85 * on card, mode and color parameters.
87 BOOL WINAPI cdtDrawExt(HDC hdc, int x, int y, int dx, int dy, int card, int mode, DWORD color)
89 HDC hMemoryDC;
90 HBITMAP hCardBitmap;
91 HGDIOBJ result;
92 DWORD rasterOp = SRCCOPY;
93 BOOL roundCornersFlag;
94 BOOL eraseFlag = FALSE;
95 BOOL drawFlag = TRUE;
97 TRACE("(%p, %d, %d, %d, %d, %d, %d, %d)\n", hdc, x, y, dx, dy, card, mode, color);
99 roundCornersFlag = !(mode & MODEFLAG_DONT_ROUND_CORNERS) &&
100 (dx == cardWidth) && (dy == cardHeight);
101 mode &= ~MODEFLAG_DONT_ROUND_CORNERS;
103 if((card < 0) || (card > CARD_MAX))
105 FIXME("Unexpected card: %d\n", card);
106 return FALSE;
109 if((mode < MODE_FACEUP) || (mode > MODE_DECKO))
111 FIXME("Unexpected mode: %d\n", mode);
112 return FALSE;
115 switch(mode)
117 case MODE_FACEUP:
118 break;
119 case MODE_FACEDOWN:
120 break;
121 case MODE_HILITE:
122 rasterOp = NOTSRCCOPY;
123 break;
124 case MODE_GHOST:
125 card = CARD_FREE_MASK;
126 eraseFlag = TRUE;
127 rasterOp = SRCAND;
128 break;
129 case MODE_REMOVE:
130 eraseFlag = TRUE;
131 drawFlag = FALSE;
132 break;
133 case MODE_INVISIBLEGHOST:
134 card = CARD_FREE_MASK;
135 rasterOp = SRCAND;
136 break;
137 case MODE_DECKX:
138 card = CARD_BACK_THE_X;
139 break;
140 case MODE_DECKO:
141 card = CARD_BACK_THE_O;
142 break;
145 hMemoryDC = CreateCompatibleDC(hdc);
146 if(hMemoryDC == 0)
147 return FALSE;
149 if(eraseFlag)
151 HBRUSH hBrush;
152 RECT rect;
153 hBrush = CreateSolidBrush(color);
154 SetRect(&rect, x, y, x + cardWidth - 1, y + cardHeight - 1);
155 FillRect(hdc, &rect, hBrush);
158 if(drawFlag)
160 hCardBitmap = cardBitmaps[card];
161 if(hCardBitmap == 0)
162 return FALSE;
164 result = SelectObject(hMemoryDC, hCardBitmap);
165 if((result == 0) || (result == HGDI_ERROR))
167 DeleteDC(hMemoryDC);
168 return FALSE;
171 SetBkColor(hdc, color);
173 if(roundCornersFlag)
175 /* NOTE: native uses Get/SetPixel for corners, but that really
176 * hurts on X11 since it needs a server round-trip for each pixel.
177 * So we use a clip region instead. */
178 HRGN saved = CreateRectRgn( 0, 0, 0, 0 );
179 HRGN line = CreateRectRgn( x + 2, y, x + dx - 2, y + 1 );
180 HRGN clip = CreateRectRgn( x, y + 2, x + dx, y + dy - 2 );
182 CombineRgn( clip, clip, line, RGN_OR );
183 SetRectRgn( line, x + 1, y + 1, x + dx - 1, y + 2 );
184 CombineRgn( clip, clip, line, RGN_OR );
185 SetRectRgn( line, x + 1, y + dy - 2, x + dx - 1, y + dy - 1 );
186 CombineRgn( clip, clip, line, RGN_OR );
187 SetRectRgn( line, x + 2, y + dy - 1, x + dx - 2, y + dy );
188 CombineRgn( clip, clip, line, RGN_OR );
189 DeleteObject( line );
191 if (!GetClipRgn( hdc, saved ))
193 DeleteObject( saved );
194 saved = 0;
196 ExtSelectClipRgn( hdc, clip, RGN_AND );
197 DeleteObject( clip );
199 do_blt(hdc, x, y, dx, dy, hMemoryDC, rasterOp);
201 SelectClipRgn( hdc, saved );
202 if (saved) DeleteObject( saved );
204 else
205 do_blt(hdc, x, y, dx, dy, hMemoryDC, rasterOp);
208 DeleteDC(hMemoryDC);
210 return TRUE;
214 /***********************************************************************
215 * Draws a card at position x, y in its default size (as returned by
216 * cdtInit.
218 * Mode controls how the card gets drawn:
219 * MODE_FACEUP ; draw card facing up
220 * MODE_FACEDOWN ; draw card facing down
221 * MODE_HILITE ; draw face up, with NOTSRCCOPY
222 * MODE_GHOST ; draw 'ghost' card
223 * MODE_REMOVE ; draw with background color
224 * MODE_INVISIBLEGHOST ; draw 'ghost' card, without clearing background
225 * MODE_DECKX ; draw X
226 * MODE_DECKO ; draw O
228 * The card parameter defines the card graphic to be drawn. If we are
229 * drawing fronts of cards, card should have a value from 0 through 51
230 * to represent the card face. If we are drawing card backs, 53 through
231 * 68 represent different card backs.
233 * When drawing card faces, two lowest bits represent the card suit
234 * (clubs, diamonds, hearts, spades), and the bits above that define the
235 * card value (ace, 2, ..., king). That is,
236 * card = face * 4 + suit.
238 * Color parameter defines the background color, used when drawing some
239 * card backs.
241 BOOL WINAPI cdtDraw(HDC hdc, int x, int y, int card, int mode, DWORD color)
243 TRACE("(%p, %d, %d, %d, %d, %d)\n", hdc, x, y, card, mode, color);
245 return cdtDrawExt(hdc, x, y, cardWidth, cardHeight, card, mode, color);
249 /***********************************************************************
250 * Animates the card backs, e.g. blinking lights on the robot, the sun
251 * donning sunglasses, bats flying across the caste, etc.. Works only
252 * for cards of normal size (as drawn with cdtDraw). To draw frames of
253 * the card back animation, start with frame = 0, and increment the
254 * frame by one, until cdtAnimate returns FALSE (to indicate that we
255 * have gone through all frames of animation).
257 BOOL WINAPI cdtAnimate(HDC hdc, int cardback, int x, int y, int frame)
259 TRACE("(%p, %d, %d, %d, %d)\n", hdc, cardback, x, y, frame);
260 FIXME("Implement me.\n");
262 return FALSE;
266 /***********************************************************************
267 * Frees resources reserved by cdtInit.
269 void WINAPI cdtTerm(void)
271 int i;
273 TRACE("()\n");
275 for(i = 0; i <= CARD_MAX; i++)
277 if(cardBitmaps[i] != 0)
278 DeleteObject(cardBitmaps[i]);
279 cardBitmaps[i] = 0;
284 /***********************************************************************
285 * DllMain.
287 BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved)
289 switch (reason)
291 case DLL_PROCESS_ATTACH:
292 hInst = inst;
293 DisableThreadLibraryCalls( inst );
294 break;
296 return TRUE;