commit d91645f8b37aa43bafa76da3146dcdc9c17963ff
Author: Gwenole Beauchesne <gbeauchesne@splitted-desktop.com>
Date:   Fri Nov 20 15:51:22 2009 +0000

    Fix detection of fglrx.

diff --git a/src/x11/Makefile.am b/src/x11/Makefile.am
index b6916f2..0b61c33 100644
--- a/src/x11/Makefile.am
+++ b/src/x11/Makefile.am
@@ -25,6 +25,23 @@ noinst_LTLIBRARIES = libva_x11.la
 libva_x11includedir = ${includedir}/va
 libva_x11include_HEADERS = va_x11.h va_dri.h va_dri2.h va_dricommon.h
 
-libva_x11_la_SOURCES = va_x11.c va_dri.c va_dri2.c va_dricommon.c dri2_util.c dri1_util.c va_nvctrl.c libdrm_glue.c
+libva_x11_la_SOURCES =	\
+	dri1_util.c	\
+	dri2_util.c	\
+	libdrm_glue.c	\
+	va_dri.c	\
+	va_dri2.c	\
+	va_dricommon.c	\
+	va_fglext.c	\
+	va_nvctrl.c	\
+	va_x11.c	\
+	$(NULL)
 
-EXTRA_DIST = va_dristr.h va_dri2str.h va_dri2tokens.h va_nvctrl.h libdrm_glue.h
+EXTRA_DIST =		\
+	libdrm_glue.h	\
+	va_dri2str.h	\
+	va_dri2tokens.h	\
+	va_dristr.h	\
+	va_fglext.h	\
+	va_nvctrl.h	\
+	$(NULL)
diff --git a/src/x11/va_fglext.c b/src/x11/va_fglext.c
new file mode 100644
index 0000000..bc58e8b
--- /dev/null
+++ b/src/x11/va_fglext.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2009 Splitted-Desktop Systems. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#define _GNU_SOURCE 1
+#include <string.h>
+
+#define NEED_REPLIES
+#include <stdlib.h>
+#include <X11/Xlibint.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/Xext.h>
+#include <X11/extensions/extutil.h>
+#include "va_fglext.h"
+
+#define ATIFGL_EXTENSION_NAME "ATIFGLEXTENSION"
+#define ATIFGL_EXTENSION_EVENTS 0
+
+typedef struct _FGLGetDriverData {
+    CARD8   reqType;
+    CARD8   fireglReqType;
+    CARD16  length B16;
+    CARD32  screen B32;
+    CARD16  size B16;
+    CARD16  pad1;
+} xFGLGetDriverDataReq;
+#define sz_xFGLGetDriverDataReq sizeof(xFGLGetDriverDataReq)
+
+typedef struct {
+    BYTE    type;
+    BYTE    pad1;
+    CARD16  sequenceNumber B16;
+    CARD32  length B32;
+    CARD8   majorVersion;
+    CARD8   minorVersion;
+    CARD8   patchlevel B16;
+    CARD8   BIOSVersionMajor;
+    CARD8   BIOSVersionMinor;
+    CARD8   HasSecondary;
+    CARD16  pad3 B16;
+    CARD32  pad4 B32;
+    CARD32  pad5 B32;
+    CARD32  pad6 B32;
+    CARD32  pad7 B32;
+    // ... there are more fields
+} xFGLGetDriverDataReply;
+#define sz_xFGLGetDriverDataReply sizeof(xFGLGetDriverDataReply)
+
+#define X_FGLGetDriverData 0
+
+static XExtensionInfo _fglext_ext_info_data;
+static XExtensionInfo *fglext_ext_info = &_fglext_ext_info_data;
+static /* const */ char *fglext_extension_name = ATIFGL_EXTENSION_NAME;
+
+#define xFGLCheckExtension(dpy,i,val) \
+  XextCheckExtension (dpy, i, fglext_extension_name, val)
+
+static int close_display();
+static /* const */ XExtensionHooks fglext_extension_hooks = {
+    NULL,                               /* create_gc */
+    NULL,                               /* copy_gc */
+    NULL,                               /* flush_gc */
+    NULL,                               /* free_gc */
+    NULL,                               /* create_font */
+    NULL,                               /* free_font */
+    close_display,                      /* close_display */
+    NULL,                               /* wire_to_event */
+    NULL,                               /* event_to_wire */
+    NULL,                               /* error */
+    NULL,                               /* error_string */
+};
+
+static XEXT_GENERATE_FIND_DISPLAY (find_display, fglext_ext_info,
+                                   fglext_extension_name, 
+                                   &fglext_extension_hooks,
+                                   ATIFGL_EXTENSION_EVENTS, NULL)
+
+static XEXT_GENERATE_CLOSE_DISPLAY (close_display, fglext_ext_info)
+
+Bool VA_FGLEXTQueryDirectRenderingCapable( Display *dpy, int screen,
+    Bool *isCapable )
+{
+    char **extensions;
+    int i, n_extensions, has_fglext = 0, has_fglrxdri = 0;
+
+    if (isCapable)
+        *isCapable = False;
+
+    extensions = XListExtensions(dpy, &n_extensions);
+    if (!extensions)
+        return False;
+
+    for (i = 0; i < n_extensions; i++) {
+        if (strcmp(extensions[i], ATIFGL_EXTENSION_NAME) == 0)
+            has_fglext = 1;
+        if (strcmp(extensions[i], "ATIFGLRXDRI") == 0)
+            has_fglrxdri = 1;
+    }
+    XFreeExtensionList(extensions);
+
+    if (!has_fglext)
+        return False;
+
+    if (isCapable)
+        *isCapable = has_fglrxdri;
+
+    return True;
+}
+
+Bool VA_FGLEXTGetClientDriverName( Display *dpy, int screen,
+    int *ddxDriverMajorVersion, int *ddxDriverMinorVersion,
+    int *ddxDriverPatchVersion, char **clientDriverName )
+{
+    XExtDisplayInfo *info = find_display (dpy);
+    xFGLGetDriverDataReply rep;
+    xFGLGetDriverDataReq  *req;
+
+    if (ddxDriverMajorVersion)
+        *ddxDriverMajorVersion = 0;
+    if (ddxDriverMinorVersion)
+        *ddxDriverMinorVersion = 0;
+    if (ddxDriverPatchVersion)
+        *ddxDriverPatchVersion = 0;
+    if (clientDriverName)
+        *clientDriverName = NULL;
+
+    if(!XextHasExtension(info))
+        return False;
+
+    xFGLCheckExtension (dpy, info, False);
+
+    LockDisplay (dpy);
+    GetReq (FGLGetDriverData, req);
+    req->reqType = info->codes->major_opcode;
+    req->fireglReqType = X_FGLGetDriverData;
+    req->screen = screen;
+    if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
+        UnlockDisplay (dpy);
+        SyncHandle ();
+        return False;
+    }
+    UnlockDisplay (dpy);
+    SyncHandle ();
+
+    if (ddxDriverMajorVersion)
+        *ddxDriverMajorVersion = rep.majorVersion;
+    if (ddxDriverMinorVersion)
+        *ddxDriverMinorVersion = rep.minorVersion;
+    if (ddxDriverPatchVersion)
+        *ddxDriverPatchVersion = rep.patchlevel;
+    if (clientDriverName)
+        *clientDriverName = strdup("fglrx");
+
+    return True;
+}
diff --git a/src/x11/va_fglext.h b/src/x11/va_fglext.h
new file mode 100644
index 0000000..f2d87c3
--- /dev/null
+++ b/src/x11/va_fglext.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2009 Splitted-Desktop Systems. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef VA_FGLEXTLIB_H
+#define VA_FGLEXTLIB_H
+
+#include <X11/Xlib.h>
+
+Bool VA_FGLEXTQueryDirectRenderingCapable( Display *dpy, int screen,
+    Bool *isCapable );
+
+Bool VA_FGLEXTGetClientDriverName( Display *dpy, int screen,
+    int *ddxDriverMajorVersion, int *ddxDriverMinorVersion,
+    int *ddxDriverPatchVersion, char **clientDriverName );
+
+#endif /* VA_FGLEXTLIB_H */
diff --git a/src/x11/va_x11.c b/src/x11/va_x11.c
index 414c261..0510e00 100644
--- a/src/x11/va_x11.c
+++ b/src/x11/va_x11.c
@@ -31,6 +31,7 @@
 #include "va_dri2.h"
 #include "va_dricommon.h"
 #include "va_nvctrl.h"
