~shnatsel/+junk/cairo-compmgr

« back to all changes in this revision

Viewing changes to test/test-clone-screen.c

  • Committer: Sergey "Shnatsel" Davidoff
  • Date: 2012-03-04 22:53:22 UTC
  • Revision ID: shnatsel@gmail.com-20120304225322-q2hz82j51yxv1qqw
fixed up build dependencies

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This program is free software; you can redistribute it and/or modify
 
3
 * it under the terms of the GNU General Public License as published by
 
4
 * the Free Software Foundation; either version 2 of the License, or
 
5
 * (at your option) any later version.
 
6
 * 
 
7
 * This program is distributed in the hope that it will be useful,
 
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
 * GNU Library General Public License for more details.
 
11
 * 
 
12
 * You should have received a copy of the GNU General Public License
 
13
 * along with this program; if not, write to the Free Software
 
14
 * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301,  USA
 
15
 */
 
16
 
 
17
#include <gdk/gdkx.h>
 
18
#include <gtk/gtk.h>
 
19
#include <X11/extensions/Xdamage.h>
 
20
 
 
21
static GdkPixmap* pixmap = NULL;
 
22
static GtkWidget* main_window = NULL;
 
23
static Damage damage = None;
 
24
int event_base;
 
25
int error_base;
 
26
int width = 400, height = 400;
 
27
Window main_xwindow;
 
28
 
 
29
void
 
30
on_realize(GtkWidget* widget, gpointer data)
 
31
{
 
32
    GdkDisplay* display = gdk_display_get_default();
 
33
    cairo_t* clone_ctx;
 
34
 
 
35
    main_xwindow = GDK_WINDOW_XWINDOW(widget->window);
 
36
        
 
37
    pixmap = gdk_pixmap_new(widget->window, width, height, -1);
 
38
    clone_ctx = gdk_cairo_create(GDK_DRAWABLE(pixmap));
 
39
    cairo_set_operator(clone_ctx, CAIRO_OPERATOR_CLEAR);
 
40
    cairo_paint(clone_ctx);
 
41
    cairo_destroy(clone_ctx);
 
42
    
 
43
    XDamageQueryExtension (GDK_DISPLAY_XDISPLAY(display), 
 
44
                           &event_base, &error_base);
 
45
    
 
46
    damage = XDamageCreate(GDK_DISPLAY_XDISPLAY(display), 
 
47
                           GDK_PIXMAP_XID(pixmap), 
 
48
                           XDamageReportBoundingBox);
 
49
    clone(TRUE);
 
50
    
 
51
    gtk_window_resize(GTK_WINDOW(main_window), width, height);
 
52
}
 
53
 
 
54
gboolean
 
55
on_delete_event(GtkWidget* widget, GdkEvent* event, gpointer data)
 
56
{
 
57
    gtk_main_quit();
 
58
    return FALSE;
 
59
}
 
60
 
 
61
gboolean
 
62
on_expose_event(GtkWidget* widget, GdkEventExpose* event, gpointer data)
 
63
{
 
64
    gboolean ret = FALSE;
 
65
    
 
66
    if (pixmap)
 
67
    {
 
68
        cairo_t* clone = gdk_cairo_create(GDK_DRAWABLE(pixmap));
 
69
        cairo_t* ctx = gdk_cairo_create(GDK_DRAWABLE(widget->window));
 
70
 
 
71
        cairo_set_operator(ctx, CAIRO_OPERATOR_CLEAR);
 
72
        cairo_paint(ctx);
 
73
        cairo_set_operator(ctx, CAIRO_OPERATOR_OVER);
 
74
        cairo_set_source_surface(ctx, cairo_get_target(clone), 0, 0);
 
75
        cairo_paint(ctx);
 
76
        cairo_destroy(ctx);
 
77
        cairo_destroy(clone);
 
78
        ret = TRUE;
 
79
    }
 
80
 
 
81
    return ret;
 
82
}
 
83
 
 
84
void
 
85
clone(gboolean enable)
 
