#
# libgl1-check.sh
#
# Idea:
#   To make sure that there is a consistency of 
#   - the driver used by X (Drver ... in /etc/X11/xorg.conf
#   - /usr/lib/libGL.so
#
#  Dynamic checking of kernel modules
#  seems to be done by NVidia and ATI proprietary modules at runtime.
#
#

# Main idea
#
#    We need to have a matching driver and libGL (and friends)
#    for proper operaton of programs based on opengl.
#
#    But due to the way pakcages are installed and
#    editing of xorg.conf by hand, may leave the matching
#    broken.
#
#    This script tries to detect the mismatch and warns the
#    problem.
#
#    Xorg Device  Driver  | libGL
#    ---------------------+----------------------------
#    fglrx	   	  | its own
#    nv                   | its own?
#    nvidia               | its own (Nvidia proprietary)
#    (proprietary ATI?)   | its own
# 
#    other                | libGL coming from libgl1-mesa-glx (on debian?)
#
#  Q?: Now I am not sure if DRM/DRI whatever has relevance here.
#  These kernel modules seem to be check for compatibility at runtime,
#  and so I don't think I need to worry about it.

#
# Note. With current libGL scheme of having different
# libGL coming from differnt driver packages,
# it is impossible to have a set of graphics cards
# that each use drivers with different libGLs
#


# (1) Obtain the X11 driver name.
#
# I would use a binary program in the end (hopefully).
# Debian Source Browser:
# Near 2497 is how config file is read and parsed by Xorg server.
# http://walrus.rave.org/source/xref/main/x/xorg-server/hw/xfree86/common/xf86Config.c
#
#
# Initial idea:
# Obtain the driver name from /etc/X11/xorg.conf assuming that it is indeed
# the config file.
#

#
# On second thought:
# Hmm, this is indeed tricky. Some people use different config file.
# Make it into an argument to this script.
#

# XCONF=/etc/X11/xorg.conf

if [ $# -ne 1 ]
then

	echo "Usage: $0 xorg_config_file "
	exit 2
fi

XCONF=$1

echo "Checking $XCONF"

#
# For now, this test of concept version only needs
# a simple handling.
# 
# search for Driver line
# if the first non white token is Driver
# check if the name is one of these.

# fglrx, nv, nvidia
# kbd, mouse, etc.
#
# TF=/tmp/t.l.c.$

# We need to add tablet and other drivers to ignore.

# strip doublequotes used in the cofig file, also.

DRIVERS=$( grep "Driver" $XCONF | 
   gawk 'BEGIN { ignore["\"keyboard\""] = 1;  ignore["\"kbd\""] = 1;  ignore["\"mouse\""]= 1;} 
         $1 == "Driver" { if ((ignore[$2] + 0) == 0)   printf("%s ",$2); }' |
        tr -d "[\"]"  )

# echo $DRIVERS


echo "You are using the graphics device drivers : $DRIVERS "

DCNT=$(echo $DRIVERS | wc -w)

if [ $DCNT -gt 1 ] 
then
    echo
    echo "If there are more than one driver lines, we may have a problem. "
    echo "(If all the graphics driver expect the same libGL, then no problem.)"
    echo
fi


###
### libGL is classified into
### nvidia
### fglrx 
### other (mesa?)
###

# Ad-hoc check

#
# Short of having the md5 check sum of versions of libGL.so,
# I have a heuristics using a string within libGL.so.
#
# It would be nice if each package puts a unique version string within
# libGL.so.*
#

# NVIDIA proprietary libGL has a string "NVIDIA:" inside.
#
# How can we check for fglrx?
#
# From mesa libGL.so
# $ strings - /usr/lib/libGL.so | grep -i version | sort -u > /tmp/mesa.mesa
#
# From Debian fglrx-lbx libGL.so
# $ strings - libGL.so.1 | grep -i version | sort -u > /tmp/mesa.fglrx
#
# $ diff -cibw /tmp/mesa.*
# diff -cibw /tmp/mesa.*
#*** /tmp/mesa.fglrx	2009-05-30 21:30:44.000000000 +0900
#--- /tmp/mesa.mesa	2009-05-30 21:30:29.000000000 +0900
#***************
#*** 1,7 ****
#  .gnu.version
#  .gnu.version_r
#! DRM_IOCTL_VERSION: %s
#  XF86DRIQueryVersion
#! ^^^^^^^^ Windows XP 64-bit Edition Version 2003 or newer should be used.
#! ^^^^^^^^Conversion from text file %s to binary %s completed
#  glXQueryVersion
#--- 1,10 ----
#  .gnu.version
#  .gnu.version_r
#! XDamageQueryVersion
#  XF86DRIQueryVersion
#! XF86VidModeQueryVersion
# ! __glXGetGLVersion
#! __glXGetInternalVersion
#! drmFreeVersion
#! drmGetVersion
#  glXQueryVersion
#

#
# fglrx coming from ATI (AMD/ATI) catalyst driver has
# "amd" string inside.
# fglrx-driver_8.573-1_i386.deb created from an RPM package.
#
# $ strings - usr/lib/libGL.so.1 | grep -i amd
# GetCapabilityvAMD
# glGetCapabilityvAMD
#
# It also have DRM_IOCTL_VERSION within.
#
# Come to think of it, if fglrx in debian uses ATI's proprietary code
# then we can simply check for amd and done with it...
#

# We may not need the differentiation for AMD/ATI-based
# catalyst package driver and debian fglrx-glx driver, but
# for the sake of completeness, I leave it there.

LIBGLFILE=/usr/lib/libGL.so

if strings - $LIBGLFILE | grep "NVIDIA:"
then
  echo "We seem to be using libGL coming from NVidia proprietary driver."
  libgl_type=nvidia
elif strings - $LIBGLFILE | grep -i  "amd"
then
  echo "We seem to be using libGL coming from FGLRX (AMD/ATI) driver."
  libgl_type=fglrx
elif strings - $LIBGLFILE | grep  "DRM_IOCTL_VERSION"
then
  echo "We seem to be using libGL coming from FGLRX driver."
  libgl_type=fglrx
else
  #
  # Assume that this is open source mesa libGL expected by many
  # graphics drivers.
  #
  libgl_type=other
fi

###
### Let us check if the graphics driver in X config file
### and the /usr/lib/libGL is consistent.
###

MISMATCH=0

for d in $DRIVERS
do
   case $d in
   fglrx)
      driver_type=fglrx;
	;;	    
   nv)
      driver_type=nvidia;
	;;
   nvidia)
      driver_type=nvidia;
	;;
   *) 
       driver_type=other;
       ;;
   esac

   if [ $libgl_type != $driver_type ]
   then
    echo "Mismatched: libGL from $libgl_type, X driver $d (expecting libGL of '$driver_type').";
    MISMATCH=1
   else
    echo "Matched: libGL from $libgl_type, X driver $d (expecting libGL of '$driver_type').";
   fi
done

if [ $MISMATCH -gt 0 ]
then
	echo
	echo "You may want to re-install opengl modules."
	echo
	#
	# These suggestions can be made more explicit based
	# on library types, and more OS-distribution specific.
	#
	# For 
	echo "E.g. Debian GNU/Linux: apt-get install --reinstall package_name"
	#
	echo 
	echo "Or use an appropriate graphics Driver for $XCONF".
	echo
	exit 2
else
	exit 0
fi

#rm -f $TF