+#include "va_fglext.h"
 #include "libdrm_glue.h"
 #include <stdio.h>
 #include <stdarg.h>
@@ -132,6 +133,29 @@ static VAStatus va_NVCTRL_GetDriverName (
     return VA_STATUS_SUCCESS;
 }
 
+static VAStatus va_FGLEXT_GetDriverName(
+    VADisplayContextP pDisplayContext,
+    char **driver_name
+)
+{
+    VADriverContextP ctx = pDisplayContext->pDriverContext;
+    int direct_capable, driver_major, driver_minor, driver_patch;
+    Bool result;
+
+    result = VA_FGLEXTQueryDirectRenderingCapable(ctx->x11_dpy, ctx->x11_screen,
+                                                  &direct_capable);
+    if (!result || !direct_capable)
+        return VA_STATUS_ERROR_UNKNOWN;
+
+    result = VA_FGLEXTGetClientDriverName(ctx->x11_dpy, ctx->x11_screen,
+                                          &driver_major, &driver_minor,
+                                          &driver_patch, driver_name);
+    if (!result)
+        return VA_STATUS_ERROR_UNKNOWN;
+
+    return VA_STATUS_SUCCESS;
+}
+
 static VAStatus va_DisplayContextGetDriverName (
     VADisplayContextP pDisplayContext,
     char **driver_name
@@ -156,7 +180,8 @@ static VAStatus va_DisplayContextGetDriverName (
         vaStatus = va_DRIGetDriverName(pDisplayContext, driver_name);
     if (vaStatus != VA_STATUS_SUCCESS)
         vaStatus = va_NVCTRL_GetDriverName(pDisplayContext, driver_name);
-   
+    if (vaStatus != VA_STATUS_SUCCESS)
+        vaStatus = va_FGLEXT_GetDriverName(pDisplayContext, driver_name);
     return vaStatus;
 }
 
