{
char *monitor_name;
float keystone_vertical;
- float cylinder_depth;
+ int curvature_type;
+ float curvature_depth;
float vertical_center;
float perspective;
} GeometryCorrection;
for(i=0; i<names_length; ++i)
if(!names[i])
++ncorrections;
- if(ncorrections*4>values_length)
- ncorrections = values_length/4;
+ if(ncorrections*5>values_length)
+ ncorrections = values_length/5;
corrections = (GeometryCorrection *)malloc((ncorrections+1)*sizeof(GeometryCorrection));
name_ptr = names;
corrections[i].monitor_name = (char *)malloc(namelen+1);
strcpy(corrections[i].monitor_name, name_ptr);
- corrections[i].keystone_vertical = values[i*4]/4096.0f;
- corrections[i].cylinder_depth = values[i*4+1]/4096.0f;
- corrections[i].vertical_center = values[i*4+2]/4096.0f;
- corrections[i].perspective = values[i*4+3]/4096.0f;
+ corrections[i].keystone_vertical = values[i*5]/4096.0f;
+ corrections[i].curvature_type = values[i*5+1];
+ corrections[i].curvature_depth = values[i*5+2]/4096.0f;
+ corrections[i].vertical_center = values[i*5+3]/4096.0f;
+ corrections[i].perspective = values[i*5+4]/4096.0f;
name_ptr += namelen+1;
}
}
names = (char *)malloc(total_len+ncorrections);
- values = (short *)malloc(ncorrections*4*sizeof(short));
+ values = (short *)malloc(ncorrections*5*sizeof(short));
name_ptr = names;
for(i=0; i<ncorrections; ++i)
{
strcpy(name_ptr, corrections[i].monitor_name);
name_ptr += strlen(name_ptr)+1;
- values[i*4] = corrections[i].keystone_vertical*4096;
- values[i*4+1] = corrections[i].cylinder_depth*4096;
- values[i*4+2] = corrections[i].vertical_center*4096;
- values[i*4+3] = corrections[i].perspective*4096;
+ values[i*5] = corrections[i].keystone_vertical*4096;
+ values[i*5+1] = corrections[i].curvature_type;
+ values[i*5+2] = corrections[i].curvature_depth*4096;
+ values[i*5+3] = corrections[i].vertical_center*4096;
+ values[i*5+4] = corrections[i].perspective*4096;
}
root = DefaultRootWindow(display);
monitors_atom = XInternAtom(display, "_MSP_GEOMETRY_CORRECTION_MONITORS", False);
correction_atom = XInternAtom(display, "_MSP_GEOMETRY_CORRECTION", False);
XChangeProperty(display, root, monitors_atom, XA_STRING, 8, PropModeReplace, (unsigned char *)names, total_len+ncorrections-1);
- XChangeProperty(display, root, correction_atom, XA_INTEGER, 16, PropModeReplace, (unsigned char *)values, ncorrections*4);
+ XChangeProperty(display, root, correction_atom, XA_INTEGER, 16, PropModeReplace, (unsigned char *)values, ncorrections*5);
free(names);
free(values);
else if(keysym==XK_a)
target->keystone_vertical -= 1.0f/64;
else if(keysym==XK_w)
- target->cylinder_depth += 1.0f/256;
+ target->curvature_depth += 1.0f/256;
else if(keysym==XK_s)
- target->cylinder_depth -= 1.0f/256;
+ target->curvature_depth -= 1.0f/256;
else if(keysym==XK_e)
target->vertical_center += 1.0f/32;
else if(keysym==XK_d)
target->perspective += 1.0f/16;
else if(keysym==XK_f)
target->perspective -= 1.0f/16;
+ else if(keysym==XK_z)
+ target->curvature_type = target->curvature_type%2+1;
else
break;
GeometryCorrection *corrections;
unsigned i;
- if(argc!=2 && argc!=6)
+ if(argc!=2 && argc!=7)
{
- fprintf(stderr, "Usage: %s <monitor> [<keystone> <cylinder> <vcenter> <perspective>]\n", argv[0]);
+ fprintf(stderr, "Usage: %s <monitor> [<keystone> <curvature> <depth> <vcenter> <perspective>]\n", argv[0]);
return 1;
}
strcpy(corrections[i].monitor_name, argv[1]);
corrections[i+1].monitor_name = NULL;
corrections[i].keystone_vertical = 0.0f;
- corrections[i].cylinder_depth = 0.0f;
+ corrections[i].curvature_type = 1;
+ corrections[i].curvature_depth = 0.0f;
corrections[i].vertical_center = 0.5f;
corrections[i].perspective = 1.0f;
}
if(argc==2)
interactive(display, corrections, &corrections[i]);
- else if(argc==6)
+ else if(argc==7)
{
+ if(!strcmp(argv[3], "cylindrical"))
+ corrections[i].curvature_type = 1;
+ else if(!strcmp(argv[3], "spherical"))
+ corrections[i].curvature_type = 2;
+ else
+ {
+ fprintf(stderr, "Invalid curvature\n");
+ return 1;
+ }
corrections[i].keystone_vertical = strtod(argv[2], NULL);
- corrections[i].cylinder_depth = strtod(argv[3], NULL);
- corrections[i].vertical_center = strtod(argv[4], NULL);
- corrections[i].perspective = strtod(argv[5], NULL);
+ corrections[i].curvature_depth = strtod(argv[4], NULL);
+ corrections[i].vertical_center = strtod(argv[5], NULL);
+ corrections[i].perspective = strtod(argv[6], NULL);
set_corrections(display, corrections);
}
int recreate_mask;
} CompositedWindow;
+enum
+{
+ CYLINDRICAL = 1,
+ SPHERICAL
+};
+
typedef struct CompositedMonitor
{
char *name;
unsigned width;
unsigned height;
float keystone_vertical;
- float cylinder_depth;
+ float curvature_type;
+ float curvature_depth;
float vertical_center;
float perspective;
unsigned vertex_buffer;
aspect = (float)monitor->width/monitor->height;
- if(monitor->cylinder_depth)
+ if(monitor->curvature_depth)
{
- cyl_radius = (monitor->cylinder_depth*monitor->cylinder_depth+0.25f)/(2.0f*monitor->cylinder_depth);
+ cyl_radius = (monitor->curvature_depth*monitor->curvature_depth+0.25f)/(2.0f*monitor->curvature_depth);
cyl_arc = 2.0f*asin(0.5f/cyl_radius);
}
v[0] = (float)x/t-0.5f;
v[1] = ((float)y/t-0.5f)/aspect;
v[2] = 0;
- if(monitor->cylinder_depth)
+ if(monitor->curvature_depth)
{
- v[2] = (1.0f-cos(v[0]*cyl_arc))*cyl_radius-monitor->cylinder_depth;
- v[0] = sin(v[0]*cyl_arc)*cyl_radius;
+ if(monitor->curvature_type==CYLINDRICAL)
+ {
+ v[2] = (1.0f-cos(v[0]*cyl_arc))*cyl_radius-monitor->curvature_depth;
+ v[0] = sin(v[0]*cyl_arc)*cyl_radius;
+ }
+ else if(monitor->curvature_type==SPHERICAL)
+ {
+ float r;
+
+ v[0] = tan(v[0]*cyl_arc)*cyl_radius;
+ v[1] = tan(v[1]*cyl_arc)*cyl_radius;
+ r = sqrt(v[0]*v[0]+v[1]*v[1]+cyl_radius*cyl_radius)/fabs(cyl_radius);
+ v[0] /= r;
+ v[1] /= r;
+ v[2] = cyl_radius-cyl_radius/r-monitor->curvature_depth;
+ }
}
}
XRRFreeOutputInfo(output);
monitor->keystone_vertical = 0.0f;
- monitor->cylinder_depth = 0.0f;
+ monitor->curvature_type = CYLINDRICAL;
+ monitor->curvature_depth = 0.0f;
monitor->vertical_center = 0.5f;
monitor->perspective = 1.0f;
use_gl(compositor, screen);
name_ptr = names;
- for(i=0; i*4+3<values_length; ++i)
+ for(i=0; i*5+4<values_length; ++i)
{
CompositedMonitor *monitor;
monitor = find_monitor_by_name(screen, name_ptr);
if(monitor)
{
- monitor->keystone_vertical = values[i*4]/4096.0f;
- monitor->cylinder_depth = values[i*4+1]/4096.0f;
- monitor->vertical_center = values[i*4+2]/4096.0f;
- monitor->perspective = values[i*4+3]/4096.0f;
+ monitor->keystone_vertical = values[i*5]/4096.0f;
+ monitor->curvature_type = values[i*5+1];
+ monitor->curvature_depth = values[i*5+2]/4096.0f;
+ monitor->vertical_center = values[i*5+3]/4096.0f;
+ monitor->perspective = values[i*5+4]/4096.0f;
if(monitor->enabled)
update_monitor_vertices(screen, monitor);