Fixed pixmap leak with the 1x1 bitmap in memory DCs.
[wine] / graphics / ttydrv / bitmap.c
1 /*
2  * TTY bitmap driver
3  *
4  * Copyright 1999 Patrik Stridvall
5  */
6
7 #include "bitmap.h"
8 #include "dc.h"
9 #include "ttydrv.h"
10 #include "winbase.h"
11 #include "debugtools.h"
12
13 DEFAULT_DEBUG_CHANNEL(ttydrv)
14
15 /**********************************************************************/
16
17 static LONG TTYDRV_DC_GetBitmapBits(BITMAPOBJ *bitmap, void *bits, LONG count);
18 static LONG TTYDRV_DC_SetBitmapBits(BITMAPOBJ *bitmap, void *bits, LONG count);
19
20 /***********************************************************************
21  *              TTYDRV_DC_AllocBitmap
22  */
23 TTYDRV_PHYSBITMAP *TTYDRV_DC_AllocBitmap(BITMAPOBJ *bitmap)
24 {
25   TTYDRV_PHYSBITMAP *physBitmap;
26   
27   if(!(physBitmap = HeapAlloc(GetProcessHeap(), 0, sizeof(TTYDRV_PHYSBITMAP)))) {
28     ERR("Can't alloc TTYDRV_PHYSBITMAP\n");
29     return NULL;
30   }
31
32   bitmap->physBitmap = physBitmap;
33   bitmap->funcs = DRIVER_FindDriver("DISPLAY");
34
35   return physBitmap;
36 }
37
38 /***********************************************************************
39  *           TTYDRV_DC_BitmapBits
40  */
41 LONG TTYDRV_DC_BitmapBits(HBITMAP hbitmap, void *bits, LONG count, WORD flags)
42 {
43   BITMAPOBJ *bitmap;
44   LONG result;
45
46   if(!(bitmap = (BITMAPOBJ *) GDI_GetObjPtr(hbitmap, BITMAP_MAGIC)))
47     return FALSE;
48   
49   if(flags == DDB_GET)
50     result = TTYDRV_DC_GetBitmapBits(bitmap, bits, count);
51   else if(flags == DDB_SET)
52     result = TTYDRV_DC_SetBitmapBits(bitmap, bits, count);
53   else {
54     ERR("Unknown flags value %d\n", flags);
55     result = 0;
56   }
57   
58   GDI_HEAP_UNLOCK(hbitmap);
59   return result;
60 }
61
62 /***********************************************************************
63  *              TTYDRV_DC_CreateBitmap
64  */
65 BOOL TTYDRV_DC_CreateBitmap(HBITMAP hbitmap)
66 {
67   TTYDRV_PHYSBITMAP *physBitmap;
68   BITMAPOBJ *bitmap;
69
70   TRACE("(0x%04x)\n", hbitmap);
71
72   if(!(bitmap = (BITMAPOBJ *) GDI_GetObjPtr(hbitmap, BITMAP_MAGIC)))
73     return FALSE;
74   
75   if(!(physBitmap = TTYDRV_DC_AllocBitmap(bitmap))) {
76     GDI_HEAP_UNLOCK(hbitmap);
77     return FALSE;
78   }
79  
80   /* Set bitmap bits */
81   if(bitmap->bitmap.bmBits) { 
82     TTYDRV_DC_BitmapBits(hbitmap, bitmap->bitmap.bmBits,
83                          bitmap->bitmap.bmHeight * bitmap->bitmap.bmWidthBytes,
84                          DDB_SET );
85   }
86
87   GDI_HEAP_UNLOCK(hbitmap);
88   
89   return TRUE;
90 }
91
92 /***********************************************************************
93  *              TTYDRV_DC_BITMAP_DeleteObject
94  */
95 BOOL TTYDRV_DC_BITMAP_DeleteObject(HBITMAP hbitmap, BITMAPOBJ *bitmap)
96 {
97   TRACE("(0x%04x, %p)\n", hbitmap, bitmap);
98
99   HeapFree(GetProcessHeap(), 0, bitmap->physBitmap);
100   bitmap->physBitmap = NULL;
101   bitmap->funcs = NULL;
102
103   return TRUE;
104 }
105
106 /***********************************************************************
107  *              TTYDRV_DC_GetBitmapBits
108  */
109 static LONG TTYDRV_DC_GetBitmapBits(BITMAPOBJ *bitmap, void *bits, LONG count)
110 {
111   FIXME("(%p, %p, %ld): stub\n", bitmap, bits, count);
112
113   memset(bits, 0, count);
114
115   return count;
116 }
117
118 /***********************************************************************
119  *              TTYDRV_DC_BITMAP_SelectObject
120  */
121 HBITMAP TTYDRV_DC_BITMAP_SelectObject(DC *dc, HBITMAP hbitmap, BITMAPOBJ *bitmap)
122 {
123   HBITMAP hPreviousBitmap;
124
125   TRACE("(%p, 0x%04x, %p)\n", dc, hbitmap, bitmap);
126
127   if(!(dc->w.flags & DC_MEMORY)) 
128     return 0;
129
130   /* Assure that the bitmap device dependent */
131   if(!bitmap->physBitmap && !TTYDRV_DC_CreateBitmap(hbitmap))
132     return 0;
133
134   if(bitmap->funcs != dc->funcs) {
135     ERR("Trying to select a non-TTY DDB into a TTY DC\n");
136     return 0;
137   }
138
139   dc->w.totalExtent.left   = 0;
140   dc->w.totalExtent.top    = 0;
141   dc->w.totalExtent.right  = bitmap->bitmap.bmWidth;
142   dc->w.totalExtent.bottom = bitmap->bitmap.bmHeight;
143
144   /* FIXME: Should be done in the common code instead */
145   if(dc->w.hVisRgn) {
146     SetRectRgn(dc->w.hVisRgn, 0, 0,
147                bitmap->bitmap.bmWidth, bitmap->bitmap.bmHeight);
148   } else { 
149     HRGN hrgn;
150
151     if(!(hrgn = CreateRectRgn(0, 0, bitmap->bitmap.bmWidth, bitmap->bitmap.bmHeight)))
152       return 0;
153
154     dc->w.hVisRgn = hrgn;
155   }
156
157   hPreviousBitmap = dc->w.hBitmap;
158   dc->w.hBitmap = hbitmap;
159
160   return hPreviousBitmap;
161 }
162
163 /***********************************************************************
164  *              TTYDRV_DC_SetBitmapBits
165  */
166 static LONG TTYDRV_DC_SetBitmapBits(BITMAPOBJ *bitmap, void *bits, LONG count)
167 {
168   FIXME("(%p, %p, %ld): semistub\n", bitmap, bits, count);
169
170   return count;
171 }