CompositedWindow *windows;
unsigned nwindows;
unsigned windows_capacity;
+ int dirty;
} CompositedScreen;
typedef struct Compositor
PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB;
PFNGLXBINDTEXIMAGEEXTPROC glXBindTexImageEXT;
PFNGLXRELEASETEXIMAGEEXTPROC glXReleaseTexImageEXT;
+ int dirty;
} Compositor;
static const char *vshader =
return NULL;
}
+CompositedScreen *find_screen_by_window(Compositor *compositor, Window w)
+{
+ unsigned i, j;
+
+ for(i=0; i<compositor->nscreens; ++i)
+ for(j=0; j<compositor->screens[i].nwindows; ++j)
+ if(compositor->screens[i].windows[j].window==w)
+ return &compositor->screens[i];
+
+ return NULL;
+}
+
int initialize_screen(Compositor *compositor, unsigned number)
{
CompositedScreen *screen;
window->map_state = IsUnviewable;
}
-void process_event(Compositor *compositor)
+void process_damage_event(Compositor *compositor, XDamageNotifyEvent *event)
+{
+ CompositedScreen *screen = find_screen_by_window(compositor, event->drawable);
+ if(!screen)
+ return;
+
+ screen->dirty = 1;
+ compositor->dirty = 1;
+}
+
+int process_event(Compositor *compositor)
{
XEvent event;
- XNextEvent(compositor->display, &event);
+ if(compositor->dirty)
+ {
+ if(!XCheckMaskEvent(compositor->display, -1, &event))
+ return 0;
+ }
+ else
+ XNextEvent(compositor->display, &event);
+
switch(event.type)
{
case CreateNotify:
process_unmap_event(compositor, &event.xunmap);
break;
default:
- if(event.type!=compositor->damage_event+XDamageNotify)
+ if(event.type==compositor->damage_event+XDamageNotify)
+ process_damage_event(compositor, (XDamageNotifyEvent *)&event);
+ else
printf("Event %d\n", event.type);
}
+
+ return 1;
}
void refresh_screens(Compositor *compositor)
}
XUngrabServer(compositor->display);
glXSwapBuffers(compositor->display, screen->glx_window);
+
+ screen->dirty = 0;
}
+
+ compositor->dirty = 0;
}
int main()
while(1)
{
- process_event(&compositor);
- refresh_screens(&compositor);
+ if(!process_event(&compositor))
+ refresh_screens(&compositor);
}
shutdown_compositor(&compositor);