diff options
author | Aaron Plattner <aplattner@nvidia.com> | 2008-02-12 21:28:55 -0800 |
---|---|---|
committer | Aaron Plattner <aplattner@nvidia.com> | 2008-02-12 21:28:55 -0800 |
commit | 1e2ff16f982f33122e4239c26aa1a3c2030f5c1d (patch) | |
tree | 42a8fa910daa8504632e1f2d14a775af1e4812ee | |
parent | 70ce3d7b12b71ea08c175017d9771cf1b65ec32d (diff) |
1.0-81741.0-8174
43 files changed, 2171 insertions, 516 deletions
@@ -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 Binary files differindex 2dac144..c508ca0 100644 --- a/src/libXNVCtrl/libXNVCtrl.a +++ b/src/libXNVCtrl/libXNVCtrl.a 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; } |