xserver: Branch 'server-1.6-branch' - 4 commits

Keith Packard keithp at kemper.freedesktop.org
Wed Feb 25 11:11:30 PST 2009


 config/hal.c                   |  111 +++++++++++++++++++++++--
 hw/xfree86/modes/xf86RandR12.c |  181 +++++++++++++++++++++++++++++++++++++++--
 hw/xfree86/modes/xf86Rotate.c  |   31 -------
 hw/xfree86/parser/Files.c      |    6 +
 hw/xfree86/parser/xf86tokens.h |    1 
 5 files changed, 285 insertions(+), 45 deletions(-)

New commits:
commit 9a59e7f304ab19c91738311bb9f1ec7709fc8847
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Feb 8 15:08:15 2009 +0100

    xf86CrtcShadowClear is unused.
    
    Remove this now that clearing is done by repainting with appropriate extend
    modes.
    Signed-off-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 60a4f1368785d26a49a3ef6df829723ca154c154)
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c
index 9f57394..6be77d5 100644
--- a/hw/xfree86/modes/xf86Rotate.c
+++ b/hw/xfree86/modes/xf86Rotate.c
@@ -146,37 +146,6 @@ xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region)
 }
 
 static void
-xf86CrtcShadowClear (xf86CrtcPtr crtc)
-{
-    PixmapPtr		dst_pixmap = crtc->rotatedPixmap;
-    ScrnInfoPtr		scrn = crtc->scrn;
-    ScreenPtr		screen = scrn->pScreen;
-    PicturePtr		dst;
-    PictFormatPtr	format = compWindowFormat (WindowTable[screen->myNum]);
-    static xRenderColor black = { 0, 0, 0, 0 };
-    xRectangle		rect;
-    int			error;
-
-    if (!dst_pixmap)
-	return;
-    dst = CreatePicture (None,
-			 &dst_pixmap->drawable,
-			 format,
-			 0L,
-			 NULL,
-			 serverClient,
-			 &error);
-    if (!dst)
-	return;
-    rect.x = 0;
-    rect.y = 0;
-    rect.width = dst_pixmap->drawable.width;
-    rect.height = dst_pixmap->drawable.height;
-    CompositeRects (PictOpSrc, dst, &black, 1, &rect);
-    FreePicture (dst, None);
-}
-
-static void
 xf86CrtcDamageShadow (xf86CrtcPtr crtc)
 {
     ScrnInfoPtr	pScrn = crtc->scrn;
commit 369d7b22a9009e7054bd121484fa128c7a6d21f6
Author: Keith Packard <keithp at keithp.com>
Date:   Thu Feb 5 11:36:54 2009 -0800

    Make panning+transform be correctly driven by mouse
    
    Figuring out how to adjust the crtc origin to keep the mouse pointer within
    the crtc is a bit of a trick
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 63810aca31b962c93be4796883bde6ccb653e3a9)
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index d8693dd..2d8c2a9 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -177,6 +177,8 @@ xf86RandR13Pan (xf86CrtcPtr crtc, int x, int y)
 {
     int newX, newY;
     int width, height;
+    struct pict_f_vector    c;
+    Bool panned = FALSE;
 
     if (crtc->version < 2)
 	return;
@@ -191,23 +193,185 @@ xf86RandR13Pan (xf86CrtcPtr crtc, int x, int y)
     width  = crtc->mode.HDisplay;
     height = crtc->mode.VDisplay;
 
+    c.v[0] = x;
+    c.v[1] = y;
+    c.v[2] = 1.0;
+    if (crtc->transform_in_use) {
+	pixman_f_transform_point(&crtc->f_framebuffer_to_crtc, &c);
+    } else {
+	c.v[0] -= crtc->x;
+	c.v[1] -= crtc->y;
+    }
+
     if ((crtc->panningTrackingArea.x2 <= crtc->panningTrackingArea.x1 ||
 	 (x >= crtc->panningTrackingArea.x1 && x < crtc->panningTrackingArea.x2)) &&
 	(crtc->panningTrackingArea.y2 <= crtc->panningTrackingArea.y1 ||
 	 (y >= crtc->panningTrackingArea.y1 && y < crtc->panningTrackingArea.y2))) {
 	if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) {
-	    if (x < crtc->x + crtc->panningBorder[0])
-		newX = x - crtc->panningBorder[0];
-	    if (x >= crtc->x + width - crtc->panningBorder[2])
-		newX = x - width + crtc->panningBorder[2] + 1;
+	    if (c.v[0] < crtc->panningBorder[0]) {
+		c.v[0] = crtc->panningBorder[0];
+		panned = TRUE;
+	    }
+	    if (c.v[0] >= width - crtc->panningBorder[2]) {
+		c.v[0] = width - crtc->panningBorder[2] - 1;
+		panned = TRUE;
+	    }
 	}
 	if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
-	    if (y < crtc->y + crtc->panningBorder[1])
-		newY = y - crtc->panningBorder[1];
-	    if (y >= crtc->y + height - crtc->panningBorder[3])
-		newY = y - height + crtc->panningBorder[3] + 1;
+	    if (c.v[1] < crtc->panningBorder[1]) {
+		c.v[1] = crtc->panningBorder[1];
+		panned = TRUE;
+	    }
+	    if (c.v[1] >= height - crtc->panningBorder[3]) {
+		c.v[1] = height - crtc->panningBorder[3] - 1;
+		panned = TRUE;
+	    }
 	}
     }
