xserver: Branch 'master'

Keith Packard keithp at kemper.freedesktop.org
Thu Mar 15 09:22:30 EET 2007


 hw/xfree86/Makefile.am         |    1 
 hw/xfree86/loader/Makefile.am  |    3 
 hw/xfree86/loader/loadmod.c    |    3 
 hw/xfree86/loader/xf86sym.c    |    5 
 hw/xfree86/modes/Makefile.am   |    4 
 hw/xfree86/modes/xf86Crtc.h    |  103 ++++++-
 hw/xfree86/modes/xf86Cursors.c |  595 +++++++++++++++++++++++++++++++++++++++++
 hw/xfree86/ramdac/Makefile.am  |    6 
 hw/xfree86/ramdac/xf86Cursor.h |    3 
 9 files changed, 710 insertions(+), 13 deletions(-)

New commits:
diff-tree ae75019ccf1edac9e8be31b6a96293624f672ccb (from 4bf1b280f7cb676ec2b172f26dd2ad9bac2eb2ca)
Author: Keith Packard <keithp at guitar.keithp.com>
Date:   Wed Mar 14 23:59:29 2007 -0700

    Create driver-independent CRTC-based cursor layer.
    
    This moves most of the cursor management code out of the intel driver and
    into the general server code. Of course, the hope is that this code will be
    useful for other driver writers as well.
    
    Check out xf86Crtc.h for the usage information, making sure you add the
    needed hooks to the crtc funcs structure for your driver.
    (cherry picked from commit 4d81c99a4660a0bf9014f789de55edabd185bd14)

diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am
index b669063..50aa673 100644
--- a/hw/xfree86/Makefile.am
+++ b/hw/xfree86/Makefile.am
@@ -56,6 +56,7 @@ XORG_LIBS = \
             parser/libxf86config.a \
 	    dixmods/libdixmods.la \
 	    modes/libxf86modes.a \
+	    ramdac/libramdac.a \
 	    ddc/libddc.a \
 	    i2c/libi2c.a \
             @XORG_LIBS@
diff --git a/hw/xfree86/loader/Makefile.am b/hw/xfree86/loader/Makefile.am
index ceb66a2..ef9ab9a 100644
--- a/hw/xfree86/loader/Makefile.am
+++ b/hw/xfree86/loader/Makefile.am
@@ -2,7 +2,8 @@ noinst_LIBRARIES = libloader.a
 
 INCLUDES = $(XORG_INCS) -I$(srcdir)/../parser -I$(srcdir)/../dixmods/extmod \
 	   -I$(srcdir)/../vbe -I$(top_srcdir)/miext/cw -I$(srcdir)/../int10 \
-	   -I$(srcdir)/../ddc -I$(srcdir)/../i2c -I$(srcdir)/../modes
+	   -I$(srcdir)/../ddc -I$(srcdir)/../i2c -I$(srcdir)/../modes \
+	   -I$(srcdir)/../ramdac
 
 #AM_LDFLAGS = -r
 AM_CFLAGS = -DIN_LOADER $(DIX_CFLAGS) $(XORG_CFLAGS)
