aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaroslav Hensl <jara@hensl.cz>2023-08-26 20:31:44 +0200
committerJaroslav Hensl <jara@hensl.cz>2023-08-26 20:31:44 +0200
commit313656bf15572becdb3c3ab2183fcd8a009ad2e8 (patch)
tree074831497877ecf851b82f8a04426f3cdc3e3fff
parentfc27a94c851ac47687a9c4dd0ca50f47674fc223 (diff)
downloadvmdisp9x-313656bf15572becdb3c3ab2183fcd8a009ad2e8.tar.gz
SVGA: HW cursor (enabled by default)
-rw-r--r--control_vxd.c11
-rw-r--r--control_vxd.h7
-rw-r--r--dibcall.c270
-rw-r--r--dpmi.h14
-rw-r--r--drvlib.c15
-rw-r--r--enable.c4
-rw-r--r--makefile2
-rw-r--r--vmware/svga.c8
-rw-r--r--vmwsvxd.c85
-rw-r--r--vmwsvxd.h3
10 files changed, 330 insertions, 89 deletions
diff --git a/control_vxd.c b/control_vxd.c
index c680047..147e491 100644
--- a/control_vxd.c
+++ b/control_vxd.c
@@ -324,9 +324,16 @@ void VXD_get_flags(DWORD __far *lpFlags)
*lpFlags = flags;
}
-BOOL VXD_FIFOCommit(DWORD bytes)
+BOOL VXD_FIFOCommit(DWORD bytes, BOOL sync)
{
static DWORD sbytes;
+ static DWORD cmd;
+
+ cmd = VMWSVXD_PM16_FIFO_COMMIT;
+ if(sync)
+ {
+ cmd = VMWSVXD_PM16_FIFO_COMMIT_SYNC;
+ }
sbytes = bytes;
@@ -340,7 +347,7 @@ BOOL VXD_FIFOCommit(DWORD bytes)
push ecx
mov ecx, [sbytes]
- mov edx, VMWSVXD_PM16_FIFO_COMMIT
+ mov edx, [cmd]
call dword ptr [VXD_srv]
pop ecx
diff --git a/control_vxd.h b/control_vxd.h
index 9a839d6..2668247 100644
--- a/control_vxd.h
+++ b/control_vxd.h
@@ -11,9 +11,12 @@ void CB_stop();
void VXD_get_addr(DWORD __far *lpLinFB, DWORD __far *lpLinFifo, DWORD __far *lpLinFifoBounce);
void VXD_get_flags(DWORD __far *lpFlags);
-BOOL VXD_FIFOCommit(DWORD bytes);
+BOOL VXD_FIFOCommit(DWORD bytes, BOOL sync);
#define VXD_FIFOCommitAll() \
- if(VXD_FIFOCommit(gSVGA.fifo.reservedSize)){gSVGA.fifo.reservedSize = 0;}else{SVGA_FIFOCommitAll();}
+ if(VXD_FIFOCommit(gSVGA.fifo.reservedSize, FALSE)){gSVGA.fifo.reservedSize = 0;}else{SVGA_FIFOCommitAll();}
+
+#define VXD_FIFOCommitSync() \
+ VXD_FIFOCommit(gSVGA.fifo.reservedSize, TRUE);gSVGA.fifo.reservedSize = 0
#endif
diff --git a/dibcall.c b/dibcall.c
index 312f341..e4281f3 100644
--- a/dibcall.c
+++ b/dibcall.c
@@ -32,6 +32,7 @@ THE SOFTWARE.
#ifdef SVGA
# include "svga_all.h"
# include <string.h>
+# include "control_vxd.h"
#endif
/*
@@ -50,13 +51,17 @@ THE SOFTWARE.
*/
/* from DDK98 */
+#pragma pack(push)
+#pragma pack(1)
typedef struct
{
int xHotSpot, yHotSpot;
int cx, cy;
int cbWidth;
- BYTE Planes, BitsPixel;
+ BYTE Planes;
+ BYTE BitsPixel;
} CURSORSHAPE;
+#pragma pack(pop)
#ifdef SVGA
BOOL cursorVisible = FALSE;
@@ -65,7 +70,6 @@ BOOL cursorVisible = FALSE;
#pragma code_seg( _TEXT )
#ifdef SVGA
-# ifndef HWCURSOR
static LONG cursorX = 0;
static LONG cursorY = 0;
static LONG cursorW = 0;
@@ -73,8 +77,85 @@ static LONG cursorH = 0;
static LONG cursorHX = 0;
static LONG cursorHY = 0;
+
+/*
+ https://learn.microsoft.com/en-us/windows-hardware/drivers/display/drawing-monochrome-pointers
+*/
+static void CursorMonoToAlpha(CURSORSHAPE __far *lpCursor, void __far *data)
+{
+ LONG __far *px = data;
+ BYTE __far *andmask = (BYTE __far *)(lpCursor + 1);
+ BYTE __far *xormask = andmask + lpCursor->cbWidth*lpCursor->cy;
+ int xi, xj, y;
+
+ for(y = 0; y < lpCursor->cy; y++)
+ {
+ for(xj = 0; xj < (lpCursor->cbWidth); xj++)
+ {
+ BYTE a = andmask[lpCursor->cbWidth*y + xj];
+ BYTE x = xormask[lpCursor->cbWidth*y + xj];
+ for(xi = 7; xi >= 0; xi--)
+ {
+ BYTE mx = (((a >> xi) & 0x1) << 1) | ((x >> xi) & 0x1);
+
+ switch(mx)
+ {
+ case 0:
+ *px = 0xFF000000; // full black
+ break;
+ case 1:
+ *px = 0xFFFFFFFF; // full white
+ break;
+ case 2:
+ *px = 0x00000000; // transparent
+ break;
+ case 3:
+ *px = 0xFFFFFFFF; // inverse = set as white
+ break;
+ }
+
+ px++;
+ }
+ }
+ }
+}
+
+static void CursorColor32ToAlpha(CURSORSHAPE __far *lpCursor, void __far *data)
+{
+ LONG __far *px = data;
+ BYTE __far *andmask = (BYTE __far *)(lpCursor + 1);
+ DWORD __far *xormask = (DWORD __far *)(andmask + lpCursor->cbWidth*lpCursor->cy);
+ int xi, xj, y;
+
+ for(y = 0; y < lpCursor->cy; y++)
+ {
+ for(xj = 0; xj < (lpCursor->cbWidth); xj++)
+ {
+ BYTE a = andmask[lpCursor->cbWidth*y + xj];
+
+ for(xi = 7; xi >= 0; xi--)
+ {
+ DWORD x = xormask[lpCursor->cx*y + xj*8 + (7-xi)] & 0x00FFFFFFUL;
+ BYTE ab = ((a >> xi) & 0x1);
+
+ switch(ab)
+ {
+ case 0:
+ *px = 0xFF000000UL | x;
+ break;
+ case 1:
+ *px = 0x00000000UL | x;
+ break;
+ }
+
+ px++;
+ }
+ }
+ }
+}
+
void update_cursor()
-{
+{
if(wBpp == 32)
{
LONG x = cursorX - cursorHX;
@@ -85,7 +166,6 @@ void update_cursor()
SVGA_UpdateRect(x, y, w, h);
}
}
-# endif
#endif
void WINAPI __loadds MoveCursor(WORD absX, WORD absY)
@@ -95,18 +175,21 @@ void WINAPI __loadds MoveCursor(WORD absX, WORD absY)
#ifdef SVGA
if(wBpp == 32)
{
-# ifdef HWCURSOR
- SVGA_MoveCursor(cursorVisible, absX, absY, 0);
-# else
- DIB_MoveCursorExt(absX, absY, lpDriverPDevice);
- update_cursor();
- cursorX = absX;
- cursorY = absY;
- update_cursor();
-# endif
+ if(gSVGA.userFlags & SVGA_USER_FLAGS_HWCURSOR)
+ {
+ SVGA_MoveCursor(cursorVisible, absX, absY, 0);
+ }
+ else
+ {
+ DIB_MoveCursorExt(absX, absY, lpDriverPDevice);
+ update_cursor();
+ cursorX = absX;
+ cursorY = absY;
+ update_cursor();
+ }
return;
}
-#endif
+#endif // SVGA
DIB_MoveCursorExt(absX, absY, lpDriverPDevice);
}
}
@@ -118,75 +201,106 @@ WORD WINAPI __loadds SetCursor_driver(CURSORSHAPE __far *lpCursor)
#ifdef SVGA
if(wBpp == 32)
{
-# ifdef HWCURSOR
- void __far* ANDMask = NULL;
- void __far* XORMask = NULL;
- SVGAFifoCmdDefineCursor cur;
-
- if(lpCursor != NULL)
+ if(gSVGA.userFlags & SVGA_USER_FLAGS_HWCURSOR)
{
- cur.id = 0;
- cur.hotspotX = lpCursor->xHotSpot;
- cur.hotspotY = lpCursor->yHotSpot;
- cur.width = lpCursor->cx;
- cur.height = lpCursor->cy;
- cur.andMaskDepth = 1;
- cur.xorMaskDepth = 1;
+ void __far* ANDMask = NULL;
+ void __far* XORMask = NULL;
+ void __far* AData = NULL;
+ SVGAFifoCmdDefineCursor cur;
+ SVGAFifoCmdDefineAlphaCursor acur;
- dbg_printf("cx: %d, cy: %d, cbWidth: %d, Planes: %d\n", lpCursor->cx, lpCursor->cy, lpCursor->cbWidth, lpCursor->Planes);
-
- SVGA_BeginDefineCursor(&cur, &ANDMask, &XORMask);
-
- if(ANDMask)
+ if(lpCursor != NULL)
{
- _fmemcpy(ANDMask, lpCursor+1, lpCursor->cbWidth*lpCursor->cy);
+ dbg_printf("cx: %d, cy: %d, colors: %d\n", lpCursor->cx, lpCursor->cy, lpCursor->BitsPixel);
+
+ if(gSVGA.userFlags & SVGA_USER_FLAGS_ALPHA_CUR)
+ {
+ acur.id = 0;
+ acur.hotspotX = lpCursor->xHotSpot;
+ acur.hotspotY = lpCursor->yHotSpot;
+ acur.width = lpCursor->cx;
+ acur.height = lpCursor->cy;
+
+ SVGA_BeginDefineAlphaCursor(&acur, &AData);
+ if(AData)
+ {
+ switch(lpCursor->BitsPixel)
+ {
+ case 1:
+ CursorMonoToAlpha(lpCursor, AData);
+ break;
+ case 32:
+ CursorColor32ToAlpha(lpCursor, AData);
+ break;
+ }
+ }
+ }
+ else
+ {
+ cur.id = 0;
+ cur.hotspotX = lpCursor->xHotSpot;
+ cur.hotspotY = lpCursor->yHotSpot;
+ cur.width = lpCursor->cx;
+ cur.height = lpCursor->cy;
+ cur.andMaskDepth = 1;
+ cur.xorMaskDepth = lpCursor->BitsPixel;
+
+ SVGA_BeginDefineCursor(&cur, &ANDMask, &XORMask);
+
+ if(ANDMask)
+ {
+ _fmemcpy(ANDMask, lpCursor+1, lpCursor->cbWidth*lpCursor->cy);
+ }
+
+ if(XORMask)
+ {
+ BYTE __far *ptr = (BYTE __far *)(lpCursor+1);
+ ptr += lpCursor->cbWidth*lpCursor->cy;
+
+ _fmemcpy(XORMask, ptr, lpCursor->cx*lpCursor->cy*((lpCursor->BitsPixel+7)/8));
+ }
+ }
+ //SVGA_FIFOCommitAll();
+ VXD_FIFOCommitSync();
+ cursorVisible = TRUE;
}
-
- if(XORMask)
+ else
{
- BYTE __far *ptr = (BYTE __far *)(lpCursor+1);
- ptr += lpCursor->cbWidth*lpCursor->cy;
+ /* virtual box bug on SVGA_MoveCursor(FALSE, ...)
+ * so if is cursor NULL, create empty
+ */
+ cur.id = 0;
+ cur.hotspotX = 0;
+ cur.hotspotY = 0;
+ cur.width = 32;
+ cur.height = 32;
+ cur.andMaskDepth = 1;
+ cur.xorMaskDepth = 1;
+
+ SVGA_BeginDefineCursor(&cur, &ANDMask, &XORMask);
+
+ if(ANDMask) _fmemset(ANDMask, 0xFF, 4*32);
+ if(XORMask) _fmemset(XORMask, 0, 4*32);
+
+ //SVGA_FIFOCommitAll();
+ VXD_FIFOCommitSync();
- _fmemcpy(XORMask, ptr, lpCursor->cbWidth*lpCursor->cy);
+ SVGA_MoveCursor(FALSE, 0, 0, 0);
+ cursorVisible = FALSE;
}
- SVGA_FIFOCommitAll();
- cursorVisible = TRUE;
- return 1;
+ return 1; /* SUCCESS */
}
else
{
- /* virtual bug on SVGA_MoveCursor(FALSE, ...)
- * so if is cursor NULL, create empty
- */
- cur.id = 0;
- cur.hotspotX = 0;
- cur.hotspotY = 0;
- cur.width = 32;
- cur.height = 32;
- cur.andMaskDepth = 1;
- cur.xorMaskDepth = 1;
-
- SVGA_BeginDefineCursor(&cur, &ANDMask, &XORMask);
-
- if(ANDMask) _fmemset(ANDMask, 0xFF, 4*32);
- if(XORMask) _fmemset(XORMask, 0, 4*32);
-
- SVGA_FIFOCommitAll();
-
- SVGA_MoveCursor(FALSE, 0, 0, 0);
- cursorVisible = FALSE;
- return 1;
- }
-# else
- if(lpCursor != NULL)
- {
- cursorW = lpCursor->cx;
- cursorH = lpCursor->cy;
- cursorHX = lpCursor->xHotSpot;
- cursorHY = lpCursor->yHotSpot;
+ if(lpCursor != NULL)
+ {
+ cursorW = lpCursor->cx;
+ cursorH = lpCursor->cy;
+ cursorHX = lpCursor->xHotSpot;
+ cursorHY = lpCursor->yHotSpot;
+ }
}
-# endif
} // 32bpp
#endif
DIB_SetCursorExt(lpCursor, lpDriverPDevice);
@@ -200,15 +314,21 @@ void WINAPI __loadds CheckCursor( void )
{
if( wEnabled ) {
#ifdef SVGA
-# ifndef HWCURSOR
+ if((gSVGA.userFlags & SVGA_USER_FLAGS_HWCURSOR) == 0)
+ {
DIB_CheckCursorExt( lpDriverPDevice );
if(wBpp == 32)
{
update_cursor();
}
-# else
- if(wBpp != 32) DIB_CheckCursorExt( lpDriverPDevice );
-# endif
+ }
+ else
+ {
+ if(wBpp != 32)
+ {
+ DIB_CheckCursorExt( lpDriverPDevice );
+ }
+ }
#else
DIB_CheckCursorExt( lpDriverPDevice );
#endif
diff --git a/dpmi.h b/dpmi.h
index aab6467..4d838fb 100644
--- a/dpmi.h
+++ b/dpmi.h
@@ -56,8 +56,18 @@ extern DWORD DPMI_AllocMemBlk(DWORD Size);
"alloc_ok:" \
"mov dx, bx" \
"mov ax, cx" \
- parm [cx bx] modify [di si];
-
+ parm [cx bx] modify [ax di si];
+
+extern WORD DPMI_FreeMemBlk(DWORD ptr);
+#pragma aux DPMI_FreeMemBlk = \
+ "xchg di, si" \
+ "mov ax, 502h" \
+ "int 31h" \
+ "jc free_error" \
+ "xor ax, ax" \
+ "free_error:" \
+ parm [di si] modify [ax];
+
static DWORD DPMI_AllocLinBlk_LinAddress = 0;
static DWORD DPMI_AllocLinBlk_MHandle = 0;
diff --git a/drvlib.c b/drvlib.c
index 33997be..3bcfae1 100644
--- a/drvlib.c
+++ b/drvlib.c
@@ -46,6 +46,21 @@ void __far *drv_malloc(DWORD dwSize, DWORD __far *lpLinear)
return NULL;
}
+void drv_free(void __far *ptr, DWORD __far *lpLinear)
+{
+ DWORD sel = ((DWORD)ptr) >> 16;
+ if(*lpLinear != 0)
+ {
+ DPMI_FreeMemBlk(*lpLinear);
+ *lpLinear = 0;
+ }
+
+ if(sel != 0)
+ {
+ DPMI_FreeLDTDesc(sel);
+ }
+}
+
/**
* MEMSET for area larger than one segment. This function is not very effective,
* I assume it will be called only in few speed non critical situation
diff --git a/enable.c b/enable.c
index af70240..321f317 100644
--- a/enable.c
+++ b/enable.c
@@ -303,6 +303,7 @@ UINT WINAPI __loadds Enable( LPVOID lpDevice, UINT style, LPSTR lpDeviceType,
} else {
/* Fill out GDIINFO for GDI. */
LPGDIINFO lpInfo = lpDevice;
+ _fmemset(lpInfo, 0, sizeof(GDIINFO));
/* Start with passing down to the DIB engine. It will set dpCurves through dpStyleLen. */
DIB_Enable( lpDevice, style, lpDeviceType, lpOutputFile, lpStuff );
@@ -409,6 +410,9 @@ UINT WINAPI __loadds Enable( LPVOID lpDevice, UINT style, LPSTR lpDeviceType,
lpInfo->dpDEVICEsize += sizeof( BITMAPINFOHEADER ) + 8 + wCount;
}
+ /* apply changes */
+ //DIB_Enable( lpInfo, 1, NULL, NULL, NULL );
+
dbg_printf( "sizeof(GDIINFO)=%d (%X), dpDEVICEsize=%X\n", sizeof( GDIINFO ), sizeof( GDIINFO ), lpInfo->dpDEVICEsize );
return( sizeof( GDIINFO ) );
}
diff --git a/makefile b/makefile
index 6ee55f0..4c0ba2b 100644
--- a/makefile
+++ b/makefile
@@ -14,8 +14,6 @@ FLAGS = -DDRV_VER_BUILD=$(VER_BUILD) -DCAP_R5G6B5_ALWAYS_WRONG
# Define HWBLT if BitBlt can be accelerated.
#FLAGS += -DHWBLT
-# Define HWCURSOR if you want accelerate cursor (SVGA only)
-#FLAGS += -DHWCURSOR
# Define VRAM256MB if you want set VRAM limit to 256MB (default is 128MB)
#FLAGS += -DVRAM256MB
diff --git a/vmware/svga.c b/vmware/svga.c
index 9a5d7bc..aaa90fb 100644
--- a/vmware/svga.c
+++ b/vmware/svga.c
@@ -91,8 +91,10 @@ static void SVGAInterruptHandler(int vector);
#pragma code_seg( _INIT )
#endif
+#ifdef DBGPRINT
static char dbg_addr[] = "PCI bars: %lx %lx %lx\n";
static char dbg_siz[] = "Size of gSVGA(1) = %d %d\n";
+#endif
/*
*-----------------------------------------------------------------------------
@@ -1790,8 +1792,8 @@ SVGA_BeginDefineCursor(const SVGAFifoCmdDefineCursor FARP *cursorInfo, // IN
SVGAFifoCmdDefineCursor FARP *cmd = SVGA_FIFOReserveCmd(SVGA_CMD_DEFINE_CURSOR,
sizeof *cmd + andSize + xorSize);
*cmd = *cursorInfo;
- *andMask = (void*) (cmd + 1);
- *xorMask = (void*) (andSize + (uint8 FARP*) *andMask);
+ *andMask = (void FARP*)(cmd + 1);
+ *xorMask = (void FARP*)(andSize + (uint8 FARP*)(*andMask));
}
@@ -1823,7 +1825,7 @@ SVGA_BeginDefineAlphaCursor(const SVGAFifoCmdDefineAlphaCursor FARP *cursorInfo,
SVGAFifoCmdDefineAlphaCursor FARP *cmd = SVGA_FIFOReserveCmd(SVGA_CMD_DEFINE_ALPHA_CURSOR,
sizeof *cmd + imageSize);
*cmd = *cursorInfo;
- *data = (void*) (cmd + 1);
+ *data = (void FARP*) (cmd + 1);
}
diff --git a/vmwsvxd.c b/vmwsvxd.c
index 41256a9..a71c014 100644
--- a/vmwsvxd.c
+++ b/vmwsvxd.c
@@ -814,6 +814,28 @@ void memset(void *dst, int c, unsigned int size)
}
}
+void *memcpy(void *dst, const void *src, unsigned int size)
+{
+ unsigned int dw_count;
+ unsigned int dw_size;
+ unsigned int i;
+
+ dw_count = size >> 2;
+ dw_size = size & 0xFFFFFFFCUL;
+
+ for(i = 0; i < dw_count; i++)
+ {
+ ((unsigned int*)dst)[i] = ((unsigned int*)src)[i];
+ }
+
+ for(i = dw_size; i < size; i++)
+ {
+ ((unsigned char*)dst)[i] = ((unsigned char*)src)[i];
+ }
+
+ return dst;
+}
+
#if 0
/* I'm using this sometimes for developing, not for end user! */
@@ -920,7 +942,7 @@ WORD __stdcall VMWS_API_Proc(PCRS_32 state)
cbe->cmd = SVGA_DC_CMD_START_STOP_CONTEXT;
cbe->cbstart.enable = 1;
cbe->cbstart.context = SVGA_CB_CONTEXT_0;
- submitCB(cbe, SVGA_CB_CONTEXT_DEVICE, TRUE);
+ submitCB(cbe, SVGA_CB_CONTEXT_DEVICE, FALSE);
dbg_printf(dbg_cb_ena);
cb_context0 = TRUE;
@@ -959,6 +981,56 @@ WORD __stdcall VMWS_API_Proc(PCRS_32 state)
DWORD cmd_size = state->Client_ECX;
if(cb_support && cb_context0) /* command buffer is supported - use CB instead of FIFO */
{
+#if 0
+ SVGACBHeader *cb = (SVGACBHeader *)gSVGA.fifo.bounceLinear;
+ memset(cb, 0, sizeof(SVGACBHeader));
+
+ cb->length = cmd_size;
+ cb->status = SVGA_CB_STATUS_NONE;
+ cb->ptr.pa.hi = 0;
+ cb->ptr.pa.low = gSVGA.fifo.bouncePhy + PAGE_SIZE;
+ cb->flags = SVGA_CB_FLAG_NO_IRQ;
+
+ cb->id.low = cmd_buf_next_id.low;
+ cb->id.hi = cmd_buf_next_id.hi;
+
+ SVGA_WriteReg(SVGA_REG_COMMAND_HIGH, 0);
+ SVGA_WriteReg(SVGA_REG_COMMAND_LOW, gSVGA.fifo.bouncePhy | SVGA_CB_CONTEXT_0);
+
+ nextID_CB();
+
+ /* wait to complete */
+ while(cb->status == SVGA_CB_STATUS_NONE)
+ {
+ SVGA_WriteReg(SVGA_REG_SYNC, 1);
+ }
+#endif
+ SVGACBHeader *cb;
+
+ do
+ {
+ cb = LockCB();
+ } while(cb == NULL);
+ memset(cb, 0, sizeof(SVGACBHeader));
+ cb->length = cmd_size;
+ memcpy(cb+1, gSVGA.fifo.bounceMem, cmd_size);
+
+ submitCB(cb, SVGA_CB_CONTEXT_0, TRUE);
+ }
+ else /* use FIFO */
+ {
+ gSVGA.fifo.reservedSize = cmd_size;
+ SVGA_FIFOCommit(cmd_size);
+ }
+
+ rc = 1;
+ break;
+ }
+ case VMWSVXD_PM16_FIFO_COMMIT_SYNC:
+ {
+ DWORD cmd_size = state->Client_ECX;
+ if(cb_support && cb_context0) /* command buffer is supported - use CB instead of FIFO */
+ {
SVGACBHeader *cb = (SVGACBHeader *)gSVGA.fifo.bounceLinear;
memset(cb, 0, sizeof(SVGACBHeader));
@@ -994,7 +1066,6 @@ WORD __stdcall VMWS_API_Proc(PCRS_32 state)
case VMWSVXD_PM16_GET_FLAGS:
state->Client_ECX = gSVGA.userFlags;
break;
-
}
if(rc == 0xFFFF)
@@ -1049,6 +1120,16 @@ void Device_Init_proc()
/* default flags */
gSVGA.userFlags |= SVGA_USER_FLAGS_RGB565_BROKEN | SVGA_USER_FLAGS_128MB_MAX;
+ if(SVGA_ReadReg(SVGA_REG_CAPABILITIES) & SVGA_CAP_CURSOR)
+ {
+ gSVGA.userFlags |= SVGA_USER_FLAGS_HWCURSOR;
+ }
+
+ if(SVGA_ReadReg(SVGA_REG_CAPABILITIES) & SVGA_CAP_ALPHA_CURSOR)
+ {
+ gSVGA.userFlags |= SVGA_USER_FLAGS_ALPHA_CUR;
+ }
+
// TODO: read config from registry
if(gSVGA.userFlags & SVGA_USER_FLAGS_128MB_MAX)
diff --git a/vmwsvxd.h b/vmwsvxd.h
index da37569..ebb6ff3 100644
--- a/vmwsvxd.h
+++ b/vmwsvxd.h
@@ -20,6 +20,7 @@
#define VMWSVXD_PM16_CB_STOP 9
#define VMWSVXD_PM16_GET_ADDR 10
#define VMWSVXD_PM16_FIFO_COMMIT 11
-#define VMWSVXD_PM16_GET_FLAGS 12
+#define VMWSVXD_PM16_FIFO_COMMIT_SYNC 12
+#define VMWSVXD_PM16_GET_FLAGS 13
#endif