+    if (panned) {
+	if (crtc->transform_in_use) {
+	    /*
+	     * Under a transformation, we want to find a new crtc offset
+	     * which places the cursor in the desired position. That is,
+	     *
+	     * Given the current transform, M, the current cursor position
+	     * on the Screen, S, and the desired cursor position on the CRTC,
+	     * C, compute a translation, T, such that:
+	     *
+	     * M T S = C
+	     *
+	     * where T is of the form
+	     *
+	     * | 1 0 dx |
+	     * | 0 1 dy |
+	     * | 0 0 1  |
+	     *
+	     * M T S =
+	     *   | M00 Sx + M01 Sy + M00 dx + M01 dy + M02 |   | Cx F |
+	     *   | M10 Sx + M11 Sy + M10 dx + M11 dy + M12 | = | Cy F |
+	     *   | M20 Sx + M21 Sy + M20 dx + M21 dy + M22 |   |  F   |
+	     *
+	     * R = M S
+	     *
+	     *   Cx F = M00 dx + M01 dy + R0
+	     *   Cy F = M10 dx + M11 dy + R1
+	     *      F = M20 dx + M21 dy + R2
+	     *
+	     * Zero out dx, then dy
+	     *
+	     * F (Cx M10 - Cy M00) =
+	     *	    (M10 M01 - M00 M11) dy + M10 R0 - M00 R1
+	     * F (M10 - Cy M20) =
+	     *	    (M10 M21 - M20 M11) dy + M10 R2 - M20 R1
+	     *
+	     * F (Cx M11 - Cy M01) =
+	     *	    (M11 M00 - M01 M10) dx + M11 R0 - M01 R1
+	     * F (M11 - Cy M21) =
+	     *	    (M11 M20 - M21 M10) dx + M11 R2 - M21 R1
+	     *
+	     * Make some temporaries
+	     *
+	     * T = | Cx M10 - Cy M00 |
+	     *     | Cx M11 - Cy M01 |
+	     *
+	     * U = | M10 M01 - M00 M11 |
+	     *     | M11 M00 - M01 M10 |
+	     *
+	     * Q = | M10 R0 - M00 R1 |
+	     *     | M11 R0 - M01 R1 |
+	     *
+	     * P = | M10 - Cy M20 |
+	     *     | M11 - Cy M21 |
+	     *
+	     * W = | M10 M21 - M20 M11 |
+	     *     | M11 M20 - M21 M10 |
+	     *
+	     * V = | M10 R2 - M20 R1 |
+	     *	   | M11 R2 - M21 R1 |
+	     *
+	     * Rewrite:
+	     *
+	     * F T0 = U0 dy + Q0
+	     * F P0 = W0 dy + V0
+	     * F T1 = U1 dx + Q1
+	     * F P1 = W1 dx + V1
+	     *
+	     * Solve for F (two ways)
+	     *
+	     * F (W0 T0 - U0 P0)  = W0 Q0 - U0 V0
+	     *
+	     *     W0 Q0 - U0 V0
+	     * F = -------------
+	     *     W0 T0 - U0 P0
+	     *
+	     * F (W1 T1 - U1 P1) = W1 Q1 - U1 V1
+	     *
+	     *     W1 Q1 - U1 V1
+	     * F = -------------
+	     *     W1 T1 - U1 P1
+	     *
+	     * We'll use which ever solution works (denominator != 0)
+	     *
+	     * Finally, solve for dx and dy:
+	     *
+	     * dx = (F T1 - Q1) / U1
+	     * dx = (F P1 - V1) / W1
+	     *
+	     * dy = (F T0 - Q0) / U0
+	     * dy = (F P0 - V0) / W0
+	     */
+	    double	r[3];
+	    double	q[2], u[2], t[2], v[2], w[2], p[2];
+	    double	f;
+	    struct pict_f_vector    d;
+	    int	i;
+	    struct pixman_f_transform	*m = &crtc->f_framebuffer_to_crtc;
+
+	    /* Get the un-normalized crtc coordinates again */
+	    for (i = 0; i < 3; i++)
+		r[i] = m->m[i][0] * x + m->m[i][1] * y + m->m[i][2];
+
+	    /* Combine values into temporaries */
+	    for (i = 0; i < 2; i++) {
+		q[i] = m->m[1][i] * r[0] - m->m[0][i] * r[1];
+		u[i] = m->m[1][i] * m->m[0][1-i] - m->m[0][i] * m->m[1][1-i];
+		t[i] = m->m[1][i] * c.v[0] - m->m[0][i] * c.v[1];
+
+		v[i] = m->m[1][i] * r[2] - m->m[2][i] * r[1];
+		w[i] = m->m[1][i] * m->m[2][1-i] - m->m[2][i] * m->m[1][1-i];
+		p[i] = m->m[1][i] - m->m[2][i] * c.v[1];
+	    }
+
+	    /* Find a way to compute f */
+	    f = 0;
+	    for (i = 0; i < 2; i++) {
+		double a = w[i] * q[i] - u[i] * v[i];
+		double b = w[i] * t[i] - u[i] * p[i];
+		if (b != 0) {
+		    f = a/b;
+		    break;
+		}
+	    }
+
+	    /* Solve for the resulting transform vector */
+	    for (i = 0; i < 2; i++) {
+		if (u[i])
+		    d.v[1-i] = (t[i] * f - q[i]) / u[i];
+		else if (w[1])
+		    d.v[1-i] = (p[i] * f - v[i]) / w[i];
+		else
+		    d.v[1-i] = 0;
+	    }
+	    d.v[2] = 1;
+	    newX -= floor (d.v[0] + 0.5);
+	    newY -= floor (d.v[1] + 0.5);
+	} else {
+	    newX = x - c.v[0];
+	    newY = y - c.v[1];
+	}
+    }
+
+#if 0
     /* Validate against [xy]1 after [xy]2, to be sure that results are > 0 for [xy]1 > 0 */
     if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) {
 	if (newX > crtc->panningTotalArea.x2 - width)
@@ -221,6 +385,7 @@ xf86RandR13Pan (xf86CrtcPtr crtc, int x, int y)
 	if (newY <  crtc->panningTotalArea.y1)
 	    newY =  crtc->panningTotalArea.y1;
     }