diff --git a/hw/xfree86/loader/loadmod.c b/hw/xfree86/loader/loadmod.c
index e489212..c220d8a 100644
--- a/hw/xfree86/loader/loadmod.c
+++ b/hw/xfree86/loader/loadmod.c
@@ -841,6 +841,7 @@ DuplicateModule(ModuleDescPtr mod, Modul
 static const char *compiled_in_modules[] = {
     "ddc",
     "i2c",
+    "ramdac",
     NULL
 };
 
@@ -861,7 +862,7 @@ doLoadModule(const char *module, const c
     PatternPtr patterns = NULL;
     int noncanonical = 0;
     char *m = NULL;
-    char **cim;
+    const char **cim;
 
     xf86MsgVerb(X_INFO, 3, "LoadModule: \"%s\"", module);
 
diff --git a/hw/xfree86/loader/xf86sym.c b/hw/xfree86/loader/xf86sym.c
index 6337265..bc7c814 100644
--- a/hw/xfree86/loader/xf86sym.c
+++ b/hw/xfree86/loader/xf86sym.c
@@ -1220,6 +1220,11 @@ _X_HIDDEN void *xfree86LookupTab[] = {
     SYMFUNC(xf86RandR12SetConfig)
     SYMFUNC(xf86RandR12SetRotations)
 #endif
+    SYMFUNC(xf86_cursors_init)
+    SYMFUNC(xf86_reload_cursors)
+    SYMFUNC(xf86_show_cursors)
+    SYMFUNC(xf86_hide_cursors)
+    SYMFUNC(xf86_cursors_fini)
 
     SYMFUNC(xf86DoEDID_DDC1)
     SYMFUNC(xf86DoEDID_DDC2)
diff --git a/hw/xfree86/modes/Makefile.am b/hw/xfree86/modes/Makefile.am
index e0b6136..1f82068 100644
--- a/hw/xfree86/modes/Makefile.am
+++ b/hw/xfree86/modes/Makefile.am
@@ -3,6 +3,7 @@ noinst_LIBRARIES = libxf86modes.a
 libxf86modes_a_SOURCES = \
 	xf86Crtc.c \
 	xf86Crtc.h \
+	xf86Cursors.c \
 	xf86cvt.c \
 	xf86DiDGA.c \
 	xf86EdidModes.c \
@@ -16,7 +17,8 @@ libxf86modes_a_SOURCES = \
 INCLUDES = $(XORG_INCS) -I$(srcdir)/../ddc -I$(srcdir)/../i2c \
 	   -I$(srcdir)/../loader -I$(srcdir)/../rac -I$(srcdir)/../parser \
            -I$(srcdir)/../scanpci -I$(srcdir)/../vbe -I$(srcdir)/../int10 \
-	   -I$(srcdir)/../vgahw -I$(srcdir)/../dixmods/extmod
+	   -I$(srcdir)/../vgahw -I$(srcdir)/../ramdac \
+	   -I$(srcdir)/../dixmods/extmod
 
 sdk_HEADERS = \
 	xf86Crtc.h \
diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index 6152ae4..df8a8aa 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -28,6 +28,7 @@
 #include "xf86Rename.h"
 #endif
 #include "xf86Modes.h"
+#include "xf86Cursor.h"
 #include "damage.h"
 
 /* Compat definitions for older X Servers. */
@@ -37,6 +38,9 @@
 #ifndef M_T_DRIVER
 #define M_T_DRIVER	0x40
 #endif
+#ifndef HARDWARE_CURSOR_ARGB
+#define HARDWARE_CURSOR_ARGB				0x00004000
+#endif
 
 typedef struct _xf86Crtc xf86CrtcRec, *xf86CrtcPtr;
 typedef struct _xf86Output xf86OutputRec, *xf86OutputPtr;
@@ -155,6 +159,42 @@ typedef struct _xf86CrtcFuncs {
     (*shadow_destroy) (xf86CrtcPtr crtc, PixmapPtr pPixmap, void *data);
 
     /**
+     * Set cursor colors
+     */
+    void
+    (*set_cursor_colors) (xf86CrtcPtr crtc, int bg, int fg);
+
+    /**
+     * Set cursor position
+     */
+    void
+    (*set_cursor_position) (xf86CrtcPtr crtc, int x, int y);
+
+    /**
+     * Show cursor
+     */
+    void
+    (*show_cursor) (xf86CrtcPtr crtc);
+
+    /**
+     * Hide cursor
+     */
+    void
+    (*hide_cursor) (xf86CrtcPtr crtc);
+
+    /**
+     * Load monochrome image
+     */
+    void
+    (*load_cursor_image) (xf86CrtcPtr crtc, CARD8 *image);
+
+    /**
+     * Load ARGB image
+     */
+     void
+     (*load_cursor_argb) (xf86CrtcPtr crtc, CARD32 *image);
+     
+    /**
      * Clean up driver-specific bits of the crtc
      */
     void
@@ -174,12 +214,6 @@ struct _xf86Crtc {
      */
     Bool	    enabled;
     
-    /** Track whether cursor is within CRTC range  */
-    Bool	    cursorInRange;
-    
-    /** Track state of cursor associated with this CRTC */
-    Bool	    cursorShown;
-    
     /**
      * Active mode
      *
@@ -232,6 +266,19 @@ struct _xf86Crtc {
 #else
     void	    *randr_crtc;
 #endif
+
+    /**
+     * Current cursor is ARGB
+     */
+    Bool	    cursor_argb;
+    /**
+     * Track whether cursor is within CRTC range 
+     */
+    Bool	    cursor_in_range;
+    /**
+     * Track state of cursor associated with this CRTC
+     */
+    Bool	    cursor_shown;
 };
 
 typedef struct _xf86OutputFuncs {
@@ -495,6 +542,13 @@ typedef struct _xf86CrtcConfig {
     const xf86CrtcConfigFuncsRec *funcs;
 
     CreateScreenResourcesProcPtr    CreateScreenResources;
+
+    /* Cursor information */
+    xf86CursorInfoPtr	cursor_info;
+    CursorPtr		cursor;
+    CARD8		*cursor_image;
+    Bool		cursor_on;
+    CARD32		cursor_fg, cursor_bg;
 } xf86CrtcConfigRec, *xf86CrtcConfigPtr;
 
 extern int xf86CrtcConfigPrivateIndex;
@@ -637,4 +691,41 @@ xf86ConnectorGetName(xf86ConnectorType c
 Bool
 xf86SetDesiredModes (ScrnInfoPtr pScrn);
 
+/**
+ * Initialize the CRTC-based cursor code. CRTC function vectors must
+ * contain relevant cursor setting functions.
+ *
+ * Driver should call this from ScreenInit function
+ */
+Bool
+xf86_cursors_init (ScreenPtr screen, int max_width, int max_height, int flags);
+
+/**
+ * Called when anything on the screen is reconfigured.
+ *
+ * Reloads cursor images as needed, then adjusts cursor positions.
+ * 
+ * Driver should call this from crtc commit function.
+ */
+void
+xf86_reload_cursors (ScreenPtr screen);
+
+/**
+ * Called from EnterVT to turn the cursors back on
+ */
+void
+xf86_show_cursors (ScrnInfoPtr scrn);
+
+/**
+ * Called by the driver to turn cursors off
+ */
+void
+xf86_hide_cursors (ScrnInfoPtr scrn);
+
+/**
+ * Clean up CRTC-based cursor code. Driver must call this at CloseScreen time.
+ */
+void
+xf86_cursors_fini (ScreenPtr screen);
+    
 #endif /* _XF86CRTC_H_ */
diff --git a/hw/xfree86/modes/xf86Cursors.c b/hw/xfree86/modes/xf86Cursors.c
new file mode 100644
index 0000000..095df48
--- /dev/null
+++ b/hw/xfree86/modes/xf86Cursors.c
@@ -0,0 +1,595 @@
+/*
+ * Copyright © 2007 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#else
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#endif
+
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "xf86.h"
+#include "xf86DDC.h"
+#include "xf86Crtc.h"
+#include "xf86Modes.h"
+#include "xf86RandR12.h"
+#include "X11/extensions/render.h"
+#define DPMS_SERVER
+#include "X11/extensions/dpms.h"
+#include "X11/Xatom.h"
+#ifdef RENDER
+#include "picturestr.h"
+#endif
+#include "cursorstr.h"
+
+/*
+ * Given a screen coordinate, rotate back to a cursor source coordinate
+ */
+static void
+xf86_crtc_rotate_coord (Rotation    rotation,
+			int	    width,
+			int	    height,
+			int	    x_dst,
+			int	    y_dst,
+			int	    *x_src,
+			int	    *y_src)
+{
+    if (rotation & RR_Reflect_X)
+	x_dst = width - x_dst - 1;
+    if (rotation & RR_Reflect_Y)
+	y_dst = height - y_dst - 1;
+    
+    switch (rotation & 0xf) {
+    case RR_Rotate_0:
+	*x_src = x_dst;
+	*y_src = y_dst;
+	break;
+    case RR_Rotate_90:
+	*x_src = height - y_dst - 1;
+	*y_src = x_dst;
+	break;
+    case RR_Rotate_180:
+	*x_src = width - x_dst - 1;
+	*y_src = height - y_dst - 1;
+	break;
+    case RR_Rotate_270:
+	*x_src = y_dst;
+	*y_src = width - x_dst - 1;
+	break;
+    }
+}
+
+/*
+ * Convert an x coordinate to a position within the cursor bitmap
+ */
+static int
+cursor_bitpos (int flags, int x, Bool mask)
+{
+    if (flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK)
+	mask = !mask;
+    if (flags & HARDWARE_CURSOR_NIBBLE_SWAPPED)
+	x = (x & ~3) | (3 - (x & 3));
+    if (flags & HARDWARE_CURSOR_BIT_ORDER_MSBFIRST)
+	x = (x & ~7) | (7 - (x & 7));
+    if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1)
+	x = (x << 1) + mask;
+    else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8)
+	x = ((x & ~7) << 1) | (mask << 3) | (x & 7);
+    else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16)
+	x = ((x & ~15) << 1) | (mask << 4) | (x & 15);
+    else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32)
+	x = ((x & ~31) << 1) | (mask << 5) | (x & 31);
+    else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64)
+	x = ((x & ~63) << 1) | (mask << 6) | (x & 63);
+    return x;
+}
+
+/*
+ * Fetch one bit from a cursor bitmap
+ */
+static CARD8
+get_bit (CARD8 *image, int stride, int flags, int x, int y, Bool mask)
+{
+    x = cursor_bitpos (flags, x, mask);
+    image += y * stride;
+    return (image[(x >> 3)] >> (x & 7)) & 1;
+}
+
+/*
+ * Set one bit in a cursor bitmap
+ */
+static void
+set_bit (CARD8 *image, int stride, int flags, int x, int y, Bool mask)
+{
+    x = cursor_bitpos (flags, x, mask);
+    image += y * stride;
+    image[(x >> 3)] |= 1 << (x & 7);
+}
+    
+/*
+ * Load a two color cursor into a driver that supports only ARGB cursors
+ */
+static void
+xf86_crtc_convert_cursor_to_argb (xf86CrtcPtr crtc, unsigned char *src)
+{
+    ScrnInfoPtr		scrn = crtc->scrn;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    xf86CursorInfoPtr	cursor_info = xf86_config->cursor_info;
+    CARD32		*cursor_image = (CARD32 *) xf86_config->cursor_image;
+    int			x, y;
+    int			xin, yin;
+    int			stride = cursor_info->MaxWidth >> 2;
+    int			flags = cursor_info->Flags;
+    CARD32		bits;
+
+#ifdef ARGB_CURSOR
+    crtc->cursor_argb = FALSE;
+#endif
+
+    for (y = 0; y < cursor_info->MaxHeight; y++)
+	for (x = 0; x < cursor_info->MaxWidth; x++) 
+	{
+	    xf86_crtc_rotate_coord (crtc->rotation,
+				    cursor_info->MaxWidth,
+				    cursor_info->MaxHeight,
+				    x, y, &xin, &yin);
+	    if (get_bit (src, stride, flags, xin, yin, TRUE) ==
+		((flags & HARDWARE_CURSOR_INVERT_MASK) == 0))
+	    {
+		if (get_bit (src, stride, flags, xin, yin, FALSE))
+		    bits = xf86_config->cursor_fg;
+		else
+		    bits = xf86_config->cursor_bg;
+	    }
+	    else
+		bits = 0;
+	    cursor_image[y * cursor_info->MaxWidth + x] = bits;
+	}
+    crtc->funcs->load_cursor_argb (crtc, cursor_image);
+}
+
+/*
+ * Set the colors for a two-color cursor (ignore for ARGB cursors)
+ */
+static void
+xf86_set_cursor_colors (ScrnInfoPtr scrn, int bg, int fg)
+{
+    ScreenPtr		screen = scrn->pScreen;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    CursorPtr		cursor = xf86_config->cursor;
+    int			c;
+    CARD8		*bits = cursor ? cursor->devPriv[screen->myNum] : NULL;
+
+    /* Save ARGB versions of these colors */
+    xf86_config->cursor_fg = (CARD32) fg | 0xff000000;
+    xf86_config->cursor_bg = (CARD32) bg | 0xff000000;
+    
+    for (c = 0; c < xf86_config->num_crtc; c++)
+    {
+	xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+	if (crtc->enabled && !crtc->cursor_argb)
+	{
+	    if (crtc->funcs->load_cursor_image)
+		crtc->funcs->set_cursor_colors (crtc, bg, fg);
+	    else if (bits)
+		xf86_crtc_convert_cursor_to_argb (crtc, bits);
+	}
+    }
+}
+
+static void
+xf86_crtc_hide_cursor (xf86CrtcPtr crtc)
+{
+    if (crtc->cursor_shown)
+    {
+	crtc->funcs->hide_cursor (crtc);
+	crtc->cursor_shown = FALSE;
+    }
+}
+
+void
+xf86_hide_cursors (ScrnInfoPtr scrn)
+{
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    int			c;
+
+    xf86_config->cursor_on = FALSE;
+    for (c = 0; c < xf86_config->num_crtc; c++)
+    {
+	xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+	if (crtc->enabled)
+	    xf86_crtc_hide_cursor (crtc);
+    }
+}
+    
+static void
+xf86_crtc_show_cursor (xf86CrtcPtr crtc)
+{
+    if (!crtc->cursor_shown && crtc->cursor_in_range)
+    {
+	crtc->funcs->show_cursor (crtc);
+	crtc->cursor_shown = TRUE;
+    }
+}
+
+void
+xf86_show_cursors (ScrnInfoPtr scrn)
+{
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    int			c;
+
+    xf86_config->cursor_on = TRUE;
+    for (c = 0; c < xf86_config->num_crtc; c++)
+    {
+	xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+	if (crtc->enabled)
+	    xf86_crtc_show_cursor (crtc);
+    }
+}
+    
+static void
+xf86_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
+{
+    ScrnInfoPtr		scrn = crtc->scrn;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    xf86CursorInfoPtr	cursor_info = xf86_config->cursor_info;
+    DisplayModePtr	mode = &crtc->mode;
+    int			x_temp;
+    int			y_temp;
+    Bool		in_range;
+
+    /* 
+     * Move to crtc coordinate space
+     */
+    x -= crtc->x;
+    y -= crtc->y;
+    
+    /*
+     * Rotate
+     */
+    switch ((crtc->rotation) & 0xf) {
+    case RR_Rotate_0:
+	break;
+    case RR_Rotate_90:
+	x_temp = y;
+	y_temp = mode->VDisplay - cursor_info->MaxWidth - x;
+	x = x_temp;
+	y = y_temp;
+	break;
+    case RR_Rotate_180:
+	x_temp = mode->HDisplay - cursor_info->MaxWidth - x;
+	y_temp = mode->VDisplay - cursor_info->MaxHeight - y;
+	x = x_temp;
+	y = y_temp;
+	break;
+    case RR_Rotate_270:
+	x_temp = mode->HDisplay - cursor_info->MaxHeight -  y;
+	y_temp = x;
+	x = x_temp;
+	y = y_temp;
+	break;
+    }
+    
+    /*
+     * Reflect
+     */
+    if (crtc->rotation & RR_Reflect_X)
+	x = mode->HDisplay - cursor_info->MaxWidth - x;
+    if (crtc->rotation & RR_Reflect_Y)
+	y = mode->VDisplay - cursor_info->MaxHeight - y;
+
+    /*
+     * Disable the cursor when it is outside the viewport
+     */
+    in_range = TRUE;
+    if (x >= mode->HDisplay || y >= mode->VDisplay ||
+	x <= -cursor_info->MaxWidth || y <= -cursor_info->MaxHeight) 
+    {
+	in_range = FALSE;
+	x = 0;
+	y = 0;
+    }
+
+    crtc->cursor_in_range = in_range;
+    
+    if (in_range)
+    {
+	crtc->funcs->set_cursor_position (crtc, x, y);
+	xf86_crtc_show_cursor (crtc);
+    }
+    else
+	xf86_crtc_hide_cursor (crtc);
+}
+
+static void
+xf86_set_cursor_position (ScrnInfoPtr scrn, int x, int y)
+{
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    int			c;
+
+    /* undo what xf86HWCurs did to the coordinates */
+    x += scrn->frameX0;
+    y += scrn->frameY0;
+    for (c = 0; c < xf86_config->num_crtc; c++)
+    {
+	xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+	if (crtc->enabled)
+	    xf86_crtc_set_cursor_position (crtc, x, y);
+    }
+}
+    
+/*
+ * Load a two-color cursor into a crtc, performing rotation as needed
+ */
+static void
+xf86_crtc_load_cursor_image (xf86CrtcPtr crtc, CARD8 *src)
+{
+    ScrnInfoPtr		scrn = crtc->scrn;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    xf86CursorInfoPtr	cursor_info = xf86_config->cursor_info;
+    CARD8		*cursor_image;
+
+#ifdef ARGB_CURSOR
+    crtc->cursor_argb = FALSE;
+#endif
+
+    if (crtc->rotation == RR_Rotate_0)
+	cursor_image = src;
+    else
+    {
+        int x, y;
+    	int xin, yin;
+	int stride = cursor_info->MaxWidth >> 2;
+	int flags = cursor_info->Flags;
+	
+	cursor_image = xf86_config->cursor_image;
+	memset(cursor_image, 0, cursor_info->MaxWidth * stride);
+	
+        for (y = 0; y < cursor_info->MaxHeight; y++)
+	    for (x = 0; x < cursor_info->MaxWidth; x++) 
+	    {
+		xf86_crtc_rotate_coord (crtc->rotation,
+					cursor_info->MaxWidth,
+					cursor_info->MaxHeight,
+					x, y, &xin, &yin);
+		if (get_bit(src, stride, flags, xin, yin, FALSE))
+		    set_bit(cursor_image, stride, flags, x, y, FALSE);
+		if (get_bit(src, stride, flags, xin, yin, TRUE))
+		    set_bit(cursor_image, stride, flags, x, y, TRUE);
+	    }
+    }
+    crtc->funcs->load_cursor_image (crtc, cursor_image);
+}
+    
+/*
+ * Load a cursor image into all active CRTCs
+ */
+static void
+xf86_load_cursor_image (ScrnInfoPtr scrn, unsigned char *src)
+{
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    int			c;
+
+    for (c = 0; c < xf86_config->num_crtc; c++)
+    {
+	xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+	if (crtc->enabled)
+	{
+	    if (crtc->funcs->load_cursor_image)
+		xf86_crtc_load_cursor_image (crtc, src);
+	    else if (crtc->funcs->load_cursor_argb)
+		xf86_crtc_convert_cursor_to_argb (crtc, src);
+	}
+    }
+}
+
+static Bool
+xf86_use_hw_cursor (ScreenPtr screen, CursorPtr cursor)
+{
+    ScrnInfoPtr		scrn = xf86Screens[screen->myNum];
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    xf86CursorInfoPtr	cursor_info = xf86_config->cursor_info;
+
+    xf86_config->cursor = cursor;
+    
+    if (cursor->bits->width > cursor_info->MaxWidth ||
+	cursor->bits->height> cursor_info->MaxHeight)
+	return FALSE;
+
+    return TRUE;
+}
+
+static Bool
+xf86_use_hw_cursor_argb (ScreenPtr screen, CursorPtr cursor)
+{
+    ScrnInfoPtr		scrn = xf86Screens[screen->myNum];
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    xf86CursorInfoPtr	cursor_info = xf86_config->cursor_info;
+    
+    xf86_config->cursor = cursor;
+    
+    /* Make sure ARGB support is available */
+    if ((cursor_info->Flags & HARDWARE_CURSOR_ARGB) == 0)
+	return FALSE;
+    
+    if (cursor->bits->width > cursor_info->MaxWidth ||
+	cursor->bits->height> cursor_info->MaxHeight)
+	return FALSE;
+
+    return TRUE;
+}
+
+static void
+xf86_crtc_load_cursor_argb (xf86CrtcPtr crtc, CursorPtr cursor)
+{
+    ScrnInfoPtr		scrn = crtc->scrn;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    xf86CursorInfoPtr	cursor_info = xf86_config->cursor_info;
+    CARD32		*cursor_image = (CARD32 *) xf86_config->cursor_image;
+    CARD32		*cursor_source = (CARD32 *) cursor->bits->argb;
+    int			x, y;
+    int			xin, yin;
+    CARD32		bits;
+    int			source_width = cursor->bits->width;
+    int			source_height = cursor->bits->height;
+    int			image_width = cursor_info->MaxWidth;
+    int			image_height = cursor_info->MaxHeight;
+    
+    for (y = 0; y < image_height; y++)
+	for (x = 0; x < image_width; x++)
+	{
+	    xf86_crtc_rotate_coord (crtc->rotation, image_width, image_height,
+				    x, y, &xin, &yin);
+	    if (xin < source_width && yin < source_height)
+		bits = cursor_source[yin * source_width + xin];
+	    else
+		bits = 0;
+	    cursor_image[y * image_width + x] = bits;
+	}
+    
+    crtc->funcs->load_cursor_argb (crtc, cursor_image);
+}
+
+static void
+xf86_load_cursor_argb (ScrnInfoPtr scrn, CursorPtr cursor)
+{
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    int			c;
+
+    for (c = 0; c < xf86_config->num_crtc; c++)
+    {
+	xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+	if (crtc->enabled)
+	    xf86_crtc_load_cursor_argb (crtc, cursor);
+    }
+}
+
+Bool
+xf86_cursors_init (ScreenPtr screen, int max_width, int max_height, int flags)
+{
+    ScrnInfoPtr		scrn = xf86Screens[screen->myNum];
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    xf86CursorInfoPtr	cursor_info;
+
+    cursor_info = xf86CreateCursorInfoRec();
+    if (!cursor_info)
+	return FALSE;
+
+    xf86_config->cursor_image = xalloc (max_width * max_height * 4);
+
+    if (!xf86_config->cursor_image)
+    {
+	xf86DestroyCursorInfoRec (cursor_info);
+	return FALSE;
+    }
+	
+    xf86_config->cursor_info = cursor_info;
+
+    cursor_info->MaxWidth = max_width;
+    cursor_info->MaxHeight = max_height;
+    cursor_info->Flags = flags;
+
+    cursor_info->SetCursorColors = xf86_set_cursor_colors;
+    cursor_info->SetCursorPosition = xf86_set_cursor_position;
+    cursor_info->LoadCursorImage = xf86_load_cursor_image;
+    cursor_info->HideCursor = xf86_hide_cursors;
+    cursor_info->ShowCursor = xf86_show_cursors;
+    cursor_info->UseHWCursor = xf86_use_hw_cursor;
+#ifdef ARGB_CURSOR
+    if (flags & HARDWARE_CURSOR_ARGB)
+    {
+	cursor_info->UseHWCursorARGB = xf86_use_hw_cursor_argb;
+	cursor_info->LoadCursorARGB = xf86_load_cursor_argb;
+    }
+#endif
+    
+    xf86_config->cursor = NULL;
+    xf86_hide_cursors (scrn);
+    
+    return xf86InitCursor (screen, cursor_info);
+}
+
+/**
+ * Called when anything on the screen is reconfigured.
+ *
+ * Reloads cursor images as needed, then adjusts cursor positions
+ */
+
+void
+xf86_reload_cursors (ScreenPtr screen)
+{
+    ScrnInfoPtr		scrn = xf86Screens[screen->myNum];
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    xf86CursorInfoPtr	cursor_info = xf86_config->cursor_info;
+    CursorPtr		cursor = xf86_config->cursor;
+    int			x, y;
+    
+    GetSpritePosition (&x, &y);
+    if (!(cursor_info->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
+	(*cursor_info->HideCursor)(scrn);
+
+    if (cursor)
+    {
+#ifdef ARGB_CURSOR
+	if (cursor->bits->argb && cursor_info->LoadCursorARGB)
+	    (*cursor_info->LoadCursorARGB) (scrn, cursor);
+	else
+#endif
+	    (*cursor_info->LoadCursorImage)(cursor_info->pScrn,
+					    cursor->devPriv[screen->myNum]);
+
+	(*cursor_info->SetCursorPosition)(cursor_info->pScrn, x, y);
+	(*cursor_info->ShowCursor)(cursor_info->pScrn);
+    }
+}
+
+/**
+ * Clean up CRTC-based cursor code
+ */
+void
+xf86_cursors_fini (ScreenPtr screen)
+{
+    ScrnInfoPtr		scrn = xf86Screens[screen->myNum];
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    
+    if (xf86_config->cursor_info)
+    {
+	xf86DestroyCursorInfoRec (xf86_config->cursor_info);
+	xf86_config->cursor_info = NULL;
+    }
+    if (xf86_config->cursor_image)
+    {
+	xfree (xf86_config->cursor_image);
+	xf86_config->cursor_image = NULL;
+    }
+}
diff --git a/hw/xfree86/ramdac/Makefile.am b/hw/xfree86/ramdac/Makefile.am
index 8d94445..2b84cb4 100644
--- a/hw/xfree86/ramdac/Makefile.am
+++ b/hw/xfree86/ramdac/Makefile.am
@@ -1,8 +1,6 @@
-module_LTLIBRARIES = libramdac.la
+noinst_LIBRARIES = libramdac.a
 
-libramdac_la_LDFLAGS = -avoid-version
-
-libramdac_la_SOURCES = xf86RamDacMod.c xf86RamDac.c xf86RamDacCmap.c \
+libramdac_a_SOURCES = xf86RamDac.c xf86RamDacCmap.c \
                       xf86Cursor.c xf86HWCurs.c IBM.c BT.c TI.c \
 		      xf86BitOrder.c
 
diff --git a/hw/xfree86/ramdac/xf86Cursor.h b/hw/xfree86/ramdac/xf86Cursor.h
index 08cca6b..469f48f 100644
--- a/hw/xfree86/ramdac/xf86Cursor.h
+++ b/hw/xfree86/ramdac/xf86Cursor.h
@@ -44,5 +44,8 @@ void xf86ForceHWCursor (ScreenPtr pScree
 #define HARDWARE_CURSOR_NIBBLE_SWAPPED			0x00000800
 #define HARDWARE_CURSOR_SHOW_TRANSPARENT		0x00001000
 #define HARDWARE_CURSOR_UPDATE_UNHIDDEN			0x00002000
+#ifdef ARGB_CURSOR
+#define HARDWARE_CURSOR_ARGB				0x00004000
+#endif
 
 #endif /* _XF86CURSOR_H */



More information about the xorg-commit mailing list