summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Plattner <aplattner@nvidia.com>2008-02-12 21:28:55 -0800
committerAaron Plattner <aplattner@nvidia.com>2008-02-12 21:28:55 -0800
commit1e2ff16f982f33122e4239c26aa1a3c2030f5c1d (patch)
tree42a8fa910daa8504632e1f2d14a775af1e4812ee
parent70ce3d7b12b71ea08c175017d9771cf1b65ec32d (diff)
1.0-81741.0-8174
-rw-r--r--Makefile18
-rw-r--r--doc/Makefile.inc3
-rw-r--r--doc/nvidia-settings-user-guide.txt338
-rw-r--r--doc/nvidia-settings.1507
-rw-r--r--samples/nv-control-events.c1
-rw-r--r--src/config-file.c7
-rw-r--r--src/gtk+-2.x/Makefile.inc6
-rw-r--r--src/gtk+-2.x/ctkclocks.c5
-rw-r--r--src/gtk+-2.x/ctkdevice.c41
-rw-r--r--src/gtk+-2.x/ctkdisplaydevice-crt.c22
-rw-r--r--src/gtk+-2.x/ctkdisplaydevice-crt.h1
-rw-r--r--src/gtk+-2.x/ctkdisplaydevice-dfp.c20
-rw-r--r--src/gtk+-2.x/ctkdisplaydevice-dfp.h1
-rw-r--r--src/gtk+-2.x/ctkdisplaydevice-tv.c20
-rw-r--r--src/gtk+-2.x/ctkdisplaydevice-tv.h1
-rw-r--r--src/gtk+-2.x/ctkedid.c271
-rw-r--r--src/gtk+-2.x/ctkedid.h91
-rw-r--r--src/gtk+-2.x/ctkevent.c196
-rw-r--r--src/gtk+-2.x/ctkglx.c41
-rw-r--r--src/gtk+-2.x/ctkimagesliders.c10
-rw-r--r--src/gtk+-2.x/ctkimagesliders.h6
-rw-r--r--src/gtk+-2.x/ctkmultisample.c30
-rw-r--r--src/gtk+-2.x/ctkopengl.c384
-rw-r--r--src/gtk+-2.x/ctkopengl.h4
-rw-r--r--src/gtk+-2.x/ctkwindow.c2
-rw-r--r--src/gtk+-2.x/ctkxvideo.c243
-rw-r--r--src/gtk+-2.x/ctkxvideo.h5
-rw-r--r--src/image_data/crt.h21
-rw-r--r--src/image_data/image.c2
-rw-r--r--src/image_data/image.h2
-rw-r--r--src/libXNVCtrl/NVCtrl.c53
-rw-r--r--src/libXNVCtrl/NVCtrl.h105
-rw-r--r--src/libXNVCtrl/NVCtrlLib.h25
-rw-r--r--src/libXNVCtrl/libXNVCtrl.abin13488 -> 14058 bytes
-rw-r--r--src/libXNVCtrl/nv_control.h30
-rw-r--r--src/libXNVCtrlAttributes/NvCtrlAttributes.c14
-rw-r--r--src/libXNVCtrlAttributes/NvCtrlAttributes.h23
-rw-r--r--src/libXNVCtrlAttributes/NvCtrlAttributesNvControl.c41
-rw-r--r--src/libXNVCtrlAttributes/NvCtrlAttributesPrivate.h6
-rw-r--r--src/libXNVCtrlAttributes/NvCtrlAttributesXrandr.c42
-rw-r--r--src/libXNVCtrlAttributes/NvCtrlAttributesXv.c8
-rw-r--r--src/parse.c20
-rw-r--r--src/query-assign.c21
43 files changed, 2171 insertions, 516 deletions
diff --git a/Makefile b/Makefile
index aa771c1..431c1e5 100644
--- a/Makefile
+++ b/Makefile
@@ -37,7 +37,7 @@
# default definitions; can be overwritten by users
SHELL = /bin/sh
-INSTALL = install -m 755
+INSTALL = install
BUILD_OS := $(shell uname)
BUILD_ARCH := $(shell uname -m)
@@ -88,15 +88,25 @@ endif
# Solaris install has a different argument syntax
ifeq ($(BUILD_OS),SunOS)
ECHO=/usr/ucb/echo
-INSTALL_RULE=$(INSTALL) -f $(bindir) $(NVIDIA_SETTINGS)
+define INSTALL_RULE
+ $(INSTALL) -m 755 -f $(bindir) $(NVIDIA_SETTINGS)
+ mkdir -p $(mandir)
+ $(INSTALL) -m 644 -f $(mandir) doc/$(MANPAGE)
+endef
LD_RUN_FLAG=-R/usr/X11R6/lib
else
ECHO=echo
-INSTALL_RULE=$(INSTALL) $(NVIDIA_SETTINGS) $(bindir)/$(NVIDIA_SETTINGS)
+define INSTALL_RULE
+ $(INSTALL) -m 755 $(NVIDIA_SETTINGS) $(bindir)/$(NVIDIA_SETTINGS)
+ mkdir -p $(mandir)
+ $(INSTALL) -m 644 doc/$(MANPAGE) $(mandir)
+ gzip -9f $(mandir)/$(MANPAGE)
+endef
endif
exec_prefix = $(prefix)
bindir = $(exec_prefix)/bin
+mandir = $(exec_prefix)/share/man/man1
X11R6_CFLAGS = -I $(X11R6_INC_DIR)
@@ -137,6 +147,8 @@ NVIDIA_SETTINGS_DISTDIR_DIRS := \
STAMP_C = g_stamp.c
+MANPAGE = nvidia-settings.1
+
# Define the files in the SAMPLES directory
SAMPLES = Makefile README nv-control-dvc.c nv-control-info.c \
diff --git a/doc/Makefile.inc b/doc/Makefile.inc
index 25c525a..63d32a6 100644
--- a/doc/Makefile.inc
+++ b/doc/Makefile.inc
@@ -28,4 +28,5 @@
EXTRA_DIST += \
NV-CONTROL-API.txt \
FRAMELOCK.txt \
- nvidia-settings-user-guide.txt
+ nvidia-settings-user-guide.txt \
+ nvidia-settings.1
diff --git a/doc/nvidia-settings-user-guide.txt b/doc/nvidia-settings-user-guide.txt
index bf100ab..6737eb9 100644
--- a/doc/nvidia-settings-user-guide.txt
+++ b/doc/nvidia-settings-user-guide.txt
@@ -1,336 +1,2 @@
-
- NVIDIA-SETTINGS USER GUIDE
-
-CONTENTS:
-
- 1. Introduction
- 2. Layout of the nvidia-settings GUI
- 3. How OpenGL Interacts with nvidia-settings
- 4. Loading Settings Automatically
- 5. Commandline Interface
- 6. X Display Names in the Config File
- 7. Connecting to Remote X Servers
- 8. Licensing
- 9. TODO
-
-
-1. Introduction
-
- The `nvidia-settings` utility is a tool for configuring the NVIDIA
- Linux graphics driver. It operates by communicating with the NVIDIA
- X driver, querying and updating state as appropriate. This
- communication is done with the NV-CONTROL X extension.
-
- Values such as brightness and gamma, XVideo attributes, temperature,
- and OpenGL settings can be queried and configured via nvidia-settings.
-
- When nvidia-settings starts, it reads the current settings from
- its configuration file and sends those settings to the X server.
- Then, it displays a graphical user interface (GUI) interface for
- configuring the current settings. When nvidia-settings exits, it
- queries the current settings from the X server and saves them to
- the configuration file.
-
-
-
-2. Layout of the nvidia-settings GUI
-
- The nvidia-settings GUI is organized with a list of different
- categories on the left side. Only one entry in the list can be
- selected at once, and the selected category controls which
- "page" is displayed on the right side of the nvidia-settings GUI.
-
- The category list is organized in a tree: each X screen contains
- the relevant subcategories beneath it. Similarly, the Display
- Devices category for a screen contains all the enabled display
- devices beneath it. Besides each X screen, the other top level
- category is "nvidia-settings Configuration", which configures
- behavior of the nvidia-settings application itself.
-
- Along the bottom of the nvidia-settings GUI, from left to right, is:
- 1) a status bar which indicates the most recently altered option;
- 2) a Help button that toggles the display of a help window which
- provides a detailed explanation of the available options in the
- current page; and 3) a Quit button to exit nvidia-settings.
-
- Most options throughout nvidia-settings are applied immediately.
- Notable exceptions are OpenGL options which are only read by OpenGL
- when an OpenGL application starts.
-
- Details about the options on each page of nvidia-settings are
- available in the help window.
-
-
-
-3. How OpenGL Interacts with nvidia-settings
-
- When an OpenGL application starts, it downloads the current values
- from the X driver, and then reads the environment (see APPENDIX E:
- OPENGL ENVIRONMENT VARIABLE SETTINGS in the README). Settings from
- the X server override OpenGL's default values, and settings from
- the environment override values from the X server.
-
- For example, by default OpenGL uses the FSAA setting requested by
- the application (normally, applications do not request any FSAA).
- An FSAA setting specified in nvidia-settings would override
- the OpenGL application's request. Similarly, the __GL_FSAA_MODE
- environment variable will override the application's FSAA setting,
- as well as any FSAA setting specified in nvidia-settings.
-
- Note that an OpenGL application only retrieves settings from the X
- server when it starts, so if you make a change to an OpenGL value
- in nvidia-settings, it will only apply to OpenGL applications which
- are started after that point in time.
-
-
-
-4. Loading Settings Automatically
-
- The NVIDIA X driver does not preserve values set with nvidia-settings
- between runs of the X server (or even between logging in and logging
- out of X, with xdm, gdm, or kdm). This is intentional, because
- different users may have different preferences, thus these settings
- are stored on a per user basis in a configuration file stored in
- the user's home directory.
-
- The configuration file is named "~/.nvidia-settings-rc". You can
- specify a different configuration file name with the "--config"
- commandline option.
-
- After you have run nvidia-settings once and have generated a
- configuration file, you can then run:
-
- nvidia-settings --load-config-only
-
- at any time in the future to upload these settings to the X
- server again. For example, you might place the above command in
- your ~/.xinitrc file so that your settings are applied automatically
- when you log in to X.
-
- Your .xinitrc file, which controls what X applications should
- be started when you log into X (or startx), might look something
- like this:
-
- nvidia-settings --load-config-only &
- xterm &
- evilwm
-
- or:
-
- nvidia-settings --load-config-only &
- gnome-session
-
- If you do not already have an ~/.xinitrc file, then chances are that
- xinit is using a system-wide xinitrc file. This system wide file
- is typically here:
-
- /etc/X11/xinit/xinitrc
-
- To use it, but also have nvidia-settings upload your settings,
- you could create an ~/.xinitrc with the contents:
-
- nvidia-settings --load-config-only &
- . /etc/X11/xinit/xinitrc
-
- System administrators may choose to place the nvidia-settings load
- command directly in the system xinitrc script.
-
- Please see the xinit(1) manpage for further details of configuring
- your ~/.xinitrc file.
-
-
-
-5. Commandline Interface
-
- nvidia-settings has a rich commandline interface: all attributes
- that can be manipulated with the GUI can also be queried and set from
- the command line. The commandline syntax for querying and assigning
- attributes matches that of the .nvidia-settings-rc configuration file.
-
- The "--query" option can be used to query the current value of
- attributes. This will also report the valid values for the attribute.
- You can run `nvidia-settings --query all` for a complete list of
- available attributes, what the current value is, and what values
- are valid for the attribute. Additionally, individual attributes
- may be specified like this:
-
- nvidia-settings --query CursorShadow
-
- Attributes that may differ per display device (for example
- DigitalVibrance can be set independently on each display device
- when in TwinView) can be appended with a "display device name"
- within brackets; eg:
-
- nvidia-settings --query DigitalVibrance[CRT-0]
-
- If an attribute is display device specific, but the query does not
- specify a display device, then the attribute value for all display
- devices will be queried.
-
- An attribute name may be prepended with an X Display name and a
- forward slash to indicate a different X Display; eg:
-
- nvidia-settings --query 192.168.1.33:0.0/DigitalVibrance[DFP-1]
-
- An attribute name may also just be prepended with the screen number
- and a forward slash:
-
- nvidia-settings --query 0/DigitalVibrance[DFP-1]
-
- in which case the default X Display will be used, but you can indicate
- to which X screen to direct the query (if your X server has multiple
- X screens). If no X screen is specified, then the attribute value
- will be queried for all X screens.
-
-
- The "--assign" option can be used to assign a new value to an
- attribute. The valid values for an attribute are reported when the
- attribute is queried. The syntax for --assign is the same as --query,
- with the additional requirement that assignments also have an equal
- sign and the new value. For example:
-
- nvidia-settings --assign FSAA=2
- nvidia-settings --assign 0/DigitalVibrance[CRT-1]=9
-
-
- Multiple queries and assignments may be specified on the commandline
- for a single invocation of nvidia-settings.
-
- If either the --query or --assign options are passed to
- nvidia-settings, the GUI will not be presented, and nvidia-settings
- will exit after processing the assignments and/or queries.
-
-
-
-6. X Display Names in the Config File
-
- In the Commandline Interface section above, it was noted that you
- can specify an attribute without any X Display qualifiers, with only
- an X screen qualifier, or with a full X Display name. For example:
-
- nvidia-settings --query FSAA
- nvidia-settings --query 0/FSAA
- nvidia-settings --query stravinsky.nvidia.com:0/FSAA
-
- In the first two cases, the default X Display will be used, in the
- second case, the screen from the default X Display can be overridden,
- and in the third case, the entire default X Display can be overridden.
-
- The same possibilities are available in the ~/.nvidia-settings-rc
- configuration file.
-
- For example, in a computer lab environment, you might log into any
- of multiple workstations, and your home directory is NFS mounted
- to each workstation. In such a situation, you might want your
- ~/.nvidia-settings-rc file to be applicable to all the workstations.
- Therefore, you would not want your config file to qualify each
- attribute with an X Display Name. Leave the "Include X Display Names
- in the Config File" option unchecked on the nvidia-settings Configuration
- page (this is the default).
-
- There may be cases when you do want attributes in the config file to
- be qualified with the X Display name. If you know what you are doing
- and want config file attributes to be qualified with an X Display,
- check the "Include X Display Names in the Config File" option on the
- nvidia-settings Configuration page.
-
- In the typical home user environment where your home directory is
- local to one computer and you are only configuring one X Display,
- then it does not matter whether each attribute setting is
- qualified with an X Display Name.
-
-
-
-7. Connecting to Remote X Servers
-
- nvidia-settings is an X client, but uses two separate X connections:
- one to display the GUI, and another to communicate the NV-CONTROL
- requests. These two X connections do not need to be to the same
- X server. For example, you might run nvidia-settings on the
- computer stravinsky.nvidia.com, export the display to the computer
- bartok.nvidia.com, but be configuring the X server on the computer
- schoenberg.nvidia.com:
-
- nvidia-settings --display=bartok.nvidia.com:0 \
- --ctrl-display=schoenberg.nvidia.com:0
-
- If "--ctrl-display" is not specified, then the X Display to control
- is what "--display" indicates. If "--display" is also not specified,
- then the $DISPLAY environment variable is used.
-
- Note, however, that you will need to have X permissions configured
- such that you can establish an X connection from the computer on
- which you are running nvidia-settings (stravinsky.nvidia.com) to the
- computer where you are displaying the GUI (bartok.nvidia.com) and the
- computer whose X Display you are configuring (schoenberg.nvidia.com).
-
- The simplest, most common, and least secure mechanism to do this
- is to use 'xhost' to allow access from the computer on which
- you are running nvidia-settings.
-
- (issued from bartok.nvidia.com)
- xhost +stravinsky.nvidia.com
-
- (issued from schoenberg.nvidia.com)
- xhost +stravinsky.nvidia.com
-
- This will allow all X clients run on stravinsky.nvidia.com to
- connect and display on bartok.nvidia.com's X server and configure
- schoenberg.nvidia.com's X server.
-
- Please see the xauth(1) and xhost(1) manpages, or refer to your Linux
- Distribution's documentation on remote X applications and security.
- You might also google for terms such as "remote X security" or "remote
- X Windows", and see documents such as the Remote X Apps mini-HOWTO:
-
- http://www.tldp.org/HOWTO/Remote-X-Apps.html
-
- Please also note that the remote X server to be controlled must
- be using the NVIDIA X driver.
-
-
-
-8. Licensing
-
- The source code to nvidia-settings is released as GPL. The most
- recent official version of the source code is available here:
-
- ftp://download.nvidia.com/XFree86/nvidia-settings/
-
- Note that nvidia-settings is simply an NV-CONTROL client. It uses
- the NV-CONTROL X extension to communicate with the NVIDIA X server
- to query current settings and make changes to settings.
-
- You can make additions directly to nvidia-settings, or write your
- own NV-CONTROL client, using nvidia-settings as an example.
-
- Documentation on the NV-CONTROL extension and additional sample
- clients are available in the nvidia-settings source tarball.
-
- Patches can be submitted to linux-bugs@nvidia.com.
-
-
-
-9. TODO
-
- There are many things still to be added to nvidia-settings. Some of
- which include:
-
- - configurability of TwinView (NVIDIA is planning to implement this)
-
- - configurability of multiple X screens (NVIDIA is planning to
- implement this)
-
- - different toolkits? the GUI for nvidia-settings is cleanly
- abstracted from the backend of nvidia-settings that parses
- the configuration file and commandline, communicates with the X
- server, etc. If someone were so inclined, a different frontend
- GUI could be implemented.
-
- - write a design document explaining how nvidia-settings is
- architected; presumably this would make it easier for people to
- become familiar with the code base.
-
- If there are other things you would like to see added (or better yet,
- would like to add yourself), please contact linux-bugs@nvidia.com.
-
+The nvidia-settings user guide has been moved to the nvidia-settings(1) man
+page.
diff --git a/doc/nvidia-settings.1 b/doc/nvidia-settings.1
new file mode 100644
index 0000000..6149adf
--- /dev/null
+++ b/doc/nvidia-settings.1
@@ -0,0 +1,507 @@
+.\" Copyright (C) 2005 NVIDIA Corporation.
+.\" Define the URL macro and then load the URL package if it exists.
+.de URL
+\\$2 \(la \\$1 \(ra\\$3
+..
+.if \n[.g] .mso www.tmac
+.TH nvidia-settings 1 2005-09-06 "nvidia-settings 1.0"
+.SH NAME
+nvidia\-settings \- configure the NVIDIA graphics driver
+.SH SYNOPSIS
+.BI "nvidia\-settings [" "options" "]"
+.br
+.BI "nvidia\-settings [" "options" "] \-\-load\-config\-only"
+.br
+.BI "nvidia\-settings [" "options" "] {\-\-query=" attr " | \-\-assign=" attr = value "} ..."
+.br
+.BI "nvidia\-settings [" "options" "] \-\-glxinfo"
+.PP
+Options:
+.BI "[-vh] [\-\-config=" configfile "] [\-c " ctrl-display ]
+.PP
+.I attr
+has the form:
+.ti +5
+.IB DISPLAY / attribute_name [ display_devices ]
+.SH DESCRIPTION
+The
+.B nvidia\-settings
+utility is a tool for configuring the NVIDIA Linux graphics driver.
+It operates by communicating with the NVIDIA X driver, querying and updating state as appropriate.
+This communication is done with the NV-CONTROL X extension.
+.PP
+Values such as brightness and gamma, XVideo attributes, temperature, and OpenGL settings can be queried and configured via
+.B nvidia\-settings.
+.PP
+When
+.B nvidia\-settings
+starts, it reads the current settings from its configuration file and sends those settings to the X server.
+Then, it displays a graphical user interface (GUI) for configuring the current settings.
+When
+.B nvidia\-settings
+exits, it queries the current settings from the X server and saves them to the configuration file.
+.SH OPTIONS
+.TP
+.B \-v, \-\-version
+Print the
+.B nvidia\-settings
+version and exit.
+.TP
+.B \-h, \-\-help
+Print usage information and exit.
+.TP
+.BI "\-\-config=" config
+Use the configuration file
+.I config
+rather than the default
+.I ~/.nvidia-settings-rc
+.TP
+.BI "\-c, \-\-ctrl\-display=" ctrl-display
+Control the specified X display.
+If this option is not given, then
+.B nvidia\-settings
+will control the display specifed by
+.B \-\-display.
+If that is not given, then the
+.I $DISPLAY
+environment variable is used.
+.TP
+.B \-l, \-\-load\-config\-only
+Load the configuration file, send the values specified therein to the X server, and exit.
+This mode of operation is useful to place in your .xinitrc file, for example.
+.TP
+.BI "\-a, \-\-assign=" assign
+The
+.I assign
+argument to the
+.B \-\-assign
+commandline option is of the form:
+.nf
+
+ {DISPLAY}/{attribute name}[{display devices}]={value}
+
+.fi
+This assigns the attribute {attribute name} to the value {value} on the X Display {DISPLAY}.
+{DISPLAY} follows the usual {host}:{display}.{screen} syntax of the DISPLAY environment variable and is optional; when it is not specified, then it is implied following the same rule as the
+.B \-\-ctrl\-display
+option.
+If the X screen is not specified, then the assignment is made to all X screens.
+Note that the '/' is only required when {DISPLAY} is present.
+The [{display devices}] portion is also optional; if it is not specified, then the attribute is assigned to all display devices.
+Some examples:
+.nf
+
+ -a FSAA=5
+ -a localhost:0.0/DigitalVibrance[CRT-0]=0
+ --assign="SyncToVBlank=1"
+
+.fi
+.TP
+.BI "\-q, \-\-query=" query
+The
+.I query
+argument to the
+.B \-\-query
+commandline option is of the form:
+.nf
+
+ {DISPLAY}/{attribute name}[{display devices}]
+
+.fi
+This queries the current value of the attribute {attribute name} on the X Display {DISPLAY}.
+The format is the same as that for the
+.B \-\-assign
+option, without
+.B ={value}.
+Specify
+.B \-q all'
+to query all attributes.
+.TP
+.B \-g, \-\-glxinfo
+Print GLX Information for the X display and exit.
+.SH "USER GUIDE"
+.SS Contents
+1. Layout of the nvidia\-settings GUI
+.br
+2. How OpenGL Interacts with nvidia-settings
+.br
+3. Loading Settings Automatically
+.br
+4. Commandline Interface
+.br
+5. X Display Names in the Config File
+.br
+6. Connecting to Remote X Servers
+.br
+7. Licensing
+.br
+8. TODO
+.br
+.SS 1. Layout of the nvidia\-settings GUI
+The
+.B nvidia\-settings
+GUI is organized with a list of different categories on the left side.
+Only one entry in the list can be selected at once, and the selected category controls which "page" is displayed on the right side of the
+.B nvidia\-settings
+GUI.
+.PP
+The category list is organized in a tree: each X screen contains the relevant subcategories beneath it.
+Similarly, the Display Devices category for a screen contains all the enabled display devices beneath it.
+Besides each X screen, the other top level category is "nvidia-settings Configuration", which configures behavior of the
+.B nvidia\-settings
+application itself.
+.PP
+Along the bottom of the
+.B nvidia\-settings
+GUI, from left to right, is:
+.TP
+1)
+a status bar which indicates the most recently altered option;
+.TP
+2)
+a Help button that toggles the display of a help window which provides a detailed explanation of the available options in the current page; and
+.TP
+3)
+a Quit button to exit
+.B nvidia\-settings.
+.PP
+Most options throughout
+.B nvidia\-settings
+are applied immediately.
+Notable exceptions are OpenGL options which are only read by OpenGL when an OpenGL application starts.
+.PP
+Details about the options on each page of
+.B nvidia\-settings
+are available in the help window.
+.SS 2. How OpenGL Interacts with nvidia-settings
+.PP
+When an OpenGL application starts, it downloads the current values from the X driver, and then reads the environment (see
+.I APPENDIX E: OPENGL ENVIRONMENT VARIABLE SETTINGS
+in the README).
+Settings from the X server override OpenGL's default values, and settings from the environment override values from the X server.
+.PP
+For example, by default OpenGL uses the FSAA setting requested by the application (normally, applications do not request any FSAA).
+An FSAA setting specified in
+.B nvidia\-settings
+would override the OpenGL application's request.
+Similarly, the
+.B __GL_FSAA_MODE
+environment variable will override the application's FSAA setting, as well as any FSAA setting specified in
+.B nvidia\-settings.
+.PP
+Note that an OpenGL application only retrieves settings from the X server when
+it starts, so if you make a change to an OpenGL value in
+.B nvidia\-settings,
+it will only apply to OpenGL applications which are started after that point in time.
+.SS 3. Loading Settings Automatically
+The NVIDIA X driver does not preserve values set with
+.B nvidia\-settings
+between runs of the X server (or even between logging in and logging out of X, with
+.BR xdm (1),
+.B gdm,
+or
+.B kdm
+).
+This is intentional, because different users may have different preferences, thus these settings are stored on a per-user basis in a configuration file stored in the user's home directory.
+.PP
+The configuration file is named
+.IR ~/.nvidia\-settings\-rc .
+You can specify a different configuration file name with the
+.B \-\-config
+commandline option.
+.PP
+After you have run
+.B nvidia\-settings
+once and have generated a configuration file, you can then run:
+.sp
+.ti +5
+nvidia-settings --load-config-only
+.sp
+at any time in the future to upload these settings to the X server again.
+For example, you might place the above command in your
+.I ~/.xinitrc
+file so that your settings are applied automatically when you log in to X.
+.PP
+Your
+.I .xinitrc
+file, which controls what X applications should be started when you log into X (or startx), might look something like this:
+.nf
+
+ nvidia-settings --load-config-only &
+ xterm &
+ evilwm
+
+.fi
+or:
+.nf
+
+ nvidia-settings --load-config-only &
+ gnome-session
+
+.fi
+If you do not already have an
+.I ~/.xinitrc
+file, then chances are that
+.BR xinit (1)
+is using a system-wide xinitrc file.
+This system wide file is typically here:
+.nf
+
+ /etc/X11/xinit/xinitrc
+
+.fi
+To use it, but also have
+.B nvidia\-settings
+upload your settings, you could create an
+.I ~/.xinitrc
+with the contents:
+.nf
+
+ nvidia-settings --load-config-only &
+ . /etc/X11/xinit/xinitrc
+
+.fi
+System administrators may choose to place the
+.B nvidia\-settings
+load command directly in the system xinitrc script.
+.PP
+Please see the
+.BR xinit (1)
+man page for further details of configuring your
+.I ~/.xinitrc
+file.
+.SS 4. Commandline Interface
+.B nvidia\-settings
+has a rich commandline interface: all attributes that can be manipulated with the GUI can also be queried and set from the command line.
+The commandline syntax for querying and assigning attributes matches that of the
+.I .nvidia\-settings\-rc
+configuration file.
+.PP
+The
+.B \-\-query
+option can be used to query the current value of attributes.
+This will also report the valid values for the attribute.
+You can run
+.B nvidia\-settings \-\-query all
+for a complete list of available attributes, what the current value is, and what values are valid for the attribute.
+Additionally, individual attributes may be specified like this:
+.nf
+
+ nvidia-settings --query CursorShadow
+
+.fi
+Attributes that may differ per display device (for example DigitalVibrance can be set independently on each display device when in TwinView) can be appended with a "display device name" within brackets; e.g.:
+.nf
+
+ nvidia-settings --query DigitalVibrance[CRT-0]
+
+.fi
+If an attribute is display device specific, but the query does not specify a display device, then the attribute value for all display devices will be queried.
+.PP
+An attribute name may be prepended with an X Display name and a forward slash
+to indicate a different X Display; e.g.:
+.nf
+
+ nvidia-settings --query 192.168.1.33:0.0/DigitalVibrance[DFP-1]
+
+.fi
+An attribute name may also just be prepended with the screen number and a forward slash:
+.nf
+
+ nvidia-settings --query 0/DigitalVibrance[DFP-1]
+
+.fi
+in which case the default X Display will be used, but you can indicate to which X screen to direct the query (if your X server has multiple X screens).
+If no X screen is specified, then the attribute value will be queried for all X screens.
+.PP
+The
+.B \-\-assign
+option can be used to assign a new value to an attribute.
+The valid values for an attribute are reported when the attribute is queried.
+The syntax for
+.B \-\-assign
+is the same as
+.B \-\-query,
+with the additional requirement that assignments also have an equal sign and the new value.
+For example:
+.nf
+
+ nvidia-settings --assign FSAA=2
+ nvidia-settings --assign 0/DigitalVibrance[CRT-1]=9
+
+.fi
+.PP
+Multiple queries and assignments may be specified on the commandline for a single invocation of
+.B nvidia\-settings.
+.PP
+If either the
+.B \-\-query
+or
+.B \-\-assign
+options are passed to
+.B nvidia\-settings,
+the GUI will not be presented, and
+.B nvidia\-settings
+will exit after processing the assignments and/or queries.
+.SS 5. X Display Names in the Config File
+In the Commandline Interface section above, it was noted that you can specify an attribute without any X Display qualifiers, with only an X screen qualifier, or with a full X Display name.
+For example:
+.nf
+
+ nvidia-settings --query FSAA
+ nvidia-settings --query 0/FSAA
+ nvidia-settings --query stravinsky.nvidia.com:0/FSAA
+
+.fi
+In the first two cases, the default X Display will be used, in the second case, the screen from the default X Display can be overridden, and in the third case, the entire default X Display can be overridden.
+.PP
+The same possibilities are available in the
+.I ~/.nvidia\-settings-rc
+configuration file.
+.PP
+For example, in a computer lab environment, you might log into any of multiple
+workstations, and your home directory is NFS mounted to each workstation.
+In such a situation, you might want your
+.I ~/.nvidia\-settings-rc
+file to be applicable to all the workstations.
+Therefore, you would not want your config file to qualify each attribute with an X Display Name.
+Leave the "Include X Display Names in the Config File" option unchecked on the
+.B nvidia\-settings
+Configuration page (this is the default).
+.PP
+There may be cases when you do want attributes in the config file to be qualified with the X Display name.
+If you know what you are doing and want config file attributes to be qualified with an X Display, check the "Include X Display Names in the Config File" option on the
+.B nvidia\-settings
+Configuration page.
+.PP
+In the typical home user environment where your home directory is local to one computer and you are only configuring one X Display, then it does not matter whether each attribute setting is qualified with an X Display Name.
+.SS 6. Connecting to Remote X Servers
+.B nvidia\-settings
+is an X client, but uses two separate X connections: one to display the GUI, and another to communicate the NV-CONTROL requests.
+These two X connections do not need to be to the same X server.
+For example, you might run
+.B nvidia\-settings
+on the computer stravinsky.nvidia.com, export the display to the computer bartok.nvidia.com, but be configuring the X server on the computer schoenberg.nvidia.com:
+.nf
+
+ nvidia-settings --display=bartok.nvidia.com:0 \\
+ --ctrl-display=schoenberg.nvidia.com:0
+
+.fi
+If
+.B \-\-ctrl-display
+is not specified, then the X Display to control is what
+.B \-\-display
+indicates.
+If
+.B \-\-display
+is also not specified, then the
+.I $DISPLAY
+environment variable is used.
+.PP
+Note, however, that you will need to have X permissions configured such that you can establish an X connection from the computer on which you are running
+.B nvidia\-settings
+(stravinsky.nvidia.com) to the computer where you are displaying the GUI (bartok.nvidia.com) and the computer whose X Display you are configuring (schoenberg.nvidia.com).
+.PP
+The simplest, most common, and least secure mechanism to do this is to use 'xhost' to allow access from the computer on which you are running
+.B nvidia\-settings.
+.nf
+
+ (issued from bartok.nvidia.com)
+ xhost +stravinsky.nvidia.com
+
+ (issued from schoenberg.nvidia.com)
+ xhost +stravinsky.nvidia.com
+
+.fi
+This will allow all X clients run on stravinsky.nvidia.com to connect and display on bartok.nvidia.com's X server and configure schoenberg.nvidia.com's X server.
+.PP
+Please see the
+.BR xauth (1)
+and
+.BR xhost (1)
+man pages, or refer to your Linux Distribution's documentation on remote X applications and security.
+You might also Google for terms such as "remote X security" or "remote X Windows", and see documents such as the Remote X Apps mini-HOWTO:
+.sp
+.ti +5
+.URL http://www.tldp.org/HOWTO/Remote-X-Apps.html
+.sp
+Please also note that the remote X server to be controlled must be using the NVIDIA X driver.
+.SS 7. Licensing
+The source code to
+.B nvidia\-settings
+is released as GPL.
+The most recent official version of the source code is available here:
+.sp
+.ti +5
+.URL ftp://download.nvidia.com/XFree86/nvidia-settings/
+.sp
+Note that
+.B nvidia\-settings
+is simply an NV-CONTROL client.
+It uses the NV-CONTROL X extension to communicate with the NVIDIA X server to query current settings and make changes to settings.
+.PP
+You can make additions directly to
+.B nvidia\-settings,
+or write your own NV-CONTROL client, using
+.B nvidia\-settings
+as an example.
+.PP
+Documentation on the NV-CONTROL extension and additional sample clients are available in the
+.B nvidia\-settings
+source tarball.
+Patches can be submitted to linux-bugs@nvidia.com.
+.SS 8. TODO
+There are many things still to be added to
+.B nvidia\-settings,
+some of which include:
+.TP
+-
+configurability of TwinView (NVIDIA is planning to implement this)
+.TP
+-
+configurability of multiple X screens (NVIDIA is planning to implement this)
+.TP
+-
+different toolkits?
+The GUI for
+.B nvidia\-settings
+is cleanly abstracted from the backend of
+.B nvidia\-settings
+that parses the configuration file and commandline, communicates with the X server, etc.
+If someone were so inclined, a different frontend GUI could be implemented.
+.TP
+-
+write a design document explaining how
+.B nvidia\-settings
+is architected; presumably this would make it easier for people to become familiar with the code base.
+.PP
+If there are other things you would like to see added (or better yet, would like to add yourself), please contact linux-bugs@nvidia.com.
+.SH FILES
+.TP
+.I ~/.nvidia\-settings\-rc
+.SH EXAMPLES
+.TP
+.B nvidia\-settings
+Starts the
+.B nvidia\-settings
+graphical interface.
+.TP
+.B nvidia\-settings \-\-load\-config\-only
+Loads the settings stored in
+.I ~/.nvidia-settings-rc
+.TP
+.B nvidia\-settings \-\-query FSAA
+Query the value of the full-screen antialiasing setting.
+.TP
+.B nvidia\-settings \-\-assign RedGamma=2.0 \-\-assign BlueGamma=2.0 \-\-assign GreenGamma=2.0
+Set the gamma of the screen to 2.0.
+.SH AUTHOR
+Aaron Plattner
+.br
+NVIDIA Corporation
+.SH "SEE ALSO"
+.BR nvidia\-xconfig (1),
+.BR nvidia\-installer (1)
+.SH COPYRIGHT
+Copyright \(co 2005 NVIDIA Corporation.
diff --git a/samples/nv-control-events.c b/samples/nv-control-events.c
index 2f89eaa..884c9c0 100644
--- a/samples/nv-control-events.c
+++ b/samples/nv-control-events.c
@@ -135,6 +135,7 @@ static const char *attr2str(int n)
case NV_CTRL_FORCE_GENERIC_CPU: return "force generic cpu"; break;
case NV_CTRL_OPENGL_AA_LINE_GAMMA: return "opengl aa line gamma"; break;
case NV_CTRL_FLIPPING_ALLOWED: return "flipping allowed"; break;
+ case NV_CTRL_FORCE_STEREO: return "force stereo"; break;
case NV_CTRL_TEXTURE_CLAMPING: return "texture clamping"; break;
case NV_CTRL_CURSOR_SHADOW: return "cursor shadow"; break;
case NV_CTRL_CURSOR_SHADOW_ALPHA: return "cursor shadow alpha"; break;
diff --git a/src/config-file.c b/src/config-file.c
index 83a739b..9c2a4a1 100644
--- a/src/config-file.c
+++ b/src/config-file.c
@@ -540,9 +540,10 @@ static int process_config_file_attributes(const char *file,
"on line %d of configuration file "
"'%s'", w[i].line, file);
/*
- * XXX should we fail if processing the attribute failed? For
- * now, we'll just keep going through the rest of the config
- * file.
+ * We do not fail if processing the attribute failed.
+ * If the GPU or the X config changed (for example stereo is disabled),
+ * some attributes written in the config file may not be advertised by
+ * the the NVCTRL extension (for example the control to force stereo)
*/
}
diff --git a/src/gtk+-2.x/Makefile.inc b/src/gtk+-2.x/Makefile.inc
index 947c560..1adf9cb 100644
--- a/src/gtk+-2.x/Makefile.inc
+++ b/src/gtk+-2.x/Makefile.inc
@@ -52,7 +52,8 @@ SRC += \
ctkdropdownmenu.c \
ctkrandr.c \
ctkclocks.c \
- ctkutils.c
+ ctkutils.c \
+ ctkedid.c
EXTRA_DIST += \
@@ -83,4 +84,5 @@ EXTRA_DIST += \
ctkdropdownmenu.h \
ctkrandr.h \
ctkclocks.h \
- ctkutils.h
+ ctkutils.h \
+ ctkedid.h
diff --git a/src/gtk+-2.x/ctkclocks.c b/src/gtk+-2.x/ctkclocks.c
index 23d7533..3f1d977 100644
--- a/src/gtk+-2.x/ctkclocks.c
+++ b/src/gtk+-2.x/ctkclocks.c
@@ -279,7 +279,6 @@ GtkWidget* ctk_clocks_new(NvCtrlAttributeHandle *handle,
GtkWidget *menu_item;
GtkWidget *scrollWin;
GtkWidget *event;
- GdkColor color;
GtkWidget *label;
@@ -553,8 +552,8 @@ GtkWidget* ctk_clocks_new(NvCtrlAttributeHandle *handle,
event = gtk_event_box_new();
ctk_object->license_window = scrollWin;
- gdk_color_parse("white", &color);
- gtk_widget_modify_bg(event, GTK_STATE_NORMAL, &color);
+ gtk_widget_modify_fg(event, GTK_STATE_NORMAL, &(event->style->text[GTK_STATE_NORMAL]));
+ gtk_widget_modify_bg(event, GTK_STATE_NORMAL, &(event->style->base[GTK_STATE_NORMAL]));
gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
diff --git a/src/gtk+-2.x/ctkdevice.c b/src/gtk+-2.x/ctkdevice.c
index 6ee5d3b..05f9721 100644
--- a/src/gtk+-2.x/ctkdevice.c
+++ b/src/gtk+-2.x/ctkdevice.c
@@ -87,8 +87,7 @@ GtkWidget* ctk_device_new(
const nv_image_t *img;
char *product_name, *bus_type, *vbios_version, *video_ram, *irq;
- char *os, *arch, *version;
- char scratch[64];
+ char *os, *arch, *version, *bus_rate, *bus;
ReturnStatus ret;
gint tmp, os_val;
@@ -117,7 +116,25 @@ GtkWidget* ctk_device_new(
if (tmp == NV_CTRL_BUS_TYPE_PCI_EXPRESS) bus_type = "PCI Express";
}
if (!bus_type) bus_type = __unknown;
-
+
+ /* NV_CTRL_BUS_RATE */
+
+ bus_rate = NULL;
+ if (tmp == NV_CTRL_BUS_TYPE_AGP ||
+ tmp == NV_CTRL_BUS_TYPE_PCI_EXPRESS) {
+ ret = NvCtrlGetAttribute(handle, NV_CTRL_BUS_RATE, &tmp);
+ if (ret == NvCtrlSuccess) {
+ bus_rate = g_strdup_printf("%dX", tmp);
+ }
+ }
+
+ if (bus_rate != NULL) {
+ bus = g_strdup_printf("%s %s", bus_type, bus_rate);
+ g_free(bus_rate);
+ } else {
+ bus = g_strdup(bus_type);
+ }
+
/* NV_CTRL_STRING_VBIOS_VERSION */
ret = NvCtrlGetStringAttribute(handle, NV_CTRL_STRING_VBIOS_VERSION,
@@ -154,12 +171,11 @@ GtkWidget* ctk_device_new(
arch = NULL;
if (ret == NvCtrlSuccess) {
if (tmp == NV_CTRL_ARCHITECTURE_X86) arch = "x86";
- if (tmp == NV_CTRL_ARCHITECTURE_X86_64) arch = "amd64";
+ if (tmp == NV_CTRL_ARCHITECTURE_X86_64) arch = "x86_64";
if (tmp == NV_CTRL_ARCHITECTURE_IA64) arch = "ia64";
}
if (!arch) arch = __unknown;
-
- snprintf(scratch, 64, "%s-%s", os, arch);
+ os = g_strdup_printf("%s-%s", os, arch);
/* NV_CTRL_STRING_NVIDIA_DRIVER_VERSION */
@@ -242,15 +258,18 @@ GtkWidget* ctk_device_new(
add_table_row(table, 0, 0, "Graphics Processor:", product_name);
- add_table_row(table, 1, 0, "Bus Type:", bus_type);
+ add_table_row(table, 1, 0, "Bus Type:", bus);
add_table_row(table, 2, 0, "VBIOS Version:", vbios_version);
add_table_row(table, 3, 0, "Video Memory:", video_ram);
add_table_row(table, 4, 0, "IRQ:", irq);
- add_table_row(table, 5, 0, "Operating System:", scratch);
+ add_table_row(table, 5, 0, "Operating System:", os);
add_table_row(table, 6, 0, "NVIDIA Driver Version:", version);
-
-
+ g_free(bus);
+ g_free(video_ram);
+ g_free(irq);
+ g_free(os);
+
gtk_widget_show_all(GTK_WIDGET(object));
return GTK_WIDGET(object);
@@ -301,7 +320,7 @@ GtkTextBuffer *ctk_device_create_help(GtkTextTagTable *table,
"X driver is running; possible values are "
"'Linux' and 'FreeBSD'. This also specifies the platform "
"on which the operating system is running, such as x86, "
- "amd64, or ia64");
+ "x86_64, or ia64");
ctk_help_heading(b, &i, "NVIDIA Driver Version");
ctk_help_para(b, &i, "This is the version of the NVIDIA Accelerated "
diff --git a/src/gtk+-2.x/ctkdisplaydevice-crt.c b/src/gtk+-2.x/ctkdisplaydevice-crt.c
index 21f5777..f208ab8 100644
--- a/src/gtk+-2.x/ctkdisplaydevice-crt.c
+++ b/src/gtk+-2.x/ctkdisplaydevice-crt.c
@@ -30,6 +30,7 @@
#include "ctkdisplaydevice-crt.h"
#include "ctkimagesliders.h"
+#include "ctkedid.h"
#include "ctkconfig.h"
#include "ctkhelp.h"
@@ -75,11 +76,12 @@ GtkWidget* ctk_display_device_crt_new(NvCtrlAttributeHandle *handle,
GtkWidget *hbox;
GtkWidget *label;
GtkWidget *alignment;
+ GtkWidget *edid;
guint8 *image_buffer = NULL;
const nv_image_t *img;
char *s;
-
+
object = g_object_new(CTK_TYPE_DISPLAY_DEVICE_CRT, NULL);
ctk_display_device_crt = CTK_DISPLAY_DEVICE_CRT(object);
@@ -161,6 +163,18 @@ GtkWidget* ctk_display_device_crt_new(NvCtrlAttributeHandle *handle,
gtk_box_pack_start(GTK_BOX(object), label, FALSE, FALSE, 0);
}
+ /* pack the EDID button */
+
+ edid = ctk_edid_new(handle, ctk_config, ctk_event,
+ ctk_display_device_crt->reset_button,
+ display_device_mask, name);
+ if (edid) {
+ gtk_box_pack_start(GTK_BOX(object), edid, FALSE, FALSE, 0);
+ ctk_display_device_crt->edid_available = TRUE;
+ } else {
+ ctk_display_device_crt->edid_available = FALSE;
+ }
+
/* show the page */
gtk_widget_show_all(GTK_WIDGET(object));
@@ -185,11 +199,15 @@ GtkTextBuffer *ctk_display_device_crt_create_help(GtkTextTagTable *table,
ctk_help_title(b, &i, "%s Help", ctk_display_device_crt->name);
if (ctk_display_device_crt->image_sliders) {
- ret = add_image_sharpening_help
+ ret = add_image_sliders_help
(CTK_IMAGE_SLIDERS(ctk_display_device_crt->image_sliders), b, &i);
} else {
ret = FALSE;
}
+
+ if (ctk_display_device_crt->edid_available) {
+ add_acquire_edid_help(b, &i);
+ }
if (!ret) {
ctk_help_para(b, &i, "There are no configurable options available "
diff --git a/src/gtk+-2.x/ctkdisplaydevice-crt.h b/src/gtk+-2.x/ctkdisplaydevice-crt.h
index 3884533..f31632a 100644
--- a/src/gtk+-2.x/ctkdisplaydevice-crt.h
+++ b/src/gtk+-2.x/ctkdisplaydevice-crt.h
@@ -65,6 +65,7 @@ struct _CtkDisplayDeviceCrt
unsigned int display_device_mask;
unsigned int active_attributes;
+ gboolean edid_available;
char *name;
};
diff --git a/src/gtk+-2.x/ctkdisplaydevice-dfp.c b/src/gtk+-2.x/ctkdisplaydevice-dfp.c
index 8909ccc..d57cc15 100644
--- a/src/gtk+-2.x/ctkdisplaydevice-dfp.c
+++ b/src/gtk+-2.x/ctkdisplaydevice-dfp.c
@@ -30,6 +30,7 @@
#include "ctkdisplaydevice-dfp.h"
#include "ctkimagesliders.h"
+#include "ctkedid.h"
#include "ctkconfig.h"
#include "ctkhelp.h"
#include "ctkutils.h"
@@ -142,6 +143,7 @@ GtkWidget* ctk_display_device_dfp_new(NvCtrlAttributeHandle *handle,
GtkWidget *radio2;
GtkWidget *radio3;
GtkWidget *alignment;
+ GtkWidget *edid;
GtkWidget *table;
@@ -389,6 +391,18 @@ GtkWidget* ctk_display_device_dfp_new(NvCtrlAttributeHandle *handle,
FALSE, FALSE, 0);
}
+ /* pack the EDID button */
+
+ edid = ctk_edid_new(handle, ctk_config, ctk_event,
+ ctk_display_device_dfp->reset_button,
+ display_device_mask, name);
+ if (edid) {
+ gtk_box_pack_start(GTK_BOX(object), edid, FALSE, FALSE, 0);
+ ctk_display_device_dfp->edid_available = TRUE;
+ } else {
+ ctk_display_device_dfp->edid_available = FALSE;
+ }
+
/* show the page */
gtk_widget_show_all(GTK_WIDGET(object));
@@ -872,10 +886,14 @@ GtkTextBuffer *ctk_display_device_dfp_create_help(GtkTextTagTable *table,
}
if (ctk_display_device_dfp->image_sliders) {
- ret |= add_image_sharpening_help
+ ret |= add_image_sliders_help
(CTK_IMAGE_SLIDERS(ctk_display_device_dfp->image_sliders), b, &i);
}
+ if (ctk_display_device_dfp->edid_available) {
+ add_acquire_edid_help(b, &i);
+ }
+
if (!ret) {
ctk_help_para(b, &i, "There are no configurable options available "
"for %s.", ctk_display_device_dfp->name);
diff --git a/src/gtk+-2.x/ctkdisplaydevice-dfp.h b/src/gtk+-2.x/ctkdisplaydevice-dfp.h
index 8ab9740..b8c432a 100644
--- a/src/gtk+-2.x/ctkdisplaydevice-dfp.h
+++ b/src/gtk+-2.x/ctkdisplaydevice-dfp.h
@@ -68,6 +68,7 @@ struct _CtkDisplayDeviceDfp
unsigned int display_device_mask;
unsigned int active_attributes;
+ gboolean edid_available;
char *name;
};
diff --git a/src/gtk+-2.x/ctkdisplaydevice-tv.c b/src/gtk+-2.x/ctkdisplaydevice-tv.c
index 02648ab..ffe669c 100644
--- a/src/gtk+-2.x/ctkdisplaydevice-tv.c
+++ b/src/gtk+-2.x/ctkdisplaydevice-tv.c
@@ -43,6 +43,7 @@
#include "ctkdisplaydevice-tv.h"
#include "ctkimagesliders.h"
+#include "ctkedid.h"
#include "ctkconfig.h"
#include "ctkhelp.h"
#include "ctkscale.h"
@@ -141,6 +142,7 @@ GtkWidget* ctk_display_device_tv_new(NvCtrlAttributeHandle *handle,
GtkWidget *hbox;
GtkWidget *label;
GtkWidget *alignment;
+ GtkWidget *edid;
guint8 *image_buffer = NULL;
const nv_image_t *img;
@@ -302,6 +304,18 @@ GtkWidget* ctk_display_device_tv_new(NvCtrlAttributeHandle *handle,
"The Reset TV Hardware Defaults button restores "
"the TV settings to their default values.");
+ /* pack the EDID button */
+
+ edid = ctk_edid_new(handle, ctk_config, ctk_event,
+ ctk_display_device_tv->reset_button,
+ display_device_mask, name);
+ if (edid) {
+ gtk_box_pack_start(GTK_BOX(object), edid, FALSE, FALSE, 0);
+ ctk_display_device_tv->edid_available = TRUE;
+ } else {
+ ctk_display_device_tv->edid_available = FALSE;
+ }
+
/* finally, display the widget */
gtk_widget_show_all(GTK_WIDGET(object));
@@ -636,9 +650,13 @@ GtkTextBuffer *ctk_display_device_tv_create_help(GtkTextTagTable *table,
}
if (ctk_display_device_tv->image_sliders) {
- ret |= add_image_sharpening_help
+ ret |= add_image_sliders_help
(CTK_IMAGE_SLIDERS(ctk_display_device_tv->image_sliders), b, &i);
}
+
+ if (ctk_display_device_tv->edid_available) {
+ add_acquire_edid_help(b, &i);
+ }
if (!ret) {
ctk_help_para(b, &i, "There are no configurable options available "
diff --git a/src/gtk+-2.x/ctkdisplaydevice-tv.h b/src/gtk+-2.x/ctkdisplaydevice-tv.h
index 9cb98bd..dbeafe2 100644
--- a/src/gtk+-2.x/ctkdisplaydevice-tv.h
+++ b/src/gtk+-2.x/ctkdisplaydevice-tv.h
@@ -73,6 +73,7 @@ struct _CtkDisplayDeviceTv
unsigned int display_device_mask;
unsigned int active_attributes;
+ gboolean edid_available;
char *name;
};
diff --git a/src/gtk+-2.x/ctkedid.c b/src/gtk+-2.x/ctkedid.c
new file mode 100644
index 0000000..e408681
--- /dev/null
+++ b/src/gtk+-2.x/ctkedid.c
@@ -0,0 +1,271 @@
+/*
+ * nvidia-settings: A tool for configuring the NVIDIA X driver on Unix
+ * and Linux systems.
+ *
+ * Copyright (C) 2004 NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of Version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See Version 2
+ * of the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the:
+ *
+ * Free Software Foundation, Inc.
+ * 59 Temple Place - Suite 330
+ * Boston, MA 02111-1307, USA
+ *
+ */
+
+#include <string.h> /* memcpy(), strerror() */
+
+#include <gtk/gtk.h>
+#include <NvCtrlAttributes.h>
+
+#include "ctkedid.h"
+
+#include "ctkscale.h"
+#include "ctkconfig.h"
+#include "ctkhelp.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <errno.h>
+
+
+#define FRAME_PADDING 5
+
+#define DEFAULT_EDID_FILENAME "edid.bin"
+
+static const char *__acquire_edid_help =
+"The Acquire EDID button allows you to save the display device's EDID "
+"(Extended Display Identification Data) information to a file.";
+
+static void button_clicked(GtkButton *button, gpointer user_data);
+static gboolean write_edid_to_file(CtkConfig *ctk_config, const gchar *filename,
+ unsigned char *data, int len);
+
+GType ctk_edid_get_type(void)
+{
+ static GType ctk_edid_type = 0;
+
+ if (!ctk_edid_type) {
+ static const GTypeInfo ctk_edid_info = {
+ sizeof (CtkEdidClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ NULL, /* class_init, */
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (CtkEdid),
+ 0, /* n_preallocs */
+ NULL, /* instance_init */
+ };
+
+ ctk_edid_type = g_type_register_static (GTK_TYPE_VBOX,
+ "CtkEdid", &ctk_edid_info, 0);
+ }
+
+ return ctk_edid_type;
+}
+
+
+GtkWidget* ctk_edid_new(NvCtrlAttributeHandle *handle,
+ CtkConfig *ctk_config, CtkEvent *ctk_event,
+ GtkWidget *reset_button,
+ unsigned int display_device_mask,
+ char *name)
+{
+ CtkEdid *ctk_edid;
+ GObject *object;
+ GtkWidget *frame, *vbox, *label, *hbox, *alignment;
+ ReturnStatus ret;
+ gint val;
+
+ /* check if EDID is available for this display device */
+
+ ret = NvCtrlGetDisplayAttribute(handle, display_device_mask,
+ NV_CTRL_EDID_AVAILABLE, &val);
+
+ if ((ret != NvCtrlSuccess) || (val != NV_CTRL_EDID_AVAILABLE_TRUE)) {
+ return NULL;
+ }
+
+ /* create the object */
+
+ object = g_object_new(CTK_TYPE_EDID, NULL);
+
+ ctk_edid = CTK_EDID(object);
+
+ ctk_edid->handle = handle;
+ ctk_edid->ctk_config = ctk_config;
+ ctk_edid->reset_button = reset_button;
+ ctk_edid->display_device_mask = display_device_mask;
+ ctk_edid->name = name;
+ ctk_edid->filename = DEFAULT_EDID_FILENAME;
+ ctk_edid->file_selector = gtk_file_selection_new("Please select file where "
+ "EDID data will be "
+ "saved.");
+
+ gtk_file_selection_set_select_multiple(GTK_FILE_SELECTION(ctk_edid->file_selector),
+ FALSE);
+
+ /* create the frame and vbox */
+
+ frame = gtk_frame_new(NULL);
+ vbox = gtk_vbox_new(FALSE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(vbox), FRAME_PADDING);
+ gtk_container_add(GTK_CONTAINER(frame), vbox);
+ gtk_box_pack_start(GTK_BOX(object), frame, FALSE, FALSE, 0);
+
+ /* create the button and label */
+
+ label = gtk_label_new("Acquire EDID...");
+ hbox = gtk_hbox_new(FALSE, 0);
+ ctk_edid->button = gtk_button_new();
+
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 15);
+ gtk_container_add(GTK_CONTAINER(ctk_edid->button), hbox);
+
+ alignment = gtk_alignment_new(1, 1, 0, 0);
+ gtk_container_add(GTK_CONTAINER(alignment), ctk_edid->button);
+
+ gtk_box_pack_end(GTK_BOX(vbox), alignment, TRUE, TRUE, 0);
+
+ ctk_config_set_tooltip(ctk_config, ctk_edid->button,
+ __acquire_edid_help);
+
+ g_signal_connect(G_OBJECT(ctk_edid->button),
+ "clicked",
+ G_CALLBACK(button_clicked),
+ (gpointer) ctk_edid);
+
+ gtk_widget_show_all(GTK_WIDGET(object));
+
+ return GTK_WIDGET(object);
+
+} /* ctk_edid_new() */
+
+
+static void button_clicked(GtkButton *button, gpointer user_data)
+{
+ ReturnStatus ret;
+ CtkEdid *ctk_edid = CTK_EDID(user_data);
+ unsigned char *data = NULL;
+ int len = 0;
+ gint result;
+
+
+ /* Grab EDID information */
+
+ ret = NvCtrlGetBinaryAttribute(ctk_edid->handle,
+ ctk_edid->display_device_mask,
+ NV_CTRL_BINARY_DATA_EDID,
+ &data, &len);
+ if (ret != NvCtrlSuccess) {
+ ctk_config_statusbar_message(ctk_edid->ctk_config,
+ "No EDID available for %s.\n",
+ ctk_edid->name);
+ } else {
+
+ /* Ask user for filename */
+
+ gtk_file_selection_set_filename(GTK_FILE_SELECTION(ctk_edid->file_selector),
+ ctk_edid->filename);
+
+ result = gtk_dialog_run(GTK_DIALOG(ctk_edid->file_selector));
+ gtk_widget_hide(ctk_edid->file_selector);
+
+ switch ( result ) {
+ case GTK_RESPONSE_ACCEPT:
+ case GTK_RESPONSE_OK:
+
+ ctk_edid->filename =
+ gtk_file_selection_get_filename(GTK_FILE_SELECTION(ctk_edid->file_selector));
+
+ write_edid_to_file(ctk_edid->ctk_config, ctk_edid->filename,
+ data, len);
+
+ break;
+ default:
+ return;
+ }
+
+ } /* EDID available */
+
+ if (data) {
+ XFree(data);
+ }
+
+} /* button_clicked() */
+
+
+static gboolean write_edid_to_file(CtkConfig *ctk_config, const gchar *filename,
+ unsigned char *data, int len)
+{
+ int fd = -1;
+ char *dst = (void *) -1;
+ char *msg = "";
+
+ fd = open(filename, O_RDWR | O_CREAT | O_TRUNC,
+ S_IRUSR | S_IWUSR | S_IRGRP);
+ if (fd == -1) {
+ msg = "Unable to open file for writing";
+ goto fail;
+ }
+
+ if (lseek(fd, len - 1, SEEK_SET) == -1) {
+ msg = "Unable to set file size";
+ goto fail;
+ }
+
+ if (write(fd, "", 1) != 1) {
+ msg = "Unable to write output file size";
+ goto fail;
+ }
+
+ if ((dst = mmap(0, len, PROT_READ | PROT_WRITE,
+ MAP_SHARED, fd, 0)) == (void *) -1) {
+ msg = "Unable to map file for copying";
+ goto fail;
+ }
+
+ memcpy(dst, data, len);
+
+ if (munmap(dst, len) == -1) {
+ msg = "Unable to unmap output file";
+ goto fail;
+ }
+
+ close(fd);
+
+ ctk_config_statusbar_message(ctk_config,
+ "EDID written to %s.\n", filename);
+ return TRUE;
+
+ fail:
+
+ if (fd != -1) close(fd);
+
+ ctk_config_statusbar_message(ctk_config,
+ "Unable to write EDID to file '%s': %s (%s).",
+ filename, msg, strerror(errno));
+ return FALSE;
+
+} /* write_edid_to_file() */
+
+
+void add_acquire_edid_help(GtkTextBuffer *b, GtkTextIter *i)
+{
+ ctk_help_heading(b, i, "Acquire EDID");
+ ctk_help_para(b, i, __acquire_edid_help);
+
+} /* add_acquire_edid_help() */
diff --git a/src/gtk+-2.x/ctkedid.h b/src/gtk+-2.x/ctkedid.h
new file mode 100644
index 0000000..80a4258
--- /dev/null
+++ b/src/gtk+-2.x/ctkedid.h
@@ -0,0 +1,91 @@
+/*
+ * nvidia-settings: A tool for configuring the NVIDIA X driver on Unix
+ * and Linux systems.
+ *
+ * Copyright (C) 2004 NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of Version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See Version 2
+ * of the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the:
+ *
+ * Free Software Foundation, Inc.
+ * 59 Temple Place - Suite 330
+ * Boston, MA 02111-1307, USA
+ *
+ */
+
+#ifndef __CTK_EDID_H__
+#define __CTK_EDID_H__
+
+#include "ctkevent.h"
+#include "ctkconfig.h"
+
+G_BEGIN_DECLS
+
+#define CTK_TYPE_EDID (ctk_edid_get_type())
+
+#define CTK_EDID(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), CTK_TYPE_EDID, \
+ CtkEdid))
+
+#define CTK_EDID_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), CTK_TYPE_EDID, \
+ CtkEdidClass))
+
+#define CTK_IS_EDID(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CTK_TYPE_EDID))
+
+#define CTK_IS_EDID_CLASS(class) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), CTK_TYPE_EDID))
+
+#define CTK_EDID_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), CTK_TYPE_EDID, \
+ CtkEdidClass))
+
+typedef struct _CtkEdid CtkEdid;
+typedef struct _CtkEdidClass CtkEdidClass;
+
+struct _CtkEdid
+{
+ GtkVBox parent;
+
+ NvCtrlAttributeHandle *handle;
+ CtkConfig *ctk_config;
+ GtkWidget *reset_button;
+ GtkWidget *button;
+ GtkWidget *file_selector;
+
+ const gchar *filename;
+ char *name;
+
+ unsigned int display_device_mask;
+};
+
+struct _CtkEdidClass
+{
+ GtkVBoxClass parent_class;
+};
+
+GType ctk_edid_get_type (void) G_GNUC_CONST;
+GtkWidget* ctk_edid_new (NvCtrlAttributeHandle *,
+ CtkConfig *, CtkEvent *,
+ GtkWidget *reset_button,
+ unsigned int display_device_mask,
+ char *name);
+
+void ctk_edid_reset(CtkEdid *);
+
+void add_acquire_edid_help(GtkTextBuffer *b, GtkTextIter *i);
+
+
+G_END_DECLS
+
+#endif /* __CTK_EDID_H__ */
diff --git a/src/gtk+-2.x/ctkevent.c b/src/gtk+-2.x/ctkevent.c
index e77d7d1..4a1cfa6 100644
--- a/src/gtk+-2.x/ctkevent.c
+++ b/src/gtk+-2.x/ctkevent.c
@@ -26,7 +26,11 @@
* ctkevent.c - the CtkEvent object registers a new input source (the
* filedescriptor associated with the NV-CONTROL Display connection)
* with the glib main loop, and emits signals when any relevant
- * NV-CONTROL events occur.
+ * NV-CONTROL events occur. GUI elements can then register
+ * callback(s) on the CtkEvent object & Signal(s).
+ *
+ * In short:
+ * NV-CONTROL -> event -> glib -> CtkEvent -> signal -> GUI
*/
#include <gtk/gtk.h>
@@ -44,19 +48,32 @@ static gboolean ctk_event_check(GSource *);
static gboolean ctk_event_dispatch(GSource *, GSourceFunc, gpointer);
-typedef struct {
+/* List of who to contact on dpy events */
+typedef struct __CtkEventNodeRec {
+ CtkEvent *ctk_event;
+ int screen;
+ struct __CtkEventNodeRec *next;
+} CtkEventNode;
+
+/* dpys should have a single event source object */
+typedef struct __CtkEventSourceRec {
GSource source;
Display *dpy;
GPollFD event_poll_fd;
int event_base;
int randr_event_base;
- CtkEvent *ctk_event;
+
+ CtkEventNode *ctk_events;
+ struct __CtkEventSourceRec *next;
} CtkEventSource;
static guint signals[NV_CTRL_LAST_ATTRIBUTE + 1];
static guint signal_RRScreenChangeNotify;
+/* List of event sources to track (one per dpy) */
+CtkEventSource *event_sources = NULL;
+
GType ctk_event_get_type(void)
@@ -142,6 +159,7 @@ static void ctk_event_class_init(CtkEventClass *ctk_event_class)
MAKE_SIGNAL(NV_CTRL_FORCE_GENERIC_CPU);
MAKE_SIGNAL(NV_CTRL_OPENGL_AA_LINE_GAMMA);
MAKE_SIGNAL(NV_CTRL_FLIPPING_ALLOWED);
+ MAKE_SIGNAL(NV_CTRL_FORCE_STEREO);
MAKE_SIGNAL(NV_CTRL_ARCHITECTURE);
MAKE_SIGNAL(NV_CTRL_TEXTURE_CLAMPING);
MAKE_SIGNAL(NV_CTRL_CURSOR_SHADOW);
@@ -193,6 +211,11 @@ static void ctk_event_class_init(CtkEventClass *ctk_event_class)
MAKE_SIGNAL(NV_CTRL_GPU_OPTIMAL_CLOCK_FREQS);
MAKE_SIGNAL(NV_CTRL_GPU_OPTIMAL_CLOCK_FREQS_DETECTION_STATE);
MAKE_SIGNAL(NV_CTRL_USE_HOUSE_SYNC);
+ MAKE_SIGNAL(NV_CTRL_IMAGE_SETTINGS);
+ MAKE_SIGNAL(NV_CTRL_XINERAMA_STEREO);
+ MAKE_SIGNAL(NV_CTRL_BUS_RATE);
+ MAKE_SIGNAL(NV_CTRL_SHOW_SLI_HUD);
+ MAKE_SIGNAL(NV_CTRL_XV_SYNC_TO_DISPLAY);
#undef MAKE_SIGNAL
@@ -203,7 +226,7 @@ static void ctk_event_class_init(CtkEventClass *ctk_event_class)
* knows about.
*/
-#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_USE_HOUSE_SYNC
+#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_XV_SYNC_TO_DISPLAY
#warning "There are attributes that do not emit signals!"
#endif
@@ -220,22 +243,94 @@ static void ctk_event_class_init(CtkEventClass *ctk_event_class)
} /* ctk_event_class_init */
+
+/* - ctk_event_register_source()
+ *
+ * Keep track of event sources globally to support
+ * dispatching events on a dpy to multiple CtkEvent
+ * objects. Since the driver only sends out one event
+ * notification per dpy (client), there should only be one
+ * event source attached per unique dpy. When an event
+ * is received, the dispatching function should then
+ * emit a signal to every CtkEvent object that
+ * requests event notification from the dpy for the
+ * given X screen.
+ */
+static void ctk_event_register_source(CtkEvent *ctk_event)
+{
+ Display *dpy = NvCtrlGetDisplayPtr(ctk_event->handle);
+ CtkEventSource *event_source;
+ CtkEventNode *event_node;
+
+ if (!dpy) {
+ return;
+ }
+
+ /* Do we already have an event source for this dpy? */
+ event_source = event_sources;
+ while (event_source) {
+ if (event_source->dpy == dpy) {
+ break;
+ }
+ event_source = event_source->next;
+ }
+
+ /* create a new input source */
+ if (!event_source) {
+ GSource *source;
+
+ static GSourceFuncs ctk_source_funcs = {
+ ctk_event_prepare,
+ ctk_event_check,
+ ctk_event_dispatch,
+ NULL
+ };
+
+ source = g_source_new(&ctk_source_funcs, sizeof(CtkEventSource));
+ event_source = (CtkEventSource *) source;
+ if (!event_source) {
+ return;
+ }
+
+ event_source->dpy = dpy;
+ event_source->event_poll_fd.fd = ConnectionNumber(dpy);
+ event_source->event_poll_fd.events = G_IO_IN;
+ event_source->event_base = NvCtrlGetEventBase(ctk_event->handle);
+ event_source->randr_event_base =
+ NvCtrlGetXrandrEventBase(ctk_event->handle);
+
+ /* add the input source to the glib main loop */
+
+ g_source_add_poll(source, &event_source->event_poll_fd);
+ g_source_attach(source, NULL);
+
+ /* add the source to the global list of sources */
+
+ event_source->next = event_sources;
+ event_sources = event_source;
+ }
+
+
+ /* Add the ctk_event object to the source's list of event objects */
+
+ event_node = (CtkEventNode *)g_malloc(sizeof(CtkEventNode));
+ if (!event_node) {
+ return;
+ }
+ event_node->ctk_event = ctk_event;
+ event_node->screen = NvCtrlGetScreen(ctk_event->handle);
+ event_node->next = event_source->ctk_events;
+ event_source->ctk_events = event_node;
+
+} /* ctk_event_create_source() */
+
+
+
GtkObject *ctk_event_new (NvCtrlAttributeHandle *handle)
{
GObject *object;
CtkEvent *ctk_event;
- Display *dpy;
- GSource *source;
- CtkEventSource *event_source;
-
- static GSourceFuncs ctk_source_funcs = {
- ctk_event_prepare,
- ctk_event_check,
- ctk_event_dispatch,
- NULL
- };
-
/* create the new object */
object = g_object_new(CTK_TYPE_EVENT, NULL);
@@ -243,26 +338,9 @@ GtkObject *ctk_event_new (NvCtrlAttributeHandle *handle)
ctk_event = CTK_EVENT(object);
ctk_event->handle = handle;
- /* get the Display connection associated with this NvCtrl handle */
+ /* Register to receive (dpy) events */
- dpy = NvCtrlGetDisplayPtr(handle);
-
- /* create a new input source */
-
- source = g_source_new(&ctk_source_funcs, sizeof(CtkEventSource));
- event_source = (CtkEventSource *) source;
-
- event_source->dpy = dpy;
- event_source->event_poll_fd.fd = ConnectionNumber(dpy);
- event_source->event_poll_fd.events = G_IO_IN;
- event_source->event_base = NvCtrlGetEventBase(handle);
- event_source->randr_event_base = NvCtrlGetXrandrEventBase(handle);
- event_source->ctk_event = ctk_event;
-
- /* add the input source to the glib main loop */
-
- g_source_add_poll(source, &event_source->event_poll_fd);
- g_source_attach(source, NULL);
+ ctk_event_register_source(ctk_event);
return GTK_OBJECT(ctk_event);
@@ -293,11 +371,22 @@ static gboolean ctk_event_check(GSource *source)
return XPending(event_source->dpy);
}
+
+#define CTK_EVENT_BROADCAST(ES, SIG, PTR, SCR) \
+do { \
+ CtkEventNode *e = (ES)->ctk_events; \
+ while (e) { \
+ if (e->screen == (SCR)) { \
+ g_signal_emit(e->ctk_event, SIG, 0, PTR); \
+ } \
+ e = e->next; \
+ } \
+} while (0)
+
static gboolean ctk_event_dispatch(GSource *source,
GSourceFunc callback, gpointer user_data)
{
XEvent event;
- XNVCtrlAttributeChangedEvent *nvctrlevent;
CtkEventSource *event_source = (CtkEventSource *) source;
CtkEventStruct event_struct;
@@ -310,13 +399,13 @@ static gboolean ctk_event_dispatch(GSource *source,
XNextEvent(event_source->dpy, &event);
/*
- * we currently only handle the ATTRIBUTE_CHANGED_EVENT NV-CONTROL
- * event
+ * Handle the ATTRIBUTE_CHANGED_EVENT NV-CONTROL event
*/
if (event.type == (event_source->event_base + ATTRIBUTE_CHANGED_EVENT)) {
- nvctrlevent = (XNVCtrlAttributeChangedEvent *) &event;
-
+ XNVCtrlAttributeChangedEvent *nvctrlevent =
+ (XNVCtrlAttributeChangedEvent *) &event;
+
/* make sure the attribute is in our signal array */
if ((nvctrlevent->attribute >= 0) &&
@@ -332,9 +421,10 @@ static gboolean ctk_event_dispatch(GSource *source,
* way of dispatching the event?
*/
- g_signal_emit(event_source->ctk_event,
- signals[nvctrlevent->attribute],
- 0, &event_struct);
+ CTK_EVENT_BROADCAST(event_source,
+ signals[nvctrlevent->attribute],
+ &event_struct,
+ nvctrlevent->screen);
}
}
@@ -343,8 +433,26 @@ static gboolean ctk_event_dispatch(GSource *source,
*/
if (event.type ==
(event_source->randr_event_base + RRScreenChangeNotify)) {
- g_signal_emit(event_source->ctk_event, signal_RRScreenChangeNotify,
- 0, &event);
+ XRRScreenChangeNotifyEvent *xrandrevent =
+ (XRRScreenChangeNotifyEvent *)&event;
+ int screen;
+
+ /* Find the screen the window belongs to */
+ screen = XScreenCount(xrandrevent->display);
+ screen--;
+ while (screen > 0) {
+ if (xrandrevent->root ==
+ RootWindow(xrandrevent->display, screen)) {
+ break;
+ }
+ screen--;
+ }
+ if (screen > 0) {
+ CTK_EVENT_BROADCAST(event_source,
+ signal_RRScreenChangeNotify,
+ &event,
+ screen);
+ }
}
return TRUE;
diff --git a/src/gtk+-2.x/ctkglx.c b/src/gtk+-2.x/ctkglx.c
index 906c9df..f1dbe29 100644
--- a/src/gtk+-2.x/ctkglx.c
+++ b/src/gtk+-2.x/ctkglx.c
@@ -66,16 +66,16 @@ static const char * __st_help =
"st (Stereo buffer) - 'y' if the configuration has left and right color "
"buffers that are rendered to in stereo. '-' if this is not supported";
static const char * __rs_help =
- "rs (Red size) - Number of bits used for ammount of red per color. "
+ "rs (Red size) - Number of bits per color used for red. "
"(Undefined for configurations that use color indexing.)";
static const char * __gs_help =
- "gs (Green size - Number of bits used for ammount of green per color. "
+ "gs (Green size - Number of bits per color used for green. "
"(Undefined for configurations that use color indexing.)";
static const char * __bs_help =
- "bs (Blue size - Number of bits used for ammount of blue per color. "
+ "bs (Blue size - Number of bits per color used for blue. "
"(Undefined for configurations that use color indexing.)";
static const char * __as_help =
- "as (Alpha size - Number of bits used for ammount of alpha per color. "
+ "as (Alpha size - Number of bits per color used for alpha. "
"(Undefined for configurations that use color indexing.)";
static const char * __aux_help =
"aux (Auxillary buffers) - Number of available auxiliary color butters.";
@@ -84,17 +84,17 @@ static const char * __dpt_help =
static const char * __stn_help =
"stn (Stencil size) - Number of bits per element in the stencil buffer.";
static const char * __acr_help =
- "acr (Accumulator red size) - Number of bits used for ammount of red per "
- "color in the accumulator buffer.";
+ "acr (Accumulator red size) - Number of bits per color used for red "
+ "in the accumulator buffer.";
static const char * __acg_help =
- "acg (Accumulator green size) - Number of bits used for ammount of green "
- "per color in the accumulator buffer.";
+ "acg (Accumulator green size) - Number of bits per color used for green "
+ "in the accumulator buffer.";
static const char * __acb_help =
- "acb (Accumulator blue size) - Number of bits used for ammount of blue per "
- "color in the accumulator buffer.";
+ "acb (Accumulator blue size) - Number of bits per color used for blue "
+ "in the accumulator buffer.";
static const char * __aca_help =
- "aca (Accumulator alpha size) - Number of bits used for ammount of alpha "
- "per color in the accumulator buffer.";
+ "aca (Accumulator alpha size) - Number of bits per color used for alpha "
+ "in the accumulator buffer.";
static const char * __ms_help =
"ms (Multisample samples) - Number of samples per multisample.";
static const char * __mb_help =
@@ -207,7 +207,6 @@ GtkWidget* ctk_glx_new(NvCtrlAttributeHandle *handle,
GtkWidget *table;
GtkWidget *scrollWin;
GtkWidget *event; /* For setting the background color to white */
- GdkColor color;
ReturnStatus ret;
@@ -244,10 +243,6 @@ GtkWidget* ctk_glx_new(NvCtrlAttributeHandle *handle,
};
- /* Parse a white color (for background) */
- gdk_color_parse ("white", &color);
-
-
/* Create the ctk glx object */
object = g_object_new(CTK_TYPE_GLX, NULL);
ctk_glx = CTK_GLX(object);
@@ -294,7 +289,8 @@ GtkWidget* ctk_glx_new(NvCtrlAttributeHandle *handle,
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollWin),
GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
gtk_box_pack_start(GTK_BOX(ctk_glx), scrollWin, TRUE, TRUE, 0);
- gtk_widget_modify_bg(event, GTK_STATE_NORMAL, &color);
+ gtk_widget_modify_fg(event, GTK_STATE_NORMAL, &(event->style->text[GTK_STATE_NORMAL]));
+ gtk_widget_modify_bg(event, GTK_STATE_NORMAL, &(event->style->base[GTK_STATE_NORMAL]));
gtk_container_add(GTK_CONTAINER(event), hbox);
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrollWin),
event);
@@ -343,9 +339,12 @@ GtkWidget* ctk_glx_new(NvCtrlAttributeHandle *handle,
table = gtk_table_new(i, NUM_FBCONFIG_ATTRIBS, FALSE);
event = gtk_event_box_new();
- gtk_widget_modify_bg (table, GTK_STATE_NORMAL, &color);
+
+ gtk_widget_modify_fg(table, GTK_STATE_NORMAL, &(table->style->text[GTK_STATE_NORMAL]));
+ gtk_widget_modify_bg(table, GTK_STATE_NORMAL, &(table->style->base[GTK_STATE_NORMAL]));
gtk_container_add (GTK_CONTAINER(event), table);
- gtk_widget_modify_bg(event, GTK_STATE_NORMAL, &color);
+ gtk_widget_modify_fg(event, GTK_STATE_NORMAL, &(event->style->text[GTK_STATE_NORMAL]));
+ gtk_widget_modify_bg(event, GTK_STATE_NORMAL, &(event->style->base[GTK_STATE_NORMAL]));
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrollWin),
event);
@@ -470,8 +469,6 @@ GtkWidget* ctk_glx_new(NvCtrlAttributeHandle *handle,
"the X server or there was a problem retrieving\n"
"GLX information from the X server."
);
- gdk_color_parse ("#FF0000", &color);
- gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &color);
gtk_label_set_selectable(GTK_LABEL(label), TRUE);
gtk_container_add(GTK_CONTAINER(ctk_glx), label);
diff --git a/src/gtk+-2.x/ctkimagesliders.c b/src/gtk+-2.x/ctkimagesliders.c
index 23cb86d..5c3ee1e 100644
--- a/src/gtk+-2.x/ctkimagesliders.c
+++ b/src/gtk+-2.x/ctkimagesliders.c
@@ -452,12 +452,12 @@ static void image_sharpening_update_received(GtkObject *object,
/*
- * add_image_sharpening_help() -
+ * add_image_sliders_help() -
*/
-gboolean add_image_sharpening_help(CtkImageSliders *ctk_image_sliders,
- GtkTextBuffer *b,
- GtkTextIter *i)
+gboolean add_image_sliders_help(CtkImageSliders *ctk_image_sliders,
+ GtkTextBuffer *b,
+ GtkTextIter *i)
{
gboolean ret = FALSE;
@@ -481,4 +481,4 @@ gboolean add_image_sharpening_help(CtkImageSliders *ctk_image_sliders,
return ret;
-} /* add_image_sharpening_help() */
+} /* add_image_sliders_help() */
diff --git a/src/gtk+-2.x/ctkimagesliders.h b/src/gtk+-2.x/ctkimagesliders.h
index 6cfebc2..1b9fc87 100644
--- a/src/gtk+-2.x/ctkimagesliders.h
+++ b/src/gtk+-2.x/ctkimagesliders.h
@@ -84,9 +84,9 @@ GtkWidget* ctk_image_sliders_new (NvCtrlAttributeHandle *,
void ctk_image_sliders_reset(CtkImageSliders *);
-gboolean add_image_sharpening_help(CtkImageSliders *ctk_image_sliders,
- GtkTextBuffer *b,
- GtkTextIter *i);
+gboolean add_image_sliders_help(CtkImageSliders *ctk_image_sliders,
+ GtkTextBuffer *b,
+ GtkTextIter *i);
G_END_DECLS
diff --git a/src/gtk+-2.x/ctkmultisample.c b/src/gtk+-2.x/ctkmultisample.c
index 131d57e..79795d1 100644
--- a/src/gtk+-2.x/ctkmultisample.c
+++ b/src/gtk+-2.x/ctkmultisample.c
@@ -653,12 +653,27 @@ static void post_fsaa_app_override_toggled(CtkMultisample *ctk_multisample,
static void fsaa_app_override_toggled(GtkWidget *widget, gpointer user_data)
{
CtkMultisample *ctk_multisample = CTK_MULTISAMPLE(user_data);
+ GtkRange *range = GTK_RANGE(ctk_multisample->fsaa_scale);
gboolean override;
override = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
NvCtrlSetAttribute(ctk_multisample->handle,
NV_CTRL_FSAA_APPLICATION_CONTROLLED, !override);
+ if (!override) {
+ NvCtrlSetAttribute(ctk_multisample->handle,
+ NV_CTRL_FSAA_MODE, NV_CTRL_FSAA_MODE_NONE);
+
+ g_signal_handlers_block_by_func(G_OBJECT(range),
+ G_CALLBACK(fsaa_value_changed),
+ (gpointer) ctk_multisample);
+
+ gtk_range_set_value(range, NV_CTRL_FSAA_MODE_NONE);
+
+ g_signal_handlers_unblock_by_func(G_OBJECT(range),
+ G_CALLBACK(fsaa_value_changed),
+ (gpointer) ctk_multisample);
+ }
post_fsaa_app_override_toggled(ctk_multisample, override);
@@ -813,12 +828,27 @@ static void log_aniso_app_override_toggled(GtkWidget *widget,
gpointer user_data)
{
CtkMultisample *ctk_multisample = CTK_MULTISAMPLE(user_data);
+ GtkRange *range = GTK_RANGE(ctk_multisample->log_aniso_scale);
gboolean override;
override = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
NvCtrlSetAttribute(ctk_multisample->handle,
NV_CTRL_LOG_ANISO_APPLICATION_CONTROLLED, !override);
+ if (!override) {
+ NvCtrlSetAttribute(ctk_multisample->handle,
+ NV_CTRL_LOG_ANISO, 0 /* default(?) */);
+
+ g_signal_handlers_block_by_func(G_OBJECT(range),
+ G_CALLBACK(log_aniso_value_changed),
+ (gpointer) ctk_multisample);
+
+ gtk_range_set_value(range, 0);
+
+ g_signal_handlers_unblock_by_func(G_OBJECT(range),
+ G_CALLBACK(log_aniso_value_changed),
+ (gpointer) ctk_multisample);
+ }
post_log_aniso_app_override_toggled(ctk_multisample, override);
diff --git a/src/gtk+-2.x/ctkopengl.c b/src/gtk+-2.x/ctkopengl.c
index 45731ce..30c2884 100644
--- a/src/gtk+-2.x/ctkopengl.c
+++ b/src/gtk+-2.x/ctkopengl.c
@@ -36,12 +36,31 @@ static void vblank_sync_button_toggled (GtkWidget *, gpointer);
static void allow_flipping_button_toggled(GtkWidget *, gpointer);
+static void force_stereo_button_toggled (GtkWidget *, gpointer);
+
+static void xinerama_stereo_button_toggled (GtkWidget *, gpointer);
+
static void force_generic_cpu_toggled (GtkWidget *, gpointer);
static void aa_line_gamma_toggled (GtkWidget *, gpointer);
+static void show_sli_hud_button_toggled (GtkWidget *, gpointer);
+
static void value_changed (GtkObject *, gpointer, gpointer);
+static const gchar *get_image_settings_string(gint val);
+
+static gchar *format_image_settings_value(GtkScale *scale, gdouble arg1,
+ gpointer user_data);
+
+static void post_image_settings_value_changed(CtkOpenGL *ctk_opengl, gint val);
+
+static void image_settings_value_changed(GtkRange *range, gpointer user_data);
+
+static void image_settings_update_received(GtkObject *object,
+ gpointer arg1, gpointer user_data);
+
+#define FRAME_PADDING 5
static const char *__sync_to_vblank_help =
"When enabled, OpenGL applications will swap "
@@ -59,11 +78,35 @@ static const char *__force_generic_cpu_help =
"OpenGL applications that are started after "
"this option is set.";
+static const char *__image_settings_slider_help =
+"The Image Settings slider controls the image quality setting.";
+
+static const char *__force_stereo_help =
+"Enabling this option causes OpenGL to force "
+"stereo flipping even if a stereo drawable is "
+"not visible. This option is applied "
+"immediately.";
+
+static const char *__xinerama_stereo_help =
+ "Enabling this option causes OpenGL to allow "
+"stereo flipping on multiple X screens configured "
+"with Xinerama. This option is applied immediately.";
+
+static const char *__show_sli_hud_help =
+"Enabling this option causes OpenGL to draw "
+"information about the current SLI mode on the "
+"screen. This option is applied to OpenGL "
+"applications that are started after this option is "
+"set.";
#define __SYNC_TO_VBLANK (1 << 1)
#define __ALLOW_FLIPPING (1 << 2)
#define __AA_LINE_GAMMA (1 << 3)
#define __FORCE_GENERIC_CPU (1 << 4)
+#define __FORCE_STEREO (1 << 5)
+#define __IMAGE_SETTINGS (1 << 6)
+#define __XINERAMA_STEREO (1 << 7)
+#define __SHOW_SLI_HUD (1 << 8)
@@ -106,9 +149,12 @@ GtkWidget* ctk_opengl_new(NvCtrlAttributeHandle *handle,
GtkWidget *hbox;
GtkWidget *vbox;
GtkWidget *check_button;
+ GtkWidget *scale;
gint force_generic_cpu_value, aa_line_gamma_value, val;
ReturnStatus ret;
+ NVCTRLAttributeValidValuesRec valid;
+
guint8 *image_buffer = NULL;
const nv_image_t *img;
@@ -232,7 +278,103 @@ GtkWidget* ctk_opengl_new(NvCtrlAttributeHandle *handle,
ctk_opengl->allow_flipping_button = check_button;
}
+
+ ret = NvCtrlGetAttribute(handle, NV_CTRL_FORCE_STEREO, &val);
+ if (ret == NvCtrlSuccess) {
+
+ label = gtk_label_new("Force Stereo Flipping");
+
+ check_button = gtk_check_button_new();
+ gtk_container_add(GTK_CONTAINER(check_button), label);
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_button), val);
+
+ gtk_box_pack_start(GTK_BOX(vbox), check_button, FALSE, FALSE, 0);
+
+ g_signal_connect(G_OBJECT(check_button), "toggled",
+ G_CALLBACK(force_stereo_button_toggled),
+ (gpointer) ctk_opengl);
+
+ g_signal_connect(G_OBJECT(ctk_event),
+ CTK_EVENT_NAME(NV_CTRL_FORCE_STEREO),
+ G_CALLBACK(value_changed), (gpointer) ctk_opengl);
+
+ ctk_config_set_tooltip(ctk_config, check_button, __force_stereo_help);
+
+ ctk_opengl->active_attributes |= __FORCE_STEREO;
+
+ ctk_opengl->force_stereo_button = check_button;
+ }
+ ret = NvCtrlGetAttribute(handle, NV_CTRL_XINERAMA_STEREO, &val);
+ if (ret == NvCtrlSuccess) {
+
+ label = gtk_label_new("Allow Xinerama Stereo Flipping");
+
+ check_button = gtk_check_button_new();
+ gtk_container_add(GTK_CONTAINER(check_button), label);
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_button), val);
+
+ gtk_box_pack_start(GTK_BOX(vbox), check_button, FALSE, FALSE, 0);
+
+ g_signal_connect(G_OBJECT(check_button), "toggled",
+ G_CALLBACK(xinerama_stereo_button_toggled),
+ (gpointer) ctk_opengl);
+
+ g_signal_connect(G_OBJECT(ctk_event),
+ CTK_EVENT_NAME(NV_CTRL_FORCE_STEREO),
+ G_CALLBACK(value_changed), (gpointer) ctk_opengl);
+
+ ctk_config_set_tooltip(ctk_config, check_button, __xinerama_stereo_help);
+
+ ctk_opengl->active_attributes |= __XINERAMA_STEREO;
+
+ ctk_opengl->xinerama_stereo_button = check_button;
+ }
+
+ /*
+ * Image Quality settings.
+ */
+
+ ret = NvCtrlGetValidAttributeValues(handle, NV_CTRL_IMAGE_SETTINGS, &valid);
+
+ if ((ret == NvCtrlSuccess) && (valid.type == ATTRIBUTE_TYPE_RANGE) &&
+ (NvCtrlGetAttribute(handle, NV_CTRL_IMAGE_SETTINGS, &val) == NvCtrlSuccess)) {
+
+ frame = gtk_frame_new("Image Settings");
+ gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 3);
+
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), FRAME_PADDING);
+ gtk_container_add(GTK_CONTAINER(frame), hbox);
+
+ scale = gtk_hscale_new_with_range(valid.u.range.min, valid.u.range.max, 1);
+ gtk_range_set_value(GTK_RANGE(scale), val);
+
+ gtk_scale_set_draw_value(GTK_SCALE(scale), TRUE);
+ gtk_scale_set_value_pos(GTK_SCALE(scale), GTK_POS_TOP);
+
+ gtk_container_add(GTK_CONTAINER(hbox), scale);
+
+ g_signal_connect(G_OBJECT(scale), "format-value",
+ G_CALLBACK(format_image_settings_value),
+ (gpointer) ctk_opengl);
+
+ g_signal_connect(G_OBJECT(scale), "value-changed",
+ G_CALLBACK(image_settings_value_changed),
+ (gpointer) ctk_opengl);
+
+ g_signal_connect(G_OBJECT(ctk_event),
+ CTK_EVENT_NAME(NV_CTRL_IMAGE_SETTINGS),
+ G_CALLBACK(image_settings_update_received),
+ (gpointer) ctk_opengl);
+
+ ctk_config_set_tooltip(ctk_config, scale, __image_settings_slider_help);
+
+ ctk_opengl->active_attributes |= __IMAGE_SETTINGS;
+ ctk_opengl->image_settings_scale = scale;
+ }
/*
* Miscellaneous section:
@@ -326,6 +468,33 @@ GtkWidget* ctk_opengl_new(NvCtrlAttributeHandle *handle,
ctk_opengl->force_generic_cpu_button = check_button;
}
+ ret = NvCtrlGetAttribute(handle, NV_CTRL_SHOW_SLI_HUD, &val);
+ if (ret == NvCtrlSuccess) {
+
+ label = gtk_label_new("Enable SLI Heads-Up-Display");
+
+ check_button = gtk_check_button_new();
+ gtk_container_add(GTK_CONTAINER(check_button), label);
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_button), val);
+
+ gtk_box_pack_start(GTK_BOX(vbox), check_button, FALSE, FALSE, 0);
+
+ g_signal_connect(G_OBJECT(check_button), "toggled",
+ G_CALLBACK(show_sli_hud_button_toggled),
+ (gpointer) ctk_opengl);
+
+ g_signal_connect(G_OBJECT(ctk_event),
+ CTK_EVENT_NAME(NV_CTRL_SHOW_SLI_HUD),
+ G_CALLBACK(value_changed), (gpointer) ctk_opengl);
+
+ ctk_config_set_tooltip(ctk_config, check_button, __show_sli_hud_help);
+
+ ctk_opengl->active_attributes |= __SHOW_SLI_HUD;
+
+ ctk_opengl->show_sli_hud_button = check_button;
+ }
+
gtk_widget_show_all(GTK_WIDGET(object));
@@ -370,6 +539,57 @@ static void allow_flipping_button_toggled(GtkWidget *widget,
}
+static void force_stereo_button_toggled(GtkWidget *widget,
+ gpointer user_data)
+{
+ CtkOpenGL *ctk_opengl;
+ gboolean enabled;
+
+ ctk_opengl = CTK_OPENGL(user_data);
+
+ enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+
+ NvCtrlSetAttribute(ctk_opengl->handle, NV_CTRL_FORCE_STEREO, enabled);
+
+ ctk_config_statusbar_message(ctk_opengl->ctk_config,
+ "OpenGL Stereo Flipping %s.",
+ enabled ? "forced" : "not forced");
+}
+
+static void show_sli_hud_button_toggled(GtkWidget *widget,
+ gpointer user_data)
+{
+ CtkOpenGL *ctk_opengl;
+ gboolean enabled;
+
+ ctk_opengl = CTK_OPENGL(user_data);
+
+ enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+
+ NvCtrlSetAttribute(ctk_opengl->handle, NV_CTRL_SHOW_SLI_HUD, enabled);
+
+ ctk_config_statusbar_message(ctk_opengl->ctk_config,
+ "OpenGL SLI HUD %s.",
+ enabled ? "enabled" : "disabled");
+}
+
+static void xinerama_stereo_button_toggled(GtkWidget *widget,
+ gpointer user_data)
+{
+ CtkOpenGL *ctk_opengl;
+ gboolean enabled;
+
+ ctk_opengl = CTK_OPENGL(user_data);
+
+ enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+
+ NvCtrlSetAttribute(ctk_opengl->handle, NV_CTRL_XINERAMA_STEREO, enabled);
+
+ ctk_config_statusbar_message(ctk_opengl->ctk_config,
+ "OpenGL Xinerama Stereo Flipping %s.",
+ enabled ? "allowed" : "not allowed");
+}
+
static void force_generic_cpu_toggled(
GtkWidget *widget,
gpointer user_data
@@ -449,6 +669,14 @@ static void value_changed(GtkObject *object, gpointer arg1, gpointer user_data)
button = GTK_TOGGLE_BUTTON(ctk_opengl->allow_flipping_button);
func = G_CALLBACK(allow_flipping_button_toggled);
break;
+ case NV_CTRL_FORCE_STEREO:
+ button = GTK_TOGGLE_BUTTON(ctk_opengl->force_stereo_button);
+ func = G_CALLBACK(force_stereo_button_toggled);
+ break;
+ case NV_CTRL_XINERAMA_STEREO:
+ button = GTK_TOGGLE_BUTTON(ctk_opengl->xinerama_stereo_button);
+ func = G_CALLBACK(xinerama_stereo_button_toggled);
+ break;
case NV_CTRL_OPENGL_AA_LINE_GAMMA:
button = GTK_TOGGLE_BUTTON(ctk_opengl->aa_line_gamma_button);
func = G_CALLBACK(aa_line_gamma_toggled);
@@ -457,6 +685,10 @@ static void value_changed(GtkObject *object, gpointer arg1, gpointer user_data)
button = GTK_TOGGLE_BUTTON(ctk_opengl->force_generic_cpu_button);
func = G_CALLBACK(force_generic_cpu_toggled);
break;
+ case NV_CTRL_SHOW_SLI_HUD:
+ button = GTK_TOGGLE_BUTTON(ctk_opengl->show_sli_hud_button);
+ func = G_CALLBACK(show_sli_hud_button_toggled);
+ break;
default:
return;
}
@@ -473,6 +705,91 @@ static void value_changed(GtkObject *object, gpointer arg1, gpointer user_data)
} /* value_changed() */
+/*
+ * get_image_settings_string() - translate the NV-CONTROL image settings value
+ * to a more comprehensible string.
+ */
+
+static const gchar *get_image_settings_string(gint val)
+{
+ static const gchar *image_settings_strings[] = {
+ "High Quality", "Quality", "Performance", "High Performance"
+ };
+
+ if ((val < NV_CTRL_IMAGE_SETTINGS_HIGH_QUALITY) ||
+ (val > NV_CTRL_IMAGE_SETTINGS_HIGH_PERFORMANCE)) return "Unknown";
+
+ return image_settings_strings[val];
+
+} /* get_image_settings_string() */
+
+/*
+ * format_image_settings_value() - callback for the "format-value" signal
+ * from the image settings scale.
+ */
+
+static gchar *format_image_settings_value(GtkScale *scale, gdouble arg1,
+ gpointer user_data)
+{
+ return g_strdup(get_image_settings_string(arg1));
+
+} /* format_image_settings_value() */
+
+/*
+ * post_image_settings_value_changed() - helper function for
+ * image_settings_value_changed(); this does whatever work is necessary
+ * after the image settings value has changed.
+ */
+
+static void post_image_settings_value_changed(CtkOpenGL *ctk_opengl, gint val)
+{
+ ctk_config_statusbar_message(ctk_opengl->ctk_config,
+ "Image Settings set to %s.",
+ get_image_settings_string(val));
+
+} /* post_image_settings_value_changed() */
+
+/*
+ * image_settings_value_changed() - callback for the "value-changed" signal
+ * from the image settings scale.
+ */
+
+static void image_settings_value_changed(GtkRange *range, gpointer user_data)
+{
+ CtkOpenGL *ctk_opengl = CTK_OPENGL(user_data);
+ gint val = gtk_range_get_value(range);
+
+ NvCtrlSetAttribute(ctk_opengl->handle, NV_CTRL_IMAGE_SETTINGS, val);
+ post_image_settings_value_changed(ctk_opengl, val);
+
+} /* image_settings_value_changed() */
+
+/*
+ * image_settings_update_received() - this function is called when the
+ * NV_CTRL_IMAGE_SETTINGS atribute is changed by another NV-CONTROL client.
+ */
+
+static void image_settings_update_received(GtkObject *object,
+ gpointer arg1, gpointer user_data)
+{
+ CtkEventStruct *event_struct = (CtkEventStruct *) arg1;
+ CtkOpenGL *ctk_opengl = CTK_OPENGL(user_data);
+ GtkRange *range = GTK_RANGE(ctk_opengl->image_settings_scale);
+
+ g_signal_handlers_block_by_func(G_OBJECT(range),
+ G_CALLBACK(image_settings_value_changed),
+ (gpointer) ctk_opengl);
+
+ gtk_range_set_value(range, event_struct->value);
+ post_image_settings_value_changed(ctk_opengl, event_struct->value);
+
+ g_signal_handlers_unblock_by_func(G_OBJECT(range),
+ G_CALLBACK(image_settings_value_changed),
+ (gpointer) ctk_opengl);
+
+} /* image_settings_update_received() */
+
+
GtkTextBuffer *ctk_opengl_create_help(GtkTextTagTable *table,
CtkOpenGL *ctk_opengl)
{
@@ -507,6 +824,49 @@ GtkTextBuffer *ctk_opengl_create_help(GtkTextTagTable *table,
"after the option is set.");
}
+ if (ctk_opengl->active_attributes & __FORCE_STEREO) {
+ ctk_help_heading(b, &i, "Force Stereo Flipping");
+ ctk_help_para(b, &i, __force_stereo_help);
+ }
+
+ if (ctk_opengl->active_attributes & __XINERAMA_STEREO) {
+ ctk_help_heading(b, &i, "Allow Xinerama Stereo Flipping");
+ ctk_help_para(b, &i, __xinerama_stereo_help);
+ }
+
+ if (ctk_opengl->active_attributes & __IMAGE_SETTINGS) {
+ ctk_help_heading(b, &i, "Image Settings");
+ ctk_help_para(b, &i, "This setting gives you full control over the "
+ "image quality in your applications.");
+ ctk_help_para(b, &i, "Several quality settings are available for "
+ "you to choose from with the Image Settings slider. "
+ "Note that choosing higher image quality settings may "
+ "result in decreased performance.");
+
+ ctk_help_term(b, &i, "High Quality");
+ ctk_help_para(b, &i, "This setting results in the best image quality "
+ "for your applications. It is not necessary for "
+ "average users who run game applications, and designed "
+ "for more advanced users to generate images that do not "
+ "take advantage of the programming capability of the "
+ "texture filtering hardware.");
+
+ ctk_help_term(b, &i, "Quality");
+ ctk_help_para(b, &i, "This is the default setting that results in "
+ "optimal image quality for your applications.");
+
+ ctk_help_term(b, &i, "Performance");
+ ctk_help_para(b, &i, "This setting offers an optimal blend of image "
+ "quality and performance. The result is optimal "
+ "performance and good image quality for your "
+ "applications.");
+
+ ctk_help_term(b, &i, "High Performance");
+ ctk_help_para(b, &i, "This setting offers the highest frame rate "
+ "possible, resulting in the best performance for your "
+ "applications.");
+ }
+
if (ctk_opengl->active_attributes & __AA_LINE_GAMMA) {
ctk_help_heading(b, &i, "Enable gamma correction for "
"antialiased lines");
@@ -525,6 +885,30 @@ GtkTextBuffer *ctk_opengl_create_help(GtkTextTagTable *table,
ctk_help_para(b, &i, __force_generic_cpu_help);
}
+ if (ctk_opengl->active_attributes & __SHOW_SLI_HUD) {
+ ctk_help_heading(b, &i, "SLI Heads-Up-Display");
+ ctk_help_para(b, &i, "This option draws information about the current "
+ "SLI mode on top of OpenGL windows. Its behavior "
+ "depends on which SLI mode is in use:");
+ ctk_help_term(b, &i, "Alternate Frame Rendering");
+ ctk_help_para(b, &i, "In AFR mode, a vertical green bar displays the "
+ "amount of scaling currently being achieved. A longer "
+ "bar indicates more scaling.");
+ ctk_help_term(b, &i, "Split-Frame Rendering");
+ ctk_help_para(b, &i, "In this mode, OpenGL draws a horizontal green "
+ "line showing where the screen is split. Everything "
+ "above the line is drawn on one GPU and everything "
+ "below is drawn on the other.");
+ ctk_help_term(b, &i, "SLI Antialiasing");
+ ctk_help_para(b, &i, "In this mode, OpenGL draws a horizontal green "
+ "line one third of the way across the screen. Above "
+ "this line, the images from both GPUs are blended to "
+ "produce the currently selected SLIAA mode. Below the "
+ "line, the image from just one GPU is displayed without "
+ "blending. This allows easy comparison between the "
+ "SLIAA and single-GPU AA modes.");
+ }
+
ctk_help_finish(b);
return b;
diff --git a/src/gtk+-2.x/ctkopengl.h b/src/gtk+-2.x/ctkopengl.h
index 068a88b..9b99476 100644
--- a/src/gtk+-2.x/ctkopengl.h
+++ b/src/gtk+-2.x/ctkopengl.h
@@ -60,8 +60,12 @@ struct _CtkOpenGL
GtkWidget *sync_to_vblank_button;
GtkWidget *allow_flipping_button;
+ GtkWidget *force_stereo_button;
+ GtkWidget *xinerama_stereo_button;
+ GtkWidget *image_settings_scale;
GtkWidget *aa_line_gamma_button;
GtkWidget *force_generic_cpu_button;
+ GtkWidget *show_sli_hud_button;
unsigned int active_attributes;
};
diff --git a/src/gtk+-2.x/ctkwindow.c b/src/gtk+-2.x/ctkwindow.c
index b7ec7be..61efb10 100644
--- a/src/gtk+-2.x/ctkwindow.c
+++ b/src/gtk+-2.x/ctkwindow.c
@@ -558,7 +558,7 @@ GtkWidget *ctk_window_new(NvCtrlAttributeHandle **handles, gint num_handles,
/* xvideo settings */
- child = ctk_xvideo_new(handles[i], ctk_config);
+ child = ctk_xvideo_new(handles[i], ctk_config, ctk_event);
if (child) {
help = ctk_xvideo_create_help(tag_table, CTK_XVIDEO(child));
add_page(child, help, ctk_window, &iter, NULL,
diff --git a/src/gtk+-2.x/ctkxvideo.c b/src/gtk+-2.x/ctkxvideo.c
index f32abde..483b4d3 100644
--- a/src/gtk+-2.x/ctkxvideo.c
+++ b/src/gtk+-2.x/ctkxvideo.c
@@ -61,11 +61,31 @@ static const char *__xv_blitter_sync_to_vblank_help =
"the vertical retrace of your display device "
"for the Blitter Xv Adaptor.";
+static const char *__xv_sync_to_display_help =
+"This controls which display device will be synched to when "
+"XVideo Sync To VBlank is enabled.";
+
static const char *__reset_button_help =
"The Reset Hardware Defaults button restores "
"the XVideo settings to their default values.";
+static void xv_sync_to_display_changed(GtkWidget *widget, gpointer user_data);
+
+static GtkWidget *xv_sync_to_display_radio_button_add(CtkXVideo *ctk_xvideo,
+ GtkWidget *vbox,
+ GtkWidget *prev_radio,
+ char *label,
+ gint value,
+ int index);
+
+static void
+xv_sync_to_display_update_radio_buttons(CtkXVideo *ctk_xvideo, gint value);
+
+static void xv_sync_to_display_changed(GtkWidget *widget, gpointer user_data);
+
+static void xv_sync_to_display_update_received(GtkObject *object, gpointer arg1,
+ gpointer user_data);
static GtkWidget *create_slider(CtkXVideo *ctk_xvideo,
GtkWidget *vbox,
@@ -109,6 +129,7 @@ static void reset_defaults(GtkButton *button, gpointer user_data);
#define __XV_OVERLAY_HUE (1 << 4)
#define __XV_TEXTURE_SYNC_TO_VBLANK (1 << 5)
#define __XV_BLITTER_SYNC_TO_VBLANK (1 << 6)
+#define __XV_SYNC_TO_DISPLAY (1 << 7)
@@ -138,6 +159,150 @@ GType ctk_xvideo_get_type(
return ctk_xvideo_type;
}
+/*
+ * xv_sync_to_display_radio_button_add() - create a radio button and plug it
+ * into the xv_sync_display radio group.
+ */
+
+static GtkWidget *xv_sync_to_display_radio_button_add(CtkXVideo *ctk_xvideo,
+ GtkWidget *vbox,
+ GtkWidget *prev_radio,
+ char *label,
+ gint value,
+ int index)
+{
+ GtkWidget *radio;
+
+ if (prev_radio) {
+ radio = gtk_radio_button_new_with_label_from_widget
+ (GTK_RADIO_BUTTON(prev_radio), label);
+ } else {
+ radio = gtk_radio_button_new_with_label(NULL, label);
+ }
+
+ gtk_box_pack_start(GTK_BOX(vbox), radio, FALSE, FALSE, 0);
+
+ g_object_set_data(G_OBJECT(radio), "xv_sync_to_display",
+ GINT_TO_POINTER(value));
+
+ g_signal_connect(G_OBJECT(radio), "toggled",
+ G_CALLBACK(xv_sync_to_display_changed),
+ (gpointer) ctk_xvideo);
+
+ ctk_xvideo->xv_sync_to_display_buttons[index] = radio;
+
+ return radio;
+
+} /* xv_sync_to_display_radio_button_add() */
+
+
+static void
+xv_sync_to_display_update_radio_buttons(CtkXVideo *ctk_xvideo, gint value)
+{
+ GtkWidget *b, *button = NULL;
+ int i;
+
+ button = ctk_xvideo->xv_sync_to_display_buttons[value];
+
+ if (!button) return;
+
+ /* turn off signal handling for all the sync buttons */
+
+ for (i = 0; i < 24; i++) {
+ b = ctk_xvideo->xv_sync_to_display_buttons[i];
+ if (!b) continue;
+
+ g_signal_handlers_block_by_func
+ (G_OBJECT(b), G_CALLBACK(xv_sync_to_display_changed),
+ (gpointer) ctk_xvideo);
+ }
+
+ /* set the appropriate button active */
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
+
+ /* turn on signal handling for all the sync buttons */
+
+ for (i = 0; i < 24; i++) {
+ b = ctk_xvideo->xv_sync_to_display_buttons[i];
+ if (!b) continue;
+
+ g_signal_handlers_unblock_by_func
+ (G_OBJECT(b), G_CALLBACK(xv_sync_to_display_changed),
+ (gpointer) ctk_xvideo);
+ }
+
+} /* xv_sync_to_display_update_radio_buttons() */
+
+
+/*
+ * xv_sync_to_display_changed() - callback function for changes to the
+ * sync_to_display radio button group; if the specified radio button is
+ * active, send xv_sync_to_display state to the server
+ */
+
+static void xv_sync_to_display_changed(GtkWidget *widget, gpointer user_data)
+{
+ CtkXVideo *ctk_xvideo = CTK_XVIDEO(user_data);
+ gboolean enabled;
+ gint value;
+ gchar *label;
+
+ enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+
+ if (enabled) {
+
+ user_data = g_object_get_data(G_OBJECT(widget), "xv_sync_to_display");
+
+ value = GPOINTER_TO_INT(user_data);
+
+ NvCtrlSetAttribute(ctk_xvideo->handle,
+ NV_CTRL_XV_SYNC_TO_DISPLAY, value);
+
+ gtk_label_get(GTK_LABEL(GTK_BIN(widget)->child), &label);
+
+ ctk_config_statusbar_message(ctk_xvideo->ctk_config,
+ "XVideo application syncing to %s.",
+ label);
+ }
+
+} /* xv_sync_to_display_changed() */
+
+
+/*
+ * xv_sync_to_display_update_received() - callback function for changed sync
+ * to display settings; this is called when we receive an event indicating that
+ * another NV-CONTROL client changed any of the settings that we care
+ * about.
+ */
+
+static void xv_sync_to_display_update_received(GtkObject *object, gpointer arg1,
+ gpointer user_data)
+{
+ CtkEventStruct *event_struct = (CtkEventStruct *) arg1;
+ CtkXVideo *ctk_xvideo = CTK_XVIDEO(user_data);
+ gint i;
+ GtkWidget *b;
+
+ switch (event_struct->attribute) {
+ case NV_CTRL_XV_SYNC_TO_DISPLAY:
+ for (i = 0; i < 24; i++) {
+ b = ctk_xvideo->xv_sync_to_display_buttons[i];
+ if (!b) continue;
+ user_data = g_object_get_data(G_OBJECT(b), "xv_sync_to_display");
+
+ if (GPOINTER_TO_INT(user_data) == event_struct->value) {
+ xv_sync_to_display_update_radio_buttons(ctk_xvideo, i);
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+} /* xv_sync_to_display_update_received() */
/*
@@ -145,7 +310,8 @@ GType ctk_xvideo_get_type(
*/
GtkWidget* ctk_xvideo_new(NvCtrlAttributeHandle *handle,
- CtkConfig *ctk_config)
+ CtkConfig *ctk_config,
+ CtkEvent *ctk_event)
{
GObject *object;
CtkXVideo *ctk_xvideo;
@@ -160,7 +326,8 @@ GtkWidget* ctk_xvideo_new(NvCtrlAttributeHandle *handle,
guint8 *image_buffer = NULL;
const nv_image_t *img;
int xv_overlay_present, xv_texture_present, xv_blitter_present;
-
+ int sync_mask;
+
ReturnStatus ret;
/*
@@ -310,6 +477,73 @@ GtkWidget* ctk_xvideo_new(NvCtrlAttributeHandle *handle,
__XV_BLITTER_SYNC_TO_VBLANK);
}
+ /* Sync to display selection */
+
+ ret = NvCtrlGetAttribute(handle,
+ NV_CTRL_XV_SYNC_TO_DISPLAY,
+ &sync_mask);
+
+ if (ret == NvCtrlSuccess) {
+ int enabled;
+
+ ret = NvCtrlGetAttribute(handle, NV_CTRL_ENABLED_DISPLAYS, &enabled);
+ if (ret == NvCtrlSuccess) {
+ GtkWidget *radio[24], *prev_radio;
+ int i, n, current = -1, mask;
+ char *name;
+
+ frame = gtk_frame_new("Sync to this display device");
+ gtk_box_pack_start(GTK_BOX(object), frame, FALSE, FALSE, 0);
+
+ vbox = gtk_vbox_new(FALSE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(vbox), FRAME_PADDING);
+ gtk_container_add(GTK_CONTAINER(frame), vbox);
+
+ ctk_xvideo->active_attributes |= __XV_SYNC_TO_DISPLAY;
+
+ for (n=0, i = 0; i < 24; i++) {
+
+ mask = 1 << i;
+ if (!(enabled & mask)) continue;
+
+ /* get the name of the display device */
+
+ ret = NvCtrlGetStringDisplayAttribute(handle, mask,
+ NV_CTRL_STRING_DISPLAY_DEVICE_NAME,
+ &name);
+
+ if ((ret != NvCtrlSuccess) || (!name)) {
+ name = g_strdup("Unknown");
+ }
+
+ if (n==0) {
+ prev_radio = NULL;
+ } else {
+ prev_radio = radio[n-1];
+ }
+ radio[n] = xv_sync_to_display_radio_button_add(ctk_xvideo, vbox,
+ prev_radio, name, mask, n);
+
+ ctk_config_set_tooltip(ctk_config, radio[n],
+ __xv_sync_to_display_help);
+
+ if (mask == sync_mask) {
+ current = n;
+ }
+
+ n++;
+ }
+
+ g_signal_connect(G_OBJECT(ctk_event),
+ CTK_EVENT_NAME(NV_CTRL_XV_SYNC_TO_DISPLAY),
+ G_CALLBACK(xv_sync_to_display_update_received),
+ (gpointer) ctk_xvideo);
+
+ if (current != -1)
+ xv_sync_to_display_update_radio_buttons(ctk_xvideo, current);
+ }
+ }
+
/* Reset button */
alignment = gtk_alignment_new(1, 1, 0, 0);
@@ -667,6 +901,11 @@ GtkTextBuffer *ctk_xvideo_create_help(GtkTextTagTable *table,
ctk_help_para(b, &i, __xv_blitter_sync_to_vblank_help);
}
+ if (ctk_xvideo->active_attributes & __XV_SYNC_TO_DISPLAY) {
+ ctk_help_heading(b, &i, "Sync to this display device");
+ ctk_help_para(b, &i, __xv_sync_to_display_help);
+ }
+
ctk_help_heading(b, &i, "Reset Hardware Defaults");
ctk_help_para(b, &i, __reset_button_help);
diff --git a/src/gtk+-2.x/ctkxvideo.h b/src/gtk+-2.x/ctkxvideo.h
index 2b584fd..6c6e5b7 100644
--- a/src/gtk+-2.x/ctkxvideo.h
+++ b/src/gtk+-2.x/ctkxvideo.h
@@ -27,6 +27,7 @@
#include "NvCtrlAttributes.h"
#include "ctkconfig.h"
+#include "ctkevent.h"
G_BEGIN_DECLS
@@ -64,6 +65,7 @@ struct _CtkXVideo
GtkWidget *overlay_hue;
GtkWidget *texture_sync_to_blank;
GtkWidget *blitter_sync_to_blank;
+ GtkWidget *xv_sync_to_display_buttons[24];
unsigned int active_attributes;
};
@@ -74,7 +76,8 @@ struct _CtkXVideoClass
};
GType ctk_xvideo_get_type (void) G_GNUC_CONST;
-GtkWidget* ctk_xvideo_new (NvCtrlAttributeHandle *, CtkConfig *);
+GtkWidget* ctk_xvideo_new (NvCtrlAttributeHandle *, CtkConfig *,
+ CtkEvent *ctk_event);
GtkTextBuffer *ctk_xvideo_create_help(GtkTextTagTable *, CtkXVideo *);
diff --git a/src/image_data/crt.h b/src/image_data/crt.h
index d286082..83bce95 100644
--- a/src/image_data/crt.h
+++ b/src/image_data/crt.h
@@ -2,27 +2,6 @@
#include "image.h"
-#define GIMP_IMAGE_WIDTH (100)
-#define GIMP_IMAGE_HEIGHT (100)
-#define GIMP_IMAGE_BYTES_PER_PIXEL (4) /* 3:RGB, 4:RGBA */
-#define GIMP_IMAGE_RLE_PIXEL_DATA ((unsigned char*) GIMP_IMAGE_rle_pixel_data)
-#define GIMP_IMAGE_RUN_LENGTH_DECODE(image_buf, rle_data, size, bpp) do \
-{ unsigned int __bpp; unsigned char *__ip; const unsigned char *__il, *__rd; \
- __bpp = (bpp); __ip = (image_buf); __il = __ip + (size) * __bpp; \
- __rd = (rle_data); if (__bpp > 3) { /* RGBA */ \
- while (__ip < __il) { unsigned int __l = *(__rd++); \
- if (__l & 128) { __l = __l - 128; \
- do { memcpy (__ip, __rd, 4); __ip += 4; } while (--__l); __rd += 4; \
- } else { __l *= 4; memcpy (__ip, __rd, __l); \
- __ip += __l; __rd += __l; } } \
- } else { /* RGB */ \
- while (__ip < __il) { unsigned int __l = *(__rd++); \
- if (__l & 128) { __l = __l - 128; \
- do { memcpy (__ip, __rd, 3); __ip += 3; } while (--__l); __rd += 3; \
- } else { __l *= 3; memcpy (__ip, __rd, __l); \
- __ip += __l; __rd += __l; } } \
- } } while (0)
-
static const nv_image_t crt_image = {
100, 100, 4,
"\377\377\0\377\0\377\377\0\377\0\225\377\0\377\0\25\336\336\337\377\333\333"
diff --git a/src/image_data/image.c b/src/image_data/image.c
index 6b36e33..22ca190 100644
--- a/src/image_data/image.c
+++ b/src/image_data/image.c
@@ -42,7 +42,7 @@ do { \
__bpp = (bpp); \
__ip = (image_buf); \
__il = __ip + (size) * __bpp; \
- __rd = (rle_data); \
+ __rd = (unsigned char *)(rle_data); \
\
if (__bpp > 3) { /* RGBA */ \
while (__ip < __il) { \
diff --git a/src/image_data/image.h b/src/image_data/image.h
index 3bbce6c..be21329 100644
--- a/src/image_data/image.h
+++ b/src/image_data/image.h
@@ -29,7 +29,7 @@ typedef struct {
unsigned int width;
unsigned int height;
unsigned int bytes_per_pixel; /* 3:RGB, 4:RGBA */
- unsigned char *rle_pixel_data;
+ char *rle_pixel_data;
} nv_image_t;
unsigned char *decompress_image_data(const nv_image_t *img);
diff --git a/src/libXNVCtrl/NVCtrl.c b/src/libXNVCtrl/NVCtrl.c
index f20b9be..0eec6bb 100644
--- a/src/libXNVCtrl/NVCtrl.c
+++ b/src/libXNVCtrl/NVCtrl.c
@@ -974,6 +974,59 @@ Bool XNVCTRLQueryDDCCITimingReport (
return exists;
}
+Bool XNVCTRLQueryBinaryData (
+ Display *dpy,
+ int screen,
+ unsigned int display_mask,
+ unsigned int attribute,
+ unsigned char **ptr,
+ int *len
+){
+ XExtDisplayInfo *info = find_display (dpy);
+ xnvCtrlQueryBinaryDataReply rep;
+ xnvCtrlQueryBinaryDataReq *req;
+ Bool exists;
+ int length, numbytes, slop;
+
+ if (!ptr) return False;
+
+ if(!XextHasExtension(info))
+ return False;
+
+ XNVCTRLCheckExtension (dpy, info, False);
+
+ LockDisplay (dpy);
+ GetReq (nvCtrlQueryBinaryData, req);
+ req->reqType = info->codes->major_opcode;
+ req->nvReqType = X_nvCtrlQueryBinaryData;
+ req->screen = screen;
+ req->display_mask = display_mask;
+ req->attribute = attribute;
+ if (!_XReply (dpy, (xReply *) &rep, 0, False)) {
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return False;
+ }
+ length = rep.length;
+ numbytes = rep.n;
+ slop = numbytes & 3;
+ *ptr = (char *) Xmalloc(numbytes);
+ if (! *ptr) {
+ _XEatData(dpy, length);
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return False;
+ } else {
+ _XRead(dpy, (char *) *ptr, numbytes);
+ if (slop) _XEatData(dpy, 4-slop);
+ }
+ exists = rep.flags;
+ if (len) *len = numbytes;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return exists;
+}
+
static Bool wire_to_event (Display *dpy, XEvent *host, xEvent *wire)
{
XExtDisplayInfo *info = find_display (dpy);
diff --git a/src/libXNVCtrl/NVCtrl.h b/src/libXNVCtrl/NVCtrl.h
index ac5b6fe..ac553b4 100644
--- a/src/libXNVCtrl/NVCtrl.h
+++ b/src/libXNVCtrl/NVCtrl.h
@@ -847,6 +847,8 @@
#define NV_CTRL_GVO_DATA_FORMAT_Y10CR8CB8Z10_TO_YCRCBZ4444 12
#define NV_CTRL_GVO_DATA_FORMAT_DUAL_R8G8B8_TO_DUAL_YCRCB422 13
#define NV_CTRL_GVO_DATA_FORMAT_DUAL_Y8CR8CB8_TO_DUAL_YCRCB422 14
+#define NV_CTRL_GVO_DATA_FORMAT_R10G10B10_TO_YCRCB422 15
+#define NV_CTRL_GVO_DATA_FORMAT_R10G10B10_TO_YCRCB444 16
/*
@@ -2348,19 +2350,101 @@
#define NV_CTRL_USE_HOUSE_SYNC_FALSE 0
#define NV_CTRL_USE_HOUSE_SYNC_TRUE 1
+/*
+ * NV_CTRL_EDID_AVAILABLE - report if an EDID is available for the
+ * specified display device.
+ */
+
+#define NV_CTRL_EDID_AVAILABLE 219 /* R-D */
+#define NV_CTRL_EDID_AVAILABLE_FALSE 0
+#define NV_CTRL_EDID_AVAILABLE_TRUE 1
+
+/*
+ * NV_CTRL_FORCE_STEREO - when TRUE, OpenGL will force stereo flipping
+ * even when no stereo drawables are visible (if the device is configured
+ * to support it, see the "Stereo" X config option).
+ * When false, fall back to the default behavior of only flipping when a
+ * stereo drawable is visible.
+ */
+
+
+#define NV_CTRL_FORCE_STEREO 220 /* RW- */
+#define NV_CTRL_FORCE_STEREO_FALSE 0
+#define NV_CTRL_FORCE_STEREO_TRUE 1
+
+
+/*
+ * NV_CTRL_IMAGE_SETTINGS - the image quality setting for OpenGL clients.
+ *
+ * This setting is only applied to OpenGL clients that are started
+ * after this setting is applied.
+ */
+
+#define NV_CTRL_IMAGE_SETTINGS 221 /* RW- */
+#define NV_CTRL_IMAGE_SETTINGS_HIGH_QUALITY 0
+#define NV_CTRL_IMAGE_SETTINGS_QUALITY 1
+#define NV_CTRL_IMAGE_SETTINGS_PERFORMANCE 2
+#define NV_CTRL_IMAGE_SETTINGS_HIGH_PERFORMANCE 3
+
+
+/*
+ * NV_CTRL_XINERAMA - return whether xinerama is enabled
+ */
+
+
+#define NV_CTRL_XINERAMA 222 /* RW- */
+#define NV_CTRL_XINERAMA_OFF 0
+#define NV_CTRL_XINERAMA_ON 1
+
+/*
+ * NV_CTRL_XINERAMA_STEREO - when TRUE, OpenGL will allow stereo flipping
+ * on multiple X screens configured with Xinerama.
+ * When FALSE, flipping is allowed only on one X screen at a time.
+ */
+
+#define NV_CTRL_XINERAMA_STEREO 223 /* RW- */
+#define NV_CTRL_XINERAMA_STEREO_FALSE 0
+#define NV_CTRL_XINERAMA_STEREO_TRUE 1
+
+
+/*
+ * NV_CTRL_BUS_RATE - if the bus type of the GPU driving the specified
+ * screen is AGP, then NV_CTRL_BUS_RATE returns the configured AGP
+ * transfer rate. If the bus type is PCI Express, then this attribute
+ * returns the width of the physical link.
+ */
+
+#define NV_CTRL_BUS_RATE 224 /* R-- */
+
+/*
+ * NV_CTRL_SHOW_SLI_HUD - when TRUE, OpenGL will draw information about the
+ * current SLI mode.
+ */
+
+#define NV_CTRL_SHOW_SLI_HUD 225 /* RW- */
+#define NV_CTRL_SHOW_SLI_HUD_FALSE 0
+#define NV_CTRL_SHOW_SLI_HUD_TRUE 1
+
+/*
+ * NV_CTRL_XV_SYNC_TO_DISPLAY - this control is valid when twinview and
+ * XVideo Sync To VBlank are enabled.
+ * It controls which display device will be synched to.
+ */
+
+#define NV_CTRL_XV_SYNC_TO_DISPLAY 226 /* RW- */
+
+
/**************************************************************************/
-#define NV_CTRL_LAST_ATTRIBUTE NV_CTRL_USE_HOUSE_SYNC
+#define NV_CTRL_LAST_ATTRIBUTE NV_CTRL_XV_SYNC_TO_DISPLAY
/**************************************************************************/
+
/*
+ *
* String Attributes:
*/
-#define QUERY_STRING_ERR 0
-#define QUERY_STRING_OK 1
-#define QUERY_STRING_STATIC 2
-
/*
* NV_CTRL_STRING_PRODUCT_NAME - the GPU product name on which the
* specified X screen is running.
@@ -2427,6 +2511,17 @@
#define NV_CTRL_STRING_LAST_ATTRIBUTE NV_CTRL_STRING_DDCCI_MISC_AUXILIARY_DISPLAY_DATA
+
+/**************************************************************************/
+
+/*
+ * Binary Data Attributes:
+ */
+
+#define NV_CTRL_BINARY_DATA_EDID 0 /* R-D */
+
+#define NV_CTRL_BINARY_DATA_LAST_ATTRIBUTE NV_CTRL_BINARY_DATA_EDID
+
/**************************************************************************/
/*
* CTRLAttributeValidValuesRec -
diff --git a/src/libXNVCtrl/NVCtrlLib.h b/src/libXNVCtrl/NVCtrlLib.h
index c5d34f6..cc4599f 100644
--- a/src/libXNVCtrl/NVCtrlLib.h
+++ b/src/libXNVCtrl/NVCtrlLib.h
@@ -428,6 +428,31 @@ Bool XNVCTRLQueryDDCCITimingReport (
/*
+ * XNVCTRLQueryBinaryData -
+ *
+ * Returns True if the attribute exists. Returns False otherwise.
+ * If XNVCTRLQueryBinaryData returns True, *ptr will point to an
+ * allocated block of memory containing the binary data attribute
+ * requested. It is the caller's responsibility to free the data
+ * when done. len will list the length of the binary data.
+ *
+ * Possible errors:
+ * BadValue - The screen doesn't exist.
+ * BadMatch - The NVIDIA driver is not present on that screen.
+ * BadAlloc - Insufficient resources to fulfill the request.
+ */
+
+Bool XNVCTRLQueryBinaryData (
+ Display *dpy,
+ int screen,
+ unsigned int display_mask,
+ unsigned int attribute,
+ unsigned char **ptr,
+ int *len
+);
+
+
+/*
* XNVCtrlSelectNotify -
*
* This enables/disables receiving of NV-CONTROL events. The type
diff --git a/src/libXNVCtrl/libXNVCtrl.a b/src/libXNVCtrl/libXNVCtrl.a
index 2dac144..c508ca0 100644
--- a/src/libXNVCtrl/libXNVCtrl.a
+++ b/src/libXNVCtrl/libXNVCtrl.a
Binary files differ
diff --git a/src/libXNVCtrl/nv_control.h b/src/libXNVCtrl/nv_control.h
index ff27a95..c1b7e3f 100644
--- a/src/libXNVCtrl/nv_control.h
+++ b/src/libXNVCtrl/nv_control.h
@@ -6,7 +6,7 @@
#define NV_CONTROL_NAME "NV-CONTROL"
#define NV_CONTROL_MAJOR 1
-#define NV_CONTROL_MINOR 6
+#define NV_CONTROL_MINOR 7
#define X_nvCtrlQueryExtension 0
#define X_nvCtrlIsNv 1
@@ -28,7 +28,8 @@
#define X_nvCtrlQueryDDCCICapabilities 17
#define X_nvCtrlQueryDDCCITimingReport 18
#define X_nvCtrlSetAttributeAndGetStatus 19
-#define X_nvCtrlLastRequest (X_nvCtrlSetAttributeAndGetStatus + 1)
+#define X_nvCtrlQueryBinaryData 20
+#define X_nvCtrlLastRequest (X_nvCtrlQueryBinaryData + 1)
/* Define 32 bit floats */
@@ -496,6 +497,31 @@ typedef struct {
CARD8 nvReqType;
CARD16 length B16;
CARD32 screen B32;
+ CARD32 display_mask B32;
+ CARD32 attribute B32;
+} xnvCtrlQueryBinaryDataReq;
+#define sz_xnvCtrlQueryBinaryDataReq 16
+
+typedef struct {
+ BYTE type;
+ BYTE pad0;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 flags B32;
+ CARD32 n B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
+ CARD32 pad7 B32;
+} xnvCtrlQueryBinaryDataReply;
+#define sz_xnvCtrlQueryBinaryDataReply 32
+
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 nvReqType;
+ CARD16 length B16;
+ CARD32 screen B32;
CARD16 notifyType B16;
CARD16 onoff B16;
} xnvCtrlSelectNotifyReq;
diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributes.c b/src/libXNVCtrlAttributes/NvCtrlAttributes.c
index f15d63e..6f3ee3b 100644
--- a/src/libXNVCtrlAttributes/NvCtrlAttributes.c
+++ b/src/libXNVCtrlAttributes/NvCtrlAttributes.c
@@ -437,6 +437,20 @@ NvCtrlGetStringDisplayAttribute(NvCtrlAttributeHandle *handle,
} /* NvCtrlGetStringDisplayAttribute() */
+ReturnStatus
+NvCtrlGetBinaryAttribute(NvCtrlAttributeHandle *handle,
+ unsigned int display_mask, int attr,
+ unsigned char **data, int *len)
+{
+ NvCtrlAttributePrivateHandle *h;
+
+ h = (NvCtrlAttributePrivateHandle *) handle;
+
+ return NvCtrlNvControlGetBinaryAttribute(h, display_mask, attr, data, len);
+
+} /* NvCtrlGetBinaryAttribute() */
+
+
char *NvCtrlAttributesStrError(ReturnStatus status)
{
switch (status) {
diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributes.h b/src/libXNVCtrlAttributes/NvCtrlAttributes.h
index 27da5d1..a2e6beb 100644
--- a/src/libXNVCtrlAttributes/NvCtrlAttributes.h
+++ b/src/libXNVCtrlAttributes/NvCtrlAttributes.h
@@ -359,25 +359,10 @@ NvCtrlGetStringDisplayAttribute (NvCtrlAttributeHandle *handle,
unsigned int display_mask,
int attr, char **ptr);
-/*
- * While some attributes should update on-the-fly, other attributes
- * should not be applied until an "Apply" button is pressed.
- *
- * To support this, NvCtrlSetAttributePending() can be called to set
- * the value of an attribute in a special cache in the backend. These
- * cached values will not be sent to the server until
- * NvCtrlFlushPendingAttributes() is called.
- * NvCtrlCancelPendingAttributes() can be called to clear the cache
- * without sending any values to the server.
- */
-
-ReturnStatus NvCtrlSetAttributePending (NvCtrlAttributeHandle *handle,
- int attr, int val);
-
-ReturnStatus NvCtrlFlushPendingAttributes (NvCtrlAttributeHandle *handle);
-
-ReturnStatus NvCtrlCancelPendingAttributes (NvCtrlAttributeHandle *handle);
-
+ReturnStatus
+NvCtrlGetBinaryAttribute(NvCtrlAttributeHandle *handle,
+ unsigned int display_mask, int attr,
+ unsigned char **data, int *len);
char *NvCtrlAttributesStrError (ReturnStatus status);
diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributesNvControl.c b/src/libXNVCtrlAttributes/NvCtrlAttributesNvControl.c
index 7e3b4ff..d9b8d25 100644
--- a/src/libXNVCtrlAttributes/NvCtrlAttributesNvControl.c
+++ b/src/libXNVCtrlAttributes/NvCtrlAttributesNvControl.c
@@ -42,7 +42,7 @@ NvCtrlNvControlAttributes *
NvCtrlInitNvControlAttributes (NvCtrlAttributePrivateHandle *h)
{
NvCtrlNvControlAttributes *nv;
- int ret, ver, rev, event, error;
+ int ret, major, minor, event, error;
ret = XNVCTRLQueryExtension (h->dpy, &event, &error);
if (ret != True) {
@@ -50,16 +50,16 @@ NvCtrlInitNvControlAttributes (NvCtrlAttributePrivateHandle *h)
return NULL;
}
- ret = XNVCTRLQueryVersion (h->dpy, &ver, &rev);
+ ret = XNVCTRLQueryVersion (h->dpy, &major, &minor);
if (ret != True) {
nv_error_msg("Failed to query NV-CONTROL extension version.");
return NULL;
}
- if (ver < NV_MINMAJOR || (ver == NV_MINMAJOR && rev < NV_MINMINOR)) {
+ if (major < NV_MINMAJOR || (major == NV_MINMAJOR && minor < NV_MINMINOR)) {
nv_error_msg("NV-CONTROL extension version %d.%d is too old; "
"the minimimum required version is %d.%d.",
- ver, rev, NV_MINMAJOR, NV_MINMINOR);
+ major, minor, NV_MINMAJOR, NV_MINMINOR);
return NULL;
}
@@ -82,9 +82,8 @@ NvCtrlInitNvControlAttributes (NvCtrlAttributePrivateHandle *h)
nv->event_base = event;
nv->error_base = error;
-
- /* currently don't need to store anything in
- NvCtrlNvControlAttributes */
+ nv->major_version = major;
+ nv->minor_version = minor;
return (nv);
@@ -160,3 +159,31 @@ NvCtrlNvControlGetStringAttribute (NvCtrlAttributePrivateHandle *h,
return NvCtrlNoAttribute;
} /* NvCtrlGetStringAttribute() */
+
+
+ReturnStatus
+NvCtrlNvControlGetBinaryAttribute(NvCtrlAttributePrivateHandle *h,
+ unsigned int display_mask, int attr,
+ unsigned char **data, int *len)
+{
+ Bool bret;
+
+ if (!h->nv) return NvCtrlMissingExtension;
+
+ /* the X_nvCtrlQueryBinaryData opcode was added in 1.7 */
+
+ if ((h->nv->major_version < 1) ||
+ ((h->nv->major_version == 1) && (h->nv->minor_version < 7))) {
+ return NvCtrlNoAttribute;
+ }
+
+ bret = XNVCTRLQueryBinaryData(h->dpy, h->screen, display_mask,
+ attr, data, len);
+
+ if (!bret) {
+ return NvCtrlError;
+ } else {
+ return NvCtrlSuccess;
+ }
+
+} /* NvCtrlNvControlGetBinaryAttribute() */
diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributesPrivate.h b/src/libXNVCtrlAttributes/NvCtrlAttributesPrivate.h
index 1617bb8..e9f622e 100644
--- a/src/libXNVCtrlAttributes/NvCtrlAttributesPrivate.h
+++ b/src/libXNVCtrlAttributes/NvCtrlAttributesPrivate.h
@@ -91,6 +91,8 @@ typedef struct __NvCtrlXrandrAttributes NvCtrlXrandrAttributes;
struct __NvCtrlNvControlAttributes {
int event_base;
int error_base;
+ int major_version;
+ int minor_version;
};
struct __NvCtrlVidModeAttributes {
@@ -303,6 +305,10 @@ NvCtrlNvControlGetStringAttribute (NvCtrlAttributePrivateHandle *,
unsigned int, int, char **);
ReturnStatus
+NvCtrlNvControlGetBinaryAttribute(NvCtrlAttributePrivateHandle *h,
+ unsigned int display_mask, int attr,
+ unsigned char **data, int *len);
+ReturnStatus
NvCtrlXvGetAttribute (NvCtrlAttributePrivateHandle *, int, int *);
ReturnStatus
diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributesXrandr.c b/src/libXNVCtrlAttributes/NvCtrlAttributesXrandr.c
index bbd61ef..1aaba8a 100644
--- a/src/libXNVCtrlAttributes/NvCtrlAttributesXrandr.c
+++ b/src/libXNVCtrlAttributes/NvCtrlAttributesXrandr.c
@@ -67,14 +67,16 @@ set_rotation(NvCtrlAttributePrivateHandle *h, Rotation rotation)
}
/* Get current size & orientation */
- sc = h->xrandr->XRRGetScreenInfo(h->xrandr->dpy, DefaultRootWindow(h->xrandr->dpy));
+ sc = h->xrandr->XRRGetScreenInfo(h->xrandr->dpy,
+ RootWindow(h->xrandr->dpy, h->screen));
if ( !sc ) {
return NvCtrlError;
}
cur_size = h->xrandr->XRRConfigCurrentConfiguration(sc, &cur_rotation);
status = h->xrandr->XRRSetScreenConfig (h->xrandr->dpy, sc,
- DefaultRootWindow(h->xrandr->dpy),
+ RootWindow(h->xrandr->dpy,
+ h->screen),
cur_size, rotation, CurrentTime);
h->xrandr->XRRFreeScreenConfigInfo(sc);
@@ -87,6 +89,14 @@ set_rotation(NvCtrlAttributePrivateHandle *h, Rotation rotation)
} /* set_rotation() */
+static int errors = 0;
+static int
+error_handler (Display *dpy, XErrorEvent *err)
+{
+ errors++;
+ return 0;
+}
+
/******************************************************************************
*
@@ -103,6 +113,7 @@ NvCtrlInitXrandrAttributes (NvCtrlAttributePrivateHandle *h)
Bool ret;
Rotation rotation;
XRRScreenSize *sizes;
+ int (*oldErrorHandler)(Display *, XErrorEvent *);
/* Check parameter */
@@ -173,8 +184,25 @@ NvCtrlInitXrandrAttributes (NvCtrlAttributePrivateHandle *h)
&xrandr->error_base);
if ( !ret ) goto fail;
- xrandr->rotations = xrandr->XRRRotations(xrandr->dpy, h->screen, &rotation);
- sizes = xrandr->XRRSizes(xrandr->dpy, h->screen, &(xrandr->nsizes));
+ /*
+ * XRRRotations fails on XFree86 4.3.0 with BadImplementation if the screen
+ * resolution is not the one the server started with. We work around that
+ * by temporarily installing an error handler, trying the call, and then
+ * disabling the rotation page if it fails.
+ */
+ XSync(xrandr->dpy, False);
+ errors = 0;
+ oldErrorHandler = XSetErrorHandler(error_handler);
+
+ xrandr->rotations = xrandr->XRRRotations(xrandr->dpy, h->screen,
+ &rotation);
+ sizes = xrandr->XRRSizes(xrandr->dpy, h->screen,
+ &(xrandr->nsizes));
+
+ XSync(xrandr->dpy, False);
+ XSetErrorHandler(oldErrorHandler);
+
+ if ( errors > 0 ) goto fail;
/* Must support more than one rotation orientation */
if ( (xrandr->rotations == 1) || (xrandr->rotations == 2) ||
@@ -184,7 +212,7 @@ NvCtrlInitXrandrAttributes (NvCtrlAttributePrivateHandle *h)
/* Register to recieve XRandR events */
- xrandr->XRRSelectInput(xrandr->dpy, DefaultRootWindow(xrandr->dpy),
+ xrandr->XRRSelectInput(xrandr->dpy, RootWindow(xrandr->dpy, h->screen),
RRScreenChangeNotifyMask);
// xrandr->rotations = 1;
@@ -279,7 +307,9 @@ NvCtrlXrandrGetAttribute (NvCtrlAttributePrivateHandle *h,
break;
case NV_CTRL_ATTR_XRANDR_ROTATION:
- sc = h->xrandr->XRRGetScreenInfo(h->xrandr->dpy, DefaultRootWindow(h->xrandr->dpy));
+ sc = h->xrandr->XRRGetScreenInfo(h->xrandr->dpy,
+ RootWindow(h->xrandr->dpy,
+ h->screen));
h->xrandr->XRRConfigRotations(sc, &rotation);
h->xrandr->XRRFreeScreenConfigInfo(sc);
diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributesXv.c b/src/libXNVCtrlAttributes/NvCtrlAttributesXv.c
index 5145d75..c105be4 100644
--- a/src/libXNVCtrlAttributes/NvCtrlAttributesXv.c
+++ b/src/libXNVCtrlAttributes/NvCtrlAttributesXv.c
@@ -62,7 +62,7 @@ NvCtrlXvAttributes * NvCtrlInitXvAttributes(NvCtrlAttributePrivateHandle *h)
XvAdaptorInfo *ainfo;
unsigned int ver, rev, req, event, error, nadaptors;
int ret, i;
- Display *dpy = h->dpy;
+ Display *dpy;
const char *error_str = NULL;
const char *warn_str = NULL;
@@ -72,6 +72,7 @@ NvCtrlXvAttributes * NvCtrlInitXvAttributes(NvCtrlAttributePrivateHandle *h)
goto fail;
}
+ dpy = h->dpy;
/* Allocate the attributes structure */
xv = (NvCtrlXvAttributes *)
@@ -323,7 +324,7 @@ ReturnStatus NvCtrlXvSetAttribute(NvCtrlAttributePrivateHandle *h,
return NvCtrlError;
}
- XFlush(h->dpy);
+ XFlush(h->xv->dpy);
return NvCtrlSuccess;
@@ -372,8 +373,7 @@ static NvCtrlXvAttribute *getXvAttribute(NvCtrlXvAttributes *xv,
{
NvCtrlXvAttribute *attr = NULL;
XvAttribute *attributes = NULL;
- unsigned int n;
- int i;
+ int i, n;
attributes = xv->XvQueryPortAttributes(xv->dpy, port, &n);
diff --git a/src/parse.c b/src/parse.c
index 434b90a..d892898 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -64,11 +64,14 @@ AttributeTableEntry attributeTable[] = {
{ "DigitalVibrance", NV_CTRL_DIGITAL_VIBRANCE, 0 },
{ "ImageSharpening", NV_CTRL_IMAGE_SHARPENING, 0 },
{ "BusType", NV_CTRL_BUS_TYPE, 0 },
+ { "BusRate", NV_CTRL_BUS_RATE, 0 },
{ "VideoRam", NV_CTRL_VIDEO_RAM, 0 },
{ "Irq", NV_CTRL_IRQ, 0 },
{ "OperatingSystem", NV_CTRL_OPERATING_SYSTEM, 0 },
{ "SyncToVBlank", NV_CTRL_SYNC_TO_VBLANK, 0 },
{ "AllowFlipping", NV_CTRL_FLIPPING_ALLOWED, 0 },
+ { "ForceStereoFlipping", NV_CTRL_FORCE_STEREO, 0 },
+ { "XineramaStereoFlipping",NV_CTRL_XINERAMA_STEREO, 0 },
{ "LogAniso", NV_CTRL_LOG_ANISO, 0 },
{ "FSAA", NV_CTRL_FSAA_MODE, 0 },
{ "TextureSharpen", NV_CTRL_TEXTURE_SHARPEN, 0 },
@@ -80,6 +83,7 @@ AttributeTableEntry attributeTable[] = {
{ "EnabledDisplays", NV_CTRL_ENABLED_DISPLAYS, 0 },
{ "ForceGenericCpu", NV_CTRL_FORCE_GENERIC_CPU, 0 },
{ "GammaCorrectedAALines", NV_CTRL_OPENGL_AA_LINE_GAMMA, 0 },
+ { "ShowSLIHUD", NV_CTRL_SHOW_SLI_HUD, 0 },
{ "CursorShadow", NV_CTRL_CURSOR_SHADOW, 0 },
{ "CursorShadowXOffset", NV_CTRL_CURSOR_SHADOW_X_OFFSET, 0 },
{ "CursorShadowYOffset", NV_CTRL_CURSOR_SHADOW_Y_OFFSET, 0 },
@@ -116,6 +120,7 @@ AttributeTableEntry attributeTable[] = {
{ "GPUCoreTemp", NV_CTRL_GPU_CORE_TEMPERATURE, N },
{ "GPUAmbientTemp", NV_CTRL_AMBIENT_TEMPERATURE, N },
{ "FramelockUseHouseSync", NV_CTRL_USE_HOUSE_SYNC, 0 },
+ { "OpenGLImageSettings", NV_CTRL_IMAGE_SETTINGS, 0 },
{ "XVideoOverlaySaturation", NV_CTRL_ATTR_XV_OVERLAY_SATURATION, V },
{ "XVideoOverlayContrast", NV_CTRL_ATTR_XV_OVERLAY_CONTRAST, V },
@@ -123,7 +128,8 @@ AttributeTableEntry attributeTable[] = {
{ "XVideoOverlayHue", NV_CTRL_ATTR_XV_OVERLAY_HUE, V },
{ "XVideoTextureSyncToVBlank", NV_CTRL_ATTR_XV_TEXTURE_SYNC_TO_VBLANK, V },
{ "XVideoBlitterSyncToVBlank", NV_CTRL_ATTR_XV_BLITTER_SYNC_TO_VBLANK, V },
-
+ { "XVideoSyncToDisplay", NV_CTRL_XV_SYNC_TO_DISPLAY, 0 },
+
{ "GPUOverclockingState", NV_CTRL_GPU_OVERCLOCKING_STATE, N },
{ "GPUDefault2DClockFreqs", NV_CTRL_GPU_DEFAULT_2D_CLOCK_FREQS, N|P },
{ "GPUDefault3DClockFreqs", NV_CTRL_GPU_DEFAULT_3D_CLOCK_FREQS, N|P },
@@ -142,6 +148,18 @@ AttributeTableEntry attributeTable[] = {
#undef P
/*
+ * When new integer attributes are added to NVCtrl.h, an entry should
+ * be added in the above attributeTable[]. The below #if should also
+ * be updated to indicate the last attribute that the table knows
+ * about.
+ */
+
+#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_XV_SYNC_TO_DISPLAY
+#warning "Have you forgotten to add a new integer attribute to attributeTable?"
+#endif
+
+
+/*
* nv_parse_attribute_string() - see comments in parse.h
*/
diff --git a/src/query-assign.c b/src/query-assign.c
index cdd7190..ed89298 100644
--- a/src/query-assign.c
+++ b/src/query-assign.c
@@ -96,10 +96,9 @@ int nv_process_assignments_and_queries(Options *op)
uint32 *nv_get_enabled_display_devices(int n, NvCtrlAttributeHandle **h)
{
ReturnStatus status;
- uint32 *d;
- int screen;
+ int *d, screen;
- d = malloc(sizeof(uint32) * n);
+ d = malloc(sizeof(int) * n);
for (screen = 0; screen < n; screen++) {
if (!h[screen]) {
@@ -118,7 +117,7 @@ uint32 *nv_get_enabled_display_devices(int n, NvCtrlAttributeHandle **h)
}
}
- return d;
+ return (uint32 *)d;
} /* nv_get_enabled_display_devices() */
@@ -961,10 +960,16 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h,
status = NvCtrlGetValidDisplayAttributeValues(h->h[screen], mask,
a->attr, &valid);
if (status != NvCtrlSuccess) {
- nv_error_msg("Error querying valid values for attribute "
- "'%s' on %s specified %s (%s).",
- a->name, h->screen_names[screen], whence,
- NvCtrlAttributesStrError(status));
+ if(status == NvCtrlAttributeNotAvailable) {
+ nv_warning_msg("Attribute '%s' specified %s is not "
+ "available on %s.",
+ a->name, whence, h->screen_names[screen]);
+ } else {
+ nv_error_msg("Error querying valid values for attribute "
+ "'%s' on %s specified %s (%s).",
+ a->name, h->screen_names[screen], whence,
+ NvCtrlAttributesStrError(status));
+ }
goto done;
}