summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README542
-rw-r--r--man/vmware.man37
-rw-r--r--src/bits2pixels.c1415
-rw-r--r--src/bits2pixels.h25
-rw-r--r--src/guest_os.h30
-rw-r--r--src/includeCheck.h3
-rw-r--r--src/offscreen_manager.c132
-rw-r--r--src/offscreen_manager.h25
-rw-r--r--src/svga_limits.h57
-rw-r--r--src/svga_reg.h456
-rw-r--r--src/svga_struct.h40
-rw-r--r--src/vm_basic_types.h173
-rw-r--r--src/vm_device_version.h64
-rw-r--r--src/vmware.c1406
-rw-r--r--src/vmware.h265
-rw-r--r--src/vmwarecurs.c445
-rw-r--r--src/vmwarexaa.c549
17 files changed, 5664 insertions, 0 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..883d311
--- /dev/null
+++ b/README
@@ -0,0 +1,542 @@
+
+Copyright (C) 1999-2002 VMware, Inc.
+All Rights Reserved
+
+The code here may be used/distributed under the terms of the standard
+XFree86 license.
+
+
+ VMware SVGA Device Interface and Programming Model
+ --------------------------------------------------
+
+
+Include Files
+-------------
+
+svga_reg.h
+ SVGA register definitions, SVGA capabilities, and FIFO command definitions.
+
+svga_limits.h
+ Included by svga_reg.h, defines maximum frame buffer and memory region
+ sizes.
+
+guest_os.h
+ Values for the GUEST_ID register.
+
+vm_basic_types.h
+ Common type definitions.
+
+vm_device_version.h
+ PCI vendor ID's and related information.
+
+
+Programming the VMware SVGA Device
+----------------------------------
+
+1. Reading/writing a register:
+
+ The SVGA registers are addressed by an index/value pair of 32 bit
+ registers in the IO address space.
+
+ The 0710 VMware SVGA chipset (PCI device ID PCI_DEVICE_ID_VMWARE_SVGA) has
+ its index and value ports hardcoded at:
+
+ index: SVGA_LEGACY_BASE_PORT + 4 * SVGA_INDEX_PORT
+ value: SVGA_LEGACY_BASE_PORT + 4 * SVGA_VALUE_PORT
+
+ The 0405 VMware SVGA chipset (PCI device ID PCI_DEVICE_ID_VMWARE_SVGA2)
+ determines its index and value ports as a function of the first base
+ address register in its PCI configuration space as:
+
+ index: <Base Address Register 0> + SVGA_INDEX_PORT
+ value: <Base Address Register 0> + SVGA_VALUE_PORT
+
+ To read a register:
+ Set the index port to the index of the register, using a dword OUT
+ Do a dword IN from the value port
+
+ To write a register:
+ Set the index port to the index of the register, using a dword OUT
+ Do a dword OUT to the value port
+
+ Example, setting the width to 1024:
+
+ mov eax, SVGA_REG_WIDTH
+ mov edx, <SVGA Address Port>
+ out dx, eax
+ mov eax, 1024
+ mov edx, <SVGA Value Port>
+ out dx, eax
+
+2. Initialization
+ Check the version number
+ loop:
+ Write into SVGA_REG_ID the maximum SVGA_ID_* the driver supports.
+ Read from SVGA_REG_ID.
+ Check if it is the value you wrote.
+ If yes, VMware SVGA device supports it
+ If no, decrement SVGA_ID_* and goto loop
+ This algorithm converges.
+
+ Map the frame buffer and the command FIFO
+ Read SVGA_REG_FB_START, SVGA_REG_FB_SIZE, SVGA_REG_MEM_START,
+ SVGA_REG_MEM_SIZE.
+ Map the frame buffer (FB) and the FIFO memory (MEM)
+
+ Get the device capabilities and frame buffer dimensions
+ Read SVGA_REG_CAPABILITIES, SVGA_REG_MAX_WIDTH, SVGA_REG_MAX_HEIGHT,
+ and SVGA_REG_HOST_BITS_PER_PIXEL / SVGA_REG_BITS_PER_PIXEL.
+
+ Note: The capabilities can and do change without the PCI device ID
+ changing or the SVGA_REG_ID changing. A driver should always check
+ the capabilities register when loading before expecting any
+ capabilities-determined feature to be available. See below for a list
+ of capabilities as of this writing.
+
+ Note: If SVGA_CAP_8BIT_EMULATION is not set, then it is possible that
+ SVGA_REG_HOST_BITS_PER_PIXEL does not exist and
+ SVGA_REG_BITS_PER_PIXEL should be read instead.
+
+ Report the Guest Operating System
+ Write SVGA_REG_GUEST_ID with the appropriate value from <guest_os.h>.
+ While not required in any way, this is useful information for the
+ virtual machine to have available for reporting and sanity checking
+ purposes.
+
+ SetMode
+ Set SVGA_REG_WIDTH, SVGA_REG_HEIGHT, SVGA_REG_BITS_PER_PIXEL
+ Read SVGA_REG_FB_OFFSET
+ (SVGA_REG_FB_OFFSET is the offset from SVGA_REG_FB_START of the
+ visible portion of the frame buffer)
+ Read SVGA_REG_BYTES_PER_LINE, SVGA_REG_DEPTH, SVGA_REG_PSEUDOCOLOR,
+ SVGA_REG_RED_MASK, SVGA_REG_GREEN_MASK, SVGA_REG_BLUE_MASK
+
+ Note: SVGA_REG_BITS_PER_PIXEL is readonly if
+ SVGA_CAP_8BIT_EMULATION is not set in the capabilities register. Even
+ if it is set, values other than 8 and SVGA_REG_HOST_BITS_PER_PIXEL
+ will be ignored.
+
+ Enable SVGA
+ Set SVGA_REG_ENABLE to 1
+ (to disable SVGA, set SVGA_REG_ENABLE to 0. Setting SVGA_REG_ENABLE
+ to 0 also enables VGA.)
+
+ Initialize the command FIFO
+ The FIFO is exclusively dword (32-bit) aligned. The first four
+ dwords define the portion of the MEM area that is used for the
+ command FIFO. These are values are all in byte offsets from the
+ start of the MEM area.
+
+ A minimum sized FIFO would have these values:
+ mem[SVGA_FIFO_MIN] = 16;
+ mem[SVGA_FIFO_MAX] = 16 + (10 * 1024);
+ mem[SVGA_FIFO_NEXT_CMD] = 16;
+ mem[SVGA_FIFO_STOP] = 16;
+
+ Set SVGA_REG_CONFIG_DONE to 1 after these values have been set.
+
+ Note: Setting SVGA_REG_CONFIG_DONE to 0 will stop the device from
+ reading the FIFO until it is reinitialized and SVGA_REG_CONFIG_DONE is
+ set to 1 again.
+
+3. SVGA command FIFO protocol
+ The FIFO is empty when SVGA_FIFO_NEXT_CMD == SVGA_FIFO_STOP. The
+ driver writes commands to the FIFO starting at the offset specified
+ by SVGA_FIFO_NEXT_CMD, and then increments SVGA_FIFO_NEXT_CMD.
+
+ The FIFO is full when SVGA_FIFO_NEXT_CMD is one word before SVGA_FIFO_STOP.
+
+ When the FIFO becomes full, the FIFO should be sync'd
+
+ To sync the FIFO
+ Write SVGA_REG_SYNC
+ Read SVGA_REG_BUSY
+ Wait for the value in SVGA_REG_BUSY to be 0
+
+ The FIFO should be sync'd before the driver touches the frame buffer, to
+ guarantee that any outstanding BLT's are completed.
+
+4. Cursor
+ When SVGA_CAP_CURSOR is set, hardware cursor support is available. In
+ practice, SVGA_CAP_CURSOR will only be set when SVGA_CAP_CURSOR_BYPASS is
+ also set and drivers supporting a hardware cursor should only worry about
+ SVGA_CAP_CURSOR_BYPASS and only use the FIFO to define the cursor. See
+ below for more information.
+
+5. Pseudocolor
+ When the read-only register SVGA_REG_PSEUDOCOLOR is 1, the device is in a
+ colormapped mode whose index width and color width are both SVGA_REG_DEPTH.
+ Thus far, 8 is the only depth at which pseudocolor is ever used.
+
+ In pseudocolor, the colormap is programmed by writing to the SVGA palette
+ registers. These start at SVGA_PALETTE_BASE and are interpreted as
+ follows:
+
+ SVGA_PALETTE_BASE + 3*n - The nth red component
+ SVGA_PALETTE_BASE + 3*n + 1 - The nth green component
+ SVGA_PALETTE_BASE + 3*n + 2 - The nth blue component
+
+ And n ranges from 0 to ((1<<SVGA_REG_DEPTH) - 1).
+
+
+Drawing to the Screen
+---------------------
+
+After initialization, the driver can write directly to the frame buffer. The
+updated frame buffer is not displayed immediately, but only when an update
+command is sent. The update command (SVGA_CMD_UPDATE) defines the rectangle
+in the frame buffer that has been modified by the driver, and causes that
+rectangle to be updated on the screen.
+
+A complete driver can be developed this way. For increased performance,
+additional commands are available to accelerate common operations. The two
+most useful are SVGA_CMD_RECT_FILL and SVGA_CMD_RECT_COPY.
+
+After issuing an accelerated command, the FIFO should be sync'd, as described
+above, before writing to the frame buffer.
+
+Addendum on 7/11/2000
+---------------------
+
+SVGA_REG_FB_OFFSET and SVGA_REG_BYTES_PER_LINE may change after SVGA_REG_WIDTH
+or SVGA_REG_HEIGHT is set. Also the VGA registers must be written to after
+setting SVGA_REG_ENABLE to 0 to change the display to a VGA mode.
+
+Addendum on 11/29/2001
+---------------------
+
+Actually, after changing any of SVGA_REG_WIDTH, SVGA_REG_HEIGHT, and
+SVGA_REG_BITS_PER_PIXEL, all of the registers listed in the 'SetMode'
+initialization section above should be reread. Additionally, when changing
+modes, it can be convenient to set SVGA_REG_ENABLE to 0, change
+SVGA_REG_WIDTH, SVGA_REG_HEIGHT, and SVGA_REG_BITS_PER_PIXEL (if available),
+and then set SVGA_REG_ENABLE to 1 again.
+
+
+Capabilities
+------------
+
+The capabilities register (SVGA_REG_CAPABILITIES) is an array of bits that
+indicates the capabilities of the SVGA emulation. A driver should check
+SVGA_REG_CAPABILITIES every time it loads before relying on any feature that
+is only optionally available.
+
+Some of the capabilities determine which FIFO commands are available. This
+table shows which capability indicates support for which command.
+
+ FIFO Command Capability
+ ------------ ----------
+
+ SVGA_CMD_RECT_FILL SVGA_CAP_RECT_FILL
+ SVGA_CMD_RECT_COPY SVGA_CAP_RECT_COPY
+ SVGA_CMD_DEFINE_BITMAP SVGA_CAP_OFFSCREEN
+ SVGA_CMD_DEFINE_BITMAP_SCANLINE SVGA_CAP_OFFSCREEN
+ SVGA_CMD_DEFINE_PIXMAP SVGA_CAP_OFFSCREEN
+ SVGA_CMD_DEFINE_PIXMAP_SCANLINE SVGA_CAP_OFFSCREEN
+ SVGA_CMD_RECT_BITMAP_FILL SVGA_CAP_RECT_PAT_FILL
+ SVGA_CMD_RECT_PIXMAP_FILL SVGA_CAP_RECT_PAT_FILL
+ SVGA_CMD_RECT_BITMAP_COPY SVGA_CAP_RECT_PAT_FILL
+ SVGA_CMD_RECT_PIXMAP_COPY SVGA_CAP_RECT_PAT_FILL
+ SVGA_CMD_FREE_OBJECT SVGA_CAP_OFFSCREEN
+ SVGA_CMD_RECT_ROP_FILL SVGA_CAP_RECT_FILL +
+ SVGA_CAP_RASTER_OP
+ SVGA_CMD_RECT_ROP_COPY SVGA_CAP_RECT_COPY +
+ SVGA_CAP_RASTER_OP
+ SVGA_CMD_RECT_ROP_BITMAP_FILL SVGA_CAP_RECT_PAT_FILL +
+ SVGA_CAP_RASTER_OP
+ SVGA_CMD_RECT_ROP_PIXMAP_FILL SVGA_CAP_RECT_PAT_FILL +
+ SVGA_CAP_RASTER_OP
+ SVGA_CMD_RECT_ROP_BITMAP_COPY SVGA_CAP_RECT_PAT_FILL +
+ SVGA_CAP_RASTER_OP
+ SVGA_CMD_RECT_ROP_PIXMAP_COPY SVGA_CAP_RECT_PAT_FILL +
+ SVGA_CAP_RASTER_OP
+ SVGA_CMD_DEFINE_CURSOR SVGA_CAP_CURSOR
+ SVGA_CMD_DISPLAY_CURSOR SVGA_CAP_CURSOR
+ SVGA_CMD_MOVE_CURSOR SVGA_CAP_CURSOR
+ SVGA_CMD_DEFINE_ALPHA_CURSOR SVGA_CAP_ALPHA_CURSOR
+ SVGA_CMD_DRAW_GLYPH SVGA_CAP_GLYPH
+ SVGA_CMD_DRAW_GLYPH_CLIPPED SVGA_CAP_GLYPH_CLIPPING
+
+Note: SVGA_CMD_DISPLAY_CURSOR and SVGA_CMD_MOVE_CURSOR should not be used.
+Drivers wishing hardware cursor support should use cursor bypass (see below).
+
+Other capabilities indicate other functionality as described below:
+
+ SVGA_CAP_CURSOR_BYPASS
+ The hardware cursor can be drawn via SVGA Registers (without requiring
+ the FIFO be synchronized and will be drawn potentially before any
+ outstanding unprocessed FIFO commands).
+
+ Note: Without SVGA_CAP_CURSOR_BYPASS_2, cursors drawn this way still
+ appear in the guest's framebuffer and need to be turned off before any
+ save under / overlapping drawing and turned back on after. This can
+ cause very noticeable cursor flicker.
+
+ SVGA_CAP_CURSOR_BYPASS_2
+ Instead of turning the cursor off and back on around any overlapping
+ drawing, the driver can write SVGA_CURSOR_ON_REMOVE_FROM_FB and
+ SVGA_CURSOR_ON_RESTORE_TO_FB to SVGA_REG_CURSOR_ON. In almost all
+ cases these are NOPs and the cursor will be remain visible without
+ appearing in the guest framebuffer. In 'direct graphics' modes like
+ Linux host fullscreen local displays, however, the cursor will still
+ be drawn in the framebuffer, still flicker, and be drawn incorrectly
+ if a driver does not use SVGA_CURSOR_ON_REMOVE_FROM_FB / RESTORE_TO_FB.
+
+ SVGA_CAP_8BIT_EMULATION
+ SVGA_REG_BITS_PER_PIXEL is writable and can be set to either 8 or
+ SVGA_REG_HOST_BITS_PER_PIXEL. Otherwise the only SVGA modes available
+ inside a virtual machine must match the host's bits per pixel.
+
+ Note: Some versions which lack SVGA_CAP_8BIT_EMULATION also lack the
+ SVGA_REG_HOST_BITS_PER_PIXEL and a driver should assume
+ SVGA_REG_BITS_PER_PIXEL is both read-only and initialized to the only
+ available value if SVGA_CAP_8BIT_EMULATION is not set.
+
+ SVGA_CAP_OFFSCREEN_1
+ SVGA_CMD_RECT_FILL, SVGA_CMD_RECT_COPY, SVGA_CMD_RECT_ROP_FILL,
+ SVGA_CMD_RECT_ROP_COPY can operate with a source or destination (or
+ both) in offscreen memory.
+
+ Usable offscreen memory is a rectangle located below the last scanline
+ of the visible memory:
+ x1 = 0
+ y1 = (SVGA_REG_FB_SIZE + SVGA_REG_BYTES_PER_LINE - 1) /
+ SVGA_REG_BYTES_PER_LINE
+ x2 = SVGA_REG_BYTES_PER_LINE / SVGA_REG_DEPTH
+ y2 = SVGA_REG_VRAM_SIZE / SVGA_REG_BYTES_PER_LINE
+
+
+Cursor Handling
+---------------
+
+Starting with GSX Server Beta 3 (after 11/15/2000), hardware cursor support
+was added. Actually, both a hardware cursor via the FIFO (SVGA_CAP_CURSOR)
+and a hardware cursor via the SVGA registers (SVGA_CAP_CURSOR_BYPASS) were
+added. SVGA_CAP_CURSOR was never available without SVGA_CAP_CURSOR_BYPASS and
+the FIFO hardware cursor should never be used and may be removed without
+warning in the future.
+
+Cursor bypass is programmed using the two FIFO commands SVGA_CMD_DEFINE_CURSOR
+and SVGA_CMD_DEFINE_ALPHA_CURSOR in conjunction with the SVGA registers
+SVGA_REG_CURSOR_ID, SVGA_REG_CURSOR_X, SVGA_REG_CURSOR_Y, and
+SVGA_REG_CURSOR_ON.
+
+A driver defines an AND/XOR hardware cursor using SVGA_CMD_DEFINE_CURSOR to
+assign an ID and establish the AND and XOR masks with the hardware. A driver
+uses SVGA_CMD_DEFINE_ALPHA_CURSOR to define a 32 bit mask whose top 8 bits are
+used to blend the cursor image with the pixels it covers. Alpha cursor
+support is only available when SVGA_CAP_ALPHA_CURSOR is set.
+
+Once a cursor is defined, a driver can draw it to the screen at any time by
+writing the SVGA_REG_CURSOR_ID register with the ID used when the cursor was
+defined, writing SVGA_REG_CURSOR_X and SVGA_REG_CURSOR_Y with the location of
+the cursor, and SVGA_CURSOR_ON_SHOW to SVGA_REG_CURSOR_ON. The drawing occurs
+when SVGA_REG_CURSOR_ON is written.
+
+Writing SVGA_CURSOR_ON_HIDE to SVGA_REG_CURSOR_ON will turn the cursor off and
+make it vanish from the display and, if present, from the framebuffer.
+SVGA_CURSOR_ON_REMOVE_FROM_FB will ensure the cursor is not in the
+framebuffer, but will only turn it off if there's no other way to remove it.
+SVGA_CURSOR_ON_RESTORE_TO_FB is the complement to
+SVGA_CURSOR_ON_REMOVE_FROM_FB. Whenever possible, the device will not put the
+cursor in the framebuffer and Remove From / Restore To will be NOPs.
+
+Note: The cursor must be out of the frame buffer before the driver (or any
+agent in the virtual machine) touches an overlapping portion of the frame
+buffer, because it is actually drawn into the frame buffer memory in the
+case of direct graphics mode (e.g. full screen mode on Linux). The cursor
+does not have to be touched before issuing an accelerated command via the
+command FIFO, this case is handled by the SVGA device.
+
+Note: If SVGA_CAP_CURSOR_BYPASS2 is not present, the driver must use
+SVGA_CURSOR_ON_HIDE and SVGA_CURSOR_ON_HIDE to be certain the cursor is out of
+the framebuffer.
+
+
+Driver Version Numbers
+----------------------
+
+The SVGA drivers use the following convention for their version numbers:
+
+Version 10.0 - The first version that uses the FIFO
+Version 10.1 - The version that uses the hardware cursor emulation via the FIFO
+Version 10.2 - The version that uses the cursor that bypasses the FIFO
+Version 10.3 - The version that can also support the 0405 chipset
+Version 10.4 - The version that knows about SVGA_CAP_CURSOR_BYPASS2
+Version 10.5 - [Never released or well defined]
+Version 10.6 - The version that knows about SVGA_CAP_8BIT_EMULATION
+Version 10.7 - The version that knows about SVGA_CAP_ALPHA_CURSOR
+Version 10.8 - The version that knows about SVGA_CAP_GLYPH
+Version 10.9 - The version that knows about SVGA_CAP_OFFSCREEN_1
+
+Note that this is merely the convention used by SVGA drivers written and
+maintained by VMware, Inc. and describes the capabilities of the driver, not
+the virtual hardware. An SVGA driver can only use the intersection of the
+functionality it supports and the functionality available in the virtual SVGA
+hardware.
+
+
+Frequently Asked Questions
+--------------------------
+
+1. My driver doesn't display anything, what's going on?
+
+First check if you are issuing an SVGA_CMD_UPDATE after drawing to
+the screen. Another check you can do is to run your driver in full
+screen mode on a Linux host. In this case you are drawing directly
+on the frame buffer, so what you draw to the screen will be immediately
+visible. If nothing is visible in this case, then most likely your
+driver hasn't mapped the frame buffer correctly.
+
+A discrepancy between what you get in full screen mode and what you
+get in window mode indicates that you have a missing or incorrect
+update command.
+
+
+2. What's the difference between bitmaps and pixmaps?
+
+Pixmaps have the same depth as the screen, while bitmaps have depth one.
+When a bitmap is drawn, the command also takes two colors, foreground and
+background. The set bits in the bitmap are replaced with the foreground
+color, and the unset bits are replaced with the background color.
+
+Pixmaps, on the other hand, can be directly copied to the screen.
+
+
+3. What's the significance of the ROP in the commands SVGA_CMD_RECT_ROP_FILL,
+SVGA_CMD_RECT_ROP_BITMAP_COPY, etc. ?
+
+The ROP in the ...ROP... commands is a raster operation. It has the same
+significance (and encoding) as it does in X. The ROP value SVGA_ROP_COPY
+means the source is copied to the destination, which makes these commands the
+same as their non-ROP counterparts. The most commonly used raster operation
+other than copy is probably SVGA_ROP_XOR, which combines the source and
+destination using exclusive-or.
+
+
+4. Tell me more about bitmaps and pixmaps. For example, the macro
+SVGA_CMD_DEFINE_BITMAP has a field <scanlines>. What should this be
+set to? Likewise with SVGA_CMD_DEFINE_PIXMAP. And when should the
+SCANLINE macros be used?
+
+OK, I'll use pixmaps as an example. First you have to define the pixmap:
+
+#define SVGA_CMD_DEFINE_PIXMAP 6
+ /* FIFO layout:
+ Pixmap ID, Width, Height, Depth, <scanlines> */
+
+The ID is something you choose, which you subsequently use to refer to
+this pixmap. It must be an integer between 0 and SVGA_MAX_ID.
+
+The width and height and depth are the dimensions of the pixmap. For now,
+the depth of the pixmap has to match the depth of the screen.
+
+The scanlines are the pixels that make up the pixmap, arranged one row
+at a time. Each row is required to be 32-bit aligned. The macros
+SVGA_PIXMAP_SCANLINE_SIZE and SVGA_PIXMAP_SIZE give the size of a
+single scanline, and the size of the entire pixmap, respectively, in
+32-bit words.
+
+The second step is to use it:
+
+#define SVGA_CMD_RECT_PIXMAP_FILL 9
+ /* FIFO layout:
+ Pixmap ID, X, Y, Width, Height */
+
+The ID here is the one you chose when defining the pixmap. X, Y,
+Width, and Height define a rectangle on the screen that is to be filled
+with the pixmap. The pixmap is screen aligned, which means that the
+coordinates in the pixmap are defined by the screen coordinates modulo
+the pixmap dimensions.
+
+If you want a different alignment between the screen and the pixmap,
+then you can use this command, which allows the pixmap coordinates to
+be defined:
+
+#define SVGA_CMD_RECT_PIXMAP_COPY 11
+ /* FIFO layout:
+ Pixmap ID, Source X, Source Y, Dest X, Dest Y, Width,
+ Height */
+
+The Source X and Source Y are pixmap coordinates, and the Dest X and
+Dest Y are screen coordinates.
+
+
+5. OK, now it works briefly, then stops displaying anything. Also,
+my log file is filled with lines like:
+ Unknown Command 0xff in SVGA command FIFO
+What's happening?
+
+The most common problem at this point is that the FIFO gets out
+of sync. This can happen if the amount of data in the FIFO doesn't
+match what the VMware SVGA device expects. To track this down, try
+to isolate the particular command which causes the problem.
+
+Another way this can happen is if the wraparound in the FIFO isn't
+done correctly. Here is some example code for writing to the FIFO
+(mem is an array of 32-bit integers that points to the FIFO memory
+region):
+
+while (TRUE) {
+ fifo_min = mem[SVGA_FIFO_MIN] / 4;
+ fifo_max = mem[SVGA_FIFO_MAX] / 4;
+ fifo_next = mem[SVGA_FIFO_NEXT_CMD] / 4;
+ fifo_stop = mem[SVGA_FIFO_STOP] / 4;
+
+ tmp_next = fifo_next+1;
+ if (tmp_next == fifo_max)
+ tmp_next = fifo_min; // Wraparound
+
+ if (tmp_next == fifo_stop) {
+ sync_fifo(); // FIFO full
+ continue; // retry
+ }
+
+ mem[fifo_next] = item;
+ mem[SVGA_FIFO_NEXT_CMD] = tmp_next * 4;
+ break;
+}
+
+This isn't the most efficient code, but it should work. It's important
+to do the increment with wraparound before the FIFO full check, and to
+check FIFO full before updating the next command pointer.
+
+
+6. My driver tries to switch modes and either nothing happens or the
+display becomes completely garbled. What's going on?
+
+When you change modes, make very sure you reread all of the registers listed
+above under SetMode. Getting the pitch (SVGA_REG_BYTES_PER_LINE) incorrect
+will cause a heavily garbled display. Also, if you change
+SVGA_REG_BITS_PER_PIXEL, make certain that SVGA_CAP_8BIT_EMULATION is present
+in the SVGA_REG_CAPABILITIES register. Also, even with 8 bit emulation, the
+driver must still use either 8 bpp or SVGA_REG_HOST_BITS_PER_PIXEL bpp,
+nothing else.
+
+
+7. Why does my driver's hardware cursor work when my virtual machine is in
+window mode, but draw/erase incorrectly or in garbled locations in fullscreen
+mode?
+
+You need to make sure you use SVGA_CURSOR_ON_REMOVE_FROM_FB and
+SVGA_CURSOR_ON_RESTORE_TO_FB _every_ time your driver or the virtual machine
+touches a region of the framebuffer that overlaps the cursor. If you forget
+to remove it then it can show up when doing save-under operations or get mixed
+in with other drawing. If you forget to restore it then can disappear. You
+also need to make sure SVGA_CAP_CURSOR_BYPASS2 is available, or else you will
+have to use SVGA_CURSOR_ON_SHOW and SVGA_CURSOR_ON_HIDE (which will flicker,
+even in window mode), or else a software cursor. Newer version of the virtual
+SVGA hardware will never put the hardware cursor in the framebuffer while in
+window mode, so everything will appear to work correctly there.
+
+
+8. Why do my accelerated glyphs look funny? OR Why does the fifo complain
+about invalid commands when I draw accelerated glyphs?
+
+The bitmap data passed to SVGA_CMD_DRAW_GLYPH_* must not have any per-scanline
+alignment. If there are any remaining bits left in the last byte of a scanline,
+the first bits of the next scanline should use them.
+
+The bitmap data as a whole must be 4 byte aligned.
+
+$XFree86: xc/programs/Xserver/hw/xfree86/drivers/vmware/README,v 1.5 2002/10/16 22:12:53 alanh Exp $
diff --git a/man/vmware.man b/man/vmware.man
new file mode 100644
index 0000000..e2d707f
--- /dev/null
+++ b/man/vmware.man
@@ -0,0 +1,37 @@
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vmware/vmware.man,v 1.2 2001/04/06 17:44:58 dawes Exp $
+.\" shorthand for double quote that works everywhere.
+.ds q \N'34'
+.TH VMWARE __drivermansuffix__ __vendorversion__
+.SH NAME
+vmware \- VMware SVGA video driver
+.SH SYNOPSIS
+.nf
+.B "Section \*qDevice\*q"
+.BI " Identifier \*q" devname \*q
+.B " Driver \*qvmware\*q"
+\ \ ...
+.B EndSection
+.fi
+.SH DESCRIPTION
+.B vmware
+is an XFree86 driver for VMware virtual video cards.
+.SH CONFIGURATION DETAILS
+Please refer to XF86Config(__filemansuffix__) for general configuration
+details. This section only covers configuration details specific to this
+driver.
+.PP
+The driver auto-detects the version of any virtual VMware SVGA adapter.
+.PP
+The following driver
+.B Options
+are supported:
+.TP
+.BI "Option \*qHWCursor\*q \*q" boolean \*q
+Enable or disable the HW cursor. Default: off.
+.TP
+.BI "Option \*qNoAccel\*q \*q" boolean \*q
+Disable or enable acceleration. Default: acceleration is enabled.
+.SH "SEE ALSO"
+XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(__miscmansuffix__)
+.SH AUTHORS
+Copyright (c) 1999-2001 VMware, Inc.
diff --git a/src/bits2pixels.c b/src/bits2pixels.c
new file mode 100644
index 0000000..416a1a7
--- /dev/null
+++ b/src/bits2pixels.c
@@ -0,0 +1,1415 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vmware/bits2pixels.c,v 1.2 2002/12/11 17:07:58 dawes Exp $ */
+/* **********************************************************
+ * Copyright (C) 1999-2001 VMware, Inc.
+ * All Rights Reserved
+ * **********************************************************/
+#ifdef VMX86_DEVEL
+char rcsId_bits2pixels[] = "Id: bits2pixels.c,v 1.6 2001/01/26 23:32:15 yoel Exp $";
+#else
+#define FILECODE "F(814)"
+#endif
+
+/*
+ * bits2pixels.c --
+ *
+ * Emulation routines to convert bitmaps to pixmaps
+ */
+
+#include "vm_basic_types.h"
+#include "bits2pixels.h"
+
+
+/*
+ * Local functions
+ */
+
+static void RasterBitsToPixels8(uint8 *bits, uint32 bits_increment,
+ uint8 *pix, uint32 pix_increment,
+ uint32 width, uint32 height, uint32 fg, uint32 bg);
+
+static void RasterBitsToPixels16(uint8 *bits, uint32 bits_increment,
+ uint8 *pix, uint32 pix_increment,
+ uint32 width, uint32 height, uint32 fg, uint32 bg);
+
+static void RasterBitsToPixels24(uint8 *bits, uint32 bits_increment,
+ uint8 *pix, uint32 pix_increment,
+ uint32 width, uint32 height, uint32 fg, uint32 bg);
+
+static void RasterBitsToPixels32(uint8 *bits, uint32 bits_increment,
+ uint8 *pix, uint32 pix_increment,
+ uint32 width, uint32 height, uint32 fg, uint32 bg);
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * vmwareRaster_BitsToPixels --
+ *
+ * Convert a bitmap to a pixmap, converting 1 bits to the foreground
+ * color (fg) and 0 bits to the background color (bg).
+ *
+ * Results:
+ * Pixmap filled with pixels
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+vmwareRaster_BitsToPixels(uint8 *bits, uint32 bits_increment,
+ uint8 *pix, uint32 pix_increment, int bytes_per_pixel,
+ uint32 width, uint32 height, uint32 fg, uint32 bg)
+{
+ switch (bytes_per_pixel) {
+ case 1:
+ RasterBitsToPixels8(bits, bits_increment, pix, pix_increment,
+ width, height, fg, bg);
+ break;
+
+ case 2:
+ RasterBitsToPixels16(bits, bits_increment, pix, pix_increment,
+ width, height, fg, bg);
+ break;
+
+ case 3:
+ RasterBitsToPixels24(bits, bits_increment, pix, pix_increment,
+ width, height, fg, bg);
+ break;
+
+ case 4:
+ RasterBitsToPixels32(bits, bits_increment, pix, pix_increment,
+ width, height, fg, bg);
+ break;
+ }
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * RasterBitsToPixels8 --
+ *
+ * Convert a bitmap to a pixmap, converting 1 bits to the foreground
+ * color (fg) and 0 bits to the background color (bg), for an 8-bit
+ * pixmap
+ *
+ * Results:
+ * Pixmap filled with pixels
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+RasterBitsToPixels8(uint8 *bits, uint32 bits_increment,
+ uint8 *pix, uint32 pix_increment,
+ uint32 width, uint32 height, uint32 fg, uint32 bg)
+{
+ uint8 *lpix, *lbits;
+ int i, j;
+ uint32 expbits = 0; /* Bits to be expanded */
+
+ for (i=0; i<height; i++) {
+ lpix = pix;
+ lbits = bits;
+ for (j = width ; j > 0; j -= 4) {
+ expbits = (*lbits >> 4) & 0x0f;
+
+ if (j < 4)
+ break;
+
+ switch (expbits) {
+ case 0:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 1:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 2:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 3:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 4:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 5:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 6:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 7:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 8:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 9:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 10:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 11:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 12:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 13:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 14:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 15:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ }
+
+ expbits = *lbits & 0x0f;
+
+ j -= 4;
+ if (j < 4) {
+ break;
+ }
+
+ switch (expbits) {
+ case 0:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 1:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 2:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 3:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 4:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 5:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 6:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 7:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 8:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 9:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 10:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 11:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 12:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 13:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 14:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 15:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ }
+ lbits++;
+ }
+
+ if (j > 0) {
+ *lpix++ = (expbits & 0x08) ? fg : bg;
+ j--;
+ if (j > 0) {
+ *lpix++ = (expbits & 0x04) ? fg : bg;
+ j--;
+ if (j > 0) {
+ *lpix++ = (expbits & 0x02) ? fg : bg;
+ j--;
+ }
+ }
+ }
+
+ pix += pix_increment;
+ bits += bits_increment;
+ }
+ return;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * RasterBitsToPixels16 --
+ *
+ * Convert a bitmap to a pixmap, converting 1 bits to the foreground
+ * color (fg) and 0 bits to the background color (bg), for a 16-bit
+ * pixmap
+ *
+ * Results:
+ * Pixmap filled with pixels
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+RasterBitsToPixels16(uint8 *bits, uint32 bits_increment,
+ uint8 *pix, uint32 pix_increment,
+ uint32 width, uint32 height, uint32 fg, uint32 bg)
+{
+ uint16 *lpix;
+ uint8 *lbits;
+ int i, j;
+ uint32 expbits = 0; /* Bits to be expanded */
+
+ for (i=0; i<height; i++) {
+ lpix = (uint16 *)pix;
+ lbits = bits;
+ for (j = width; j > 0; j -= 4) {
+ expbits = (*lbits >> 4) & 0x0f;
+
+ if (j < 4)
+ break;
+
+ switch (expbits) {
+ case 0:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 1:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 2:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 3:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 4:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 5:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 6:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 7:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 8:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 9:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 10:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 11:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 12:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 13:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 14:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 15:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ }
+
+ expbits = *lbits & 0x0f;
+
+ j -= 4;
+ if (j < 4) {
+ break;
+ }
+
+ switch (expbits) {
+ case 0:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 1:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 2:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 3:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 4:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 5:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 6:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 7:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 8:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 9:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 10:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 11:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 12:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 13:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 14:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 15:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ }
+ lbits++;
+ }
+
+ if (j > 0) {
+ *lpix++ = (expbits & 0x08) ? fg : bg;
+ j--;
+ if (j > 0) {
+ *lpix++ = (expbits & 0x04) ? fg : bg;
+ j--;
+ if (j > 0) {
+ *lpix++ = (expbits & 0x02) ? fg : bg;
+ j--;
+ }
+ }
+ }
+
+ pix += pix_increment;
+ bits += bits_increment;
+ }
+ return;
+}
+
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * RasterBitsToPixels24 --
+ *
+ * Convert a bitmap to a pixmap, converting 1 bits to the foreground
+ * color (fg) and 0 bits to the background color (bg), for a 24-bit
+ * pixmap
+ *
+ * Results:
+ * Pixmap filled with pixels
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+RasterBitsToPixels24(uint8 *bits, uint32 bits_increment,
+ uint8 *pix, uint32 pix_increment,
+ uint32 width, uint32 height, uint32 fg, uint32 bg)
+{
+ uint8 *lpix, *lbits;
+ uint32 fgColor1, fgColor2, fgColor3;
+ uint32 bgColor1, bgColor2, bgColor3;
+
+ int i, j;
+ uint32 expbits = 0; /* Bits to be expanded */
+
+ fgColor1 = fg & 0x000000ff;
+ fgColor2 = (fg >> 8) & 0x000000ff;
+ fgColor3 = (fg >> 16) & 0x000000ff;
+
+ bgColor1 = bg & 0x000000ff;
+ bgColor2 = (bg >> 8) & 0x000000ff;
+ bgColor3 = (bg >> 16) & 0x000000ff;
+
+ for (i=0; i<height; i++) {
+ lpix = pix;
+ lbits = bits;
+ for (j = width; j > 0; j -= 4) {
+ expbits = (*lbits >> 4) & 0x0f;
+
+ if (j < 4)
+ break;
+
+ switch (expbits) {
+ case 0:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 1:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ case 2:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 3:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ case 4:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 5:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ case 6:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 7:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ case 8:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 9:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ case 10:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 11:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ case 12:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 13:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ case 14:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 15:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ }
+
+ expbits = *lbits & 0x0f;
+
+ j -= 4;
+ if (j < 4) {
+ break;
+ }
+
+ switch (expbits) {
+ case 0:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 1:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ case 2:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 3:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ case 4:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 5:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ case 6:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 7:
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ case 8:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 9:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ case 10:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 11:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ case 12:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 13:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ case 14:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = bgColor1;
+ *lpix++ = bgColor2;
+ *lpix++ = bgColor3;
+ break;
+ case 15:
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ *lpix++ = fgColor1;
+ *lpix++ = fgColor2;
+ *lpix++ = fgColor3;
+ break;
+ }
+ lbits++;
+ }
+
+ if (j > 0) {
+ *lpix++ = (expbits & 0x08) ? fgColor1 : bgColor1;
+ *lpix++ = (expbits & 0x08) ? fgColor2 : bgColor2;
+ *lpix++ = (expbits & 0x08) ? fgColor3 : bgColor3;
+ j--;
+ if (j > 0) {
+ *lpix++ = (expbits & 0x04) ? fgColor1 : bgColor1;
+ *lpix++ = (expbits & 0x04) ? fgColor2 : bgColor2;
+ *lpix++ = (expbits & 0x04) ? fgColor3 : bgColor3;
+ j--;
+ if (j > 0) {
+ *lpix++ = (expbits & 0x02) ? fgColor1 : bgColor1;
+ *lpix++ = (expbits & 0x02) ? fgColor2 : bgColor2;
+ *lpix++ = (expbits & 0x02) ? fgColor3 : bgColor3;
+ j--;
+ }
+ }
+ }
+
+ pix += pix_increment;
+ bits += bits_increment;
+ }
+ return;
+}
+
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * RasterBitsToPixels32 --
+ *
+ * Convert a bitmap to a pixmap, converting 1 bits to the foreground
+ * color (fg) and 0 bits to the background color (bg), for a 32-bit
+ * pixmap
+ *
+ * Results:
+ * Pixmap filled with pixels
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+RasterBitsToPixels32(uint8 *bits, uint32 bits_increment,
+ uint8 *pix, uint32 pix_increment,
+ uint32 width, uint32 height, uint32 fg, uint32 bg)
+{
+ uint32 *lpix;
+ uint8 *lbits;
+ int i, j;
+ uint32 expbits = 0; /* Bits to be expanded */
+
+ for (i=0; i<height; i++) {
+ lpix = (uint32 *)pix;
+ lbits = bits;
+ for (j = width; j > 0; j -= 4) {
+ expbits = (*lbits >> 4) & 0x0f;
+
+ if (j < 4)
+ break;
+
+ switch (expbits) {
+ case 0:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 1:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 2:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 3:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 4:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 5:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 6:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 7:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 8:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 9:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 10:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 11:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 12:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 13:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 14:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 15:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ }
+
+ expbits = *lbits & 0x0f;
+
+ j -= 4;
+ if (j < 4) {
+ break;
+ }
+
+ switch (expbits) {
+ case 0:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 1:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 2:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 3:
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 4:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 5:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 6:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 7:
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 8:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 9:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 10:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 11:
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ case 12:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = bg;
+ break;
+ case 13:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ *lpix++ = fg;
+ break;
+ case 14:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = bg;
+ break;
+ case 15:
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ *lpix++ = fg;
+ break;
+ }
+ lbits++;
+ }
+
+ if (j > 0) {
+ *lpix++ = (expbits & 0x08) ? fg : bg;
+ j--;
+ if (j > 0) {
+ *lpix++ = (expbits & 0x04) ? fg : bg;
+ j--;
+ if (j > 0) {
+ *lpix++ = (expbits & 0x02) ? fg : bg;
+ j--;
+ }
+ }
+ }
+
+ pix += pix_increment;
+ bits += bits_increment;
+ }
+ return;
+}
diff --git a/src/bits2pixels.h b/src/bits2pixels.h
new file mode 100644
index 0000000..585f6fc
--- /dev/null
+++ b/src/bits2pixels.h
@@ -0,0 +1,25 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vmware/bits2pixels.h,v 1.2 2002/12/11 17:07:58 dawes Exp $ */
+/* **********************************************************
+ * Copyright (C) 1999-2001 VMware, Inc.
+ * All Rights Reserved
+ * Id: bits2pixels.h,v 1.4 2001/01/26 23:32:15 yoel Exp $
+ * **********************************************************/
+
+/*
+ * bits2pixels.h --
+ *
+ * Drawing emulation routines
+ */
+
+#ifndef _BITS2PIXELS_H_
+#define _BITS2PIXELS_H_
+
+#define INCLUDE_ALLOW_USERLEVEL
+#include "includeCheck.h"
+
+void
+vmwareRaster_BitsToPixels(uint8 *bits, uint32 bits_increment,
+ uint8 *pix, uint32 pix_increment, int bytes_per_pixel,
+ uint32 width, uint32 height, uint32 fg, uint32 bg);
+
+#endif /* _BITS4PIXELS_H_ */
diff --git a/src/guest_os.h b/src/guest_os.h
new file mode 100644
index 0000000..dedebe0
--- /dev/null
+++ b/src/guest_os.h
@@ -0,0 +1,30 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vmware/guest_os.h,v 1.1 2001/04/05 19:29:44 dawes Exp $ */
+/* *********************************************************
+ * Copyright (C) 1999-2001 VMware, Inc.
+ * All Rights Reserved
+ * Id: guest_os.h,v 1.5 2001/01/26 23:32:15 yoel Exp $
+ * **********************************************************/
+
+#ifndef _GUEST_OS_H_
+#define _GUEST_OS_H_
+
+#define INCLUDE_ALLOW_USERLEVEL
+#include "includeCheck.h"
+
+#define GUEST_OS_BASE 0x5000
+
+#define GUEST_OS_DOS (GUEST_OS_BASE+1)
+#define GUEST_OS_WIN31 (GUEST_OS_BASE+2)
+#define GUEST_OS_WINDOWS95 (GUEST_OS_BASE+3)
+#define GUEST_OS_WINDOWS98 (GUEST_OS_BASE+4)
+#define GUEST_OS_WINDOWSME (GUEST_OS_BASE+5)
+#define GUEST_OS_NT (GUEST_OS_BASE+6)
+#define GUEST_OS_WIN2000 (GUEST_OS_BASE+7)
+#define GUEST_OS_LINUX (GUEST_OS_BASE+8)
+#define GUEST_OS_OS2 (GUEST_OS_BASE+9)
+#define GUEST_OS_OTHER (GUEST_OS_BASE+10)
+#define GUEST_OS_FREEBSD (GUEST_OS_BASE+11)
+#define GUEST_OS_WHISTLER (GUEST_OS_BASE+12)
+
+
+#endif
diff --git a/src/includeCheck.h b/src/includeCheck.h
new file mode 100644
index 0000000..8df4666
--- /dev/null
+++ b/src/includeCheck.h
@@ -0,0 +1,3 @@
+/* This space intentionally left blank. */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vmware/includeCheck.h,v 1.3 2002/10/16 22:12:53 alanh Exp $ */
+
diff --git a/src/offscreen_manager.c b/src/offscreen_manager.c
new file mode 100644
index 0000000..68c8632
--- /dev/null
+++ b/src/offscreen_manager.c
@@ -0,0 +1,132 @@
+/* **********************************************************
+ * Copyright (C) 1998-2002 VMware, Inc.
+ * All Rights Reserved
+ * **********************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vmware/offscreen_manager.c,v 1.2 2002/12/11 17:07:58 dawes Exp $ */
+
+#include "vmware.h"
+
+struct _Heap {
+ CARD8* ptr;
+ CARD32 size;
+ CARD32 maxSlots;
+ CARD32 startOffset;
+ SVGASurface* frontBuffer;
+ SVGASurface* slotsStart;
+ Bool clear;
+};
+
+static SVGASurface* FillInSurface(Heap* heap, SVGASurface* surface,
+ CARD32 width, CARD32 height,
+ CARD32 bpp, CARD32 pitch, CARD32 size,
+ CARD32 sizeUsed);
+
+Heap*
+vmwareHeap_Create(CARD8* ptr, CARD32 size, CARD32 maxSlots, CARD32 startOffset,
+ CARD32 sWidth, CARD32 sHeight, CARD32 sBPP, CARD32 sPitch,
+ CARD32 sFbOffset)
+{
+ Heap* newHeap = malloc(sizeof (Heap));
+
+ newHeap->ptr = ptr;
+ newHeap->size = size - sizeof(SVGASurface); /* leave room for frontbuffer */
+ newHeap->maxSlots = maxSlots;
+ newHeap->startOffset = startOffset;
+
+ newHeap->frontBuffer = FillInSurface(newHeap,
+ (SVGASurface*)(ptr + newHeap->size),
+ sWidth, sHeight, sBPP, sPitch,
+ sHeight * sPitch, 0);
+ newHeap->frontBuffer->dataOffset = sFbOffset;
+ newHeap->frontBuffer->numQueued = newHeap->frontBuffer->numDequeued = 0;
+
+ newHeap->slotsStart = (SVGASurface*)(newHeap->ptr + newHeap->size) -
+ newHeap->maxSlots;
+ newHeap->clear = FALSE;
+ vmwareHeap_Clear(newHeap);
+
+ return newHeap;
+}
+
+void
+vmwareHeap_Destroy(Heap* heap)
+{
+ free(heap);
+}
+
+void
+vmwareHeap_Clear(Heap* heap)
+{
+ if (!heap->clear) {
+ memset(heap->slotsStart, 0, heap->maxSlots * sizeof (SVGASurface));
+ heap->clear = TRUE;
+ }
+}
+
+static SVGASurface*
+FillInSurface(Heap* heap, SVGASurface* surface, CARD32 width, CARD32 height,
+ CARD32 bpp, CARD32 pitch, CARD32 size, CARD32 offset)
+{
+ surface->size = sizeof (SVGASurface);
+ surface->version = SVGA_SURFACE_VERSION_1;
+ surface->bpp = bpp;
+ surface->width = width;
+ surface->height = height;
+ surface->pitch = pitch;
+ if (surface->userData == 0) {
+ /*
+ * We allocate exactly what we need the first time we use a slot, so
+ * all reuses of this slot will be equal or smaller.
+ */
+ surface->userData = size;
+ }
+ surface->dataOffset = offset + heap->startOffset;
+
+ return surface;
+}
+
+SVGASurface*
+vmwareHeap_GetFrontBuffer(Heap* heap)
+{
+ return heap->frontBuffer;
+}
+
+SVGASurface*
+vmwareHeap_AllocSurface(Heap* heap, CARD32 width, CARD32 height,
+ CARD32 pitch, CARD32 bpp)
+{
+ CARD32 size = pitch * height;
+ CARD32 sizeUsed = 0;
+ SVGASurface* surface = heap->slotsStart;
+ int i;
+
+ /*
+ * NOTE: we use SVGASurface::userData to store the largest this slot's
+ * size has ever been, since we don't ever compact anything.
+ */
+
+ /* find a free slot that's big enough */
+ for (i = 0; i < heap->maxSlots; i++) {
+ if (surface[i].userData == 0) { /* this surface has never been used */
+ if ((CARD8*)heap->slotsStart - heap->ptr - sizeUsed < size) {
+ /* no room left for data*/
+ return NULL;
+ }
+
+ heap->clear = FALSE;
+ return FillInSurface(heap, surface + i, width, height, bpp,
+ pitch, size, sizeUsed);
+ }
+
+ if (surface[i].numQueued == surface[i].numDequeued &&
+ surface[i].userData >= size) { /* free and big enough, sweet! */
+ heap->clear = FALSE;
+ return FillInSurface(heap, surface + i, width, height, bpp,
+ pitch, size, sizeUsed);
+ }
+
+ sizeUsed += surface[i].userData;
+ }
+
+ return NULL;
+}
diff --git a/src/offscreen_manager.h b/src/offscreen_manager.h
new file mode 100644
index 0000000..e948da9
--- /dev/null
+++ b/src/offscreen_manager.h
@@ -0,0 +1,25 @@
+/* **********************************************************
+ * Copyright (C) 1998-2002 VMware, Inc.
+ * All Rights Reserved
+ * **********************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vmware/offscreen_manager.h,v 1.2 2002/12/11 17:07:58 dawes Exp $ */
+
+#ifndef OFFSCREEN_MANAGER_H
+#define OFFSCREEN_MANAGER_H
+
+struct _Heap;
+typedef struct _Heap Heap;
+
+extern Heap* vmwareHeap_Create(CARD8* ptr, CARD32 size, CARD32 maxSlots,
+ CARD32 startOffset, CARD32 sWidth, CARD32 sHeight,
+ CARD32 sBPP, CARD32 sPitch, CARD32 sFbOffset);
+extern void vmwareHeap_Destroy(Heap* heap);
+
+extern void vmwareHeap_Clear(Heap* heap);
+
+extern SVGASurface* vmwareHeap_GetFrontBuffer(Heap* heap);
+
+extern SVGASurface* vmwareHeap_AllocSurface(Heap* heap, CARD32 width, CARD32 height,
+ CARD32 pitch, CARD32 bpp);
+
+#endif
diff --git a/src/svga_limits.h b/src/svga_limits.h
new file mode 100644
index 0000000..016c2b8
--- /dev/null
+++ b/src/svga_limits.h
@@ -0,0 +1,57 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vmware/svga_limits.h,v 1.2 2002/10/16 22:12:53 alanh Exp $ */
+/* **********************************************************
+ * Copyright (C) 1998-2001 VMware, Inc.
+ * All Rights Reserved
+ * $Id$
+ * **********************************************************/
+
+/*
+ * svga_limits.h --
+ *
+ * SVGA limits
+ */
+
+#ifndef _SVGA_LIMITS_H_
+#define _SVGA_LIMITS_H_
+
+#define INCLUDE_ALLOW_USERLEVEL
+#define INCLUDE_ALLOW_MONITOR
+#include "includeCheck.h"
+
+/*
+ * Location and size of SVGA frame buffer and the FIFO.
+ */
+#define SVGA_VRAM_SIZE (16*1024*1024)
+#define SVGA_MEM_SIZE (256*1024)
+
+/*
+ * SVGA_FB_START is the default starting address of the SVGA frame
+ * buffer in the guest's physical address space.
+ * SVGA_FB_START_BIGMEM is the starting address of the SVGA frame
+ * buffer for VMs that have a large amount of physical memory.
+ *
+ * The address of SVGA_FB_START is set to 2GB - (SVGA_FB_MAX_SIZE + SVGA_MEM_SIZE),
+ * thus the SVGA frame buffer sits at [SVGA_FB_START .. 2GB-1] in the
+ * physical address space. Our older SVGA drivers for NT treat the
+ * address of the frame buffer as a signed integer. For backwards
+ * compatibility, we keep the default location of the frame buffer
+ * at under 2GB in the address space. This restricts VMs to have "only"
+ * up to ~2031MB (i.e., up to SVGA_FB_START) of physical memory.
+ *
+ * For VMs that want more memory than the ~2031MB, we place the SVGA
+ * frame buffer at SVGA_FB_START_BIGMEM. This allows VMs to have up
+ * to 3584MB, at least as far as the SVGA frame buffer is concerned
+ * (note that there may be other issues that limit the VM memory
+ * size). PCI devices use high memory addresses, so we have to put
+ * SVGA_FB_START_BIGMEM low enough so that it doesn't overlap with any
+ * of these devices. Placing SVGA_FB_START_BIGMEM at 0xE0000000
+ * should leave plenty of room for the PCI devices.
+ *
+ * NOTE: All of that is only true for the 0710 chipset. As of the 0405
+ * chipset, the framebuffer start is determined solely based on the value
+ * the guest BIOS or OS programs into the PCI base address registers.
+ */
+#define SVGA_FB_LEGACY_START 0x7EFC0000
+#define SVGA_FB_LEGACY_START_BIGMEM 0xE0000000
+
+#endif
diff --git a/src/svga_reg.h b/src/svga_reg.h
new file mode 100644
index 0000000..2d6800d
--- /dev/null
+++ b/src/svga_reg.h
@@ -0,0 +1,456 @@
+/* **********************************************************
+ * Copyright (C) 1998-2001 VMware, Inc.
+ * All Rights Reserved
+ * $Id$
+ * **********************************************************/
+
+/*
+ * svga_reg.h --
+ *
+ * SVGA hardware definitions
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vmware/svga_reg.h,v 1.8 2003/02/04 01:39:53 dawes Exp $ */
+
+#ifndef _SVGA_REG_H_
+#define _SVGA_REG_H_
+
+#define INCLUDE_ALLOW_USERLEVEL
+#define INCLUDE_ALLOW_MONITOR
+#include "includeCheck.h"
+
+#include "svga_limits.h"
+
+/*
+ * Memory and port addresses and fundamental constants
+ */
+
+/*
+ * Note-- MAX_WIDTH and MAX_HEIGHT are largely ignored by the code. This
+ * isn't such a bad thing for forward compatibility. --Jeremy.
+ */
+#define SVGA_MAX_WIDTH 2360
+#define SVGA_MAX_HEIGHT 1770
+#define SVGA_MAX_BITS_PER_PIXEL 32
+
+#define PAGE_SHIFT 12
+#define SVGA_FB_MAX_SIZE \
+ ((((SVGA_MAX_WIDTH * SVGA_MAX_HEIGHT * \
+ SVGA_MAX_BITS_PER_PIXEL / 8) >> PAGE_SHIFT) + 1) << PAGE_SHIFT)
+
+#if SVGA_FB_MAX_SIZE > SVGA_VRAM_SIZE
+#error "Bad SVGA maximum sizes"
+#endif
+#define SVGA_MAX_PSEUDOCOLOR_DEPTH 8
+#define SVGA_MAX_PSEUDOCOLORS (1 << SVGA_MAX_PSEUDOCOLOR_DEPTH)
+
+#define SVGA_MAGIC 0x900000
+#define SVGA_MAKE_ID(ver) (SVGA_MAGIC << 8 | (ver))
+
+/* Version 2 let the address of the frame buffer be unsigned on Win32 */
+#define SVGA_VERSION_2 2
+#define SVGA_ID_2 SVGA_MAKE_ID(SVGA_VERSION_2)
+
+/* Version 1 has new registers starting with SVGA_REG_CAPABILITIES so
+ PALETTE_BASE has moved */
+#define SVGA_VERSION_1 1
+#define SVGA_ID_1 SVGA_MAKE_ID(SVGA_VERSION_1)
+
+/* Version 0 is the initial version */
+#define SVGA_VERSION_0 0
+#define SVGA_ID_0 SVGA_MAKE_ID(SVGA_VERSION_0)
+
+/* Invalid SVGA_ID_ */
+#define SVGA_ID_INVALID 0xFFFFFFFF
+
+/* More backwards compatibility, old location of color map: */
+#define SVGA_OLD_PALETTE_BASE 17
+
+/* Base and Offset gets us headed the right way for PCI Base Addr Registers */
+#define SVGA_LEGACY_BASE_PORT 0x4560
+#define SVGA_INDEX_PORT 0x0
+#define SVGA_VALUE_PORT 0x1
+#define SVGA_BIOS_PORT 0x2
+#define SVGA_NUM_PORTS 0x3
+
+/* This port is deprecated, but retained because of old drivers. */
+#define SVGA_LEGACY_ACCEL_PORT 0x3
+
+/* Legal values for the SVGA_REG_CURSOR_ON register in cursor bypass mode */
+#define SVGA_CURSOR_ON_HIDE 0x0 /* Must be 0 to maintain backward compatibility */
+#define SVGA_CURSOR_ON_SHOW 0x1 /* Must be 1 to maintain backward compatibility */
+#define SVGA_CURSOR_ON_REMOVE_FROM_FB 0x2 /* Remove the cursor from the framebuffer because we need to see what's under it */
+#define SVGA_CURSOR_ON_RESTORE_TO_FB 0x3 /* Put the cursor back in the framebuffer so the user can see it */
+
+/*
+ * Registers
+ */
+
+enum {
+ SVGA_REG_ID = 0,
+ SVGA_REG_ENABLE = 1,
+ SVGA_REG_WIDTH = 2,
+ SVGA_REG_HEIGHT = 3,
+ SVGA_REG_MAX_WIDTH = 4,
+ SVGA_REG_MAX_HEIGHT = 5,
+ SVGA_REG_DEPTH = 6,
+ SVGA_REG_BITS_PER_PIXEL = 7, /* Current bpp in the guest */
+ SVGA_REG_PSEUDOCOLOR = 8,
+ SVGA_REG_RED_MASK = 9,
+ SVGA_REG_GREEN_MASK = 10,
+ SVGA_REG_BLUE_MASK = 11,
+ SVGA_REG_BYTES_PER_LINE = 12,
+ SVGA_REG_FB_START = 13,
+ SVGA_REG_FB_OFFSET = 14,
+ SVGA_REG_VRAM_SIZE = 15,
+ SVGA_REG_FB_SIZE = 16,
+
+ SVGA_REG_CAPABILITIES = 17,
+ SVGA_REG_MEM_START = 18, /* Memory for command FIFO and bitmaps */
+ SVGA_REG_MEM_SIZE = 19,
+ SVGA_REG_CONFIG_DONE = 20, /* Set when memory area configured */
+ SVGA_REG_SYNC = 21, /* Write to force synchronization */
+ SVGA_REG_BUSY = 22, /* Read to check if sync is done */
+ SVGA_REG_GUEST_ID = 23, /* Set guest OS identifier */
+ SVGA_REG_CURSOR_ID = 24, /* ID of cursor */
+ SVGA_REG_CURSOR_X = 25, /* Set cursor X position */
+ SVGA_REG_CURSOR_Y = 26, /* Set cursor Y position */
+ SVGA_REG_CURSOR_ON = 27, /* Turn cursor on/off */
+ SVGA_REG_HOST_BITS_PER_PIXEL = 28, /* Current bpp in the host */
+
+ SVGA_REG_TOP = 30, /* Must be 1 greater than the last register */
+
+ SVGA_PALETTE_BASE = 1024 /* Base of SVGA color map */
+};
+
+
+/*
+ * Capabilities
+ */
+
+#define SVGA_CAP_NONE 0x0000
+#define SVGA_CAP_RECT_FILL 0x0001
+#define SVGA_CAP_RECT_COPY 0x0002
+#define SVGA_CAP_RECT_PAT_FILL 0x0004
+#define SVGA_CAP_LEGACY_OFFSCREEN 0x0008
+#define SVGA_CAP_RASTER_OP 0x0010
+#define SVGA_CAP_CURSOR 0x0020
+#define SVGA_CAP_CURSOR_BYPASS 0x0040
+#define SVGA_CAP_CURSOR_BYPASS_2 0x0080
+#define SVGA_CAP_8BIT_EMULATION 0x0100
+#define SVGA_CAP_ALPHA_CURSOR 0x0200
+#define SVGA_CAP_GLYPH 0x0400
+#define SVGA_CAP_GLYPH_CLIPPING 0x0800
+#define SVGA_CAP_OFFSCREEN_1 0x1000
+#define SVGA_CAP_ALPHA_BLEND 0x2000
+
+
+/*
+ * Raster op codes (same encoding as X) used by FIFO drivers.
+ */
+
+#define SVGA_ROP_CLEAR 0x00 /* 0 */
+#define SVGA_ROP_AND 0x01 /* src AND dst */
+#define SVGA_ROP_AND_REVERSE 0x02 /* src AND NOT dst */
+#define SVGA_ROP_COPY 0x03 /* src */
+#define SVGA_ROP_AND_INVERTED 0x04 /* NOT src AND dst */
+#define SVGA_ROP_NOOP 0x05 /* dst */
+#define SVGA_ROP_XOR 0x06 /* src XOR dst */
+#define SVGA_ROP_OR 0x07 /* src OR dst */
+#define SVGA_ROP_NOR 0x08 /* NOT src AND NOT dst */
+#define SVGA_ROP_EQUIV 0x09 /* NOT src XOR dst */
+#define SVGA_ROP_INVERT 0x0a /* NOT dst */
+#define SVGA_ROP_OR_REVERSE 0x0b /* src OR NOT dst */
+#define SVGA_ROP_COPY_INVERTED 0x0c /* NOT src */
+#define SVGA_ROP_OR_INVERTED 0x0d /* NOT src OR dst */
+#define SVGA_ROP_NAND 0x0e /* NOT src OR NOT dst */
+#define SVGA_ROP_SET 0x0f /* 1 */
+#define SVGA_ROP_UNSUPPORTED 0x10
+
+#define SVGA_NUM_SUPPORTED_ROPS 16
+#define SVGA_ROP_ALL (MASK(SVGA_NUM_SUPPORTED_ROPS))
+#define SVGA_IS_VALID_ROP(rop) (rop >= 0 && rop < SVGA_NUM_SUPPORTED_ROPS)
+
+/*
+ * Ops
+ * For each pixel, the four channels of the image are computed with:
+ *
+ * C = Ca * Fa + Cb * Fb
+ *
+ * where C, Ca, Cb are the values of the respective channels and Fa
+ * and Fb come from the following table:
+ *
+ * BlendOp Fa Fb
+ * ------------------------------------------
+ * Clear 0 0
+ * Src 1 0
+ * Dst 0 1
+ * Over 1 1-Aa
+ * OverReverse 1-Ab 1
+ * In Ab 0
+ * InReverse 0 Aa
+ * Out 1-Ab 0
+ * OutReverse 0 1-Aa
+ * Atop Ab 1-Aa
+ * AtopReverse 1-Ab Aa
+ * Xor 1-Ab 1-Aa
+ * Add 1 1
+ * Saturate min(1,(1-Ab)/Aa) 1
+ *
+ * Flags
+ * You can use the following flags to achieve additional affects:
+ *
+ * Flag Effect
+ * ------------------------------------------
+ * ConstantSourceAlpha Ca = Ca * Param0
+ * ConstantDestAlpha Cb = Cb * Param1
+ *
+ * Flag effects resolve before the op. For example
+ * BlendOp == Add && Flags == ConstantSourceAlpha |
+ * ConstantDestAlpha results in:
+ *
+ * C = (Ca * Param0) + (Cb * Param1)
+ */
+
+#define SVGA_BLENDOP_CLEAR 0
+#define SVGA_BLENDOP_SRC 1
+#define SVGA_BLENDOP_DST 2
+#define SVGA_BLENDOP_OVER 3
+#define SVGA_BLENDOP_OVER_REVERSE 4
+#define SVGA_BLENDOP_IN 5
+#define SVGA_BLENDOP_IN_REVERSE 6
+#define SVGA_BLENDOP_OUT 7
+#define SVGA_BLENDOP_OUT_REVERSE 8
+#define SVGA_BLENDOP_ATOP 9
+#define SVGA_BLENDOP_ATOP_REVERSE 10
+#define SVGA_BLENDOP_XOR 11
+#define SVGA_BLENDOP_ADD 12
+#define SVGA_BLENDOP_SATURATE 13
+
+#define SVGA_NUM_BLENDOPS 14
+#define SVGA_IS_VALID_BLENDOP(op) (op >= 0 && op < SVGA_NUM_BLENDOPS)
+
+#define SVGA_BLENDFLAG_CONSTANT_SOURCE_ALPHA 0x01
+#define SVGA_BLENDFLAG_CONSTANT_DEST_ALPHA 0x02
+#define SVGA_NUM_BLENDFLAGS 2
+#define SVGA_BLENDFLAG_ALL (MASK(SVGA_NUM_BLENDFLAGS))
+#define SVGA_IS_VALID_BLENDFLAG(flag) ((flag & ~SVGA_BLENDFLAG_ALL) == 0)
+
+/*
+ * Memory area offsets (viewed as an array of 32-bit words)
+ */
+
+/*
+ * The distance from MIN to MAX must be at least 10K
+ */
+
+#define SVGA_FIFO_MIN 0
+#define SVGA_FIFO_MAX 1
+#define SVGA_FIFO_NEXT_CMD 2
+#define SVGA_FIFO_STOP 3
+
+#define SVGA_FIFO_USER_DEFINED 4
+
+/*
+ * Drawing object ID's, in the range 0 to SVGA_MAX_ID
+ */
+
+#define SVGA_MAX_ID 499
+
+/*
+ * Macros to compute variable length items (sizes in 32-bit words, except
+ * for SVGA_GLYPH_SCANLINE_SIZE, which is in bytes).
+ */
+
+#define SVGA_BITMAP_SIZE(w,h) ((((w)+31) >> 5) * (h))
+#define SVGA_BITMAP_SCANLINE_SIZE(w) (( (w)+31 ) >> 5)
+#define SVGA_PIXMAP_SIZE(w,h,bpp) ((( ((w)*(bpp))+31 ) >> 5) * (h))
+#define SVGA_PIXMAP_SCANLINE_SIZE(w,bpp) (( ((w)*(bpp))+31 ) >> 5)
+#define SVGA_GLYPH_SIZE(w,h) ((((((w) + 7) >> 3) * (h)) + 3) >> 2)
+#define SVGA_GLYPH_SCANLINE_SIZE(w) (((w) + 7) >> 3)
+
+/*
+ * Get the width and height of VRAM in the current mode (for offscreen memory)
+ */
+#define SVGA_VRAM_WIDTH_HEIGHT(width /* out */, height /* out */) { \
+ uint32 pitch = svga->reg[SVGA_REG_BYTES_PER_LINE]; \
+ width = (pitch * 8) / ((svga->reg[SVGA_REG_BITS_PER_PIXEL] + 7) & ~7); \
+ height = (svga->reg[SVGA_REG_VRAM_SIZE] - \
+ svga->reg[SVGA_REG_FB_OFFSET]) / pitch; \
+}
+
+/*
+ * Increment from one scanline to the next of a bitmap or pixmap
+ */
+#define SVGA_BITMAP_INCREMENT(w) ((( (w)+31 ) >> 5) * sizeof (uint32))
+#define SVGA_PIXMAP_INCREMENT(w,bpp) ((( ((w)*(bpp))+31 ) >> 5) * sizeof (uint32))
+
+/*
+ * Transparent color for DRAW_GLYPH_CLIPPED
+ */
+#define SVGA_COLOR_TRANSPARENT (~0)
+
+/*
+ * Commands in the command FIFO
+ */
+
+#define SVGA_CMD_INVALID_CMD 0
+ /* FIFO layout:
+ <nothing> (well, undefined) */
+
+#define SVGA_CMD_UPDATE 1
+ /* FIFO layout:
+ X, Y, Width, Height */
+
+#define SVGA_CMD_RECT_FILL 2
+ /* FIFO layout:
+ Color, X, Y, Width, Height */
+
+#define SVGA_CMD_RECT_COPY 3
+ /* FIFO layout:
+ Source X, Source Y, Dest X, Dest Y, Width, Height */
+
+#define SVGA_CMD_DEFINE_BITMAP 4
+ /* FIFO layout:
+ Pixmap ID, Width, Height, <scanlines> */
+
+#define SVGA_CMD_DEFINE_BITMAP_SCANLINE 5
+ /* FIFO layout:
+ Pixmap ID, Width, Height, Line #, scanline */
+
+#define SVGA_CMD_DEFINE_PIXMAP 6
+ /* FIFO layout:
+ Pixmap ID, Width, Height, Depth, <scanlines> */
+
+#define SVGA_CMD_DEFINE_PIXMAP_SCANLINE 7
+ /* FIFO layout:
+ Pixmap ID, Width, Height, Depth, Line #, scanline */
+
+#define SVGA_CMD_RECT_BITMAP_FILL 8
+ /* FIFO layout:
+ Bitmap ID, X, Y, Width, Height, Foreground, Background */
+
+#define SVGA_CMD_RECT_PIXMAP_FILL 9
+ /* FIFO layout:
+ Pixmap ID, X, Y, Width, Height */
+
+#define SVGA_CMD_RECT_BITMAP_COPY 10
+ /* FIFO layout:
+ Bitmap ID, Source X, Source Y, Dest X, Dest Y,
+ Width, Height, Foreground, Background */
+
+#define SVGA_CMD_RECT_PIXMAP_COPY 11
+ /* FIFO layout:
+ Pixmap ID, Source X, Source Y, Dest X, Dest Y, Width, Height */
+
+#define SVGA_CMD_FREE_OBJECT 12
+ /* FIFO layout:
+ Object (pixmap, bitmap, ...) ID */
+
+#define SVGA_CMD_RECT_ROP_FILL 13
+ /* FIFO layout:
+ Color, X, Y, Width, Height, ROP */
+
+#define SVGA_CMD_RECT_ROP_COPY 14
+ /* FIFO layout:
+ Source X, Source Y, Dest X, Dest Y, Width, Height, ROP */
+
+#define SVGA_CMD_RECT_ROP_BITMAP_FILL 15
+ /* FIFO layout:
+ ID, X, Y, Width, Height, Foreground, Background, ROP */
+
+#define SVGA_CMD_RECT_ROP_PIXMAP_FILL 16
+ /* FIFO layout:
+ ID, X, Y, Width, Height, ROP */
+
+#define SVGA_CMD_RECT_ROP_BITMAP_COPY 17
+ /* FIFO layout:
+ ID, Source X, Source Y,
+ Dest X, Dest Y, Width, Height, Foreground, Background, ROP */
+
+#define SVGA_CMD_RECT_ROP_PIXMAP_COPY 18
+ /* FIFO layout:
+ ID, Source X, Source Y, Dest X, Dest Y, Width, Height, ROP */
+
+#define SVGA_CMD_DEFINE_CURSOR 19
+ /* FIFO layout:
+ ID, Hotspot X, Hotspot Y, Width, Height,
+ Depth for AND mask, Depth for XOR mask,
+ <scanlines for AND mask>, <scanlines for XOR mask> */
+
+#define SVGA_CMD_DISPLAY_CURSOR 20
+ /* FIFO layout:
+ ID, On/Off (1 or 0) */
+
+#define SVGA_CMD_MOVE_CURSOR 21
+ /* FIFO layout:
+ X, Y */
+
+#define SVGA_CMD_DEFINE_ALPHA_CURSOR 22
+ /* FIFO layout:
+ ID, Hotspot X, Hotspot Y, Width, Height,
+ <scanlines> */
+
+#define SVGA_CMD_DRAW_GLYPH 23
+ /* FIFO layout:
+ X, Y, W, H, FGCOLOR, <stencil buffer> */
+
+#define SVGA_CMD_DRAW_GLYPH_CLIPPED 24
+ /* FIFO layout:
+ X, Y, W, H, FGCOLOR, BGCOLOR, <cliprect>, <stencil buffer>
+ Transparent color expands are done by setting BGCOLOR to ~0 */
+
+#define SVGA_CMD_UPDATE_VERBOSE 25
+ /* FIFO layout:
+ X, Y, Width, Height, Reason */
+
+#define SVGA_CMD_SURFACE_FILL 26
+ /* FIFO layout:
+ color, dstSurfaceOffset, x, y, w, h, rop */
+
+#define SVGA_CMD_SURFACE_COPY 27
+ /* FIFO layout:
+ srcSurfaceOffset, dstSurfaceOffset, srcX, srcY,
+ destX, destY, w, h, rop */
+
+#define SVGA_CMD_SURFACE_ALPHA_BLEND 28
+ /* FIFO layout:
+ srcSurfaceOffset, dstSurfaceOffset, srcX, srcY,
+ destX, destY, w, h, op (SVGA_BLENDOP*), flags (SVGA_BLENDFLAGS*),
+ param1, param2 */
+
+#define SVGA_CMD_MAX 29
+
+/* SURFACE_ALPHA_BLEND currently has the most (non-data) arguments: 12 */
+#define SVGA_CMD_MAX_ARGS 12
+
+
+/*
+ * A sync request is sent via a non-zero write to the SVGA_REG_SYNC
+ * register. In devel builds, the driver will write a specific value
+ * indicating exactly why the sync is necessary
+ */
+enum {
+ SVGA_SYNC_INVALIDREASON = 0, /* Don't ever write a zero */
+ SVGA_SYNC_GENERIC = 1, /* Legacy drivers will always write a 1 */
+ SVGA_SYNC_FIFOFULL = 2, /* Need to drain FIFO for next write */
+ SVGA_SYNC_FB_WRITE = 3, /* About write to shadow frame buffer (generic) */
+ SVGA_SYNC_FB_BITBLT = 4, /* Unaccelerated DrvBitBlt */
+ SVGA_SYNC_FB_COPYBITS = 5, /* Unacclerated DrvCopyBits bits */
+ SVGA_SYNC_FB_FILLPATH = 6, /* Unacclerated DrvFillPath */
+ SVGA_SYNC_FB_LINETO = 7, /* Unacclerated DrvLineTo */
+ SVGA_SYNC_FB_PAINT = 8, /* Unacclerated DrvPaint */
+ SVGA_SYNC_FB_STRETCHBLT = 9, /* Unacclerated DrvStretchBlt */
+ SVGA_SYNC_FB_STROKEFILL = 10, /* Unacclerated DrvStrokeAndFillPath */
+ SVGA_SYNC_FB_STROKE = 11, /* Unacclerated DrvStrokePath */
+ SVGA_SYNC_FB_TEXTOUT = 12, /* Unacclerated DrvTextOut */
+ SVGA_SYNC_FB_ALPHABLEND = 13, /* Unacclerated DrvAlphaBlend */
+ SVGA_SYNC_FB_GRADIENT = 14, /* Unacclerated DrvGradientFill */
+ SVGA_SYNC_FB_PLGBLT = 15, /* Unacclerated DrvPlgBlt */
+ SVGA_SYNC_FB_STRETCHROP = 16, /* Unacclerated DrvStretchBltROP */
+ SVGA_SYNC_FB_TRANSPARENT = 17, /* Unacclerated DrvTransparentBlt */
+ SVGA_SYNC_FB_NEWCURSOR = 18, /* Defined a new cursor */
+ SVGA_SYNC_FB_SYNCSURFACE = 19, /* DrvSynchrnoizeSurface call */
+ SVGA_SYNC_FB_NUM_REASONS /* Total number of reasons */
+};
+
+#endif
diff --git a/src/svga_struct.h b/src/svga_struct.h
new file mode 100644
index 0000000..fe4f0bf
--- /dev/null
+++ b/src/svga_struct.h
@@ -0,0 +1,40 @@
+/* **********************************************************
+ * Copyright (C) 1998-2000 VMware, Inc.
+ * All Rights Reserved
+ * **********************************************************/
+
+#ifndef _SVGA_STRUCT_H_
+#define _SVGA_STRUCT_H_
+
+#define INCLUDE_ALLOW_USERLEVEL
+#define INCLUDE_ALLOW_MONITOR
+#include "includeCheck.h"
+
+ /*
+ * Offscreen memory surface structure
+ *
+ */
+
+enum SVGASurfaceVersion {
+ SVGA_SURFACE_VERSION_1 = 1 /* Initial version... */
+};
+
+typedef struct _SVGASurface {
+ uint32 size; /* Size of the structure */
+ uint32 version; /* Version of this surface structure. */
+ uint32 bpp; /* Format of the surface */
+ uint32 width; /* Width of the surface */
+ uint32 height; /* Height of the surface */
+ uint32 pitch; /* Pitch of the surface */
+ volatile uint32 numQueued; /* Number of times this bitmap has been queued */
+ volatile uint32 numDequeued; /* Number of times this bitmap has been dequeued */
+ uint32 userData; /* Driver defined data */
+ uint32 dataOffset; /* Offset to the data */
+} SVGASurface;
+
+typedef struct SVGAPoint {
+ int16 x;
+ int16 y;
+} SVGAPoint;
+
+#endif
diff --git a/src/vm_basic_types.h b/src/vm_basic_types.h
new file mode 100644
index 0000000..673522f
--- /dev/null
+++ b/src/vm_basic_types.h
@@ -0,0 +1,173 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vmware/vm_basic_types.h,v 1.5 2002/01/07 20:38:29 dawes Exp $ */
+/* **********************************************************
+ * Copyright (C) 1998-2001 VMware, Inc.
+ * All Rights Reserved
+ * Id: vm_basic_types.h,v 1.9 2001/02/14 22:22:53 bennett Exp $
+ * **********************************************************/
+
+/*
+ *
+ * vm_basic_types.h --
+ *
+ * basic data types.
+ */
+
+
+#ifndef _VM_BASIC_TYPES_H_
+#define _VM_BASIC_TYPES_H_
+
+#define INCLUDE_ALLOW_USERLEVEL
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_VMKERNEL
+#include "includeCheck.h"
+
+/* STRICT ANSI means the Xserver build and X defines Bool differently. */
+#if 0
+typedef char Bool;
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifdef _MSC_VER
+typedef unsigned __int64 uint64;
+typedef signed __int64 int64;
+
+#pragma warning (disable :4018) // signed/unsigned mismatch
+#pragma warning (disable :4761) // integral size mismatch in argument; conversion supplied
+#pragma warning (disable :4305) // truncation from 'const int' to 'short'
+#pragma warning (disable :4244) // conversion from 'unsigned short' to 'unsigned char'
+//#pragma warning (disable :4101) // unreferenced local variable
+#pragma warning (disable :4133) // incompatible types - from 'struct VM *' to 'int *'
+#pragma warning (disable :4047) // differs in levels of indirection
+#pragma warning (disable :4146) // unary minus operator applied to unsigned type, result still unsigned
+#pragma warning (disable :4142) // benign redefinition of type
+
+#elif defined(__GNUC__)
+/* The Xserver source compiles with -ansi -pendantic */
+#ifndef __STRICT_ANSI__
+typedef unsigned long long uint64;
+typedef long long int64;
+#endif
+#else
+/* int64/uint64 aren't actually used in the vmware driver. */
+#if 0
+#error - Need compiler define for int64/uint64
+#endif
+#endif
+
+typedef unsigned int uint32;
+typedef unsigned short uint16;
+typedef unsigned char uint8;
+
+typedef int int32;
+typedef short int16;
+typedef char int8;
+
+
+/*
+ * Printf format for 64-bit number. Use it like this:
+ * printf("%"FMT64"d\n", big);
+ */
+
+#ifdef _MSC_VER
+#define FMT64 "I64"
+#elif defined(__GNUC__)
+#define FMT64 "L"
+#else
+/* FMT64 isn't actually used in the vmware driver. */
+#if 0
+#error - Need compiler define for FMT64
+#endif
+#endif
+
+typedef uint32 VA;
+typedef uint32 VPN;
+
+typedef uint32 PA;
+typedef uint32 PPN;
+
+typedef uint32 MA;
+typedef uint32 MPN;
+
+#define INVALID_MPN ((MPN)-1)
+
+#define EXTERN extern
+/*
+ * Right now our use of CONST is broken enough that it only works
+ * with GCC. XXX Need to fix this.
+ */
+#ifdef __GNUC__
+#define CONST const
+#else
+#ifndef CONST
+#define CONST
+#endif
+#endif
+
+#ifdef _MSC_VER
+#ifndef INLINE
+#define INLINE __inline
+#endif
+#else
+#ifndef INLINE
+#define INLINE inline
+#endif
+#endif
+
+
+#if defined(WIN32) && !defined(VMX86_NO_THREADS)
+#define THREADSPECIFIC _declspec(thread)
+#else
+#define THREADSPECIFIC
+#endif
+
+/*
+ * Like "INLINE" but use this token to mark functions that are inline
+ * because they have only a single call site. In other words, if a second
+ * call site is introduced, the "INLINE_SINGLE_CALLER" token should be
+ * removed.
+ */
+#define INLINE_SINGLE_CALLER INLINE
+
+/*
+ * Attributes placed on function declarations to tell the compiler
+ * that the function never returns.
+ */
+#ifdef _MSC_VER
+#define NORETURN_DECL(_fndecl) __declspec(noreturn) _fndecl
+#elif defined(__GNUC__) && __GNUC__ >= 2 && __GNUC_MINOR__ >= 5
+#define NORETURN_DECL(_fndecl) _fndecl __attribute__((__noreturn__))
+#else
+#define NORETURN_DECL(_fndecl) _fndecl
+#endif
+
+
+/*
+ * GCC's argument checking for printf-like functions
+ * This is conditional until we have replaced all `"%x", void *'
+ * with `"0x%08x", (uint32) void *'. Note that %p prints different things
+ * on different platforms.
+ *
+ * fmtPos is the position of the format string argument, beginning at 1
+ * varPos is the position of the variable argument, beginning at 1
+ */
+#if defined(__GNUC__) && defined(notdef)
+# define PRINTF_DECL(fmtPos, varPos) __attribute__((__format__(__printf__, fmtPos, varPos)))
+#else
+# define PRINTF_DECL(fmtPos, varPos)
+#endif
+
+/*
+ * Used to silence compiler warnings that get generated when the
+ * compiler thinks that a function returns when it is marked noreturn.
+ */
+#define INFINITE_LOOP() do { } while (1)
+
+#endif
diff --git a/src/vm_device_version.h b/src/vm_device_version.h
new file mode 100644
index 0000000..8f6dd3b
--- /dev/null
+++ b/src/vm_device_version.h
@@ -0,0 +1,64 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vmware/vm_device_version.h,v 1.1 2001/04/05 19:29:44 dawes Exp $ */
+/* **********************************************************
+ * Copyright (C) 1998-2001 VMware, Inc.
+ * All Rights Reserved
+ * Id: vm_device_version.h,v 1.2 2001/01/26 21:53:27 yoel Exp $
+ * **********************************************************/
+
+
+#ifndef VM_DEVICE_VERSION_H
+#define VM_DEVICE_VERSION_H
+
+#define INCLUDE_ALLOW_USERLEVEL
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_VMKERNEL
+#include "includeCheck.h"
+
+#define PCI_VENDOR_ID_VMWARE 0x15AD
+#define PCI_DEVICE_ID_VMWARE_SVGA2 0x0405
+#define PCI_DEVICE_ID_VMWARE_SVGA 0x0710
+#define PCI_DEVICE_ID_VMWARE_NET 0x0720
+#define PCI_DEVICE_ID_VMWARE_SCSI 0x0730
+#define PCI_DEVICE_ID_VMWARE_IDE 0x1729
+
+/* From linux/pci.h. We emulate an AMD ethernet controller */
+#define PCI_VENDOR_ID_AMD 0x1022
+#define PCI_DEVICE_ID_AMD_VLANCE 0x2000
+#define PCI_VENDOR_ID_BUSLOGIC 0x104B
+#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140
+#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER 0x1040
+
+/* Intel Values for the chipset */
+#define PCI_VENDOR_ID_INTEL 0x8086
+#define PCI_DEVICE_ID_INTEL_82439TX 0x7100
+#define PCI_DEVICE_ID_INTEL_82371AB_0 0x7110
+#define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113
+#define PCI_DEVICE_ID_INTEL_82371AB 0x7111
+#define PCI_DEVICE_ID_INTEL_82443BX 0x7192
+
+
+/************* Strings for IDE Identity Fields **************************/
+#define VIDE_ID_SERIAL_STR "00000000000000000001" /* Must be 20 Bytes */
+#define VIDE_ID_FIRMWARE_STR "00000001" /* Must be 8 Bytes */
+
+/* No longer than 40 Bytes and must be an even length. */
+#define VIDE_ATA_MODEL_STR PRODUCT_GENERIC_NAME " Virtual IDE Hard Drive "
+#define VIDE_ATAPI_MODEL_STR PRODUCT_GENERIC_NAME " Virtual IDE CDROM Drive "
+
+#define ATAPI_VENDOR_ID "NECVMWar" /* Must be 8 Bytes */
+#define ATAPI_PRODUCT_ID PRODUCT_GENERIC_NAME " IDE CDROM" /* Must be 16 Bytes */
+#define ATAPI_REV_LEVEL "1.00" /* Must be 4 Bytes */
+
+
+/************* Strings for SCSI Identity Fields **************************/
+#define SCSI_DISK_MODEL_STR PRODUCT_GENERIC_NAME " Virtual SCSI Hard Drive"
+#define SCSI_CDROM_MODEL_STR PRODUCT_GENERIC_NAME " Virtual SCSI CDROM Drive"
+
+/************* Strings for the VESA BIOS Identity Fields *****************/
+#define VBE_OEM_STRING COMPANY_NAME " SVGA"
+#define VBE_VENDOR_NAME COMPANY_NAME
+#define VBE_PRODUCT_NAME PRODUCT_GENERIC_NAME
+
+
+#endif /* VM_DEVICE_VERSION_H */
diff --git a/src/vmware.c b/src/vmware.c
new file mode 100644
index 0000000..d21ebb7
--- /dev/null
+++ b/src/vmware.c
@@ -0,0 +1,1406 @@
+/* **********************************************************
+ * Copyright (C) 1998-2001 VMware, Inc.
+ * All Rights Reserved
+ * **********************************************************/
+#ifdef VMX86_DEVEL
+char rcsId_vmware[] =
+ "Id: vmware.c,v 1.11 2001/02/23 02:10:39 yoel Exp $";
+#endif
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vmware/vmware.c,v 1.17 2003/02/18 19:10:36 alanh Exp $ */
+
+/*
+ * TODO: support the vmware linux kernel fb driver (Option "UseFBDev").
+ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Resources.h"
+
+#include "compiler.h" /* inb/outb */
+
+#include "xf86PciInfo.h" /* pci vendor id */
+#include "xf86Pci.h" /* pci */
+
+#include "mipointer.h" /* sw cursor */
+#include "mibstore.h" /* backing store */
+#include "micmap.h" /* mi color map */
+#include "vgaHW.h" /* VGA hardware */
+#include "fb.h"
+#include "shadowfb.h" /* ShadowFB wrappers */
+
+#include "xf86cmap.h" /* xf86HandleColormaps */
+
+#include "vmware.h"
+#include "guest_os.h"
+#include "vm_device_version.h"
+
+/*
+ * Sanity check that xf86PciInfo.h has the correct values (which come from
+ * the VMware source tree in vm_device_version.h.
+ */
+#if PCI_CHIP_VMWARE0405 != PCI_DEVICE_ID_VMWARE_SVGA2
+#error "PCI_CHIP_VMWARE0405 is wrong, update it from vm_device_version.h"
+#endif
+#if PCI_CHIP_VMWARE0710 != PCI_DEVICE_ID_VMWARE_SVGA
+#error "PCI_CHIP_VMWARE0710 is wrong, update it from vm_device_version.h"
+#endif
+#if PCI_VENDOR_VMWARE != PCI_VENDOR_ID_VMWARE
+#error "PCI_VENDOR_VMWARE is wrong, update it from vm_device_version.h"
+#endif
+
+/*
+ * This is the only way I know to turn a #define of an integer constant into
+ * a constant string.
+ */
+#define VMW_INNERSTRINGIFY(s) #s
+#define VMW_STRING(str) VMW_INNERSTRINGIFY(str)
+
+#define VMWARE_NAME "VMWARE"
+#define VMWARE_DRIVER_NAME "vmware"
+#define VMWARE_MAJOR_VERSION 10
+#define VMWARE_MINOR_VERSION 10
+#define VMWARE_PATCHLEVEL 2
+#define VERSION (VMWARE_MAJOR_VERSION * 65536 + VMWARE_MINOR_VERSION * 256 + VMWARE_PATCHLEVEL)
+
+static const char VMWAREBuildStr[] = "VMware Guest X Server "
+ VMW_STRING(VMWARE_MAJOR_VERSION) "." VMW_STRING(VMWARE_MINOR_VERSION)
+ "." VMW_STRING(VMWARE_PATCHLEVEL) " - build=$Name$\n";
+
+static SymTabRec VMWAREChipsets[] = {
+ { PCI_CHIP_VMWARE0405, "vmware0405" },
+ { PCI_CHIP_VMWARE0710, "vmware0710" },
+ { -1, NULL }
+};
+
+static resRange vmwareLegacyRes[] = {
+ { ResExcIoBlock, SVGA_LEGACY_BASE_PORT,
+ SVGA_LEGACY_BASE_PORT + SVGA_NUM_PORTS*sizeof(uint32)},
+ _VGA_EXCLUSIVE, _END
+};
+
+/*
+ * Currently, even the PCI obedient 0405 chip still only obeys IOSE and
+ * MEMSE for the SVGA resources. Thus, RES_EXCLUSIVE_VGA is required.
+ *
+ * The 0710 chip also uses hardcoded IO ports that aren't disablable.
+ */
+
+static PciChipsets VMWAREPciChipsets[] = {
+ { PCI_CHIP_VMWARE0405, PCI_CHIP_VMWARE0405, RES_EXCLUSIVE_VGA },
+ { PCI_CHIP_VMWARE0710, PCI_CHIP_VMWARE0710, vmwareLegacyRes },
+ { -1, -1, RES_UNDEFINED }
+};
+
+static const char *vgahwSymbols[] = {
+ "vgaHWGetHWRec",
+ "vgaHWGetIOBase",
+ "vgaHWGetIndex",
+ "vgaHWInit",
+ "vgaHWProtect",
+ "vgaHWRestore",
+ "vgaHWSave",
+ "vgaHWSaveScreen",
+ "vgaHWUnlock",
+ NULL
+};
+
+static const char *fbSymbols[] = {
+ "fbCreateDefColormap",
+ "fbPictureInit",
+ "fbScreenInit",
+ NULL
+};
+
+static const char *ramdacSymbols[] = {
+ "xf86CreateCursorInfoRec",
+ "xf86DestroyCursorInfoRec",
+ "xf86InitCursor",
+ NULL
+};
+
+static const char *shadowfbSymbols[] = {
+ "ShadowFBInit2",
+ NULL
+};
+
+#ifdef XFree86LOADER
+static XF86ModuleVersionInfo vmwareVersRec = {
+ "vmware",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ VMWARE_MAJOR_VERSION, VMWARE_MINOR_VERSION, VMWARE_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ { 0, 0, 0, 0}
+};
+#endif /* XFree86LOADER */
+
+typedef enum {
+ OPTION_HW_CURSOR,
+ OPTION_NOACCEL
+} VMWAREOpts;
+
+static const OptionInfoRec VMWAREOptions[] = {
+ { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+static void VMWAREStopFIFO(ScrnInfoPtr pScrn);
+
+static Bool
+VMWAREGetRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate != NULL) {
+ return TRUE;
+ }
+ pScrn->driverPrivate = xnfcalloc(sizeof(VMWARERec), 1);
+ /* FIXME: Initialize driverPrivate... */
+ return TRUE;
+}
+
+static void
+VMWAREFreeRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate) {
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+ }
+}
+
+CARD32
+vmwareReadReg(VMWAREPtr pVMWARE, int index)
+{
+ /*
+ * Block SIGIO for the duration, so we don't get interrupted after the
+ * outl but before the inl by a mouse move (which write to our registers).
+ */
+ int oldsigio, ret;
+ oldsigio = xf86BlockSIGIO();
+ outl(pVMWARE->indexReg, index);
+ ret = inl(pVMWARE->valueReg);
+ xf86UnblockSIGIO(oldsigio);
+ return ret;
+}
+
+void
+vmwareWriteReg(VMWAREPtr pVMWARE, int index, CARD32 value)
+{
+ /*
+ * Block SIGIO for the duration, so we don't get interrupted in between
+ * the outls by a mouse move (which write to our registers).
+ */
+ int oldsigio;
+ oldsigio = xf86BlockSIGIO();
+ outl(pVMWARE->indexReg, index);
+ outl(pVMWARE->valueReg, value);
+ xf86UnblockSIGIO(oldsigio);
+}
+
+void
+vmwareWriteWordToFIFO(VMWAREPtr pVMWARE, CARD32 value)
+{
+ CARD32* vmwareFIFO = pVMWARE->vmwareFIFO;
+
+ /* Need to sync? */
+ if ((vmwareFIFO[SVGA_FIFO_NEXT_CMD] + sizeof(CARD32) == vmwareFIFO[SVGA_FIFO_STOP])
+ || (vmwareFIFO[SVGA_FIFO_NEXT_CMD] == vmwareFIFO[SVGA_FIFO_MAX] - sizeof(CARD32) &&
+ vmwareFIFO[SVGA_FIFO_STOP] == vmwareFIFO[SVGA_FIFO_MIN])) {
+ VmwareLog(("Syncing because of full fifo\n"));
+ vmwareWaitForFB(pVMWARE);
+ }
+
+ vmwareFIFO[vmwareFIFO[SVGA_FIFO_NEXT_CMD] / sizeof(CARD32)] = value;
+ if(vmwareFIFO[SVGA_FIFO_NEXT_CMD] == vmwareFIFO[SVGA_FIFO_MAX] -
+ sizeof(CARD32)) {
+ vmwareFIFO[SVGA_FIFO_NEXT_CMD] = vmwareFIFO[SVGA_FIFO_MIN];
+ } else {
+ vmwareFIFO[SVGA_FIFO_NEXT_CMD] += sizeof(CARD32);
+ }
+}
+
+void
+vmwareWaitForFB(VMWAREPtr pVMWARE)
+{
+ vmwareWriteReg(pVMWARE, SVGA_REG_SYNC, 1);
+ while (vmwareReadReg(pVMWARE, SVGA_REG_BUSY));
+}
+
+void
+vmwareSendSVGACmdUpdate(VMWAREPtr pVMWARE, BoxPtr pBB)
+{
+ vmwareWriteWordToFIFO(pVMWARE, SVGA_CMD_UPDATE);
+ vmwareWriteWordToFIFO(pVMWARE, pBB->x1);
+ vmwareWriteWordToFIFO(pVMWARE, pBB->y1);
+ vmwareWriteWordToFIFO(pVMWARE, pBB->x2 - pBB->x1);
+ vmwareWriteWordToFIFO(pVMWARE, pBB->y2 - pBB->y1);
+}
+
+static void
+vmwareSendSVGACmdUpdateFullScreen(VMWAREPtr pVMWARE)
+{
+ BoxRec BB;
+
+ BB.x1 = 0;
+ BB.y1 = 0;
+ BB.x2 = pVMWARE->ModeReg.svga_reg_width;
+ BB.y2 = pVMWARE->ModeReg.svga_reg_height;
+ vmwareSendSVGACmdUpdate(pVMWARE, &BB);
+}
+
+static CARD32
+vmwareCalculateWeight(CARD32 mask)
+{
+ CARD32 weight;
+
+ for (weight = 0; mask; mask >>= 1) {
+ if (mask & 1) {
+ weight++;
+ }
+ }
+ return weight;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VMXGetVMwareSvgaId --
+ *
+ * Retrieve the SVGA_ID of the VMware SVGA adapter.
+ * This function should hide any backward compatibility mess.
+ *
+ * Results:
+ * The SVGA_ID_* of the present VMware adapter.
+ *
+ * Side effects:
+ * ins/outs
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static uint32
+VMXGetVMwareSvgaId(VMWAREPtr pVMWARE)
+{
+ uint32 vmware_svga_id;
+
+ /* Any version with any SVGA_ID_* support will initialize SVGA_REG_ID
+ * to SVGA_ID_0 to support versions of this driver with SVGA_ID_0.
+ *
+ * Versions of SVGA_ID_0 ignore writes to the SVGA_REG_ID register.
+ *
+ * Versions of SVGA_ID_1 will allow us to overwrite the content
+ * of the SVGA_REG_ID register only with the values SVGA_ID_0 or SVGA_ID_1.
+ *
+ * Versions of SVGA_ID_2 will allow us to overwrite the content
+ * of the SVGA_REG_ID register only with the values SVGA_ID_0 or SVGA_ID_1
+ * or SVGA_ID_2.
+ */
+
+ vmwareWriteReg(pVMWARE, SVGA_REG_ID, SVGA_ID_2);
+ vmware_svga_id = vmwareReadReg(pVMWARE, SVGA_REG_ID);
+ if (vmware_svga_id == SVGA_ID_2) {
+ return SVGA_ID_2;
+ }
+
+ vmwareWriteReg(pVMWARE, SVGA_REG_ID, SVGA_ID_1);
+ vmware_svga_id = vmwareReadReg(pVMWARE, SVGA_REG_ID);
+ if (vmware_svga_id == SVGA_ID_1) {
+ return SVGA_ID_1;
+ }
+
+ if (vmware_svga_id == SVGA_ID_0) {
+ return SVGA_ID_0;
+ }
+
+ /* No supported VMware SVGA devices found */
+ return SVGA_ID_INVALID;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * RewriteTagString --
+ *
+ * Rewrites the given string, removing the $Name$, and
+ * replacing it with the contents. The output string must
+ * have enough room, or else.
+ *
+ * Results:
+ *
+ * Output string updated.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+RewriteTagString(const char *istr, char *ostr, int osize)
+{
+ int chr;
+ Bool inTag = FALSE;
+ char *op = ostr;
+
+ do {
+ chr = *istr++;
+ if (chr == '$') {
+ if (inTag) {
+ inTag = FALSE;
+ for (; op > ostr && op[-1] == ' '; op--) {
+ }
+ continue;
+ }
+ if (strncmp(istr, "Name:", 5) == 0) {
+ istr += 5;
+ istr += strspn(istr, " ");
+ inTag = TRUE;
+ continue;
+ }
+ }
+ *op++ = chr;
+ } while (chr);
+}
+
+static void
+VMWAREIdentify(int flags)
+{
+ xf86PrintChipsets(VMWARE_NAME, "driver for VMware SVGA", VMWAREChipsets);
+}
+
+static const OptionInfoRec *
+VMWAREAvailableOptions(int chipid, int busid)
+{
+ return VMWAREOptions;
+}
+
+static Bool
+VMWAREPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ MessageType from;
+ VMWAREPtr pVMWARE;
+ OptionInfoPtr options;
+ int bpp24flags;
+ uint32 id;
+ int i;
+ ClockRange* clockRanges;
+ IOADDRESS domainIOBase = 0;
+
+#ifndef BUILD_FOR_420
+ domainIOBase = pScrn->domainIOBase;
+#endif
+
+ if (flags & PROBE_DETECT) {
+ return FALSE;
+ }
+
+ if (pScrn->numEntities != 1) {
+ return FALSE;
+ }
+
+ if (!VMWAREGetRec(pScrn)) {
+ return FALSE;
+ }
+ pVMWARE = VMWAREPTR(pScrn);
+
+ pVMWARE->pvtSema = &pScrn->vtSema;
+
+ pVMWARE->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+ if (pVMWARE->pEnt->location.type != BUS_PCI) {
+ return FALSE;
+ }
+ pVMWARE->PciInfo = xf86GetPciInfoForEntity(pVMWARE->pEnt->index);
+ if (pVMWARE->PciInfo == NULL) {
+ return FALSE;
+ }
+
+ if (pVMWARE->PciInfo->chipType == PCI_CHIP_VMWARE0710) {
+ pVMWARE->indexReg = domainIOBase +
+ SVGA_LEGACY_BASE_PORT + SVGA_INDEX_PORT*sizeof(uint32);
+ pVMWARE->valueReg = domainIOBase +
+ SVGA_LEGACY_BASE_PORT + SVGA_VALUE_PORT*sizeof(uint32);
+ } else {
+ /* Note: This setting of valueReg causes unaligned I/O */
+ pVMWARE->indexReg = domainIOBase +
+ pVMWARE->PciInfo->ioBase[0] + SVGA_INDEX_PORT;
+ pVMWARE->valueReg = domainIOBase +
+ pVMWARE->PciInfo->ioBase[0] + SVGA_VALUE_PORT;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "VMware SVGA regs at (0x%04x, 0x%04x)\n",
+ pVMWARE->indexReg, pVMWARE->valueReg);
+
+ id = VMXGetVMwareSvgaId(pVMWARE);
+ if (id == SVGA_ID_0 || id == SVGA_ID_INVALID) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No supported VMware SVGA found (read ID 0x%08x).\n", id);
+ return FALSE;
+ }
+
+ if (!xf86LoadSubModule(pScrn, "vgahw")) {
+ return FALSE;
+ }
+
+ xf86LoaderReqSymLists(vgahwSymbols, NULL);
+
+ if (!vgaHWGetHWRec(pScrn)) {
+ return FALSE;
+ }
+
+ pVMWARE->PciTag = pciTag(pVMWARE->PciInfo->bus, pVMWARE->PciInfo->device,
+ pVMWARE->PciInfo->func);
+ pVMWARE->Primary = xf86IsPrimaryPci(pVMWARE->PciInfo);
+
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+#ifdef ACCELERATE_OPS
+ pVMWARE->vmwareCapability = vmwareReadReg(pVMWARE, SVGA_REG_CAPABILITIES);
+#else
+ pVMWARE->vmwareCapability = 0;
+#endif
+
+ if (pVMWARE->vmwareCapability & SVGA_CAP_8BIT_EMULATION) {
+ pVMWARE->bitsPerPixel =
+ vmwareReadReg(pVMWARE, SVGA_REG_HOST_BITS_PER_PIXEL);
+ vmwareWriteReg(pVMWARE,
+ SVGA_REG_BITS_PER_PIXEL, pVMWARE->bitsPerPixel);
+ } else {
+ pVMWARE->bitsPerPixel =
+ vmwareReadReg(pVMWARE, SVGA_REG_BITS_PER_PIXEL);
+ }
+ pVMWARE->depth = vmwareReadReg(pVMWARE, SVGA_REG_DEPTH);
+ pVMWARE->videoRam = vmwareReadReg(pVMWARE, SVGA_REG_VRAM_SIZE);
+ pVMWARE->memPhysBase = vmwareReadReg(pVMWARE, SVGA_REG_FB_START);
+ pVMWARE->maxWidth = vmwareReadReg(pVMWARE, SVGA_REG_MAX_WIDTH);
+ pVMWARE->maxHeight = vmwareReadReg(pVMWARE, SVGA_REG_MAX_HEIGHT);
+ pVMWARE->cursorDefined = FALSE;
+ pVMWARE->cursorShouldBeHidden = FALSE;
+
+ if (pVMWARE->vmwareCapability & SVGA_CAP_CURSOR_BYPASS_2) {
+ pVMWARE->cursorRemoveFromFB = SVGA_CURSOR_ON_REMOVE_FROM_FB;
+ pVMWARE->cursorRestoreToFB = SVGA_CURSOR_ON_RESTORE_TO_FB;
+ } else {
+ pVMWARE->cursorRemoveFromFB = SVGA_CURSOR_ON_HIDE;
+ pVMWARE->cursorRestoreToFB = SVGA_CURSOR_ON_SHOW;
+ }
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "caps: 0x%08X\n", pVMWARE->vmwareCapability);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "depth: %d\n", pVMWARE->depth);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "bpp: %d\n", pVMWARE->bitsPerPixel);
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "vram: %d\n", pVMWARE->videoRam);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "pbase: %p\n", pVMWARE->memPhysBase);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "mwidt: %d\n", pVMWARE->maxWidth);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "mheig: %d\n", pVMWARE->maxHeight);
+
+ switch (pVMWARE->depth) {
+ case 16:
+ /*
+ * In certain cases, the Windows host appears to
+ * report 16 bpp and 16 depth but 555 weight. Just
+ * silently convert it to depth of 15.
+ */
+ if (pVMWARE->bitsPerPixel == 16 &&
+ pVMWARE->weight.green == 5)
+ pVMWARE->depth = 15;
+ case 8:
+ case 15:
+ bpp24flags = NoDepth24Support;
+ break;
+
+ case 32:
+ /*
+ * There is no 32 bit depth, apparently it can get
+ * reported this way sometimes on the Windows host.
+ */
+ if (pVMWARE->bitsPerPixel == 32)
+ pVMWARE->depth = 24;
+ case 24:
+ if (pVMWARE->bitsPerPixel == 24)
+ bpp24flags = Support24bppFb;
+ else
+ bpp24flags = Support32bppFb;
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Adapter is using an unsupported depth (%d).\n",
+ pVMWARE->depth);
+ return FALSE;
+ }
+
+ if (!xf86SetDepthBpp(pScrn, pVMWARE->depth, pVMWARE->bitsPerPixel, pVMWARE->bitsPerPixel, bpp24flags)) {
+ return FALSE;
+ }
+
+ if (pScrn->bitsPerPixel != pVMWARE->bitsPerPixel) {
+ if (pScrn->bitsPerPixel == 8 &&
+ pVMWARE->vmwareCapability & SVGA_CAP_8BIT_EMULATION) {
+ vmwareWriteReg(pVMWARE, SVGA_REG_BITS_PER_PIXEL, 8);
+ pVMWARE->bitsPerPixel =
+ vmwareReadReg(pVMWARE, SVGA_REG_BITS_PER_PIXEL);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Currently unavailable depth/bpp of %d/%d requested.\n"
+ "\tThe guest X server must run at the same depth and bpp as the host\n"
+ "\t(which are currently %d/%d). This is automatically detected. Please\n"
+ "\tdo not specify a depth on the command line or via the config file.\n",
+ pScrn->depth, pScrn->bitsPerPixel,
+ pVMWARE->depth, pVMWARE->bitsPerPixel);
+ return FALSE;
+ }
+ }
+
+ /*
+ * Reread depth and defer reading the colour registers until here
+ * in case we changed bpp above.
+ */
+
+ pVMWARE->depth = vmwareReadReg(pVMWARE, SVGA_REG_DEPTH);
+ pVMWARE->weight.red =
+ vmwareCalculateWeight(vmwareReadReg(pVMWARE, SVGA_REG_RED_MASK));
+ pVMWARE->weight.green =
+ vmwareCalculateWeight(vmwareReadReg(pVMWARE, SVGA_REG_GREEN_MASK));
+ pVMWARE->weight.blue =
+ vmwareCalculateWeight(vmwareReadReg(pVMWARE, SVGA_REG_BLUE_MASK));
+ pVMWARE->offset.blue = 0;
+ pVMWARE->offset.green = pVMWARE->weight.blue;
+ pVMWARE->offset.red = pVMWARE->weight.green + pVMWARE->offset.green;
+ pVMWARE->defaultVisual = vmwareReadReg(pVMWARE, SVGA_REG_PSEUDOCOLOR) ?
+ PseudoColor : TrueColor;
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED,
+ 2, "depth: %d\n", pVMWARE->depth);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED,
+ 2, "bpp: %d\n", pVMWARE->bitsPerPixel);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED,
+ 2, "w.red: %d\n", pVMWARE->weight.red);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED,
+ 2, "w.grn: %d\n", pVMWARE->weight.green);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED,
+ 2, "w.blu: %d\n", pVMWARE->weight.blue);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED,
+ 2, "vis: %d\n", pVMWARE->defaultVisual);
+
+ if (pScrn->depth != pVMWARE->depth) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Currently unavailable depth of %d requested.\n"
+ "\tThe guest X server must run at the same depth as the host (which\n"
+ "\tis currently %d). This is automatically detected. Please do not\n"
+ "\tspecify a depth on the command line or via the config file.\n",
+ pScrn->depth, pVMWARE->depth);
+ return FALSE;
+ }
+ xf86PrintDepthBpp(pScrn);
+
+#if 0
+ if (pScrn->depth == 24 && pix24bpp == 0) {
+ pix24bpp = xf86GetBppFromDepth(pScrn, 24);
+ }
+#endif
+
+ if (pScrn->depth > 8) {
+ rgb zeros = { 0, 0, 0 };
+
+ if (!xf86SetWeight(pScrn, pVMWARE->weight, zeros)) {
+ return FALSE;
+ }
+ /* FIXME check returned weight */
+ }
+ if (!xf86SetDefaultVisual(pScrn, pVMWARE->defaultVisual)) {
+ return FALSE;
+ }
+ if (pScrn->defaultVisual != pVMWARE->defaultVisual) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given visual (%d) is not supported by this driver (%d is required)\n",
+ pScrn->defaultVisual, pVMWARE->defaultVisual);
+ return FALSE;
+ }
+#if 0
+ bytesPerPixel = pScrn->bitsPerPixel / 8;
+#endif
+ pScrn->progClock = TRUE;
+
+#if 0 /* MGA does not do this */
+ if (pScrn->visual != 0) { /* FIXME */
+ /* print error message */
+ return FALSE;
+ }
+#endif
+
+ xf86CollectOptions(pScrn, NULL);
+ if (!(options = xalloc(sizeof(VMWAREOptions))))
+ return FALSE;
+ memcpy(options, VMWAREOptions, sizeof(VMWAREOptions));
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
+
+ if (pScrn->depth <= 8) {
+ pScrn->rgbBits = 8;
+ }
+
+ from = X_PROBED;
+ pScrn->chipset = (char*)xf86TokenToString(VMWAREChipsets, pVMWARE->PciInfo->chipType);
+
+ if (!pScrn->chipset) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ChipID 0x%04 is not recognised\n", pVMWARE->PciInfo->chipType);
+ return FALSE;
+ }
+
+ from = X_DEFAULT;
+ pVMWARE->hwCursor = TRUE;
+ if (xf86GetOptValBool(options, OPTION_HW_CURSOR, &pVMWARE->hwCursor)) {
+ from = X_CONFIG;
+ }
+ if (pVMWARE->hwCursor && !(pVMWARE->vmwareCapability & SVGA_CAP_CURSOR)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "HW cursor is not supported in this configuration\n");
+ from = X_PROBED;
+ pVMWARE->hwCursor = FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
+ pVMWARE->hwCursor ? "HW" : "SW");
+ if (xf86IsOptionSet(options, OPTION_NOACCEL)) {
+ pVMWARE->noAccel = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
+ } else {
+ pVMWARE->noAccel = FALSE;
+ }
+ pScrn->videoRam = pVMWARE->videoRam / 1024;
+ pScrn->memPhysBase = pVMWARE->memPhysBase;
+ xfree(options);
+
+ {
+ Gamma zeros = { 0.0, 0.0, 0.0 };
+ if (!xf86SetGamma(pScrn, zeros)) {
+ return FALSE;
+ }
+ }
+#if 0
+ if ((i = xf86GetPciInfoForScreen(pScrn->scrnIndex, &pciList, NULL)) != 1) {
+ /* print error message */
+ VMWAREFreeRec(pScrn);
+ if (i > 0) {
+ xfree(pciList);
+ }
+ return FALSE;
+ }
+#endif
+ clockRanges = xnfcalloc(sizeof(ClockRange), 1);
+ clockRanges->next = NULL;
+ clockRanges->minClock = 1;
+ clockRanges->maxClock = 400000000;
+ clockRanges->clockIndex = -1;
+ clockRanges->interlaceAllowed = FALSE;
+ clockRanges->doubleScanAllowed = FALSE;
+ clockRanges->ClockMulFactor = 1;
+ clockRanges->ClockDivFactor = 1;
+
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, pScrn->display->modes,
+ clockRanges, NULL, 256, pVMWARE->maxWidth, 32 * 32,
+ 128, pVMWARE->maxHeight,
+ pScrn->display->virtualX, pScrn->display->virtualY,
+ pVMWARE->videoRam,
+ LOOKUP_BEST_REFRESH);
+ if (i == -1) {
+ VMWAREFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86PruneDriverModes(pScrn);
+ if (i == 0 || pScrn->modes == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
+ VMWAREFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
+ pScrn->currentMode = pScrn->modes;
+ xf86PrintModes(pScrn);
+ xf86SetDpi(pScrn, 0, 0);
+ if (!xf86LoadSubModule(pScrn, "fb") ||
+ !xf86LoadSubModule(pScrn, "shadowfb")) {
+ VMWAREFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(fbSymbols, shadowfbSymbols, NULL);
+
+ /* Need ramdac for hwcursor */
+ if (pVMWARE->hwCursor) {
+ if (!xf86LoadSubModule(pScrn, "ramdac")) {
+ VMWAREFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(ramdacSymbols, NULL);
+ }
+
+ if (!pVMWARE->noAccel) {
+ if (!xf86LoadSubModule(pScrn, "xaa")) {
+ VMWAREFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(vmwareXaaSymbols, NULL);
+ }
+
+ return TRUE;
+}
+
+static Bool
+VMWAREMapMem(ScrnInfoPtr pScrn)
+{
+ VMWAREPtr pVMWARE;
+
+ pVMWARE = VMWAREPTR(pScrn);
+
+ pVMWARE->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ pVMWARE->PciTag,
+ pVMWARE->memPhysBase,
+ pVMWARE->videoRam);
+ if (!pVMWARE->FbBase)
+ return FALSE;
+
+ VmwareLog(("FB Mapped: %p/%u -> %p/%u\n",
+ pVMWARE->memPhysBase, pVMWARE->videoRam,
+ pVMWARE->FbBase, pVMWARE->videoRam));
+ return TRUE;
+}
+
+static Bool
+VMWAREUnmapMem(ScrnInfoPtr pScrn)
+{
+ VMWAREPtr pVMWARE;
+
+ pVMWARE = VMWAREPTR(pScrn);
+
+ VmwareLog(("Unmapped: %p/%u\n", pVMWARE->FbBase, pVMWARE->videoRam));
+
+ xf86UnMapVidMem(pScrn->scrnIndex, pVMWARE->FbBase, pVMWARE->videoRam);
+ pVMWARE->FbBase = NULL;
+ return TRUE;
+}
+
+static void
+VMWARESave(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr vgaReg = &hwp->SavedReg;
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ VMWARERegPtr vmwareReg = &pVMWARE->SavedReg;
+
+ vgaHWSave(pScrn, vgaReg, VGA_SR_ALL);
+
+ vmwareReg->svga_reg_enable = vmwareReadReg(pVMWARE, SVGA_REG_ENABLE);
+ vmwareReg->svga_reg_width = vmwareReadReg(pVMWARE, SVGA_REG_WIDTH);
+ vmwareReg->svga_reg_height = vmwareReadReg(pVMWARE, SVGA_REG_HEIGHT);
+ vmwareReg->svga_reg_bits_per_pixel =
+ vmwareReadReg(pVMWARE, SVGA_REG_BITS_PER_PIXEL);
+
+ /* XXX this should be based on the cap bit, not hwCursor... */
+ if (pVMWARE->hwCursor) {
+ vmwareReg->svga_reg_cursor_on =
+ vmwareReadReg(pVMWARE, SVGA_REG_CURSOR_ON);
+ vmwareReg->svga_reg_cursor_x =
+ vmwareReadReg(pVMWARE, SVGA_REG_CURSOR_X);
+ vmwareReg->svga_reg_cursor_y =
+ vmwareReadReg(pVMWARE, SVGA_REG_CURSOR_Y);
+ vmwareReg->svga_reg_cursor_id =
+ vmwareReadReg(pVMWARE, SVGA_REG_CURSOR_ID);
+ }
+
+ vmwareReg->svga_fifo_enabled = vmwareReadReg(pVMWARE, SVGA_REG_CONFIG_DONE);
+}
+
+static void
+VMWARERestoreRegs(ScrnInfoPtr pScrn, VMWARERegPtr vmwareReg)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ VmwareLog(("VMWARERestoreRegs: W: %d, H: %d, BPP: %d, Enable: %d\n",
+ vmwareReg->svga_reg_width, vmwareReg->svga_reg_height,
+ vmwareReg->svga_reg_bits_per_pixel, vmwareReg->svga_reg_enable));
+ if (vmwareReg->svga_reg_enable) {
+ vmwareWriteReg(pVMWARE, SVGA_REG_WIDTH, vmwareReg->svga_reg_width);
+ vmwareWriteReg(pVMWARE, SVGA_REG_HEIGHT, vmwareReg->svga_reg_height);
+ vmwareWriteReg(pVMWARE, SVGA_REG_BITS_PER_PIXEL,
+ vmwareReg->svga_reg_bits_per_pixel);
+ vmwareWriteReg(pVMWARE, SVGA_REG_ENABLE, vmwareReg->svga_reg_enable);
+ vmwareWriteReg(pVMWARE, SVGA_REG_GUEST_ID, GUEST_OS_LINUX);
+ if (pVMWARE->hwCursor) {
+ vmwareWriteReg(pVMWARE, SVGA_REG_CURSOR_ID,
+ vmwareReg->svga_reg_cursor_id);
+ vmwareWriteReg(pVMWARE, SVGA_REG_CURSOR_X,
+ vmwareReg->svga_reg_cursor_x);
+ vmwareWriteReg(pVMWARE, SVGA_REG_CURSOR_Y,
+ vmwareReg->svga_reg_cursor_y);
+ vmwareWriteReg(pVMWARE, SVGA_REG_CURSOR_ON,
+ vmwareReg->svga_reg_cursor_on);
+ }
+ } else {
+ vmwareWriteReg(pVMWARE, SVGA_REG_ENABLE, vmwareReg->svga_reg_enable);
+ }
+}
+
+static void
+VMWARERestore(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr vgaReg = &hwp->SavedReg;
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ VMWARERegPtr vmwareReg = &pVMWARE->SavedReg;
+
+ vmwareWaitForFB(pVMWARE);
+ if (!vmwareReg->svga_fifo_enabled) {
+ VMWAREStopFIFO(pScrn);
+ }
+
+ vgaHWProtect(pScrn, TRUE);
+ VMWARERestoreRegs(pScrn, vmwareReg);
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
+ vgaHWProtect(pScrn, FALSE);
+}
+
+static Bool
+VMWAREModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr vgaReg = &hwp->ModeReg;
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ VMWARERegPtr vmwareReg = &pVMWARE->ModeReg;
+
+ vgaHWUnlock(hwp);
+ if (!vgaHWInit(pScrn, mode))
+ return FALSE;
+ pScrn->vtSema = TRUE;
+
+ vmwareReg->svga_reg_enable = 1;
+ vmwareReg->svga_reg_width = max(mode->HDisplay, pScrn->virtualX);
+ vmwareReg->svga_reg_height = max(mode->VDisplay, pScrn->virtualY);
+ vmwareReg->svga_reg_bits_per_pixel = pVMWARE->bitsPerPixel;
+
+ vgaHWProtect(pScrn, TRUE);
+
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
+ VMWARERestoreRegs(pScrn, vmwareReg);
+
+ if (pVMWARE->hwCursor) {
+ vmwareCursorModeInit(pScrn, mode);
+ }
+
+ VmwareLog(("Required mode: %ux%u\n", mode->HDisplay, mode->VDisplay));
+ VmwareLog(("Virtual: %ux%u\n", pScrn->virtualX, pScrn->virtualY));
+ VmwareLog(("dispWidth: %u\n", pScrn->displayWidth));
+ pVMWARE->fbOffset = vmwareReadReg(pVMWARE, SVGA_REG_FB_OFFSET);
+ pVMWARE->fbPitch = vmwareReadReg(pVMWARE, SVGA_REG_BYTES_PER_LINE);
+ pVMWARE->FbSize = vmwareReadReg(pVMWARE, SVGA_REG_FB_SIZE);
+
+ pScrn->displayWidth = (pVMWARE->fbPitch * 8) / ((pScrn->bitsPerPixel + 7) & ~7);
+ VmwareLog(("fbOffset: %u\n", pVMWARE->fbOffset));
+ VmwareLog(("fbPitch: %u\n", pVMWARE->fbPitch));
+ VmwareLog(("fbSize: %u\n", pVMWARE->FbSize));
+ VmwareLog(("New dispWidth: %u\n", pScrn->displayWidth));
+
+ vgaHWProtect(pScrn, FALSE);
+
+ /*
+ * XXX -- If we want to check that we got the mode we asked for, this
+ * would be a good place.
+ */
+
+ /*
+ * Let XAA know about the mode change.
+ */
+ if (!pVMWARE->noAccel) {
+ if (!vmwareXAAModeInit(pScrn, mode)) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+static void
+VMWAREAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ /* FIXME */
+}
+
+static void
+VMWAREInitFIFO(ScrnInfoPtr pScrn)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ CARD32* vmwareFIFO;
+
+ TRACEPOINT
+
+ pVMWARE->mmioPhysBase = vmwareReadReg(pVMWARE, SVGA_REG_MEM_START);
+ pVMWARE->mmioSize = vmwareReadReg(pVMWARE, SVGA_REG_MEM_SIZE) & ~3;
+ pVMWARE->mmioVirtBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
+ pVMWARE->PciTag,
+ pVMWARE->mmioPhysBase,
+ pVMWARE->mmioSize);
+ vmwareFIFO = pVMWARE->vmwareFIFO = (CARD32*)pVMWARE->mmioVirtBase;
+ vmwareFIFO[SVGA_FIFO_MIN] = 4 * sizeof(CARD32);
+ vmwareFIFO[SVGA_FIFO_MAX] = pVMWARE->mmioSize;
+ vmwareFIFO[SVGA_FIFO_NEXT_CMD] = 4 * sizeof(CARD32);
+ vmwareFIFO[SVGA_FIFO_STOP] = 4 * sizeof(CARD32);
+ vmwareWriteReg(pVMWARE, SVGA_REG_CONFIG_DONE, 1);
+}
+
+static void
+VMWAREStopFIFO(ScrnInfoPtr pScrn)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+
+ TRACEPOINT
+
+ vmwareWriteReg(pVMWARE, SVGA_REG_CONFIG_DONE, 0);
+ xf86UnMapVidMem(pScrn->scrnIndex, pVMWARE->mmioVirtBase, pVMWARE->mmioSize);
+}
+
+static Bool
+VMWARECloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ ScreenPtr save = &pVMWARE->ScrnFuncs;
+
+ VmwareLog(("cursorSema: %d\n", pVMWARE->cursorSema));
+
+ if (*pVMWARE->pvtSema) {
+ if (pVMWARE->CursorInfoRec) {
+ vmwareCursorCloseScreen(pScreen);
+ }
+
+ if (pVMWARE->xaaInfo) {
+ vmwareXAACloseScreen(pScreen);
+ }
+
+ VMWARERestore(pScrn);
+ VMWAREUnmapMem(pScrn);
+
+ pScrn->vtSema = FALSE;
+ }
+
+ pScreen->CloseScreen = save->CloseScreen;
+ pScreen->SaveScreen = save->SaveScreen;
+
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+}
+
+static Bool
+VMWARESaveScreen(ScreenPtr pScreen, int mode)
+{
+ VmwareLog(("VMWareSaveScreen() mode = %d\n", mode));
+
+ /*
+ * This thoroughly fails to do anything useful to svga mode. I doubt
+ * we care; who wants to idle-blank their VM's screen anyway?
+ */
+ return vgaHWSaveScreen(pScreen, mode);
+}
+
+/* disabled by default to reduce spew in DEBUG_LOGGING mode. */
+/*#define DEBUG_LOG_UPDATES*/
+
+static void
+VMWAREPreDirtyBBUpdate(ScrnInfoPtr pScrn, int nboxes, BoxPtr boxPtr)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+
+#ifdef DEBUG_LOG_UPDATES
+ {
+ int i;
+ for (i = 0; i < nboxes; i++) {
+ VmwareLog(("PreUpdate #%d (%d, %d, w = %d, h = %d)\n", nboxes - i,
+ boxPtr[i].x1, boxPtr[i].y1,
+ boxPtr[i].x2 - boxPtr[i].x1,
+ boxPtr[i].y2 - boxPtr[i].y1));
+ }
+ }
+#endif
+
+ /*
+ * We only register this callback if we have a HW cursor.
+ */
+ while (nboxes--) {
+ if (BOX_INTERSECT(*boxPtr, pVMWARE->hwcur.box)) {
+ PRE_OP_HIDE_CURSOR();
+ pVMWARE->cursorExcludedForUpdate = TRUE;
+ break;
+ }
+ boxPtr++;
+ }
+}
+
+static void
+VMWAREPostDirtyBBUpdate(ScrnInfoPtr pScrn, int nboxes, BoxPtr boxPtr)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ while (nboxes--) {
+#ifdef DEBUG_LOG_UPDATES
+ VmwareLog(("PostUpdate #%d (%d, %d, w = %d, h = %d)\n", nboxes,
+ boxPtr->x1, boxPtr->y1,
+ boxPtr->x2 - boxPtr->x1, boxPtr->y2 - boxPtr->y1));
+#endif
+
+ /* Clip off (y only) for offscreen memory */
+ if (boxPtr->y2 >= pVMWARE->ModeReg.svga_reg_height)
+ boxPtr->y2 = pVMWARE->ModeReg.svga_reg_height;
+ if (boxPtr->y1 >= pVMWARE->ModeReg.svga_reg_height)
+ boxPtr->y1 = pVMWARE->ModeReg.svga_reg_height;
+ if (boxPtr->y1 == boxPtr->y2) {
+ boxPtr++;
+ continue;
+ }
+
+ vmwareSendSVGACmdUpdate(pVMWARE, boxPtr++);
+ }
+
+ if (pVMWARE->hwCursor && pVMWARE->cursorExcludedForUpdate) {
+ POST_OP_SHOW_CURSOR();
+ pVMWARE->cursorExcludedForUpdate = FALSE;
+ }
+}
+
+static void
+VMWARELoadPalette(ScrnInfoPtr pScrn, int numColors, int* indices,
+ LOCO* colors, VisualPtr pVisual)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ int i;
+
+ for (i = 0; i < numColors; i++) {
+ vmwareWriteReg(pVMWARE, SVGA_PALETTE_BASE + *indices * 3 + 0, colors[*indices].red);
+ vmwareWriteReg(pVMWARE, SVGA_PALETTE_BASE + *indices * 3 + 1, colors[*indices].green);
+ vmwareWriteReg(pVMWARE, SVGA_PALETTE_BASE + *indices * 3 + 2, colors[*indices].blue);
+ indices++;
+ }
+ VmwareLog(("Palette loading done\n"));
+}
+
+static Bool
+VMWAREScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ ScrnInfoPtr pScrn;
+ vgaHWPtr hwp;
+ VMWAREPtr pVMWARE;
+
+ /* Get the ScrnInfoRec */
+ pScrn = xf86Screens[pScreen->myNum];
+ pVMWARE = VMWAREPTR(pScrn);
+
+ /*
+ * If using the vgahw module, its data structures and related
+ * things are typically initialised/mapped here.
+ */
+
+ hwp = VGAHWPTR(pScrn);
+ vgaHWGetIOBase(hwp);
+
+ /* Save the current video state */
+ VMWARESave(pScrn);
+
+ VMWAREInitFIFO(pScrn);
+
+ /* Initialise the first mode */
+ VMWAREModeInit(pScrn, pScrn->currentMode);
+
+ /* Set the viewport if supported */
+ VMWAREAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ /*
+ * Setup the screen's visuals, and initialise the framebuffer
+ * code.
+ */
+ VMWAREMapMem(pScrn);
+
+ /*
+ * Clear the framebuffer (and any black-border mode areas).
+ */
+ memset(pVMWARE->FbBase, 0, pVMWARE->FbSize);
+ vmwareSendSVGACmdUpdateFullScreen(pVMWARE);
+
+ /* Reset the visual list */
+ miClearVisualTypes();
+
+ /*
+ * Setup the visuals supported. This driver only supports
+ * TrueColor for bpp > 8, so the default set of visuals isn't
+ * acceptable. To deal with this, call miSetVisualTypes with
+ * the appropriate visual mask.
+ */
+
+ if (pScrn->bitsPerPixel > 8) {
+ if (!miSetVisualTypes(pScrn->depth, TrueColorMask,
+ pScrn->rgbBits, pScrn->defaultVisual)) {
+ return FALSE;
+ }
+ } else {
+ if (!miSetVisualTypes(pScrn->depth,
+ miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual)) {
+ return FALSE;
+ }
+ }
+
+ miSetPixmapDepths();
+
+ /*
+ * Initialise the framebuffer.
+ */
+ if (!fbScreenInit(pScreen, pVMWARE->FbBase + pVMWARE->fbOffset,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth,
+ pScrn->bitsPerPixel)) {
+ return FALSE;
+ }
+
+ /* Override the default mask/offset settings */
+ if (pScrn->bitsPerPixel > 8) {
+ int i;
+ VisualPtr visual;
+
+ for (i = 0, visual = pScreen->visuals;
+ i < pScreen->numVisuals; i++, visual++) {
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+ }
+
+ /* must be after RGB ordering fixed */
+ fbPictureInit (pScreen, 0, 0);
+
+ /*
+ * Save the old screen vector, then wrap CloseScreen and
+ * set SaveScreen.
+ */
+ pVMWARE->ScrnFuncs = *pScreen;
+ pScreen->CloseScreen = VMWARECloseScreen;
+ pScreen->SaveScreen = VMWARESaveScreen;
+
+ /*
+ * Set initial black & white colourmap indices.
+ */
+ xf86SetBlackWhitePixels(pScreen);
+
+ /*
+ * Initialize shadowfb to notify us of dirty rectangles. We only
+ * need preFB access callbacks if we're using the hw cursor.
+ */
+ if (!ShadowFBInit2(pScreen,
+ pVMWARE->hwCursor ? VMWAREPreDirtyBBUpdate : NULL,
+ VMWAREPostDirtyBBUpdate)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ShadowFB initialization failed\n");
+ return FALSE;
+ }
+
+ /*
+ * If we have a hw cursor, we need to hook functions that might
+ * read from the framebuffer.
+ */
+ if (pVMWARE->hwCursor) {
+ vmwareCursorHookWrappers(pScreen);
+ }
+
+ /*
+ * Initialize acceleration.
+ */
+ if (!pVMWARE->noAccel) {
+ if (!vmwareXAAScreenInit(pScreen)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "XAA initialization failed -- running unaccelerated!\n");
+ pVMWARE->noAccel = TRUE;
+ }
+ }
+
+ /*
+ * If backing store is to be supported (as is usually the case),
+ * initialise it.
+ */
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+ xf86SetSilkenMouse(pScreen);
+
+ /*
+ * Initialize software cursor.
+ */
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+ /*
+ * Initialize hardware cursor.
+ */
+ if (pVMWARE->hwCursor) {
+ if (!vmwareCursorInit(pScreen)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Hardware cursor initialization failed\n");
+ pVMWARE->hwCursor = FALSE;
+ }
+ }
+
+ /*
+ * Install colourmap functions. If using the vgahw module,
+ * vgaHandleColormaps would usually be called here.
+ */
+
+ if (!fbCreateDefColormap(pScreen))
+ return FALSE;
+
+ if (!xf86HandleColormaps(pScreen, 256, 8,
+ VMWARELoadPalette, NULL,
+ CMAP_PALETTED_TRUECOLOR |
+ CMAP_RELOAD_ON_MODE_SWITCH)) {
+ return FALSE;
+ }
+
+ /* Report any unused options (only for the first generation) */
+ if (serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ }
+
+ /* Done */
+ return TRUE;
+}
+
+static Bool
+VMWARESwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ return VMWAREModeInit(xf86Screens[scrnIndex], mode);
+}
+
+static Bool
+VMWAREEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+
+ if (!pVMWARE->SavedReg.svga_fifo_enabled) {
+ VMWAREInitFIFO(pScrn);
+ }
+ return VMWAREModeInit(pScrn, pScrn->currentMode);
+}
+
+static void
+VMWARELeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ VMWARERestore(pScrn);
+}
+
+static void
+VMWAREFreeScreen(int scrnIndex, int flags)
+{
+ /*
+ * If the vgahw module is used vgaHWFreeHWRec() would be called
+ * here.
+ */
+ VMWAREFreeRec(xf86Screens[scrnIndex]);
+}
+
+static Bool
+VMWAREValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+{
+ return MODE_OK;
+}
+
+static Bool
+VMWAREProbe(DriverPtr drv, int flags)
+{
+ int numDevSections, numUsed;
+ GDevPtr *devSections;
+ int *usedChips;
+ int i;
+ Bool foundScreen = FALSE;
+ char buildString[sizeof(VMWAREBuildStr)];
+
+ RewriteTagString(VMWAREBuildStr, buildString, sizeof(VMWAREBuildStr));
+ xf86MsgVerb(X_PROBED, 4, "%s", buildString);
+
+ numDevSections = xf86MatchDevice(VMWARE_DRIVER_NAME, &devSections);
+ if (numDevSections <= 0) {
+#ifdef DEBUG
+ xf86MsgVerb(X_ERROR, 0, "No vmware driver section\n");
+#endif
+ return FALSE;
+ }
+ if (xf86GetPciVideoInfo()) {
+ VmwareLog(("Some PCI Video Info Exists\n"));
+ numUsed = xf86MatchPciInstances(VMWARE_NAME, PCI_VENDOR_VMWARE,
+ VMWAREChipsets, VMWAREPciChipsets, devSections,
+ numDevSections, drv, &usedChips);
+ xfree(devSections);
+ if (numUsed <= 0)
+ return FALSE;
+ if (flags & PROBE_DETECT)
+ foundScreen = TRUE;
+ else
+ for (i = 0; i < numUsed; i++) {
+ ScrnInfoPtr pScrn = NULL;
+
+ VmwareLog(("Even some VMware SVGA PCI instances exists\n"));
+ pScrn = xf86ConfigPciEntity(pScrn, flags, usedChips[i],
+ VMWAREPciChipsets, NULL, NULL, NULL,
+ NULL, NULL);
+ if (pScrn) {
+ VmwareLog(("And even configuration suceeded\n"));
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = VMWARE_DRIVER_NAME;
+ pScrn->name = VMWARE_NAME;
+ pScrn->Probe = VMWAREProbe;
+ pScrn->PreInit = VMWAREPreInit;
+ pScrn->ScreenInit = VMWAREScreenInit;
+ pScrn->SwitchMode = VMWARESwitchMode;
+ pScrn->AdjustFrame = VMWAREAdjustFrame;
+ pScrn->EnterVT = VMWAREEnterVT;
+ pScrn->LeaveVT = VMWARELeaveVT;
+ pScrn->FreeScreen = VMWAREFreeScreen;
+ pScrn->ValidMode = VMWAREValidMode;
+ foundScreen = TRUE;
+ }
+ }
+ xfree(usedChips);
+ }
+ return foundScreen;
+}
+
+DriverRec VMWARE = {
+ VERSION,
+ VMWARE_DRIVER_NAME,
+ VMWAREIdentify,
+ VMWAREProbe,
+ VMWAREAvailableOptions,
+ NULL,
+ 0
+};
+
+#ifdef XFree86LOADER
+static MODULESETUPPROTO(vmwareSetup);
+
+XF86ModuleData vmwareModuleData = { &vmwareVersRec, vmwareSetup, NULL };
+
+static pointer
+vmwareSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ if (!setupDone) {
+ setupDone = TRUE;
+ xf86AddDriver(&VMWARE, module, 0);
+
+ LoaderRefSymLists(vgahwSymbols, fbSymbols, ramdacSymbols,
+ shadowfbSymbols, vmwareXaaSymbols, NULL);
+
+ return (pointer)1;
+ }
+ if (errmaj) {
+ *errmaj = LDR_ONCEONLY;
+ }
+ return NULL;
+}
+#endif /* XFree86LOADER */
diff --git a/src/vmware.h b/src/vmware.h
new file mode 100644
index 0000000..4059275
--- /dev/null
+++ b/src/vmware.h
@@ -0,0 +1,265 @@
+/* **********************************************************
+ * Copyright (C) 1998-2001 VMware, Inc.
+ * All Rights Reserved
+ * Id: vmware.h,v 1.6 2001/01/30 18:13:47 bennett Exp $
+ * **********************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vmware/vmware.h,v 1.10 2003/02/04 01:39:53 dawes Exp $ */
+
+#ifndef VMWARE_H
+#define VMWARE_H
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Resources.h"
+
+#include "compiler.h" /* inb/outb */
+
+#include "xf86PciInfo.h" /* pci vendor id */
+#include "xf86Pci.h" /* pci */
+#include "xf86Cursor.h" /* hw cursor */
+
+#include "vgaHW.h" /* VGA hardware */
+#include "fb.h"
+#include "xaa.h"
+
+#include "xf86cmap.h" /* xf86HandleColormaps */
+
+#include "vm_basic_types.h"
+#include "svga_reg.h"
+#include "svga_struct.h"
+
+#include "offscreen_manager.h"
+
+/* Arbitrarily choose max cursor dimensions. The emulation doesn't care. */
+#define MAX_CURS 32
+
+typedef struct {
+ CARD32 svga_reg_enable;
+ CARD32 svga_reg_width;
+ CARD32 svga_reg_height;
+ CARD32 svga_reg_bits_per_pixel;
+
+ CARD32 svga_reg_cursor_on;
+ CARD32 svga_reg_cursor_x;
+ CARD32 svga_reg_cursor_y;
+ CARD32 svga_reg_cursor_id;
+
+ Bool svga_fifo_enabled;
+} VMWARERegRec, *VMWARERegPtr;
+
+typedef struct {
+ EntityInfoPtr pEnt;
+ pciVideoPtr PciInfo;
+ PCITAG PciTag;
+ Bool Primary;
+ int depth;
+ int bitsPerPixel;
+ rgb weight;
+ rgb offset;
+ int defaultVisual;
+ int videoRam;
+ unsigned long memPhysBase;
+ unsigned long fbOffset;
+ unsigned long fbPitch;
+ unsigned long ioBase;
+ int maxWidth;
+ int maxHeight;
+ unsigned int vmwareCapability;
+
+ unsigned char* FbBase;
+ unsigned long FbSize;
+
+ VMWARERegRec SavedReg;
+ VMWARERegRec ModeReg;
+
+ Bool* pvtSema;
+
+ Bool noAccel;
+ Bool hwCursor;
+ Bool cursorDefined;
+ int cursorSema;
+ Bool cursorExcludedForUpdate;
+ Bool cursorShouldBeHidden;
+
+ unsigned int cursorRemoveFromFB;
+ unsigned int cursorRestoreToFB;
+
+#ifdef RENDER
+ CompositeProcPtr Composite;
+#endif /* RENDER */
+
+ unsigned long mmioPhysBase;
+ unsigned long mmioSize;
+
+ unsigned char* mmioVirtBase;
+ CARD32* vmwareFIFO;
+
+ xf86CursorInfoPtr CursorInfoRec;
+ struct {
+ int bg, fg, x, y;
+ BoxRec box;
+
+ uint32 mask[SVGA_BITMAP_SIZE(MAX_CURS, MAX_CURS)];
+ uint32 maskPixmap[SVGA_PIXMAP_SIZE(MAX_CURS, MAX_CURS, 32)];
+ uint32 source[SVGA_BITMAP_SIZE(MAX_CURS, MAX_CURS)];
+ uint32 sourcePixmap[SVGA_PIXMAP_SIZE(MAX_CURS, MAX_CURS, 32)];
+ } hwcur;
+
+ IOADDRESS indexReg, valueReg;
+
+ ScreenRec ScrnFuncs;
+
+ /*
+ * XAA info rec and misc storage
+ */
+ XAAInfoRecPtr xaaInfo;
+ int xaaFGColor;
+ int xaaBGColor;
+ int xaaRop;
+
+ unsigned char* xaaColorExpScanLine[1];
+ unsigned int xaaColorExpSize; /* size of current scan line in DWords */
+
+ Heap* heap;
+ SVGASurface* frontBuffer;
+
+ SVGASurface* curPict;
+ int op;
+
+} VMWARERec, *VMWAREPtr;
+
+#define VMWAREPTR(p) ((VMWAREPtr)((p)->driverPrivate))
+
+static __inline ScrnInfoPtr infoFromScreen(ScreenPtr s) {
+ return xf86Screens[s->myNum];
+}
+
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#define ABS(x) (((x) >= 0) ? (x) : -(x))
+
+#define BOX_INTERSECT(a, b) \
+ (ABS(((a).x1 + (a).x2) - ((b).x1 + (b).x2)) <= \
+ ((a).x2 - (a).x1) + ((b).x2 - (b).x1) && \
+ ABS(((a).y1 + (a).y2) - ((b).y1 + (b).y2)) <= \
+ ((a).y2 - (a).y1) + ((b).y2 - (b).y1))
+
+#define SVGA_GLYPH_SCANLINE_SIZE_DWORDS(w) (((w) + 31) >> 5)
+
+#define PRE_OP_HIDE_CURSOR() \
+ if (pVMWARE->cursorDefined && *pVMWARE->pvtSema) { \
+ pVMWARE->cursorSema++; \
+ if (pVMWARE->cursorSema == 1) { \
+ vmwareWriteCursorRegs(pVMWARE, FALSE, FALSE); \
+ } \
+ }
+#define POST_OP_SHOW_CURSOR() \
+ if (pVMWARE->cursorDefined && *pVMWARE->pvtSema) { \
+ pVMWARE->cursorSema--; \
+ if (!pVMWARE->cursorSema && !pVMWARE->cursorShouldBeHidden) { \
+ vmwareWriteCursorRegs(pVMWARE, TRUE, FALSE); \
+ } \
+ }
+
+#define MOUSE_ID 1
+
+extern const char *vmwareXaaSymbols[];
+
+/*#define DEBUG_LOGGING*/
+#ifdef DEBUG_LOGGING
+# define VmwareLog(args) ErrorF args
+# define TRACEPOINT VmwareLog((__FUNCTION__ ":" __FILE__ "\n"));
+#else
+# define VmwareLog(args)
+# define TRACEPOINT
+#endif
+
+/* Undefine this to kill all acceleration */
+#define ACCELERATE_OPS
+
+void vmwareWriteReg(
+#if NeedFunctionPrototypes
+ VMWAREPtr pVMWARE, int index, CARD32 value
+#endif
+ );
+
+CARD32 vmwareReadReg(
+#if NeedFunctionPrototypes
+ VMWAREPtr pVMWARE, int index
+#endif
+ );
+
+void vmwareWriteWordToFIFO(
+#if NeedFunctionPrototypes
+ VMWAREPtr pVMWARE, CARD32 value
+#endif
+ );
+
+void vmwareWaitForFB(
+#ifdef NeedFunctionPrototypes
+ VMWAREPtr pVMWARE
+#endif
+ );
+
+void vmwareSendSVGACmdUpdate(
+#if NeedFunctionPrototypes
+ VMWAREPtr pVMWARE, BoxPtr pBB
+#endif
+ );
+
+/* vmwarecurs.c */
+Bool vmwareCursorInit(
+#if NeedFunctionPrototypes
+ ScreenPtr pScr
+#endif
+ );
+
+void vmwareCursorModeInit(
+#if NeedFunctionPrototypes
+ ScrnInfoPtr pScrn,
+ DisplayModePtr mode
+#endif
+ );
+
+void vmwareCursorCloseScreen(
+#if NeedFunctionPrototypes
+ ScreenPtr pScr
+#endif
+ );
+
+void vmwareWriteCursorRegs(
+#if NeedFunctionPrototypes
+ VMWAREPtr pVMWARE,
+ Bool visible,
+ Bool force
+#endif
+ );
+
+void vmwareCursorHookWrappers(
+#if NeedFunctionPrototypes
+ ScreenPtr pScreen
+#endif
+ );
+
+
+/* vmwarexaa.c */
+Bool vmwareXAAScreenInit(
+#if NeedFunctionPrototypes
+ ScreenPtr pScreen
+#endif
+ );
+
+Bool vmwareXAAModeInit(
+#if NeedFunctionPrototypes
+ ScrnInfoPtr pScrn, DisplayModePtr mode
+#endif
+ );
+
+void vmwareXAACloseScreen(
+#if NeedFunctionPrototypes
+ ScreenPtr pScreen
+#endif
+ );
+
+#endif
diff --git a/src/vmwarecurs.c b/src/vmwarecurs.c
new file mode 100644
index 0000000..1a7c6eb
--- /dev/null
+++ b/src/vmwarecurs.c
@@ -0,0 +1,445 @@
+/* **********************************************************
+ * Copyright (C) 1998-2001 VMware, Inc.
+ * All Rights Reserved
+ * **********************************************************/
+#ifdef VMX86_DEVEL
+char rcsId_vmwarecurs[] =
+ "Id: vmwarecurs.c,v 1.5 2001/01/30 23:33:02 bennett Exp $";
+#endif
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vmware/vmwarecurs.c,v 1.11 2003/02/05 12:47:42 dawes Exp $ */
+
+#include "vmware.h"
+#include "bits2pixels.h"
+
+static void VMWAREGetImage(DrawablePtr src, int x, int y, int w, int h,
+ unsigned int format, unsigned long planeMask,
+ char *pBinImage);
+static void VMWARECopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc);
+
+#ifdef RENDER
+static void VMWAREComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask,
+ PicturePtr pDst, INT16 xSrc, INT16 ySrc,
+ INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst,
+ CARD16 width, CARD16 height);
+#endif /* RENDER */
+
+static void
+RedefineCursor(VMWAREPtr pVMWARE)
+{
+ int i;
+
+ VmwareLog(("RedefineCursor\n"));
+
+ pVMWARE->cursorDefined = FALSE;
+
+ /* Define cursor */
+ vmwareWriteWordToFIFO(pVMWARE, SVGA_CMD_DEFINE_CURSOR);
+ vmwareWriteWordToFIFO(pVMWARE, MOUSE_ID);
+ vmwareWriteWordToFIFO(pVMWARE, 0); /* HotX/HotY seem to be zero? */
+ vmwareWriteWordToFIFO(pVMWARE, 0); /* HotX/HotY seem to be zero? */
+ vmwareWriteWordToFIFO(pVMWARE, pVMWARE->CursorInfoRec->MaxWidth);
+ vmwareWriteWordToFIFO(pVMWARE, pVMWARE->CursorInfoRec->MaxHeight);
+ vmwareWriteWordToFIFO(pVMWARE, 1);
+ vmwareWriteWordToFIFO(pVMWARE, pVMWARE->bitsPerPixel);
+
+ /*
+ * Since we have AND and XOR masks rather than 'source' and 'mask',
+ * color expand 'mask' with all zero as its foreground and all one as
+ * its background. This makes 'image & 0 ^ 'source' = source. We
+ * arange for 'image' & 1 ^ 'source' = 'image' below when we clip
+ * 'source' below.
+ */
+ vmwareRaster_BitsToPixels((uint8 *) pVMWARE->hwcur.mask,
+ SVGA_BITMAP_INCREMENT(pVMWARE->CursorInfoRec->MaxWidth),
+ (uint8 *) pVMWARE->hwcur.maskPixmap,
+ SVGA_PIXMAP_INCREMENT(pVMWARE->CursorInfoRec->MaxWidth,
+ pVMWARE->bitsPerPixel),
+ pVMWARE->bitsPerPixel / 8,
+ pVMWARE->CursorInfoRec->MaxWidth,
+ pVMWARE->CursorInfoRec->MaxHeight, 0, ~0);
+ for (i = 0; i < SVGA_BITMAP_SIZE(pVMWARE->CursorInfoRec->MaxWidth,
+ pVMWARE->CursorInfoRec->MaxHeight); i++) {
+ vmwareWriteWordToFIFO(pVMWARE, ~pVMWARE->hwcur.mask[i]);
+ }
+
+ vmwareRaster_BitsToPixels((uint8 *) pVMWARE->hwcur.source,
+ SVGA_BITMAP_INCREMENT(pVMWARE->CursorInfoRec->MaxWidth),
+ (uint8 *) pVMWARE->hwcur.sourcePixmap,
+ SVGA_PIXMAP_INCREMENT(pVMWARE->CursorInfoRec->MaxWidth,
+ pVMWARE->bitsPerPixel),
+ pVMWARE->bitsPerPixel / 8,
+ pVMWARE->CursorInfoRec->MaxWidth,
+ pVMWARE->CursorInfoRec->MaxHeight,
+ pVMWARE->hwcur.fg, pVMWARE->hwcur.bg);
+ /*
+ * As pointed out above, we need to clip the expanded 'source' against
+ * the expanded 'mask' since we actually have AND and XOR masks in the
+ * virtual hardware. Effectively, 'source' becomes a three color fg/bg/0
+ * pixmap that XORs appropriately.
+ */
+ for (i = 0; i < SVGA_PIXMAP_SIZE(pVMWARE->CursorInfoRec->MaxWidth,
+ pVMWARE->CursorInfoRec->MaxHeight,
+ pVMWARE->bitsPerPixel); i++) {
+ pVMWARE->hwcur.sourcePixmap[i] &= ~pVMWARE->hwcur.maskPixmap[i];
+ vmwareWriteWordToFIFO(pVMWARE, pVMWARE->hwcur.sourcePixmap[i]);
+ }
+
+ /* Sync the FIFO, so that the definition preceeds any use of the cursor */
+ vmwareWaitForFB(pVMWARE);
+ pVMWARE->cursorDefined = TRUE;
+}
+
+static void
+vmwareSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ TRACEPOINT
+
+ if (pVMWARE->hwcur.fg != fg || pVMWARE->hwcur.bg != bg) {
+ VmwareLog(("SetCursorColors(0x%08x, 0x%08x)\n", bg, fg));
+ pVMWARE->hwcur.fg = fg;
+ pVMWARE->hwcur.bg = bg;
+ RedefineCursor(pVMWARE);
+ }
+}
+
+static void
+vmwareLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src )
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ const int imageSize = SVGA_BITMAP_SIZE(pVMWARE->CursorInfoRec->MaxWidth,
+ pVMWARE->CursorInfoRec->MaxHeight);
+ TRACEPOINT
+
+ memcpy(pVMWARE->hwcur.source, src, imageSize * sizeof(uint32));
+ memcpy(pVMWARE->hwcur.mask,
+ src + imageSize * sizeof(uint32), imageSize * sizeof(uint32));
+ RedefineCursor(pVMWARE);
+}
+
+#ifdef ARGB_CURSOR
+#include "cursorstr.h"
+
+static Bool
+vmwareUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs)
+{
+ ScrnInfoPtr pScrn = infoFromScreen(pScreen);
+ return pCurs->bits->height <= MAX_CURS &&
+ pCurs->bits->width <= MAX_CURS &&
+ pScrn->bitsPerPixel > 8;
+}
+
+static void
+vmwareLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ CARD32 width = pCurs->bits->width;
+ CARD32 height = pCurs->bits->height;
+ CARD32* image = pCurs->bits->argb;
+ CARD32* imageEnd = image + (width * height);
+
+ pVMWARE->cursorDefined = FALSE;
+
+ vmwareWriteWordToFIFO(pVMWARE, SVGA_CMD_DEFINE_ALPHA_CURSOR);
+ vmwareWriteWordToFIFO(pVMWARE, MOUSE_ID);
+ vmwareWriteWordToFIFO(pVMWARE, 0);
+ vmwareWriteWordToFIFO(pVMWARE, 0);
+ vmwareWriteWordToFIFO(pVMWARE, width);
+ vmwareWriteWordToFIFO(pVMWARE, height);
+
+ while (image != imageEnd) {
+ vmwareWriteWordToFIFO(pVMWARE, *image++);
+ }
+
+ vmwareWaitForFB(pVMWARE);
+
+ pVMWARE->cursorDefined = TRUE;
+}
+#endif
+
+void
+vmwareWriteCursorRegs(VMWAREPtr pVMWARE, Bool visible, Bool force)
+{
+ int enableVal;
+
+ vmwareWriteReg(pVMWARE, SVGA_REG_CURSOR_ID, MOUSE_ID);
+ if (visible) {
+ vmwareWriteReg(pVMWARE, SVGA_REG_CURSOR_X, pVMWARE->hwcur.x);
+ vmwareWriteReg(pVMWARE, SVGA_REG_CURSOR_Y, pVMWARE->hwcur.y);
+ }
+
+ if (force) {
+ enableVal = visible ? SVGA_CURSOR_ON_SHOW : SVGA_CURSOR_ON_HIDE;
+ } else {
+ enableVal = visible ? pVMWARE->cursorRestoreToFB :
+ pVMWARE->cursorRemoveFromFB;
+ }
+ vmwareWriteReg(pVMWARE, SVGA_REG_CURSOR_ON, enableVal);
+}
+
+/* disabled by default to reduce spew in DEBUG_LOGGING mode. */
+/* #define DEBUG_LOG_MOUSE_HIDE_SHOW */
+
+static void
+vmwareShowCursor(ScrnInfoPtr pScrn)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+#ifdef DEBUG_LOG_MOUSE_HIDE_SHOW
+ VmwareLog(("Show: %d %d %d\n", pVMWARE->cursorSema, pVMWARE->cursorDefined,
+ pVMWARE->cursorShouldBeHidden));
+#endif
+ pVMWARE->cursorShouldBeHidden = FALSE;
+ if (pVMWARE->cursorSema == 0 && pVMWARE->cursorDefined) {
+ vmwareWriteCursorRegs(pVMWARE, TRUE, TRUE);
+ }
+}
+
+static void
+vmwareHideCursor(ScrnInfoPtr pScrn)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+#ifdef DEBUG_LOG_MOUSE_HIDE_SHOW
+ VmwareLog(("Hide: %d %d %d\n", pVMWARE->cursorSema, pVMWARE->cursorDefined,
+ pVMWARE->cursorShouldBeHidden));
+#endif
+ if (pVMWARE->cursorDefined) {
+ vmwareWriteCursorRegs(pVMWARE, FALSE, TRUE);
+ }
+ pVMWARE->cursorShouldBeHidden = TRUE;
+}
+
+/* disabled by default to reduce spew in DEBUG_LOGGING mode. */
+/* #define DEBUG_LOG_MOUSE_MOVE */
+
+static void
+vmwareSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+#ifdef DEBUG_LOG_MOUSE_MOVE
+ VmwareLog(("Move: %d %d %d\n", pVMWARE->cursorSema, pVMWARE->cursorDefined,
+ pVMWARE->cursorShouldBeHidden));
+#endif
+ /*
+ * We're bad people. We have no concept of a frame (VMWAREAdjustFrame()
+ * is a NOP). The hwcursor code expects us to be frame aware though, so
+ * we have to do this. I'm open to suggestions. I tried not even
+ * hooking AdjustFrame and it didn't help.
+ */
+ pVMWARE->hwcur.x = x + pScrn->frameX0;
+ pVMWARE->hwcur.y = y + pScrn->frameY0;
+ pVMWARE->hwcur.box.x1 = pVMWARE->hwcur.x;
+ pVMWARE->hwcur.box.x2 = pVMWARE->hwcur.x + pVMWARE->CursorInfoRec->MaxWidth;
+ pVMWARE->hwcur.box.y1 = pVMWARE->hwcur.y;
+ pVMWARE->hwcur.box.y2 = pVMWARE->hwcur.y + pVMWARE->CursorInfoRec->MaxHeight;
+
+ vmwareShowCursor(pScrn);
+}
+
+void
+vmwareCursorModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+
+ if (pVMWARE->cursorDefined) {
+ vmwareWriteCursorRegs(pVMWARE, !pVMWARE->cursorShouldBeHidden, TRUE);
+ }
+}
+
+Bool
+vmwareCursorInit(ScreenPtr pScreen)
+{
+ xf86CursorInfoPtr infoPtr;
+ VMWAREPtr pVMWARE = VMWAREPTR(infoFromScreen(pScreen));
+ Bool ret;
+
+ TRACEPOINT
+
+ /* Require cursor bypass for hwcursor. Ignore deprecated FIFO hwcursor */
+ if (!(pVMWARE->vmwareCapability & SVGA_CAP_CURSOR_BYPASS)) {
+ return FALSE;
+ }
+
+ infoPtr = xf86CreateCursorInfoRec();
+ if (!infoPtr)
+ return FALSE;
+
+ pVMWARE->CursorInfoRec = infoPtr;
+
+ infoPtr->MaxWidth = MAX_CURS;
+ infoPtr->MaxHeight = MAX_CURS;
+ infoPtr->Flags = HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
+ HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED;
+ infoPtr->SetCursorColors = vmwareSetCursorColors;
+ infoPtr->SetCursorPosition = vmwareSetCursorPosition;
+ infoPtr->LoadCursorImage = vmwareLoadCursorImage;
+ infoPtr->HideCursor = vmwareHideCursor;
+ infoPtr->ShowCursor = vmwareShowCursor;
+
+#ifdef ARGB_CURSOR
+ if (pVMWARE->vmwareCapability & SVGA_CAP_ALPHA_CURSOR) {
+ infoPtr->UseHWCursorARGB = vmwareUseHWCursorARGB;
+ infoPtr->LoadCursorARGB = vmwareLoadCursorARGB;
+ }
+#endif
+
+ ret = xf86InitCursor(pScreen, infoPtr);
+ if (!ret) {
+ xf86DestroyCursorInfoRec(infoPtr);
+ pVMWARE->CursorInfoRec = NULL;
+ }
+ return ret;
+}
+
+void
+vmwareCursorCloseScreen(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = infoFromScreen(pScreen);
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+#ifdef RENDER
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+#endif
+
+ pScreen->GetImage = pVMWARE->ScrnFuncs.GetImage;
+ pScreen->CopyWindow = pVMWARE->ScrnFuncs.CopyWindow;
+#ifdef RENDER
+ if (ps) {
+ ps->Composite = pVMWARE->Composite;
+ }
+#endif /* RENDER */
+
+ vmwareHideCursor(pScrn);
+ xf86DestroyCursorInfoRec(pVMWARE->CursorInfoRec);
+}
+
+/*** Wrap functions that read from the framebuffer ***/
+
+void
+vmwareCursorHookWrappers(ScreenPtr pScreen)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(infoFromScreen(pScreen));
+#ifdef RENDER
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+#endif
+
+ TRACEPOINT
+
+ pVMWARE->ScrnFuncs.GetImage = pScreen->GetImage;
+ pVMWARE->ScrnFuncs.CopyWindow = pScreen->CopyWindow;
+ pScreen->GetImage = VMWAREGetImage;
+ pScreen->CopyWindow = VMWARECopyWindow;
+
+#ifdef RENDER
+ if (ps) {
+ pVMWARE->Composite = ps->Composite;
+ ps->Composite = VMWAREComposite;
+ }
+#endif /* RENDER */
+
+}
+
+static void
+VMWAREGetImage(DrawablePtr src, int x, int y, int w, int h,
+ unsigned int format, unsigned long planeMask, char *pBinImage)
+{
+ ScreenPtr pScreen = src->pScreen;
+ VMWAREPtr pVMWARE = VMWAREPTR(infoFromScreen(src->pScreen));
+ BoxRec box;
+ Bool hidden = FALSE;
+
+ VmwareLog(("VMWAREGetImage(%p, %d, %d, %d, %d, %d, %d, %p)\n",
+ src, x, y, w, h, format, planeMask, pBinImage));
+
+ box.x1 = src->x + x;
+ box.y1 = src->y + y;
+ box.x2 = box.x1 + w;
+ box.y2 = box.y1 + h;
+
+ if (BOX_INTERSECT(box, pVMWARE->hwcur.box)) {
+ PRE_OP_HIDE_CURSOR();
+ hidden = TRUE;
+ }
+
+ pScreen->GetImage = pVMWARE->ScrnFuncs.GetImage;
+ (*pScreen->GetImage)(src, x, y, w, h, format, planeMask, pBinImage);
+ pScreen->GetImage = VMWAREGetImage;
+
+ if (hidden) {
+ POST_OP_SHOW_CURSOR();
+ }
+}
+
+static void
+VMWARECopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ VMWAREPtr pVMWARE = VMWAREPTR(infoFromScreen(pWin->drawable.pScreen));
+ BoxPtr pBB;
+ Bool hidden = FALSE;
+
+ /*
+ * We only worry about the source region here, since shadowfb will
+ * take care of the destination region.
+ */
+ pBB = REGION_EXTENTS(pWin->drawable.pScreen, prgnSrc);
+
+ VmwareLog(("VMWARECopyWindow(%p, (%d, %d), (%d, %d - %d, %d)\n",
+ pWin, ptOldOrg.x, ptOldOrg.y,
+ pBB->x1, pBB->y1, pBB->x2, pBB->y2));
+
+ if (BOX_INTERSECT(*pBB, pVMWARE->hwcur.box)) {
+ PRE_OP_HIDE_CURSOR();
+ hidden = TRUE;
+ }
+
+ pScreen->CopyWindow = pVMWARE->ScrnFuncs.CopyWindow;
+ (*pScreen->CopyWindow)(pWin, ptOldOrg, prgnSrc);
+ pScreen->CopyWindow = VMWARECopyWindow;
+
+ if (hidden) {
+ POST_OP_SHOW_CURSOR();
+ }
+}
+
+#ifdef RENDER
+static void
+VMWAREComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask,
+ PicturePtr pDst, INT16 xSrc, INT16 ySrc,
+ INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst,
+ CARD16 width, CARD16 height)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ VMWAREPtr pVMWARE = VMWAREPTR(infoFromScreen(pScreen));
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ BoxRec box;
+ Bool hidden = FALSE;
+
+ VmwareLog(("VMWAREComposite op = %d, pSrc = %p, pMask = %p, pDst = %p,"
+ " src = (%d, %d), mask = (%d, %d), dst = (%d, %d), w = %d,"
+ " h = %d\n", op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
+ xDst, yDst, width, height));
+
+ /*
+ * We only worry about the source region here, since shadowfb or XAA will
+ * take care of the destination region.
+ */
+ box.x1 = pSrc->pDrawable->x + xSrc;
+ box.y1 = pSrc->pDrawable->y + ySrc;
+ box.x2 = box.x1 + width;
+ box.y2 = box.y1 + height;
+
+ if (BOX_INTERSECT(box, pVMWARE->hwcur.box)) {
+ PRE_OP_HIDE_CURSOR();
+ hidden = TRUE;
+ }
+
+ ps->Composite = pVMWARE->Composite;
+ (*ps->Composite)(op, pSrc, pMask, pDst, xSrc, ySrc,
+ xMask, yMask, xDst, yDst, width, height);
+ ps->Composite = VMWAREComposite;
+
+ if (hidden) {
+ POST_OP_SHOW_CURSOR();
+ }
+}
+#endif /* RENDER */
diff --git a/src/vmwarexaa.c b/src/vmwarexaa.c
new file mode 100644
index 0000000..b8e67cf
--- /dev/null
+++ b/src/vmwarexaa.c
@@ -0,0 +1,549 @@
+/* **********************************************************
+ * Copyright (C) 1998-2001 VMware, Inc.
+ * All Rights Reserved
+ * **********************************************************/
+#ifdef VMX86_DEVEL
+char rcsId_vmwarexaa[] =
+ "Id: $";
+#endif
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vmware/vmwarexaa.c,v 1.5 2003/02/04 01:39:53 dawes Exp $ */
+
+#include "vmware.h"
+
+#define OFFSCREEN_SCRATCH_SIZE 1*1024*1024
+/* We'll assume we average about 32x32 alpha surfaces (4096 bytes) or larger */
+#define OFFSCREEN_SCRATCH_MAX_SLOTS OFFSCREEN_SCRATCH_SIZE / 4096
+
+const char *vmwareXaaSymbols[] = {
+ "XAACreateInfoRec",
+ "XAADestroyInfoRec",
+ "XAAInit",
+ NULL
+};
+
+static void vmwareXAASync(ScrnInfoPtr pScrn);
+
+static void vmwareSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask);
+static void vmwareSubsequentSolidFillRect(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h);
+
+static void vmwareSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask,
+ int trans_color);
+static void vmwareSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int x1, int y1,
+ int x2, int y2,
+ int width, int height);
+
+static void vmwareSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask);
+static void vmwareSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y,
+ int w, int h,
+ int skipleft );
+static void vmwareSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
+
+#ifdef RENDER
+static Bool vmwareSetupForCPUToScreenAlphaTexture(ScrnInfoPtr pScrn, int op,
+ CARD16 red, CARD16 green,
+ CARD16 blue, CARD16 alpha,
+ int alphaType, CARD8 *alphaPtr,
+ int alphaPitch,
+ int width, int height,
+ int flags);
+
+static Bool vmwareSetupForCPUToScreenTexture(ScrnInfoPtr pScrn, int op,
+ int texType, CARD8 *texPtr,
+ int texPitch,
+ int width, int height,
+ int flags);
+
+static void vmwareSubsequentCPUToScreenTexture(ScrnInfoPtr pScrn,
+ int dstx, int dsty,
+ int srcx, int srcy,
+ int width, int height);
+
+CARD32 vmwareAlphaTextureFormats[2] = {PICT_a8, 0};
+CARD32 vmwareTextureFormats[2] = {PICT_a8r8g8b8, 0};
+
+#endif
+
+#define DESTROY_XAA_INFO(pVMWARE) \
+ if (pVMWARE->xaaInfo) { XAADestroyInfoRec(pVMWARE->xaaInfo); \
+ pVMWARE->xaaInfo = NULL; }
+
+Bool
+vmwareXAAScreenInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ XAAInfoRecPtr xaaInfo;
+
+ pVMWARE->xaaInfo = XAACreateInfoRec();
+ if (!pVMWARE->xaaInfo) {
+ return FALSE;
+ }
+
+ xaaInfo = pVMWARE->xaaInfo;
+
+ xaaInfo->Sync = vmwareXAASync;
+
+ if (pVMWARE->vmwareCapability & SVGA_CAP_RECT_FILL) {
+ xaaInfo->SetupForSolidFill = vmwareSetupForSolidFill;
+ xaaInfo->SubsequentSolidFillRect = vmwareSubsequentSolidFillRect;
+
+ xaaInfo->SolidFillFlags = NO_PLANEMASK |
+ (pVMWARE->vmwareCapability & SVGA_CAP_RASTER_OP ? 0 : GXCOPY_ONLY);
+ }
+
+ if (pVMWARE->vmwareCapability & SVGA_CAP_RECT_COPY) {
+ xaaInfo->SetupForScreenToScreenCopy = vmwareSetupForScreenToScreenCopy;
+ xaaInfo->SubsequentScreenToScreenCopy =
+ vmwareSubsequentScreenToScreenCopy;
+
+ xaaInfo->ScreenToScreenCopyFlags = NO_TRANSPARENCY | NO_PLANEMASK |
+ (pVMWARE->vmwareCapability & SVGA_CAP_RASTER_OP ? 0 : GXCOPY_ONLY);
+ }
+
+ /*
+ * We don't support SVGA_CAP_GLYPH without clipping, since we use clipping
+ * for normal glyphs.
+ */
+ if (pVMWARE->vmwareCapability & SVGA_CAP_GLYPH_CLIPPING) {
+ xaaInfo->SetupForScanlineCPUToScreenColorExpandFill =
+ vmwareSetupForScanlineCPUToScreenColorExpandFill;
+ xaaInfo->SubsequentScanlineCPUToScreenColorExpandFill =
+ vmwareSubsequentScanlineCPUToScreenColorExpandFill;
+ xaaInfo->SubsequentColorExpandScanline =
+ vmwareSubsequentColorExpandScanline;
+
+ xaaInfo->NumScanlineColorExpandBuffers = 1;
+ xaaInfo->ScanlineColorExpandBuffers = pVMWARE->xaaColorExpScanLine;
+
+ xaaInfo->ScanlineCPUToScreenColorExpandFillFlags = GXCOPY_ONLY |
+ NO_PLANEMASK | BIT_ORDER_IN_BYTE_MSBFIRST | LEFT_EDGE_CLIPPING;
+ }
+
+ if (pVMWARE->vmwareCapability & SVGA_CAP_OFFSCREEN_1) {
+ int scratchSizeBytes = ((OFFSCREEN_SCRATCH_SIZE + pVMWARE->fbPitch - 1) /
+ pVMWARE->fbPitch) * pVMWARE->fbPitch;
+ BoxRec box;
+ RegionRec region;
+
+ box.x1 = 0;
+ box.y1 = (pVMWARE->FbSize + pVMWARE->fbPitch - 1) / pVMWARE->fbPitch;
+ box.x2 = pScrn->displayWidth;
+ box.y2 = pVMWARE->videoRam / pVMWARE->fbPitch;
+
+#ifdef RENDER
+ if (pVMWARE->vmwareCapability & SVGA_CAP_ALPHA_BLEND &&
+ pScrn->bitsPerPixel > 8) {
+ if (box.y2 - (scratchSizeBytes / pVMWARE->fbPitch) > box.y1 + 4) {
+ CARD8* osPtr = pVMWARE->FbBase + pVMWARE->videoRam -
+ scratchSizeBytes;
+ box.y2 -= scratchSizeBytes / pVMWARE->fbPitch;
+
+ VmwareLog(("Allocated %d bytes at offset %d for alpha scratch\n",
+ scratchSizeBytes,
+ pVMWARE->videoRam - scratchSizeBytes));
+
+ pVMWARE->heap = vmwareHeap_Create(osPtr,
+ scratchSizeBytes,
+ OFFSCREEN_SCRATCH_MAX_SLOTS,
+ pVMWARE->videoRam - scratchSizeBytes,
+ pScrn->virtualX,
+ pScrn->virtualY,
+ pVMWARE->bitsPerPixel,
+ pVMWARE->fbPitch,
+ pVMWARE->fbOffset);
+ pVMWARE->frontBuffer = vmwareHeap_GetFrontBuffer(pVMWARE->heap);
+
+ xaaInfo->SetupForCPUToScreenAlphaTexture =
+ vmwareSetupForCPUToScreenAlphaTexture;
+ xaaInfo->SubsequentCPUToScreenAlphaTexture =
+ vmwareSubsequentCPUToScreenTexture;
+ xaaInfo->CPUToScreenAlphaTextureFlags = XAA_RENDER_NO_TILE |
+ XAA_RENDER_NO_SRC_ALPHA;
+ xaaInfo->CPUToScreenAlphaTextureFormats = vmwareAlphaTextureFormats;
+
+ xaaInfo->SetupForCPUToScreenTexture =
+ vmwareSetupForCPUToScreenTexture;
+ xaaInfo->SubsequentCPUToScreenTexture =
+ vmwareSubsequentCPUToScreenTexture;
+ xaaInfo->CPUToScreenTextureFlags = XAA_RENDER_NO_TILE;
+ xaaInfo->CPUToScreenTextureFormats = vmwareTextureFormats;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Allocation of offscreen "
+ "scratch area for alpha blending failed\n");
+ }
+ }
+#endif
+
+ if (box.y2 > box.y1) {
+ REGION_INIT(pScreen, &region, &box, 1);
+
+ if (REGION_NOTEMPTY(pScreen, &region) &&
+ xf86InitFBManagerRegion(pScreen, &region)) {
+ VmwareLog(("Offscreen memory initialized: (%d, %d) - (%d, %d)\n",
+ box.x1, box.y1, box.x2, box.y2));
+
+ xaaInfo->Flags =
+ LINEAR_FRAMEBUFFER | PIXMAP_CACHE | OFFSCREEN_PIXMAPS;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Offscreen memory manager "
+ "initialization failed.\n");
+ }
+
+ REGION_UNINIT(pScreen, &region);
+ }
+ }
+
+ if (!XAAInit(pScreen, xaaInfo)) {
+ DESTROY_XAA_INFO(pVMWARE);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool
+vmwareXAAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+
+ /*
+ * Alloc a sufficiently large buffer for XAA to render scanlines
+ * for a color expand into.
+ */
+ if (pVMWARE->vmwareCapability & SVGA_CAP_GLYPH) {
+ /*
+ * This formula came straight from the XAA.HOWTO doc. The +62 is
+ * there because we potentially have 31 extra bits off to the left,
+ * since we claim LEFT_EDGE_CLIPPING support.
+ */
+ int scanLineSize = ((pScrn->virtualX + 62)/32) * 4;
+ if (pVMWARE->xaaColorExpScanLine[0]) {
+ xfree(pVMWARE->xaaColorExpScanLine[0]);
+ }
+ pVMWARE->xaaColorExpScanLine[0] = xalloc(scanLineSize);
+ return pVMWARE->xaaColorExpScanLine[0] != NULL;
+ }
+
+ return TRUE;
+}
+
+void
+vmwareXAACloseScreen(ScreenPtr pScreen)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(xf86Screens[pScreen->myNum]);
+
+ if (pVMWARE->xaaColorExpScanLine[0]) {
+ xfree(pVMWARE->xaaColorExpScanLine[0]);
+ pVMWARE->xaaColorExpScanLine[0] = NULL;
+ }
+
+ DESTROY_XAA_INFO(pVMWARE);
+
+#ifdef RENDER
+ if (pVMWARE->heap) {
+ vmwareHeap_Destroy(pVMWARE->heap);
+ pVMWARE->heap = NULL;
+ }
+#endif
+}
+
+static void
+vmwareXAASync(ScrnInfoPtr pScrn)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+
+ VmwareLog(("Sync\n"));
+
+ vmwareWaitForFB(pVMWARE);
+
+#ifdef RENDER
+ if (pVMWARE->heap) {
+ vmwareHeap_Clear(pVMWARE->heap);
+ }
+#endif
+}
+
+static void
+vmwareSetupForSolidFill(ScrnInfoPtr pScrn,
+ int color, int rop, unsigned int planemask)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ pVMWARE->xaaFGColor = color;
+ pVMWARE->xaaRop = rop;
+
+ VmwareLog(("Setup Solid Fill (color = %d, rop = %d)\n", color, rop));
+}
+
+static void
+vmwareSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+
+ VmwareLog((" Do Solid Fill (x = %d, y = %d, w = %d, h = %d)\n", x, y, w, h));
+
+ if (pVMWARE->xaaRop != GXcopy) {
+ /*
+ * We'll never get here if SVGA_CAP_RASTER_OP isn't set, since
+ * we tell XAA we are GXCOPY_ONLY.
+ */
+ vmwareWriteWordToFIFO(pVMWARE, SVGA_CMD_RECT_ROP_FILL);
+ vmwareWriteWordToFIFO(pVMWARE, pVMWARE->xaaFGColor);
+ vmwareWriteWordToFIFO(pVMWARE, x);
+ vmwareWriteWordToFIFO(pVMWARE, y);
+ vmwareWriteWordToFIFO(pVMWARE, w);
+ vmwareWriteWordToFIFO(pVMWARE, h);
+ vmwareWriteWordToFIFO(pVMWARE, pVMWARE->xaaRop);
+ } else {
+ vmwareWriteWordToFIFO(pVMWARE, SVGA_CMD_RECT_FILL);
+ vmwareWriteWordToFIFO(pVMWARE, pVMWARE->xaaFGColor);
+ vmwareWriteWordToFIFO(pVMWARE, x);
+ vmwareWriteWordToFIFO(pVMWARE, y);
+ vmwareWriteWordToFIFO(pVMWARE, w);
+ vmwareWriteWordToFIFO(pVMWARE, h);
+ }
+}
+
+static void
+vmwareSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask,
+ int trans_color)
+{
+ /*
+ * We can safely ignore xdir and ydir since our "hardware" is smart
+ * enough to figure out the direction from the srcx/y, dstx/y, w and h.
+ */
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ pVMWARE->xaaRop = rop;
+
+ VmwareLog(("Setup Screen2Screen copy (rop = %d)\n", rop));
+}
+
+static void
+vmwareSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int x1, int y1,
+ int x2, int y2,
+ int width, int height)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+
+ VmwareLog((" Do Screen2Screen copy (x1 = %d, y1 = %d, x2 = %d, y2 = %d,"
+ " w = %d, h = %d)\n", x1, y1, x2, y2, width, height));
+
+ if (pVMWARE->xaaRop != GXcopy) {
+ /*
+ * We'll never get here if SVGA_CAP_RASTER_OP isn't set, since
+ * we tell XAA we are GXCOPY_ONLY.
+ */
+ vmwareWriteWordToFIFO(pVMWARE, SVGA_CMD_RECT_ROP_COPY);
+ vmwareWriteWordToFIFO(pVMWARE, x1);
+ vmwareWriteWordToFIFO(pVMWARE, y1);
+ vmwareWriteWordToFIFO(pVMWARE, x2);
+ vmwareWriteWordToFIFO(pVMWARE, y2);
+ vmwareWriteWordToFIFO(pVMWARE, width);
+ vmwareWriteWordToFIFO(pVMWARE, height);
+ vmwareWriteWordToFIFO(pVMWARE, pVMWARE->xaaRop);
+ } else {
+ vmwareWriteWordToFIFO(pVMWARE, SVGA_CMD_RECT_COPY);
+ vmwareWriteWordToFIFO(pVMWARE, x1);
+ vmwareWriteWordToFIFO(pVMWARE, y1);
+ vmwareWriteWordToFIFO(pVMWARE, x2);
+ vmwareWriteWordToFIFO(pVMWARE, y2);
+ vmwareWriteWordToFIFO(pVMWARE, width);
+ vmwareWriteWordToFIFO(pVMWARE, height);
+ }
+}
+
+static void
+vmwareSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+
+ pVMWARE->xaaFGColor = fg;
+ pVMWARE->xaaBGColor = bg;
+ VmwareLog(("Setup color expand (fg = %d, bg = %d, rop = %d)\n",
+ fg, bg, rop));
+}
+
+static void
+vmwareSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y,
+ int w, int h,
+ int skipleft )
+{
+ /*
+ * XXX TODO: if xaaColorExpSize will fit entirely into the FIFO,
+ * temporarily switch to direct mode, and have XAA write bits
+ * directly into the fifo. See ATI driver for an example.
+ */
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+
+ pVMWARE->xaaColorExpSize = SVGA_GLYPH_SCANLINE_SIZE_DWORDS(w);
+
+ VmwareLog((" Do color expand (x = %d, y = %d, w = %d, h = %d,"
+ " skipleft = %d, sizedw = %d)\n",
+ x, y, w, h, skipleft, pVMWARE->xaaColorExpSize));
+
+ vmwareWriteWordToFIFO(pVMWARE, SVGA_CMD_DRAW_GLYPH_CLIPPED);
+ vmwareWriteWordToFIFO(pVMWARE, x);
+ vmwareWriteWordToFIFO(pVMWARE, y);
+ vmwareWriteWordToFIFO(pVMWARE, pVMWARE->xaaColorExpSize * 32U);
+ vmwareWriteWordToFIFO(pVMWARE, h);
+ vmwareWriteWordToFIFO(pVMWARE, pVMWARE->xaaFGColor);
+ vmwareWriteWordToFIFO(pVMWARE, pVMWARE->xaaBGColor);
+ vmwareWriteWordToFIFO(pVMWARE, x + skipleft);
+ vmwareWriteWordToFIFO(pVMWARE, y);
+ vmwareWriteWordToFIFO(pVMWARE, w - skipleft);
+ vmwareWriteWordToFIFO(pVMWARE, h);
+}
+
+static void
+vmwareSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ CARD32* scanLine = (CARD32*)pVMWARE->xaaColorExpScanLine[0];
+ unsigned int dwords = pVMWARE->xaaColorExpSize;
+
+ while (dwords--) {
+ vmwareWriteWordToFIFO(pVMWARE, *scanLine++);
+ }
+}
+
+#ifdef RENDER
+
+static void
+RGBPlusAlphaChannelToPremultipliedRGBA(
+ CARD8 red, CARD8 blue, CARD8 green,
+ CARD8 *alphaPtr, /* in bytes */
+ int alphaPitch,
+ CARD32 *dstPtr,
+ int dstPitch, /* in dwords */
+ int width, int height)
+{
+ int x;
+
+ while (height--) {
+ for (x = 0; x < width; x++) {
+ CARD8 alpha = alphaPtr[x];
+ dstPtr[x] = (alpha << 24) |
+ ((red * alpha / 255) << 16) |
+ ((green * alpha / 255) << 8) |
+ (blue * alpha / 255);
+ }
+ dstPtr += dstPitch;
+ alphaPtr += alphaPitch;
+ }
+}
+
+Bool
+vmwareSetupForCPUToScreenAlphaTexture(ScrnInfoPtr pScrn, int op,
+ CARD16 red, CARD16 green,
+ CARD16 blue, CARD16 alpha,
+ int alphaType, CARD8 *alphaPtr,
+ int alphaPitch,
+ int width, int height,
+ int flags)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ SVGASurface* surf;
+
+ VmwareLog(("Setup alpha texture (op = %d, r = %d, g = %d, b = %d,"
+ " a = %d, alphaType = %d, alphaPitch = %d, w = %d, h = %d,"
+ " flags = %d)\n", op, red, green, blue, alpha, alphaType,
+ alphaPitch, width, height, flags));
+
+ if (op > PictOpSaturate) {
+ return FALSE;
+ }
+
+ surf = vmwareHeap_AllocSurface(pVMWARE->heap, width, height, width * 4, 32);
+
+ if (!surf) {
+ return FALSE;
+ }
+
+ RGBPlusAlphaChannelToPremultipliedRGBA(
+ red >> 8, green >> 8, blue >> 8,
+ alphaPtr, alphaPitch,
+ (CARD32*)(pVMWARE->FbBase + surf->dataOffset),
+ width, width, height);
+
+ pVMWARE->curPict = surf;
+ pVMWARE->op = op;
+
+ return TRUE;
+}
+
+Bool
+vmwareSetupForCPUToScreenTexture(ScrnInfoPtr pScrn, int op,
+ int texType, CARD8 *texPtr,
+ int texPitch,
+ int width, int height,
+ int flags)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+ SVGASurface* surf;
+
+ VmwareLog(("Setup texture (op = %d, texType = %d, texPitch = %d,"
+ " w = %d, h = %d, flags = %d)\n", op, texType, texPitch,
+ width, height, flags));
+
+ if (op > PictOpSaturate) {
+ return FALSE;
+ }
+
+ surf = vmwareHeap_AllocSurface(pVMWARE->heap, width, height, texPitch, 32);
+
+ if (!surf) {
+ return FALSE;
+ }
+
+ memcpy(pVMWARE->FbBase + surf->dataOffset, texPtr, texPitch * height);
+
+ pVMWARE->curPict = surf;
+ pVMWARE->op = op;
+
+ return TRUE;
+}
+
+void
+vmwareSubsequentCPUToScreenTexture(ScrnInfoPtr pScrn,
+ int dstx, int dsty,
+ int srcx, int srcy,
+ int width, int height)
+{
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+
+ VmwareLog((" Do texture (dstx = %d, dsty = %d, srcx = %d, srcy = %d"
+ " w = %d, h = %d)\n", dstx, dsty, srcx, srcy, width, height));
+
+ pVMWARE->curPict->numQueued++;
+ pVMWARE->frontBuffer->numQueued++;
+
+ vmwareWriteWordToFIFO(pVMWARE, SVGA_CMD_SURFACE_ALPHA_BLEND);
+ vmwareWriteWordToFIFO(pVMWARE, (CARD8*)pVMWARE->curPict - pVMWARE->FbBase);
+ vmwareWriteWordToFIFO(pVMWARE, (CARD8*)pVMWARE->frontBuffer - pVMWARE->FbBase);
+ vmwareWriteWordToFIFO(pVMWARE, srcx);
+ vmwareWriteWordToFIFO(pVMWARE, srcy);
+ vmwareWriteWordToFIFO(pVMWARE, dstx);
+ vmwareWriteWordToFIFO(pVMWARE, dsty);
+ vmwareWriteWordToFIFO(pVMWARE, width);
+ vmwareWriteWordToFIFO(pVMWARE, height);
+ vmwareWriteWordToFIFO(pVMWARE, pVMWARE->op);
+ vmwareWriteWordToFIFO(pVMWARE, 0); /* flags */
+ vmwareWriteWordToFIFO(pVMWARE, 0); /* param1 */
+ vmwareWriteWordToFIFO(pVMWARE, 0); /* param2 */
+}
+#endif