/* * 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 * */ /* nv-ddcci-client: A tool for exercising all the display-supported DDC/CI VCP codes * * This test program does the following: * - Check for the available displays * - For each available display: * + Get the timing report * + Get the monitor capabilities (list of vcp supported codes) * + Write and reads each supported vcp code * + Try to excercise the special vcp codes. These are vcp codes * that cannot be implemented with the XNVCTRLSetAttribute...() * interface. * * Usage: * Just run the client on a display * * Options: * -defaults: Tries to restore the display defaults only. Does not run the test * * If the monitor does not support the factory defaults reset through DDC/CI, * it is strongly recommended to do so through the OSD. * After the test all monitor settings are changed, and the client tries to * restore the factory defaults. */ #include #include #include #include #include "NVCtrl.h" #include "NVCtrlLib.h" static void Do_Capable(Display *dpy, int screen, unsigned int *ddcci_devices); static void Do_Timing_Report(Display *dpy, int screen, unsigned int ddcci_devices); static void Do_VCP_List(Display *dpy, int screen, unsigned int ddcci_devices, unsigned int display_mask, unsigned int *nvctrl_vcp_supported, unsigned int *possible_values_offset, unsigned int *possible_values_size, unsigned int *nvctrl_vcp_possible_values); static void Do_String_VCP(Display *dpy, int screen, unsigned int ddcci_devices, unsigned int display_mask, unsigned int *nvctrl_string_vcp_supported); static void Do_Special_VCP(Display *dpy, int screen, unsigned int ddcci_devices, unsigned int display_mask); static Bool Do_Capabilities(Display *dpy, int screen, unsigned int ddcci_devices, unsigned int display_mask, unsigned int **nvctrl_vcp_supported, unsigned int **possible_values_offset, unsigned int **possible_values_size, unsigned int **nvctrl_vcp_possible_values, unsigned int **nvctrl_string_vcp_supported); static void RestoreDefaults(Display *dpy, int screen, unsigned int ddcci_devices, unsigned int display_mask, unsigned int *nvctrl_vcp_supported); #define DISPLAY_DEVICES 0xFF #define TRUE 1 #define FALSE 0 #define RETRIES 1 #define VERSION "1.0" int main(int argc, char **argv) { Display *dpy; int screen; int bit; unsigned int display_mask; unsigned int ddcci_devices; unsigned int *nvctrl_vcp_supported; unsigned int *possible_values_offset; unsigned int *possible_values_size; unsigned int *nvctrl_vcp_possible_values; unsigned int *nvctrl_string_vcp_supported; int defaults=0; Bool ret; printf("nv-ddcci-client v%s\n\n", VERSION); if(argc==2 && !strcmp(argv[1], "-defaults") ) { defaults=1; } else if(argc!=1) { printf("Usage: nv-ddcci-client [-defaults]\n"); printf("Option -defaults: Tries to restore the display defaults only\n"); return 1; } dpy = XOpenDisplay(NULL); if(dpy==NULL) { printf("Cannot open display\n"); return 1; } screen=DefaultScreen(dpy); Do_Capable(dpy, screen, &ddcci_devices); if(ddcci_devices==0) { printf("No capable devices found.\n"); printf("Please make sure you allowed DDC/CI with the X config option\n"); printf("\"AllowDDCCI\" set to \"1\" in the device section of your X config file, i.e.:\n"); printf("Option \"AllowDDCCI\" \"1\"\n"); return 1; } if(defaults==0) Do_Timing_Report(dpy, screen, ddcci_devices); for (bit = 0; bit < 24; bit++) { display_mask = (1 << bit); ret=Do_Capabilities(dpy, screen, ddcci_devices, display_mask, &nvctrl_vcp_supported, &possible_values_offset, &possible_values_size, &nvctrl_vcp_possible_values, &nvctrl_string_vcp_supported); if(ret==FALSE) continue; if(defaults==0) { Do_VCP_List(dpy, screen, ddcci_devices, display_mask, nvctrl_vcp_supported, possible_values_offset, possible_values_size, nvctrl_vcp_possible_values); Do_String_VCP(dpy, screen, ddcci_devices, display_mask, nvctrl_string_vcp_supported); Do_Special_VCP(dpy, screen, ddcci_devices, display_mask); } RestoreDefaults(dpy, screen, ddcci_devices, display_mask, nvctrl_vcp_supported); } return 0 ; } /* * - RestoreDefaults * Restore display defaults * If the display does not support this command, the display has to be reset manually */ static void RestoreDefaults(Display *dpy, int screen, unsigned int ddcci_devices, unsigned int display_mask, unsigned int *nvctrl_vcp_supported) { int display_devices=DISPLAY_DEVICES; if ((display_mask & display_devices) == 0x0) return; if ((display_mask & ddcci_devices) == 0x0) return; printf("Restoring defaults\n"); printf("------------------\n"); printf(" Display Mask 0x%x\n", display_mask); if(nvctrl_vcp_supported[NV_CTRL_DDCCI_PRESET_SETTINGS_RESTORE_FACTORY_DEFAULTS]) { printf(" Sending request\n"); XNVCTRLSetAttribute (dpy, screen, display_mask, NV_CTRL_DDCCI_PRESET_SETTINGS_RESTORE_FACTORY_DEFAULTS, 1); } else printf(" Code not supported on display. PLEASE RESET YOUR DISPLAY MANUALLY !\n"); printf("================================================================================\n\n"); } /* * - Do_Capable * Returns in ddcci_devices a mask of DDC/CI capable displays */ static void Do_Capable(Display *dpy, int screen, unsigned int *ddcci_devices) { int status; unsigned int display_mask; int bit; unsigned int display_devices=DISPLAY_DEVICES; int val; *ddcci_devices=0; printf("DDC/CI Capable\n"); printf("--------------\n"); for (bit = 0; bit < 24; bit++) { display_mask = (1 << bit); if ((display_mask & display_devices) == 0x0) continue; printf(" Display Mask 0x%x\n", display_mask); status = XNVCTRLQueryAttribute (dpy, screen, display_mask, NV_CTRL_DDCCI_CAPABLE, &val); if (!status) { printf(" Error when querying attribute\n"); } else if(val==1) { printf(" Display is DDC/CI capable\n"); *ddcci_devices |= display_mask; } else printf(" Display is not DDC/CI capable\n"); } printf("================================================================================\n\n"); } /* * - Do_Timing_Report * Prints the timing report */ static void Do_Timing_Report(Display *dpy, int screen, unsigned int ddcci_devices) { int status; unsigned int display_mask; int bit; int display_devices=DISPLAY_DEVICES; unsigned int sync_freq_out_range, unstable_count, positive_h_sync, positive_v_sync, h_freq, v_freq; printf("Timing Report\n"); printf("-------------\n"); for (bit = 0; bit < 24; bit++) { display_mask = (1 << bit); if ((display_mask & display_devices) == 0x0) continue; if ((display_mask & ddcci_devices) == 0x0) continue; printf(" Display Mask 0x%x\n", display_mask); status = XNVCTRLQueryDDCCITimingReport (dpy, screen, display_mask, &sync_freq_out_range, &unstable_count, &positive_h_sync, &positive_v_sync, &h_freq, &v_freq); if (!status) { printf(" Error when querying Timing Report\n"); continue; } if(sync_freq_out_range) printf(" - Sync out of range\n"); if(unstable_count) printf(" - Unstable count\n"); if(positive_h_sync) printf(" - Positive H sync\n"); else printf(" - Negative H sync\n"); if(positive_v_sync) printf(" - Positive V sync\n"); else printf(" - Negative V sync\n"); printf(" - H Freq = %d\n", h_freq); printf(" - V Freq = %d\n", v_freq); } printf("================================================================================\n\n"); } /* - Do_Capabilities * Gets the supported NV-CONTROL DDC/CI attributes */ static Bool Do_Capabilities(Display *dpy, int screen, unsigned int ddcci_devices, unsigned int display_mask, unsigned int **nvctrl_vcp_supported, unsigned int **possible_values_offset, unsigned int **possible_values_size, unsigned int **nvctrl_vcp_possible_values, unsigned int **nvctrl_string_vcp_supported) { int status; int display_devices=DISPLAY_DEVICES; int i; if ((display_mask & display_devices) == 0x0) return FALSE; if ((display_mask & ddcci_devices) == 0x0) return FALSE; printf("Capabilities Query\n"); printf("------------------\n"); printf(" Display Mask 0x%x\n", display_mask); status = NVCTRLQueryDDCCICapabilities (dpy, screen, display_mask, nvctrl_vcp_supported, possible_values_offset, possible_values_size, nvctrl_vcp_possible_values, nvctrl_string_vcp_supported); if (!status) { printf(" Error when querying Capabilities\n"); return FALSE; } printf(" Supported NV_CTRL:"); for(i=0;i