From 5750974d5d64ce46fa4590f13d8c64ba3830a2a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Sandmann?= Date: Fri, 5 May 2006 16:52:05 +0000 Subject: [PATCH] Some experimental code to handle sync counter notifications on a window. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fri May 5 12:50:58 2006 Søren Sandmann * src/c-window.c (has_counter): Some experimental code to handle sync counter notifications on a window. * src/c-screen.c (meta_comp_screen_add_window): Pass a MetaDisplay --- ChangeLog | 7 +++ src/c-screen.c | 9 +++- src/c-window.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++- src/c-window.h | 4 +- 4 files changed, 150 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index c4c748194..31ea04fdc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Fri May 5 12:50:58 2006 Søren Sandmann + + * src/c-window.c (has_counter): Some experimental code to handle + sync counter notifications on a window. + + * src/c-screen.c (meta_comp_screen_add_window): Pass a MetaDisplay + 2006-04-25 Elijah Newren Clear _NET_WM_VISIBLE_NAME (and the ICON_ equivalent) when no diff --git a/src/c-screen.c b/src/c-screen.c index b21ffb1e5..245b7aedd 100644 --- a/src/c-screen.c +++ b/src/c-screen.c @@ -526,7 +526,7 @@ meta_comp_screen_add_window (MetaCompScreen *info, goto out; } - comp_window = meta_comp_window_new (drawable); + comp_window = meta_comp_window_new (info->meta_screen->display, drawable); g_hash_table_insert (info->windows_by_xid, (gpointer)WS_RESOURCE_XID (drawable), comp_window); @@ -534,7 +534,12 @@ meta_comp_screen_add_window (MetaCompScreen *info, out: if (comp_window) - meta_comp_window_refresh_attrs (comp_window); + { + /* This function is called both when windows are created and when they + * are mapped, so for now we have this silly function. + */ + meta_comp_window_refresh_attrs (comp_window); + } ws_display_end_error_trap (info->display); diff --git a/src/c-window.c b/src/c-window.c index 53cf22553..40d9e256d 100644 --- a/src/c-window.c +++ b/src/c-window.c @@ -34,15 +34,19 @@ struct _MetaCompWindow { + MetaDisplay *display; WsDrawable *drawable; + WsPixmap *pixmap; CmNode *node; gboolean updates; + WsSyncAlarm *alarm; WsRectangle size; }; MetaCompWindow * -meta_comp_window_new (WsDrawable *drawable) +meta_comp_window_new (MetaDisplay *display, + WsDrawable *drawable) { MetaCompWindow *window; WsRectangle geometry; @@ -50,7 +54,8 @@ meta_comp_window_new (WsDrawable *drawable) ws_drawable_query_geometry (drawable, &geometry); window = g_new0 (MetaCompWindow, 1); - + + window->display = display; window->drawable = g_object_ref (drawable); window->node = CM_NODE (cm_drawable_node_new (drawable, &geometry)); window->updates = TRUE; @@ -123,6 +128,128 @@ has_type (WsWindow *window, const char *check_type) return result; } +static MetaWindow * +find_meta_window (MetaCompWindow *comp_window) +{ + Window xwindow = WS_RESOURCE_XID (comp_window->drawable); + MetaWindow *window = + meta_display_lookup_x_window (comp_window->display, xwindow); + + return window; +} + +static Window +find_app_window (MetaCompWindow *comp_window) +{ + Window xwindow = WS_RESOURCE_XID (comp_window->drawable); + MetaWindow *meta_window = + meta_display_lookup_x_window (comp_window->display, xwindow); + + if (meta_window) + return meta_window->xwindow; + else + return xwindow; +} + +static WsPixmap * +take_snapshot (WsDrawable *drawable) +{ + WsDisplay *display = WS_RESOURCE (drawable)->display; + WsRectangle geometry; + WsPixmap *pixmap; + + ws_display_begin_error_trap (display); + + ws_drawable_query_geometry (drawable, &geometry); + + pixmap = ws_pixmap_new (drawable, geometry.width, geometry.height); + + ws_drawable_copy_area (drawable, 0, 0, geometry.width, geometry.height, + WS_DRAWABLE (pixmap), 0, 0, + NULL); + + ws_display_end_error_trap (display); + + return pixmap; +} + +static void +on_alarm (WsSyncAlarm *alarm, + WsAlarmNotifyEvent *event, + MetaCompWindow *window) +{ + g_print ("received alarm\n"); + + if (window->pixmap) + g_object_unref (window->pixmap); + + window->pixmap = take_snapshot (window->drawable); + + ws_sync_alarm_set (window->alarm, event->counter_value + 2); + ws_sync_counter_change (event->counter, 1); +} + +static gboolean +has_counter (MetaCompWindow *comp_window) +{ + Window xwindow = find_app_window (comp_window); + WsDisplay *display = WS_RESOURCE (comp_window->drawable)->display; + WsWindow *window = ws_window_lookup (display, xwindow); + WsSyncCounter *counter; + + ws_display_init_sync (display); + + counter = ws_window_get_property_sync_counter ( + window, "_NET_WM_FINISH_FRAME_COUNTER"); + + if (counter) + { + WsSyncAlarm *alarm; + gint64 value = ws_sync_counter_query_value (counter); + + g_print ("counter value %lld\n", ws_sync_counter_query_value (counter)); + alarm = ws_sync_alarm_new (display, counter); + + g_signal_connect (alarm, "alarm_notify_event", + G_CALLBACK (on_alarm), comp_window); + + if (value % 2 == 1) + { + ws_sync_alarm_set (alarm, value + 2); + + g_print ("wait for %lld\n", value + 2); + + g_print ("increasing counter\n"); + ws_sync_counter_change (counter, 1); + + g_print ("counter value %lld\n", ws_sync_counter_query_value (counter)); + } + else + { + g_print ("wait for %lld\n", value + 1); + ws_sync_alarm_set (alarm, value + 1); + } + + comp_window->alarm = alarm; + + } + +#if 0 + if (counter) + { + g_print ("found counter %lx on %lx\n", + WS_RESOURCE_XID (counter), + WS_RESOURCE_XID (window)); + } + else + { + g_print ("no counter found for %lx\n", WS_RESOURCE_XID (window)); + } +#endif + + return TRUE; +} + void meta_comp_window_refresh_attrs (MetaCompWindow *comp_window) { @@ -139,6 +266,10 @@ meta_comp_window_refresh_attrs (MetaCompWindow *comp_window) cm_drawable_node_unset_patch (CM_DRAWABLE_NODE (node)); + find_meta_window (comp_window); + + has_counter (comp_window); + if (has_type (window, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU")) { alpha = 0.3; diff --git a/src/c-window.h b/src/c-window.h index 15375957a..838c1bb8d 100644 --- a/src/c-window.h +++ b/src/c-window.h @@ -18,10 +18,12 @@ */ #include +#include "display.h" typedef struct _MetaCompWindow MetaCompWindow; -MetaCompWindow *meta_comp_window_new (WsDrawable *drawable); +MetaCompWindow *meta_comp_window_new (MetaDisplay *display, + WsDrawable *drawable); CmNode *meta_comp_window_get_node (MetaCompWindow *window); void meta_comp_window_free (MetaCompWindow *window); void meta_comp_window_set_size (MetaCompWindow *window,