7 typedef struct GeometryCorrection
10 float keystone_vertical;
12 float vertical_center;
16 GeometryCorrection *get_corrections(Display *display)
23 unsigned long overflow;
24 unsigned long names_length;
26 unsigned long values_length;
28 unsigned ncorrections;
30 GeometryCorrection *corrections;
33 root = DefaultRootWindow(display);
34 monitors_atom = XInternAtom(display, "GEOMETRY_CORRECTION_MONITORS", False);
35 correction_atom = XInternAtom(display, "GEOMETRY_CORRECTION", False);
37 XGetWindowProperty(display, root, monitors_atom, 0, 64, False, XA_STRING,
38 &prop_type, &prop_format, &names_length, &overflow, (unsigned char **)&names);
39 if(prop_type!=XA_STRING || prop_format!=8)
42 XGetWindowProperty(display, root, correction_atom, 0, 64, False, XA_INTEGER,
43 &prop_type, &prop_format, &values_length, &overflow, (unsigned char **)&values);
44 if(prop_type!=XA_INTEGER || prop_format!=16)
50 ncorrections = (names_length>0);
51 for(i=0; i<names_length; ++i)
54 if(ncorrections*4>values_length)
55 ncorrections = values_length/4;
56 corrections = (GeometryCorrection *)malloc((ncorrections+1)*sizeof(GeometryCorrection));
59 for(i=0; i<ncorrections; ++i)
63 namelen = strlen(name_ptr);
64 corrections[i].monitor_name = (char *)malloc(namelen+1);
65 strcpy(corrections[i].monitor_name, name_ptr);
67 corrections[i].keystone_vertical = values[i*4]/10000.0f;
68 corrections[i].cylinder_depth = values[i*4+1]/10000.0f;
69 corrections[i].vertical_center = values[i*4+2]/10000.0f;
70 corrections[i].perspective = values[i*4+3]/10000.0f;
72 name_ptr += namelen+1;
75 corrections[ncorrections].monitor_name = NULL;
83 void set_corrections(Display *display, GeometryCorrection *corrections)
85 unsigned ncorrections;
97 for(i=0; corrections[i].monitor_name; ++i)
100 total_len += strlen(corrections[i].monitor_name);
103 names = (char *)malloc(total_len+ncorrections);
104 values = (short *)malloc(ncorrections*4*sizeof(short));
106 for(i=0; i<ncorrections; ++i)
108 strcpy(name_ptr, corrections[i].monitor_name);
109 name_ptr += strlen(name_ptr)+1;
111 values[i*4] = corrections[i].keystone_vertical*10000;
112 values[i*4+1] = corrections[i].cylinder_depth*10000;
113 values[i*4+2] = corrections[i].vertical_center*10000;
114 values[i*4+3] = corrections[i].perspective*10000;
117 root = DefaultRootWindow(display);
118 monitors_atom = XInternAtom(display, "GEOMETRY_CORRECTION_MONITORS", False);
119 correction_atom = XInternAtom(display, "GEOMETRY_CORRECTION", False);
120 XChangeProperty(display, root, monitors_atom, XA_STRING, 8, PropModeReplace, (unsigned char *)names, total_len+ncorrections-1);
121 XChangeProperty(display, root, correction_atom, XA_INTEGER, 16, PropModeReplace, (unsigned char *)values, ncorrections*4);
127 int main(int argc, char **argv)
130 GeometryCorrection *corrections;
135 fprintf(stderr, "Usage: %s <monitor> <keystone> <cylinder> <vcenter> <perspective>\n", argv[0]);
139 display = XOpenDisplay(NULL);
141 corrections = get_corrections(display);
144 for(i=0; corrections[i].monitor_name; ++i)
145 if(!strcmp(corrections[i].monitor_name, argv[1]))
151 if(!corrections || !corrections[i].monitor_name)
155 corrections = (GeometryCorrection *)realloc(corrections, (i+2)*sizeof(GeometryCorrection));
156 namelen = strlen(argv[1]);
157 corrections[i].monitor_name = (char *)malloc(namelen+1);
158 strcpy(corrections[i].monitor_name, argv[1]);
159 corrections[i+1].monitor_name = NULL;
162 corrections[i].keystone_vertical = strtod(argv[2], NULL);
163 corrections[i].cylinder_depth = strtod(argv[3], NULL);
164 corrections[i].vertical_center = strtod(argv[4], NULL);
165 corrections[i].perspective = strtod(argv[5], NULL);
167 set_corrections(display, corrections);
169 XCloseDisplay(display);