summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Plattner <aplattner@nvidia.com>2014-04-08 09:46:52 -0700
committerAaron Plattner <aplattner@nvidia.com>2014-04-08 09:46:52 -0700
commit9cd9e9b40bacf743a206d3a7803f5e3a96cdb59c (patch)
treee830a87f9ed43af13b289adf3bbaec35420867ff
parentce5520370853a9f6a7f1bab625b41d2b4339d1b6 (diff)
337.12337.12
-rw-r--r--doc/version.mk2
-rw-r--r--samples/Makefile19
-rw-r--r--samples/nv-control-dpy.c603
-rw-r--r--samples/nv-control-dvc.c109
-rw-r--r--samples/nv-control-events.c2
-rw-r--r--samples/nv-control-info.c1
-rw-r--r--samples/version.mk2
-rw-r--r--src/Makefile15
-rw-r--r--src/gtk+-2.x/ctk3dvisionpro.c4
-rw-r--r--src/gtk+-2.x/ctkappprofile.c247
-rw-r--r--src/gtk+-2.x/ctkclocks.c2
-rw-r--r--src/gtk+-2.x/ctkcolorcontrols.c4
-rw-r--r--src/gtk+-2.x/ctkcolorcorrection.c282
-rw-r--r--src/gtk+-2.x/ctkcolorcorrection.h6
-rw-r--r--src/gtk+-2.x/ctkcolorcorrectionpage.c4
-rw-r--r--src/gtk+-2.x/ctkcurve.c7
-rw-r--r--src/gtk+-2.x/ctkcurve.h1
-rw-r--r--src/gtk+-2.x/ctkdisplayconfig.c526
-rw-r--r--src/gtk+-2.x/ctkdisplaydevice.c44
-rw-r--r--src/gtk+-2.x/ctkdisplaylayout.c22
-rw-r--r--src/gtk+-2.x/ctkdisplaylayout.h2
-rw-r--r--src/gtk+-2.x/ctkditheringcontrols.c6
-rw-r--r--src/gtk+-2.x/ctkdropdownmenu.c197
-rw-r--r--src/gtk+-2.x/ctkdropdownmenu.h11
-rw-r--r--src/gtk+-2.x/ctkecc.c7
-rw-r--r--src/gtk+-2.x/ctkevent.c7
-rw-r--r--src/gtk+-2.x/ctkframelock.c131
-rw-r--r--src/gtk+-2.x/ctkgvi.c2
-rw-r--r--src/gtk+-2.x/ctkgvo-csc.c6
-rw-r--r--src/gtk+-2.x/ctkgvo-sync.c10
-rw-r--r--src/gtk+-2.x/ctkhelp.c9
-rw-r--r--src/gtk+-2.x/ctkmultisample.c6
-rw-r--r--src/gtk+-2.x/ctkpowermizer.c587
-rw-r--r--src/gtk+-2.x/ctkpowermizer.h9
-rw-r--r--src/gtk+-2.x/ctkpowersavings.c230
-rw-r--r--src/gtk+-2.x/ctkpowersavings.h73
-rw-r--r--src/gtk+-2.x/ctkscale.c3
-rw-r--r--src/gtk+-2.x/ctkscreen.c28
-rw-r--r--src/gtk+-2.x/ctkserver.c1
-rw-r--r--src/gtk+-2.x/ctkslimm.c14
-rw-r--r--src/gtk+-2.x/ctkthermal.c3
-rw-r--r--src/gtk+-2.x/ctkwindow.c23
-rw-r--r--src/jansson/dump.c30
-rw-r--r--src/jansson/hashtable.c78
-rw-r--r--src/jansson/hashtable.h5
-rw-r--r--src/jansson/hashtable_seed.c277
-rw-r--r--src/jansson/jansson.h57
-rw-r--r--src/jansson/jansson_config.h47
-rw-r--r--src/jansson/jansson_private.h11
-rw-r--r--src/jansson/jansson_private_config.h57
-rw-r--r--src/jansson/load.c123
-rw-r--r--src/jansson/lookup3.h366
-rw-r--r--src/jansson/memory.c16
-rw-r--r--src/jansson/pack_unpack.c290
-rw-r--r--src/jansson/strbuffer.c11
-rw-r--r--src/jansson/strbuffer.h4
-rw-r--r--src/jansson/strconv.c5
-rw-r--r--src/jansson/utf.c29
-rw-r--r--src/jansson/utf.h34
-rw-r--r--src/jansson/value.c168
-rw-r--r--src/libXNVCtrl/Makefile51
-rw-r--r--src/libXNVCtrl/NVCtrl.h285
-rw-r--r--src/libXNVCtrl/utils.mk353
-rw-r--r--src/libXNVCtrl/version.mk1
-rw-r--r--src/libXNVCtrlAttributes/NvCtrlAttributes.c14
-rw-r--r--src/libXNVCtrlAttributes/NvCtrlAttributes.h7
-rw-r--r--src/libXNVCtrlAttributes/NvCtrlAttributesPrivate.h7
-rw-r--r--src/libXNVCtrlAttributes/NvCtrlAttributesVidMode.c33
-rw-r--r--src/libXNVCtrlAttributes/NvCtrlAttributesXrandr.c22
-rw-r--r--src/parse.c16
-rw-r--r--src/src.mk25
-rw-r--r--src/version.mk2
-rw-r--r--version.mk2
73 files changed, 3755 insertions, 1938 deletions
diff --git a/doc/version.mk b/doc/version.mk
index 434103e..64bf1a5 100644
--- a/doc/version.mk
+++ b/doc/version.mk
@@ -1 +1 @@
-NVIDIA_VERSION = 334.21
+NVIDIA_VERSION = 337.12
diff --git a/samples/Makefile b/samples/Makefile
index ee8777b..3809736 100644
--- a/samples/Makefile
+++ b/samples/Makefile
@@ -48,13 +48,15 @@ endif
X_CFLAGS ?=
-LIBXNVCTRL_DIR ?= ../src/libXNVCtrl
+XNVCTRL_DIR ?= ../src/libXNVCtrl
+XNVCTRL_MAKEFILE ?= Makefile
+XNVCTRL_ARCHIVE ?= $(XNVCTRL_DIR)/libXNVCtrl.a
CFLAGS += $(X_CFLAGS)
-CFLAGS += -I $(LIBXNVCTRL_DIR)
+CFLAGS += -I $(XNVCTRL_DIR)
LDFLAGS += $(X_LDFLAGS)
-LDFLAGS += -L $(LIBXNVCTRL_DIR)
+LDFLAGS += -L $(XNVCTRL_DIR)
LIBS += -lXNVCtrl -lXext -lX11
@@ -76,14 +78,14 @@ SAMPLE_SOURCES += nv-control-warpblend.c
# build rules
##############################################################################
-.PHONY: all clean clobber install
+.PHONY: all clean clobber install build-xnvctrl
# define the rule to build each object file
$(foreach src, $(SAMPLE_SOURCES), $(eval $(call DEFINE_OBJECT_RULE,TARGET,$(src))))
# 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))
+ $$(OUTPUTDIR)/$(1:.c=): $$(call BUILD_OBJECT_LIST,$(1)) $(XNVCTRL_ARCHIVE)
$$(call quiet_cmd,LINK) $$(CFLAGS) $$(LDFLAGS) $$(BIN_LDFLAGS) -o $$@ $$< $$(LIBS)
all:: $$(OUTPUTDIR)/$(1:.c=)
SAMPLES += $$(OUTPUTDIR)/$(1:.c=)
@@ -91,8 +93,15 @@ endef
$(foreach sample,$(SAMPLE_SOURCES),$(eval $(call link_sample_from_object,$(sample))))
+# define the rule to build $(XNVCTRL_ARCHIVE)
+$(XNVCTRL_ARCHIVE): build-xnvctrl
+
+build-xnvctrl:
+ @$(MAKE) -C $(XNVCTRL_DIR) -f $(XNVCTRL_MAKEFILE)
+
clean clobber:
rm -rf *~ $(OUTPUTDIR)/*.o $(OUTPUTDIR)/*.d $(SAMPLES)
+ @$(MAKE) -C $(XNVCTRL_DIR) -f $(XNVCTRL_MAKEFILE) clean
install:
@# don't install samples, this is just to satisfy the top-level
diff --git a/samples/nv-control-dpy.c b/samples/nv-control-dpy.c
index 437cea1..87e28dd 100644
--- a/samples/nv-control-dpy.c
+++ b/samples/nv-control-dpy.c
@@ -42,16 +42,13 @@
#include "nv-control-screen.h"
-static char *display_device_name(int mask);
-static unsigned int display_device_mask(char *str);
static char *remove_whitespace(char *str);
+static char *mode_strtok(char *str);
static void parse_mode_string(char *modeString, char **modeName,
- unsigned int *mask);
+ int *dpyId);
static char *find_modeline(char *modeString, char *pModeLines,
int ModeLineLen);
-
-
static void print_display_name(Display *dpy, int target_id, int attr,
char *name)
{
@@ -72,19 +69,15 @@ static void print_display_name(Display *dpy, int target_id, int attr,
XFree(str);
}
-
-
-
int main(int argc, char *argv[])
{
Display *dpy;
Bool ret;
- int screen, display_devices, mask, major, minor, len, j;
+ int screen, major, minor, len, i, j;
char *str, *start, *str0, *str1;
- char *displayDeviceNames[8];
- int nDisplayDevice;
-
-
+ int *enabledDpyIds;
+
+
/*
* Open a display connection, and make sure the NV-CONTROL X
* extension is present on the screen we want to use.
@@ -105,40 +98,43 @@ int main(int argc, char *argv[])
return 1;
}
- printf("\nUsing NV-CONTROL extension %d.%d on %s\n",
+ printf("\nUsing NV-CONTROL extension %d.%d on %s\n\n",
major, minor, XDisplayName(NULL));
-
-
+
+
/*
- * query the connected display devices on this X screen and print
- * basic information about each X screen
+ * query the enabled display devices on this X screen and print basic
+ * information about each X screen.
*/
- ret = XNVCTRLQueryAttribute(dpy, screen, 0,
- NV_CTRL_CONNECTED_DISPLAYS, &display_devices);
-
- if (!ret) {
+ ret = XNVCTRLQueryTargetBinaryData(dpy,
+ NV_CTRL_TARGET_TYPE_X_SCREEN,
+ screen,
+ 0,
+ NV_CTRL_BINARY_DATA_DISPLAYS_ENABLED_ON_XSCREEN,
+ (unsigned char **) &enabledDpyIds,
+ &len);
+ if (!ret || (len < sizeof(enabledDpyIds[0]))) {
fprintf(stderr, "Failed to query the enabled Display Devices.\n\n");
return 1;
}
- printf("Connected Display Devices:\n");
-
- nDisplayDevice = 0;
- for (mask = 1; mask < (1 << 24); mask <<= 1) {
-
- if (display_devices & mask) {
-
- XNVCTRLQueryStringAttribute(dpy, screen, mask,
- NV_CTRL_STRING_DISPLAY_DEVICE_NAME,
- &str);
-
- displayDeviceNames[nDisplayDevice++] = str;
-
- printf(" %s (0x%08x): %s\n",
- display_device_name(mask), mask, str);
- }
+ printf("Enabled Display Devices:\n");
+
+ for (i = 0; i < enabledDpyIds[0]; i++) {
+ int dpyId = enabledDpyIds[i+1];
+
+ XNVCTRLQueryTargetStringAttribute(dpy,
+ NV_CTRL_TARGET_TYPE_DISPLAY,
+ dpyId,
+ 0,
+ NV_CTRL_STRING_DISPLAY_DEVICE_NAME,
+ &str);
+
+ printf(" DPY-%d : %s\n", dpyId, str);
+ XFree(str);
}
+
printf("\n");
@@ -151,23 +147,22 @@ int main(int argc, char *argv[])
/*
- * for each connected display device on this X screen, query the
- * list of modelines in the mode pool using
- * NV_CTRL_BINARY_DATA_MODELINES, then print the results
+ * for each enabled display device on this X screen, query the list of
+ * modelines in the mode pool using NV_CTRL_BINARY_DATA_MODELINES, then
+ * print the results.
*/
-
+
if (strcmp(argv[1], "--print-modelines") == 0) {
- nDisplayDevice = 0;
-
- for (mask = 1; mask < (1 << 24); mask <<= 1) {
-
- if (!(display_devices & mask)) continue;
-
- ret = XNVCTRLQueryBinaryData(dpy, screen, mask,
- NV_CTRL_BINARY_DATA_MODELINES,
- (void *) &str, &len);
-
+ for (i = 0; i < enabledDpyIds[0]; i++) {
+ int dpyId = enabledDpyIds[i+1];
+
+ ret = XNVCTRLQueryTargetBinaryData(dpy,
+ NV_CTRL_TARGET_TYPE_DISPLAY,
+ dpyId,
+ 0,
+ NV_CTRL_BINARY_DATA_MODELINES,
+ (void *) &str, &len);
if (!ret) {
fprintf(stderr, "Failed to query ModeLines.\n\n");
return 1;
@@ -180,48 +175,44 @@ int main(int argc, char *argv[])
*
* so walk from one "\0" to the next to print each ModeLine.
*/
-
- printf("Modelines for %s:\n",
- displayDeviceNames[nDisplayDevice++]);
-
+
+ printf("Modelines for DPY-%d:\n", dpyId);
+
start = str;
for (j = 0; j < len; j++) {
if (str[j] == '\0') {
printf(" %s\n", start);
start = &str[j+1];
- }
+ }
}
-
+
XFree(str);
}
}
-
+
/*
- * for each connected display device on this X screen, query the
- * current modeline using NV_CTRL_STRING_CURRENT_MODELINE
+ * for each enabled display device on this X screen, query the current
+ * modeline using NV_CTRL_STRING_CURRENT_MODELINE.
*/
-
- else if (strcmp(argv[1], "--print-current-modeline") == 0) {
- nDisplayDevice = 0;
+ else if (strcmp(argv[1], "--print-current-modeline") == 0) {
- for (mask = 1; mask < (1 << 24); mask <<= 1) {
-
- if (!(display_devices & mask)) continue;
+ for (i = 0; i < enabledDpyIds[0]; i++) {
+ int dpyId = enabledDpyIds[i+1];
- ret =
- XNVCTRLQueryStringAttribute(dpy, screen, mask,
- NV_CTRL_STRING_CURRENT_MODELINE,
- &str);
-
+ ret = XNVCTRLQueryTargetStringAttribute(dpy,
+ NV_CTRL_TARGET_TYPE_DISPLAY,
+ dpyId,
+ 0,
+ NV_CTRL_STRING_CURRENT_MODELINE,
+ &str);
if (!ret) {
fprintf(stderr, "Failed to query current ModeLine.\n\n");
return 1;
}
-
- printf("Current Modeline for %s:\n",
- displayDeviceNames[nDisplayDevice++]);
+
+ printf("Current Modeline for DPY-%d:\n", dpyId);
printf(" %s\n\n", str);
XFree(str);
@@ -237,22 +228,23 @@ int main(int argc, char *argv[])
else if ((strcmp(argv[1], "--add-modeline") == 0) &&
argv[2] && argv[3]) {
- mask = strtol(argv[2], NULL, 0);
+ int dpyId = strtol(argv[2], NULL, 0);
- ret = XNVCTRLSetStringAttribute(dpy,
- screen,
- mask,
- NV_CTRL_STRING_ADD_MODELINE,
- argv[3]);
+ ret = XNVCTRLSetTargetStringAttribute(dpy,
+ NV_CTRL_TARGET_TYPE_DISPLAY,
+ dpyId,
+ 0,
+ NV_CTRL_STRING_ADD_MODELINE,
+ argv[3]);
if (!ret) {
- fprintf(stderr, "Failed to add the modeline \"%s\" to %s's "
- "mode pool.\n\n", argv[3], display_device_name(mask));
+ fprintf(stderr, "Failed to add the modeline \"%s\" to DPY-%d's "
+ "mode pool.\n\n", argv[3], dpyId);
return 1;
}
- printf("Added modeline \"%s\" to %s's mode pool.\n\n",
- argv[3], display_device_name(mask));
+ printf("Added modeline \"%s\" to DPY-%d's mode pool.\n\n",
+ argv[3], dpyId);
}
@@ -264,22 +256,23 @@ int main(int argc, char *argv[])
else if ((strcmp(argv[1], "--delete-modeline") == 0) &&
argv[2] && argv[3]) {
- mask = strtol(argv[2], NULL, 0);
+ int dpyId = strtol(argv[2], NULL, 0);
- ret = XNVCTRLSetStringAttribute(dpy,
- screen,
- mask,
- NV_CTRL_STRING_DELETE_MODELINE,
- argv[3]);
+ ret = XNVCTRLSetTargetStringAttribute(dpy,
+ NV_CTRL_TARGET_TYPE_DISPLAY,
+ dpyId,
+ 0,
+ NV_CTRL_STRING_DELETE_MODELINE,
+ argv[3]);
if (!ret) {
- fprintf(stderr, "Failed to delete the mode \"%s\" from %s's "
- "mode pool.\n\n", argv[3], display_device_name(mask));
+ fprintf(stderr, "Failed to delete the mode \"%s\" from DPY-%d's "
+ "mode pool.\n\n", argv[3], dpyId);
return 1;
}
- printf("Deleted modeline \"%s\" from %s's mode pool.\n\n",
- argv[3], display_device_name(mask));
+ printf("Deleted modeline \"%s\" from DPY-%d's mode pool.\n\n",
+ argv[3], dpyId);
}
@@ -435,7 +428,7 @@ int main(int argc, char *argv[])
else if (strcmp(argv[1], "--print-current-metamode") == 0) {
- ret = XNVCTRLQueryStringAttribute(dpy, screen, mask,
+ ret = XNVCTRLQueryStringAttribute(dpy, screen, 0,
NV_CTRL_STRING_CURRENT_METAMODE,
&str);
@@ -459,7 +452,7 @@ int main(int argc, char *argv[])
else if (strcmp(argv[1], "--print-current-metamode-version2") == 0) {
- ret = XNVCTRLQueryStringAttribute(dpy, screen, mask,
+ ret = XNVCTRLQueryStringAttribute(dpy, screen, 0,
NV_CTRL_STRING_CURRENT_METAMODE_VERSION_2,
&str);
@@ -491,9 +484,9 @@ int main(int argc, char *argv[])
* "nvidia-auto-select, nvidia-auto-select"
*
* Using NV-CONTROL extension 1.12 on :0
- * Connected Display Devices:
- * CRT-0 (0x00000001): EIZO F931
- * CRT-1 (0x00000002): ViewSonic P815-4
+ * Enabled Display Devices:
+ * DPY-0 : EIZO F931
+ * DPY-1 : ViewSonic P815-4
*
* Added MetaMode "nvidia-auto-select, nvidia-auto-select";
* pOut: "id=52"
@@ -563,42 +556,37 @@ int main(int argc, char *argv[])
*/
else if (strcmp(argv[1], "--get-valid-freq-ranges") == 0) {
-
- nDisplayDevice = 0;
- for (mask = 1; mask < (1 << 24); mask <<= 1) {
+ for (i = 0; i < enabledDpyIds[0]; i++) {
+ int dpyId = enabledDpyIds[i+1];
- if (!(display_devices & mask)) continue;
-
- ret = XNVCTRLQueryStringAttribute
- (dpy, screen, mask,
+ ret = XNVCTRLQueryTargetStringAttribute
+ (dpy, NV_CTRL_TARGET_TYPE_DISPLAY, dpyId, 0,
NV_CTRL_STRING_VALID_HORIZ_SYNC_RANGES,
&str0);
-
+
if (!ret) {
- fprintf(stderr, "Failed to query HorizSync for %s.\n\n",
- display_device_name(mask));
+ fprintf(stderr, "Failed to query HorizSync for DPY-%d.\n\n",
+ dpyId);
return 1;
}
-
- ret = XNVCTRLQueryStringAttribute
- (dpy, screen, mask,
+ ret = XNVCTRLQueryTargetStringAttribute
+ (dpy, NV_CTRL_TARGET_TYPE_DISPLAY, dpyId, 0,
NV_CTRL_STRING_VALID_VERT_REFRESH_RANGES,
&str1);
-
+
if (!ret) {
- fprintf(stderr, "Failed to query VertRefresh for %s.\n\n",
- display_device_name(mask));
+ fprintf(stderr, "Failed to query VertRefresh for DPY-%d.\n\n",
+ dpyId);
XFree(str0);
return 1;
}
-
- printf("frequency information for %s:\n",
- displayDeviceNames[nDisplayDevice++]);
+
+ printf("frequency information for DPY-%d:\n", dpyId);
printf(" HorizSync : \"%s\"\n", str0);
printf(" VertRefresh : \"%s\"\n\n", str1);
-
+
XFree(str0);
XFree(str1);
}
@@ -611,85 +599,64 @@ int main(int argc, char *argv[])
*/
else if (strcmp(argv[1], "--build-modepool") == 0) {
-
- for (mask = 1; mask < (1 << 24); mask <<= 1) {
-
- if (!(display_devices & mask)) continue;
-
+
+ for (i = 0; i < enabledDpyIds[0]; i++) {
+ int dpyId = enabledDpyIds[i+1];
+
ret = XNVCTRLStringOperation
(dpy,
- NV_CTRL_TARGET_TYPE_X_SCREEN,
- screen,
- mask,
+ NV_CTRL_TARGET_TYPE_DISPLAY,
+ dpyId,
+ 0,
NV_CTRL_STRING_OPERATION_BUILD_MODEPOOL,
argv[2],
&str0);
-
+
if (!ret) {
- fprintf(stderr, "Failed to build modepool for %s (it most "
- "likely already has a modepool).\n\n",
- display_device_name(mask));
+ fprintf(stderr, "Failed to build modepool for DPY-%d (it most "
+ "likely already has a modepool).\n\n", dpyId);
} else {
- printf("Built modepool for %s.\n\n",
- display_device_name(mask));
+ printf("Built modepool for DPY-%d.\n\n", dpyId);
}
}
}
/*
- * query the associated display devices on this X screen; these
- * are the display devices that are available to the X screen for
- * use by MetaModes.
+ * query the assigned display devices on this X screen; these are the
+ * display devices that are available to the X screen for use by MetaModes.
*/
-
- else if (strcmp(argv[1], "--get-associated-dpys") == 0) {
-
- ret = XNVCTRLQueryAttribute(dpy,
- screen,
- 0,
- NV_CTRL_ASSOCIATED_DISPLAY_DEVICES,
- &mask);
-
- if (ret) {
- printf("associated display device mask: 0x%08x\n\n", mask);
- } else {
- fprintf(stderr, "failed to query the associated display device "
- "mask.\n\n");
+
+ else if (strcmp(argv[1], "--get-assigned-dpys") == 0) {
+
+ int *pData = NULL;
+ int len;
+
+ ret = XNVCTRLQueryTargetBinaryData(dpy,
+ NV_CTRL_TARGET_TYPE_X_SCREEN,
+ screen,
+ 0,
+ NV_CTRL_BINARY_DATA_DISPLAYS_ASSIGNED_TO_XSCREEN,
+ (unsigned char **) &pData,
+ &len);
+ if (!ret || (len < sizeof(pData[0]))) {
+ fprintf(stderr, "failed to query the assigned display "
+ "devices.\n\n");
return 1;
}
-
- }
-
-
- /*
- * assign the associated display device mask for this X screen;
- * these are the display devices that are available to the X
- * screen for use by MetaModes.
- */
-
- else if ((strcmp(argv[1], "--set-associated-dpys") == 0) && (argv[2])) {
- mask = strtol(argv[2], NULL, 0);
+ printf("Assigned display devices:\n");
- ret = XNVCTRLSetAttributeAndGetStatus
- (dpy,
- screen,
- 0,
- NV_CTRL_ASSOCIATED_DISPLAY_DEVICES,
- mask);
-
- if (ret) {
- printf("set the associated display device mask to 0x%08x\n\n",
- mask);
- } else {
- fprintf(stderr, "failed to set the associated display device "
- "mask to 0x%08x\n\n", mask);
- return 1;
+ for (i = 0; i < pData[0]; i++) {
+ int dpyId = pData[i+1];
+
+ printf(" DPY-%d\n", dpyId);
}
+
+ printf("\n");
+ XFree(pData);
}
-
/*
* query information about the GPUs in the system
*/
@@ -697,7 +664,7 @@ int main(int argc, char *argv[])
else if (strcmp(argv[1], "--query-gpus") == 0) {
int num_gpus, num_screens, i;
- unsigned int *pData;
+ int *pData;
printf("GPU Information:\n");
@@ -725,7 +692,7 @@ int main(int argc, char *argv[])
(unsigned char **) &pData,
&len);
- if (!ret) {
+ if (!ret || (len < sizeof(pData[0]))) {
fprintf(stderr, "Failed to query list of X Screens\n");
return 1;
}
@@ -775,7 +742,7 @@ int main(int argc, char *argv[])
(unsigned char **) &pData,
&len);
- if (!ret) {
+ if (!ret || (len < sizeof(pData[0]))) {
fprintf(stderr, "Failed to query list of gpus\n\n");
return 1;
}
@@ -823,6 +790,8 @@ int main(int argc, char *argv[])
/* Probe and list the Display devices */
for (i = 0; i < num_gpus; i++) {
+ int deprecated;
+ int *pData;
/* Get the gpu name */
@@ -841,7 +810,7 @@ int main(int argc, char *argv[])
NV_CTRL_TARGET_TYPE_GPU, i,
0,
NV_CTRL_PROBE_DISPLAYS,
- &display_devices);
+ &deprecated);
if (!ret) {
fprintf(stderr, "Failed to probe the enabled Display "
@@ -853,21 +822,32 @@ int main(int argc, char *argv[])
XFree(str);
/* Report results */
-
- for (mask = 1; mask < (1 << 24); mask <<= 1) {
-
- if (display_devices & mask) {
-
- XNVCTRLQueryTargetStringAttribute
- (dpy, NV_CTRL_TARGET_TYPE_GPU, i, mask,
- NV_CTRL_STRING_DISPLAY_DEVICE_NAME,
- &str);
-
- printf(" %s (0x%08x): %s\n",
- display_device_name(mask), mask, str);
- }
+
+ ret = XNVCTRLQueryTargetBinaryData(dpy,
+ NV_CTRL_TARGET_TYPE_GPU, i,
+ 0,
+ NV_CTRL_BINARY_DATA_DISPLAYS_CONNECTED_TO_GPU,
+ (unsigned char **) &pData,
+ &len);
+ if (!ret || (len < sizeof(pData[0]))) {
+ fprintf(stderr, "Failed to query the connected Display Devices.\n\n");
+ return 1;
}
-
+
+ for (j = 0; j < pData[0]; j++) {
+ int dpyId = pData[j+1];
+
+ XNVCTRLQueryTargetStringAttribute(dpy,
+ NV_CTRL_TARGET_TYPE_DISPLAY,
+ dpyId,
+ 0,
+ NV_CTRL_STRING_DISPLAY_DEVICE_NAME,
+ &str);
+
+ printf(" DPY-%d : %s\n", dpyId, str);
+ XFree(str);
+ }
+
printf("\n");
}
@@ -986,34 +966,32 @@ int main(int argc, char *argv[])
char *pMetaModes, *pModeLines[8], *tmp, *modeString;
char *modeLine, *modeName, *noWhiteSpace;
- int MetaModeLen, ModeLineLen[8];
- unsigned int thisMask;
-
+ int MetaModeLen, ModeLineLen[8], ModeLineDpyId[8];
+ int dpyId;
+
/* first, we query the MetaModes on this X screen */
- XNVCTRLQueryBinaryData(dpy, screen, 0, // n/a
- NV_CTRL_BINARY_DATA_METAMODES,
+ XNVCTRLQueryBinaryData(dpy, screen, 0,
+ NV_CTRL_BINARY_DATA_METAMODES_VERSION_2,
(void *) &pMetaModes, &MetaModeLen);
/*
* then, we query the ModeLines for each display device on
* this X screen; we'll need these later
*/
-
- nDisplayDevice = 0;
- for (mask = 1; mask < (1 << 24); mask <<= 1) {
-
- if (!(display_devices & mask)) continue;
-
- XNVCTRLQueryBinaryData(dpy, screen, mask,
- NV_CTRL_BINARY_DATA_MODELINES,
- (void *) &str, &len);
-
- pModeLines[nDisplayDevice] = str;
- ModeLineLen[nDisplayDevice] = len;
+ for (i = 0; i < enabledDpyIds[0]; i++) {
+ dpyId = enabledDpyIds[i+1];
+
+ XNVCTRLQueryTargetBinaryData(dpy, NV_CTRL_TARGET_TYPE_DISPLAY,
+ dpyId,
+ 0,
+ NV_CTRL_BINARY_DATA_MODELINES,
+ (void *) &str, &len);
- nDisplayDevice++;
+ pModeLines[i] = str;
+ ModeLineLen[i] = len;
+ ModeLineDpyId[i] = dpyId;
}
/* now, parse each MetaMode */
@@ -1051,40 +1029,40 @@ int main(int argc, char *argv[])
tmp = noWhiteSpace;
}
- /* split the MetaMode string by comma */
+ /* Parse each mode from the metamode */
- for (modeString = strtok(tmp, ",");
+ for (modeString = mode_strtok(tmp);
modeString;
- modeString = strtok(NULL, ",")) {
+ modeString = mode_strtok(NULL)) {
/*
- * retrieve the modeName and display device mask
+ * retrieve the modeName and display device id
* for this segment of the Metamode
*/
- parse_mode_string(modeString, &modeName, &thisMask);
+ parse_mode_string(modeString, &modeName, &dpyId);
/* lookup the modeline that matches */
-
- nDisplayDevice = 0;
-
- if (thisMask) {
- for (mask = 1; mask < (1 << 24); mask <<= 1) {
- if (!(display_devices & mask)) continue;
- if (thisMask & mask) break;
- nDisplayDevice++;
+
+ for (i = 0; i < enabledDpyIds[0]; i++) {
+ if (ModeLineDpyId[i] == dpyId) {
+ break;
}
}
-
+ if ( i >= enabledDpyIds[0] ) {
+ fprintf(stderr, " Failed to find modelines for "
+ "DPY-%d.\n\n",
+ dpyId);
+ continue;
+ }
modeLine = find_modeline(modeName,
- pModeLines[nDisplayDevice],
- ModeLineLen[nDisplayDevice]);
-
- printf(" %s: %s\n",
- display_device_name(thisMask), modeLine);
+ pModeLines[i],
+ ModeLineLen[i]);
+
+ printf(" DPY-%d: %s\n", dpyId, modeLine);
}
-
+
printf("\n");
free(noWhiteSpace);
@@ -1100,7 +1078,7 @@ int main(int argc, char *argv[])
/* Display all names each display device goes by
*/
else if (strcmp(argv[1], "--print-display-names") == 0) {
- unsigned int *pData;
+ int *pData;
int len, i;
printf("Display Device Information:\n");
@@ -1112,7 +1090,7 @@ int main(int argc, char *argv[])
NV_CTRL_BINARY_DATA_DISPLAY_TARGETS,
(unsigned char **) &pData,
&len);
- if (!ret) {
+ if (!ret || (len < sizeof(pData[0]))) {
fprintf(stderr, "Failed to query number of display devices.\n\n");
return 1;
}
@@ -1163,10 +1141,10 @@ int main(int argc, char *argv[])
printf(" --print-current-modeline: print the current modeline "
"for each Display Device.\n\n");
- printf(" --add-modeline [dpy mask] [modeline]: "
+ printf(" --add-modeline [dpy id] [modeline]: "
"add new modeline.\n\n");
- printf(" --delete-modeline [dpy mask] [modename]: "
+ printf(" --delete-modeline [dpy id] [modename]: "
"delete modeline with modename.\n\n");
printf(" --generate-gtf-modeline [width] [height] [refreshrate]:"
@@ -1206,11 +1184,8 @@ int main(int argc, char *argv[])
printf(" --build-modepool: build a modepool for any display device "
"that does not already have one.\n\n");
- printf(" --get-associated-dpys: query the associated display device "
- "mask for this X screen\n\n");
-
- printf(" --set-associated-dpys [mask]: set the associated display "
- "device mask for this X screen\n\n");
+ printf(" --get-assigned-dpys: query the assigned display device for "
+ "this X screen\n\n");
printf(" --query-gpus: print GPU information and relationship to "
"X screens.\n\n");
@@ -1245,87 +1220,6 @@ int main(int argc, char *argv[])
/*
- * display_device_name() - return the display device name corresponding
- * to the specified display device mask.
- */
-
-static char *display_device_name(int mask)
-{
- switch (mask) {
- case (1 << 0): return "CRT-0"; break;
- case (1 << 1): return "CRT-1"; break;
- case (1 << 2): return "CRT-2"; break;
- case (1 << 3): return "CRT-3"; break;
- case (1 << 4): return "CRT-4"; break;
- case (1 << 5): return "CRT-5"; break;
- case (1 << 6): return "CRT-6"; break;
- case (1 << 7): return "CRT-7"; break;
-
- case (1 << 8): return "TV-0"; break;
- case (1 << 9): return "TV-1"; break;
- case (1 << 10): return "TV-2"; break;
- case (1 << 11): return "TV-3"; break;
- case (1 << 12): return "TV-4"; break;
- case (1 << 13): return "TV-5"; break;
- case (1 << 14): return "TV-6"; break;
- case (1 << 15): return "TV-7"; break;
-
- case (1 << 16): return "DFP-0"; break;
- case (1 << 17): return "DFP-1"; break;
- case (1 << 18): return "DFP-2"; break;
- case (1 << 19): return "DFP-3"; break;
- case (1 << 20): return "DFP-4"; break;
- case (1 << 21): return "DFP-5"; break;
- case (1 << 22): return "DFP-6"; break;
- case (1 << 23): return "DFP-7"; break;
- default: return "Unknown";
- }
-
-} /* display_device_name() */
-
-
-
-/*
- * display_device_mask() - given a display device name, translate to
- * the display device mask
- */
-
-static unsigned int display_device_mask(char *str)
-{
- if (strcmp(str, "CRT-0") == 0) return (1 << 0);
- if (strcmp(str, "CRT-1") == 0) return (1 << 1);
- if (strcmp(str, "CRT-2") == 0) return (1 << 2);
- if (strcmp(str, "CRT-3") == 0) return (1 << 3);
- if (strcmp(str, "CRT-4") == 0) return (1 << 4);
- if (strcmp(str, "CRT-5") == 0) return (1 << 5);
- if (strcmp(str, "CRT-6") == 0) return (1 << 6);
- if (strcmp(str, "CRT-7") == 0) return (1 << 7);
-
- if (strcmp(str, "TV-0") == 0) return (1 << 8);
- if (strcmp(str, "TV-1") == 0) return (1 << 9);
- if (strcmp(str, "TV-2") == 0) return (1 << 10);
- if (strcmp(str, "TV-3") == 0) return (1 << 11);
- if (strcmp(str, "TV-4") == 0) return (1 << 12);
- if (strcmp(str, "TV-5") == 0) return (1 << 13);
- if (strcmp(str, "TV-6") == 0) return (1 << 14);
- if (strcmp(str, "TV-7") == 0) return (1 << 15);
-
- if (strcmp(str, "DFP-0") == 0) return (1 << 16);
- if (strcmp(str, "DFP-1") == 0) return (1 << 17);
- if (strcmp(str, "DFP-2") == 0) return (1 << 18);
- if (strcmp(str, "DFP-3") == 0) return (1 << 19);
- if (strcmp(str, "DFP-4") == 0) return (1 << 20);
- if (strcmp(str, "DFP-5") == 0) return (1 << 21);
- if (strcmp(str, "DFP-6") == 0) return (1 << 22);
- if (strcmp(str, "DFP-7") == 0) return (1 << 23);
-
- return 0;
-
-} /* display_device_mask() */
-
-
-
-/*
* remove_whitespace() - return an allocated copy of the given string,
* with any whitespace removed
*/
@@ -1355,28 +1249,61 @@ static char *remove_whitespace(char *str)
/*
+ * Special strtok function for parsing modes. This function ignores
+ * anything between curly braces, including commas when parsing tokens
+ * delimited by commas.
+ */
+static char *mode_strtok(char *str)
+{
+ static char *intStr = NULL;
+ char *start;
+
+ if (str) {
+ intStr = str;
+ }
+
+ if (!intStr || *intStr == '\0') {
+ return NULL;
+ }
+
+ /* Mark off the next token value */
+ start = intStr;
+ while (*intStr != '\0') {
+ if (*intStr == '{') {
+ while (*intStr != '}' && *intStr != '\0') {
+ intStr++;
+ }
+ }
+ if (*intStr == ',') {
+ *intStr = '\0';
+ intStr++;
+ break;
+ }
+ intStr++;
+ }
+
+ return start;
+}
+
+
+
+/*
* parse_mode_string() - extract the modeName and the display device
- * mask for the per-display device MetaMode string in 'modeString'
+ * id for the per-display device MetaMode string in 'modeString'
*/
static void parse_mode_string(char *modeString, char **modeName,
- unsigned int *mask)
+ int *dpyId)
{
char *colon, *s, tmp;
colon = strchr(modeString, ':');
-
- if (colon) {
-
- *colon = '\0';
- *mask = display_device_mask(modeString);
- *colon = ':';
-
- modeString = colon + 1;
- } else {
- *mask = 0;
- }
-
+ *colon = '\0';
+ *dpyId = strtol(modeString+4, NULL, 0);
+ *colon = ':';
+
+ modeString = colon + 1;
+
/*
* find the modename; trim off any panning domain or
* offsets
diff --git a/samples/nv-control-dvc.c b/samples/nv-control-dvc.c
index e8243bc..02a4faa 100644
--- a/samples/nv-control-dvc.c
+++ b/samples/nv-control-dvc.c
@@ -47,53 +47,15 @@
#include "nv-control-screen.h"
-/*
- * display_device_name() - return the display device name correspoding
- * to the display device mask.
- */
-
-static char *display_device_name(int mask)
-{
- switch (mask) {
- case (1 << 0): return "CRT-0"; break;
- case (1 << 1): return "CRT-1"; break;
- case (1 << 2): return "CRT-2"; break;
- case (1 << 3): return "CRT-3"; break;
- case (1 << 4): return "CRT-4"; break;
- case (1 << 5): return "CRT-5"; break;
- case (1 << 6): return "CRT-6"; break;
- case (1 << 7): return "CRT-7"; break;
-
- case (1 << 8): return "TV-0"; break;
- case (1 << 9): return "TV-1"; break;
- case (1 << 10): return "TV-2"; break;
- case (1 << 11): return "TV-3"; break;
- case (1 << 12): return "TV-4"; break;
- case (1 << 13): return "TV-5"; break;
- case (1 << 14): return "TV-6"; break;
- case (1 << 15): return "TV-7"; break;
-
- case (1 << 16): return "DFP-0"; break;
- case (1 << 17): return "DFP-1"; break;
- case (1 << 18): return "DFP-2"; break;
- case (1 << 19): return "DFP-3"; break;
- case (1 << 20): return "DFP-4"; break;
- case (1 << 21): return "DFP-5"; break;
- case (1 << 22): return "DFP-6"; break;
- case (1 << 23): return "DFP-7"; break;
- default: return "Unknown";
- }
-} /* display_device_name() */
-
-
-
int main(int argc, char *argv[])
{
Display *dpy;
Bool ret;
int screen, retval, setval = -1;
- int display_devices, mask;
NVCTRLAttributeValidValuesRec valid_values;
+ int *data;
+ int len;
+ int i;
/*
* If there is a commandline argument, interpret it as the value
@@ -120,14 +82,16 @@ int main(int argc, char *argv[])
/*
- * Get the bitmask of enabled display devices
+ * Get the list of enabled display devices on the X screen
*/
- ret = XNVCTRLQueryAttribute(dpy,
- screen,
- 0,
- NV_CTRL_ENABLED_DISPLAYS,
- &display_devices);
+ ret = XNVCTRLQueryTargetBinaryData(dpy,
+ NV_CTRL_TARGET_TYPE_X_SCREEN,
+ screen,
+ 0,
+ NV_CTRL_BINARY_DATA_DISPLAYS_ENABLED_ON_XSCREEN,
+ (unsigned char **)&data,
+ &len);
if (!ret) {
fprintf(stderr, "Unable to determine enabled display devices for "
"screen %d of '%s'\n", screen, XDisplayName(NULL));
@@ -139,24 +103,25 @@ int main(int argc, char *argv[])
* loop over each enabled display device
*/
- for (mask = 1; mask < (1<<24); mask <<= 1) {
+ for (i = 1; i <= data[0]; i++) {
- if (!(mask & display_devices)) continue;
+ int dpyId = data[i];
/*
* Query the valid values for NV_CTRL_DIGITAL_VIBRANCE
*/
- ret = XNVCTRLQueryValidAttributeValues(dpy,
- screen,
- mask,
- NV_CTRL_DIGITAL_VIBRANCE,
- &valid_values);
+ ret = XNVCTRLQueryValidTargetAttributeValues(dpy,
+ NV_CTRL_TARGET_TYPE_DISPLAY,
+ dpyId,
+ 0,
+ NV_CTRL_DIGITAL_VIBRANCE,
+ &valid_values);
if (!ret) {
fprintf(stderr, "Unable to query the valid values for "
- "NV_CTRL_DIGITAL_VIBRANCE on display device %s of "
+ "NV_CTRL_DIGITAL_VIBRANCE on display device DPY-%d of "
"screen %d of '%s'.\n",
- display_device_name(mask),
+ dpyId,
screen, XDisplayName(NULL));
return 1;
}
@@ -182,29 +147,29 @@ int main(int argc, char *argv[])
if (setval != -1) {
- XNVCTRLSetAttribute(dpy,
- screen,
- mask,
- NV_CTRL_DIGITAL_VIBRANCE,
- setval);
+ XNVCTRLSetTargetAttribute(dpy,
+ NV_CTRL_TARGET_TYPE_DISPLAY,
+ dpyId,
+ 0,
+ NV_CTRL_DIGITAL_VIBRANCE,
+ setval);
XFlush(dpy);
printf("Set NV_CTRL_DIGITAL_VIBRANCE to %d on display device "
- "%s of screen %d of '%s'.\n", setval,
- display_device_name(mask),
- screen, XDisplayName(NULL));
+ "DPY-%d of screen %d of '%s'.\n", setval, dpyId, screen,
+ XDisplayName(NULL));
} else {
- ret = XNVCTRLQueryAttribute(dpy,
- screen,
- mask,
- NV_CTRL_DIGITAL_VIBRANCE,
- &retval);
+ ret = XNVCTRLQueryTargetAttribute(dpy,
+ NV_CTRL_TARGET_TYPE_DISPLAY,
+ dpyId,
+ 0,
+ NV_CTRL_DIGITAL_VIBRANCE,
+ &retval);
printf("The current value of NV_CTRL_DIGITAL_VIBRANCE "
- "is %d on display device %s of screen %d of '%s'.\n",
- retval, display_device_name(mask),
- screen, XDisplayName(NULL));
+ "is %d on display device DPY-%d of screen %d of '%s'.\n",
+ retval, dpyId, screen, XDisplayName(NULL));
}
}
diff --git a/samples/nv-control-events.c b/samples/nv-control-events.c
index b9711a0..be23e20 100644
--- a/samples/nv-control-events.c
+++ b/samples/nv-control-events.c
@@ -612,7 +612,6 @@ static AttrEntry attr_table[] = {
MAKE_ENTRY(NV_CTRL_HWOVERLAY),
MAKE_ENTRY(NV_CTRL_NUM_GPU_ERRORS_RECOVERED),
MAKE_ENTRY(NV_CTRL_REFRESH_RATE_3),
- MAKE_ENTRY(NV_CTRL_ONDEMAND_VBLANK_INTERRUPTS),
MAKE_ENTRY(NV_CTRL_GPU_POWER_SOURCE),
MAKE_ENTRY(NV_CTRL_GPU_CURRENT_PERFORMANCE_MODE),
MAKE_ENTRY(NV_CTRL_GLYPH_CACHE),
@@ -742,5 +741,6 @@ static AttrEntry attr_table[] = {
MAKE_ENTRY(NV_CTRL_MULTIGPU_MASTER_POSSIBLE),
MAKE_ENTRY(NV_CTRL_GPU_POWER_MIZER_DEFAULT_MODE),
MAKE_ENTRY(NV_CTRL_XV_SYNC_TO_DISPLAY_ID),
+ MAKE_ENTRY(NV_CTRL_PALETTE_UPDATE_EVENT),
{ -1, NULL, NULL }
};
diff --git a/samples/nv-control-info.c b/samples/nv-control-info.c
index ae92d18..bb57515 100644
--- a/samples/nv-control-info.c
+++ b/samples/nv-control-info.c
@@ -195,7 +195,6 @@ static AttrEntry attr_int_table[] = {
MAKE_ENTRY(NV_CTRL_HWOVERLAY),
MAKE_ENTRY(NV_CTRL_NUM_GPU_ERRORS_RECOVERED),
MAKE_ENTRY(NV_CTRL_REFRESH_RATE_3),
- MAKE_ENTRY(NV_CTRL_ONDEMAND_VBLANK_INTERRUPTS),
MAKE_ENTRY(NV_CTRL_GPU_POWER_SOURCE),
MAKE_ENTRY(NV_CTRL_GPU_CURRENT_PERFORMANCE_MODE),
MAKE_ENTRY(NV_CTRL_GLYPH_CACHE),
diff --git a/samples/version.mk b/samples/version.mk
index 434103e..64bf1a5 100644
--- a/samples/version.mk
+++ b/samples/version.mk
@@ -1 +1 @@
-NVIDIA_VERSION = 334.21
+NVIDIA_VERSION = 337.12
diff --git a/src/Makefile b/src/Makefile
index 1790b4f..b4f4d60 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -60,7 +60,10 @@ ifndef VDPAU_CFLAGS
endif
ifndef JANSSON_CFLAGS
- JANSSON_CFLAGS = -Wno-cast-qual
+ JANSSON_CFLAGS = -Wno-cast-qual
+ JANSSON_CFLAGS += -Wno-strict-prototypes
+ JANSSON_CFLAGS += -Wno-unused-function
+ JANSSON_CFLAGS += -DHAVE_CONFIG_H
ifeq ($(TARGET_ARCH),armv7l)
JANSSON_CFLAGS += -Wno-unused-but-set-variable
endif
@@ -78,6 +81,7 @@ endif
##############################################################################
XNVCTRL_DIR ?= libXNVCtrl
+XNVCTRL_MAKEFILE ?= Makefile
XNVCTRL_ARCHIVE ?= $(XNVCTRL_DIR)/libXNVCtrl.a
XCONFIG_PARSER_DIR ?= XF86Config-parser
COMMON_UTILS_DIR ?= common-utils
@@ -169,7 +173,7 @@ $(call BUILD_OBJECT_LIST,$(JANSSON_SRC)): CFLAGS += $(JANSSON_CFLAGS)
# build rules
##############################################################################
-.PNONY: all install NVIDIA_SETTINGS_install clean clobber
+.PHONY: all install NVIDIA_SETTINGS_install clean clobber build-xnvctrl
all: $(NVIDIA_SETTINGS)
@@ -190,7 +194,14 @@ $(foreach src,$(SRC),$(eval $(call DEFINE_OBJECT_RULE,TARGET,$(src))))
# define the rule to generate $(STAMP_C)
$(eval $(call DEFINE_STAMP_C_RULE, $(OBJS),$(NVIDIA_SETTINGS_PROGRAM_NAME)))
+# define the rule to build $(XNVCTRL_ARCHIVE)
+$(XNVCTRL_ARCHIVE): build-xnvctrl
+
+build-xnvctrl:
+ @$(MAKE) -C $(XNVCTRL_DIR) -f $(XNVCTRL_MAKEFILE)
+
clean clobber:
rm -rf $(NVIDIA_SETTINGS) *~ $(STAMP_C) \
$(OUTPUTDIR)/*.o $(OUTPUTDIR)/*.d
+ @$(MAKE) -C $(XNVCTRL_DIR) -f $(XNVCTRL_MAKEFILE) clean
diff --git a/src/gtk+-2.x/ctk3dvisionpro.c b/src/gtk+-2.x/ctk3dvisionpro.c
index ccf53d5..ec1e30c 100644
--- a/src/gtk+-2.x/ctk3dvisionpro.c
+++ b/src/gtk+-2.x/ctk3dvisionpro.c
@@ -282,7 +282,7 @@ static GtkWidget *create_glasses_list_menu(Ctk3DVisionPro *ctk_3d_vision_pro,
int i;
mnu_glasses_name = (CtkDropDownMenu *)
- ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_COMBO);
+ ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_READONLY);
g_signal_connect(G_OBJECT(mnu_glasses_name), "changed",
G_CALLBACK(glasses_name_changed),
(gpointer) dlg);
@@ -1687,7 +1687,7 @@ GtkWidget* ctk_3d_vision_pro_new(NvCtrlAttributeHandle *handle,
hbox = gtk_hbox_new(FALSE, 5);
menu = (CtkDropDownMenu *)
- ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_COMBO);
+ ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_READONLY);
ctk_drop_down_menu_append_item(menu, "Short Range (up to 5 meters)", 0);
ctk_drop_down_menu_append_item(menu, "Medium Range (up to 15 meters)", 1);
ctk_drop_down_menu_append_item(menu, "Long Range", 2);
diff --git a/src/gtk+-2.x/ctkappprofile.c b/src/gtk+-2.x/ctkappprofile.c
index 69d9f57..6116518 100644
--- a/src/gtk+-2.x/ctkappprofile.c
+++ b/src/gtk+-2.x/ctkappprofile.c
@@ -103,6 +103,7 @@ typedef struct _ToolbarItemTemplate {
#define TOOLBAR_ITEM_GHOST_IF_NOTHING_SELECTED (1 << 0)
#define TOOLBAR_ITEM_USE_WIDGET (1 << 1)
+#define TOOLBAR_ITEM_USE_SEPARATOR (1 << 2)
/*
* Template used to construct tree view columns and generate help text with
@@ -128,11 +129,7 @@ typedef struct _TreeViewColumnTemplate {
const gchar *extended_help_text;
} TreeViewColumnTemplate;
-#if JSON_INTEGER_IS_LONG_LONG
-# define JSON_INTEGER_HEX_FORMAT "llx"
-#else
-# define JSON_INTEGER_HEX_FORMAT "lx"
-#endif
+#define JSON_INTEGER_HEX_FORMAT "llx"
/*
* Function prototypes
@@ -253,6 +250,15 @@ static void app_profile_finalize(GObject *object)
ctk_help_data_list_free_full(ctk_app_profile->save_reload_help_data);
}
+static void tool_button_set_label_and_stock_icon(GtkToolButton *button, const gchar *label_text, const gchar *icon_id)
+{
+ GtkWidget *icon;
+ icon = gtk_image_new_from_stock(icon_id, GTK_ICON_SIZE_SMALL_TOOLBAR);
+ gtk_tool_button_set_icon_widget(button, icon);
+ gtk_tool_button_set_label(button, label_text);
+ gtk_widget_show_all(GTK_WIDGET(button));
+}
+
static void button_set_label_and_stock_icon(GtkButton *button, const gchar *label_text, const gchar *icon_id)
{
GtkWidget *hbox;
@@ -343,10 +349,11 @@ static GtkWidget *populate_registry_key_combo_callback(gpointer init_data)
}
menu = (CtkDropDownMenu *)
- ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_COMBO);
+ ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_READONLY);
dialog->registry_key_combo = GTK_WIDGET(menu);
ctk_drop_down_menu_append_item(menu, "Custom", -1);
+ ctk_drop_down_menu_set_current_value(menu, -1);
for (i = 0; i < json_array_size(key_docs); i++) {
json_t *json_key_object = json_array_get(key_docs, i);
json_t *json_name = json_object_get(json_key_object, "key");
@@ -369,6 +376,8 @@ static void populate_toolbar(GtkToolbar *toolbar,
WidgetDataItem *widget_data_item;
GtkWidget *widget;
GtkWidget *icon;
+ GtkTooltips *tooltips = gtk_tooltips_new();
+ GtkToolItem *tool_item;
if (help_data) {
*help_data = NULL;
@@ -387,29 +396,40 @@ static void populate_toolbar(GtkToolbar *toolbar,
if (item->flags & TOOLBAR_ITEM_USE_WIDGET) {
widget = (*item->init_callback)(item->init_data);
if (widget) {
- gtk_toolbar_append_widget(toolbar, widget,
+ tool_item = gtk_tool_item_new();
+ gtk_tool_item_set_tooltip(tool_item, tooltips,
item->help_text, NULL);
+ gtk_container_add(GTK_CONTAINER(tool_item), widget);
+ gtk_toolbar_insert(toolbar, tool_item, -1);
} else {
item++;
continue;
}
+ } else if (item->flags & TOOLBAR_ITEM_USE_SEPARATOR) {
+ widget = GTK_WIDGET(gtk_separator_tool_item_new());
+ gtk_separator_tool_item_set_draw(GTK_SEPARATOR_TOOL_ITEM(widget),
+ FALSE);
+ gtk_tool_item_set_expand(GTK_TOOL_ITEM(widget), TRUE);
+ gtk_toolbar_insert(toolbar, GTK_TOOL_ITEM(widget), -1);
} else {
- widget = gtk_toolbar_append_item(toolbar,
- item->text,
- item->help_text,
- NULL,
- icon,
- item->callback,
- item->user_data);
+ tool_item = GTK_TOOL_ITEM(gtk_tool_button_new(icon, item->text));
+ gtk_tool_item_set_tooltip(tool_item, tooltips,
+ item->help_text, NULL);
+
+ g_signal_connect(G_OBJECT(tool_item), "clicked",
+ G_CALLBACK(item->callback),
+ (gpointer)item->user_data);
+ gtk_toolbar_insert(toolbar, tool_item, -1);
+ widget = GTK_WIDGET(tool_item);
}
- if (help_data) {
+ if (help_data && item->text) {
ctk_help_data_list_prepend(help_data,
item->text,
item->help_text,
item->extended_help_text);
}
- if (widget_data) {
+ if (widget_data && item->text) {
widget_data_item = malloc(sizeof(WidgetDataItem));
widget_data_item->label = strdup(item->text);
widget_data_item->widget = widget;
@@ -434,6 +454,8 @@ static void populate_toolbar(GtkToolbar *toolbar,
if (widget_data) {
*widget_data = g_list_reverse(*widget_data);
}
+
+ gtk_toolbar_set_show_arrow(GTK_TOOLBAR(toolbar), FALSE);
}
typedef struct CellRendererRegisterKeyDataRec {
@@ -947,23 +969,21 @@ static void string_list_free_full(GList *list)
g_list_free(list);
}
-static GList *get_source_filenames(CtkAppProfile *ctk_app_profile)
+static void populate_source_combo_box(CtkAppProfile *ctk_app_profile,
+ GtkComboBoxEntry *combo_box_entry)
{
size_t i, size;
json_t *json_filename, *json_filenames;
- GList *filenames = NULL;
json_filenames = nv_app_profile_config_get_source_filenames(ctk_app_profile->cur_config);
for (i = 0, size = json_array_size(json_filenames); i < size; i++) {
json_filename = json_array_get(json_filenames, i);
- filenames = g_list_prepend(filenames, strdup(json_string_value(json_filename)));
+ gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box_entry),
+ strdup(json_string_value(json_filename)));
}
- filenames = g_list_reverse(filenames);
json_decref(json_filenames);
-
- return filenames;
}
static gboolean append_profile_name(GtkTreeModel *model,
@@ -971,28 +991,16 @@ static gboolean append_profile_name(GtkTreeModel *model,
GtkTreeIter *iter,
gpointer data)
{
- GList **profile_names = (GList **)data;
+ GtkComboBoxEntry *combo_box = GTK_COMBO_BOX_ENTRY(data);
gchar *profile_name;
gtk_tree_model_get(model, iter, CTK_APC_PROFILE_MODEL_COL_NAME, &profile_name, -1);
- *profile_names = g_list_prepend(*profile_names, profile_name);
+ gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box), profile_name);
return FALSE;
}
-static GList *get_profile_names(CtkAppProfile *ctk_app_profile)
-{
- GList *profile_names = NULL;
-
- gtk_tree_model_foreach(GTK_TREE_MODEL(ctk_app_profile->apc_profile_model),
- append_profile_name,
- (gpointer)&profile_names);
-
- profile_names = g_list_reverse(profile_names);
- return profile_names;
-}
-
static gboolean unref_setting_object(GtkTreeModel *model,
GtkTreePath *path,
GtkTreeIter *iter,
@@ -1040,29 +1048,27 @@ static void load_settings_from_profile(CtkAppProfile *ctk_app_profile,
static void edit_rule_dialog_load_profile(EditRuleDialog *dialog,
const char *profile_name)
{
- GList *strings;
- GtkCombo *combo;
+ CtkAppProfile *ctk_app_profile = CTK_APP_PROFILE(dialog->parent);
+ GtkComboBoxEntry *combo_box_entry;
// profile name
- combo = GTK_COMBO(dialog->profile_name_combo);
- strings = get_profile_names(CTK_APP_PROFILE(dialog->parent));
- gtk_combo_set_popdown_strings(combo, strings);
+ combo_box_entry = GTK_COMBO_BOX_ENTRY(dialog->profile_name_combo);
+ gtk_tree_model_foreach(GTK_TREE_MODEL(ctk_app_profile->apc_profile_model),
+ append_profile_name,
+ (gpointer)combo_box_entry);
+ gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box_entry), 0);
if (!profile_name) {
- if (g_list_length(strings)) {
- // Choose first string in the list
- g_string_assign(dialog->profile_name, (gchar *)strings->data);
- } else {
- g_string_assign(dialog->profile_name, "");
- }
+ gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box_entry), 0);
+ g_string_assign(dialog->profile_name,
+ gtk_entry_get_text(
+ GTK_ENTRY(GTK_BIN(combo_box_entry)->child)));
} else {
g_string_assign(dialog->profile_name, profile_name);
+ gtk_entry_set_text(GTK_ENTRY(GTK_BIN(combo_box_entry)->child),
+ dialog->profile_name->str);
}
- gtk_entry_set_text(GTK_ENTRY(combo->entry), dialog->profile_name->str);
-
- string_list_free_full(strings);
-
// profile settings
load_settings_from_profile(CTK_APP_PROFILE(dialog->parent),
dialog->profile_settings_store,
@@ -1071,8 +1077,7 @@ static void edit_rule_dialog_load_profile(EditRuleDialog *dialog,
static void edit_rule_dialog_load_values(EditRuleDialog *dialog)
{
- GList *strings;
- GtkCombo *combo;
+ GtkComboBoxEntry *combo_box_entry;
char *profile_name_copy;
// window title
@@ -1080,28 +1085,23 @@ static void edit_rule_dialog_load_values(EditRuleDialog *dialog)
dialog->new_rule ? "Add new rule" : "Edit existing rule");
// add/edit button
- button_set_label_and_stock_icon(GTK_BUTTON(dialog->add_edit_rule_button),
- "Update Rule",
- dialog->new_rule ? GTK_STOCK_ADD : GTK_STOCK_PREFERENCES);
+ tool_button_set_label_and_stock_icon(
+ GTK_TOOL_BUTTON(dialog->add_edit_rule_button), "Update Rule",
+ dialog->new_rule ? GTK_STOCK_ADD : GTK_STOCK_PREFERENCES);
// source file
- combo = GTK_COMBO(dialog->source_file_combo);
- strings = get_source_filenames(CTK_APP_PROFILE(dialog->parent));
+ combo_box_entry = GTK_COMBO_BOX_ENTRY(dialog->source_file_combo);
+ populate_source_combo_box(CTK_APP_PROFILE(dialog->parent), combo_box_entry);
- gtk_combo_set_popdown_strings(combo, strings);
+ gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box_entry), 0);
if (dialog->new_rule) {
- if (g_list_length(strings)) {
- // Choose first string in the list
- g_string_assign(dialog->source_file, (gchar *)strings->data);
- } else {
- g_string_assign(dialog->source_file, "");
- }
+ g_string_assign(dialog->source_file,
+ gtk_entry_get_text(GTK_ENTRY(GTK_BIN(combo_box_entry)->child)));
}
- gtk_entry_set_text(GTK_ENTRY(combo->entry), dialog->source_file->str);
-
- string_list_free_full(strings);
+ gtk_entry_set_text(GTK_ENTRY(GTK_BIN(combo_box_entry)->child),
+ dialog->source_file->str);
// feature and matches
ctk_drop_down_menu_set_current_value(CTK_DROP_DOWN_MENU(dialog->feature_menu),
@@ -1122,15 +1122,17 @@ static void edit_rule_dialog_show(EditRuleDialog *dialog)
// the update below and callbacks which fire when the window opens
g_signal_handler_block(G_OBJECT(dialog->feature_menu),
dialog->feature_changed_signal);
- g_signal_handler_block(G_OBJECT(GTK_COMBO(dialog->profile_name_combo)->entry),
- dialog->rule_profile_name_changed_signal);
+ g_signal_handler_block(
+ G_OBJECT(GTK_ENTRY(GTK_BIN(dialog->profile_name_combo)->child)),
+ dialog->rule_profile_name_changed_signal);
edit_rule_dialog_load_values(dialog);
gtk_widget_show_all(dialog->top_window);
g_signal_handler_unblock(G_OBJECT(dialog->feature_menu),
dialog->feature_changed_signal);
- g_signal_handler_unblock(G_OBJECT(GTK_COMBO(dialog->profile_name_combo)->entry),
- dialog->rule_profile_name_changed_signal);
+ g_signal_handler_unblock(
+ G_OBJECT(GTK_ENTRY(GTK_BIN(dialog->profile_name_combo)->child)),
+ dialog->rule_profile_name_changed_signal);
// disable focusing to main window until this window closed
gtk_window_set_transient_for(GTK_WINDOW(dialog->top_window),
@@ -1326,7 +1328,8 @@ static gboolean rule_browse_button_clicked(GtkWidget *widget, gpointer user_data
case GTK_RESPONSE_ACCEPT:
case GTK_RESPONSE_OK:
filename = gtk_file_selection_get_filename(GTK_FILE_SELECTION(dialog->file_sel));
- gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(dialog->source_file_combo)->entry), filename);
+ gtk_entry_set_text(GTK_ENTRY(GTK_BIN(dialog->source_file_combo)->child),
+ filename);
default:
break;
}
@@ -1352,7 +1355,8 @@ static gboolean profile_browse_button_clicked(GtkWidget *widget, gpointer user_d
case GTK_RESPONSE_ACCEPT:
case GTK_RESPONSE_OK:
filename = gtk_file_selection_get_filename(GTK_FILE_SELECTION(dialog->file_sel));
- gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(dialog->source_file_combo)->entry), filename);
+ gtk_entry_set_text(GTK_ENTRY(GTK_BIN(dialog->source_file_combo)->child),
+ filename);
default:
break;
}
@@ -1395,7 +1399,7 @@ static void config_create_source_file_entry(CtkConfig *ctk_config,
{
GtkWidget *hbox;
GtkWidget *label;
- GtkWidget *combo_box;
+ GtkWidget *combo_box_entry;
GtkWidget *browse_button;
GString *help_string;
@@ -1416,7 +1420,7 @@ static void config_create_source_file_entry(CtkConfig *ctk_config,
help_string->str,
NULL);
- combo_box = gtk_combo_new();
+ combo_box_entry = gtk_combo_box_entry_new_text();
browse_button = gtk_button_new();
button_set_label_and_stock_icon(GTK_BUTTON(browse_button),
@@ -1433,7 +1437,7 @@ static void config_create_source_file_entry(CtkConfig *ctk_config,
NULL);
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(hbox), combo_box, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), combo_box_entry, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(hbox), browse_button, FALSE, FALSE, 0);
g_signal_connect(G_OBJECT(browse_button), "clicked",
@@ -1441,7 +1445,7 @@ static void config_create_source_file_entry(CtkConfig *ctk_config,
user_data);
*pcontainer = hbox;
- *psource_file_combo = combo_box;
+ *psource_file_combo = combo_box_entry;
g_string_free(help_string, TRUE);
}
@@ -1458,7 +1462,7 @@ static GtkWidget *create_feature_menu(EditRuleDialog *dialog)
{
size_t i;
- dialog->feature_menu = ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_COMBO);
+ dialog->feature_menu = ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_READONLY);
for (i = 0; i < NUM_RULE_FEATURES; i++) {
ctk_drop_down_menu_append_item(CTK_DROP_DOWN_MENU(dialog->feature_menu),
@@ -1568,7 +1572,7 @@ static GtkWidget *create_rule_profile_name_entry(EditRuleDialog *dialog)
GtkWidget *hbox;
GtkWidget *button;
GtkWidget *label;
- GtkWidget *combo_box;
+ GtkWidget *combo_box_entry;
hbox = gtk_hbox_new(FALSE, 8);
@@ -1576,12 +1580,12 @@ static GtkWidget *create_rule_profile_name_entry(EditRuleDialog *dialog)
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
- dialog->profile_name_combo = combo_box = gtk_combo_new();
+ dialog->profile_name_combo = combo_box_entry = gtk_combo_box_entry_new_text();
- gtk_box_pack_start(GTK_BOX(hbox), combo_box, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), combo_box_entry, TRUE, TRUE, 0);
dialog->rule_profile_name_changed_signal =
- g_signal_connect(G_OBJECT(GTK_COMBO(combo_box)->entry), "changed",
+ g_signal_connect(G_OBJECT(GTK_BIN(combo_box_entry)->child), "changed",
G_CALLBACK(rule_profile_name_changed),
(gpointer)dialog);
@@ -1837,7 +1841,7 @@ static void edit_rule_dialog_save_changes(GtkWidget *widget, gpointer user_data)
{
EditRuleDialog *dialog = (EditRuleDialog *)user_data;
CtkAppProfile *ctk_app_profile = CTK_APP_PROFILE(dialog->parent);
- GtkWidget *source_file_entry = GTK_COMBO(dialog->source_file_combo)->entry;
+ GtkWidget *source_file_entry = GTK_BIN(dialog->source_file_combo)->child;
json_t *rule_json = json_object();
json_t *pattern_json = json_object();
@@ -1893,6 +1897,10 @@ static ToolbarItemTemplate *get_edit_rule_dialog_toolbar_items(EditRuleDialog *d
ToolbarItemTemplate *items_copy;
const ToolbarItemTemplate items[] = {
{
+ .text = NULL,
+ .flags = TOOLBAR_ITEM_USE_SEPARATOR,
+ },
+ {
.text = UPDATE_RULE_LABEL,
.help_text = "The Update Rule button allows you to save changes made to the rule definition.",
.icon_id = GTK_STOCK_SAVE,
@@ -1942,7 +1950,6 @@ static EditRuleDialog* edit_rule_dialog_new(CtkAppProfile *ctk_app_profile)
GtkWidget *entry;
GtkWidget *tree_view;
GtkWidget *toolbar;
- GtkWidget *alignment;
GtkWidget *scroll_win;
GList *toolbar_help_items;
GList *toolbar_widget_items;
@@ -2103,7 +2110,6 @@ static EditRuleDialog* edit_rule_dialog_new(CtkAppProfile *ctk_app_profile)
gtk_box_pack_start(GTK_BOX(main_vbox), frame, TRUE, TRUE, 0);
- alignment = gtk_alignment_new(1.0, 0.5, 0.0, 0.0);
toolbar = gtk_toolbar_new();
dialog->help_data = g_list_reverse(dialog->help_data);
@@ -2125,8 +2131,7 @@ static EditRuleDialog* edit_rule_dialog_new(CtkAppProfile *ctk_app_profile)
free(edit_rule_dialog_toolbar_items);
- gtk_container_add(GTK_CONTAINER(alignment), toolbar);
- gtk_box_pack_start(GTK_BOX(main_vbox), alignment, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(main_vbox), toolbar, FALSE, FALSE, 0);
return dialog;
}
@@ -2417,10 +2422,10 @@ static void edit_profile_dialog_save_changes(GtkWidget *widget, gpointer user_da
EditProfileDialog *profile_dialog = (EditProfileDialog *)user_data;
EditRuleDialog *rule_dialog;
CtkAppProfile *ctk_app_profile = CTK_APP_PROFILE(profile_dialog->parent);
- GtkWidget *source_file_entry = GTK_COMBO(profile_dialog->source_file_combo)->entry;
+ GtkWidget *source_file_entry =
+ GTK_BIN(profile_dialog->source_file_combo)->child;
json_t *profile_json = json_object();
- GtkCombo *combo;
- GList *source_filenames;
+ GtkComboBoxEntry *combo_box_entry;
gboolean rules_fixed_up = FALSE;
rule_dialog = ctk_app_profile->edit_rule_dialog;
@@ -2470,11 +2475,10 @@ static void edit_profile_dialog_save_changes(GtkWidget *widget, gpointer user_da
if (widget_get_visible(rule_dialog->top_window)) {
// XXX could this be abstracted?
edit_rule_dialog_load_profile(rule_dialog, profile_dialog->name->str);
- source_filenames = get_source_filenames(ctk_app_profile);
- combo = GTK_COMBO(rule_dialog->source_file_combo);
- gtk_combo_set_popdown_strings(combo, source_filenames);
- gtk_entry_set_text(GTK_ENTRY(combo->entry), rule_dialog->source_file->str);
- string_list_free_full(source_filenames);
+ combo_box_entry = GTK_COMBO_BOX_ENTRY(rule_dialog->source_file_combo);
+ populate_source_combo_box(ctk_app_profile, combo_box_entry);
+ gtk_entry_set_text(GTK_ENTRY(GTK_BIN(combo_box_entry)->child),
+ rule_dialog->source_file->str);
}
json_decref(profile_json);
@@ -2547,6 +2551,10 @@ static void get_profile_dialog_toolbar_items(EditProfileDialog *dialog,
const ToolbarItemTemplate dialog_items[] = {
{
+ .text = NULL,
+ .flags = TOOLBAR_ITEM_USE_SEPARATOR,
+ },
+ {
.text = UPDATE_PROFILE_LABEL,
.help_text = "The Update Profile button allows you to save changes made to the profile definition.",
.icon_id = GTK_STOCK_SAVE,
@@ -2874,7 +2882,6 @@ static EditProfileDialog *edit_profile_dialog_new(CtkAppProfile *ctk_app_profile
GtkWidget *toolbar;
GtkWidget *tree_view;
GtkWidget *scroll_win;
- GtkWidget *alignment;
GtkWidget *button;
GList *toolbar_widget_items;
@@ -3009,7 +3016,6 @@ static EditProfileDialog *edit_profile_dialog_new(CtkAppProfile *ctk_app_profile
gtk_box_pack_start(GTK_BOX(main_vbox), dialog->error_statusbar.widget,
FALSE, FALSE, 0);
- alignment = gtk_alignment_new(1.0, 0.5, 0.0, 0.0);
toolbar = gtk_toolbar_new();
populate_toolbar(GTK_TOOLBAR(toolbar),
@@ -3024,8 +3030,7 @@ static EditProfileDialog *edit_profile_dialog_new(CtkAppProfile *ctk_app_profile
widget_data_list_free_full(toolbar_widget_items);
- gtk_container_add(GTK_CONTAINER(alignment), toolbar);
- gtk_box_pack_start(GTK_BOX(main_vbox), alignment, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(main_vbox), toolbar, FALSE, FALSE, 0);
free(edit_profile_settings_toolbar_items);
free(edit_profile_dialog_toolbar_items);
@@ -3306,39 +3311,34 @@ static gboolean profiles_tree_view_key_press_event(GtkWidget *widget,
static void edit_profile_dialog_load_values(EditProfileDialog *dialog)
{
- GList *strings;
- GtkCombo *combo;
+ GtkComboBoxEntry *combo_box_entry;
// window title
gtk_window_set_title(GTK_WINDOW(dialog->top_window),
dialog->new_profile ? "Add new profile" : "Edit existing profile");
// add/edit button
- button_set_label_and_stock_icon(GTK_BUTTON(dialog->add_edit_profile_button),
- "Update Profile",
- dialog->new_profile ? GTK_STOCK_ADD : GTK_STOCK_PREFERENCES);
+ tool_button_set_label_and_stock_icon(
+ GTK_TOOL_BUTTON(dialog->add_edit_profile_button),
+ "Update Profile",
+ dialog->new_profile ? GTK_STOCK_ADD : GTK_STOCK_PREFERENCES);
// profile name
gtk_entry_set_text(GTK_ENTRY(dialog->name_entry), dialog->name->str);
// source file
- combo = GTK_COMBO(dialog->source_file_combo);
- strings = get_source_filenames(CTK_APP_PROFILE(dialog->parent));
+ combo_box_entry = GTK_COMBO_BOX_ENTRY(dialog->source_file_combo);
+ populate_source_combo_box(CTK_APP_PROFILE(dialog->parent), combo_box_entry);
- gtk_combo_set_popdown_strings(combo, strings);
+ gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box_entry), 0);
if (dialog->new_profile) {
- if (g_list_length(strings)) {
- // Choose first string in the list
- g_string_assign(dialog->source_file, (gchar *)strings->data);
- } else {
- g_string_assign(dialog->source_file, "");
- }
+ g_string_assign(dialog->source_file,
+ gtk_entry_get_text(GTK_ENTRY(GTK_BIN(combo_box_entry)->child)));
}
- gtk_entry_set_text(GTK_ENTRY(combo->entry), dialog->source_file->str);
-
- string_list_free_full(strings);
+ gtk_entry_set_text(GTK_ENTRY(GTK_BIN(combo_box_entry)->child),
+ dialog->source_file->str);
// profile settings
if (!dialog->new_profile) {
@@ -3724,6 +3724,10 @@ static ToolbarItemTemplate *get_save_reload_toolbar_items(CtkAppProfile *ctk_app
ToolbarItemTemplate *save_reload_toolbar_items_copy;
const ToolbarItemTemplate save_reload_toolbar_items[] = {
{
+ .text = NULL,
+ .flags = TOOLBAR_ITEM_USE_SEPARATOR,
+ },
+ {
.text = "Save Changes",
.help_text = "The Save Changes button allows you to save any changes to application profile "
"configuration files to disk.",
@@ -3994,7 +3998,7 @@ static SaveAppProfileChangesDialog *save_app_profile_changes_dialog_new(CtkAppPr
hbox = gtk_hbox_new(FALSE, 8);
- dialog->preview_file_menu = menu = ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_COMBO);
+ dialog->preview_file_menu = menu = ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_READONLY);
gtk_box_pack_start(GTK_BOX(hbox), menu, TRUE, TRUE, 0);
dialog->preview_changed_signal =
@@ -4028,7 +4032,7 @@ static SaveAppProfileChangesDialog *save_app_profile_changes_dialog_new(CtkAppPr
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
dialog->preview_backup_entry = gtk_entry_new();
gtk_box_pack_start(GTK_BOX(hbox), dialog->preview_backup_entry, TRUE, TRUE, 0);
- gtk_entry_set_editable(GTK_ENTRY(dialog->preview_backup_entry), FALSE);
+ gtk_editable_set_editable(GTK_EDITABLE(dialog->preview_backup_entry), FALSE);
gtk_box_pack_start(GTK_BOX(preview_vbox), hbox, FALSE, FALSE, 0);
@@ -4320,7 +4324,6 @@ GtkWidget* ctk_app_profile_new(CtkConfig *ctk_config,
GtkWidget *hseparator;
GtkWidget *hbox;
GtkWidget *label;
- GtkWidget *alignment;
GtkWidget *notebook;
GtkWidget *rules_page, *profiles_page;
GtkWidget *toolbar;
@@ -4417,7 +4420,6 @@ GtkWidget* ctk_app_profile_new(CtkConfig *ctk_config,
gtk_box_pack_start(GTK_BOX(ctk_app_profile), notebook, TRUE, TRUE, 0);
/* Create the save and restore buttons */
- alignment = gtk_alignment_new(1.0, 0.5, 0.0, 0.0);
toolbar = gtk_toolbar_new();
save_reload_toolbar_items = get_save_reload_toolbar_items(ctk_app_profile, &num_save_reload_toolbar_items);
populate_toolbar(GTK_TOOLBAR(toolbar),
@@ -4427,8 +4429,7 @@ GtkWidget* ctk_app_profile_new(CtkConfig *ctk_config,
NULL, NULL);
free(save_reload_toolbar_items);
- gtk_container_add(GTK_CONTAINER(alignment), toolbar);
- gtk_box_pack_start(GTK_BOX(ctk_app_profile), alignment, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(ctk_app_profile), toolbar, FALSE, FALSE, 0);
gtk_widget_show_all(GTK_WIDGET(ctk_app_profile));
diff --git a/src/gtk+-2.x/ctkclocks.c b/src/gtk+-2.x/ctkclocks.c
index 47d7158..bcee633 100644
--- a/src/gtk+-2.x/ctkclocks.c
+++ b/src/gtk+-2.x/ctkclocks.c
@@ -295,7 +295,7 @@ GtkWidget* ctk_clocks_new(NvCtrlAttributeHandle *handle,
/* Create the Clock menu widget */
menu = (CtkDropDownMenu *)
- ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_COMBO);
+ ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_READONLY);
i = 0;
if ( can_access_2d_clocks ) {
diff --git a/src/gtk+-2.x/ctkcolorcontrols.c b/src/gtk+-2.x/ctkcolorcontrols.c
index 575e21a..a429a93 100644
--- a/src/gtk+-2.x/ctkcolorcontrols.c
+++ b/src/gtk+-2.x/ctkcolorcontrols.c
@@ -198,7 +198,7 @@ GtkWidget* ctk_color_controls_new(NvCtrlAttributeHandle *handle,
/* dropdown list for color space */
menu = (CtkDropDownMenu *)
- ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_COMBO);
+ ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_READONLY);
for (i = 0; i < ctk_color_controls->color_space_table_size; i++) {
switch (ctk_color_controls->color_space_table[i]) {
@@ -257,7 +257,7 @@ GtkWidget* ctk_color_controls_new(NvCtrlAttributeHandle *handle,
/* dropdown list for color range */
ctk_color_controls->color_range_menu =
- ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_COMBO);
+ ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_READONLY);
ctk_config_set_tooltip(ctk_config,
ctk_color_controls->color_range_menu,
diff --git a/src/gtk+-2.x/ctkcolorcorrection.c b/src/gtk+-2.x/ctkcolorcorrection.c
index d8d7e26..59f83fa 100644
--- a/src/gtk+-2.x/ctkcolorcorrection.c
+++ b/src/gtk+-2.x/ctkcolorcorrection.c
@@ -57,7 +57,7 @@ static const char *__color_curve_help = "The color curve graph changes to "
"sliders.";
static void
-option_menu_changed (GtkOptionMenu *, gpointer);
+color_channel_changed (GtkComboBox *, gpointer);
static void
set_button_sensitive (GtkButton *);
@@ -91,6 +91,9 @@ apply_parsed_attribute_list(CtkColorCorrection *, ParsedAttribute *);
static gboolean
do_confirm_countdown (gpointer);
+static void callback_palette_update(GtkObject *object, gpointer arg1,
+ gpointer user_data);
+
static void
update_confirm_text (CtkColorCorrection *);
@@ -178,21 +181,52 @@ ctk_color_correction_class_init(CtkColorCorrectionClass
static void ctk_color_correction_finalize(GObject *object)
{
- CtkColorCorrection *ctk_object = CTK_COLOR_CORRECTION(object);
+ CtkColorCorrection *ctk_color_correction = CTK_COLOR_CORRECTION(object);
- /* kill the timer */
- if (ctk_object->confirm_timer) {
- g_source_remove(ctk_object->confirm_timer);
- ctk_object->confirm_timer = 0;
+ if (ctk_color_correction->confirm_timer) {
+ /*
+ * This situation comes, if user perform VT-switching
+ * without confirmation of color-correction settings.
+ */
+ gint attr, ch;
+ unsigned int channels = 0;
+ unsigned int attributes = 0;
+
+ /* kill the timer */
+ g_source_remove(ctk_color_correction->confirm_timer);
+ ctk_color_correction->confirm_timer = 0;
+
+ /*
+ * Reset color settings to previous state,
+ * since user did not confirm settings yet.
+ */
+ for (attr = CONTRAST_INDEX; attr <= GAMMA_INDEX; attr++) {
+ for (ch = RED; ch <= ALL_CHANNELS_INDEX; ch++) {
+ /* Check for attribute channel value change. */
+ int index = attr - CONTRAST_INDEX;
+
+ ctk_color_correction->cur_slider_val[index][ch] =
+ ctk_color_correction->prev_slider_val[index][ch];
+
+ attributes |= (1 << attr);
+ channels |= (1 << ch);
+ }
+ }
+
+ NvCtrlSetColorAttributes(ctk_color_correction->handle,
+ ctk_color_correction->cur_slider_val[CONTRAST],
+ ctk_color_correction->cur_slider_val[BRIGHTNESS],
+ ctk_color_correction->cur_slider_val[GAMMA],
+ attributes | channels);
}
- g_signal_handlers_disconnect_matched(G_OBJECT(ctk_object->ctk_event),
+ g_signal_handlers_disconnect_matched(G_OBJECT(ctk_color_correction->ctk_event),
G_SIGNAL_MATCH_DATA,
0,
0,
NULL,
NULL,
- (gpointer) ctk_object);
+ (gpointer) ctk_color_correction);
}
@@ -207,12 +241,10 @@ GtkWidget* ctk_color_correction_new(NvCtrlAttributeHandle *handle,
CtkColorCorrection *ctk_color_correction;
GtkRequisition requisition;
- GtkWidget *menu;
GtkWidget *image;
GtkWidget *label;
GtkWidget *scale;
GtkWidget *curve;
- GtkWidget *menu_item;
GtkWidget *alignment;
GtkWidget *mainhbox;
GtkWidget *leftvbox;
@@ -222,7 +254,12 @@ GtkWidget* ctk_color_correction_new(NvCtrlAttributeHandle *handle,
GtkWidget *button, *confirm_button, *confirm_label;
GtkWidget *widget;
GtkWidget *hsep;
+ GtkWidget *center_alignment;
GtkWidget *eventbox;
+ GtkWidget *combo_box;
+ GtkListStore *store;
+ GtkTreeIter iter;
+ GtkCellRenderer *renderer;
object = g_object_new(CTK_TYPE_COLOR_CORRECTION, NULL);
@@ -266,76 +303,53 @@ GtkWidget* ctk_color_correction_new(NvCtrlAttributeHandle *handle,
gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
gtk_container_add(GTK_CONTAINER(alignment), vbox);
- menu = gtk_menu_new();
-
- menu_item = gtk_menu_item_new();
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
-
- hbox = gtk_hbox_new(FALSE, 0);
- gtk_container_add(GTK_CONTAINER(menu_item), hbox);
-
- label = gtk_label_new("All Channels");
- image = gtk_image_new_from_pixbuf(gdk_pixbuf_new_from_xpm_data(rgb_xpm));
-
- gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 10);
-
-
- menu_item = gtk_menu_item_new();
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
-
- hbox = gtk_hbox_new(FALSE, 0);
- gtk_container_add(GTK_CONTAINER(menu_item), hbox);
-
- label = gtk_label_new ("Red");
- image = gtk_image_new_from_pixbuf(gdk_pixbuf_new_from_xpm_data(red_xpm));
-
- gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 10);
-
-
- menu_item = gtk_menu_item_new();
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
-
- hbox = gtk_hbox_new(FALSE, 0);
- gtk_container_add(GTK_CONTAINER(menu_item), hbox);
-
- label = gtk_label_new("Green");
- image = gtk_image_new_from_pixbuf(gdk_pixbuf_new_from_xpm_data(green_xpm));
-
- gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 10);
-
-
- menu_item = gtk_menu_item_new();
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
-
- hbox = gtk_hbox_new(FALSE, 0);
- gtk_container_add(GTK_CONTAINER(menu_item), hbox);
-
- label = gtk_label_new("Blue");
- image = gtk_image_new_from_pixbuf(gdk_pixbuf_new_from_xpm_data(blue_xpm));
-
- gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 10);
-
-
- ctk_color_correction->option_menu = gtk_option_menu_new ();
- gtk_option_menu_set_menu
- (GTK_OPTION_MENU(ctk_color_correction->option_menu), menu);
+ store = gtk_list_store_new(2, GDK_TYPE_PIXBUF, G_TYPE_STRING);
+
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter,
+ 0, gdk_pixbuf_new_from_xpm_data(rgb_xpm),
+ 1, "All Channels", -1);
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter,
+ 0, gdk_pixbuf_new_from_xpm_data(red_xpm),
+ 1, "Red", -1);
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter,
+ 0, gdk_pixbuf_new_from_xpm_data(green_xpm),
+ 1, "Green", -1);
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter,
+ 0, gdk_pixbuf_new_from_xpm_data(blue_xpm),
+ 1, "Blue", -1);
+
+ combo_box = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
+
+ renderer = gtk_cell_renderer_pixbuf_new();
+ gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo_box), renderer, FALSE);
+ gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo_box), renderer,
+ "pixbuf", 0, NULL);
+
+ renderer = gtk_cell_renderer_text_new();
+ gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo_box), renderer, FALSE);
+ gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo_box), renderer,
+ "text", 1, NULL);
+
+ gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), 0);
+
+ ctk_color_correction->color_channel = combo_box;
gtk_box_pack_start(GTK_BOX(vbox),
- ctk_color_correction->option_menu,
+ ctk_color_correction->color_channel,
FALSE, FALSE, 0);
- g_object_set_data(G_OBJECT(ctk_color_correction->option_menu),
+ g_object_set_data(G_OBJECT(ctk_color_correction->color_channel),
"color_channel", GINT_TO_POINTER(ALL_CHANNELS));
-
- g_signal_connect(G_OBJECT(ctk_color_correction->option_menu), "changed",
- G_CALLBACK(option_menu_changed),
+
+ g_signal_connect(G_OBJECT(ctk_color_correction->color_channel), "changed",
+ G_CALLBACK(color_channel_changed),
(gpointer) ctk_color_correction);
- ctk_config_set_tooltip(ctk_config, ctk_color_correction->option_menu,
+ ctk_config_set_tooltip(ctk_config, ctk_color_correction->color_channel,
__active_color_help);
/*
* Gamma curve: BOTTOM - LEFT
@@ -353,6 +367,7 @@ GtkWidget* ctk_color_correction_new(NvCtrlAttributeHandle *handle,
gtk_container_add(GTK_CONTAINER(alignment), eventbox);
ctk_config_set_tooltip(ctk_config, eventbox, __color_curve_help);
+ ctk_color_correction->curve = curve;
/*
* Reset button: BOTTOM - RIGHT (see below)
@@ -382,6 +397,7 @@ GtkWidget* ctk_color_correction_new(NvCtrlAttributeHandle *handle,
ctk_color_correction->confirm_label = confirm_label;
ctk_color_correction->confirm_button = confirm_button;
+ ctk_color_correction->reset_button = button;
ctk_config_set_tooltip(ctk_config, eventbox, __confirm_button_help);
ctk_config_set_tooltip(ctk_config, button, __resest_button_help);
@@ -499,10 +515,36 @@ GtkWidget* ctk_color_correction_new(NvCtrlAttributeHandle *handle,
gtk_container_add(GTK_CONTAINER(alignment), hbox);
gtk_box_pack_start(GTK_BOX(object), alignment, TRUE, TRUE, 0);
+ /* external update notification label */
+
+ center_alignment = gtk_alignment_new(0.5, 0.5, 0, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), center_alignment, TRUE, TRUE, 0);
+
+ hbox = gtk_hbox_new(FALSE, 10);
+ gtk_container_add(GTK_CONTAINER(center_alignment), hbox);
+
+ label = gtk_label_new("Warning: The color settings have been changed "
+ "outside of nvidia-settings so the current slider "
+ "values may be incorrect.");
+ gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+
+ image = gtk_image_new_from_stock(GTK_STOCK_DIALOG_WARNING,
+ GTK_ICON_SIZE_BUTTON);
+
+ gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+ ctk_color_correction->warning_container = hbox;
+
+
/* finally, show the widget */
gtk_widget_show_all(GTK_WIDGET(object));
+ /* except the external color change update warning */
+
+ gtk_widget_hide(ctk_color_correction->warning_container);
+
/*
* lock the size of the confirm button, so that it is not resized
* when we change the button text later.
@@ -520,12 +562,17 @@ GtkWidget* ctk_color_correction_new(NvCtrlAttributeHandle *handle,
gtk_widget_set_size_request(ctk_color_correction->confirm_label,
requisition.width, -1);
+ g_signal_connect(G_OBJECT(ctk_event),
+ CTK_EVENT_NAME(NV_CTRL_PALETTE_UPDATE_EVENT),
+ G_CALLBACK(callback_palette_update),
+ (gpointer) ctk_color_correction);
+
return GTK_WIDGET(object);
}
-static void option_menu_changed(
- GtkOptionMenu *option_menu,
+static void color_channel_changed(
+ GtkComboBox *combo_box,
gpointer user_data
)
{
@@ -537,7 +584,7 @@ static void option_menu_changed(
ctk_color_correction = CTK_COLOR_CORRECTION(user_data);
- history = gtk_option_menu_get_history(option_menu);
+ history = gtk_combo_box_get_active(combo_box);
switch (history) {
default:
@@ -561,7 +608,7 @@ static void option_menu_changed(
* response to slider changes
*/
- g_object_set_data(G_OBJECT(option_menu), "color_channel",
+ g_object_set_data(G_OBJECT(combo_box), "color_channel",
GINT_TO_POINTER(channel));
for (i = 0; i < 3; i++) {
@@ -687,7 +734,7 @@ static void reset_button_clicked(
)
{
CtkColorCorrection *ctk_color_correction;
- GtkOptionMenu *option_menu;
+ GtkComboBox *combo_box;
ctk_color_correction = CTK_COLOR_CORRECTION(user_data);
/* Set default values */
set_color_state(ctk_color_correction, CONTRAST, ALL_CHANNELS,
@@ -697,21 +744,23 @@ static void reset_button_clicked(
set_color_state(ctk_color_correction, GAMMA, ALL_CHANNELS,
GAMMA_DEFAULT, TRUE);
+ ctk_color_correction->num_expected_updates++;
+
flush_attribute_channel_values(ctk_color_correction,
ALL_VALUES, ALL_CHANNELS);
- option_menu = GTK_OPTION_MENU(ctk_color_correction->option_menu);
+ combo_box = GTK_COMBO_BOX(ctk_color_correction->color_channel);
- if (gtk_option_menu_get_history(option_menu) == 0) {
+ if (gtk_combo_box_get_active(combo_box) == 0) {
/*
- * gtk_option_menu_set_history will not emit the "changed" signal
- * unless the new index differs from the old one; reasonable, but
- * we need to cope with it here.
+ * We use the color_channel_changed function to reload color information
+ * from the server. If we are already on the correct channel, we cannot
+ * rely on the "changed" signal to be triggered so we will just call it
+ * directly here.
*/
- gtk_option_menu_set_history(option_menu, 1);
- gtk_option_menu_set_history(option_menu, 0);
+ color_channel_changed(combo_box, user_data);
} else {
- gtk_option_menu_set_history(option_menu, 0);
+ gtk_combo_box_set_active(combo_box, 0);
}
ctk_config_statusbar_message(ctk_color_correction->ctk_config,
@@ -748,11 +797,13 @@ static void adjustment_value_changed(
attribute = GPOINTER_TO_INT(user_data);
user_data = g_object_get_data
- (G_OBJECT(ctk_color_correction->option_menu), "color_channel");
+ (G_OBJECT(ctk_color_correction->color_channel), "color_channel");
channel = GPOINTER_TO_INT(user_data);
value = gtk_adjustment_get_value(adjustment);
+ ctk_color_correction->num_expected_updates++;
+
/* start timer for confirming changes */
ctk_color_correction->confirm_countdown =
DEFAULT_CONFIRM_COLORCORRECTION_TIMEOUT;
@@ -865,6 +916,8 @@ static void flush_attribute_channel_values(
ctk_color_correction->cur_slider_val[GAMMA],
attribute | channel);
+ gtk_widget_hide(ctk_color_correction->warning_container);
+
g_signal_emit(ctk_color_correction, signals[CHANGED], 0);
}
@@ -876,6 +929,7 @@ static void apply_parsed_attribute_list(
{
int target_type, target_id;
unsigned int attr = 0;
+ ctk_color_correction->num_expected_updates = 0;
set_color_state(ctk_color_correction, CONTRAST, ALL_CHANNELS,
CONTRAST_DEFAULT, TRUE);
@@ -894,6 +948,18 @@ static void apply_parsed_attribute_list(
if (!p->next) goto next_attribute;
if (a->type != NV_PARSER_ATTRIBUTE_TYPE_COLOR) {
+ if (a->attr == NV_CTRL_COLOR_SPACE ||
+ a->attr == NV_CTRL_COLOR_RANGE) {
+ for (node = p->targets; node ; node = node->next) {
+ int attr_target_type = NvCtrlGetTargetType(node->t->h);
+ int attr_target_id = NvCtrlGetTargetId(node->t->h);
+
+ if ((attr_target_type == target_type) &&
+ (attr_target_id == target_id)) {
+ ctk_color_correction->num_expected_updates++;
+ }
+ }
+ }
goto next_attribute;
}
@@ -902,8 +968,8 @@ static void apply_parsed_attribute_list(
* correction's target matches one of the (parse attribute's)
* specification targets.
*/
-
- for (node = p->targets; node && node->next; node = node->next) {
+
+ for (node = p->targets; node; node = node->next) {
int attr_target_type = NvCtrlGetTargetType(node->t->h);
int attr_target_id = NvCtrlGetTargetId(node->t->h);
@@ -957,6 +1023,8 @@ static void apply_parsed_attribute_list(
continue;
}
+ ctk_color_correction->num_expected_updates++;
+
attr |= (a->attr & (ALL_VALUES | ALL_CHANNELS));
}
@@ -986,6 +1054,8 @@ static void apply_parsed_attribute_list(
}
}
+ ctk_color_correction->num_expected_updates++;
+
NvCtrlSetColorAttributes(ctk_color_correction->handle,
ctk_color_correction->cur_slider_val[CONTRAST],
ctk_color_correction->cur_slider_val[BRIGHTNESS],
@@ -1024,8 +1094,8 @@ static gboolean do_confirm_countdown(gpointer data)
CtkColorCorrection *ctk_color_correction = (CtkColorCorrection *)(data);
unsigned int channels = 0;
unsigned int attributes = 0;
- GtkOptionMenu *option_menu =
- GTK_OPTION_MENU(ctk_color_correction->option_menu);
+ GtkComboBox *combo_box =
+ GTK_COMBO_BOX(ctk_color_correction->color_channel);
ctk_color_correction->confirm_countdown--;
if (ctk_color_correction->confirm_countdown > 0) {
@@ -1033,6 +1103,8 @@ static gboolean do_confirm_countdown(gpointer data)
return True;
}
+ ctk_color_correction->num_expected_updates++;
+
/* Countdown timed out, reset color settings to previous state */
for (attr = CONTRAST_INDEX; attr <= GAMMA_INDEX; attr++) {
for (ch = RED; ch <= ALL_CHANNELS_INDEX; ch++) {
@@ -1053,7 +1125,7 @@ static gboolean do_confirm_countdown(gpointer data)
}
/* Refresh color correction page for current selected channel. */
- option_menu_changed(option_menu, (gpointer)(ctk_color_correction));
+ color_channel_changed(combo_box, (gpointer)(ctk_color_correction));
/* Reset confirm button text */
gtk_label_set_text(GTK_LABEL(ctk_color_correction->confirm_label),
@@ -1134,3 +1206,29 @@ void ctk_color_correction_tab_help(GtkTextBuffer *b, GtkTextIter *i,
ctk_help_term(b, i, "Confirm Current Changes");
ctk_help_para(b, i, "%s", __confirm_button_help);
}
+
+
+static void callback_palette_update(GtkObject *object, gpointer arg1,
+ gpointer user_data)
+{
+ gboolean reload_needed;
+ CtkColorCorrection *ctk_color_correction = (CtkColorCorrection *)user_data;
+
+ reload_needed = (ctk_color_correction->num_expected_updates <= 0);
+
+ if (ctk_color_correction->num_expected_updates > 0) {
+ ctk_color_correction->num_expected_updates--;
+ }
+
+ if (reload_needed) {
+ NvCtrlReloadColorRamp(ctk_color_correction->handle);
+
+ ctk_curve_color_changed(ctk_color_correction->curve);
+ gtk_widget_set_sensitive(ctk_color_correction->reset_button, TRUE);
+
+ gtk_widget_show(ctk_color_correction->warning_container);
+ } else {
+ gtk_widget_hide(ctk_color_correction->warning_container);
+ }
+}
+
diff --git a/src/gtk+-2.x/ctkcolorcorrection.h b/src/gtk+-2.x/ctkcolorcorrection.h
index d160542..f32984c 100644
--- a/src/gtk+-2.x/ctkcolorcorrection.h
+++ b/src/gtk+-2.x/ctkcolorcorrection.h
@@ -56,10 +56,13 @@ struct _CtkColorCorrection
NvCtrlAttributeHandle *handle;
CtkConfig *ctk_config;
CtkEvent *ctk_event;
- GtkWidget *option_menu;
+ GtkWidget *color_channel;
GtkObject *brightness_adjustment;
GtkObject *contrast_adjustment;
GtkObject *gamma_adjustment;
+ GtkWidget *curve;
+ GtkWidget *warning_container;
+ GtkWidget *reset_button;
GtkWidget *confirm_button;
GtkWidget *confirm_label;
gint confirm_countdown;
@@ -67,6 +70,7 @@ struct _CtkColorCorrection
gfloat cur_slider_val[3][4]; // as [attribute][channel]
gfloat prev_slider_val[3][4]; // as [attribute][channel]
guint enabled_display_devices;
+ int num_expected_updates;
};
struct _CtkColorCorrectionClass
diff --git a/src/gtk+-2.x/ctkcolorcorrectionpage.c b/src/gtk+-2.x/ctkcolorcorrectionpage.c
index 003ff03..46b0d2f 100644
--- a/src/gtk+-2.x/ctkcolorcorrectionpage.c
+++ b/src/gtk+-2.x/ctkcolorcorrectionpage.c
@@ -114,11 +114,11 @@ GtkWidget* ctk_color_correction_page_new(NvCtrlAttributeHandle *handle,
gtk_box_pack_start(GTK_BOX(ctk_color_correction_page),
banner, FALSE, FALSE, 0);
+ gtk_widget_show_all(GTK_WIDGET(object));
+
gtk_box_pack_start(GTK_BOX(ctk_color_correction_page),
ctk_color_correction, TRUE, TRUE, 0);
- gtk_widget_show_all(GTK_WIDGET(object));
-
return GTK_WIDGET(object);
}
diff --git a/src/gtk+-2.x/ctkcurve.c b/src/gtk+-2.x/ctkcurve.c
index d3eed4d..0d1b8fd 100644
--- a/src/gtk+-2.x/ctkcurve.c
+++ b/src/gtk+-2.x/ctkcurve.c
@@ -212,9 +212,7 @@ static void ctk_curve_size_request(
requisition->height = REQUESTED_HEIGHT;
}
-static void color_changed(
- GtkWidget *widget
-)
+void ctk_curve_color_changed(GtkWidget *widget)
{
GdkRectangle rectangle;
@@ -268,7 +266,8 @@ GtkWidget* ctk_curve_new(NvCtrlAttributeHandle *handle, GtkWidget *color)
g_signal_connect_swapped(G_OBJECT(ctk_curve->color), "changed",
- G_CALLBACK(color_changed), (gpointer) ctk_curve);
+ G_CALLBACK(ctk_curve_color_changed),
+ (gpointer) ctk_curve);
return GTK_WIDGET(object);
}
diff --git a/src/gtk+-2.x/ctkcurve.h b/src/gtk+-2.x/ctkcurve.h
index 1a9e79d..04c2a9f 100644
--- a/src/gtk+-2.x/ctkcurve.h
+++ b/src/gtk+-2.x/ctkcurve.h
@@ -69,6 +69,7 @@ struct _CtkCurveClass
GType ctk_curve_get_type (void) G_GNUC_CONST;
GtkWidget* ctk_curve_new (NvCtrlAttributeHandle *, GtkWidget *);
+void ctk_curve_color_changed(GtkWidget *);
G_END_DECLS
diff --git a/src/gtk+-2.x/ctkdisplayconfig.c b/src/gtk+-2.x/ctkdisplayconfig.c
index 119d7cc..8b2240f 100644
--- a/src/gtk+-2.x/ctkdisplayconfig.c
+++ b/src/gtk+-2.x/ctkdisplayconfig.c
@@ -1175,9 +1175,6 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
GSList *slitem;
gint max_width;
- GtkWidget *menu;
- GtkWidget *menu_item;
-
gchar *err_str = NULL;
gchar *layout_str = NULL;
gchar *sli_mode = NULL;
@@ -1319,7 +1316,7 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
(gpointer) ctk_object);
/* Selected display/X screen dropdown */
- ctk_object->mnu_selected_item = gtk_option_menu_new();
+ ctk_object->mnu_selected_item = gtk_combo_box_new_text();
ctk_config_set_tooltip(ctk_config, ctk_object->mnu_selected_item,
__selected_item_help);
g_signal_connect(G_OBJECT(ctk_object->mnu_selected_item), "changed",
@@ -1327,7 +1324,7 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
(gpointer) ctk_object);
/* Display configuration (Disabled, TwinView, Separate X screen) */
- ctk_object->mnu_display_config = gtk_option_menu_new();
+ ctk_object->mnu_display_config = gtk_combo_box_new_text();
ctk_config_set_tooltip(ctk_config, ctk_object->mnu_display_config,
__dpy_configuration_mnu_help);
g_signal_connect(G_OBJECT(ctk_object->mnu_display_config), "changed",
@@ -1355,7 +1352,7 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
/* Display resolution */
- ctk_object->mnu_display_resolution = gtk_option_menu_new();
+ ctk_object->mnu_display_resolution = gtk_combo_box_new_text();
ctk_config_set_tooltip(ctk_config, ctk_object->mnu_display_resolution,
__dpy_resolution_mnu_help);
g_signal_connect(G_OBJECT(ctk_object->mnu_display_resolution), "changed",
@@ -1364,7 +1361,7 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
/* Display refresh */
- ctk_object->mnu_display_refresh = gtk_option_menu_new();
+ ctk_object->mnu_display_refresh = gtk_combo_box_new_text();
ctk_config_set_tooltip(ctk_config, ctk_object->mnu_display_refresh,
__dpy_refresh_mnu_help);
g_signal_connect(G_OBJECT(ctk_object->mnu_display_refresh), "changed",
@@ -1376,16 +1373,13 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
gtk_label_set_selectable(GTK_LABEL(ctk_object->txt_display_modename), TRUE);
/* Display passive stereo eye dropdown */
- ctk_object->mnu_display_stereo = gtk_option_menu_new();
- menu = gtk_menu_new();
- menu_item = gtk_menu_item_new_with_label("None");
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- menu_item = gtk_menu_item_new_with_label("Left");
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- menu_item = gtk_menu_item_new_with_label("Right");
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- gtk_option_menu_set_menu
- (GTK_OPTION_MENU(ctk_object->mnu_display_stereo), menu);
+ ctk_object->mnu_display_stereo = gtk_combo_box_new_text();
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ctk_object->mnu_display_stereo),
+ "None");
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ctk_object->mnu_display_stereo),
+ "Left");
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ctk_object->mnu_display_stereo),
+ "Right");
ctk_config_set_tooltip(ctk_config, ctk_object->mnu_display_stereo,
__dpy_stereo_help);
g_signal_connect(G_OBJECT(ctk_object->mnu_display_stereo),
@@ -1393,18 +1387,15 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
(gpointer) ctk_object);
/* Display rotation dropdown */
- ctk_object->mnu_display_rotation = gtk_option_menu_new();
- menu = gtk_menu_new();
- menu_item = gtk_menu_item_new_with_label("No Rotation");
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- menu_item = gtk_menu_item_new_with_label("Rotate Left");
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- menu_item = gtk_menu_item_new_with_label("Invert");
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- menu_item = gtk_menu_item_new_with_label("Rotate Right");
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- gtk_option_menu_set_menu
- (GTK_OPTION_MENU(ctk_object->mnu_display_rotation), menu);
+ ctk_object->mnu_display_rotation = gtk_combo_box_new_text();
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ctk_object->mnu_display_rotation),
+ "No Rotation");
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ctk_object->mnu_display_rotation),
+ "Rotate Left");
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ctk_object->mnu_display_rotation),
+ "Invert");
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ctk_object->mnu_display_rotation),
+ "Rotate Right");
ctk_config_set_tooltip(ctk_config, ctk_object->mnu_display_rotation,
__dpy_rotation_help);
g_signal_connect(G_OBJECT(ctk_object->mnu_display_rotation),
@@ -1412,18 +1403,15 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
(gpointer) ctk_object);
/* Display reflection dropdown */
- ctk_object->mnu_display_reflection = gtk_option_menu_new();
- menu = gtk_menu_new();
- menu_item = gtk_menu_item_new_with_label("No Reflection");
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- menu_item = gtk_menu_item_new_with_label("Reflect along X");
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- menu_item = gtk_menu_item_new_with_label("Reflect along Y");
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- menu_item = gtk_menu_item_new_with_label("Reflect along XY");
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- gtk_option_menu_set_menu
- (GTK_OPTION_MENU(ctk_object->mnu_display_reflection), menu);
+ ctk_object->mnu_display_reflection = gtk_combo_box_new_text();
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ctk_object->mnu_display_reflection),
+ "No Reflection");
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ctk_object->mnu_display_reflection),
+ "Reflect along X");
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ctk_object->mnu_display_reflection),
+ "Reflect along Y");
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ctk_object->mnu_display_reflection),
+ "Reflect along XY");
ctk_config_set_tooltip(ctk_config, ctk_object->mnu_display_reflection,
__dpy_reflection_help);
g_signal_connect(G_OBJECT(ctk_object->mnu_display_reflection),
@@ -1431,7 +1419,8 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
(gpointer) ctk_object);
/* Display Underscan text box and slider */
- ctk_object->txt_display_underscan = gtk_entry_new_with_max_length(6);
+ ctk_object->txt_display_underscan = gtk_entry_new();
+ gtk_entry_set_max_length(GTK_ENTRY(ctk_object->txt_display_underscan), 6);
gtk_entry_set_width_chars(GTK_ENTRY(ctk_object->txt_display_underscan), 6);
gtk_entry_set_text(GTK_ENTRY(ctk_object->txt_display_underscan), "0");
ctk_config_set_tooltip(ctk_config, ctk_object->txt_display_underscan,
@@ -1456,22 +1445,19 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
(gpointer) ctk_object);
/* Display Position Type (Absolute/Relative Menu) */
- ctk_object->mnu_display_position_type = gtk_option_menu_new();
- menu = gtk_menu_new();
- menu_item = gtk_menu_item_new_with_label("Absolute");
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- menu_item = gtk_menu_item_new_with_label("Right of");
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- menu_item = gtk_menu_item_new_with_label("Left of");
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- menu_item = gtk_menu_item_new_with_label("Above");
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- menu_item = gtk_menu_item_new_with_label("Below");
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- menu_item = gtk_menu_item_new_with_label("Clones");
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- gtk_option_menu_set_menu
- (GTK_OPTION_MENU(ctk_object->mnu_display_position_type), menu);
+ ctk_object->mnu_display_position_type = gtk_combo_box_new_text();
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ctk_object->mnu_display_position_type),
+ "Absolute");
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ctk_object->mnu_display_position_type),
+ "Right of");
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ctk_object->mnu_display_position_type),
+ "Left of");
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ctk_object->mnu_display_position_type),
+ "Above");
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ctk_object->mnu_display_position_type),
+ "Below");
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ctk_object->mnu_display_position_type),
+ "Same as");
ctk_config_set_tooltip(ctk_config, ctk_object->mnu_display_position_type,
__dpy_position_type_help);
g_signal_connect(G_OBJECT(ctk_object->mnu_display_position_type),
@@ -1479,7 +1465,7 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
(gpointer) ctk_object);
/* Display Position Relative (Display device to be relative to) */
- ctk_object->mnu_display_position_relative = gtk_option_menu_new();
+ ctk_object->mnu_display_position_relative = gtk_combo_box_new_text();
ctk_config_set_tooltip(ctk_config,
ctk_object->mnu_display_position_relative,
__dpy_position_relative_help);
@@ -1542,7 +1528,7 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
(gpointer) ctk_object);
/* X screen depth */
- ctk_object->mnu_screen_depth = gtk_option_menu_new();
+ ctk_object->mnu_screen_depth = gtk_combo_box_new_text();
ctk_config_set_tooltip(ctk_config, ctk_object->mnu_screen_depth,
__screen_depth_help);
g_signal_connect(G_OBJECT(ctk_object->mnu_screen_depth), "changed",
@@ -1554,8 +1540,7 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
if (ret == NvCtrlSuccess) {
- ctk_object->mnu_screen_stereo = gtk_option_menu_new();
- menu = gtk_menu_new();
+ ctk_object->mnu_screen_stereo = gtk_combo_box_new_text();
ctk_object->stereo_table_size = 0;
memset(ctk_object->stereo_table, 0,
@@ -1586,13 +1571,12 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
valid.u.bits.ints & (1 << stereo_mode)))) {
ctk_object->stereo_table[ctk_object->stereo_table_size++] =
stereo_mode;
- menu_item = gtk_menu_item_new_with_label(stereo_mode_str);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
+ gtk_combo_box_append_text(
+ GTK_COMBO_BOX(ctk_object->mnu_screen_stereo),
+ stereo_mode_str);
}
}
- gtk_option_menu_set_menu
- (GTK_OPTION_MENU(ctk_object->mnu_screen_stereo), menu);
ctk_config_set_tooltip(ctk_config, ctk_object->mnu_screen_stereo,
__screen_stereo_help);
g_signal_connect(G_OBJECT(ctk_object->mnu_screen_stereo),
@@ -1603,23 +1587,20 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
}
/* Screen Position Type (Absolute/Relative Menu) */
- ctk_object->mnu_screen_position_type = gtk_option_menu_new();
- menu = gtk_menu_new();
- menu_item = gtk_menu_item_new_with_label("Absolute");
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- menu_item = gtk_menu_item_new_with_label("Right of");
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- menu_item = gtk_menu_item_new_with_label("Left of");
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- menu_item = gtk_menu_item_new_with_label("Above");
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- menu_item = gtk_menu_item_new_with_label("Below");
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
+ ctk_object->mnu_screen_position_type = gtk_combo_box_new_text();
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ctk_object->mnu_screen_position_type),
+ "Absolute");
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ctk_object->mnu_screen_position_type),
+ "Right of");
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ctk_object->mnu_screen_position_type),
+ "Left of");
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ctk_object->mnu_screen_position_type),
+ "Above");
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ctk_object->mnu_screen_position_type),
+ "Below");
// XXX Add better support for this later.
- //menu_item = gtk_menu_item_new_with_label("Relative to");
- //gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- gtk_option_menu_set_menu
- (GTK_OPTION_MENU(ctk_object->mnu_screen_position_type), menu);
+ //gtk_combo_box_append_text(GTK_COMBO_BOX(ctk_object->mnu_screen_position_type),
+ // "Relative to");
ctk_config_set_tooltip(ctk_config, ctk_object->mnu_screen_position_type,
__screen_position_type_help);
g_signal_connect(G_OBJECT(ctk_object->mnu_screen_position_type),
@@ -1627,7 +1608,7 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
(gpointer) ctk_object);
/* Screen Position Relative (Screen to be relative to) */
- ctk_object->mnu_screen_position_relative = gtk_option_menu_new();
+ ctk_object->mnu_screen_position_relative = gtk_combo_box_new_text();
ctk_config_set_tooltip(ctk_config,
ctk_object->mnu_screen_position_relative,
__screen_position_relative_help);
@@ -2498,13 +2479,11 @@ static void update_selected_page(CtkDisplayConfig *ctk_object)
*
**/
-static GtkWidget* generate_selected_item_dropdown(CtkDisplayConfig *ctk_object,
- nvDisplayPtr cur_display,
- nvScreenPtr cur_screen,
- int *cur_idx)
+static void generate_selected_item_dropdown(CtkDisplayConfig *ctk_object,
+ nvDisplayPtr cur_display,
+ nvScreenPtr cur_screen,
+ int *cur_idx)
{
- GtkWidget *menu;
- GtkWidget *menu_item;
nvLayoutPtr layout = ctk_object->layout;
nvGpuPtr gpu;
nvDisplayPtr display;
@@ -2529,17 +2508,17 @@ static GtkWidget* generate_selected_item_dropdown(CtkDisplayConfig *ctk_object,
calloc(ctk_object->selected_item_table_len,
sizeof(SelectableItem));
+ gtk_list_store_clear(GTK_LIST_STORE(gtk_combo_box_get_model(
+ GTK_COMBO_BOX(ctk_object->mnu_selected_item))));
+
if (!ctk_object->selected_item_table) {
ctk_object->selected_item_table_len = 0;
- gtk_option_menu_remove_menu
- (GTK_OPTION_MENU(ctk_object->mnu_selected_item));
gtk_widget_set_sensitive(ctk_object->mnu_selected_item, False);
- return NULL;
+ return;
}
/* Create the dropdown menu and fill the lookup table */
- menu = gtk_menu_new();
idx = 0;
show_gpu_info = ((layout->num_gpus > 1) || ctk_object->advanced_mode) ? True : False;
@@ -2551,10 +2530,9 @@ static GtkWidget* generate_selected_item_dropdown(CtkDisplayConfig *ctk_object,
str = g_strdup_printf("X screen %d", screen->scrnum);
- menu_item = gtk_menu_item_new_with_label(str);
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ctk_object->mnu_selected_item),
+ str);
g_free(str);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- gtk_widget_show(menu_item);
ctk_object->selected_item_table[idx].type = SELECTABLE_ITEM_SCREEN;
ctk_object->selected_item_table[idx].u.screen = screen;
@@ -2581,10 +2559,9 @@ static GtkWidget* generate_selected_item_dropdown(CtkDisplayConfig *ctk_object,
str = g_strdup_printf("%s)", tmp);
g_free(tmp);
- menu_item = gtk_menu_item_new_with_label(str);
+ gtk_combo_box_append_text(
+ GTK_COMBO_BOX(ctk_object->mnu_selected_item), str);
g_free(str);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- gtk_widget_show(menu_item);
ctk_object->selected_item_table[idx].type = SELECTABLE_ITEM_DISPLAY;
ctk_object->selected_item_table[idx].u.display = display;
@@ -2592,8 +2569,6 @@ static GtkWidget* generate_selected_item_dropdown(CtkDisplayConfig *ctk_object,
}
}
- return menu;
-
} /* generate_selected_item_dropdown() */
@@ -2606,14 +2581,12 @@ static GtkWidget* generate_selected_item_dropdown(CtkDisplayConfig *ctk_object,
static void setup_selected_item_dropdown(CtkDisplayConfig *ctk_object)
{
- GtkWidget *menu;
nvDisplayPtr display = ctk_display_layout_get_selected_display
(CTK_DISPLAY_LAYOUT(ctk_object->obj_layout));
nvScreenPtr screen = ctk_display_layout_get_selected_screen
(CTK_DISPLAY_LAYOUT(ctk_object->obj_layout));
int cur_idx = 0;
-
if (!display && !screen) {
gtk_widget_set_sensitive(ctk_object->mnu_selected_item, False);
gtk_widget_hide(ctk_object->mnu_selected_item);
@@ -2623,23 +2596,15 @@ static void setup_selected_item_dropdown(CtkDisplayConfig *ctk_object)
gtk_widget_set_sensitive(ctk_object->mnu_selected_item, True);
gtk_widget_show(ctk_object->mnu_selected_item);
- menu = generate_selected_item_dropdown(ctk_object, display, screen,
- &cur_idx);
- if (!menu) {
- gtk_widget_set_sensitive(ctk_object->mnu_selected_item, False);
- return;
- }
-
/* Setup the menu and select the current model */
g_signal_handlers_block_by_func
(G_OBJECT(ctk_object->mnu_selected_item),
G_CALLBACK(selected_item_changed), (gpointer) ctk_object);
- gtk_option_menu_set_menu
- (GTK_OPTION_MENU(ctk_object->mnu_selected_item), menu);
+ generate_selected_item_dropdown(ctk_object, display, screen, &cur_idx);
- gtk_option_menu_set_history
- (GTK_OPTION_MENU(ctk_object->mnu_selected_item), cur_idx);
+ gtk_combo_box_set_active
+ (GTK_COMBO_BOX(ctk_object->mnu_selected_item), cur_idx);
g_signal_handlers_unblock_by_func
(G_OBJECT(ctk_object->mnu_selected_item),
@@ -2669,14 +2634,14 @@ static void setup_display_modename(CtkDisplayConfig *ctk_object)
if (!display->cur_mode || !display->cur_mode->modeline) {
- gtk_label_set(GTK_LABEL(ctk_object->txt_display_modename), "");
+ gtk_label_set_text(GTK_LABEL(ctk_object->txt_display_modename), "");
gtk_widget_set_sensitive(ctk_object->box_display_modename, FALSE);
return;
}
gtk_widget_set_sensitive(ctk_object->box_display_modename, TRUE);
- gtk_label_set(GTK_LABEL(ctk_object->txt_display_modename),
+ gtk_label_set_text(GTK_LABEL(ctk_object->txt_display_modename),
display->cur_mode->modeline->data.identifier);
} /* setup_display_modename() */
@@ -2763,43 +2728,40 @@ static void setup_display_config(CtkDisplayConfig *ctk_object)
ctk_object->display_config_table_len = num_options;
{
- GtkWidget *menu = gtk_menu_new();
int i;
gchar *label;
+ g_signal_handlers_block_by_func(G_OBJECT(ctk_object->mnu_display_config),
+ G_CALLBACK(display_config_changed),
+ (gpointer) ctk_object);
+
+ gtk_list_store_clear(GTK_LIST_STORE(gtk_combo_box_get_model
+ (GTK_COMBO_BOX(ctk_object->mnu_display_config))));
+
for (i = 0; i < num_options; i++) {
- GtkWidget *menu_item = NULL;
switch (options[i].config) {
case DPY_CFG_DISABLED:
- menu_item = gtk_menu_item_new_with_label("Disabled");
+ gtk_combo_box_append_text(
+ GTK_COMBO_BOX(ctk_object->mnu_display_config), "Disabled");
break;
case DPY_CFG_NEW_X_SCREEN:
- menu_item =
- gtk_menu_item_new_with_label("New X screen (requires X "
- "restart)");
+ gtk_combo_box_append_text(
+ GTK_COMBO_BOX(ctk_object->mnu_display_config),
+ "New X screen (requires X restart)");
break;
case DPY_CFG_X_SCREEN:
label = g_strdup_printf("X screen %d",
options[i].screen->scrnum);
- menu_item = gtk_menu_item_new_with_label(label);
+ gtk_combo_box_append_text(
+ GTK_COMBO_BOX(ctk_object->mnu_display_config), label);
g_free(label);
break;
}
- if (menu_item) {
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- gtk_widget_show(menu_item);
- }
}
- g_signal_handlers_block_by_func(G_OBJECT(ctk_object->mnu_display_config),
- G_CALLBACK(display_config_changed),
- (gpointer) ctk_object);
-
- gtk_option_menu_set_menu
- (GTK_OPTION_MENU(ctk_object->mnu_display_config), menu);
- gtk_option_menu_set_history(GTK_OPTION_MENU(ctk_object->mnu_display_config),
- cur_option);
+ gtk_combo_box_set_active(GTK_COMBO_BOX(ctk_object->mnu_display_config),
+ cur_option);
gtk_widget_set_sensitive(ctk_object->mnu_display_config, TRUE);
g_signal_handlers_unblock_by_func(G_OBJECT(ctk_object->mnu_display_config),
@@ -2820,8 +2782,7 @@ static void setup_display_config(CtkDisplayConfig *ctk_object)
static void setup_display_refresh_dropdown(CtkDisplayConfig *ctk_object)
{
- GtkWidget *menu;
- GtkWidget *menu_item;
+ GtkComboBox *combo_box = GTK_COMBO_BOX(ctk_object->mnu_display_refresh);
nvModeLinePtr modeline;
nvModeLinePtr auto_modeline;
nvModeLinePtr modelines;
@@ -2860,14 +2821,16 @@ static void setup_display_refresh_dropdown(CtkDisplayConfig *ctk_object)
/* Generate the refresh dropdown */
- menu = gtk_menu_new();
+ g_signal_handlers_block_by_func(G_OBJECT(ctk_object->mnu_display_refresh),
+ G_CALLBACK(display_refresh_changed),
+ (gpointer) ctk_object);
+ gtk_list_store_clear(GTK_LIST_STORE(gtk_combo_box_get_model
+ (GTK_COMBO_BOX(ctk_object->mnu_display_refresh))));
/* Special case the 'nvidia-auto-select' mode. */
if (IS_NVIDIA_DEFAULT_MODE(cur_modeline)) {
- menu_item = gtk_menu_item_new_with_label("Auto");
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- gtk_widget_show(menu_item);
+ gtk_combo_box_append_text(combo_box, "Auto");
ctk_object->refresh_table[ctk_object->refresh_table_len++] =
cur_modeline;
modelines = NULL; /* Skip building rest of refresh dropdown */
@@ -2995,23 +2958,17 @@ static void setup_display_refresh_dropdown(CtkDisplayConfig *ctk_object)
/* Add the modeline entry to the dropdown */
- menu_item = gtk_menu_item_new_with_label(name);
+ gtk_combo_box_append_text(combo_box, name);
g_free(name);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- gtk_widget_show(menu_item);
ctk_object->refresh_table[ctk_object->refresh_table_len++] = modeline;
}
- /* Setup the menu and select the current modeline */
- g_signal_handlers_block_by_func(G_OBJECT(ctk_object->mnu_display_refresh),
- G_CALLBACK(display_refresh_changed),
- (gpointer) ctk_object);
- gtk_option_menu_set_menu
- (GTK_OPTION_MENU(ctk_object->mnu_display_refresh), menu);
- gtk_option_menu_set_history(GTK_OPTION_MENU(ctk_object->mnu_display_refresh), cur_idx);
+ /* Select the current modeline */
+ gtk_combo_box_set_active(GTK_COMBO_BOX(ctk_object->mnu_display_refresh),
+ cur_idx);
gtk_widget_set_sensitive(ctk_object->mnu_display_refresh, True);
g_signal_handlers_unblock_by_func(G_OBJECT(ctk_object->mnu_display_refresh),
@@ -3084,7 +3041,7 @@ allocate_selected_mode(char *name,
selected_mode = (nvSelectedModePtr)nvalloc(sizeof(nvSelectedMode));
- selected_mode->label = gtk_menu_item_new_with_label(name);
+ selected_mode->text = g_strdup(name);
selected_mode->modeline = modeline;
selected_mode->isSpecial = isSpecial;
@@ -3118,6 +3075,7 @@ free_selected_modes(nvSelectedModePtr selected_mode)
{
if (selected_mode) {
free_selected_modes(selected_mode->next);
+ g_free(selected_mode->text);
free(selected_mode);
}
}
@@ -3280,20 +3238,26 @@ static void generate_selected_modes(const nvDisplayPtr display)
nvSelectedModePtr selected_mode = NULL;
nvModeLinePtr modeline;
- /* Add the off item */
- selected_mode = allocate_selected_mode("Off",
- NULL /* modeline */,
- TRUE /* isSpecial */,
- NULL /* viewPortIn */,
- NULL /* viewPortOut */);
+ display->num_selected_modes = 0;
+ display->selected_modes = NULL;
+
+ /* Add the off item if we have more than one display */
+ if (display->screen->num_displays > 1) {
+ selected_mode = allocate_selected_mode("Off",
+ NULL /* modeline */,
+ TRUE /* isSpecial */,
+ NULL /* viewPortIn */,
+ NULL /* viewPortOut */);
- display->num_selected_modes = 1;
- display->selected_modes = selected_mode;
+ display->num_selected_modes = 1;
+ display->selected_modes = selected_mode;
+ }
modeline = display->modelines;
while (modeline) {
gchar *name;
Bool isSpecial;
+ Bool mode_added;
if (IS_NVIDIA_DEFAULT_MODE(modeline)) {
name = g_strdup_printf("Auto");
@@ -3310,8 +3274,15 @@ static void generate_selected_modes(const nvDisplayPtr display)
NULL /* viewPortOut */);
g_free(name);
- if (append_unique_selected_mode(display->selected_modes,
- selected_mode)) {
+ if (!display->selected_modes) {
+ display->selected_modes = selected_mode;
+ mode_added = TRUE;
+ } else {
+ mode_added = append_unique_selected_mode(display->selected_modes,
+ selected_mode);
+ }
+
+ if (mode_added) {
display->num_selected_modes++;
if (matches_current_selected_mode(display, selected_mode,
@@ -3407,9 +3378,6 @@ static void generate_scaled_selected_modes(const nvDisplayPtr display)
static void setup_display_resolution_dropdown(CtkDisplayConfig *ctk_object)
{
- GtkWidget *menu;
- GtkWidget *menu_item;
-
nvDisplayPtr display = ctk_display_layout_get_selected_display
(CTK_DISPLAY_LAYOUT(ctk_object->obj_layout));
@@ -3447,22 +3415,36 @@ static void setup_display_resolution_dropdown(CtkDisplayConfig *ctk_object)
}
- if (display->cur_mode->modeline) {
- cur_idx = 1; /* Modeline is set, start off as 'nvidia-auto-select' */
+ if (display->cur_mode->modeline && display->screen->num_displays > 1) {
+ /*
+ * Modeline is set and we have more than 1 display, start off as
+ * 'nvidia-auto-select'
+ */
+ cur_idx = 1;
} else {
- cur_idx = 0; /* Modeline not set, start off as 'off'. */
+ /*
+ * Modeline not set, start off as 'off'. If we do not have more than
+ * 1 display, 'auto' will be at index 0.
+ */
+ cur_idx = 0;
}
- /* Start the menu generation */
- menu = gtk_menu_new();
+ /* Setup the menu */
+ g_signal_handlers_block_by_func
+ (G_OBJECT(ctk_object->mnu_display_resolution),
+ G_CALLBACK(display_resolution_changed), (gpointer) ctk_object);
+
+ gtk_list_store_clear(GTK_LIST_STORE(gtk_combo_box_get_model
+ (GTK_COMBO_BOX(ctk_object->mnu_display_resolution))));
/* Fill dropdown menu */
selected_mode = display->selected_modes;
while (selected_mode) {
- menu_item = selected_mode->label;
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- gtk_widget_show(menu_item);
+ gtk_combo_box_append_text(
+ GTK_COMBO_BOX(ctk_object->mnu_display_resolution),
+ selected_mode->text);
+
ctk_object->resolution_table[ctk_object->resolution_table_len] =
selected_mode;
@@ -3470,26 +3452,13 @@ static void setup_display_resolution_dropdown(CtkDisplayConfig *ctk_object)
cur_idx = ctk_object->resolution_table_len;
}
- if (selected_mode->isSpecial &&
- !selected_mode->modeline &&
- display->screen->num_displays <= 1) {
- gtk_widget_set_sensitive(menu_item, FALSE);
- }
-
ctk_object->resolution_table_len++;
selected_mode = selected_mode->next;
}
- /* Setup the menu and select the current mode */
- g_signal_handlers_block_by_func
- (G_OBJECT(ctk_object->mnu_display_resolution),
- G_CALLBACK(display_resolution_changed), (gpointer) ctk_object);
-
- gtk_option_menu_set_menu
- (GTK_OPTION_MENU(ctk_object->mnu_display_resolution), menu);
-
- gtk_option_menu_set_history
- (GTK_OPTION_MENU(ctk_object->mnu_display_resolution), cur_idx);
+ /* Select the current mode */
+ gtk_combo_box_set_active
+ (GTK_COMBO_BOX(ctk_object->mnu_display_resolution), cur_idx);
ctk_object->last_resolution_idx = cur_idx;
/* If dropdown has only one item, disable menu selection */
@@ -3510,8 +3479,8 @@ static void setup_display_resolution_dropdown(CtkDisplayConfig *ctk_object)
/* Handle failures */
fail:
- gtk_option_menu_remove_menu
- (GTK_OPTION_MENU(ctk_object->mnu_display_resolution));
+ gtk_list_store_clear(GTK_LIST_STORE(gtk_combo_box_get_model(
+ GTK_COMBO_BOX(ctk_object->mnu_display_resolution))));
gtk_widget_set_sensitive(ctk_object->mnu_display_resolution, FALSE);
@@ -3566,8 +3535,8 @@ static void setup_display_stereo_dropdown(CtkDisplayConfig *ctk_object)
break;
}
- gtk_option_menu_set_history
- (GTK_OPTION_MENU(ctk_object->mnu_display_stereo), idx);
+ gtk_combo_box_set_active
+ (GTK_COMBO_BOX(ctk_object->mnu_display_stereo), idx);
g_signal_handlers_unblock_by_func
(G_OBJECT(ctk_object->mnu_display_stereo),
@@ -3657,8 +3626,8 @@ static void setup_display_rotation_dropdown(CtkDisplayConfig *ctk_object)
break;
}
- gtk_option_menu_set_history
- (GTK_OPTION_MENU(ctk_object->mnu_display_rotation), idx);
+ gtk_combo_box_set_active
+ (GTK_COMBO_BOX(ctk_object->mnu_display_rotation), idx);
g_signal_handlers_unblock_by_func
(G_OBJECT(ctk_object->mnu_display_rotation),
@@ -3703,8 +3672,8 @@ static void setup_display_reflection_dropdown(CtkDisplayConfig *ctk_object)
break;
}
- gtk_option_menu_set_history
- (GTK_OPTION_MENU(ctk_object->mnu_display_reflection), idx);
+ gtk_combo_box_set_active
+ (GTK_COMBO_BOX(ctk_object->mnu_display_reflection), idx);
g_signal_handlers_unblock_by_func
(G_OBJECT(ctk_object->mnu_display_reflection),
@@ -3942,8 +3911,8 @@ static void setup_display_position_type(CtkDisplayConfig *ctk_object)
(G_OBJECT(ctk_object->mnu_display_position_type),
G_CALLBACK(display_position_type_changed), (gpointer) ctk_object);
- gtk_option_menu_set_history
- (GTK_OPTION_MENU(ctk_object->mnu_display_position_type),
+ gtk_combo_box_set_active
+ (GTK_COMBO_BOX(ctk_object->mnu_display_position_type),
display->cur_mode->position_type);
g_signal_handlers_unblock_by_func
@@ -3966,8 +3935,6 @@ static void setup_display_position_relative(CtkDisplayConfig *ctk_object)
nvDisplayPtr relative_to;
int idx;
int selected_idx;
- GtkWidget *menu;
- GtkWidget *menu_item;
display = ctk_display_layout_get_selected_display
(CTK_DISPLAY_LAYOUT(ctk_object->obj_layout));
@@ -3996,9 +3963,15 @@ static void setup_display_position_relative(CtkDisplayConfig *ctk_object)
/* Generate the lookup table and display dropdown */
+ g_signal_handlers_block_by_func
+ (G_OBJECT(ctk_object->mnu_display_position_relative),
+ G_CALLBACK(display_position_relative_changed), (gpointer) ctk_object);
+
+ gtk_list_store_clear(GTK_LIST_STORE(gtk_combo_box_get_model
+ (GTK_COMBO_BOX(ctk_object->mnu_display_position_relative))));
+
idx = 0;
selected_idx = 0;
- menu = gtk_menu_new();
for (relative_to = display->screen->displays;
relative_to;
relative_to = relative_to->next_in_screen) {
@@ -4011,23 +3984,16 @@ static void setup_display_position_relative(CtkDisplayConfig *ctk_object)
ctk_object->display_position_table[idx] = relative_to;
- menu_item = gtk_menu_item_new_with_label(relative_to->logName);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- gtk_widget_show(menu_item);
+ gtk_combo_box_append_text
+ (GTK_COMBO_BOX(ctk_object->mnu_display_position_relative),
+ relative_to->logName);
idx++;
}
/* Set the menu and the selected display */
- g_signal_handlers_block_by_func
- (G_OBJECT(ctk_object->mnu_display_position_relative),
- G_CALLBACK(display_position_relative_changed), (gpointer) ctk_object);
-
- gtk_option_menu_set_menu
- (GTK_OPTION_MENU(ctk_object->mnu_display_position_relative), menu);
-
- gtk_option_menu_set_history
- (GTK_OPTION_MENU(ctk_object->mnu_display_position_relative),
+ gtk_combo_box_set_active
+ (GTK_COMBO_BOX(ctk_object->mnu_display_position_relative),
selected_idx);
g_signal_handlers_unblock_by_func
@@ -4346,8 +4312,6 @@ static gboolean grow_screen_depth_table(CtkDisplayConfig *ctk_object)
static void setup_screen_depth_dropdown(CtkDisplayConfig *ctk_object)
{
- GtkWidget *menu;
- GtkWidget *menu_item;
int cur_idx;
gboolean add_depth_30_option;
nvScreenPtr screen = ctk_display_layout_get_selected_screen
@@ -4363,7 +4327,13 @@ static void setup_screen_depth_dropdown(CtkDisplayConfig *ctk_object)
ctk_object->screen_depth_table = NULL;
ctk_object->screen_depth_table_len = 0;
- menu = gtk_menu_new();
+ g_signal_handlers_block_by_func(G_OBJECT(ctk_object->mnu_screen_depth),
+ G_CALLBACK(screen_depth_changed),
+ (gpointer) ctk_object);
+
+ gtk_list_store_clear(GTK_LIST_STORE(gtk_combo_box_get_model
+ (GTK_COMBO_BOX(ctk_object->mnu_screen_depth))));
+
/* If Xinerama is enabled, only allow depth 30 if all
* gpu/screens have support for depth 30.
@@ -4378,54 +4348,42 @@ static void setup_screen_depth_dropdown(CtkDisplayConfig *ctk_object)
if (add_depth_30_option) {
if (grow_screen_depth_table(ctk_object)) {
- menu_item = gtk_menu_item_new_with_label
- ("1.1 Billion Colors (Depth 30) - Experimental");
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- gtk_widget_show(menu_item);
-
+ gtk_combo_box_append_text
+ (GTK_COMBO_BOX(ctk_object->mnu_screen_depth),
+ "1.1 Billion Colors (Depth 30) - Experimental");
ctk_object->screen_depth_table[ctk_object->screen_depth_table_len-1] = 30;
}
}
if (grow_screen_depth_table(ctk_object)) {
- menu_item = gtk_menu_item_new_with_label("16.7 Million Colors (Depth 24)");
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- gtk_widget_show(menu_item);
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ctk_object->mnu_screen_depth),
+ "16.7 Million Colors (Depth 24)");
ctk_object->screen_depth_table[ctk_object->screen_depth_table_len-1] = 24;
}
if (grow_screen_depth_table(ctk_object)) {
- menu_item = gtk_menu_item_new_with_label("65,536 Colors (Depth 16)");
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- gtk_widget_show(menu_item);
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ctk_object->mnu_screen_depth),
+ "65,536 Colors (Depth 16)");
ctk_object->screen_depth_table[ctk_object->screen_depth_table_len-1] = 16;
}
if (grow_screen_depth_table(ctk_object)) {
- menu_item = gtk_menu_item_new_with_label("32,768 Colors (Depth 15)");
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- gtk_widget_show(menu_item);
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ctk_object->mnu_screen_depth),
+ "32,768 Colors (Depth 15)");
ctk_object->screen_depth_table[ctk_object->screen_depth_table_len-1] = 15;
}
if (grow_screen_depth_table(ctk_object)) {
- menu_item = gtk_menu_item_new_with_label("256 Colors (Depth 8)");
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- gtk_widget_show(menu_item);
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ctk_object->mnu_screen_depth),
+ "256 Colors (Depth 8)");
ctk_object->screen_depth_table[ctk_object->screen_depth_table_len-1] = 8;
}
- g_signal_handlers_block_by_func(G_OBJECT(ctk_object->mnu_screen_depth),
- G_CALLBACK(screen_depth_changed),
- (gpointer) ctk_object);
-
- gtk_option_menu_set_menu
- (GTK_OPTION_MENU(ctk_object->mnu_screen_depth), menu);
for (cur_idx = 0; cur_idx < ctk_object->screen_depth_table_len; cur_idx++) {
if (screen->depth == ctk_object->screen_depth_table[cur_idx]) {
- gtk_option_menu_set_history
- (GTK_OPTION_MENU(ctk_object->mnu_screen_depth), cur_idx);
+ gtk_combo_box_set_active
+ (GTK_COMBO_BOX(ctk_object->mnu_screen_depth), cur_idx);
}
}
@@ -4475,8 +4433,8 @@ static void setup_screen_stereo_dropdown(CtkDisplayConfig *ctk_object)
(G_OBJECT(ctk_object->mnu_screen_stereo),
G_CALLBACK(screen_stereo_changed), (gpointer) ctk_object);
- gtk_option_menu_set_history
- (GTK_OPTION_MENU(ctk_object->mnu_screen_stereo),
+ gtk_combo_box_set_active
+ (GTK_COMBO_BOX(ctk_object->mnu_screen_stereo),
index);
g_signal_handlers_unblock_by_func
@@ -4515,8 +4473,8 @@ static void setup_screen_position_type(CtkDisplayConfig *ctk_object)
(G_OBJECT(ctk_object->mnu_screen_position_type),
G_CALLBACK(screen_position_type_changed), (gpointer) ctk_object);
- gtk_option_menu_set_history
- (GTK_OPTION_MENU(ctk_object->mnu_screen_position_type),
+ gtk_combo_box_set_active
+ (GTK_COMBO_BOX(ctk_object->mnu_screen_position_type),
screen->position_type);
g_signal_handlers_unblock_by_func
@@ -4540,8 +4498,6 @@ static void setup_screen_position_relative(CtkDisplayConfig *ctk_object)
nvScreenPtr relative_to;
int idx;
int selected_idx;
- GtkWidget *menu;
- GtkWidget *menu_item;
screen = ctk_display_layout_get_selected_screen
(CTK_DISPLAY_LAYOUT(ctk_object->obj_layout));
@@ -4571,9 +4527,15 @@ static void setup_screen_position_relative(CtkDisplayConfig *ctk_object)
/* Generate the lookup table and screen dropdown */
+ g_signal_handlers_block_by_func
+ (G_OBJECT(ctk_object->mnu_screen_position_relative),
+ G_CALLBACK(screen_position_relative_changed), (gpointer) ctk_object);
+
+ gtk_list_store_clear(GTK_LIST_STORE(gtk_combo_box_get_model
+ (GTK_COMBO_BOX(ctk_object->mnu_screen_position_relative))));
+
idx = 0;
selected_idx = 0;
- menu = gtk_menu_new();
for (relative_to = layout->screens;
relative_to;
@@ -4591,24 +4553,16 @@ static void setup_screen_position_relative(CtkDisplayConfig *ctk_object)
tmp_str = g_strdup_printf("X screen %d",
relative_to->scrnum);
- menu_item = gtk_menu_item_new_with_label(tmp_str);
+ gtk_combo_box_append_text
+ (GTK_COMBO_BOX(ctk_object->mnu_screen_position_relative), tmp_str);
g_free(tmp_str);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- gtk_widget_show(menu_item);
idx++;
}
/* Set the menu and the selected display */
- g_signal_handlers_block_by_func
- (G_OBJECT(ctk_object->mnu_screen_position_relative),
- G_CALLBACK(screen_position_relative_changed), (gpointer) ctk_object);
-
- gtk_option_menu_set_menu
- (GTK_OPTION_MENU(ctk_object->mnu_screen_position_relative), menu);
-
- gtk_option_menu_set_history
- (GTK_OPTION_MENU(ctk_object->mnu_screen_position_relative),
+ gtk_combo_box_set_active
+ (GTK_COMBO_BOX(ctk_object->mnu_screen_position_relative),
selected_idx);
g_signal_handlers_unblock_by_func
@@ -5289,7 +5243,7 @@ static void selected_item_changed(GtkWidget *widget, gpointer user_data)
gint idx;
SelectableItem *item;
- idx = gtk_option_menu_get_history(GTK_OPTION_MENU(widget));
+ idx = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
item = &(ctk_object->selected_item_table[idx]);
switch (item->type) {
@@ -5792,7 +5746,7 @@ static void display_config_changed(GtkWidget *widget, gpointer user_data)
}
table_idx =
- gtk_option_menu_get_history(GTK_OPTION_MENU(ctk_object->mnu_display_config));
+ gtk_combo_box_get_active(GTK_COMBO_BOX(ctk_object->mnu_display_config));
option = &(ctk_object->display_config_table[table_idx]);
switch (option->config) {
@@ -5880,7 +5834,7 @@ static void display_refresh_changed(GtkWidget *widget, gpointer user_data)
/* Get the modeline and display to set */
- idx = gtk_option_menu_get_history(GTK_OPTION_MENU(widget));
+ idx = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
modeline = ctk_object->refresh_table[idx];
display = ctk_display_layout_get_selected_display
(CTK_DISPLAY_LAYOUT(ctk_object->obj_layout));
@@ -5934,7 +5888,7 @@ static void display_resolution_changed(GtkWidget *widget, gpointer user_data)
/* Get the modeline and display to set */
- idx = gtk_option_menu_get_history(GTK_OPTION_MENU(widget));
+ idx = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
selected_mode = ctk_object->resolution_table[idx];
display = ctk_display_layout_get_selected_display
(CTK_DISPLAY_LAYOUT(ctk_object->obj_layout));
@@ -6012,7 +5966,7 @@ static void display_stereo_changed(GtkWidget *widget, gpointer user_data)
if (display && display->cur_mode) {
mode = display->cur_mode;
- idx = gtk_option_menu_get_history(GTK_OPTION_MENU(widget));
+ idx = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
switch (idx) {
case 1:
mode->passive_stereo_eye = PASSIVE_STEREO_EYE_LEFT;
@@ -6056,7 +6010,7 @@ static void display_rotation_changed(GtkWidget *widget, gpointer user_data)
return;
}
- idx = gtk_option_menu_get_history(GTK_OPTION_MENU(widget));
+ idx = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
switch (idx) {
case 1:
rotation = ROTATION_90;
@@ -6103,7 +6057,7 @@ static void display_reflection_changed(GtkWidget *widget, gpointer user_data)
return;
}
- idx = gtk_option_menu_get_history(GTK_OPTION_MENU(widget));
+ idx = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
switch (idx) {
case 1:
reflection = REFLECTION_X;
@@ -6293,14 +6247,14 @@ static void display_position_type_changed(GtkWidget *widget,
/* Get the new position type */
position_idx =
- gtk_option_menu_get_history
- (GTK_OPTION_MENU(ctk_object->mnu_display_position_type));
+ gtk_combo_box_get_active
+ (GTK_COMBO_BOX(ctk_object->mnu_display_position_type));
position_type = __position_table[position_idx];
relative_to_idx =
- gtk_option_menu_get_history
- (GTK_OPTION_MENU(ctk_object->mnu_display_position_relative));
+ gtk_combo_box_get_active
+ (GTK_COMBO_BOX(ctk_object->mnu_display_position_relative));
if (relative_to_idx >= 0 &&
relative_to_idx < ctk_object->display_position_table_len) {
@@ -6353,13 +6307,13 @@ static void display_position_relative_changed(GtkWidget *widget,
(CTK_DISPLAY_LAYOUT(ctk_object->obj_layout));
/* Get the new display to be relative to */
- position_idx = gtk_option_menu_get_history
- (GTK_OPTION_MENU(ctk_object->mnu_display_position_type));
+ position_idx = gtk_combo_box_get_active
+ (GTK_COMBO_BOX(ctk_object->mnu_display_position_type));
position_type = __position_table[position_idx];
- relative_to_idx = gtk_option_menu_get_history
- (GTK_OPTION_MENU(ctk_object->mnu_display_position_relative));
+ relative_to_idx = gtk_combo_box_get_active
+ (GTK_COMBO_BOX(ctk_object->mnu_display_position_relative));
if (relative_to_idx >= 0 &&
relative_to_idx < ctk_object->display_position_table_len) {
@@ -6606,7 +6560,7 @@ static gboolean txt_focus_out(GtkWidget *widget, GdkEvent *event,
static void screen_depth_changed(GtkWidget *widget, gpointer user_data)
{
CtkDisplayConfig *ctk_object = CTK_DISPLAY_CONFIG(user_data);
- gint idx = gtk_option_menu_get_history(GTK_OPTION_MENU(widget));
+ gint idx = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
int depth;
nvScreenPtr screen = ctk_display_layout_get_selected_screen
(CTK_DISPLAY_LAYOUT(ctk_object->obj_layout));
@@ -6660,7 +6614,7 @@ static void screen_depth_changed(GtkWidget *widget, gpointer user_data)
static void screen_stereo_changed(GtkWidget *widget, gpointer user_data)
{
CtkDisplayConfig *ctk_object = CTK_DISPLAY_CONFIG(user_data);
- gint idx = gtk_option_menu_get_history(GTK_OPTION_MENU(widget));
+ gint idx = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
nvScreenPtr screen = ctk_display_layout_get_selected_screen
(CTK_DISPLAY_LAYOUT(ctk_object->obj_layout));
@@ -6709,14 +6663,14 @@ static void screen_position_type_changed(GtkWidget *widget,
/* Get the new position type */
position_idx =
- gtk_option_menu_get_history
- (GTK_OPTION_MENU(ctk_object->mnu_screen_position_type));
+ gtk_combo_box_get_active
+ (GTK_COMBO_BOX(ctk_object->mnu_screen_position_type));
position_type = __position_table[position_idx];
relative_to_idx =
- gtk_option_menu_get_history
- (GTK_OPTION_MENU(ctk_object->mnu_screen_position_relative));
+ gtk_combo_box_get_active
+ (GTK_COMBO_BOX(ctk_object->mnu_screen_position_relative));
if (relative_to_idx >= 0 &&
relative_to_idx < ctk_object->screen_position_table_len) {
@@ -6769,13 +6723,13 @@ static void screen_position_relative_changed(GtkWidget *widget,
if (!screen) return;
/* Get the new X screen to be relative to */
- position_idx = gtk_option_menu_get_history
- (GTK_OPTION_MENU(ctk_object->mnu_screen_position_type));
+ position_idx = gtk_combo_box_get_active
+ (GTK_COMBO_BOX(ctk_object->mnu_screen_position_type));
position_type = __position_table[position_idx];
- relative_to_idx = gtk_option_menu_get_history
- (GTK_OPTION_MENU(ctk_object->mnu_screen_position_relative));
+ relative_to_idx = gtk_combo_box_get_active
+ (GTK_COMBO_BOX(ctk_object->mnu_screen_position_relative));
if (relative_to_idx >= 0 &&
relative_to_idx < ctk_object->screen_position_table_len) {
diff --git a/src/gtk+-2.x/ctkdisplaydevice.c b/src/gtk+-2.x/ctkdisplaydevice.c
index e8900ae..4184ba0 100644
--- a/src/gtk+-2.x/ctkdisplaydevice.c
+++ b/src/gtk+-2.x/ctkdisplaydevice.c
@@ -54,6 +54,7 @@ static void callback_link_changed(GtkObject *object, gpointer arg1,
static void callback_refresh_rate_changed(GtkObject *object, gpointer arg1,
gpointer user_data);
+static gboolean update_guid_info(InfoEntry *entry);
static gboolean update_tv_encoder_info(InfoEntry *entry);
static gboolean update_chip_info(InfoEntry *entry);
static gboolean update_signal_info(InfoEntry *entry);
@@ -77,6 +78,9 @@ static const char *__info_help =
"This section describes basic information about the connection to the display "
"device.";
+static const char*__guid_help =
+"The Global Unique Identifier for the display port display device.";
+
static const char* __tv_encoder_name_help =
"The TV Encoder name displays the name of the TV Encoder.";
@@ -110,7 +114,14 @@ typedef struct {
static InfoEntryData __info_entry_data[] = {
{
- "TV Encoder:",
+ "GUID",
+ &__guid_help,
+ update_guid_info,
+ NULL,
+ NULL,
+ },
+ {
+ "TV Encoder",
&__tv_encoder_name_help,
update_tv_encoder_info,
NULL,
@@ -412,13 +423,19 @@ GtkWidget* ctk_display_device_new(NvCtrlAttributeHandle *handle,
gtk_label_new("Controls"));
}
+ /*
+ * Show all widgets on this page so far. After this, the color correction
+ * tab and other widgets can control their own visibility.
+ */
+
+ gtk_widget_show_all(GTK_WIDGET(object));
+
/* add the color correction tab if RandR is available */
add_color_correction_tab(ctk_object, ctk_config, ctk_event, notebook, p);
/* Update the GUI */
- gtk_widget_show_all(GTK_WIDGET(object));
display_device_setup(ctk_object);
/* Listen to events */
@@ -531,6 +548,28 @@ GtkTextBuffer *ctk_display_device_create_help(GtkTextTagTable *table,
} /* ctk_display_device_create_help() */
+
+static gboolean update_guid_info(InfoEntry *entry)
+{
+ CtkDisplayDevice *ctk_object = entry->ctk_object;
+ ReturnStatus ret;
+ char *str;
+
+ ret = NvCtrlGetStringDisplayAttribute(ctk_object->handle, 0,
+ NV_CTRL_STRING_DISPLAY_NAME_DP_GUID, &str);
+ if (ret != NvCtrlSuccess) {
+ return FALSE;
+ }
+
+ gtk_label_set_text(GTK_LABEL(entry->txt), str);
+
+ XFree(str);
+
+ return TRUE;
+}
+
+
+
static gboolean update_tv_encoder_info(InfoEntry *entry)
{
CtkDisplayDevice *ctk_object = entry->ctk_object;
@@ -919,4 +958,5 @@ static void add_color_correction_tab(CtkDisplayDevice *ctk_object,
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), box,
gtk_label_new("Color Correction"));
+ gtk_widget_show(box);
}
diff --git a/src/gtk+-2.x/ctkdisplaylayout.c b/src/gtk+-2.x/ctkdisplaylayout.c
index 8cdc438..1913776 100644
--- a/src/gtk+-2.x/ctkdisplaylayout.c
+++ b/src/gtk+-2.x/ctkdisplaylayout.c
@@ -514,7 +514,7 @@ static int point_in_screen(nvScreenPtr screen, int x, int y)
/** get_point_relative_position() ************************************
*
* Returns where the point (x, y) is, relative to the given rectangle
- * as: above, below, left-of, right-of, inside/clones.
+ * as: above, below, left-of, right-of, inside.
*
**/
@@ -710,7 +710,7 @@ static int resolve_display(nvDisplayPtr display, int mode_idx,
pos->y = relative_pos.y - pos->height;
break;
- case CONF_ADJ_RELATIVE: /* Clone */
+ case CONF_ADJ_RELATIVE: /* Inside */
resolve_display(mode->relative_to, mode_idx, &relative_pos);
pos->x = relative_pos.x;
pos->y = relative_pos.y;
@@ -826,7 +826,7 @@ static int resolve_screen(nvScreenPtr screen, GdkRectangle *pos)
pos->y = relative_pos.y - pos->height;
break;
- case CONF_ADJ_RELATIVE: /* Clone */
+ case CONF_ADJ_RELATIVE: /* Inside */
resolve_screen(screen->relative_to, &relative_pos);
pos->x = relative_pos.x;
pos->y = relative_pos.y;
@@ -4152,13 +4152,13 @@ void ctk_display_layout_set_screen_position(CtkDisplayLayout *ctk_object,
* circular setup
*
* eg. CRT-0 left of CRT-1
- * CRT-1 clones CRT-0 <- Shouldn't allow this
+ * CRT-1 same as CRT-0 <- Shouldn't allow this
*
* also:
*
* CRT-0 left of CRT-1
* CRT-1 left of CRT-2
- * CRT-2 clones CRT-0 ... Eep!
+ * CRT-2 same as CRT-0 ... Eep!
*/
/* Recalculate the layout */
@@ -4252,12 +4252,12 @@ expose_event_callback(GtkWidget *widget, GdkEventExpose *event, gpointer data)
gdk_gc_set_values(fg_gc, &old_gc_values, GDK_GC_FOREGROUND);
- gdk_draw_pixmap(widget->window,
- fg_gc,
- ctk_object->pixmap,
- event->area.x, event->area.y,
- event->area.x, event->area.y,
- event->area.width, event->area.height);
+ gdk_draw_drawable(widget->window,
+ fg_gc,
+ ctk_object->pixmap,
+ event->area.x, event->area.y,
+ event->area.x, event->area.y,
+ event->area.width, event->area.height);
gdk_window_end_paint(widget->window);
diff --git a/src/gtk+-2.x/ctkdisplaylayout.h b/src/gtk+-2.x/ctkdisplaylayout.h
index 34a7b44..f8039d6 100644
--- a/src/gtk+-2.x/ctkdisplaylayout.h
+++ b/src/gtk+-2.x/ctkdisplaylayout.h
@@ -166,7 +166,7 @@ typedef struct nvModeLineRec {
typedef struct nvSelectedModeRec {
struct nvSelectedModeRec *next;
- GtkWidget *label; /* Label shown in dropdown menu */
+ gchar *text; /* Text shown in dropdown menu */
nvModeLinePtr modeline; /* Modeline this mode references */
diff --git a/src/gtk+-2.x/ctkditheringcontrols.c b/src/gtk+-2.x/ctkditheringcontrols.c
index cb4e391..97d4a15 100644
--- a/src/gtk+-2.x/ctkditheringcontrols.c
+++ b/src/gtk+-2.x/ctkditheringcontrols.c
@@ -201,7 +201,7 @@ GtkWidget* ctk_dithering_controls_new(NvCtrlAttributeHandle *handle,
/* Build Dithering widgets & pack them in table */
/* dropdown list for dithering configuration */
menu = (CtkDropDownMenu *)
- ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_COMBO);
+ ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_READONLY);
ctk_drop_down_menu_append_item(menu, "Auto", 0);
ctk_drop_down_menu_append_item(menu, "Enabled", 1);
@@ -258,7 +258,7 @@ GtkWidget* ctk_dithering_controls_new(NvCtrlAttributeHandle *handle,
/* dropdown list for dithering modes - populated in setup */
ctk_dithering_controls->dithering_mode_menu =
- ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_COMBO);
+ ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_READONLY);
ctk_config_set_tooltip(ctk_config,
ctk_dithering_controls->dithering_mode_menu,
__dithering_mode_help);
@@ -309,7 +309,7 @@ GtkWidget* ctk_dithering_controls_new(NvCtrlAttributeHandle *handle,
/* dithering depth */
menu = (CtkDropDownMenu *)
- ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_COMBO);
+ ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_READONLY);
ctk_drop_down_menu_append_item(menu, "Auto", 0);
ctk_drop_down_menu_append_item(menu, "6 bpc", 1);
diff --git a/src/gtk+-2.x/ctkdropdownmenu.c b/src/gtk+-2.x/ctkdropdownmenu.c
index ec830b5..0ef6e28 100644
--- a/src/gtk+-2.x/ctkdropdownmenu.c
+++ b/src/gtk+-2.x/ctkdropdownmenu.c
@@ -18,6 +18,7 @@
*/
#include <gtk/gtk.h>
+#include <assert.h>
#include <string.h>
#include "ctkdropdownmenu.h"
@@ -35,6 +36,8 @@ ctk_drop_down_menu_class_init(CtkDropDownMenuClass *ctk_drop_down_menu_class);
static void ctk_drop_down_menu_free(GObject *object);
+static void ctk_drop_down_menu_set_current_index(CtkDropDownMenu *d, gint index);
+
GType ctk_drop_down_menu_get_type(
void
@@ -87,7 +90,7 @@ ctk_drop_down_menu_class_init(CtkDropDownMenuClass *ctk_drop_down_menu_class)
* changed() - emit the "changed" signal
*/
-static void changed(GtkWidget *menu, gpointer user_data)
+static void changed(GtkWidget *combo_box, gpointer user_data)
{
CtkDropDownMenu *d = CTK_DROP_DOWN_MENU(user_data);
@@ -109,11 +112,7 @@ static void ctk_drop_down_menu_free(GObject *object)
d = CTK_DROP_DOWN_MENU(object);
g_free(d->values);
-
- if (d->glist) {
- g_list_free(d->glist);
- }
-
+
} /* ctk_drop_down_menu_free() */
@@ -128,17 +127,17 @@ GObject *ctk_drop_down_menu_change_object(GtkWidget* widget)
{
CtkDropDownMenu *d = CTK_DROP_DOWN_MENU(widget);
- if (d->flags & CTK_DROP_DOWN_MENU_FLAG_COMBO) {
- return G_OBJECT(GTK_EDITABLE(GTK_COMBO(d->menu)->entry));
+ if (d->flags & CTK_DROP_DOWN_MENU_FLAG_READWRITE) {
+ return G_OBJECT(GTK_EDITABLE(GTK_BIN(d->combo_box)->child));
} else {
- return G_OBJECT(d->option_menu);
+ return G_OBJECT(d->combo_box);
}
} /* ctk_drop_down_menu_change_object() */
/*
- * ctk_drop_down_menu_changed() - callback function for GtkCombo menu
+ * ctk_drop_down_menu_changed() - callback function for GtkCombo combo box
* changed.
*/
@@ -167,7 +166,6 @@ GtkWidget* ctk_drop_down_menu_new(guint flags)
{
GObject *object;
CtkDropDownMenu *d;
- GtkWidget *menu_widget; // used to emit "changed" signal
object = g_object_new(CTK_TYPE_DROP_DOWN_MENU, NULL);
@@ -176,26 +174,23 @@ GtkWidget* ctk_drop_down_menu_new(guint flags)
d->flags = flags;
d->values = NULL;
d->num_entries = 0;
+ d->current_selected_item = -1;
- if (flags & CTK_DROP_DOWN_MENU_FLAG_COMBO) {
- d->menu = gtk_combo_new();
- menu_widget = d->menu;
- g_signal_connect(G_OBJECT(GTK_EDITABLE(GTK_COMBO(d->menu)->entry)),
+ if (flags & CTK_DROP_DOWN_MENU_FLAG_READWRITE) {
+ d->combo_box = gtk_combo_box_entry_new_text();
+ g_signal_connect(G_OBJECT(GTK_EDITABLE(GTK_BIN(d->combo_box)->child)),
"changed",
G_CALLBACK(ctk_drop_down_menu_changed),
(gpointer) d);
} else {
- d->option_menu = gtk_option_menu_new();
- d->menu = gtk_menu_new();
- gtk_option_menu_set_menu(GTK_OPTION_MENU(d->option_menu), d->menu);
- menu_widget = d->option_menu;
- g_signal_connect(G_OBJECT(d->option_menu), "changed",
+ d->combo_box = gtk_combo_box_new_text();
+ g_signal_connect(G_OBJECT(d->combo_box), "changed",
G_CALLBACK(changed), (gpointer) d);
}
gtk_box_set_spacing(GTK_BOX(d), 0);
- gtk_box_pack_start(GTK_BOX(d), menu_widget, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(d), d->combo_box, FALSE, FALSE, 0);
return GTK_WIDGET(d);
@@ -204,15 +199,13 @@ GtkWidget* ctk_drop_down_menu_new(guint flags)
/*
- * ctk_drop_down_menu_reset() - Clears the internal menu
+ * ctk_drop_down_menu_reset() - Clears the internal combo box
*/
void ctk_drop_down_menu_reset(CtkDropDownMenu *d)
{
- if (d->glist) {
- g_list_free(d->glist);
- d->glist = NULL;
- }
+ GtkComboBox *combobox = GTK_COMBO_BOX(d->combo_box);
+
if (d->values) {
g_free(d->values);
d->values = NULL;
@@ -220,10 +213,7 @@ void ctk_drop_down_menu_reset(CtkDropDownMenu *d)
d->num_entries = 0;
- if (!(d->flags & CTK_DROP_DOWN_MENU_FLAG_COMBO)) {
- d->menu = gtk_menu_new();
- gtk_option_menu_set_menu(GTK_OPTION_MENU(d->option_menu), d->menu);
- }
+ gtk_list_store_clear(GTK_LIST_STORE(gtk_combo_box_get_model(combobox)));
} /* ctk_drop_down_menu_reset() */
@@ -231,7 +221,7 @@ void ctk_drop_down_menu_reset(CtkDropDownMenu *d)
/*
* ctk_drop_down_menu_append_item() - add a new entry to the drop down
- * menu
+ * combo box
*/
GtkWidget *ctk_drop_down_menu_append_item(CtkDropDownMenu *d,
@@ -239,119 +229,133 @@ GtkWidget *ctk_drop_down_menu_append_item(CtkDropDownMenu *d,
const gint value)
{
GtkWidget *label = NULL;
-
+
d->values = g_realloc(d->values,
sizeof(CtkDropDownMenuValue) * (d->num_entries + 1));
-
- if (d->flags & CTK_DROP_DOWN_MENU_FLAG_COMBO) {
- d->glist = g_list_append(d->glist,
- g_strdup(name));
- gtk_combo_set_popdown_strings(GTK_COMBO(d->menu), d->glist);
- gtk_editable_set_editable(GTK_EDITABLE(GTK_COMBO(d->menu)->entry), FALSE);
- d->values[d->num_entries].glist_item = g_strdup(name);
- } else {
- GtkWidget *menu_item, *alignment;
- gchar *str;
-
- menu_item = gtk_menu_item_new();
- gtk_menu_shell_append(GTK_MENU_SHELL(d->menu), menu_item);
-
- if (d->flags & CTK_DROP_DOWN_MENU_FLAG_MONOSPACE) {
- str = g_strconcat("<tt><small>", name, "</small></tt>", NULL);
- label = gtk_label_new(NULL);
- gtk_label_set_markup(GTK_LABEL(label), str);
- g_free(str);
- } else {
- label = gtk_label_new(name);
- }
- alignment = gtk_alignment_new(0, 0, 0, 0);
- gtk_container_add(GTK_CONTAINER(alignment), label);
- gtk_container_add(GTK_CONTAINER(menu_item), alignment);
- d->values[d->num_entries].menu_item = menu_item;
-
- }
+ gtk_combo_box_append_text(GTK_COMBO_BOX(d->combo_box), name);
+ d->values[d->num_entries].glist_item = g_strdup(name);
d->values[d->num_entries].value = value;
d->num_entries++;
+ if (d->num_entries == 1) {
+ /*
+ * If this is the first item, make this the current item.
+ */
+ ctk_drop_down_menu_set_current_index(d, 0);
+ }
+
return label;
-
+
} /* ctk_drop_down_menu_append_item() */
/*
- * ctk_drop_down_menu_get_current_value() - return the current value
- * selected in the drop down menu, or 0 if the current item is undefined.
+ * ctk_drop_down_menu_get_current_value() - return the current value selected in
+ * the drop down combo box. In the case where no current item is selected and
+ * the menu has one or more valid items, this has the side effect of selecting
+ * the first item from the menu as its current item, then returning its value.
+ *
+ * In the case where the menu has no valid items, this function returns 0.
*/
-
gint ctk_drop_down_menu_get_current_value(CtkDropDownMenu *d)
{
gint i;
- if (d->flags & CTK_DROP_DOWN_MENU_FLAG_COMBO) {
+ if (d->flags & CTK_DROP_DOWN_MENU_FLAG_READWRITE) {
i = d->current_selected_item;
} else {
- i = gtk_option_menu_get_history(GTK_OPTION_MENU(d->option_menu));
+ /* This returns -1 if no item is active */
+ i = gtk_combo_box_get_active(GTK_COMBO_BOX(d->combo_box));
}
- if (i < d->num_entries) {
+ if (d->num_entries > 0) {
+ /* Default to the first item if the current selection is invalid */
+ if ((i < 0) || (i >= d->num_entries)) {
+ i = 0;
+ ctk_drop_down_menu_set_current_index(d, 0);
+ }
return d->values[i].value;
- } else {
- return 0; /* XXX??? */
+ } else {
+ return 0;
}
} /* ctk_drop_down_menu_get_current_value() */
/*
- * ctk_drop_down_menu_get_current_name() - get the current name in the menu, or
- * an empty string if the current item is undefined. The returned string points
- * to internally allocated storage in the widget and must not be modified,
- * freed, or stored.
+ * ctk_drop_down_menu_get_current_name() - get the current name in the combo
+ * box. In the case where no current item is selected and the menu has one
+ * or more valid items, this has the side effect of selecting the first item
+ * from the menu as its current item, then returning its name.
+ *
+ * In the case where the menu has no valid items, this will return an empty
+ * string.
+ *
+ * The returned string points to internally allocated storage in the widget
+ * and must not be modified, freed, or stored.
*/
const char *ctk_drop_down_menu_get_current_name(CtkDropDownMenu *d)
{
gint i;
- if (d->flags & CTK_DROP_DOWN_MENU_FLAG_COMBO) {
+ if (d->flags & CTK_DROP_DOWN_MENU_FLAG_READWRITE) {
i = d->current_selected_item;
} else {
- i = gtk_option_menu_get_history(GTK_OPTION_MENU(d->option_menu));
-
+ /* This returns -1 if no item is active */
+ i = gtk_combo_box_get_active(GTK_COMBO_BOX(d->combo_box));
}
- if (i < d->num_entries) {
+ if (d->num_entries > 0) {
+ /* Default to the first item if the current selection is invalid */
+ if ((i < 0) || (i >= d->num_entries)) {
+ i = 0;
+ ctk_drop_down_menu_set_current_index(d, 0);
+ }
return d->values[i].glist_item;
- } else {
- return ""; /* XXX??? */
+ } else {
+ return "";
}
}
/*
* ctk_drop_down_menu_set_current_value() - set the current value in
- * the menu
+ * the combo box
*/
void ctk_drop_down_menu_set_current_value(CtkDropDownMenu *d, gint value)
{
gint i;
-
+
for (i = 0; i < d->num_entries; i++) {
if (d->values[i].value == value) {
- if (d->flags & CTK_DROP_DOWN_MENU_FLAG_COMBO) {
- gtk_entry_set_text
- (GTK_ENTRY(GTK_COMBO(d->menu)->entry),
- d->values[i].glist_item);
- } else {
- gtk_option_menu_set_history(GTK_OPTION_MENU(d->option_menu), i);
- }
+ ctk_drop_down_menu_set_current_index(d, i);
return;
}
}
} /* ctk_drop_down_menu_set_current_value() */
+/*
+ * ctk_drop_down_menu_set_current_index() - set the current item (name/value)
+ * in the combo box to the item at the given index. Caller is expected to
+ * pass in a valid index argument.
+ */
+void ctk_drop_down_menu_set_current_index(CtkDropDownMenu *d, gint index)
+{
+ assert((index >= 0) && (index < d->num_entries));
+
+ if (d->flags & CTK_DROP_DOWN_MENU_FLAG_READWRITE) {
+ gtk_entry_set_text
+ (GTK_ENTRY(GTK_BIN(d->combo_box)->child),
+ d->values[index].glist_item);
+ d->current_selected_item = index;
+ } else {
+ gtk_combo_box_set_active(GTK_COMBO_BOX(d->combo_box), index);
+ }
+} /* ctk_drop_down_menu_set_current_index() */
+
/*
@@ -363,9 +367,9 @@ void ctk_drop_down_menu_set_value_sensitive(CtkDropDownMenu *d,
gint value, gboolean sensitive)
{
- if (d->flags & CTK_DROP_DOWN_MENU_FLAG_COMBO) {
+ if (d->flags & CTK_DROP_DOWN_MENU_FLAG_READWRITE) {
ctk_drop_down_menu_set_current_value(d, value);
- gtk_widget_set_sensitive(GTK_WIDGET(GTK_COMBO(d->menu)->entry),
+ gtk_widget_set_sensitive(GTK_WIDGET(GTK_BIN(d->combo_box)->child),
sensitive);
} else {
gint i;
@@ -377,3 +381,16 @@ void ctk_drop_down_menu_set_value_sensitive(CtkDropDownMenu *d,
}
}
} /* ctk_drop_down_menu_set_value_sensitive() */
+
+
+/*
+ * ctk_drop_down_menu_set_tooltip() - adds the tooltip to the widget used
+ * for the drop down combo box
+ */
+
+void ctk_drop_down_menu_set_tooltip(CtkConfig *ctk_config, CtkDropDownMenu *d,
+ const gchar *text)
+{
+ ctk_config_set_tooltip(ctk_config, GTK_WIDGET(d->combo_box), text);
+}
+
diff --git a/src/gtk+-2.x/ctkdropdownmenu.h b/src/gtk+-2.x/ctkdropdownmenu.h
index 8b6bc9d..b0cdc9d 100644
--- a/src/gtk+-2.x/ctkdropdownmenu.h
+++ b/src/gtk+-2.x/ctkdropdownmenu.h
@@ -46,8 +46,8 @@ G_BEGIN_DECLS
CtkDropDownMenuClass))
-#define CTK_DROP_DOWN_MENU_FLAG_MONOSPACE 0x1
-#define CTK_DROP_DOWN_MENU_FLAG_COMBO 0x2
+#define CTK_DROP_DOWN_MENU_FLAG_READONLY 0x0
+#define CTK_DROP_DOWN_MENU_FLAG_READWRITE 0x1
typedef struct _CtkDropDownMenu CtkDropDownMenu;
@@ -66,15 +66,13 @@ struct _CtkDropDownMenu
{
GtkVBox parent;
- GtkWidget *menu;
- GtkWidget *option_menu;
+ GtkWidget *combo_box;
guint flags;
gint num_entries;
gint current_selected_item;
- GList *glist;
// currently selected item in the drop down
GtkWidget *current_selected_item_widget;
CtkDropDownMenuValue *values;
@@ -98,6 +96,9 @@ void ctk_drop_down_menu_set_value_sensitive (CtkDropDownMenu *d,
gint value,
gboolean sensitive);
void ctk_drop_down_menu_reset (CtkDropDownMenu *d);
+void ctk_drop_down_menu_set_tooltip (CtkConfig *ctk_config,
+ CtkDropDownMenu *d,
+ const gchar *text);
GObject *ctk_drop_down_menu_change_object(GtkWidget* widget);
diff --git a/src/gtk+-2.x/ctkecc.c b/src/gtk+-2.x/ctkecc.c
index 04127ad..b15797f 100644
--- a/src/gtk+-2.x/ctkecc.c
+++ b/src/gtk+-2.x/ctkecc.c
@@ -420,6 +420,7 @@ GtkWidget* ctk_ecc_new(NvCtrlAttributeHandle *handle,
gboolean ecc_default_status;
ReturnStatus ret;
gchar *ecc_enabled_string;
+ gchar *str = NULL;
/* make sure we have a handle */
@@ -652,12 +653,16 @@ GtkWidget* ctk_ecc_new(NvCtrlAttributeHandle *handle,
(gpointer) ctk_ecc);
/* Register a timer callback to update Ecc status info */
+ str = g_strdup_printf("ECC Settings (GPU %d)",
+ NvCtrlGetTargetId(handle));
ctk_config_add_timer(ctk_ecc->ctk_config,
DEFAULT_UPDATE_ECC_STATUS_INFO_TIME_INTERVAL,
- "ECC Settings",
+ str,
(GSourceFunc) update_ecc_info,
(gpointer) ctk_ecc);
+
+ g_free(str);
gtk_widget_show_all(GTK_WIDGET(ctk_ecc));
diff --git a/src/gtk+-2.x/ctkevent.c b/src/gtk+-2.x/ctkevent.c
index dc9e5bf..a565239 100644
--- a/src/gtk+-2.x/ctkevent.c
+++ b/src/gtk+-2.x/ctkevent.c
@@ -236,7 +236,6 @@ static void ctk_event_class_init(CtkEventClass *ctk_event_class)
MAKE_SIGNAL(NV_CTRL_GVO_OUTPUT_VIDEO_LOCKED);
MAKE_SIGNAL(NV_CTRL_GVO_SYNC_LOCK_STATUS);
MAKE_SIGNAL(NV_CTRL_GVO_ANC_TIME_CODE_GENERATION);
- MAKE_SIGNAL(NV_CTRL_ONDEMAND_VBLANK_INTERRUPTS);
MAKE_SIGNAL(NV_CTRL_GVO_COMPOSITE);
MAKE_SIGNAL(NV_CTRL_GVO_COMPOSITE_ALPHA_KEY);
MAKE_SIGNAL(NV_CTRL_GVO_COMPOSITE_NUM_KEY_RANGES);
@@ -333,6 +332,10 @@ static void ctk_event_class_init(CtkEventClass *ctk_event_class)
MAKE_SIGNAL(NV_CTRL_GPU_LOGO_BRIGHTNESS);
MAKE_SIGNAL(NV_CTRL_GPU_SLI_LOGO_BRIGHTNESS);
MAKE_SIGNAL(NV_CTRL_THERMAL_COOLER_SPEED);
+ MAKE_SIGNAL(NV_CTRL_PALETTE_UPDATE_EVENT);
+ MAKE_SIGNAL(NV_CTRL_VIDEO_ENCODER_UTILIZATION);
+ MAKE_SIGNAL(NV_CTRL_GPU_NVCLOCK_OFFSET);
+ MAKE_SIGNAL(NV_CTRL_GPU_MEM_TRANSFER_RATE_OFFSET);
#undef MAKE_SIGNAL
/*
@@ -342,7 +345,7 @@ static void ctk_event_class_init(CtkEventClass *ctk_event_class)
* knows about.
*/
-#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_THERMAL_COOLER_SPEED
+#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_GPU_MEM_TRANSFER_RATE_OFFSET
#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 769feec..688ffe2 100644
--- a/src/gtk+-2.x/ctkframelock.c
+++ b/src/gtk+-2.x/ctkframelock.c
@@ -359,7 +359,7 @@ static void toggle_client(GtkWidget *, gpointer);
static void toggle_sync_enable(GtkWidget *, gpointer);
static void toggle_test_link(GtkWidget *, gpointer);
static void sync_interval_changed(GtkRange *, gpointer);
-static void changed_video_mode(GtkEditable *, gpointer);
+static void changed_video_mode(GtkComboBox *, gpointer);
static void toggle_detect_video_mode(GtkToggleButton *, gpointer);
static gboolean update_framelock_status(gpointer);
@@ -495,7 +495,7 @@ static GtkWidget *create_sync_state_button(CtkFramelock *ctk_framelock)
* gtk_container_remove() later, it doesn't get destroyed
*/
- gtk_object_ref(GTK_OBJECT(hbox2));
+ g_object_ref(GTK_OBJECT(hbox2));
ctk_framelock->enable_syncing_label = hbox2;
@@ -524,7 +524,7 @@ static GtkWidget *create_sync_state_button(CtkFramelock *ctk_framelock)
* gtk_container_remove() later, it doesn't get destroyed
*/
- gtk_object_ref(GTK_OBJECT(hbox2));
+ g_object_ref(GTK_OBJECT(hbox2));
ctk_framelock->disable_syncing_label = hbox2;
@@ -3363,26 +3363,23 @@ static gchar *format_sync_interval(GtkScale *scale, gdouble arg1,
* sync edge.
*
*/
-static void changed_sync_edge(GtkEditable *editable, gpointer user_data)
+static void changed_sync_edge(GtkComboBox *combo_box, 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(GTK_ENTRY(editable));
- gint edge;
- if (!entry || !str) return;
+ /* sync_edge values are 1..n but combo indexes are 0..n-1 */
+ gint edge = gtk_combo_box_get_active(combo_box) + 1;
+
+ if (!entry || edge < 0) {
+ return;
+ }
data = (nvFrameLockDataPtr) entry->data;
- for (edge = NV_CTRL_FRAMELOCK_POLARITY_RISING_EDGE;
- edge <= NV_CTRL_FRAMELOCK_POLARITY_BOTH_EDGES; edge++) {
- if (strcmp(syncEdgeStrings[edge], str) == 0) {
- NvCtrlSetAttribute(data->handle, NV_CTRL_FRAMELOCK_POLARITY, edge);
- return;
- }
- }
+ NvCtrlSetAttribute(data->handle, NV_CTRL_FRAMELOCK_POLARITY, edge);
}
@@ -3393,28 +3390,21 @@ static void changed_sync_edge(GtkEditable *editable, gpointer user_data)
* mode.
*
*/
-static void changed_video_mode(GtkEditable *editable, gpointer user_data)
+static void changed_video_mode(GtkComboBox *combo_box, 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(GTK_ENTRY(editable));
- gint mode;
+ gint mode = gtk_combo_box_get_active(combo_box);
- if (!entry || !str) return;
+ if (!entry || mode < 0) {
+ return;
+ }
data = (nvFrameLockDataPtr) entry->data;
- for (mode = NV_CTRL_FRAMELOCK_VIDEO_MODE_NONE;
- mode <= NV_CTRL_FRAMELOCK_VIDEO_MODE_HDTV; mode++) {
-
- if (strcmp(houseFormatStrings[mode], str) == 0) {
- NvCtrlSetAttribute(data->handle,
- NV_CTRL_FRAMELOCK_VIDEO_MODE, mode);
- return;
- }
- }
+ NvCtrlSetAttribute(data->handle, NV_CTRL_FRAMELOCK_VIDEO_MODE, mode);
}
@@ -4038,9 +4028,9 @@ static void update_house_sync_controls(CtkFramelock *ctk_framelock)
if (sync_edge > NV_CTRL_FRAMELOCK_POLARITY_BOTH_EDGES)
sync_edge = NV_CTRL_FRAMELOCK_POLARITY_BOTH_EDGES;
- gtk_entry_set_text
- (GTK_ENTRY(GTK_COMBO(ctk_framelock->sync_edge_combo)->entry),
- syncEdgeStrings[sync_edge]);
+ /* sync_edge values are 1..n but combo indexes are 0..n-1 */
+ gtk_combo_box_set_active(GTK_COMBO_BOX(ctk_framelock->sync_edge_combo),
+ sync_edge - 1);
if (house_format < NV_CTRL_FRAMELOCK_VIDEO_MODE_NONE)
house_format = NV_CTRL_FRAMELOCK_VIDEO_MODE_NONE;
@@ -4048,9 +4038,8 @@ static void update_house_sync_controls(CtkFramelock *ctk_framelock)
house_format = NV_CTRL_FRAMELOCK_VIDEO_MODE_HDTV;
if (!ctk_framelock->video_mode_read_only) {
- gtk_entry_set_text
- (GTK_ENTRY(GTK_COMBO(ctk_framelock->video_mode_widget)->entry),
- houseFormatStrings[house_format]);
+ gtk_combo_box_set_active(
+ GTK_COMBO_BOX(ctk_framelock->video_mode_widget), house_format);
} else {
gtk_label_set_text(GTK_LABEL(ctk_framelock->video_mode_widget),
houseFormatStrings[house_format]);
@@ -4478,16 +4467,16 @@ static void framelock_state_received(GtkObject *object,
sync_edge = NV_CTRL_FRAMELOCK_POLARITY_BOTH_EDGES;
g_signal_handlers_block_by_func
- (G_OBJECT(GTK_COMBO(ctk_framelock->sync_edge_combo)->entry),
+ (G_OBJECT(GTK_COMBO_BOX(ctk_framelock->sync_edge_combo)),
G_CALLBACK(changed_sync_edge),
(gpointer) ctk_framelock);
- gtk_entry_set_text
- (GTK_ENTRY(GTK_COMBO(ctk_framelock->sync_edge_combo)->entry),
- syncEdgeStrings[sync_edge]);
+ /* sync_edge values are 1..n but combo indexes are 0..n-1 */
+ gtk_combo_box_set_active(GTK_COMBO_BOX(ctk_framelock->sync_edge_combo),
+ sync_edge - 1);
g_signal_handlers_unblock_by_func
- (G_OBJECT(GTK_COMBO(ctk_framelock->sync_edge_combo)->entry),
+ (G_OBJECT(GTK_COMBO_BOX(ctk_framelock->sync_edge_combo)),
G_CALLBACK(changed_sync_edge),
(gpointer) ctk_framelock);
@@ -4502,16 +4491,15 @@ static void framelock_state_received(GtkObject *object,
if (!ctk_framelock->video_mode_read_only) {
g_signal_handlers_block_by_func
- (G_OBJECT(GTK_COMBO(ctk_framelock->video_mode_widget)->entry),
+ (G_OBJECT(GTK_COMBO_BOX(ctk_framelock->video_mode_widget)),
G_CALLBACK(changed_video_mode),
(gpointer) ctk_framelock);
- gtk_entry_set_text
- (GTK_ENTRY(GTK_COMBO(ctk_framelock->video_mode_widget)->entry),
- houseFormatStrings[house_format]);
+ gtk_combo_box_set_active(
+ GTK_COMBO_BOX(ctk_framelock->video_mode_widget), house_format);
g_signal_handlers_unblock_by_func
- (G_OBJECT(GTK_COMBO(ctk_framelock->video_mode_widget)->entry),
+ (G_OBJECT(GTK_COMBO_BOX(ctk_framelock->video_mode_widget)),
G_CALLBACK(changed_video_mode),
(gpointer) ctk_framelock);
} else {
@@ -4620,8 +4608,7 @@ GtkWidget* ctk_framelock_new(NvCtrlAttributeHandle *handle,
GtkWidget *hbox;
GtkWidget *vbox;
GtkWidget *label;
- GtkWidget *combo;
- GList *glist;
+ GtkWidget *combo_box;
GtkWidget *button;
GtkWidget *image;
NVCTRLAttributeValidValuesRec valid;
@@ -4770,26 +4757,22 @@ GtkWidget* ctk_framelock_new(NvCtrlAttributeHandle *handle,
}
if (!ctk_framelock->video_mode_read_only) {
- combo = gtk_combo_new();
- glist = NULL;
- glist = g_list_append
- (glist,
- houseFormatStrings[NV_CTRL_FRAMELOCK_VIDEO_MODE_COMPOSITE_AUTO]);
- glist = g_list_append
- (glist,
- houseFormatStrings[NV_CTRL_FRAMELOCK_VIDEO_MODE_COMPOSITE_BI_LEVEL]);
- glist = g_list_append
- (glist,
- houseFormatStrings[NV_CTRL_FRAMELOCK_VIDEO_MODE_COMPOSITE_TRI_LEVEL]);
- glist = g_list_append
- (glist, houseFormatStrings[NV_CTRL_FRAMELOCK_VIDEO_MODE_TTL]);
-
- gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist);
- gtk_editable_set_editable(GTK_EDITABLE(GTK_COMBO(combo)->entry), FALSE);
- g_signal_connect(G_OBJECT(GTK_EDITABLE(GTK_COMBO(combo)->entry)),
+ combo_box = gtk_combo_box_new_text();
+ gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box),
+ houseFormatStrings[NV_CTRL_FRAMELOCK_VIDEO_MODE_COMPOSITE_AUTO]);
+ gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box),
+ houseFormatStrings[NV_CTRL_FRAMELOCK_VIDEO_MODE_TTL]);
+ gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box),
+ houseFormatStrings[NV_CTRL_FRAMELOCK_VIDEO_MODE_COMPOSITE_BI_LEVEL]);
+ gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box),
+ houseFormatStrings[NV_CTRL_FRAMELOCK_VIDEO_MODE_COMPOSITE_TRI_LEVEL]);
+
+ gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), 0);
+
+ g_signal_connect(G_OBJECT(GTK_COMBO_BOX(combo_box)),
"changed", G_CALLBACK(changed_video_mode),
(gpointer) ctk_framelock);
- ctk_framelock->video_mode_widget = combo;
+ ctk_framelock->video_mode_widget = combo_box;
} else {
ctk_framelock->video_mode_widget = gtk_label_new("None");
}
@@ -4797,26 +4780,22 @@ GtkWidget* ctk_framelock_new(NvCtrlAttributeHandle *handle,
__video_mode_help);
- combo = gtk_combo_new();
- glist = NULL;
- glist = g_list_append
- (glist,
+ combo_box = gtk_combo_box_new_text();
+ gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box),
syncEdgeStrings[NV_CTRL_FRAMELOCK_POLARITY_RISING_EDGE]);
- glist = g_list_append
- (glist,
+ gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box),
syncEdgeStrings[NV_CTRL_FRAMELOCK_POLARITY_FALLING_EDGE]);
- glist = g_list_append
- (glist,
+ gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box),
syncEdgeStrings[NV_CTRL_FRAMELOCK_POLARITY_BOTH_EDGES]);
- gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist);
- gtk_editable_set_editable(GTK_EDITABLE(GTK_COMBO(combo)->entry), FALSE);
- g_signal_connect(G_OBJECT(GTK_EDITABLE(GTK_COMBO(combo)->entry)),
+ gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), 0);
+
+ g_signal_connect(G_OBJECT(GTK_COMBO_BOX(combo_box)),
"changed", G_CALLBACK(changed_sync_edge),
(gpointer) ctk_framelock);
- ctk_config_set_tooltip(ctk_config, combo,
+ ctk_config_set_tooltip(ctk_config, combo_box,
__sync_edge_combo_help);
- ctk_framelock->sync_edge_combo = combo;
+ ctk_framelock->sync_edge_combo = combo_box;
/* Cache images */
diff --git a/src/gtk+-2.x/ctkgvi.c b/src/gtk+-2.x/ctkgvi.c
index f44a51c..08628ff 100644
--- a/src/gtk+-2.x/ctkgvi.c
+++ b/src/gtk+-2.x/ctkgvi.c
@@ -290,7 +290,7 @@ static GtkWidget *create_jack_channel_menu(CtkGvi *ctk_gvi)
/* Create the menu */
menu = (CtkDropDownMenu *)
- ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_COMBO);
+ ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_READONLY);
/* Just show all jack/channel pairs in dropdown */
diff --git a/src/gtk+-2.x/ctkgvo-csc.c b/src/gtk+-2.x/ctkgvo-csc.c
index 0f4400f..004457f 100644
--- a/src/gtk+-2.x/ctkgvo-csc.c
+++ b/src/gtk+-2.x/ctkgvo-csc.c
@@ -330,11 +330,11 @@ GtkWidget* ctk_gvo_csc_new(NvCtrlAttributeHandle *handle,
ctk_gvo_csc->initializeDropDown =
- ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_MONOSPACE);
+ ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_READONLY);
- ctk_config_set_tooltip
+ ctk_drop_down_menu_set_tooltip
(ctk_config,
- CTK_DROP_DOWN_MENU(ctk_gvo_csc->initializeDropDown)->option_menu,
+ CTK_DROP_DOWN_MENU(ctk_gvo_csc->initializeDropDown),
__initialize_help);
ctk_drop_down_menu_append_item
diff --git a/src/gtk+-2.x/ctkgvo-sync.c b/src/gtk+-2.x/ctkgvo-sync.c
index ac75521..6643f64 100644
--- a/src/gtk+-2.x/ctkgvo-sync.c
+++ b/src/gtk+-2.x/ctkgvo-sync.c
@@ -487,8 +487,8 @@ GtkWidget* ctk_gvo_sync_new(NvCtrlAttributeHandle *handle,
ctk_gvo_sync->sync_mode_menu = menu;
- ctk_config_set_tooltip(ctk_config, CTK_DROP_DOWN_MENU(menu)->option_menu,
- __sync_mode_help);
+ ctk_drop_down_menu_set_tooltip(ctk_config, CTK_DROP_DOWN_MENU(menu),
+ __sync_mode_help);
ctk_drop_down_menu_set_current_value
(CTK_DROP_DOWN_MENU(ctk_gvo_sync->sync_mode_menu),
@@ -512,8 +512,8 @@ GtkWidget* ctk_gvo_sync_new(NvCtrlAttributeHandle *handle,
ctk_gvo_sync->sync_format_menu = menu;
- ctk_config_set_tooltip(ctk_config, CTK_DROP_DOWN_MENU(menu)->option_menu,
- __sync_format_help);
+ ctk_drop_down_menu_set_tooltip(ctk_config, CTK_DROP_DOWN_MENU(menu),
+ __sync_format_help);
init_sync_format_menu(ctk_gvo_sync);
@@ -693,7 +693,7 @@ static GtkWidget *start_menu(const gchar *name, GtkWidget *table,
alignment, 0, 1, row, row+1, GTK_FILL, GTK_FILL,
TABLE_PADDING, TABLE_PADDING);
- menu = ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_MONOSPACE);
+ menu = ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_READONLY);
return menu;
}
diff --git a/src/gtk+-2.x/ctkhelp.c b/src/gtk+-2.x/ctkhelp.c
index d2d9efa..6a50461 100644
--- a/src/gtk+-2.x/ctkhelp.c
+++ b/src/gtk+-2.x/ctkhelp.c
@@ -431,10 +431,13 @@ void ctk_help_data_list_prepend(GList **list,
const gchar *help_text,
const gchar *extended_help_text)
{
- CtkHelpDataItem *item = nvalloc(sizeof(CtkHelpDataItem));
+ CtkHelpDataItem *item;
+
+ if (!label || !help_text) {
+ return;
+ }
- assert(label);
- assert(help_text);
+ item = nvalloc(sizeof(CtkHelpDataItem));
item->label = nvstrdup(label);
item->help_text = nvstrdup(help_text);
diff --git a/src/gtk+-2.x/ctkmultisample.c b/src/gtk+-2.x/ctkmultisample.c
index d179de6..4b674f8 100644
--- a/src/gtk+-2.x/ctkmultisample.c
+++ b/src/gtk+-2.x/ctkmultisample.c
@@ -704,7 +704,7 @@ static GtkWidget *create_fsaa_setting_menu(CtkMultisample *ctk_multisample,
/* Create the menu */
d = (CtkDropDownMenu *)
- ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_COMBO);
+ ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_READONLY);
for (i = 0; i < ARRAY_LEN(applicationSettings); i++) {
ctk_drop_down_menu_append_item(d, applicationSettings[i], i);
@@ -723,8 +723,8 @@ static GtkWidget *create_fsaa_setting_menu(CtkMultisample *ctk_multisample,
/* set the menu item */
ctk_drop_down_menu_set_current_value(d, idx);
- ctk_config_set_tooltip(ctk_multisample->ctk_config, d->menu,
- __aa_menu_help);
+ ctk_drop_down_menu_set_tooltip(ctk_multisample->ctk_config, d,
+ __aa_menu_help);
g_signal_connect(G_OBJECT(d),
"changed",
diff --git a/src/gtk+-2.x/ctkpowermizer.c b/src/gtk+-2.x/ctkpowermizer.c
index 84b5341..d3dba6a 100644
--- a/src/gtk+-2.x/ctkpowermizer.c
+++ b/src/gtk+-2.x/ctkpowermizer.c
@@ -28,6 +28,7 @@
#include "ctkutils.h"
#include "ctkhelp.h"
#include "ctkpowermizer.h"
+#include "ctklicense.h"
#include "ctkbanner.h"
#include "ctkdropdownmenu.h"
@@ -50,6 +51,21 @@ static void dp_update_config_status(CtkPowermizer *, gboolean);
static void dp_configuration_update_received(GtkObject *, gpointer, gpointer);
static void post_dp_configuration_update(CtkPowermizer *);
static void show_dp_toggle_warning_dlg(CtkPowermizer *ctk_powermizer);
+static void post_set_attribute_offset_value(CtkPowermizer *ctk_powermizer,
+ gint attribute,
+ gint val);
+static void offset_entry_set_value(CtkPowermizer *ctk_powermizer,
+ GtkWidget *widget,
+ gint offset);
+
+static void offset_value_changed_event_received(GtkObject *object,
+ gpointer arg1,
+ gpointer user_data);
+
+static void update_editable_perf_level_info(CtkPowermizer *ctk_powermizer);
+
+static void enable_perf_level_editing_toggled(GtkWidget *widget,
+ gpointer user_data);
static const char *__adaptive_clock_help =
"The Adaptive Clocking status describes if this feature "
@@ -85,6 +101,24 @@ static const char *__performance_levels_table_help =
"performance level is shown in regular text. All other performance "
"levels are shown in gray.";
+static const char * __enable_button_help =
+"The 'Enable Performance Level Editing' checkbox allows manipulation "
+"of an over- and under-clocking offset. This option is only available "
+"when the 'Coolbits' X configuration option is set to '8'."
+" Overclocking your GPU is not recommended and is done at your own risk.";
+
+static const char *__editable_performance_levels_table_help =
+"Each Performance Level that allows clock modifications will allow custom "
+"offsets to be applied to the Graphics clock and Memory Transfer Rate."
+" For clock domains that have a minimum and maximum clock per "
+"performance level, the offset applies to both the minimum and maximum.";
+
+static const char *__gpu_clock_offset_help =
+"This is the amount, in MHz, to over- or under-clock the Graphics Clock.";
+
+static const char *__memory_transfer_rate_offset_help =
+"This is the amount, in MHz, to over- or under-clock the Memory Transfer Rate.";
+
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. "
@@ -145,15 +179,28 @@ GType ctk_powermizer_get_type(void)
typedef struct {
gint perf_level;
+ gboolean perf_level_specified;
gint nvclock;
+ gboolean nvclock_specified;
gint processorclock;
+ gboolean processorclock_specified;
gint nvclockmin;
+ gboolean nvclockmin_specified;
gint nvclockmax;
+ gint nvclockeditable;
+ gboolean nvclockmax_specified;
gint memtransferrate;
+ gboolean memtransferrate_specified;
gint memtransferratemin;
+ gboolean memtransferratemin_specified;
gint memtransferratemax;
+ gint memtransferrateeditable;
+ gboolean memtransferratemax_specified;
gint processorclockmin;
+ gboolean processorclockmin_specified;
gint processorclockmax;
+ gint processorclockeditable;
+ gboolean processorclockmax_specified;
} perfModeEntry, * perfModeEntryPtr;
@@ -163,28 +210,459 @@ static void apply_perf_mode_token(char *token, char *value, void *data)
if (!strcasecmp("perf", token)) {
pEntry->perf_level = atoi(value);
+ pEntry->perf_level_specified = TRUE;
} else if (!strcasecmp("nvclock", token)) {
pEntry->nvclock = atoi(value);
+ pEntry->nvclock_specified = TRUE;
} else if (!strcasecmp("nvclockmin", token)) {
pEntry->nvclockmin = atoi(value);
+ pEntry->nvclockmin_specified = TRUE;
} else if (!strcasecmp("nvclockmax", token)) {
pEntry->nvclockmax = atoi(value);
+ pEntry->nvclockmax_specified = TRUE;
+ } else if (!strcasecmp("nvclockeditable", token)) {
+ pEntry->nvclockeditable = atoi(value);
} else if (!strcasecmp("memtransferrate", token)) {
pEntry->memtransferrate = atoi(value);
+ pEntry->memtransferrate_specified = TRUE;
} else if (!strcasecmp("memtransferratemin", token)) {
pEntry->memtransferratemin = atoi(value);
+ pEntry->memtransferratemin_specified = TRUE;
} else if (!strcasecmp("memtransferratemax", token)) {
pEntry->memtransferratemax = atoi(value);
+ pEntry->memtransferratemax_specified = TRUE;
+ } else if (!strcasecmp("memtransferrateeditable", token)) {
+ pEntry->memtransferrateeditable = atoi(value);
} else if (!strcasecmp("processorclock", token)) {
pEntry->processorclock = atoi(value);
+ pEntry->processorclock_specified = TRUE;
} else if (!strcasecmp("processorclockmin", token)) {
pEntry->processorclockmin = atoi(value);
+ pEntry->processorclockmax_specified = TRUE;
} else if (!strcasecmp("processorclockmax", token)) {
pEntry->processorclockmax = atoi(value);
+ pEntry->processorclockmax_specified = TRUE;
+ } else if (!strcasecmp("processorclockeditable", token)) {
+ pEntry->nvclockeditable = atoi(value);
+ }
+}
+
+
+
+static void offset_value_changed_event_received(GtkObject *object,
+ gpointer arg1,
+ gpointer user_data)
+{
+ CtkEventStruct *event_struct = (CtkEventStruct *) arg1;
+ CtkPowermizer *ctk_powermizer = CTK_POWERMIZER(user_data);
+
+ update_editable_perf_level_info(ctk_powermizer);
+ post_set_attribute_offset_value(ctk_powermizer,
+ event_struct->attribute,
+ event_struct->value);
+}
+
+
+
+static void post_set_attribute_offset_value(CtkPowermizer *ctk_powermizer,
+ gint attribute,
+ gint val)
+{
+ const char *str = NULL;
+
+ switch (attribute) {
+ case NV_CTRL_GPU_NVCLOCK_OFFSET:
+ str = "Graphics Clock";
+ break;
+ case NV_CTRL_GPU_MEM_TRANSFER_RATE_OFFSET:
+ str = "Memory Transfer Rate";
+ break;
+ default:
+ str = "unknown";
+ break;
+ }
+
+ ctk_config_statusbar_message(ctk_powermizer->ctk_config,
+ "The %s offset set to %d.", str, val);
+}
+
+
+
+static void enable_perf_level_editing_toggled(GtkWidget *widget,
+ gpointer user_data)
+{
+ CtkPowermizer *ctk_powermizer = CTK_POWERMIZER(user_data);
+ gboolean enabled;
+ gint result;
+
+ /* Get enabled state */
+
+ enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+
+ /* Verify user knows the risks involved */
+
+ if (enabled && !ctk_powermizer->license_accepted) {
+
+ result = ctk_license_run_dialog(CTK_LICENSE_DIALOG(ctk_powermizer->enable_dialog));
+
+ switch (result) {
+ case GTK_RESPONSE_ACCEPT:
+ ctk_powermizer->license_accepted = TRUE;
+ gtk_widget_set_sensitive(ctk_powermizer->editable_perf_level_table,
+ TRUE);
+ break;
+ case GTK_RESPONSE_REJECT:
+ default:
+ /* Cancel */
+ g_signal_handlers_block_by_func(G_OBJECT(widget),
+ G_CALLBACK(enable_perf_level_editing_toggled),
+ (gpointer) ctk_powermizer);
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), FALSE);
+
+ g_signal_handlers_unblock_by_func(G_OBJECT(widget),
+ G_CALLBACK(enable_perf_level_editing_toggled),
+ (gpointer) ctk_powermizer);
+ return;
+ }
}
}
+
+static void set_attribute_offset_value(GtkWidget *widget,
+ gpointer user_data)
+{
+ CtkPowermizer *ctk_powermizer = CTK_POWERMIZER(user_data);
+ gint offset;
+ gint perf_level, attribute, ret;
+ const gchar *txt_entry = gtk_entry_get_text(GTK_ENTRY(widget));
+
+ parse_read_integer(txt_entry, &offset);
+ user_data = g_object_get_data(G_OBJECT(widget), "attribute");
+ attribute = GPOINTER_TO_INT(user_data);
+ user_data = g_object_get_data(G_OBJECT(widget), "perf level");
+ perf_level = GPOINTER_TO_INT(user_data);
+
+ ret = NvCtrlSetDisplayAttribute(ctk_powermizer->attribute_handle,
+ perf_level,
+ attribute,
+ offset);
+
+ if (ret == NvCtrlSuccess) {
+ post_set_attribute_offset_value(ctk_powermizer, attribute, offset);
+ }
+}
+
+
+
+static void offset_entry_set_value(CtkPowermizer *ctk_powermizer,
+ GtkWidget *widget,
+ gint offset)
+{
+ char *text = g_strdup_printf("%d", offset);
+
+ g_signal_handlers_block_by_func(G_OBJECT(widget),
+ G_CALLBACK(set_attribute_offset_value),
+ (gpointer) ctk_powermizer);
+
+ gtk_entry_set_text(GTK_ENTRY(widget), text);
+
+ g_signal_handlers_unblock_by_func(G_OBJECT(widget),
+ G_CALLBACK(set_attribute_offset_value),
+ (gpointer) ctk_powermizer);
+ g_free(text);
+}
+
+
+
+static void update_editable_perf_level_info(CtkPowermizer *ctk_powermizer)
+
+{
+ GtkWidget *table;
+ GtkWidget *label;
+ char tmp_str[24];
+ gint ret;
+ gint row_idx = 0; /* Where to insert into the perf mode table */
+ gint col_idx = 0; /* Column index adjustment factor */
+ gboolean active = TRUE;
+ GtkWidget *vsep, *vbox, *hsep, *hbox;
+ gint i = 0;
+
+ table = gtk_table_new(5, 15, FALSE);
+ row_idx = row_idx + 3;
+ col_idx = 1;
+ 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);
+
+ vbox = gtk_vbox_new(FALSE, 5);
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+
+ label = gtk_label_new("Editable Performance Levels");
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+ hsep = gtk_hseparator_new();
+ gtk_box_pack_start(GTK_BOX(hbox), hsep, TRUE, TRUE, 5);
+
+ gtk_box_pack_start(GTK_BOX(ctk_powermizer->performance_table_hbox1),
+ vbox, FALSE, FALSE, 0);
+
+ /* Create the enable dialog */
+
+ ctk_powermizer->enable_dialog =
+ ctk_license_dialog_new(GTK_WIDGET(ctk_powermizer),
+ "Performance Level Editing");
+
+ /* Create the Enable Performance Level Editing checkbox widget */
+
+ ctk_powermizer->enable_checkbox =
+ gtk_check_button_new_with_label("Enable Performance Level Editing");
+
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON(ctk_powermizer->enable_checkbox),
+ FALSE);
+
+ g_signal_connect(G_OBJECT(ctk_powermizer->enable_checkbox), "toggled",
+ G_CALLBACK(enable_perf_level_editing_toggled),
+ (gpointer) ctk_powermizer);
+
+ ctk_config_set_tooltip(ctk_powermizer->ctk_config, ctk_powermizer->enable_checkbox,
+ __enable_button_help);
+
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), ctk_powermizer->enable_checkbox, TRUE, TRUE, 5);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
+ gtk_box_pack_start(GTK_BOX(vbox),
+ table, FALSE, FALSE, 5);
+
+ /* Enable access to overclock settings only if license accepted */
+ if (!ctk_powermizer->license_accepted) {
+ gtk_widget_set_sensitive(GTK_WIDGET(table), FALSE);
+ }
+ /* create the editable performance level table */
+ ctk_powermizer->editable_perf_level_table = table;
+
+ if (ctk_powermizer->performance_level) {
+ label = gtk_label_new("Level");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+
+ /* Vertical separator */
+ vsep = gtk_vseparator_new();
+ gtk_table_attach(GTK_TABLE(table), vsep, 1, 2, 0, row_idx,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 0, 0);
+ }
+ if (ctk_powermizer->gpu_clock) {
+ /* Graphics clock */
+ label = gtk_label_new("Graphics Clock Offset");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, col_idx+1, col_idx+4, 0, 1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ label = gtk_label_new("Current");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, col_idx+1, col_idx+2, 1, 2,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ label = gtk_label_new("Min");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, col_idx+2, col_idx+3, 1, 2,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ label = gtk_label_new("Max");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, col_idx+3, col_idx+4, 1, 2,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+
+ /* Vertical separator */
+ vsep = gtk_vseparator_new();
+ gtk_table_attach(GTK_TABLE(table), vsep, col_idx+4, col_idx+5, 0, row_idx,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 0, 0);
+ col_idx = 6;
+ }
+ if (ctk_powermizer->memory_transfer_rate) {
+ /* Memory transfer rate */
+ label = gtk_label_new("Memory Transfer Rate Offset");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, col_idx+1, col_idx+4, 0, 1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ label = gtk_label_new("Current");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, col_idx+1, col_idx+2, 1, 2,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ label = gtk_label_new("Min");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, col_idx+2, col_idx+3, 1, 2,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ label = gtk_label_new("Max");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, col_idx+3, col_idx+4, 1, 2,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+
+ /* Vertical separator */
+ vsep = gtk_vseparator_new();
+ gtk_table_attach(GTK_TABLE(table), vsep, col_idx+4, col_idx+5,
+ 0, row_idx,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 0, 0);
+ col_idx += 4;
+ }
+
+ /* Parse the perf levels and populate the table */
+
+ row_idx = 2; //reset value used to calculate vseparator.
+ for (i = 0; i < ctk_powermizer->num_perf_levels; i++) {
+ NVCTRLAttributeValidValuesRec gpu_clock_valid_val;
+ NVCTRLAttributeValidValuesRec mem_transfer_rate_valid_val;
+ GtkWidget *txt_nvclock_offset = NULL;
+ GtkWidget *txt_mem_transfer_rate_offset = NULL;
+ gint gpu_clock_val = 0, mem_transfer_rate_val = 0;
+
+ col_idx = 0;
+
+ /* Query GPU clock offset information */
+ if (ctk_powermizer->gpu_clock) {
+ ret = NvCtrlGetValidDisplayAttributeValues(ctk_powermizer->attribute_handle,
+ i,
+ NV_CTRL_GPU_NVCLOCK_OFFSET,
+ &gpu_clock_valid_val);
+ if ((ret == NvCtrlSuccess) &&
+ (gpu_clock_valid_val.permissions & ATTRIBUTE_TYPE_WRITE)) {
+ ret = NvCtrlGetDisplayAttribute(ctk_powermizer->attribute_handle,
+ i,
+ NV_CTRL_GPU_NVCLOCK_OFFSET,
+ &gpu_clock_val);
+ if (ret == NvCtrlSuccess) {
+ /* Create input entry field */
+ txt_nvclock_offset = gtk_entry_new();
+ gtk_entry_set_max_length(GTK_ENTRY(txt_nvclock_offset), 6);
+ gtk_entry_set_width_chars(GTK_ENTRY(txt_nvclock_offset), 6);
+ ctk_config_set_tooltip(ctk_powermizer->ctk_config,
+ txt_nvclock_offset,
+ __gpu_clock_offset_help);
+ g_signal_connect(G_OBJECT(txt_nvclock_offset), "activate",
+ G_CALLBACK(set_attribute_offset_value),
+ (gpointer) ctk_powermizer);
+ }
+ }
+ }
+
+ /* Query Memory transfer rate offset information */
+ if (ctk_powermizer->memory_transfer_rate) {
+ ret = NvCtrlGetValidDisplayAttributeValues(ctk_powermizer->attribute_handle,
+ i,
+ NV_CTRL_GPU_MEM_TRANSFER_RATE_OFFSET,
+ &mem_transfer_rate_valid_val);
+ if ((ret == NvCtrlSuccess) &&
+ (mem_transfer_rate_valid_val.permissions & ATTRIBUTE_TYPE_WRITE)) {
+ ret = NvCtrlGetDisplayAttribute(ctk_powermizer->attribute_handle,
+ i,
+ NV_CTRL_GPU_MEM_TRANSFER_RATE_OFFSET,
+ &mem_transfer_rate_val);
+ if (ret == NvCtrlSuccess) {
+ /* Create input entry field */
+ txt_mem_transfer_rate_offset = gtk_entry_new();
+ gtk_entry_set_max_length(GTK_ENTRY(txt_mem_transfer_rate_offset),
+ 6);
+ gtk_entry_set_width_chars(GTK_ENTRY(txt_mem_transfer_rate_offset),
+ 6);
+ ctk_config_set_tooltip(ctk_powermizer->ctk_config,
+ txt_mem_transfer_rate_offset,
+ __memory_transfer_rate_offset_help);
+ g_signal_connect(G_OBJECT(txt_mem_transfer_rate_offset),
+ "activate",
+ G_CALLBACK(set_attribute_offset_value),
+ (gpointer) ctk_powermizer);
+ }
+ }
+ }
+
+ /* Continue if no field is editable */
+ if (!txt_nvclock_offset && !txt_mem_transfer_rate_offset) {
+ continue;
+ }
+ /* XXX Assume the perf levels are sorted by the server */
+
+ gtk_table_resize(GTK_TABLE(table), row_idx+1, 10);
+
+ if (ctk_powermizer->performance_level) {
+ g_snprintf(tmp_str, 24, "%d", i);
+ 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, 0, 1, row_idx, row_idx+1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ col_idx =1;
+ }
+ if (txt_nvclock_offset) {
+ g_object_set_data(G_OBJECT(txt_nvclock_offset), "attribute",
+ GINT_TO_POINTER(NV_CTRL_GPU_NVCLOCK_OFFSET));
+ g_object_set_data(G_OBJECT(txt_nvclock_offset), "perf level",
+ GINT_TO_POINTER(i));
+ /* Set current value */
+ offset_entry_set_value(ctk_powermizer, txt_nvclock_offset,
+ gpu_clock_val);
+
+ gtk_table_attach(GTK_TABLE(table), txt_nvclock_offset,
+ col_idx+1, col_idx+2, row_idx, row_idx+1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ /* Min */
+ g_snprintf(tmp_str, 24, "%jd MHz", gpu_clock_valid_val.u.range.min);
+ 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,
+ col_idx+2, col_idx+3, row_idx, row_idx+1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ /* Max */
+ g_snprintf(tmp_str, 24, "%jd MHz", gpu_clock_valid_val.u.range.max);
+ 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,
+ col_idx+3, col_idx+4, row_idx, row_idx+1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ col_idx +=5;
+ }
+ if (txt_mem_transfer_rate_offset) {
+ g_object_set_data(G_OBJECT(GTK_ENTRY(txt_mem_transfer_rate_offset)),
+ "attribute",
+ GINT_TO_POINTER(NV_CTRL_GPU_MEM_TRANSFER_RATE_OFFSET));
+ g_object_set_data(G_OBJECT(GTK_ENTRY(txt_mem_transfer_rate_offset)),
+ "perf level",
+ GINT_TO_POINTER(i));
+ /* Set current value */
+ offset_entry_set_value(ctk_powermizer,
+ txt_mem_transfer_rate_offset,
+ mem_transfer_rate_val);
+ gtk_table_attach(GTK_TABLE(table), txt_mem_transfer_rate_offset,
+ col_idx+1, col_idx+2, row_idx, row_idx+1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+
+ /* Min */
+ g_snprintf(tmp_str, 24, "%jd MHz",
+ mem_transfer_rate_valid_val.u.range.min);
+ 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,
+ col_idx+2, col_idx+3, row_idx, row_idx+1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ /* Max */
+ g_snprintf(tmp_str, 24, "%jd MHz",
+ mem_transfer_rate_valid_val.u.range.max);
+ 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,
+ col_idx+3, col_idx+4, row_idx, row_idx+1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ col_idx +=4;
+ }
+ }
+}
+
+
+
static void update_perf_mode_table(CtkPowermizer *ctk_powermizer,
gint perf_level)
{
@@ -230,14 +708,14 @@ static void update_perf_mode_table(CtkPowermizer *ctk_powermizer,
tmpEntry = NULL;
/* Invalidate perf mode entry */
- memset(pEntry + index, -1, sizeof(*pEntry));
+ memset(pEntry + index, 0, sizeof(*pEntry));
parse_token_value_pairs(tokens, apply_perf_mode_token,
(void *) &pEntry[index]);
/* Only add complete perf mode entries */
- if ((pEntry[index].perf_level != -1) &&
- (pEntry[index].nvclockmax != -1)) {
+ if (pEntry[index].perf_level_specified &&
+ pEntry[index].nvclockmax_specified) {
/* Set hasDecoupledClocks flag to decide new/old clock
* interface to show.
*/
@@ -249,12 +727,23 @@ static void update_perf_mode_table(CtkPowermizer *ctk_powermizer,
pEntry[index].processorclockmin))) {
ctk_powermizer->hasDecoupledClock = TRUE;
}
+ /* Set hasEditablePerfLevel flag to decide editable performance
+ * table to show
+ */
+ if (!ctk_powermizer->hasEditablePerfLevel &&
+ (pEntry[index].nvclockeditable ||
+ pEntry[index].memtransferrateeditable)) {
+ ctk_powermizer->hasEditablePerfLevel = TRUE;
+ }
+
row_idx++;
}
index++;
}
+ ctk_powermizer->num_perf_levels = index;
g_free(tmp_perf_modes);
+
/* Since table cell management in GTK lacks, just remove and rebuild
* the table from scratch.
*/
@@ -262,7 +751,7 @@ static void update_perf_mode_table(CtkPowermizer *ctk_powermizer,
/* Dump out the old table */
ctk_empty_container(ctk_powermizer->performance_table_hbox);
-
+
/* Generate a new table */
if (ctk_powermizer->hasDecoupledClock) {
@@ -281,7 +770,7 @@ static void update_perf_mode_table(CtkPowermizer *ctk_powermizer,
gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2,
GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
-
+
/* Vertical separator */
vsep = gtk_vseparator_new();
gtk_table_attach(GTK_TABLE(table), vsep, 1, 2, 0, row_idx,
@@ -305,15 +794,15 @@ static void update_perf_mode_table(CtkPowermizer *ctk_powermizer,
/* Vertical separator */
vsep = gtk_vseparator_new();
- gtk_table_attach(GTK_TABLE(table), vsep, col_idx+4, col_idx+5, 0,
- row_idx,
+ gtk_table_attach(GTK_TABLE(table), vsep, col_idx+4, col_idx+5,
+ 0, row_idx,
GTK_FILL, GTK_FILL | GTK_EXPAND, 0, 0);
col_idx += 4;
}
/* Memory transfer rate */
if (ctk_powermizer->memory_transfer_rate &&
- pEntry[i].memtransferrate != -1) {
+ pEntry[i].memtransferratemin_specified) {
label = gtk_label_new("Memory Transfer Rate");
gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
gtk_table_attach(GTK_TABLE(table), label, col_idx+1, col_idx+3, 0, 1,
@@ -334,6 +823,7 @@ static void update_perf_mode_table(CtkPowermizer *ctk_powermizer,
GTK_FILL, GTK_FILL | GTK_EXPAND, 0, 0);
col_idx += 4;
}
+
if (ctk_powermizer->processor_clock) {
/* Processor clock */
label = gtk_label_new("Processor Clock");
@@ -348,7 +838,7 @@ static void update_perf_mode_table(CtkPowermizer *ctk_powermizer,
gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
gtk_table_attach(GTK_TABLE(table), label, col_idx+2, col_idx+3, 1, 2,
GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
-
+
/* Vertical separator */
vsep = gtk_vseparator_new();
gtk_table_attach(GTK_TABLE(table), vsep, col_idx+3, col_idx+4,
@@ -380,7 +870,7 @@ static void update_perf_mode_table(CtkPowermizer *ctk_powermizer,
col_idx++;
}
- if (pEntry[i].memtransferrate != -1 &&
+ if (pEntry[i].memtransferrate_specified &&
ctk_powermizer->memory_transfer_rate) {
label = gtk_label_new("Memory Transfer Rate");
gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
@@ -400,12 +890,12 @@ static void update_perf_mode_table(CtkPowermizer *ctk_powermizer,
/* Parse the perf levels and populate the table */
row_idx = 0; //reset value used to calculate vseparator.
row_idx = 3;
- for (i = 0; i < index; i++) {
+ for (i = 0; i < index; i++) {
col_idx = 0;
/* Only add complete perf mode entries */
if (ctk_powermizer->hasDecoupledClock &&
- (pEntry[i].perf_level != -1) &&
- (pEntry[i].nvclockmax != -1)) {
+ (pEntry[i].perf_level_specified) &&
+ (pEntry[i].nvclockmax_specified)) {
active = (pEntry[i].perf_level == perf_level);
@@ -442,7 +932,7 @@ static void update_perf_mode_table(CtkPowermizer *ctk_powermizer,
col_idx +=3;
}
if (ctk_powermizer->memory_transfer_rate &&
- pEntry[i].memtransferrate != -1) {
+ pEntry[i].memtransferratemin_specified) {
g_snprintf(tmp_str, 24, "%d MHz", pEntry[i].memtransferratemin);
label = gtk_label_new(tmp_str);
gtk_widget_set_sensitive(label, active);
@@ -457,7 +947,7 @@ static void update_perf_mode_table(CtkPowermizer *ctk_powermizer,
gtk_table_attach(GTK_TABLE(table), label, col_idx+2, col_idx+3,
row_idx, row_idx+1,
GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
- col_idx +=3;
+ col_idx +=4;
}
if (ctk_powermizer->processor_clock) {
g_snprintf(tmp_str, 24, "%d MHz", pEntry[i].processorclockmin);
@@ -476,8 +966,8 @@ static void update_perf_mode_table(CtkPowermizer *ctk_powermizer,
GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
}
row_idx++;
- } else if ((pEntry[i].perf_level != -1) &&
- (pEntry[i].nvclock != -1)) {
+ } else if ((pEntry[i].perf_level_specified) &&
+ (pEntry[i].nvclock_specified)) {
active = (pEntry[i].perf_level == perf_level);
@@ -507,7 +997,7 @@ static void update_perf_mode_table(CtkPowermizer *ctk_powermizer,
col_idx++;
}
if (ctk_powermizer->memory_transfer_rate &&
- pEntry[i].memtransferrate != -1) {
+ pEntry[i].memtransferrate_specified) {
g_snprintf(tmp_str, 24, "%d MHz", pEntry[i].memtransferrate);
label = gtk_label_new(tmp_str);
@@ -587,12 +1077,12 @@ static gboolean update_powermizer_info(gpointer user_data)
if (ret == NvCtrlSuccess && ctk_powermizer->gpu_clock) {
/* Invalidate the entries */
- memset(&pEntry, -1, sizeof(pEntry));
+ memset(&pEntry, 0, sizeof(pEntry));
parse_token_value_pairs(clock_string, apply_perf_mode_token,
&pEntry);
- if (pEntry.nvclock != -1) {
+ if (pEntry.nvclock_specified) {
gpu_clock = pEntry.nvclock;
s = g_strdup_printf("%d Mhz", gpu_clock);
gtk_label_set_text(GTK_LABEL(ctk_powermizer->gpu_clock), s);
@@ -601,14 +1091,14 @@ static gboolean update_powermizer_info(gpointer user_data)
}
if (ctk_powermizer->memory_transfer_rate &&
- pEntry.memtransferrate != -1) {
+ pEntry.memtransferrate_specified) {
memory_transfer_rate = pEntry.memtransferrate;
s = g_strdup_printf("%d Mhz", memory_transfer_rate);
gtk_label_set_text(GTK_LABEL(ctk_powermizer->memory_transfer_rate), s);
g_free(s);
}
- if (ctk_powermizer->processor_clock && pEntry.processorclock != -1) {
+ if (ctk_powermizer->processor_clock && pEntry.processorclock_specified) {
s = g_strdup_printf("%d Mhz", pEntry.processorclock);
gtk_label_set_text(GTK_LABEL(ctk_powermizer->processor_clock), s);
g_free(s);
@@ -656,8 +1146,6 @@ static gboolean update_powermizer_info(gpointer user_data)
}
if (ctk_powermizer->performance_level && ctk_powermizer->gpu_clock) {
- /* update the perf table */
-
update_perf_mode_table(ctk_powermizer, perf_level);
}
@@ -753,11 +1241,11 @@ GtkWidget* ctk_powermizer_new(NvCtrlAttributeHandle *handle,
gint row = 0;
gchar *s = NULL;
gint tmp;
- gboolean gpu_clock_available = FALSE;
- gboolean mem_transfer_rate_available = FALSE;
gboolean processor_clock_available = FALSE;
gboolean power_source_available = FALSE;
gboolean perf_level_available = FALSE;
+ gboolean gpu_clock_available = FALSE;
+ gboolean mem_transfer_rate_available = FALSE;
gboolean adaptive_clock_state_available = FALSE;
gboolean cuda_dp_ui = FALSE;
gboolean pcie_gen_queriable = FALSE;
@@ -788,6 +1276,7 @@ GtkWidget* ctk_powermizer_new(NvCtrlAttributeHandle *handle,
adaptive_clock_state_available = TRUE;
}
+
/* Check if reporting value of the clock supported */
ret = NvCtrlGetStringAttribute(handle,
@@ -797,18 +1286,18 @@ GtkWidget* ctk_powermizer_new(NvCtrlAttributeHandle *handle,
if (ret == NvCtrlSuccess) {
/* Invalidate the entries */
- memset(&pEntry, -1, sizeof(pEntry));
+ memset(&pEntry, 0, sizeof(pEntry));
parse_token_value_pairs(clock_string, apply_perf_mode_token,
&pEntry);
- if (pEntry.nvclock != -1) {
+ if (pEntry.nvclock_specified) {
gpu_clock_available = TRUE;
}
- if (pEntry.memtransferrate != -1) {
+ if (pEntry.memtransferrate_specified) {
mem_transfer_rate_available = TRUE;
}
- if (pEntry.processorclock != -1) {
+ if (pEntry.processorclock_specified) {
processor_clock_available = TRUE;
}
}
@@ -836,6 +1325,8 @@ GtkWidget* ctk_powermizer_new(NvCtrlAttributeHandle *handle,
ctk_powermizer->ctk_config = ctk_config;
ctk_powermizer->pcie_gen_queriable = pcie_gen_queriable;
ctk_powermizer->hasDecoupledClock = FALSE;
+ ctk_powermizer->hasEditablePerfLevel = FALSE;
+ ctk_powermizer->license_accepted = FALSE;
/* set container properties for the CtkPowermizer widget */
@@ -1021,6 +1512,9 @@ GtkWidget* ctk_powermizer_new(NvCtrlAttributeHandle *handle,
hbox = gtk_hbox_new(FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
ctk_powermizer->performance_table_hbox = hbox;
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+ ctk_powermizer->performance_table_hbox1 = hbox;
}
/* Register a timer callback to update the temperatures */
@@ -1067,7 +1561,7 @@ GtkWidget* ctk_powermizer_new(NvCtrlAttributeHandle *handle,
/* Specifying drop down list */
menu = (CtkDropDownMenu *)
- ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_COMBO);
+ ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_READONLY);
create_powermizer_menu_entry(
menu, bit_mask,
@@ -1241,6 +1735,15 @@ GtkWidget* ctk_powermizer_new(NvCtrlAttributeHandle *handle,
/* Updating the powermizer page */
update_powermizer_info(ctk_powermizer);
+
+ /* Add editable performance level table */
+
+ if (ctk_powermizer->hasEditablePerfLevel) {
+ update_editable_perf_level_info(ctk_powermizer);
+ } else {
+ ctk_empty_container(ctk_powermizer->performance_table_hbox1);
+ }
+
gtk_widget_show_all(GTK_WIDGET(ctk_powermizer));
g_signal_connect(G_OBJECT(ctk_event),
@@ -1248,6 +1751,16 @@ GtkWidget* ctk_powermizer_new(NvCtrlAttributeHandle *handle,
G_CALLBACK(update_powermizer_menu_event),
(gpointer) ctk_powermizer);
+ g_signal_connect(G_OBJECT(ctk_event),
+ CTK_EVENT_NAME(NV_CTRL_GPU_NVCLOCK_OFFSET),
+ G_CALLBACK(offset_value_changed_event_received),
+ (gpointer) ctk_powermizer);
+
+ g_signal_connect(G_OBJECT(ctk_event),
+ CTK_EVENT_NAME(NV_CTRL_GPU_MEM_TRANSFER_RATE_OFFSET),
+ G_CALLBACK(offset_value_changed_event_received),
+ (gpointer) ctk_powermizer);
+
return GTK_WIDGET(ctk_powermizer);
}
@@ -1484,7 +1997,6 @@ static void dp_configuration_update_received(GtkObject *object,
} /* dp_configuration_update_received() */
-
/*
* dp_config_button_toggled() - callback function for
* enable CUDA - Double Precision Boost checkbox.
@@ -1583,6 +2095,17 @@ GtkTextBuffer *ctk_powermizer_create_help(GtkTextTagTable *table,
ctk_help_para(b, &i, "%s", __performance_levels_table_help);
}
+ ctk_help_heading(b, &i, "Enable overclock Settings");
+ ctk_help_para(b, &i, "%s", __enable_button_help);
+ if (ctk_powermizer->hasEditablePerfLevel) {
+ ctk_help_heading(b, &i, "Editable Performance Levels (Table)");
+ ctk_help_para(b, &i, "%s", __editable_performance_levels_table_help);
+ ctk_help_heading(b, &i, "Graphics Clock Offset");
+ ctk_help_para(b, &i, "%s", __gpu_clock_offset_help);
+ ctk_help_heading(b, &i, "Memory Transfer Rate Offset");
+ ctk_help_para(b, &i, "%s", __memory_transfer_rate_offset_help);
+ }
+
if (ctk_powermizer->powermizer_menu) {
ctk_help_heading(b, &i, "PowerMizer Settings");
ctk_help_para(b, &i, "%s", ctk_powermizer->powermizer_menu_help);
diff --git a/src/gtk+-2.x/ctkpowermizer.h b/src/gtk+-2.x/ctkpowermizer.h
index fc0f971..a4e4f7a 100644
--- a/src/gtk+-2.x/ctkpowermizer.h
+++ b/src/gtk+-2.x/ctkpowermizer.h
@@ -43,7 +43,6 @@ G_BEGIN_DECLS
#define CTK_POWERMIZER_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), CTK_TYPE_POWERMIZER, CtkPowermizerClass))
-
typedef struct _CtkPowermizer CtkPowermizer;
typedef struct _CtkPowermizerClass CtkPowermizerClass;
@@ -61,6 +60,7 @@ struct _CtkPowermizer
GtkWidget *power_source;
GtkWidget *performance_level;
GtkWidget *performance_table_hbox;
+ GtkWidget *performance_table_hbox1;
GtkWidget *powermizer_menu;
GtkWidget *powermizer_txt;
GtkWidget *box_powermizer_menu;
@@ -71,10 +71,17 @@ struct _CtkPowermizer
gboolean dp_enabled;
gboolean dp_toggle_warning_dlg_shown;
gboolean hasDecoupledClock;
+ gboolean hasEditablePerfLevel;
+ gboolean license_accepted;
gint attribute;
gint powermizer_default_mode;
GtkWidget *status;
+ GtkWidget *enable_dialog;
+ GtkWidget *enable_checkbox;
+ GtkWidget *editable_perf_level_table;
+ gint num_perf_levels;
+
GtkWidget *link_width;
GtkWidget *link_speed;
gboolean pcie_gen_queriable;
diff --git a/src/gtk+-2.x/ctkpowersavings.c b/src/gtk+-2.x/ctkpowersavings.c
deleted file mode 100644
index 1c5ebfe..0000000
--- a/src/gtk+-2.x/ctkpowersavings.c
+++ /dev/null
@@ -1,230 +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 and conditions of the GNU General Public License,
- * version 2, 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 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, see <http://www.gnu.org/licenses>.
- */
-
-#include <gtk/gtk.h>
-#include <NvCtrlAttributes.h>
-
-#include "ctkbanner.h"
-
-#include "ctkpowersavings.h"
-
-#include "ctkconfig.h"
-#include "ctkhelp.h"
-
-static void vblank_control_button_toggled (GtkWidget *, gpointer);
-static void post_vblank_control_button_toggled (CtkPowerSavings *, gboolean);
-static void value_changed (GtkObject *, gpointer, gpointer);
-
-static const char *__vblank_control_help =
-"When enabled, VBlank interrupts will be generated by the GPU "
-"only if they are required by the driver. Normally, VBlank "
-"interrupts are generated on every vertical refresh of every "
-"display device connected to the GPU. Enabling on-demand VBlank "
-"interrupt control can help conserve power.";
-
-
-GType ctk_power_savings_get_type(void)
-{
- static GType ctk_power_savings_type = 0;
-
- if (!ctk_power_savings_type) {
- static const GTypeInfo ctk_power_savings_info = {
- sizeof (CtkPowerSavingsClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- NULL, /* class_init, */
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (CtkPowerSavings),
- 0, /* n_preallocs */
- NULL, /* instance_init */
- NULL /* value_table */
- };
-
- ctk_power_savings_type = g_type_register_static (GTK_TYPE_VBOX,
- "CtkPowerSavings", &ctk_power_savings_info, 0);
- }
-
- return ctk_power_savings_type;
-}
-
-GtkWidget* ctk_power_savings_new(NvCtrlAttributeHandle *handle,
- CtkConfig *ctk_config, CtkEvent *ctk_event)
-{
- GObject *object;
- CtkPowerSavings *ctk_power_savings;
- GtkWidget *label;
- GtkWidget *banner;
- GtkWidget *hseparator;
- GtkWidget *hbox;
- GtkWidget *vbox;
- GtkWidget *check_button;
-
- gint ondemand_vblank_control;
-
- /* query power savings settings */
-
- if (NvCtrlGetAttribute(handle, NV_CTRL_ONDEMAND_VBLANK_INTERRUPTS,
- &ondemand_vblank_control)
- != NvCtrlSuccess) {
- return NULL;
- }
-
- object = g_object_new(CTK_TYPE_POWER_SAVINGS, NULL);
-
- ctk_power_savings = CTK_POWER_SAVINGS(object);
- ctk_power_savings->handle = handle;
- ctk_power_savings->ctk_config = ctk_config;
-
- gtk_box_set_spacing(GTK_BOX(object), 10);
-
- banner = ctk_banner_image_new(BANNER_ARTWORK_GPU);
- gtk_box_pack_start(GTK_BOX(object), banner, FALSE, FALSE, 0);
-
-
- /* 'Interrupts' section */
-
- hbox = gtk_hbox_new(FALSE, 5);
- gtk_box_pack_start(GTK_BOX(object), hbox, FALSE, FALSE, 0);
-
- label = gtk_label_new("Interrupts");
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-
- hseparator = gtk_hseparator_new();
- gtk_box_pack_start(GTK_BOX(hbox), hseparator, TRUE, TRUE, 0);
-
-
- vbox = gtk_vbox_new(FALSE, 2);
- gtk_box_pack_start(GTK_BOX(object), vbox, FALSE, FALSE, 0);
-
-
- /* 'On-Demand VBlank interrupts' toggle */
-
- label = gtk_label_new("On-Demand VBlank Interrupts");
-
- check_button = gtk_check_button_new();
- gtk_container_add(GTK_CONTAINER(check_button), label);
-
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_button),
- ondemand_vblank_control);
-
- gtk_box_pack_start(GTK_BOX(vbox), check_button, FALSE, FALSE, 0);
-
- g_signal_connect(G_OBJECT(check_button), "toggled",
- G_CALLBACK(vblank_control_button_toggled),
- (gpointer)ctk_power_savings);
-
- g_signal_connect(G_OBJECT(ctk_event),
- CTK_EVENT_NAME(NV_CTRL_ONDEMAND_VBLANK_INTERRUPTS),
- G_CALLBACK(value_changed), (gpointer)ctk_power_savings);
-
- ctk_config_set_tooltip(ctk_config, check_button,
- __vblank_control_help);
-
- ctk_power_savings->vblank_control_button = check_button;
-
-
- gtk_widget_show_all(GTK_WIDGET(object));
-
- return GTK_WIDGET(object);
-}
-
-/*
- * Prints a status bar message.
- */
-static void post_vblank_control_button_toggled(CtkPowerSavings *ctk_power_savings,
- gboolean enabled)
-{
- ctk_config_statusbar_message(ctk_power_savings->ctk_config,
- "On-Demand VBlank Interrupts %s.",
- enabled ? "enabled" : "disabled");
-}
-
-static void vblank_control_button_toggled(
- GtkWidget *widget,
- gpointer user_data
-)
-{
- CtkPowerSavings *ctk_power_savings;
- gboolean enabled;
-
- ctk_power_savings = CTK_POWER_SAVINGS(user_data);
-
- enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
-
- NvCtrlSetAttribute(ctk_power_savings->handle,
- NV_CTRL_ONDEMAND_VBLANK_INTERRUPTS, enabled);
-
- post_vblank_control_button_toggled(ctk_power_savings, enabled);
-}
-
-/*
- * value_changed() - callback function for changed NV-CONTROL
- * attribute settings.
- */
-static void value_changed(GtkObject *object, gpointer arg1, gpointer user_data)
-{
- CtkEventStruct *event_struct;
- CtkPowerSavings *ctk_power_savings;
- gboolean enabled;
- GtkToggleButton *button;
- GCallback func;
-
- event_struct = (CtkEventStruct *)arg1;
- ctk_power_savings = CTK_POWER_SAVINGS(user_data);
-
- switch (event_struct->attribute) {
- case NV_CTRL_ONDEMAND_VBLANK_INTERRUPTS:
- button = GTK_TOGGLE_BUTTON(ctk_power_savings->vblank_control_button);
- func = G_CALLBACK(vblank_control_button_toggled);
- post_vblank_control_button_toggled(ctk_power_savings, event_struct->value);
- break;
- default:
- return;
- }
-
- enabled = gtk_toggle_button_get_active(button);
-
- if (enabled != event_struct->value) {
- g_signal_handlers_block_by_func(button, func, ctk_power_savings);
- gtk_toggle_button_set_active(button, event_struct->value);
- g_signal_handlers_unblock_by_func(button, func, ctk_power_savings);
- }
-
-}
-
-GtkTextBuffer *ctk_power_savings_create_help(GtkTextTagTable *table,
- CtkPowerSavings *ctk_power_savings)
-{
- GtkTextIter i;
- GtkTextBuffer *b;
-
- b = gtk_text_buffer_new(table);
-
- gtk_text_buffer_get_iter_at_offset(b, &i, 0);
-
- ctk_help_title(b, &i, "Power Savings Help");
-
- ctk_help_heading(b, &i, "On-Demand VBlank Interrupts");
- ctk_help_para(b, &i, "%s", __vblank_control_help);
-
- ctk_help_finish(b);
-
- return b;
-}
diff --git a/src/gtk+-2.x/ctkpowersavings.h b/src/gtk+-2.x/ctkpowersavings.h
deleted file mode 100644
index 77ed6ed..0000000
--- a/src/gtk+-2.x/ctkpowersavings.h
+++ /dev/null
@@ -1,73 +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 and conditions of the GNU General Public License,
- * version 2, 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 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, see <http://www.gnu.org/licenses>.
- */
-
-#ifndef __CTK_POWER_SAVINGS_H__
-#define __CTK_POWER_SAVINGS_H__
-
-#include "ctkevent.h"
-#include "ctkconfig.h"
-
-G_BEGIN_DECLS
-
-#define CTK_TYPE_POWER_SAVINGS (ctk_power_savings_get_type())
-
-#define CTK_POWER_SAVINGS(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), CTK_TYPE_POWER_SAVINGS, CtkPowerSavings))
-
-#define CTK_POWER_SAVINGS_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), CTK_TYPE_POWER_SAVINGS, CtkPowerSavingsClass))
-
-#define CTK_IS_POWER_SAVINGS(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CTK_TYPE_POWER_SAVINGS))
-
-#define CTK_IS_POWER_SAVINGS_CLASS(class) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), CTK_TYPE_POWER_SAVINGS))
-
-#define CTK_POWER_SAVINGS_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), CTK_TYPE_POWER_SAVINGS, CtkPowerSavingsClass))
-
-
-typedef struct _CtkPowerSavings CtkPowerSavings;
-typedef struct _CtkPowerSavingsClass CtkPowerSavingsClass;
-
-struct _CtkPowerSavings
-{
- GtkVBox parent;
-
- NvCtrlAttributeHandle *handle;
- CtkConfig *ctk_config;
-
- GtkWidget *vblank_control_button;
-};
-
-struct _CtkPowerSavingsClass
-{
- GtkVBoxClass parent_class;
-};
-
-GType ctk_power_savings_get_type (void) G_GNUC_CONST;
-GtkWidget* ctk_power_savings_new (NvCtrlAttributeHandle *,
- CtkConfig *, CtkEvent *);
-
-GtkTextBuffer *ctk_power_savings_create_help(GtkTextTagTable *, CtkPowerSavings *);
-
-G_END_DECLS
-
-#endif /* __CTK_POWER_SAVINGS_H__ */
-
diff --git a/src/gtk+-2.x/ctkscale.c b/src/gtk+-2.x/ctkscale.c
index fb68ceb..40d0c25 100644
--- a/src/gtk+-2.x/ctkscale.c
+++ b/src/gtk+-2.x/ctkscale.c
@@ -244,7 +244,8 @@ GtkWidget* ctk_scale_new(GtkAdjustment *gtk_adjustment,
/* text entry */
- ctk_scale->text_entry = gtk_entry_new_with_max_length(6);
+ ctk_scale->text_entry = gtk_entry_new();
+ gtk_entry_set_max_length(GTK_ENTRY(ctk_scale->text_entry), 6);
gtk_entry_set_width_chars(GTK_ENTRY(ctk_scale->text_entry), 6);
/* text entry container */
diff --git a/src/gtk+-2.x/ctkscreen.c b/src/gtk+-2.x/ctkscreen.c
index 2a654bb..4d22a03 100644
--- a/src/gtk+-2.x/ctkscreen.c
+++ b/src/gtk+-2.x/ctkscreen.c
@@ -38,9 +38,6 @@ void ctk_screen_event_handler(GtkWidget *widget,
XRRScreenChangeNotifyEvent *ev,
gpointer data);
-static void associated_displays_received(GtkObject *object, gpointer arg1,
- gpointer user_data);
-
static void info_update_gpu_error(GtkObject *object, gpointer arg1,
gpointer user_data);
@@ -322,12 +319,6 @@ GtkWidget* ctk_screen_new(NvCtrlAttributeHandle *handle,
g_free(depth);
g_free(gpus);
g_free(displays);
-
- /* Handle updates to the list of associated display devices */
- g_signal_connect(G_OBJECT(ctk_event),
- CTK_EVENT_NAME(NV_CTRL_ASSOCIATED_DISPLAY_DEVICES),
- G_CALLBACK(associated_displays_received),
- (gpointer) ctk_screen);
/* Setup widget to handle XRRScreenChangeNotify events */
g_signal_connect(G_OBJECT(ctk_event), "CTK_EVENT_RRScreenChangeNotify",
@@ -438,25 +429,6 @@ void ctk_screen_event_handler(GtkWidget *widget,
/*
- * When the list of associated displays on this screen changes, we should
- * update the display device list shown on the page.
- */
-static void associated_displays_received(GtkObject *object, gpointer arg1,
- gpointer user_data)
-{
- CtkScreen *ctk_object = CTK_SCREEN(user_data);
- gchar *str;
-
- str = make_display_device_list(ctk_object->handle);
-
- gtk_label_set_text(GTK_LABEL(ctk_object->displays), str);
-
- g_free(str);
-
-} /* associated_displays_received() */
-
-
-/*
* When the number of gpu errors occurred changes,
* update the count showed on the page.
*/
diff --git a/src/gtk+-2.x/ctkserver.c b/src/gtk+-2.x/ctkserver.c
index 19851e1..755c30b 100644
--- a/src/gtk+-2.x/ctkserver.c
+++ b/src/gtk+-2.x/ctkserver.c
@@ -296,6 +296,7 @@ GtkWidget* ctk_server_new(NvCtrlAttributeHandle *handle,
else if (tmp == NV_CTRL_ARCHITECTURE_X86_64) arch = "x86_64";
else if (tmp == NV_CTRL_ARCHITECTURE_IA64) arch = "ia64";
else if (tmp == NV_CTRL_ARCHITECTURE_ARM) arch = "ARM";
+ else if (tmp == NV_CTRL_ARCHITECTURE_AARCH64) arch = "AArch64";
}
if (!arch) arch = "Unknown";
os = g_strdup_printf("%s-%s", os, arch);
diff --git a/src/gtk+-2.x/ctkslimm.c b/src/gtk+-2.x/ctkslimm.c
index bfbc638..9717105 100644
--- a/src/gtk+-2.x/ctkslimm.c
+++ b/src/gtk+-2.x/ctkslimm.c
@@ -577,12 +577,12 @@ static void setup_display_refresh_dropdown(CtkSLIMM *ctk_object)
/* Generate the refresh dropdown */
menu = CTK_DROP_DOWN_MENU(ctk_object->mnu_display_refresh);
- ctk_drop_down_menu_reset(menu);
-
g_signal_handlers_block_by_func
(G_OBJECT(ctk_object->mnu_display_refresh),
G_CALLBACK(display_refresh_changed), (gpointer) ctk_object);
+ ctk_drop_down_menu_reset(menu);
+
/* Generate the refresh rate dropdown from the modelines list */
for (modeline = ctk_object->modelines; modeline; modeline = modeline->next) {
@@ -1545,7 +1545,7 @@ GtkWidget* ctk_slimm_new(NvCtrlAttributeHandle *handle,
/* Option menu for Display Grid Configuration */
menu = (CtkDropDownMenu *)
- ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_COMBO);
+ ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_READONLY);
ctk_slimm->mnu_display_config = GTK_WIDGET(menu);
grid_menu_selected_id = 0;
@@ -1606,7 +1606,7 @@ GtkWidget* ctk_slimm_new(NvCtrlAttributeHandle *handle,
/* Option menu for resolutions */
hbox = gtk_hbox_new(FALSE, 0);
ctk_slimm->mnu_display_resolution =
- ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_COMBO);
+ ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_READONLY);
/* Create a drop down menu */
setup_display_resolution_dropdown(ctk_object);
@@ -1624,7 +1624,7 @@ GtkWidget* ctk_slimm_new(NvCtrlAttributeHandle *handle,
/* Option menu for refresh rates */
hbox = gtk_hbox_new(FALSE, 0);
ctk_slimm->mnu_display_refresh =
- ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_COMBO);
+ ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_READONLY);
setup_display_refresh_dropdown(ctk_object);
g_signal_connect(G_OBJECT(ctk_object->mnu_display_refresh), "changed",
G_CALLBACK(display_refresh_changed),
@@ -1852,6 +1852,10 @@ GtkTextBuffer *ctk_slimm_create_help(GtkTextTagTable *table,
ctk_help_para(b, &i, "This is the total size of the X screen formed using all "
"displays in SLI Mosaic Mode.");
+ ctk_help_heading(b, &i, "Maximum Size");
+ ctk_help_para(b, &i, "This is the maximum allowable size of the X screen "
+ "formed using all displays in SLI Mosaic Mode.");
+
ctk_help_heading(b, &i, "Save to X Configuration File");
ctk_help_para(b, &i, "Clicking this button saves the selected SLI Mosaic Mode "
"settings into the X Configuration File.");
diff --git a/src/gtk+-2.x/ctkthermal.c b/src/gtk+-2.x/ctkthermal.c
index d5f2947..b0a8773 100644
--- a/src/gtk+-2.x/ctkthermal.c
+++ b/src/gtk+-2.x/ctkthermal.c
@@ -1314,7 +1314,8 @@ GtkWidget* ctk_thermal_new(NvCtrlAttributeHandle *handle,
eventbox = gtk_event_box_new();
gtk_box_pack_start(GTK_BOX(hbox2), eventbox, FALSE, FALSE, 0);
- entry = gtk_entry_new_with_max_length(5);
+ entry = gtk_entry_new();
+ gtk_entry_set_max_length(GTK_ENTRY(entry), 5);
gtk_container_add(GTK_CONTAINER(eventbox), entry);
gtk_widget_set_sensitive(entry, FALSE);
gtk_entry_set_width_chars(GTK_ENTRY(entry), 5);
diff --git a/src/gtk+-2.x/ctkwindow.c b/src/gtk+-2.x/ctkwindow.c
index 2848734..5286655 100644
--- a/src/gtk+-2.x/ctkwindow.c
+++ b/src/gtk+-2.x/ctkwindow.c
@@ -53,7 +53,6 @@
#include "ctkpowermizer.h"
#include "ctkclocks.h"
#include "ctkvcs.h"
-#include "ctkpowersavings.h"
#include "ctk3dvisionpro.h"
#include "ctkdisplaydevice.h"
@@ -638,7 +637,7 @@ GtkWidget *ctk_window_new(ParsedAttribute *p, ConfigProperties *conf,
screen_name = NvCtrlGetDisplayName(screen_handle);
child = ctk_screen_new(screen_handle, ctk_event);
- gtk_object_ref(GTK_OBJECT(child));
+ g_object_ref(GTK_OBJECT(child));
gtk_tree_store_set(ctk_window->tree_store, &iter,
CTK_WINDOW_WIDGET_COLUMN, child, -1);
gtk_tree_store_set(ctk_window->tree_store, &iter,
@@ -794,7 +793,7 @@ GtkWidget *ctk_window_new(ParsedAttribute *p, ConfigProperties *conf,
child = ctk_gpu_new(gpu_handle, h->targets[X_SCREEN_TARGET].t, ctk_event,
ctk_config);
- gtk_object_ref(GTK_OBJECT(child));
+ g_object_ref(GTK_OBJECT(child));
gtk_tree_store_set(ctk_window->tree_store, &iter,
CTK_WINDOW_WIDGET_COLUMN, child, -1);
gtk_tree_store_set(ctk_window->tree_store, &iter,
@@ -810,15 +809,6 @@ GtkWidget *ctk_window_new(ParsedAttribute *p, ConfigProperties *conf,
CTK_WINDOW_UNSELECT_WIDGET_FUNC_COLUMN,
ctk_gpu_page_unselect, -1);
- /* power savings */
-
- child = ctk_power_savings_new(gpu_handle, ctk_config, ctk_event);
- if (child) {
- help = ctk_power_savings_create_help(tag_table, CTK_POWER_SAVINGS(child));
- add_page(child, help, ctk_window, &iter, NULL,
- "Power Savings Settings", NULL, NULL, NULL);
- }
-
/* thermal information */
child = ctk_thermal_new(gpu_handle, ctk_config, ctk_event);
@@ -912,7 +902,7 @@ GtkWidget *ctk_window_new(ParsedAttribute *p, ConfigProperties *conf,
gtk_tree_store_set(ctk_window->tree_store, &iter,
CTK_WINDOW_LABEL_COLUMN, vcs_name, -1);
child = ctk_vcs_new(vcs_handle, ctk_config);
- gtk_object_ref(GTK_OBJECT(child));
+ g_object_ref(GTK_OBJECT(child));
gtk_tree_store_set(ctk_window->tree_store, &iter,
CTK_WINDOW_WIDGET_COLUMN, child, -1);
gtk_tree_store_set(ctk_window->tree_store, &iter,
@@ -961,7 +951,7 @@ GtkWidget *ctk_window_new(ParsedAttribute *p, ConfigProperties *conf,
gtk_tree_store_set(ctk_window->tree_store, &iter,
CTK_WINDOW_LABEL_COLUMN, gvi_name, -1);
child = ctk_gvi_new(gvi_handle, ctk_config, ctk_event);
- gtk_object_ref(GTK_OBJECT(child));
+ g_object_ref(GTK_OBJECT(child));
gtk_tree_store_set(ctk_window->tree_store, &iter,
CTK_WINDOW_WIDGET_COLUMN, child, -1);
gtk_tree_store_set(ctk_window->tree_store, &iter,
@@ -1035,7 +1025,10 @@ GtkWidget *ctk_window_new(ParsedAttribute *p, ConfigProperties *conf,
}
widget = ctk_app_profile_new(ctk_config, driver_version);
- XFree(driver_version);
+
+ if (driver_version) {
+ XFree(driver_version);
+ }
add_page(widget, ctk_app_profile_create_help(CTK_APP_PROFILE(widget), tag_table),
ctk_window, NULL, NULL, "Application Profiles",
diff --git a/src/jansson/dump.c b/src/jansson/dump.c
index 2c7dee9..7eddd5a 100644
--- a/src/jansson/dump.c
+++ b/src/jansson/dump.c
@@ -1,11 +1,14 @@
/*
- * Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
+ * Copyright (c) 2009-2014 Petri Lehtinen <petri@digip.org>
*
* Jansson is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
+#ifndef _GNU_SOURCE
#define _GNU_SOURCE
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -38,7 +41,7 @@ static int dump_to_file(const char *buffer, size_t size, void *data)
}
/* 32 spaces (the maximum indentation size) */
-static char whitespace[] = " ";
+static const char whitespace[] = " ";
static int dump_indent(size_t flags, int depth, int space, json_dump_callback_t dump, void *data)
{
@@ -62,24 +65,25 @@ static int dump_indent(size_t flags, int depth, int space, json_dump_callback_t
return 0;
}
-static int dump_string(const char *str, json_dump_callback_t dump, void *data, size_t flags)
+static int dump_string(const char *str, size_t len, json_dump_callback_t dump, void *data, size_t flags)
{
- const char *pos, *end;
+ const char *pos, *end, *lim;
int32_t codepoint;
if(dump("\"", 1, data))
return -1;
end = pos = str;
+ lim = str + len;
while(1)
{
const char *text;
char seq[13];
int length;
- while(*end)
+ while(end < lim)
{
- end = utf8_iterate(pos, &codepoint);
+ end = utf8_iterate(pos, lim - pos, &codepoint);
if(!end)
return -1;
@@ -123,7 +127,7 @@ static int dump_string(const char *str, json_dump_callback_t dump, void *data, s
/* codepoint is in BMP */
if(codepoint < 0x10000)
{
- sprintf(seq, "\\u%04x", codepoint);
+ sprintf(seq, "\\u%04X", codepoint);
length = 6;
}
@@ -136,7 +140,7 @@ static int dump_string(const char *str, json_dump_callback_t dump, void *data, s
first = 0xD800 | ((codepoint & 0xffc00) >> 10);
last = 0xDC00 | (codepoint & 0x003ff);
- sprintf(seq, "\\u%04x\\u%04x", first, last);
+ sprintf(seq, "\\u%04X\\u%04X", first, last);
length = 12;
}
@@ -171,6 +175,9 @@ static int object_key_compare_serials(const void *key1, const void *key2)
static int do_dump(const json_t *json, size_t flags, int depth,
json_dump_callback_t dump, void *data)
{
+ if(!json)
+ return -1;
+
switch(json_typeof(json)) {
case JSON_NULL:
return dump("null", 4, data);
@@ -209,7 +216,7 @@ static int do_dump(const json_t *json, size_t flags, int depth,
}
case JSON_STRING:
- return dump_string(json_string_value(json), dump, data, flags);
+ return dump_string(json_string_value(json), json_string_length(json), dump, data, flags);
case JSON_ARRAY:
{
@@ -330,7 +337,7 @@ static int do_dump(const json_t *json, size_t flags, int depth,
value = json_object_get(json, key);
assert(value);
- dump_string(key, dump, data, flags);
+ dump_string(key, strlen(key), dump, data, flags);
if(dump(separator, separator_length, data) ||
do_dump(value, flags, depth + 1, dump, data))
{
@@ -366,8 +373,9 @@ static int do_dump(const json_t *json, size_t flags, int depth,
while(iter)
{
void *next = json_object_iter_next((json_t *)json, iter);
+ const char *key = json_object_iter_key(iter);
- dump_string(json_object_iter_key(iter), dump, data, flags);
+ dump_string(key, strlen(key), dump, data, flags);
if(dump(separator, separator_length, data) ||
do_dump(json_object_iter_value(iter), flags, depth + 1,
dump, data))
diff --git a/src/jansson/hashtable.c b/src/jansson/hashtable.c
index bcbaa8c..4c4b565 100644
--- a/src/jansson/hashtable.c
+++ b/src/jansson/hashtable.c
@@ -1,12 +1,21 @@
/*
- * Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
+ * Copyright (c) 2009-2014 Petri Lehtinen <petri@digip.org>
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
+#if HAVE_CONFIG_H
+#include <jansson_private_config.h>
+#endif
+
#include <stdlib.h>
#include <string.h>
+
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
#include <jansson_config.h> /* for JSON_INLINE */
#include "jansson_private.h" /* for container_of() */
#include "hashtable.h"
@@ -15,24 +24,13 @@ typedef struct hashtable_list list_t;
typedef struct hashtable_pair pair_t;
typedef struct hashtable_bucket bucket_t;
-#define list_to_pair(list_) container_of(list_, pair_t, list)
-
-/* From http://www.cse.yorku.ca/~oz/hash.html */
-static size_t hash_str(const void *ptr)
-{
- const char *str = (const char *)ptr;
+extern volatile uint32_t hashtable_seed;
- size_t hash = 5381;
- size_t c;
+/* Implementation of the hash function */
+#include "lookup3.h"
- while((c = (size_t)*str))
- {
- hash = ((hash << 5) + hash) + c;
- str++;
- }
-
- return hash;
-}
+#define list_to_pair(list_) container_of(list_, pair_t, list)
+#define hash_str(key) ((size_t)hashlittle((key), strlen(key), hashtable_seed))
static JSON_INLINE void list_init(list_t *list)
{
@@ -74,19 +72,6 @@ static void insert_to_bucket(hashtable_t *hashtable, bucket_t *bucket,
}
}
-static const size_t primes[] = {
- 5, 13, 23, 53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593,
- 49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469,
- 12582917, 25165843, 50331653, 100663319, 201326611, 402653189,
- 805306457, 1610612741
-};
-
-static JSON_INLINE size_t num_buckets(hashtable_t *hashtable)
-{
- return primes[hashtable->num_buckets];
-}
-
-
static pair_t *hashtable_find_pair(hashtable_t *hashtable, bucket_t *bucket,
const char *key, size_t hash)
{
@@ -120,7 +105,7 @@ static int hashtable_do_del(hashtable_t *hashtable,
bucket_t *bucket;
size_t index;
- index = hash % num_buckets(hashtable);
+ index = hash & hashmask(hashtable->order);
bucket = &hashtable->buckets[index];
pair = hashtable_find_pair(hashtable, bucket, key, hash);
@@ -167,14 +152,14 @@ static int hashtable_do_rehash(hashtable_t *hashtable)
jsonp_free(hashtable->buckets);
- hashtable->num_buckets++;
- new_size = num_buckets(hashtable);
+ hashtable->order++;
+ new_size = hashsize(hashtable->order);
hashtable->buckets = jsonp_malloc(new_size * sizeof(bucket_t));
if(!hashtable->buckets)
return -1;
- for(i = 0; i < num_buckets(hashtable); i++)
+ for(i = 0; i < hashsize(hashtable->order); i++)
{
hashtable->buckets[i].first = hashtable->buckets[i].last =
&hashtable->list;
@@ -199,14 +184,14 @@ int hashtable_init(hashtable_t *hashtable)
size_t i;
hashtable->size = 0;
- hashtable->num_buckets = 0; /* index to primes[] */
- hashtable->buckets = jsonp_malloc(num_buckets(hashtable) * sizeof(bucket_t));
+ hashtable->order = 3;
+ hashtable->buckets = jsonp_malloc(hashsize(hashtable->order) * sizeof(bucket_t));
if(!hashtable->buckets)
return -1;
list_init(&hashtable->list);
- for(i = 0; i < num_buckets(hashtable); i++)
+ for(i = 0; i < hashsize(hashtable->order); i++)
{
hashtable->buckets[i].first = hashtable->buckets[i].last =
&hashtable->list;
@@ -230,12 +215,12 @@ int hashtable_set(hashtable_t *hashtable,
size_t hash, index;
/* rehash if the load ratio exceeds 1 */
- if(hashtable->size >= num_buckets(hashtable))
+ if(hashtable->size >= hashsize(hashtable->order))
if(hashtable_do_rehash(hashtable))
return -1;
hash = hash_str(key);
- index = hash % num_buckets(hashtable);
+ index = hash & hashmask(hashtable->order);
bucket = &hashtable->buckets[index];
pair = hashtable_find_pair(hashtable, bucket, key, hash);
@@ -249,7 +234,14 @@ int hashtable_set(hashtable_t *hashtable,
/* offsetof(...) returns the size of pair_t without the last,
flexible member. This way, the correct amount is
allocated. */
- pair = jsonp_malloc(offsetof(pair_t, key) + strlen(key) + 1);
+
+ size_t len = strlen(key);
+ if(len >= (size_t)-1 - offsetof(pair_t, key)) {
+ /* Avoid an overflow if the key is very long */
+ return -1;
+ }
+
+ pair = jsonp_malloc(offsetof(pair_t, key) + len + 1);
if(!pair)
return -1;
@@ -273,7 +265,7 @@ void *hashtable_get(hashtable_t *hashtable, const char *key)
bucket_t *bucket;
hash = hash_str(key);
- bucket = &hashtable->buckets[hash % num_buckets(hashtable)];
+ bucket = &hashtable->buckets[hash & hashmask(hashtable->order)];
pair = hashtable_find_pair(hashtable, bucket, key, hash);
if(!pair)
@@ -294,7 +286,7 @@ void hashtable_clear(hashtable_t *hashtable)
hashtable_do_clear(hashtable);
- for(i = 0; i < num_buckets(hashtable); i++)
+ for(i = 0; i < hashsize(hashtable->order); i++)
{
hashtable->buckets[i].first = hashtable->buckets[i].last =
&hashtable->list;
@@ -316,7 +308,7 @@ void *hashtable_iter_at(hashtable_t *hashtable, const char *key)
bucket_t *bucket;
hash = hash_str(key);
- bucket = &hashtable->buckets[hash % num_buckets(hashtable)];
+ bucket = &hashtable->buckets[hash & hashmask(hashtable->order)];
pair = hashtable_find_pair(hashtable, bucket, key, hash);
if(!pair)
diff --git a/src/jansson/hashtable.h b/src/jansson/hashtable.h
index de1df26..f54c3fe 100644
--- a/src/jansson/hashtable.h
+++ b/src/jansson/hashtable.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
+ * Copyright (c) 2009-2014 Petri Lehtinen <petri@digip.org>
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
@@ -32,7 +32,7 @@ struct hashtable_bucket {
typedef struct hashtable {
size_t size;
struct hashtable_bucket *buckets;
- size_t num_buckets; /* index to primes[] */
+ size_t order; /* hashtable has pow(2, order) buckets */
struct hashtable_list list;
} hashtable_t;
@@ -40,6 +40,7 @@ typedef struct hashtable {
#define hashtable_key_to_iter(key_) \
(&(container_of(key_, struct hashtable_pair, key)->list))
+
/**
* hashtable_init - Initialize a hashtable object
*
diff --git a/src/jansson/hashtable_seed.c b/src/jansson/hashtable_seed.c
new file mode 100644
index 0000000..751e0e3
--- /dev/null
+++ b/src/jansson/hashtable_seed.c
@@ -0,0 +1,277 @@
+/* Generate sizeof(uint32_t) bytes of as random data as possible to seed
+ the hash function.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <jansson_private_config.h>
+#endif
+
+#include <stdio.h>
+#include <time.h>
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_SCHED_H
+#include <sched.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#if defined(_WIN32)
+/* For GetModuleHandle(), GetProcAddress() and GetCurrentProcessId() */
+#include <windows.h>
+#endif
+
+#include "jansson.h"
+
+
+static uint32_t buf_to_uint32(char *data) {
+ size_t i;
+ uint32_t result = 0;
+
+ for (i = 0; i < sizeof(uint32_t); i++)
+ result = (result << 8) | (unsigned char)data[i];
+
+ return result;
+}
+
+
+
+/* /dev/urandom */
+#if !defined(_WIN32) && defined(USE_URANDOM)
+static int seed_from_urandom(uint32_t *seed) {
+ /* Use unbuffered I/O if we have open(), close() and read(). Otherwise
+ fall back to fopen() */
+
+ char data[sizeof(uint32_t)];
+ int ok;
+
+#if defined(HAVE_OPEN) && defined(HAVE_CLOSE) && defined(HAVE_READ)
+ int urandom;
+ urandom = open("/dev/urandom", O_RDONLY);
+ if (urandom == -1)
+ return 1;
+
+ ok = read(urandom, data, sizeof(uint32_t)) == sizeof(uint32_t);
+ close(urandom);
+#else
+ FILE *urandom;
+
+ urandom = fopen("/dev/urandom", "rb");
+ if (!urandom)
+ return 1;
+
+ ok = fread(data, 1, sizeof(uint32_t), urandom) == sizeof(uint32_t);
+ fclose(urandom);
+#endif
+
+ if (!ok)
+ return 1;
+
+ *seed = buf_to_uint32(data);
+ return 0;
+}
+#endif
+
+/* Windows Crypto API */
+#if defined(_WIN32) && defined(USE_WINDOWS_CRYPTOAPI)
+#include <wincrypt.h>
+
+typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv, LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType, DWORD dwFlags);
+typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer);
+typedef BOOL (WINAPI *CRYPTRELEASECONTEXT)(HCRYPTPROV hProv, DWORD dwFlags);
+
+static int seed_from_windows_cryptoapi(uint32_t *seed)
+{
+ HINSTANCE hAdvAPI32 = NULL;
+ CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
+ CRYPTGENRANDOM pCryptGenRandom = NULL;
+ CRYPTRELEASECONTEXT pCryptReleaseContext = NULL;
+ HCRYPTPROV hCryptProv = 0;
+ BYTE data[sizeof(uint32_t)];
+ int ok;
+
+ hAdvAPI32 = GetModuleHandle(TEXT("advapi32.dll"));
+ if(hAdvAPI32 == NULL)
+ return 1;
+
+ pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(hAdvAPI32, "CryptAcquireContextA");
+ if (!pCryptAcquireContext)
+ return 1;
+
+ pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(hAdvAPI32, "CryptGenRandom");
+ if (!pCryptGenRandom)
+ return 1;
+
+ pCryptReleaseContext = (CRYPTRELEASECONTEXT)GetProcAddress(hAdvAPI32, "CryptReleaseContext");
+ if (!pCryptReleaseContext)
+ return 1;
+
+ if (!pCryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
+ return 1;
+
+ ok = pCryptGenRandom(hCryptProv, sizeof(uint32_t), data);
+ pCryptReleaseContext(hCryptProv, 0);
+
+ if (!ok)
+ return 1;
+
+ *seed = buf_to_uint32((char *)data);
+ return 0;
+}
+#endif
+
+/* gettimeofday() and getpid() */
+static int seed_from_timestamp_and_pid(uint32_t *seed) {
+#ifdef HAVE_GETTIMEOFDAY
+ /* XOR of seconds and microseconds */
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ *seed = (uint32_t)tv.tv_sec ^ (uint32_t)tv.tv_usec;
+#else
+ /* Seconds only */
+ *seed = (uint32_t)time(NULL);
+#endif
+
+ /* XOR with PID for more randomness */
+#if defined(_WIN32)
+ *seed ^= (uint32_t)GetCurrentProcessId();
+#elif defined(HAVE_GETPID)
+ *seed ^= (uint32_t)getpid();
+#endif
+
+ return 0;
+}
+
+static uint32_t generate_seed() {
+ uint32_t seed;
+ int done = 0;
+
+#if !defined(_WIN32) && defined(USE_URANDOM)
+ if (!done && seed_from_urandom(&seed) == 0)
+ done = 1;
+#endif
+
+#if defined(_WIN32) && defined(USE_WINDOWS_CRYPTOAPI)
+ if (!done && seed_from_windows_cryptoapi(&seed) == 0)
+ done = 1;
+#endif
+
+ if (!done) {
+ /* Fall back to timestamp and PID if no better randomness is
+ available */
+ seed_from_timestamp_and_pid(&seed);
+ }
+
+ /* Make sure the seed is never zero */
+ if (seed == 0)
+ seed = 1;
+
+ return seed;
+}
+
+
+volatile uint32_t hashtable_seed = 0;
+
+#if defined(HAVE_ATOMIC_BUILTINS) && (defined(HAVE_SCHED_YIELD) || !defined(_WIN32))
+static volatile char seed_initialized = 0;
+
+void json_object_seed(size_t seed) {
+ uint32_t new_seed = (uint32_t)seed;
+
+ if (hashtable_seed == 0) {
+ if (__atomic_test_and_set(&seed_initialized, __ATOMIC_RELAXED) == 0) {
+ /* Do the seeding ourselves */
+ if (new_seed == 0)
+ new_seed = generate_seed();
+
+ __atomic_store_n(&hashtable_seed, new_seed, __ATOMIC_RELEASE);
+ } else {
+ /* Wait for another thread to do the seeding */
+ do {
+#ifdef HAVE_SCHED_YIELD
+ sched_yield();
+#endif
+ } while(__atomic_load_n(&hashtable_seed, __ATOMIC_ACQUIRE) == 0);
+ }
+ }
+}
+#elif defined(HAVE_SYNC_BUILTINS) && (defined(HAVE_SCHED_YIELD) || !defined(_WIN32))
+void json_object_seed(size_t seed) {
+ uint32_t new_seed = (uint32_t)seed;
+
+ if (hashtable_seed == 0) {
+ if (new_seed == 0) {
+ /* Explicit synchronization fences are not supported by the
+ __sync builtins, so every thread getting here has to
+ generate the seed value.
+ */
+ new_seed = generate_seed();
+ }
+
+ do {
+ if (__sync_bool_compare_and_swap(&hashtable_seed, 0, new_seed)) {
+ /* We were the first to seed */
+ break;
+ } else {
+ /* Wait for another thread to do the seeding */
+#ifdef HAVE_SCHED_YIELD
+ sched_yield();
+#endif
+ }
+ } while(hashtable_seed == 0);
+ }
+}
+#elif defined(_WIN32)
+static long seed_initialized = 0;
+void json_object_seed(size_t seed) {
+ uint32_t new_seed = (uint32_t)seed;
+
+ if (hashtable_seed == 0) {
+ if (InterlockedIncrement(&seed_initialized) == 1) {
+ /* Do the seeding ourselves */
+ if (new_seed == 0)
+ new_seed = generate_seed();
+
+ hashtable_seed = new_seed;
+ } else {
+ /* Wait for another thread to do the seeding */
+ do {
+ SwitchToThread();
+ } while (hashtable_seed == 0);
+ }
+ }
+}
+#else
+/* Fall back to a thread-unsafe version */
+void json_object_seed(size_t seed) {
+ uint32_t new_seed = (uint32_t)seed;
+
+ if (hashtable_seed == 0) {
+ if (new_seed == 0)
+ new_seed = generate_seed();
+
+ hashtable_seed = new_seed;
+ }
+}
+#endif
diff --git a/src/jansson/jansson.h b/src/jansson/jansson.h
index 352c6ce..85215f4 100644
--- a/src/jansson/jansson.h
+++ b/src/jansson/jansson.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
+ * Copyright (c) 2009-2014 Petri Lehtinen <petri@digip.org>
*
* Jansson is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
@@ -21,11 +21,11 @@ extern "C" {
/* version */
#define JANSSON_MAJOR_VERSION 2
-#define JANSSON_MINOR_VERSION 4
+#define JANSSON_MINOR_VERSION 6
#define JANSSON_MICRO_VERSION 0
/* Micro version is omitted if it's 0 */
-#define JANSSON_VERSION "2.4"
+#define JANSSON_VERSION "2.6"
/* Version as a 3-byte hex number, e.g. 0x010201 == 1.2.1. Use this
for numeric comparisons, e.g. #if JANSSON_VERSION_HEX >= ... */
@@ -47,11 +47,12 @@ typedef enum {
JSON_NULL
} json_type;
-typedef struct {
+typedef struct json_t {
json_type type;
size_t refcount;
} json_t;
+#ifndef JANSSON_USING_CMAKE /* disabled if using cmake */
#if JSON_INTEGER_IS_LONG_LONG
#ifdef _WIN32
#define JSON_INTEGER_FORMAT "I64d"
@@ -63,25 +64,29 @@ typedef long long json_int_t;
#define JSON_INTEGER_FORMAT "ld"
typedef long json_int_t;
#endif /* JSON_INTEGER_IS_LONG_LONG */
+#endif
#define json_typeof(json) ((json)->type)
-#define json_is_object(json) (json && json_typeof(json) == JSON_OBJECT)
-#define json_is_array(json) (json && json_typeof(json) == JSON_ARRAY)
-#define json_is_string(json) (json && json_typeof(json) == JSON_STRING)
-#define json_is_integer(json) (json && json_typeof(json) == JSON_INTEGER)
-#define json_is_real(json) (json && json_typeof(json) == JSON_REAL)
+#define json_is_object(json) ((json) && json_typeof(json) == JSON_OBJECT)
+#define json_is_array(json) ((json) && json_typeof(json) == JSON_ARRAY)
+#define json_is_string(json) ((json) && json_typeof(json) == JSON_STRING)
+#define json_is_integer(json) ((json) && json_typeof(json) == JSON_INTEGER)
+#define json_is_real(json) ((json) && json_typeof(json) == JSON_REAL)
#define json_is_number(json) (json_is_integer(json) || json_is_real(json))
-#define json_is_true(json) (json && json_typeof(json) == JSON_TRUE)
-#define json_is_false(json) (json && json_typeof(json) == JSON_FALSE)
+#define json_is_true(json) ((json) && json_typeof(json) == JSON_TRUE)
+#define json_is_false(json) ((json) && json_typeof(json) == JSON_FALSE)
+#define json_boolean_value json_is_true
#define json_is_boolean(json) (json_is_true(json) || json_is_false(json))
-#define json_is_null(json) (json && json_typeof(json) == JSON_NULL)
+#define json_is_null(json) ((json) && json_typeof(json) == JSON_NULL)
/* construction, destruction, reference counting */
json_t *json_object(void);
json_t *json_array(void);
json_t *json_string(const char *value);
+json_t *json_stringn(const char *value, size_t len);
json_t *json_string_nocheck(const char *value);
+json_t *json_stringn_nocheck(const char *value, size_t len);
json_t *json_integer(json_int_t value);
json_t *json_real(double value);
json_t *json_true(void);
@@ -124,6 +129,7 @@ typedef struct {
/* getters, setters, manipulation */
+void json_object_seed(size_t seed);
size_t json_object_size(const json_t *object);
json_t *json_object_get(const json_t *object, const char *key);
int json_object_set_new(json_t *object, const char *key, json_t *value);
@@ -146,6 +152,11 @@ int json_object_iter_set_new(json_t *object, void *iter, json_t *value);
key && (value = json_object_iter_value(json_object_key_to_iter(key))); \
key = json_object_iter_key(json_object_iter_next(object, json_object_key_to_iter(key))))
+#define json_array_foreach(array, index, value) \
+ for(index = 0; \
+ index < json_array_size(array) && (value = json_array_get(array, index)); \
+ index++)
+
static JSON_INLINE
int json_object_set(json_t *object, const char *key, json_t *value)
{
@@ -174,9 +185,9 @@ int json_array_clear(json_t *array);
int json_array_extend(json_t *array, json_t *other);
static JSON_INLINE
-int json_array_set(json_t *array, size_t index, json_t *value)
+int json_array_set(json_t *array, size_t ind, json_t *value)
{
- return json_array_set_new(array, index, json_incref(value));
+ return json_array_set_new(array, ind, json_incref(value));
}
static JSON_INLINE
@@ -186,22 +197,24 @@ int json_array_append(json_t *array, json_t *value)
}
static JSON_INLINE
-int json_array_insert(json_t *array, size_t index, json_t *value)
+int json_array_insert(json_t *array, size_t ind, json_t *value)
{
- return json_array_insert_new(array, index, json_incref(value));
+ return json_array_insert_new(array, ind, json_incref(value));
}
const char *json_string_value(const json_t *string);
+size_t json_string_length(const json_t *string);
json_int_t json_integer_value(const json_t *integer);
double json_real_value(const json_t *real);
double json_number_value(const json_t *json);
int json_string_set(json_t *string, const char *value);
+int json_string_setn(json_t *string, const char *value, size_t len);
int json_string_set_nocheck(json_t *string, const char *value);
+int json_string_setn_nocheck(json_t *string, const char *value, size_t len);
int json_integer_set(json_t *integer, json_int_t value);
int json_real_set(json_t *real, double value);
-
/* pack, unpack */
json_t *json_pack(const char *fmt, ...);
@@ -224,14 +237,16 @@ int json_equal(json_t *value1, json_t *value2);
/* copying */
json_t *json_copy(json_t *value);
-json_t *json_deep_copy(json_t *value);
+json_t *json_deep_copy(const json_t *value);
/* decoding */
-#define JSON_REJECT_DUPLICATES 0x1
-#define JSON_DISABLE_EOF_CHECK 0x2
-#define JSON_DECODE_ANY 0x4
+#define JSON_REJECT_DUPLICATES 0x1
+#define JSON_DISABLE_EOF_CHECK 0x2
+#define JSON_DECODE_ANY 0x4
+#define JSON_DECODE_INT_AS_REAL 0x8
+#define JSON_ALLOW_NUL 0x10
typedef size_t (*json_load_callback_t)(void *buffer, size_t buflen, void *data);
diff --git a/src/jansson/jansson_config.h b/src/jansson/jansson_config.h
index e576cd1..31ad6b3 100644
--- a/src/jansson/jansson_config.h
+++ b/src/jansson/jansson_config.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2012 Petri Lehtinen <petri@digip.org>
+ * Copyright (c) 2010-2014 Petri Lehtinen <petri@digip.org>
*
* Jansson is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
@@ -9,15 +9,38 @@
* Jansson, namely those things that affect the public API in
* jansson.h.
*
- * The configure script copies this file to jansson_config.h and
- * replaces @var@ substitutions by values that fit your system. If you
- * cannot run the configure script, you can do the value substitution
- * by hand.
+ * The CMake system will generate the jansson_config.h file and
+ * copy it to the build and install directories.
*/
#ifndef JANSSON_CONFIG_H
#define JANSSON_CONFIG_H
+/* Define this so that we can disable scattered automake configuration in source files */
+#ifndef JANSSON_USING_CMAKE
+#define JANSSON_USING_CMAKE
+#endif
+
+/* Note: when using cmake, JSON_INTEGER_IS_LONG_LONG is not defined nor used,
+ * as we will also check for __int64 etc types.
+ * (the definition was used in the automake system) */
+
+/* Bring in the cmake-detected defines */
+#define HAVE_STDINT_H 1
+/* #undef HAVE_INTTYPES_H */
+#define HAVE_SYS_TYPES_H 1
+
+/* Include our standard type header for the integer typedef */
+
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#elif defined(HAVE_SYS_TYPES_H)
+# include <sys/types.h>
+#endif
+
+
/* If your compiler supports the inline keyword in C, JSON_INLINE is
defined to `inline', otherwise empty. In C++, the inline is always
supported. */
@@ -27,13 +50,15 @@
#define JSON_INLINE inline
#endif
-/* If your compiler supports the `long long` type and the strtoll()
- library function, JSON_INTEGER_IS_LONG_LONG is defined to 1,
- otherwise to 0. */
-#define JSON_INTEGER_IS_LONG_LONG 1
-/* If locale.h and localeconv() are available, define to 1,
- otherwise to 0. */
+#define json_int_t long long
+#define json_strtoint strtoll
+#define JSON_INTEGER_FORMAT "lld"
+
+
+/* If locale.h and localeconv() are available, define to 1, otherwise to 0. */
#define JSON_HAVE_LOCALECONV 1
+
+
#endif
diff --git a/src/jansson/jansson_private.h b/src/jansson/jansson_private.h
index 7d6d09d..c6f437c 100644
--- a/src/jansson/jansson_private.h
+++ b/src/jansson/jansson_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
+ * Copyright (c) 2009-2014 Petri Lehtinen <petri@digip.org>
*
* Jansson is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
@@ -49,6 +49,7 @@ typedef struct {
typedef struct {
json_t json;
char *value;
+ size_t length;
} json_string_t;
typedef struct {
@@ -64,9 +65,13 @@ typedef struct {
#define json_to_object(json_) container_of(json_, json_object_t, json)
#define json_to_array(json_) container_of(json_, json_array_t, json)
#define json_to_string(json_) container_of(json_, json_string_t, json)
-#define json_to_real(json_) container_of(json_, json_real_t, json)
+#define json_to_real(json_) container_of(json_, json_real_t, json)
#define json_to_integer(json_) container_of(json_, json_integer_t, json)
+/* Create a string by taking ownership of an existing buffer */
+json_t *jsonp_stringn_nocheck_own(const char *value, size_t len);
+
+/* Error message formatting */
void jsonp_error_init(json_error_t *error, const char *source);
void jsonp_error_set_source(json_error_t *error, const char *source);
void jsonp_error_set(json_error_t *error, int line, int column,
@@ -81,7 +86,9 @@ int jsonp_dtostr(char *buffer, size_t size, double value);
/* Wrappers for custom memory functions */
void* jsonp_malloc(size_t size);
void jsonp_free(void *ptr);
+char *jsonp_strndup(const char *str, size_t length);
char *jsonp_strdup(const char *str);
+char *jsonp_strndup(const char *str, size_t len);
/* Windows compatibility */
#ifdef _WIN32
diff --git a/src/jansson/jansson_private_config.h b/src/jansson/jansson_private_config.h
new file mode 100644
index 0000000..cbff15e
--- /dev/null
+++ b/src/jansson/jansson_private_config.h
@@ -0,0 +1,57 @@
+#if defined(NV_LINUX)
+# define HAVE_ENDIAN_H 1
+#endif
+
+/* Prevent value.c from overriding Solaris's builtin isnan() */
+#if defined(NV_SUNOS)
+# define isnan isnan
+#endif
+
+#define HAVE_FCNTL_H 1
+#define HAVE_SCHED_H 1
+#define HAVE_UNISTD_H 1
+#define HAVE_SYS_PARAM_H 1
+#define HAVE_SYS_STAT_H 1
+#define HAVE_SYS_TIME_H 1
+#define HAVE_SYS_TYPES_H 1
+#define HAVE_STDINT_H 1
+
+#define HAVE_CLOSE 1
+#define HAVE_GETPID 1
+#define HAVE_GETTIMEOFDAY 1
+#define HAVE_OPEN 1
+#define HAVE_READ 1
+#define HAVE_SCHED_YIELD 1
+
+/* #undef HAVE_SYNC_BUILTINS */
+/* #undef HAVE_ATOMIC_BUILTINS */
+
+#define HAVE_LOCALE_H 1
+#define HAVE_SETLOCALE 1
+
+#define HAVE_INT32_T 1
+#ifndef HAVE_INT32_T
+# define int32_t int32_t
+#endif
+
+#define HAVE_UINT32_T 1
+#ifndef HAVE_UINT32_T
+# define uint32_t uint32_t
+#endif
+
+#define HAVE_SSIZE_T 1
+
+#ifndef HAVE_SSIZE_T
+# define ssize_t
+#endif
+
+#define HAVE_SNPRINTF 1
+
+#ifndef HAVE_SNPRINTF
+# define snprintf snprintf
+#endif
+
+/* #undef HAVE_VSNPRINTF */
+
+#define USE_URANDOM 1
+#define USE_WINDOWS_CRYPTOAPI 1
diff --git a/src/jansson/load.c b/src/jansson/load.c
index d88a704..56c8ee3 100644
--- a/src/jansson/load.c
+++ b/src/jansson/load.c
@@ -1,11 +1,14 @@
/*
- * Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
+ * Copyright (c) 2009-2014 Petri Lehtinen <petri@digip.org>
*
* Jansson is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
+#ifndef _GNU_SOURCE
#define _GNU_SOURCE
+#endif
+
#include <errno.h>
#include <limits.h>
#include <stdio.h>
@@ -37,7 +40,7 @@
#define l_isalpha(c) (l_isupper(c) || l_islower(c))
#define l_isdigit(c) ('0' <= (c) && (c) <= '9')
#define l_isxdigit(c) \
- (l_isdigit(c) || 'A' <= (c) || (c) <= 'F' || 'a' <= (c) || (c) <= 'f')
+ (l_isdigit(c) || ('A' <= (c) && (c) <= 'F') || ('a' <= (c) && (c) <= 'f'))
/* Read one byte from stream, convert to unsigned char, then int, and
return. return EOF on end of file. This corresponds to the
@@ -60,7 +63,10 @@ typedef struct {
strbuffer_t saved_text;
int token;
union {
- char *string;
+ struct {
+ char *val;
+ size_t len;
+ } string;
json_int_t integer;
double real;
} value;
@@ -250,9 +256,18 @@ static void lex_unget(lex_t *lex, int c)
static void lex_unget_unsave(lex_t *lex, int c)
{
if(c != STREAM_STATE_EOF && c != STREAM_STATE_ERROR) {
+ /* Since we treat warnings as errors, when assertions are turned
+ * off the "d" variable would be set but never used. Which is
+ * treated as an error by GCC.
+ */
+ #ifndef NDEBUG
char d;
+ #endif
stream_unget(&lex->stream, c);
- d = strbuffer_pop(&lex->saved_text);
+ #ifndef NDEBUG
+ d =
+ #endif
+ strbuffer_pop(&lex->saved_text);
assert(c == d);
}
}
@@ -267,6 +282,13 @@ static void lex_save_cached(lex_t *lex)
}
}
+static void lex_free_string(lex_t *lex)
+{
+ jsonp_free(lex->value.string.val);
+ lex->value.string.val = NULL;
+ lex->value.string.len = 0;
+}
+
/* assumes that str points to 'u' plus at least 4 valid hex digits */
static int32_t decode_unicode_escape(const char *str)
{
@@ -285,7 +307,7 @@ static int32_t decode_unicode_escape(const char *str)
else if(l_isupper(c))
value += c - 'A' + 10;
else
- assert(0);
+ return -1;
}
return value;
@@ -298,7 +320,7 @@ static void lex_scan_string(lex_t *lex, json_error_t *error)
char *t;
int i;
- lex->value.string = NULL;
+ lex->value.string.val = NULL;
lex->token = TOKEN_INVALID;
c = lex_get_save(lex, error);
@@ -353,14 +375,12 @@ static void lex_scan_string(lex_t *lex, json_error_t *error)
- two \uXXXX escapes (length 12) forming an UTF-16 surrogate pair
are converted to 4 bytes
*/
- lex->value.string = jsonp_malloc(lex->saved_text.length + 1);
- if(!lex->value.string) {
+ t = jsonp_malloc(lex->saved_text.length + 1);
+ if(!t) {
/* this is not very nice, since TOKEN_INVALID is returned */
goto out;
}
-
- /* the target */
- t = lex->value.string;
+ lex->value.string.val = t;
/* + 1 to skip the " */
p = strbuffer_value(&lex->saved_text) + 1;
@@ -369,17 +389,24 @@ static void lex_scan_string(lex_t *lex, json_error_t *error)
if(*p == '\\') {
p++;
if(*p == 'u') {
- char buffer[4];
- int length;
+ size_t length;
int32_t value;
value = decode_unicode_escape(p);
+ if(value < 0) {
+ error_set(error, lex, "invalid Unicode escape '%.6s'", p - 1);
+ goto out;
+ }
p += 5;
if(0xD800 <= value && value <= 0xDBFF) {
/* surrogate pair */
if(*p == '\\' && *(p + 1) == 'u') {
int32_t value2 = decode_unicode_escape(++p);
+ if(value2 < 0) {
+ error_set(error, lex, "invalid Unicode escape '%.6s'", p - 1);
+ goto out;
+ }
p += 5;
if(0xDC00 <= value2 && value2 <= 0xDFFF) {
@@ -408,16 +435,9 @@ static void lex_scan_string(lex_t *lex, json_error_t *error)
error_set(error, lex, "invalid Unicode '\\u%04X'", value);
goto out;
}
- else if(value == 0)
- {
- error_set(error, lex, "\\u0000 is not allowed");
- goto out;
- }
- if(utf8_encode(value, buffer, &length))
+ if(utf8_encode(value, t, &length))
assert(0);
-
- memcpy(t, buffer, length);
t += length;
}
else {
@@ -439,15 +459,17 @@ static void lex_scan_string(lex_t *lex, json_error_t *error)
*(t++) = *(p++);
}
*t = '\0';
+ lex->value.string.len = t - lex->value.string.val;
lex->token = TOKEN_STRING;
return;
out:
- jsonp_free(lex->value.string);
+ lex_free_string(lex);
}
+#ifndef JANSSON_USING_CMAKE /* disabled if using cmake */
#if JSON_INTEGER_IS_LONG_LONG
-#ifdef _MSC_VER // Microsoft Visual Studio
+#ifdef _MSC_VER /* Microsoft Visual Studio */
#define json_strtoint _strtoi64
#else
#define json_strtoint strtoll
@@ -455,6 +477,7 @@ out:
#else
#define json_strtoint strtol
#endif
+#endif
static int lex_scan_number(lex_t *lex, int c, json_error_t *error)
{
@@ -557,10 +580,8 @@ static int lex_scan(lex_t *lex, json_error_t *error)
strbuffer_clear(&lex->saved_text);
- if(lex->token == TOKEN_STRING) {
- jsonp_free(lex->value.string);
- lex->value.string = NULL;
- }
+ if(lex->token == TOKEN_STRING)
+ lex_free_string(lex);
c = lex_get(lex, error);
while(c == ' ' || c == '\t' || c == '\n' || c == '\r')
@@ -621,13 +642,14 @@ out:
return lex->token;
}
-static char *lex_steal_string(lex_t *lex)
+static char *lex_steal_string(lex_t *lex, size_t *out_len)
{
char *result = NULL;
- if(lex->token == TOKEN_STRING)
- {
- result = lex->value.string;
- lex->value.string = NULL;
+ if(lex->token == TOKEN_STRING) {
+ result = lex->value.string.val;
+ *out_len = lex->value.string.len;
+ lex->value.string.val = NULL;
+ lex->value.string.len = 0;
}
return result;
}
@@ -645,7 +667,7 @@ static int lex_init(lex_t *lex, get_func get, void *data)
static void lex_close(lex_t *lex)
{
if(lex->token == TOKEN_STRING)
- jsonp_free(lex->value.string);
+ lex_free_string(lex);
strbuffer_close(&lex->saved_text);
}
@@ -666,6 +688,7 @@ static json_t *parse_object(lex_t *lex, size_t flags, json_error_t *error)
while(1) {
char *key;
+ size_t len;
json_t *value;
if(lex->token != TOKEN_STRING) {
@@ -673,9 +696,14 @@ static json_t *parse_object(lex_t *lex, size_t flags, json_error_t *error)
goto error;
}
- key = lex_steal_string(lex);
+ key = lex_steal_string(lex, &len);
if(!key)
return NULL;
+ if (memchr(key, '\0', len)) {
+ jsonp_free(key);
+ error_set(error, lex, "NUL byte in object key not supported");
+ goto error;
+ }
if(flags & JSON_REJECT_DUPLICATES) {
if(json_object_get(object, key)) {
@@ -770,15 +798,38 @@ error:
static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error)
{
json_t *json;
+ double value;
switch(lex->token) {
case TOKEN_STRING: {
- json = json_string_nocheck(lex->value.string);
+ const char *value = lex->value.string.val;
+ size_t len = lex->value.string.len;
+
+ if(!(flags & JSON_ALLOW_NUL)) {
+ if(memchr(value, '\0', len)) {
+ error_set(error, lex, "\\u0000 is not allowed without JSON_ALLOW_NUL");
+ return NULL;
+ }
+ }
+
+ json = jsonp_stringn_nocheck_own(value, len);
+ if(json) {
+ lex->value.string.val = NULL;
+ lex->value.string.len = 0;
+ }
break;
}
case TOKEN_INTEGER: {
- json = json_integer(lex->value.integer);
+ if (flags & JSON_DECODE_INT_AS_REAL) {
+ if(jsonp_strtod(&lex->saved_text, &value)) {
+ error_set(error, lex, "real number overflow");
+ return NULL;
+ }
+ json = json_real(value);
+ } else {
+ json = json_integer(lex->value.integer);
+ }
break;
}
diff --git a/src/jansson/lookup3.h b/src/jansson/lookup3.h
new file mode 100644
index 0000000..8847483
--- /dev/null
+++ b/src/jansson/lookup3.h
@@ -0,0 +1,366 @@
+/*
+-------------------------------------------------------------------------------
+lookup3.c, by Bob Jenkins, May 2006, Public Domain.
+
+These are functions for producing 32-bit hashes for hash table lookup.
+hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final()
+are externally useful functions. Routines to test the hash are included
+if SELF_TEST is defined. You can use this free for any purpose. It's in
+the public domain. It has no warranty.
+
+You probably want to use hashlittle(). hashlittle() and hashbig()
+hash byte arrays. hashlittle() is is faster than hashbig() on
+little-endian machines. Intel and AMD are little-endian machines.
+On second thought, you probably want hashlittle2(), which is identical to
+hashlittle() except it returns two 32-bit hashes for the price of one.
+You could implement hashbig2() if you wanted but I haven't bothered here.
+
+If you want to find a hash of, say, exactly 7 integers, do
+ a = i1; b = i2; c = i3;
+ mix(a,b,c);
+ a += i4; b += i5; c += i6;
+ mix(a,b,c);
+ a += i7;
+ final(a,b,c);
+then use c as the hash value. If you have a variable length array of
+4-byte integers to hash, use hashword(). If you have a byte array (like
+a character string), use hashlittle(). If you have several byte arrays, or
+a mix of things, see the comments above hashlittle().
+
+Why is this so big? I read 12 bytes at a time into 3 4-byte integers,
+then mix those integers. This is fast (you can do a lot more thorough
+mixing with 12*3 instructions on 3 integers than you can with 3 instructions
+on 1 byte), but shoehorning those bytes into integers efficiently is messy.
+-------------------------------------------------------------------------------
+*/
+
+#include <stdlib.h>
+
+#ifdef HAVE_CONFIG_H
+#include <jansson_private_config.h>
+#endif
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h> /* defines uint32_t etc */
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h> /* attempt to define endianness */
+#endif
+
+#ifdef HAVE_ENDIAN_H
+# include <endian.h> /* attempt to define endianness */
+#endif
+
+/*
+ * My best guess at if you are big-endian or little-endian. This may
+ * need adjustment.
+ */
+#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \
+ __BYTE_ORDER == __LITTLE_ENDIAN) || \
+ (defined(i386) || defined(__i386__) || defined(__i486__) || \
+ defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL))
+# define HASH_LITTLE_ENDIAN 1
+# define HASH_BIG_ENDIAN 0
+#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \
+ __BYTE_ORDER == __BIG_ENDIAN) || \
+ (defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel))
+# define HASH_LITTLE_ENDIAN 0
+# define HASH_BIG_ENDIAN 1
+#else
+# define HASH_LITTLE_ENDIAN 0
+# define HASH_BIG_ENDIAN 0
+#endif
+
+#define hashsize(n) ((uint32_t)1<<(n))
+#define hashmask(n) (hashsize(n)-1)
+#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
+
+/*
+-------------------------------------------------------------------------------
+mix -- mix 3 32-bit values reversibly.
+
+This is reversible, so any information in (a,b,c) before mix() is
+still in (a,b,c) after mix().
+
+If four pairs of (a,b,c) inputs are run through mix(), or through
+mix() in reverse, there are at least 32 bits of the output that
+are sometimes the same for one pair and different for another pair.
+This was tested for:
+* pairs that differed by one bit, by two bits, in any combination
+ of top bits of (a,b,c), or in any combination of bottom bits of
+ (a,b,c).
+* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed
+ the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
+ is commonly produced by subtraction) look like a single 1-bit
+ difference.
+* the base values were pseudorandom, all zero but one bit set, or
+ all zero plus a counter that starts at zero.
+
+Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that
+satisfy this are
+ 4 6 8 16 19 4
+ 9 15 3 18 27 15
+ 14 9 3 7 17 3
+Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing
+for "differ" defined as + with a one-bit base and a two-bit delta. I
+used http://burtleburtle.net/bob/hash/avalanche.html to choose
+the operations, constants, and arrangements of the variables.
+
+This does not achieve avalanche. There are input bits of (a,b,c)
+that fail to affect some output bits of (a,b,c), especially of a. The
+most thoroughly mixed value is c, but it doesn't really even achieve
+avalanche in c.
+
+This allows some parallelism. Read-after-writes are good at doubling
+the number of bits affected, so the goal of mixing pulls in the opposite
+direction as the goal of parallelism. I did what I could. Rotates
+seem to cost as much as shifts on every machine I could lay my hands
+on, and rotates are much kinder to the top and bottom bits, so I used
+rotates.
+-------------------------------------------------------------------------------
+*/
+#define mix(a,b,c) \
+{ \
+ a -= c; a ^= rot(c, 4); c += b; \
+ b -= a; b ^= rot(a, 6); a += c; \
+ c -= b; c ^= rot(b, 8); b += a; \
+ a -= c; a ^= rot(c,16); c += b; \
+ b -= a; b ^= rot(a,19); a += c; \
+ c -= b; c ^= rot(b, 4); b += a; \
+}
+
+/*
+-------------------------------------------------------------------------------
+final -- final mixing of 3 32-bit values (a,b,c) into c
+
+Pairs of (a,b,c) values differing in only a few bits will usually
+produce values of c that look totally different. This was tested for
+* pairs that differed by one bit, by two bits, in any combination
+ of top bits of (a,b,c), or in any combination of bottom bits of
+ (a,b,c).
+* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed
+ the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
+ is commonly produced by subtraction) look like a single 1-bit
+ difference.
+* the base values were pseudorandom, all zero but one bit set, or
+ all zero plus a counter that starts at zero.
+
+These constants passed:
+ 14 11 25 16 4 14 24
+ 12 14 25 16 4 14 24
+and these came close:
+ 4 8 15 26 3 22 24
+ 10 8 15 26 3 22 24
+ 11 8 15 26 3 22 24
+-------------------------------------------------------------------------------
+*/
+#define final(a,b,c) \
+{ \
+ c ^= b; c -= rot(b,14); \
+ a ^= c; a -= rot(c,11); \
+ b ^= a; b -= rot(a,25); \
+ c ^= b; c -= rot(b,16); \
+ a ^= c; a -= rot(c,4); \
+ b ^= a; b -= rot(a,14); \
+ c ^= b; c -= rot(b,24); \
+}
+
+/*
+-------------------------------------------------------------------------------
+hashlittle() -- hash a variable-length key into a 32-bit value
+ k : the key (the unaligned variable-length array of bytes)
+ length : the length of the key, counting by bytes
+ initval : can be any 4-byte value
+Returns a 32-bit value. Every bit of the key affects every bit of
+the return value. Two keys differing by one or two bits will have
+totally different hash values.
+
+The best hash table sizes are powers of 2. There is no need to do
+mod a prime (mod is sooo slow!). If you need less than 32 bits,
+use a bitmask. For example, if you need only 10 bits, do
+ h = (h & hashmask(10));
+In which case, the hash table should have hashsize(10) elements.
+
+If you are hashing n strings (uint8_t **)k, do it like this:
+ for (i=0, h=0; i<n; ++i) h = hashlittle( k[i], len[i], h);
+
+By Bob Jenkins, 2006. bob_jenkins@burtleburtle.net. You may use this
+code any way you wish, private, educational, or commercial. It's free.
+
+Use for hash table lookup, or anything where one collision in 2^^32 is
+acceptable. Do NOT use for cryptographic purposes.
+-------------------------------------------------------------------------------
+*/
+
+static uint32_t hashlittle(const void *key, size_t length, uint32_t initval)
+{
+ uint32_t a,b,c; /* internal state */
+ union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */
+
+ /* Set up the internal state */
+ a = b = c = 0xdeadbeef + ((uint32_t)length) + initval;
+
+ u.ptr = key;
+ if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
+ const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */
+
+#ifdef VALGRIND
+ const uint8_t *k8;
+#endif
+
+ /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
+ while (length > 12)
+ {
+ a += k[0];
+ b += k[1];
+ c += k[2];
+ mix(a,b,c);
+ length -= 12;
+ k += 3;
+ }
+
+ /*----------------------------- handle the last (probably partial) block */
+ /*
+ * "k[2]&0xffffff" actually reads beyond the end of the string, but
+ * then masks off the part it's not allowed to read. Because the
+ * string is aligned, the masked-off tail is in the same word as the
+ * rest of the string. Every machine with memory protection I've seen
+ * does it on word boundaries, so is OK with this. But VALGRIND will
+ * still catch it and complain. The masking trick does make the hash
+ * noticably faster for short strings (like English words).
+ */
+#ifndef VALGRIND
+
+ switch(length)
+ {
+ case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
+ case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
+ case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break;
+ case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break;
+ case 8 : b+=k[1]; a+=k[0]; break;
+ case 7 : b+=k[1]&0xffffff; a+=k[0]; break;
+ case 6 : b+=k[1]&0xffff; a+=k[0]; break;
+ case 5 : b+=k[1]&0xff; a+=k[0]; break;
+ case 4 : a+=k[0]; break;
+ case 3 : a+=k[0]&0xffffff; break;
+ case 2 : a+=k[0]&0xffff; break;
+ case 1 : a+=k[0]&0xff; break;
+ case 0 : return c; /* zero length strings require no mixing */
+ }
+
+#else /* make valgrind happy */
+
+ k8 = (const uint8_t *)k;
+ switch(length)
+ {
+ case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
+ case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
+ case 10: c+=((uint32_t)k8[9])<<8; /* fall through */
+ case 9 : c+=k8[8]; /* fall through */
+ case 8 : b+=k[1]; a+=k[0]; break;
+ case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
+ case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */
+ case 5 : b+=k8[4]; /* fall through */
+ case 4 : a+=k[0]; break;
+ case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
+ case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */
+ case 1 : a+=k8[0]; break;
+ case 0 : return c;
+ }
+
+#endif /* !valgrind */
+
+ } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
+ const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */
+ const uint8_t *k8;
+
+ /*--------------- all but last block: aligned reads and different mixing */
+ while (length > 12)
+ {
+ a += k[0] + (((uint32_t)k[1])<<16);
+ b += k[2] + (((uint32_t)k[3])<<16);
+ c += k[4] + (((uint32_t)k[5])<<16);
+ mix(a,b,c);
+ length -= 12;
+ k += 6;
+ }
+
+ /*----------------------------- handle the last (probably partial) block */
+ k8 = (const uint8_t *)k;
+ switch(length)
+ {
+ case 12: c+=k[4]+(((uint32_t)k[5])<<16);
+ b+=k[2]+(((uint32_t)k[3])<<16);
+ a+=k[0]+(((uint32_t)k[1])<<16);
+ break;
+ case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
+ case 10: c+=k[4];
+ b+=k[2]+(((uint32_t)k[3])<<16);
+ a+=k[0]+(((uint32_t)k[1])<<16);
+ break;
+ case 9 : c+=k8[8]; /* fall through */
+ case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
+ a+=k[0]+(((uint32_t)k[1])<<16);
+ break;
+ case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
+ case 6 : b+=k[2];
+ a+=k[0]+(((uint32_t)k[1])<<16);
+ break;
+ case 5 : b+=k8[4]; /* fall through */
+ case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
+ break;
+ case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
+ case 2 : a+=k[0];
+ break;
+ case 1 : a+=k8[0];
+ break;
+ case 0 : return c; /* zero length requires no mixing */
+ }
+
+ } else { /* need to read the key one byte at a time */
+ const uint8_t *k = (const uint8_t *)key;
+
+ /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
+ while (length > 12)
+ {
+ a += k[0];
+ a += ((uint32_t)k[1])<<8;
+ a += ((uint32_t)k[2])<<16;
+ a += ((uint32_t)k[3])<<24;
+ b += k[4];
+ b += ((uint32_t)k[5])<<8;
+ b += ((uint32_t)k[6])<<16;
+ b += ((uint32_t)k[7])<<24;
+ c += k[8];
+ c += ((uint32_t)k[9])<<8;
+ c += ((uint32_t)k[10])<<16;
+ c += ((uint32_t)k[11])<<24;
+ mix(a,b,c);
+ length -= 12;
+ k += 12;
+ }
+
+ /*-------------------------------- last block: affect all 32 bits of (c) */
+ switch(length) /* all the case statements fall through */
+ {
+ case 12: c+=((uint32_t)k[11])<<24;
+ case 11: c+=((uint32_t)k[10])<<16;
+ case 10: c+=((uint32_t)k[9])<<8;
+ case 9 : c+=k[8];
+ case 8 : b+=((uint32_t)k[7])<<24;
+ case 7 : b+=((uint32_t)k[6])<<16;
+ case 6 : b+=((uint32_t)k[5])<<8;
+ case 5 : b+=k[4];
+ case 4 : a+=((uint32_t)k[3])<<24;
+ case 3 : a+=((uint32_t)k[2])<<16;
+ case 2 : a+=((uint32_t)k[1])<<8;
+ case 1 : a+=k[0];
+ break;
+ case 0 : return c;
+ }
+ }
+
+ final(a,b,c);
+ return c;
+}
diff --git a/src/jansson/memory.c b/src/jansson/memory.c
index 543ecc4..ca44d6b 100644
--- a/src/jansson/memory.c
+++ b/src/jansson/memory.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
+ * Copyright (c) 2009-2014 Petri Lehtinen <petri@digip.org>
* Copyright (c) 2011-2012 Basile Starynkevitch <basile@starynkevitch.net>
*
* Jansson is free software; you can redistribute it and/or modify it
@@ -12,6 +12,10 @@
#include "jansson.h"
#include "jansson_private.h"
+/* C89 allows these to be macros */
+#undef malloc
+#undef free
+
/* memory function pointers */
static json_malloc_t do_malloc = malloc;
static json_free_t do_free = free;
@@ -34,13 +38,19 @@ void jsonp_free(void *ptr)
char *jsonp_strdup(const char *str)
{
+ return jsonp_strndup(str, strlen(str));
+}
+
+char *jsonp_strndup(const char *str, size_t len)
+{
char *new_str;
- new_str = jsonp_malloc(strlen(str) + 1);
+ new_str = jsonp_malloc(len + 1);
if(!new_str)
return NULL;
- strcpy(new_str, str);
+ memcpy(new_str, str, len);
+ new_str[len] = '\0';
return new_str;
}
diff --git a/src/jansson/pack_unpack.c b/src/jansson/pack_unpack.c
index 39db9b8..af381a5 100644
--- a/src/jansson/pack_unpack.c
+++ b/src/jansson/pack_unpack.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
+ * Copyright (c) 2009-2014 Petri Lehtinen <petri@digip.org>
* Copyright (c) 2011-2012 Graeme Smecher <graeme.smecher@mail.mcgill.ca>
*
* Jansson is free software; you can redistribute it and/or modify
@@ -12,16 +12,28 @@
#include "utf.h"
typedef struct {
+ int line;
+ int column;
+ size_t pos;
+ char token;
+} token_t;
+
+typedef struct {
const char *start;
const char *fmt;
- char token;
+ token_t prev_token;
+ token_t token;
+ token_t next_token;
json_error_t *error;
size_t flags;
int line;
int column;
+ size_t pos;
} scanner_t;
-static const char *type_names[] = {
+#define token(scanner) ((scanner)->token.token)
+
+static const char * const type_names[] = {
"object",
"array",
"string",
@@ -34,7 +46,7 @@ static const char *type_names[] = {
#define type_name(x) type_names[json_typeof(x)]
-static const char *unpack_value_starters = "{[siIbfFOon";
+static const char unpack_value_starters[] = "{[siIbfFOon";
static void scanner_init(scanner_t *s, json_error_t *error,
@@ -43,14 +55,28 @@ static void scanner_init(scanner_t *s, json_error_t *error,
s->error = error;
s->flags = flags;
s->fmt = s->start = fmt;
+ memset(&s->prev_token, 0, sizeof(token_t));
+ memset(&s->token, 0, sizeof(token_t));
+ memset(&s->next_token, 0, sizeof(token_t));
s->line = 1;
s->column = 0;
+ s->pos = 0;
}
static void next_token(scanner_t *s)
{
- const char *t = s->fmt;
+ const char *t;
+ s->prev_token = s->token;
+
+ if(s->next_token.line) {
+ s->token = s->next_token;
+ s->next_token.line = 0;
+ return;
+ }
+
+ t = s->fmt;
s->column++;
+ s->pos++;
/* skip space and ignored chars */
while(*t == ' ' || *t == '\t' || *t == '\n' || *t == ',' || *t == ':') {
@@ -61,23 +87,32 @@ static void next_token(scanner_t *s)
else
s->column++;
+ s->pos++;
t++;
}
- s->token = *t;
+ s->token.token = *t;
+ s->token.line = s->line;
+ s->token.column = s->column;
+ s->token.pos = s->pos;
t++;
s->fmt = t;
}
+static void prev_token(scanner_t *s)
+{
+ s->next_token = s->token;
+ s->token = s->prev_token;
+}
+
static void set_error(scanner_t *s, const char *source, const char *fmt, ...)
{
va_list ap;
- size_t pos;
va_start(ap, fmt);
- pos = (size_t)(s->fmt - s->start);
- jsonp_error_vset(s->error, s->line, s->column, pos, fmt, ap);
+ jsonp_error_vset(s->error, s->token.line, s->token.column, s->token.pos,
+ fmt, ap);
jsonp_error_set_source(s->error, source);
@@ -86,47 +121,135 @@ static void set_error(scanner_t *s, const char *source, const char *fmt, ...)
static json_t *pack(scanner_t *s, va_list *ap);
+
+/* ours will be set to 1 if jsonp_free() must be called for the result
+ afterwards */
+static char *read_string(scanner_t *s, va_list *ap,
+ const char *purpose, size_t *out_len, int *ours)
+{
+ char t;
+ strbuffer_t strbuff;
+ const char *str;
+ size_t length;
+
+ next_token(s);
+ t = token(s);
+ prev_token(s);
+
+ if(t != '#' && t != '%' && t != '+') {
+ /* Optimize the simple case */
+ str = va_arg(*ap, const char *);
+
+ if(!str) {
+ set_error(s, "<args>", "NULL string argument");
+ return NULL;
+ }
+
+ length = strlen(str);
+
+ if(!utf8_check_string(str, length)) {
+ set_error(s, "<args>", "Invalid UTF-8 %s", purpose);
+ return NULL;
+ }
+
+ *out_len = length;
+ *ours = 0;
+ return (char *)str;
+ }
+
+ strbuffer_init(&strbuff);
+
+ while(1) {
+ str = va_arg(*ap, const char *);
+ if(!str) {
+ set_error(s, "<args>", "NULL string argument");
+ strbuffer_close(&strbuff);
+ return NULL;
+ }
+
+ next_token(s);
+
+ if(token(s) == '#') {
+ length = va_arg(*ap, int);
+ }
+ else if(token(s) == '%') {
+ length = va_arg(*ap, size_t);
+ }
+ else {
+ prev_token(s);
+ length = strlen(str);
+ }
+
+ if(strbuffer_append_bytes(&strbuff, str, length) == -1) {
+ set_error(s, "<internal>", "Out of memory");
+ strbuffer_close(&strbuff);
+ return NULL;
+ }
+
+ next_token(s);
+ if(token(s) != '+') {
+ prev_token(s);
+ break;
+ }
+ }
+
+ if(!utf8_check_string(strbuff.value, strbuff.length)) {
+ set_error(s, "<args>", "Invalid UTF-8 %s", purpose);
+ strbuffer_close(&strbuff);
+ return NULL;
+ }
+
+ *out_len = strbuff.length;
+ *ours = 1;
+ return strbuffer_steal_value(&strbuff);
+}
+
static json_t *pack_object(scanner_t *s, va_list *ap)
{
json_t *object = json_object();
next_token(s);
- while(s->token != '}') {
- const char *key;
+ while(token(s) != '}') {
+ char *key;
+ size_t len;
+ int ours;
json_t *value;
- if(!s->token) {
+ if(!token(s)) {
set_error(s, "<format>", "Unexpected end of format string");
goto error;
}
- if(s->token != 's') {
- set_error(s, "<format>", "Expected format 's', got '%c'", s->token);
- goto error;
- }
-
- key = va_arg(*ap, const char *);
- if(!key) {
- set_error(s, "<args>", "NULL object key");
+ if(token(s) != 's') {
+ set_error(s, "<format>", "Expected format 's', got '%c'", token(s));
goto error;
}
- if(!utf8_check_string(key, -1)) {
- set_error(s, "<args>", "Invalid UTF-8 in object key");
+ key = read_string(s, ap, "object key", &len, &ours);
+ if(!key)
goto error;
- }
next_token(s);
value = pack(s, ap);
- if(!value)
+ if(!value) {
+ if(ours)
+ jsonp_free(key);
+
goto error;
+ }
if(json_object_set_new_nocheck(object, key, value)) {
+ if(ours)
+ jsonp_free(key);
+
set_error(s, "<internal>", "Unable to add key \"%s\"", key);
goto error;
}
+ if(ours)
+ jsonp_free(key);
+
next_token(s);
}
@@ -142,10 +265,10 @@ static json_t *pack_array(scanner_t *s, va_list *ap)
json_t *array = json_array();
next_token(s);
- while(s->token != ']') {
+ while(token(s) != ']') {
json_t *value;
- if(!s->token) {
+ if(!token(s)) {
set_error(s, "<format>", "Unexpected end of format string");
goto error;
}
@@ -170,7 +293,7 @@ error:
static json_t *pack(scanner_t *s, va_list *ap)
{
- switch(s->token) {
+ switch(token(s)) {
case '{':
return pack_object(s, ap);
@@ -179,16 +302,18 @@ static json_t *pack(scanner_t *s, va_list *ap)
case 's': /* string */
{
- const char *str = va_arg(*ap, const char *);
- if(!str) {
- set_error(s, "<args>", "NULL string argument");
- return NULL;
- }
- if(!utf8_check_string(str, -1)) {
- set_error(s, "<args>", "Invalid UTF-8 string");
+ char *str;
+ size_t len;
+ int ours;
+
+ str = read_string(s, ap, "string", &len, &ours);
+ if(!str)
return NULL;
- }
- return json_string_nocheck(str);
+
+ if (ours)
+ return jsonp_stringn_nocheck_own(str, len);
+ else
+ return json_stringn_nocheck(str, len);
}
case 'n': /* null */
@@ -214,7 +339,7 @@ static json_t *pack(scanner_t *s, va_list *ap)
default:
set_error(s, "<format>", "Unexpected format character '%c'",
- s->token);
+ token(s));
return NULL;
}
}
@@ -225,6 +350,7 @@ static int unpack_object(scanner_t *s, json_t *root, va_list *ap)
{
int ret = -1;
int strict = 0;
+ int gotopt = 0;
/* Use a set (emulated by a hashtable) to check that all object
keys are accessed. Checking that the correct number of keys
@@ -245,30 +371,30 @@ static int unpack_object(scanner_t *s, json_t *root, va_list *ap)
}
next_token(s);
- while(s->token != '}') {
+ while(token(s) != '}') {
const char *key;
json_t *value;
int opt = 0;
if(strict != 0) {
set_error(s, "<format>", "Expected '}' after '%c', got '%c'",
- (strict == 1 ? '!' : '*'), s->token);
+ (strict == 1 ? '!' : '*'), token(s));
goto out;
}
- if(!s->token) {
+ if(!token(s)) {
set_error(s, "<format>", "Unexpected end of format string");
goto out;
}
- if(s->token == '!' || s->token == '*') {
- strict = (s->token == '!' ? 1 : -1);
+ if(token(s) == '!' || token(s) == '*') {
+ strict = (token(s) == '!' ? 1 : -1);
next_token(s);
continue;
}
- if(s->token != 's') {
- set_error(s, "<format>", "Expected format 's', got '%c'", s->token);
+ if(token(s) != 's') {
+ set_error(s, "<format>", "Expected format 's', got '%c'", token(s));
goto out;
}
@@ -280,8 +406,8 @@ static int unpack_object(scanner_t *s, json_t *root, va_list *ap)
next_token(s);
- if(s->token == '?') {
- opt = 1;
+ if(token(s) == '?') {
+ opt = gotopt = 1;
next_token(s);
}
@@ -307,10 +433,26 @@ static int unpack_object(scanner_t *s, json_t *root, va_list *ap)
if(strict == 0 && (s->flags & JSON_STRICT))
strict = 1;
- if(root && strict == 1 && key_set.size != json_object_size(root)) {
- long diff = (long)json_object_size(root) - (long)key_set.size;
- set_error(s, "<validation>", "%li object item(s) left unpacked", diff);
- goto out;
+ if(root && strict == 1) {
+ /* We need to check that all non optional items have been parsed */
+ const char *key;
+ json_t *value;
+ long unpacked = 0;
+ if (gotopt) {
+ /* We have optional keys, we need to iter on each key */
+ json_object_foreach(root, key, value) {
+ if(!hashtable_get(&key_set, key)) {
+ unpacked++;
+ }
+ }
+ } else {
+ /* No optional keys, we can just compare the number of items */
+ unpacked = (long)json_object_size(root) - (long)key_set.size;
+ }
+ if (unpacked) {
+ set_error(s, "<validation>", "%li object item(s) left unpacked", unpacked);
+ goto out;
+ }
}
ret = 0;
@@ -331,30 +473,30 @@ static int unpack_array(scanner_t *s, json_t *root, va_list *ap)
}
next_token(s);
- while(s->token != ']') {
+ while(token(s) != ']') {
json_t *value;
if(strict != 0) {
set_error(s, "<format>", "Expected ']' after '%c', got '%c'",
(strict == 1 ? '!' : '*'),
- s->token);
+ token(s));
return -1;
}
- if(!s->token) {
+ if(!token(s)) {
set_error(s, "<format>", "Unexpected end of format string");
return -1;
}
- if(s->token == '!' || s->token == '*') {
- strict = (s->token == '!' ? 1 : -1);
+ if(token(s) == '!' || token(s) == '*') {
+ strict = (token(s) == '!' ? 1 : -1);
next_token(s);
continue;
}
- if(!strchr(unpack_value_starters, s->token)) {
+ if(!strchr(unpack_value_starters, token(s))) {
set_error(s, "<format>", "Unexpected format character '%c'",
- s->token);
+ token(s));
return -1;
}
@@ -392,7 +534,7 @@ static int unpack_array(scanner_t *s, json_t *root, va_list *ap)
static int unpack(scanner_t *s, json_t *root, va_list *ap)
{
- switch(s->token)
+ switch(token(s))
{
case '{':
return unpack_object(s, root, ap);
@@ -408,16 +550,32 @@ static int unpack(scanner_t *s, json_t *root, va_list *ap)
}
if(!(s->flags & JSON_VALIDATE_ONLY)) {
- const char **target;
+ const char **str_target;
+ size_t *len_target = NULL;
- target = va_arg(*ap, const char **);
- if(!target) {
+ str_target = va_arg(*ap, const char **);
+ if(!str_target) {
set_error(s, "<args>", "NULL string argument");
return -1;
}
- if(root)
- *target = json_string_value(root);
+ next_token(s);
+
+ if(token(s) == '%') {
+ len_target = va_arg(*ap, size_t *);
+ if(!len_target) {
+ set_error(s, "<args>", "NULL string length argument");
+ return -1;
+ }
+ }
+ else
+ prev_token(s);
+
+ if(root) {
+ *str_target = json_string_value(root);
+ if(len_target)
+ *len_target = json_string_length(root);
+ }
}
return 0;
@@ -521,7 +679,7 @@ static int unpack(scanner_t *s, json_t *root, va_list *ap)
default:
set_error(s, "<format>", "Unexpected format character '%c'",
- s->token);
+ token(s));
return -1;
}
}
@@ -551,7 +709,7 @@ json_t *json_vpack_ex(json_error_t *error, size_t flags,
return NULL;
next_token(&s);
- if(s.token) {
+ if(token(&s)) {
json_decref(value);
set_error(&s, "<format>", "Garbage after format string");
return NULL;
@@ -614,7 +772,7 @@ int json_vunpack_ex(json_t *root, json_error_t *error, size_t flags,
va_end(ap_copy);
next_token(&s);
- if(s.token) {
+ if(token(&s)) {
set_error(&s, "<format>", "Garbage after format string");
return -1;
}
diff --git a/src/jansson/strbuffer.c b/src/jansson/strbuffer.c
index 6d4edd6..b3ddd0e 100644
--- a/src/jansson/strbuffer.c
+++ b/src/jansson/strbuffer.c
@@ -1,11 +1,14 @@
/*
- * Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
+ * Copyright (c) 2009-2014 Petri Lehtinen <petri@digip.org>
*
* Jansson is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
+#ifndef _GNU_SOURCE
#define _GNU_SOURCE
+#endif
+
#include <stdlib.h>
#include <string.h>
#include "jansson_private.h"
@@ -31,7 +34,9 @@ int strbuffer_init(strbuffer_t *strbuff)
void strbuffer_close(strbuffer_t *strbuff)
{
- jsonp_free(strbuff->value);
+ if(strbuff->value)
+ jsonp_free(strbuff->value);
+
strbuff->size = 0;
strbuff->length = 0;
strbuff->value = NULL;
@@ -51,7 +56,7 @@ const char *strbuffer_value(const strbuffer_t *strbuff)
char *strbuffer_steal_value(strbuffer_t *strbuff)
{
char *result = strbuff->value;
- strbuffer_init(strbuff);
+ strbuff->value = NULL;
return result;
}
diff --git a/src/jansson/strbuffer.h b/src/jansson/strbuffer.h
index 23f8fff..fc11ec0 100644
--- a/src/jansson/strbuffer.h
+++ b/src/jansson/strbuffer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
+ * Copyright (c) 2009-2014 Petri Lehtinen <petri@digip.org>
*
* Jansson is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
@@ -20,6 +20,8 @@ void strbuffer_close(strbuffer_t *strbuff);
void strbuffer_clear(strbuffer_t *strbuff);
const char *strbuffer_value(const strbuffer_t *strbuff);
+
+/* Steal the value and close the strbuffer */
char *strbuffer_steal_value(strbuffer_t *strbuff);
int strbuffer_append(strbuffer_t *strbuff, const char *string);
diff --git a/src/jansson/strconv.c b/src/jansson/strconv.c
index caa9ab8..3a70c6f 100644
--- a/src/jansson/strconv.c
+++ b/src/jansson/strconv.c
@@ -5,6 +5,11 @@
#include "jansson_private.h"
#include "strbuffer.h"
+/* need jansson_private_config.h to get the correct snprintf */
+#ifdef HAVE_CONFIG_H
+#include <jansson_private_config.h>
+#endif
+
#if JSON_HAVE_LOCALECONV
#include <locale.h>
diff --git a/src/jansson/utf.c b/src/jansson/utf.c
index 0359ee2..b56e125 100644
--- a/src/jansson/utf.c
+++ b/src/jansson/utf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
+ * Copyright (c) 2009-2014 Petri Lehtinen <petri@digip.org>
*
* Jansson is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
@@ -8,7 +8,7 @@
#include <string.h>
#include "utf.h"
-int utf8_encode(int32_t codepoint, char *buffer, int *size)
+int utf8_encode(int32_t codepoint, char *buffer, size_t *size)
{
if(codepoint < 0)
return -1;
@@ -44,7 +44,7 @@ int utf8_encode(int32_t codepoint, char *buffer, int *size)
return 0;
}
-int utf8_check_first(char byte)
+size_t utf8_check_first(char byte)
{
unsigned char u = (unsigned char)byte;
@@ -80,9 +80,9 @@ int utf8_check_first(char byte)
}
}
-int utf8_check_full(const char *buffer, int size, int32_t *codepoint)
+size_t utf8_check_full(const char *buffer, size_t size, int32_t *codepoint)
{
- int i;
+ size_t i;
int32_t value = 0;
unsigned char u = (unsigned char)buffer[0];
@@ -136,12 +136,12 @@ int utf8_check_full(const char *buffer, int size, int32_t *codepoint)
return 1;
}
-const char *utf8_iterate(const char *buffer, int32_t *codepoint)
+const char *utf8_iterate(const char *buffer, size_t bufsize, int32_t *codepoint)
{
- int count;
+ size_t count;
int32_t value;
- if(!*buffer)
+ if(!bufsize)
return buffer;
count = utf8_check_first(buffer[0]);
@@ -152,7 +152,7 @@ const char *utf8_iterate(const char *buffer, int32_t *codepoint)
value = (unsigned char)buffer[0];
else
{
- if(!utf8_check_full(buffer, count, &value))
+ if(count > bufsize || !utf8_check_full(buffer, count, &value))
return NULL;
}
@@ -162,21 +162,18 @@ const char *utf8_iterate(const char *buffer, int32_t *codepoint)
return buffer + count;
}
-int utf8_check_string(const char *string, int length)
+int utf8_check_string(const char *string, size_t length)
{
- int i;
-
- if(length == -1)
- length = strlen(string);
+ size_t i;
for(i = 0; i < length; i++)
{
- int count = utf8_check_first(string[i]);
+ size_t count = utf8_check_first(string[i]);
if(count == 0)
return 0;
else if(count > 1)
{
- if(i + count > length)
+ if(count > length - i)
return 0;
if(!utf8_check_full(&string[i], count, NULL))
diff --git a/src/jansson/utf.h b/src/jansson/utf.h
index 2495cdd..2cebea0 100644
--- a/src/jansson/utf.h
+++ b/src/jansson/utf.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
+ * Copyright (c) 2009-2014 Petri Lehtinen <petri@digip.org>
*
* Jansson is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
@@ -9,31 +9,19 @@
#define UTF_H
#ifdef HAVE_CONFIG_H
-#include <config.h>
-
-#ifdef HAVE_INTTYPES_H
-/* inttypes.h includes stdint.h in a standard environment, so there's
-no need to include stdint.h separately. If inttypes.h doesn't define
-int32_t, it's defined in config.h. */
-#include <inttypes.h>
-#endif /* HAVE_INTTYPES_H */
-
-#else /* !HAVE_CONFIG_H */
-#ifdef _WIN32
-typedef int int32_t;
-#else /* !_WIN32 */
-/* Assume a standard environment */
-#include <inttypes.h>
-#endif /* _WIN32 */
+#include <jansson_private_config.h>
+#endif
-#endif /* HAVE_CONFIG_H */
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
-int utf8_encode(int codepoint, char *buffer, int *size);
+int utf8_encode(int32_t codepoint, char *buffer, size_t *size);
-int utf8_check_first(char byte);
-int utf8_check_full(const char *buffer, int size, int32_t *codepoint);
-const char *utf8_iterate(const char *buffer, int32_t *codepoint);
+size_t utf8_check_first(char byte);
+size_t utf8_check_full(const char *buffer, size_t size, int32_t *codepoint);
+const char *utf8_iterate(const char *buffer, size_t size, int32_t *codepoint);
-int utf8_check_string(const char *string, int length);
+int utf8_check_string(const char *string, size_t length);
#endif
diff --git a/src/jansson/value.c b/src/jansson/value.c
index 1a6d902..644bc87 100644
--- a/src/jansson/value.c
+++ b/src/jansson/value.c
@@ -1,17 +1,27 @@
/*
- * Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
+ * Copyright (c) 2009-2014 Petri Lehtinen <petri@digip.org>
*
* Jansson is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
+#ifndef _GNU_SOURCE
#define _GNU_SOURCE
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include <jansson_private_config.h>
+#endif
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
#include "jansson.h"
#include "hashtable.h"
#include "jansson_private.h"
@@ -19,12 +29,10 @@
/* Work around nonstandard isnan() and isinf() implementations */
#ifndef isnan
-static JSON_INLINE int jansson_isnan(double x) { return x != x; }
-# define isnan jansson_isnan
+static JSON_INLINE int isnan(double x) { return x != x; }
#endif
#ifndef isinf
-static JSON_INLINE int jansson_isinf(double x) { return !isnan(x) && isnan(x - x); }
-# define isinf jansson_isinf
+static JSON_INLINE int isinf(double x) { return !isnan(x) && isnan(x - x); }
#endif
static JSON_INLINE void json_init(json_t *json, json_type type)
@@ -36,11 +44,19 @@ static JSON_INLINE void json_init(json_t *json, json_type type)
/*** object ***/
+extern volatile uint32_t hashtable_seed;
+
json_t *json_object(void)
{
json_object_t *object = jsonp_malloc(sizeof(json_object_t));
if(!object)
return NULL;
+
+ if (!hashtable_seed) {
+ /* Autoseed */
+ json_object_seed(0);
+ }
+
json_init(&object->json, JSON_OBJECT);
if(hashtable_init(&object->hashtable))
@@ -76,7 +92,7 @@ json_t *json_object_get(const json_t *json, const char *key)
{
json_object_t *object;
- if(!json_is_object(json))
+ if(!key || !json_is_object(json))
return NULL;
object = json_to_object(json);
@@ -108,7 +124,7 @@ int json_object_set_new_nocheck(json_t *json, const char *key, json_t *value)
int json_object_set_new(json_t *json, const char *key, json_t *value)
{
- if(!key || !utf8_check_string(key, -1))
+ if(!key || !utf8_check_string(key, strlen(key)))
{
json_decref(value);
return -1;
@@ -121,7 +137,7 @@ int json_object_del(json_t *json, const char *key)
{
json_object_t *object;
- if(!json_is_object(json))
+ if(!key || !json_is_object(json))
return -1;
object = json_to_object(json);
@@ -292,19 +308,27 @@ static json_t *json_object_copy(json_t *object)
return result;
}
-static json_t *json_object_deep_copy(json_t *object)
+static json_t *json_object_deep_copy(const json_t *object)
{
json_t *result;
-
- const char *key;
- json_t *value;
+ void *iter;
result = json_object();
if(!result)
return NULL;
- json_object_foreach(object, key, value)
+ /* Cannot use json_object_foreach because object has to be cast
+ non-const */
+ iter = json_object_iter((json_t *)object);
+ while(iter) {
+ const char *key;
+ const json_t *value;
+ key = json_object_iter_key(iter);
+ value = json_object_iter_value(iter);
+
json_object_set_new_nocheck(result, key, json_deep_copy(value));
+ iter = json_object_iter_next((json_t *)object, iter);
+ }
return result;
}
@@ -511,7 +535,10 @@ int json_array_remove(json_t *json, size_t index)
json_decref(array->table[index]);
- array_move(array, index, index + 1, array->entries - index);
+ /* If we're removing the last element, nothing has to be moved */
+ if(index < array->entries - 1)
+ array_move(array, index, index + 1, array->entries - index - 1);
+
array->entries--;
return 0;
@@ -592,7 +619,7 @@ static json_t *json_array_copy(json_t *array)
return result;
}
-static json_t *json_array_deep_copy(json_t *array)
+static json_t *json_array_deep_copy(const json_t *array)
{
json_t *result;
size_t i;
@@ -609,33 +636,68 @@ static json_t *json_array_deep_copy(json_t *array)
/*** string ***/
-json_t *json_string_nocheck(const char *value)
+static json_t *string_create(const char *value, size_t len, int own)
{
+ char *v;
json_string_t *string;
if(!value)
return NULL;
+ if(own)
+ v = (char *)value;
+ else {
+ v = jsonp_strndup(value, len);
+ if(!v)
+ return NULL;
+ }
+
string = jsonp_malloc(sizeof(json_string_t));
- if(!string)
+ if(!string) {
+ if(!own)
+ jsonp_free(v);
return NULL;
+ }
json_init(&string->json, JSON_STRING);
+ string->value = v;
+ string->length = len;
+
+ return &string->json;
+}
- string->value = jsonp_strdup(value);
- if(!string->value) {
- jsonp_free(string);
+json_t *json_string_nocheck(const char *value)
+{
+ if(!value)
return NULL;
- }
- return &string->json;
+ return string_create(value, strlen(value), 0);
+}
+
+json_t *json_stringn_nocheck(const char *value, size_t len)
+{
+ return string_create(value, len, 0);
+}
+
+/* this is private; "steal" is not a public API concept */
+json_t *jsonp_stringn_nocheck_own(const char *value, size_t len)
+{
+ return string_create(value, len, 1);
}
json_t *json_string(const char *value)
{
- if(!value || !utf8_check_string(value, -1))
+ if(!value)
+ return NULL;
+
+ return json_stringn(value, strlen(value));
+}
+
+json_t *json_stringn(const char *value, size_t len)
+{
+ if(!value || !utf8_check_string(value, len))
return NULL;
- return json_string_nocheck(value);
+ return json_stringn_nocheck(value, len);
}
const char *json_string_value(const json_t *json)
@@ -646,31 +708,56 @@ const char *json_string_value(const json_t *json)
return json_to_string(json)->value;
}
+size_t json_string_length(const json_t *json)
+{
+ if(!json_is_string(json))
+ return 0;
+
+ return json_to_string(json)->length;
+}
+
int json_string_set_nocheck(json_t *json, const char *value)
{
+ if(!value)
+ return -1;
+
+ return json_string_setn_nocheck(json, value, strlen(value));
+}
+
+int json_string_setn_nocheck(json_t *json, const char *value, size_t len)
+{
char *dup;
json_string_t *string;
if(!json_is_string(json) || !value)
return -1;
- dup = jsonp_strdup(value);
+ dup = jsonp_strndup(value, len);
if(!dup)
return -1;
string = json_to_string(json);
jsonp_free(string->value);
string->value = dup;
+ string->length = len;
return 0;
}
int json_string_set(json_t *json, const char *value)
{
- if(!value || !utf8_check_string(value, -1))
+ if(!value)
return -1;
- return json_string_set_nocheck(json, value);
+ return json_string_setn(json, value, strlen(value));
+}
+
+int json_string_setn(json_t *json, const char *value, size_t len)
+{
+ if(!value || !utf8_check_string(value, len))
+ return -1;
+
+ return json_string_setn_nocheck(json, value, len);
}
static void json_delete_string(json_string_t *string)
@@ -681,12 +768,25 @@ static void json_delete_string(json_string_t *string)
static int json_string_equal(json_t *string1, json_t *string2)
{
- return strcmp(json_string_value(string1), json_string_value(string2)) == 0;
+ json_string_t *s1, *s2;
+
+ if(!json_is_string(string1) || !json_is_string(string2))
+ return 0;
+
+ s1 = json_to_string(string1);
+ s2 = json_to_string(string2);
+ return s1->length == s2->length && !memcmp(s1->value, s2->value, s1->length);
}
-static json_t *json_string_copy(json_t *string)
+static json_t *json_string_copy(const json_t *string)
{
- return json_string_nocheck(json_string_value(string));
+ json_string_t *s;
+
+ if(!json_is_string(string))
+ return NULL;
+
+ s = json_to_string(string);
+ return json_stringn_nocheck(s->value, s->length);
}
@@ -731,7 +831,7 @@ static int json_integer_equal(json_t *integer1, json_t *integer2)
return json_integer_value(integer1) == json_integer_value(integer2);
}
-static json_t *json_integer_copy(json_t *integer)
+static json_t *json_integer_copy(const json_t *integer)
{
return json_integer(json_integer_value(integer));
}
@@ -783,7 +883,7 @@ static int json_real_equal(json_t *real1, json_t *real2)
return json_real_value(real1) == json_real_value(real2);
}
-static json_t *json_real_copy(json_t *real)
+static json_t *json_real_copy(const json_t *real)
{
return json_real(json_real_value(real));
}
@@ -909,7 +1009,7 @@ json_t *json_copy(json_t *json)
return NULL;
}
-json_t *json_deep_copy(json_t *json)
+json_t *json_deep_copy(const json_t *json)
{
if(!json)
return NULL;
@@ -933,7 +1033,7 @@ json_t *json_deep_copy(json_t *json)
return json_real_copy(json);
if(json_is_true(json) || json_is_false(json) || json_is_null(json))
- return json;
+ return (json_t *)json;
return NULL;
}
diff --git a/src/libXNVCtrl/Makefile b/src/libXNVCtrl/Makefile
index d40ec01..19ea803 100644
--- a/src/libXNVCtrl/Makefile
+++ b/src/libXNVCtrl/Makefile
@@ -19,15 +19,52 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
-RANLIB ?= ranlib
+
+##############################################################################
+# include common variables and functions
+##############################################################################
+
+include utils.mk
+
+
+##############################################################################
+# assign variables
+##############################################################################
+
+LIBXNVCTRL = libXNVCtrl.a
+
+LIBXNVCTRL_PROGRAM_NAME = "libXNVCtrl"
+
+LIBXNVCTRL_VERSION := $(NVIDIA_VERSION)
+
+CFLAGS += -I .
CFLAGS += -fPIC
+CFLAGS += -I $(OUTPUTDIR)
+CFLAGS += -DPROGRAM_NAME=\"$(LIBXNVCTRL_PROGRAM_NAME)\"
-libXNVCtrl.a : libXNVCtrl.a(NVCtrl.o)
- $(RANLIB) $@
+SRC += NVCtrl.c
+SRC += $(STAMP_C)
-NVCtrl.o : NVCtrl.h nv_control.h NVCtrlLib.h
-.INTERMEDIATE: NVCtrl.o
+OBJS = $(call BUILD_OBJECT_LIST,$(SRC))
+
+
+##############################################################################
+# build rules
+##############################################################################
-clean ::
- rm -f libXNVCtrl.a *.o
.PHONY: clean
+
+all: $(LIBXNVCTRL)
+
+$(LIBXNVCTRL) : $(OBJS)
+ $(AR) ru $@ $(OBJS)
+
+# define the rule to build each object file
+$(foreach src,$(SRC),$(eval $(call DEFINE_OBJECT_RULE,TARGET,$(src))))
+
+# define the rule to generate $(STAMP_C)
+$(eval $(call DEFINE_STAMP_C_RULE, $(OBJS),$(LIBXNVCTRL_PROGRAM_NAME)))
+
+clean:
+ rm -rf $(LIBXNVCTRL) *~ $(STAMP_C) \
+ $(OUTPUTDIR)/*.o $(OUTPUTDIR)/*.d
diff --git a/src/libXNVCtrl/NVCtrl.h b/src/libXNVCtrl/NVCtrl.h
index 8436643..2565d50 100644
--- a/src/libXNVCtrl/NVCtrl.h
+++ b/src/libXNVCtrl/NVCtrl.h
@@ -150,14 +150,15 @@
/*
- * NV_CTRL_FLATPANEL_DITHERING is deprecated; NV_CTRL_DITHERING should
- * be used instead.
+ * NV_CTRL_FLATPANEL_DITHERING - deprecated
+ *
+ * NV_CTRL_DITHERING should be used instead.
*/
#define NV_CTRL_FLATPANEL_DITHERING 3 /* RWDG */
-#define NV_CTRL_FLATPANEL_DITHERING_DEFAULT 0
-#define NV_CTRL_FLATPANEL_DITHERING_ENABLED 1
-#define NV_CTRL_FLATPANEL_DITHERING_DISABLED 2
+#define NV_CTRL_FLATPANEL_DITHERING_DEFAULT 0 /* deprecated */
+#define NV_CTRL_FLATPANEL_DITHERING_ENABLED 1 /* deprecated */
+#define NV_CTRL_FLATPANEL_DITHERING_DISABLED 2 /* deprecated */
/*
* NV_CTRL_DITHERING - the requested dithering configuration;
@@ -364,27 +365,31 @@
/*
- * NV_CTRL_CONNECTED_DISPLAYS - returns a display mask indicating the last
- * cached state of the display devices connected to the GPU or GPU driving
- * the specified X screen.
+ * NV_CTRL_CONNECTED_DISPLAYS - deprecated
*
- * This attribute may be queried through XNVCTRLQueryTargetAttribute()
- * using a NV_CTRL_TARGET_TYPE_GPU or NV_CTRL_TARGET_TYPE_X_SCREEN target.
+ * NV_CTRL_BINARY_DATA_DISPLAYS_CONNECTED_TO_GPU and
+ * NV_CTRL_BINARY_DATA_DISPLAYS_ASSIGNED_TO_XSCREEN should be used instead.
*/
#define NV_CTRL_CONNECTED_DISPLAYS 19 /* R--G */
/*
- * NV_CTRL_ENABLED_DISPLAYS - returns a display mask indicating what
- * display devices are enabled for use on the specified X screen or
- * GPU.
+ * NV_CTRL_ENABLED_DISPLAYS - Event that notifies when one or more display
+ * devices are enabled or disabled on a GPU and/or X screen.
*
* This attribute may be queried through XNVCTRLQueryTargetAttribute()
* using a NV_CTRL_TARGET_TYPE_GPU or NV_CTRL_TARGET_TYPE_X_SCREEN target.
+ *
+ * Note: Querying this value has been deprecated.
+ * NV_CTRL_BINARY_DATA_DISPLAYS_CONNECTED_TO_GPU,
+ * NV_CTRL_DISPLAY_ENABLED, and
+ * NV_CTRL_BINARY_DATA_DISPLAYS_ENABLED_ON_XSCREEN should be used
+ * instead to obtain the list of enabled displays.
*/
-#define NV_CTRL_ENABLED_DISPLAYS 20 /* R--G */
+#define NV_CTRL_ENABLED_DISPLAYS 20 /* ---G */
+
/**************************************************************************/
/*
@@ -408,13 +413,14 @@
/*
- * NV_CTRL_FRAMELOCK_MASTER is deprecated; NV_CTRL_FRAMELOCK_DISPLAY_CONFIG
- * should be used instead.
+ * NV_CTRL_FRAMELOCK_MASTER - deprecated
+ *
+ * NV_CTRL_FRAMELOCK_DISPLAY_CONFIG should be used instead.
*/
#define NV_CTRL_FRAMELOCK_MASTER 22 /* RW-G */
-#define NV_CTRL_FRAMELOCK_MASTER_FALSE 0 // deprecated
-#define NV_CTRL_FRAMELOCK_MASTER_TRUE 1 // deprecated
+#define NV_CTRL_FRAMELOCK_MASTER_FALSE 0 /* deprecated */
+#define NV_CTRL_FRAMELOCK_MASTER_TRUE 1 /* deprecated */
/*
@@ -453,8 +459,8 @@
*/
#define NV_CTRL_FRAMELOCK_SYNC_DELAY 24 /* RW-F */
-#define NV_CTRL_FRAMELOCK_SYNC_DELAY_MAX 2047 // deprecated
-#define NV_CTRL_FRAMELOCK_SYNC_DELAY_FACTOR 7.81 // deprecated
+#define NV_CTRL_FRAMELOCK_SYNC_DELAY_MAX 2047 /* deprecated */
+#define NV_CTRL_FRAMELOCK_SYNC_DELAY_FACTOR 7.81 /* deprecated */
/*
@@ -643,20 +649,14 @@
/**************************************************************************/
/*
- * NV_CTRL_FORCE_GENERIC_CPU - inhibit the use of CPU specific
- * features such as MMX, SSE, or 3DNOW! for OpenGL clients; this
- * option may result in performance loss, but may be useful in
- * conjunction with software such as the Valgrind memory debugger.
- * This setting is only applied to OpenGL clients that are started
- * after this setting is applied.
+ * NV_CTRL_FORCE_GENERIC_CPU - deprecated
*
- * USAGE NOTE: This attribute is deprecated. CPU compatibility is now
- * checked each time during initialization.
+ * CPU compatibility is now checked each time during initialization.
*/
#define NV_CTRL_FORCE_GENERIC_CPU 37 /* RW-X */
-#define NV_CTRL_FORCE_GENERIC_CPU_DISABLE 0
-#define NV_CTRL_FORCE_GENERIC_CPU_ENABLE 1
+#define NV_CTRL_FORCE_GENERIC_CPU_DISABLE 0 /* deprecated */
+#define NV_CTRL_FORCE_GENERIC_CPU_ENABLE 1 /* deprecated */
/*
@@ -707,6 +707,7 @@
#define NV_CTRL_ARCHITECTURE_X86_64 1
#define NV_CTRL_ARCHITECTURE_IA64 2
#define NV_CTRL_ARCHITECTURE_ARM 3
+#define NV_CTRL_ARCHITECTURE_AARCH64 4
/*
@@ -1141,9 +1142,11 @@
#define NV_CTRL_GVIO_DETECTED_VIDEO_FORMAT 71 /* R--I */
/*
- * The following is deprecated. Use NV_CTRL_GVIO_DETECTED_VIDEO_FORMAT,
- * instead.
+ * NV_CTRL_GVO_INPUT_VIDEO_FORMAT - deprecated
+ *
+ * NV_CTRL_GVIO_DETECTED_VIDEO_FORMAT should be used instead.
*/
+
#define NV_CTRL_GVO_INPUT_VIDEO_FORMAT 71 /* R-- */
/*
@@ -1252,9 +1255,9 @@
/*
- * NV_CTRL_GVO_FPGA_VERSION - indicates the version of the Firmware on
- * the GVO device. Deprecated; use
- * NV_CTRL_STRING_GVIO_FIRMWARE_VERSION instead.
+ * NV_CTRL_GVO_FPGA_VERSION - deprecated
+ *
+ * NV_CTRL_STRING_GVIO_FIRMWARE_VERSION should be used instead.
*/
#define NV_CTRL_GVO_FIRMWARE_VERSION 78 /* R-- */
@@ -1299,28 +1302,14 @@
/*
- * NV_CTRL_GVO_GLX_LOCKED - indicates that GVO configurability is
- * locked by GLX; this occurs when either glXGetVideoDeviceNV (part of
- * GLX_NV_video_out) or glXBindVideoDeviceNV (part of
- * GLX_NV_present_video) is called. All GVO output resources are
- * locked until released by the GLX_NV_video_out/GLX_NV_present_video
- * client.
+ * NV_CTRL_GVO_GLX_LOCKED - deprecated
*
- * When GVO is locked, setting of the following GVO NV-CONTROL attributes will
- * not happen immediately and will instead be cached. The GVO resource will
- * need to be disabled/released and re-enabled/claimed for the values to be
- * flushed. These attributes are:
- * NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT
- * NV_CTRL_GVO_DATA_FORMAT
- * NV_CTRL_GVO_FLIP_QUEUE_SIZE
- *
- * This attribute is deprecated and may be removed in a future release. Its
- * functionality has been replaced by NV_CTRL_GVO_LOCK_OWNER.
+ * NV_CTRL_GVO_LOCK_OWNER should be used instead.
*/
#define NV_CTRL_GVO_GLX_LOCKED 82 /* R-- */
-#define NV_CTRL_GVO_GLX_LOCKED_FALSE 0
-#define NV_CTRL_GVO_GLX_LOCKED_TRUE 1
+#define NV_CTRL_GVO_GLX_LOCKED_FALSE 0 /* deprecated */
+#define NV_CTRL_GVO_GLX_LOCKED_TRUE 1 /* deprecated */
/*
@@ -1614,9 +1603,9 @@
#define NV_CTRL_SHOW_SLI_VISUAL_INDICATOR_TRUE 1
/*
- * NV_CTRL_XV_SYNC_TO_DISPLAY - this control is valid when TwinView and
- * XVideo Sync To VBlank are enabled.
- * It controls which display device will be synched to.
+ * NV_CTRL_XV_SYNC_TO_DISPLAY - deprecated
+ *
+ * NV_CTRL_XV_SYNC_TO_DISPLAY_ID should be used instead.
*/
#define NV_CTRL_XV_SYNC_TO_DISPLAY 226 /* RW- */
@@ -1630,9 +1619,10 @@
#define NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT2 227 /* ---GI */
-/*
- * The following is deprecated; use NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT2,
- * instead
+/*
+ * NV_CTRL_GVO_OUTPUT_VIDEO_FORMAT2 - deprecated
+ *
+ * NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT2 should be used instead.
*/
#define NV_CTRL_GVO_OUTPUT_VIDEO_FORMAT2 227 /* --- */
@@ -1699,23 +1689,25 @@
/*
- * NV_CTRL_ASSOCIATED_DISPLAY_DEVICES - display device mask indicating
- * which display devices are "associated" with the specified X screen
- * (ie: are available to the X screen for displaying the X screen).
+ * NV_CTRL_ASSOCIATED_DISPLAY_DEVICES - deprecated
+ *
+ * NV_CTRL_BINARY_DATA_DISPLAYS_ASSIGNED_TO_XSCREEN should be used instead.
*/
-
+
#define NV_CTRL_ASSOCIATED_DISPLAY_DEVICES 231 /* RW- */
/*
- * NV_CTRL_FRAMELOCK_SLAVES is deprecated; NV_CTRL_FRAMELOCK_DISPLAY_CONFIG
- * should be used instead.
+ * NV_CTRL_FRAMELOCK_SLAVES - deprecated
+ *
+ * NV_CTRL_FRAMELOCK_DISPLAY_CONFIG should be used instead.
*/
#define NV_CTRL_FRAMELOCK_SLAVES 232 /* RW-G */
/*
- * NV_CTRL_FRAMELOCK_MASTERABLE is deprecated; NV_CTRL_FRAMELOCK_DISPLAY_CONFIG
- * should be used instead.
+ * NV_CTRL_FRAMELOCK_MASTERABLE - deprecated
+ *
+ * NV_CTRL_FRAMELOCK_DISPLAY_CONFIG should be used instead.
*/
#define NV_CTRL_FRAMELOCK_MASTERABLE 233 /* R-DG */
@@ -1723,7 +1715,7 @@
/*
* NV_CTRL_PROBE_DISPLAYS - re-probes the hardware to detect what
* display devices are connected to the GPU or GPU driving the
- * specified X screen. Returns a display mask.
+ * specified X screen. The return value is deprecated and should not be used.
*
* This attribute may be queried through XNVCTRLQueryTargetAttribute()
* using a NV_CTRL_TARGET_TYPE_GPU or NV_CTRL_TARGET_TYPE_X_SCREEN target.
@@ -1835,12 +1827,12 @@
/*
- * NV_CTRL_MAX_DISPLAYS - the maximum number of display devices that
+ * NV_CTRL_MAX_DISPLAYS - The maximum number of display devices that
* can be driven simultaneously on a GPU (e.g., that can be used in a
* MetaMode at once). Note that this does not indicate the maximum
- * number of bits that can be set in NV_CTRL_CONNECTED_DISPLAYS,
- * because more display devices can be connected than are actively in
- * use.
+ * number of displays that are listed in NV_CTRL_BINARY_DATA_DISPLAYS_ON_GPU
+ * and NV_CTRL_BINARY_DATA_DISPLAYS_CONNECTED_TO_GPU because more display
+ * devices can be connected than are actively in use.
*/
#define NV_CTRL_MAX_DISPLAYS 245 /* R--G */
@@ -2010,10 +2002,7 @@
/*
- * NV_CTRL_ONDEMAND_VBLANK_INTERRUPTS - if the OnDemandVBlankInterrupts
- * X driver option is set to true, this attribute can be used to
- * determine if on-demand VBlank interrupt control is enabled on the
- * specified GPU, as well as to enable or disable this feature.
+ * NV_CTRL_ONDEMAND_VBLANK_INTERRUPTS - not supported
*/
#define NV_CTRL_ONDEMAND_VBLANK_INTERRUPTS 261 /* RW-G */
@@ -2032,12 +2021,12 @@
/*
- * NV_CTRL_GPU_CURRENT_PERFORMANCE_MODE is deprecated
+ * NV_CTRL_GPU_CURRENT_PERFORMANCE_MODE - deprecated
*/
#define NV_CTRL_GPU_CURRENT_PERFORMANCE_MODE 263 /* R--G */
-#define NV_CTRL_GPU_CURRENT_PERFORMANCE_MODE_DESKTOP 0
-#define NV_CTRL_GPU_CURRENT_PERFORMANCE_MODE_MAXPERF 1
+#define NV_CTRL_GPU_CURRENT_PERFORMANCE_MODE_DESKTOP 0 /* deprecated */
+#define NV_CTRL_GPU_CURRENT_PERFORMANCE_MODE_MAXPERF 1 /* deprecated */
/* NV_CTRL_GLYPH_CACHE - Enables RENDER Glyph Caching to VRAM */
@@ -2183,8 +2172,7 @@
/*
- * NV_CTRL_SWITCH_TO_DISPLAYS - Can be used to select which displays
- * to switch to (as a hotkey event).
+ * NV_CTRL_SWITCH_TO_DISPLAYS - deprecated
*/
#define NV_CTRL_SWITCH_TO_DISPLAYS 276 /* -W- */
@@ -2202,8 +2190,7 @@
#define NV_CTRL_NOTEBOOK_DISPLAY_CHANGE_LID_EVENT_OPEN 1
/*
- * NV_CTRL_NOTEBOOK_INTERNAL_LCD - Returns the display device mask of
- * the intenal LCD of a notebook.
+ * NV_CTRL_NOTEBOOK_INTERNAL_LCD - deprecated
*/
#define NV_CTRL_NOTEBOOK_INTERNAL_LCD 278 /* R-- */
@@ -2286,8 +2273,9 @@
#define NV_CTRL_GVO_CSC_CHANGED_EVENT 294 /* --- */
/*
- * NV_CTRL_FRAMELOCK_SLAVEABLE is deprecated; NV_CTRL_FRAMELOCK_DISPLAY_CONFIG
- * should be used instead.
+ * NV_CTRL_FRAMELOCK_SLAVEABLE - deprecated
+ *
+ * NV_CTRL_FRAMELOCK_DISPLAY_CONFIG should be used instead.
*/
#define NV_CTRL_FRAMELOCK_SLAVEABLE 295 /* R-DG */
@@ -3318,7 +3306,65 @@
#define NV_CTRL_THERMAL_COOLER_SPEED 405 /* R--C */
-#define NV_CTRL_LAST_ATTRIBUTE NV_CTRL_THERMAL_COOLER_SPEED
+/*
+ * NV_CTRL_PALETTE_UPDATE_EVENT - The Color Palette has been changed and the
+ * color correction info needs to be updated.
+ */
+
+#define NV_CTRL_PALETTE_UPDATE_EVENT 406 /* --- */
+
+/*
+ * NV_CTRL_VIDEO_ENCODER_UTILIZATION - Returns the video encoder engine
+ * utilization as a percentage.
+ */
+#define NV_CTRL_VIDEO_ENCODER_UTILIZATION 407 /* R--G */
+
+/*
+ * NV_CTRL_GSYNC_ALLOWED - when TRUE, OpenGL will enable G-SYNC when possible;
+ * when FALSE, OpenGL will always use a fixed monitor refresh rate.
+ */
+
+#define NV_CTRL_GSYNC_ALLOWED 408 /* RW-X */
+#define NV_CTRL_GSYNC_ALLOWED_FALSE 0
+#define NV_CTRL_GSYNC_ALLOWED_TRUE 1
+
+/*
+ * NV_CTRL_GPU_NVCLOCK_OFFSET - This attribute controls the GPU clock offsets
+ * (in MHz) used for overclocking per performance level.
+ * Use the display_mask parameter to specify the performance level.
+ *
+ * Note: To enable overclocking support, set the X configuration
+ * option "Coolbits" to value "8".
+ *
+ * This offset can have any integer value between
+ * NVCTRLAttributeValidValues.u.range.min and
+ * NVCTRLAttributeValidValues.u.range.max (inclusive).
+ *
+ * This attribute is available on GeForce GTX 400 series and later
+ * Geforce GPUs.
+ */
+#define NV_CTRL_GPU_NVCLOCK_OFFSET 409 /* RW-G */
+
+/*
+ * NV_CTRL_GPU_MEM_TRANSFER_RATE_OFFSET - This attribute controls
+ * the memory transfer rate offsets (in MHz) used for overclocking
+ * per performance level.
+ * Use the display_mask parameter to specify the performance level.
+ *
+ * Note: To enable overclocking support, set the X configuration
+ * option "Coolbits" to value "8".
+ *
+ * This offset can have any integer value between
+ * NVCTRLAttributeValidValues.u.range.min and
+ * NVCTRLAttributeValidValues.u.range.max (inclusive).
+ *
+ * This attribute is available on GeForce GTX 400 series and later
+ * Geforce GPUs.
+ */
+#define NV_CTRL_GPU_MEM_TRANSFER_RATE_OFFSET 410 /* RW-G */
+
+#define NV_CTRL_LAST_ATTRIBUTE NV_CTRL_GPU_MEM_TRANSFER_RATE_OFFSET
+
/**************************************************************************/
@@ -3394,8 +3440,9 @@
#define NV_CTRL_STRING_GVIO_FIRMWARE_VERSION 8 /* R--I */
/*
- * The following is deprecated; use NV_CTRL_STRING_GVIO_FIRMWARE_VERSION,
- * instead
+ * NV_CTRL_STRING_GVO_FIRMWARE_VERSION - deprecated
+ *
+ * NV_CTRL_STRING_GVIO_FIRMWARE_VERSION should be used instead.
*/
#define NV_CTRL_STRING_GVO_FIRMWARE_VERSION 8 /* R-- */
@@ -3709,6 +3756,10 @@
* processorclock those are the same as nvclockmin, memclockmin and
* processorclockmin.
*
+ * Note: These clock values take into account the offset
+ * set by clients through NV_CTRL_GPU_NVCLOCK_OFFSET and
+ * NV_CTRL_GPU_MEM_TRANSFER_RATE_OFFSET.
+ *
* Each performance modes are returned as a comma-separated list of
* "token=value" pairs. Each set of performance mode tokens are separated
* by a ";". Valid tokens:
@@ -3718,30 +3769,40 @@
* "nvclock" integer - the GPU clocks (in MHz) for the perf level
* "nvclockmin" integer - the GPU clocks min (in MHz) for the perf level
* "nvclockmax" integer - the GPU clocks max (in MHz) for the perf level
+ * "nvclockeditable" integer - if the GPU clock domain is editable
+ * for the perf level
* "memclock" integer - the memory clocks (in MHz) for the perf level
* "memclockmin" integer - the memory clocks min (in MHz) for the perf level
* "memclockmax" integer - the memory clocks max (in MHz) for the perf level
+ * "memclockeditable" integer - if the memory clock domain is editable
+ * for the perf level
* "memtransferrate" integer - the memory transfer rate (in MHz)
* for the perf level
* "memtransferratemin" integer - the memory transfer rate min (in MHz)
* for the perf level
* "memtransferratemax" integer - the memory transfer rate max (in MHz)
* for the perf level
- * "processorclock" integer - the processor clocks (in MHz)
- * for the perf level
- * "processorclockmin" integer - the processor clocks min (in MHz)
- * for the perf level
- * "processorclockmax" integer - the processor clocks max (in MHz)
- * for the perf level
+ * "memtransferrateeditable" integer - if the memory transfer rate is editable
+ * for the perf level
+ * "processorclock" integer - the processor clocks (in MHz)
+ * for the perf level
+ * "processorclockmin" integer - the processor clocks min (in MHz)
+ * for the perf level
+ * "processorclockmax" integer - the processor clocks max (in MHz)
+ * for the perf level
+ * "processorclockeditable" integer - if the processor clock domain is editable
+ * for the perf level
*
* Example:
*
- * perf=0, nvclock=324, nvclockmin=324, nvclockmax=324, memclock=324,
- * memclockmin=324, memclockmax=324, memtransferrate=648,
- * memtransferratemin=648,memtransferratemax=648 ;
- * perf=1, nvclock=324, nvclockmin=324, nvclockmax=640, memclock=810,
- * memclockmin=810, memclockmax=810, memtransferrate=1620,
- * memtransferrate=1620, memtransferrate=1620 ;
+ * perf=0, nvclock=324, nvclockmin=324, nvclockmax=324, nvclockeditable=0,
+ * memclock=324, memclockmin=324, memclockmax=324, memclockeditable=0,
+ * memtransferrate=648, memtransferratemin=648, memtransferratemax=648,
+ * memtransferrateeditable=0 ;
+ * perf=1, nvclock=324, nvclockmin=324, nvclockmax=640, nvclockeditable=0,
+ * memclock=810, memclockmin=810, memclockmax=810, memclockeditable=0,
+ * memtransferrate=1620, memtransferrate=1620, memtransferrate=1620,
+ * memtransferrateeditable=0 ;
*
* This attribute may be queried through XNVCTRLQueryTargetStringAttribute()
* using a NV_CTRL_TARGET_TYPE_GPU or NV_CTRL_TARGET_TYPE_X_SCREEN target.
@@ -3843,8 +3904,9 @@
#define NV_CTRL_STRING_GVIO_VIDEO_FORMAT_NAME 33 /* R--GI */
/*
- * The following is deprecated; use NV_CTRL_STRING_GVIO_VIDEO_FORMAT_NAME,
- * instead
+ * NV_CTRL_STRING_GVO_VIDEO_FORMAT_NAME - deprecated
+ *
+ * NV_CTRL_STRING_GVIO_VIDEO_FORMAT_NAME should be used instead.
*/
#define NV_CTRL_STRING_GVO_VIDEO_FORMAT_NAME 33 /* R--- */
@@ -3852,13 +3914,17 @@
/*
* 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", "nvclockmin", "nvclockmax",
* "memclock", "memclockmin", "memclockmax", "processorclock",
* "processorclockmin" and "processorclockmax".
* Not all tokens will be reported on all GPUs, and additional tokens
* may be added in the future.
*
+ * Note: These clock values take into account the offset
+ * set by clients through NV_CTRL_GPU_NVCLOCK_OFFSET and
+ * NV_CTRL_GPU_MEM_TRANSFER_RATE_OFFSET.
+ *
* Clock values are returned as a comma-separated list of
* "token=value" pairs.
* Valid tokens:
@@ -3867,26 +3933,35 @@
* "nvclock" integer - the GPU clocks (in MHz) for the perf level
* "nvclockmin" integer - the GPU clocks min (in MHz) for the perf level
* "nvclockmax" integer - the GPU clocks max (in MHz) for the perf level
+ * "nvclockeditable" integer - if the GPU clock domain is editable
+ * for the perf level
* "memclock" integer - the memory clocks (in MHz) for the perf level
* "memclockmin" integer - the memory clocks min (in MHz) for the perf level
* "memclockmax" integer - the memory clocks (max in MHz) for the perf level
+ * "memclockeditable" integer - if the memory clock domain is editable
+ * for the perf level
* "memtransferrate" integer - the memory transfer rate (in MHz)
* for the perf level
* "memtransferratemin" integer - the memory transfer rate min (in MHz)
* for the perf level
* "memtransferratemax" integer - the memory transfer rate max (in MHz)
* for the perf level
+ * "memtransferrateeditable" integer - if the memory transfer rate is editable
+ * for the perf level
* "processorclock" integer - the processor clocks (in MHz)
* for the perf level
* "processorclockmin" integer - the processor clocks min (in MHz)
* for the perf level
* "processorclockmax" integer - the processor clocks max (in MHz)
* for the perf level
+ * "processorclockeditable" integer - if the processor clock domain is editable
+ * for the perf level
*
* Example:
*
- * nvclock=324, nvclockmin=324, nvclockmax=324,
- * memclock=324, memclockmin=324, memclockmax=324, memtrasferrate=628
+ * nvclock=324, nvclockmin=324, nvclockmax=324, nvclockeditable=0
+ * memclock=324, memclockmin=324, memclockmax=324, memclockeditable=0
+ * memtrasferrate=628
*
* This attribute may be queried through XNVCTRLQueryTargetStringAttribute()
* using an NV_CTRL_TARGET_TYPE_GPU or NV_CTRL_TARGET_TYPE_X_SCREEN target.
diff --git a/src/libXNVCtrl/utils.mk b/src/libXNVCtrl/utils.mk
new file mode 100644
index 0000000..a725f14
--- /dev/null
+++ b/src/libXNVCtrl/utils.mk
@@ -0,0 +1,353 @@
+#
+# Copyright (C) 2008 NVIDIA Corporation
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, 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 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, see <http://www.gnu.org/licenses>.
+#
+#
+# utils.mk: common Makefile fragment used by nvidia-xconfig,
+# nvidia-installer, and nvidia-settings
+#
+
+
+
+##############################################################################
+# The calling Makefile (when building as part of the NVIDIA graphics
+# driver) may export any of the following variables; we assign default
+# values if they are not exported by the caller
+##############################################################################
+
+CC ?= gcc
+LD ?= ld
+# only set these warnings and optimizations if CFLAGS is unset
+CFLAGS ?= -Wall -O2
+# always set these -f CFLAGS
+CFLAGS += -fno-strict-aliasing -fno-omit-frame-pointer -Wformat=2
+CC_ONLY_CFLAGS ?=
+LDFLAGS ?=
+BIN_LDFLAGS ?=
+
+HOST_CC ?= $(CC)
+HOST_LD ?= $(LD)
+HOST_CFLAGS ?= $(CFLAGS)
+HOST_LDFLAGS ?= $(LDFLAGS)
+HOST_BIN_LDFLAGS ?=
+
+# always disable warnings that will break the build
+CFLAGS += -Wno-unused-parameter -Wno-format-zero-length
+HOST_CFLAGS += -Wno-unused-parameter -Wno-format-zero-length
+
+ifeq ($(DEBUG),1)
+ STRIP_CMD ?= true
+ CFLAGS += -O0 -g
+else
+ STRIP_CMD ?= strip
+endif
+
+INSTALL ?= install
+INSTALL_BIN_ARGS ?= -m 755
+INSTALL_DOC_ARGS ?= -m 644
+
+M4 ?= m4
+SED ?= sed
+M4 ?= m4
+ECHO ?= echo
+PRINTF ?= printf
+MKDIR ?= mkdir -p
+RM ?= rm -f
+TOUCH ?= touch
+WHOAMI ?= whoami
+HOSTNAME_CMD ?= hostname
+DATE ?= date
+GZIP_CMD ?= gzip
+CHMOD ?= chmod
+
+NV_AUTO_DEPEND ?= 1
+NV_VERBOSE ?= 0
+
+ifndef TARGET_OS
+ TARGET_OS := $(shell uname)
+endif
+
+ifeq ($(TARGET_OS),Linux)
+ CFLAGS += -DNV_LINUX
+endif
+
+ifeq ($(TARGET_OS),FreeBSD)
+ CFLAGS += -DNV_BSD
+endif
+
+ifeq ($(TARGET_OS),SunOS)
+ CFLAGS += -DNV_SUNOS
+endif
+
+ifndef TARGET_ARCH
+ TARGET_ARCH := $(shell uname -m)
+ TARGET_ARCH := $(subst i386,x86,$(TARGET_ARCH))
+ TARGET_ARCH := $(subst i486,x86,$(TARGET_ARCH))
+ TARGET_ARCH := $(subst i586,x86,$(TARGET_ARCH))
+ TARGET_ARCH := $(subst i686,x86,$(TARGET_ARCH))
+endif
+
+ifeq ($(TARGET_OS),Linux)
+ LIBDL_LIBS = -ldl
+else
+ LIBDL_LIBS =
+endif
+
+# This variable controls which floating-point ABI is targeted. For ARM, it
+# defaults to "gnueabi" for softfp. Another option is "gnueabihf" for
+# hard(fp). This is necessary to pick up the correct rtld_test binary.
+# All other architectures default to empty.
+ifeq ($(TARGET_ARCH),armv7l)
+ TARGET_ARCH_ABI ?= gnueabi
+endif
+TARGET_ARCH_ABI ?=
+
+OUTPUTDIR ?= _out/$(TARGET_OS)_$(TARGET_ARCH)
+OUTPUTDIR_ABSOLUTE ?= $(CURDIR)/$(OUTPUTDIR)
+
+NV_QUIET_COMMAND_REMOVED_TARGET_PREFIX ?=
+
+CFLAGS += $(CC_ONLY_CFLAGS)
+
+
+##############################################################################
+# This makefile uses the $(eval) builtin function, which was added in
+# GNU make 3.80. Check that the current make version recognizes it.
+# Idea suggested by: http://www.jgc.org/blog/cookbook-sample.pdf
+##############################################################################
+
+_eval_available :=
+$(eval _eval_available := T)
+
+ifneq ($(_eval_available),T)
+ $(error This Makefile requires a GNU Make that supports 'eval'. Please upgrade to GNU make 3.80 or later)
+endif
+
+
+##############################################################################
+# define variables used when installing the open source utilities from
+# the source tarball
+##############################################################################
+
+PREFIX ?= /usr/local
+
+BINDIR = $(DESTDIR)$(PREFIX)/bin
+MANDIR = $(DESTDIR)$(PREFIX)/share/man/man1
+
+
+##############################################################################
+# default build rule, so that nothing here in utils.mk accidentally
+# gets selected as the default rule
+##############################################################################
+
+default build: all
+
+
+##############################################################################
+# get the definition of NVIDIA_VERSION from version.mk
+#
+# version.mk may be in one of two places: either in $(OUTPUTDIR) when
+# building as part of the NVIDIA driver build, or directly in the
+# source directory when building from the source tarball
+#
+# Throw an error if one of these two places did not define NVIDIA_VERSION.
+##############################################################################
+
+VERSION_MK := $(wildcard $(OUTPUTDIR)/version.mk version.mk)
+include $(VERSION_MK)
+
+ifndef NVIDIA_VERSION
+$(error NVIDIA_VERSION undefined)
+endif
+
+
+##############################################################################
+# Several of the functions below take an argument that indicates if
+# the expression is for the target platform (the system the built
+# program is going to run on) or the host platform (the system
+# performing the build). The argument is either "HOST" or "TARGET"
+# and needs to be converted:
+#
+# "HOST" -> "HOST_"
+# "TARGET" -> ""
+#
+# and prepended to "CC" or "CFLAGS"
+##############################################################################
+
+host_target = $(patsubst HOST,HOST_,$(patsubst TARGET,,$(1)))
+host_target_cc = $(call host_target,$(1))CC
+host_target_cflags = $(call host_target,$(1))CFLAGS
+
+
+##############################################################################
+# to generate the dependency files, use the compiler's "-MM" option to
+# generate output of the form "foo.o : foo.c foo.h"; then, use sed to
+# wrap the prerequisites with $(wildcard ...); the wildcard function
+# serves as an existence filter, so that files that are later removed
+# from the build do not cause stale references. Also, "-MM" will
+# cause the compiler to name the target as if it were in the current
+# directory ("foo.o: "); use sed to rename the target in the output
+# directory ("_out/Linux_x86/foo.o: ") so that the target actually
+# applies to the object files produced in the build.
+#
+# Arguments:
+# $(1): whether for host or target platform ("HOST" or "TARGET")
+# $(2): source filename
+# $(3): object filename
+##############################################################################
+
+ifeq ($(NV_AUTO_DEPEND),1)
+ AUTO_DEP_CMD = && $($(call host_target_cc,$(1))) \
+ -MM $$($(call host_target_cflags,$(1))) $$< | $$(SED) \
+ -e "s,: ,: $$$$\(wildcard ," \
+ -e "s,\([^\\]\)$$$$,\1)," \
+ -e "s;^$$(addsuffix .o,$$(notdir $$(basename $(2)))): ;$(3): ;" \
+ > $$(@:.o=.d)
+else
+ AUTO_DEP_CMD =
+endif
+
+
+##############################################################################
+# echo minimal compile information in the non-NV_VERBOSE case
+#
+# NV_MODULE_LOGGING_NAME can be set to prepend quiet build output with a
+# label of which build component is being built
+##############################################################################
+
+NV_MODULE_LOGGING_NAME ?=
+
+ifeq ($(NV_VERBOSE),0)
+ quiet_cmd = @$(PRINTF) \
+ " $(if $(NV_MODULE_LOGGING_NAME),[ %-17.17s ]) $(quiet_$(1))\n" \
+ "$(NV_MODULE_LOGGING_NAME)" && $($(1))
+else
+ quiet_cmd = $($(1))
+endif
+
+# define LINK and HOST_LINK to be the same as CC; this is so that,
+# even though we use CC to link programs, we can have a different
+# quiet rule that uses '$@' as it's arg, rather than '$<'
+LINK = $(CC)
+HOST_LINK = $(HOST_CC)
+
+# strip NV_QUIET_COMMAND_REMOVED_TARGET_PREFIX from the target string
+define_quiet_cmd = $(1) $(patsubst $(NV_QUIET_COMMAND_REMOVED_TARGET_PREFIX)/%,%,$(2))
+
+# define the quiet commands:
+quiet_CC = $(call define_quiet_cmd,CC ,$<)
+quiet_HOST_CC = $(call define_quiet_cmd,HOST_CC ,$<)
+quiet_LINK = $(call define_quiet_cmd,LINK ,$@)
+quiet_HOST_LINK = $(call define_quiet_cmd,HOST_LINK ,$@)
+quiet_M4 = $(call define_quiet_cmd,M4 ,$<)
+quiet_STRIP_CMD = $(call define_quiet_cmd,STRIP ,$@)
+
+##############################################################################
+# Tell gmake to delete the target of a rule if it has changed and its
+# commands exit with a nonzero exit status.
+##############################################################################
+.DELETE_ON_ERROR:
+
+
+##############################################################################
+# function to generate a list of object files from their corresponding
+# source files; example usage:
+#
+# OBJS = $(call BUILD_OBJECT_LIST,$(SRC))
+##############################################################################
+
+BUILD_OBJECT_LIST = \
+ $(addprefix $(OUTPUTDIR)/,$(notdir $(addsuffix .o,$(basename $(1)))))
+
+
+##############################################################################
+# function to generate a list of dependency files from their
+# corresponding source files; example usage:
+#
+# DEPS = $(call BUILD_DEPENDENCY_LIST,$(SRC))
+##############################################################################
+
+BUILD_DEPENDENCY_LIST = \
+ $(addprefix $(OUTPUTDIR)/,$(notdir $(addsuffix .d,$(basename $(1)))))
+
+
+##############################################################################
+# functions to define a rule to build an object file; the first
+# argument whether the rule is for the target or host platform ("HOST"
+# or "TARGET"), the second argument is the source file to compile, and
+# the third argument (_WITH_OBJECT_NAME-only) is the object filename
+# to produce. Example usage:
+#
+# $(eval $(call DEFINE_OBJECT_RULE,TARGET,foo.c))
+#
+# Note this also attempts to include the dependency file for this
+# source file.
+#
+# The DEFINE_OBJECT_RULE is functionally equivalent to
+# DEFINE_OBJECT_RULE_WITH_OBJECT_NAME, but infers the object file name
+# from the source file name (this is normally what you want).
+##############################################################################
+
+define DEFINE_OBJECT_RULE_WITH_OBJECT_NAME
+ $(3): $(2)
+ @$(MKDIR) $(OUTPUTDIR)
+ $$(call quiet_cmd,$(call host_target_cc,$(1))) \
+ $$($(call host_target_cflags,$(1))) -c $$< -o $$@ \
+ $(call AUTO_DEP_CMD,$(1),$(2),$(3))
+
+ -include $$(call BUILD_DEPENDENCY_LIST,$(3))
+
+ # declare empty rule for generating dependency file; we generate the
+ # dependency files implicitly when compiling the source file (see
+ # AUTO_DEP_CMD above), so we don't want gmake to spend time searching
+ # for an explicit rule to generate the dependency file
+ $$(call BUILD_DEPENDENCY_LIST,$(3)): ;
+
+endef
+
+define DEFINE_OBJECT_RULE
+ $$(eval $$(call DEFINE_OBJECT_RULE_WITH_OBJECT_NAME,$(1),$(2),\
+ $$(call BUILD_OBJECT_LIST,$(2))))
+endef
+
+
+##############################################################################
+# STAMP_C - this is a source file that is generated during the build
+# to capture information about the build environment for the utility.
+#
+# The DEFINE_STAMP_C_RULE function is used to define the rule for
+# generating STAMP_C. First argument is a list of dependencies for
+# STAMP_C (g_stamp.o is filtered out of the list); second argument is
+# the name of the program being built.
+#
+# The includer of utils.mk should add $(STAMP_C) to its list of source
+# files
+##############################################################################
+
+STAMP_C = $(OUTPUTDIR)/g_stamp.c
+
+define DEFINE_STAMP_C_RULE
+
+ $$(STAMP_C): $$(filter-out \
+ $$(call BUILD_OBJECT_LIST,$$(STAMP_C)),$(1)) \
+ $$(VERSION_MK)
+ @ $$(RM) $$@
+ @ $$(PRINTF) "const char NV_ID[] = \"nvidia id: " >> $$@
+ @ $$(PRINTF) "$(2): " >> $$@
+ @ $$(PRINTF) "version $$(NVIDIA_VERSION) " >> $$@
+ @ $$(PRINTF) "($$(shell $$(WHOAMI))@$$(shell $$(HOSTNAME_CMD))) " >> $$@
+ @ $$(PRINTF) "$$(shell $(DATE))\";\n" >> $$@
+ @ $$(PRINTF) "const char *pNV_ID = NV_ID + 11;\n" >> $$@
+
+endef
diff --git a/src/libXNVCtrl/version.mk b/src/libXNVCtrl/version.mk
new file mode 100644
index 0000000..64bf1a5
--- /dev/null
+++ b/src/libXNVCtrl/version.mk
@@ -0,0 +1 @@
+NVIDIA_VERSION = 337.12
diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributes.c b/src/libXNVCtrlAttributes/NvCtrlAttributes.c
index ce4b8d1..d8033d2 100644
--- a/src/libXNVCtrlAttributes/NvCtrlAttributes.c
+++ b/src/libXNVCtrlAttributes/NvCtrlAttributes.c
@@ -1039,6 +1039,20 @@ ReturnStatus NvCtrlGetColorRamp(NvCtrlAttributeHandle *handle,
}
+ReturnStatus NvCtrlReloadColorRamp(NvCtrlAttributeHandle *handle)
+{
+ NvCtrlAttributePrivateHandle *h = (NvCtrlAttributePrivateHandle *) handle;
+
+ if (h->target_type == NV_CTRL_TARGET_TYPE_X_SCREEN) {
+ return NvCtrlVidModeReloadColorRamp(h);
+ } else if (h->target_type == NV_CTRL_TARGET_TYPE_DISPLAY) {
+ return NvCtrlXrandrReloadColorRamp(h);
+ }
+
+ return NvCtrlBadHandle;
+}
+
+
/* helper functions private to the libXNVCtrlAttributes backend */
void NvCtrlInitGammaInputStruct(NvCtrlGammaInput *pGammaInput)
diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributes.h b/src/libXNVCtrlAttributes/NvCtrlAttributes.h
index dac483d..e08d749 100644
--- a/src/libXNVCtrlAttributes/NvCtrlAttributes.h
+++ b/src/libXNVCtrlAttributes/NvCtrlAttributes.h
@@ -330,6 +330,13 @@ ReturnStatus NvCtrlGetColorRamp (NvCtrlAttributeHandle *handle,
int *n);
/*
+ * NvCtrlReloadColorRamp() - Reloads the current color ramp for all
+ * channels for the given handle.
+ */
+
+ReturnStatus NvCtrlReloadColorRamp (NvCtrlAttributeHandle *handle);
+
+/*
* NvCtrlQueryTargetCount() - query the number of targets available
* on the server of the given target type. This is used, for example
* to return the number of GPUs the server knows about.
diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributesPrivate.h b/src/libXNVCtrlAttributes/NvCtrlAttributesPrivate.h
index 90204b1..55264bc 100644
--- a/src/libXNVCtrlAttributes/NvCtrlAttributesPrivate.h
+++ b/src/libXNVCtrlAttributes/NvCtrlAttributesPrivate.h
@@ -149,6 +149,9 @@ NvCtrlInitNvControlAttributes (NvCtrlAttributePrivateHandle *);
NvCtrlVidModeAttributes *
NvCtrlInitVidModeAttributes (NvCtrlAttributePrivateHandle *);
+ReturnStatus
+NvCtrlFreeVidModeAttributes (NvCtrlAttributePrivateHandle *);
+
/* Xv attribute functions */
@@ -208,6 +211,8 @@ ReturnStatus NvCtrlXrandrGetColorRamp(NvCtrlAttributePrivateHandle *h,
uint16_t **lut,
int *n);
+ReturnStatus NvCtrlXrandrReloadColorRamp(NvCtrlAttributePrivateHandle *h);
+
/* XF86 Video Mode extension attribute functions */
ReturnStatus NvCtrlVidModeGetColorAttributes(NvCtrlAttributePrivateHandle *h,
@@ -226,6 +231,8 @@ ReturnStatus NvCtrlVidModeGetColorRamp(NvCtrlAttributePrivateHandle *h,
uint16_t **lut,
int *n);
+ReturnStatus NvCtrlVidModeReloadColorRamp(NvCtrlAttributePrivateHandle *h);
+
ReturnStatus
NvCtrlVidModeGetStringAttribute (NvCtrlAttributePrivateHandle *,
unsigned int, int, char **);
diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributesVidMode.c b/src/libXNVCtrlAttributes/NvCtrlAttributesVidMode.c
index 3192f0f..127d83f 100644
--- a/src/libXNVCtrlAttributes/NvCtrlAttributesVidMode.c
+++ b/src/libXNVCtrlAttributes/NvCtrlAttributesVidMode.c
@@ -94,18 +94,30 @@ NvCtrlInitVidModeAttributes(NvCtrlAttributePrivateHandle *h)
return vm;
failed:
- if (vm) {
- free(vm->lut[RED_CHANNEL_INDEX]);
- free(vm->lut[GREEN_CHANNEL_INDEX]);
- free(vm->lut[BLUE_CHANNEL_INDEX]);
- free(vm);
- }
+ NvCtrlFreeVidModeAttributes(h);
return NULL;
} /* NvCtrlInitVidModeAttributes() */
+ReturnStatus NvCtrlFreeVidModeAttributes(NvCtrlAttributePrivateHandle *h)
+{
+ if (!h || !h->vm) {
+ return NvCtrlBadHandle;
+ }
+
+ free(h->vm->lut[RED_CHANNEL_INDEX]);
+ free(h->vm->lut[GREEN_CHANNEL_INDEX]);
+ free(h->vm->lut[BLUE_CHANNEL_INDEX]);
+ free(h->vm);
+
+ h->vm = NULL;
+
+ return NvCtrlSuccess;
+}
+
+
ReturnStatus NvCtrlVidModeGetColorAttributes(NvCtrlAttributePrivateHandle *h,
float contrast[3],
float brightness[3],
@@ -201,6 +213,15 @@ ReturnStatus NvCtrlVidModeGetColorRamp(NvCtrlAttributePrivateHandle *h,
return NvCtrlSuccess;
}
+ReturnStatus NvCtrlVidModeReloadColorRamp(NvCtrlAttributePrivateHandle *h)
+{
+ NvCtrlFreeVidModeAttributes(h);
+
+ h->vm = NvCtrlInitVidModeAttributes(h);
+
+ return h->vm ? NvCtrlSuccess : NvCtrlError;
+}
+
/*
* Get XF86 Video Mode String Attribute Values
*/
diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributesXrandr.c b/src/libXNVCtrlAttributes/NvCtrlAttributesXrandr.c
index 79f95d5..8ab0315 100644
--- a/src/libXNVCtrlAttributes/NvCtrlAttributesXrandr.c
+++ b/src/libXNVCtrlAttributes/NvCtrlAttributesXrandr.c
@@ -529,3 +529,25 @@ ReturnStatus NvCtrlXrandrGetColorRamp(NvCtrlAttributePrivateHandle *h,
return NvCtrlSuccess;
}
+
+ReturnStatus NvCtrlXrandrReloadColorRamp(NvCtrlAttributePrivateHandle *h)
+{
+ if ((h->xrandr->pGammaRamp != NULL) &&
+ (__libXrandr->XRRFreeGamma != NULL)) {
+ __libXrandr->XRRFreeGamma(h->xrandr->pGammaRamp);
+ } else {
+ assert(!"There should already be a Gamma Ramp");
+ }
+
+ if ((h->xrandr->gammaCrtc != None) && (__libXrandr->XRRGetCrtcGamma != NULL)) {
+ h->xrandr->pGammaRamp =
+ __libXrandr->XRRGetCrtcGamma(h->dpy, h->xrandr->gammaCrtc);
+ NvCtrlInitGammaInputStruct(&h->xrandr->gammaInput);
+ } else {
+ return NvCtrlError;
+ }
+
+ return h->xrandr->pGammaRamp ? NvCtrlSuccess : NvCtrlError;
+
+}
+
diff --git a/src/parse.c b/src/parse.c
index d647594..c2fa7e0 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -90,9 +90,8 @@ const AttributeTableEntry attributeTable[] = {
{ "InitialPixmapPlacement", NV_CTRL_INITIAL_PIXMAP_PLACEMENT, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Controls where X pixmaps are initially created." },
{ "MultiGpuDisplayOwner", NV_CTRL_MULTIGPU_DISPLAY_OWNER, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "GPU ID of the GPU that has the display device(s) used for showing the X screen." },
{ "HWOverlay", NV_CTRL_HWOVERLAY, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "When a workstation overlay is in use, this value is 1 if the hardware overlay is used, or 0 if the overlay is emulated." },
- { "OnDemandVBlankInterrupts", NV_CTRL_ONDEMAND_VBLANK_INTERRUPTS, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Enable/Disable/Query of on-demand vertical blanking interrupt control on the GPU. The 'OnDemandVBlankInterrupts' X server configuration option must be enabled for this option to be available." },
{ "GlyphCache", NV_CTRL_GLYPH_CACHE, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Enable or disable caching of glyphs (text) in video memory." },
- { "SwitchToDisplays", NV_CTRL_SWITCH_TO_DISPLAYS, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,1,0,0,1} }, "Used to set which displays should be active." },
+ { "SwitchToDisplays", NV_CTRL_SWITCH_TO_DISPLAYS, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,1,0,0,1} }, "DEPRECATED." },
{ "NotebookDisplayChangeLidEvent", NV_CTRL_NOTEBOOK_DISPLAY_CHANGE_LID_EVENT, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Reports notebook lid open/close events." },
{ "NotebookInternalLCD", NV_CTRL_NOTEBOOK_INTERNAL_LCD, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,1,0,0,0} }, "DEPRECATED." },
{ "Depth30Allowed", NV_CTRL_DEPTH_30_ALLOWED, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns whether the NVIDIA X driver supports depth 30 on the specified X screen or GPU." },
@@ -110,7 +109,7 @@ const AttributeTableEntry attributeTable[] = {
{ "LogAniso", NV_CTRL_LOG_ANISO, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Enables anisotropic filtering for OpenGL clients; on some NVIDIA hardware, this can only be enabled or disabled; on other hardware different levels of anisotropic filtering can be specified. This setting only takes effect on OpenGL clients started after it is set." },
{ "FSAA", NV_CTRL_FSAA_MODE, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "The full screen antialiasing setting for OpenGL clients. This setting only takes effect on OpenGL clients started after it is set. Enabling antialiasing will disable FXAA." },
{ "TextureSharpen", NV_CTRL_TEXTURE_SHARPEN, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Enables texture sharpening for OpenGL clients. This setting only takes effect on OpenGL clients started after it is set." },
- { "ForceGenericCpu", NV_CTRL_FORCE_GENERIC_CPU, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Inhibit the use of CPU-specific features such as MMX, SSE, or 3DNOW! for OpenGL clients; this option may result in performance loss, but may be useful in conjunction with software such as the Valgrind memory debugger. This setting only takes effect on OpenGL clients started after it is set." },
+ { "ForceGenericCpu", NV_CTRL_FORCE_GENERIC_CPU, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "DEPRECATED." },
{ "GammaCorrectedAALines", NV_CTRL_OPENGL_AA_LINE_GAMMA, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "For OpenGL clients, allow gamma-corrected antialiased lines to consider variances in the color display capabilities of output devices when rendering smooth lines. Only available on recent Quadro GPUs. This setting only takes effect on OpenGL clients started after it is set." },
{ "TextureClamping", NV_CTRL_TEXTURE_CLAMPING, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Define the behavior of OpenGL texture clamping for unbordered textures. If enabled (1), the conformant behavior is used. If disabled (0), GL_CLAMP is remapped to GL_CLAMP_TO_EDGE to avoid seams in applications that rely on this behavior, which was the only option in some very old hardware." },
{ "FXAA", NV_CTRL_FXAA, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Enables or disables the use of FXAA, Fast Approximate Anti-Aliasing. Enabling FXAA will disable regular antialiasing modes." },
@@ -160,7 +159,7 @@ const AttributeTableEntry attributeTable[] = {
{ "PCIEGen", NV_CTRL_GPU_PCIE_GENERATION, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the PCIe generation that this GPU, in this system, is compliant with." },
{ "GPUErrors", NV_CTRL_NUM_GPU_ERRORS_RECOVERED, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the number of GPU errors occurred." },
{ "GPUPowerSource", NV_CTRL_GPU_POWER_SOURCE, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Reports the type of power source of the GPU." },
- { "GPUCurrentPerfMode", NV_CTRL_GPU_CURRENT_PERFORMANCE_MODE, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Reports the current performance mode of the GPU driving the X screen. Running a 3D app, for example, will change this performance mode if Adaptive Clocking is enabled." },
+ { "GPUCurrentPerfMode", NV_CTRL_GPU_CURRENT_PERFORMANCE_MODE, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "DEPRECATED." },
{ "GPUCurrentPerfLevel", NV_CTRL_GPU_CURRENT_PERFORMANCE_LEVEL, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Reports the current Performance level of the GPU driving the X screen. Each Performance level has associated NVClock and Mem Clock values." },
{ "GPUAdaptiveClockState", NV_CTRL_GPU_ADAPTIVE_CLOCK_STATE, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Reports if Adaptive Clocking is Enabled on the GPU driving the X screen." },
{ "GPUPowerMizerMode", NV_CTRL_GPU_POWER_MIZER_MODE, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Allows setting different GPU powermizer modes." },
@@ -187,6 +186,7 @@ const AttributeTableEntry attributeTable[] = {
{ "GPUDoublePrecisionBoostReboot", NV_CTRL_GPU_DOUBLE_PRECISION_BOOST_REBOOT, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Toggles GPU double precision; the change is applied on the next reboot. Only available when the change requires a reboot." },
{ "BaseMosaic", NV_CTRL_BASE_MOSAIC, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the current Base Mosaic configuration." },
{ "MultiGpuMasterPossible", NV_CTRL_MULTIGPU_MASTER_POSSIBLE, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns whether or not the GPU can be configured as the master GPU for a Multi GPU configuration (SLI, SLI Mosaic, Base Mosaic, ...)." },
+ { "VideoEncoderUtilization", NV_CTRL_VIDEO_ENCODER_UTILIZATION, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the video encoder engine utilization as a percentage." },
{ "GPUCurrentClockFreqsString", NV_CTRL_STRING_GPU_CURRENT_CLOCK_FREQS, STR_ATTR, {0,0,0,0,1,0}, {}, "Returns the current GPU, memory and Processor clocks of the graphics device driving the X screen." },
{ "GPUPerfModes", NV_CTRL_STRING_PERFORMANCE_MODES, STR_ATTR, {0,0,0,0,1,0}, {}, "Returns a string with all the performance modes defined for this GPU along with their associated NV Clock and Memory Clock values." },
{ "GpuUUID", NV_CTRL_STRING_GPU_UUID, STR_ATTR, {0,0,0,0,1,0}, {}, "Returns the global unique identifier of the GPU." },
@@ -307,8 +307,8 @@ const AttributeTableEntry attributeTable[] = {
{ "RefreshRate", NV_CTRL_REFRESH_RATE, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {1,0,0,0,0,0,0} }, "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, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,1,0,0,0,0,0} }, "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, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Adjust the amount of overscan compensation scaling, in pixels, to apply to the specified display device." },
- { "ColorSpace", NV_CTRL_COLOR_SPACE, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Sets the color space of the signal sent to the display device." },
- { "ColorRange", NV_CTRL_COLOR_RANGE, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Sets the color range of the signal sent to the display device." },
+ { "ColorSpace", NV_CTRL_COLOR_SPACE, INT_ATTR, {1,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Sets the color space of the signal sent to the display device." },
+ { "ColorRange", NV_CTRL_COLOR_RANGE, INT_ATTR, {1,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Sets the color range of the signal sent to the display device." },
{ "SynchronousPaletteUpdates", NV_CTRL_SYNCHRONOUS_PALETTE_UPDATES, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Controls whether colormap updates are synchronized with X rendering." },
{ "CurrentMetaModeID", NV_CTRL_CURRENT_METAMODE_ID, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "The ID of the current MetaMode." },
{ "RandROutputID", NV_CTRL_DISPLAY_RANDR_OUTPUT_ID, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "The RandR Output ID that corresponds to the display device." },
@@ -327,7 +327,7 @@ const AttributeTableEntry attributeTable[] = {
{ "TVSaturation", NV_CTRL_TV_SATURATION, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Adjusts the amount of saturation on the specified display device." },
/* X Video */
- { "XVideoSyncToDisplay", NV_CTRL_XV_SYNC_TO_DISPLAY, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,1,0,1,0} }, "Controls which display device is synced to by the texture and blitter adaptors when they are set to synchronize to the vertical blanking." },
+ { "XVideoSyncToDisplay", NV_CTRL_XV_SYNC_TO_DISPLAY, INT_ATTR, {0,0,0,0,1,0}, { .int_flags = {0,0,0,1,0,1,0} }, "DEPRECATED: Use \"XVideoSyncToDisplayID\" instead." },
{ "XVideoSyncToDisplayID", NV_CTRL_XV_SYNC_TO_DISPLAY_ID, INT_ATTR, {0,0,0,0,0,0}, { .int_flags = {0,0,0,0,1,0,0} }, "Controls which display device is synced to by the texture and blitter adaptors when they are set to synchronize to the vertical blanking." },
/* 3D Vision Pro */
@@ -369,7 +369,7 @@ const int attributeTableLen = ARRAY_LEN(attributeTable);
* the last attribute that the table knows about.
*/
-#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_THERMAL_COOLER_SPEED
+#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_GPU_MEM_TRANSFER_RATE_OFFSET
#warning "Have you forgotten to add a new integer attribute to attributeTable?"
#endif
diff --git a/src/src.mk b/src/src.mk
index e3d5aa7..bd1616b 100644
--- a/src/src.mk
+++ b/src/src.mk
@@ -207,7 +207,6 @@ GTK_SRC += gtk+-2.x/ctkvcs.c
GTK_SRC += gtk+-2.x/ctkdisplayconfig-utils.c
GTK_SRC += gtk+-2.x/ctkgvo-banner.c
GTK_SRC += gtk+-2.x/ctkgvo-sync.c
-GTK_SRC += gtk+-2.x/ctkpowersavings.c
GTK_SRC += gtk+-2.x/ctkgvi.c
GTK_SRC += gtk+-2.x/ctklicense.c
GTK_SRC += gtk+-2.x/ctkecc.c
@@ -256,7 +255,6 @@ GTK_EXTRA_DIST += gtk+-2.x/ctkgpu.h
GTK_EXTRA_DIST += gtk+-2.x/ctkbanner.h
GTK_EXTRA_DIST += gtk+-2.x/ctkvcs.h
GTK_EXTRA_DIST += gtk+-2.x/ctkdisplayconfig-utils.h
-GTK_EXTRA_DIST += gtk+-2.x/ctkpowersavings.h
GTK_EXTRA_DIST += gtk+-2.x/ctkgvo-banner.h
GTK_EXTRA_DIST += gtk+-2.x/ctkgvo-sync.h
GTK_EXTRA_DIST += gtk+-2.x/ctkgvi.h
@@ -274,25 +272,28 @@ NVIDIA_SETTINGS_EXTRA_DIST += $(GTK_EXTRA_DIST)
#
# files in the src/jansson directory of nvidia-settings
#
-JANSSON_SRC += jansson/load.c
-JANSSON_SRC += jansson/value.c
-JANSSON_SRC += jansson/pack_unpack.c
-JANSSON_SRC += jansson/utf.c
JANSSON_SRC += jansson/dump.c
-JANSSON_SRC += jansson/strconv.c
-JANSSON_SRC += jansson/strbuffer.c
-JANSSON_SRC += jansson/memory.c
JANSSON_SRC += jansson/error.c
JANSSON_SRC += jansson/hashtable.c
+JANSSON_SRC += jansson/hashtable_seed.c
+JANSSON_SRC += jansson/load.c
+JANSSON_SRC += jansson/memory.c
+JANSSON_SRC += jansson/pack_unpack.c
+JANSSON_SRC += jansson/strbuffer.c
+JANSSON_SRC += jansson/strconv.c
+JANSSON_SRC += jansson/utf.c
+JANSSON_SRC += jansson/value.c
NVIDIA_SETTINGS_SRC += $(JANSSON_SRC)
-JANSSON_EXTRA_DIST += jansson/utf.h
+JANSSON_EXTRA_DIST += jansson/hashtable.h
JANSSON_EXTRA_DIST += jansson/jansson_config.h
-JANSSON_EXTRA_DIST += jansson/strbuffer.h
JANSSON_EXTRA_DIST += jansson/jansson.h
-JANSSON_EXTRA_DIST += jansson/hashtable.h
+JANSSON_EXTRA_DIST += jansson/jansson_private_config.h
JANSSON_EXTRA_DIST += jansson/jansson_private.h
+JANSSON_EXTRA_DIST += jansson/lookup3.h
+JANSSON_EXTRA_DIST += jansson/strbuffer.h
+JANSSON_EXTRA_DIST += jansson/utf.h
NVIDIA_SETTINGS_EXTRA_DIST += $(JANSSON_EXTRA_DIST)
diff --git a/src/version.mk b/src/version.mk
index 434103e..64bf1a5 100644
--- a/src/version.mk
+++ b/src/version.mk
@@ -1 +1 @@
-NVIDIA_VERSION = 334.21
+NVIDIA_VERSION = 337.12
diff --git a/version.mk b/version.mk
index 434103e..64bf1a5 100644
--- a/version.mk
+++ b/version.mk
@@ -1 +1 @@
-NVIDIA_VERSION = 334.21
+NVIDIA_VERSION = 337.12