"Initial commit to Gerrit"
[profile/ivi/cogl.git] / examples / cogl-x11-foreign.c
1 #include <cogl/cogl.h>
2 #include <cogl/cogl-xlib.h>
3 #include <glib.h>
4 #include <stdio.h>
5
6 #include <X11/Xlib.h>
7 #include <X11/Xutil.h>
8
9 #define X11_FOREIGN_EVENT_MASK \
10   (KeyPressMask | \
11    KeyReleaseMask | \
12    ButtonPressMask | \
13    ButtonReleaseMask | \
14    PointerMotionMask)
15
16 static void
17 update_cogl_x11_event_mask (CoglOnscreen *onscreen,
18                             guint32 event_mask,
19                             void *user_data)
20 {
21   Display *xdpy = user_data;
22   XSetWindowAttributes attrs;
23   guint32 xwin;
24
25   attrs.event_mask = event_mask | X11_FOREIGN_EVENT_MASK;
26   xwin = cogl_x11_onscreen_get_window_xid (onscreen);
27
28   XChangeWindowAttributes (xdpy,
29                            (Window)xwin,
30                            CWEventMask,
31                            &attrs);
32 }
33
34 int
35 main (int argc, char **argv)
36 {
37   Display *xdpy;
38   CoglRenderer *renderer;
39   CoglSwapChain *chain;
40   CoglOnscreenTemplate *onscreen_template;
41   CoglDisplay *display;
42   CoglContext *ctx;
43   CoglOnscreen *onscreen;
44   CoglFramebuffer *fb;
45   CoglPipeline *pipeline;
46   GError *error = NULL;
47   guint32 visual;
48   XVisualInfo template, *xvisinfo;
49   int visinfos_count;
50   XSetWindowAttributes xattr;
51   unsigned long mask;
52   Window xwin;
53   CoglVertexP2C4 triangle_vertices[] = {
54       {0, 0.7, 0xff, 0x00, 0x00, 0x80},
55       {-0.7, -0.7, 0x00, 0xff, 0x00, 0xff},
56       {0.7, -0.7, 0x00, 0x00, 0xff, 0xff}
57   };
58   CoglPrimitive *triangle;
59
60
61   /* Since we want to test external ownership of the X display,
62    * connect to X manually... */
63   xdpy = XOpenDisplay (NULL);
64   if (!xdpy)
65     {
66       fprintf (stderr, "Failed to open X Display\n");
67       return 1;
68     }
69
70   /* Conceptually choose a GPU... */
71   renderer = cogl_renderer_new ();
72   /* FIXME: This should conceptually be part of the configuration of
73    * a renderer. */
74   cogl_xlib_renderer_set_foreign_display (renderer, xdpy);
75   if (!cogl_renderer_connect (renderer, &error))
76     {
77       fprintf (stderr, "Failed to connect to a renderer: %s\n",
78                error->message);
79     }
80
81   chain = cogl_swap_chain_new ();
82   cogl_swap_chain_set_has_alpha (chain, TRUE);
83
84   /* Conceptually declare upfront the kinds of windows we anticipate
85    * creating so that when we configure the display pipeline we can avoid
86    * having an impedance miss-match between the format of windows and the
87    * format the display pipeline expects. */
88   onscreen_template = cogl_onscreen_template_new (chain);
89   cogl_object_unref (chain);
90
91   /* Conceptually setup a display pipeline */
92   display = cogl_display_new (renderer, onscreen_template);
93   cogl_object_unref (renderer);
94   if (!cogl_display_setup (display, &error))
95     {
96       fprintf (stderr, "Failed to setup a display pipeline: %s\n",
97                error->message);
98       return 1;
99     }
100
101   ctx = cogl_context_new (display, &error);
102   if (!ctx)
103     {
104       fprintf (stderr, "Failed to create context: %s\n", error->message);
105       return 1;
106     }
107
108   onscreen = cogl_onscreen_new (ctx, 640, 480);
109
110   /* We want to test that Cogl can handle foreign X windows... */
111
112   visual = cogl_x11_onscreen_get_visual_xid (onscreen);
113   if (!visual)
114     {
115       fprintf (stderr, "Failed to query an X visual suitable for the "
116                "configured CoglOnscreen framebuffer\n");
117       return 1;
118     }
119
120   template.visualid = visual;
121   xvisinfo = XGetVisualInfo (xdpy, VisualIDMask, &template, &visinfos_count);
122
123   /* window attributes */
124   xattr.background_pixel = WhitePixel (xdpy, DefaultScreen (xdpy));
125   xattr.border_pixel = 0;
126   xattr.colormap = XCreateColormap (xdpy,
127                                     DefaultRootWindow (xdpy),
128                                     xvisinfo->visual,
129                                     AllocNone);
130   mask = CWBorderPixel | CWColormap;
131
132   xwin = XCreateWindow (xdpy,
133                         DefaultRootWindow (xdpy),
134                         0, 0,
135                         800, 600,
136                         0,
137                         xvisinfo->depth,
138                         InputOutput,
139                         xvisinfo->visual,
140                         mask, &xattr);
141
142   XFree (xvisinfo);
143
144   cogl_x11_onscreen_set_foreign_window_xid (onscreen, xwin,
145                                             update_cogl_x11_event_mask,
146                                             xdpy);
147
148   XMapWindow (xdpy, xwin);
149
150   fb = COGL_FRAMEBUFFER (onscreen);
151
152   triangle = cogl_primitive_new_p2c4 (ctx, COGL_VERTICES_MODE_TRIANGLES,
153                                       3, triangle_vertices);
154   pipeline = cogl_pipeline_new (ctx);
155   for (;;)
156     {
157       CoglPollFD *poll_fds;
158       int n_poll_fds;
159       gint64 timeout;
160
161       while (XPending (xdpy))
162         {
163           XEvent event;
164           XNextEvent (xdpy, &event);
165           switch (event.type)
166             {
167             case KeyRelease:
168             case ButtonRelease:
169               return 0;
170             }
171           cogl_xlib_renderer_handle_event (renderer, &event);
172         }
173       cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
174       cogl_framebuffer_draw_primitive (fb, pipeline, triangle);
175       cogl_onscreen_swap_buffers (onscreen);
176
177       cogl_poll_get_info (ctx, &poll_fds, &n_poll_fds, &timeout);
178       g_poll ((GPollFD *) poll_fds, n_poll_fds, 0);
179       cogl_poll_dispatch (ctx, poll_fds, n_poll_fds);
180     }
181
182   return 0;
183 }