Date: Wed, 27 Mar 2019 18:03:34 +0000 (UTC) From: Bruce Evans <bde@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r345585 - head/lib/libvgl Message-ID: <201903271803.x2RI3YIa028514@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: bde Date: Wed Mar 27 18:03:34 2019 New Revision: 345585 URL: https://svnweb.freebsd.org/changeset/base/345585 Log: Fix accessing pixels under the mouse cursor: Reading of single pixels didn't look under the cursor. Copying of 1x1 bitmaps didn't look under the cursor for either reading or writing. Copying of larger bitmaps looked under the cursor for at most the destination. Copying of larger bitmaps looked under a garbage cursor (for the Display bitmap) when the destination is a MEMBUF. The results are not used, so this only wasted time and flickered the cursor. Writing of single pixels looked under a garbage cursor for MEMBUF destinations, as above except this clobbered the current cursor and didn't update the MEMBUF. Writing of single pixels is not implemented yet in depths > 8. Otherwise, writing of single pixels worked. It was the only working case for accessing pixels under the cursor. Clearing of MEMBUFs wasted time freezing the cursor in the Display bitmap. The fixes abuse the top bits in the color arg to the cursor freezing function to control the function. Also clear the top 8 bits so that applications can't clobber the control bits or create 256 aliases for every 24-bit pixel value in depth 32. Races fixed: Showing and hiding the cursor only tried to avoid races with the mouse event signal handler for internal operations. There are still many shorter races from not using volatile or sig_atomic_t for the variable to control this. This variable also controls freezes, and has more complicated states than before. The internal operation of unfreezing the cursor opened a race window by unsetting the signal/freeze variable before showing the cursor. Modified: head/lib/libvgl/bitmap.c head/lib/libvgl/mouse.c head/lib/libvgl/simple.c Modified: head/lib/libvgl/bitmap.c ============================================================================== --- head/lib/libvgl/bitmap.c Wed Mar 27 17:55:39 2019 (r345584) +++ head/lib/libvgl/bitmap.c Wed Mar 27 18:03:34 2019 (r345585) @@ -361,9 +361,13 @@ VGLBitmapCopy(VGLBitmap *src, int srcx, int srcy, { int error; - VGLMouseFreeze(dstx, dsty, width, hight, 0); + if (src->Type != MEMBUF) + VGLMouseFreeze(srcx, srcy, width, hight, 0); + if (dst->Type != MEMBUF) + VGLMouseFreeze(dstx, dsty, width, hight, 0); error = __VGLBitmapCopy(src, srcx, srcy, dst, dstx, dsty, width, hight); - VGLMouseUnFreeze(); + if (src->Type != MEMBUF || dst->Type != MEMBUF) + VGLMouseUnFreeze(); return error; } Modified: head/lib/libvgl/mouse.c ============================================================================== --- head/lib/libvgl/mouse.c Wed Mar 27 17:55:39 2019 (r345584) +++ head/lib/libvgl/mouse.c Wed Mar 27 18:03:34 2019 (r345585) @@ -102,6 +102,7 @@ VGLMousePointerShow() int i, pos, pos1; if (!VGLMouseVisible) { + VGLMouseFrozen++; VGLMouseVisible = 1; crtcidx = inb(0x3c4); crtcval = inb(0x3c5); @@ -124,6 +125,7 @@ VGLMousePointerShow() outb(0x3c5, crtcval); outb(0x3ce, gdcidx); outb(0x3cf, gdcval); + VGLMouseFrozen--; } } @@ -133,6 +135,7 @@ VGLMousePointerHide() byte crtcidx, crtcval, gdcidx, gdcval; if (VGLMouseVisible) { + VGLMouseFrozen++; VGLMouseVisible = 0; crtcidx = inb(0x3c4); crtcval = inb(0x3c5); @@ -144,6 +147,7 @@ VGLMousePointerHide() outb(0x3c5, crtcval); outb(0x3ce, gdcidx); outb(0x3cf, gdcval); + VGLMouseFrozen--; } } @@ -170,7 +174,7 @@ VGLMouseAction(int dummy) struct mouse_info mouseinfo; if (VGLMouseFrozen) { - VGLMouseFrozen++; + VGLMouseFrozen += 8; return; } mouseinfo.operation = MOUSE_GETINFO; @@ -257,9 +261,8 @@ VGLMouseFreeze(int x, int y, int width, int hight, u_l { int i, xstride, ystride; - if (!VGLMouseFrozen) { - VGLMouseFrozen = 1; - if (width > 1 || hight > 1) { /* bitmap */ + VGLMouseFrozen++; + if (width > 1 || hight > 1 || (color & 0xc0000000) == 0) { /* bitmap */ if (VGLMouseShown == 1) { int overlap; @@ -283,29 +286,38 @@ VGLMouseFreeze(int x, int y, int width, int hight, u_l y >= VGLMouseYpos && y < VGLMouseYpos + MOUSE_IMG_SIZE) { xstride = VGLDisplay->PixelBytes; ystride = MOUSE_IMG_SIZE * xstride; - for (i = 0; i < xstride; i++, color >>= 8) - VGLMouseSave.Bitmap[(y-VGLMouseYpos)*ystride+ - (x-VGLMouseXpos)*xstride+i] = color; - if (VGLMouseAndMask->Bitmap - [(y-VGLMouseYpos)*MOUSE_IMG_SIZE+(x-VGLMouseXpos)]) { - return 1; + if (color & 0x40000000) { /* Get */ + color = 0; + for (i = xstride - 1; i >= 0; i--) + color = (color << 8) | + VGLMouseSave.Bitmap[(y-VGLMouseYpos)*ystride+ + (x-VGLMouseXpos)*xstride+i]; + return 0x40000000 | (color & 0xffffff); + } else { /* Set */ + color &= 0xffffff; /* discard flag and other garbage */ + for (i = 0; i < xstride; i++, color >>= 8) + VGLMouseSave.Bitmap[(y-VGLMouseYpos)*ystride+ + (x-VGLMouseXpos)*xstride+i] = color; + if (VGLMouseAndMask->Bitmap + [(y-VGLMouseYpos)*MOUSE_IMG_SIZE+(x-VGLMouseXpos)]) { + return 1; + } } } } - } return 0; } void VGLMouseUnFreeze() { - if (VGLMouseFrozen > 1) { + if (VGLMouseFrozen > 8) { VGLMouseFrozen = 0; VGLMouseAction(0); } else { - VGLMouseFrozen = 0; if (VGLMouseShown == VGL_MOUSESHOW && !VGLMouseVisible) VGLMousePointerShow(); + VGLMouseFrozen = 0; } } Modified: head/lib/libvgl/simple.c ============================================================================== --- head/lib/libvgl/simple.c Wed Mar 27 17:55:39 2019 (r345584) +++ head/lib/libvgl/simple.c Wed Mar 27 18:03:34 2019 (r345585) @@ -98,7 +98,8 @@ VGLSetXY(VGLBitmap *object, int x, int y, u_long color VGLCheckSwitch(); if (x>=0 && x<object->VXsize && y>=0 && y<object->VYsize) { - if (!VGLMouseFreeze(x, y, 1, 1, color)) { + if (object->Type == MEMBUF || + !VGLMouseFreeze(x, y, 1, 1, 0x80000000 | color)) { switch (object->Type) { case MEMBUF: case VIDBUF8: @@ -139,12 +140,13 @@ set_planar: object->Bitmap[offset] |= (byte)color; } } - VGLMouseUnFreeze(); + if (object->Type != MEMBUF) + VGLMouseUnFreeze(); } } -u_long -VGLGetXY(VGLBitmap *object, int x, int y) +static u_long +__VGLGetXY(VGLBitmap *object, int x, int y) { int offset; byte b[4]; @@ -152,9 +154,6 @@ VGLGetXY(VGLBitmap *object, int x, int y) u_long color; byte mask; - VGLCheckSwitch(); - if (x<0 || x>=object->VXsize || y<0 || y>=object->VYsize) - return 0; switch (object->Type) { case MEMBUF: case VIDBUF8: @@ -195,6 +194,27 @@ get_planar: return 0; /* XXX black? */ } +u_long +VGLGetXY(VGLBitmap *object, int x, int y) +{ + u_long color; + + VGLCheckSwitch(); + if (x<0 || x>=object->VXsize || y<0 || y>=object->VYsize) + return 0; + if (object->Type != MEMBUF) { + color = VGLMouseFreeze(x, y, 1, 1, 0x40000000); + if (color & 0x40000000) { + VGLMouseUnFreeze(); + return color & 0xffffff; + } + } + color = __VGLGetXY(object, x, y); + if (object->Type != MEMBUF) + VGLMouseUnFreeze(); + return color; +} + /* * Symmetric Double Step Line Algorithm by Brian Wyvill from * "Graphics Gems", Academic Press, 1990. @@ -501,7 +521,8 @@ VGLClear(VGLBitmap *object, u_long color) byte b[4]; VGLCheckSwitch(); - VGLMouseFreeze(0, 0, object->Xsize, object->Ysize, color); /* XXX */ + if (object->Type != MEMBUF) + VGLMouseFreeze(0, 0, object->Xsize, object->Ysize, color); switch (object->Type) { case MEMBUF: case VIDBUF8: @@ -565,7 +586,8 @@ VGLClear(VGLBitmap *object, u_long color) outb(0x3ce, 0x05); outb(0x3cf, 0x00); break; } - VGLMouseUnFreeze(); + if (object->Type != MEMBUF) + VGLMouseUnFreeze(); } void
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201903271803.x2RI3YIa028514>