Test initialisation of MUIA_List_AdjustWidth and MUIA_List_AdjustHeight, and
[AROS.git] / arch / all-mingw32 / hidd / wingdi / gdigfx.c
blobfdbdcef1848a9f9575aa9b4899253a1d8bbcd45b
1 /*
2 Copyright 1995-2015, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: GDI gfx HIDD for AROS.
6 Lang: English.
7 */
9 #define __OOP_NOATTRBASES__
11 #include <exec/libraries.h>
12 #include <exec/rawfmt.h>
13 #include <exec/types.h>
14 #include <exec/resident.h>
15 #include <exec/memory.h>
16 #include <graphics/displayinfo.h>
17 #include <aros/libcall.h>
18 #include <proto/alib.h>
19 #include <proto/exec.h>
20 #include <proto/kernel.h>
21 #include <proto/oop.h>
22 #include <proto/utility.h>
23 #include <oop/oop.h>
25 #include <hidd/hidd.h>
26 #include <hidd/graphics.h>
28 #include <aros/symbolsets.h>
30 #include "gdi.h"
31 #include "bitmap.h"
33 #include LC_LIBDEFS_FILE
35 #define SDEBUG 0
36 #define DEBUG 0
37 #include <aros/debug.h>
39 #ifdef DEBUG_POINTER
41 #define PRINT_POINTER(image, xsize, xmax, ymax) \
42 bug("[GDIGfx] Pointer data:\n"); \
43 { \
44 ULONG *pix = (ULONG *)image; \
45 ULONG x, y; \
47 for (y = 0; y < ymax; y++) { \
48 for (x = 0; x < xmax; x++) \
49 bug("0x%08X ", pix[x]); \
50 bug("\n"); \
51 pix += xsize; \
52 } \
55 #else
56 #define PRINT_POINTER(image, xsize, xmax, ymax)
57 #endif
59 /****************************************************************************************/
61 /* Some attrbases needed as global vars.
62 These are write-once read-many */
64 static OOP_AttrBase HiddBitMapAttrBase;
65 static OOP_AttrBase HiddGDIBitMapAB;
66 static OOP_AttrBase HiddSyncAttrBase;
67 static OOP_AttrBase HiddPixFmtAttrBase;
68 static OOP_AttrBase HiddGfxAttrBase;
69 OOP_AttrBase HiddAttrBase;
71 static struct OOP_ABDescr attrbases[] =
73 { IID_Hidd_BitMap , &HiddBitMapAttrBase },
74 { IID_Hidd_GDIBitMap, &HiddGDIBitMapAB },
75 { IID_Hidd_Sync , &HiddSyncAttrBase },
76 { IID_Hidd_PixFmt , &HiddPixFmtAttrBase },
77 { IID_Hidd_Gfx , &HiddGfxAttrBase },
78 { IID_Hidd , &HiddAttrBase },
79 { NULL , NULL }
82 static void GfxIntHandler(struct gdi_staticdata *xsd, void *unused)
84 struct gfx_data *active;
86 /* Process ShowDone IRQ */
87 if (xsd->ctl->ShowDone)
89 xsd->ctl->ShowDone = FALSE;
90 if (xsd->showtask)
91 Signal(xsd->showtask, SIGF_BLIT);
94 /* Process display window activation */
95 active = xsd->ctl->Active;
96 if (active)
98 xsd->ctl->Active = NULL;
99 D(bug("Activated display data 0x%p\n", active));
100 if (active->cb)
101 active->cb(active->cbdata, NULL);
105 /****************************************************************************************/
107 OOP_Object *GDICl__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
109 struct TagItem pftags[] =
111 /* Shifts are non-obviously calculated from the MSB, not from the LSB.
112 I. e. color value is placed in the most significant byte of the ULONG
113 before shifting (cc000000, not 000000cc) */
114 { aHidd_PixFmt_RedShift , 24 },
115 { aHidd_PixFmt_GreenShift , 16 },
116 { aHidd_PixFmt_BlueShift , 8 },
117 { aHidd_PixFmt_AlphaShift , 0 },
118 { aHidd_PixFmt_RedMask , 0x000000FF },
119 { aHidd_PixFmt_GreenMask , 0x0000FF00 },
120 { aHidd_PixFmt_BlueMask , 0x00FF0000 },
121 { aHidd_PixFmt_AlphaMask , 0x00000000 },
122 /* Windows effectively hides from us all details of
123 color management and everything looks like if the
124 display mode is always truecolor */
125 { aHidd_PixFmt_ColorModel , vHidd_ColorModel_TrueColor },
126 { aHidd_PixFmt_Depth , 24 },
127 { aHidd_PixFmt_BytesPerPixel, 4 },
128 { aHidd_PixFmt_BitsPerPixel , 24 },
129 { aHidd_PixFmt_StdPixFmt , vHidd_StdPixFmt_Native },
130 { aHidd_PixFmt_BitMapType , vHidd_BitMapType_Chunky },
131 { TAG_DONE , 0UL }
134 struct TagItem tags_160_160[] =
136 { aHidd_Sync_HDisp , 160 },
137 { aHidd_Sync_VDisp , 160 },
138 { TAG_DONE , 0UL }
141 struct TagItem tags_240_320[] =
143 { aHidd_Sync_HDisp , 240 },
144 { aHidd_Sync_VDisp , 320 },
145 { TAG_DONE , 0UL }
148 struct TagItem tags_320_240[] =
150 { aHidd_Sync_HDisp , 320 },
151 { aHidd_Sync_VDisp , 240 },
152 { TAG_DONE , 0UL }
155 struct TagItem tags_512_384[] =
157 { aHidd_Sync_HDisp , 512 },
158 { aHidd_Sync_VDisp , 384 },
159 { TAG_DONE , 0UL }
162 struct TagItem tags_640_480[] =
164 { aHidd_Sync_HDisp , 640 },
165 { aHidd_Sync_VDisp , 480 },
166 { TAG_DONE , 0UL }
169 struct TagItem tags_800_600[] =
171 { aHidd_Sync_HDisp , 800 },
172 { aHidd_Sync_VDisp , 600 },
173 { TAG_DONE , 0UL }
176 struct TagItem tags_1024_768[] =
178 { aHidd_Sync_HDisp , 1024 },
179 { aHidd_Sync_VDisp , 768 },
180 { TAG_DONE , 0UL }
183 struct TagItem tags_1152_864[] =
185 { aHidd_Sync_HDisp , 1152 },
186 { aHidd_Sync_VDisp , 864 },
187 { TAG_DONE , 0UL }
190 struct TagItem tags_1280_800[] =
192 { aHidd_Sync_HDisp , 1280 },
193 { aHidd_Sync_VDisp , 800 },
194 { TAG_DONE , 0UL }
197 struct TagItem tags_1280_960[] =
199 { aHidd_Sync_HDisp , 1280 },
200 { aHidd_Sync_VDisp , 960 },
201 { TAG_DONE , 0UL }
204 struct TagItem tags_1280_1024[] =
206 { aHidd_Sync_HDisp , 1280 },
207 { aHidd_Sync_VDisp , 1024 },
208 { TAG_DONE , 0UL }
211 struct TagItem tags_1600_1200[] =
213 { aHidd_Sync_HDisp , 1600 },
214 { aHidd_Sync_VDisp , 1200 },
215 { TAG_DONE , 0UL }
218 struct TagItem mode_tags[] =
220 { aHidd_Gfx_PixFmtTags , (IPTR)pftags },
222 /* Default values for the sync attributes */
223 { aHidd_Sync_PixelClock , 0 },
224 { aHidd_Sync_HTotal , 0 },
225 { aHidd_Sync_VTotal , 0 },
226 { aHidd_Sync_HMin , 112 }, /* In fact these can be even smaller, and */
227 { aHidd_Sync_VMin , 112 }, /* maximum can be even bigger... */
228 { aHidd_Sync_HMax , 16384 },
229 { aHidd_Sync_VMax , 16384 },
230 /* Formatting stands for:
231 %b - board number
232 %h - HDisp
233 %v - VDisp */
234 { aHidd_Sync_Description, (IPTR)"Windows %b: %hx%v"},
235 { aHidd_Sync_BoardNumber, XSD(cl)->displaynum },
237 /* The different syncmodes. The default attribute values above
238 will be applied to each of these. Note that
239 you can alter the defaults between the tags below
241 { aHidd_Gfx_SyncTags , (IPTR)tags_160_160 },
242 { aHidd_Gfx_SyncTags , (IPTR)tags_240_320 },
243 { aHidd_Gfx_SyncTags , (IPTR)tags_320_240 },
244 { aHidd_Gfx_SyncTags , (IPTR)tags_512_384 },
245 { aHidd_Gfx_SyncTags , (IPTR)tags_640_480 },
246 { aHidd_Gfx_SyncTags , (IPTR)tags_800_600 },
247 { aHidd_Gfx_SyncTags , (IPTR)tags_1024_768 },
248 { aHidd_Gfx_SyncTags , (IPTR)tags_1152_864 },
249 { aHidd_Gfx_SyncTags , (IPTR)tags_1280_800 },
250 { aHidd_Gfx_SyncTags , (IPTR)tags_1280_960 },
251 { aHidd_Gfx_SyncTags , (IPTR)tags_1280_1024 },
252 { aHidd_Gfx_SyncTags , (IPTR)tags_1600_1200 },
253 { TAG_DONE , 0UL }
256 STRPTR name[32];
257 struct TagItem mytags[] =
259 { aHidd_Gfx_ModeTags , (IPTR)mode_tags },
260 { aHidd_Name , (IPTR)name },
261 { aHidd_HardwareName , (IPTR)"Windows GDI" },
262 { aHidd_ProducerName , (IPTR)"Microsoft corporation"},
263 { TAG_MORE , (IPTR)msg->attrList }
265 struct pRoot_New mymsg = { msg->mID, mytags };
266 APTR display;
267 ULONG vfreq, htotal, vtotal;
269 EnterFunc(bug("GDIGfx::New()\n"));
271 Forbid();
273 /* TODO: If we replace "DISPLAY" with something else here,
274 we get a possibility to select on which monitor to work.
275 Perhaps we should have some kind of preferences for this. */
276 display = GDICALL(CreateDC, "DISPLAY", NULL, NULL, NULL);
277 if (!display) {
278 Permit();
279 ReturnPtr("GDIGfx::New()", OOP_Object *, NULL);
282 /* Fill in sync data */
283 vfreq = GDICALL(GetDeviceCaps, display, VREFRESH);
284 htotal = GDICALL(GetDeviceCaps, display, HORZRES);
285 vtotal = GDICALL(GetDeviceCaps, display, VERTRES);
287 Permit();
289 D(bug("[GDI] Display size is %u x %u, Vertical refresh rate is %d Hz\n", htotal, vtotal, vfreq));
290 /* Sometimes Windows may refuse to provide us with the valid refresh rate.
291 In this case it returns either 0 or 1 (which means "hardware default").
292 Perhaps we should assume two standard VGA clocks for 0 and 1 ? */
293 if (vfreq > 1)
294 mode_tags[1].ti_Data = vfreq * htotal * vtotal;
295 mode_tags[2].ti_Data = htotal;
296 mode_tags[3].ti_Data = vtotal;
298 NewRawDoFmt("gdi%lu.monitor", (VOID_FUNC)RAWFMTFUNC_STRING, name, XSD(cl)->displaynum);
300 /* Register gfxmodes */
301 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)&mymsg);
302 if (NULL != o)
304 struct gfx_data *data = OOP_INST_DATA(cl, o);
306 D(bug("GDIGfx::New(): Got object from super\n"));
307 data->display = display;
308 NewList((struct List *)&data->bitmaps);
309 XSD(cl)->displaynum++;
311 ReturnPtr("GDIGfx::New", OOP_Object *, o);
314 /********** GfxHidd::Dispose() ******************************/
315 VOID GDICl__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
317 struct gfx_data *data;
319 EnterFunc(bug("GDIGfx::Dispose(o=%p)\n", o));
321 data = OOP_INST_DATA(cl, o);
323 Forbid();
324 if (data->fbwin)
325 NATIVECALL(GDI_PutMsg, data->fbwin, WM_CLOSE, 0, 0);
326 if (data->cursor)
327 USERCALL(DestroyIcon, data->cursor);
329 GDICALL(DeleteDC, data->display);
331 D(bug("GDIGfx::Dispose: calling super\n"));
332 OOP_DoSuperMethod(cl, o, msg);
334 ReturnVoid("GDIGfx::Dispose");
337 /****************************************************************************************/
339 OOP_Object *GDICl__Hidd_Gfx__CreateObject(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_CreateObject *msg)
341 OOP_Object *object = NULL;
343 if (msg->cl == XSD(cl)->basebm)
345 HIDDT_ModeID modeid;
346 struct pHidd_Gfx_CreateObject p;
347 HIDDT_StdPixFmt stdpf;
349 struct gfx_data *data;
350 struct TagItem tags[] =
352 { aHidd_GDIBitMap_SysDisplay, 0UL }, /* 0 */
353 { TAG_IGNORE , 0UL }, /* 1 */
354 { TAG_IGNORE , 32 }, /* 2 */
355 { TAG_MORE , 0UL } /* 3 */
358 EnterFunc(bug("GDIGfx::CreateObject()\n"));
359 data = OOP_INST_DATA(cl, o);
361 tags[0].ti_Data = (IPTR)data->display;
362 tags[1].ti_Data = (IPTR)XSD(cl)->bmclass;
363 tags[3].ti_Data = (IPTR)msg->attrList;
365 /* Create a GDI bitmap if we have a valid ModeID.
367 Also GDI bitmap can be created if there's no explicit
368 pixelformat specification and a friend bitmap is supplied,
369 which is a GDI bitmap. This is handled in the
370 superclass.
372 Some day when AROS learns to deal with several display drivers at once, this check may go
373 away completely. This should really be handled by graphics.library. We do it here only because
374 display bitmap classes are currently private and only drivers themselves know about them.
376 modeid = (HIDDT_ModeID)GetTagData(aHidd_BitMap_ModeID, vHidd_ModeID_Invalid, msg->attrList);
377 stdpf = (HIDDT_StdPixFmt)GetTagData(aHidd_BitMap_StdPixFmt, vHidd_StdPixFmt_Unknown, msg->attrList);
379 if (modeid != vHidd_ModeID_Invalid) {
380 tags[1].ti_Tag = aHidd_BitMap_ClassPtr;
381 D(bug("[GDI] ModeID: 0x%08lX, ClassPtr: 0x%p\n", modeid, tags[1].ti_Data));
383 /* longword-align planar bitmaps. This is needed for BlitColorExpansion() to work properly. */
384 if (stdpf == vHidd_StdPixFmt_Plane)
385 tags[2].ti_Tag = aHidd_BitMap_Align;
387 p.mID = msg->mID;
388 p.cl = msg->cl;
389 p.attrList = tags;
391 object = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)&p);
393 else
394 object = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
396 ReturnPtr("GDIGfx::CreateObject", OOP_Object *, object);
399 /****************************************************************************************/
401 VOID GDICl__Root__Get(OOP_Class *cl, OOP_Object *o, struct pRoot_Get *msg)
403 ULONG idx;
405 if (IS_GFX_ATTR(msg->attrID, idx))
407 switch (idx)
409 case aoHidd_Gfx_IsWindowed:
410 case aoHidd_Gfx_SupportsHWCursor:
411 case aoHidd_Gfx_NoFrameBuffer:
412 *msg->storage = TRUE;
413 return;
415 case aoHidd_Gfx_HWSpriteTypes:
416 *msg->storage = vHidd_SpriteType_DirectColor;
417 return;
419 case aoHidd_Gfx_DriverName:
420 *msg->storage = (IPTR)"GDI";
421 return;
424 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
427 /****************************************************************************************/
429 VOID GDICl__Root__Set(OOP_Class *cl, OOP_Object *obj, struct pRoot_Set *msg)
431 struct gfx_data *data = OOP_INST_DATA(cl, obj);
432 struct TagItem *tag, *tstate;
433 ULONG idx;
435 tstate = msg->attrList;
436 while((tag = NextTagItem(&tstate)))
438 if (IS_GFX_ATTR(tag->ti_Tag, idx)) {
439 switch(idx)
441 case aoHidd_Gfx_ActiveCallBack:
442 data->cb = (void *)tag->ti_Data;
443 break;
445 case aoHidd_Gfx_ActiveCallBackData:
446 data->cbdata = (APTR)tag->ti_Data;
447 break;
451 OOP_DoSuperMethod(cl, obj, (OOP_Msg)msg);
454 /****************************************************************************************/
456 static void AddToList(struct MinList *list, OOP_Object *bitmap)
458 OOP_Class *bmclass = OOP_OCLASS(bitmap);
459 struct bitmap_data *bmdata = OOP_INST_DATA(bmclass, bitmap);
461 D(bug("[GDI] Will display bitmap data 0x%p, window 0x%p\n", bmdata, bmdata->window));
462 if (bmdata->node.mln_Pred) {
463 D(bug("[GDI] This bitmap is already on display\n"));
464 Remove((struct Node *)bmdata);
466 AddTail((struct List *)list, (struct Node *)bmdata);
469 static void ShowList(struct gdi_staticdata *xsd, struct gfx_data *data, struct MinList *list)
471 struct bitmap_data *bmdata;
473 /* If something left in displayed bitmaps list, close it */
474 for (bmdata = (struct bitmap_data *)data->bitmaps.mlh_Head;
475 bmdata->node.mln_Succ; bmdata = (struct bitmap_data *)bmdata->node.mln_Succ) {
476 D(bug("[GDI] Hiding bitmap data 0x%p, window 0x%p\n", bmdata, bmdata->window));
477 if (bmdata->window) {
478 NATIVECALL(GDI_PutMsg, bmdata->window, WM_CLOSE, 0, 0);
479 bmdata->window = NULL;
481 /* This indicates that the bitmap is not in the list any more */
482 bmdata->node.mln_Pred = NULL;
485 /* Transfer the contents of our temporary list into display list */
486 data->bitmaps.mlh_Head = list->mlh_Head;
487 data->bitmaps.mlh_Head->mln_Pred = (struct MinNode *)&data->bitmaps.mlh_Head;
488 data->bitmaps.mlh_TailPred = list->mlh_TailPred;
489 data->bitmaps.mlh_TailPred->mln_Succ = (struct MinNode *)&data->bitmaps.mlh_Tail;
491 /* Own our virtual hardware. We are in Forbid() state and i hope it's enough */
492 xsd->showtask = FindTask(NULL);
493 SetSignal(0, SIGF_BLIT);
495 /* This will show display list and sort bitmaps in correct Z-order.
496 Windows must be created by control thread in order to be owned
497 by it. */
498 NATIVECALL(GDI_PutMsg, data->fbwin, NOTY_SHOW, (IPTR)data, 0);
499 Wait(SIGF_BLIT);
501 /* Disown virtual hardware */
502 xsd->showtask = NULL;
505 ULONG GDICl__Hidd_Gfx__ShowViewPorts(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_ShowViewPorts *msg)
507 struct gfx_data *data = OOP_INST_DATA(cl, o);
508 struct HIDD_ViewPortData *vpdata;
509 struct MinList new_bitmaps;
511 Forbid();
513 NewList((struct List *)&new_bitmaps);
515 /* Traverse through bitmaps chain and move them from old displayed list to the new temporary one */
516 for (vpdata = msg->Data; vpdata; vpdata = vpdata->Next)
517 AddToList(&new_bitmaps, vpdata->Bitmap);
518 ShowList(XSD(cl), data, &new_bitmaps);
520 Permit();
522 /* We always return TRUE in order to indicate that we support this method.
523 LoadView() has no return code, so we have no rights for error too. */
524 return TRUE;
527 /****************************************************************************************/
529 /* This method is needed for software mouse sprite emulation so that we can test it on
530 this driver */
532 OOP_Object *GDICl__Hidd_Gfx__Show(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_Show *msg)
534 struct gfx_data *data = OOP_INST_DATA(cl, o);
535 struct MinList new_bitmaps;
537 Forbid();
539 NewList((struct List *)&new_bitmaps);
541 if (msg->bitMap)
542 AddToList(&new_bitmaps, msg->bitMap);
543 ShowList(XSD(cl), data, &new_bitmaps);
545 Permit();
547 return msg->bitMap;
550 /****************************************************************************************/
552 extern ULONG Copy_DrawModeTable[];
554 VOID GDICl__Hidd_Gfx__CopyBox(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_CopyBox *msg)
556 APTR src = NULL, dest = NULL;
557 ULONG drmd;
558 IPTR xoffset, yoffset;
560 EnterFunc(bug("[GDI] hidd.gfx.wingdi::CopyBox(0x%p(%lu, %lu, %lu, %lu) -> 0x%p(%lu, %lu)\n", msg->src, msg->srcX, msg->srcY, msg->width, msg->height,
561 msg->dest, msg->destX, msg->destY));
563 OOP_GetAttr(msg->src, aHidd_GDIBitMap_DeviceContext, (IPTR *)&src);
564 OOP_GetAttr(msg->dest, aHidd_GDIBitMap_DeviceContext, (IPTR *)&dest);
565 OOP_GetAttr(msg->dest, aHidd_BitMap_LeftEdge, &xoffset);
566 OOP_GetAttr(msg->dest, aHidd_BitMap_TopEdge, &yoffset);
568 if (NULL == dest || NULL == src)
570 D(bug("[GDI] Process by superclass\n"));
571 /* The destination object is not a GDI bitmap.
572 Let the superclass do the copying in a more general way
574 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
576 return;
579 drmd = GC_DRMD(msg->gc);
580 Forbid();
581 GDICALL(BitBlt, dest, msg->destX, msg->destY, msg->width, msg->height, src, msg->srcX, msg->srcY, Copy_DrawModeTable[drmd]);
582 Permit();
586 /****************************************************************************************/
588 BOOL GDICl__Hidd_Gfx__SetCursorShape(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_SetCursorShape *msg)
590 struct gfx_data *data = OOP_INST_DATA(cl, o);
591 OOP_Object *pfmt;
592 OOP_Object *colormap;
593 IPTR depth;
594 IPTR width, height;
595 ULONG *buf, *mask;
596 ULONG bufsize;
597 APTR buf_bm, mask_bm;
598 APTR cursor = NULL;
600 OOP_GetAttr(msg->shape, aHidd_BitMap_Width, &width);
601 OOP_GetAttr(msg->shape, aHidd_BitMap_Height, &height);
602 OOP_GetAttr(msg->shape, aHidd_BitMap_PixFmt, (APTR)&pfmt);
603 OOP_GetAttr(pfmt, aHidd_PixFmt_Depth, &depth);
604 OOP_GetAttr(msg->shape, aHidd_BitMap_ColorMap, (APTR)&colormap);
606 bufsize = width * height * 4;
607 buf = AllocMem(bufsize, MEMF_ANY);
608 if (buf) {
609 mask = AllocMem(bufsize, MEMF_ANY);
610 if (mask) {
611 BITMAP bm;
612 ULONG i;
614 HIDD_BM_GetImage(msg->shape, (UBYTE *)buf, width * 4, 0, 0, width, height, vHidd_StdPixFmt_ARGB32_Native);
615 PRINT_POINTER(buf, width, 8, 8);
616 /* Construct the mask from alpha channel data. The mask will be used on pre-XP systems or
617 on LUT screens. Of course there'll be no alpha blending there. */
618 for (i = 0; i < width * height; i++)
619 mask[i] = (buf[i] & 0xFF000000) ? 0 : 0xFFFFFFFF;
621 bm.bmType = 0;
622 bm.bmWidth = width;
623 bm.bmHeight = height;
624 bm.bmWidthBytes = width * 4;
625 bm.bmPlanes = 1;
626 bm.bmBitsPixel = 32;
627 bm.bmBits = buf;
628 Forbid();
629 buf_bm = GDICALL(CreateBitmapIndirect, &bm);
630 if (buf_bm) {
631 bm.bmBits = mask;
632 mask_bm = GDICALL(CreateBitmapIndirect, &bm);
633 if (mask_bm) {
634 ICONINFO curs = {
635 FALSE,
636 -msg->xoffset, -msg->yoffset,
637 mask_bm, buf_bm
639 cursor = USERCALL(CreateIconIndirect, &curs);
640 if (cursor) {
641 APTR old_cursor = data->cursor;
643 D(bug("[GDI] Created cursor 0x%p, old cursor 0x%p\n", cursor, old_cursor));
644 data->cursor = cursor;
645 USERCALL(SetCursor, cursor);
646 if (old_cursor)
647 USERCALL(DestroyIcon, old_cursor);
649 GDICALL(DeleteObject, mask_bm);
651 GDICALL(DeleteObject, buf_bm);
653 Permit();
654 FreeMem(mask, bufsize);
656 FreeMem(buf, bufsize);
658 return cursor ? TRUE : FALSE;
661 /****************************************************************************************/
663 /* This is simple - all modes have the same properties */
664 static struct HIDD_ModeProperties mode_props = {
665 DIPF_IS_SPRITES,
667 COMPF_ABOVE|COMPF_BELOW|COMPF_LEFT|COMPF_RIGHT
670 ULONG GDICl__Hidd_Gfx__ModeProperties(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_ModeProperties *msg)
672 ULONG len = msg->propsLen;
674 if (len > sizeof(mode_props))
675 len = sizeof(mode_props);
676 CopyMem(&mode_props, msg->props, len);
678 return len;
681 /****************************************************************************************/
683 static int gdigfx_init(LIBBASETYPEPTR LIBBASE)
685 InitSemaphore(&LIBBASE->xsd.sema);
686 LIBBASE->xsd.displaynum = 1;
688 if (OOP_ObtainAttrBases(attrbases)) {
689 D(bug("[GDI] Starting up GDI controller\n"));
691 Forbid();
692 LIBBASE->xsd.ctl = NATIVECALL(GDI_Init);
693 Permit();
695 if (LIBBASE->xsd.ctl) {
696 LIBBASE->xsd.gfx_int = KrnAddIRQHandler(LIBBASE->xsd.ctl->GfxIrq, GfxIntHandler, &LIBBASE->xsd, NULL);
697 if (LIBBASE->xsd.gfx_int)
698 return TRUE;
701 return FALSE;
704 /****************************************************************************************/
706 static int gdigfx_expunge(LIBBASETYPEPTR LIBBASE)
708 if (LIBBASE->xsd.gfx_int)
709 KrnRemIRQHandler(LIBBASE->xsd.gfx_int);
711 if (LIBBASE->xsd.ctl) {
712 Forbid();
713 NATIVECALL(GDI_Shutdown, LIBBASE->xsd.ctl);
714 Permit();
716 OOP_ReleaseAttrBases(attrbases);
718 return TRUE;
721 /****************************************************************************************/
723 ADD2INITLIB(gdigfx_init, 0);
724 ADD2EXPUNGELIB(gdigfx_expunge, 0);