summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Plattner <aplattner@nvidia.com>2010-09-28 13:09:37 -0700
committerAaron Plattner <aplattner@nvidia.com>2010-09-28 13:09:37 -0700
commit98d47fcfbb9dc1ae90e194c101c1370cf715d742 (patch)
tree80c925a28ffea2642c0ca4bab1439bda9fe1e306
parent229313f0e3192855999cae5034e20e4686217bad (diff)
260.19.04260.19.04
-rw-r--r--Makefile50
-rw-r--r--doc/nvidia-settings.1.m4163
-rw-r--r--samples/Makefile99
-rw-r--r--samples/README35
-rw-r--r--samples/nv-control-gvi.c46
-rw-r--r--samples/src.mk1
-rw-r--r--src/command-line.c225
-rw-r--r--src/command-line.h2
-rw-r--r--src/common-utils/nvgetopt.c (renamed from src/nvgetopt.c)230
-rw-r--r--src/common-utils/nvgetopt.h156
-rw-r--r--src/common-utils/src.mk7
-rw-r--r--src/gen-manpage-opts.c147
-rw-r--r--src/gtk+-2.x/ctkclocks.c16
-rw-r--r--src/gtk+-2.x/ctkcolorcontrols.c580
-rw-r--r--src/gtk+-2.x/ctkcolorcontrols.h97
-rw-r--r--src/gtk+-2.x/ctkcolorcorrection.c177
-rw-r--r--src/gtk+-2.x/ctkcolorcorrection.h4
-rw-r--r--src/gtk+-2.x/ctkdisplayconfig.c73
-rw-r--r--src/gtk+-2.x/ctkdisplaydevice-dfp.c61
-rw-r--r--src/gtk+-2.x/ctkdisplaydevice-dfp.h2
-rw-r--r--src/gtk+-2.x/ctkdisplaylayout.c83
-rw-r--r--src/gtk+-2.x/ctkdisplaylayout.h11
-rw-r--r--src/gtk+-2.x/ctkditheringcontrols.c683
-rw-r--r--src/gtk+-2.x/ctkditheringcontrols.h98
-rw-r--r--src/gtk+-2.x/ctkedid.c246
-rw-r--r--src/gtk+-2.x/ctkedid.h3
-rw-r--r--src/gtk+-2.x/ctkevent.c11
-rw-r--r--src/gtk+-2.x/ctkframelock.c133
-rw-r--r--src/gtk+-2.x/ctkframelock.h4
-rwxr-xr-xsrc/gtk+-2.x/ctkgvi.c34
-rw-r--r--src/gtk+-2.x/ctkgvo-csc.c55
-rw-r--r--src/gtk+-2.x/ctkgvo.c4
-rw-r--r--src/gtk+-2.x/ctkimagesliders.c21
-rw-r--r--src/gtk+-2.x/ctkpowermizer.c87
-rw-r--r--src/gtk+-2.x/ctkpowermizer.h1
-rw-r--r--src/gtk+-2.x/ctkscreen.c133
-rw-r--r--src/gtk+-2.x/ctkslimm.c26
-rw-r--r--src/gtk+-2.x/ctkwindow.c2
-rw-r--r--src/gtk+-2.x/src.mk4
-rw-r--r--src/libXNVCtrl/NVCtrl.h117
-rw-r--r--src/libXNVCtrl/nv_control.h6
-rw-r--r--src/msg.c43
-rw-r--r--src/msg.h1
-rw-r--r--src/nvgetopt.h47
-rw-r--r--src/option-table.h156
-rw-r--r--src/parse.c59
-rw-r--r--src/parse.h14
-rw-r--r--src/query-assign.c79
-rw-r--r--src/src.mk4
-rw-r--r--utils.mk10
-rw-r--r--version.mk2
51 files changed, 3422 insertions, 926 deletions
diff --git a/Makefile b/Makefile
index 1cc5f41..0b4d202 100644
--- a/Makefile
+++ b/Makefile
@@ -34,7 +34,6 @@ include utils.mk
# assign default values if they are not exported by the caller
##############################################################################
-
ifndef X_LDFLAGS
ifeq ($(TARGET_OS)-$(TARGET_ARCH),Linux-x86_64)
X_LDFLAGS = -L/usr/X11R6/lib64
@@ -59,19 +58,20 @@ endif
##############################################################################
-# The XF86Config-parser and libXNVCtrl directories may be in one of
-# two places: either elsewhere in the driver source tree when building
-# nvidia-settings as part of the NVIDIA driver build (in which case,
-# XNVCTRL_DIR, XNVCTRL_ARCHIVE, and XCONFIG_PARSER_DIR should be
-# defined by the calling makefile), or directly in the source
-# directory when building from the nvidia-settings source tarball (in
-# which case, the below conditional assignments should be used)
+# The XF86Config-parser, libXNVCtrl, and common-utils directories may
+# be in one of two places: either elsewhere in the driver source tree
+# when building nvidia-settings as part of the NVIDIA driver build (in
+# which case, XNVCTRL_DIR, XNVCTRL_ARCHIVE, XCONFIG_PARSER_DIR and
+# COMMON_UTILS_DIR should be defined by the calling makefile), or
+# directly in the source directory when building from the
+# nvidia-settings source tarball (in which case, the below conditional
+# assignments should be used)
##############################################################################
XNVCTRL_DIR ?= src/libXNVCtrl
XNVCTRL_ARCHIVE ?= $(XNVCTRL_DIR)/libXNVCtrl.a
XCONFIG_PARSER_DIR ?= src/XF86Config-parser
-
+COMMON_UTILS_DIR ?= src/common-utils
##############################################################################
# assign variables
@@ -114,6 +114,8 @@ ifeq ($(MANPAGE_GZIP),1)
else
MANPAGE = $(MANPAGE_not_gzipped)
endif
+GEN_MANPAGE_OPTS = $(OUTPUTDIR)/gen-manpage-opts
+OPTIONS_1_INC = $(OUTPUTDIR)/options.1.inc
# Include all the source lists; dist-files.mk will define SRC
include dist-files.mk
@@ -121,6 +123,9 @@ include dist-files.mk
include $(XCONFIG_PARSER_DIR)/src.mk
SRC += $(addprefix $(XCONFIG_PARSER_DIR)/,$(XCONFIG_PARSER_SRC))
+include $(COMMON_UTILS_DIR)/src.mk
+SRC += $(addprefix $(COMMON_UTILS_DIR)/,$(COMMON_UTILS_SRC))
+
SRC += $(STAMP_C)
OBJS = $(call BUILD_OBJECT_LIST,$(SRC))
@@ -132,6 +137,7 @@ CFLAGS += -I $(XCONFIG_PARSER_DIR)/..
CFLAGS += -I src/libXNVCtrlAttributes
CFLAGS += -I src/xpm_data
CFLAGS += -I src/gtk+-2.x
+CFLAGS += -I $(COMMON_UTILS_DIR)
CFLAGS += -I $(OUTPUTDIR)
$(call BUILD_OBJECT_LIST,$(GTK_SRC)): CFLAGS += $(GTK_CFLAGS)
@@ -168,7 +174,8 @@ $(eval $(call DEFINE_STAMP_C_RULE, $(OBJS),$(NVIDIA_SETTINGS_PROGRAM_NAME)))
clean clobber:
rm -rf $(NVIDIA_SETTINGS) $(MANPAGE) *~ $(STAMP_C) \
- $(OUTPUTDIR)/*.o $(OUTPUTDIR)/*.d
+ $(OUTPUTDIR)/*.o $(OUTPUTDIR)/*.d \
+ $(GEN_MANPAGE_OPTS) $(OPTIONS_1_INC)
##############################################################################
@@ -179,12 +186,33 @@ AUTO_TEXT = ".\\\" WARNING: THIS FILE IS AUTO-GENERATED! Edit $< instead."
doc: $(MANPAGE)
-$(MANPAGE_not_gzipped): doc/nvidia-settings.1.m4
+GEN_MANPAGE_OPTS_SRC = src/gen-manpage-opts.c
+
+BUILD_MANPAGE_OBJECT_LIST = \
+ $(patsubst %.o,%.manpage.o,$(call BUILD_OBJECT_LIST,$(1)))
+
+GEN_MANPAGE_OPTS_OBJS = \
+ $(call BUILD_MANPAGE_OBJECT_LIST,$(GEN_MANPAGE_OPTS_SRC))
+
+$(GEN_MANPAGE_OPTS): $(GEN_MANPAGE_OPTS_OBJS)
+ $(call quiet_cmd,HOST_LINK) $(GEN_MANPAGE_OPTS_OBJS) -o $@ \
+ $(HOST_CFLAGS) $(HOST_LDFLAGS) $(HOST_BIN_LDFLAGS)
+
+# define a rule to build each GEN_MANPAGE_OPTS object file
+$(foreach src,$(GEN_MANPAGE_OPTS_SRC),\
+ $(eval $(call DEFINE_OBJECT_RULE_WITH_OBJECT_NAME,HOST_CC,$(src),\
+ $(call BUILD_MANPAGE_OBJECT_LIST,$(src)))))
+
+$(OPTIONS_1_INC): $(GEN_MANPAGE_OPTS)
+ @./$< > $@
+
+$(MANPAGE_not_gzipped): doc/nvidia-settings.1.m4 $(OPTIONS_1_INC)
$(call quiet_cmd,M4) \
-D__HEADER__=$(AUTO_TEXT) \
-D__BUILD_OS__=$(TARGET_OS) \
-D__VERSION__=$(NVIDIA_VERSION) \
-D__DATE__="`$(DATE) +%F`" \
+ -I $(OUTPUTDIR) \
$< > $@
$(MANPAGE_gzipped): $(MANPAGE_not_gzipped)
diff --git a/doc/nvidia-settings.1.m4 b/doc/nvidia-settings.1.m4
index c97e8af..1349ccd 100644
--- a/doc/nvidia-settings.1.m4
+++ b/doc/nvidia-settings.1.m4
@@ -1,4 +1,5 @@
changequote([[[, ]]])dnl
+define(__OPTIONS__, [[[include([[[options.1.inc]]])dnl]]])dnl
dnl Solaris man chokes on three-letter macros.
ifelse(__BUILD_OS__,SunOS,[[[define(__URL__,UR)]]],[[[define(__URL__,URL)]]])dnl
.\" Copyright (C) 2010 NVIDIA Corporation.
@@ -51,166 +52,8 @@ Then, it displays a graphical user interface (GUI) for configuring the current s
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 specified by
-.B \-\-display.
-If that is not given, then the
-.I $DISPLAY
-environment variable is used.
-.TP
-.B \-n, \-\-no\-config
-Do not load the configuration file.
-This mode of operation is useful if
-.B nvidia\-settings
-has difficulties starting due to problems with applying settings in the configuration file.
-.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
-.B \-r, \-\-rewrite\-config\-file
-Write the current X server configuration to the configuration file, and exit without starting
-a graphical user interface.
-See the EXAMPLES section.
-.TP
-.BI "\-V, \-\-verbose=" verbosity
-Controls how much information is printed.
-By default, the verbosity is
-.B errors
-and only error messages are printed.
-.br
-
-.I verbosity
-can be one of the following values:
-.ti +5
-.B errors
-- Print errors.
-.ti +5
-.B warnings
-- Print errors and warnings.
-.ti +5
-.B all
-- Print errors, warnings, and other information.
-.TP
-.BI "\-a, \-\-assign=" assign
-The
-.I assign
-argument to the
-.B \-\-assign
-command line 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.
-.sp
-.br
-{DISPLAY} can additionally include a target specification to direct an assignment to something other than an X screen.
-A target specification is contained within brackets and consists of a target type name, a colon, and the target id.
-The target type name can be one of
-.B screen,
-.B gpu,
-.B framelock,
-.B vcs,
-.B gvi,
-or
-.B fan;
-the target id is the index into the list of targets (for that target type).
-The target specification can be used in {DISPLAY} wherever an X screen can be used, following the syntax {host}:{display}[{target_type}:{target_id}].
-See the output of
-.nf
-
- nvidia-settings --query all
-
-.fi
-for information on which target types can be used with which attributes.
-See the output of
-.nf
-
- nvidia-settings -q screens -q gpus -q framelocks -q vcs -q gvis -q fans
-
-.fi
-for lists of targets for each target type.
-.br
-.sp
-The [{display devices}] portion is also optional; if it is not specified, then the attribute is assigned to all display devices.
-.br
-.sp
-Some examples:
-.nf
-
- -a FSAA=5
- -a localhost:0.0/DigitalVibrance[CRT-0]=0
- --assign="SyncToVBlank=1"
- -a [gpu:0]/DigitalVibrance[DFP-1]=63
-
-.fi
-.TP
-.BI "\-q, \-\-query=" query
-The
-.I query
-argument to the
-.B \-\-query
-command line 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 syntax is the same as that for the
-.B \-\-assign
-option, without
-.B ={value}.
-Specify
-.B \-q screens,
-.B \-q gpus,
-.B \-q framelocks,
-.B \-q vcs,
-.B \-q gvis,
-or
-.B \-q fans
-to query a list of X screens, GPUs, Frame Lock devices, Visual Computing Systems, SDI Input Devices, or fans, respectively, that are present on the X Display {DISPLAY}.
-Specify
-.B \-q all
-to query all attributes.
-.TP
-.B \-t, \-\-terse
-When querying attribute values with the '--query' command line option, only print the current value, rather than the more verbose description of the attribute, its valid values, and its current value.
-.TP
-.B \-d, \-\-display\-device\-string
-When printing attribute values in response to the '--query' option, if the attribute value is a display device mask, print the value as a list of display devices (e.g., "CRT-0, DFP-0"), rather than a hexadecimal bit mask (e.g., 0x00010001).
-.TP
-.B \-g, \-\-glxinfo
-Print GLX Information for the X display and exit.
-.TP
-.B \-e, \-\-describe
-Prints information about a particular attribute. Specify 'all' to list the descriptions of all attributes. Specify 'list' to list the attribute names without a descriptions.
+dnl Call gen-manpage-opts to generate this section.
+__OPTIONS__
.SH "USER GUIDE"
.SS Contents
1. Layout of the nvidia\-settings GUI
diff --git a/samples/Makefile b/samples/Makefile
index 1d5d350..3796158 100644
--- a/samples/Makefile
+++ b/samples/Makefile
@@ -2,7 +2,7 @@
# NV-CONTROL samples: Sample tools for configuring the NVIDIA X driver on Unix
# and Linux systems.
#
-# Copyright (c) 2004-2008 NVIDIA, Corporation
+# Copyright (c) 2010 NVIDIA, Corporation
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -24,62 +24,71 @@
# SOFTWARE.
#
-# Below are variables that users can override, either here or on the
-# make commandline
-#
-# CC = gcc
-# CFLAGS = -Wall
-# LDFLAGS =
-# X11R6_INC_DIR = /usr/X11R6/include
-# X11R6_LIB_DIR = /usr/X11R6/lib/
+##############################################################################
+# include common variables and functions
+##############################################################################
-BUILD_OS := $(shell uname)
-BUILD_ARCH := $(shell uname -m)
+UTILS_MK_DIR ?= ..
-ifndef CC
- CC = gcc
-endif
+include $(UTILS_MK_DIR)/utils.mk
-ifndef CFLAGS
- CFLAGS = -Wall
-endif
-ifndef LDFLAGS
- LDFLAGS =
-endif
+##############################################################################
+# The calling Makefile may export any of the following variables; we
+# assign default values if they are not exported by the caller
+##############################################################################
-ifndef X11R6_INC_DIR
- X11R6_INC_DIR = /usr/X11R6/include/
-endif
-
-ifndef X11R6_LIB_DIR
- ifeq ($(BUILD_OS)-$(BUILD_ARCH),Linux-x86_64)
- X11R6_LIB_DIR = /usr/X11R6/lib64
+ifndef X_LDFLAGS
+ ifeq ($(TARGET_OS)-$(TARGET_ARCH),Linux-x86_64)
+ X_LDFLAGS = -L/usr/X11R6/lib64
else
- X11R6_LIB_DIR = /usr/X11R6/lib
+ X_LDFLAGS = -L/usr/X11R6/lib
endif
endif
-LIBXNVCTRL_DIR = ../src/libXNVCtrl
+X_CFLAGS ?=
+
+LIBXNVCTRL_DIR ?= ../src/libXNVCtrl
+
+CFLAGS += $(X_CFLAGS)
+CFLAGS += -I $(LIBXNVCTRL_DIR)
+
+LDFLAGS += $(X_LDFLAGS)
+LDFLAGS += -L $(LIBXNVCTRL_DIR)
+LDFLAGS += -lXNVCtrl -lXext -lX11
+
+
+##############################################################################
+# samples
+##############################################################################
+
+SAMPLE_SOURCES += nv-control-info.c
+SAMPLE_SOURCES += nv-control-dvc.c
+SAMPLE_SOURCES += nv-control-events.c
+SAMPLE_SOURCES += nv-control-dpy.c
+SAMPLE_SOURCES += nv-control-targets.c
+SAMPLE_SOURCES += nv-control-framelock.c
+SAMPLE_SOURCES += nv-control-gvi.c
+
+##############################################################################
+# build rules
+##############################################################################
-ALL_CFLAGS = $(CFLAGS) -I $(LIBXNVCTRL_DIR) -I $(X11R6_INC_DIR)
-ALL_LDFLAGS = $(LDFLAGS) -L $(LIBXNVCTRL_DIR) -L $(X11R6_LIB_DIR) \
- -lXNVCtrl -lXext -lX11
+.PHONY: all clean clobber
-SAMPLES = \
- nv-control-info \
- nv-control-dvc \
- nv-control-events \
- nv-control-dpy \
- nv-control-targets \
- nv-control-framelock \
- nv-control-gvi
+# define the rule to build each object file
+$(foreach src, $(SAMPLE_SOURCES), $(eval $(call DEFINE_OBJECT_RULE,CC,$(src))))
-all: $(SAMPLES)
+# define the rule to link each sample app from its corresponding object file
+define link_sample_from_object
+ $$(OUTPUTDIR)/$(1:.c=): $$(call BUILD_OBJECT_LIST,$(1))
+ $$(call quiet_cmd,LINK) $$(CFLAGS) -o $$@ $$< $$(LDFLAGS) $$(BIN_LDFLAGS)
+ all:: $$(OUTPUTDIR)/$(1:.c=)
+ SAMPLES += $$(OUTPUTDIR)/$(1:.c=)
+endef
-% : %.c
- $(CC) $(ALL_CFLAGS) $< -o $@ $(ALL_LDFLAGS)
+$(foreach sample,$(SAMPLE_SOURCES),$(eval $(call link_sample_from_object,$(sample))))
-clean:
- rm -rf *.o *~ $(SAMPLES)
+clean clobber:
+ rm -rf *~ $(OUTPUTDIR)/*.o $(OUTPUTDIR)/*.d $(SAMPLES)
diff --git a/samples/README b/samples/README
index 750f115..4709166 100644
--- a/samples/README
+++ b/samples/README
@@ -2,7 +2,7 @@ NV-CONTROL X Extension Samples
The `nvidia-settings` application is fairly involved, and is not
the easiest source code to read through for someone interested in
-learning how to use the NV-CONTROL.
+learning how to use the NV-CONTROL X extension.
The applications in this directory are trivial examples demonstrating
how to use the NV-CONTROL X extension. For more thorough
@@ -12,24 +12,29 @@ source package).
Sample applications:
- nv-control-info: demonstrates how to query for extension
- presense, basic information.
+ nv-control-info: Demonstrates how to query for extension
+ presence and basic information.
- nv-control-dvc: demonstrates how to query and assign an
- integer attribute (NV_CTRL_DIGITAL_VIBRANCE); also
- shows how to handle multiple display devices.
+ nv-control-dvc: Demonstrates how to query and assign an
+ integer attribute (NV_CTRL_DIGITAL_VIBRANCE); also
+ shows how to handle multiple display devices.
- nv-control-events: demonstrates how to register to receive and
- interpret NV-CONTROL events.
+ nv-control-events: Demonstrates how to register to receive and
+ interpret NV-CONTROL events.
- nv-control-dpy: demonstrates how to configure display devices
- using the NV-CONTROL X extension.
+ nv-control-dpy: Demonstrates how to configure display devices
+ using the NV-CONTROL X extension.
- nv-control-targets: demonstrates how to query various attributes
- from varying target types (GPUs, X Screens,
- Frame Lock Boards) using the XNVCTRL target
- functions.
+ nv-control-targets: Demonstrates how to query various attributes
+ from varying target types (GPUs, X Screens,
+ Frame Lock Boards) using the XNVCTRL target
+ functions.
- nv-control-framelock: demonstrates how to query frame lock related
+ nv-control-framelock: Demonstrates how to query frame lock related
attributes. Also demonstrates how to enable/
disable frame lock.
+
+ nv-control-gvi: Demonstrates how to interact with the Graphics-to-
+ Video-In (GVI) capabilities of a GVI target via
+ NV-CONTROL.
+
diff --git a/samples/nv-control-gvi.c b/samples/nv-control-gvi.c
index 8bc988b..6e0a4de 100644
--- a/samples/nv-control-gvi.c
+++ b/samples/nv-control-gvi.c
@@ -38,18 +38,22 @@
#include "NVCtrlLib.h"
+/* Used to stringify NV_CTRL_XXX #defines */
+
+#define ADD_NVCTRL_CASE(FMT) \
+case (FMT): \
+ return #FMT;
+
+
/*
* Decode SDI input value returned.
*/
char *SyncTypeName(int value)
{
switch (value) {
- case NV_CTRL_GVO_SDI_SYNC_INPUT_DETECTED_HD:
- return "NV_CTRL_GVO_SDI_SYNC_INPUT_DETECTED_HD";
- case NV_CTRL_GVO_SDI_SYNC_INPUT_DETECTED_SD:
- return "NV_CTRL_GVO_SDI_SYNC_INPUT_DETECTED_SD";
- case NV_CTRL_GVO_SDI_SYNC_INPUT_DETECTED_NONE:
- return "NV_CTRL_GVO_SDI_SYNC_INPUT_DETECTED_NONE";
+ ADD_NVCTRL_CASE(NV_CTRL_GVO_SDI_SYNC_INPUT_DETECTED_HD);
+ ADD_NVCTRL_CASE(NV_CTRL_GVO_SDI_SYNC_INPUT_DETECTED_SD);
+ ADD_NVCTRL_CASE(NV_CTRL_GVO_SDI_SYNC_INPUT_DETECTED_NONE);
default:
return "Invalid Value";
}
@@ -59,11 +63,6 @@ char *SyncTypeName(int value)
* Decode provided signal format.
*/
-#define ADD_NVCTRL_CASE(FMT) \
-case (FMT): \
- return #FMT;
-
-
char *VideoFormatName(int value)
{
switch(value) {
@@ -663,6 +662,7 @@ void do_listconfig(Display *dpy, int gvi)
unsigned int fmt_list = fmts[i];
unsigned int fmt_bit;
unsigned int fmt;
+ unsigned int fmt_flags;
unsigned int bpcs;
unsigned int bpc_bit;
@@ -678,7 +678,29 @@ void do_listconfig(Display *dpy, int gvi)
fmt_list &= (~fmt_bit);
fmt = ffs(fmt_bit) - 1 + (32*i);
- printf("\n%s:\n", VideoFormatName(fmt));
+ printf("\n%s", VideoFormatName(fmt));
+ ret = XNVCTRLQueryTargetAttribute(dpy,
+ NV_CTRL_TARGET_TYPE_GVI,
+ gvi,
+ fmt, // display_mask
+ NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS,
+ (int *)&fmt_flags);
+ if (!ret) {
+ printf(" - Failed to query flag bits for video format for "
+ "GVI %d.\n", gvi);
+ } else if (fmt_flags == NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_NONE) {
+ printf(" (No flags set): \n");
+ } else {
+ printf(" (Flags:");
+ printf("%c", (fmt_flags & NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_INTERLACED) ? 'I' : '_');
+ printf("%c", (fmt_flags & NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_PROGRESSIVE) ? 'P' : '_');
+ printf("%c", (fmt_flags & NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_PSF) ? 'F' : '_');
+ printf("%c", (fmt_flags & NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_3G_LEVEL_A) ? 'A' : '_');
+ printf("%c", (fmt_flags & NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_3G_LEVEL_B) ? 'B' : '_');
+ printf("%c", (fmt_flags & NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_3G_1080P_NO_12BPC) ? 'N' : '_');
+ printf("):\n");
+ }
+
// Set the video format
XNVCTRLSetTargetAttribute(dpy,
diff --git a/samples/src.mk b/samples/src.mk
index 930b684..e76f2ba 100644
--- a/samples/src.mk
+++ b/samples/src.mk
@@ -4,7 +4,6 @@
SAMPLES_SRC +=
-SAMPLES_EXTRA_DIST += Makefile
SAMPLES_EXTRA_DIST += README
SAMPLES_EXTRA_DIST += nv-control-dvc.c
SAMPLES_EXTRA_DIST += nv-control-dpy.c
diff --git a/src/command-line.c b/src/command-line.c
index 7aa1452..8fe3843 100644
--- a/src/command-line.c
+++ b/src/command-line.c
@@ -30,7 +30,7 @@
#include <stdio.h>
#include <ctype.h>
-#include "command-line.h"
+#include "option-table.h"
#include "query-assign.h"
#include "msg.h"
#include "nvgetopt.h"
@@ -39,13 +39,8 @@
#include "NvCtrlAttributes.h"
-#define TAB " "
-#define BIGTAB " "
-
/* local prototypes */
-static void print_assign_help(void);
-static void print_query_help(void);
static void print_attribute_help(char *attr);
static void print_help(void);
static char *nvstrcat(const char *str, ...);
@@ -71,188 +66,15 @@ static void print_version(void)
nv_msg(TAB, "The NVIDIA X Server Settings tool.");
nv_msg(NULL, "");
nv_msg(TAB, "This program is used to configure the "
- "NVIDIA Linux graphics driver.");
+ "NVIDIA Linux graphics driver.");
+ nv_msg(TAB, "For more detail, please see the nvidia-settings(1) "
+ "man page.");
nv_msg(NULL, "");
nv_msg(TAB, "Copyright (C) 2004 - 2010 NVIDIA Corporation.");
nv_msg(NULL, "");
} /* print_version() */
-
-/*
- * Options table; the fields are:
- *
- * name - this is the long option name
- *
- * shortname - this is the one character short option name
- *
- * flags - bitmask; possible values are NVGETOPT_HAS_ARGUMENT and
- * NVGETOPT_IS_BOOLEAN
- *
- * description function - function to call to display description
- * through nv_msg()
- *
- * description - text for use by print_help() to describe the option
- */
-
-#define CONFIG_FILE_OPTION 1
-
-static const NVGetoptOption __options[] = {
- { "version", 'v', 0, NULL,
- "Print the nvidia-settings version and exit." },
-
- { "help", 'h', 0, NULL,
- "Print usage information and exit." },
-
- { "config", CONFIG_FILE_OPTION, NVGETOPT_HAS_ARGUMENT, NULL,
- "Use the configuration file [CONFIG] rather than the "
- "default " DEFAULT_RC_FILE },
-
- { "ctrl-display", 'c', NVGETOPT_HAS_ARGUMENT, NULL,
- "Control the specified X display. If this option is not given, then "
- "nvidia-settings will control the display specifed by '--display'. If "
- "that is not given, then the $DISPLAY environment variable is used." },
-
- { "load-config-only", 'l', 0, NULL,
- "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." },
-
- { "no-config", 'n', 0, NULL,
- "Do not load the configuration file. This mode of operation is useful "
- "if nvidia-settings has difficulties starting due to problems with "
- "applying settings in the configuration file." },
-
- { "rewrite-config-file", 'r', 0, NULL,
- "Write the X server configuration to the configuration file, and exit, "
- "without starting the graphical user interface." },
-
- { "verbose", 'V', NVGETOPT_HAS_ARGUMENT|NVGETOPT_ARGUMENT_IS_OPTIONAL, NULL,
- "Controls how much information is printed. Valid values are 'errors' "
- "(print error messages), 'warnings' (print error and warning messages), "
- "and 'all' (print error, warning and other informational messages). By "
- "default, only errors are printed." },
-
- { "assign", 'a', NVGETOPT_HAS_ARGUMENT, print_assign_help, NULL },
-
- { "query", 'q', NVGETOPT_HAS_ARGUMENT, print_query_help, NULL },
-
- { "terse", 't', 0, NULL,
- "When querying attribute values with the '--query' commandline option, "
- "only print the current value, rather than the more verbose description "
- "of the attribute, its valid values, and its current value." },
-
- { "display-device-string", 'd', 0, NULL,
- "When printing attribute values in response to the '--query' option, "
- "if the attribute value is a display device mask, print the value "
- "as a list of display devices (e.g., \"CRT-0, DFP-0\"), rather than "
- "a hexidecimal bitmask (e.g., 0x00010001)." },
-
- { "glxinfo", 'g', 0, NULL,
- "Print GLX Information for the X display and exit." },
-
- { "describe", 'e', NVGETOPT_HAS_ARGUMENT, NULL,
- "Prints information about a particular attribute. Specify 'all' to "
- "list the descriptions of all attributes. Specify 'list' to list the "
- "attribute names without a descriptions." },
-
- { NULL, 0, 0, 0 },
-};
-
-
-
-/*
- * print_assign_help() - print help information for the assign option.
- */
-
-static void print_assign_help(void)
-{
- nv_msg(BIGTAB, "The ASSIGN argument to the '--assign' commandline option "
- "is of the form:");
-
- nv_msg(NULL, "");
-
- nv_msg(BIGTAB TAB, "{DISPLAY}/{attribute name}[{display devices}]"
- "={value}");
-
- nv_msg(NULL, "");
-
- nv_msg(BIGTAB, "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 --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.");
-
- nv_msg(NULL, "");
-
- nv_msg(BIGTAB, "{DISPLAY} can additionally include a target "
- "specification to direct an assignment to something other than "
- "an X screen. A target specification is contained within brackets "
- "and consists of a target type name, a colon, and the "
- "target id. The target type name can be one of \"screen\", "
- "\"gpu\", \"framelock\", \"vcs\", \"gvi\", or \"fan\"; the target "
- "id is the index into the "
- "list of targets (for that target type). The target specification "
- "can be used in {DISPLAY} wherever an X screen can be used, "
- "following the syntax {host}:{display}[{target_type}:"
- "{target_id}]. See the output of `nvidia-settings -q all` for "
- "information on which target types can be used with which "
- "attributes. See the output of `nvidia-settings -q screens "
- "-q gpus -q framelocks -q vcs -q gvis -q fans` for lists of targets "
- "for each target type.");
-
- nv_msg(NULL, "");
-
- nv_msg(BIGTAB, "The [{display devices}] portion is also optional; "
- "if it is not specified, then the attribute is assigned to all "
- "display devices.");
-
- nv_msg(NULL, "");
-
- nv_msg(BIGTAB, "Some examples:");
-
- nv_msg(NULL, "");
-
- nv_msg(BIGTAB TAB, "-a FSAA=5");
- nv_msg(BIGTAB TAB, "-a localhost:0.0/DigitalVibrance[CRT-0]=0");
- nv_msg(BIGTAB TAB, "--assign=\"SyncToVBlank=1\"");
- nv_msg(BIGTAB TAB, "-a [gpu:0]/DigitalVibrance[DFP-1]=63");
-
-} /* print_assign_help() */
-
-
-
-/*
- * print_query_help() - print help information for the query option.
- */
-
-static void print_query_help(void)
-{
- nv_msg(BIGTAB, "The QUERY argument to the '--query' commandline option "
- "is of the form:");
-
- nv_msg(NULL, "");
-
- nv_msg(BIGTAB TAB, "{DISPLAY}/{attribute name}[{display devices}]");
-
- nv_msg(NULL, "");
-
- nv_msg(BIGTAB, "This queries the current value of the attribute "
- "{attribute name} on the X Display {DISPLAY}. The format is "
- "the same as that for the '--assign' option, without "
- "'={value}'. Specify '-q screens', '-q gpus', '-q framelocks', "
- "'-q vcs', '-q gvis', or '-q fans' to query a list of X screens, "
- "GPUs, Frame Lock devices, Visual Computing Systems, SDI Input "
- "Devices, or Fans, respectively, that are present on the X Display "
- "{DISPLAY}. Specify '-q all' to query all attributes.");
-
-} /* print_query_help() */
-
-
-
/*
* print_attribute_help() - print information about the specified attribute.
*/
@@ -362,10 +184,37 @@ void print_help(void)
msg = tmp;
}
nv_msg(TAB, msg);
- if (o->description) nv_msg(BIGTAB, o->description);
- if (o->print_description) (*(o->print_description))();
- nv_msg(NULL, "");
free(msg);
+
+ if (o->description) {
+ char *buf = NULL, *pbuf = NULL, *s = NULL;
+
+ buf = calloc(1, 1 + strlen(o->description));
+ if (!buf) {
+ /* XXX There should be better message than this */
+ nv_error_msg("Not enough memory\n");
+ return;
+ }
+ pbuf = buf;
+
+ for (s = o->description; s && *s; s++) {
+ switch (*s) {
+ case '<':
+ case '>':
+ case '^':
+ break;
+ default:
+ *pbuf = *s;
+ pbuf++;
+ break;
+ }
+ }
+ *pbuf = '\0';
+ nv_msg_preserve_whitespace(BIGTAB, buf);
+ free(buf);
+ }
+
+ nv_msg(NULL, "");
}
} /* print_help() */
@@ -400,7 +249,11 @@ Options *parse_command_line(int argc, char *argv[], char *dpy)
op->ctrl_display = dpy;
while (1) {
- c = nvgetopt(argc, argv, __options, &strval, NULL);
+ c = nvgetopt(argc, argv, __options, &strval,
+ NULL, /* boolval */
+ NULL, /* intval */
+ NULL, /* doubleval */
+ NULL); /* disable_val */
if (c == -1)
break;
diff --git a/src/command-line.h b/src/command-line.h
index c173524..9e062be 100644
--- a/src/command-line.h
+++ b/src/command-line.h
@@ -28,6 +28,8 @@
#include <NvCtrlAttributes.h>
#define DEFAULT_RC_FILE "~/.nvidia-settings-rc"
+#define CONFIG_FILE_OPTION 1
+
#define VERBOSITY_ERROR 0 /* errors only */
#define VERBOSITY_WARNING 1 /* errors and warnings */
diff --git a/src/nvgetopt.c b/src/common-utils/nvgetopt.c
index 14a1d4c..3bea6f8 100644
--- a/src/nvgetopt.c
+++ b/src/common-utils/nvgetopt.c
@@ -1,31 +1,26 @@
/*
- * nvidia-settings: A tool for configuring the NVIDIA X driver on Unix
- * and Linux systems.
- *
- * Copyright (C) 2004 NVIDIA Corporation.
+ * Copyright (C) 2004-2010 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.
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
*
* 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 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
+ * Free Software Foundation, Inc.
+ * 59 Temple Place - Suite 330
+ * Boston, MA 02111-1307, USA
+ *
*
- */
-
-/*
* nvgetopt.c - portable getopt_long() replacement; removes the need
- * for the stupid optstring argument. Also adds support for the
- * "-feature"/"+feature" syntax.
+ * for the stupid optstring argument.
*/
#include <stdio.h>
@@ -35,51 +30,45 @@
#include "nvgetopt.h"
-
-/*
- * nvgetopt() - see the glibc getopt_long(3) manpage for usage
- * description. Options can be prepended with any of "--", "-", or
- * "+".
- *
- * A global variable stores the current index into the argv array, so
- * subsequent calls to nvgetopt() will advance through argv[].
- *
- * On success, the matching NVGetoptOption.val is returned.
- *
- * On failure, an error is printed to stderr, and 0 is returned.
- *
- * When there are no more options to parse, -1 is returned.
- */
-
-int nvgetopt(int argc, char *argv[], const NVGetoptOption *options,
- char **strval, int *boolval)
+int nvgetopt(int argc,
+ char *argv[],
+ const NVGetoptOption *options,
+ char **strval,
+ int *boolval,
+ int *intval,
+ double *doubleval,
+ int *disable_val)
{
char *c, *a, *arg, *name = NULL, *argument=NULL;
- int i, found = NVGETOPT_FALSE, ret = 0, val = NVGETOPT_FALSE;
+ int i, found = NVGETOPT_FALSE;
+ int ret = 0;
+ int negate = NVGETOPT_FALSE;
+ int disable = NVGETOPT_FALSE;
const NVGetoptOption *o = NULL;
static int argv_index = 0;
-
+
+ if (strval) *strval = NULL;
+ if (boolval) *boolval = NVGETOPT_FALSE;
+ if (intval) *intval = 0;
+ if (doubleval) *doubleval = 0.0;
+ if (disable_val) *disable_val = NVGETOPT_FALSE;
+
argv_index++;
/* if no more options, return -1 */
if (argv_index >= argc) return -1;
-
+
/* get the argument in question */
arg = strdup(argv[argv_index]);
-
- /* look for "--", "-", or "+" */
-
+
+ /* look for "--" or "-" */
+
if ((arg[0] == '-') && (arg[1] == '-')) {
name = arg + 2;
- val = NVGETOPT_INVALID;
} else if (arg[0] == '-') {
name = arg + 1;
- val = NVGETOPT_FALSE;
- } else if (arg[0] == '+') {
- name = arg + 1;
- val = NVGETOPT_TRUE;
} else {
fprintf(stderr, "%s: invalid option: \"%s\"\n", argv[0], arg);
goto done;
@@ -96,7 +85,7 @@ int nvgetopt(int argc, char *argv[], const NVGetoptOption *options,
if (*c == '=') { argument = c + 1; *c = '\0'; break; }
c++;
}
-
+
/*
* if the string is terminated after one character, interpret it
* as a short option. Otherwise, interpret it as a long option.
@@ -111,8 +100,30 @@ int nvgetopt(int argc, char *argv[], const NVGetoptOption *options,
}
} else { /* long option */
for (i = 0; options[i].name; i++) {
- if (strcmp(options[i].name, name) == 0) {
+ const char *tmpname;
+ int tmp_negate;
+
+ /*
+ * if this option allows negation by prepending with
+ * "--no-" (true for IS_BOOLEAN and ALLOW_DISABLE), then
+ * skip any leading "no-" in the argument
+ */
+
+ if ((options[i].flags & (NVGETOPT_IS_BOOLEAN |
+ NVGETOPT_ALLOW_DISABLE)) &&
+ (name[0] == 'n') &&
+ (name[1] == 'o') &&
+ (name[2] == '-')) {
+ tmpname = name + 3;
+ tmp_negate = NVGETOPT_TRUE;
+ } else {
+ tmpname = name;
+ tmp_negate = NVGETOPT_FALSE;
+ }
+
+ if (strcmp(tmpname, options[i].name) == 0) {
o = &options[i];
+ negate = tmp_negate;
break;
}
}
@@ -134,7 +145,7 @@ int nvgetopt(int argc, char *argv[], const NVGetoptOption *options,
}
if (!found) break;
}
-
+
if (found) {
/*
@@ -144,40 +155,40 @@ int nvgetopt(int argc, char *argv[], const NVGetoptOption *options,
for (i = 0; options[i].name; i++) {
if (options[i].val == name[0]) {
-
+
/*
* don't allow options with arguments to be
* processed in this way
*/
-
+
if (options[i].flags & NVGETOPT_HAS_ARGUMENT) break;
-
+
/*
* remove the first short option from
* argv[argv_index]
*/
-
+
a = argv[argv_index];
if (a[0] == '-') a++;
if (a[0] == '-') a++;
if (a[0] == '+') a++;
-
+
while(a[0]) { a[0] = a[1]; a++; }
-
+
/*
* decrement argv_index so that we process this
* entry again
*/
-
+
argv_index--;
-
+
o = &options[i];
break;
}
}
}
}
-
+
/* if we didn't find an option, return */
if (!o) {
@@ -185,41 +196,41 @@ int nvgetopt(int argc, char *argv[], const NVGetoptOption *options,
goto done;
}
+
+ /* if the option is boolean, record !negate as the boolean value */
+
if (o->flags & NVGETOPT_IS_BOOLEAN) {
+ if (boolval) *boolval = !negate;
+ }
- /*
- * if this option is boolean, then make sure it wasn't
- * prepended with "--"
- */
- if (val == NVGETOPT_INVALID) {
- fprintf(stderr, "%s: incorrect usage: \"%s\". The option \"%s\" "
- "should be prepended with either one \"-\" (to disable "
- "%s) or one \"+\" (to enable %s)\n",
- argv[0], arg, o->name, o->name, o->name);
- goto done;
- }
+ /*
+ * if this option is flagged as "disable-able", then let the
+ * "--no-" prefix get interpreted to mean that the option should
+ * be disabled
+ */
- /* assign boolval */
-
- if (boolval) *boolval = val;
+ if ((o->flags & NVGETOPT_ALLOW_DISABLE) && (negate == NVGETOPT_TRUE)) {
+ disable = NVGETOPT_TRUE;
}
+
/*
- * if this option takes an argument, then we either need to use
- * what was after the "=" in this argv[] entry, ot we need to pull
- * the next entry off of argv[]
+ * if the option takes an argument (either string or integer), and
+ * we haven't already decided to disable the option, then we
+ * either need to use what was after the "=" in this argv[] entry,
+ * or we need to pull the next entry off of argv[]
*/
- if (o->flags & NVGETOPT_HAS_ARGUMENT) {
+ if ((o->flags & NVGETOPT_HAS_ARGUMENT) && !disable) {
if (argument) {
if (!argument[0]) {
- fprintf(stderr, "%s: option \"%s\" requires an argument.\n",
- argv[0], arg);
+ fprintf(stderr, "%s: option \"%s\" requires an "
+ "argument.\n", argv[0], arg);
goto done;
}
- if (strval) *strval = strdup(argument);
} else {
+
/*
* if the argument is optional, and we're either at the
* end of the argv list, or the next argv starts with '-',
@@ -229,23 +240,76 @@ int nvgetopt(int argc, char *argv[], const NVGetoptOption *options,
if ((o->flags & NVGETOPT_ARGUMENT_IS_OPTIONAL) &&
((argv_index == (argc - 1)) ||
(argv[argv_index + 1][0] == '-'))) {
- if (strval) *strval = NULL;
+ argument = NULL;
+ goto argument_processing_done;
} else {
argv_index++;
if (argv_index >= argc) {
- fprintf(stderr, "%s: option \"%s\" requires an argument.\n",
- argv[0], arg);
+ fprintf(stderr, "%s: option \"%s\" requires an "
+ "argument.\n", argv[0], arg);
goto done;
}
- if (strval) *strval = argv[argv_index];
+ argument = argv[argv_index];
+ }
+ }
+
+ /* argument is now a valid string: parse it */
+
+ if ((o->flags & NVGETOPT_INTEGER_ARGUMENT) && (intval)) {
+
+ /* parse the argument as an integer */
+
+ char *endptr;
+ *intval = (int) strtol(argument, &endptr, 0);
+ if (*endptr) {
+ fprintf(stderr, "%s: \"%s\" is not a valid argument for "
+ "option \"%s\".\n", argv[0], argument, arg);
+ goto done;
+ }
+ } else if ((o->flags & NVGETOPT_STRING_ARGUMENT) && (strval)) {
+
+ /* treat the argument as a string */
+
+ *strval = strdup(argument);
+ } else if ((o->flags & NVGETOPT_DOUBLE_ARGUMENT) && (doubleval)) {
+
+ /* parse the argument as a double */
+
+ char *endptr;
+ *doubleval = (double) strtod(argument, &endptr);
+ if (*endptr) {
+ fprintf(stderr, "%s: \"%s\" is not a valid argument for "
+ "option \"%s\".\n", argv[0], argument, arg);
+ goto done;
}
+ } else {
+ fprintf(stderr, "%s: error while assigning argument for "
+ "option \"%s\".\n", argv[0], arg);
+ goto done;
+ }
+
+ } else {
+
+ /* if we have an argument when we shouldn't; complain */
+
+ if (argument) {
+ fprintf(stderr, "%s: option \"%s\" does not take an argument, but "
+ "was given an argument of \"%s\".\n",
+ argv[0], arg, argument);
+ goto done;
}
}
-
+
+ argument_processing_done:
+
ret = o->val;
+ /* fall through */
+
done:
+ if (disable_val) *disable_val = disable;
+
free(arg);
return ret;
diff --git a/src/common-utils/nvgetopt.h b/src/common-utils/nvgetopt.h
new file mode 100644
index 0000000..7083860
--- /dev/null
+++ b/src/common-utils/nvgetopt.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2004-2010 NVIDIA Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * 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 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
+ *
+ *
+ * nvgetopt.h
+ */
+
+#ifndef __NVGETOPT_H__
+#define __NVGETOPT_H__
+
+#define NVGETOPT_FALSE 0
+#define NVGETOPT_TRUE 1
+
+
+/*
+ * indicates that the option is a boolean value; the presence of the
+ * option will be interpretted as a TRUE value; if the option is
+ * prepended with '--no-', the option will be interpretted as a FALSE
+ * value. On success, nvgetopt will return the parsed boolean value
+ * through 'boolval'.
+ */
+
+#define NVGETOPT_IS_BOOLEAN 0x01
+
+
+/*
+ * indicates that the option takes an argument to be interpreted as a
+ * string; on success, nvgetopt will return the parsed string argument
+ * through 'strval'.
+ */
+
+#define NVGETOPT_STRING_ARGUMENT 0x02
+
+
+/*
+ * indicates that the option takes an argument to be interpreted as an
+ * integer; on success, nvgetopt will return the parsed integer
+ * argument through 'intval'.
+ */
+
+#define NVGETOPT_INTEGER_ARGUMENT 0x04
+
+
+/*
+ * indicates that the option takes an argument to be interpreted as
+ * an double; on success, nvgetopt will return the parsed double
+ * argument through 'doubleval'.
+ */
+
+#define NVGETOPT_DOUBLE_ARGUMENT 0x08
+
+
+/* helper macro */
+
+#define NVGETOPT_HAS_ARGUMENT (NVGETOPT_STRING_ARGUMENT | \
+ NVGETOPT_INTEGER_ARGUMENT | \
+ NVGETOPT_DOUBLE_ARGUMENT)
+
+/*
+ * indicates that the option, which normally takes an argument, can be
+ * disabled if the option is prepended with '--no-', in which case,
+ * the option does not take an argument. If the option is disabled,
+ * nvgetopt will return TRUE through 'disable_val'.
+ *
+ * Note that NVGETOPT_ALLOW_DISABLE can only be used with options that
+ * take arguments.
+ */
+
+#define NVGETOPT_ALLOW_DISABLE 0x10
+
+
+/*
+ * indicates that the argument for this option is optional; if no
+ * argument is present (either the option is already at the end of the
+ * argv array, or the next option in argv starts with '-'), then the
+ * option is returned without an argument.
+ */
+
+#define NVGETOPT_ARGUMENT_IS_OPTIONAL 0x20
+
+
+/*
+ * The NVGETOPT_HELP_ALWAYS flag is not used by nvgetopt() itself, but
+ * is often used by other users of NVGetoptOption tables, who print
+ * out basic and advanced help. In such cases, OPTION_HELP_ALWAYS is
+ * used to indicate that the help for the option should always be
+ * printed.
+ */
+
+#define NVGETOPT_HELP_ALWAYS 0x40
+
+
+typedef struct {
+ const char *name;
+ int val;
+ unsigned int flags;
+ char *arg_name; /* not used by nvgetopt() */
+ char *description; /* not used by nvgetopt() */
+} NVGetoptOption;
+
+
+/*
+ * nvgetopt() - see the glibc getopt_long(3) manpage for usage
+ * description. Options can be prepended with "--", "-", or "--no-".
+ *
+ * A global variable stores the current index into the argv array, so
+ * subsequent calls to nvgetopt() will advance through argv[].
+ *
+ * On success, the matching NVGetoptOption.val is returned.
+ *
+ * If the NVGETOPT_IS_BOOLEAN flag is set, boolval will be set to TRUE
+ * (or FALSE, if the option string was prepended with "--no-").
+ *
+ * disable_val will be assigned TRUE if the option string was
+ * prepended with "--no-", otherwise it will be assigned FALSE.
+ *
+ * If an argument is successfully parsed, one of strval, intval, or
+ * doubleval will be assigned, based on which of
+ * NVGETOPT_STRING_ARGUMENT, NVGETOPT_INTEGER_ARGUMENT, or
+ * NVGETOPT_DOUBLE_ARGUMENT is set in the option's flags. If strval
+ * is assigned to a non-NULL value by nvgetopt, then it is the
+ * caller's responsibility to free the string when done with it.
+ *
+ * On failure, an error is printed to stderr, and 0 is returned.
+ *
+ * When there are no more options to parse, -1 is returned.
+ */
+
+int nvgetopt(int argc,
+ char *argv[],
+ const NVGetoptOption *options,
+ char **strval,
+ int *boolval,
+ int *intval,
+ double *doubleval,
+ int *disable_val);
+
+
+#endif /* __NVGETOPT_H__ */
diff --git a/src/common-utils/src.mk b/src/common-utils/src.mk
new file mode 100644
index 0000000..b93479e
--- /dev/null
+++ b/src/common-utils/src.mk
@@ -0,0 +1,7 @@
+# makefile fragment included by nvidia-xconfig, nvidia-settings, and nvidia-installer
+
+COMMON_UTILS_SRC += nvgetopt.c
+
+COMMON_UTILS_EXTRA_DIST += nvgetopt.h
+COMMON_UTILS_EXTRA_DIST += src.mk
+
diff --git a/src/gen-manpage-opts.c b/src/gen-manpage-opts.c
new file mode 100644
index 0000000..2bcd766
--- /dev/null
+++ b/src/gen-manpage-opts.c
@@ -0,0 +1,147 @@
+/*
+ * nvidia-settings: A tool for configuring the NVIDIA X driver on Unix
+ * and Linux systems.
+ *
+ * Copyright (C) 2010 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 <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "nvgetopt.h"
+#include "option-table.h"
+
+#define NV_FMT_BUF_LEN 512
+
+/*
+ * Prints the option help in a form that is suitable to include in the manpage.
+ */
+
+static void print_option(const NVGetoptOption *o)
+{
+ int omitWhiteSpace;
+
+ /* if we are going to need the argument, process it now */
+
+ printf(".TP\n.BI \"");
+ /* Print the name of the option */
+ /* XXX We should backslashify the '-' characters in o->name. */
+
+ if (isalpha(o->val)) {
+ /* '\-c \-\-name' */
+ printf("\\-%c, \\-\\-%s", o->val, o->name);
+ } else {
+ printf("\\-\\-%s", o->name);
+ }
+
+ /* '=" "ARG' */
+ if (o->flags & NVGETOPT_HAS_ARGUMENT) {
+ int len, j;
+ char tbuf[32];
+ len = strlen(o->name);
+ for (j = 0; j < len; j++)
+ tbuf[j] = toupper(o->name[j]);
+ tbuf[len] = '\0';
+ printf("=\" \"%s", tbuf);
+ }
+
+ printf("\"\n");
+
+ /* Print the option description */
+ /* XXX Each sentence should be on its own line! */
+
+ /*
+ * Print the option description: write each character one at a
+ * time (ugh) so that we can special-case a few characters:
+ *
+ * "^" --> "\n.I "
+ * "<" --> "\n.B "
+ * ">" --> "\n"
+ *
+ * '^' is used to mark the text as underlined till it is turned off with '>'.
+ * '<' is used to mark the text as bold till it is turned off with '>'.
+ *
+ * XXX Each sentence should be on its own line!
+ */
+
+ if (o->description) {
+ char *buf = NULL, *s = NULL, *pbuf = NULL;
+
+ buf = calloc(1, NV_FMT_BUF_LEN + strlen(o->description));
+ if (!buf) {
+ /* XXX There should be better message than this */
+ printf("Not enough memory\n");
+ return;
+ }
+ pbuf = buf;
+
+ omitWhiteSpace = 0;
+ for (s = o->description; s && *s; s++) {
+ switch (*s) {
+ case '<':
+ sprintf(pbuf, "\n.B ");
+ pbuf = pbuf + 4;
+ omitWhiteSpace = 0;
+ break;
+ case '^':
+ sprintf(pbuf, "\n.I ");
+ pbuf = pbuf + 4;
+ omitWhiteSpace = 0;
+ break;
+ case '>':
+ *pbuf = '\n';
+ pbuf++;
+ omitWhiteSpace = 1;
+ break;
+ case ' ':
+ if (!omitWhiteSpace) {
+ *pbuf = *s;
+ pbuf++;
+ }
+ break;
+ default:
+ *pbuf = *s;
+ pbuf++;
+ omitWhiteSpace = 0;
+ break;
+ }
+ }
+ printf("%s", buf);
+ free(buf);
+ }
+
+ printf("\n");
+}
+
+int main(int argc, char* argv[])
+{
+ int i;
+ const NVGetoptOption *o;
+
+ printf(".SH OPTIONS\n");
+ for (i = 0; __options[i].name; i++) {
+ o = &__options[i];
+ print_option(o);
+ }
+
+ return 0;
+}
diff --git a/src/gtk+-2.x/ctkclocks.c b/src/gtk+-2.x/ctkclocks.c
index e09b413..1a5ed78 100644
--- a/src/gtk+-2.x/ctkclocks.c
+++ b/src/gtk+-2.x/ctkclocks.c
@@ -101,9 +101,9 @@ static const char * __clock_menu_help =
"Selects which clock frequencies to modify. Standard (2D) only affects 2D "
"applications. Performance (3D) only affects 3D applications.";
-static const char * __gpu_clock_help =
-"The GPU Clock Frequency is the core clock speed that the NVIDIA GPU will be "
-"set to when the graphics card is operating in this mode (2D/3D).";
+static const char * __graphics_clock_help =
+"The Graphics Clock Frequency is the core clock speed that the NVIDIA "
+"GPU will be set to when the graphics card is operating in this mode (2D/3D).";
static const char * __mem_clock_help =
"The Memory Clock Frequency is the clock speed of the memory interface on "
@@ -324,7 +324,7 @@ GtkWidget* ctk_clocks_new(NvCtrlAttributeHandle *handle,
gtk_widget_set_sensitive(ctk_object->clock_menu,
overclocking_enabled && !probing_optimal);
- /* Create the GPU clock frequency slider widget */
+ /* Create the Graphics clock frequency slider widget */
if ( can_access_2d_clocks ) {
adjustment =
@@ -352,7 +352,7 @@ GtkWidget* ctk_clocks_new(NvCtrlAttributeHandle *handle,
ctk_config_set_tooltip(ctk_config,
CTK_SCALE(ctk_object->gpu_clk_scale)->gtk_scale,
- __gpu_clock_help);
+ __graphics_clock_help);
gtk_widget_set_sensitive(ctk_object->gpu_clk_scale,
overclocking_enabled && !probing_optimal);
@@ -619,8 +619,8 @@ GtkTextBuffer *ctk_clocks_create_help(GtkTextTagTable *table,
"The 3D clock frequencies are the performance clock "
"frequencies used when running 3D applications."
);
- ctk_help_heading(b, &i, "GPU Clock Frequency");
- ctk_help_para(b, &i, __gpu_clock_help);
+ ctk_help_heading(b, &i, "Graphics Clock Frequency");
+ ctk_help_para(b, &i, __graphics_clock_help);
ctk_help_heading(b, &i, "Memory Clock Frequency");
ctk_help_para(b, &i, __mem_clock_help);
ctk_help_heading(b, &i, "Applying Custom Clock Frequencies");
@@ -679,7 +679,7 @@ static void sync_gui_sensitivity(CtkClocks *ctk_object)
gtk_widget_set_sensitive(ctk_object->clock_menu, enabled && !probing);
- /* Update the GPU clock slider */
+ /* Update the Graphics clock slider */
gtk_widget_set_sensitive(ctk_object->gpu_clk_scale, enabled && !probing);
diff --git a/src/gtk+-2.x/ctkcolorcontrols.c b/src/gtk+-2.x/ctkcolorcontrols.c
new file mode 100644
index 0000000..6a2c23a
--- /dev/null
+++ b/src/gtk+-2.x/ctkcolorcontrols.c
@@ -0,0 +1,580 @@
+/*
+ * nvidia-settings: A tool for configuring the NVIDIA X driver on Unix
+ * and Linux systems.
+ *
+ * Copyright (C) 2010 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 <gtk/gtk.h>
+#include <NvCtrlAttributes.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <errno.h>
+
+#include "ctkconfig.h"
+#include "ctkhelp.h"
+#include "ctkcolorcontrols.h"
+
+/* function prototypes */
+static gboolean build_color_space_table(CtkColorControls *ctk_color_controls,
+ NVCTRLAttributeValidValuesRec valid);
+
+static gint map_nvctrl_value_to_table(CtkColorControls *ctk_color_controls,
+ gint val);
+
+static Bool update_color_space_menu_info(gpointer user_data);
+
+static void color_space_menu_changed(GtkOptionMenu *color_space_menu,
+ gpointer user_data);
+static void color_range_menu_changed(GtkOptionMenu *color_range_menu,
+ gpointer user_data);
+
+static void color_control_update_received(GtkObject *object, gpointer arg1,
+ gpointer user_data);
+
+static
+void post_color_range_update(CtkColorControls *ctk_color_controls,
+ gint color_range);
+
+static
+void post_color_space_update(CtkColorControls *ctk_color_controls,
+ gint color_space);
+
+/* macros */
+#define FRAME_PADDING 5
+
+/* help text */
+static const char * __color_controls_help =
+"The Color Controls allow changing the color space and color range "
+"of the display device. The possible values for Color Space vary "
+"depending on the capabilities of the display device and the GPU, but "
+"may contain \"RGB\", \"YCbCr422\", and \"YCbCr444\". The possible values "
+"for Color Range are \"Limited\" and \"Full\".";
+
+GType ctk_color_controls_get_type(void)
+{
+ static GType ctk_color_controls_type = 0;
+
+ if (!ctk_color_controls_type) {
+ static const GTypeInfo ctk_color_controls_info = {
+ sizeof (CtkColorControlsClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ NULL, /* class_init, */
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (CtkColorControls),
+ 0, /* n_preallocs */
+ NULL, /* instance_init */
+ };
+
+ ctk_color_controls_type =
+ g_type_register_static (GTK_TYPE_VBOX,
+ "CtkColorControls",
+ &ctk_color_controls_info, 0);
+ }
+
+ return ctk_color_controls_type;
+} /* ctk_color_controls_get_type() */
+
+GtkWidget* ctk_color_controls_new(NvCtrlAttributeHandle *handle,
+ CtkConfig *ctk_config,
+ CtkEvent *ctk_event,
+ GtkWidget *reset_button,
+ unsigned int display_device_mask,
+ char *name)
+{
+ GObject *object;
+ CtkColorControls *ctk_color_controls;
+ GtkWidget *frame, *hbox, *label, *eventbox;
+ GtkWidget *menu, *table, *menu_item = NULL, *separator;
+ ReturnStatus ret1, ret2;
+ NVCTRLAttributeValidValuesRec valid1, valid2;
+ gint i;
+
+ /* check if color configuration is supported */
+ ret1 = NvCtrlGetValidDisplayAttributeValues(handle, display_device_mask,
+ NV_CTRL_COLOR_SPACE,
+ &valid1);
+ ret2 = NvCtrlGetValidDisplayAttributeValues(handle, display_device_mask,
+ NV_CTRL_COLOR_RANGE,
+ &valid2);
+
+ if ((ret1 != NvCtrlSuccess) || (ret2 != NvCtrlSuccess)) {
+ return NULL;
+ }
+
+ /* create the object */
+ object = g_object_new(CTK_TYPE_COLOR_CONTROLS, NULL);
+ if (!object) {
+ return NULL;
+ }
+
+ ctk_color_controls = CTK_COLOR_CONTROLS(object);
+ ctk_color_controls->handle = handle;
+ ctk_color_controls->ctk_config = ctk_config;
+ ctk_color_controls->reset_button = reset_button;
+ ctk_color_controls->display_device_mask = display_device_mask;
+ ctk_color_controls->name = strdup(name);
+
+ /* build a table holding available color space */
+ if (!build_color_space_table(ctk_color_controls, valid1)) {
+ return NULL;
+ }
+
+ /* create main color box & frame */
+
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(object), hbox, FALSE, FALSE, FRAME_PADDING);
+ ctk_color_controls->color_controls_main = hbox;
+
+ frame = gtk_frame_new("Color Controls");
+ eventbox = gtk_event_box_new();
+ gtk_container_add(GTK_CONTAINER(eventbox), frame);
+ gtk_box_pack_start(GTK_BOX(hbox), eventbox, FALSE, FALSE, 0);
+ ctk_config_set_tooltip(ctk_config, eventbox, __color_controls_help);
+
+ table = gtk_table_new(1, 6, FALSE);
+ gtk_container_add(GTK_CONTAINER(frame), table);
+ gtk_table_set_row_spacings(GTK_TABLE(table), 5);
+ gtk_table_set_col_spacings(GTK_TABLE(table), 15);
+ gtk_container_set_border_width(GTK_CONTAINER(table), 5);
+
+ /* dropdown list for color space */
+ menu = gtk_menu_new();
+
+ for (i = 0; i < ctk_color_controls->color_space_table_size; i++) {
+ switch (ctk_color_controls->color_space_table[i]) {
+ case NV_CTRL_COLOR_SPACE_YCbCr422:
+ menu_item = gtk_menu_item_new_with_label("YCbCr422");
+ break;
+ case NV_CTRL_COLOR_SPACE_YCbCr444:
+ menu_item = gtk_menu_item_new_with_label("YCbCr444");
+ break;
+ default:
+ case NV_CTRL_COLOR_SPACE_RGB:
+ menu_item = gtk_menu_item_new_with_label("RGB");
+ break;
+ }
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
+ gtk_widget_show(menu_item);
+ }
+
+ ctk_color_controls->color_space_menu = gtk_option_menu_new();
+ gtk_option_menu_set_menu
+ (GTK_OPTION_MENU(ctk_color_controls->color_space_menu),
+ menu);
+
+ g_signal_connect(G_OBJECT(ctk_color_controls->color_space_menu),
+ "changed", G_CALLBACK(color_space_menu_changed),
+ (gpointer) ctk_color_controls);
+
+
+ /* pack the label & drop down */
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 0, 1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ label = gtk_label_new("Color Space: ");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+ hbox = gtk_hbox_new(FALSE, 0);
+ ctk_color_controls->color_space_box = hbox;
+ gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 0, 1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ gtk_box_pack_start(GTK_BOX(hbox),
+ ctk_color_controls->color_space_menu,
+ FALSE, FALSE, 0);
+
+ /* V-bar */
+ hbox = gtk_hbox_new(FALSE, 0);
+ separator = gtk_vseparator_new();
+ gtk_box_pack_start(GTK_BOX(hbox), separator, FALSE, FALSE, 0);
+ gtk_table_attach(GTK_TABLE(table), hbox, 2, 3, 0, 1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+
+ /* Build color widgets & pack them in table */
+ /* dropdown list for color range */
+ menu = gtk_menu_new();
+
+ menu_item = gtk_menu_item_new_with_label("Full");
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
+ gtk_widget_show(menu_item);
+
+ menu_item = gtk_menu_item_new_with_label("Limited");
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
+ gtk_widget_show(menu_item);
+
+ ctk_color_controls->color_range_menu = gtk_option_menu_new();
+ gtk_option_menu_set_menu
+ (GTK_OPTION_MENU(ctk_color_controls->color_range_menu),
+ menu);
+
+ g_signal_connect(G_OBJECT(ctk_color_controls->color_range_menu),
+ "changed", G_CALLBACK(color_range_menu_changed),
+ (gpointer) ctk_color_controls);
+
+ /* Packing label & dropdown */
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_table_attach(GTK_TABLE(table), hbox, 3, 4, 0, 1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+
+ label = gtk_label_new("Color Range: ");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_table_attach(GTK_TABLE(table), hbox, 4, 5, 0, 1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ gtk_box_pack_start(GTK_BOX(hbox),
+ ctk_color_controls->color_range_menu,
+ FALSE, FALSE, 0);
+
+ gtk_widget_show_all(GTK_WIDGET(object));
+
+ ctk_color_controls_setup(ctk_color_controls);
+
+ g_signal_connect(G_OBJECT(ctk_event),
+ CTK_EVENT_NAME(NV_CTRL_COLOR_RANGE),
+ G_CALLBACK(color_control_update_received),
+ (gpointer) ctk_color_controls);
+ g_signal_connect(G_OBJECT(ctk_event),
+ CTK_EVENT_NAME(NV_CTRL_COLOR_SPACE),
+ G_CALLBACK(color_control_update_received),
+ (gpointer) ctk_color_controls);
+
+ return GTK_WIDGET(object);
+
+} /* ctk_color_controls_new() */
+
+
+/*
+ * ctk_color_controls_setup() - Setup routine for color attributes. Used
+ * in DFP setup stage as well as for updating the GUI when there is change in
+ * color range or color space.
+ */
+void ctk_color_controls_setup(CtkColorControls *ctk_color_controls)
+{
+ gint val;
+
+ if (!ctk_color_controls) {
+ return;
+ }
+
+ /* color range */
+ if (NvCtrlSuccess !=
+ NvCtrlGetDisplayAttribute(ctk_color_controls->handle,
+ ctk_color_controls->display_device_mask,
+ NV_CTRL_COLOR_RANGE, &val)) {
+ val = NV_CTRL_COLOR_RANGE_FULL;
+ }
+
+ g_signal_handlers_block_by_func
+ (G_OBJECT(ctk_color_controls->color_range_menu),
+ G_CALLBACK(color_range_menu_changed),
+ (gpointer) ctk_color_controls);
+
+ gtk_option_menu_set_history
+ (GTK_OPTION_MENU(ctk_color_controls->color_range_menu),
+ val);
+
+ g_signal_handlers_unblock_by_func
+ (G_OBJECT(ctk_color_controls->color_range_menu),
+ G_CALLBACK(color_range_menu_changed),
+ (gpointer) ctk_color_controls);
+
+ /* color space */
+ if (!update_color_space_menu_info
+ ((gpointer)ctk_color_controls)) {
+ gtk_widget_set_sensitive(ctk_color_controls->color_controls_main,
+ FALSE);
+ gtk_widget_hide_all(ctk_color_controls->color_controls_main);
+ }
+
+} /* ctk_color_controls_setup() */
+
+
+static Bool update_color_space_menu_info(gpointer user_data)
+{
+ CtkColorControls *ctk_color_controls =
+ CTK_COLOR_CONTROLS(user_data);
+ gint color_space = NV_CTRL_COLOR_SPACE_RGB;
+
+ /* color space */
+ if (NvCtrlSuccess !=
+ NvCtrlGetDisplayAttribute(ctk_color_controls->handle,
+ ctk_color_controls->display_device_mask,
+ NV_CTRL_COLOR_SPACE,
+ &color_space)) {
+ free(ctk_color_controls->color_space_table);
+ return FALSE;
+ }
+
+ color_space = map_nvctrl_value_to_table(ctk_color_controls,
+ color_space);
+
+ g_signal_handlers_block_by_func
+ (G_OBJECT(ctk_color_controls->color_space_menu),
+ G_CALLBACK(color_space_menu_changed),
+ (gpointer) ctk_color_controls);
+
+ gtk_option_menu_set_history
+ (GTK_OPTION_MENU(ctk_color_controls->color_space_menu),
+ color_space);
+
+ g_signal_handlers_unblock_by_func
+ (G_OBJECT(ctk_color_controls->color_space_menu),
+ G_CALLBACK(color_space_menu_changed),
+ (gpointer) ctk_color_controls);
+
+ return True;
+} /* update_color_space_menu_info() */
+
+static
+void post_color_range_update(CtkColorControls *ctk_color_controls,
+ gint color_range)
+{
+ static const char *color_range_table[] = {
+ "Full", /* NV_CTRL_COLOR_RANGE_FULL */
+ "Limited" /* NV_CTRL_COLOR_RANGE_LIMITED */
+ };
+
+ ctk_config_statusbar_message(ctk_color_controls->ctk_config,
+ "Color Range set to %s for %s.",
+ color_range_table[color_range],
+ ctk_color_controls->name);
+}
+
+static
+void post_color_space_update(CtkColorControls *ctk_color_controls,
+ gint color_space)
+{
+ static const char *color_space_table[] = {
+ "RGB", /* NV_CTRL_COLOR_SPACE_RGB */
+ "YCbCr422", /* NV_CTRL_COLOR_SPACE_YCbCr422 */
+ "YCbCr444" /* NV_CTRL_COLOR_SPACE_YCbCr444 */
+ };
+
+ ctk_config_statusbar_message(ctk_color_controls->ctk_config,
+ "Color Space set to %s for %s.",
+ color_space_table[color_space],
+ ctk_color_controls->name);
+}
+
+static void color_range_menu_changed(GtkOptionMenu *color_range_menu,
+ gpointer user_data)
+{
+ CtkColorControls *ctk_color_controls =
+ CTK_COLOR_CONTROLS(user_data);
+ gint history, color_range = NV_CTRL_COLOR_RANGE_FULL;
+
+ history = gtk_option_menu_get_history(color_range_menu);
+
+ switch (history) {
+ case 1:
+ color_range = NV_CTRL_COLOR_RANGE_LIMITED;
+ break;
+ default:
+ case 0:
+ color_range = NV_CTRL_COLOR_RANGE_FULL;
+ break;
+ }
+
+ NvCtrlSetDisplayAttribute(ctk_color_controls->handle,
+ ctk_color_controls->display_device_mask,
+ NV_CTRL_COLOR_RANGE,
+ color_range);
+
+ g_signal_handlers_block_by_func
+ (G_OBJECT(ctk_color_controls->color_range_menu),
+ G_CALLBACK(color_range_menu_changed),
+ (gpointer) ctk_color_controls);
+
+ gtk_option_menu_set_history
+ (GTK_OPTION_MENU(ctk_color_controls->color_range_menu),
+ color_range);
+
+ g_signal_handlers_unblock_by_func
+ (G_OBJECT(ctk_color_controls->color_range_menu),
+ G_CALLBACK(color_range_menu_changed),
+ (gpointer) ctk_color_controls);
+
+ /* reflecting the change in color range to other widgets & reset button */
+ ctk_color_controls_setup(ctk_color_controls);
+ post_color_range_update(ctk_color_controls, color_range);
+ gtk_widget_set_sensitive(ctk_color_controls->reset_button, TRUE);
+
+} /* color_range_menu_changed() */
+
+
+static void color_space_menu_changed(GtkOptionMenu *color_space_menu,
+ gpointer user_data)
+{
+ CtkColorControls *ctk_color_controls =
+ CTK_COLOR_CONTROLS(user_data);
+ gint history, color_space = NV_CTRL_COLOR_SPACE_RGB;
+
+ history = gtk_option_menu_get_history(color_space_menu);
+
+ color_space = ctk_color_controls->color_space_table[history];
+
+ NvCtrlSetDisplayAttribute(ctk_color_controls->handle,
+ ctk_color_controls->display_device_mask,
+ NV_CTRL_COLOR_SPACE,
+ color_space);
+
+ color_space = map_nvctrl_value_to_table(ctk_color_controls,
+ color_space);
+ g_signal_handlers_block_by_func
+ (G_OBJECT(ctk_color_controls->color_space_menu),
+ G_CALLBACK(color_space_menu_changed),
+ (gpointer) ctk_color_controls);
+
+ gtk_option_menu_set_history
+ (GTK_OPTION_MENU(ctk_color_controls->color_space_menu),
+ color_space);
+
+ g_signal_handlers_unblock_by_func
+ (G_OBJECT(ctk_color_controls->color_space_menu),
+ G_CALLBACK(color_space_menu_changed),
+ (gpointer) ctk_color_controls);
+
+ /* reflecting the change in color space to other widgets & reset button */
+ ctk_color_controls_setup(ctk_color_controls);
+ post_color_space_update(ctk_color_controls, color_space);
+ gtk_widget_set_sensitive(ctk_color_controls->reset_button, TRUE);
+
+} /* color_space_menu_changed() */
+
+
+/*
+ * ctk_color_controls_reset() - Resets the color range and
+ * & color space when Reset HW Defaults is clicked
+ */
+void ctk_color_controls_reset(CtkColorControls *ctk_color_controls)
+{
+ if (!ctk_color_controls) {
+ return;
+ }
+
+ NvCtrlSetDisplayAttribute(ctk_color_controls->handle,
+ ctk_color_controls->display_device_mask,
+ NV_CTRL_COLOR_SPACE,
+ NV_CTRL_COLOR_SPACE_RGB);
+
+ NvCtrlSetDisplayAttribute(ctk_color_controls->handle,
+ ctk_color_controls->display_device_mask,
+ NV_CTRL_COLOR_RANGE,
+ NV_CTRL_COLOR_RANGE_FULL);
+
+ ctk_color_controls_setup(ctk_color_controls);
+} /* ctk_color_controls_reset() */
+
+
+/*
+ * add_color_controls_help() -
+ */
+void add_color_controls_help(CtkColorControls *ctk_color_controls,
+ GtkTextBuffer *b,
+ GtkTextIter *i)
+{
+ ctk_help_heading(b, i, "Color Controls");
+ ctk_help_para(b, i, __color_controls_help);
+} /* add_color_controls_help() */
+
+
+/*
+ * When other client updated color controls
+ * we should update the GUI to reflect the current color range
+ * and color space.
+ */
+static void color_control_update_received(GtkObject *object, gpointer arg1,
+ gpointer user_data)
+{
+ CtkColorControls *ctk_object = CTK_COLOR_CONTROLS(user_data);
+ CtkEventStruct *event_struct = (CtkEventStruct *) arg1;
+
+ /* if the event is not for this display device, return */
+
+ if (!(event_struct->display_mask & ctk_object->display_device_mask)) {
+ return;
+ }
+
+ ctk_color_controls_setup(ctk_object);
+} /* color_control_update_received() */
+
+
+/*
+ * build_color_space_table() - build a table of color space, showing
+ * modes supported by the DFP.
+ */
+static gboolean build_color_space_table(CtkColorControls *ctk_color_controls,
+ NVCTRLAttributeValidValuesRec valid)
+{
+ gint i, n = 0, color_space_count = 0;
+ gint mask = valid.u.bits.ints;
+
+ if (valid.type != ATTRIBUTE_TYPE_INT_BITS) {
+ return False;
+ }
+
+ /* count no. of supported color space */
+ while(mask) {
+ mask = mask & (mask - 1);
+ color_space_count++;
+ }
+
+ ctk_color_controls->color_space_table_size = color_space_count;
+ ctk_color_controls->color_space_table =
+ calloc(color_space_count, sizeof(ctk_color_controls->color_space_table[0]));
+ if (!ctk_color_controls->color_space_table) {
+ return False;
+ }
+
+ for (i = 0, n = 0; n < ctk_color_controls->color_space_table_size; i++) {
+ if (valid.u.bits.ints & (1 << i)) {
+ ctk_color_controls->color_space_table[n] = i;
+ n++;
+ }
+ }
+
+ return True;
+
+} /* build_color_space_table() */
+
+
+static gint map_nvctrl_value_to_table(CtkColorControls *ctk_color_controls,
+ gint val)
+{
+ int i;
+ for (i = 0; i < ctk_color_controls->color_space_table_size; i++) {
+ if (val == ctk_color_controls->color_space_table[i]) {
+ return i;
+ }
+ }
+
+ return 0;
+} /*map_nvctrl_value_to_table() */
diff --git a/src/gtk+-2.x/ctkcolorcontrols.h b/src/gtk+-2.x/ctkcolorcontrols.h
new file mode 100644
index 0000000..5faa6ab
--- /dev/null
+++ b/src/gtk+-2.x/ctkcolorcontrols.h
@@ -0,0 +1,97 @@
+/*
+ * nvidia-settings: A tool for configuring the NVIDIA X driver on Unix
+ * and Linux systems.
+ *
+ * Copyright (C) 2010 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_COLOR_CONTROLS_H__
+#define __CTK_COLOR_CONTROLS_H__
+
+#include "ctkevent.h"
+#include "ctkconfig.h"
+
+G_BEGIN_DECLS
+
+#define CTK_TYPE_COLOR_CONTROLS (ctk_color_controls_get_type())
+
+#define CTK_COLOR_CONTROLS(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), CTK_TYPE_COLOR_CONTROLS, \
+ CtkColorControls))
+
+#define CTK_COLOR_CONTROLS_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), CTK_TYPE_COLOR_CONTROLS, \
+ CtkColorControlsClass))
+
+#define CTK_IS_COLOR_CONTROLS(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CTK_TYPE_COLOR_CONTROLS))
+
+#define CTK_IS_COLOR_CONTROLS_CLASS(class) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), CTK_TYPE_COLOR_CONTROLS))
+
+#define CTK_COLOR_CONTROLS_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), CTK_TYPE_COLOR_CONTROLS, \
+ CtkCOLORControlsClass))
+
+typedef struct _CtkColorControls CtkColorControls;
+typedef struct _CtkColorControlsClass CtkColorControlsClass;
+
+struct _CtkColorControls
+{
+ GtkVBox parent;
+
+ NvCtrlAttributeHandle *handle;
+ CtkConfig *ctk_config;
+ GtkWidget *reset_button;
+ GtkWidget *color_controls_main;
+ GtkWidget *color_space_box;
+
+ GtkWidget *color_range_menu;
+ GtkWidget *color_space_menu;
+ GtkWidget *color_current_config;
+
+ gint display_device_mask;
+ gint *color_space_table;
+ gint color_space_table_size;
+ gint default_color_config;
+ gint default_color_space;
+ char *name;
+};
+
+struct _CtkColorControlsClass
+{
+ GtkVBoxClass parent_class;
+};
+
+GType ctk_color_controls_get_type (void) G_GNUC_CONST;
+GtkWidget* ctk_color_controls_new (NvCtrlAttributeHandle *,
+ CtkConfig *, CtkEvent *,
+ GtkWidget *,
+ unsigned int display_device_mask,
+ char *);
+
+void ctk_color_controls_reset (CtkColorControls*);
+void ctk_color_controls_setup (CtkColorControls*);
+void add_color_controls_help (CtkColorControls*, GtkTextBuffer *b,
+ GtkTextIter *i);
+
+G_END_DECLS
+
+#endif /* __CTK_COLOR_CONTROLS_H__ */
diff --git a/src/gtk+-2.x/ctkcolorcorrection.c b/src/gtk+-2.x/ctkcolorcorrection.c
index 169190e..464905d 100644
--- a/src/gtk+-2.x/ctkcolorcorrection.c
+++ b/src/gtk+-2.x/ctkcolorcorrection.c
@@ -84,7 +84,7 @@ static gfloat
get_attribute_channel_value (CtkColorCorrection *, gint, gint);
static void
-flush_attribute_channel_values (CtkColorCorrection *, gint, gint, gfloat);
+flush_attribute_channel_values (CtkColorCorrection *, gint, gint);
static void
ctk_color_correction_class_init(CtkColorCorrectionClass *);
@@ -109,6 +109,8 @@ static guint signals[LAST_SIGNAL] = { 0 };
#define GREEN GREEN_CHANNEL_INDEX
#define BLUE BLUE_CHANNEL_INDEX
+#define ALL_CHANNELS_INDEX 3
+
#define CONTRAST (CONTRAST_INDEX - CONTRAST_INDEX)
#define BRIGHTNESS (BRIGHTNESS_INDEX - CONTRAST_INDEX)
#define GAMMA (GAMMA_INDEX - CONTRAST_INDEX)
@@ -536,6 +538,15 @@ static void option_menu_changed(
break;
}
+ /*
+ * store the currently selected color channel, so that
+ * adjustment_value_changed() can update the correct channel(s) in
+ * response to slider changes
+ */
+
+ g_object_set_data(G_OBJECT(option_menu), "color_channel",
+ GINT_TO_POINTER(channel));
+
for (i = 0; i < 3; i++) {
if (i == 0) {
@@ -549,9 +560,6 @@ static void option_menu_changed(
attribute = GAMMA_VALUE;
}
- g_object_set_data(G_OBJECT(option_menu), "color_channel",
- GINT_TO_POINTER(channel));
-
value = get_attribute_channel_value(ctk_color_correction,
attribute, channel);
@@ -566,9 +574,6 @@ static void option_menu_changed(
(G_OBJECT(adjustment),
G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
G_CALLBACK(adjustment_value_changed), NULL);
-
- if (channel == ALL_CHANNELS)
- gtk_adjustment_value_changed(GTK_ADJUSTMENT(adjustment));
}
}
@@ -583,27 +588,43 @@ static void set_button_sensitive(
/** set_color_state() *******************
*
- * Stores color state to cur_val[attribute][channel]
- * and prev_val[attribute][channel].
+ * Stores color state to cur_slider_val[attribute][channel]
+ * and prev_slider_val[attribute][channel].
*
**/
static void set_color_state(CtkColorCorrection *ctk_color_correction,
- gint attribute_idx, gint channel_idx,
+ gint attribute_idx, gint channel_mask,
gfloat value, gboolean all
)
{
- if ( channel_idx != ALL_CHANNELS ) {
- ctk_color_correction->cur_val
- [attribute_idx][channel_idx] = value;
- if ( all ) {
- ctk_color_correction->prev_val
- [attribute_idx][channel_idx] = value;
+ if (channel_mask & RED_CHANNEL) {
+ ctk_color_correction->cur_slider_val[attribute_idx][RED] = value;
+ if (all) {
+ ctk_color_correction->prev_slider_val[attribute_idx][RED] = value;
}
- } else {
- gint ch;
- for ( ch = RED; ch <= BLUE; ch++ ) {
- set_color_state(ctk_color_correction, attribute_idx, ch, value, all);
+ }
+
+ if (channel_mask & GREEN_CHANNEL) {
+ ctk_color_correction->cur_slider_val[attribute_idx][GREEN] = value;
+ if (all) {
+ ctk_color_correction->prev_slider_val[attribute_idx][GREEN] = value;
+ }
+ }
+
+ if (channel_mask & BLUE_CHANNEL) {
+ ctk_color_correction->cur_slider_val[attribute_idx][BLUE] = value;
+ if (all) {
+ ctk_color_correction->prev_slider_val[attribute_idx][BLUE] = value;
+ }
+ }
+
+ if (channel_mask == ALL_CHANNELS) {
+ ctk_color_correction->cur_slider_val
+ [attribute_idx][ALL_CHANNELS_INDEX] = value;
+ if (all) {
+ ctk_color_correction->prev_slider_val
+ [attribute_idx][ALL_CHANNELS_INDEX] = value;
}
}
} /* set_color_state() */
@@ -624,9 +645,11 @@ static void confirm_button_clicked(
{
CtkColorCorrection *ctk_color_correction = CTK_COLOR_CORRECTION(user_data);
- /* Store cur_val[attribute][channel] to prev_val[attribute][channel]. */
- memcpy (ctk_color_correction->prev_val, ctk_color_correction->cur_val,
- sizeof(ctk_color_correction->cur_val));
+ /* Store cur_slider_val[attribute][channel] to
+ prev_slider_val[attribute][channel]. */
+ memcpy (ctk_color_correction->prev_slider_val,
+ ctk_color_correction->cur_slider_val,
+ sizeof(ctk_color_correction->cur_slider_val));
/* kill the timer */
g_source_remove(ctk_color_correction->confirm_timer);
@@ -657,12 +680,9 @@ static void reset_button_clicked(
set_color_state(ctk_color_correction, GAMMA, ALL_CHANNELS,
GAMMA_DEFAULT, TRUE);
- NvCtrlSetColorAttributes(ctk_color_correction->handle,
- ctk_color_correction->cur_val[CONTRAST],
- ctk_color_correction->cur_val[BRIGHTNESS],
- ctk_color_correction->cur_val[GAMMA],
- ALL_VALUES | ALL_CHANNELS);
-
+ flush_attribute_channel_values(ctk_color_correction,
+ ALL_VALUES, ALL_CHANNELS);
+
option_menu = GTK_OPTION_MENU(ctk_color_correction->option_menu);
if (gtk_option_menu_get_history(option_menu) == 0) {
@@ -699,7 +719,7 @@ static void adjustment_value_changed(
{
CtkColorCorrection *ctk_color_correction;
gint attribute, channel;
- gint attribute_idx, channel_idx;
+ gint attribute_idx;
gfloat value;
gchar *channel_str, *attribute_str;
@@ -745,30 +765,25 @@ static void adjustment_value_changed(
switch (channel) {
case RED_CHANNEL:
- channel_idx = RED;
channel_str = "red ";
break;
case GREEN_CHANNEL:
- channel_idx = GREEN;
channel_str = "green ";
break;
case BLUE_CHANNEL:
- channel_idx = BLUE;
channel_str = "blue ";
break;
case ALL_CHANNELS:
- channel_idx = ALL_CHANNELS;
channel_str = "";
break;
default:
return;
}
- set_color_state(ctk_color_correction, attribute_idx, channel_idx,
+ set_color_state(ctk_color_correction, attribute_idx, channel,
value, FALSE);
- flush_attribute_channel_values(ctk_color_correction,
- attribute, channel, value);
+ flush_attribute_channel_values(ctk_color_correction, attribute, channel);
ctk_config_statusbar_message(ctk_color_correction->ctk_config,
"Set %s%s to %f.",
@@ -781,51 +796,54 @@ static gfloat get_attribute_channel_value(CtkColorCorrection
*ctk_color_correction,
gint attribute, gint channel)
{
- gfloat values[3] = { 0.0, 0.0, 0.0 };
- gfloat ignore[3] = { 0.0, 0.0, 0.0 };
-
- NvCtrlAttributeHandle *handle = ctk_color_correction->handle;
+ int attribute_idx, channel_idx;
switch (attribute) {
case CONTRAST_VALUE:
- NvCtrlGetColorAttributes(handle, values, ignore, ignore);
+ attribute_idx = CONTRAST;
break;
case BRIGHTNESS_VALUE:
- NvCtrlGetColorAttributes(handle, ignore, values, ignore);
+ attribute_idx = BRIGHTNESS;
break;
case GAMMA_VALUE:
- NvCtrlGetColorAttributes(handle, ignore, ignore, values);
+ attribute_idx = GAMMA;
break;
default:
return 0.0;
}
switch (channel) {
- case ALL_CHANNELS: /* XXX what to do for all channels? */
+ case ALL_CHANNELS:
+ channel_idx = ALL_CHANNELS_INDEX;
+ break;
case RED_CHANNEL:
- return values[0];
+ channel_idx = RED_CHANNEL_INDEX;
+ break;
case GREEN_CHANNEL:
- return values[1];
+ channel_idx = GREEN_CHANNEL_INDEX;
+ break;
case BLUE_CHANNEL:
- return values[2];
+ channel_idx = BLUE_CHANNEL_INDEX;
+ break;
default:
- return 0;
+ return 0.0;
}
+
+ return ctk_color_correction->cur_slider_val[attribute_idx][channel_idx];
}
static void flush_attribute_channel_values(
CtkColorCorrection *ctk_color_correction,
gint attribute,
- gint channel,
- gfloat value
+ gint channel
)
{
NvCtrlAttributeHandle *handle = ctk_color_correction->handle;
NvCtrlSetColorAttributes(handle,
- ctk_color_correction->cur_val[CONTRAST],
- ctk_color_correction->cur_val[BRIGHTNESS],
- ctk_color_correction->cur_val[GAMMA],
+ ctk_color_correction->cur_slider_val[CONTRAST],
+ ctk_color_correction->cur_slider_val[BRIGHTNESS],
+ ctk_color_correction->cur_slider_val[GAMMA],
attribute | channel);
g_signal_emit(ctk_color_correction, signals[CHANGED], 0);
@@ -867,39 +885,39 @@ static void apply_parsed_attribute_list(
switch (p->attr & (ALL_VALUES | ALL_CHANNELS)) {
case (CONTRAST_VALUE | RED_CHANNEL):
set_color_state(ctk_color_correction, CONTRAST,
- RED, p->fval, TRUE); break;
+ RED_CHANNEL, p->fval, TRUE); break;
case (CONTRAST_VALUE | GREEN_CHANNEL):
set_color_state(ctk_color_correction, CONTRAST,
- GREEN, p->fval, TRUE); break;
+ GREEN_CHANNEL, p->fval, TRUE); break;
case (CONTRAST_VALUE | BLUE_CHANNEL):
set_color_state(ctk_color_correction, CONTRAST,
- BLUE, p->fval, TRUE); break;
+ BLUE_CHANNEL, p->fval, TRUE); break;
case (CONTRAST_VALUE | ALL_CHANNELS):
set_color_state(ctk_color_correction, CONTRAST,
ALL_CHANNELS, p->fval, TRUE); break;
case (BRIGHTNESS_VALUE | RED_CHANNEL):
set_color_state(ctk_color_correction, BRIGHTNESS,
- RED, p->fval, TRUE); break;
+ RED_CHANNEL, p->fval, TRUE); break;
case (BRIGHTNESS_VALUE | GREEN_CHANNEL):
set_color_state(ctk_color_correction, BRIGHTNESS,
- GREEN, p->fval, TRUE); break;
+ GREEN_CHANNEL, p->fval, TRUE); break;
case (BRIGHTNESS_VALUE | BLUE_CHANNEL):
set_color_state(ctk_color_correction, BRIGHTNESS,
- BLUE, p->fval, TRUE); break;
+ BLUE_CHANNEL, p->fval, TRUE); break;
case (BRIGHTNESS_VALUE | ALL_CHANNELS):
set_color_state(ctk_color_correction, BRIGHTNESS,
ALL_CHANNELS, p->fval, TRUE); break;
case (GAMMA_VALUE | RED_CHANNEL):
set_color_state(ctk_color_correction, GAMMA,
- RED, p->fval, TRUE); break;
+ RED_CHANNEL, p->fval, TRUE); break;
case (GAMMA_VALUE | GREEN_CHANNEL):
set_color_state(ctk_color_correction, GAMMA,
- GREEN, p->fval, TRUE); break;
+ GREEN_CHANNEL, p->fval, TRUE); break;
case (GAMMA_VALUE | BLUE_CHANNEL):
set_color_state(ctk_color_correction, GAMMA,
- BLUE, p->fval, TRUE); break;
+ BLUE_CHANNEL, p->fval, TRUE); break;
case (GAMMA_VALUE | ALL_CHANNELS):
set_color_state(ctk_color_correction, GAMMA,
ALL_CHANNELS, p->fval, TRUE); break;
@@ -917,9 +935,9 @@ static void apply_parsed_attribute_list(
if (attr) {
NvCtrlSetColorAttributes(ctk_color_correction->handle,
- ctk_color_correction->cur_val[CONTRAST],
- ctk_color_correction->cur_val[BRIGHTNESS],
- ctk_color_correction->cur_val[GAMMA],
+ ctk_color_correction->cur_slider_val[CONTRAST],
+ ctk_color_correction->cur_slider_val[BRIGHTNESS],
+ ctk_color_correction->cur_slider_val[GAMMA],
attr);
}
@@ -952,7 +970,8 @@ static gboolean do_confirm_countdown(gpointer data)
{
gint attr, ch;
CtkColorCorrection *ctk_color_correction = (CtkColorCorrection *)(data);
- unsigned int active_attributes_channels = 0;
+ unsigned int channels = 0;
+ unsigned int attributes = 0;
GtkOptionMenu *option_menu =
GTK_OPTION_MENU(ctk_color_correction->option_menu);
@@ -964,23 +983,21 @@ static gboolean do_confirm_countdown(gpointer data)
/* Countdown timed out, reset color settings to previous state */
for (attr = CONTRAST_INDEX; attr <= GAMMA_INDEX; attr++) {
- for (ch = RED; ch <= BLUE; ch++) {
+ for (ch = RED; ch <= ALL_CHANNELS_INDEX; ch++) {
/* Check for attribute channel value change. */
- if (ctk_color_correction->cur_val[attr - CONTRAST_INDEX][ch] !=
- ctk_color_correction->prev_val[attr - CONTRAST_INDEX][ch]) {
- ctk_color_correction->cur_val[attr - CONTRAST_INDEX][ch] =
- ctk_color_correction->prev_val[attr - CONTRAST_INDEX][ch];
- active_attributes_channels |= (1 << attr) | (1 << ch);
+ int index = attr - CONTRAST_INDEX;
+ if (ctk_color_correction->cur_slider_val[index][ch] !=
+ ctk_color_correction->prev_slider_val[index][ch]) {
+ ctk_color_correction->cur_slider_val[index][ch] =
+ ctk_color_correction->prev_slider_val[index][ch];
+ attributes |= (1 << attr);
+ channels |= (1 << ch);
}
}
}
- if (active_attributes_channels) {
- NvCtrlSetColorAttributes(ctk_color_correction->handle,
- ctk_color_correction->cur_val[CONTRAST],
- ctk_color_correction->cur_val[BRIGHTNESS],
- ctk_color_correction->cur_val[GAMMA],
- active_attributes_channels);
- g_signal_emit(ctk_color_correction, signals[CHANGED], 0);
+ if (attributes | channels) {
+ flush_attribute_channel_values(ctk_color_correction,
+ attributes, channels);
}
/* Refresh color correction page for current selected channel. */
diff --git a/src/gtk+-2.x/ctkcolorcorrection.h b/src/gtk+-2.x/ctkcolorcorrection.h
index 746a787..28ea926 100644
--- a/src/gtk+-2.x/ctkcolorcorrection.h
+++ b/src/gtk+-2.x/ctkcolorcorrection.h
@@ -67,8 +67,8 @@ struct _CtkColorCorrection
GtkWidget *confirm_button;
gint confirm_countdown;
guint confirm_timer;
- gfloat cur_val[3][3]; // as [attribute][channel]
- gfloat prev_val[3][3]; // as [attribute][channel]
+ gfloat cur_slider_val[3][4]; // as [attribute][channel]
+ gfloat prev_slider_val[3][4]; // as [attribute][channel]
guint enabled_display_devices;
};
diff --git a/src/gtk+-2.x/ctkdisplayconfig.c b/src/gtk+-2.x/ctkdisplayconfig.c
index f8c5250..f9bd9f0 100644
--- a/src/gtk+-2.x/ctkdisplayconfig.c
+++ b/src/gtk+-2.x/ctkdisplayconfig.c
@@ -495,6 +495,43 @@ static void consolidate_xinerama(CtkDisplayConfig *ctk_object,
+/** update_btn_apply() **************************************************
+ *
+ * Updates the apply button's sensitvity (if possible)
+ *
+ **/
+
+void update_btn_apply(CtkDisplayConfig *ctk_object, Bool sensitive)
+{
+ Bool xrandr_available = FALSE;
+ nvGpuPtr gpu;
+ nvScreenPtr screen;
+
+
+ if (sensitive) {
+ /* If XRandR is disabled (for all screens), we can't apply */
+ for (gpu = ctk_object->layout->gpus; gpu; gpu = gpu->next) {
+
+ for (screen = gpu->screens; screen; screen = screen->next) {
+ if (NvCtrlGetXrandrEventBase(screen->handle) >= 0) {
+ xrandr_available = TRUE;
+ break;
+ }
+ }
+ if (xrandr_available) break;
+ }
+
+ if (!xrandr_available) {
+ sensitive = FALSE;
+ }
+ }
+
+ gtk_widget_set_sensitive(ctk_object->btn_apply, sensitive);
+
+} /* update_btn_apply() */
+
+
+
/** xconfigPrint() ******************************************************
*
* xconfigPrint() - this is the one entry point that a user of the
@@ -1013,7 +1050,7 @@ GtkWidget * create_validation_apply_dialog(CtkDisplayConfig *ctk_object)
static void user_changed_attributes(CtkDisplayConfig *ctk_object)
{
if (ctk_object->forced_reset_allowed) {
- gtk_widget_set_sensitive(ctk_object->btn_apply, True);
+ update_btn_apply(ctk_object, TRUE);
ctk_object->forced_reset_allowed = FALSE;
}
@@ -1185,11 +1222,7 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
ctk_object->obj_layout = ctk_display_layout_new(handle, ctk_config,
ctk_object->layout,
300, /* min width */
- 225, /* min height */
- layout_selected_callback,
- (void *)ctk_object,
- layout_modified_callback,
- (void *)ctk_object);
+ 225); /* min height */
/* Make sure all X screens have the same depth if Xinerama is enabled */
consolidate_xinerama(ctk_object, NULL);
@@ -1518,7 +1551,7 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
/* Apply button */
ctk_object->btn_apply = gtk_button_new_with_label("Apply");
- gtk_widget_set_sensitive(ctk_object->btn_apply, False);
+ update_btn_apply(ctk_object, FALSE);
ctk_config_set_tooltip(ctk_config, ctk_object->btn_apply,
__apply_button_help);
g_signal_connect(G_OBJECT(ctk_object->btn_apply), "clicked",
@@ -1873,6 +1906,12 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
setup_display_page(ctk_object);
setup_screen_page(ctk_object);
+ /* Register to receive updates when layout changed */
+ ctk_display_layout_register_callbacks(CTK_DISPLAY_LAYOUT(ctk_object->obj_layout),
+ layout_selected_callback,
+ (void *)ctk_object,
+ layout_modified_callback,
+ (void *)ctk_object);
return GTK_WIDGET(ctk_object);
@@ -1978,12 +2017,14 @@ GtkTextBuffer *ctk_display_config_create_help(GtkTextTagTable *table,
ctk_help_para(b, &i, "");
ctk_help_heading(b, &i, "Buttons");
ctk_help_heading(b, &i, "Apply");
- ctk_help_para(b, &i, "%s Note that not all settings can be applied to an "
- "active X server; these require restarting the X server "
- "after saving the desired settings to the X configuration "
- "file. Examples of such settings include changing the "
- "position of any X screen, adding/removing an X screen, and "
- "changing the X screen color depth.", __apply_button_help);
+ ctk_help_para(b, &i, "%s Note that XRandR must be available to apply "
+ "settings. Also note that even when XRandR is available, "
+ "not all settings can be applied to an active X server; "
+ "these require restarting the X server after saving the "
+ "desired settings to the X configuration file. Examples "
+ "of such settings include changing the position of any X "
+ "screen, adding/removing an X screen, and changing the X "
+ "screen color depth.", __apply_button_help);
ctk_help_heading(b, &i, "Detect Displays");
ctk_help_para(b, &i, __detect_displays_button_help);
ctk_help_heading(b, &i, "Advanced/Basic...");
@@ -5980,7 +6021,7 @@ static Bool switch_to_current_metamode(CtkDisplayConfig *ctk_object,
/* XRandR must be available to do mode switching */
- if (!NvCtrlGetXrandrEventBase(screen->handle)) {
+ if (NvCtrlGetXrandrEventBase(screen->handle) < 0) {
dlg = gtk_message_dialog_new
(GTK_WINDOW(parent),
GTK_DIALOG_DESTROY_WITH_PARENT,
@@ -7609,7 +7650,7 @@ static void reset_layout(CtkDisplayConfig *ctk_object)
/* Clear the apply button */
ctk_object->apply_possible = TRUE;
- gtk_widget_set_sensitive(ctk_object->btn_apply, FALSE);
+ update_btn_apply(ctk_object, FALSE);
ctk_object->forced_reset_allowed = TRUE; /* OK to reset w/o user input */
ctk_object->notify_user_of_reset = TRUE; /* Notify user of new changes */
@@ -7733,7 +7774,7 @@ static gboolean force_layout_reset(gpointer user_data)
* until they have reloaded the layout manually.
*/
ctk_object->notify_user_of_reset = FALSE;
- gtk_widget_set_sensitive(ctk_object->btn_apply, False);
+ update_btn_apply(ctk_object, FALSE);
break;
}
gtk_widget_destroy(dlg);
diff --git a/src/gtk+-2.x/ctkdisplaydevice-dfp.c b/src/gtk+-2.x/ctkdisplaydevice-dfp.c
index 887fbd1..b9c7747 100644
--- a/src/gtk+-2.x/ctkdisplaydevice-dfp.c
+++ b/src/gtk+-2.x/ctkdisplaydevice-dfp.c
@@ -29,6 +29,8 @@
#include "ctkdisplaydevice-dfp.h"
+#include "ctkditheringcontrols.h"
+#include "ctkcolorcontrols.h"
#include "ctkimagesliders.h"
#include "ctkedid.h"
#include "ctkconfig.h"
@@ -459,6 +461,32 @@ GtkWidget* ctk_display_device_dfp_new(NvCtrlAttributeHandle *handle,
G_CALLBACK(dfp_update_received),
(gpointer) ctk_display_device_dfp);
+ /* pack the color controls */
+
+ ctk_display_device_dfp->color_controls =
+ ctk_color_controls_new(handle, ctk_config, ctk_event,
+ ctk_display_device_dfp->reset_button,
+ display_device_mask, name);
+
+ if (ctk_display_device_dfp->color_controls) {
+ gtk_box_pack_start(GTK_BOX(object),
+ ctk_display_device_dfp->color_controls,
+ FALSE, FALSE, 0);
+ }
+
+ /* pack the dithering controls */
+
+ ctk_display_device_dfp->dithering_controls =
+ ctk_dithering_controls_new(handle, ctk_config, ctk_event,
+ ctk_display_device_dfp->reset_button,
+ display_device_mask, name);
+
+ if (ctk_display_device_dfp->dithering_controls) {
+ gtk_box_pack_start(GTK_BOX(object),
+ ctk_display_device_dfp->dithering_controls,
+ FALSE, FALSE, 0);
+ }
+
/* pack the image sliders */
ctk_display_device_dfp->image_sliders =
@@ -705,7 +733,19 @@ static void reset_button_clicked(GtkButton *button, gpointer user_data)
dfp_scaling_setup(ctk_display_device_dfp);
}
-
+
+ /* Reset the color configuration */
+ if (ctk_display_device_dfp->color_controls) {
+ ctk_color_controls_reset
+ (CTK_COLOR_CONTROLS(ctk_display_device_dfp->color_controls));
+ }
+
+ /* Reset the dithering configuration */
+ if (ctk_display_device_dfp->dithering_controls) {
+ ctk_dithering_controls_reset
+ (CTK_DITHERING_CONTROLS(ctk_display_device_dfp->dithering_controls));
+ }
+
/* Update the reset button */
gtk_widget_set_sensitive(ctk_display_device_dfp->reset_button, FALSE);
@@ -907,6 +947,16 @@ GtkTextBuffer *ctk_display_device_dfp_create_help(GtkTextTagTable *table,
"aspect ratio) to expand and fit as much of the entire "
"flat panel as possible.");
+ if (ctk_display_device_dfp->color_controls) {
+ add_color_controls_help
+ (CTK_COLOR_CONTROLS(ctk_display_device_dfp->color_controls), b, &i);
+ }
+
+ if (ctk_display_device_dfp->dithering_controls) {
+ add_dithering_controls_help
+ (CTK_DITHERING_CONTROLS(ctk_display_device_dfp->dithering_controls), b, &i);
+ }
+
add_image_sliders_help
(CTK_IMAGE_SLIDERS(ctk_display_device_dfp->image_sliders), b, &i);
@@ -1242,6 +1292,15 @@ static void ctk_display_device_dfp_setup(CtkDisplayDeviceDfp
ctk_display_device_dfp->edid, TRUE, TRUE, 0);
}
+ /* Update the color control setup */
+
+ ctk_color_controls_setup
+ (CTK_COLOR_CONTROLS(ctk_display_device_dfp->color_controls));
+
+ /* Update the dithering setup */
+
+ ctk_dithering_controls_setup
+ (CTK_DITHERING_CONTROLS(ctk_display_device_dfp->dithering_controls));
/* update the reset button */
diff --git a/src/gtk+-2.x/ctkdisplaydevice-dfp.h b/src/gtk+-2.x/ctkdisplaydevice-dfp.h
index bd9b1ee..f247412 100644
--- a/src/gtk+-2.x/ctkdisplaydevice-dfp.h
+++ b/src/gtk+-2.x/ctkdisplaydevice-dfp.h
@@ -65,6 +65,8 @@ struct _CtkDisplayDeviceDfp
GtkWidget *reset_button;
GtkWidget *edid_box;
GtkWidget *edid;
+ GtkWidget *dithering_controls;
+ GtkWidget *color_controls;
GtkWidget *txt_chip_location;
GtkWidget *txt_link;
diff --git a/src/gtk+-2.x/ctkdisplaylayout.c b/src/gtk+-2.x/ctkdisplaylayout.c
index 3a119f3..d43737a 100644
--- a/src/gtk+-2.x/ctkdisplaylayout.c
+++ b/src/gtk+-2.x/ctkdisplaylayout.c
@@ -682,7 +682,8 @@ static int resolve_display(nvDisplayPtr display, int mode_idx,
*
**/
-static void resolve_displays_in_screen(nvScreenPtr screen, int all_modes)
+static void resolve_displays_in_screen(nvScreenPtr screen,
+ int resolve_all_modes)
{
nvDisplayPtr display;
int pos[4];
@@ -690,7 +691,7 @@ static void resolve_displays_in_screen(nvScreenPtr screen, int all_modes)
int last_idx;
int mode_idx;
- if (all_modes) {
+ if (resolve_all_modes) {
first_idx = 0;
last_idx = screen->num_metamodes -1;
} else {
@@ -1191,17 +1192,17 @@ static void recenter_layout(nvLayoutPtr layout)
*
**/
-void reposition_screen(nvScreenPtr screen, int advanced)
+static void reposition_screen(nvScreenPtr screen, int resolve_all_modes)
{
int orig_screen_x = screen->dim[X];
int orig_screen_y = screen->dim[Y];
-
+
/* Resolve new relative positions. In basic mode,
* relative position changes apply to all modes of a
* display so we should resolve all modes (since they
* were all changed.)
*/
- resolve_displays_in_screen(screen, !advanced);
+ resolve_displays_in_screen(screen, resolve_all_modes);
/* Reestablish the screen's original position */
screen->dim[X] = orig_screen_x;
@@ -1856,7 +1857,7 @@ static int move_selected(CtkDisplayLayout *ctk_object, int x, int y, int snap)
}
/* Make sure the screen position does not change */
- reposition_screen(info->screen, ctk_object->advanced_mode);
+ reposition_screen(info->screen, !ctk_object->advanced_mode);
/* Always update the modify dim for relative positioning */
info->modify_dirty = 1;
}
@@ -2819,11 +2820,7 @@ GtkWidget* ctk_display_layout_new(NvCtrlAttributeHandle *handle,
CtkConfig *ctk_config,
nvLayoutPtr layout,
int width,
- int height,
- ctk_display_layout_selected_callback selected_callback,
- void *selected_callback_data,
- ctk_display_layout_modified_callback modified_callback,
- void *modified_callback_data)
+ int height)
{
GObject *object;
CtkDisplayLayout *ctk_object;
@@ -2839,13 +2836,13 @@ GtkWidget* ctk_display_layout_new(NvCtrlAttributeHandle *handle,
/* Create the ctk object */
object = g_object_new(CTK_TYPE_DISPLAY_LAYOUT, NULL);
ctk_object = CTK_DISPLAY_LAYOUT(object);
+ ctk_object->selected_callback = NULL;
+ ctk_object->selected_callback_data = NULL;
+ ctk_object->modified_callback = NULL;
+ ctk_object->modified_callback_data = NULL;
/* Setup widget properties */
ctk_object->ctk_config = ctk_config;
- ctk_object->selected_callback = selected_callback;
- ctk_object->selected_callback_data = selected_callback_data;
- ctk_object->modified_callback = modified_callback;
- ctk_object->modified_callback_data = modified_callback_data;
ctk_object->handle = handle;
ctk_object->layout = layout;
@@ -3900,10 +3897,12 @@ void ctk_display_layout_set_mode_modeline(CtkDisplayLayout *ctk_object,
mode->pan[H] = mode->display->modelines->data.vdisplay;
}
- /* The metamode that this mode belongs to should now be
- * considered a user metamode.
+ /* In advanced mode, changing the resolution a display uses for a
+ * particular metamode should make this metamode non-implicit.
*/
- if (mode->metamode) {
+ if (ctk_object->advanced_mode &&
+ (old_modeline != modeline) &&
+ mode->metamode) {
mode->metamode->source = METAMODE_SOURCE_NVCONTROL;
}
@@ -3931,6 +3930,7 @@ void ctk_display_layout_set_display_position(CtkDisplayLayout *ctk_object,
GdkGC *fg_gc = get_widget_fg_gc(drawing_area);
GdkGCValues old_gc_values;
int modified = 0;
+ int resolve_all_modes = !ctk_object->advanced_mode;
if (!display) return;
@@ -3953,25 +3953,36 @@ void ctk_display_layout_set_display_position(CtkDisplayLayout *ctk_object,
*/
if (position_type != CONF_ADJ_ABSOLUTE) {
-
+
nvDisplayPtr other;
+ nvModePtr mode;
for (other = display->gpu->displays; other; other = other->next) {
if (other->screen != display->screen) continue;
- if (!other->cur_mode) continue;
+ if (!resolve_all_modes) {
+ mode = other->cur_mode;
+ if (mode && mode->relative_to == display) {
+ mode->position_type = CONF_ADJ_ABSOLUTE;
+ mode->relative_to = NULL;
+ }
- if (other->cur_mode->relative_to == display) {
- other->cur_mode->position_type = CONF_ADJ_ABSOLUTE;
- other->cur_mode->relative_to = NULL;
+ } else {
+
+ for (mode = other->modes; mode; mode = mode->next) {
+ if (mode->relative_to == display) {
+ mode->position_type = CONF_ADJ_ABSOLUTE;
+ mode->relative_to = NULL;
+ }
+ }
}
}
}
/* Set the new positioning type */
- if (ctk_object->advanced_mode) {
+ if (!resolve_all_modes) {
display->cur_mode->position_type = position_type;
display->cur_mode->relative_to = relative_to;
@@ -4006,7 +4017,7 @@ void ctk_display_layout_set_display_position(CtkDisplayLayout *ctk_object,
default:
/* Make sure the screen position does not change */
- reposition_screen(display->screen, ctk_object->advanced_mode);
+ reposition_screen(display->screen, resolve_all_modes);
/* Recalculate the layout */
ctk_display_layout_update(ctk_object);
@@ -4361,6 +4372,28 @@ void ctk_display_layout_set_advanced_mode(CtkDisplayLayout *ctk_object,
+/** ctk_display_layout_register_callbacks() **************************
+ *
+ * Sets up callbacks so users of the display layout can recieve
+ * notifications.
+ *
+ **/
+
+void ctk_display_layout_register_callbacks(CtkDisplayLayout *ctk_object,
+ ctk_display_layout_selected_callback selected_callback,
+ void *selected_callback_data,
+ ctk_display_layout_modified_callback modified_callback,
+ void *modified_callback_data)
+{
+ ctk_object->selected_callback = selected_callback;
+ ctk_object->selected_callback_data = selected_callback_data;
+ ctk_object->modified_callback = modified_callback;
+ ctk_object->modified_callback_data = modified_callback_data;
+
+} /* ctk_display_layout_register_callbacks() */
+
+
+
/** expose_event_callback() ******************************************
*
* Handles expose events.
diff --git a/src/gtk+-2.x/ctkdisplaylayout.h b/src/gtk+-2.x/ctkdisplaylayout.h
index 63b44c9..784094a 100644
--- a/src/gtk+-2.x/ctkdisplaylayout.h
+++ b/src/gtk+-2.x/ctkdisplaylayout.h
@@ -463,11 +463,7 @@ GtkWidget* ctk_display_layout_new (NvCtrlAttributeHandle *,
CtkConfig *,
nvLayoutPtr, /* Layout to display */
int, /* Width of image */
- int, /* Height of image */
- ctk_display_layout_selected_callback,
- void *selected_callback_data,
- ctk_display_layout_modified_callback,
- void *modified_callback_data
+ int /* Height of image */
);
void ctk_display_layout_update (CtkDisplayLayout *);
@@ -526,6 +522,11 @@ void ctk_display_layout_disable_display (CtkDisplayLayout *ctk_object,
void ctk_display_layout_set_advanced_mode (CtkDisplayLayout *ctk_object,
int advanced_mode);
+void ctk_display_layout_register_callbacks(CtkDisplayLayout *ctk_object,
+ ctk_display_layout_selected_callback,
+ void *selected_callback_data,
+ ctk_display_layout_modified_callback,
+ void *modified_callback_data);
G_END_DECLS
diff --git a/src/gtk+-2.x/ctkditheringcontrols.c b/src/gtk+-2.x/ctkditheringcontrols.c
new file mode 100644
index 0000000..6b1de92
--- /dev/null
+++ b/src/gtk+-2.x/ctkditheringcontrols.c
@@ -0,0 +1,683 @@
+/*
+ * nvidia-settings: A tool for configuring the NVIDIA X driver on Unix
+ * and Linux systems.
+ *
+ * Copyright (C) 2010 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 <gtk/gtk.h>
+#include <NvCtrlAttributes.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <errno.h>
+
+#include "ctkconfig.h"
+#include "ctkhelp.h"
+#include "ctkditheringcontrols.h"
+
+/* function prototypes */
+static gboolean build_dithering_mode_table(CtkDitheringControls *ctk_dithering_controls,
+ NVCTRLAttributeValidValuesRec valid);
+
+static gint map_nvctrl_value_to_table(CtkDitheringControls *ctk_dithering_controls,
+ gint val);
+
+static Bool update_dithering_mode_menu_info(gpointer user_data);
+
+static void dithering_mode_menu_changed(GtkOptionMenu *dithering_mode_menu,
+ gpointer user_data);
+static void dithering_config_menu_changed(GtkOptionMenu *dithering_config_menu,
+ gpointer user_data);
+
+static void dithering_update_received(GtkObject *object, gpointer arg1,
+ gpointer user_data);
+
+static
+void post_dithering_config_update(CtkDitheringControls *ctk_dithering_controls,
+ gint dithering_config);
+
+static
+void post_dithering_mode_update(CtkDitheringControls *ctk_dithering_controls,
+ gint dithering_mode);
+
+/* macros */
+#define FRAME_PADDING 5
+
+/* help text */
+static const char * __dithering_help =
+"The Dithering Controls show the current state of dithering and allow "
+"changing the dithering configuration and/or mode. Dithering will be "
+"performed when dithering is enabled here, and the panel's bitdepth is "
+"less than that of the GPU's internal pixel pipeline.";
+
+GType ctk_dithering_controls_get_type(void)
+{
+ static GType ctk_dithering_controls_type = 0;
+
+ if (!ctk_dithering_controls_type) {
+ static const GTypeInfo ctk_dithering_controls_info = {
+ sizeof (CtkDitheringControlsClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ NULL, /* class_init, */
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (CtkDitheringControls),
+ 0, /* n_preallocs */
+ NULL, /* instance_init */
+ };
+
+ ctk_dithering_controls_type =
+ g_type_register_static (GTK_TYPE_VBOX,
+ "CtkDitheringControls",
+ &ctk_dithering_controls_info, 0);
+ }
+
+ return ctk_dithering_controls_type;
+} /* ctk_dithering_controls_get_type() */
+
+GtkWidget* ctk_dithering_controls_new(NvCtrlAttributeHandle *handle,
+ CtkConfig *ctk_config,
+ CtkEvent *ctk_event,
+ GtkWidget *reset_button,
+ unsigned int display_device_mask,
+ char *name)
+{
+ GObject *object;
+ CtkDitheringControls *ctk_dithering_controls;
+ GtkWidget *frame, *vbox, *hbox, *label, *eventbox;
+ GtkWidget *menu, *table, *menu_item = NULL, *separator;
+ ReturnStatus ret1, ret2;
+ NVCTRLAttributeValidValuesRec valid1, valid2;
+ gint i;
+
+ /* check if dithering configuration is supported */
+ ret1 = NvCtrlGetValidDisplayAttributeValues(handle, display_device_mask,
+ NV_CTRL_DITHERING,
+ &valid1);
+ ret2 = NvCtrlGetValidDisplayAttributeValues(handle, display_device_mask,
+ NV_CTRL_DITHERING_MODE,
+ &valid2);
+
+ if ((ret1 != NvCtrlSuccess) || (ret2 != NvCtrlSuccess) ||
+ (valid1.type != ATTRIBUTE_TYPE_INTEGER) ||
+ (valid2.type != ATTRIBUTE_TYPE_INT_BITS)) {
+ return NULL;
+ }
+
+ /* create the object */
+ object = g_object_new(CTK_TYPE_DITHERING_CONTROLS, NULL);
+ if (!object) {
+ return NULL;
+ }
+
+ ctk_dithering_controls = CTK_DITHERING_CONTROLS(object);
+ ctk_dithering_controls->handle = handle;
+ ctk_dithering_controls->ctk_config = ctk_config;
+ ctk_dithering_controls->reset_button = reset_button;
+ ctk_dithering_controls->display_device_mask = display_device_mask;
+ ctk_dithering_controls->name = strdup(name);
+
+ /* build a table holding available dithering modes */
+ if (!build_dithering_mode_table(ctk_dithering_controls, valid2)) {
+ return NULL;
+ }
+
+ /* create main dithering box & frame */
+
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(object), hbox, FALSE, FALSE, FRAME_PADDING);
+ ctk_dithering_controls->dithering_controls_main = hbox;
+
+ frame = gtk_frame_new("Dithering Controls");
+ eventbox = gtk_event_box_new();
+ gtk_container_add(GTK_CONTAINER(eventbox), frame);
+ gtk_box_pack_start(GTK_BOX(hbox), eventbox, FALSE, FALSE, 0);
+ ctk_config_set_tooltip(ctk_config, eventbox, __dithering_help);
+
+ table = gtk_table_new(3, 4, FALSE);
+ gtk_container_add(GTK_CONTAINER(frame), table);
+ gtk_table_set_row_spacings(GTK_TABLE(table), 5);
+ gtk_table_set_col_spacings(GTK_TABLE(table), 15);
+ gtk_container_set_border_width(GTK_CONTAINER(table), 5);
+
+ /* Build Dithering widgets & pack them in table */
+ /* dropdown list for dithering configuration */
+ menu = gtk_menu_new();
+
+ menu_item = gtk_menu_item_new_with_label("Auto");
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
+ gtk_widget_show(menu_item);
+
+ menu_item = gtk_menu_item_new_with_label("Enabled");
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
+ gtk_widget_show(menu_item);
+
+ menu_item = gtk_menu_item_new_with_label("Disabled");
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
+ gtk_widget_show(menu_item);
+
+ ctk_dithering_controls->dithering_config_menu = gtk_option_menu_new();
+ gtk_option_menu_set_menu
+ (GTK_OPTION_MENU(ctk_dithering_controls->dithering_config_menu),
+ menu);
+
+ g_signal_connect(G_OBJECT(ctk_dithering_controls->dithering_config_menu),
+ "changed", G_CALLBACK(dithering_config_menu_changed),
+ (gpointer) ctk_dithering_controls);
+
+ /* Packing label & dropdown */
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 0, 1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+
+ label = gtk_label_new("Dithering: ");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 0, 1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ gtk_box_pack_start(GTK_BOX(hbox),
+ ctk_dithering_controls->dithering_config_menu,
+ FALSE, FALSE, 0);
+
+ /* Build CurrentDithering widget */
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_table_attach(GTK_TABLE(table), hbox, 2, 3, 0, 1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ label = gtk_label_new("Current Dithering: ");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_table_attach(GTK_TABLE(table), hbox, 3, 4, 0, 1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ label = gtk_label_new(NULL);
+ ctk_dithering_controls->dithering_current_config = label;
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+ /* H-bar */
+ vbox = gtk_vbox_new(FALSE, 0);
+ separator = gtk_hseparator_new();
+ gtk_box_pack_start(GTK_BOX(vbox), separator, FALSE, FALSE, 0);
+ gtk_table_attach(GTK_TABLE(table), vbox, 0, 4, 1, 2,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+
+ /* dropdown list for dithering modes */
+ menu = gtk_menu_new();
+
+ for (i = 0; i < ctk_dithering_controls->dithering_mode_table_size; i++) {
+ switch (ctk_dithering_controls->dithering_mode_table[i]) {
+ case NV_CTRL_DITHERING_MODE_DYNAMIC_2X2:
+ menu_item = gtk_menu_item_new_with_label("Dynamic 2X2");
+ break;
+ case NV_CTRL_DITHERING_MODE_STATIC_2X2:
+ menu_item = gtk_menu_item_new_with_label("Static 2X2");
+ break;
+ default:
+ case NV_CTRL_DITHERING_MODE_AUTO:
+ menu_item = gtk_menu_item_new_with_label("Auto");
+ break;
+ }
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
+ gtk_widget_show(menu_item);
+ }
+
+ ctk_dithering_controls->dithering_mode_menu = gtk_option_menu_new();
+ gtk_option_menu_set_menu
+ (GTK_OPTION_MENU(ctk_dithering_controls->dithering_mode_menu),
+ menu);
+
+ g_signal_connect(G_OBJECT(ctk_dithering_controls->dithering_mode_menu),
+ "changed", G_CALLBACK(dithering_mode_menu_changed),
+ (gpointer) ctk_dithering_controls);
+
+
+ /* pack the label & drop down */
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 2, 3,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ label = gtk_label_new("Mode: ");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+ hbox = gtk_hbox_new(FALSE, 0);
+ ctk_dithering_controls->dithering_mode_box = hbox;
+ gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 2, 3,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ gtk_box_pack_start(GTK_BOX(hbox),
+ ctk_dithering_controls->dithering_mode_menu,
+ FALSE, FALSE, 0);
+
+ /* Build CurrentMode widget */
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_table_attach(GTK_TABLE(table), hbox, 2, 3, 2, 3,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ label = gtk_label_new("Current Mode: ");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_table_attach(GTK_TABLE(table), hbox, 3, 4, 2, 3,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ label = gtk_label_new(NULL);
+ ctk_dithering_controls->dithering_current_mode = label;
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+ gtk_widget_show_all(GTK_WIDGET(object));
+
+ ctk_dithering_controls_setup(ctk_dithering_controls);
+
+ g_signal_connect(G_OBJECT(ctk_event),
+ CTK_EVENT_NAME(NV_CTRL_DITHERING),
+ G_CALLBACK(dithering_update_received),
+ (gpointer) ctk_dithering_controls);
+ g_signal_connect(G_OBJECT(ctk_event),
+ CTK_EVENT_NAME(NV_CTRL_DITHERING_MODE),
+ G_CALLBACK(dithering_update_received),
+ (gpointer) ctk_dithering_controls);
+ g_signal_connect(G_OBJECT(ctk_event),
+ CTK_EVENT_NAME(NV_CTRL_CURRENT_DITHERING),
+ G_CALLBACK(dithering_update_received),
+ (gpointer) ctk_dithering_controls);
+ g_signal_connect(G_OBJECT(ctk_event),
+ CTK_EVENT_NAME(NV_CTRL_CURRENT_DITHERING_MODE),
+ G_CALLBACK(dithering_update_received),
+ (gpointer) ctk_dithering_controls);
+
+ return GTK_WIDGET(object);
+
+} /* ctk_dithering_controls_new() */
+
+
+/*
+ * ctk_dithering_controls_setup() - Setup routine for dithering attributes. Used
+ * in DFP setup stage as well as for updating the GUI when there is change in
+ * dithering mode or config (enabled/disabled).
+ */
+void ctk_dithering_controls_setup(CtkDitheringControls *ctk_dithering_controls)
+{
+ gint val;
+
+ if (!ctk_dithering_controls) {
+ return;
+ }
+
+ /* dithering */
+ if (NvCtrlSuccess !=
+ NvCtrlGetDisplayAttribute(ctk_dithering_controls->handle,
+ ctk_dithering_controls->display_device_mask,
+ NV_CTRL_DITHERING, &val)) {
+ val = NV_CTRL_DITHERING_AUTO;
+ }
+
+ g_signal_handlers_block_by_func
+ (G_OBJECT(ctk_dithering_controls->dithering_config_menu),
+ G_CALLBACK(dithering_config_menu_changed),
+ (gpointer) ctk_dithering_controls);
+
+ gtk_option_menu_set_history
+ (GTK_OPTION_MENU(ctk_dithering_controls->dithering_config_menu),
+ val);
+
+ g_signal_handlers_unblock_by_func
+ (G_OBJECT(ctk_dithering_controls->dithering_config_menu),
+ G_CALLBACK(dithering_config_menu_changed),
+ (gpointer) ctk_dithering_controls);
+
+ if (!update_dithering_mode_menu_info
+ ((gpointer)ctk_dithering_controls)) {
+ gtk_widget_set_sensitive(ctk_dithering_controls->dithering_controls_main,
+ FALSE);
+ gtk_widget_hide_all(ctk_dithering_controls->dithering_controls_main);
+ }
+
+} /* ctk_dithering_controls_setup() */
+
+
+static Bool update_dithering_mode_menu_info(gpointer user_data)
+{
+ CtkDitheringControls *ctk_dithering_controls =
+ CTK_DITHERING_CONTROLS(user_data);
+ gint val, dithering_mode = NV_CTRL_DITHERING_MODE_AUTO;
+
+ /* dithering mode */
+ if (NvCtrlSuccess !=
+ NvCtrlGetDisplayAttribute(ctk_dithering_controls->handle,
+ ctk_dithering_controls->display_device_mask,
+ NV_CTRL_DITHERING_MODE,
+ &dithering_mode)) {
+ free(ctk_dithering_controls->dithering_mode_table);
+ return FALSE;
+ }
+
+ dithering_mode = map_nvctrl_value_to_table(ctk_dithering_controls,
+ dithering_mode);
+
+ g_signal_handlers_block_by_func
+ (G_OBJECT(ctk_dithering_controls->dithering_mode_menu),
+ G_CALLBACK(dithering_mode_menu_changed),
+ (gpointer) ctk_dithering_controls);
+
+ gtk_option_menu_set_history
+ (GTK_OPTION_MENU(ctk_dithering_controls->dithering_mode_menu),
+ dithering_mode);
+
+ g_signal_handlers_unblock_by_func
+ (G_OBJECT(ctk_dithering_controls->dithering_mode_menu),
+ G_CALLBACK(dithering_mode_menu_changed),
+ (gpointer) ctk_dithering_controls);
+
+ /* current dithering */
+ if (NvCtrlSuccess !=
+ NvCtrlGetDisplayAttribute(ctk_dithering_controls->handle,
+ ctk_dithering_controls->display_device_mask,
+ NV_CTRL_CURRENT_DITHERING, &val)) {
+ val = NV_CTRL_CURRENT_DITHERING_DISABLED;
+ }
+
+ if (val == NV_CTRL_CURRENT_DITHERING_ENABLED) {
+ gtk_label_set_text(GTK_LABEL(ctk_dithering_controls->dithering_current_config),
+ "Enabled");
+ gtk_widget_set_sensitive(ctk_dithering_controls->dithering_mode_box, TRUE);
+ gtk_widget_show(ctk_dithering_controls->dithering_mode_box);
+ } else if (val == NV_CTRL_CURRENT_DITHERING_DISABLED) {
+ gtk_label_set_text(GTK_LABEL(ctk_dithering_controls->dithering_current_config),
+ "Disabled");
+ gtk_widget_set_sensitive(ctk_dithering_controls->dithering_mode_box, FALSE);
+ }
+
+ /* current dithering mode */
+ dithering_mode = NV_CTRL_CURRENT_DITHERING_MODE_NONE;
+ if (NvCtrlSuccess !=
+ NvCtrlGetDisplayAttribute(ctk_dithering_controls->handle,
+ ctk_dithering_controls->display_device_mask,
+ NV_CTRL_CURRENT_DITHERING_MODE,
+ &dithering_mode)) {
+ free(ctk_dithering_controls->dithering_mode_table);
+ return FALSE;
+ }
+
+ switch (dithering_mode) {
+ case NV_CTRL_CURRENT_DITHERING_MODE_DYNAMIC_2X2:
+ gtk_label_set_text(GTK_LABEL(ctk_dithering_controls->dithering_current_mode),
+ "Dynamic 2x2");
+ break;
+ case NV_CTRL_CURRENT_DITHERING_MODE_STATIC_2X2:
+ gtk_label_set_text(GTK_LABEL(ctk_dithering_controls->dithering_current_mode),
+ "Static 2x2");
+ break;
+ default:
+ case NV_CTRL_CURRENT_DITHERING_MODE_NONE:
+ gtk_label_set_text(GTK_LABEL(ctk_dithering_controls->dithering_current_mode),
+ "None");
+ break;
+ }
+
+ return True;
+} /* update_dithering_mode_menu_info() */
+
+static
+void post_dithering_config_update(CtkDitheringControls *ctk_dithering_controls,
+ gint dithering_config)
+{
+ static const char *dither_config_table[] = {
+ "Auto", /* NV_CTRL_DITHERING_AUTO */
+ "Enabled", /* NV_CTRL_DITHERING_ENABLED */
+ "Disabled" /* NV_CTRL_DITHERING_DISABLED */
+ };
+
+ if (dithering_config < NV_CTRL_DITHERING_AUTO ||
+ dithering_config > NV_CTRL_DITHERING_DISABLED) {
+ return;
+ }
+
+ ctk_config_statusbar_message(ctk_dithering_controls->ctk_config,
+ "Dithering set to %s for %s.",
+ dither_config_table[dithering_config],
+ ctk_dithering_controls->name);
+}
+
+static
+void post_dithering_mode_update(CtkDitheringControls *ctk_dithering_controls,
+ gint dithering_mode)
+{
+ static const char *dither_mode_table[] = {
+ "Auto", /* NV_CTRL_DITHERING_MODE_AUTO */
+ "Dynamic 2x2", /* NV_CTRL_DITHERING_MODE_DYNAMIC_2X2 */
+ "Static 2x2" /* NV_CTRL_DITHERING_MODE_STATIC_2X2 */
+ };
+
+ if (dithering_mode < NV_CTRL_DITHERING_MODE_AUTO ||
+ dithering_mode > NV_CTRL_DITHERING_MODE_STATIC_2X2) {
+ return;
+ }
+
+ ctk_config_statusbar_message(ctk_dithering_controls->ctk_config,
+ "Dithering mode set to %s for %s.",
+ dither_mode_table[dithering_mode],
+ ctk_dithering_controls->name);
+}
+
+static void dithering_config_menu_changed(GtkOptionMenu *dithering_config_menu,
+ gpointer user_data)
+{
+ CtkDitheringControls *ctk_dithering_controls =
+ CTK_DITHERING_CONTROLS(user_data);
+ gint history, dithering_config = NV_CTRL_DITHERING_AUTO;
+
+ history = gtk_option_menu_get_history(dithering_config_menu);
+
+ switch (history) {
+ case 2:
+ dithering_config = NV_CTRL_DITHERING_DISABLED;
+ break;
+ case 1:
+ dithering_config = NV_CTRL_DITHERING_ENABLED;
+ break;
+ default:
+ case 0:
+ dithering_config = NV_CTRL_DITHERING_AUTO;
+ break;
+ }
+
+ NvCtrlSetDisplayAttribute(ctk_dithering_controls->handle,
+ ctk_dithering_controls->display_device_mask,
+ NV_CTRL_DITHERING,
+ dithering_config);
+
+ g_signal_handlers_block_by_func
+ (G_OBJECT(ctk_dithering_controls->dithering_config_menu),
+ G_CALLBACK(dithering_config_menu_changed),
+ (gpointer) ctk_dithering_controls);
+
+ gtk_option_menu_set_history
+ (GTK_OPTION_MENU(ctk_dithering_controls->dithering_config_menu),
+ dithering_config);
+
+ g_signal_handlers_unblock_by_func
+ (G_OBJECT(ctk_dithering_controls->dithering_config_menu),
+ G_CALLBACK(dithering_config_menu_changed),
+ (gpointer) ctk_dithering_controls);
+
+ /* reflecting the change in configuration to other widgets & reset button */
+ ctk_dithering_controls_setup(ctk_dithering_controls);
+ post_dithering_config_update(ctk_dithering_controls, dithering_config);
+ gtk_widget_set_sensitive(ctk_dithering_controls->reset_button, TRUE);
+
+} /* dithering_config_menu_changed() */
+
+
+static void dithering_mode_menu_changed(GtkOptionMenu *dithering_mode_menu,
+ gpointer user_data)
+{
+ CtkDitheringControls *ctk_dithering_controls =
+ CTK_DITHERING_CONTROLS(user_data);
+ gint history, dithering_mode = NV_CTRL_DITHERING_MODE_AUTO;
+
+ history = gtk_option_menu_get_history(dithering_mode_menu);
+
+ dithering_mode = ctk_dithering_controls->dithering_mode_table[history];
+
+ NvCtrlSetDisplayAttribute(ctk_dithering_controls->handle,
+ ctk_dithering_controls->display_device_mask,
+ NV_CTRL_DITHERING_MODE,
+ dithering_mode);
+
+ dithering_mode = map_nvctrl_value_to_table(ctk_dithering_controls,
+ dithering_mode);
+ g_signal_handlers_block_by_func
+ (G_OBJECT(ctk_dithering_controls->dithering_mode_menu),
+ G_CALLBACK(dithering_mode_menu_changed),
+ (gpointer) ctk_dithering_controls);
+
+ gtk_option_menu_set_history
+ (GTK_OPTION_MENU(ctk_dithering_controls->dithering_mode_menu),
+ dithering_mode);
+
+ g_signal_handlers_unblock_by_func
+ (G_OBJECT(ctk_dithering_controls->dithering_mode_menu),
+ G_CALLBACK(dithering_mode_menu_changed),
+ (gpointer) ctk_dithering_controls);
+
+ /* reflecting the change in mode to other widgets & reset button */
+ ctk_dithering_controls_setup(ctk_dithering_controls);
+ post_dithering_mode_update(ctk_dithering_controls, dithering_mode);
+ gtk_widget_set_sensitive(ctk_dithering_controls->reset_button, TRUE);
+
+} /* dithering_mode_menu_changed() */
+
+
+/*
+ * ctk_dithering_controls_reset() - Resets the dithering config (enabled/disabled)
+ * & dithering mode when Reset HW Defaults is clicked
+ */
+void ctk_dithering_controls_reset(CtkDitheringControls *ctk_dithering_controls)
+{
+ if (!ctk_dithering_controls) {
+ return;
+ }
+
+ NvCtrlSetDisplayAttribute(ctk_dithering_controls->handle,
+ ctk_dithering_controls->display_device_mask,
+ NV_CTRL_DITHERING,
+ NV_CTRL_DITHERING_AUTO);
+
+ NvCtrlSetDisplayAttribute(ctk_dithering_controls->handle,
+ ctk_dithering_controls->display_device_mask,
+ NV_CTRL_DITHERING_MODE,
+ NV_CTRL_DITHERING_MODE_AUTO);
+
+ ctk_dithering_controls_setup(ctk_dithering_controls);
+} /* ctk_dithering_controls_reset() */
+
+
+/*
+ * add_dithering_controls_help() -
+ */
+void add_dithering_controls_help(CtkDitheringControls *ctk_dithering_controls,
+ GtkTextBuffer *b,
+ GtkTextIter *i)
+{
+ ctk_help_heading(b, i, "Dithering Controls");
+ ctk_help_para(b, i, __dithering_help);
+} /* add_dithering_controls_help() */
+
+
+/*
+ * When dithering configuration is enabled/disabled,
+ * we should update the GUI to reflect the current state & mode.
+ */
+static void dithering_update_received(GtkObject *object, gpointer arg1,
+ gpointer user_data)
+{
+ CtkDitheringControls *ctk_object = CTK_DITHERING_CONTROLS(user_data);
+ CtkEventStruct *event_struct = (CtkEventStruct *) arg1;
+
+ /* if the event is not for this display device, return */
+
+ if (!(event_struct->display_mask & ctk_object->display_device_mask)) {
+ return;
+ }
+
+ ctk_dithering_controls_setup(ctk_object);
+} /* dithering_update_received() */
+
+
+/*
+ * build_dithering_mode_table() - build a table of dithering modes, showing
+ * modes supported by the hardware.
+ */
+static gboolean build_dithering_mode_table(CtkDitheringControls *ctk_dithering_controls,
+ NVCTRLAttributeValidValuesRec valid)
+{
+ gint i, n = 0, num_of_modes = 0;
+ gint mask = valid.u.bits.ints;
+
+ if (valid.type != ATTRIBUTE_TYPE_INT_BITS) {
+ return False;
+ }
+
+ /* count no. of supported modes */
+ while(mask) {
+ mask = mask & (mask - 1);
+ num_of_modes++;
+ }
+
+ ctk_dithering_controls->dithering_mode_table_size = num_of_modes;
+ ctk_dithering_controls->dithering_mode_table =
+ calloc(num_of_modes, sizeof(ctk_dithering_controls->dithering_mode_table[0]));
+ if (!ctk_dithering_controls->dithering_mode_table) {
+ return False;
+ }
+
+ for (i = 0; i < num_of_modes; i++) {
+ if (valid.u.bits.ints & (1 << i)) {
+ ctk_dithering_controls->dithering_mode_table[n] = i;
+ n++;
+ }
+ }
+
+ return True;
+
+} /* build_dithering_mode_table() */
+
+
+static gint map_nvctrl_value_to_table(CtkDitheringControls *ctk_dithering_controls,
+ gint val)
+{
+ int i;
+ for (i = 0; i < ctk_dithering_controls->dithering_mode_table_size; i++) {
+ if (val == ctk_dithering_controls->dithering_mode_table[i]) {
+ return i;
+ }
+ }
+
+ return 0;
+} /*map_nvctrl_value_to_table() */
diff --git a/src/gtk+-2.x/ctkditheringcontrols.h b/src/gtk+-2.x/ctkditheringcontrols.h
new file mode 100644
index 0000000..72178a1
--- /dev/null
+++ b/src/gtk+-2.x/ctkditheringcontrols.h
@@ -0,0 +1,98 @@
+/*
+ * nvidia-settings: A tool for configuring the NVIDIA X driver on Unix
+ * and Linux systems.
+ *
+ * Copyright (C) 2010 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_DITHERING_CONTROLS_H__
+#define __CTK_DITHERING_CONTROLS_H__
+
+#include "ctkevent.h"
+#include "ctkconfig.h"
+
+G_BEGIN_DECLS
+
+#define CTK_TYPE_DITHERING_CONTROLS (ctk_dithering_controls_get_type())
+
+#define CTK_DITHERING_CONTROLS(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), CTK_TYPE_DITHERING_CONTROLS, \
+ CtkDitheringControls))
+
+#define CTK_DITHERING_CONTROLS_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), CTK_TYPE_DITHERING_CONTROLS, \
+ CtkDitheringControlsClass))
+
+#define CTK_IS_DITHERING_CONTROLS(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CTK_TYPE_DITHERING_CONTROLS))
+
+#define CTK_IS_DITHERING_CONTROLS_CLASS(class) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), CTK_TYPE_DITHERING_CONTROLS))
+
+#define CTK_DITHERING_CONTROLS_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), CTK_TYPE_DITHERING_CONTROLS, \
+ CtkDitheringControlsClass))
+
+typedef struct _CtkDitheringControls CtkDitheringControls;
+typedef struct _CtkDitheringControlsClass CtkDitheringControlsClass;
+
+struct _CtkDitheringControls
+{
+ GtkVBox parent;
+
+ NvCtrlAttributeHandle *handle;
+ CtkConfig *ctk_config;
+ GtkWidget *reset_button;
+ GtkWidget *dithering_controls_main;
+ GtkWidget *dithering_mode_box;
+
+ GtkWidget *dithering_config_menu;
+ GtkWidget *dithering_mode_menu;
+ GtkWidget *dithering_current_config;
+ GtkWidget *dithering_current_mode;
+
+ gint display_device_mask;
+ gint *dithering_mode_table;
+ gint dithering_mode_table_size;
+ gint default_dithering_config;
+ gint default_dithering_mode;
+ char *name;
+};
+
+struct _CtkDitheringControlsClass
+{
+ GtkVBoxClass parent_class;
+};
+
+GType ctk_dithering_controls_get_type (void) G_GNUC_CONST;
+GtkWidget* ctk_dithering_controls_new (NvCtrlAttributeHandle *,
+ CtkConfig *, CtkEvent *,
+ GtkWidget *,
+ unsigned int display_device_mask,
+ char *);
+
+void ctk_dithering_controls_reset (CtkDitheringControls*);
+void ctk_dithering_controls_setup (CtkDitheringControls*);
+void add_dithering_controls_help (CtkDitheringControls*, GtkTextBuffer *b,
+ GtkTextIter *i);
+
+G_END_DECLS
+
+#endif /* __CTK_DITHERING_CONTROLS_H__ */
diff --git a/src/gtk+-2.x/ctkedid.c b/src/gtk+-2.x/ctkedid.c
index 6c625ea..aacd26c 100644
--- a/src/gtk+-2.x/ctkedid.c
+++ b/src/gtk+-2.x/ctkedid.c
@@ -35,23 +35,32 @@
#include <sys/types.h>
#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/mman.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <errno.h>
#define FRAME_PADDING 5
-#define DEFAULT_EDID_FILENAME "edid.bin"
+/* file formats */
+#define FILE_FORMAT_BINARY 1
+#define FILE_FORMAT_ASCII 2
+
+/* default file names */
+#define DEFAULT_EDID_FILENAME_BINARY "edid.bin"
+#define DEFAULT_EDID_FILENAME_ASCII "edid.txt"
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.";
+"(Extended Display Identification Data) information to a file. By "
+"default it saves information in binary format but one can also choose "
+"to save in ASCII format.";
+static void file_format_changed(GtkWidget *widget, gpointer user_data);
+static void normalize_filename(CtkEdid *ctk_edid);
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);
+ int format, unsigned char *data, int len);
GType ctk_edid_get_type(void)
{
@@ -110,13 +119,15 @@ GtkWidget* ctk_edid_new(NvCtrlAttributeHandle *handle,
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->filename = DEFAULT_EDID_FILENAME_BINARY;
+ ctk_edid->file_format = FILE_FORMAT_BINARY;
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);
+ gtk_file_selection_set_select_multiple
+ (GTK_FILE_SELECTION(ctk_edid->file_selector),
+ FALSE);
/* create the frame and vbox */
@@ -148,6 +159,47 @@ GtkWidget* ctk_edid_new(NvCtrlAttributeHandle *handle,
G_CALLBACK(button_clicked),
(gpointer) ctk_edid);
+ /* adding file format selection option to file selector dialog */
+
+ frame = gtk_frame_new(NULL);
+ gtk_box_pack_start
+ (GTK_BOX(GTK_FILE_SELECTION(ctk_edid->file_selector)->main_vbox),
+ frame, FALSE, FALSE, 15);
+ gtk_box_reorder_child
+ (GTK_BOX(GTK_FILE_SELECTION(ctk_edid->file_selector)->main_vbox),
+ frame, 0);
+
+ hbox = gtk_hbox_new(FALSE, 10);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), FRAME_PADDING);
+ gtk_container_add(GTK_CONTAINER(frame), hbox);
+
+ label = gtk_label_new("EDID File Format: ");
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+ ctk_edid->file_format_binary_radio_button =
+ gtk_radio_button_new_with_label(NULL, "Binary");
+ gtk_box_pack_start(GTK_BOX(hbox), ctk_edid->file_format_binary_radio_button,
+ FALSE, FALSE, 0);
+ g_signal_connect(G_OBJECT(ctk_edid->file_format_binary_radio_button),
+ "toggled", G_CALLBACK(file_format_changed),
+ (gpointer) ctk_edid);
+
+ ctk_edid->file_format_ascii_radio_button =
+ gtk_radio_button_new_with_label_from_widget
+ (GTK_RADIO_BUTTON(ctk_edid->file_format_binary_radio_button),
+ "ASCII");
+ gtk_box_pack_start(GTK_BOX(hbox), ctk_edid->file_format_ascii_radio_button,
+ FALSE, FALSE, 0);
+ g_signal_connect(G_OBJECT(ctk_edid->file_format_ascii_radio_button),
+ "toggled", G_CALLBACK(file_format_changed),
+ (gpointer) ctk_edid);
+
+ gtk_window_set_resizable(GTK_WINDOW(ctk_edid->file_selector),
+ FALSE);
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON(ctk_edid->file_format_binary_radio_button), TRUE);
+ gtk_widget_show_all(GTK_FILE_SELECTION(ctk_edid->file_selector)->main_vbox);
+
gtk_widget_show_all(GTK_WIDGET(object));
return GTK_WIDGET(object);
@@ -155,6 +207,83 @@ GtkWidget* ctk_edid_new(NvCtrlAttributeHandle *handle,
} /* ctk_edid_new() */
+static void normalize_filename(CtkEdid *ctk_edid)
+{
+ char *buffer = NULL, *filename = NULL;
+ char *end = NULL, *slash = NULL;
+ int len = 0, n;
+
+ ctk_edid->filename =
+ gtk_file_selection_get_filename(GTK_FILE_SELECTION(ctk_edid->file_selector));
+
+ len = strlen(ctk_edid->filename);
+ filename = malloc(len + 1);
+ if (!filename) {
+ goto done;
+ }
+ strncpy(filename, ctk_edid->filename, len);
+
+ /*
+ * It is possible that filename is entered without any extension,
+ * in that case we need to make room for the extension string e.g.
+ * '.bin' or '.txt', so total buffer length will be filename plus 5.
+ */
+ buffer = malloc(len + 5);
+ if (!buffer) {
+ goto done;
+ }
+
+ /* find the last forward slash (or the start of the filename) */
+
+ slash = strrchr(filename, '/');
+ if (!slash) {
+ slash = filename;
+ }
+
+ /*
+ * find where to truncate the filename: either the last period
+ * after 'slash', or the end of the filename
+ */
+
+ for (end = filename + len; end > slash; end--) {
+ if (*end == '.') break;
+ }
+
+ if (end == slash) {
+ end = filename + len;
+ }
+
+ /*
+ * print the characters between filename and end; then append the
+ * suffix
+ */
+ n = end - filename;
+ strncpy(buffer, filename, n);
+
+ if (gtk_toggle_button_get_active
+ (GTK_TOGGLE_BUTTON(ctk_edid->file_format_binary_radio_button))) {
+ ctk_edid->file_format = FILE_FORMAT_BINARY;
+ snprintf(buffer + n, 5, ".bin");
+ } else if (gtk_toggle_button_get_active
+ (GTK_TOGGLE_BUTTON(ctk_edid->file_format_ascii_radio_button))) {
+ ctk_edid->file_format = FILE_FORMAT_ASCII;
+ snprintf(buffer + n, 5, ".txt");
+ }
+
+ /* modify the file name as per the format selected */
+ gtk_file_selection_set_filename(GTK_FILE_SELECTION(ctk_edid->file_selector),
+ buffer);
+ done:
+ free(filename);
+ free(buffer);
+}
+
+static void file_format_changed(GtkWidget *widget, gpointer user_data)
+{
+ CtkEdid *ctk_edid = CTK_EDID(user_data);
+ normalize_filename(ctk_edid);
+}
+
static void button_clicked(GtkButton *button, gpointer user_data)
{
ReturnStatus ret;
@@ -188,11 +317,12 @@ static void button_clicked(GtkButton *button, gpointer user_data)
case GTK_RESPONSE_ACCEPT:
case GTK_RESPONSE_OK:
+ normalize_filename(ctk_edid);
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);
+ ctk_edid->file_format, data, len);
break;
default:
@@ -209,51 +339,77 @@ 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)
+ int format, unsigned char *data, int len)
{
- int fd = -1;
- char *dst = (void *) -1;
+ int i;
+ FILE *fp = NULL;
char *msg = "";
+ char *tmpbuf = NULL, *pbuf = NULL;
- 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;
+
+ if (format == FILE_FORMAT_ASCII) {
+ fp = fopen(filename, "wt");
+ if (!fp) {
+ msg = "ASCII Mode: Unable to open file for writing";
+ goto fail;
+ }
+ /*
+ * for printing every member we reserve 2 locations i.e. %02x and
+ * one extra space to comply with NVIDIA Windows Control Panel
+ * ASCII file output, so in all 3 bytes are required for every entry.
+ */
+ tmpbuf = calloc(1, 1 + (len * 3));
+ if (!tmpbuf) {
+ msg = "ASCII Mode: Could not allocate enough memory";
+ goto fail;
+ }
+ pbuf = tmpbuf;
+
+ for (i = 0; i < len; i++) {
+ if (sprintf(pbuf, "%02x ", data[i]) < 0) {
+ msg = "ASCII Mode: Unable to write to buffer";
+ goto fail;
+ }
+ pbuf = pbuf + 3;
+ }
+ /* being extra cautious */
+ sprintf(pbuf, "%c", '\0');
+
+ if (fprintf(fp, "%s", tmpbuf) < 0) {
+ msg = "ASCII Mode: Unable to write to file";
+ goto fail;
+ }
+
+ free(tmpbuf);
+ tmpbuf = pbuf = NULL;
+
+ } else {
+ fp = fopen(filename, "wb");
+ if (!fp) {
+ msg = "Binary Mode: Unable to open file for writing";
+ goto fail;
+ }
+
+ if (fwrite(data, 1, len, fp) != len) {
+ msg = "Binary Mode: Unable to write to file";
+ goto fail;
+ }
}
-
- close(fd);
-
+
+ fclose(fp);
+
ctk_config_statusbar_message(ctk_config,
"EDID written to %s.", filename);
return TRUE;
fail:
- if (fd != -1) close(fd);
+ free(tmpbuf);
+ tmpbuf = pbuf = NULL;
+
+ if (fp) {
+ fclose(fp);
+ }
ctk_config_statusbar_message(ctk_config,
"Unable to write EDID to file '%s': %s (%s).",
diff --git a/src/gtk+-2.x/ctkedid.h b/src/gtk+-2.x/ctkedid.h
index 80a4258..1f48c0f 100644
--- a/src/gtk+-2.x/ctkedid.h
+++ b/src/gtk+-2.x/ctkedid.h
@@ -62,11 +62,14 @@ struct _CtkEdid
GtkWidget *reset_button;
GtkWidget *button;
GtkWidget *file_selector;
+ GtkWidget *file_format_binary_radio_button;
+ GtkWidget *file_format_ascii_radio_button;
const gchar *filename;
char *name;
unsigned int display_device_mask;
+ gint file_format;
};
struct _CtkEdidClass
diff --git a/src/gtk+-2.x/ctkevent.c b/src/gtk+-2.x/ctkevent.c
index c3e369e..7acaea6 100644
--- a/src/gtk+-2.x/ctkevent.c
+++ b/src/gtk+-2.x/ctkevent.c
@@ -302,9 +302,17 @@ static void ctk_event_class_init(CtkEventClass *ctk_event_class)
MAKE_SIGNAL(NV_CTRL_GPU_CORES);
MAKE_SIGNAL(NV_CTRL_GPU_MEMORY_BUS_WIDTH);
MAKE_SIGNAL(NV_CTRL_GVI_TEST_MODE);
+ MAKE_SIGNAL(NV_CTRL_COLOR_SPACE);
+ MAKE_SIGNAL(NV_CTRL_COLOR_RANGE);
+ MAKE_SIGNAL(NV_CTRL_DITHERING);
+ MAKE_SIGNAL(NV_CTRL_DITHERING_MODE);
+ MAKE_SIGNAL(NV_CTRL_CURRENT_DITHERING);
+ MAKE_SIGNAL(NV_CTRL_CURRENT_DITHERING_MODE);
MAKE_SIGNAL(NV_CTRL_THERMAL_SENSOR_READING);
MAKE_SIGNAL(NV_CTRL_THERMAL_SENSOR_PROVIDER);
MAKE_SIGNAL(NV_CTRL_THERMAL_SENSOR_TARGET);
+ MAKE_SIGNAL(NV_CTRL_GPU_CURRENT_PROCESSOR_CLOCK_FREQS);
+ MAKE_SIGNAL(NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS);
MAKE_SIGNAL(NV_CTRL_GPU_PCIE_MAX_LINK_SPEED);
#undef MAKE_SIGNAL
@@ -358,9 +366,10 @@ static void ctk_event_class_init(CtkEventClass *ctk_event_class)
MAKE_STRING_SIGNAL(NV_CTRL_STRING_SLI_MODE);
MAKE_STRING_SIGNAL(NV_CTRL_STRING_PERFORMANCE_MODES);
MAKE_STRING_SIGNAL(NV_CTRL_STRING_GVIO_VIDEO_FORMAT_NAME);
+ MAKE_STRING_SIGNAL(NV_CTRL_STRING_GPU_CURRENT_CLOCK_FREQS);
#undef MAKE_STRING_SIGNAL
-#if NV_CTRL_STRING_LAST_ATTRIBUTE != NV_CTRL_STRING_GVO_VIDEO_FORMAT_NAME
+#if NV_CTRL_STRING_LAST_ATTRIBUTE != NV_CTRL_STRING_GPU_CURRENT_CLOCK_FREQS
#warning "There are attributes that do not emit signals!"
#endif
diff --git a/src/gtk+-2.x/ctkframelock.c b/src/gtk+-2.x/ctkframelock.c
index c9e1ad9..d0c3e01 100644
--- a/src/gtk+-2.x/ctkframelock.c
+++ b/src/gtk+-2.x/ctkframelock.c
@@ -287,8 +287,8 @@ static const char * __use_house_sync_button_help =
"(if a house sync signal is detected) instead of using internal timing from "
"the server GPU/display device.";
-static const char * __sync_interval_entry_help =
-"The Sync Interval entry allows you to set the number of incoming house sync "
+static const char * __sync_interval_scale_help =
+"The Sync Interval allows you to set the number of incoming house sync "
"pulses the master frame lock board recieves before generating an outgoing "
"frame lock sync pulse. A value of 0 means a frame lock sync pulse is sent "
"for every house sync pulse.";
@@ -350,7 +350,7 @@ static void toggle_server(GtkWidget *, gpointer);
static void toggle_client(GtkWidget *, gpointer);
static void toggle_sync_enable(GtkWidget *, gpointer);
static void toggle_test_link(GtkWidget *, gpointer);
-static void activate_sync_interval(GtkEntry *, gpointer);
+static void sync_interval_changed(GtkRange *, gpointer);
static void changed_video_mode(GtkEditable *, gpointer);
static void toggle_detect_video_mode(GtkToggleButton *, gpointer);
@@ -3151,24 +3151,23 @@ static void toggle_test_link(GtkWidget *button, gpointer data)
-/** activate_sync_interval() *****************************************
+/** sync_interval_changed() *****************************************
*
* Callback function for when the user changes the house sync
* interval.
*
*/
-static void activate_sync_interval(GtkEntry *widget, gpointer user_data)
+static void sync_interval_changed(GtkRange *range, gpointer user_data)
{
CtkFramelock *ctk_framelock = (CtkFramelock *)user_data;
nvListTreePtr tree = (nvListTreePtr)(ctk_framelock->tree);
nvListEntryPtr entry = get_framelock_server_entry(tree);
- nvFrameLockDataPtr data;
- const gchar *str = gtk_entry_get_text(widget);
- gint interval;
-
- if (!entry || !str) return;
+ nvFrameLockDataPtr data = NULL;
+ gint interval = gtk_range_get_value(range);
- interval = strtol(str, NULL, 10);
+ if (!entry) {
+ return;
+ }
data = (nvFrameLockDataPtr)(entry->data);
@@ -3177,6 +3176,20 @@ static void activate_sync_interval(GtkEntry *widget, gpointer user_data)
}
+/*
+ * format_sync_interval() - callback for the "format-value" signal from
+ * the sync interval scale; return a string describing the current value of the
+ * scale.
+ */
+static gchar *format_sync_interval(GtkScale *scale, gdouble arg1,
+ gpointer user_data)
+{
+ gint val = (gint)arg1;
+
+ return g_strdup_printf("%d", val);
+
+}
+
/** changed_sync_edge() **********************************************
*
@@ -3786,16 +3799,15 @@ static void update_house_sync_controls(CtkFramelock *ctk_framelock)
gtk_widget_set_sensitive(ctk_framelock->house_sync_frame, !enabled);
if (enabled || !use_house) {
- gtk_widget_set_sensitive(ctk_framelock->house_sync_hbox, FALSE);
+ gtk_widget_set_sensitive(ctk_framelock->house_sync_vbox, FALSE);
} else {
gint sync_interval;
gint sync_edge;
gint house_format;
- gchar str[32];
nvFrameLockDataPtr data;
- gtk_widget_set_sensitive(ctk_framelock->house_sync_hbox, TRUE);
+ gtk_widget_set_sensitive(ctk_framelock->house_sync_vbox, TRUE);
data = (nvFrameLockDataPtr)(entry->data);
@@ -3812,9 +3824,18 @@ static void update_house_sync_controls(CtkFramelock *ctk_framelock)
/* Update GUI to reflect server settings */
- snprintf(str, 32, "%d", sync_interval);
- gtk_entry_set_text(GTK_ENTRY(ctk_framelock->sync_interval_entry),
- str);
+ g_signal_handlers_block_by_func
+ (G_OBJECT(ctk_framelock->sync_interval_scale),
+ G_CALLBACK(sync_interval_changed),
+ (gpointer) ctk_framelock);
+
+ gtk_range_set_value(GTK_RANGE(ctk_framelock->sync_interval_scale),
+ sync_interval);
+
+ g_signal_handlers_unblock_by_func
+ (G_OBJECT(ctk_framelock->sync_interval_scale),
+ G_CALLBACK(sync_interval_changed),
+ (gpointer) ctk_framelock);
if (sync_edge < NV_CTRL_FRAMELOCK_POLARITY_RISING_EDGE)
sync_edge = NV_CTRL_FRAMELOCK_POLARITY_RISING_EDGE;
@@ -4130,7 +4151,6 @@ static void framelock_state_received(GtkObject *object,
nvListEntryPtr server_entry =
get_framelock_server_entry(entry->tree);
- char str[32];
gint sync_edge;
gint house_format;
@@ -4160,17 +4180,16 @@ static void framelock_state_received(GtkObject *object,
case NV_CTRL_FRAMELOCK_SYNC_INTERVAL:
g_signal_handlers_block_by_func
- (G_OBJECT(ctk_framelock->sync_interval_entry),
- G_CALLBACK(activate_sync_interval),
+ (G_OBJECT(ctk_framelock->sync_interval_scale),
+ G_CALLBACK(sync_interval_changed),
(gpointer) ctk_framelock);
- snprintf(str, 32, "%d", event->value);
- gtk_entry_set_text(GTK_ENTRY(ctk_framelock->sync_interval_entry),
- str);
+ gtk_range_set_value(GTK_RANGE(ctk_framelock->sync_interval_scale),
+ event->value);
g_signal_handlers_unblock_by_func
- (G_OBJECT(ctk_framelock->sync_interval_entry),
- G_CALLBACK(activate_sync_interval),
+ (G_OBJECT(ctk_framelock->sync_interval_scale),
+ G_CALLBACK(sync_interval_changed),
(gpointer) ctk_framelock);
break;
@@ -4310,20 +4329,23 @@ GtkWidget* ctk_framelock_new(NvCtrlAttributeHandle *handle,
ReturnStatus ret;
unsigned int num_framelocks;
gchar *string;
+ gint val;
GtkWidget *frame;
GtkWidget *padding;
GtkWidget *sw; /* Scrollable window */
GtkWidget *vp; /* Viewport */
+ GtkWidget *scale;
+ GtkObject *adjustment;
GtkWidget *hbox;
GtkWidget *vbox;
GtkWidget *label;
- GtkWidget *entry;
GtkWidget *combo;
GList *glist;
GtkWidget *button;
GtkWidget *image;
+ NVCTRLAttributeValidValuesRec valid;
@@ -4605,33 +4627,60 @@ GtkWidget* ctk_framelock_new(NvCtrlAttributeHandle *handle,
gtk_box_pack_start(GTK_BOX(hbox), ctk_framelock->use_house_sync,
FALSE, FALSE, 0);
- padding = gtk_hbox_new(FALSE, 5);
- ctk_framelock->house_sync_hbox = padding;
+ padding = gtk_vbox_new(FALSE, 5);
+ ctk_framelock->house_sync_vbox = padding;
gtk_box_pack_start(GTK_BOX(vbox), padding, FALSE, FALSE, 0);
/* add the house sync interval */
{
GtkWidget *frame2 = gtk_frame_new(NULL);
+
+ ret = NvCtrlGetValidAttributeValues(ctk_framelock->attribute_handle,
+ NV_CTRL_FRAMELOCK_SYNC_INTERVAL,
+ &valid);
+ /*
+ * pick a conservative default range if we could not query the
+ * range from NV-CONTROL
+ */
+
+ if ((ret != NvCtrlSuccess) || (valid.type != ATTRIBUTE_TYPE_RANGE)) {
+ valid.type = ATTRIBUTE_TYPE_RANGE;
+ valid.u.range.min = 0;
+ valid.u.range.max = 4;
+ }
+
+ if (NvCtrlSuccess !=
+ NvCtrlGetAttribute(ctk_framelock->attribute_handle,
+ NV_CTRL_FRAMELOCK_SYNC_INTERVAL,
+ &val)) {
+ return NULL;
+ }
+
hbox = gtk_hbox_new(FALSE, 5);
label = gtk_label_new("Sync Interval:");
- entry = gtk_entry_new();
- gtk_entry_set_text(GTK_ENTRY(entry), "0");
- gtk_entry_set_width_chars(GTK_ENTRY(entry), 4);
- g_signal_connect(G_OBJECT(entry),
- "activate", G_CALLBACK(activate_sync_interval),
+
+ adjustment = gtk_adjustment_new(val, valid.u.range.min,
+ valid.u.range.max, 1, 1, 0);
+ scale = gtk_hscale_new(GTK_ADJUSTMENT(adjustment));
+ gtk_adjustment_set_value(GTK_ADJUSTMENT(adjustment), val);
+
+ gtk_scale_set_draw_value(GTK_SCALE(scale), TRUE);
+ gtk_scale_set_value_pos(GTK_SCALE(scale), GTK_POS_TOP);
+
+ g_signal_connect(G_OBJECT(scale), "format-value",
+ G_CALLBACK(format_sync_interval),
+ (gpointer) ctk_framelock);
+ g_signal_connect(G_OBJECT(scale), "value-changed",
+ G_CALLBACK(sync_interval_changed),
(gpointer) ctk_framelock);
- ctk_config_set_tooltip(ctk_config, entry, __sync_interval_entry_help);
+ ctk_config_set_tooltip(ctk_config, scale, __sync_interval_scale_help);
+
ctk_framelock->sync_interval_frame = frame2;
- ctk_framelock->sync_interval_entry = entry;
+ ctk_framelock->sync_interval_scale = scale;
gtk_box_pack_start(GTK_BOX(padding), frame2, FALSE, FALSE, 0);
-
- gtk_entry_set_text(GTK_ENTRY(entry), "0");
- gtk_entry_set_width_chars(GTK_ENTRY(entry), 4);
-
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 5);
- gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, TRUE, 5);
-
+ gtk_box_pack_start(GTK_BOX(hbox), scale, TRUE, TRUE, 5);
gtk_container_add(GTK_CONTAINER(frame2), hbox);
}
@@ -5779,7 +5828,7 @@ GtkTextBuffer *ctk_framelock_create_help(GtkTextTagTable *table)
"fall back to using internal timings from the primary GPU.");
ctk_help_heading(b, &i, "Sync Interval");
- ctk_help_para(b, &i, __sync_interval_entry_help);
+ ctk_help_para(b, &i, __sync_interval_scale_help);
ctk_help_heading(b, &i, "Sync Edge");
ctk_help_para(b, &i, __sync_edge_combo_help);
diff --git a/src/gtk+-2.x/ctkframelock.h b/src/gtk+-2.x/ctkframelock.h
index 24f3ad3..96398ee 100644
--- a/src/gtk+-2.x/ctkframelock.h
+++ b/src/gtk+-2.x/ctkframelock.h
@@ -76,10 +76,10 @@ struct _CtkFramelock
/* House sync */
GtkWidget *house_sync_frame;
- GtkWidget *house_sync_hbox;
+ GtkWidget *house_sync_vbox;
GtkWidget *use_house_sync;
GtkWidget *sync_interval_frame;
- GtkWidget *sync_interval_entry;
+ GtkWidget *sync_interval_scale;
GtkWidget *sync_edge_frame;
GtkWidget *sync_edge_combo;
GtkWidget *video_mode_frame;
diff --git a/src/gtk+-2.x/ctkgvi.c b/src/gtk+-2.x/ctkgvi.c
index 1087009..d2a89d5 100755
--- a/src/gtk+-2.x/ctkgvi.c
+++ b/src/gtk+-2.x/ctkgvi.c
@@ -751,25 +751,21 @@ GtkTextBuffer *ctk_gvi_create_help(GtkTextTagTable *table,
ctk_help_para(b, &i, "This is the interrupt request line assigned to "
"this GVI device.");
- ctk_help_heading(b, &i, "Fill A");
- ctk_help_para(b, &i, "This reports the detected incoming video format on "
- "first jack on the GVI device.");
-
- ctk_help_heading(b, &i, "Key A");
- ctk_help_para(b, &i, "This reports the detected incoming video format on "
- "second jack on the GVI device.");
-
- ctk_help_heading(b, &i, "Fill B");
- ctk_help_para(b, &i, "This reports the detected incoming video format on "
- "third jack on the GVI device.");
-
- ctk_help_heading(b, &i, "Key B");
- ctk_help_para(b, &i, "This reports the detected incoming video format on "
- "fourth jack on the GVI device.");
-
- ctk_help_heading(b, &i, "Sync Output");
- ctk_help_para(b, &i, "This reports the output sync signal from "
- "the GVI device.");
+ ctk_help_heading(b, &i, "Input Information");
+ ctk_help_para(b, &i, "This section shows the detected video format(s) on "
+ "each jack of the GVI device. When condensed mode is "
+ "selected, the detected video format is shown for each "
+ "jack (and channel). when detailed mode is selected, "
+ "information pertaining to the single channel on a jack "
+ "selected is given as such:");
+
+ ctk_help_para(b, &i, "Video Format: The detected SMPTE video format.");
+ ctk_help_para(b, &i, "Component Sampling: The detected composition of the "
+ "channel.");
+ ctk_help_para(b, &i, "Color Space: The detected color space.");
+ ctk_help_para(b, &i, "Bites Per Component: The detected number of bits "
+ "per component.");
+ ctk_help_para(b, &i, "Link ID: The detected link ID of the channel.");
ctk_help_finish(b);
diff --git a/src/gtk+-2.x/ctkgvo-csc.c b/src/gtk+-2.x/ctkgvo-csc.c
index 51433b0..e511968 100644
--- a/src/gtk+-2.x/ctkgvo-csc.c
+++ b/src/gtk+-2.x/ctkgvo-csc.c
@@ -930,64 +930,41 @@ static void initialize_csc_dropdown_changed(CtkDropDownMenu *menu,
gpointer user_data)
{
CtkGvoCsc *ctk_gvo_csc = (CtkGvoCsc *) user_data;
- const gfloat (*std)[5];
+ const float *std = NULL;
gint column, row, value;
-
- // red green blue offset scale
- static const float itu601[3][5] = {
- { 0.2991, 0.5870, 0.1150, 0.0625, 0.85547 }, // Y
- { 0.5000, -0.4185, -0.0810, 0.5000, 0.87500 }, // Cr
- { -0.1685, -0.3310, 0.5000, 0.5000, 0.87500 }, // Cb
- };
-
- static const float itu709[3][5] = {
- { 0.2130, 0.7156, 0.0725, 0.0625, 0.85547 }, // Y
- { 0.5000, -0.4542, -0.0455, 0.5000, 0.87500 }, // Cr
- { -0.1146, -0.3850, 0.5000, 0.5000, 0.87500 }, // Cb
- };
-
- static const float itu177[3][5] = {
- { 0.412391, 0.357584, 0.180481, 0.0, 0.85547 }, // Y
- { 0.019331, 0.119195, 0.950532, 0.0, 0.87500 }, // Cr
- { 0.212639, 0.715169, 0.072192, 0.0, 0.87500 }, // Cb
- };
-
- static const float identity[3][5] = {
- { 0.0000, 1.0000, 0.0000, 0.0000, 1.0 }, // Y (Green)
- { 1.0000, 0.0000, 0.0000, 0.0000, 1.0 }, // Cr (Red)
- { 0.0000, 0.0000, 1.0000, 0.0000, 1.0 }, // Cb (Blue)
- };
-
value = ctk_drop_down_menu_get_current_value(menu);
-
+
switch (value) {
- case CSC_STANDARD_ITU_601: std = itu601; break;
- case CSC_STANDARD_ITU_709: std = itu709; break;
- case CSC_STANDARD_ITU_177: std = itu177; break;
- case CSC_STANDARD_IDENTITY: std = identity; break;
- default: return;
+ case CSC_STANDARD_ITU_601: std = nv_get_sdi_csc_matrix("itu_601"); break;
+ case CSC_STANDARD_ITU_709: std = nv_get_sdi_csc_matrix("itu_709"); break;
+ case CSC_STANDARD_ITU_177: std = nv_get_sdi_csc_matrix("itu_177"); break;
+ case CSC_STANDARD_IDENTITY: std = nv_get_sdi_csc_matrix("identity"); break;
+ default: return;
}
-
+ if (!std) {
+ return;
+ }
+
for (row = 0; row < 3; row++) {
for (column = 0; column < 3; column++) {
- ctk_gvo_csc->matrix[row][column] = std[row][column];
+ ctk_gvo_csc->matrix[row][column] = std[row*5 + column];
gtk_spin_button_set_value
(GTK_SPIN_BUTTON(ctk_gvo_csc->matrixWidget[row][column]),
ctk_gvo_csc->matrix[row][column]);
}
-
- ctk_gvo_csc->offset[row] = std[row][3];
+
+ ctk_gvo_csc->offset[row] = std[row*5 + 3];
gtk_spin_button_set_value
(GTK_SPIN_BUTTON(ctk_gvo_csc->offsetWidget[row]),
ctk_gvo_csc->offset[row]);
- ctk_gvo_csc->scale[row] = std[row][4];
+ ctk_gvo_csc->scale[row] = std[row*5 + 4];
gtk_spin_button_set_value
(GTK_SPIN_BUTTON(ctk_gvo_csc->scaleWidget[row]),
ctk_gvo_csc->scale[row]);
}
-
+
/*
* the data has changed, make sure the apply button is sensitive
*/
diff --git a/src/gtk+-2.x/ctkgvo.c b/src/gtk+-2.x/ctkgvo.c
index 614a88c..417f51f 100644
--- a/src/gtk+-2.x/ctkgvo.c
+++ b/src/gtk+-2.x/ctkgvo.c
@@ -1428,6 +1428,10 @@ static void output_video_format_ui_changed(CtkDropDownMenu *menu,
update_gvo_sensitivity(ctk_gvo);
+ /* Made GVO banner to update current output video format */
+ CTK_GVO_BANNER(ctk_gvo->banner)->output_video_format =
+ ctk_gvo->output_video_format;
+
post_output_video_format_changed(ctk_gvo);
} /* output_video_format_ui_changed() */
diff --git a/src/gtk+-2.x/ctkimagesliders.c b/src/gtk+-2.x/ctkimagesliders.c
index 761acf3..5450436 100644
--- a/src/gtk+-2.x/ctkimagesliders.c
+++ b/src/gtk+-2.x/ctkimagesliders.c
@@ -340,6 +340,27 @@ void ctk_image_sliders_reset(CtkImageSliders *ctk_image_sliders)
0);
}
+ /*
+ * The above may have triggered events (e.g., changing
+ * NV_CTRL_OVERSCAN_COMPENSATION may trigger an
+ * NV_CTRL_IMAGE_SHARPENING value change). Such an event will
+ * cause scale_value_changed() and post_scale_value_changed() to
+ * be called when control returns to the gtk_main loop.
+ * post_scale_value_changed() will write a status message to the
+ * statusbar.
+ *
+ * However, the caller of ctk_image_sliders_reset() (e.g.,
+ * ctkdisplaydevice-dfp.c:reset_button_clicked()) may also want to
+ * write a status message to the statusbar. To ensure that the
+ * caller's statusbar message takes precedence (i.e., is the last
+ * thing written to the statusbar), process any generated events
+ * now, before returning to the caller.
+ */
+
+ while (gtk_events_pending()) {
+ gtk_main_iteration_do(FALSE);
+ }
+
ctk_image_sliders_setup(ctk_image_sliders);
} /* ctk_image_sliders_reset() */
diff --git a/src/gtk+-2.x/ctkpowermizer.c b/src/gtk+-2.x/ctkpowermizer.c
index 714b3bd..716b5ab 100644
--- a/src/gtk+-2.x/ctkpowermizer.c
+++ b/src/gtk+-2.x/ctkpowermizer.c
@@ -69,28 +69,32 @@ static const char *__performance_mode_help =
"CUDA application is running).";
static const char *__gpu_clock_freq_help =
-"This indicates the current GPU Clock frequency.";
+"This indicates the current Graphics Clock frequency.";
static const char *__memory_clock_freq_help =
"This indicates the current Memory Clock frequency.";
+static const char *__processor_clock_freq_help =
+"This indicates the current Processor Clock frequency.";
+
static const char *__clock_freq_help =
-"This indicates the current GPU Clock and Memory Clock frequencies.";
+"This indicates the GPU's current Graphics Clock, Memory Clock and Processor "
+"Clock frequencies.";
static const char *__performance_levels_table_help =
"This indicates the Performance Levels available for the GPU. Each "
"performance level is indicated by a Performance Level number, along with "
-"the GPU and Memory clocks for that level. The currently active performance "
-"level is shown in regular text. All other performance levels are shown in "
-"gray.";
+"the Graphics, Memory and Processor clocks for that level. The currently active "
+"performance level is shown in regular text. All other performance "
+"levels are shown in gray.";
static const char *__powermizer_menu_help =
"The Preferred Mode menu allows you to choose the preferred Performance "
"State for the GPU, provided the GPU has multiple Performance Levels. "
"'Adaptive' mode allows the GPU clocks to be adjusted based on GPU "
"utilization. 'Prefer Maximum Performance' hints to the driver to prefer "
-"higher GPU clocks, when possible. If a single X server is running, the mode "
-"selected in nvidia-settings is what the system will be using; if two or "
+"higher GPU clocks, when possible. If a single X server is running, the "
+"mode selected in nvidia-settings is what the system will be using; if two or "
"more X servers are running, the behavior is undefined. If any CUDA "
"application is running, the system will always be in the 'Prefer Maximum "
"Performance' mode.";
@@ -127,6 +131,7 @@ typedef struct {
gint perf_level;
gint nvclock;
gint memclock;
+ gint processorclock;
} perfModeEntry, * perfModeEntryPtr;
@@ -140,6 +145,8 @@ static void apply_perf_mode_token(char *token, char *value, void *data)
pEntry->nvclock = atoi(value);
} else if (!strcasecmp("memclock", token)) {
pEntry->memclock = atoi(value);
+ } else if (!strcasecmp("processorclock", token)) {
+ pEntry->processorclock = atoi(value);
} else {
nv_warning_msg("Unknown Perf Mode token value pair: %s=%s",
token, value);
@@ -170,7 +177,7 @@ static void update_perf_mode_table(CtkPowermizer *ctk_powermizer,
/* Generate a new table */
- table = gtk_table_new(1, 3, FALSE);
+ table = gtk_table_new(1, 4, FALSE);
gtk_table_set_row_spacings(GTK_TABLE(table), 3);
gtk_table_set_col_spacings(GTK_TABLE(table), 15);
gtk_container_set_border_width(GTK_CONTAINER(table), 5);
@@ -183,7 +190,7 @@ static void update_perf_mode_table(CtkPowermizer *ctk_powermizer,
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
- label = gtk_label_new("NV Clock");
+ label = gtk_label_new("Graphics Clock");
gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
gtk_table_attach(GTK_TABLE(table), label, 1, 2, 0, 1,
GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
@@ -193,6 +200,12 @@ static void update_perf_mode_table(CtkPowermizer *ctk_powermizer,
gtk_table_attach(GTK_TABLE(table), label, 2, 3, 0, 1,
GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ if (ctk_powermizer->processor_clock) {
+ label = gtk_label_new("Processor Clock");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 3, 4, 0, 1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ }
/* Get the current list of perf levels */
ret = NvCtrlGetStringAttribute(ctk_powermizer->attribute_handle,
@@ -216,6 +229,7 @@ static void update_perf_mode_table(CtkPowermizer *ctk_powermizer,
entry.perf_level = -1;
entry.nvclock = -1;
entry.memclock = -1;
+ entry.processorclock = -1;
parse_token_value_pairs(tokens, apply_perf_mode_token,
&entry);
@@ -229,7 +243,7 @@ static void update_perf_mode_table(CtkPowermizer *ctk_powermizer,
/* XXX Assume the perf levels are sorted by the server */
- gtk_table_resize(GTK_TABLE(table), row_idx+1, 3);
+ gtk_table_resize(GTK_TABLE(table), row_idx+1, 4);
g_snprintf(tmp_str, 24, "%d", entry.perf_level);
label = gtk_label_new(tmp_str);
@@ -252,11 +266,20 @@ static void update_perf_mode_table(CtkPowermizer *ctk_powermizer,
gtk_table_attach(GTK_TABLE(table), label, 2, 3, row_idx, row_idx+1,
GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ if (ctk_powermizer->processor_clock) {
+ g_snprintf(tmp_str, 24, "%d MHz", entry.processorclock);
+ label = gtk_label_new(tmp_str);
+ gtk_widget_set_sensitive(label, active);
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 3, 4, row_idx, row_idx+1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ }
row_idx++;
} else {
nv_warning_msg("Incomplete Perf Mode (perf=%d, nvclock=%d,"
" memclock=%d)",
- entry.perf_level, entry.nvclock, entry.memclock);
+ entry.perf_level, entry.nvclock,
+ entry.memclock);
}
}
@@ -270,7 +293,7 @@ static void update_perf_mode_table(CtkPowermizer *ctk_powermizer,
static gboolean update_powermizer_info(gpointer user_data)
{
gint power_source, perf_mode, adaptive_clock, perf_level;
- gint clockret, gpu_clock, memory_clock;
+ gint clockret, gpu_clock, memory_clock, processor_clock;
CtkPowermizer *ctk_powermizer;
NvCtrlAttributeHandle *handle;
@@ -316,6 +339,17 @@ static gboolean update_powermizer_info(gpointer user_data)
gtk_label_set_text(GTK_LABEL(ctk_powermizer->memory_clock), s);
g_free(s);
+ if (ctk_powermizer->processor_clock) {
+ ret = NvCtrlGetAttribute(handle,
+ NV_CTRL_GPU_CURRENT_PROCESSOR_CLOCK_FREQS,
+ &processor_clock);
+ if (ret == NvCtrlSuccess) {
+ s = g_strdup_printf("%d Mhz", processor_clock);
+ gtk_label_set_text(GTK_LABEL(ctk_powermizer->processor_clock), s);
+ g_free(s);
+ }
+ }
+
ret = NvCtrlGetAttribute(handle, NV_CTRL_GPU_POWER_SOURCE, &power_source);
if (ret != NvCtrlSuccess) {
return FALSE;
@@ -382,6 +416,7 @@ GtkWidget* ctk_powermizer_new(NvCtrlAttributeHandle *handle,
ReturnStatus ret;
gchar *s;
gint val;
+ gboolean processor_clock_available = FALSE;
/* make sure we have a handle */
@@ -419,6 +454,12 @@ GtkWidget* ctk_powermizer_new(NvCtrlAttributeHandle *handle,
return NULL;
}
+ ret = NvCtrlGetAttribute(handle, NV_CTRL_GPU_CURRENT_PROCESSOR_CLOCK_FREQS,
+ &val);
+ if (ret == NvCtrlSuccess) {
+ processor_clock_available = TRUE;
+ }
+
/* create the CtkPowermizer object */
object = g_object_new(CTK_TYPE_POWERMIZER, NULL);
@@ -480,7 +521,7 @@ GtkWidget* ctk_powermizer_new(NvCtrlAttributeHandle *handle,
gtk_table_attach(GTK_TABLE(table), hbox2, 0, 1, 4, 5,
GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
- label = gtk_label_new("GPU Clock:");
+ label = gtk_label_new("Graphics Clock:");
gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
@@ -512,6 +553,26 @@ GtkWidget* ctk_powermizer_new(NvCtrlAttributeHandle *handle,
ctk_config_set_tooltip(ctk_config, eventbox, __memory_clock_freq_help);
ctk_powermizer->memory_clock = label;
+ /* Processor clock */
+ if (processor_clock_available) {
+ hbox2 = gtk_hbox_new(FALSE, 0);
+ gtk_table_attach(GTK_TABLE(table), hbox2, 0, 1, 6, 7,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+
+ label = gtk_label_new("Processor Clock:");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
+
+ eventbox = gtk_event_box_new();
+ gtk_table_attach(GTK_TABLE(table), eventbox, 1, 2, 6, 7,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+
+ label = gtk_label_new(NULL);
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
+ gtk_container_add(GTK_CONTAINER(eventbox), label);
+ ctk_config_set_tooltip(ctk_config, eventbox, __processor_clock_freq_help);
+ ctk_powermizer->processor_clock = label;
+ }
/* Power Source */
hbox2 = gtk_hbox_new(FALSE, 0);
diff --git a/src/gtk+-2.x/ctkpowermizer.h b/src/gtk+-2.x/ctkpowermizer.h
index 316d94a..90f3127 100644
--- a/src/gtk+-2.x/ctkpowermizer.h
+++ b/src/gtk+-2.x/ctkpowermizer.h
@@ -62,6 +62,7 @@ struct _CtkPowermizer
GtkWidget *adaptive_clock_status;
GtkWidget *gpu_clock;
GtkWidget *memory_clock;
+ GtkWidget *processor_clock;
GtkWidget *power_source;
GtkWidget *performance_level;
GtkWidget *performance_mode;
diff --git a/src/gtk+-2.x/ctkscreen.c b/src/gtk+-2.x/ctkscreen.c
index 8cb5490..2d3f764 100644
--- a/src/gtk+-2.x/ctkscreen.c
+++ b/src/gtk+-2.x/ctkscreen.c
@@ -44,7 +44,7 @@ static const _CtkStereoMode stereoMode[] = {
{ NV_CTRL_STEREO_DDC, "DDC Stereo" },
{ NV_CTRL_STEREO_BLUELINE, "Blueline Stereo" },
{ NV_CTRL_STEREO_DIN, "Onboard DIN Stereo" },
- { NV_CTRL_STEREO_TWINVIEW, "TwinView clone Stereo" },
+ { NV_CTRL_STEREO_PASSIVE_EYE_PER_DPY, "Passive One-Eye-per-Display Stereo" },
{ NV_CTRL_STEREO_VERTICAL_INTERLACED, "Vertical Interlaced Stereo" },
{ NV_CTRL_STEREO_COLOR_INTERLACED, "Color Interleaved Stereo" },
{ NV_CTRL_STEREO_HORIZONTAL_INTERLACED, "Horizontal Interlaced Stereo" },
@@ -104,39 +104,73 @@ GType ctk_screen_get_type(
-static gchar *make_display_device_list(NvCtrlAttributeHandle *handle,
- unsigned int display_devices)
+/* Generates a list of display device names for those display devices that
+ * are enabled on the given GPU and, if Xinerama is disabled, are also
+ * associated to the given X screen (handle).
+ */
+static gchar *make_gpu_display_device_list(NvCtrlAttributeHandle *handle,
+ int gpu_id,
+ int xinerama_enabled)
{
gchar *displays = NULL;
gchar *type;
gchar *name;
gchar *tmp_str;
+ unsigned int display_devices;
unsigned int mask;
- ReturnStatus ret;
-
+ Bool valid;
+
+
+ /* Get the list of enabled display devices on the GPU */
+
+ valid =
+ XNVCTRLQueryTargetAttribute(NvCtrlGetDisplayPtr(handle),
+ NV_CTRL_TARGET_TYPE_GPU,
+ gpu_id,
+ 0,
+ NV_CTRL_ENABLED_DISPLAYS,
+ (int *)&display_devices);
+ if (!valid) return NULL;
- /* List of Display Device connected on GPU */
+ /* If Xinerama is disabled, only show displays that are associated
+ * to this X screen.
+ */
+ if (!xinerama_enabled) {
+ ReturnStatus ret;
+ unsigned int associated_devices;
+
+ ret = NvCtrlGetAttribute(handle,
+ NV_CTRL_ASSOCIATED_DISPLAY_DEVICES,
+ (int *)&associated_devices);
+ if (ret == NvCtrlSuccess) {
+ display_devices &= associated_devices;
+ }
+ }
+
+ /* Make the list of display device names */
for (mask = 1; mask; mask <<= 1) {
-
+
if (!(mask & display_devices)) continue;
-
+
type = display_device_mask_to_display_device_name(mask);
name = NULL;
-
- ret =
- NvCtrlGetStringDisplayAttribute(handle,
- mask,
- NV_CTRL_STRING_DISPLAY_DEVICE_NAME,
- &name);
- if (ret != NvCtrlSuccess) {
+
+ valid =
+ XNVCTRLQueryTargetStringAttribute(NvCtrlGetDisplayPtr(handle),
+ NV_CTRL_TARGET_TYPE_GPU,
+ gpu_id,
+ mask,
+ NV_CTRL_STRING_DISPLAY_DEVICE_NAME,
+ &name);
+ if (!valid) {
tmp_str = g_strdup_printf("Unknown (%s)", type);
} else {
tmp_str = g_strdup_printf("%s (%s)", name, type);
XFree(name);
}
free(type);
-
+
if (displays) {
name = g_strdup_printf("%s,\n%s", tmp_str, displays);
g_free(displays);
@@ -147,6 +181,60 @@ static gchar *make_display_device_list(NvCtrlAttributeHandle *handle,
displays = name;
}
+ return displays;
+}
+
+
+
+/* Generates a list of display devices for the logical X screen
+ * given as "handle".
+ */
+static gchar *make_display_device_list(NvCtrlAttributeHandle *handle)
+{
+ ReturnStatus ret;
+ int len;
+ int i;
+ int *pData;
+ gchar *displays = NULL;
+ int xinerama_enabled;
+
+
+ /* See if Xinerama is enabled */
+ ret = NvCtrlGetAttribute(handle, NV_CTRL_XINERAMA, &xinerama_enabled);
+ if (ret != NvCtrlSuccess) {
+ goto done;
+ }
+
+ /* Get all GPUs driving this X screen */
+ ret = NvCtrlGetBinaryAttribute(handle,
+ 0,
+ NV_CTRL_BINARY_DATA_GPUS_USED_BY_LOGICAL_XSCREEN,
+ (unsigned char **)(&pData),
+ &len);
+ if (ret != NvCtrlSuccess) {
+ goto done;
+ }
+
+ /* Generate the list of display device names that display this X screen */
+ for (i = 1; i <= pData[0]; i++) {
+ gchar *new_str;
+ gchar *tmp_str;
+
+ new_str = make_gpu_display_device_list(handle, pData[i],
+ xinerama_enabled);
+ if (new_str) {
+ if (displays) {
+ tmp_str = g_strdup_printf("%s,\n%s", displays, new_str);
+ g_free(displays);
+ g_free(new_str);
+ displays = tmp_str;
+ } else {
+ displays = new_str;
+ }
+ }
+ }
+
+ done:
if (!displays) {
displays = g_strdup("None");
}
@@ -224,8 +312,6 @@ GtkWidget* ctk_screen_new(NvCtrlAttributeHandle *handle,
double xres, yres;
- unsigned int display_devices;
-
int *pData;
int len;
int i;
@@ -308,12 +394,7 @@ GtkWidget* ctk_screen_new(NvCtrlAttributeHandle *handle,
/* get the list of Display Devices displaying this X screen */
- displays = NULL;
- ret = NvCtrlGetAttribute(handle, NV_CTRL_ASSOCIATED_DISPLAY_DEVICES,
- (int *)&display_devices);
- if (ret == NvCtrlSuccess) {
- displays = make_display_device_list(handle, display_devices);
- }
+ displays = make_display_device_list(handle);
/* get the number of gpu errors occurred */
@@ -522,12 +603,10 @@ void ctk_screen_event_handler(GtkWidget *widget,
static void associated_displays_received(GtkObject *object, gpointer arg1,
gpointer user_data)
{
- CtkEventStruct *event_struct = (CtkEventStruct *) arg1;
CtkScreen *ctk_object = CTK_SCREEN(user_data);
- unsigned int associated_displays = event_struct->value;
gchar *str;
- str = make_display_device_list(ctk_object->handle, associated_displays);
+ str = make_display_device_list(ctk_object->handle);
gtk_label_set_text(GTK_LABEL(ctk_object->displays), str);
diff --git a/src/gtk+-2.x/ctkslimm.c b/src/gtk+-2.x/ctkslimm.c
index 7566614..fc8f896 100644
--- a/src/gtk+-2.x/ctkslimm.c
+++ b/src/gtk+-2.x/ctkslimm.c
@@ -1248,6 +1248,8 @@ GtkWidget* ctk_slimm_new(NvCtrlAttributeHandle *handle,
gchar *tmp;
gchar *sli_mode = NULL;
ReturnStatus ret;
+ ReturnStatus ret1;
+ int major = 0, minor = 0;
gint val;
nvLayoutPtr layout;
@@ -1258,6 +1260,8 @@ GtkWidget* ctk_slimm_new(NvCtrlAttributeHandle *handle,
int count;
Bool valid_layout = FALSE;
+ Bool trust_slimm_available = FALSE;
+ int vcs_target_count;
int hoverlap = 0;
int voverlap = 0;
@@ -1273,7 +1277,29 @@ GtkWidget* ctk_slimm_new(NvCtrlAttributeHandle *handle,
ctk_slimm->handle = handle;
ctk_slimm->ctk_config = ctk_config;
ctk_object = ctk_slimm;
+
+ /*
+ * Check for NV-CONTROL protocol version.
+ * This used for not trust old X drivers which always reported
+ * it available (on NV50+).
+ */
+ ret = NvCtrlGetAttribute(handle,
+ NV_CTRL_ATTR_NV_MAJOR_VERSION, &major);
+ ret1 = NvCtrlGetAttribute(handle,
+ NV_CTRL_ATTR_NV_MINOR_VERSION, &minor);
+
+ if ((ret == NvCtrlSuccess) && (ret1 == NvCtrlSuccess) &&
+ ((major > 1) || ((major == 1) && (minor > 23)))) {
+ trust_slimm_available = TRUE;
+ }
+ vcs_target_count = ctk_config->pCtrlHandles->targets[VCS_TARGET].n;
+
+ /* return on old X drivers if target is other than VCS. */
+ if (!vcs_target_count && !trust_slimm_available) {
+ return NULL;
+ }
+
/* Check if this screen supports SLI Mosaic Mode */
ret = NvCtrlGetAttribute(ctk_object->handle,
NV_CTRL_SLI_MOSAIC_MODE_AVAILABLE, &val);
diff --git a/src/gtk+-2.x/ctkwindow.c b/src/gtk+-2.x/ctkwindow.c
index d14b6bf..11daaa2 100644
--- a/src/gtk+-2.x/ctkwindow.c
+++ b/src/gtk+-2.x/ctkwindow.c
@@ -638,7 +638,7 @@ GtkWidget *ctk_window_new(ParsedAttribute *p, ConfigProperties *conf,
CTK_WINDOW_CONFIG_FILE_ATTRIBUTES_FUNC_COLUMN,
NULL, -1);
- if (h->targets[VCS_TARGET].n && !slimm_page_added) {
+ if (!slimm_page_added) {
/* SLI Mosaic Mode information */
child = ctk_slimm_new(screen_handle, ctk_event, ctk_config);
diff --git a/src/gtk+-2.x/src.mk b/src/gtk+-2.x/src.mk
index c867aa6..4b7ad45 100644
--- a/src/gtk+-2.x/src.mk
+++ b/src/gtk+-2.x/src.mk
@@ -21,6 +21,7 @@ GTK_SRC += ctkimagesliders.c
GTK_SRC += ctkdisplaydevice-crt.c
GTK_SRC += ctkdisplaydevice-tv.c
GTK_SRC += ctkdisplaydevice-dfp.c
+GTK_SRC += ctkditheringcontrols.c
GTK_SRC += ctkthermal.c
GTK_SRC += ctkpowermizer.c
GTK_SRC += ctkgvo.c
@@ -45,6 +46,7 @@ GTK_SRC += ctkpowersavings.c
GTK_SRC += ctkgvi.c
GTK_SRC += ctklicense.c
GTK_SRC += ctkecc.c
+GTK_SRC += ctkcolorcontrols.c
GTK_EXTRA_DIST += ctkxvideo.h
GTK_EXTRA_DIST += ctkcursorshadow.h
@@ -65,6 +67,7 @@ GTK_EXTRA_DIST += ctkimagesliders.h
GTK_EXTRA_DIST += ctkdisplaydevice-crt.h
GTK_EXTRA_DIST += ctkdisplaydevice-tv.h
GTK_EXTRA_DIST += ctkdisplaydevice-dfp.h
+GTK_EXTRA_DIST += ctkditheringcontrols.h
GTK_EXTRA_DIST += ctkconstants.h
GTK_EXTRA_DIST += ctkthermal.h
GTK_EXTRA_DIST += ctkpowermizer.h
@@ -90,4 +93,5 @@ GTK_EXTRA_DIST += ctkgvo-sync.h
GTK_EXTRA_DIST += ctkgvi.h
GTK_EXTRA_DIST += ctklicense.h
GTK_EXTRA_DIST += ctkecc.h
+GTK_EXTRA_DIST += ctkcolorcontrols.h
GTK_EXTRA_DIST += src.mk
diff --git a/src/libXNVCtrl/NVCtrl.h b/src/libXNVCtrl/NVCtrl.h
index 180b4c7..45d976d 100644
--- a/src/libXNVCtrl/NVCtrl.h
+++ b/src/libXNVCtrl/NVCtrl.h
@@ -152,14 +152,8 @@
/*
- * NV_CTRL_FLATPANEL_DITHERING - the current flat panel dithering
- * state; possible values are:
- *
- * 0: default (the driver will decide when to dither)
- * 1: enabled (the driver will always dither when possible)
- * 2: disabled (the driver will never dither)
- *
- * USAGE NOTE: This attribute had been deprecated.
+ * NV_CTRL_FLATPANEL_DITHERING is deprecated; NV_CTRL_DITHERING should
+ * be used instead.
*/
#define NV_CTRL_FLATPANEL_DITHERING 3 /* RWDG */
@@ -167,6 +161,20 @@
#define NV_CTRL_FLATPANEL_DITHERING_ENABLED 1
#define NV_CTRL_FLATPANEL_DITHERING_DISABLED 2
+/*
+ * NV_CTRL_DITHERING - the requested dithering configuration;
+ * possible values are:
+ *
+ * 0: auto (the driver will decide when to dither)
+ * 1: enabled (the driver will always dither when possible)
+ * 2: disabled (the driver will never dither)
+ */
+
+#define NV_CTRL_DITHERING 3 /* RWDG */
+#define NV_CTRL_DITHERING_AUTO 0
+#define NV_CTRL_DITHERING_ENABLED 1
+#define NV_CTRL_DITHERING_DISABLED 2
+
/*
* NV_CTRL_DIGITAL_VIBRANCE - sets the digital vibrance level for the
@@ -323,7 +331,7 @@
#define NV_CTRL_STEREO_DDC 1
#define NV_CTRL_STEREO_BLUELINE 2
#define NV_CTRL_STEREO_DIN 3
-#define NV_CTRL_STEREO_TWINVIEW 4
+#define NV_CTRL_STEREO_PASSIVE_EYE_PER_DPY 4
#define NV_CTRL_STEREO_VERTICAL_INTERLACED 5
#define NV_CTRL_STEREO_COLOR_INTERLACED 6
#define NV_CTRL_STEREO_HORIZONTAL_INTERLACED 7
@@ -2844,7 +2852,7 @@
#define NV_CTRL_GPU_CORES 345 /* R--G */
-/*
+/*
* NV_CTRL_GPU_MEMORY_BUS_WIDTH - Returns memory bus bandwidth on the associated
* subdevice.
*/
@@ -2863,6 +2871,22 @@
#define NV_CTRL_GVI_TEST_MODE_DISABLE 0
#define NV_CTRL_GVI_TEST_MODE_ENABLE 1
+/*
+ * NV_CTRL_COLOR_SPACE - This option sets color space of the video
+ * signal.
+ */
+#define NV_CTRL_COLOR_SPACE 348 /* RWDG */
+#define NV_CTRL_COLOR_SPACE_RGB 0
+#define NV_CTRL_COLOR_SPACE_YCbCr422 1
+#define NV_CTRL_COLOR_SPACE_YCbCr444 2
+
+/*
+ * NV_CTRL_COLOR_RANGE - This option sets color range of the video
+ * signal.
+ */
+#define NV_CTRL_COLOR_RANGE 349 /* RWDG */
+#define NV_CTRL_COLOR_RANGE_FULL 0
+#define NV_CTRL_COLOR_RANGE_LIMITED 1
/*
* NV_CTRL_GPU_SCALING_DEFAULT_TARGET - Returns the default scaling target
@@ -2877,6 +2901,40 @@
#define NV_CTRL_GPU_SCALING_DEFAULT_TARGET 350 /* R-DG */
#define NV_CTRL_GPU_SCALING_DEFAULT_METHOD 351 /* R-DG */
+/*
+ * NV_CTRL_DITHERING_MODE - Controls the dithering mode, when
+ * NV_CTRL_CURRENT_DITHERING is Enabled.
+ *
+ * AUTO: allow the driver to choose the dithering mode automatically.
+ *
+ * DYNAMIC_2X2: use a 2x2 matrix to dither from the GPU's pixel
+ * pipeline to the bit depth of the flat panel. The matrix values
+ * are changed from frame to frame.
+ *
+ * STATIC_2X2: use a 2x2 matrix to dither from the GPU's pixel
+ * pipeline to the bit depth of the flat panel. The matrix values
+ * do not change from frame to frame.
+ */
+#define NV_CTRL_DITHERING_MODE 352 /* RWDG */
+#define NV_CTRL_DITHERING_MODE_AUTO 0
+#define NV_CTRL_DITHERING_MODE_DYNAMIC_2X2 1
+#define NV_CTRL_DITHERING_MODE_STATIC_2X2 2
+
+/*
+ * NV_CTRL_CURRENT_DITHERING - Returns the current dithering state.
+ */
+#define NV_CTRL_CURRENT_DITHERING 353 /* R-DG */
+#define NV_CTRL_CURRENT_DITHERING_DISABLED 0
+#define NV_CTRL_CURRENT_DITHERING_ENABLED 1
+
+/*
+ * NV_CTRL_CURRENT_DITHERING_MODE - Returns the current dithering
+ * mode.
+ */
+#define NV_CTRL_CURRENT_DITHERING_MODE 354 /* R-DG */
+#define NV_CTRL_CURRENT_DITHERING_MODE_NONE 0
+#define NV_CTRL_CURRENT_DITHERING_MODE_DYNAMIC_2X2 1
+#define NV_CTRL_CURRENT_DITHERING_MODE_STATIC_2X2 2
/*
* NV_CTRL_THERMAL_SENSOR_READING - Returns the thermal sensor's current
@@ -2961,7 +3019,6 @@
(NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_3G_LEVEL_B))
#define NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_3G_1080P_NO_12BPC 0x00000020
-
/*
* NV_CTRL_GPU_PCIE_MAX_LINK_SPEED - returns maximum PCI-E link speed.
*/
@@ -3358,8 +3415,8 @@
*
* Token Value
* "perf" integer - the Performance level
- * "nvClock" integer - the GPU clocks (in MHz) for the perf level
- * "memClock" integer - the memory clocks (in MHz) for the perf level
+ * "nvclock" integer - the GPU clocks (in MHz) for the perf level
+ * "memclock" integer - the memory clocks (in MHz) for the perf level
*
*
* Example:
@@ -3471,8 +3528,40 @@
*/
#define NV_CTRL_STRING_GVO_VIDEO_FORMAT_NAME 33 /* R--- */
+
+/*
+ * NV_CTRL_STRING_GPU_CURRENT_CLOCK_FREQS - returns a string with the
+ * associated NV Clock, Memory Clock and Processor Clock values.
+ *
+ * Current valid tokens are "nvclock", "memclock", and "processorclock".
+ * Not all tokens will be reported on all GPUs, and additional tokens
+ * may be added in the future.
+ *
+ * Clock values are returned as a comma-separated list of
+ * "token=value" pairs.
+ * Valid tokens:
+ *
+ * Token Value
+ * "nvclock" integer - the GPU clocks (in MHz) for the current
+ * perf level
+ * "memclock" integer - the memory clocks (in MHz) for the current
+ * perf level
+ * "processorclock" integer - the processor clocks (in MHz) for the perf level
+ *
+ *
+ * Example:
+ *
+ * nvclock=459, memclock=400, processorclock=918
+ *
+ * This attribute may be queried through XNVCTRLQueryTargetStringAttribute()
+ * using an NV_CTRL_TARGET_TYPE_GPU or NV_CTRL_TARGET_TYPE_X_SCREEN target.
+ */
+
+#define NV_CTRL_STRING_GPU_CURRENT_CLOCK_FREQS 34 /* RW-G */
+
+
#define NV_CTRL_STRING_LAST_ATTRIBUTE \
- NV_CTRL_STRING_GVIO_VIDEO_FORMAT_NAME
+ NV_CTRL_STRING_GPU_CURRENT_CLOCK_FREQS
/**************************************************************************/
diff --git a/src/libXNVCtrl/nv_control.h b/src/libXNVCtrl/nv_control.h
index 97229f9..a6b8546 100644
--- a/src/libXNVCtrl/nv_control.h
+++ b/src/libXNVCtrl/nv_control.h
@@ -46,8 +46,10 @@
* 1.20 Added COOLER TargetType
* 1.21 Added initial 64-bit integer attribute support (read-only)
* 1.22 Added X_nvCtrlQueryValidStringAttributeValues to check
- * string attribute permissions.
+ * string attribute permissions.
* 1.23 Added SENSOR TargetType
+ * 1.24 Fixed a bug where SLI_MOSAIC_MODE_AVAILABLE attribute would
+ * report false positives via the GPU and X screen target types
*/
#ifndef __NVCONTROL_H
@@ -58,7 +60,7 @@
#define NV_CONTROL_NAME "NV-CONTROL"
#define NV_CONTROL_MAJOR 1
-#define NV_CONTROL_MINOR 23
+#define NV_CONTROL_MINOR 24
#define X_nvCtrlQueryExtension 0
#define X_nvCtrlIsNv 1
diff --git a/src/msg.c b/src/msg.c
index a176cd2..eb295c3 100644
--- a/src/msg.c
+++ b/src/msg.c
@@ -38,15 +38,15 @@
extern int __verbosity;
-static void format(FILE*, const char*, char *);
+static void format(FILE*, const char*, char *, int);
static int get_terminal_width(void);
-#define NV_FORMAT(stream, prefix, fmt) \
-do { \
- char *buf; \
- NV_VSNPRINTF(buf, fmt); \
- format(stream, prefix, buf); \
- free (buf); \
+#define NV_FORMAT(stream, prefix, fmt, whitespace) \
+do { \
+ char *buf; \
+ NV_VSNPRINTF(buf, fmt); \
+ format(stream, prefix, buf, whitespace); \
+ free (buf); \
} while(0)
/*
@@ -62,7 +62,7 @@ void nv_error_msg(const char *fmt, ...)
fprintf(stderr, "\n");
- NV_FORMAT(stderr, "ERROR: ", fmt);
+ NV_FORMAT(stderr, "ERROR: ", fmt, False);
fprintf(stderr, "\n");
@@ -83,7 +83,7 @@ void nv_warning_msg(const char *fmt, ...)
fprintf(stdout, "\n");
- NV_FORMAT(stdout, "WARNING: ", fmt);
+ NV_FORMAT(stdout, "WARNING: ", fmt, False);
fprintf(stdout, "\n");
@@ -102,7 +102,7 @@ void nv_info_msg(const char *prefix, const char *fmt, ...)
{
if (__verbosity < VERBOSITY_ALL) return;
- NV_FORMAT(stdout, prefix, fmt);
+ NV_FORMAT(stdout, prefix, fmt, False);
} /* nv_info_msg() */
@@ -118,11 +118,23 @@ void nv_info_msg(const char *prefix, const char *fmt, ...)
void nv_msg(const char *prefix, const char *fmt, ...)
{
- NV_FORMAT(stdout, prefix, fmt);
+ NV_FORMAT(stdout, prefix, fmt, False);
} /* nv_msg() */
+/*
+ * nv_msg_preserve_whitespace() - Prints the message, just like nv_msg()
+ * using format(), the difference is, whitespace characters are not
+ * skipped during the text processing.
+ */
+
+void nv_msg_preserve_whitespace(const char *prefix, const char *fmt, ...)
+{
+ NV_FORMAT(stdout, prefix, fmt, True);
+
+} /* nv_msg_preserve_whitespace() */
+
/*
* XXX gcc's '-ansi' option causes vsnprintf to not be defined, so
@@ -142,7 +154,7 @@ int vsnprintf(char *str, size_t size, const char *format,
*/
static void format(FILE *stream, const char *prefix,
- char *buf)
+ char *buf, int preserveWhitespace)
{
int len, prefix_len, z, w, i, max_width;
char *line, *local_prefix, *a, *b, *c;
@@ -224,9 +236,10 @@ static void format(FILE *stream, const char *prefix,
z -= (b - a + 1);
a = b + 1;
- /* move to the first non whitespace character */
-
- while ((z > 0) && (isspace(*a))) a++, z--;
+ if (!preserveWhitespace) {
+ /* move to the first non whitespace character */
+ while ((z > 0) && (isspace(*a))) a++, z--;
+ }
if (local_prefix) {
for (i = 0; i < prefix_len; i++) local_prefix[i] = ' ';
diff --git a/src/msg.h b/src/msg.h
index e710f9f..613944c 100644
--- a/src/msg.h
+++ b/src/msg.h
@@ -32,6 +32,7 @@ void nv_error_msg(const char*, ...);
void nv_warning_msg(const char*, ...);
void nv_info_msg(const char*, const char*, ...);
void nv_msg(const char*, const char*, ...);
+void nv_msg_preserve_whitespace(const char*, const char*, ...);
/*
* NV_VSNPRINTF(): macro that assigns buf using vsnprintf(). This is
diff --git a/src/nvgetopt.h b/src/nvgetopt.h
deleted file mode 100644
index d1cbcc8..0000000
--- a/src/nvgetopt.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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 __NVGETOPT_H__
-#define __NVGETOPT_H__
-
-#define NVGETOPT_FALSE 0
-#define NVGETOPT_TRUE 1
-#define NVGETOPT_INVALID 2
-
-#define NVGETOPT_HAS_ARGUMENT 0x1
-#define NVGETOPT_IS_BOOLEAN 0x2
-#define NVGETOPT_ARGUMENT_IS_OPTIONAL 0x4
-
-typedef struct {
- const char *name;
- int val;
- unsigned int flags;
- void (*print_description)(void); /* not used by nvgetopt() */
- char *description; /* not used by nvgetopt() */
-} NVGetoptOption;
-
-int nvgetopt(int argc, char *argv[], const NVGetoptOption *options,
- char **strval, int *boolval);
-
-#endif /* __NVGETOPT_H__ */
diff --git a/src/option-table.h b/src/option-table.h
new file mode 100644
index 0000000..c28f44c
--- /dev/null
+++ b/src/option-table.h
@@ -0,0 +1,156 @@
+/*
+ * nvidia-settings: A tool for configuring the NVIDIA X driver on Unix
+ * and Linux systems.
+ *
+ * Copyright (C) 2010 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 __OPTION_TABLE_H__
+#define __OPTION_TABLE_H__
+
+#include "nvgetopt.h"
+#include "command-line.h"
+
+#define TAB " "
+#define BIGTAB " "
+
+/*
+ * Options table; see nvgetopt.h for a description of the fields.
+ */
+
+static const NVGetoptOption __options[] = {
+ { "version", 'v', 0, NULL,
+ "Print the <nvidia-settings> version and exit." },
+
+ { "help", 'h', 0, NULL,
+ "Print usage information and exit." },
+
+ { "config", CONFIG_FILE_OPTION, NVGETOPT_STRING_ARGUMENT, NULL,
+ "Use the configuration file ^CONFIG> rather than the "
+ "default ^" DEFAULT_RC_FILE ">" },
+
+ { "ctrl-display", 'c', NVGETOPT_STRING_ARGUMENT, NULL,
+ "Control the specified X display. If this option is not given, then "
+ "<nvidia-settings> will control the display specified by <'--display'>; "
+ "if that is not given, then the ^$DISPLAY> environment variable is used." },
+
+ { "load-config-only", 'l', 0, NULL,
+ "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." },
+
+ { "no-config", 'n', 0, NULL,
+ "Do not load the configuration file. This mode of operation is useful "
+ "if <nvidia-settings> has difficulties starting due to problems with "
+ "applying settings in the configuration file." },
+
+ { "rewrite-config-file", 'r', 0, NULL,
+ "Write the X server configuration to the configuration file, and exit, "
+ "without starting the graphical user interface. See EXAMPLES section." },
+
+ { "verbose", 'V',
+ NVGETOPT_STRING_ARGUMENT | NVGETOPT_ARGUMENT_IS_OPTIONAL, NULL,
+ "Controls how much information is printed. By default, the verbosity "
+ "is <errors> and only error messages are printed. Valid values are "
+ "<'errors'> (print error messages), <'warnings'> (print error and "
+ "warning messages), and <'all'> (print error, warning and other "
+ "informational messages)." },
+
+ { "assign", 'a', NVGETOPT_STRING_ARGUMENT, NULL,
+ "The ^ASSIGN> argument to the <'--assign'> command line option is of the "
+ "form:\n"
+ "\n"
+ TAB "{DISPLAY}/{attribute name}[{display devices}]={value}\n"
+ "\n"
+ "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 <--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.\n"
+ "\n"
+ "{DISPLAY} can additionally include a target specification to direct "
+ "an assignment to something other than an X screen. A target "
+ "specification is contained within brackets and consists of a target "
+ "type name, a colon, and the target id. The target type name can be "
+ "one of <\"screen\", \"gpu\", \"framelock\", \"vcs\", \"gvi\",> or "
+ "<\"fan\";> the target id is the index into the list of targets "
+ "(for that target type). The target specification can be used in "
+ "{DISPLAY} wherever an X screen can be used, following the syntax "
+ "{host}:{display}[{target_type}:{target_id}]. See the output of\n"
+ "\n"
+ TAB "nvidia-settings -q all \n"
+ "\n"
+ "for information on which target types can be used with which "
+ "attributes. See the output of\n"
+ "\n"
+ TAB " nvidia-settings -q screens -q gpus -q framelocks -q vcs -q gvis "
+ "-q fans \n"
+ "\n"
+ "for lists of targets for each target type.\n"
+ "\n"
+ "The [{display devices}] portion is also optional; if it is not "
+ "specified, then the attribute is assigned to all display devices.\n"
+ "\n"
+ "Some examples:\n"
+ "\n"
+ TAB "-a FSAA=5\n"
+ TAB "-a localhost:0.0/DigitalVibrance[CRT-0]=0\n"
+ TAB "--assign=\"SyncToVBlank=1\"\n"
+ TAB "-a [gpu:0]/DigitalVibrance[DFP-1]=63\n" },
+
+ { "query", 'q', NVGETOPT_STRING_ARGUMENT, NULL,
+ "The ^QUERY> argument to the <'--query'> command line option is of the "
+ "form:\n"
+ "\n"
+ TAB "{DISPLAY}/{attribute name}[{display devices}]\n"
+ "\n"
+ "This queries the current value of the attribute {attribute name} on the "
+ "X Display {DISPLAY}. The syntax is the same as that for the "
+ "<'--assign'> option, without '=<{value}'>; specify <'-q screens', "
+ "'-q gpus', '-q framelocks', '-q vcs', '-q gvis', or '-q fans'> to "
+ "query a list of X screens, GPUs, Frame Lock devices, Visual Computing "
+ "Systems, SDI Input Devices, or Fans, respectively, that are present "
+ "on the X Display {DISPLAY}. Specify <'-q all'> to query all attributes." },
+
+ { "terse", 't', 0, NULL,
+ "When querying attribute values with the '--query' command line option, "
+ "only print the current value, rather than the more verbose description "
+ "of the attribute, its valid values, and its current value." },
+
+ { "display-device-string", 'd', 0, NULL,
+ "When printing attribute values in response to the '--query' option, "
+ "if the attribute value is a display device mask, print the value "
+ "as a list of display devices (e.g., \"CRT-0, DFP-0\"), rather than "
+ "a hexadecimal bit mask (e.g., 0x00010001)." },
+
+ { "glxinfo", 'g', 0, NULL,
+ "Print GLX Information for the X display and exit." },
+
+ { "describe", 'e', NVGETOPT_STRING_ARGUMENT, NULL,
+ "Prints information about a particular attribute. Specify 'all' to "
+ "list the descriptions of all attributes. Specify 'list' to list the "
+ "attribute names without a descriptions." },
+
+ { NULL, 0, 0, NULL, NULL},
+};
+
+#endif //_OPTION_TABLE_H
diff --git a/src/parse.c b/src/parse.c
index 3e66013..1232947 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -64,6 +64,7 @@ static char *nv_strndup(char *s, int n);
#define S NV_PARSER_TYPE_STRING_ATTRIBUTE
#define I NV_PARSER_TYPE_SDI
#define W NV_PARSER_TYPE_VALUE_IS_SWITCH_DISPLAY
+#define M NV_PARSER_TYPE_SDI_CSC
AttributeTableEntry attributeTable[] = {
@@ -148,6 +149,8 @@ AttributeTableEntry attributeTable[] = {
{ "GPUDefault2DClockFreqs", NV_CTRL_GPU_DEFAULT_2D_CLOCK_FREQS, N|P, "Returns the default memory and GPU core clocks when operating in 2D mode." },
{ "GPUDefault3DClockFreqs", NV_CTRL_GPU_DEFAULT_3D_CLOCK_FREQS, N|P, "Returns the default memory and GPU core clocks when operating in 3D mode." },
{ "GPUCurrentClockFreqs", NV_CTRL_GPU_CURRENT_CLOCK_FREQS, N|P, "Returns the current GPU and memory clocks of the graphics device driving the X screen." },
+ { "GPUCurrentProcessorClockFreqs", NV_CTRL_GPU_CURRENT_PROCESSOR_CLOCK_FREQS, N, "Returns the current processor clock of the graphics device driving the X screen." },
+ { "GPUCurrentClockFreqsString", NV_CTRL_STRING_GPU_CURRENT_CLOCK_FREQS, S|N, "Returns the current GPU, memory and Processor clocks of the graphics device driving the X screen." },
{ "BusRate", NV_CTRL_BUS_RATE, 0, "If the device is on an AGP bus, then BusRate returns the configured AGP rate. If the device is on a PCI Express bus, then this attribute returns the width of the physical link." },
{ "PCIDomain", NV_CTRL_PCI_DOMAIN, N, "Returns the PCI domain number for the specified device." },
{ "PCIBus", NV_CTRL_PCI_BUS, N, "Returns the PCI bus number for the specified device." },
@@ -256,6 +259,7 @@ AttributeTableEntry attributeTable[] = {
{ "GviNumCaptureSurfaces", NV_CTRL_GVI_NUM_CAPTURE_SURFACES, I|N, "Controls the number of capture buffers for storing incoming video from the GVI device." },
{ "GviBoundGpu", NV_CTRL_GVI_BOUND_GPU, I|N, "Returns the target index of the GPU currently attached to the GVI device." },
{ "GviTestMode", NV_CTRL_GVI_TEST_MODE, I|N, "Enable or disable GVI test mode." },
+ { "GvoCSCMatrix", 0, I|M|N, "Sets the GVO Color Space Conversion (CSC) matrix. Accepted values are \"ITU_601\", \"ITU_709\", \"ITU_177\", and \"Identity\"." },
/* Display */
{ "Brightness", BRIGHTNESS_VALUE|ALL_CHANNELS, N|C|G, "Controls the overall brightness of the display." },
@@ -270,7 +274,10 @@ AttributeTableEntry attributeTable[] = {
{ "RedGamma", GAMMA_VALUE|RED_CHANNEL, C|G, "Controls the gamma of the color red in the display." },
{ "GreenGamma", GAMMA_VALUE|GREEN_CHANNEL, C|G, "Controls the gamma of the color green in the display." },
{ "BlueGamma", GAMMA_VALUE|BLUE_CHANNEL, C|G, "Controls the gamma of the color blue in the display." },
- { "FlatpanelDithering", NV_CTRL_FLATPANEL_DITHERING, 0, "This is the current state of flat panel dithering. This attribute has been deprecated." },
+ { "Dithering", NV_CTRL_DITHERING, 0, "Controls the dithering: auto (0), enabled (1), disabled (2)." },
+ { "CurrentDithering", NV_CTRL_CURRENT_DITHERING, 0, "Returns the current dithering state: enabled (1), disabled (0)." },
+ { "DitheringMode", NV_CTRL_DITHERING_MODE, 0, "Controls the dithering mode when CurrentDithering=1; auto (0), temporally dynamic dithering pattern (1), temporally static dithering pattern (2)." },
+ { "CurrentDitheringMode", NV_CTRL_CURRENT_DITHERING_MODE, 0, "Returns the current dithering mode: none (0), temporally dynamic dithering pattern (1), temporally static dithering pattern (2)." },
{ "DigitalVibrance", NV_CTRL_DIGITAL_VIBRANCE, 0, "Sets the digital vibrance level of the display device." },
{ "ImageSharpening", NV_CTRL_IMAGE_SHARPENING, 0, "Adjusts the sharpness of the display's image quality by amplifying high frequency content." },
{ "ImageSharpeningDefault", NV_CTRL_IMAGE_SHARPENING_DEFAULT, 0, "Returns default value of image sharpening." },
@@ -286,6 +293,8 @@ AttributeTableEntry attributeTable[] = {
{ "RefreshRate", NV_CTRL_REFRESH_RATE, N|H, "Returns the refresh rate of the specified display device in cHz (Centihertz) (to get the refresh rate in Hz, divide the returned value by 100)." },
{ "RefreshRate3", NV_CTRL_REFRESH_RATE_3, N|K, "Returns the refresh rate of the specified display device in mHz (Millihertz) (to get the refresh rate in Hz, divide the returned value by 1000)." },
{ "OverscanCompensation", NV_CTRL_OVERSCAN_COMPENSATION, 0, "Adjust the amount of overscan compensation scaling, in pixels, to apply to the specified display device." },
+ { "ColorSpace", NV_CTRL_COLOR_SPACE, 0, "Sets the color space of the signal sent to the display device." },
+ { "ColorRange", NV_CTRL_COLOR_RANGE, 0, "Sets the color range of the signal sent to the display device." },
/* TV */
{ "TVOverScan", NV_CTRL_TV_OVERSCAN, 0, "Adjusts the amount of overscan on the specified display device." },
@@ -308,7 +317,7 @@ AttributeTableEntry attributeTable[] = {
{ "XVideoTextureSyncToVBlank", NV_CTRL_ATTR_XV_TEXTURE_SYNC_TO_VBLANK, V, "Enables sync to vertical blanking for X video texture adaptor." },
{ "XVideoBlitterSyncToVBlank", NV_CTRL_ATTR_XV_BLITTER_SYNC_TO_VBLANK, V, "Enables sync to vertical blanking for X video blitter adaptor." },
{ "XVideoSyncToDisplay", NV_CTRL_XV_SYNC_TO_DISPLAY, D|Z, "Controls which display device is synced to by the texture and blitter adaptors when they are set to synchronize to the vertical blanking." },
-
+
{ NULL, 0, 0, NULL }
};
@@ -409,6 +418,48 @@ TargetTypeEntry targetTypeTable[] = {
/*
+ * nv_get_sdi_csc_matrix() - see comments in parse.h
+ */
+
+static const float sdi_csc_itu601[15] = {
+ 0.2991, 0.5870, 0.1150, 0.0625, 0.85547, // Y
+ 0.5000, -0.4185, -0.0810, 0.5000, 0.87500, // Cr
+ -0.1685, -0.3310, 0.5000, 0.5000, 0.87500, // Cb
+};
+static const float sdi_csc_itu709[15] = {
+ 0.2130, 0.7156, 0.0725, 0.0625, 0.85547, // Y
+ 0.5000, -0.4542, -0.0455, 0.5000, 0.87500, // Cr
+ -0.1146, -0.3850, 0.5000, 0.5000, 0.87500, // Cb
+};
+static const float sdi_csc_itu177[15] = {
+ 0.412391, 0.357584, 0.180481, 0.0, 0.85547, // Y
+ 0.019331, 0.119195, 0.950532, 0.0, 0.87500, // Cr
+ 0.212639, 0.715169, 0.072192, 0.0, 0.87500, // Cb
+};
+static const float sdi_csc_identity[15] = {
+ 0.0000, 1.0000, 0.0000, 0.0000, 1.0, // Y (Green)
+ 1.0000, 0.0000, 0.0000, 0.0000, 1.0, // Cr (Red)
+ 0.0000, 0.0000, 1.0000, 0.0000, 1.0, // Cb (Blue)
+};
+
+const float * nv_get_sdi_csc_matrix(char *s)
+{
+ if (nv_strcasecmp(s, "itu_601")) {
+ return sdi_csc_itu601;
+ } else if (nv_strcasecmp(s, "itu_709")) {
+ return sdi_csc_itu709;
+ } else if (nv_strcasecmp(s, "itu_177")) {
+ return sdi_csc_itu177;
+ } else if (nv_strcasecmp(s, "identity")) {
+ return sdi_csc_identity;
+ }
+
+ return NULL;
+}
+
+
+
+/*
* nv_parse_attribute_string() - see comments in parse.h
*/
@@ -542,6 +593,10 @@ int nv_parse_attribute_string(const char *str, int query, ParsedAttribute *a)
a->val = strtol(s, &tmp, 0);
}
}
+ } else if (a->flags & NV_PARSER_TYPE_SDI_CSC) {
+ /* String that names a standard CSC matrix */
+ a->pfval = nv_get_sdi_csc_matrix(s);
+ tmp = s + strlen(s);
} else {
/* all other attributes are integer */
a->val = strtol(s, &tmp, 0);
diff --git a/src/parse.h b/src/parse.h
index 403782d..852e32b 100644
--- a/src/parse.h
+++ b/src/parse.h
@@ -58,6 +58,7 @@
#define NV_PARSER_TYPE_VALUE_IS_SWITCH_DISPLAY (1<<28)
#define NV_PARSER_TYPE_1000Hz (1<<29)
#define NV_PARSER_TYPE_SDI (1<<30)
+#define NV_PARSER_TYPE_SDI_CSC (1<<31)
#define NV_PARSER_ASSIGNMENT 0
#define NV_PARSER_QUERY 1
@@ -123,6 +124,7 @@ typedef struct _ParsedAttribute {
int attr;
int val;
float fval; /* XXX put in a union with val? */
+ const float *pfval; /* XXX put in a union with val? */
uint32 display_device_mask;
uint32 flags;
struct _ParsedAttribute *next;
@@ -189,6 +191,18 @@ typedef struct {
extern TargetTypeEntry targetTypeTable[];
+/* nv_get_sdi_csc_matrxi() - Returns an array of floats that specifies
+ * all the color, offset and scale values for specifing one of the
+ * Standard CSC. 's' is a string that names the matrix values to return.
+ * The values are placed in the float buffer like so:
+ *
+ * { YR, YG, YB, YOffset, YScale,
+ * CrR, CrG, CrB, CrOffset, CrScale,
+ * CbR, CbG, CbB, CbOffset, CbScale }
+ *
+ */
+const float * nv_get_sdi_csc_matrix(char *s);
+
/*
* nv_parse_attribute_string() - this function parses an attribute
* string, the syntax for which is:
diff --git a/src/query-assign.c b/src/query-assign.c
index 64f6d64..61d1df6 100644
--- a/src/query-assign.c
+++ b/src/query-assign.c
@@ -2018,6 +2018,85 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h,
}
}
+ /* Special case the GVO CSC attribute */
+
+ if (a->flags & NV_PARSER_TYPE_SDI_CSC) {
+ float colorMatrix[3][3];
+ float colorOffset[3];
+ float colorScale[3];
+ int r, c;
+
+ if (assign) {
+
+ /* Make sure the standard is known */
+ if (!a->pfval) {
+ nv_error_msg("The attribute '%s' specified %s cannot be "
+ "assigned; valid values are \"ITU_601\", "
+ "\"ITU_709\", \"ITU_177\", and \"Identity\".",
+ a->name, whence);
+ continue;
+ }
+
+ for (r = 0; r < 3; r++) {
+ for (c = 0; c < 3; c++) {
+ colorMatrix[r][c] = a->pfval[r*5 + c];
+ }
+ colorOffset[r] = a->pfval[r*5 + 3];
+ colorScale[r] = a->pfval[r*5 + 4];
+ }
+
+ status = NvCtrlSetGvoColorConversion(t->h,
+ colorMatrix,
+ colorOffset,
+ colorScale);
+ } else {
+ status = NvCtrlGetGvoColorConversion(t->h,
+ colorMatrix,
+ colorOffset,
+ colorScale);
+ }
+
+ if (status != NvCtrlSuccess) {
+ nv_error_msg("The attribute '%s' specified %s cannot be "
+ "%s; error on %s (%s).",
+ a->name, whence,
+ assign ? "assigned" : "queried",
+ t->name, NvCtrlAttributesStrError(status));
+ continue;
+ }
+
+
+ /* Print results */
+ if (!assign) {
+#define INDENT " "
+
+ nv_msg(INDENT, " Red Green Blue Offset Scale");
+ nv_msg(INDENT, "----------------------------------------------------");
+ nv_msg(INDENT, " Y % -0.6f % -0.6f % -0.6f % -0.6f % -0.6f",
+ colorMatrix[0][0],
+ colorMatrix[0][1],
+ colorMatrix[0][2],
+ colorOffset[0],
+ colorScale[0]);
+ nv_msg(INDENT, "Cr % -0.6f % -0.6f % -0.6f % -0.6f % -0.6f",
+ colorMatrix[1][0],
+ colorMatrix[1][1],
+ colorMatrix[1][2],
+ colorOffset[1],
+ colorScale[1]);
+ nv_msg(INDENT, "Cb % -0.6f % -0.6f % -0.6f % -0.6f % -0.6f",
+ colorMatrix[2][0],
+ colorMatrix[2][1],
+ colorMatrix[2][2],
+ colorOffset[2],
+ colorScale[2]);
+#undef INDENT
+ }
+
+ continue;
+ }
+
+
/* loop over the display devices */
for (bit = 0; bit < 24; bit++) {
diff --git a/src/src.mk b/src/src.mk
index 2711f64..dda3891 100644
--- a/src/src.mk
+++ b/src/src.mk
@@ -9,15 +9,15 @@ SRC_SRC += msg.c
SRC_SRC += nvidia-settings.c
SRC_SRC += parse.c
SRC_SRC += query-assign.c
-SRC_SRC += nvgetopt.c
SRC_SRC += glxinfo.c
SRC_EXTRA_DIST += src.mk
SRC_EXTRA_DIST += command-line.h
+SRC_EXTRA_DIST += option-table.h
SRC_EXTRA_DIST += config-file.h
SRC_EXTRA_DIST += lscf.h
SRC_EXTRA_DIST += msg.h
SRC_EXTRA_DIST += parse.h
SRC_EXTRA_DIST += query-assign.h
-SRC_EXTRA_DIST += nvgetopt.h
SRC_EXTRA_DIST += glxinfo.h
+SRC_EXTRA_DIST += gen-manpage-opts.c
diff --git a/utils.mk b/utils.mk
index f14772c..882b6ce 100644
--- a/utils.mk
+++ b/utils.mk
@@ -33,7 +33,8 @@
CC ?= gcc
LD ?= ld
-CFLAGS ?= -Wall -fno-strict-aliasing
+CFLAGS ?=
+CFLAGS += -Wall -fno-strict-aliasing -Wno-unused-parameter
CFLAGS += -O2 -fno-omit-frame-pointer
CC_ONLY_CFLAGS ?=
LDFLAGS ?=
@@ -147,14 +148,15 @@ include $(wildcard $(OUTPUTDIR)/version.mk version.mk)
#
# Arguments:
# $(1): CC command (CC or HOST_CC)
-# $(2): object filename
+# $(2): source filename
+# $(3): object filename
##############################################################################
ifeq ($(NV_AUTO_DEPEND),1)
AUTO_DEP_CMD = && $($(1)) -MM $$(CFLAGS) $$< | $$(SED) \
-e "s,: ,: $$$$\(wildcard ," \
-e "s,\([^\\]\)$$$$,\1)," \
- -e "s;^$$(notdir $(2)): ;$(2): ;" \
+ -e "s;^$$(addsuffix .o,$$(notdir $$(basename $(2)))): ;$(3): ;" \
> $$(@:.o=.d)
else
AUTO_DEP_CMD =
@@ -244,7 +246,7 @@ define DEFINE_OBJECT_RULE_WITH_OBJECT_NAME
$(3): $(2)
@$(MKDIR) $(OUTPUTDIR)
$$(call quiet_cmd,$(1)) -c $$< -o $$@ $$(CFLAGS) \
- $(call AUTO_DEP_CMD,$(1),$(3))
+ $(call AUTO_DEP_CMD,$(1),$(2),$(3))
-include $$(call BUILD_DEPENDENCY_LIST,$(3))
diff --git a/version.mk b/version.mk
index 3ec45a8..9a025b4 100644
--- a/version.mk
+++ b/version.mk
@@ -1 +1 @@
-NVIDIA_VERSION = 256.53
+NVIDIA_VERSION = 260.19.04