]> git.tdb.fi Git - geometrycompositor.git/commitdiff
Provide geometry correction data through the X11 selection mechanism
authorMikko Rasa <tdb@tdb.fi>
Mon, 14 Dec 2015 17:36:09 +0000 (19:36 +0200)
committerMikko Rasa <tdb@tdb.fi>
Mon, 14 Dec 2015 17:36:09 +0000 (19:36 +0200)
This will be the basis of an interactive adjustment mode.

source/main.c

index 061d7b73e9c4a214165e4102ea0b677e62807a38..8aa377fbcf40a0c11a768df8bd83d0a3a287ad9b 100644 (file)
@@ -49,6 +49,8 @@ typedef struct CompositedMonitor
        unsigned vertex_array;
        unsigned tessellation;
        unsigned nelements;
+       short *geometry_data;
+       unsigned geometry_data_size;
 } CompositedMonitor;
 
 typedef struct CompositedScreen
@@ -95,6 +97,8 @@ typedef struct Compositor
        Atom root_pmap_atom;
        Atom correction_atom;
        Atom monitors_atom;
+       Atom geometry_data_atom;
+       Window selection_window;
        int dirty;
 } Compositor;
 
@@ -641,6 +645,20 @@ void update_monitor_vertices(CompositedScreen *screen, CompositedMonitor *monito
                        }
                }
 
+       monitor->geometry_data[0] = t;
+       for(i=0; i<3; ++i)
+               monitor->geometry_data[1+i] = eye[i]*10000;
+       for(y=0; y<2; ++y)
+               for(x=0; x<2; ++x)
+               {
+                       i = 1+(1+y*2+x)*3;
+                       monitor->geometry_data[i] = ((x-0.5f)*distance/monitor->perspective)*10000;
+                       monitor->geometry_data[i+1] = (eye[1]+look[1]*distance-(y-0.5f)*look[2]*distance/monitor->perspective/aspect)*10000;
+                       monitor->geometry_data[i+2] = (eye[2]+look[2]*distance+(y-0.5f)*look[1]*distance/monitor->perspective/aspect)*10000;
+               }
+       for(i=0; i<(t+1)*(t+1)*3; ++i)
+               monitor->geometry_data[16+i] = vertex_data[i]*10000;
+
        for(y=t; y<=t; --y)
                for(x=t; x<=t; --x)
                {
@@ -705,6 +723,7 @@ int initialize_monitor(Compositor *compositor, CompositedScreen *screen, XRRScre
        if(!monitor->enabled)
        {
                XRRFreeOutputInfo(output);
+               monitor->geometry_data = NULL;
                return 1;
        }
 
@@ -726,6 +745,8 @@ int initialize_monitor(Compositor *compositor, CompositedScreen *screen, XRRScre
        monitor->index_buffer = buffers[1];
 
        monitor->tessellation = 50;
+       monitor->geometry_data_size = (monitor->tessellation+1)*(monitor->tessellation+1)*3+16;
+       monitor->geometry_data = (short *)malloc(monitor->geometry_data_size*sizeof(short));
        update_monitor_vertices(screen, monitor);
        stride = 4*sizeof(float);
 
@@ -754,6 +775,24 @@ CompositedMonitor *find_monitor_by_name(CompositedScreen *screen, char *name)
        return NULL;
 }
 
+CompositedMonitor *find_monitor_by_name_global(Compositor *compositor, char *name, CompositedScreen **screen)
+{
+       unsigned i, j;
+
+       for(i=0; i<compositor->nscreens; ++i)
+               for(j=0; j<compositor->screens[i].nmonitors; ++j)
+                       if(!strcmp(compositor->screens[i].monitors[j].name, name))
+                       {
+                               if(screen)
+                                       *screen = &compositor->screens[i];
+                               return &compositor->screens[i].monitors[j];
+                       }
+
+       if(screen)
+               *screen = NULL;
+       return NULL;
+}
+
 void update_geometry_correction(Compositor *compositor, CompositedScreen *screen)
 {
        Atom prop_type;
@@ -970,6 +1009,7 @@ int initialize_compositor(Compositor *compositor)
        compositor->root_pmap_atom = XInternAtom(compositor->display, "_XROOTPMAP_ID", False);
        compositor->correction_atom = XInternAtom(compositor->display, "_MSP_GEOMETRY_CORRECTION", False);
        compositor->monitors_atom = XInternAtom(compositor->display, "_MSP_GEOMETRY_CORRECTION_MONITORS", False);
+       compositor->geometry_data_atom = XInternAtom(compositor->display, "_MSP_GEOMETRY_CORRECTION_DATA", False);
 
        compositor->nscreens = ScreenCount(compositor->display);
        compositor->screens = (CompositedScreen *)malloc(compositor->nscreens*sizeof(CompositedScreen));
@@ -977,6 +1017,9 @@ int initialize_compositor(Compositor *compositor)
                if(!initialize_screen(compositor, i))
                        return 0;
 
+       compositor->selection_window = XCreateWindow(compositor->display, compositor->screens[0].root, 0, 0, 1, 1, 0, CopyFromParent, InputOutput, CopyFromParent, 0, NULL);
+       XSetSelectionOwner(compositor->display, compositor->geometry_data_atom, compositor->selection_window, CurrentTime);
+
        compositor->dirty = 1;
 
        return 1;
@@ -1009,6 +1052,8 @@ void shutdown_screen(Compositor *compositor, CompositedScreen *screen)
                        glDeleteBuffers(1, &screen->monitors[i].index_buffer);
                        glDeleteVertexArrays(1, &screen->monitors[i].vertex_array);
                }
+               if(screen->monitors[i].geometry_data)
+                       free(screen->monitors[i].geometry_data);
        }
 
        glDeleteTextures(1, &screen->root_texture);
@@ -1042,6 +1087,8 @@ void shutdown_compositor(Compositor *compositor)
                shutdown_screen(compositor, &compositor->screens[i]);
        free(compositor->screens);
 
+       XDestroyWindow(compositor->display, compositor->selection_window);
+
        XCloseDisplay(compositor->display);
 }
 
