Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / arch / i386-pc / drivers / vga.hidd / vgaclass.c
blob6fceb839e08f7c04dd6238db44478e123fdc9252
1 /*
2 Copyright © 1995-2006, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Class for VGA and compatible cards.
6 Lang: English.
7 */
9 #define __OOP_NOATTRBASES__
11 #include <proto/exec.h>
12 #include <proto/utility.h>
13 #include <proto/oop.h>
14 #include <oop/oop.h>
16 #include <exec/alerts.h>
17 #include <exec/memory.h>
19 #include <hidd/hidd.h>
20 #include <hidd/graphics.h>
22 #include <aros/symbolsets.h>
24 #include <hardware/custom.h>
26 #include <devices/inputevent.h>
27 #include <string.h>
29 #include "vga.h"
30 #include "vgaclass.h"
31 #include "bitmap.h"
33 #include LC_LIBDEFS_FILE
35 #define DEBUG 0
36 #include <aros/debug.h>
38 #define ONLY640
40 /* Some attrbases needed as global vars.
41 These are write-once read-many */
43 /* Don't initialize them with "= 0", otherwise they end up in the DATA segment! */
45 static OOP_AttrBase HiddBitMapAttrBase;
46 static OOP_AttrBase HiddPixFmtAttrBase;
47 static OOP_AttrBase HiddGfxAttrBase;
48 static OOP_AttrBase HiddSyncAttrBase;
49 static OOP_AttrBase HiddVGAAB;
50 static OOP_AttrBase HiddVGABitMapAB;
52 static struct OOP_ABDescr attrbases[] =
54 { IID_Hidd_BitMap, &HiddBitMapAttrBase },
55 { IID_Hidd_VGABitMap, &HiddVGABitMapAB },
56 { IID_Hidd_VGAgfx, &HiddVGAAB },
57 { IID_Hidd_PixFmt, &HiddPixFmtAttrBase },
58 { IID_Hidd_Sync, &HiddSyncAttrBase },
59 { IID_Hidd_Gfx, &HiddGfxAttrBase },
60 { NULL, NULL }
63 /* Default graphics modes */
65 struct vgaModeDesc
66 vgaDefMode[NUM_MODES]={
67 {"640x480x4 @ 60Hz", // h: 31.5 kHz v: 60Hz
68 640,480,4,0,
70 640,664,760,800,0,
71 480,491,493,525} //,
72 #ifndef ONLY640
73 {"768x576x4 @ 54Hz", // h: 32.5 kHz v: 54Hz
74 768,576,4,1,
76 768,795,805,872,0,
77 576,577,579,600},
78 {"800x600x4 @ 52Hz", // h: 31.5 kHz v: 52Hz
79 800,600,4,1,
81 800,826,838,900,0, // 900
82 600,601,603,617} // 617
83 #endif
86 /* Default mouse shape */
88 UBYTE shape[] =
90 9,11,00,00,00,00,00,00,00,00,00,
91 10, 9,11,11,00,00,00,00,00,00,00,
92 00,10, 9, 9,11,11,00,00,00,00,00,
93 00,10, 9, 9, 9, 9,11,11,00,00,00,
94 00,00,10, 9, 9, 9, 9, 9,11,11,00,
95 00,00,10, 9, 9, 9, 9, 9, 9, 9,00,
96 00,00,00,10, 9, 9, 9,11,00,00,00,
97 00,00,00,10, 9, 9,10, 9,11,00,00,
98 00,00,00,00,10, 9,00,10, 9,11,00,
99 00,00,00,00,10, 9,00,00,10, 9,11,
100 00,00,00,00,00,00,00,00,00,10,11
103 /*********************
104 ** GfxHidd::New() **
105 *********************/
107 #define NUM_SYNC_TAGS 11
108 #define SET_SYNC_TAG(taglist, idx, tag, val) \
109 taglist[idx].ti_Tag = aHidd_Sync_ ## tag; \
110 taglist[idx].ti_Data = val
112 VOID init_sync_tags(struct TagItem *tags, struct vgaModeDesc *md, STRPTR name)
114 ULONG clock = (md->clock == 1) ? 28322000 : 25175000;
115 SET_SYNC_TAG(tags, 0, PixelClock, clock );
116 SET_SYNC_TAG(tags, 1, HDisp, md->HDisplay );
117 SET_SYNC_TAG(tags, 2, VDisp, md->VDisplay );
118 SET_SYNC_TAG(tags, 3, HSyncStart, md->HSyncStart );
119 SET_SYNC_TAG(tags, 4, HSyncEnd, md->HSyncEnd );
120 SET_SYNC_TAG(tags, 5, HTotal, md->HTotal );
121 SET_SYNC_TAG(tags, 6, VSyncStart, md->VSyncStart );
122 SET_SYNC_TAG(tags, 7, VSyncEnd, md->VSyncEnd );
123 SET_SYNC_TAG(tags, 8, VTotal, md->VTotal );
124 SET_SYNC_TAG(tags, 9, Description, (IPTR)name );
125 tags[10].ti_Tag = TAG_DONE;
128 OOP_Object *PCVGA__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
130 struct TagItem pftags[] = {
131 { aHidd_PixFmt_RedShift, 0 }, /* 0 */
132 { aHidd_PixFmt_GreenShift, 0 }, /* 1 */
133 { aHidd_PixFmt_BlueShift, 0 }, /* 2 */
134 { aHidd_PixFmt_AlphaShift, 0 }, /* 3 */
135 { aHidd_PixFmt_RedMask, 0 }, /* 4 */
136 { aHidd_PixFmt_GreenMask, 0 }, /* 5 */
137 { aHidd_PixFmt_BlueMask, 0 }, /* 6 */
138 { aHidd_PixFmt_AlphaMask, 0 }, /* 7 */
139 { aHidd_PixFmt_ColorModel, 0 }, /* 8 */
140 { aHidd_PixFmt_Depth, 0 }, /* 9 */
141 { aHidd_PixFmt_BytesPerPixel, 0 }, /* 10 */
142 { aHidd_PixFmt_BitsPerPixel, 0 }, /* 11 */
143 { aHidd_PixFmt_StdPixFmt, 0 }, /* 12 */
144 { aHidd_PixFmt_CLUTShift, 0 }, /* 13 */
145 { aHidd_PixFmt_CLUTMask, 0x0f }, /* 14 */
146 { aHidd_PixFmt_BitMapType, 0 }, /* 15 */
147 { TAG_DONE, 0UL }
150 struct TagItem sync_640_480[NUM_SYNC_TAGS];
151 #ifndef ONLY640
152 struct TagItem sync_758_576[NUM_SYNC_TAGS];
153 struct TagItem sync_800_600[NUM_SYNC_TAGS];
154 #endif
156 struct TagItem modetags[] = {
157 { aHidd_Gfx_PixFmtTags, (IPTR)pftags },
158 { aHidd_Gfx_SyncTags, (IPTR)sync_640_480 },
159 #ifndef ONLY640
160 { aHidd_Gfx_SyncTags, (IPTR)sync_758_576 },
161 { aHidd_Gfx_SyncTags, (IPTR)sync_800_600 },
162 #endif
163 { TAG_DONE, 0UL }
166 struct TagItem mytags[] = {
167 { aHidd_Gfx_ModeTags, (IPTR)modetags },
168 { TAG_MORE, 0UL }
170 struct pRoot_New mymsg;
172 /* Init the pixel format */
173 pftags[0].ti_Data = 0;
174 pftags[1].ti_Data = 0;
175 pftags[2].ti_Data = 0;
176 pftags[3].ti_Data = 0;
178 pftags[4].ti_Data = 0x00003f;
179 pftags[5].ti_Data = 0x003f00;
180 pftags[6].ti_Data = 0x3f0000;
181 pftags[7].ti_Data = 0;
183 pftags[8].ti_Data = vHidd_ColorModel_Palette;
184 pftags[9].ti_Data = 4;
185 pftags[10].ti_Data = 1;
186 pftags[11].ti_Data = 4;
187 pftags[12].ti_Data = vHidd_StdPixFmt_Native;
189 #warning Is this true in all cases ?
190 pftags[15].ti_Data = vHidd_BitMapType_Chunky;
193 /* First init the sync tags */
194 init_sync_tags(sync_640_480, &vgaDefMode[0], "VGA:640x480");
195 #ifndef ONLY640
196 init_sync_tags(sync_758_576, &vgaDefMode[1], "VGA:758x576");
197 init_sync_tags(sync_800_600, &vgaDefMode[2], "VGA:800x600");
198 #endif
200 /* init mytags. We use TAG_MORE to attach our own tags before we send them
201 to the superclass */
202 mytags[1].ti_Tag = TAG_MORE;
203 mytags[1].ti_Data = (IPTR)msg->attrList;
205 /* Init mymsg. We have to use our own message struct because
206 one should not alter the one passed to this method.
207 message structs passed to a method are allways read-only.
208 (The user who called us might want to reuse the same msg struct
209 for several calls, but that will break if som method changes the
210 msg struct contents)
212 mymsg.mID = msg->mID; /* We got New() method and we are sending
213 the same method to the superclass */
214 mymsg.attrList = mytags;
217 msg = &mymsg;
219 EnterFunc(bug("VGAGfx::New()\n"));
222 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
223 if (o)
225 D(bug("Got object from super\n"));
228 XSD(cl)->mouseW = 11;
229 XSD(cl)->mouseH = 11;
230 XSD(cl)->mouseShape = shape;
231 XSD(cl)->mouseVisible = 1;
233 XSD(cl)->vgahidd = o;
235 ReturnPtr("VGAGfx::New", OOP_Object *, o);
238 ReturnPtr("VGAGfx::New", OOP_Object *, NULL);
241 VOID PCVGA__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
243 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
244 return;
247 VOID PCVGA__Root__Get(OOP_Class *cl, OOP_Object *o, struct pRoot_Get *msg)
249 ULONG idx;
250 BOOL found = FALSE;
251 if (IS_GFX_ATTR(msg->attrID, idx)) {
252 switch (idx) {
253 case aoHidd_Gfx_SupportsHWCursor:
254 *msg->storage = (IPTR)TRUE;
255 found = TRUE;
256 break;
260 if (!found)
261 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
263 return;
266 /********** GfxHidd::NewBitMap() ****************************/
267 OOP_Object *PCVGA__Hidd_Gfx__NewBitMap(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_NewBitMap *msg)
270 BOOL displayable, framebuffer;
271 struct vga_data *data;
272 OOP_Class *classptr = NULL;
273 struct TagItem mytags[2];
274 struct pHidd_Gfx_NewBitMap mymsg;
276 EnterFunc(bug("VGAGfx::NewBitMap()\n"));
278 data = OOP_INST_DATA(cl, o);
280 /* Displayable bitmap ? */
281 displayable = GetTagData(aHidd_BitMap_Displayable, FALSE, msg->attrList);
282 framebuffer = GetTagData(aHidd_BitMap_FrameBuffer, FALSE, msg->attrList);
284 if (framebuffer) {
285 /* If the user asks for a framebuffer map we must ALLWAYS supply a class */
286 classptr = XSD(cl)->onbmclass;
288 } else if (displayable) {
289 classptr = XSD(cl)->offbmclass;
290 } else {
291 HIDDT_ModeID modeid;
293 For the non-displayable case we can either supply a class ourselves
294 if we can optimize a certain type of non-displayable bitmaps. Or we
295 can let the superclass create on for us.
297 The attributes that might come from the user deciding the bitmap
298 pixel format are:
299 - aHidd_BitMap_ModeID: a modeid. create a nondisplayable
300 bitmap with the size and pixelformat of a gfxmode.
301 - aHidd_BitMap_StdPixFmt: a standard pixelformat as described in
302 hidd/graphics.h
303 - aHidd_BitMap_Friend: if this is supplied and none of the two above
304 are supplied, then the pixel format of the created bitmap
305 will be the same as the one of the friend bitmap.
307 These tags are listed in prioritized order, so if
308 the user supplied a ModeID tag, then you should not care about StdPixFmt
309 or Friend. If there is no ModeID, but a StdPixFmt tag supplied,
310 then you should not care about Friend because you have to
311 create the correct pixelformat. And as said above, if only Friend
312 is supplied, you can create a bitmap with same pixelformat as Frien
316 modeid = (HIDDT_ModeID)GetTagData(aHidd_BitMap_ModeID, vHidd_ModeID_Invalid, msg->attrList);
317 if (vHidd_ModeID_Invalid != modeid) {
318 /* User supplied a valid modeid. We can use our offscreen class */
319 classptr = XSD(cl)->offbmclass;
320 } else {
321 /* We may create an offscreen bitmap if the user supplied a friend
322 bitmap. But we need to check that he did not supplied a StdPixFmt
324 HIDDT_StdPixFmt stdpf;
325 stdpf = (HIDDT_StdPixFmt)GetTagData(aHidd_BitMap_StdPixFmt, vHidd_StdPixFmt_Unknown, msg->attrList);
326 if (vHidd_StdPixFmt_Unknown == stdpf) {
327 /* No std pixfmt supplied */
328 OOP_Object *friend;
330 /* Did the user supply a friend bitmap ? */
331 friend = (OOP_Object *)GetTagData(aHidd_BitMap_Friend, 0, msg->attrList);
332 if (NULL != friend) {
333 OOP_Object * gfxhidd;
334 /* User supplied friend bitmap. Is the friend bitmap a
335 VGA Gfx hidd bitmap ? */
336 OOP_GetAttr(friend, aHidd_BitMap_GfxHidd, &gfxhidd);
337 if (gfxhidd == o) {
338 /* Friend was VGA hidd bitmap. Now we can supply our own class */
339 classptr = XSD(cl)->offbmclass;
346 /* Do we supply our own class ? */
347 if (NULL != classptr) {
348 /* Yes. We must let the superclass not that we do this. This is
349 done through adding a tag in the frot of the taglist */
350 mytags[0].ti_Tag = aHidd_BitMap_ClassPtr;
351 mytags[0].ti_Data = (IPTR)classptr;
352 mytags[1].ti_Tag = TAG_MORE;
353 mytags[1].ti_Data = (IPTR)msg->attrList;
355 /* Like in Gfx::New() we init a new message struct */
356 mymsg.mID = msg->mID;
357 mymsg.attrList = mytags;
359 /* Pass the new message to the superclass */
360 msg = &mymsg;
363 ReturnPtr("VGAGfx::NewBitMap", OOP_Object *, (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg));
366 /********* GfxHidd::CopyBox() ***************************/
368 VOID PCVGA__Hidd_Gfx__CopyBox(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_CopyBox *msg)
370 ULONG mode;
371 unsigned char *src = 0, *dest = 0;
372 struct Box box = {0, 0, 0, 0};
374 mode = GC_DRMD(msg->gc);
376 EnterFunc(bug("VGAGfx.BitMap::CopyBox( %d,%d to %d,%d of dim %d,%d\n",
377 msg->srcX, msg->srcY, msg->destX, msg->destY, msg->width, msg->height));
379 OOP_GetAttr(msg->src, aHidd_VGABitMap_Drawable, &src);
380 OOP_GetAttr(msg->dest, aHidd_VGABitMap_Drawable, &dest);
382 if (!dest || !src ||
383 ((mode != vHidd_GC_DrawMode_Copy) &&
384 (mode != vHidd_GC_DrawMode_And) &&
385 (mode != vHidd_GC_DrawMode_Xor) &&
386 (mode != vHidd_GC_DrawMode_Clear) &&
387 (mode != vHidd_GC_DrawMode_Invert)))
389 /* The source and/or destination object is no VGA bitmap, onscreen nor offscreen.
390 Or drawmode is not one of those we accelerate. Let the superclass do the
391 copying in a more general way
393 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
394 return;
399 struct bitmap_data *data = OOP_INST_DATA(OOP_OCLASS(msg->src), msg->src);
400 struct bitmap_data *ddata = OOP_INST_DATA(OOP_OCLASS(msg->dest), msg->dest);
401 int i, width, phase, j;
402 BOOL descending;
404 // start of Source data
405 unsigned char *s_start = data->VideoData +
406 msg->srcX + (msg->srcY * data->width);
407 // adder for each line
408 ULONG s_add = data->width - msg->width;
409 ULONG cnt = msg->height;
411 unsigned char *d_start = ddata->VideoData +
412 msg->destX + (msg->destY * ddata->width);
413 ULONG d_add = ddata->width - msg->width;
415 width = msg->width;
417 if ((msg->srcY > msg->destY) || ((msg->srcY == msg->destY) && (msg->srcX >= msg->destX)))
419 if ((phase = ((LONG)s_start & 3L)))
421 phase = 4 - phase;
422 if (phase > width) phase = width;
423 width -= phase;
425 descending = FALSE;
427 else
429 s_start += (cnt - 1) * data->width + width;
430 d_start += (cnt - 1) * ddata->width + width;
432 phase = ((LONG)s_start & 3L);
433 if (phase > width) phase = width;
434 width -= phase;
436 descending = TRUE;
439 switch(mode)
441 case vHidd_GC_DrawMode_Copy:
442 HIDD_BM_CopyMemBox8(msg->dest,
443 data->VideoData,
444 msg->srcX,
445 msg->srcY,
446 ddata->VideoData,
447 msg->destX,
448 msg->destY,
449 msg->width,
450 msg->height,
451 data->width,
452 ddata->width);
453 break;
455 case vHidd_GC_DrawMode_And:
456 if (!descending)
458 while (cnt--)
460 i = width;
461 j = phase;
462 while (j--)
464 *d_start++ &= *s_start++;
466 while (i >= 4)
468 *((ULONG*)d_start) &= *((ULONG*)s_start);
469 d_start += 4;
470 s_start += 4;
471 i -= 4;
473 while (i--)
475 *d_start++ &= *s_start++;
477 d_start += d_add;
478 s_start += s_add;
481 else
483 while (cnt--)
485 i = width;
486 j = phase;
487 while (j--)
489 *--d_start &= *--s_start;
491 while (i >= 4)
493 d_start -= 4;
494 s_start -= 4;
495 *((ULONG*)d_start) &= *((ULONG*)s_start);
496 i -= 4;
498 while (i--)
500 *--d_start &= *--s_start;
502 d_start -= d_add;
503 s_start -= s_add;
507 break;
509 case vHidd_GC_DrawMode_Xor:
510 if (!descending)
512 while (cnt--)
514 i = width;
515 j = phase;
516 while (j--)
518 *d_start++ ^= *s_start++;
520 while (i >= 4)
522 *((ULONG*)d_start) ^= *((ULONG*)s_start);
523 d_start += 4;
524 s_start += 4;
525 i -= 4;
527 while (i--)
529 *d_start++ ^= *s_start++;
531 d_start += d_add;
532 s_start += s_add;
535 else
537 while (cnt--)
539 i = width;
540 j = phase;
541 while (j--)
543 *--d_start ^= *--s_start;
545 while (i >= 4)
547 d_start -= 4;
548 s_start -= 4;
549 *((ULONG*)d_start) ^= *((ULONG*)s_start);
550 i -= 4;
552 while (i--)
554 *--d_start ^= *--s_start;
556 d_start -= d_add;
557 s_start -= s_add;
560 break;
562 case vHidd_GC_DrawMode_Clear:
563 if (!descending)
565 while (cnt--)
567 i = width;
568 j = phase;
569 while (j--)
571 *d_start++ = 0;
573 while (i >= 4)
575 *((ULONG*)d_start) = 0;
576 d_start += 4;
577 i -= 4;
579 while (i--)
581 *d_start++ = 0;
583 d_start += d_add;
586 else
588 while (cnt--)
590 i = width;
591 j = phase;
592 while (j--)
594 *--d_start = 0;
596 while (i >= 4)
598 d_start -= 4;
599 *((ULONG*)d_start) = 0;
600 i -= 4;
602 while (i--)
604 *--d_start = 0;
606 d_start -= d_add;
609 break;
611 case vHidd_GC_DrawMode_Invert:
612 if (!descending)
614 while (cnt--)
616 i = width;
617 j = phase;
618 while (j--)
620 *d_start = ~*d_start;
621 d_start++;
623 while (i >= 4)
625 *((ULONG*)d_start) = ~*((ULONG*)d_start);
626 d_start += 4;
627 i -= 4;
629 while (i--)
631 *d_start = ~*d_start;
632 d_start++;
634 d_start += d_add;
637 else
639 while (cnt--)
641 i = width;
642 j = phase;
643 while (j--)
645 *d_start = ~*d_start;
646 d_start--;
648 while (i >= 4)
650 d_start -= 4;
651 *((ULONG*)d_start) = ~*((ULONG*)d_start);
652 i -= 4;
654 while (i--)
656 *d_start = ~*d_start;
657 d_start--;
659 d_start -= d_add;
661 break;
663 break;
665 } /* switch(mode) */
667 if (ddata->disp)
669 box.x1 = msg->destX;
670 box.y1 = msg->destY;
671 box.x2 = box.x1 + msg->width;
672 box.y2 = box.y1 + msg->height;
674 ObtainSemaphore(&XSD(cl)->HW_acc);
676 vgaRefreshArea(ddata, 1, &box);
677 if ( ( (XSD(cl)->mouseX + XSD(cl)->mouseW >= box.x1) &&
678 (XSD(cl)->mouseX <= box.x2) ) ||
679 ( (XSD(cl)->mouseY + XSD(cl)->mouseH >= box.y1) &&
680 (XSD(cl)->mouseY <= box.y2) ) )
681 draw_mouse(XSD(cl));
683 ReleaseSemaphore(&XSD(cl)->HW_acc);
687 ReturnVoid("VGAGfx.BitMap::CopyBox");
690 VOID PCVGA__Hidd_Gfx__ShowImminentReset(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
692 struct bitmap_data *data;
694 Disable();
695 data = XSD(cl)->visible;
696 if (data)
698 struct Box box = {0, 0, data->width - 1, data->height - 1};
700 memset(data->VideoData, 0, data->width * data->height);
702 vgaRefreshArea(data, 1, &box);
704 Enable();
709 /* stuff added by stegerg */
711 /********** GfxHidd::SetCursorShape() ****************************/
713 BOOL PCVGA__Hidd_Gfx__SetCursorShape(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_SetCursorShape *msg)
715 /* hmm ... moHidd_Gfx_SetCursorShape seems to have a HIDD bitmap in msg->shape, while
716 the old (obsolete?) native moHidd_Gfx_SetMouseShape seems to expect a simple
717 chunky array. So don't do anything for now (it would have to be done similiar as
718 in config/hidd/fakegfxhidd.c I guess */
720 return TRUE;
723 /********** GfxHidd::SetCursorPos() ****************************/
725 BOOL PCVGA__Hidd_Gfx__SetCursorPos(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_SetCursorPos *msg)
727 struct Box box = {0, 0, 0, 0};
729 box.x1 = XSD(cl)->mouseX;
730 box.y1 = XSD(cl)->mouseY;
731 box.x2 = box.x1 + XSD(cl)->mouseW;
732 box.y2 = box.y1 + XSD(cl)->mouseH;
734 ObtainSemaphore(&XSD(cl)->HW_acc);
736 if (XSD(cl)->visible)
737 vgaRefreshArea(XSD(cl)->visible, 1, &box);
739 XSD(cl)->mouseX = (short)msg->x;
740 XSD(cl)->mouseY = (short)msg->y;
742 if (XSD(cl)->visible)
744 if (XSD(cl)->mouseX < 0) XSD(cl)->mouseX = 0;
745 if (XSD(cl)->mouseY < 0) XSD(cl)->mouseY = 0;
746 if (XSD(cl)->mouseX >= XSD(cl)->visible->width) XSD(cl)->mouseX = XSD(cl)->visible->width - 1;
747 if (XSD(cl)->mouseY >= XSD(cl)->visible->height) XSD(cl)->mouseY = XSD(cl)->visible->height - 1;
750 draw_mouse(XSD(cl));
752 ReleaseSemaphore(&XSD(cl)->HW_acc);
754 return TRUE;
757 /********** GfxHidd::SetCursorVisible() ****************************/
759 VOID PCVGA__Hidd_Gfx__SetCursorVisible(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_SetCursorVisible *msg)
761 XSD(cl)->mouseVisible = msg->visible;
763 ObtainSemaphore(&XSD(cl)->HW_acc);
764 draw_mouse(XSD(cl));
765 ReleaseSemaphore(&XSD(cl)->HW_acc);
768 /* end of stuff added by stegerg */
770 /******************** init_vgaclass() *********************************/
772 static int PCVGA_InitAttrs(LIBBASETYPEPTR LIBBASE)
774 EnterFunc(bug("PCVGA_Init\n"));
776 ReturnInt("PCVGA_Init", ULONG, OOP_ObtainAttrBases(attrbases));
779 /*************** free_vgaclass() **********************************/
780 static int PCVGA_ExpungeAttrs(LIBBASETYPEPTR LIBBASE)
782 EnterFunc(bug("PCVGA_Expunge\n"));
784 OOP_ReleaseAttrBases(attrbases);
786 ReturnInt("PCVGA_Expunge", int, TRUE);
789 /*******************************************************************/
791 ADD2INITLIB(PCVGA_InitAttrs, 0)
792 ADD2EXPUNGELIB(PCVGA_ExpungeAttrs, 0)
794 /*******************************************************************/
796 #undef XSD
797 #define XSD(cl) xsd
799 void draw_mouse(struct vga_staticdata *xsd)
801 int pix;
802 unsigned char *ptr, *data;
803 int x, y, width, fg, x_i, y_i;
805 if (xsd->mouseVisible)
807 if (xsd->visible)
809 /* Get display width */
810 width = xsd->visible->width;
812 /* And pointer data */
813 data = xsd->mouseShape;
815 ObtainSemaphore(&xsd->HW_acc);
817 outw(0x3c4,0x0f02);
818 outw(0x3ce,0x0005);
819 outw(0x3ce,0x0003);
820 outw(0x3ce,0x0f01);
822 for (y_i = 0, y = xsd->mouseY ; y_i < xsd->mouseH; y_i++, y++)
824 for (x_i = 0, x = xsd->mouseX; x_i < xsd->mouseW; x_i++, x++)
826 ptr = (char *)(0xa0000 + (x + (y * width)) / 8);
827 pix = 0x8000 >> (x % 8);
829 fg = (char)*data++;
831 if (fg && (x < width))
833 outw(0x3ce,pix | 8);
834 outw(0x3ce,(fg << 8));
836 *ptr |= 1; // This or'ed value isn't important
841 ReleaseSemaphore(&xsd->HW_acc);