/*1* Cards dll implementation2*3* Copyright (C) 2004 Sami Nopanen4*5* This library is free software; you can redistribute it and/or6* modify it under the terms of the GNU Lesser General Public7* License as published by the Free Software Foundation; either8* version 2.1 of the License, or (at your option) any later version.9*10* This library is distributed in the hope that it will be useful,11* but WITHOUT ANY WARRANTY; without even the implied warranty of12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU13* Lesser General Public License for more details.14*15* You should have received a copy of the GNU Lesser General Public16* License along with this library; if not, write to the Free Software17* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA18*/1920#include <stdarg.h>2122#include "windef.h"23#include "winbase.h"24#include "winuser.h"25#include "wingdi.h"2627#include "cards.h"28#include "wine/debug.h"2930WINE_DEFAULT_DEBUG_CHANNEL(cards);313233void WINAPI cdtTerm(void);343536static HINSTANCE hInst;37static int cardWidth;38static int cardHeight;39static HBITMAP cardBitmaps[CARD_MAX + 1];404142/***********************************************************************43* Initializes the cards.dll library. Loads the card bitmaps from the44* resources, and initializes the card size variables.45*/46BOOL WINAPI cdtInit(int *width, int *height)47{48BITMAP bm;49int i;5051TRACE("(%p, %p)\n", width, height);5253for(i = 0; i <= CARD_MAX; i++)54cardBitmaps[i] = 0;5556for(i = 0; i <= CARD_MAX; i++)57{58cardBitmaps[i] = LoadBitmapA(hInst, MAKEINTRESOURCEA(i));59if(cardBitmaps[i] == 0)60{61cdtTerm();62return FALSE;63}64}6566GetObjectA(cardBitmaps[0], sizeof(BITMAP), &bm);67*width = cardWidth = bm.bmWidth;68*height = cardHeight = bm.bmHeight;69return TRUE;70}7172static DWORD do_blt(HDC hdc, int x, int y, int dx, int dy, HDC hMemoryDC, DWORD rasterOp )73{74if((cardWidth == dx) && (cardHeight == dy))75return BitBlt(hdc, x, y, cardWidth, cardHeight, hMemoryDC, 0, 0, rasterOp);76return StretchBlt(hdc, x, y, dx, dy, hMemoryDC, 0, 0, cardWidth, cardHeight, rasterOp);77}7879/***********************************************************************80* Draw a card. Unlike cdtDrawCard, this version allows you to stretch81* card bitmaps to the size you specify (dx, dy). See cdtDraw for info82* on card, mode and color parameters.83*/84BOOL WINAPI cdtDrawExt(HDC hdc, int x, int y, int dx, int dy, int card, int mode, DWORD color)85{86HDC hMemoryDC;87HBITMAP hCardBitmap;88HGDIOBJ result;89DWORD rasterOp = SRCCOPY;90BOOL roundCornersFlag;91BOOL eraseFlag = FALSE;92BOOL drawFlag = TRUE;9394TRACE("(%p, %d, %d, %d, %d, %d, %d, %ld)\n", hdc, x, y, dx, dy, card, mode, color);9596roundCornersFlag = !(mode & MODEFLAG_DONT_ROUND_CORNERS) &&97(dx == cardWidth) && (dy == cardHeight);98mode &= ~MODEFLAG_DONT_ROUND_CORNERS;99100if((card < 0) || (card > CARD_MAX))101{102FIXME("Unexpected card: %d\n", card);103return FALSE;104}105106if((mode < MODE_FACEUP) || (mode > MODE_DECKO))107{108FIXME("Unexpected mode: %d\n", mode);109return FALSE;110}111112switch(mode)113{114case MODE_FACEUP:115break;116case MODE_FACEDOWN:117break;118case MODE_HILITE:119rasterOp = NOTSRCCOPY;120break;121case MODE_GHOST:122card = CARD_FREE_MASK;123eraseFlag = TRUE;124rasterOp = SRCAND;125break;126case MODE_REMOVE:127eraseFlag = TRUE;128drawFlag = FALSE;129break;130case MODE_INVISIBLEGHOST:131card = CARD_FREE_MASK;132rasterOp = SRCAND;133break;134case MODE_DECKX:135card = CARD_BACK_THE_X;136break;137case MODE_DECKO:138card = CARD_BACK_THE_O;139break;140}141142hMemoryDC = CreateCompatibleDC(hdc);143if(hMemoryDC == 0)144return FALSE;145146if(eraseFlag)147{148HBRUSH hBrush;149RECT rect;150hBrush = CreateSolidBrush(color);151SetRect(&rect, x, y, x + cardWidth - 1, y + cardHeight - 1);152FillRect(hdc, &rect, hBrush);153}154155if(drawFlag)156{157hCardBitmap = cardBitmaps[card];158if(hCardBitmap == 0)159return FALSE;160161result = SelectObject(hMemoryDC, hCardBitmap);162if((result == 0) || (result == HGDI_ERROR))163{164DeleteDC(hMemoryDC);165return FALSE;166}167168SetBkColor(hdc, color);169170if(roundCornersFlag)171{172/* NOTE: native uses Get/SetPixel for corners, but that really173* hurts on X11 since it needs a server round-trip for each pixel.174* So we use a clip region instead. */175HRGN saved = CreateRectRgn( 0, 0, 0, 0 );176HRGN line = CreateRectRgn( x + 2, y, x + dx - 2, y + 1 );177HRGN clip = CreateRectRgn( x, y + 2, x + dx, y + dy - 2 );178179CombineRgn( clip, clip, line, RGN_OR );180SetRectRgn( line, x + 1, y + 1, x + dx - 1, y + 2 );181CombineRgn( clip, clip, line, RGN_OR );182SetRectRgn( line, x + 1, y + dy - 2, x + dx - 1, y + dy - 1 );183CombineRgn( clip, clip, line, RGN_OR );184SetRectRgn( line, x + 2, y + dy - 1, x + dx - 2, y + dy );185CombineRgn( clip, clip, line, RGN_OR );186DeleteObject( line );187188if (!GetClipRgn( hdc, saved ))189{190DeleteObject( saved );191saved = 0;192}193ExtSelectClipRgn( hdc, clip, RGN_AND );194DeleteObject( clip );195196do_blt(hdc, x, y, dx, dy, hMemoryDC, rasterOp);197198SelectClipRgn( hdc, saved );199if (saved) DeleteObject( saved );200}201else202do_blt(hdc, x, y, dx, dy, hMemoryDC, rasterOp);203}204205DeleteDC(hMemoryDC);206207return TRUE;208}209210211/***********************************************************************212* Draws a card at position x, y in its default size (as returned by213* cdtInit.214*215* Mode controls how the card gets drawn:216* MODE_FACEUP ; draw card facing up217* MODE_FACEDOWN ; draw card facing down218* MODE_HILITE ; draw face up, with NOTSRCCOPY219* MODE_GHOST ; draw 'ghost' card220* MODE_REMOVE ; draw with background color221* MODE_INVISIBLEGHOST ; draw 'ghost' card, without clearing background222* MODE_DECKX ; draw X223* MODE_DECKO ; draw O224*225* The card parameter defines the card graphic to be drawn. If we are226* drawing fronts of cards, card should have a value from 0 through 51227* to represent the card face. If we are drawing card backs, 53 through228* 68 represent different card backs.229*230* When drawing card faces, two lowest bits represent the card suit231* (clubs, diamonds, hearts, spades), and the bits above that define the232* card value (ace, 2, ..., king). That is,233* card = face * 4 + suit.234*235* Color parameter defines the background color, used when drawing some236* card backs.237*/238BOOL WINAPI cdtDraw(HDC hdc, int x, int y, int card, int mode, DWORD color)239{240TRACE("(%p, %d, %d, %d, %d, %ld)\n", hdc, x, y, card, mode, color);241242return cdtDrawExt(hdc, x, y, cardWidth, cardHeight, card, mode, color);243}244245246/***********************************************************************247* Animates the card backs, e.g. blinking lights on the robot, the sun248* donning sunglasses, bats flying across the caste, etc.. Works only249* for cards of normal size (as drawn with cdtDraw). To draw frames of250* the card back animation, start with frame = 0, and increment the251* frame by one, until cdtAnimate returns FALSE (to indicate that we252* have gone through all frames of animation).253*/254BOOL WINAPI cdtAnimate(HDC hdc, int cardback, int x, int y, int frame)255{256TRACE("(%p, %d, %d, %d, %d)\n", hdc, cardback, x, y, frame);257FIXME("Implement me.\n");258259return FALSE;260}261262263/***********************************************************************264* Frees resources reserved by cdtInit.265*/266void WINAPI cdtTerm(void)267{268int i;269270TRACE("()\n");271272for(i = 0; i <= CARD_MAX; i++)273{274if(cardBitmaps[i] != 0)275DeleteObject(cardBitmaps[i]);276cardBitmaps[i] = 0;277}278}279280281/***********************************************************************282* DllMain.283*/284BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved)285{286switch (reason)287{288case DLL_PROCESS_ATTACH:289hInst = inst;290DisableThreadLibraryCalls( inst );291break;292}293return TRUE;294}295296297