@@ -1174,6 +1221,38 @@ void process_property_event(Compositor *compositor, XPropertyEvent *event)
                update_root_pixmap(compositor, screen);
 }
 
+void process_selection_request_event(Compositor *compositor, XSelectionRequestEvent *event)
+{
+       Atom prop_type;
+       int prop_format;
+       unsigned long overflow;
+       unsigned long names_length;
+       XSelectionEvent notify;
+
+       if(event->selection==compositor->geometry_data_atom)
+       {
+               char *monitor_name;
+               CompositedMonitor *monitor;
+
+               XGetWindowProperty(compositor->display, event->requestor, event->property, 0, 64, False, XA_STRING,
+                       &prop_type, &prop_format, &names_length, &overflow, (unsigned char **)&monitor_name);
+               if(prop_type!=XA_STRING || prop_format!=8)
+                       return;
+
+               monitor = find_monitor_by_name_global(compositor, monitor_name, NULL);
+               if(monitor && monitor->enabled)
+                       XChangeProperty(compositor->display, event->requestor, event->property, XA_INTEGER, 16, PropModeReplace, (unsigned char *)monitor->geometry_data, monitor->geometry_data_size);
+
+               notify.type = SelectionNotify;
+               notify.requestor = event->requestor;
+               notify.selection = event->selection;
+               notify.target = event->target;
+               notify.property = (monitor ? event->property : None);
+               notify.time = event->time;
+               XSendEvent(compositor->display, event->requestor, False, 0, (XEvent *)&notify);
+       }
+}
+
 void process_damage_event(Compositor *compositor, XDamageNotifyEvent *event)
 {
        CompositedScreen *screen;
@@ -1238,6 +1317,9 @@ void process_events(Compositor *compositor)
                case PropertyNotify:
                        process_property_event(compositor, &event.xproperty);
                        break;
+               case SelectionRequest:
+                       process_selection_request_event(compositor, &event.xselectionrequest);
+                       break;
                default:
                        if(event.type==compositor->damage_event+XDamageNotify)
                                process_damage_event(compositor, (XDamageNotifyEvent *)&event);