86
{
 
87
    GdkScreen* screen = gdk_screen_get_default();
 
88
    GdkEvent event;
 
89
    GdkAtom ccm_atom = gdk_atom_intern_static_string("_CCM_CLIENT_MESSAGE");
 
90
    GdkAtom clone_atom = enable ? 
 
91
                         gdk_atom_intern_static_string("_CCM_CLONE_SCREEN_ENABLE") :
 
92
                         gdk_atom_intern_static_string("_CCM_CLONE_SCREEN_DISABLE");
 
93
    
 
94
    event.client.type = GDK_CLIENT_EVENT;
 
95
    event.client.window = gdk_screen_get_root_window(screen);
 
96
    event.client.send_event = TRUE;
 
97
    event.client.message_type = ccm_atom;
 
98
    event.client.data_format = 32;
 
99
    event.client.data.l[0] = gdk_x11_atom_to_xatom(clone_atom);
 
100
    event.client.data.l[1] = GDK_WINDOW_XWINDOW(gdk_screen_get_root_window(screen));
 
101
    event.client.data.l[2] = GDK_DRAWABLE_XID(pixmap);
 
102
    event.client.data.l[3] = gdk_drawable_get_depth(GDK_DRAWABLE(pixmap));
 
103
    event.client.data.l[4] = main_xwindow;
 
104
 
 
105
    gdk_event_send_clientmessage_toall(&event);
 
106
    gtk_widget_queue_draw(main_window);
 
107
}
 
108
      
 
109
gboolean 
 
110
on_configure_event(GtkWidget* widget, GdkEventConfigure* event, gpointer data)
 
111
{
 
112
    if (pixmap && 
 
113
        (event->width != width || event->height != height))
 
114
    {
 
115
        GdkDisplay* display = gdk_display_get_default();
 
116
        cairo_t* ctx;
 
117
        
 
118
        width = event->width;
 
119
        height = event->height;
 
120
        
 
121
        clone (FALSE);
 
122
        if (pixmap) g_object_unref(pixmap);
 
123
        XDamageDestroy(GDK_DISPLAY_XDISPLAY(display), damage);
 
124
 
 
125
        pixmap = gdk_pixmap_new(widget->window, width, height, -1);
 
126
        ctx = gdk_cairo_create(GDK_DRAWABLE(pixmap));
 
127
        cairo_set_operator(ctx, CAIRO_OPERATOR_CLEAR);
 
128
        cairo_paint(ctx);
 
129
        cairo_destroy(ctx);
 
130
 
 
131
        damage = XDamageCreate(GDK_DISPLAY_XDISPLAY(display), 
 
132
                                   GDK_PIXMAP_XID(pixmap), 
 
133
                                   XDamageReportBoundingBox);
 
134
        
 
135
        clone (TRUE);
 
136
    }
 
137
 
 
138
    return FALSE;
 
139
}
 
140
 
 
141
GdkFilterReturn
 
142
on_filter_event(XEvent* xevent, GdkEvent* event, gpointer data)
 
143
{
 
144
    if (xevent->type == event_base + XDamageNotify)
 
145
    {
 
146
        XDamageSubtract(xevent->xany.display, damage, None, None);
 
147
        gtk_widget_queue_draw(main_window);
 
148
    }
 
149
    
 
150
    return GDK_FILTER_CONTINUE;
 
151
}
 
152
 
 
153
gint
 
154
main(gint argc, gchar** argv)
 
155
{
 
156
    gtk_init(&argc, &argv);
 
157
 
 
158
    main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
 
159
    g_signal_connect(main_window, "realize", G_CALLBACK(on_realize), NULL);
 
160
    g_signal_connect(main_window, "delete-event", G_CALLBACK(on_delete_event), NULL);
 
161
    g_signal_connect(main_window, "expose-event", G_CALLBACK(on_expose_event), NULL);
 
162
    g_signal_connect(main_window, "configure-event", G_CALLBACK(on_configure_event), NULL);
 
163
  
 
164
    gdk_window_add_filter(NULL, (GdkFilterFunc)on_filter_event, NULL);
 
165
 
 
166
    gtk_widget_set_app_paintable(main_window, TRUE);
 
167
    gtk_widget_realize(main_window);
 
168
    gdk_window_set_back_pixmap(main_window->window, NULL, FALSE);
 
169
    gtk_widget_show(main_window);
 
170
 
 
171
    gtk_main();
 
172
 
 
173
    clone (FALSE);
 
174
    if (pixmap) g_object_unref(pixmap);
 
175
            
 
176
    return 0;
 
177
}