+#endif
     if (newX != crtc->x || newY != crtc->y)
 	xf86CrtcSetOrigin (crtc, newX, newY);
 }
commit c0a36197002c7de98f14dc98969409778d29dc50
Author: Alan Coopersmith <alan.coopersmith at sun.com>
Date:   Tue Feb 17 18:48:52 2009 -0800

    Make RgbPath keyword in xorg.conf a non-fatal error
    
    Xorg shouldn't refuse to run just because the user has an xorg.conf that
    had the previously-used RgbPath keyword in it.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at sun.com>
    Acked-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit d2cf562bbad553d7f09b70202134f5b6ada0114e)
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/parser/Files.c b/hw/xfree86/parser/Files.c
index 2f77c0e..c352302 100644
--- a/hw/xfree86/parser/Files.c
+++ b/hw/xfree86/parser/Files.c
@@ -73,6 +73,8 @@ static xf86ConfigSymTabRec FilesTab[] =
 	{INPUTDEVICES, "inputdevices"},
 	{LOGFILEPATH, "logfile"},
 	{XKBDIR, "xkbdir"},
+	/* Obsolete keywords that aren't used but shouldn't cause errors: */
+	{OBSOLETE_TOKEN, "rgbpath"},
 	{-1, ""},
 };
 
@@ -189,6 +191,10 @@ xf86parseFilesSection (void)
 		case EOF_TOKEN:
 			Error (UNEXPECTED_EOF_MSG, NULL);
 			break;
