wip prep commit in lieu of gfx subsystem update changes.
[AROS.git] / arch / all-mingw32 / hidd / wingdi / wingdi_bitmapclass.c
blobde71c16ffeef5154e345b323f34a24888eb235f3
1 /*
2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Bitmap class for GDI hidd.
6 Lang: English.
8 Note: this implementation ignores GC_COLMASK. Windows GDI has no way to support it,
9 however color masks seem to be not used anywhere in AROS.
12 /****************************************************************************************/
14 #define __OOP_NOATTRBASES__
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <string.h>
20 #include <proto/oop.h>
21 #include <proto/utility.h>
22 #include <exec/alerts.h>
23 #include <aros/macros.h>
24 #include <exec/memory.h>
25 #include <exec/lists.h>
26 #include <graphics/rastport.h>
27 #include <graphics/gfx.h>
28 #include <oop/oop.h>
29 #include <hidd/gfx.h>
30 #include <aros/symbolsets.h>
32 #define SDEBUG 0
33 #define DEBUG 0
34 #define DEBUG_TEXT(x)
35 #include <aros/debug.h>
37 #include LC_LIBDEFS_FILE
39 #include "gdi.h"
41 #include "wingdi_bitmap.h"
43 /****************************************************************************************/
45 #define AO(x) (aoHidd_BitMap_ ## x)
46 #define GOT_BM_ATTR(code) GOT_ATTR(code, aoHidd_BitMap, bitmap)
48 struct bitmapinfo_mono
50 BITMAPINFOHEADER bmiHeader;
51 UWORD bmiColors[2];
54 static OOP_AttrBase HiddBitMapAttrBase;
55 static OOP_AttrBase HiddSyncAttrBase;
56 static OOP_AttrBase HiddPixFmtAttrBase;
57 static OOP_AttrBase HiddGDIBitMapAB;
59 static struct OOP_ABDescr attrbases[] =
61 { IID_Hidd_BitMap , &HiddBitMapAttrBase },
62 { IID_Hidd_Sync , &HiddSyncAttrBase },
63 { IID_Hidd_PixFmt , &HiddPixFmtAttrBase },
64 /* Private bases */
65 { IID_Hidd_BitMap_WinGDI, &HiddGDIBitMapAB },
66 { NULL , NULL }
69 /****************************************************************************************/
71 #ifdef DEBUG_PLANAR
72 #define PRINT_PLANE(bm, n, startx, xlim, ylim) \
73 { \
74 ULONG start = startx / 8; \
75 ULONG xlimit = xlim / 8; \
76 ULONG ylimit = (ylim < bm.Rows) ? ylim : bm.Rows; \
77 UBYTE *plane = bm.Planes[n] + start; \
78 UBYTE i; \
79 ULONG x, y; \
81 if (xlimit > (start - bm.BytesPerRow)) \
82 xlimit = start - bm.BytesPerRow; \
83 bug("[GDIBitMap] Plane %u data (%u pixels from %u, address 0x%p):\n", n, xlimit * 8, start * 8, plane); \
84 for (y = 0; y < ylimit; y++) { \
85 for (x = 0; x < xlimit; x++) { \
86 for (i = 0x80; i; i >>= 1) \
87 bug((plane[x] & i) ? "#" : "."); \
88 } \
89 bug("\n"); \
90 plane += bm.BytesPerRow; \
91 } \
94 #define PRINT_MONO_DC(dc, startx, starty, width, height) \
95 { \
96 ULONG x, y; \
98 bug("[GDIBitMap] Device context data:\n"); \
99 for (y = starty; y < height; y++) { \
100 for (x = startx; x < width; x++) { \
101 ULONG pix = GDICALL(GetPixel, dc, x, y); \
103 bug(pix ? "." : "#"); \
105 bug("\n"); \
109 #else
110 #define PRINT_PLANE(bm, n, startx, xlim, ylim)
111 #define PRINT_MONO_DC(dc, startx, starty, width, height)
112 #endif
114 /****************************************************************************************/
116 VOID GDIBM__Hidd_BitMap__PutPixel(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutPixel *msg)
118 struct bitmap_data *data = OOP_INST_DATA(cl, o);
120 DB2(bug("[WinGDI:BitMap] hidd.bitmap.gdibitmap::PutPixel(0x%p): (%lu, %lu) = 0x%08lX\n", o, msg->x, msg->y, msg->pixel));
121 Forbid();
122 GDICALL(SetROP2, data->dc, R2_COPYPEN);
123 GDICALL(SetPixel, data->dc, msg->x, msg->y, msg->pixel);
124 Permit();
125 CHECK_STACK
128 /****************************************************************************************/
130 HIDDT_Pixel GDIBM__Hidd_BitMap__GetPixel(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_GetPixel *msg)
132 struct bitmap_data *data = OOP_INST_DATA(cl, o);
133 HIDDT_Pixel pixel;
135 Forbid();
136 pixel = GDICALL(GetPixel, data->dc, msg->x, msg->y);
137 Permit();
138 CHECK_STACK
140 return pixel;
143 /****************************************************************************************/
145 static void FillRect(struct bitmap_data *data, ULONG col, ULONG mode, ULONG minX, ULONG minY, ULONG width, ULONG height)
147 APTR br, orig_br;
148 DB2(bug("[WinGDI:BitMap] Brush color 0x%08lX, mode 0x%08lX\n", col, mode));
150 Forbid();
151 br = GDICALL(CreateSolidBrush, col);
152 if (br) {
153 orig_br = GDICALL(SelectObject, data->dc, br);
154 GDICALL(PatBlt, data->dc, minX, minY, width, height, mode);
155 GDICALL(SelectObject, data->dc, orig_br);
156 GDICALL(DeleteObject, br);
158 Permit();
161 /* Table of raster operations (ROPs) corresponding to AROS GC drawmodes */
162 static ULONG Fill_DrawModeTable[] = {
163 BLACKNESS,
164 0x00A000C9,
165 0x00500325,
166 PATCOPY,
167 0x000A0329,
168 0x00AA0029,
169 PATINVERT,
170 0x00FA0089,
171 0x000500A9,
172 0x00A50065, /* PDnx - not sure */
173 DSTINVERT,
174 0x00F50225,
175 0x000F0001,
176 0x00AF0229,
177 0x005F00E9,
178 WHITENESS
181 VOID GDIBM__Hidd_BitMap__FillRect(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_DrawRect *msg)
183 struct bitmap_data *data = OOP_INST_DATA(cl, o);
184 ULONG col = GC_FG(msg->gc);
185 ULONG mode = Fill_DrawModeTable[GC_DRMD(msg->gc)];
187 D(bug("[WinGDI:BitMap] hidd.bitmap.gdibitmap::FillRect(0x%p, %d,%d,%d,%d)\n", o, msg->minX, msg->minY, msg->maxX, msg->maxY));
188 FillRect(data, col, mode, msg->minX, msg->minY, msg->maxX - msg->minX + 1, msg->maxY - msg->minY + 1);
189 CHECK_STACK
192 /****************************************************************************************/
194 /* Raster operations for drawing primitives */
195 static ULONG R2_DrawModeTable[] = {
196 R2_BLACK,
197 R2_MASKPEN, /* bitmap AND pen */
198 R2_MASKPENNOT, /* NOT bitmap AND pen */
199 R2_COPYPEN, /* pen */
200 R2_MASKNOTPEN, /* bitmap AND NOT pen */
201 R2_NOP, /* bitmap */
202 R2_XORPEN, /* bitmap XOR pen */
203 R2_MERGEPEN, /* bitmap OR pen */
204 R2_NOTMERGEPEN, /* NOT (bitmap OR pen) */
205 R2_NOTXORPEN, /* NOT (bitmap XOR pen) */
206 R2_NOT, /* NOT bitmap */
207 R2_MERGEPENNOT, /* NOT bitmap OR pen */
208 R2_NOTCOPYPEN, /* NOT pen */
209 R2_MERGENOTPEN, /* NOT pen OR bitmap */
210 R2_NOTMASKPEN, /* NOT (pen AND bitmap) */
211 R2_WHITE
214 ULONG GDIBM__Hidd_BitMap__DrawPixel(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_DrawPixel *msg)
216 struct bitmap_data *data = OOP_INST_DATA(cl, o);
217 ULONG col, mode;
219 DB2(bug("[WinGDI:BitMap] hidd.bitmap.gdibitmap::DrawPixel(0x%p): (%lu, %lu)\n", o, msg->x, msg->y));
220 col = GC_FG(msg->gc);
221 mode = R2_DrawModeTable[GC_DRMD(msg->gc)];
223 Forbid();
224 GDICALL(SetROP2, data->dc, mode);
225 GDICALL(SetPixel, data->dc, msg->x, msg->y, col);
226 Permit();
227 CHECK_STACK
228 return 0;
231 /****************************************************************************************/
233 /* Raster operations for copying a bitmap */
234 ULONG Copy_DrawModeTable[] = {
235 BLACKNESS,
236 SRCAND, /* DSa - src AND dest */
237 SRCERASE, /* SDna - src AND NOT dest */
238 SRCCOPY, /* S - src */
239 0x00220326, /* DSna - NOT src AND dest */
240 0x00AA0029, /* D - dest */
241 SRCINVERT, /* DSx - src XOR dest */
242 SRCPAINT, /* DSo - src OR dest */
243 NOTSRCERASE, /* DSon - NOT (src OR dest) */
244 0x00990066, /* DSxn - NOT (src XOR dest) */
245 DSTINVERT, /* Dn - NOT dest */
246 0x00DD0228, /* SDno - src OR NOT dest */
247 NOTSRCCOPY, /* Sn - NOT src */
248 MERGEPAINT, /* DSno - NOT src OR dest */
249 0x007700E6, /* DSan - NOT (src AND dest) */
250 WHITENESS
253 VOID GDIBM__Hidd_BitMap__PutImage(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutImage *msg)
255 struct bitmap_data *data = OOP_INST_DATA(cl, o);
256 HIDDT_PixelFormat *src_pixfmt, *dst_pixfmt;
257 OOP_Object *gfxhidd;
258 HIDDT_StdPixFmt src_stdpf;
259 APTR buf, src, dst;
260 ULONG bufmod, bufsize;
261 BITMAPINFOHEADER bitmapinfo =
263 sizeof(BITMAPINFOHEADER),
264 0, 0,
267 BI_RGB,
268 0, 0, 0, 0, 0
271 /* EnterFunc(bug("GDIGfx.BitMap::PutImage(pa=%p, x=%d, y=%d, w=%d, h=%d)\n",
272 msg->pixels, msg->x, msg->y, msg->width, msg->height));*/
274 switch(msg->pixFmt) {
275 case vHidd_StdPixFmt_Native:
276 case vHidd_StdPixFmt_Native32:
277 src_stdpf = vHidd_StdPixFmt_0BGR32_Native;
278 break;
279 default:
280 src_stdpf = msg->pixFmt;
283 bufmod = msg->width * sizeof(HIDDT_Pixel);
284 bufsize = bufmod * msg->height;
285 buf = AllocMem(bufsize, MEMF_ANY);
286 if (buf)
288 ULONG drmd = GC_DRMD(msg->gc);
290 OOP_GetAttr(o, aHidd_BitMap_GfxHidd, (IPTR *)&gfxhidd);
291 src_pixfmt = (HIDDT_PixelFormat *)HIDD_Gfx_GetPixFmt(gfxhidd, src_stdpf);
292 /* DIB pixels are expected to be 0x00RRGGBB */
293 dst_pixfmt = (HIDDT_PixelFormat *)HIDD_Gfx_GetPixFmt(gfxhidd, vHidd_StdPixFmt_0RGB32_Native);
294 src = msg->pixels;
295 dst = buf;
296 HIDD_BM_ConvertPixels(o, &src, src_pixfmt, msg->modulo, &dst, dst_pixfmt, bufmod,
297 msg->width, msg->height, NULL);
298 bitmapinfo.biWidth = msg->width;
299 bitmapinfo.biHeight = -msg->height; /* Minus here means top-down bitmap */
300 Forbid();
301 GDICALL(StretchDIBits, data->dc, msg->x, msg->y, msg->width, msg->height, 0, 0, msg->width, msg->height, buf, (BITMAPINFO *)&bitmapinfo, DIB_RGB_COLORS, Copy_DrawModeTable[drmd]);
302 Permit();
303 FreeMem(buf, bufsize);
305 CHECK_STACK
308 /****************************************************************************************/
310 /* TODO: These little stubs help to detect methods calls */
312 VOID GDIBM__Hidd_BitMap__PutImageLUT(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutImageLUT *msg)
314 EnterFunc(bug("GDIGfx.BitMap::PutImageLUT(pa=%p, x=%d, y=%d, w=%d, h=%d)\n",
315 msg->pixels, msg->x, msg->y, msg->width, msg->height));
317 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
318 CHECK_STACK
321 VOID GDIBM__Hidd_BitMap__GetImageLUT(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_GetImageLUT *msg)
323 EnterFunc(bug("GDIGfx.BitMap::GetImageLUT(pa=%p, x=%d, y=%d, w=%d, h=%d)\n",
324 msg->pixels, msg->x, msg->y, msg->width, msg->height));
326 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
327 CHECK_STACK
330 /****************************************************************************************/
332 VOID GDIBM__Hidd_BitMap__GetImage(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_GetImage *msg)
334 struct bitmap_data *data = OOP_INST_DATA(cl, o);
335 HIDDT_PixelFormat *src_pixfmt, *dst_pixfmt;
336 OOP_Object *gfxhidd;
337 HIDDT_StdPixFmt dst_stdpf;
338 APTR tmp_dc, tmp_bitmap, dc_bitmap;
339 APTR buf, src, dst;
340 ULONG bufmod, bufsize;
341 BITMAPINFOHEADER bitmapinfo = {
342 sizeof(BITMAPINFOHEADER),
343 0, 0,
346 BI_RGB,
347 0, 0, 0, 0, 0
350 /* EnterFunc(bug("GDIGfx.BitMap::GetImage(pa=%p, x=%d, y=%d, w=%d, h=%d)\n",
351 msg->pixels, msg->x, msg->y, msg->width, msg->height));*/
353 switch(msg->pixFmt) {
354 case vHidd_StdPixFmt_Native:
355 case vHidd_StdPixFmt_Native32:
356 dst_stdpf = vHidd_StdPixFmt_0BGR32_Native;
357 break;
358 default:
359 dst_stdpf = msg->pixFmt;
362 bufmod = msg->width * sizeof(HIDDT_Pixel);
363 bufsize = bufmod * msg->height;
364 buf = AllocMem(bufsize, MEMF_ANY);
365 if (buf) {
366 /* First we have to extract requested rectangle into temporary bitmap because GetDIBits() can limit only scan lines number */
367 Forbid();
368 tmp_dc = GDICALL(CreateCompatibleDC, data->display);
369 if (tmp_dc) {
370 tmp_bitmap = GDICALL(CreateCompatibleBitmap, data->display, msg->width, msg->height);
371 if (tmp_bitmap) {
372 dc_bitmap = GDICALL(SelectObject, tmp_dc, tmp_bitmap);
373 if (dc_bitmap) {
374 GDICALL(BitBlt, tmp_dc, 0, 0, msg->width, msg->height, data->dc, msg->x, msg->y, SRCCOPY);
375 bitmapinfo.biWidth = msg->width;
376 bitmapinfo.biHeight = -msg->height; /* Minus here means top-down bitmap */
377 GDICALL(GetDIBits, tmp_dc, tmp_bitmap, 0, msg->height, buf, (BITMAPINFO *)&bitmapinfo, DIB_RGB_COLORS);
378 GDICALL(SelectObject, tmp_dc, dc_bitmap);
380 GDICALL(DeleteObject, tmp_bitmap);
382 GDICALL(DeleteDC, tmp_dc);
384 Permit();
385 OOP_GetAttr(o, aHidd_BitMap_GfxHidd, (IPTR *)&gfxhidd);
386 /* DIB pixels will be 0x00RRGGBB) */
387 src_pixfmt = (HIDDT_PixelFormat *)HIDD_Gfx_GetPixFmt(gfxhidd, vHidd_StdPixFmt_0RGB32_Native);
388 dst_pixfmt = (HIDDT_PixelFormat *)HIDD_Gfx_GetPixFmt(gfxhidd, dst_stdpf);
389 dst = msg->pixels;
390 src = buf;
391 HIDD_BM_ConvertPixels(o, &src, src_pixfmt, bufmod, &dst, dst_pixfmt, msg->modulo,
392 msg->width, msg->height, NULL);
393 FreeMem(buf, bufsize);
395 CHECK_STACK
398 /****************************************************************************************/
400 VOID GDIBM__Root__Get(OOP_Class *cl, OOP_Object *o, struct pRoot_Get *msg)
402 struct bitmap_data *data = OOP_INST_DATA(cl, o);
403 ULONG idx;
405 if (IS_GDIBM_ATTR(msg->attrID, idx)) {
406 switch (idx)
408 case aoHidd_GDIBitMap_DeviceContext:
409 *msg->storage = (IPTR)data->dc;
410 return;
412 } else if (IS_BM_ATTR(msg->attrID, idx)) {
413 switch (idx)
415 case aoHidd_BitMap_LeftEdge:
416 *msg->storage = data->bm_left;
417 return;
418 case aoHidd_BitMap_TopEdge:
419 *msg->storage = data->bm_top;
420 return;
423 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
426 /****************************************************************************************/
428 VOID GDIBM__Root__Set(OOP_Class *cl, OOP_Object *obj, struct pRoot_Set *msg)
430 struct bitmap_data *data = OOP_INST_DATA(cl, obj);
431 struct TagItem *tag, *tstate;
432 ULONG idx;
433 BOOL change_position = FALSE;
435 tstate = msg->attrList;
436 while((tag = NextTagItem(&tstate)))
438 if (IS_BM_ATTR(tag->ti_Tag, idx)) {
439 switch(idx)
441 case aoHidd_BitMap_LeftEdge:
442 data->bm_left = tag->ti_Data;
443 change_position = TRUE;
444 break;
445 case aoHidd_BitMap_TopEdge:
446 data->bm_top = tag->ti_Data;
447 change_position = TRUE;
448 break;
453 if (change_position) {
454 /* Fix up position. We can completely scroll out
455 of our window into all 4 sides, but not more */
456 if (data->bm_left > data->win_width)
457 data->bm_left = data->win_width;
458 else if (data->bm_left < -data->bm_width)
459 data->bm_left = -data->bm_width;
460 if (data->bm_top > data->win_height)
461 data->bm_top = data->win_height;
462 else if (data->bm_top < -data->bm_height)
463 data->bm_top = -data->bm_height;
465 Forbid();
466 if (data->window)
467 USERCALL(SetWindowPos, data->window, NULL, data->bm_left - 1, data->bm_top - 1, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
468 Permit();
471 OOP_DoSuperMethod(cl, obj, (OOP_Msg)msg);
474 /****************************************************************************************/
476 OOP_Object *GDIBM__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
478 OOP_Object *friend = NULL, *pixfmt;
479 APTR display, my_dc, my_bitmap = NULL;
480 APTR orig_bitmap = NULL;
481 ULONG width, height;
482 HIDDT_ModeID modeid;
483 IPTR win_width = 0;
484 IPTR win_height = 0;
485 IPTR depth;
486 IPTR attrs[num_Hidd_BitMap_Attrs];
487 struct bitmap_data *data;
489 DECLARE_ATTRCHECK(bitmap);
491 EnterFunc(bug("GDIBM::New()\n"));
492 /* Parse the attributes */
493 if (0 != OOP_ParseAttrs(msg->attrList, attrs, num_Hidd_BitMap_Attrs,
494 &ATTRCHECK(bitmap), HiddBitMapAttrBase))
496 D(kprintf("!!! GDIGfx::BitMap() FAILED TO PARSE ATTRS !!!\n"));
498 return NULL;
501 if (GOT_BM_ATTR(Friend))
502 friend = (OOP_Object *)attrs[AO(Friend)];
503 else
504 friend = NULL;
506 width = attrs[AO(Width)];
507 height = attrs[AO(Height)];
508 pixfmt = (OOP_Object *)attrs[AO(PixFmt)];
510 OOP_GetAttr(pixfmt, aHidd_PixFmt_Depth, &depth);
512 /* Get the device context from the friend bitmap */
513 #if 0
514 if (NULL != friend)
516 OOP_GetAttr(friend, aHidd_GDIBitMap_Drawable, (IPTR *)&friend_drawable);
518 #else
519 (void)friend; // Unused
520 #endif
522 D(bug("Creating GDI bitmap: %ldx%ldx%ld\n", width, height, depth));
523 display = (APTR)GetTagData(aHidd_GDIBitMap_SysDisplay, 0, msg->attrList);
524 modeid = (HIDDT_ModeID)GetTagData(aHidd_BitMap_ModeID, vHidd_ModeID_Invalid, msg->attrList);
525 /* This relies on the fact that bitmaps with aHidd_BitMap_Displayable set to TRUE always
526 also get aHidd_BitMap_ModeID with valid value. Currently this seems to be true and i
527 beleive it should stay so */
528 if (modeid != vHidd_ModeID_Invalid) {
529 OOP_Object *gfx = (OOP_Object *)attrs[AO(GfxHidd)];
530 OOP_Object *sync, *pixfmt;
532 D(bug("[WinGDI:BitMap] Display driver object: 0x%p\n", gfx));
533 HIDD_Gfx_GetMode(gfx, modeid, &sync, &pixfmt);
534 OOP_GetAttr(sync, aHidd_Sync_HDisp, &win_width);
535 OOP_GetAttr(sync, aHidd_Sync_VDisp, &win_height);
536 D(bug("[WinGDI:BitMap] Display window size: %dx%d\n", win_width, win_height));
539 Forbid();
540 my_dc = GDICALL(CreateCompatibleDC, display);
541 D(bug("[WinGDI:BitMap] Memory device context: 0x%p\n", my_dc));
542 if (my_dc) {
543 my_bitmap = GDICALL(CreateCompatibleBitmap, display, (width + 15) & ~15, height);
544 D(bug("[WinGDI:BitMap] Memory bitmap: 0x%p\n", my_bitmap));
545 if (my_bitmap)
546 orig_bitmap = GDICALL(SelectObject, my_dc, my_bitmap);
547 D(bug("[WinGDI:BitMap] Olriginal DC bitmap: 0x%p\n", orig_bitmap));
549 Permit();
551 if (!my_dc)
552 return NULL;
553 if (!orig_bitmap)
554 goto dispose_bitmap;
556 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg) msg);
557 D(bug("[WinGDI:BitMap] Object created by superclass: 0x%p\n", o));
558 if (o) {
559 data = OOP_INST_DATA(cl, o);
560 /* Get some info passed to us by the gdigfxhidd class */
561 data->dc = my_dc;
562 data->bitmap = my_bitmap;
563 data->dc_bitmap = orig_bitmap;
564 data->display = display;
565 data->window = NULL;
566 data->win_width = win_width;
567 data->win_height = win_height;
568 data->bm_width = width;
569 data->bm_height = height;
570 data->bm_left = 0;
571 data->bm_top = 0;
572 CHECK_STACK
573 ReturnPtr("GDIGfx.BitMap::New()", OOP_Object *, o);
574 } /* if (object allocated by superclass) */
575 dispose_bitmap:
576 Forbid();
577 if (orig_bitmap)
578 GDICALL(SelectObject, my_dc, orig_bitmap);
579 if (my_bitmap)
580 GDICALL(DeleteObject, my_bitmap);
581 GDICALL(DeleteDC, my_dc);
582 Permit();
584 ReturnPtr("GDIGfx.BitMap::New()", OOP_Object *, NULL);
588 /****************************************************************************************/
590 VOID GDIBM__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
592 struct bitmap_data *data = OOP_INST_DATA(cl, o);
594 EnterFunc(bug("GDIGfx.BitMap::Dispose()\n"));
596 Forbid();
597 if (data->node.mln_Pred)
598 Remove((struct Node *)data);
599 if (data->window)
600 NATIVECALL(GDI_PutMsg, data->window, WM_CLOSE, 0, 0);
601 if (data->dc_bitmap)
602 GDICALL(SelectObject, data->dc, data->dc_bitmap);
603 if (data->bitmap)
604 GDICALL(DeleteObject, data->bitmap);
605 if (data->dc)
606 GDICALL(DeleteDC, data->dc);
607 Permit();
609 OOP_DoSuperMethod(cl, o, msg);
611 CHECK_STACK
612 ReturnVoid("GDIGfx.BitMap::Dispose");
615 /****************************************************************************************/
617 VOID GDIBM__Hidd_BitMap__Clear(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_Clear *msg)
619 struct bitmap_data *data = OOP_INST_DATA(cl, o);
620 IPTR width, height;
622 EnterFunc(bug("[WinGDI:BitMap] hidd.bitmap.gdibitmap::Clear()\n"));
624 /* Get width & height from bitmap superclass */
626 OOP_GetAttr(o, aHidd_BitMap_Width, &width);
627 OOP_GetAttr(o, aHidd_BitMap_Height, &height);
629 FillRect(data, GC_BG(msg->gc), PATCOPY, 0, 0, width, height);
632 /****************************************************************************************/
634 VOID GDIBM__Hidd_BitMap__UpdateRect(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_UpdateRect *msg)
636 struct bitmap_data *data = OOP_INST_DATA(cl, o);
638 Forbid();
639 if (data->window) {
640 RECT r = {
641 msg->x,
642 msg->y,
643 msg->x + msg->width,
644 msg->y + msg->height
647 USERCALL(RedrawWindow, data->window, &r, NULL, RDW_INVALIDATE|RDW_UPDATENOW);
649 Permit();
652 /****************************************************************************************/
654 static int GDIBM_Init(LIBBASETYPEPTR LIBBASE)
656 return OOP_ObtainAttrBases(attrbases);
659 /****************************************************************************************/
661 static int GDIBM_Expunge(LIBBASETYPEPTR LIBBASE)
663 OOP_ReleaseAttrBases(attrbases);
664 return TRUE;
667 /****************************************************************************************/
669 ADD2INITLIB(GDIBM_Init, 0);
670 ADD2EXPUNGELIB(GDIBM_Expunge, 0);