diff options
author | Aaron Plattner <aplattner@nvidia.com> | 2008-02-12 21:29:00 -0800 |
---|---|---|
committer | Aaron Plattner <aplattner@nvidia.com> | 2008-02-12 21:29:00 -0800 |
commit | f984a7a8a1e090275f54c8c5ba33d30950a0c1f6 (patch) | |
tree | ae60c4a8364480be6f06f25a67424a9d1e2582d4 | |
parent | 9e1bb0627faf1777bfe0db3d8810704422581b67 (diff) |
169.04169.04
35 files changed, 1853 insertions, 409 deletions
diff --git a/samples/nv-control-dpy.c b/samples/nv-control-dpy.c index f74d4ec..b137a45 100644 --- a/samples/nv-control-dpy.c +++ b/samples/nv-control-dpy.c @@ -77,7 +77,7 @@ int main(int argc, char *argv[]) screen = DefaultScreen(dpy); if (!XNVCTRLIsNvScreen(dpy, screen)) { - fprintf(stderr, "The NV-CONTROL X not available on screen " + fprintf(stderr, "The NV-CONTROL X extension is not available on screen " "%d of '%s'.\n\n", screen, XDisplayName(NULL)); return 1; } @@ -207,6 +207,8 @@ int main(int argc, char *argv[]) printf("Current Modeline for %s:\n", displayDeviceNames[nDisplayDevice++]); printf(" %s\n\n", str); + + XFree(str); } } @@ -387,6 +389,8 @@ int main(int argc, char *argv[]) } printf("current metamode: \"%s\"\n\n", str); + + XFree(str); } @@ -506,6 +510,7 @@ int main(int argc, char *argv[]) if (!ret) { fprintf(stderr, "Failed to query VertRefresh for %s.\n\n", display_device_name(mask)); + XFree(str0); return 1; } @@ -655,6 +660,7 @@ int main(int argc, char *argv[]) printf(" %d", pData[j]); } printf("\n"); + XFree(pData); } @@ -704,6 +710,7 @@ int main(int argc, char *argv[]) printf(" %d", pData[j]); } printf("\n"); + XFree(pData); } printf("\n"); diff --git a/samples/nv-control-events.c b/samples/nv-control-events.c index 5b8a618..102a16b 100644 --- a/samples/nv-control-events.c +++ b/samples/nv-control-events.c @@ -345,12 +345,20 @@ static const char *attr2str(int n) case NV_CTRL_FSAA_MODE: return "fsaa mode"; break; case NV_CTRL_TEXTURE_SHARPEN: return "texture sharpen"; break; case NV_CTRL_EMULATE: return "OpenGL software emulation"; break; + case NV_CTRL_CONNECTED_DISPLAYS: return "connected displays"; break; + case NV_CTRL_ENABLED_DISPLAYS: return "enabled displays"; break; case NV_CTRL_FRAMELOCK_MASTER: return "frame lock master"; break; case NV_CTRL_FRAMELOCK_POLARITY: return "frame lock sync edge"; break; case NV_CTRL_FRAMELOCK_SYNC_DELAY: return "frame lock sync delay"; break; case NV_CTRL_FRAMELOCK_SYNC_INTERVAL: return "frame lock sync interval"; break; + case NV_CTRL_FRAMELOCK_PORT0_STATUS: return "frame lock port 0 status"; break; + case NV_CTRL_FRAMELOCK_PORT1_STATUS: return "frame lock port 1 status"; break; + case NV_CTRL_FRAMELOCK_HOUSE_STATUS: return "frame lock house status"; break; case NV_CTRL_FRAMELOCK_SYNC: return "frame lock sync"; break; + case NV_CTRL_FRAMELOCK_SYNC_READY: return "frame lock sync ready"; break; + case NV_CTRL_FRAMELOCK_STEREO_SYNC: return "frame lock stereo sync"; break; case NV_CTRL_FRAMELOCK_TEST_SIGNAL: return "frame lock test signal"; break; + case NV_CTRL_FRAMELOCK_ETHERNET_DETECTED: return "frame lock ethernet detected"; break; case NV_CTRL_FRAMELOCK_VIDEO_MODE: return "frame lock video mode"; break; case NV_CTRL_FORCE_GENERIC_CPU: return "force generic cpu"; break; case NV_CTRL_OPENGL_AA_LINE_GAMMA: return "opengl aa line gamma"; break; @@ -380,7 +388,27 @@ static const char *attr2str(int n) case NV_CTRL_AMBIENT_TEMPERATURE: return "ambient temperature"; break; case NV_CTRL_PBUFFER_SCANOUT_XID: return "scanout pbuffer xid"; break; - /* XXX GVO stuff */ + case NV_CTRL_GVO_SUPPORTED: return "x screen supports gvo"; break; + case NV_CTRL_GVO_SYNC_MODE: return "gvo sync mode"; break; + case NV_CTRL_GVO_SYNC_SOURCE: return "gvo sync source"; break; + case NV_CTRL_GVO_OUTPUT_VIDEO_FORMAT: return "gvo output video format"; break; + case NV_CTRL_GVO_DISPLAY_X_SCREEN: return "gvo clone mode"; break; + case NV_CTRL_GVO_COMPOSITE_SYNC_INPUT_DETECTED: return "gvo composite sync input is detected"; break; + case NV_CTRL_GVO_COMPOSITE_SYNC_INPUT_DETECT_MODE: return "gvo composite sync input detect mode"; break; + case NV_CTRL_GVO_SDI_SYNC_INPUT_DETECTED: return "gvo sync input detected"; break; + case NV_CTRL_GVO_VIDEO_OUTPUTS: return "gvo video outputs"; break; + case NV_CTRL_GVO_FIRMWARE_VERSION: return "gvo firmware version"; break; + case NV_CTRL_GVO_SYNC_DELAY_PIXELS: return "gvo sync delay pixels"; break; + case NV_CTRL_GVO_SYNC_DELAY_LINES: return "gvo sync delay lines"; break; + case NV_CTRL_GVO_INPUT_VIDEO_FORMAT_REACQUIRE: return "gvo input video format reacquire"; break; + case NV_CTRL_GVO_GLX_LOCKED: return "gvo glx locked"; break; + case NV_CTRL_GVO_X_SCREEN_PAN_X: return "gvo x screen pan x"; break; + case NV_CTRL_GVO_X_SCREEN_PAN_Y: return "gvo x screen pan y"; break; + case NV_CTRL_GVO_OVERRIDE_HW_CSC: return "gvo override hw csc"; break; + case NV_CTRL_GVO_CAPABILITIES: return "gvo capabilities"; break; + case NV_CTRL_GVO_COMPOSITE_TERMINATION: return "gvo composite termination"; break; + case NV_CTRL_GVO_FLIP_QUEUE_SIZE: return "gvo flip queue size"; break; + case NV_CTRL_GVO_LOCK_OWNER: return "gvo lock owner"; break; case NV_CTRL_GPU_OVERCLOCKING_STATE: return "overclocking state"; break; case NV_CTRL_GPU_2D_CLOCK_FREQS: return "gpu 2d clock frequencies"; break; @@ -399,12 +427,33 @@ static const char *attr2str(int n) case NV_CTRL_SHOW_SLI_HUD: return "show sli hud"; break; case NV_CTRL_XV_SYNC_TO_DISPLAY: return "xv sync to display"; break; - /* XXX More GVO stuff */ - case NV_CTRL_ASSOCIATED_DISPLAY_DEVICES: return "associated_display_devices"; break; case NV_CTRL_FRAMELOCK_SLAVES: return "frame lock slaves"; break; + case NV_CTRL_FRAMELOCK_MASTERABLE: return "frame lock masterable"; break; case NV_CTRL_PROBE_DISPLAYS: return "probed displays"; break; + case NV_CTRL_REFRESH_RATE: return "refresh rate"; break; + case NV_CTRL_CURRENT_SCANLINE: return "current scanline"; break; + case NV_CTRL_INITIAL_PIXMAP_PLACEMENT: return "initial pixmap placement"; break; + case NV_CTRL_PCI_BUS: return "pci bus"; break; + case NV_CTRL_PCI_DEVICE: return "pci device"; break; + case NV_CTRL_PCI_FUNCTION: return "pci function"; break; + case NV_CTRL_FRAMELOCK_FPGA_REVISION: return "framelock fpga revision"; break; + case NV_CTRL_MAX_SCREEN_WIDTH: return "max screen width"; break; + case NV_CTRL_MAX_SCREEN_HEIGHT: return "max screen height"; break; + case NV_CTRL_MAX_DISPLAYS: return "max displays"; break; + case NV_CTRL_DYNAMIC_TWINVIEW: return "dynamic twinview"; break; + case NV_CTRL_MULTIGPU_DISPLAY_OWNER: return "multigpu display owner"; break; + case NV_CTRL_GPU_SCALING: return "gpu scaling"; break; + case NV_CTRL_FRONTEND_RESOLUTION: return "frontend resolution"; break; + case NV_CTRL_BACKEND_RESOLUTION: return "backend resolution"; break; + case NV_CTRL_FLATPANEL_NATIVE_RESOLUTION: return "flatpanel native resolution"; break; + case NV_CTRL_FLATPANEL_BEST_FIT_RESOLUTION: return "flatpanel best fit resolution"; break; + case NV_CTRL_GPU_SCALING_ACTIVE: return "gpu scaling active"; break; + case NV_CTRL_DFP_SCALING_ACTIVE: return "dfp scaling active"; break; + case NV_CTRL_FSAA_APPLICATION_ENHANCED: return "fsaa application enhanced"; break; + case NV_CTRL_FRAMELOCK_SYNC_RATE_4: return "framelock sync rate (4)"; break; + default: return "Unknown"; } diff --git a/samples/nv-control-framelock.c b/samples/nv-control-framelock.c index 2e251ee..83778fb 100644 --- a/samples/nv-control-framelock.c +++ b/samples/nv-control-framelock.c @@ -202,6 +202,8 @@ static void do_query(Display *dpy) } /* Done disabling GPUs */ + XFree(data); + } /* Done disabling Frame Lock Devices */ } /* do_query() */ @@ -435,6 +437,8 @@ static void do_enable(Display *dpy) } /* Done enabling GPUs */ + XFree(data); + } /* Done enabling framelocks */ } @@ -511,6 +515,8 @@ static void do_disable(Display *dpy) } /* Done disabling GPUs */ + XFree(data); + } /* Done disabling Frame Lock Devices */ } /* do_disable() */ diff --git a/samples/nv-control-targets.c b/samples/nv-control-targets.c index bdee17c..9866df3 100644 --- a/samples/nv-control-targets.c +++ b/samples/nv-control-targets.c @@ -277,6 +277,7 @@ int main(int argc, char *argv[]) &display_devices); if (!ret) { fprintf(stderr, "Failed to query connected displays\n"); + XFree(pData); return 1; } printf(" Display Device Mask (Connected) : 0x%08x\n", @@ -293,6 +294,7 @@ int main(int argc, char *argv[]) &display_devices); if (!ret) { fprintf(stderr, "Failed to query enabled displays\n"); + XFree(pData); return 1; } printf(" Display Device Mask (Enabled) : 0x%08x\n", @@ -319,6 +321,7 @@ int main(int argc, char *argv[]) str); } } + XFree(pData); } return 0; diff --git a/src/XF86Config-parser/Flags.c b/src/XF86Config-parser/Flags.c index 21413c9..b86b7a4 100644 --- a/src/XF86Config-parser/Flags.c +++ b/src/XF86Config-parser/Flags.c @@ -123,30 +123,26 @@ xconfigParseFlagsSection (void) int i = 0; while (ServerFlagsTab[i].token != -1) { - char *tmp; - if (ServerFlagsTab[i].token == token) { + char buff[16]; char *valstr = NULL; - /* can't use strdup because it calls malloc */ - tmp = xconfigStrdup (ServerFlagsTab[i].name); if (hasvalue) { tokentype = xconfigGetSubToken(&(ptr->comment)); if (strvalue) { if (tokentype != STRING) - Error (QUOTE_MSG, tmp); + Error (QUOTE_MSG, ServerFlagsTab[i].name); valstr = val.str; } else { if (tokentype != NUMBER) - Error (NUMBER_MSG, tmp); - valstr = malloc(16); - if (valstr) - sprintf(valstr, "%d", val.num); + Error (NUMBER_MSG, ServerFlagsTab[i].name); + snprintf(buff, 16, "%d", val.num); + valstr = buff; } } ptr->options = xconfigAddNewOption - (ptr->options, tmp, valstr); + (ptr->options, ServerFlagsTab[i].name, valstr); } i++; } @@ -185,8 +181,8 @@ xconfigPrintServerFlagsSection (FILE * f, XConfigFlagsPtr flags) fprintf (f, "EndSection\n\n"); } -static XConfigOptionPtr -addNewOption2 (XConfigOptionPtr head, char *name, char *val, int used) +XConfigOptionPtr +xconfigAddNewOption (XConfigOptionPtr head, const char *name, const char *val) { XConfigOptionPtr new, old = NULL; @@ -196,12 +192,11 @@ addNewOption2 (XConfigOptionPtr head, char *name, char *val, int used) TEST_FREE(old->val); new = old; } else { - new = calloc (1, sizeof (XConfigOptionRec)); + new = calloc(1, sizeof (XConfigOptionRec)); new->next = NULL; } - new->name = name; - new->val = val; - new->used = used; + new->name = xconfigStrdup(name); + new->val = xconfigStrdup(val); if (old == NULL) return ((XConfigOptionPtr) xconfigAddListItem ((GenericListPtr) head, @@ -210,12 +205,6 @@ addNewOption2 (XConfigOptionPtr head, char *name, char *val, int used) return head; } -XConfigOptionPtr -xconfigAddNewOption (XConfigOptionPtr head, char *name, char *val) -{ - return addNewOption2(head, name, val, 0); -} - void xconfigFreeFlags (XConfigFlagsPtr flags) { @@ -233,11 +222,8 @@ xconfigOptionListDup (XConfigOptionPtr opt) while (opt) { - newopt = xconfigAddNewOption(newopt, xconfigStrdup(opt->name), - xconfigStrdup(opt->val)); - newopt->used = opt->used; - if (opt->comment) - newopt->comment = xconfigStrdup(opt->comment); + newopt = xconfigAddNewOption(newopt, opt->name, opt->val); + newopt->comment = xconfigStrdup(opt->comment); opt = opt->next; } return newopt; @@ -276,7 +262,7 @@ xconfigOptionValue(XConfigOptionPtr opt) } XConfigOptionPtr -xconfigNewOption(char *name, char *value) +xconfigNewOption(const char *name, const char *value) { XConfigOptionPtr opt; @@ -284,10 +270,9 @@ xconfigNewOption(char *name, char *value) if (!opt) return NULL; - opt->used = 0; - opt->next = 0; - opt->name = name; - opt->val = value; + opt->name = xconfigStrdup(name); + opt->val = xconfigStrdup(value); + opt->next = NULL; return opt; } @@ -388,39 +373,6 @@ xconfigFindOptionBoolean (XConfigOptionPtr list, const char *name) return 0; } -XConfigOptionPtr -xconfigOptionListCreate( const char **options, int count, int used ) -{ - XConfigOptionPtr p = NULL; - char *t1, *t2; - int i; - - if (count == -1) - { - for (count = 0; options[count]; count++) - ; - } - if( (count % 2) != 0 ) - { - xconfigErrorMsg(InternalErrorMsg, "xconfigOptionListCreate: count must " - "be an even number.\n"); - return (NULL); - } - for (i = 0; i < count; i += 2) - { - /* can't use strdup because it calls malloc */ - t1 = malloc (sizeof (char) * - (strlen (options[i]) + 1)); - strcpy (t1, options[i]); - t2 = malloc (sizeof (char) * - (strlen (options[i + 1]) + 1)); - strcpy (t2, options[i + 1]); - p = addNewOption2 (p, t1, t2, used); - } - - return (p); -} - /* the 2 given lists are merged. If an option with the same name is present in * both, the option from the user list - specified in the second argument - * is used. The end result is a single valid list of options. Duplicates diff --git a/src/XF86Config-parser/Generate.c b/src/XF86Config-parser/Generate.c index 008730a..0b6c9bd 100644 --- a/src/XF86Config-parser/Generate.c +++ b/src/XF86Config-parser/Generate.c @@ -450,7 +450,7 @@ XConfigMonitorPtr xconfigAddMonitor(XConfigPtr config, int count) monitor->vrefresh[0].lo = 50.0; monitor->vrefresh[0].hi = 150.0; - opt = xconfigAddNewOption(opt, xconfigStrdup("DPMS"), NULL); + opt = xconfigAddNewOption(opt, "DPMS", NULL); monitor->options = opt; @@ -584,7 +584,7 @@ static void add_inputref(XConfigPtr config, XConfigLayoutPtr layout, inputRef->input_name = xconfigStrdup(name); inputRef->input = xconfigFindInput(inputRef->input_name, config->inputs); inputRef->options = - xconfigAddNewOption(NULL, xconfigStrdup(coreKeyword), NULL); + xconfigAddNewOption(NULL, coreKeyword, NULL); inputRef->next = layout->inputs; layout->inputs = inputRef; @@ -1032,20 +1032,19 @@ int xconfigAddMouse(GenerateOptions *gop, XConfigPtr config) device_path = xconfigStrcat("/dev/", entry->device, NULL); - opt = xconfigAddNewOption(opt, xconfigStrdup("Protocol"), - xconfigStrdup(entry->Xproto)); - opt = xconfigAddNewOption(opt, xconfigStrdup("Device"), device_path); - opt = xconfigAddNewOption(opt, xconfigStrdup("Emulate3Buttons"), - entry->emulate3 ? - xconfigStrdup("yes") : xconfigStrdup("no")); + opt = xconfigAddNewOption(opt, "Protocol", entry->Xproto); + opt = xconfigAddNewOption(opt, "Device", device_path); + opt = xconfigAddNewOption(opt, "Emulate3Buttons", + (entry->emulate3 ? "yes" : "no")); + TEST_FREE(device_path); + /* * This will make wheel mice work, and non-wheel mice should * ignore ZAxisMapping */ - opt = xconfigAddNewOption(opt, xconfigStrdup("ZAxisMapping"), - xconfigStrdup("4 5")); + opt = xconfigAddNewOption(opt, "ZAxisMapping", "4 5"); input->options = opt; @@ -1299,21 +1298,13 @@ int xconfigAddKeyboard(GenerateOptions *gop, XConfigPtr config) */ if (entry && entry->layout) - opt = xconfigAddNewOption(opt, - xconfigStrdup("XkbLayout"), - xconfigStrdup(entry->layout)); + opt = xconfigAddNewOption(opt, "XkbLayout", entry->layout); if (entry && entry->model) - opt = xconfigAddNewOption(opt, - xconfigStrdup("XkbModel"), - xconfigStrdup(entry->model)); + opt = xconfigAddNewOption(opt, "XkbModel", entry->model); if (entry && entry->variant) - opt = xconfigAddNewOption(opt, - xconfigStrdup("XkbVariant"), - xconfigStrdup(entry->variant)); + opt = xconfigAddNewOption(opt, "XkbVariant", entry->variant); if (entry && entry->options) - opt = xconfigAddNewOption(opt, - xconfigStrdup("XkbOptions"), - xconfigStrdup(entry->options)); + opt = xconfigAddNewOption(opt, "XkbOptions", entry->options); input->options = opt; diff --git a/src/XF86Config-parser/Input.c b/src/XF86Config-parser/Input.c index 1665600..4b660f6 100644 --- a/src/XF86Config-parser/Input.c +++ b/src/XF86Config-parser/Input.c @@ -239,9 +239,9 @@ static int getCoreInputDevice(GenerateOptions *gop, opt2 = xconfigFindOption(inputRef->options, coreKeyword); if (opt1 || opt2) { - if (!core) { - core = input; - } else { + if (!core) { + core = input; + } else { if (opt1) input->options = xconfigRemoveOption(input->options, opt1); if (opt2) inputRef->options = @@ -265,13 +265,13 @@ static int getCoreInputDevice(GenerateOptions *gop, */ if (!core) { - for (input = config->inputs; input; input = input->next) { - if (xconfigFindOption(input->options, coreKeyword)) { + for (input = config->inputs; input; input = input->next) { + if (xconfigFindOption(input->options, coreKeyword)) { core = input; found_msg = foundMsg0; break; - } - } + } + } } /* @@ -285,16 +285,16 @@ static int getCoreInputDevice(GenerateOptions *gop, if (!core) { input = xconfigFindInput(implicitDriverName, config->inputs); - if (!input && defaultDriver0) { - input = xconfigFindInputByDriver(defaultDriver0, config->inputs); - } + if (!input && defaultDriver0) { + input = xconfigFindInputByDriver(defaultDriver0, config->inputs); + } if (!input && defaultDriver1) { - input = xconfigFindInputByDriver(defaultDriver1, config->inputs); + input = xconfigFindInputByDriver(defaultDriver1, config->inputs); + } + if (input) { + core = input; + found_msg = foundMsg1; } - if (input) { - core = input; - found_msg = foundMsg1; - } } /* @@ -368,8 +368,7 @@ static int getCoreInputDevice(GenerateOptions *gop, if (!opt1 && !opt2) { inputRef->options = xconfigAddNewOption(inputRef->options, - strdup(coreKeyword), - NULL); + coreKeyword, NULL); } break; } diff --git a/src/XF86Config-parser/Merge.c b/src/XF86Config-parser/Merge.c index 2931934..a9f2c97 100644 --- a/src/XF86Config-parser/Merge.c +++ b/src/XF86Config-parser/Merge.c @@ -120,8 +120,7 @@ static void xconfigMergeOption(XConfigOptionPtr *dstHead, xconfigAddRemovedOptionComment(comments, dstOption); } *dstHead = xconfigAddNewOption - (*dstHead, xconfigStrdup(name), - xconfigStrdup(xconfigOptionValue(srcOption))); + (*dstHead, name, xconfigOptionValue(srcOption)); } } @@ -402,8 +401,7 @@ static int xconfigMergeDriverOptions(XConfigScreenPtr dstScreen, dstScreen->options = xconfigAddNewOption(dstScreen->options, - xconfigStrdup(name), - xconfigStrdup(xconfigOptionValue(option))); + name, xconfigOptionValue(option)); option = option->next; } @@ -424,7 +422,6 @@ static int xconfigMergeDisplays(XConfigScreenPtr dstScreen, { XConfigDisplayPtr dstDisplay; XConfigDisplayPtr srcDisplay; - XConfigOptionPtr srcOption; XConfigModePtr srcMode, dstMode, lastDstMode; /* Free all the displays in the destination screen */ @@ -458,14 +455,7 @@ static int xconfigMergeDisplays(XConfigScreenPtr dstScreen, /* Copy options over */ - srcOption = srcDisplay->options; - while (srcOption) { - xconfigMergeOption(&(dstDisplay->options), - &(srcDisplay->options), - xconfigOptionName(srcOption), - NULL); - srcOption = srcOption->next; - } + dstDisplay->options = xconfigOptionListDup(srcDisplay->options); /* Copy modes over */ diff --git a/src/XF86Config-parser/Pointer.c b/src/XF86Config-parser/Pointer.c index d1e282a..ed49669 100644 --- a/src/XF86Config-parser/Pointer.c +++ b/src/XF86Config-parser/Pointer.c @@ -111,76 +111,68 @@ xconfigParsePointerSection (void) if (xconfigGetSubToken (&(ptr->comment)) != STRING) Error (QUOTE_MSG, "Protocol"); ptr->options = xconfigAddNewOption(ptr->options, - xconfigStrdup("Protocol"), - val.str); + "Protocol", val.str); break; case PDEVICE: if (xconfigGetSubToken (&(ptr->comment)) != STRING) Error (QUOTE_MSG, "Device"); ptr->options = xconfigAddNewOption(ptr->options, - xconfigStrdup("Device"), - val.str); + "Device", val.str); break; case EMULATE3: ptr->options = - xconfigAddNewOption(ptr->options, - xconfigStrdup("Emulate3Buttons"), - NULL); + xconfigAddNewOption(ptr->options, "Emulate3Buttons", NULL); break; case EM3TIMEOUT: if (xconfigGetSubToken (&(ptr->comment)) != NUMBER || val.num < 0) Error (POSITIVE_INT_MSG, "Emulate3Timeout"); s = xconfigULongToString(val.num); ptr->options = - xconfigAddNewOption(ptr->options, - xconfigStrdup("Emulate3Timeout"), - s); + xconfigAddNewOption(ptr->options, "Emulate3Timeout", s); + TEST_FREE(s); break; case CHORDMIDDLE: - ptr->options = xconfigAddNewOption(ptr->options, - xconfigStrdup("ChordMiddle"), - NULL); + ptr->options = xconfigAddNewOption(ptr->options, "ChordMiddle", + NULL); break; case PBUTTONS: if (xconfigGetSubToken (&(ptr->comment)) != NUMBER || val.num < 0) Error (POSITIVE_INT_MSG, "Buttons"); s = xconfigULongToString(val.num); - ptr->options = xconfigAddNewOption(ptr->options, - xconfigStrdup("Buttons"), s); + ptr->options = xconfigAddNewOption(ptr->options, "Buttons", s); + TEST_FREE(s); break; case BAUDRATE: if (xconfigGetSubToken (&(ptr->comment)) != NUMBER || val.num < 0) Error (POSITIVE_INT_MSG, "BaudRate"); s = xconfigULongToString(val.num); ptr->options = - xconfigAddNewOption(ptr->options, - xconfigStrdup("BaudRate"), s); + xconfigAddNewOption(ptr->options, "BaudRate", s); + TEST_FREE(s); break; case SAMPLERATE: if (xconfigGetSubToken (&(ptr->comment)) != NUMBER || val.num < 0) Error (POSITIVE_INT_MSG, "SampleRate"); s = xconfigULongToString(val.num); ptr->options = - xconfigAddNewOption(ptr->options, - xconfigStrdup("SampleRate"), s); + xconfigAddNewOption(ptr->options, "SampleRate", s); + TEST_FREE(s); break; case PRESOLUTION: if (xconfigGetSubToken (&(ptr->comment)) != NUMBER || val.num < 0) Error (POSITIVE_INT_MSG, "Resolution"); s = xconfigULongToString(val.num); ptr->options = - xconfigAddNewOption(ptr->options, - xconfigStrdup("Resolution"), s); + xconfigAddNewOption(ptr->options, "Resolution", s); + TEST_FREE(s); break; case CLEARDTR: ptr->options = - xconfigAddNewOption(ptr->options, - xconfigStrdup("ClearDTR"), NULL); + xconfigAddNewOption(ptr->options, "ClearDTR", NULL); break; case CLEARRTS: ptr->options = - xconfigAddNewOption(ptr->options, - xconfigStrdup("ClearRTS"), NULL); + xconfigAddNewOption(ptr->options, "ClearRTS", NULL); break; case ZAXISMAPPING: switch (xconfigGetToken(ZMapTab)) { @@ -209,9 +201,8 @@ xconfigParsePointerSection (void) break; } ptr->options = - xconfigAddNewOption(ptr->options, - xconfigStrdup("ZAxisMapping"), - s); + xconfigAddNewOption(ptr->options, "ZAxisMapping", s); + TEST_FREE(s); break; case ALWAYSCORE: break; @@ -226,8 +217,7 @@ xconfigParsePointerSection (void) ptr->identifier = xconfigStrdup(CONF_IMPLICIT_POINTER); ptr->driver = xconfigStrdup("mouse"); - ptr->options = xconfigAddNewOption(ptr->options, - xconfigStrdup("CorePointer"), NULL); + ptr->options = xconfigAddNewOption(ptr->options, "CorePointer", NULL); return ptr; } diff --git a/src/XF86Config-parser/xf86Parser.h b/src/XF86Config-parser/xf86Parser.h index 7013b9b..c81574c 100644 --- a/src/XF86Config-parser/xf86Parser.h +++ b/src/XF86Config-parser/xf86Parser.h @@ -148,7 +148,6 @@ typedef struct __xconfigoptionrec { struct __xconfigoptionrec *next; char *name; char *val; - int used; char *comment; } XConfigOptionRec, *XConfigOptionPtr; @@ -675,22 +674,20 @@ XConfigLoadPtr xconfigRemoveLoadDirective(XConfigLoadPtr head, */ XConfigOptionPtr xconfigAddNewOption(XConfigOptionPtr head, - char *name, char *val); + const char *name, const char *val); XConfigOptionPtr xconfigRemoveOption(XConfigOptionPtr list, XConfigOptionPtr opt); XConfigOptionPtr xconfigOptionListDup(XConfigOptionPtr opt); void xconfigOptionListFree(XConfigOptionPtr opt); char *xconfigOptionName(XConfigOptionPtr opt); char *xconfigOptionValue(XConfigOptionPtr opt); -XConfigOptionPtr xconfigNewOption(char *name, char *value); +XConfigOptionPtr xconfigNewOption(const char *name, const char *value); XConfigOptionPtr xconfigNextOption(XConfigOptionPtr list); XConfigOptionPtr xconfigFindOption(XConfigOptionPtr list, const char *name); char *xconfigFindOptionValue(XConfigOptionPtr list, const char *name); int xconfigFindOptionBoolean (XConfigOptionPtr, const char *name); -XConfigOptionPtr xconfigOptionListCreate(const char **options, - int count, int used); XConfigOptionPtr xconfigOptionListMerge(XConfigOptionPtr head, XConfigOptionPtr tail); diff --git a/src/command-line.c b/src/command-line.c index 6161358..b83d706 100644 --- a/src/command-line.c +++ b/src/command-line.c @@ -56,8 +56,8 @@ static char *nvstrcat(const char *str, ...); */ int __verbosity = VERBOSITY_DEFAULT; - - +int __terse = NV_FALSE; +int __display_device_string = NV_FALSE; /* * print_version() - print version information */ @@ -127,7 +127,7 @@ static const NVGetoptOption __options[] = { "Write the X server configuration to the configuration file, and exit, " "without starting the graphical user interface." }, - { "verbose", 'V', NVGETOPT_HAS_ARGUMENT, NULL, + { "verbose", 'V', NVGETOPT_HAS_ARGUMENT|NVGETOPT_ARGUMENT_IS_OPTIONAL, NULL, "Controls how much information is printed. Valid values are 'errors' " "(print error messages), 'warnings' (print error and warning messages), " "and 'all' (print error, warning and other informational messages). By " @@ -137,6 +137,17 @@ static const NVGetoptOption __options[] = { { "query", 'q', NVGETOPT_HAS_ARGUMENT, print_query_help, NULL }, + { "terse", 't', 0, NULL, + "When querying attribute values with the '--query' commandline option, " + "only print the current value, rather than the more verbose description " + "of the attribute, its valid values, and its current value." }, + + { "display-device-string", 'd', 0, NULL, + "When printing attribute values in response to the '--query' option, " + "if the attribute value is a display device mask, print the value " + "as a list of display devices (e.g., \"CRT-0, DFP-0\"), rather than " + "a hexidecimal bitmask (e.g., 0x00010001)." }, + { "glxinfo", 'g', 0, NULL, "Print GLX Information for the X display and exit." }, @@ -321,7 +332,10 @@ Options *parse_command_line(int argc, char *argv[], char *dpy) case 'c': op->ctrl_display = strval; break; case 'V': __verbosity = VERBOSITY_DEFAULT; - if (nv_strcasecmp(strval, "errors") == NV_TRUE) { + if (!strval) { + /* user didn't give argument, assume "all" */ + __verbosity = VERBOSITY_ALL; + } else if (nv_strcasecmp(strval, "errors") == NV_TRUE) { __verbosity = VERBOSITY_ERROR; } else if (nv_strcasecmp(strval, "warnings") == NV_TRUE) { __verbosity = VERBOSITY_WARNING; @@ -348,6 +362,8 @@ Options *parse_command_line(int argc, char *argv[], char *dpy) break; case CONFIG_FILE_OPTION: op->config = strval; break; case 'g': print_glxinfo(NULL); exit(0); break; + case 't': __terse = NV_TRUE; break; + case 'd': __display_device_string = NV_TRUE; break; default: nv_error_msg("Invalid commandline, please run `%s --help` " "for usage information.\n", argv[0]); diff --git a/src/gtk+-2.x/Makefile.inc b/src/gtk+-2.x/Makefile.inc index 2ff777b..5f7bd6d 100644 --- a/src/gtk+-2.x/Makefile.inc +++ b/src/gtk+-2.x/Makefile.inc @@ -46,6 +46,7 @@ SRC += \ ctkdisplaydevice-tv.c \ ctkdisplaydevice-dfp.c \ ctkthermal.c \ + ctkpowermizer.c \ ctkgvo.c \ ctkgvo-csc.c \ ctkdropdownmenu.c \ @@ -88,6 +89,7 @@ EXTRA_DIST += \ ctkdisplaydevice-dfp.h \ ctkconstants.h \ ctkthermal.h \ + ctkpowermizer.h \ ctkgvo.h \ ctkgvo-csc.h \ ctkdropdownmenu.h \ diff --git a/src/gtk+-2.x/ctkdisplayconfig-utils.c b/src/gtk+-2.x/ctkdisplayconfig-utils.c index eed1149..610ab51 100644 --- a/src/gtk+-2.x/ctkdisplayconfig-utils.c +++ b/src/gtk+-2.x/ctkdisplayconfig-utils.c @@ -923,6 +923,10 @@ void screen_remove_display(nvDisplayPtr display) screen->displays_mask &= ~(display->device_mask); screen->num_displays--; + if (screen->primaryDisplay == display) { + screen->primaryDisplay = NULL; + } + /* Clean up old references to the screen in the display */ display_remove_modes(display); display->screen = NULL; @@ -1713,7 +1717,7 @@ static int gpu_add_screen_from_server(nvGpuPtr gpu, int screen_id, nvScreenPtr screen; int val, tmp; ReturnStatus ret; - + gchar *primary_str = NULL; /* Create the screen structure */ screen = (nvScreenPtr)calloc(1, sizeof(nvScreen)); @@ -1781,8 +1785,31 @@ static int gpu_add_screen_from_server(nvGpuPtr gpu, int screen_id, screen_id, NvCtrlGetTargetId(gpu->handle)); goto fail; } + + /* Query & parse the screen's primary display */ + screen->primaryDisplay = NULL; + ret = NvCtrlGetStringDisplayAttribute + (screen->handle, + 0, + NV_CTRL_STRING_TWINVIEW_XINERAMA_INFO_ORDER, + &primary_str); + + if (ret == NvCtrlSuccess) { + nvDisplayPtr d; + unsigned int device_mask; + /* Parse the device mask */ + parse_read_display_name(primary_str, &device_mask); + /* Find the matching primary display */ + for (d = gpu->displays; d; d = d->next) { + if (d->screen == screen && + d->device_mask & device_mask) { + screen->primaryDisplay = d; + break; + } + } + } /* Add the screen at the end of the gpu's screen list */ gpu->screens = (nvScreenPtr)xconfigAddListItem((GenericListPtr)gpu->screens, @@ -1835,10 +1862,12 @@ static Bool gpu_add_screens_from_server(nvGpuPtr gpu, gchar **err_str) nv_warning_msg("Failed to add screen %d to GPU-%d '%s'.", pData[i], NvCtrlGetTargetId(gpu->handle), gpu->name); + XFree(pData); goto fail; } } + XFree(pData); return TRUE; diff --git a/src/gtk+-2.x/ctkdisplayconfig.c b/src/gtk+-2.x/ctkdisplayconfig.c index d1a5d9f..9d841a7 100644 --- a/src/gtk+-2.x/ctkdisplayconfig.c +++ b/src/gtk+-2.x/ctkdisplayconfig.c @@ -58,12 +58,13 @@ void layout_modified_callback(nvLayoutPtr layout, void *data); static void setup_layout_frame(CtkDisplayConfig *ctk_object); -static void setup_display_frame(CtkDisplayConfig *ctk_object); +static void setup_display_page(CtkDisplayConfig *ctk_object); static void display_config_clicked(GtkWidget *widget, gpointer user_data); static void display_resolution_changed(GtkWidget *widget, gpointer user_data); static void display_refresh_changed(GtkWidget *widget, gpointer user_data); +static void display_modelname_changed(GtkWidget *widget, gpointer user_data); static void display_position_type_changed(GtkWidget *widget, gpointer user_data); static void display_position_offset_activate(GtkWidget *widget, gpointer user_data); @@ -71,7 +72,7 @@ static void display_position_relative_changed(GtkWidget *widget, gpointer user_d static void display_panning_activate(GtkWidget *widget, gpointer user_data); -static void setup_screen_frame(CtkDisplayConfig *ctk_object); +static void setup_screen_page(CtkDisplayConfig *ctk_object); static void screen_depth_changed(GtkWidget *widget, gpointer user_data); @@ -149,12 +150,15 @@ static int __position_table[] = { CONF_ADJ_ABSOLUTE, /* Layout tooltips */ static const char * __layout_xinerama_button_help = -"The Enable Xinerama checkbox enables the Xinerama X extension; Changing " +"The Enable Xinerama checkbox enables the Xinerama X extension; changing " "this option will require restarting your X server."; /* Display tooltips */ +static const char * __dpy_model_help = +"The Display drop-down allows you to select a desired display device."; + static const char * __dpy_resolution_mnu_help = "The Resolution drop-down allows you to select a desired resolution " "for the currently selected display device."; @@ -181,27 +185,32 @@ static const char * __dpy_panning_help = "The Panning Domain sets the total width/height that the display " "device may pan within."; +static const char * __dpy_primary_help = +"The primary display is often used by window managers to know which of the " +"displays in a multi-display setup to show information and other " +"important windows etc; changing this option may require restarting your X " +"server, depending on your window manager."; /* Screen tooltips */ static const char * __screen_depth_help = "The Depth drop-down allows setting of the color quality for the selected " -"screen; Changing this option will require restarting your X server."; +"screen; changing this option will require restarting your X server."; static const char * __screen_position_type_help = "The Position Type drop-down allows you to set how the selected screen " -"is placed within the X server layout; Changing this option will require " +"is placed within the X server layout; changing this option will require " "restarting your X server."; static const char * __screen_position_relative_help = "The Position Relative drop-down allows you to set which other Screen " -"the selected screen should be relative to; Changing this option will " +"the selected screen should be relative to; changing this option will " "require restarting your X server."; static const char * __screen_position_offset_help = "The Position Offset identifies the top left of the selected Screen as " -"an offset from the top left of the X server layout in absolute coordinates; " -"Changing this option will require restarting your X server."; +"an offset from the top left of the X server layout in absolute coordinates; " +"changing this option will require restarting your X server."; static const char * __screen_metamode_help = "The MetaMode selection menu allows you to set the currently displayed " @@ -833,6 +842,23 @@ GtkWidget * create_validation_apply_dialog(CtkDisplayConfig *ctk_object) } /* create_validation_apply_dialog() */ +static void screen_primary_display_toggled(GtkWidget *widget, + gpointer user_data) +{ + CtkDisplayConfig *ctk_object = CTK_DISPLAY_CONFIG(user_data); + gint enabled; + nvDisplayPtr display = ctk_display_layout_get_selected_display + (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout)); + nvScreenPtr screen = display->screen; + enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); + + if (enabled) { + screen->primaryDisplay = display; + } + + //Make the apply button sensitive to user input + gtk_widget_set_sensitive(ctk_object->btn_apply, True); +} /* screen_primary_display_toggled() */ /** ctk_display_config_new() ***************************************** * @@ -844,10 +870,12 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle, CtkConfig *ctk_config) { GObject *object; - CtkDisplayConfig *ctk_object; + CtkDisplayConfig *ctk_object; GtkWidget *banner; GtkWidget *frame; + GtkWidget *notebook; + GtkWidget *tab_label; GtkWidget *hbox; GtkWidget *hbox2; GtkWidget *vbox; @@ -855,9 +883,6 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle, GtkRequisition req; - GtkWidget *vpanel; - GtkWidget *scrolled_window; - GtkWidget *viewport; GtkWidget *menu; GtkWidget *menu_item; @@ -956,10 +981,13 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle, /* Display model name */ - ctk_object->txt_display_model = gtk_label_new(""); - gtk_label_set_selectable(GTK_LABEL(ctk_object->txt_display_model), TRUE); - gtk_misc_set_alignment(GTK_MISC(ctk_object->txt_display_model), 0.0f, 0.5f); - + ctk_object->mnu_display_model = gtk_option_menu_new(); + ctk_config_set_tooltip(ctk_config, ctk_object->mnu_display_model, + __dpy_model_help); + g_signal_connect(G_OBJECT(ctk_object->mnu_display_model), "changed", + G_CALLBACK(display_modelname_changed), + (gpointer) ctk_object); + /* Display configuration (Disabled, TwinView, Separate X screen */ ctk_object->btn_display_config = gtk_button_new_with_label("Configure..."); @@ -1035,6 +1063,7 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle, /* Display modeline modename */ ctk_object->txt_display_modename = gtk_label_new(""); + gtk_label_set_selectable(GTK_LABEL(ctk_object->txt_display_modename), TRUE); /* Display Position Type (Absolute/Relative Menu) */ ctk_object->mnu_display_position_type = gtk_option_menu_new(); @@ -1325,11 +1354,12 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle, { /* Layout section */ frame = gtk_frame_new("Layout"); - hbox = gtk_hbox_new(FALSE, 5); /* main panel */ - vbox = gtk_vbox_new(FALSE, 5); /* layout panel */ - gtk_box_pack_start(GTK_BOX(ctk_object), hbox, FALSE, FALSE, 0); + hbox = gtk_hbox_new(TRUE, 5); /* main panel */ + vbox = gtk_vbox_new(TRUE, 5); /* layout panel */ + gtk_box_pack_start(GTK_BOX(ctk_object), hbox, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5); + gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 5); + gtk_widget_set_size_request(frame, -1, 200); hbox = gtk_hbox_new(FALSE, 5); /* layout panel */ gtk_container_set_border_width(GTK_CONTAINER(hbox), 5); @@ -1339,7 +1369,7 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle, /* Pack the layout widget */ gtk_box_pack_start(GTK_BOX(vbox), ctk_object->obj_layout, - FALSE, FALSE, 0); + TRUE, TRUE, 0); /* Xinerama checkbox */ gtk_box_pack_start(GTK_BOX(vbox), ctk_object->chk_xinerama_enabled, @@ -1347,38 +1377,25 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle, } - /* Scrolled window */ - scrolled_window = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), - GTK_POLICY_NEVER, - GTK_POLICY_AUTOMATIC); - gtk_box_pack_start(GTK_BOX(ctk_object), scrolled_window, TRUE, TRUE, 0); - gtk_widget_set_size_request(scrolled_window, -1, 200); - - viewport = gtk_viewport_new(NULL, NULL); - gtk_viewport_set_shadow_type(GTK_VIEWPORT(viewport), GTK_SHADOW_NONE); - gtk_container_add(GTK_CONTAINER(scrolled_window), viewport); - - - /* Panel for the display/screen sections */ - vpanel = gtk_vbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(viewport), vpanel); + /* Panel for the notebook sections */ + vbox = gtk_vbox_new(FALSE, 5); + gtk_box_pack_start(GTK_BOX(ctk_object), vbox, FALSE, FALSE, 5); { /* Display section */ GtkWidget *longest_hbox; - /* Create the display frame */ - frame = gtk_frame_new("Display"); - ctk_object->display_frame = frame; + /* Create the display page */ + tab_label = gtk_label_new("Display"); + notebook = gtk_notebook_new(); hbox = gtk_hbox_new(FALSE, 5); - gtk_box_pack_start(GTK_BOX(hbox), frame, TRUE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(vpanel), hbox, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(hbox), notebook, TRUE, TRUE, 5); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); /* Generate the major vbox for the display section */ vbox = gtk_vbox_new(FALSE, 5); + ctk_object->display_page = vbox; gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); - gtk_container_add(GTK_CONTAINER(frame), vbox); /* Display Configuration */ hbox = gtk_hbox_new(FALSE, 5); @@ -1395,12 +1412,12 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle, /* Display model name */ hbox = gtk_hbox_new(FALSE, 5); - gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5); label = gtk_label_new("Model:"); gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f); gtk_widget_set_size_request(label, req.width, -1); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 5); - gtk_box_pack_start(GTK_BOX(hbox), ctk_object->txt_display_model, + gtk_box_pack_start(GTK_BOX(hbox), ctk_object->mnu_display_model, TRUE, TRUE, 0); /* Pack the display configuration line */ @@ -1463,26 +1480,39 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle, TRUE, TRUE, 0); ctk_object->box_display_panning = hbox; + /* checkbox for primary display of X screen */ + hbox = gtk_hbox_new(FALSE, 5); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0); + ctk_object->chk_primary_display = + gtk_check_button_new_with_label("Make this Primary Display " + "for X Screen"); + ctk_config_set_tooltip(ctk_config, ctk_object->chk_primary_display, + __dpy_primary_help); + g_signal_connect(G_OBJECT(ctk_object->chk_primary_display), "toggled", + G_CALLBACK(screen_primary_display_toggled), + (gpointer) ctk_object); + + gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f); + gtk_widget_set_size_request(label, req.width, -1); + gtk_box_pack_start(GTK_BOX(hbox), ctk_object->chk_primary_display, + TRUE, TRUE, 0); + gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, tab_label); } /* Display sub-section */ { /* X screen */ - /* Create the X screen frame */ - frame = gtk_frame_new("X Screen"); - ctk_object->screen_frame = frame; - hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(hbox), frame, TRUE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(vpanel), hbox, FALSE, FALSE, 5); + /* Create the X screen page */ + tab_label = gtk_label_new("X Screen"); /* Generate the major vbox for the display section */ vbox = gtk_vbox_new(FALSE, 5); + ctk_object->screen_page = vbox; gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); - gtk_container_add(GTK_CONTAINER(frame), vbox); /* X screen number */ hbox = gtk_hbox_new(FALSE, 5); - gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5); label = gtk_label_new("Screen Number:"); gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f); gtk_widget_size_request(label, &req); @@ -1520,7 +1550,7 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle, ctk_object->box_screen_position = hbox; /* X screen metamode drop down & buttons */ - hbox = gtk_hbox_new(FALSE, 5); + hbox = gtk_hbox_new(FALSE, 5); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); label = gtk_label_new("MetaMode:"); gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f); @@ -1534,6 +1564,7 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle, TRUE, TRUE, 0); ctk_object->box_screen_metamode = hbox; + gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, tab_label); } /* X screen sub-section */ @@ -1665,8 +1696,8 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle, /* Setup the GUI */ setup_layout_frame(ctk_object); - setup_display_frame(ctk_object); - setup_screen_frame(ctk_object); + setup_display_page(ctk_object); + setup_screen_page(ctk_object); return GTK_WIDGET(ctk_object); @@ -1717,6 +1748,8 @@ GtkTextBuffer *ctk_display_config_create_help(GtkTextTagTable *table, "settings for the currently selected display device."); ctk_help_heading(b, &i, "Model"); ctk_help_para(b, &i, "The Model name is the name of the display device."); + ctk_help_heading(b, &i, "Select Display"); + ctk_help_para(b, &i, __dpy_model_help); ctk_help_heading(b, &i, "Resolution"); ctk_help_para(b, &i, __dpy_resolution_mnu_help); ctk_help_heading(b, &i, "Refresh"); @@ -1734,6 +1767,8 @@ GtkTextBuffer *ctk_display_config_create_help(GtkTextTagTable *table, ctk_help_para(b, &i, __dpy_position_offset_help); ctk_help_heading(b, &i, "Panning"); ctk_help_para(b, &i, "%s. (Advanced view only)", __dpy_panning_help); + ctk_help_heading(b, &i, "Primary Display"); + ctk_help_para(b, &i, __dpy_primary_help); ctk_help_para(b, &i, ""); @@ -1823,7 +1858,7 @@ static void setup_layout_frame(CtkDisplayConfig *ctk_object) g_signal_handlers_unblock_by_func (G_OBJECT(ctk_object->chk_xinerama_enabled), G_CALLBACK(xinerama_state_toggled), (gpointer) ctk_object); - + } /* setup_layout_frame() */ @@ -1891,7 +1926,7 @@ static void setup_display_config(CtkDisplayConfig *ctk_object) -/** setup_display_refresh_dropdwon() ********************************* +/** setup_display_refresh_dropdown() ********************************* * * Generates the refresh rate dropdown based on the currently selected * display. @@ -2129,7 +2164,7 @@ static void setup_display_refresh_dropdown(CtkDisplayConfig *ctk_object) -/** setup_display_resolution_dropdwon() ****************************** +/** setup_display_resolution_dropdown() ****************************** * * Generates the resolution dropdown based on the currently selected * display. @@ -2291,6 +2326,109 @@ static void setup_display_resolution_dropdown(CtkDisplayConfig *ctk_object) } /* setup_display_resolution_dropdown() */ +/** generate_display_modelname_dropdown() ******************************** + * + * Generate display modelname dropdown menu. + * + **/ +static GtkWidget* generate_display_modelname_dropdown + (CtkDisplayConfig *ctk_object, int *cur_idx) +{ + GtkWidget *menu; + GtkWidget *menu_item; + nvGpuPtr gpu; + nvDisplayPtr display; + int display_count = 0; + nvDisplayPtr d = ctk_display_layout_get_selected_display + (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout)); + /* Create the display modelname lookup table for the dropdown */ + if (ctk_object->display_model_table) { + free(ctk_object->display_model_table); + } + ctk_object->display_model_table_len = 0; + for (gpu = ctk_object->layout->gpus; gpu; gpu = gpu->next) { + display_count += gpu->num_displays; + } + + ctk_object->display_model_table = + (nvDisplayPtr *)calloc(1, display_count * sizeof(nvDisplayPtr)); + + if (!ctk_object->display_model_table) { + gtk_option_menu_remove_menu + (GTK_OPTION_MENU(ctk_object->mnu_display_model)); + gtk_widget_set_sensitive(ctk_object->mnu_display_model, False); + return NULL; + } + + /* Generate the popup menu */ + menu = gtk_menu_new(); + for (gpu = ctk_object->layout->gpus; gpu; gpu = gpu->next) { + for (display = gpu->displays; display; display = display->next) { + gchar *str, *type; + if (d == display) { + *cur_idx = ctk_object->display_model_table_len; + } + /* Setup the menu item text */ + type = display_get_type_str(display->device_mask, 0); + str = g_strdup_printf("%s (%s on GPU-%d)", + display->name, type, + NvCtrlGetTargetId(gpu->handle)); + menu_item = gtk_menu_item_new_with_label(str); + g_free(str); + g_free(type); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); + gtk_widget_show(menu_item); + ctk_object->display_model_table + [ctk_object->display_model_table_len++] = display; + } + } + return menu; +} /* generate_display_modelname_dropdown() */ + +/** setup_display_modelname_dropdown() ************************** + * + * Setup display modelname dropdown menu. + * + **/ +static void setup_display_modelname_dropdown(CtkDisplayConfig *ctk_object) +{ + GtkWidget *menu; + int cur_idx = 0; /* Currently selected display */ + nvDisplayPtr display = ctk_display_layout_get_selected_display + (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout)); + + /* If no display is selected or there is no screen, hide the frame */ + if (!display) { + gtk_widget_set_sensitive(ctk_object->mnu_display_model, False); + gtk_widget_hide(ctk_object->mnu_display_model); + return; + } + + /* Enable display widgets and setup widget information */ + gtk_widget_set_sensitive(ctk_object->mnu_display_model, True); + + menu = generate_display_modelname_dropdown(ctk_object, &cur_idx); + + /* If menu not generated return */ + if (!menu) { + return; + } + /* Setup the menu and select the current model */ + g_signal_handlers_block_by_func + (G_OBJECT(ctk_object->mnu_display_model), + G_CALLBACK(display_modelname_changed), (gpointer) ctk_object); + + gtk_option_menu_set_menu + (GTK_OPTION_MENU(ctk_object->mnu_display_model), menu); + + gtk_option_menu_set_history + (GTK_OPTION_MENU(ctk_object->mnu_display_model), cur_idx); + + + g_signal_handlers_unblock_by_func + (G_OBJECT(ctk_object->mnu_display_model), + G_CALLBACK(display_modelname_changed), (gpointer) ctk_object); +} /* setup_display_modelname_dropdown() */ /** setup_display_position_type() ************************************ @@ -2516,6 +2654,41 @@ static void setup_display_position(CtkDisplayConfig *ctk_object) } /* setup_display_position */ +static void setup_primary_display(CtkDisplayConfig *ctk_object) +{ + nvDisplayPtr display = ctk_display_layout_get_selected_display + (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout)); + + /* Hide the checkbox if this screen only has one display */ + if (!display || !display->screen || display->screen->num_displays <= 1) { + gtk_widget_hide(ctk_object->chk_primary_display); + return; + } + + gtk_widget_show(ctk_object->chk_primary_display); + + g_signal_handlers_block_by_func + (G_OBJECT(ctk_object->chk_primary_display), + G_CALLBACK(screen_primary_display_toggled), (gpointer) ctk_object); + + if ( display->screen && display == display->screen->primaryDisplay ) { + // Primary display checkbox should be checked. + gtk_toggle_button_set_active + (GTK_TOGGLE_BUTTON(ctk_object->chk_primary_display), + TRUE); + } else { + // This display does not have a screen or is not the screen's + // primary display. + gtk_toggle_button_set_active + (GTK_TOGGLE_BUTTON(ctk_object->chk_primary_display), + FALSE); + } + + g_signal_handlers_unblock_by_func + (G_OBJECT(ctk_object->chk_primary_display), + G_CALLBACK(screen_primary_display_toggled), + (gpointer) ctk_object); +} /* setup_primary_display() */ /** setup_display_panning() ****************************************** * @@ -2560,47 +2733,40 @@ static void setup_display_panning(CtkDisplayConfig *ctk_object) -/** setup_display_frame() ******************************************** +/** setup_display_page() ******************************************** * * Sets up the display frame to reflect the currently selected * display. * **/ -static void setup_display_frame(CtkDisplayConfig *ctk_object) +static void setup_display_page(CtkDisplayConfig *ctk_object) { nvDisplayPtr display = ctk_display_layout_get_selected_display (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout)); - gchar *type; - gchar *str; - /* If no display is selected or there is no screen, hide the frame */ if (!display) { - gtk_widget_set_sensitive(ctk_object->display_frame, False); - gtk_widget_hide(ctk_object->display_frame); + gtk_widget_set_sensitive(ctk_object->display_page, False); + gtk_widget_hide(ctk_object->display_page); return; } /* Enable display widgets and setup widget information */ - gtk_widget_set_sensitive(ctk_object->display_frame, True); + gtk_widget_set_sensitive(ctk_object->display_page, True); - /* Setup the display name */ - type = display_get_type_str(display->device_mask, 0); - str = g_strdup_printf("%s (%s)", display->name, type); - g_free(type); - gtk_label_set_text(GTK_LABEL(ctk_object->txt_display_model), str); - g_free(str); + /* Setup the display modelname dropdown */ + setup_display_modelname_dropdown(ctk_object); - /* Setp the seleted mode modename */ + /* Setup the seleted mode modename */ setup_display_config(ctk_object); - /* Setp the seleted mode modename */ + /* Setup the seleted mode modename */ setup_display_modename(ctk_object); @@ -2615,10 +2781,12 @@ static void setup_display_frame(CtkDisplayConfig *ctk_object) /* Setup panning */ setup_display_panning(ctk_object); + /* Setup first display */ + setup_primary_display(ctk_object); - gtk_widget_show(ctk_object->display_frame); + gtk_widget_show(ctk_object->display_page); -} /* setup_display_frame() */ +} /* setup_display_page() */ @@ -2940,7 +3108,7 @@ static void setup_screen_metamode(CtkDisplayConfig *ctk_object) } - /* Update the meatamode selector button */ + /* Update the metamode selector button */ str = g_strdup_printf("%d - ...", screen->cur_metamode_idx +1); gtk_button_set_label(GTK_BUTTON(ctk_object->btn_screen_metamode), str); g_free(str); @@ -2955,13 +3123,13 @@ static void setup_screen_metamode(CtkDisplayConfig *ctk_object) -/** setup_screen_frame() ********************************************* +/** setup_screen_page() ********************************************* * * Sets up the screen frame to reflect the currently selected screen. * **/ -static void setup_screen_frame(CtkDisplayConfig *ctk_object) +static void setup_screen_page(CtkDisplayConfig *ctk_object) { nvDisplayPtr display = ctk_display_layout_get_selected_display (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout)); @@ -2970,14 +3138,14 @@ static void setup_screen_frame(CtkDisplayConfig *ctk_object) /* If there is no display or no screen selected, hide the frame */ if (!display || !display->screen) { - gtk_widget_set_sensitive(ctk_object->screen_frame, False); - gtk_widget_hide(ctk_object->screen_frame); + gtk_widget_set_sensitive(ctk_object->screen_page, False); + gtk_widget_hide(ctk_object->screen_page); return; } /* Enable display widgets and setup widget information */ - gtk_widget_set_sensitive(ctk_object->screen_frame, True); + gtk_widget_set_sensitive(ctk_object->screen_page, True); /* Setup the screen number */ @@ -2998,9 +3166,9 @@ static void setup_screen_frame(CtkDisplayConfig *ctk_object) setup_screen_metamode(ctk_object); - gtk_widget_show(ctk_object->screen_frame); + gtk_widget_show(ctk_object->screen_page); -} /* setup_screen_frame() */ +} /* setup_screen_page() */ @@ -3439,8 +3607,8 @@ static int validate_layout(CtkDisplayConfig *ctk_object, int validation_type) result = validation_auto_fix(ctk_object); /* Update the GUI to reflect any updates made by auto fix */ - setup_display_frame(ctk_object); - setup_screen_frame(ctk_object); + setup_display_page(ctk_object); + setup_screen_page(ctk_object); return result; case GTK_RESPONSE_REJECT: @@ -3519,8 +3687,8 @@ void layout_selected_callback(nvLayoutPtr layout, void *data) /* Reconfigure GUI to display information about the selected screen. */ - setup_display_frame(ctk_object); - setup_screen_frame(ctk_object); + setup_display_page(ctk_object); + setup_screen_page(ctk_object); get_cur_screen_pos(ctk_object); @@ -4006,6 +4174,11 @@ static void do_configure_display_for_xscreen(CtkDisplayConfig *ctk_object, display->screen = new_screen; + if (display == screen->primaryDisplay) { + new_screen->primaryDisplay = display; + screen->primaryDisplay = NULL; + } + /* Append the screen to the gpu */ gpu->screens = (nvScreenPtr)xconfigAddListItem((GenericListPtr)gpu->screens, @@ -4547,8 +4720,8 @@ static void display_config_clicked(GtkWidget *widget, gpointer user_data) /* Update GUI */ setup_layout_frame(ctk_object); - setup_display_frame(ctk_object); - setup_screen_frame(ctk_object); + setup_display_page(ctk_object); + setup_screen_page(ctk_object); gtk_widget_set_sensitive(ctk_object->btn_apply, True); } @@ -4674,7 +4847,28 @@ static void display_resolution_changed(GtkWidget *widget, gpointer user_data) } /* display_resolution_changed() */ +/** display_modelname_changed() ***************************** + * + * Called when user selectes a new display from display modelname dropdown. + * + **/ +static void display_modelname_changed(GtkWidget *widget, gpointer user_data) +{ + CtkDisplayConfig *ctk_object = CTK_DISPLAY_CONFIG(user_data); + nvDisplayPtr display; + gint idx; + + /* Get the modeline and display to set */ + idx = gtk_option_menu_get_history(GTK_OPTION_MENU(widget)); + display = ctk_object->display_model_table[idx]; + ctk_display_layout_select_display + (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout), display); + ctk_display_layout_redraw(CTK_DISPLAY_LAYOUT(ctk_object->obj_layout)); + /* Reconfigure GUI to display information about the selected display. */ + setup_display_page(ctk_object); + setup_screen_page(ctk_object); +} /* display_modelname_changed() */ /** display_position_type_changed() ********************************** * @@ -5139,7 +5333,7 @@ static void screen_metamode_activate(GtkWidget *widget, gpointer user_data) /* Sync the display frame */ - setup_display_frame(ctk_object); + setup_display_page(ctk_object); gtk_widget_set_sensitive(ctk_object->btn_apply, True); @@ -5168,8 +5362,8 @@ static void screen_metamode_add_clicked(GtkWidget *widget, gpointer user_data) /* Update the GUI */ - setup_display_frame(ctk_object); - setup_screen_frame(ctk_object); + setup_display_page(ctk_object); + setup_screen_page(ctk_object); gtk_widget_set_sensitive(ctk_object->btn_apply, True); @@ -5198,8 +5392,8 @@ static void screen_metamode_delete_clicked(GtkWidget *widget, screen, screen->cur_metamode_idx); /* Update the GUI */ - setup_display_frame(ctk_object); - setup_screen_frame(ctk_object); + setup_display_page(ctk_object); + setup_screen_page(ctk_object); gtk_widget_set_sensitive(ctk_object->btn_apply, True); @@ -5226,7 +5420,7 @@ static void xinerama_state_toggled(GtkWidget *widget, gpointer user_data) /* Make sure all screens have the same bpp when Xinerama is enabled */ consolidate_xinerama(ctk_object, NULL); - setup_screen_frame(ctk_object); + setup_screen_page(ctk_object); /* Make the apply button sensitive to user input */ gtk_widget_set_sensitive(ctk_object->btn_apply, True); @@ -5415,8 +5609,8 @@ static Bool switch_to_current_metamode(CtkDisplayConfig *ctk_object, NvCtrlGetTargetId(screen)); /* Update the GUI */ - setup_display_frame(ctk_object); - setup_screen_frame(ctk_object); + setup_display_page(ctk_object); + setup_screen_page(ctk_object); break; case GTK_RESPONSE_OK: /* Nothing to do with last metamode */ @@ -5793,6 +5987,7 @@ static void apply_clicked(GtkWidget *widget, gpointer user_data) { CtkDisplayConfig *ctk_object = CTK_DISPLAY_CONFIG(user_data); nvGpuPtr gpu; + ReturnStatus ret; int clear_apply = 1; @@ -5836,6 +6031,22 @@ static void apply_clicked(GtkWidget *widget, gpointer user_data) screen->displays_mask); } } + + if (screen->primaryDisplay) { + gchar *primary_str = + display_get_type_str(screen->primaryDisplay->device_mask, 0); + + ret = NvCtrlSetStringAttribute(screen->handle, + NV_CTRL_STRING_TWINVIEW_XINERAMA_INFO_ORDER, + primary_str, NULL); + g_free(primary_str); + + if (ret != NvCtrlSuccess) { + nv_error_msg("Failed to set primary display" + "for screen %d (GPU:%s)", screen->scrnum, + screen->gpu->name); + } + } } } @@ -6324,7 +6535,7 @@ static Bool add_monitor_to_xconfig(nvDisplayPtr display, XConfigPtr config, /* Add other options */ - opt = xconfigAddNewOption(opt, xconfigStrdup("DPMS"), NULL); + opt = xconfigAddNewOption(opt, "DPMS", NULL); monitor->options = opt; /* Add modelines used by this display */ @@ -6511,14 +6722,23 @@ static int add_screen_to_xconfig(CtkDisplayConfig *ctk_object, } /* Set the TwinView option */ - conf_screen->options = xconfigAddNewOption - (conf_screen->options, - xconfigStrdup("TwinView"), - xconfigStrdup( (screen->num_displays > 1) ? "1" : "0" )); + conf_screen->options = xconfigAddNewOption(conf_screen->options, + "TwinView", + ((screen->num_displays > 1) ? + "1" : "0" )); - /* XXX Setup any other twinview options ... */ - + /* Set the TwinviewXineramaInfoOrder option */ + + if (screen->primaryDisplay) { + gchar *primary_str = + display_get_type_str(screen->primaryDisplay->device_mask, 0); + + conf_screen->options = xconfigAddNewOption(conf_screen->options, + "TwinViewXineramaInfoOrder", + primary_str); + g_free(primary_str); + } /* Create the "metamode" option string. */ ret = generate_xconf_metamode_str(ctk_object, screen, &metamode_strs); @@ -6534,9 +6754,9 @@ static int add_screen_to_xconfig(CtkDisplayConfig *ctk_object, if (metamode_strs) { conf_screen->options = - xconfigAddNewOption(conf_screen->options, - xconfigStrdup("metamodes"), + xconfigAddNewOption(conf_screen->options, "metamodes", metamode_strs); + free(metamode_strs); } @@ -6757,8 +6977,8 @@ static Bool add_layout_to_xconfig(nvLayoutPtr layout, XConfigPtr config) } config->flags->options = xconfigAddNewOption(config->flags->options, - xconfigStrdup("Xinerama"), - xconfigStrdup(layout->xinerama_enabled?"1":"0")); + "Xinerama", + (layout->xinerama_enabled ? "1" : "0")); layout->conf_layout = conf_layout; return TRUE; @@ -7212,8 +7432,8 @@ static void advanced_clicked(GtkWidget *widget, gpointer user_data) /* Update the GUI to show the right widgets */ - setup_display_frame(ctk_object); - setup_screen_frame(ctk_object); + setup_display_page(ctk_object); + setup_screen_page(ctk_object); } /* advanced_clicked() */ @@ -7329,9 +7549,9 @@ static void probe_clicked(GtkWidget *widget, gpointer user_data) /* Sync the GUI */ ctk_display_layout_redraw(CTK_DISPLAY_LAYOUT(ctk_object->obj_layout)); - setup_display_frame(ctk_object); + setup_display_page(ctk_object); - setup_screen_frame(ctk_object); + setup_screen_page(ctk_object); } /* probe_clicked() */ @@ -7403,8 +7623,8 @@ static void reset_clicked(GtkWidget *widget, gpointer user_data) /* Setup the GUI */ setup_layout_frame(ctk_object); - setup_display_frame(ctk_object); - setup_screen_frame(ctk_object); + setup_display_page(ctk_object); + setup_screen_page(ctk_object); /* Get new position */ get_cur_screen_pos(ctk_object); diff --git a/src/gtk+-2.x/ctkdisplayconfig.h b/src/gtk+-2.x/ctkdisplayconfig.h index ed80e29..2917c1d 100644 --- a/src/gtk+-2.x/ctkdisplayconfig.h +++ b/src/gtk+-2.x/ctkdisplayconfig.h @@ -66,12 +66,15 @@ typedef struct _CtkDisplayConfig GtkWidget *obj_layout; GtkWidget *chk_xinerama_enabled; + GtkWidget *chk_primary_display; /* Display - Info */ - GtkWidget *display_frame; + GtkWidget *display_page; - GtkWidget *txt_display_model; + GtkWidget *mnu_display_model; + nvDisplayPtr *display_model_table; /* Lookup table for display modelname */ + int display_model_table_len; GtkWidget *txt_display_gpu; GtkWidget *btn_display_config; @@ -102,7 +105,7 @@ typedef struct _CtkDisplayConfig /* X Screen - Info */ - GtkWidget *screen_frame; + GtkWidget *screen_page; GtkWidget *txt_screen_num; diff --git a/src/gtk+-2.x/ctkdisplaylayout.c b/src/gtk+-2.x/ctkdisplaylayout.c index 5f76656..2928a93 100644 --- a/src/gtk+-2.x/ctkdisplaylayout.c +++ b/src/gtk+-2.x/ctkdisplaylayout.c @@ -3447,7 +3447,22 @@ void ctk_display_layout_set_display_panning(CtkDisplayLayout *ctk_object, } /* ctk_display_layout_set_display_panning() */ - +/** ctk_display_layout_select_display() *********************** + * + * Updates the currently selected display. + * + **/ +void ctk_display_layout_select_display(CtkDisplayLayout *ctk_object, + nvDisplayPtr display) +{ + if (display) { + /* Select the new display */ + select_display(ctk_object, display); + } else if (ctk_object->Zcount) { + /* Select the new topmost display */ + select_display(ctk_object, ctk_object->Zorder[0]); + } +} /* ctk_display_layout_select_display() */ /** ctk_display_layout_update_display_count() ************************ * @@ -3461,14 +3476,9 @@ void ctk_display_layout_update_display_count(CtkDisplayLayout *ctk_object, { /* Update the Z order */ zorder_layout(ctk_object); - if (display) { - /* Select the previously selected display */ - select_display(ctk_object, display); - } else if (ctk_object->Zcount) { - /* Select the new topmost display */ - select_display(ctk_object, ctk_object->Zorder[0]); - } + /* Select the previously selected display */ + ctk_display_layout_select_display(ctk_object, display); } /* ctk_display_layout_update_display_count() */ diff --git a/src/gtk+-2.x/ctkdisplaylayout.h b/src/gtk+-2.x/ctkdisplaylayout.h index 2062d99..c20913e 100644 --- a/src/gtk+-2.x/ctkdisplaylayout.h +++ b/src/gtk+-2.x/ctkdisplaylayout.h @@ -252,7 +252,7 @@ typedef struct nvScreenRec { int num_metamodes; /* # modes per display device */ nvMetaModePtr cur_metamode; /* Current metamode to display */ int cur_metamode_idx; /* Current metamode to display */ - + nvDisplayPtr primaryDisplay; // Used for generating metamode strings. int dim[4]; /* Bounding box of all metamodes (Absolute coords) */ @@ -431,7 +431,8 @@ void ctk_display_layout_set_display_position (CtkDisplayLayout *ctk_object, void ctk_display_layout_set_display_panning (CtkDisplayLayout *ctk_object, nvDisplayPtr display, int width, int height); - +void ctk_display_layout_select_display (CtkDisplayLayout *ctk_object, + nvDisplayPtr display); void ctk_display_layout_update_display_count (CtkDisplayLayout *, nvDisplayPtr); diff --git a/src/gtk+-2.x/ctkevent.c b/src/gtk+-2.x/ctkevent.c index dd1fc79..877217d 100644 --- a/src/gtk+-2.x/ctkevent.c +++ b/src/gtk+-2.x/ctkevent.c @@ -242,8 +242,9 @@ static void ctk_event_class_init(CtkEventClass *ctk_event_class) MAKE_SIGNAL(NV_CTRL_FSAA_APPLICATION_ENHANCED); MAKE_SIGNAL(NV_CTRL_FRAMELOCK_SYNC_RATE_4); MAKE_SIGNAL(NV_CTRL_GVO_LOCK_OWNER); - MAKE_SIGNAL(NV_CTRL_REFRESH_RATE_3); + MAKE_SIGNAL(NV_CTRL_NUM_GPU_ERRORS_RECOVERED); MAKE_SIGNAL(NV_CTRL_ONDEMAND_VBLANK_INTERRUPTS); + MAKE_SIGNAL(NV_CTRL_NOTEBOOK_DISPLAY_CHANGE_LID_EVENT); #undef MAKE_SIGNAL @@ -254,7 +255,7 @@ static void ctk_event_class_init(CtkEventClass *ctk_event_class) * knows about. */ -#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_ONDEMAND_VBLANK_INTERRUPTS +#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_NOTEBOOK_INTERNAL_LCD #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 80feef4..7aa1a76 100644 --- a/src/gtk+-2.x/ctkframelock.c +++ b/src/gtk+-2.x/ctkframelock.c @@ -82,7 +82,7 @@ enum * that entry. */ -#define NUM_GPU_SIGNALS 6 +#define NUM_GPU_SIGNALS 5 const char *__GPUSignals[NUM_GPU_SIGNALS] = { @@ -90,8 +90,7 @@ const char *__GPUSignals[NUM_GPU_SIGNALS] = CTK_EVENT_NAME(NV_CTRL_FRAMELOCK_SLAVES), CTK_EVENT_NAME(NV_CTRL_FRAMELOCK_SYNC), CTK_EVENT_NAME(NV_CTRL_FRAMELOCK_TEST_SIGNAL), - CTK_EVENT_NAME(NV_CTRL_REFRESH_RATE), - CTK_EVENT_NAME(NV_CTRL_REFRESH_RATE_3) + CTK_EVENT_NAME(NV_CTRL_REFRESH_RATE) }; /* @@ -184,7 +183,6 @@ struct _nvDisplayDataRec { GtkWidget *rate_label; GtkWidget *rate_text; guint rate; - guint rate_precision; GtkWidget *stereo_label; GtkWidget *stereo_hbox; /* LED */ @@ -3491,7 +3489,7 @@ void list_entry_update_display_status(CtkFramelock *ctk_framelock, /** list_entry_update_status() *************************************** * * Updates the (GUI) state of a list entry, its children and siblings - * by querying the X Server. + * by queryin ghte X Server. * */ void list_entry_update_status(CtkFramelock *ctk_framelock, @@ -3938,7 +3936,6 @@ static void gpu_state_received(GtkObject *object, case NV_CTRL_REFRESH_RATE: - case NV_CTRL_REFRESH_RATE_3: /* Update the display device's refresh rate */ display_entry = get_display_on_gpu(gpu_entry, event->display_mask); if (display_entry && display_entry->data) { @@ -3949,18 +3946,8 @@ static void gpu_state_received(GtkObject *object, (nvDisplayDataPtr)(display_entry->data); display_data->rate = event->value; - if (event->attribute == NV_CTRL_REFRESH_RATE_3 && - display_data->rate_precision == 3) { - fvalue = ((float)(display_data->rate)) / 1000.0f; - snprintf(str, 32, "%.3f Hz", fvalue); - } else if (display_data->rate_precision == 2 ){ - fvalue = ((float)(display_data->rate)) / 100.0f; - snprintf(str, 32, "%.2f Hz", fvalue); - } else { - // wrong signal (got 2 but support 3 or got 3 but - // don't support it); - break; - } + fvalue = ((float)(display_data->rate)) / 100.0f; + snprintf(str, 32, "%.2f Hz", fvalue); gtk_label_set_text(GTK_LABEL(display_data->rate_text), str); } @@ -4715,7 +4702,7 @@ static unsigned int add_display_devices(CtkFramelock *ctk_framelock, unsigned int master_mask; unsigned int slaves_mask; gfloat fvalue; /* To print the refresh rate */ - gchar rr_str[32]; + gchar str[32]; nvListEntryPtr server_entry = NULL; nvDisplayDataPtr server_data = NULL; @@ -4809,24 +4796,10 @@ static unsigned int add_display_devices(CtkFramelock *ctk_framelock, goto fail; } - // If we can't get either percision, then fail - if (NvCtrlSuccess != - (ret = NvCtrlGetDisplayAttribute(gpu_data->handle, - display_mask, - NV_CTRL_REFRESH_RATE_3, - (int *)&(display_data->rate)))) { - ret = NvCtrlGetDisplayAttribute(gpu_data->handle, - display_mask, - NV_CTRL_REFRESH_RATE, - (int *)&(display_data->rate)); - fvalue = ((float)(display_data->rate)) / 100.0f; - snprintf(rr_str, 32, "%.2f Hz", fvalue); - display_data->rate_precision = 2; - } else { - fvalue = ((float)(display_data->rate)) / 1000.0f; - snprintf(rr_str, 32, "%.3f Hz", fvalue); - display_data->rate_precision = 3; - } + ret = NvCtrlGetDisplayAttribute(gpu_data->handle, + display_mask, + NV_CTRL_REFRESH_RATE, + (int *)&(display_data->rate)); if (ret != NvCtrlSuccess) { goto fail; } @@ -4846,7 +4819,9 @@ static unsigned int add_display_devices(CtkFramelock *ctk_framelock, __client_checkbox_help); display_data->rate_label = gtk_label_new("Refresh:"); - display_data->rate_text = gtk_label_new(rr_str); + fvalue = ((float)(display_data->rate)) / 100.0f; + snprintf(str, 32, "%.2f Hz", fvalue); + display_data->rate_text = gtk_label_new(str); display_data->stereo_label = gtk_label_new("Stereo"); display_data->stereo_hbox = gtk_hbox_new(FALSE, 0); @@ -4976,6 +4951,7 @@ static unsigned int add_gpu_devices(CtkFramelock *ctk_framelock, /* Create the GPU data structure */ gpu_data = (nvGPUDataPtr) calloc(1, sizeof(nvGPUDataRec)); if (!gpu_data) { + XFree(data); goto fail; } @@ -5029,6 +5005,8 @@ static unsigned int add_gpu_devices(CtkFramelock *ctk_framelock, } } + XFree(data); + return gpus_added; @@ -5098,7 +5076,7 @@ static unsigned int add_framelock_devices(CtkFramelock *ctk_framelock, if (ret != NvCtrlSuccess) { goto fail; } - revision_str = g_strdup_printf("0x%X", val); + revision_str = g_strdup_printf("%d", val); /* Create the frame lock widgets */ framelock_data->label = gtk_label_new(""); diff --git a/src/gtk+-2.x/ctkgpu.c b/src/gtk+-2.x/ctkgpu.c index 0e25633..b6ee0d6 100644 --- a/src/gtk+-2.x/ctkgpu.c +++ b/src/gtk+-2.x/ctkgpu.c @@ -292,6 +292,7 @@ GtkWidget* ctk_gpu_new( screens = tmp_str; } } + XFree(pData); } } diff --git a/src/gtk+-2.x/ctkpowermizer.c b/src/gtk+-2.x/ctkpowermizer.c new file mode 100644 index 0000000..c942656 --- /dev/null +++ b/src/gtk+-2.x/ctkpowermizer.c @@ -0,0 +1,460 @@ +/* + * nvidia-settings: A tool for configuring the NVIDIA X driver on Unix + * and Linux systems. + * + * Copyright (C) 2004 NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of Version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See Version 2 + * of the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307, USA + * + */ + +#include <gtk/gtk.h> +#include <NvCtrlAttributes.h> + +#include "ctkhelp.h" +#include "ctkpowermizer.h" +#include "ctkimage.h" + +#define FRAME_PADDING 10 +#define DEFAULT_UPDATE_POWERMIZER_INFO_TIME_INTERVAL 1000 + +static gboolean update_powermizer_info(gpointer); + +static const char *__adaptive_clock_help = +"The Adaptive Clocking status describes if this feature " +"is currently enabled in this GPU."; + +static const char *__power_source_help = +"The Power Source indicates whether the machine " +"is running on AC or Battery power."; + +static const char *__performance_level_help = +"This indicates the current Performance Level of the GPU."; + +static const char *__performance_mode_short_help = +"This indicates the current Performance Mode of the GPU.\n"; + +static const char *__performance_mode_help = +"This indicates the current Performance Mode of the GPU.\n" +"Performance Mode can be either \"Desktop\" or\n" +"\"Maximum Performance\"."; + +static const char *__gpu_clock_freq_help = +"This indicates the current GPU Clock frequency."; + +static const char *__memory_clock_freq_help = +"This indicates the current Memory Clock frequency."; + +static const char *__clock_freq_help = +"This indicates the current GPU Clock and Memory Clock frequencies."; + +GType ctk_powermizer_get_type(void) +{ + static GType ctk_powermizer_type = 0; + + if (!ctk_powermizer_type) { + static const GTypeInfo ctk_powermizer_info = { + sizeof (CtkPowermizerClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + NULL, /* constructor */ + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (CtkPowermizer), + 0, /* n_preallocs */ + NULL, /* instance_init */ + }; + + ctk_powermizer_type = + g_type_register_static(GTK_TYPE_VBOX, "CtkPowermizer", + &ctk_powermizer_info, 0); + } + + return ctk_powermizer_type; + +} /* ctk_powermizer_get_type() */ + +static gboolean update_powermizer_info(gpointer user_data) +{ + gint power_source, perf_mode, adaptive_clock, perf_level; + gint clockret, gpu_clock, memory_clock; + + CtkPowermizer *ctk_powermizer; + NvCtrlAttributeHandle *handle; + gint ret; gchar *s; + + ctk_powermizer = CTK_POWERMIZER(user_data); + handle = ctk_powermizer->attribute_handle; + + ret = NvCtrlGetAttribute(handle, NV_CTRL_GPU_ADAPTIVE_CLOCK_STATE, &adaptive_clock); + if (ret != NvCtrlSuccess) { + return FALSE; + } + + if (adaptive_clock == NV_CTRL_GPU_ADAPTIVE_CLOCK_STATE_ENABLED) { + s = g_strdup_printf("Enabled"); + } + else if (adaptive_clock == NV_CTRL_GPU_ADAPTIVE_CLOCK_STATE_DISABLED) { + s = g_strdup_printf("Disabled"); + } + else { + s = g_strdup_printf("Error"); + } + + gtk_label_set_text(GTK_LABEL(ctk_powermizer->adaptive_clock_status), s); + g_free(s); + + ret = NvCtrlGetAttribute(handle, NV_CTRL_GPU_CURRENT_CLOCK_FREQS, + &clockret); + if (ret != NvCtrlSuccess) { + return FALSE; + } + + memory_clock = clockret & 0x0000FFFF; + gpu_clock = (clockret >> 16); + + s = g_strdup_printf("%d Mhz", gpu_clock); + gtk_label_set_text(GTK_LABEL(ctk_powermizer->gpu_clock), s); + g_free(s); + + s = g_strdup_printf("%d Mhz", memory_clock); + gtk_label_set_text(GTK_LABEL(ctk_powermizer->memory_clock), s); + g_free(s); + + ret = NvCtrlGetAttribute(handle, NV_CTRL_GPU_POWER_SOURCE, &power_source); + if (ret != NvCtrlSuccess) { + return FALSE; + } + + if (power_source == NV_CTRL_GPU_POWER_SOURCE_AC) { + s = g_strdup_printf("AC"); + } + else if (power_source == NV_CTRL_GPU_POWER_SOURCE_BATTERY) { + s = g_strdup_printf("Battery"); + } + else { + s = g_strdup_printf("Error"); + } + + gtk_label_set_text(GTK_LABEL(ctk_powermizer->power_source), s); + g_free(s); + + ret = NvCtrlGetAttribute(handle, NV_CTRL_GPU_CURRENT_PERFORMANCE_LEVEL, + &perf_level); + if (ret != NvCtrlSuccess) { + return FALSE; + } + + s = g_strdup_printf("%d", perf_level); + gtk_label_set_text(GTK_LABEL(ctk_powermizer->performance_level), s); + g_free(s); + + ret = NvCtrlGetAttribute(handle, NV_CTRL_GPU_CURRENT_PERFORMANCE_MODE, + &perf_mode); + if (ret != NvCtrlSuccess) { + return FALSE; + } + + if (perf_mode == NV_CTRL_GPU_CURRENT_PERFORMANCE_MODE_DESKTOP) { + s = g_strdup_printf("Desktop"); + } + else if (perf_mode == NV_CTRL_GPU_CURRENT_PERFORMANCE_MODE_MAXPERF) { + s = g_strdup_printf("Maximum Performance"); + } + else { + s = g_strdup_printf("Default"); + } + + gtk_label_set_text(GTK_LABEL(ctk_powermizer->performance_mode), s); + g_free(s); + + + return TRUE; +} + +GtkWidget* ctk_powermizer_new(NvCtrlAttributeHandle *handle, + CtkConfig *ctk_config) +{ + GObject *object; + CtkPowermizer *ctk_powermizer; + GtkWidget *hbox, *hbox2, *vbox, *hsep, *table; + GtkWidget *banner, *label; + GtkWidget *eventbox; + ReturnStatus ret; + gchar *s; + gint val; + + /* make sure we have a handle */ + + g_return_val_if_fail(handle != NULL, NULL); + + /* check if this screen supports powermizer querying */ + + ret = NvCtrlGetAttribute(handle, NV_CTRL_GPU_POWER_SOURCE, &val); + if (ret != NvCtrlSuccess) { + return NULL; + } + + ret = NvCtrlGetAttribute(handle, NV_CTRL_GPU_CURRENT_PERFORMANCE_LEVEL, + &val); + if (ret != NvCtrlSuccess) { + return NULL; + } + + ret = NvCtrlGetAttribute(handle, NV_CTRL_GPU_CURRENT_PERFORMANCE_MODE, + &val); + if (ret != NvCtrlSuccess) { + return NULL; + } + + + ret = NvCtrlGetAttribute(handle, NV_CTRL_GPU_ADAPTIVE_CLOCK_STATE, + &val); + if (ret != NvCtrlSuccess) { + return NULL; + } + + ret = NvCtrlGetAttribute(handle, NV_CTRL_GPU_CURRENT_CLOCK_FREQS, + &val); + if (ret != NvCtrlSuccess) { + return NULL; + } + + /* create the CtkPowermizer object */ + + object = g_object_new(CTK_TYPE_POWERMIZER, NULL); + + ctk_powermizer = CTK_POWERMIZER(object); + ctk_powermizer->attribute_handle = handle; + ctk_powermizer->ctk_config = ctk_config; + + /* set container properties for the CtkPowermizer widget */ + + gtk_box_set_spacing(GTK_BOX(ctk_powermizer), 7); + + /* banner */ + + banner = ctk_banner_image_new(BANNER_ARTWORK_THERMAL); + gtk_box_pack_start(GTK_BOX(object), banner, FALSE, FALSE, 0); + + vbox = gtk_vbox_new(FALSE, 5); + gtk_box_pack_start(GTK_BOX(object), vbox, TRUE, TRUE, 0); + + hbox = gtk_hbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + + label = gtk_label_new("PowerMizer Information"); + 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); + + table = gtk_table_new(15, 2, FALSE); + gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0); + 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); + + /* Adaptive Clocking State */ + + hbox2 = gtk_hbox_new(FALSE, 0); + gtk_table_attach(GTK_TABLE(table), hbox2, 0, 1, 0, 1, + GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0); + + label = gtk_label_new("Adaptive Clocking:"); + gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f); + gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0); + + eventbox = gtk_event_box_new(); + gtk_table_attach(GTK_TABLE(table), eventbox, 1, 2, 0, 1, + GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0); + + label = gtk_label_new(NULL); + gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f); + gtk_container_add(GTK_CONTAINER(eventbox), label); + ctk_config_set_tooltip(ctk_config, eventbox, __adaptive_clock_help); + ctk_powermizer->adaptive_clock_status = label; + + /* Clock Frequencies */ + + hbox2 = gtk_hbox_new(FALSE, 0); + gtk_table_attach(GTK_TABLE(table), hbox2, 0, 1, 4, 5, + GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0); + + label = gtk_label_new("GPU Clock:"); + gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f); + gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0); + + eventbox = gtk_event_box_new(); + gtk_table_attach(GTK_TABLE(table), eventbox, 1, 2, 4, 5, + GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0); + + label = gtk_label_new(NULL); + gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); + gtk_container_add(GTK_CONTAINER(eventbox), label); + ctk_config_set_tooltip(ctk_config, eventbox, __gpu_clock_freq_help); + ctk_powermizer->gpu_clock = label; + + hbox2 = gtk_hbox_new(FALSE, 0); + gtk_table_attach(GTK_TABLE(table), hbox2, 0, 1, 5, 6, + GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0); + + label = gtk_label_new("Memory Clock:"); + gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f); + gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0); + + eventbox = gtk_event_box_new(); + gtk_table_attach(GTK_TABLE(table), eventbox, 1, 2, 5, 6, + GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0); + + label = gtk_label_new(NULL); + gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); + gtk_container_add(GTK_CONTAINER(eventbox), label); + ctk_config_set_tooltip(ctk_config, eventbox, __memory_clock_freq_help); + ctk_powermizer->memory_clock = label; + + /* Power Source */ + + hbox2 = gtk_hbox_new(FALSE, 0); + gtk_table_attach(GTK_TABLE(table), hbox2, 0, 1, 9, 10, + GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0); + + label = gtk_label_new("Power Source:"); + gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f); + gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0); + + eventbox = gtk_event_box_new(); + gtk_table_attach(GTK_TABLE(table), eventbox, 1, 2, 9, 10, + GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0); + + label = gtk_label_new(NULL); + gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); + gtk_container_add(GTK_CONTAINER(eventbox), label); + ctk_config_set_tooltip(ctk_config, eventbox, __power_source_help); + ctk_powermizer->power_source = label; + + + /* Performance Level */ + + hbox2 = gtk_hbox_new(FALSE, 0); + gtk_table_attach(GTK_TABLE(table), hbox2, 0, 1, 13, 14, + GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0); + + label = gtk_label_new("Performance Level:"); + gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f); + gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0); + + eventbox = gtk_event_box_new(); + gtk_table_attach(GTK_TABLE(table), eventbox, 1, 2, 13, 14, + GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0); + + label = gtk_label_new(NULL); + gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); + gtk_container_add(GTK_CONTAINER(eventbox), label); + ctk_config_set_tooltip(ctk_config, eventbox, __performance_level_help); + ctk_powermizer->performance_level = label; + + /* Performance Mode */ + + hbox2 = gtk_hbox_new(FALSE, 0); + gtk_table_attach(GTK_TABLE(table), hbox2, 0, 1, 14, 15, + GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0); + + label = gtk_label_new("Performance Mode:"); + gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f); + gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0); + + eventbox = gtk_event_box_new(); + gtk_table_attach(GTK_TABLE(table), eventbox, 1, 2, 14, 15, + GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0); + + label = gtk_label_new(NULL); + gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); + gtk_container_add(GTK_CONTAINER(eventbox), label); + ctk_config_set_tooltip(ctk_config, eventbox, __performance_mode_short_help); + ctk_powermizer->performance_mode = label; + + /* Register a timer callback to update the temperatures */ + + s = g_strdup_printf("PowerMizer Monitor (GPU %d)", + NvCtrlGetTargetId(handle)); + + ctk_config_add_timer(ctk_powermizer->ctk_config, + DEFAULT_UPDATE_POWERMIZER_INFO_TIME_INTERVAL, + s, + (GSourceFunc) update_powermizer_info, + (gpointer) ctk_powermizer); + g_free(s); + + update_powermizer_info(ctk_powermizer); + gtk_widget_show_all(GTK_WIDGET(ctk_powermizer)); + + return GTK_WIDGET(ctk_powermizer); +} + +GtkTextBuffer *ctk_powermizer_create_help(GtkTextTagTable *table, + CtkPowermizer *ctk_powermizer) +{ + 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, "PowerMizer Monitor Help"); + + ctk_help_heading(b, &i, "Adaptive Clocking"); + ctk_help_para(b, &i, __adaptive_clock_help); + + ctk_help_heading(b, &i, "Power Source"); + ctk_help_para(b, &i, __power_source_help); + + ctk_help_heading(b, &i, "Clock Frequencies"); + ctk_help_para(b, &i, __clock_freq_help); + + ctk_help_heading(b, &i, "Performance Level"); + ctk_help_para(b, &i, __performance_level_help); + + ctk_help_heading(b, &i, "Performance Mode"); + ctk_help_para(b, &i, __performance_mode_help); + ctk_help_finish(b); + + return b; +} + +void ctk_powermizer_start_timer(GtkWidget *widget) +{ + CtkPowermizer *ctk_powermizer = CTK_POWERMIZER(widget); + + /* Start the powermizer timer */ + + ctk_config_start_timer(ctk_powermizer->ctk_config, + (GSourceFunc) update_powermizer_info, + (gpointer) ctk_powermizer); +} + +void ctk_powermizer_stop_timer(GtkWidget *widget) +{ + CtkPowermizer *ctk_powermizer = CTK_POWERMIZER(widget); + + /* Stop the powermizer timer */ + + ctk_config_stop_timer(ctk_powermizer->ctk_config, + (GSourceFunc) update_powermizer_info, + (gpointer) ctk_powermizer); +} diff --git a/src/gtk+-2.x/ctkpowermizer.h b/src/gtk+-2.x/ctkpowermizer.h new file mode 100644 index 0000000..175515b --- /dev/null +++ b/src/gtk+-2.x/ctkpowermizer.h @@ -0,0 +1,83 @@ +/* + * nvidia-settings: A tool for configuring the NVIDIA X driver on Unix + * and Linux systems. + * + * Copyright (C) 2004 NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of Version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See Version 2 + * of the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307, USA + * + */ + +#ifndef __CTK_POWERMIZER_H__ +#define __CTK_POWERMIZER_H__ + +#include "NvCtrlAttributes.h" +#include "ctkconfig.h" + +G_BEGIN_DECLS + +#define CTK_TYPE_POWERMIZER (ctk_powermizer_get_type()) + +#define CTK_POWERMIZER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), CTK_TYPE_POWERMIZER, CtkPowermizer)) + +#define CTK_POWERMIZER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), CTK_TYPE_POWERMIZER, CtkPowermizerClass)) + +#define CTK_IS_POWERMIZER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CTK_TYPE_POWERMIZER)) + +#define CTK_IS_POWERMIZER_CLASS(class) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), CTK_TYPE_POWERMIZER)) + +#define CTK_POWERMIZER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), CTK_TYPE_POWERMIZER, CtkPowermizerClass)) + + +typedef struct _CtkPowermizer CtkPowermizer; +typedef struct _CtkPowermizerClass CtkPowermizerClass; + +struct _CtkPowermizer +{ + GtkVBox parent; + + NvCtrlAttributeHandle *attribute_handle; + CtkConfig *ctk_config; + + GtkWidget *adaptive_clock_status; + GtkWidget *gpu_clock; + GtkWidget *memory_clock; + GtkWidget *power_source; + GtkWidget *performance_level; + GtkWidget *performance_mode; +}; + +struct _CtkPowermizerClass +{ + GtkVBoxClass parent_class; +}; + +GType ctk_powermizer_get_type (void) G_GNUC_CONST; +GtkWidget* ctk_powermizer_new (NvCtrlAttributeHandle *, CtkConfig *); +GtkTextBuffer* ctk_powermizer_create_help (GtkTextTagTable *, CtkPowermizer *); + +void ctk_powermizer_start_timer (GtkWidget *); +void ctk_powermizer_stop_timer (GtkWidget *); + +G_END_DECLS + +#endif /* __CTK_POWERMIZER_H__ */ diff --git a/src/gtk+-2.x/ctkscreen.c b/src/gtk+-2.x/ctkscreen.c index d2aafd9..5d9c9cb 100644 --- a/src/gtk+-2.x/ctkscreen.c +++ b/src/gtk+-2.x/ctkscreen.c @@ -46,6 +46,9 @@ void ctk_screen_event_handler(GtkWidget *widget, 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); + GType ctk_screen_get_type( void ) @@ -188,6 +191,10 @@ GtkWidget* ctk_screen_new(NvCtrlAttributeHandle *handle, gchar *depth; gchar *gpus; gchar *displays; + gint gpu_errors; + + + char tmp[16]; double xres, yres; @@ -265,6 +272,7 @@ GtkWidget* ctk_screen_new(NvCtrlAttributeHandle *handle, if (!gpus) { gpus = g_strdup("None"); } + XFree(pData); } /* get the list of Display Devices displaying this X screen */ @@ -275,7 +283,16 @@ GtkWidget* ctk_screen_new(NvCtrlAttributeHandle *handle, if (ret == NvCtrlSuccess) { displays = make_display_device_list(handle, display_devices); } - + + /* get the number of gpu errors occurred */ + + gpu_errors = 0; + ret = NvCtrlGetDisplayAttribute(handle, + 0, + NV_CTRL_NUM_GPU_ERRORS_RECOVERED, + (int *)&gpu_errors); + + snprintf(tmp, 16, "%d", gpu_errors); /* now, create the object */ @@ -317,7 +334,7 @@ GtkWidget* ctk_screen_new(NvCtrlAttributeHandle *handle, hseparator = gtk_hseparator_new(); gtk_box_pack_start(GTK_BOX(hbox), hseparator, TRUE, TRUE, 5); - table = gtk_table_new(16, 2, FALSE); + table = gtk_table_new(20, 2, FALSE); gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0); gtk_table_set_row_spacings(GTK_TABLE(table), 3); gtk_table_set_col_spacings(GTK_TABLE(table), 15); @@ -335,7 +352,10 @@ GtkWidget* ctk_screen_new(NvCtrlAttributeHandle *handle, /* spacing */ ctk_screen->displays = add_table_row(table, 15, 0, 0, "Displays:", 0, 0, displays); - + /* gpu errors */ + ctk_screen->gpu_errors = + add_table_row(table, 19, 0, 0, "Recovered GPU Errors:", 0, 0, tmp); + g_free(screen_number); free(display_name); g_free(dimensions); @@ -355,6 +375,13 @@ GtkWidget* ctk_screen_new(NvCtrlAttributeHandle *handle, G_CALLBACK(ctk_screen_event_handler), (gpointer) ctk_screen); + /* Setup widget to reflect the latest number of gpu errors */ + g_signal_connect(G_OBJECT(ctk_event), + CTK_EVENT_NAME(NV_CTRL_NUM_GPU_ERRORS_RECOVERED), + G_CALLBACK(info_update_gpu_error), + (gpointer) ctk_screen); + + gtk_widget_show_all(GTK_WIDGET(object)); return GTK_WIDGET(object); @@ -404,6 +431,16 @@ GtkTextBuffer *ctk_screen_create_help(GtkTextTagTable *table, ctk_help_para(b, &i, "This is the list of Display Devices (CRTs, TVs etc) " "enabled on this X Screen."); + ctk_help_heading(b, &i, "Recovered GPU Errors"); + ctk_help_para(b, &i, "The GPU can encounter errors, either due to bugs in " + "the NVIDIA driver, or due to corruption of the command " + "stream as it is sent from the NVIDIA X driver to the GPU. " + "When the GPU encounters one of these errors, it reports it " + "to the NVIDIA X driver and the NVIDIA X driver attempts to " + "recover from the error. This reports how many errors the " + "GPU received and the NVIDIA X driver successfully recovered " + "from."); + ctk_help_finish(b); return b; @@ -454,3 +491,27 @@ static void associated_displays_received(GtkObject *object, gpointer arg1, g_free(str); } /* associated_displays_received() */ + + +/* + * When the number of gpu errors occured changes, + * update the count showed on the page. + */ + +static void info_update_gpu_error(GtkObject *object, gpointer arg1, + gpointer data) +{ + CtkScreen *ctk_screen = (CtkScreen *) data; + ReturnStatus ret; + gint gpu_errors = 0; + char tmp[16]; + + /* get the number of gpu errors occurred */ + ret = NvCtrlGetDisplayAttribute(ctk_screen->handle, 0, + NV_CTRL_NUM_GPU_ERRORS_RECOVERED, + (int *)&gpu_errors); + if (ret == NvCtrlSuccess) { + snprintf(tmp, 16, "%d", gpu_errors); + gtk_label_set_text(GTK_LABEL(ctk_screen->gpu_errors), tmp); + } +} /* info_update_gpu_error() */ diff --git a/src/gtk+-2.x/ctkscreen.h b/src/gtk+-2.x/ctkscreen.h index 75f8422..f021346 100644 --- a/src/gtk+-2.x/ctkscreen.h +++ b/src/gtk+-2.x/ctkscreen.h @@ -61,6 +61,7 @@ struct _CtkScreen GtkWidget *dimensions; GtkWidget *displays; + GtkWidget *gpu_errors; }; struct _CtkScreenClass diff --git a/src/gtk+-2.x/ctkui.c b/src/gtk+-2.x/ctkui.c index c840911..42fd756 100644 --- a/src/gtk+-2.x/ctkui.c +++ b/src/gtk+-2.x/ctkui.c @@ -22,11 +22,11 @@ * */ +#include <gtk/gtk.h> +#include <gdk-pixbuf/gdk-pixdata.h> #include "ctkui.h" #include "ctkwindow.h" - -#include <gtk/gtk.h> - +#include "nvidia_icon_pixdata.h" /* * This source file provides thin wrappers over the gtk routines, so * that nvidia-settings.c doesn't need to include gtk+ @@ -48,7 +48,9 @@ void ctk_main(NvCtrlAttributeHandle **screen_handles, int num_screen_handles, ParsedAttribute *p, ConfigProperties *conf) { int i, has_nv_control = FALSE; - + GList *list = NULL; + list = g_list_append (list, gdk_pixbuf_from_pixdata(&nvidia_icon_pixdata, TRUE, NULL)); + gtk_window_set_default_icon_list(list); ctk_window_new(screen_handles, num_screen_handles, gpu_handles, num_gpu_handles, vcsc_handles, num_vcsc_handles, diff --git a/src/gtk+-2.x/ctkwindow.c b/src/gtk+-2.x/ctkwindow.c index 12ba447..2de713e 100644 --- a/src/gtk+-2.x/ctkwindow.c +++ b/src/gtk+-2.x/ctkwindow.c @@ -51,6 +51,7 @@ #include "ctkglx.h" #include "ctkmultisample.h" #include "ctkthermal.h" +#include "ctkpowermizer.h" #include "ctkclocks.h" #include "ctkvcsc.h" #include "ctkpowersavings.h" @@ -795,7 +796,16 @@ GtkWidget *ctk_window_new(NvCtrlAttributeHandle **screen_handles, add_page(child, help, ctk_window, &iter, NULL, "Thermal Monitor", NULL, ctk_thermal_start_timer, ctk_thermal_stop_timer); } - + + /* Powermizer information */ + child = ctk_powermizer_new(gpu_handle, ctk_config); + if (child) { + help = ctk_powermizer_create_help(tag_table, CTK_POWERMIZER(child)); + add_page(child, help, ctk_window, &iter, NULL, "PowerMizer", + NULL, ctk_powermizer_start_timer, + ctk_powermizer_stop_timer); + } + /* clocks (GPU overclocking) */ child = ctk_clocks_new(gpu_handle, ctk_config, ctk_event); diff --git a/src/image_data/Makefile.inc b/src/image_data/Makefile.inc index 64a1706..63cd23d 100644 --- a/src/image_data/Makefile.inc +++ b/src/image_data/Makefile.inc @@ -53,6 +53,7 @@ EXTRA_DIST += \ tv_pixdata.h \ background_pixdata.h \ logo_pixdata.h \ + nvidia_icon_pixdata.h \ antialias_pixdata.h \ thermal_pixdata.h \ x_pixdata.h \ diff --git a/src/image_data/nvidia_icon_pixdata.h b/src/image_data/nvidia_icon_pixdata.h new file mode 100644 index 0000000..73e9343 --- /dev/null +++ b/src/image_data/nvidia_icon_pixdata.h @@ -0,0 +1,425 @@ +/* GdkPixbuf RGBA C-Source image dump 1-byte-run-length-encoded */ + +static guint8 nvidia_icon_pixdata_pixel_data[] = { + "\377\0\0\0\0\377\0\0\0\0\377\0\0\0\0\377\0\0\0\0\377\0\0\0\0\377\0\0" + "\0\0\346\0\0\0\0\226\0\0\0\1\227\0\0\0\2\202\0\0\0\1\233\0\0\0\0\11\0" + "\0\0\3<[\4""8\244\325J\243\273\352d\245\273\352e\245\273\352e\246\275" + "\352j\246\277\352n\247\277\352o\247\202\277\352o\250\10\277\352p\251" + "\277\353q\252\300\353q\252\300\353r\252\300\353r\253\301\354s\254\301" + "\354r\255\301\354s\255\202\302\354t\256\12\302\354s\260\302\354s\261" + "\303\355t\261\303\355v\262\303\354v\262\303\354v\263\303\354w\263\303" + "\354x\263\304\355y\264\303\354x\265\202\304\354y\265\202\304\354y\266" + "\17\304\354z\266\304\354y\267\304\354z\267\304\354z\270\303\354y\270" + "\303\354y\271\304\354y\271\304\355y\272\303\355w\272\302\355t\273\303" + "\355t\273\302\356s\274\237\314N\263\16\24\1\14\0\0\0\1\232\0\0\0\0\3" + "\0\0\0\12""7T\1x\274\345r\377\202\331\377\225\377\6\331\377\226\377\332" + "\377\230\377\332\377\231\377\333\377\231\377\332\377\231\377\333\377" + "\231\377\215\333\377\232\377\4\333\377\233\377\334\377\233\377\333\377" + "\233\377\334\377\233\377\202\333\377\233\377\203\334\377\235\377\203" + "\334\377\234\377\203\335\377\236\377\202\334\377\235\377\203\333\377" + "\232\377\6\332\377\231\377\332\377\230\377\331\377\227\377\260\330g\370" + "\12\17\1!\0\0\0\4\231\0\0\0\0\7\0\0\0\1\0\0\0\21""1K\1\206\301\350z\377" + "\333\377\233\377\334\377\234\377\334\377\233\377\206\334\377\234\377" + "\206\334\377\235\377\2\334\377\236\377\335\377\236\377\202\334\377\236" + "\377\2\334\377\235\377\335\377\236\377\204\335\377\237\377\1\335\377" + "\236\377\207\335\377\237\377\1\335\377\240\377\204\335\377\237\377\1" + "\335\377\236\377\203\334\377\235\377\5\333\377\233\377\333\377\232\377" + "\266\334p\371\10\14\0""1\0\0\0\6\231\0\0\0\0\5\0\0\0\1\0\0\0\24/H\1\212" + "\306\353\201\377\335\377\237\377\206\335\377\240\377\202\335\377\241" + "\377\2\336\377\241\377\335\377\241\377\212\336\377\241\377\1\336\377" + "\242\377\202\336\377\241\377\202\335\377\241\377\202\336\377\242\377" + "\202\336\377\241\377\2\335\377\240\377\335\377\241\377\202\336\377\243" + "\377\3\336\377\242\377\335\377\241\377\335\377\240\377\203\335\377\237" + "\377\203\335\377\240\377\4\335\377\237\377\275\342y\371\10\14\0""4\0" + "\0\0\7\231\0\0\0\0\4\0\0\0\1\0\0\0\24/H\1\213\312\355\211\377\206\336" + "\377\243\377\3\336\377\244\377\336\377\243\377\336\377\244\377\203\337" + "\377\244\377\213\337\377\245\377\1\336\377\244\377\202\337\377\244\377" + "\3\337\377\246\377\337\377\244\377\336\377\244\377\202\336\377\243\377" + "\2\336\377\244\377\337\377\244\377\213\336\377\243\377\3\303\347\201" + "\371\10\13\0""5\0\0\0\7\231\0\0\0\0\14\0\0\0\1\0\0\0\24-E\1\213q\233" + "%\377y\243,\377{\247-\377\201\2544\377\212\265>\377\227\302K\377\251" + "\322^\377\277\344z\377\326\370\231\377\206\340\377\250\377\1\340\377" + "\251\377\203\340\377\250\377\203\340\377\251\377\210\340\377\250\377" + "\1\340\377\247\377\203\340\377\250\377\2\340\377\247\377\337\377\246" + "\377\204\337\377\245\377\1\336\377\244\377\202\337\377\244\377\202\336" + "\377\244\377\3\310\353\210\372\13\20\0""7\0\0\0\7\226\0\0\0\0\7\0\0\0" + "\1\1\2\0\3Rs\17\14\212\2629)h\215#V1J\5\240<\\\1\377\205;[\1\377\7<]" + "\1\377Ad\1\377Jq\3\377f\220\33\377\222\272H\377\275\342{\377\336\375" + "\245\377\202\341\377\253\377\7\341\377\254\377\342\377\254\377\341\377" + "\253\377\341\377\254\377\342\377\254\377\341\377\254\377\342\377\254" + "\377\205\341\377\253\377\202\341\377\252\377\203\340\377\251\377\1\341" + "\377\251\377\211\340\377\250\377\203\340\377\247\377\3\315\356\217\374" + "\20\31\0<\0\0\0\7\222\0\0\0\0\21\0\0\0\1\4\5\0\3s\232&\31\270\334o[\312" + "\354\210\230\321\362\221\316\330\371\233\364\340\376\247\377\237\305" + "Z\377<\\\1\3774P\1\3422M\1\3353N\1\3354O\1\3415R\1\3518V\1\363;[\1\375" + "\202;[\1\377\202;Z\1\377\4@c\1\377W\177\17\377\220\270J\377\313\354\216" + "\377\215\342\377\255\377\202\342\377\254\377\3\341\377\253\377\341\377" + "\254\377\341\377\253\377\203\340\377\251\377\211\340\377\250\377\3\322" + "\363\225\375\24\40\0A\0\0\0\10\217\0\0\0\0\7\0\0\0\1\0\0\0\3\203\247" + "9\36\301\343|s\320\362\221\304\334\374\241\373\340\377\251\377\203\341" + "\377\252\377\24\330\367\235\377\220\266J\3777U\1\377\13\21\1y\0\0\0]" + "\0\0\0Z\0\0\0\\\0\0\0`\0\0\0d\4\6\0p\24\36\1\212#5\1\254/G\1\3178V\1" + "\363;Z\1\377:Y\1\377:Z\1\377Cg\1\377u\234.\377\276\340\177\377\213\342" + "\377\255\377\204\342\377\254\377\1\341\377\253\377\202\341\377\252\377" + "\212\340\377\250\377\3\325\366\231\376\33*\1F\0\0\0\10\215\0\0\0\0\35" + "\0\0\0\1/@\12\7\261\324iL\316\357\215\263\334\374\241\371\340\377\250" + "\377\340\377\251\377\334\373\242\377\273\337z\377\226\274P\377s\233," + "\377U|\16\377Ej\3\377@c\1\3778V\1\377\22\33\1Z\3\5\0'\1\2\0\40\0\0\0" + "\40\0\0\0\"\0\0\0%\0\0\0,\0\0\0""5\0\0\0C\0\0\0T\3\4\0g\31&\1\223-E\1" + "\3129W\1\367\202:Y\1\377\3\77b\1\377q\230,\377\304\345\210\377\205\342" + "\377\255\377\202\342\377\254\377\2\341\377\254\377\341\377\253\377\202" + "\341\377\252\377\3\340\377\251\377\341\377\251\377\340\377\251\377\210" + "\340\377\250\377\2\340\377\247\377\337\377\246\377\202\337\377\245\377" + "\3\326\370\231\377!2\2K\0\0\0\11\213\0\0\0\0\14\0\0\0\1CY\23\12\273\336" + "te\322\364\221\325\337\377\245\377\337\377\246\377\337\376\245\377\270" + "\334v\377\200\2479\377Ou\12\377@b\1\377<\\\1\377\204;[\1\377\26Ac\2\377" + "\313\356\212\362\325\366\227\356\323\365\223\346\317\361\216\324\311" + "\354\210\264\275\341y\210\231\302NQ0G\10\30\0\0\0\22\0\0\0\31\0\0\0'" + "\0\0\0:\0\0\0Q\10\14\1p%9\1\2617T\1\360:Y\1\3779X\1\377Be\3\377\206\253" + "B\377\330\366\237\377\202\341\377\253\377\202\340\377\251\377\2\340\377" + "\250\377\340\377\251\377\207\340\377\250\377\202\340\377\247\377\202" + "\337\377\246\377\1\337\377\245\377\202\336\377\244\377\204\336\377\243" + "\377\3\330\372\233\377(:\7O\0\0\0\12\211\0\0\0\0\4\0\0\0\1""7I\17\11" + "\274\336sd\324\366\223\337\202\336\377\243\377\4\331\373\234\377\241" + "\307\\\377\\\203\25\377\77b\1\377\204;[\1\377\6:Z\1\3734P\1\343-E\1\311" + "&:\1\2675Q\4\315\332\372\236\377\206\340\377\247\377\17\325\370\226\364" + "\305\353\200\254\234\307LN\23\35\1\14\0\0\0\15\0\0\0\30\0\0\0+\0\0\0" + "F\4\6\0f%8\1\2567U\1\3649X\1\377:Y\1\377Qv\20\377\262\325r\377\202\340" + "\377\250\377\202\340\377\247\377\1\337\377\246\377\202\337\377\245\377" + "\202\336\377\244\377\1\337\377\244\377\202\336\377\244\377\205\336\377" + "\243\377\205\336\377\242\377\4\336\377\241\377\331\373\232\377.B\12S" + "\0\0\0\12\207\0\0\0\0\4\0\0\0\1\3\5\0\4\260\322gJ\322\365\216\322\202" + "\335\377\237\377\5\333\376\235\377\247\315a\377V}\21\377=^\1\377;Z\1" + "\377\202;[\1\377\14""9W\1\363-D\1\306\34+\1\227\6\11\0m\0\0\0Z\0\0\0" + "O\0\0\0R/G\6\241\326\367\227\377\330\371\232\377\331\372\234\377\335" + "\376\241\377\205\336\377\243\377\21\335\376\241\377\312\361\205\326\243" + "\317S^\40""1\2\12\0\0\0\10\0\0\0\23\0\0\0'\0\0\0E\11\16\1m,C\1\3049X" + "\1\3759X\1\377=_\2\377\203\250A\377\332\373\236\377\336\377\243\377\336" + "\377\244\377\202\336\377\243\377\4\336\377\242\377\335\377\240\377\336" + "\377\241\377\336\377\242\377\203\335\377\241\377\202\335\377\240\377" + "\205\335\377\237\377\1\334\377\236\377\202\334\377\234\377\3\331\374" + "\230\3774J\16W\0\0\0\13\206\0\0\0\0\37\0\0\0\2\207\2549!\304\357q\255" + "\326\376\215\376\327\377\220\377\330\377\221\377\302\351|\377i\220\"" + "\377>_\1\377:Z\1\377;Z\1\377;[\1\3775Q\1\341\40""1\1\237\5\7\0e\0\0\0" + "L\0\0\0""8\0\0\0(\0\0\0\35\0\0\0\26\0\0\0$+A\1\220Gk\6\377Dg\3\377Dh" + "\5\377Lp\14\377`\204\37\377\201\245A\377\254\320k\377\326\372\224\377" + "\332\377\230\377\202\332\377\227\377%\331\376\224\377\300\355o\313\206" + "\2660=\0\0\0\5\0\0\0\7\0\0\0\23\0\0\0+\0\0\0M\31&\1\2145R\1\3539X\1\377" + ":Y\1\377a\206\37\377\314\356\214\377\335\377\240\377\335\377\237\377" + "\334\377\235\377\333\377\231\377\331\377\223\377\333\377\231\377\331" + "\377\225\377\330\377\221\377\327\377\220\377\327\377\216\377\326\377" + "\214\377\326\377\215\377\327\377\217\377\326\377\216\377\326\377\213" + "\377\324\377\206\377\321\377\177\377\317\377y\377\320\377{\377\321\377" + "~\377\320\375\177\3779P\21[\0\0\0\13\204\0\0\0\0\30\0\0\0\1\6\10\1\5" + "\250\333Ed\304\372a\356\311\377i\377\312\377k\377\312\376k\377\225\303" + "@\377Fj\4\377:Z\1\377:Y\1\377;Z\1\3776R\1\345\35,\1\224\0\1\0V\0\0\0" + ";\0\0\0$\0\0\0\25\0\0\0\13\0\0\0\7Dc\12\20\223\3054;a\211\31n4L\10\252" + "\207;[\1\377\3Eg\10\377\177\2467\377\300\356l\377\202\317\377x\377\12" + "\316\377w\377\310\372m\374\243\330C\2143M\4\15\0\0\0\3\0\0\0\10\0\0\0" + "\31\0\0\0""8\10\13\1e.F\2\313\2029X\1\377\30Mp\16\377\267\337n\377\325" + "\377\210\377\323\377\203\377\320\377|\377\321\377}\377\320\377z\377\316" + "\377u\377\315\377s\377\315\377r\377\314\377q\377\313\377o\377\313\377" + "l\377\311\377i\377\311\377g\377\307\377b\377\305\377^\377\305\377]\377" + "\305\377\\\377\305\377^\377\306\377a\377\306\375c\377<V\17_\0\0\0\14" + "\203\0\0\0\0\11\0\0\0\2x\245\"\37\256\355;\262\273\375F\377\275\376I" + "\377\276\376K\377\272\371H\377r\241\35\377=_\1\377\202:Y\1\377\32:X\1" + "\370';\1\252\3\4\0Y\0\0\0""7\0\0\0\35\0\0\0\15\0\0\0\7x\247\36#\247\343" + "8u\264\361E\300\275\372O\365\304\377Y\377}\255&\3779X\1\3770I\1\322+" + "B\1\303*A\1\301,D\1\3101L\1\3318V\1\361;[\1\377:Z\1\377:Y\1\377@a\4\377" + "\202\2553\377\302\372^\377\202\305\377^\377\3\304\377[\377\254\350\77" + "\311c\220\22%\202\0\0\0\3\24\0\0\0\16\0\0\0(\1\1\0P%8\2\2508W\1\3748" + "W\1\377Bd\5\377\244\323N\377\312\377k\377\311\377i\377\310\377e\377\307" + "\377c\377\305\377]\377\302\377V\377\300\377R\377\277\377O\377\277\376" + "M\377\276\376K\377\274\375I\377\273\375F\377\202\273\375E\377\7\272\375" + "E\377\272\375D\377\273\375F\377\274\375H\377\273\374G\377>Z\14b\0\0\0" + "\14\202\0\0\0\0\4\0\0\0\4\221\311*N\256\3609\352\263\366=\377\202\264" + "\367>\377\3\255\356:\377]\212\16\377;[\1\377\202:Y\1\377\11""5Q\1\341" + "\23\35\1v\0\0\0\77\0\0\0\37\0\0\0\15\10\14\1\10\215\305&D\252\3527\263" + "\265\370\77\372\202\270\373B\377\15\271\374C\377\263\365\77\377r\244" + "\31\3776S\1\377\15\23\1r\0\0\0O\0\0\0K\0\0\0O\0\0\0X\1\2\0e\23\35\1\210" + ")\77\1\2758U\1\363\2029X\1\377\26Sy\15\377\247\344:\377\271\374D\377" + "\271\374C\377\271\374D\377\253\3548\346q\243\27<\0\0\0\3\0\0\0\2\0\0" + "\0\10\0\0\0\35\0\0\0C\34+\1\2167U\1\3668W\1\377\77`\3\377\231\3159\377" + "\276\375L\377\273\374H\377\271\373C\377\267\372A\377\266\371@\377\202" + "\265\370\77\377\202\264\367>\377\1\263\366=\377\202\264\367>\377\205" + "\263\366=\377\7\264\367=\377A^\15e\0\0\0\15\0\0\0\1#1\6\11\231\325*\203" + "\252\3554\375\203\254\3576\377#\244\3452\377U~\12\377:Y\1\3779X\1\377" + ":Y\1\377/H\2\305\5\10\1W\0\0\0,\0\0\0\21\0\0\0\10\201\266\37""8\243\343" + "0\277\256\3618\377\257\3629\377\260\363:\377\226\322,\377k\233\27\377" + "Kq\7\377>_\1\377=_\1\3776R\1\377\22\32\1Q\0\0\0\31\0\0\0\23\0\0\0\25" + "\0\0\0\33\0\0\0%\0\0\0""5\0\0\0K\6\10\1j&:\1\2648V\1\3708W\1\377Ac\4" + "\377\223\316,\377\203\261\364;\377\14\250\3513\361s\247\27I\0\0\0\4\0" + "\0\0\1\0\0\0\5\0\0\0\26\0\0\0:\26\"\1~6T\1\3618W\1\377>_\3\377\222\315" + "+\377\202\260\363:\377\3\257\3629\377\256\3618\377\255\3607\377\202\254" + "\3576\377\202\255\3607\377\206\254\3576\377\7\255\3607\377\255\3606\377" + "B_\15g\0\0\0\15Wz\22\25\232\331'\266\243\346-\377\203\244\347.\377\21" + "\237\341,\377T}\12\3779Y\1\3779X\1\3779X\1\376+A\2\261\1\1\0H\0\0\0\40" + "\0\0\0\13Ed\14\22\224\322$\222\245\347/\373\247\3521\377\250\3532\377" + "\230\326*\377[\206\16\377=]\1\377\204;[\1\377\4\77a\2\377q\244\27\222" + "b\222\15""0\4\5\1\4\202\0\0\0\2\32\0\0\0\4\0\0\0\12\0\0\0\25\0\0\0*\0" + "\0\0I\17\27\1y2M\1\3358W\1\377=]\2\377\214\307%\377\251\3543\377\250" + "\3532\377\251\3543\377\240\342,\364l\236\22G\0\0\0\4\0\0\0\0\0\0\0\3" + "\0\0\0\22\0\0\0""4\24\36\1w6T\1\3618W\1\377@a\3\377\224\321(\377\250" + "\3532\377\202\246\3510\377\203\245\350/\377\2\246\3510\377\245\350/\377" + "\203\244\347.\377\202\245\350/\377\6\246\3510\377\245\350/\377\244\347" + ".\377Ca\14i\0\0\0\15\226\327\"\321\202\234\337&\377\1\234\340'\377\202" + "\235\340'\377\2]\212\15\3779Y\1\377\2029X\1\377\6)\77\2\252\0\0\0@\0" + "\0\0\31\0\0\0\11n\241\25""0\227\331$\325\202\237\342)\377\4\237\343)" + "\377}\264\33\377Ac\3\377:Z\1\377\202;[\1\377\11""7U\1\355-D\1\310%8\1" + "\264;[\4\317\240\343*\377\236\340(\375\217\317\35\267\\\212\10(\0\0\0" + "\3\202\0\0\0\0\11\0\0\0\2\0\0\0\7\0\0\0\26\0\0\0""3\3\5\0],C\1\3048W" + "\1\377\77`\3\377\223\321$\377\202\241\344+\377\15\240\343*\377\230\331" + "%\357Gm\5""5\0\0\0\3\0\0\0\0\0\0\0\3\0\0\0\20\0\0\0""2\26!\1y7U\1\365" + "8W\1\377Mt\7\377\236\341(\377\204\237\342)\377\205\236\341(\377\202\237" + "\342)\377\10\236\341(\377\234\337&\377\235\340'\377\235\341'\377Ba\12" + "k\0\0\0\15\222\324\35\377\225\330\37\377\203\226\331\40\377\12\212\311" + "\32\377=^\1\3778W\1\3779X\1\377,C\2\263\0\1\0>\0\0\0\26\0\0\0\10x\257" + "\26M\224\327\40\360\202\230\333\"\377\14\231\334#\377n\241\22\377;[\1" + "\377:Y\1\377:Z\1\3776T\1\350\36.\1\231\1\2\0`\0\0\0O\0\0\0Q3N\4\237\230" + "\333\"\377\202\231\334#\377\4\215\315\33\357R}\5W\0\0\0\6\0\0\0\1\202" + "\0\0\0\0\26\0\0\0\2\0\0\0\14\0\0\0&\1\1\0Q+A\1\275c\224\13\377\226\331" + "!\377\232\335$\377\232\335#\377\231\334#\377v\256\25\3779V\3\320\15\22" + "\4\22\0\0\0\2\0\0\0\0\0\0\0\2\0\0\0\17\0\0\0""4\32(\1\205=_\1\372\201" + "\276\25\377\230\333\"\377\203\231\334#\377\202\230\333\"\377\1\227\332" + "!\377\204\230\333\"\377\1\227\332!\377\202\226\331\40\377\5\225\330\37" + "\377\227\332!\377Aa\11l\0\0\0\16p\245\21\327\202\220\323\32\377\1\217" + "\322\31\377\202\220\323\32\377\10U\203\4\3777U\1\3771K\2\317\2\2\0B\0" + "\0\0\26\0\0\0\5\1\1\0\20|\266\25\334\203\222\325\34\377\14\201\276\25" + "\377:Z\1\3779X\1\377:Y\1\377-D\1\277\5\7\0^\0\0\0:\0\0\0\"\0\0\0\26\0" + "\0\0$7T\4\220\222\325\34\377\203\223\326\35\377\3}\272\21\373>_\2\\\0" + "\0\0\6\203\0\0\0\0\5\0\0\0\1\0\0\0\12\31&\1""3r\251\20\312\222\325\34" + "\377\203\223\326\35\377\5\177\272\25\377>_\1\3777T\1\362\31%\1""4\0\0" + "\0\5\202\0\0\0\0\7\0\0\0\3\0\0\0\26'<\1lx\263\20\371\221\324\33\377\222" + "\325\34\377\223\326\35\377\202\222\325\34\377\202\221\324\33\377\203" + "\222\325\34\377\203\221\324\33\377\203\220\323\32\377\5\221\324\33\377" + "@_\7m\0\0\0\16""4N\5\210\211\313\24\377\203\212\315\24\377\11\213\316" + "\25\377r\254\13\377Ae\1\377,C\1\270\0\0\0\40\0\0\0\5\0\0\0\3\0\0\0\36" + "R{\11\260\202\214\317\26\377\15\213\316\25\377\210\312\24\377Ek\1\377" + "8V\1\376';\2\251\0\0\0H\0\0\0#\0\0\0\15\0\0\0\4\0\0\0\2\0\0\0\26""8U" + "\3\212\215\317\27\377\204\215\320\27\377\3e\232\7\361)>\2""4\0\0\0\4" + "\202\0\0\0\0\4\0\0\0\2Q{\5'\201\300\21\321\214\317\26\377\202\215\320" + "\27\377\7\216\321\30\377\177\275\22\377Cf\2\3778V\1\375\37""0\1\210\0" + "\0\0$\0\0\0\5\202\0\0\0\0\3\0\0\0\4""7U\2=t\257\14\356\203\214\317\26" + "\377\203\215\320\27\377\1\214\317\26\377\202\215\320\27\377\4\213\316" + "\25\377\214\317\26\377\213\316\25\377\214\317\25\377\202\213\316\25\377" + "\1\212\315\24\377\202\213\316\25\377\6\77^\6m\0\0\0\16\1\2\0Fi\236\13" + "\336\206\311\20\377\206\311\17\377\202\206\311\20\377\11\202\304\16\377" + "R\177\1\3779X\1\367\26\40\2'\0\0\0\2\0\0\0\3\0\0\0\36\36-\1{{\270\16" + "\377\203\207\312\21\377\13d\231\6\3775Q\1\367\7\13\1O\0\0\0\32\0\0\0" + "\6\0\0\0\1\0\0\0\0\0\0\0\1\0\0\0\26""7S\3\213\210\312\22\377\204\210" + "\313\22\377\7\202\304\17\377Mw\2\304\4\6\1\20\0\0\0\2\0\0\0\4`\221\6" + ">\201\302\17\346\203\210\313\22\377\14\211\314\23\377}\274\17\377Di\2" + "\3778W\1\377&:\1\252\0\0\0\77\0\0\0\23\0\0\0\2\0\0\0\0\0\0\0\4>_\2""6" + "t\260\12\350\202\210\313\22\377\202\207\312\21\377\1\210\313\22\377\203" + "\211\314\23\377\1\207\312\22\377\203\207\312\21\377\2\206\311\20\377" + "\207\312\21\377\202\206\311\20\377\203\207\312\21\377\5=]\5m\0\0\0\16" + "\0\0\0)+B\3\207\177\300\13\376\204\202\305\14\377\17j\242\5\377Ho\1\377" + "3M\2\203\0\0\0\7\0\0\0\1\0\0\0\23\2\2\0IR}\5\344\204\307\15\377\203\306" + "\15\377\204\306\16\377{\273\13\377Fk\1\377(=\2{\0\0\0\13\203\0\0\0\0" + "\3\0\0\0\1\0\0\0\26""6R\2\212\202\204\307\16\377\1\203\306\15\377\203" + "\204\307\16\377\6o\252\7\377;Z\2l\0\0\0\14h\236\6]\201\302\14\365\205" + "\310\17\377\202\204\307\16\377\15\205\310\17\377y\266\14\377Ej\2\377" + "8W\1\377+B\1\275\1\1\0I\0\0\0\32\0\0\0\4\0\0\0\1\0\0\0\4Dh\2""9s\260" + "\10\350\203\306\15\377\204\204\307\16\377\3\203\305\16\377k\241\11\377" + "\203\306\16\377\204\204\307\16\377\210\203\306\15\377\5<[\4m\0\0\0\16" + "\0\0\0\24\0\1\0FY\210\6\321\204\177\302\11\377\12|\275\10\377V\206\1" + "\377Cg\1\350\30#\2\33\0\0\0\2\0\0\0\11\0\0\0""0$7\1\233q\255\7\377\177" + "\302\11\377\202\200\303\12\377\4d\232\3\3779X\1\334\10\13\1\25\0\0\0" + "\1\202\0\0\0\0\4\0\0\0\1\0\0\0\26""5Q\2\212\200\303\12\377\204\201\304" + "\13\377\202\200\303\12\377\3[\215\2\352e\234\5\223\177\301\12\374\204" + "\201\304\13\377\16s\256\11\377Bf\2\3778X\1\377-E\1\305\2\3\0O\0\0\0\37" + "\0\0\0\6\0\0\0\1\0\0\0\5Jr\2=t\261\6\352\201\304\13\377\200\303\12\377" + "\201\304\13\377\202\200\303\12\377\6}\275\13\377Nw\4\377<\\\1\377Kt\3" + "\377s\257\11\377\201\305\13\377\203\201\304\13\377\5\200\303\12\377\177" + "\302\11\377\200\303\12\377\201\304\13\377\201\303\13\377\202\177\302" + "\11\377\6""9X\3l\0\0\0\16\0\0\0\7\0\0\0(\24\36\1sr\257\6\371\204|\277" + "\6\377\11l\247\4\377P|\1\377>`\2\204\0\0\0\7\0\0\0\3\0\0\0\32\3\4\0R" + "Dh\2\350{\275\7\377\202}\300\7\377\4y\273\6\377S\201\1\3770I\2w\0\0\0" + "\7\202\0\0\0\0\6\0\0\0\1\0\0\0\26""5Q\2\212}\300\10\377~\301\10\377}" + "\300\7\377\204~\301\10\377\2{\275\7\377~\300\10\377\204~\301\10\377\14" + "h\240\5\377\77`\1\3779X\1\377-E\1\305\1\2\0Q\0\0\0\"\0\0\0\10\0\0\0\1" + "\0\0\0\6S\200\2Lu\265\5\360}\300\7\377\204~\301\10\377\10t\262\7\377" + "Ej\2\377;[\1\376<\\\1\377;[\1\377=]\1\377U\203\3\377w\266\10\377\203" + "~\301\10\377\2}\301\7\377~\301\10\377\202}\300\7\377\12|\277\6\377}\300" + "\7\3778V\2k\0\0\0\16\0\0\0\1\0\0\0\22\0\0\0B;[\2\261y\273\4\377z\275" + "\4\377\202y\274\3\377\25y\273\3\377^\222\1\377Kt\1\361)=\3(\0\0\0\2\0" + "\0\0\12\0\0\0""1\34+\1\217X\207\3\376z\275\4\377{\276\5\377z\275\4\377" + "p\256\3\377Lv\1\360$7\2.\0\0\0\3\0\0\0\0\0\0\0\1\0\0\0\26""5Q\2\212{" + "\275\5\377\212{\276\5\377\14z\273\5\377Z\212\3\377<\\\1\3779X\1\376*" + "@\1\272\1\2\0Q\0\0\0\"\0\0\0\10\0\0\0\2\1\1\0\10]\220\2iv\267\4\370\204" + "{\276\5\377\7|\277\6\377j\244\4\377>`\1\3777U\1\367\32(\1\244!3\1\254" + "9W\1\362\202;[\1\377\7\77a\1\377\\\216\4\377y\272\6\377|\277\6\377{\276" + "\5\377z\275\4\377{\276\5\377\203z\275\4\377\7""6T\2j\0\0\0\16\0\0\0\0" + "\0\0\0\5\0\0\0\"\4\6\0]V\206\2\345\203w\272\1\377\12w\271\1\377q\261" + "\1\377V\205\1\377Be\2\255\1\1\0\11\0\0\0\3\0\0\0\27\0\0\0J/G\1\311b\231" + "\2\377\203x\273\2\377\7k\246\1\377Mw\1\313\30$\2\25\0\0\0\2\0\0\0\1\0" + "\0\0\26""6S\1\212\206x\273\2\377\202y\274\3\377\16x\273\2\377y\274\3" + "\377m\252\3\377Iq\1\377;Z\1\3779X\1\373#5\1\244\0\0\0L\0\0\0!\0\0\0\10" + "\0\0\0\3\30$\1\16f\237\2\223w\271\2\375\204x\273\2\377\12x\273\3\377" + "\\\216\2\377;Z\1\3775R\1\355\23\36\1\204\0\0\0O\0\0\0K\11\15\0k+A\1\275" + ":Z\1\372\202;[\1\377\3Ch\1\377d\233\2\377y\273\3\377\204x\273\2\377\11" + "w\272\2\3774P\1i\0\0\0\15\0\0\0\0\0\0\0\1\0\0\0\15\0\0\0""6\30$\1\206" + "f\236\1\374\202u\266\1\377\14u\267\1\377u\266\1\377i\243\1\377Oz\1\377" + "8U\2^\0\0\0\5\0\0\0\7\0\0\0'\10\14\1e7T\1\351e\236\1\377v\267\1\377\202" + "v\270\1\377\7k\246\1\377R~\1\267\30$\2\21\0\0\0\2\0\0\0\26""7V\1\212" + "v\267\1\377\206v\270\1\377\20v\271\1\377p\257\1\377U\204\1\377>_\1\377" + ";[\1\3777T\1\353\27#\1\207\0\0\0D\0\0\0\35\0\0\0\7\0\0\0\4Fm\2&m\252" + "\1\303v\267\1\377v\270\1\377v\271\1\377\202v\270\1\377\22s\264\1\377" + "Nx\1\3779Y\1\3772M\1\335\13\21\1q\0\0\0;\0\0\0\32\0\0\0\25\0\0\0)\0\0" + "\0J\17\27\1y/I\1\315;[\1\376;[\1\377<\\\1\377Ny\1\377q\260\1\377v\270" + "\1\377\203v\267\1\377\2""1L\1f\0\0\0\15\202\0\0\0\0\23\0\0\0\3\0\0\0" + "\27\0\0\0I-E\1\263l\247\1\377s\262\1\377r\261\1\377r\262\1\377r\261\1" + "\377c\231\1\377Ho\1\355-D\3,\0\0\0\3\0\0\0\16\0\0\0""5\22\33\1|9Y\1\364" + "`\225\1\377t\263\1\377\202s\263\1\377\30n\253\1\377\\\216\1\3057T\2%" + "\0\0\0\31""9X\1\212s\263\1\377t\264\1\377t\265\1\377u\265\1\377t\265" + "\1\377r\261\1\377e\236\1\377Q~\1\377\77`\1\377;[\1\377;Z\1\375,C\1\302" + "\7\12\0f\0\0\0""8\0\0\0\26\0\0\0\6\2\3\0\10`\224\2^p\257\1\354\202t\264" + "\1\377\27t\265\1\377t\264\1\377t\265\1\377h\241\1\377Ch\1\3779X\1\376" + "*@\1\276\3\4\0_\0\0\0""2\0\0\0\22\0\0\0\4\0\0\0\2\0\0\0\7\0\0\0\26\0" + "\0\0""0\0\0\0Q\30$\1\2125Q\1\342;[\1\377:Y\1\377Ek\1\377q\260\1\377t" + "\264\1\377\202s\263\1\377\2.G\1c\0\0\0\15\203\0\0\0\0\5\0\0\0\7\0\0\0" + "$\2\2\0Z<\\\1\327l\250\1\377\202o\255\1\377&p\255\1\377n\253\1\377^\222" + "\1\377Ch\1\316\36-\2\25\0\0\0\4\0\0\0\24\0\0\0>\26!\1\2108W\1\365S\201" + "\1\377n\254\1\377p\257\1\377p\256\1\377p\255\1\377h\242\1\355Oz\1\204" + ".G\1\227Cg\1\377Lv\1\377P{\1\377Ny\1\377Ho\1\377\77b\1\377<]\1\377;[" + "\1\377;[\1\3751K\1\324\24\37\1\205\0\0\0N\0\0\0*\0\0\0\20\0\0\0\7Ir\2" + "$j\244\1\256p\257\1\376p\257\1\377q\260\1\377\202q\257\1\377\11p\257" + "\1\377V\206\1\377<\\\1\3778W\1\367\36.\1\235\0\0\0Q\0\0\0)\0\0\0\15\0" + "\0\0\2\203\0\0\0\0\10\0\0\0\2\0\0\0\12\0\0\0\33\0\0\0""8\3\4\0_,D\1\307" + "Gm\1\377h\241\1\377\204p\256\1\377\2+B\1`\0\0\0\15\203\0\0\0\0\25\0\0" + "\0\1\0\0\0\14\0\0\0""0\11\16\1mCg\1\352j\245\1\377l\247\1\377l\250\1" + "\377l\247\1\377k\246\1\377[\216\1\377Ac\2\264\21\31\3\15\0\0\0\5\0\0" + "\0\27\0\0\0A\22\34\1\2025R\1\353Di\1\377_\223\1\377m\250\1\377\202m\251" + "\1\377\3W\207\1\377<\\\1\3769X\1\365\204<\\\1\377\13<\\\1\3756S\1\350" + "*@\1\276\21\32\1\202\0\0\0U\0\0\0""6\0\0\0\32\0\0\0\13,E\2\23e\234\1" + "}l\250\1\361\202m\252\1\377\203n\253\1\377\11f\236\1\377Fm\1\377;Z\1" + "\3772M\1\335\20\30\1|\0\0\0E\0\0\0\37\0\0\0\11\0\0\0\1\206\0\0\0\0\5" + "\0\0\0\4\1\1\0\24+B\1\205T\203\1\370l\250\1\377\204m\251\1\377\3l\250" + "\1\377(>\1]\0\0\0\14\204\0\0\0\0\6\0\0\0\2\0\0\0\21\0\0\0:\21\31\1\177" + "Ek\1\363g\240\1\377\203h\242\1\377\35h\241\1\377[\216\1\377@b\2\251\25" + "\37\2\15\0\0\0\6\0\0\0\27\0\0\0=\10\13\0n-E\1\314;[\1\376Ek\1\377X\210" + "\1\377f\236\1\377U\203\1\3778U\1\377\14\23\1\211\13\21\1\201\27#\1\222" + "\31'\1\226\25\40\1\214\7\13\0u\0\0\0`\0\0\0L\0\0\0""4\0\0\0\36\0\0\0" + "\17""3P\1\27c\232\1ti\243\1\343\202j\245\1\377\15k\245\1\377j\244\1\377" + "j\245\1\377h\242\1\377R~\1\377=]\1\377:X\1\372%9\1\260\2\2\0_\0\0\0""6" + "\0\0\0\26\0\0\0\5\0\0\0\1\206\0\0\0\0\7\0\0\0\3)>\2(Ks\1\271d\233\1\377" + "i\244\1\377j\244\1\377j\245\1\377\203j\244\1\377\3i\243\1\377%9\1Z\0" + "\0\0\14\205\0\0\0\0\6\0\0\0\3\0\0\0\26\0\0\0B\25\40\1\212Dh\1\367c\231" + "\1\377\203e\235\1\377\17f\236\1\377^\222\1\377Ad\2\263\37/\2\23\0\0\0" + "\5\0\0\0\23\0\0\0""2\0\0\0Y\30%\1\2243N\1\336;[\1\376=^\1\377Ad\1\377" + "6S\1\377\20\30\1c\202\0\0\0""9\14\0\0\0;\0\0\0""7\0\0\0.\0\0\0#\0\0\0" + "\30\13\21\0\23W\207\2>d\233\1\225g\240\1\354g\237\1\377g\240\1\377g\237" + "\1\377\202g\240\1\377\12f\236\1\377V\205\1\377@c\1\377;[\1\3773N\1\335" + "\22\34\1\203\0\0\0L\0\0\0'\0\0\0\16\0\0\0\3\206\0\0\0\0\5\0\0\0\2\35" + ",\2\23Ho\2\204^\221\1\363g\240\1\377\206g\237\1\377\4f\237\1\377f\235" + "\1\377!3\1U\0\0\0\13\206\0\0\0\0\7\0\0\0\5\0\0\0\32\0\0\0E\26\"\1\215" + "\77b\1\365^\222\1\377c\231\1\377\203c\232\1\377\26b\231\1\377Gn\1\317" + "-D\2+\0\0\0\5\0\0\0\14\0\0\0\"\0\0\0A\0\0\0`\24\37\1\215*A\1\3036S\1" + "\352;[\1\376=^\1\177:Y\1=,D\2)-F\1(Fm\1""3Z\214\1Ja\227\1pd\233\1\242" + "e\235\1\341e\234\1\377\205d\233\1\377\13b\231\1\377T\202\1\377Ad\1\377" + "<\\\1\3778U\1\357\40""1\1\244\1\1\0^\0\0\0""9\0\0\0\31\0\0\0\7\0\0\0" + "\1\205\0\0\0\0\5\0\0\0\2\32'\2\17Kt\2q]\221\1\345f\236\1\377\203d\233" + "\1\377\1d\232\1\377\202d\233\1\377\1c\232\1\377\202d\233\1\377\3c\231" + "\1\377\36.\1R\0\0\0\13\207\0\0\0\0\6\0\0\0\5\0\0\0\33\0\0\0F\23\34\1" + "\207:Y\1\357W\206\1\377\204a\227\1\377\15e\235\1\377T\202\1\3619W\2l" + "\16\25\1\12\0\0\0\7\0\0\0\21\0\0\0$\0\0\0<\0\0\0S\0\0\0h&;\1\250b\231" + "\1\377f\236\1\377\202f\237\1\376\2e\234\1\377b\231\1\377\207b\230\1\377" + "\13[\215\1\377Mw\1\377\77a\1\377<\\\1\3778V\1\361%8\1\261\4\7\0k\0\0" + "\0F\0\0\0%\0\0\0\16\0\0\0\3\204\0\0\0\0\6\0\0\0\1\0\0\0\3+@\2\27R\177" + "\1y_\224\1\345e\235\1\377\204a\227\1\377\202b\227\1\377\202a\227\1\377" + "\1b\230\1\377\202a\227\1\377\3`\225\1\377\34*\1N\0\0\0\13\210\0\0\0\0" + "\7\0\0\0\6\0\0\0\32\0\0\0B\14\22\0y3N\1\340Ku\1\377_\223\1\377\203`\226" + "\1\377\14b\231\1\377b\230\1\377Nx\1\3122M\2J\10\14\1\10\0\0\0\6\0\0\0" + "\15\0\0\0\31\0\0\0""3(=\1\224`\224\1\377a\226\1\377\207a\227\1\377\16" + "_\224\1\377X\211\1\377Ny\1\377Cg\1\377=]\1\377<\\\1\3775R\1\346\"4\1" + "\253\5\7\0l\0\0\0K\0\0\0,\0\0\0\24\0\0\0\6\0\0\0\1\203\0\0\0\0\6\0\0" + "\0\1\5\7\0\5>`\2""2[\214\1\230c\231\1\361d\233\1\377\202`\226\1\377\206" + "a\226\1\377\203`\226\1\377\202`\225\1\377\3^\222\1\376\30$\1J\0\0\0\12" + "\211\0\0\0\0\10\0\0\0\5\0\0\0\26\0\0\0:\3\5\0h)\77\1\300@c\1\375V\205" + "\1\377a\226\1\377\203a\227\1\377\11d\234\1\377b\230\1\377T\202\1\316" + "=^\2n\"4\2\35\0\0\0\6\0\0\0\32+B\1\212W\207\1\377\202Z\214\1\377\7Y\212" + "\1\377W\210\1\377T\203\1\377P|\1\377Kt\1\377Di\1\377>`\1\377\202<]\1" + "\377\11""8V\1\357+B\1\305\25\40\1\217\0\1\0c\0\0\0H\0\0\0-\0\0\0\26\0" + "\0\0\10\0\0\0\2\202\0\0\0\0\10\0\0\0\1\0\0\0\4.G\2\36T\202\2ra\226\1" + "\310f\236\1\375c\232\1\377b\227\1\377\205a\227\1\377\2a\226\1\377`\226" + "\1\377\206`\225\1\377\4`\226\1\377]\221\1\375\24\35\1E\0\0\0\11\212\0" + "\0\0\0\11\0\0\0\3\0\0\0\21\0\0\0/\0\0\0W\27#\1\2246S\1\351Fl\1\377Y\212" + "\1\377b\230\1\377\203c\231\1\377\6c\232\1\377h\242\1\377`\225\1\373[" + "\215\1\315Nx\1\2402M\1\276\204=^\1\377\203<]\1\377\14;[\1\3727T\1\352" + "/I\1\321$8\1\262\22\33\1\212\1\1\0h\0\0\0S\0\0\0<\0\0\0%\0\0\0\24\0\0" + "\0\10\0\0\0\2\202\0\0\0\1\6\0\0\0\4&9\2\30Mx\2e_\223\1\274f\236\1\372" + "g\237\1\377\202c\232\1\377\203c\231\1\377\207b\230\1\377\1b\227\1\377" + "\205a\227\1\377\3]\221\1\374\20\30\1@\0\0\0\11\213\0\0\0\0\12\0\0\0\2" + "\0\0\0\13\0\0\0\"\0\0\0E\3\5\0l$7\1\2639X\1\363Fl\1\377V\206\1\377c\232" + "\1\377\205e\235\1\377\33X\210\1\3779X\1\377\36.\1\251\35,\1\243\37/\1" + "\247\36.\1\245\34+\1\237\27#\1\225\16\25\0\205\4\7\0s\0\0\0f\0\0\0Z\0" + "\0\0K\0\0\0:\0\0\0)\0\0\0\31\0\0\0\15\0\0\0\5\0\0\0\2\0\0\0\3\16\25\1" + "\10""4O\2""3R\177\1y_\224\1\277f\236\1\366k\246\1\377g\237\1\377\202" + "f\236\1\377\3e\235\1\377d\234\1\377e\235\1\377\203d\233\1\377\1c\232" + "\1\377\202d\233\1\377\203c\233\1\377\202d\233\1\377\1c\232\1\377\203" + "c\231\1\377\3^\222\1\373\14\21\1;\0\0\0\10\214\0\0\0\0'\0\0\0\1\0\0\0" + "\6\0\0\0\25\0\0\0/\0\0\0Q\6\11\0t%8\1\2657U\1\355\77b\1\377Lv\1\377Y" + "\213\1\377d\233\1\377i\242\1\377i\243\1\377Z\213\1\3778U\1\377\17\26" + "\1p\0\0\0I\0\0\0F\0\0\0E\0\0\0C\0\0\0>\0\0\0""7\0\0\0/\0\0\0&\0\0\0\34" + "\0\0\0\23\0\0\0\14\0\0\0\7\0\0\0\5\11\16\1\10,C\2-Gn\2dZ\213\2\241b\230" + "\1\342l\247\1\377m\251\1\377j\244\1\377i\244\1\377\202i\243\1\377\5h" + "\242\1\377h\241\1\377g\241\1\377g\240\1\377h\240\1\377\203g\240\1\377" + "\1g\237\1\377\203g\240\1\377\202g\237\1\377\203g\240\1\377\6g\237\1\377" + "f\236\1\377f\235\1\377`\224\1\371\10\13\0""7\0\0\0\10\216\0\0\0\0#\0" + "\0\0\2\0\0\0\12\0\0\0\32\0\0\0""3\0\0\0P\1\2\0k\31&\1\232-E\1\3149W\1" + "\362=_\1\377Cg\1\377Ku\1\377Lu\1\3778V\1\377\24\36\1S\0\0\0\27\0\0\0" + "\21\0\0\0\20\0\0\0\17\0\0\0\15\0\0\0\13\0\0\0\11\0\0\0\10\24\36\2\17" + ")>\2*=]\2TR~\2\205^\221\2\273d\233\2\356n\253\1\377q\261\1\377o\255\1" + "\377n\254\1\377n\253\1\377m\252\1\377\202m\251\1\377\203l\250\1\377\1" + "l\247\1\377\203k\247\1\377\2l\250\1\377k\247\1\377\207k\246\1\377\205" + "j\245\1\377\4j\244\1\377b\227\1\367\4\6\1""3\0\0\0\7\220\0\0\0\0\37\0" + "\0\0\3\0\0\0\12\0\0\0\31\0\0\0-\0\0\0D\0\0\0[\2\3\0o\22\34\1\216#6\1" + "\261-E\1\3143O\1\3409W\1\364Ek\2\255Hn\2\201Fl\2tGm\2vLu\2\200R\177\3" + "\216X\210\3\243]\220\3\273a\227\2\332g\237\2\364o\254\2\376u\266\2\377" + "u\265\1\377t\264\1\377t\263\1\377s\263\1\377s\262\1\377r\262\1\377r\261" + "\1\377\206q\260\1\377\202q\257\1\377\2p\257\1\377p\256\1\377\202p\257" + "\1\377\1q\257\1\377\202p\256\1\377\1o\255\1\377\203p\256\1\377\202o\255" + "\1\377\202o\254\1\377\1n\254\1\377\202n\253\1\377\3c\232\1\365\2\3\1" + "1\0\0\0\7\222\0\0\0\0\14\0\0\0\2\0\0\0\7\0\0\0\21\0\0\0\36\0\0\0.\0\0" + "\0>\0\0\0M\0\0\0Z\0\0\0h\"4\1\244q\257\3\377z\275\4\377\202z\276\4\377" + "\1z\275\4\377\202y\274\3\377\203x\273\2\377\2x\272\2\377w\272\2\377\202" + "w\272\1\377\204w\271\1\377\1v\271\1\377\207v\270\1\377\202v\267\1\377" + "\203u\267\1\377\1v\267\1\377\202u\266\1\377\3t\265\1\377u\266\1\377u" + "\265\1\377\202u\266\1\377\1t\265\1\377\202t\264\1\377\203s\263\1\377" + "\3f\236\1\364\2\3\1/\0\0\0\6\224\0\0\0\0\11\0\0\0\1\0\0\0\3\0\0\0\7\0" + "\0\0\15\0\0\0\24\0\0\0\35\0\0\0""1%9\1\222r\260\6\377\214}\300\7\377" + "\207|\277\6\377\2{\276\5\377|\277\6\377\206{\276\5\377\206z\275\4\377" + "\206y\274\3\377\203x\273\2\377\202x\272\2\377\3g\240\2\363\1\2\0.\0\0" + "\0\6\230\0\0\0\0\5\0\0\0\1\0\0\0\3\0\0\0\26(>\1\207t\261\10\377\221\201" + "\304\13\377\211\200\303\12\377\202\177\302\11\377\205~\301\10\377\202" + "}\300\7\377\203|\277\6\377\206}\300\7\377\3i\241\5\362\1\2\0-\0\0\0\6" + "\231\0\0\0\0\4\0\0\0\1\0\0\0\23)\77\1\205s\260\11\377\224\203\306\15" + "\377\207\202\305\14\377\3\201\304\13\377\200\303\12\377\201\304\13\377" + "\203\200\303\12\377\206\177\302\11\377\205\200\303\12\377\3h\237\6\361" + "\1\1\0,\0\0\0\6\231\0\0\0\0\4\0\0\0\1\0\0\0\23)@\1\204Y\211\4\377\202" + "a\224\5\377\2a\224\6\377`\223\6\377\202`\222\6\377\1a\224\6\377\202a" + "\225\6\377\24a\224\6\377`\223\6\377_\222\6\377_\221\6\377_\222\6\377" + "a\224\6\377a\225\6\377b\225\6\377b\226\6\377b\225\6\377b\226\6\377b\225" + "\6\377a\225\5\377a\224\5\377`\223\5\377`\222\5\377_\222\5\377^\221\5" + "\377^\220\5\377^\217\5\377\203]\217\5\377\2^\217\5\377^\220\5\377\204" + "_\222\4\377\4^\220\4\377]\217\5\377]\216\5\377\\\216\5\377\202\\\215" + "\4\377\3P{\3\361\1\1\0,\0\0\0\5\231\0\0\0\0\4\0\0\0\1\0\0\0\21\37/\1" + "f.G\1\301\212-E\1\311\1-D\1\311\203-E\1\311\4-D\1\311-E\1\311,D\1\311" + "-E\1\311\202,D\1\310\1,D\1\311\217,D\1\310\1,C\1\310\202,D\1\310\204" + ",C\1\310\4,D\1\306.F\1\256\0\1\0(\0\0\0\5\232\0\0\0\0\3\0\0\0\13\0\0" + "\0-\0\0\0O\253\0\0\0[\4\0\0\0W\0\0\0A\0\0\0\32\0\0\0\3\232\0\0\0\0\4" + "\0\0\0\3\0\0\0\16\0\0\0\31\0\0\0\34\211\0\0\0\35\241\0\0\0\34\4\0\0\0" + "\33\0\0\0\24\0\0\0\10\0\0\0\1\233\0\0\0\0\1\0\0\0\1\255\0\0\0\2\202\0" + "\0\0\1\377\0\0\0\0\377\0\0\0\0\377\0\0\0\0\377\0\0\0\0\377\0\0\0\0\377" + "\0\0\0\0\313\0\0\0\0", +}; + +static const GdkPixdata nvidia_icon_pixdata = { + 0x47646b50, /* Pixbuf magic: 'GdkP' */ + 24 + 10776, /* header length + pixel_data length */ + 0x2010002, /* pixdata_type */ + 304, /* rowstride */ + 76, /* width */ + 76, /* height */ + nvidia_icon_pixdata_pixel_data, /* pixel_data: */ +}; diff --git a/src/libXNVCtrl/NVCtrl.h b/src/libXNVCtrl/NVCtrl.h index a705c66..f146e4a 100644 --- a/src/libXNVCtrl/NVCtrl.h +++ b/src/libXNVCtrl/NVCtrl.h @@ -3062,6 +3062,7 @@ #define NV_CTRL_GVO_LOCK_OWNER_X_SCREEN 3 + /* * NV_CTRL_HWOVERLAY - when a workstation overlay is in use, reports * whether the hardware overlay is used, or if the overlay is emulated. @@ -3071,17 +3072,14 @@ #define NV_CTRL_HWOVERLAY_FALSE 0 #define NV_CTRL_HWOVERLAY_TRUE 1 - /* - * NV_CTRL_REFRESH_RATE_3 - Returns the refresh rate of the specified - * display device in 1000 * Hz (ie. to get the refresh rate in Hz, divide - * the returned value by 1000.) - * - * This attribute may be queried through XNVCTRLQueryTargetAttribute() - * using a NV_CTRL_TARGET_TYPE_GPU or NV_CTRL_TARGET_TYPE_X_SCREEN target. + * NV_CTRL_NUM_GPU_ERRORS_RECOVERED - Returns the number of gpu errors + * occured. This attribute may be queried through XNVCTRLQueryTargetAttribute() + * using a NV_CTRL_TARGET_TYPE_X_SCREEN target. */ -#define NV_CTRL_REFRESH_RATE_3 260 /* R-DG */ +#define NV_CTRL_NUM_GPU_ERRORS_RECOVERED 259 /* R--- */ + /* @@ -3096,8 +3094,71 @@ #define NV_CTRL_ONDEMAND_VBLANK_INTERRUPTS_ON 1 -#define NV_CTRL_LAST_ATTRIBUTE NV_CTRL_ONDEMAND_VBLANK_INTERRUPTS +/* + * NV_CTRL_GPU_POWER_SOURCE reports the type of power source + * of the GPU driving the X screen. + */ + +#define NV_CTRL_GPU_POWER_SOURCE 262 /* R--G */ +#define NV_CTRL_GPU_POWER_SOURCE_AC 0 +#define NV_CTRL_GPU_POWER_SOURCE_BATTERY 1 + + +/* + * NV_CTRL_GPU_CURRENT_PERFORMANCE_MODE 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. + */ + +#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 + + +/* + * NV_CTRL_GPU_CURRENT_PERFORMANCE_LEVEL reports the current + * Performance level of the GPU driving the X screen. Each + * Performance level has associated NVClock and Mem Clock values. + */ + +#define NV_CTRL_GPU_CURRENT_PERFORMANCE_LEVEL 265 /* R--G */ + + +/* + * NV_CTRL_GPU_ADAPTIVE_CLOCK_STATE reports if Adaptive Clocking + * is Enabled on the GPU driving the X screen. + */ + +#define NV_CTRL_GPU_ADAPTIVE_CLOCK_STATE 266 /* R--G */ +#define NV_CTRL_GPU_ADAPTIVE_CLOCK_STATE_DISABLED 0 +#define NV_CTRL_GPU_ADAPTIVE_CLOCK_STATE_ENABLED 1 + +/* + * NV_CTRL_SWITCH_TO_DISPLAYS takes display to which + * user wants to switch. + */ + +#define NV_CTRL_SWITCH_TO_DISPLAYS 276 /* -W- */ + +/* + * NV_CTRL_NOTEBOOK_DISPLAY_CHANGE_LID_EVENT can be used to send event + * to notify open/closure of the lid. + */ + +#define NV_CTRL_NOTEBOOK_DISPLAY_CHANGE_LID_EVENT 277 /* RW- */ +#define NV_CTRL_NOTEBOOK_DISPLAY_CHANGE_LID_EVENT_CLOSE 0 +#define NV_CTRL_NOTEBOOK_DISPLAY_CHANGE_LID_EVENT_OPEN 1 + +/* + * NV_CTRL_NOTEBOOK_INTERNAL_LCD returns intenal LCD + * of Notebook. + */ + +#define NV_CTRL_NOTEBOOK_INTERNAL_LCD 278 /* R-- */ + +#define NV_CTRL_LAST_ATTRIBUTE NV_CTRL_NOTEBOOK_INTERNAL_LCD /**************************************************************************/ diff --git a/src/libXNVCtrl/libXNVCtrl.a b/src/libXNVCtrl/libXNVCtrl.a Binary files differindex b4368fa..c18ed09 100644 --- a/src/libXNVCtrl/libXNVCtrl.a +++ b/src/libXNVCtrl/libXNVCtrl.a diff --git a/src/nvgetopt.c b/src/nvgetopt.c index 8e8120e..14a1d4c 100644 --- a/src/nvgetopt.c +++ b/src/nvgetopt.c @@ -220,14 +220,26 @@ int nvgetopt(int argc, char *argv[], const NVGetoptOption *options, } if (strval) *strval = strdup(argument); } else { - argv_index++; - if (argv_index >= argc) { - fprintf(stderr, "%s: option \"%s\" requires an argument.\n", - argv[0], arg); - goto done; + /* + * if the argument is optional, and we're either at the + * end of the argv list, or the next argv starts with '-', + * then assume there is no argument for this option + */ + + if ((o->flags & NVGETOPT_ARGUMENT_IS_OPTIONAL) && + ((argv_index == (argc - 1)) || + (argv[argv_index + 1][0] == '-'))) { + if (strval) *strval = NULL; + } else { + argv_index++; + if (argv_index >= argc) { + fprintf(stderr, "%s: option \"%s\" requires an argument.\n", + argv[0], arg); + goto done; + } + if (strval) *strval = argv[argv_index]; } - if (strval) *strval = argv[argv_index]; - } + } } ret = o->val; diff --git a/src/nvgetopt.h b/src/nvgetopt.h index a6ed8b6..d1cbcc8 100644 --- a/src/nvgetopt.h +++ b/src/nvgetopt.h @@ -29,8 +29,9 @@ #define NVGETOPT_TRUE 1 #define NVGETOPT_INVALID 2 -#define NVGETOPT_HAS_ARGUMENT 0x1 -#define NVGETOPT_IS_BOOLEAN 0x2 +#define NVGETOPT_HAS_ARGUMENT 0x1 +#define NVGETOPT_IS_BOOLEAN 0x2 +#define NVGETOPT_ARGUMENT_IS_OPTIONAL 0x4 typedef struct { const char *name; diff --git a/src/parse.c b/src/parse.c index 4b12e23..9442955 100644 --- a/src/parse.c +++ b/src/parse.c @@ -60,8 +60,8 @@ static char *nv_strndup(char *s, int n); #define A NV_PARSER_TYPE_NO_QUERY_ALL #define Z NV_PARSER_TYPE_NO_ZERO_VALUE #define H NV_PARSER_TYPE_100Hz -#define K NV_PARSER_TYPE_1000Hz #define S NV_PARSER_TYPE_STRING_ATTRIBUTE +#define W NV_PARSER_TYPE_VALUE_IS_SWITCH_DISPLAY AttributeTableEntry attributeTable[] = { @@ -87,8 +87,11 @@ AttributeTableEntry attributeTable[] = { { "HWOverlay", NV_CTRL_HWOVERLAY, 0 }, { "Stereo", NV_CTRL_STEREO, 0 }, { "TwinView", NV_CTRL_TWINVIEW, 0 }, - { "ConnectedDisplays", NV_CTRL_CONNECTED_DISPLAYS, 0 }, - { "EnabledDisplays", NV_CTRL_ENABLED_DISPLAYS, 0 }, + { "ConnectedDisplays", NV_CTRL_CONNECTED_DISPLAYS, D }, + { "EnabledDisplays", NV_CTRL_ENABLED_DISPLAYS, D }, + { "NotebookInternalLCD", NV_CTRL_NOTEBOOK_INTERNAL_LCD, N|D }, + { "NotebookDisplayChangeLidEvent", NV_CTRL_NOTEBOOK_DISPLAY_CHANGE_LID_EVENT, N }, + { "SwitchToDisplays", NV_CTRL_SWITCH_TO_DISPLAYS, D|N|W }, { "AssociatedDisplays", NV_CTRL_ASSOCIATED_DISPLAY_DEVICES, N|D }, { "ProbeDisplays", NV_CTRL_PROBE_DISPLAYS, A }, { "ForceGenericCpu", NV_CTRL_FORCE_GENERIC_CPU, 0 }, @@ -104,7 +107,6 @@ AttributeTableEntry attributeTable[] = { { "FSAAAppControlled", NV_CTRL_FSAA_APPLICATION_CONTROLLED, 0 }, { "LogAnisoAppControlled", NV_CTRL_LOG_ANISO_APPLICATION_CONTROLLED,0 }, { "RefreshRate", NV_CTRL_REFRESH_RATE, N|H }, - { "RefreshRate3", NV_CTRL_REFRESH_RATE_3, N|K }, { "InitialPixmapPlacement",NV_CTRL_INITIAL_PIXMAP_PLACEMENT, N }, { "PCIBus", NV_CTRL_PCI_BUS, N }, { "PCIDevice", NV_CTRL_PCI_DEVICE, N }, @@ -119,6 +121,7 @@ AttributeTableEntry attributeTable[] = { { "GPUScalingActive", NV_CTRL_GPU_SCALING_ACTIVE, N }, { "DFPScalingActive", NV_CTRL_DFP_SCALING_ACTIVE, N }, { "FSAAAppEnhanced", NV_CTRL_FSAA_APPLICATION_ENHANCED, 0 }, + { "GPUErrors", NV_CTRL_NUM_GPU_ERRORS_RECOVERED, N }, { "OnDemandVBlankInterrupts", NV_CTRL_ONDEMAND_VBLANK_INTERRUPTS, 0 }, { "FrameLockMaster", NV_CTRL_FRAMELOCK_MASTER, N|F|G|D }, @@ -214,7 +217,10 @@ AttributeTableEntry attributeTable[] = { { "XF86VidModeVersion", NV_CTRL_STRING_XF86VIDMODE_VERSION, S|N }, { "XvVersion", NV_CTRL_STRING_XV_VERSION, S|N }, { "SLIMode", NV_CTRL_STRING_SLI_MODE, S|N }, - + { "GPUCurrentPerfMode", NV_CTRL_GPU_CURRENT_PERFORMANCE_MODE, N }, + { "GPUCurrentPerfLevel", NV_CTRL_GPU_CURRENT_PERFORMANCE_LEVEL, N }, + { "GPUAdaptiveClockState", NV_CTRL_GPU_ADAPTIVE_CLOCK_STATE, N }, + { "GPUPowerSource", NV_CTRL_GPU_POWER_SOURCE, N }, { NULL, 0, 0 } }; @@ -228,8 +234,8 @@ AttributeTableEntry attributeTable[] = { #undef A #undef Z #undef H -#undef K #undef S +#undef W /* * When new integer attributes are added to NVCtrl.h, an entry should @@ -238,7 +244,7 @@ AttributeTableEntry attributeTable[] = { * about. */ -#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_ONDEMAND_VBLANK_INTERRUPTS +#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_NOTEBOOK_INTERNAL_LCD #warning "Have you forgotten to add a new integer attribute to attributeTable?" #endif diff --git a/src/parse.h b/src/parse.h index 8a596bd..ddf45b6 100644 --- a/src/parse.h +++ b/src/parse.h @@ -34,28 +34,28 @@ * Flag values used in the flags field of the ParsedAttribute struct. */ -#define NV_PARSER_HAS_X_DISPLAY (1<<0) -#define NV_PARSER_HAS_TARGET (1<<2) -#define NV_PARSER_HAS_DISPLAY_DEVICE (1<<3) -#define NV_PARSER_HAS_VAL (1<<4) +#define NV_PARSER_HAS_X_DISPLAY (1<<0) +#define NV_PARSER_HAS_TARGET (1<<2) +#define NV_PARSER_HAS_DISPLAY_DEVICE (1<<3) +#define NV_PARSER_HAS_VAL (1<<4) /* * Flag values used in the flags field of the AttributeTableEntry struct. */ -#define NV_PARSER_TYPE_FRAMELOCK (1<<16) -#define NV_PARSER_TYPE_COLOR_ATTRIBUTE (1<<17) -#define NV_PARSER_TYPE_NO_CONFIG_WRITE (1<<18) -#define NV_PARSER_TYPE_GUI_ATTRIUBUTE (1<<19) -#define NV_PARSER_TYPE_XVIDEO_ATTRIBUTE (1<<20) -#define NV_PARSER_TYPE_PACKED_ATTRIBUTE (1<<21) -#define NV_PARSER_TYPE_VALUE_IS_DISPLAY (1<<22) -#define NV_PARSER_TYPE_NO_QUERY_ALL (1<<23) -#define NV_PARSER_TYPE_NO_ZERO_VALUE (1<<24) -#define NV_PARSER_TYPE_100Hz (1<<25) -#define NV_PARSER_TYPE_STRING_ATTRIBUTE (1<<26) -#define NV_PARSER_TYPE_ASSIGN_ALL_DISPLAYS (1<<27) -#define NV_PARSER_TYPE_1000Hz (1<<28) +#define NV_PARSER_TYPE_FRAMELOCK (1<<16) +#define NV_PARSER_TYPE_COLOR_ATTRIBUTE (1<<17) +#define NV_PARSER_TYPE_NO_CONFIG_WRITE (1<<18) +#define NV_PARSER_TYPE_GUI_ATTRIUBUTE (1<<19) +#define NV_PARSER_TYPE_XVIDEO_ATTRIBUTE (1<<20) +#define NV_PARSER_TYPE_PACKED_ATTRIBUTE (1<<21) +#define NV_PARSER_TYPE_VALUE_IS_DISPLAY (1<<22) +#define NV_PARSER_TYPE_NO_QUERY_ALL (1<<23) +#define NV_PARSER_TYPE_NO_ZERO_VALUE (1<<24) +#define NV_PARSER_TYPE_100Hz (1<<25) +#define NV_PARSER_TYPE_STRING_ATTRIBUTE (1<<26) +#define NV_PARSER_TYPE_ASSIGN_ALL_DISPLAYS (1<<27) +#define NV_PARSER_TYPE_VALUE_IS_SWITCH_DISPLAY (1<<28) #define NV_PARSER_ASSIGNMENT 0 #define NV_PARSER_QUERY 1 diff --git a/src/query-assign.c b/src/query-assign.c index 2a490ef..eda350d 100644 --- a/src/query-assign.c +++ b/src/query-assign.c @@ -38,6 +38,8 @@ #include "query-assign.h" extern int __verbosity; +extern int __terse; +extern int __display_device_string; /* local prototypes */ @@ -340,7 +342,7 @@ static int process_attribute_queries(int num, char **queries, /* print a newline before we begin */ - nv_msg(NULL, ""); + if (!__terse) nv_msg(NULL, ""); /* loop over each requested query */ @@ -405,8 +407,7 @@ static int process_attribute_queries(int num, char **queries, if (ret == NV_FALSE) goto done; /* print a newline at the end */ - - nv_msg(NULL, ""); + if (!__terse) nv_msg(NULL, ""); } /* query */ @@ -620,6 +621,10 @@ static void print_valid_values(char *name, uint32 flags, char *c2; char **at; + /* do not print any valid values information when we are in 'terse' mode */ + + if (__terse) return; + #define INDENT " " switch (valid.type) { @@ -741,22 +746,32 @@ static void print_valid_values(char *name, uint32 flags, * from NV-CONTROL */ +typedef enum { + VerboseLevelTerse, + VerboseLevelAbbreviated, + VerboseLevelVerbose, +} VerboseLevel; + static void print_queried_value(CtrlHandleTarget *t, NVCTRLAttributeValidValuesRec *v, int val, uint32 flags, char *name, uint32 mask, - const char *indent) + const char *indent, + const VerboseLevel level) { char d_str[64], val_str[64], *tmp_d_str; /* assign val_str */ - - if (flags & NV_PARSER_TYPE_100Hz) { + + if ((flags & NV_PARSER_TYPE_VALUE_IS_DISPLAY) && + (__display_device_string)) { + tmp_d_str = display_device_mask_to_display_device_name(val); + snprintf(val_str, 64, "%s", tmp_d_str); + free(tmp_d_str); + } else if (flags & NV_PARSER_TYPE_100Hz) { snprintf(val_str, 64, "%.2f Hz", ((float) val) / 100.0); - } else if (flags & NV_PARSER_TYPE_1000Hz) { - snprintf(val_str, 64, "%.3f Hz", ((float) val) / 1000.0); } else if (v->type == ATTRIBUTE_TYPE_BITMASK) { snprintf(val_str, 64, "0x%08x", val); } else if (flags & NV_PARSER_TYPE_PACKED_ATTRIBUTE) { @@ -774,12 +789,31 @@ static void print_queried_value(CtrlHandleTarget *t, } else { d_str[0] = '\0'; } - - /* print the string */ - nv_msg(indent, "Attribute '%s' (%s%s): %s.", - name, t->name, d_str, val_str); - + /* print the value */ + + switch (level) { + + case VerboseLevelTerse: + /* print value alone */ + nv_msg(NULL, "%s", val_str); + break; + + case VerboseLevelAbbreviated: + /* print the value with indentation and the attribute name */ + nv_msg(indent, "%s: %s", name, val_str); + break; + + case VerboseLevelVerbose: + /* + * or print the value along with other information about the + * attribute + */ + nv_msg(indent, "Attribute '%s' (%s%s): %s.", + name, t->name, d_str, val_str); + break; + } + } /* print_queried_value() */ @@ -821,7 +855,8 @@ static int query_all(const char *display_name) if (!t->h) continue; nv_msg(NULL, "Attributes for %s:", t->name); - nv_msg(NULL, ""); + + if (!__terse) nv_msg(NULL, ""); for (entry = 0; attributeTable[entry].name; entry++) { @@ -867,7 +902,12 @@ static int query_all(const char *display_name) goto exit_bit_loop; } - nv_msg(" ", "Attribute '%s' (%s%s): %s ", a->name, t->name, "", tmp_str); + if (__terse) { + nv_msg(" ", "%s: %s", a->name, tmp_str); + } else { + nv_msg(" ", "Attribute '%s' (%s%s): %s ", + a->name, t->name, "", tmp_str); + } free(tmp_str); tmp_str = NULL; @@ -895,12 +935,15 @@ static int query_all(const char *display_name) goto exit_bit_loop; } - print_queried_value(t, &valid, val, a->flags, a->name, mask, INDENT); + print_queried_value(t, &valid, val, a->flags, a->name, + mask, INDENT, __terse ? + VerboseLevelAbbreviated : + VerboseLevelVerbose); print_valid_values(a->name, a->flags, valid); } - nv_msg(NULL,""); + if (!__terse) nv_msg(NULL,""); if (valid.permissions & ATTRIBUTE_TYPE_DISPLAY) { continue; @@ -1341,7 +1384,13 @@ static int process_parsed_attribute_internal(CtrlHandleTarget *t, NvCtrlAttributesStrError(status)); return NV_FALSE; } else { - nv_msg(" ", "Attribute '%s' (%s%s): %s", a->name, t->name, str, tmp_str); + + if (__terse) { + nv_msg(NULL, "%s", tmp_str); + } else { + nv_msg(" ", "Attribute '%s' (%s%s): %s", + a->name, t->name, str, tmp_str); + } free(tmp_str); tmp_str = NULL; } @@ -1360,8 +1409,9 @@ static int process_parsed_attribute_internal(CtrlHandleTarget *t, NvCtrlAttributesStrError(status)); return NV_FALSE; } else { - print_queried_value(t, &valid, a->val, a->flags, a->name, d, " "); - + print_queried_value(t, &valid, a->val, a->flags, a->name, d, + " ", __terse ? + VerboseLevelTerse : VerboseLevelVerbose); print_valid_values(a->name, a->flags, valid); } } @@ -1631,26 +1681,52 @@ int nv_process_parsed_attribute(ParsedAttribute *a, CtrlHandles *h, /* * If we are assigning, and the value for this attribute is a * display device, then we need to validate the value against - * the mask of enabled display devices. + * either the mask of enabled display devices or the mask of + * connected display devices. */ if (assign && (a->flags & NV_PARSER_TYPE_VALUE_IS_DISPLAY)) { + char *display_device_descriptor = NULL; + uint32 check_mask; + + /* use the complete mask if requested */ + if (a->flags & NV_PARSER_TYPE_ASSIGN_ALL_DISPLAYS) { - a->val = t->d; + if (a->flags & NV_PARSER_TYPE_VALUE_IS_SWITCH_DISPLAY) { + a->val = t->c; + } else { + a->val = t->d; + } } - - if ((t->d & a->val) != a->val) { + + /* + * if we are hotkey switching, check against all connected + * displays; otherwise, check agains the currently active + * display devices + */ + + if (a->flags & NV_PARSER_TYPE_VALUE_IS_SWITCH_DISPLAY) { + check_mask = t->c; + display_device_descriptor = "connected"; + } else { + check_mask = t->d; + display_device_descriptor = "enabled"; + } + + if ((check_mask & a->val) != a->val) { tmp_d_str0 = display_device_mask_to_display_device_name(a->val); - tmp_d_str1 = display_device_mask_to_display_device_name(t->d); + tmp_d_str1 = + display_device_mask_to_display_device_name(check_mask); nv_error_msg("The attribute '%s' specified %s cannot be " - "assigned the value of %s (the currently enabled " + "assigned the value of %s (the currently %s " "display devices are %s on %s).", - a->name, whence, tmp_d_str0, tmp_d_str1, - t->name); + a->name, whence, tmp_d_str0, + display_device_descriptor, + tmp_d_str1, t->name); free(tmp_d_str0); free(tmp_d_str1); |