+		case OBSOLETE_TOKEN:
+			xf86parseError (OBSOLETE_MSG, xf86tokenString ());
+			xf86getSubToken (&(ptr->file_comment));
+			break;
 		default:
 			Error (INVALID_KEYWORD_MSG, xf86tokenString ());
 			break;
diff --git a/hw/xfree86/parser/xf86tokens.h b/hw/xfree86/parser/xf86tokens.h
index 8091f09..b2d2350 100644
--- a/hw/xfree86/parser/xf86tokens.h
+++ b/hw/xfree86/parser/xf86tokens.h
@@ -70,6 +70,7 @@
 
 typedef enum {
     /* errno-style tokens */
+    OBSOLETE_TOKEN	= -5,
     EOF_TOKEN		= -4,
     LOCK_TOKEN		= -3,
     ERROR_TOKEN		= -2,
commit 6b8bbbd21b39181e9dd3175fa73c05008c361ba2
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Feb 4 11:50:18 2009 +1000

    config: if we can't connect to HAL, listen for a startup notification.
    
    If HAL isn't available when we try to connect, the registered NameOwnerChanged
    signal handler waits until HAL is available. Once we connected to HAL, we
    unregister the signal handler again.
    This allows HAL to be started in parallel or after the server has started.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 4844bff58f296b2851be4e6b955c3a68d02437a9)
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/config/hal.c b/config/hal.c
index 8dfbb07..36fa839 100644
--- a/config/hal.c
+++ b/config/hal.c
@@ -467,11 +467,10 @@ disconnect_hook(void *data)
     info->system_bus = NULL;
 }
 
