19a57b7d2SSøren Schmidt /*- 25e53a4f9SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 35e53a4f9SPedro F. Giffuni * 4bf3f9db6SUlrich Spörlein * Copyright (c) 1991-1997 Søren Schmidt 59a57b7d2SSøren Schmidt * All rights reserved. 69a57b7d2SSøren Schmidt * 79a57b7d2SSøren Schmidt * Redistribution and use in source and binary forms, with or without 89a57b7d2SSøren Schmidt * modification, are permitted provided that the following conditions 99a57b7d2SSøren Schmidt * are met: 109a57b7d2SSøren Schmidt * 1. Redistributions of source code must retain the above copyright 119a57b7d2SSøren Schmidt * notice, this list of conditions and the following disclaimer 129a57b7d2SSøren Schmidt * in this position and unchanged. 139a57b7d2SSøren Schmidt * 2. Redistributions in binary form must reproduce the above copyright 149a57b7d2SSøren Schmidt * notice, this list of conditions and the following disclaimer in the 159a57b7d2SSøren Schmidt * documentation and/or other materials provided with the distribution. 169a57b7d2SSøren Schmidt * 3. The name of the author may not be used to endorse or promote products 1721dc7d4fSJens Schweikhardt * derived from this software without specific prior written permission 189a57b7d2SSøren Schmidt * 199a57b7d2SSøren Schmidt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 209a57b7d2SSøren Schmidt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 219a57b7d2SSøren Schmidt * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 229a57b7d2SSøren Schmidt * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 239a57b7d2SSøren Schmidt * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 249a57b7d2SSøren Schmidt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 259a57b7d2SSøren Schmidt * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 269a57b7d2SSøren Schmidt * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 279a57b7d2SSøren Schmidt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 289a57b7d2SSøren Schmidt * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 299a57b7d2SSøren Schmidt */ 309a57b7d2SSøren Schmidt 31e67f5b9fSMatthew Dillon #include <sys/cdefs.h> 32e67f5b9fSMatthew Dillon __FBSDID("$FreeBSD$"); 33e67f5b9fSMatthew Dillon 349a57b7d2SSøren Schmidt #include <stdio.h> 359a57b7d2SSøren Schmidt #include <sys/types.h> 369a57b7d2SSøren Schmidt #include <sys/ioctl.h> 379a57b7d2SSøren Schmidt #include <sys/signal.h> 3800d25f51SPoul-Henning Kamp #include <sys/consio.h> 3900d25f51SPoul-Henning Kamp #include <sys/fbio.h> 409a57b7d2SSøren Schmidt #include "vgl.h" 419a57b7d2SSøren Schmidt 42*c0ce6f7dSBruce Evans static void VGLMouseAction(int dummy); 43*c0ce6f7dSBruce Evans 44a93ca07aSBruce Evans #define BORDER 0xff /* default border -- light white in rgb 3:3:2 */ 45a93ca07aSBruce Evans #define INTERIOR 0xa0 /* default interior -- red in rgb 3:3:2 */ 46a93ca07aSBruce Evans #define X 0xff /* any nonzero in And mask means part of cursor */ 47a93ca07aSBruce Evans #define B BORDER 48a93ca07aSBruce Evans #define I INTERIOR 499a57b7d2SSøren Schmidt static byte StdAndMask[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE] = { 509a57b7d2SSøren Schmidt X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 519a57b7d2SSøren Schmidt X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0, 529a57b7d2SSøren Schmidt X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0, 539a57b7d2SSøren Schmidt X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0, 549a57b7d2SSøren Schmidt X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0, 559a57b7d2SSøren Schmidt X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0, 569a57b7d2SSøren Schmidt X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0, 579a57b7d2SSøren Schmidt X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0, 58a93ca07aSBruce Evans X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0, 59a93ca07aSBruce Evans X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0, 609a57b7d2SSøren Schmidt X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0, 61a93ca07aSBruce Evans X,X,X,0,X,X,X,X,0,0,0,0,0,0,0,0, 62a93ca07aSBruce Evans X,X,0,0,X,X,X,X,0,0,0,0,0,0,0,0, 63a93ca07aSBruce Evans 0,0,0,0,0,X,X,X,X,0,0,0,0,0,0,0, 64a93ca07aSBruce Evans 0,0,0,0,0,X,X,X,X,0,0,0,0,0,0,0, 65a93ca07aSBruce Evans 0,0,0,0,0,0,X,X,0,0,0,0,0,0,0,0, 669a57b7d2SSøren Schmidt }; 679a57b7d2SSøren Schmidt static byte StdOrMask[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE] = { 68a93ca07aSBruce Evans B,B,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 69a93ca07aSBruce Evans B,I,B,0,0,0,0,0,0,0,0,0,0,0,0,0, 70a93ca07aSBruce Evans B,I,I,B,0,0,0,0,0,0,0,0,0,0,0,0, 71a93ca07aSBruce Evans B,I,I,I,B,0,0,0,0,0,0,0,0,0,0,0, 72a93ca07aSBruce Evans B,I,I,I,I,B,0,0,0,0,0,0,0,0,0,0, 73a93ca07aSBruce Evans B,I,I,I,I,I,B,0,0,0,0,0,0,0,0,0, 74a93ca07aSBruce Evans B,I,I,I,I,I,I,B,0,0,0,0,0,0,0,0, 75a93ca07aSBruce Evans B,I,I,I,I,I,I,I,B,0,0,0,0,0,0,0, 76a93ca07aSBruce Evans B,I,I,I,I,I,I,I,I,B,0,0,0,0,0,0, 77a93ca07aSBruce Evans B,I,I,I,I,I,B,B,B,B,0,0,0,0,0,0, 78a93ca07aSBruce Evans B,I,I,B,I,I,B,0,0,0,0,0,0,0,0,0, 79a93ca07aSBruce Evans B,I,B,0,B,I,I,B,0,0,0,0,0,0,0,0, 80a93ca07aSBruce Evans B,B,0,0,B,I,I,B,0,0,0,0,0,0,0,0, 81a93ca07aSBruce Evans 0,0,0,0,0,B,I,I,B,0,0,0,0,0,0,0, 82a93ca07aSBruce Evans 0,0,0,0,0,B,I,I,B,0,0,0,0,0,0,0, 83a93ca07aSBruce Evans 0,0,0,0,0,0,B,B,0,0,0,0,0,0,0,0, 849a57b7d2SSøren Schmidt }; 859a57b7d2SSøren Schmidt #undef X 86a93ca07aSBruce Evans #undef B 87a93ca07aSBruce Evans #undef I 889a57b7d2SSøren Schmidt static VGLBitmap VGLMouseStdAndMask = 895acf51eaSKazutaka YOKOTA VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdAndMask); 909a57b7d2SSøren Schmidt static VGLBitmap VGLMouseStdOrMask = 915acf51eaSKazutaka YOKOTA VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdOrMask); 929a57b7d2SSøren Schmidt static VGLBitmap *VGLMouseAndMask, *VGLMouseOrMask; 93c7432537SBruce Evans static int VGLMouseShown = VGL_MOUSEHIDE; 949a57b7d2SSøren Schmidt static int VGLMouseXpos = 0; 959a57b7d2SSøren Schmidt static int VGLMouseYpos = 0; 969a57b7d2SSøren Schmidt static int VGLMouseButtons = 0; 970410dc5fSBruce Evans static volatile sig_atomic_t VGLMintpending; 980410dc5fSBruce Evans static volatile sig_atomic_t VGLMsuppressint; 990410dc5fSBruce Evans 1000410dc5fSBruce Evans #define INTOFF() (VGLMsuppressint++) 1010410dc5fSBruce Evans #define INTON() do { \ 1020410dc5fSBruce Evans if (--VGLMsuppressint == 0 && VGLMintpending) \ 1030410dc5fSBruce Evans VGLMouseAction(0); \ 1040410dc5fSBruce Evans } while (0) 1059a57b7d2SSøren Schmidt 106*c0ce6f7dSBruce Evans int 107*c0ce6f7dSBruce Evans __VGLMouseMode(int mode) 1089a57b7d2SSøren Schmidt { 109*c0ce6f7dSBruce Evans int oldmode; 1109a57b7d2SSøren Schmidt 1110410dc5fSBruce Evans INTOFF(); 112*c0ce6f7dSBruce Evans oldmode = VGLMouseShown; 113*c0ce6f7dSBruce Evans if (mode == VGL_MOUSESHOW) { 114*c0ce6f7dSBruce Evans if (VGLMouseShown == VGL_MOUSEHIDE) { 115*c0ce6f7dSBruce Evans VGLMouseShown = VGL_MOUSESHOW; 1161fa51420SBruce Evans __VGLBitmapCopy(&VGLVDisplay, VGLMouseXpos, VGLMouseYpos, VGLDisplay, 117*c0ce6f7dSBruce Evans VGLMouseXpos, VGLMouseYpos, 118*c0ce6f7dSBruce Evans MOUSE_IMG_SIZE, -MOUSE_IMG_SIZE); 1199a57b7d2SSøren Schmidt } 1209a57b7d2SSøren Schmidt } 121*c0ce6f7dSBruce Evans else { 122*c0ce6f7dSBruce Evans if (VGLMouseShown == VGL_MOUSESHOW) { 123*c0ce6f7dSBruce Evans VGLMouseShown = VGL_MOUSEHIDE; 124*c0ce6f7dSBruce Evans __VGLBitmapCopy(&VGLVDisplay, VGLMouseXpos, VGLMouseYpos, VGLDisplay, 125*c0ce6f7dSBruce Evans VGLMouseXpos, VGLMouseYpos, 126*c0ce6f7dSBruce Evans MOUSE_IMG_SIZE, MOUSE_IMG_SIZE); 127*c0ce6f7dSBruce Evans } 128*c0ce6f7dSBruce Evans } 129*c0ce6f7dSBruce Evans INTON(); 130*c0ce6f7dSBruce Evans return oldmode; 131*c0ce6f7dSBruce Evans } 1329a57b7d2SSøren Schmidt 1339a57b7d2SSøren Schmidt void 1349a57b7d2SSøren Schmidt VGLMouseMode(int mode) 1359a57b7d2SSøren Schmidt { 136*c0ce6f7dSBruce Evans __VGLMouseMode(mode); 1379a57b7d2SSøren Schmidt } 1389a57b7d2SSøren Schmidt 139*c0ce6f7dSBruce Evans static void 1409a57b7d2SSøren Schmidt VGLMouseAction(int dummy) 1419a57b7d2SSøren Schmidt { 1429a57b7d2SSøren Schmidt struct mouse_info mouseinfo; 143*c0ce6f7dSBruce Evans int mousemode; 1449a57b7d2SSøren Schmidt 1450410dc5fSBruce Evans if (VGLMsuppressint) { 1460410dc5fSBruce Evans VGLMintpending = 1; 1479a57b7d2SSøren Schmidt return; 1489a57b7d2SSøren Schmidt } 1490410dc5fSBruce Evans again: 1500410dc5fSBruce Evans INTOFF(); 1510410dc5fSBruce Evans VGLMintpending = 0; 1529a57b7d2SSøren Schmidt mouseinfo.operation = MOUSE_GETINFO; 1539a57b7d2SSøren Schmidt ioctl(0, CONS_MOUSECTL, &mouseinfo); 154*c0ce6f7dSBruce Evans if (VGLMouseXpos != mouseinfo.u.data.x || 155*c0ce6f7dSBruce Evans VGLMouseYpos != mouseinfo.u.data.y) { 156*c0ce6f7dSBruce Evans mousemode = __VGLMouseMode(VGL_MOUSEHIDE); 1579a57b7d2SSøren Schmidt VGLMouseXpos = mouseinfo.u.data.x; 1589a57b7d2SSøren Schmidt VGLMouseYpos = mouseinfo.u.data.y; 159*c0ce6f7dSBruce Evans __VGLMouseMode(mousemode); 160*c0ce6f7dSBruce Evans } 1619a57b7d2SSøren Schmidt VGLMouseButtons = mouseinfo.u.data.buttons; 1620410dc5fSBruce Evans 1630410dc5fSBruce Evans /* 1640410dc5fSBruce Evans * Loop to handle any new (suppressed) signals. This is INTON() without 1650410dc5fSBruce Evans * recursion. !SA_RESTART prevents recursion in signal handling. So the 1660410dc5fSBruce Evans * maximum recursion is 2 levels. 1670410dc5fSBruce Evans */ 1680410dc5fSBruce Evans VGLMsuppressint = 0; 1690410dc5fSBruce Evans if (VGLMintpending) 1700410dc5fSBruce Evans goto again; 1719a57b7d2SSøren Schmidt } 1729a57b7d2SSøren Schmidt 1739a57b7d2SSøren Schmidt void 1749a57b7d2SSøren Schmidt VGLMouseSetImage(VGLBitmap *AndMask, VGLBitmap *OrMask) 1759a57b7d2SSøren Schmidt { 176*c0ce6f7dSBruce Evans int mousemode; 177*c0ce6f7dSBruce Evans 178*c0ce6f7dSBruce Evans mousemode = __VGLMouseMode(VGL_MOUSEHIDE); 179a93ca07aSBruce Evans 1809a57b7d2SSøren Schmidt VGLMouseAndMask = AndMask; 181a93ca07aSBruce Evans 182a93ca07aSBruce Evans if (VGLMouseOrMask != NULL) { 183a93ca07aSBruce Evans free(VGLMouseOrMask->Bitmap); 184a93ca07aSBruce Evans free(VGLMouseOrMask); 185a93ca07aSBruce Evans } 186a93ca07aSBruce Evans VGLMouseOrMask = VGLBitmapCreate(MEMBUF, OrMask->VXsize, OrMask->VYsize, 0); 187a93ca07aSBruce Evans VGLBitmapAllocateBits(VGLMouseOrMask); 188a93ca07aSBruce Evans VGLBitmapCvt(OrMask, VGLMouseOrMask); 189a93ca07aSBruce Evans 190*c0ce6f7dSBruce Evans __VGLMouseMode(mousemode); 1919a57b7d2SSøren Schmidt } 1929a57b7d2SSøren Schmidt 1939a57b7d2SSøren Schmidt void 1949a57b7d2SSøren Schmidt VGLMouseSetStdImage() 1959a57b7d2SSøren Schmidt { 196a93ca07aSBruce Evans VGLMouseSetImage(&VGLMouseStdAndMask, &VGLMouseStdOrMask); 1979a57b7d2SSøren Schmidt } 1989a57b7d2SSøren Schmidt 1999a57b7d2SSøren Schmidt int 2009a57b7d2SSøren Schmidt VGLMouseInit(int mode) 2019a57b7d2SSøren Schmidt { 2029a57b7d2SSøren Schmidt struct mouse_info mouseinfo; 203a93ca07aSBruce Evans int andmask, border, error, i, interior; 2049a57b7d2SSøren Schmidt 205aa1ce985SBruce Evans switch (VGLModeInfo.vi_mem_model) { 206aa1ce985SBruce Evans case V_INFO_MM_PACKED: 207aa1ce985SBruce Evans case V_INFO_MM_PLANAR: 208a93ca07aSBruce Evans andmask = 0x0f; 209a93ca07aSBruce Evans border = 0x0f; 210a93ca07aSBruce Evans interior = 0x04; 211aa1ce985SBruce Evans break; 212aa1ce985SBruce Evans case V_INFO_MM_VGAX: 213a93ca07aSBruce Evans andmask = 0x3f; 214a93ca07aSBruce Evans border = 0x3f; 215a93ca07aSBruce Evans interior = 0x24; 216aa1ce985SBruce Evans break; 217aa1ce985SBruce Evans default: 218a93ca07aSBruce Evans andmask = 0xff; 219a93ca07aSBruce Evans border = BORDER; 220a93ca07aSBruce Evans interior = INTERIOR; 221aa1ce985SBruce Evans break; 222aa1ce985SBruce Evans } 223a93ca07aSBruce Evans if (VGLModeInfo.vi_mode == M_BG640x480) 224a93ca07aSBruce Evans border = 0; /* XXX (palette makes 0x04 look like 0x0f) */ 225a93ca07aSBruce Evans if (getenv("VGLMOUSEBORDERCOLOR") != NULL) 226a93ca07aSBruce Evans border = strtoul(getenv("VGLMOUSEBORDERCOLOR"), NULL, 0); 227a93ca07aSBruce Evans if (getenv("VGLMOUSEINTERIORCOLOR") != NULL) 228a93ca07aSBruce Evans interior = strtoul(getenv("VGLMOUSEINTERIORCOLOR"), NULL, 0); 229a93ca07aSBruce Evans for (i = 0; i < MOUSE_IMG_SIZE*MOUSE_IMG_SIZE; i++) 230a93ca07aSBruce Evans VGLMouseStdOrMask.Bitmap[i] = VGLMouseStdOrMask.Bitmap[i] == BORDER ? 231a93ca07aSBruce Evans border : VGLMouseStdOrMask.Bitmap[i] == INTERIOR ? interior : 0; 2329a57b7d2SSøren Schmidt VGLMouseSetStdImage(); 2339a57b7d2SSøren Schmidt mouseinfo.operation = MOUSE_MODE; 2349a57b7d2SSøren Schmidt mouseinfo.u.mode.signal = SIGUSR2; 2359a57b7d2SSøren Schmidt if ((error = ioctl(0, CONS_MOUSECTL, &mouseinfo))) 2369a57b7d2SSøren Schmidt return error; 2379a57b7d2SSøren Schmidt signal(SIGUSR2, VGLMouseAction); 2389a57b7d2SSøren Schmidt mouseinfo.operation = MOUSE_GETINFO; 2399a57b7d2SSøren Schmidt ioctl(0, CONS_MOUSECTL, &mouseinfo); 2409a57b7d2SSøren Schmidt VGLMouseXpos = mouseinfo.u.data.x; 2419a57b7d2SSøren Schmidt VGLMouseYpos = mouseinfo.u.data.y; 2429a57b7d2SSøren Schmidt VGLMouseButtons = mouseinfo.u.data.buttons; 2439a57b7d2SSøren Schmidt VGLMouseMode(mode); 2449a57b7d2SSøren Schmidt return 0; 2459a57b7d2SSøren Schmidt } 2469a57b7d2SSøren Schmidt 247e848f3d1SBruce Evans void 248e848f3d1SBruce Evans VGLMouseRestore(void) 249e848f3d1SBruce Evans { 250e848f3d1SBruce Evans struct mouse_info mouseinfo; 251e848f3d1SBruce Evans 252e848f3d1SBruce Evans INTOFF(); 253e848f3d1SBruce Evans mouseinfo.operation = MOUSE_GETINFO; 254e848f3d1SBruce Evans if (ioctl(0, CONS_MOUSECTL, &mouseinfo) == 0) { 255e848f3d1SBruce Evans mouseinfo.operation = MOUSE_MOVEABS; 256e848f3d1SBruce Evans mouseinfo.u.data.x = VGLMouseXpos; 257e848f3d1SBruce Evans mouseinfo.u.data.y = VGLMouseYpos; 258e848f3d1SBruce Evans ioctl(0, CONS_MOUSECTL, &mouseinfo); 259e848f3d1SBruce Evans } 260e848f3d1SBruce Evans INTON(); 261e848f3d1SBruce Evans } 262e848f3d1SBruce Evans 2639a57b7d2SSøren Schmidt int 2649a57b7d2SSøren Schmidt VGLMouseStatus(int *x, int *y, char *buttons) 2659a57b7d2SSøren Schmidt { 2660410dc5fSBruce Evans INTOFF(); 2679a57b7d2SSøren Schmidt *x = VGLMouseXpos; 2689a57b7d2SSøren Schmidt *y = VGLMouseYpos; 2699a57b7d2SSøren Schmidt *buttons = VGLMouseButtons; 2700410dc5fSBruce Evans INTON(); 2719a57b7d2SSøren Schmidt return VGLMouseShown; 2729a57b7d2SSøren Schmidt } 2739a57b7d2SSøren Schmidt 274c7432537SBruce Evans void 275c7432537SBruce Evans VGLMouseFreeze(void) 2769a57b7d2SSøren Schmidt { 2770410dc5fSBruce Evans INTOFF(); 278c7432537SBruce Evans } 279c7432537SBruce Evans 280c7432537SBruce Evans int 281c7432537SBruce Evans VGLMouseFreezeXY(int x, int y) 282c7432537SBruce Evans { 283c7432537SBruce Evans INTOFF(); 284c7432537SBruce Evans if (VGLMouseShown != VGL_MOUSESHOW) 285c7432537SBruce Evans return 0; 286c7432537SBruce Evans if (x >= VGLMouseXpos && x < VGLMouseXpos + MOUSE_IMG_SIZE && 287c7432537SBruce Evans y >= VGLMouseYpos && y < VGLMouseYpos + MOUSE_IMG_SIZE && 288c7432537SBruce Evans VGLMouseAndMask->Bitmap[(y-VGLMouseYpos)*MOUSE_IMG_SIZE+(x-VGLMouseXpos)]) 289c7432537SBruce Evans return 1; 290c7432537SBruce Evans return 0; 291c7432537SBruce Evans } 292c7432537SBruce Evans 293c7432537SBruce Evans int 294c7432537SBruce Evans VGLMouseOverlap(int x, int y, int width, int hight) 295c7432537SBruce Evans { 2969a57b7d2SSøren Schmidt int overlap; 2979a57b7d2SSøren Schmidt 298c7432537SBruce Evans if (VGLMouseShown != VGL_MOUSESHOW) 299c7432537SBruce Evans return 0; 3009a57b7d2SSøren Schmidt if (x > VGLMouseXpos) 3019a57b7d2SSøren Schmidt overlap = (VGLMouseXpos + MOUSE_IMG_SIZE) - x; 3029a57b7d2SSøren Schmidt else 3039a57b7d2SSøren Schmidt overlap = (x + width) - VGLMouseXpos; 304c7432537SBruce Evans if (overlap <= 0) 305c7432537SBruce Evans return 0; 3069a57b7d2SSøren Schmidt if (y > VGLMouseYpos) 3079a57b7d2SSøren Schmidt overlap = (VGLMouseYpos + MOUSE_IMG_SIZE) - y; 3089a57b7d2SSøren Schmidt else 3099a57b7d2SSøren Schmidt overlap = (y + hight) - VGLMouseYpos; 310c7432537SBruce Evans return overlap > 0; 3119a57b7d2SSøren Schmidt } 3129a57b7d2SSøren Schmidt 3139a57b7d2SSøren Schmidt void 314a07067eaSBruce Evans VGLMouseMerge(int x, int y, int width, byte *line) 315a07067eaSBruce Evans { 316a07067eaSBruce Evans int pos, x1, xend, xstart; 317a07067eaSBruce Evans 318a07067eaSBruce Evans xstart = x; 319a07067eaSBruce Evans if (xstart < VGLMouseXpos) 320a07067eaSBruce Evans xstart = VGLMouseXpos; 321a07067eaSBruce Evans xend = x + width; 322a07067eaSBruce Evans if (xend > VGLMouseXpos + MOUSE_IMG_SIZE) 323a07067eaSBruce Evans xend = VGLMouseXpos + MOUSE_IMG_SIZE; 324a07067eaSBruce Evans for (x1 = xstart; x1 < xend; x1++) { 325a07067eaSBruce Evans pos = (y - VGLMouseYpos) * MOUSE_IMG_SIZE + x1 - VGLMouseXpos; 326a07067eaSBruce Evans if (VGLMouseAndMask->Bitmap[pos]) 327a07067eaSBruce Evans bcopy(&VGLMouseOrMask->Bitmap[pos * VGLDisplay->PixelBytes], 328a07067eaSBruce Evans &line[(x1 - x) * VGLDisplay->PixelBytes], VGLDisplay->PixelBytes); 329a07067eaSBruce Evans } 330a07067eaSBruce Evans } 331a07067eaSBruce Evans 332a07067eaSBruce Evans void 3339a57b7d2SSøren Schmidt VGLMouseUnFreeze() 3349a57b7d2SSøren Schmidt { 3350410dc5fSBruce Evans INTON(); 3369a57b7d2SSøren Schmidt } 337