"Initial commit to Gerrit"
[profile/ivi/cogl.git] / examples / cogl-x11-tfp.c
1 #include <cogl/cogl.h>
2 #include <cogl/cogl-xlib.h>
3 #include <cogl/winsys/cogl-texture-pixmap-x11.h>
4 #include <glib.h>
5 #include <stdio.h>
6
7 #include <X11/Xlib.h>
8 #include <X11/Xutil.h>
9
10 #include <X11/extensions/Xcomposite.h>
11
12 #define X11_FOREIGN_EVENT_MASK \
13   (KeyPressMask | \
14    KeyReleaseMask | \
15    ButtonPressMask | \
16    ButtonReleaseMask | \
17    PointerMotionMask)
18
19 #define TFP_XWIN_WIDTH 200
20 #define TFP_XWIN_HEIGHT 200
21
22 static void
23 update_cogl_x11_event_mask (CoglOnscreen *onscreen,
24                             guint32 event_mask,
25                             void *user_data)
26 {
27   Display *xdpy = user_data;
28   XSetWindowAttributes attrs;
29   guint32 xwin;
30
31   attrs.event_mask = event_mask | X11_FOREIGN_EVENT_MASK;
32   xwin = cogl_x11_onscreen_get_window_xid (onscreen);
33
34   XChangeWindowAttributes (xdpy,
35                            (Window)xwin,
36                            CWEventMask,
37                            &attrs);
38 }
39
40 int
41 main (int argc, char **argv)
42 {
43   Display *xdpy;
44   int composite_error = 0, composite_event = 0;
45   CoglRenderer *renderer;
46   CoglSwapChain *chain;
47   CoglOnscreenTemplate *onscreen_template;
48   CoglDisplay *display;
49   CoglContext *ctx;
50   CoglOnscreen *onscreen;
51   CoglFramebuffer *fb;
52   GError *error = NULL;
53   guint32 visual;
54   XVisualInfo template, *xvisinfo;
55   int visinfos_count;
56   XSetWindowAttributes xattr;
57   unsigned long mask;
58   Window xwin;
59   int screen;
60   Window tfp_xwin;
61   Pixmap pixmap;
62   CoglTexturePixmapX11 *tfp;
63   GC gc;
64
65   g_print ("NB: Don't use this example as a benchmark since there is "
66            "no synchonization between X window updates and onscreen "
67            "framebuffer updates!\n");
68
69   /* Since we want to test external ownership of the X display,
70    * connect to X manually... */
71   xdpy = XOpenDisplay (NULL);
72   if (!xdpy)
73     {
74       fprintf (stderr, "Failed to open X Display\n");
75       return 1;
76     }
77
78   XSynchronize (xdpy, True);
79
80   if (XCompositeQueryExtension (xdpy, &composite_event, &composite_error))
81     {
82       int major = 0, minor = 0;
83       if (XCompositeQueryVersion (xdpy, &major, &minor))
84         {
85           if (major != 0 || minor < 3)
86             g_error ("Missing XComposite extension >= 0.3");
87         }
88     }
89
90   /* Conceptually choose a GPU... */
91   renderer = cogl_renderer_new ();
92   /* FIXME: This should conceptually be part of the configuration of
93    * a renderer. */
94   cogl_xlib_renderer_set_foreign_display (renderer, xdpy);
95   if (!cogl_renderer_connect (renderer, &error))
96     {
97       fprintf (stderr, "Failed to connect to a renderer: %s\n",
98                error->message);
99     }
100
101   chain = cogl_swap_chain_new ();
102   cogl_swap_chain_set_has_alpha (chain, TRUE);
103
104   /* Conceptually declare upfront the kinds of windows we anticipate
105    * creating so that when we configure the display pipeline we can avoid
106    * having an impedance miss-match between the format of windows and the
107    * format the display pipeline expects. */
108   onscreen_template = cogl_onscreen_template_new (chain);
109   cogl_object_unref (chain);
110
111   /* Conceptually setup a display pipeline */
112   display = cogl_display_new (renderer, onscreen_template);
113   cogl_object_unref (renderer);
114   if (!cogl_display_setup (display, &error))
115     {
116       fprintf (stderr, "Failed to setup a display pipeline: %s\n",
117                error->message);
118       return 1;
119     }
120
121   ctx = cogl_context_new (display, &error);
122   if (!ctx)
123     {
124       fprintf (stderr, "Failed to create context: %s\n", error->message);
125       return 1;
126     }
127
128   onscreen = cogl_onscreen_new (ctx, 640, 480);
129
130   /* We want to test that Cogl can handle foreign X windows... */
131
132   visual = cogl_x11_onscreen_get_visual_xid (onscreen);
133   if (!visual)
134     {
135       fprintf (stderr, "Failed to query an X visual suitable for the "
136                "configured CoglOnscreen framebuffer\n");
137       return 1;
138     }
139
140   template.visualid = visual;
141   xvisinfo = XGetVisualInfo (xdpy, VisualIDMask, &template, &visinfos_count);
142
143   /* window attributes */
144   xattr.background_pixel = WhitePixel (xdpy, DefaultScreen (xdpy));
145   xattr.border_pixel = 0;
146   xattr.colormap = XCreateColormap (xdpy,
147                                     DefaultRootWindow (xdpy),
148                                     xvisinfo->visual,
149                                     AllocNone);
150   mask = CWBorderPixel | CWColormap;
151
152   xwin = XCreateWindow (xdpy,
153                         DefaultRootWindow (xdpy),
154                         0, 0,
155                         800, 600,
156                         0,
157                         xvisinfo->depth,
158                         InputOutput,
159                         xvisinfo->visual,
160                         mask, &xattr);
161
162   XFree (xvisinfo);
163
164   cogl_x11_onscreen_set_foreign_window_xid (onscreen, xwin,
165                                             update_cogl_x11_event_mask,
166                                             xdpy);
167
168   XMapWindow (xdpy, xwin);
169
170   XCompositeRedirectSubwindows (xdpy, xwin, CompositeRedirectManual);
171
172   screen = DefaultScreen (xdpy);
173   tfp_xwin = XCreateSimpleWindow (xdpy, xwin,
174                                   0, 0, TFP_XWIN_WIDTH, TFP_XWIN_HEIGHT,
175                                   0,
176                                   WhitePixel (xdpy, screen),
177                                   WhitePixel (xdpy, screen));
178   XMapWindow (xdpy, tfp_xwin);
179
180   gc = XCreateGC (xdpy, tfp_xwin, 0, NULL);
181
182   pixmap = XCompositeNameWindowPixmap (xdpy, tfp_xwin);
183
184   tfp = cogl_texture_pixmap_x11_new (ctx, pixmap, TRUE, &error);
185   if (!tfp)
186     {
187       fprintf (stderr, "Failed to create CoglTexturePixmapX11: %s",
188                error->message);
189       return 1;
190     }
191
192   fb = COGL_FRAMEBUFFER (onscreen);
193   cogl_push_framebuffer (fb);
194
195   for (;;)
196     {
197       unsigned long pixel;
198
199       while (XPending (xdpy))
200         {
201           XEvent event;
202           KeySym keysym;
203           XNextEvent (xdpy, &event);
204           switch (event.type)
205             {
206             case KeyRelease:
207               keysym = XLookupKeysym (&event.xkey, 0);
208               if (keysym == XK_q || keysym == XK_Q || keysym == XK_Escape)
209                 return 0;
210             }
211           cogl_xlib_renderer_handle_event (renderer, &event);
212         }
213
214       pixel =
215         g_random_int_range (0, 255) << 24 |
216         g_random_int_range (0, 255) << 16 |
217         g_random_int_range (0, 255) << 8;
218         g_random_int_range (0, 255);
219       XSetForeground (xdpy, gc, pixel);
220       XFillRectangle (xdpy, tfp_xwin, gc, 0, 0, TFP_XWIN_WIDTH, TFP_XWIN_HEIGHT);
221       XFlush (xdpy);
222
223       cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
224       cogl_set_source_texture (COGL_TEXTURE (tfp));
225       cogl_rectangle (-0.8, 0.8, 0.8, -0.8);
226       cogl_onscreen_swap_buffers (onscreen);
227     }
228
229   return 0;
230 }