-static void
-connect_hook(DBusConnection *connection, void *data)
+static BOOL
+connect_and_register(DBusConnection *connection, struct config_hal_info *info)
 {
     DBusError error;
-    struct config_hal_info *info = data;
     char **devices;
     int num_devices, i;
 
@@ -479,8 +478,10 @@ connect_hook(DBusConnection *connection, void *data)
 
     dbus_error_init(&error);
 
-    if (!info->hal_ctx)
-        info->hal_ctx = libhal_ctx_new();
+    if (info->hal_ctx)
+        return TRUE; /* already registered, pretend we did something */
+
+    info->hal_ctx = libhal_ctx_new();
     if (!info->hal_ctx) {
         LogMessage(X_ERROR, "config/hal: couldn't create HAL context\n");
         goto out_err;
@@ -512,7 +513,7 @@ connect_hook(DBusConnection *connection, void *data)
 
     dbus_error_free(&error);
 
-    return;
+    return TRUE;
 
 out_ctx2:
     if (!libhal_ctx_shutdown(info->hal_ctx, &error))
@@ -526,6 +527,104 @@ out_err:
     info->hal_ctx = NULL;
     info->system_bus = NULL;
 
+    return FALSE;
+}
+
+
+/**
+ * Handle NewOwnerChanged signals to deal with HAL startup at X server runtime.
+ *
+ * NewOwnerChanged is send once when HAL shuts down, and once again when it
+ * comes back up. Message has three arguments, first is the name
+ * (org.freedesktop.Hal), the second one is the old owner, third one is new
+ * owner.
+ */
+static DBusHandlerResult
+ownerchanged_handler(DBusConnection *connection, DBusMessage *message, void *data)
+{
+    int ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+    if (dbus_message_is_signal(message,
+                               "org.freedesktop.DBus",
+                               "NameOwnerChanged")) {
+        DBusError error;
+        char *name, *old_owner, *new_owner;
+
+        dbus_error_init(&error);
+        dbus_message_get_args(message, &error,
+                              DBUS_TYPE_STRING, &name,
+                              DBUS_TYPE_STRING, &old_owner,
+                              DBUS_TYPE_STRING, &new_owner,
+                              DBUS_TYPE_INVALID);
+
+        if (dbus_error_is_set(&error)) {
+            ErrorF("[config/hal] failed to get NameOwnerChanged args: %s (%s)\n",
+                   error.name, error.message);
+        } else if (name && strcmp(name, "org.freedesktop.Hal") == 0) {
+
+            if (!old_owner || !strlen(old_owner)) {
+                DebugF("[config/hal] HAL startup detected.\n");
+                if (connect_and_register(connection, (struct config_hal_info*)data))
+                    dbus_connection_unregister_object_path(connection,
+                                                     "/org/freedesktop/DBus");
+                else
+                    ErrorF("[config/hal] Failed to connect to HAL bus.\n");
+            }
+
+            ret = DBUS_HANDLER_RESULT_HANDLED;
+        }
+        dbus_error_free(&error);
+    }
+
+    return ret;
+}
+
+/**
+ * Register a handler for the NameOwnerChanged signal.
+ */
+static BOOL
+listen_for_startup(DBusConnection *connection, void *data)
+{
+    DBusObjectPathVTable vtable = { .message_function = ownerchanged_handler, };
+    DBusError error;
+    const char MATCH_RULE[] = "sender='org.freedesktop.DBus',"
+                              "interface='org.freedesktop.DBus',"
+                              "type='signal',"
+                              "path='/org/freedesktop/DBus',"
+                              "member='NameOwnerChanged'";
+    int rc = FALSE;
+
+    dbus_error_init(&error);
+    dbus_bus_add_match(connection, MATCH_RULE, &error);
+    if (!dbus_error_is_set(&error)) {
+        if (dbus_connection_register_object_path(connection,
+                                                  "/org/freedesktop/DBus",
+                                                  &vtable,
+                                                  data))
+            rc = TRUE;
+        else
+            ErrorF("[config/hal] cannot register object path.\n");
+    } else {
+        ErrorF("[config/hal] couldn't add match rule: %s (%s)\n", error.name,
+                error.message);
+        ErrorF("[config/hal] cannot detect a HAL startup.\n");
+    }
+
+    dbus_error_free(&error);
+
+    return rc;
+}
+
+static void
+connect_hook(DBusConnection *connection, void *data)
+{
+    struct config_hal_info *info = data;
+
+    if (listen_for_startup(connection, data) &&
+        connect_and_register(connection, info))
+        dbus_connection_unregister_object_path(connection,
+                                               "/org/freedesktop/DBus");
+
     return;
 }
 


More information about the xorg-commit mailing list