aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaroslav Hensl <jara@hensl.cz>2024-02-03 23:52:13 +0100
committerJaroslav Hensl <jara@hensl.cz>2024-02-03 23:52:13 +0100
commit981b488286abc6d7c8c10933d41a0a0bb2483921 (patch)
tree10586e9bd93bd4198d7f09e124ca2495247921f0
parentc8fa3c1ff1a18a6013d927e4b14f82bae343adbb (diff)
downloadvmdisp9x-981b488286abc6d7c8c10933d41a0a0bb2483921.tar.gz
driver code refactoring / PART3: mouse cursor (SW)
-rw-r--r--3d_accel.h31
-rw-r--r--cursor.h6
-rw-r--r--dibcall.c80
-rw-r--r--enable.c10
-rw-r--r--init.c12
-rw-r--r--makefile12
-rw-r--r--minidrv.h3
-rw-r--r--pm16_calls.c118
-rw-r--r--vmdisp9x.inf3
-rw-r--r--vxd.h2
-rw-r--r--vxd_fbhda.c5
-rw-r--r--vxd_lib.c26
-rw-r--r--vxd_lib.h9
-rw-r--r--vxd_main.c22
-rw-r--r--vxd_mouse.c243
-rw-r--r--vxd_mouse_conv.h279
-rw-r--r--vxd_strings.h8
-rw-r--r--vxd_svga.c9
-rw-r--r--vxd_vbe.c5
19 files changed, 850 insertions, 33 deletions
diff --git a/3d_accel.h b/3d_accel.h
index d61a95c..a263afb 100644
--- a/3d_accel.h
+++ b/3d_accel.h
@@ -68,11 +68,12 @@ THE SOFTWARE.
#define OP_VESA_SETMODE 0x4001 /* DRV */
#define OP_VESA_VALIDMODE 0x4002 /* DRV */
-#define OP_MOUSE_LOAD 0x1F00 /* DRV */
-#define OP_MOUSE_MOVE 0x1F01 /* DRV */
-#define OP_MOUSE_HIDE 0x1F02 /* DRV */
+#define OP_MOUSE_BUFFER 0x1F00 /* DRV */
+#define OP_MOUSE_LOAD 0x1F01 /* DRV */
+#define OP_MOUSE_MOVE 0x1F02 /* DRV */
#define OP_MOUSE_SHOW 0x1F03 /* DRV */
-#define OP_MOUSE_RESET 0x1F04 /* DRV */
+#define OP_MOUSE_HIDE 0x1F04 /* DRV */
+
#pragma pack(push)
#pragma pack(1)
@@ -111,8 +112,7 @@ typedef struct FBHDA
#define FB_ACCEL_VMSVGA 16
#define FB_ACCEL_VMSVGA3D 32
#define FB_ACCEL_VMSVGA10 64
-
-#define FB_MOUSE_RESTORE 1
+#define FB_MOUSE_NO_BLIT 128
/* for internal use in RING-0 by VXD only */
BOOL FBHDA_init_hw();
@@ -139,9 +139,22 @@ void FBHDA_palette_set(unsigned char index, DWORD rgb);
DWORD FBHDA_palette_get(unsigned char index);
/* mouse */
-void mouse_load(void FBPTR mouse_data);
-void mouse_move(DWORD x, DWORD y);
-void mouse_reset();
+#ifdef FBHDA_SIXTEEN
+void mouse_buffer(void __far* __far* pBuf, DWORD __far* pLinear);
+#else
+void *mouse_buffer();
+#endif
+BOOL mouse_load();
+void mouse_move(int x, int y);
+void mouse_show();
+void mouse_hide();
+
+/* vxd internal */
+void mouse_invalidate();
+void mouse_blit();
+void mouse_erase();
+
+#define MOUSE_BUFFER_SIZE 65535
/*
* VMWare SVGA-II API
diff --git a/cursor.h b/cursor.h
index 99784f7..fbf37df 100644
--- a/cursor.h
+++ b/cursor.h
@@ -6,9 +6,9 @@
#pragma pack(1)
typedef struct _CURSORSHAPE
{
- int xHotSpot, yHotSpot;
- int cx, cy;
- int cbWidth;
+ short xHotSpot, yHotSpot;
+ short cx, cy;
+ short cbWidth;
BYTE Planes;
BYTE BitsPixel;
} CURSORSHAPE;
diff --git a/dibcall.c b/dibcall.c
index 5ad5d7e..5cf8641 100644
--- a/dibcall.c
+++ b/dibcall.c
@@ -32,6 +32,30 @@ THE SOFTWARE.
#include "minidrv.h"
#include "cursor.h"
+#include "3d_accel.h"
+
+DWORD mouse_buf_lin = 0;
+void __far* mouse_buf = NULL;
+BOOL mouse_vxd = FALSE;
+
+static void cs_enter()
+{
+ _asm
+ {
+ mov ax, 1681h
+ int 2Fh
+ };
+}
+
+static void cs_leave()
+{
+ _asm
+ {
+ mov ax, 1682h
+ int 2Fh
+ };
+}
+
/*
* What's this all about? Most of the required exported driver functions can
* be passed straight to the DIB Engine. The DIB Engine in some cases requires
@@ -49,19 +73,64 @@ THE SOFTWARE.
#pragma code_seg( _TEXT )
-void WINAPI __loadds MoveCursor(WORD absX, WORD absY)
+void WINAPI __loadds MoveCursor(int absX, int absY)
{
if(wEnabled)
{
- DIB_MoveCursorExt(absX, absY, lpDriverPDevice);
+ if(mouse_vxd)
+ {
+ mouse_move(absX, absY);
+ }
+ else
+ {
+ DIB_MoveCursorExt(absX, absY, lpDriverPDevice);
+ }
}
}
+static size_t mouse_cursor_size(CURSORSHAPE __far *lpCursor)
+{
+ size_t s = sizeof(CURSORSHAPE);
+ s += ((lpCursor->cx + 7)/8) * lpCursor->cy; // size of AND mask
+ if(lpCursor->BitsPixel == 1)
+ {
+ s += ((lpCursor->cx + 7)/8) * lpCursor->cy; // size of XOR mask 1bpp
+ }
+ else
+ {
+ s += ((lpCursor->BitsPixel + 7)/8) * lpCursor->cx * lpCursor->cy; // size of XOR mask (mode bpp)
+ }
+
+ return s;
+}
+
WORD WINAPI __loadds SetCursor_driver(CURSORSHAPE __far *lpCursor)
{
if(wEnabled)
{
- DIB_SetCursorExt(lpCursor, lpDriverPDevice);
+ cs_enter();
+ if(mouse_vxd)
+ {
+ if(lpCursor != NULL)
+ {
+ size_t ms = mouse_cursor_size(lpCursor);
+ if(ms > 0)
+ {
+ _fmemcpy(mouse_buf, lpCursor, ms);
+ mouse_load();
+ goto setcursor_exit;
+ }
+ }
+ mouse_hide();
+ }
+ else
+ {
+ DIB_SetCursorExt(lpCursor, lpDriverPDevice);
+ }
+
+ setcursor_exit:
+ cs_leave();
+
}
return 0;
@@ -72,7 +141,10 @@ void WINAPI __loadds CheckCursor( void )
{
if(wEnabled)
{
- DIB_CheckCursorExt(lpDriverPDevice);
+ if(!mouse_vxd)
+ {
+ DIB_CheckCursorExt(lpDriverPDevice);
+ }
}
}
diff --git a/enable.c b/enable.c
index 405dcb9..c7434d7 100644
--- a/enable.c
+++ b/enable.c
@@ -152,7 +152,10 @@ VOID WINAPI __loadds BeginAccess_VXD( LPPDEVICE lpDevice, WORD wLeft, WORD wTop,
}
FBHDA_access_begin(dflags);
- DIB_BeginAccess(lpDevice, wLeft, wTop, wRight, wBottom, wFlags);
+ if(!mouse_vxd)
+ {
+ DIB_BeginAccess(lpDevice, wLeft, wTop, wRight, wBottom, wFlags);
+ }
}
VOID WINAPI __loadds EndAccess_VXD( LPPDEVICE lpDevice, WORD wFlags )
@@ -163,7 +166,10 @@ VOID WINAPI __loadds EndAccess_VXD( LPPDEVICE lpDevice, WORD wFlags )
dflags |= FBHDA_IGNORE_CURSOR;
}
- DIB_EndAccess(lpDevice, wFlags);
+ if(!mouse_vxd)
+ {
+ DIB_EndAccess(lpDevice, wFlags);
+ }
FBHDA_access_end(dflags);
}
diff --git a/init.c b/init.c
index 72d304d..3c3a6ca 100644
--- a/init.c
+++ b/init.c
@@ -83,11 +83,6 @@ void ReadDisplayConfig( void )
WORD wX, wY;
UINT bIgnoreRegistry;
MODEDESC mode;
-#ifdef QEMU
- DEVNODE devNode;
- DISPLAYINFO DispInfo;
- DWORD dwRc;
-#endif
/* Get the DPI, default to 96. */
wDpi = GetPrivateProfileInt( "display", "dpi", 96, "system.ini" );
@@ -197,6 +192,13 @@ UINT FAR DriverInit( UINT cbHeap, UINT hModule, LPSTR lpCmdLine )
dbg_printf("VXD connect success!\n");
FBHDA_setup(&hda, &hda_linear);
+ mouse_buffer(&mouse_buf, &mouse_buf_lin);
+ if(mouse_buf != NULL)
+ {
+ dbg_printf("VXD mouse ON\n");
+ mouse_vxd = TRUE;
+ }
+
if(hda == NULL)
{
dbg_printf("DriverInit: failed to get FBHDA!\n");
diff --git a/makefile b/makefile
index 217714f..f5877c2 100644
--- a/makefile
+++ b/makefile
@@ -7,7 +7,7 @@ OBJS = &
OBJS += &
dbgprint32.obj svga.obj pci.obj vxd_fbhda.obj vxd_lib.obj vxd_main.obj &
vxd_main_qemu.obj vxd_main_svga.obj vxd_svga.obj vxd_vdd.obj vxd_vdd_qemu.obj &
- vxd_vdd_svga.obj vxd_vbe.obj vxd_vbe_qemu.obj
+ vxd_vdd_svga.obj vxd_vbe.obj vxd_vbe_qemu.obj vxd_mouse.obj
INCS = -I$(%WATCOM)\h\win -Iddk -Ivmware
@@ -16,12 +16,12 @@ VER_BUILD = 24
FLAGS = -DDRV_VER_BUILD=$(VER_BUILD)
# Define HWBLT if BitBlt can be accelerated.
-#FLAGS += -DHWBLT
+FLAGS += -DHWBLT
# Define VRAM256MB if you want set VRAM limit to 256MB (default is 128MB)
#FLAGS += -DVRAM256MB
# Set DBGPRINT to add debug printf logging.
-#DBGPRINT = 1
+DBGPRINT = 1
!ifdef DBGPRINT
FLAGS += -DDBGPRINT
@@ -130,6 +130,9 @@ vxd_main_qemu.obj : vxd_main_qemu.c .autodepend
vxd_main_svga.obj : vxd_main_svga.c .autodepend
$(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
+vxd_mouse.obj : vxd_mouse.c .autodepend
+ $(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
+
vxd_svga.obj : vxd_svga.c .autodepend
$(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
@@ -395,6 +398,7 @@ file vxd_fbhda.obj
file vxd_lib.obj
file vxd_svga.obj
file vxd_vdd_svga.obj
+file vxd_mouse.obj
segment '_LTEXT' PRELOAD NONDISCARDABLE
segment '_TEXT' PRELOAD NONDISCARDABLE
segment '_DATA' PRELOAD NONDISCARDABLE
@@ -416,6 +420,7 @@ file vxd_fbhda.obj
file vxd_lib.obj
file vxd_vbe_qemu.obj
file vxd_vdd_qemu.obj
+file vxd_mouse.obj
segment '_LTEXT' PRELOAD NONDISCARDABLE
segment '_TEXT' PRELOAD NONDISCARDABLE
segment '_DATA' PRELOAD NONDISCARDABLE
@@ -434,6 +439,7 @@ file vxd_fbhda.obj
file vxd_vbe.obj
file vxd_lib.obj
file vxd_vdd.obj
+file vxd_mouse.obj
segment '_LTEXT' PRELOAD NONDISCARDABLE
segment '_TEXT' PRELOAD NONDISCARDABLE
segment '_DATA' PRELOAD NONDISCARDABLE
diff --git a/minidrv.h b/minidrv.h
index d85bf8f..52f3291 100644
--- a/minidrv.h
+++ b/minidrv.h
@@ -106,6 +106,9 @@ typedef struct FBHDA FBHDA_t;
extern FBHDA_t __far * hda;
extern DWORD hda_linear;
+extern DWORD mouse_buf_lin;
+extern void __far* mouse_buf;
+extern BOOL mouse_vxd;
/* Inlines needed in multiple modules. */
diff --git a/pm16_calls.c b/pm16_calls.c
index 9f6bc0c..7b42184 100644
--- a/pm16_calls.c
+++ b/pm16_calls.c
@@ -262,6 +262,124 @@ DWORD FBHDA_palette_get(unsigned char index)
return sRGB;
}
+BOOL mouse_load()
+{
+ static BOOL status;
+
+ _asm
+ {
+ .386
+ push eax
+ push edx
+ push ecx
+
+ mov edx, OP_MOUSE_LOAD
+ call dword ptr [VXD_VM]
+ mov [status],cx
+
+ pop ecx
+ pop edx
+ pop eax
+ }
+
+ return status == 0 ? FALSE : TRUE;
+}
+
+void mouse_buffer(void __far* __far* pBuf, DWORD __far* pLinear)
+{
+ static DWORD buffer;
+
+ _asm
+ {
+ .386
+ push eax
+ push edx
+ push ecx
+
+ mov edx, OP_MOUSE_BUFFER
+ call dword ptr [VXD_VM]
+ mov [buffer],ecx
+
+ pop ecx
+ pop edx
+ pop eax
+ }
+
+ if(buffer)
+ {
+ void __far *longptr = NULL;
+ WORD desc = DPMI_AllocLDTDesc(1);
+ DPMI_SetSegBase(desc, buffer);
+ DPMI_SetSegLimit(desc, MOUSE_BUFFER_SIZE);
+
+ longptr = desc :> 0;
+
+ *pBuf = longptr;
+ *pLinear = buffer;
+ }
+}
+
+void mouse_move(int x, int y)
+{
+ static DWORD sx;
+ static DWORD sy;
+
+ sx = x;
+ sy = y;
+
+ _asm
+ {
+ .386
+ push eax
+ push edx
+ push esi
+ push edi
+
+ mov esi, [sx]
+ mov edi, [sy]
+ mov edx, OP_MOUSE_MOVE
+ call dword ptr [VXD_VM]
+
+ pop edi
+ pop esi
+ pop edx
+ pop eax
+ }
+}
+
+void mouse_show()
+{
+ _asm
+ {
+ .386
+ push eax
+ push edx
+
+ mov edx, OP_MOUSE_SHOW
+ call dword ptr [VXD_VM]
+
+ pop edx
+ pop eax
+ }
+}
+
+void mouse_hide()
+{
+ _asm
+ {
+ .386
+ push eax
+ push edx
+
+ mov edx, OP_MOUSE_HIDE
+ call dword ptr [VXD_VM]
+
+ pop edx
+ pop eax
+ }
+}
+
+
#ifdef SVGA
BOOL SVGA_valid()
{
diff --git a/vmdisp9x.inf b/vmdisp9x.inf
index b0b4380..4b3e910 100644
--- a/vmdisp9x.inf
+++ b/vmdisp9x.inf
@@ -143,8 +143,7 @@ HKLM,Software\Microsoft\Windows\CurrentVersion\OpenGLdrivers,VMWSVGA
[VM.AddReg]
HKR,,Ver,,4.0
HKR,,DevLoader,,*vdd
-HKR,DEFAULT,vdd,,"*vdd,*vflatd"
-;HKR,DEFAULT,carddvdd,,cardsamp.vxd
+HKR,DEFAULT,vdd,,"*vdd"
HKR,DEFAULT,RefreshRate,,-1
HKR,DEFAULT,DDC,,1
HKR,DEFAULT,ExtModeSwitch,,0
diff --git a/vxd.h b/vxd.h
index 49b0632..627c02a 100644
--- a/vxd.h
+++ b/vxd.h
@@ -17,7 +17,7 @@
#define VXD_DEVICE_NAME "QEMUVXD"
#else
#define VXD_DEVICE_ID VXD_DEVICE_VBE_ID
-#define VXD_DEVICE_NAME "VBE_VXD"
+#define VXD_DEVICE_NAME "BOXVVXD"
#endif
#define VXD_MAJOR_VER 4 /* should be 4 for windows 95 and newer */
diff --git a/vxd_fbhda.c b/vxd_fbhda.c
index d47129f..b090341 100644
--- a/vxd_fbhda.c
+++ b/vxd_fbhda.c
@@ -82,7 +82,10 @@ FBHDA_t *FBHDA_setup()
void FBHDA_access_begin(DWORD flags)
{
//Wait_Semaphore(hda_sem, 0);
- fb_lock_cnt++;
+ if(fb_lock_cnt++ == 0)
+ {
+ mouse_erase();
+ }
}
void FBHDA_clean()
diff --git a/vxd_lib.c b/vxd_lib.c
index bab7ff5..07fc652 100644
--- a/vxd_lib.c
+++ b/vxd_lib.c
@@ -177,6 +177,32 @@ void __cdecl Signal_Semaphore(ULONG SemHandle)
_asm pop eax
}
+void __cdecl *Map_Flat(BYTE SegOffset, BYTE OffOffset)
+{
+ static BYTE sSegOffset;
+ static BYTE sOffOffset;
+ static void *result;
+
+ sSegOffset = SegOffset;
+ sOffOffset = OffOffset;
+
+ _asm
+ {
+ push eax
+ xor eax, eax
+ mov al, [sOffOffset]
+ mov ah, [sSegOffset]
+ }
+ VMMCall(Map_Flat);
+ _asm
+ {
+ mov [result],eax
+ pop eax
+ }
+
+ return result;
+}
+
ULONG __declspec(naked) __cdecl _PageAllocate(ULONG nPages, ULONG pType, ULONG VM, ULONG AlignMask, ULONG minPhys, ULONG maxPhys, ULONG *PhysAddr, ULONG flags)
{
VMMJmp(_PageAllocate);
diff --git a/vxd_lib.h b/vxd_lib.h
index dd36f32..4589be9 100644
--- a/vxd_lib.h
+++ b/vxd_lib.h
@@ -45,12 +45,21 @@ ULONG __cdecl Create_Semaphore(ULONG TokenCount);
void __cdecl Destroy_Semaphore(ULONG SemHandle);
void __cdecl Wait_Semaphore(ULONG semHandle, ULONG flags);
void __cdecl Signal_Semaphore(ULONG SemHandle);
+void __cdecl *Map_Flat(BYTE SegOffset, BYTE OffOfset);
/**
* round size in bytes to number of pages
**/
#define RoundToPages(_size) (((_size) + P_SIZE - 1)/P_SIZE)
+/**
+ * PM16 to PM32 memory mapping
+ **/
+#define INVALID_FLAT_ADDRESS ((void*)(0xFFFFFFFFUL))
+#define Client_Ptr_Flat(_pcrs, _segReg, _offReg) Map_Flat( \
+ ((DWORD)(&(_pcrs->_segReg)))-((DWORD)(_pcrs)), \
+ ((DWORD)(&(_pcrs->_offReg)))-((DWORD)(_pcrs)) )
+
/* sometimes missing */
#ifndef ERROR_SUCCESS
#define ERROR_SUCCESS 0
diff --git a/vxd_main.c b/vxd_main.c
index 6923869..f86334f 100644
--- a/vxd_main.c
+++ b/vxd_main.c
@@ -249,6 +249,9 @@ WORD __stdcall VXD_API_Proc(PCRS_32 state)
{
WORD rc = 0xFFFF;
WORD service = state->Client_EDX & 0xFFFF;
+
+ //dbg_printf(dbg_vxd_api, service);
+
switch(service)
{
case VXD_PM16_VERSION:
@@ -300,6 +303,25 @@ WORD __stdcall VXD_API_Proc(PCRS_32 state)
rc = 1;
break;
}
+ /* mouse */
+ case OP_MOUSE_LOAD:
+ state->Client_ECX = mouse_load();
+ rc = 1;
+ break;
+ case OP_MOUSE_BUFFER:
+ state->Client_ECX = (DWORD)mouse_buffer();
+ rc = 1;
+ break;
+ case OP_MOUSE_MOVE:
+ mouse_move(state->Client_ESI, state->Client_EDI);
+ rc = 1;
+ break;
+ case OP_MOUSE_SHOW:
+ mouse_show();
+ break;
+ case OP_MOUSE_HIDE:
+ mouse_hide();
+ break;
#ifdef SVGA
case OP_SVGA_VALID:
{
diff --git a/vxd_mouse.c b/vxd_mouse.c
new file mode 100644
index 0000000..5e5a2ad
--- /dev/null
+++ b/vxd_mouse.c
@@ -0,0 +1,243 @@
+/*****************************************************************************
+
+Copyright (c) 2024 Jaroslav Hensl <emulator@emulace.cz>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*****************************************************************************/
+
+#include "winhack.h"
+#include "vmm.h"
+#include "vxd.h"
+
+#include "vxd_lib.h"
+#include "3d_accel.h"
+
+#include "cursor.h"
+
+#include "code32.h"
+
+extern FBHDA_t *hda;
+
+static void *mouse_buffer_mem = NULL;
+static void *mouse_andmask_data = NULL;
+static void *mouse_xormask_data = NULL;
+static void *mouse_swap_data = NULL;
+static DWORD mouse_mem_size = 0;
+
+static int mouse_x = 0;
+static int mouse_y = 0;
+
+static int mouse_w = 0;
+static int mouse_h = 0;
+static int mouse_pointx = 0;
+static int mouse_pointy = 0;
+static int mouse_swap_x = 0;
+static int mouse_swap_y = 0;
+static int mouse_swap_w = 0;
+static int mouse_swap_h = 0;
+static int mouse_swap_valid = FALSE;
+static int mouse_ps = 0;
+
+static BOOL mouse_valid = FALSE;
+static BOOL mouse_empty = FALSE;
+static BOOL mouse_visible = FALSE;
+
+#define CUR_MIN_SIZE (32*32*4)
+
+#include "vxd_strings.h"
+
+#include "vxd_mouse_conv.h"
+
+void *mouse_buffer()
+{
+ if(mouse_buffer_mem == NULL)
+ {
+ mouse_buffer_mem = (void*)_PageAllocate(RoundToPages(MOUSE_BUFFER_SIZE), PG_SYS, 0, 0, 0x0, 0x100000, NULL, PAGEFIXED);
+ }
+
+ return mouse_buffer_mem;
+}
+
+static void mouse_notify_accel()
+{
+ if(mouse_valid && mouse_visible && !mouse_empty)
+ {
+ hda->flags &= ~((DWORD)FB_MOUSE_NO_BLIT);
+ }
+ else
+ {
+ hda->flags |= FB_MOUSE_NO_BLIT;
+ }
+}
+
+BOOL mouse_load()
+{
+ DWORD ms = 0;
+ void *andmask_ptr;
+ void *xormask_ptr;
+ CURSORSHAPE *cur;
+ DWORD cbw;
+
+ if(!mouse_buffer_mem) return FALSE;
+
+ cur = (CURSORSHAPE*)mouse_buffer_mem;
+
+ dbg_printf(dbg_mouse_cur, cur->cx, cur->cy, cur->BitsPixel, cur->Planes);
+
+ /* erase cursor if present */
+ FBHDA_access_begin(0);
+
+ mouse_valid = FALSE;
+
+ /* check and alocate/resize buffer */
+ ms = (cur->cx * cur->cy * 4);
+ if(ms < CUR_MIN_SIZE)
+ ms = CUR_MIN_SIZE;
+
+ if(ms > mouse_mem_size)
+ {
+ if(mouse_andmask_data)
+ _PageFree(mouse_andmask_data, 0);
+
+ if(mouse_xormask_data)
+ _PageFree(mouse_xormask_data, 0);
+
+ if(mouse_swap_data)
+ _PageFree(mouse_swap_data, 0);
+
+ mouse_andmask_data =
+ (void*)_PageAllocate(RoundToPages(ms), PG_SYS, 0, 0, 0x0, 0x100000, NULL, PAGEFIXED);
+
+ mouse_xormask_data =
+ (void*)_PageAllocate(RoundToPages(ms), PG_SYS, 0, 0, 0x0, 0x100000, NULL, PAGEFIXED);
+
+ mouse_swap_data =
+ (void*)_PageAllocate(RoundToPages(ms), PG_SYS, 0, 0, 0x0, 0x100000, NULL, PAGEFIXED);
+
+ mouse_mem_size = ms;
+ }
+
+ /* can't allocate memory */
+ if(mouse_andmask_data == NULL ||
+ mouse_xormask_data == NULL ||
+ mouse_swap_data == NULL)
+ {
+ FBHDA_access_end(0);
+ return FALSE;
+ }
+
+ mouse_w = cur->cx;
+ mouse_h = cur->cy;
+ mouse_pointx = cur->xHotSpot;
+ mouse_pointy = cur->yHotSpot;
+
+ andmask_ptr = (void*)(cur + 1);
+ xormask_ptr = (void*)(((BYTE*)andmask_ptr) + cur->cbWidth*cur->cy);
+
+ mouse_ps = (hda->bpp + 7) / 8;
+
+ cbw = (mouse_w+7)/8;
+
+ /* AND mask (always 1bpp) */
+ convmask(cur, cbw, andmask_ptr, mouse_andmask_data);
+
+ /* XOR mask (1bpp or screen bpp) */
+ if(cur->BitsPixel == 1)
+ {
+ convmask(cur, cbw, xormask_ptr, mouse_xormask_data);
+ }
+ else
+ {
+ memcpy(mouse_xormask_data, xormask_ptr,
+ ((cur->BitsPixel + 7)/8) * cur->cx * cur->cy
+ );
+ }
+
+ mouse_valid = TRUE;
+ mouse_visible = TRUE;
+ mouse_empty = cursor_is_empty();
+
+ dbg_printf(dbg_cursor_empty, mouse_empty);
+
+ /* blit new cursor */
+ FBHDA_access_end(0);
+
+ mouse_notify_accel();
+
+ return TRUE;
+}
+
+void mouse_move(int x, int y)
+{
+ if(mouse_valid && mouse_visible && !mouse_empty)
+ {
+ FBHDA_access_begin(0);
+ mouse_x = x;
+ mouse_y = y;
+ FBHDA_access_end(0);
+ }
+ else
+ {
+ mouse_x = x;
+ mouse_y = y;
+ }
+}
+
+void mouse_show()
+{
+ mouse_visible = TRUE;
+
+ mouse_notify_accel();
+}
+
+void mouse_hide()
+{
+ FBHDA_access_begin(0);
+ mouse_visible = FALSE;
+ FBHDA_access_end(0);
+
+ mouse_notify_accel();
+}
+
+void mouse_invalidate()
+{
+ mouse_valid = FALSE;
+
+ mouse_notify_accel();
+}
+
+/* called by FBHDA_access_end */
+void mouse_blit()
+{
+ if(mouse_valid && mouse_visible && !mouse_empty)
+ {
+ draw_save(mouse_x, mouse_y);
+ draw_blit(mouse_x, mouse_y);
+ }
+}
+
+/* called by FBHA_access_begin */
+void mouse_erase()
+{
+ if(mouse_valid && mouse_visible && !mouse_empty)
+ {
+ draw_restore();
+ }
+}
diff --git a/vxd_mouse_conv.h b/vxd_mouse_conv.h
new file mode 100644
index 0000000..2fd079e
--- /dev/null
+++ b/vxd_mouse_conv.h
@@ -0,0 +1,279 @@
+
+static BOOL calc_save(int x, int y)
+{
+ mouse_swap_w = mouse_w;
+ mouse_swap_x = x - mouse_pointx;
+
+ if(mouse_swap_x < 0)
+ {
+ mouse_swap_w -= x;
+ mouse_swap_x = 0;
+ }
+
+ if(mouse_swap_x + mouse_swap_w > hda->width)
+ mouse_swap_w = hda->width - mouse_swap_x;
+
+ mouse_swap_h = mouse_h;
+ mouse_swap_y = y - mouse_pointy;
+
+ if(mouse_swap_y < 0)
+ {
+ mouse_swap_h -= y;
+ mouse_swap_y = 0;
+ }
+
+ if(mouse_swap_y + mouse_swap_h > hda->height)
+ mouse_swap_h = hda->height - mouse_swap_y;
+
+ if(mouse_swap_w <= 0 || mouse_swap_h <= 0)
+ {
+ mouse_swap_valid = FALSE;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+#define DEF_SAVE(_bpp, _type) \
+static void save ## _bpp(int mx, int my){ \
+ int x, y; \
+ _type *screen; \
+ _type *buf = mouse_swap_data; \
+ if(!calc_save(mx, my)){ return; } \
+ screen = (_type*)((BYTE*)hda->vram_pm32 + hda->pitch * mouse_swap_y); \
+ for(y = 0; y < mouse_swap_h; y++) { \
+ for(x = 0; x < mouse_swap_w; x++) { \
+ *buf = screen[mouse_swap_x + x]; \
+ buf++; \
+ } \
+ screen = (_type*)((BYTE*)screen+hda->pitch); \
+ } \
+ mouse_swap_valid = TRUE; }
+
+DEF_SAVE( 8, BYTE)
+DEF_SAVE(16, WORD)
+DEF_SAVE(32, DWORD)
+
+static void save24(int mx, int my)
+{
+ int x, y;
+ BYTE *screen;
+ BYTE *buf = mouse_swap_data;
+ if(!calc_save(mx, my)){ return; }
+ screen = (BYTE*)hda->vram_pm32 + hda->pitch * mouse_swap_y;
+ for(y = 0; y < mouse_swap_h; y++)
+ {
+ for(x = 0; x < mouse_swap_w; x++)
+ {
+ *(buf++) = screen[(mouse_swap_x + x)*3 ];
+ *(buf++) = screen[(mouse_swap_x + x)*3 + 1];
+ *(buf++) = screen[(mouse_swap_x + x)*3 + 2];
+ }
+ screen += hda->pitch;
+ }
+ mouse_swap_valid = TRUE;
+}
+
+#define DEF_RESTORE(_bpp, _type) \
+static void restore ## _bpp () { \
+ int x, y; \
+ _type *screen; \
+ _type *buf = mouse_swap_data; \
+ if(!mouse_swap_valid){ return; } \
+ screen = (_type*)((BYTE*)hda->vram_pm32 + hda->pitch * mouse_swap_y); \
+ for(y = 0; y < mouse_swap_h; y++) { \
+ for(x = 0; x < mouse_swap_w; x++) { \
+ screen[mouse_swap_x + x] = *buf; buf++; \
+ } \
+ screen = (_type*)((BYTE*)screen+hda->pitch); \
+ } \
+ mouse_swap_valid = FALSE; }
+
+DEF_RESTORE( 8, BYTE)
+DEF_RESTORE(16, WORD)
+DEF_RESTORE(32, DWORD)
+
+void restore24()
+{
+ int x, y;
+ BYTE *screen;
+ BYTE *buf = mouse_swap_data;
+ if(!mouse_swap_valid){ return; }
+ screen = (BYTE*)hda->vram_pm32 + hda->pitch * mouse_swap_y;
+ for(y = 0; y < mouse_swap_h; y++)
+ {
+ for(x = 0; x < mouse_swap_w; x++)
+ {
+ screen[(mouse_swap_x + x)*3 ] = *(buf++);
+ screen[(mouse_swap_x + x)*3 + 1] = *(buf++);
+ screen[(mouse_swap_x + x)*3 + 2] = *(buf++);
+ }
+ screen += hda->pitch;
+ }
+ mouse_swap_valid = FALSE;
+}
+
+#define DEF_BLIT(_bpp, _type) \
+static void blit ## _bpp (int mx, int my) { \
+ int x, y; \
+ _type *screen_line; \
+ _type *and_line; \
+ _type *xor_line; \
+ int real_x = mx - mouse_pointx; \
+ int real_y = my - mouse_pointy; \
+ int real_xx, real_yy; \
+ for(y = 0; y < mouse_h; y++) { \
+ real_yy = real_y+y; \
+ if(real_yy >= 0 && real_yy < hda->height) { \
+ screen_line = (_type*)(((BYTE*)hda->vram_pm32) + hda->pitch * (real_yy)); \
+ and_line = ((_type*)mouse_andmask_data + mouse_w * y); \
+ xor_line = ((_type*)mouse_xormask_data + mouse_w * y); \
+ for(x = 0; x < mouse_w; x++) { \
+ real_xx = real_x+x; \
+ if(real_xx >= 0 && real_xx < hda->width) { \
+ screen_line[real_xx] &= and_line[x]; \
+ screen_line[real_xx] ^= xor_line[x]; \
+} } } } }
+
+DEF_BLIT(8, BYTE)
+DEF_BLIT(16, WORD)
+DEF_BLIT(32, DWORD)
+
+static void blit24(int mx, int my)
+{
+ int x, y;
+ BYTE *screen_line;
+ BYTE *and_line;
+ BYTE *xor_line;
+ int real_x = mx - mouse_pointx;
+ int real_y = my - mouse_pointy;
+ int real_xx, real_yy;
+ int real_xx3, x3;
+ for(y = 0; y < mouse_h; y++)
+ {
+ real_yy = real_y+y;
+ if(real_yy >= 0 && real_yy < hda->height)
+ {
+ screen_line = ((BYTE*)hda->vram_pm32) + hda->pitch * real_yy;
+ and_line = ((BYTE*)mouse_andmask_data) + mouse_w * y * 3;
+ xor_line = ((BYTE*)mouse_xormask_data) + mouse_w * y * 3;
+ for(x = 0; x < mouse_w; x++)
+ {
+ real_xx = real_x+x;
+ if(real_xx >= 0 && real_xx < hda->width)
+ {
+ real_xx3 = real_xx*3;
+ x3 = x*3;
+ screen_line[real_xx3 ] &= and_line[x3 ]; screen_line[real_xx3 ] ^= xor_line[x3 ];
+ screen_line[real_xx3+1] &= and_line[x3+1]; screen_line[real_xx3+1] ^= xor_line[x3+1];
+ screen_line[real_xx3+2] &= and_line[x3+2]; screen_line[real_xx3+2] ^= xor_line[x3+2];
+ }
+ }
+ }
+ }
+}
+
+#define EXPAND_BIT(_dsttype, _bit) (~(((_dsttype)(_bit))-1))
+
+#define DEF_CONVMASK(_bpp, _type) \
+static void convmask ## _bpp(CURSORSHAPE *lpCursor, DWORD cbWidth, void *src, void *dst) { \
+ _type *ptr = dst; \
+ int x, y, xb, x8; \
+ BYTE pix8; \
+ for(y = 0; y < lpCursor->cy; y++) { \
+ for(x = 0; x < cbWidth; x++) { \
+ pix8 = ((BYTE *)src)[cbWidth*y + x]; \
+ x8 = x*8; \
+ for(xb = 7; xb >= 0 && x8 < lpCursor->cx; xb--,x8++) { \
+ *(ptr++) = EXPAND_BIT(_type, ((pix8 >> xb) & 0x1)); \
+} } } }
+
+DEF_CONVMASK( 8, BYTE)
+DEF_CONVMASK(16, WORD)
+DEF_CONVMASK(32, DWORD)
+
+static void convmask24(CURSORSHAPE *lpCursor, DWORD cbWidth, void *src, void *dst)
+{
+ BYTE *ptr = dst;
+ int x, y, xb, x8;
+ BYTE pix8;
+ BYTE mask;
+ for(y = 0; y < lpCursor->cy; y++)
+ {
+ for(x = 0; x < cbWidth; x++)
+ {
+ pix8 = ((BYTE *)src)[cbWidth*y + x];
+ x8 = x*8;
+ for(xb = 7; xb >= 0 && x8 < lpCursor->cx; xb--,x8++)
+ {
+ mask = EXPAND_BIT(BYTE, ((pix8 >> xb) & 0x1));
+ *(ptr++) = mask;
+ *(ptr++) = mask;
+ *(ptr++) = mask;
+ }
+ }
+ }
+}
+
+static void draw_save(int mx, int my)
+{
+ switch(mouse_ps)
+ {
+ case 1: save8(mx, my); return;
+ case 2: save16(mx, my); return;
+ case 3: save24(mx, my); return;
+ case 4: save32(mx, my); return;
+ }
+}
+
+static void draw_restore()
+{
+ switch(mouse_ps)
+ {
+ case 1: restore8(); return;
+ case 2: restore16(); return;
+ case 3: restore24(); return;
+ case 4: restore32(); return;
+ }
+}
+
+static void draw_blit(int mx, int my)
+{
+ switch(mouse_ps)
+ {
+ case 1: blit8(mx, my); return;
+ case 2: blit16(mx, my); return;
+ case 3: blit24(mx, my); return;
+ case 4: blit32(mx, my); return;
+ }
+}
+
+static void convmask(CURSORSHAPE *lpCursor, DWORD cbWidth, void *src, void *dst)
+{
+ switch(mouse_ps)
+ {
+ case 1: convmask8(lpCursor, cbWidth, src, dst); return;
+ case 2: convmask16(lpCursor, cbWidth, src, dst); return;
+ case 3: convmask24(lpCursor, cbWidth, src, dst); return;
+ case 4: convmask32(lpCursor, cbWidth, src, dst); return;
+ }
+}
+
+static BOOL cursor_is_empty()
+{
+ DWORD s = mouse_w * mouse_h * mouse_ps;
+ BYTE *and_mask = (BYTE *)mouse_andmask_data;
+ BYTE *xor_mask = (BYTE *)mouse_xormask_data;
+
+ while(s--)
+ {
+ if((*and_mask) != 0xFF || (*xor_mask) != 0x00)
+ {
+ return FALSE;
+ }
+ and_mask++;
+ xor_mask++;
+ }
+
+ return TRUE;
+}
diff --git a/vxd_strings.h b/vxd_strings.h
index 20ce5fb..197066c 100644
--- a/vxd_strings.h
+++ b/vxd_strings.h
@@ -89,6 +89,14 @@ DSTR(dbg_vbe_lfb, "LFB at %X\n");
DSTR(dbg_fbhda_setup, "FBHDA_setup()\n");
+DSTR(dbg_mouse_cur, "Mouse %d %d %d %d\n");
+
+DSTR(dbg_flatptr, "Flatptr: %X\n");
+
+DSTR(dbg_vxd_api, "VXD_API_Proc, service: %X\n");
+
+DSTR(dbg_cursor_empty, "new cursor: empty %X\n");
+
#undef DSTR
#endif
diff --git a/vxd_svga.c b/vxd_svga.c
index 89d0cb7..8780cfc 100644
--- a/vxd_svga.c
+++ b/vxd_svga.c
@@ -914,7 +914,8 @@ BOOL SVGA_region_create(SVGA_region_info_t *rinfo)
dbg_printf(dbg_gmr, rinfo->region_id, rinfo->region_ppn);
- SVGA_Flush_CB();
+ // JH: no need here
+ //SVGA_Flush_CB();
if(rinfo->region_id <= SVGA_ReadReg(SVGA_REG_GMR_MAX_IDS))
{
@@ -945,7 +946,7 @@ void SVGA_region_free(SVGA_region_info_t *rinfo)
SVGA_Flush_CB();
SVGA_WriteReg(SVGA_REG_GMR_ID, rinfo->region_id);
SVGA_WriteReg(SVGA_REG_GMR_DESCRIPTOR, 0);
- SVGA_Flush_CB();
+ //SVGA_Flush_CB();
if(rinfo->region_address != NULL)
{
@@ -1232,6 +1233,8 @@ BOOL SVGA_setmode(DWORD w, DWORD h, DWORD bpp)
hda->stride = hda->height * hda->pitch;
hda->surface = 0;
+ mouse_invalidate();
+
if(has3D && SVGA_GetDevCap(SVGA3D_DEVCAP_3D) > 0)
{
hda->flags |= FB_ACCEL_VMSVGA3D;
@@ -1394,6 +1397,8 @@ void FBHDA_access_end(DWORD flags)
if(fb_lock_cnt == 0)
{
+ mouse_blit();
+
if(hda->bpp == 32)
{
SVGAFifoCmdUpdate *cmd_update;
diff --git a/vxd_vbe.c b/vxd_vbe.c
index adb5ccd..18fcae1 100644
--- a/vxd_vbe.c
+++ b/vxd_vbe.c
@@ -259,8 +259,10 @@ BOOL VBE_setmode(DWORD w, DWORD h, DWORD bpp)
hda->height = h;
hda->bpp = bpp;
hda->pitch = VBE_pitch(w, bpp);
- hda->surface = 0;
hda->stride = h * hda->bpp;
+ hda->surface = 0;
+
+ mouse_invalidate();
return TRUE;
}
@@ -314,6 +316,7 @@ void FBHDA_access_end(DWORD flags)
if(fb_lock_cnt == 0)
{
+ mouse_blit();
// cursor
}