DIB Engine: introduction of bitmaplist structure
[wine/hacks.git] / dlls / winedib.drv / bitmaplist.c
blob455f36a3b17257fa1499f346da7804e8f8d228dd
1 /*
2 * DIBDRV in-memory bitmap list
4 * Copyright 2009 Massimo Del Fedele
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 /* this modules manages association between HBITMAP handles and DIBDRVBITMAP
22 * physical bitmap objects. Needed mostly to get palettes from DIBs without
23 * resorting to GetDIBColorTable() or GETDIBits(), which are DC dependent.
24 * It makes also much easier (and faster) many bitmap operations */
26 #include "config.h"
27 #include "wine/port.h"
29 #include "dibdrv.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
33 static CRITICAL_SECTION BITMAPLIST_CritSection;
34 static CRITICAL_SECTION_DEBUG critsect_debug =
36 0, 0, &BITMAPLIST_CritSection,
37 { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
38 0, 0, { (DWORD_PTR)(__FILE__ ": BITMAPLIST_CritSection") }
40 static CRITICAL_SECTION BITMAPLIST_CritSection = { &critsect_debug, -1, 0, 0, 0, 0 };
42 typedef struct _BITMAPLIST_NODE
44 HBITMAP hbmp;
45 DIBDRVBITMAP *bmp;
46 UINT refCount;
47 struct _BITMAPLIST_NODE *prev, *next;
49 } BITMAPLIST_NODE;
51 /* the list */
52 static BITMAPLIST_NODE *DIBDRV_BITMAPLIST;
54 /* initializes bitmap list -- to be called at process attach */
55 void _BITMAPLIST_Init(void)
57 DIBDRV_BITMAPLIST = NULL;
60 /* terminates bitmap list -- to be called at process detach */
61 void _BITMAPLIST_Terminate(void)
63 BITMAPLIST_NODE *curNode, *nextNode;
65 EnterCriticalSection(&BITMAPLIST_CritSection);
67 /* frees all stored bitmaps, if any left */
68 curNode = DIBDRV_BITMAPLIST;
69 while(curNode)
71 nextNode = curNode->next;
72 ERR("Unfreed DIB found, handle is %p\n", curNode->hbmp);
73 HeapFree(GetProcessHeap(), 0, curNode);
74 curNode = nextNode;
76 DIBDRV_BITMAPLIST = NULL;
77 LeaveCriticalSection(&BITMAPLIST_CritSection);
78 DeleteCriticalSection(&BITMAPLIST_CritSection);
81 /* scan list for a DIB -- returns node containing it */
82 static BITMAPLIST_NODE *GetNode(HBITMAP hbmp)
84 BITMAPLIST_NODE *node = DIBDRV_BITMAPLIST;
85 while(node)
87 if(node->hbmp == hbmp)
88 return node;
89 node = node->next;
91 return NULL;
94 /* adds a DIB to the list - it adds it on top, as
95 usually most recently created DIBs are used first */
96 BOOL _BITMAPLIST_Add(HBITMAP hbmp, DIBDRVBITMAP *bmp)
98 BITMAPLIST_NODE *existNode, *node;
100 EnterCriticalSection(&BITMAPLIST_CritSection);
102 /* checks if already there */
103 node = NULL;
104 existNode = GetNode(hbmp);
105 if(!existNode)
107 node = HeapAlloc(GetProcessHeap(), 0, sizeof(BITMAPLIST_NODE));
108 if(!node)
109 ERR("HeapAlloc failed\n");
110 else
112 node->next = DIBDRV_BITMAPLIST;
113 node->prev = NULL;
114 DIBDRV_BITMAPLIST = node;
115 if(node->next)
116 node->next->prev = node;
117 node->hbmp = hbmp;
118 node->bmp = bmp;
121 LeaveCriticalSection(&BITMAPLIST_CritSection);
122 return !existNode && node;
125 /* removes a DIB from the list */
126 DIBDRVBITMAP *_BITMAPLIST_Remove(HBITMAP hbmp)
128 BITMAPLIST_NODE *node;
129 DIBDRVBITMAP *bmp;
131 /* checks if already there */
132 EnterCriticalSection(&BITMAPLIST_CritSection);
133 node = GetNode(hbmp);
134 if(node)
136 if(node->prev)
137 node->prev->next = node->next;
138 else
139 DIBDRV_BITMAPLIST = node->next;
140 if(node->next)
141 node->next->prev = node->prev;
143 LeaveCriticalSection(&BITMAPLIST_CritSection);
144 if(node)
146 bmp = node->bmp;
147 HeapFree(GetProcessHeap(), 0, node);
149 else
150 bmp = NULL;
151 return bmp;
154 /* scans list for a DIB */
155 DIBDRVBITMAP *_BITMAPLIST_Get(HBITMAP hbmp)
157 BITMAPLIST_NODE *node;
158 DIBDRVBITMAP *bmp;
160 EnterCriticalSection(&BITMAPLIST_CritSection);
161 node = GetNode(hbmp);
162 if(!node)
163 bmp = NULL;
164 else
165 bmp = node->bmp;
166 LeaveCriticalSection(&BITMAPLIST_CritSection);
167 return bmp;