~ubuntu-branches/ubuntu/quantal/weston/quantal

« back to all changes in this revision

Viewing changes to src/compositor-x11.c

  • Committer: Package Import Robot
  • Author(s): Timo Aaltonen
  • Date: 2012-08-23 18:02:55 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120823180255-pg1bq6pq3cg92541
Tags: 0.95.0-0ubuntu1
Merge from unreleased debian git.

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
#endif
27
27
 
28
28
#include <stddef.h>
29
 
#include <stdio.h>
30
29
#include <stdlib.h>
31
30
#include <string.h>
32
31
#include <fcntl.h>
36
35
#include <linux/input.h>
37
36
 
38
37
#include <xcb/xcb.h>
 
38
#ifdef HAVE_XCB_XKB
 
39
#include <xcb/xkb.h>
 
40
#endif
 
41
 
39
42
#include <X11/Xlib.h>
40
43
#include <X11/Xlib-xcb.h>
41
44
 
 
45
#include <xkbcommon/xkbcommon.h>
 
46
 
42
47
#include <GLES2/gl2.h>
43
48
#include <EGL/egl.h>
44
49
 
45
50
#include "compositor.h"
 
51
#include "../shared/config-parser.h"
 
52
#include "log.h"
46
53
 
47
54
struct x11_compositor {
48
55
        struct weston_compositor         base;
49
56
 
 
57
        EGLSurface               dummy_pbuffer;
 
58
 
50
59
        Display                 *dpy;
51
60
        xcb_connection_t        *conn;
52
61
        xcb_screen_t            *screen;
53
62
        xcb_cursor_t             null_cursor;
54
63
        struct wl_array          keys;
55
64
        struct wl_event_source  *xcb_source;
 
65
        struct xkb_keymap       *xkb_keymap;
 
66
        unsigned int             has_xkb;
 
67
        uint8_t                  xkb_event_base;
56
68
        struct {
57
69
                xcb_atom_t               wm_protocols;
58
70
                xcb_atom_t               wm_normal_hints;
66
78
                xcb_atom_t               string;
67
79
                xcb_atom_t               utf8_string;
68
80
                xcb_atom_t               cardinal;
 
81
                xcb_atom_t               xkb_names;
69
82
        } atom;
70
83
};
71
84
 
79
92
};
80
93
 
81
94
struct x11_input {
82
 
        struct weston_input_device base;
 
95
        struct weston_seat base;
83
96
};
84
97
 
 
98
static struct xkb_keymap *
 
99
x11_compositor_get_keymap(struct x11_compositor *c)
 
100
{
 
101
        xcb_get_property_cookie_t cookie;
 
102
        xcb_get_property_reply_t *reply;
 
103
        xcb_generic_error_t *error;
 
104
        struct xkb_rule_names names;
 
105
        struct xkb_keymap *ret;
 
106
        const char *value_all, *value_part;
 
107
        int length_all, length_part;
 
108
 
 
109
        memset(&names, 0, sizeof(names));
 
110
 
 
111
        cookie = xcb_get_property(c->conn, 0, c->screen->root,
 
112
                                  c->atom.xkb_names, c->atom.string, 0, 1024);
 
113
        reply = xcb_get_property_reply(c->conn, cookie, &error);
 
114
        if (reply == NULL)
 
115
                return NULL;
 
116
 
 
117
        value_all = xcb_get_property_value(reply);
 
118
        length_all = xcb_get_property_value_length(reply);
 
119
        value_part = value_all;
 
120
 
 
121
#define copy_prop_value(to) \
 
122
        length_part = strlen(value_part); \
 
123
        if (value_part + length_part < (value_all + length_all) && \
 
124
            length_part > 0) \
 
125
                names.to = value_part; \
 
126
        value_part += length_part + 1;
 
127
 
 
128
        copy_prop_value(rules);
 
129
        copy_prop_value(model);
 
130
        copy_prop_value(layout);
 
131
        copy_prop_value(variant);
 
132
        copy_prop_value(options);
 
133
#undef copy_prop_value
 
134
 
 
135
        ret = xkb_map_new_from_names(c->base.xkb_context, &names, 0);
 
136
 
 
137
        free(reply);
 
138
        return ret;
 
139
}
 
140
 
 
141
static void
 
142
x11_compositor_setup_xkb(struct x11_compositor *c)
 
143
{
 
144
#ifndef HAVE_XCB_XKB
 
145
        weston_log("XCB-XKB not available during build\n");
 
146
        c->has_xkb = 0;
 
147
        c->xkb_event_base = 0;
 
148
        return;
 
149
#else
 
150
        const xcb_query_extension_reply_t *ext;
 
151
        xcb_generic_error_t *error;
 
152
        xcb_void_cookie_t select;
 
153
        xcb_xkb_per_client_flags_cookie_t pcf;
 
154
        xcb_xkb_per_client_flags_reply_t *pcf_reply;
 
155
 
 
156
        c->has_xkb = 0;
 
157
        c->xkb_event_base = 0;
 
158
 
 
159
        ext = xcb_get_extension_data(c->conn, &xcb_xkb_id);
 
160
        if (!ext) {
 
161
                weston_log("XKB extension not available on host X11 server\n");
 
162
                return;
 
163
        }
 
164
        c->xkb_event_base = ext->first_event;
 
165
 
 
166
        select = xcb_xkb_select_events(c->conn,
 
167
                                       XCB_XKB_ID_USE_CORE_KBD,
 
168
                                       XCB_XKB_EVENT_TYPE_STATE_NOTIFY,
 
169
                                       0,
 
170
                                       XCB_XKB_EVENT_TYPE_STATE_NOTIFY,
 
171
                                       0,
 
172
                                       0,
 
173
                                       NULL);
 
174
        error = xcb_request_check(c->conn, select);
 
175
        if (error) {
 
176
                weston_log("error: failed to select for XKB state events\n");
 
177
                return;
 
178
        }
 
179
 
 
180
        pcf = xcb_xkb_per_client_flags(c->conn,
 
181
                                       XCB_XKB_ID_USE_CORE_KBD,
 
182
                                       XCB_XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT,
 
183
                                       XCB_XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT,
 
184
                                       0,
 
185
                                       0,
 
186
                                       0);
 
187
        pcf_reply = xcb_xkb_per_client_flags_reply(c->conn, pcf, &error);
 
188
        free(pcf_reply);
 
189
        if (error) {
 
190
                weston_log("failed to set XKB per-client flags, not using "
 
191
                           "detectable repeat\n");
 
192
                return;
 
193
        }
 
194
 
 
195
        c->has_xkb = 1;
 
196
#endif
 
197
}
85
198
 
86
199
static int
87
 
x11_input_create(struct x11_compositor *c)
 
200
x11_input_create(struct x11_compositor *c, int no_input)
88
201
{
89
202
        struct x11_input *input;
 
203
        struct xkb_keymap *keymap;
90
204
 
91
205
        input = malloc(sizeof *input);
92
206
        if (input == NULL)
93
207
                return -1;
94
208
 
95
209
        memset(input, 0, sizeof *input);
96
 
        weston_input_device_init(&input->base, &c->base);
97
 
 
98
 
        c->base.input_device = &input->base.input_device;
 
210
        weston_seat_init(&input->base, &c->base);
 
211
        c->base.seat = &input->base;
 
212
 
 
213
        if (no_input)
 
214
                return 0;
 
215
 
 
216
        weston_seat_init_pointer(&input->base);
 
217
 
 
218
        x11_compositor_setup_xkb(c);
 
219
 
 
220
        keymap = x11_compositor_get_keymap(c);
 
221
        weston_seat_init_keyboard(&input->base, keymap);
 
222
        if (keymap)
 
223
                xkb_map_unref(keymap);
99
224
 
100
225
        return 0;
101
226
}
103
228
static void
104
229
x11_input_destroy(struct x11_compositor *compositor)
105
230
{
106
 
        struct x11_input *input = container_of(compositor->base.input_device,
 
231
        struct x11_input *input = container_of(compositor->base.seat,
107
232
                                               struct x11_input,
108
 
                                               base.input_device);
 
233
                                               base);
109
234
 
110
 
        weston_input_device_release(&input->base);
 
235
        weston_seat_release(&input->base);
111
236
        free(input);
112
237
}
113
238
 
116
241
{
117
242
        EGLint major, minor;
118
243
        EGLint n;
119
 
        const char *extensions;
120
244
        EGLint config_attribs[] = {
121
245
                EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
122
246
                EGL_RED_SIZE, 1,
123
247
                EGL_GREEN_SIZE, 1,
124
248
                EGL_BLUE_SIZE, 1,
125
 
                EGL_DEPTH_SIZE, 1,
126
249
                EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
127
250
                EGL_NONE
128
251
        };
131
254
                EGL_NONE
132
255
        };
133
256
 
134
 
        c->base.display = eglGetDisplay(c->dpy);
135
 
        if (c->base.display == NULL) {
136
 
                fprintf(stderr, "failed to create display\n");
137
 
                return -1;
138
 
        }
139
 
 
140
 
        if (!eglInitialize(c->base.display, &major, &minor)) {
141
 
                fprintf(stderr, "failed to initialize display\n");
142
 
                return -1;
143
 
        }
144
 
 
145
 
        extensions = eglQueryString(c->base.display, EGL_EXTENSIONS);
146
 
        if (!strstr(extensions, "EGL_KHR_surfaceless_gles2")) {
147
 
                fprintf(stderr, "EGL_KHR_surfaceless_gles2 not available\n");
 
257
        static const EGLint pbuffer_attribs[] = {
 
258
                EGL_WIDTH, 10,
 
259
                EGL_HEIGHT, 10,
 
260
                EGL_NONE
 
261
        };
 
262
 
 
263
        c->base.egl_display = eglGetDisplay(c->dpy);
 
264
        if (c->base.egl_display == NULL) {
 
265
                weston_log("failed to create display\n");
 
266
                return -1;
 
267
        }
 
268
 
 
269
        if (!eglInitialize(c->base.egl_display, &major, &minor)) {
 
270
                weston_log("failed to initialize display\n");
148
271
                return -1;
149
272
        }
150
273
 
151
274
        if (!eglBindAPI(EGL_OPENGL_ES_API)) {
152
 
                fprintf(stderr, "failed to bind EGL_OPENGL_ES_API\n");
153
 
                return -1;
154
 
        }
155
 
        if (!eglChooseConfig(c->base.display, config_attribs,
156
 
                             &c->base.config, 1, &n) || n == 0) {
157
 
                fprintf(stderr, "failed to choose config: %d\n", n);
158
 
                return -1;
159
 
        }
160
 
 
161
 
        c->base.context = eglCreateContext(c->base.display, c->base.config,
162
 
                                           EGL_NO_CONTEXT, context_attribs);
163
 
        if (c->base.context == NULL) {
164
 
                fprintf(stderr, "failed to create context\n");
165
 
                return -1;
166
 
        }
167
 
 
168
 
        if (!eglMakeCurrent(c->base.display, EGL_NO_SURFACE,
169
 
                            EGL_NO_SURFACE, c->base.context)) {
170
 
                fprintf(stderr, "failed to make context current\n");
 
275
                weston_log("failed to bind EGL_OPENGL_ES_API\n");
 
276
                return -1;
 
277
        }
 
278
        if (!eglChooseConfig(c->base.egl_display, config_attribs,
 
279
                             &c->base.egl_config, 1, &n) || n == 0) {
 
280
                weston_log("failed to choose config: %d\n", n);
 
281
                return -1;
 
282
        }
 
283
 
 
284
        c->base.egl_context =
 
285
                eglCreateContext(c->base.egl_display, c->base.egl_config,
 
286
                                 EGL_NO_CONTEXT, context_attribs);
 
287
        if (c->base.egl_context == NULL) {
 
288
                weston_log("failed to create context\n");
 
289
                return -1;
 
290
        }
 
291
 
 
292
        c->dummy_pbuffer = eglCreatePbufferSurface(c->base.egl_display,
 
293
                                                   c->base.egl_config,
 
294
                                                   pbuffer_attribs);
 
295
        if (c->dummy_pbuffer == NULL) {
 
296
                weston_log("failed to create dummy pbuffer\n");
 
297
                return -1;
 
298
        }
 
299
 
 
300
        if (!eglMakeCurrent(c->base.egl_display, c->dummy_pbuffer,
 
301
                            c->dummy_pbuffer, c->base.egl_context)) {
 
302
                weston_log("failed to make context current\n");
171
303
                return -1;
172
304
        }
173
305
 
177
309
static void
178
310
x11_compositor_fini_egl(struct x11_compositor *compositor)
179
311
{
180
 
        eglMakeCurrent(compositor->base.display,
 
312
        eglMakeCurrent(compositor->base.egl_display,
181
313
                       EGL_NO_SURFACE, EGL_NO_SURFACE,
182
314
                       EGL_NO_CONTEXT);
183
315
 
184
 
        eglTerminate(compositor->base.display);
 
316
        eglTerminate(compositor->base.egl_display);
185
317
        eglReleaseThread();
186
318
}
187
319
 
188
 
static int
189
 
x11_output_prepare_render(struct weston_output *output_base)
 
320
static void
 
321
x11_output_repaint(struct weston_output *output_base,
 
322
                   pixman_region32_t *damage)
190
323
{
191
 
        struct x11_output *output = (struct x11_output *) output_base;
192
 
        struct weston_compositor *ec = output->base.compositor;
 
324
        struct x11_output *output = (struct x11_output *)output_base;
 
325
        struct x11_compositor *compositor =
 
326
                (struct x11_compositor *)output->base.compositor;
 
327
        struct weston_surface *surface;
193
328
 
194
 
        if (!eglMakeCurrent(ec->display, output->egl_surface,
195
 
                            output->egl_surface, ec->context)) {
196
 
                fprintf(stderr, "failed to make current\n");
197
 
                return -1;
 
329
        if (!eglMakeCurrent(compositor->base.egl_display, output->egl_surface,
 
330
                            output->egl_surface,
 
331
                            compositor->base.egl_context)) {
 
332
                weston_log("failed to make current\n");
 
333
                return;
198
334
        }
199
335
 
200
 
        return 0;
 
336
        wl_list_for_each_reverse(surface, &compositor->base.surface_list, link)
 
337
                weston_surface_draw(surface, &output->base, damage);
 
338
 
 
339
        wl_signal_emit(&output->base.frame_signal, output);
 
340
 
 
341
        eglSwapBuffers(compositor->base.egl_display, output->egl_surface);
 
342
 
 
343
        wl_event_source_timer_update(output->finish_frame_timer, 10);
201
344
}
202
345
 
203
346
static int
214
357
        return 1;
215
358
}
216
359
 
217
 
static int
218
 
x11_output_present(struct weston_output *output_base)
219
 
{
220
 
        struct x11_output *output = (struct x11_output *) output_base;
221
 
        struct weston_compositor *ec = output->base.compositor;
222
 
 
223
 
        if (x11_output_prepare_render(&output->base))
224
 
                return -1;
225
 
 
226
 
        eglSwapBuffers(ec->display, output->egl_surface);
227
 
 
228
 
        wl_event_source_timer_update(output->finish_frame_timer, 10);
229
 
 
230
 
        return 0;
231
 
}
232
 
 
233
 
static int
234
 
x11_output_prepare_scanout_surface(struct weston_output *output_base,
235
 
                                   struct weston_surface *es)
236
 
{
237
 
        return -1;
238
 
}
239
 
 
240
 
static int
241
 
x11_output_set_cursor(struct weston_output *output_base,
242
 
                      struct weston_input_device *input)
243
 
{
244
 
        return -1;
245
 
}
246
 
 
247
360
static void
248
361
x11_output_destroy(struct weston_output *output_base)
249
362
{
254
367
        wl_list_remove(&output->base.link);
255
368
        wl_event_source_remove(output->finish_frame_timer);
256
369
 
257
 
        eglDestroySurface(compositor->base.display, output->egl_surface);
 
370
        eglDestroySurface(compositor->base.egl_display, output->egl_surface);
258
371
 
259
372
        xcb_destroy_window(compositor->conn, output->window);
260
373
 
332
445
x11_output_set_icon(struct x11_compositor *c,
333
446
                    struct x11_output *output, const char *filename)
334
447
{
335
 
        uint32_t *icon, *pixels, stride;
 
448
        uint32_t *icon;
336
449
        int32_t width, height;
 
450
        pixman_image_t *image;
337
451
 
338
 
        pixels = weston_load_image(filename, &width, &height, &stride);
339
 
        if (!pixels)
 
452
        image = load_image(filename);
 
453
        if (!image)
340
454
                return;
 
455
        width = pixman_image_get_width(image);
 
456
        height = pixman_image_get_height(image);
341
457
        icon = malloc(width * height * 4 + 8);
342
458
        if (!icon) {
343
 
                free(pixels);
 
459
                pixman_image_unref(image);
344
460
                return;
345
461
        }
346
462
 
347
463
        icon[0] = width;
348
464
        icon[1] = height;
349
 
        memcpy(icon + 2, pixels, width * height * 4);
 
465
        memcpy(icon + 2, pixman_image_get_data(image), width * height * 4);
350
466
        xcb_change_property(c->conn, XCB_PROP_MODE_REPLACE, output->window,
351
467
                            c->atom.net_wm_icon, c->atom.cardinal, 32,
352
468
                            width * height + 2, icon);
353
469
        free(icon);
354
 
        free(pixels);
 
470
        pixman_image_unref(image);
355
471
}
356
472
 
357
473
static int
358
474
x11_compositor_create_output(struct x11_compositor *c, int x, int y,
359
 
                             int width, int height, int fullscreen)
 
475
                             int width, int height, int fullscreen,
 
476
                             int no_input)
360
477
{
361
478
        static const char name[] = "Weston Compositor";
362
479
        static const char class[] = "weston-1\0Weston Compositor";
365
482
        struct wm_normal_hints normal_hints;
366
483
        struct wl_event_loop *loop;
367
484
        uint32_t mask = XCB_CW_EVENT_MASK | XCB_CW_CURSOR;
368
 
        uint32_t values[2] = { 
369
 
                XCB_EVENT_MASK_KEY_PRESS |
370
 
                XCB_EVENT_MASK_KEY_RELEASE |
371
 
                XCB_EVENT_MASK_BUTTON_PRESS |
372
 
                XCB_EVENT_MASK_BUTTON_RELEASE |
373
 
                XCB_EVENT_MASK_POINTER_MOTION |
 
485
        uint32_t values[2] = {
374
486
                XCB_EVENT_MASK_EXPOSURE |
375
 
                XCB_EVENT_MASK_STRUCTURE_NOTIFY |
376
 
                XCB_EVENT_MASK_ENTER_WINDOW |
377
 
                XCB_EVENT_MASK_LEAVE_WINDOW |
378
 
                XCB_EVENT_MASK_KEYMAP_STATE |
379
 
                XCB_EVENT_MASK_FOCUS_CHANGE,
 
487
                XCB_EVENT_MASK_STRUCTURE_NOTIFY,
380
488
                0
381
489
        };
382
490
 
 
491
        if (!no_input)
 
492
                values[0] |=
 
493
                        XCB_EVENT_MASK_KEY_PRESS |
 
494
                        XCB_EVENT_MASK_KEY_RELEASE |
 
495
                        XCB_EVENT_MASK_BUTTON_PRESS |
 
496
                        XCB_EVENT_MASK_BUTTON_RELEASE |
 
497
                        XCB_EVENT_MASK_POINTER_MOTION |
 
498
                        XCB_EVENT_MASK_ENTER_WINDOW |
 
499
                        XCB_EVENT_MASK_LEAVE_WINDOW |
 
500
                        XCB_EVENT_MASK_KEYMAP_STATE |
 
501
                        XCB_EVENT_MASK_FOCUS_CHANGE;
 
502
 
383
503
        output = malloc(sizeof *output);
384
504
        if (output == NULL)
385
505
                return -1;
390
510
                WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
391
511
        output->mode.width = width;
392
512
        output->mode.height = height;
393
 
        output->mode.refresh = 60;
 
513
        output->mode.refresh = 60000;
394
514
        wl_list_init(&output->base.mode_list);
395
515
        wl_list_insert(&output->base.mode_list, &output->mode.link);
396
516
 
397
517
        output->base.current = &output->mode;
 
518
        output->base.make = "xwayland";
 
519
        output->base.model = "none";
398
520
        weston_output_init(&output->base, &c->base, x, y, width, height,
399
521
                         WL_OUTPUT_FLIPPED);
400
522
 
445
567
                                        c->atom.net_wm_state_fullscreen);
446
568
 
447
569
        output->egl_surface = 
448
 
                eglCreateWindowSurface(c->base.display, c->base.config,
 
570
                eglCreateWindowSurface(c->base.egl_display, c->base.egl_config,
449
571
                                       output->window, NULL);
450
572
        if (!output->egl_surface) {
451
 
                fprintf(stderr, "failed to create window surface\n");
 
573
                weston_log("failed to create window surface\n");
452
574
                return -1;
453
575
        }
454
 
        if (!eglMakeCurrent(c->base.display, output->egl_surface,
455
 
                            output->egl_surface, c->base.context)) {
456
 
                fprintf(stderr, "failed to make surface current\n");
 
576
        if (!eglMakeCurrent(c->base.egl_display, output->egl_surface,
 
577
                            output->egl_surface, c->base.egl_context)) {
 
578
                weston_log("failed to make surface current\n");
457
579
                return -1;
458
580
        }
459
581
 
461
583
        output->finish_frame_timer =
462
584
                wl_event_loop_add_timer(loop, finish_frame_handler, output);
463
585
 
464
 
        output->base.prepare_render = x11_output_prepare_render;
465
 
        output->base.present = x11_output_present;
466
 
        output->base.prepare_scanout_surface =
467
 
                x11_output_prepare_scanout_surface;
468
 
        output->base.set_hardware_cursor = x11_output_set_cursor;
 
586
        output->base.origin = output->base.current;
 
587
        output->base.repaint = x11_output_repaint;
469
588
        output->base.destroy = x11_output_destroy;
 
589
        output->base.assign_planes = NULL;
 
590
        output->base.set_backlight = NULL;
 
591
        output->base.set_dpms = NULL;
 
592
        output->base.switch_mode = NULL;
470
593
 
471
594
        wl_list_insert(c->base.output_list.prev, &output->base.link);
472
595
 
 
596
        weston_log("x11 output %dx%d, window id %d\n",
 
597
                   width, height, output->window);
 
598
 
473
599
        return 0;
474
600
}
475
601
 
486
612
        return NULL;
487
613
}
488
614
 
 
615
static uint32_t
 
616
get_xkb_mod_mask(struct x11_compositor *c, uint32_t in)
 
617
{
 
618
        struct weston_xkb_info *info = &c->base.seat->xkb_info;
 
619
        uint32_t ret = 0;
 
620
 
 
621
        if ((in & ShiftMask) && info->shift_mod != XKB_MOD_INVALID)
 
622
                ret |= (1 << info->shift_mod);
 
623
        if ((in & LockMask) && info->caps_mod != XKB_MOD_INVALID)
 
624
                ret |= (1 << info->caps_mod);
 
625
        if ((in & ControlMask) && info->ctrl_mod != XKB_MOD_INVALID)
 
626
                ret |= (1 << info->ctrl_mod);
 
627
        if ((in & Mod1Mask) && info->alt_mod != XKB_MOD_INVALID)
 
628
                ret |= (1 << info->alt_mod);
 
629
        if ((in & Mod2Mask) && info->mod2_mod != XKB_MOD_INVALID)
 
630
                ret |= (1 << info->mod2_mod);
 
631
        if ((in & Mod3Mask) && info->mod3_mod != XKB_MOD_INVALID)
 
632
                ret |= (1 << info->mod3_mod);
 
633
        if ((in & Mod4Mask) && info->super_mod != XKB_MOD_INVALID)
 
634
                ret |= (1 << info->super_mod);
 
635
        if ((in & Mod5Mask) && info->mod5_mod != XKB_MOD_INVALID)
 
636
                ret |= (1 << info->mod5_mod);
 
637
 
 
638
        return ret;
 
639
}
 
640
 
 
641
#ifdef HAVE_XCB_XKB
 
642
static void
 
643
update_xkb_state(struct x11_compositor *c, xcb_xkb_state_notify_event_t *state)
 
644
{
 
645
        struct weston_compositor *ec = &c->base;
 
646
        struct wl_seat *seat = &ec->seat->seat;
 
647
 
 
648
        xkb_state_update_mask(c->base.seat->xkb_state.state,
 
649
                              get_xkb_mod_mask(c, state->baseMods),
 
650
                              get_xkb_mod_mask(c, state->latchedMods),
 
651
                              get_xkb_mod_mask(c, state->lockedMods),
 
652
                              0,
 
653
                              0,
 
654
                              state->group);
 
655
 
 
656
        notify_modifiers(seat, wl_display_next_serial(c->base.wl_display));
 
657
}
 
658
#endif
 
659
 
 
660
/**
 
661
 * This is monumentally unpleasant.  If we don't have XCB-XKB bindings,
 
662
 * the best we can do (given that XCB also lacks XI2 support), is to take
 
663
 * the state from the core key events.  Unfortunately that only gives us
 
664
 * the effective (i.e. union of depressed/latched/locked) state, and we
 
665
 * need the granularity.
 
666
 *
 
667
 * So we still update the state with every key event we see, but also use
 
668
 * the state field from X11 events as a mask so we don't get any stuck
 
669
 * modifiers.
 
670
 */
 
671
static void
 
672
update_xkb_state_from_core(struct x11_compositor *c, uint16_t x11_mask)
 
673
{
 
674
        uint32_t mask = get_xkb_mod_mask(c, x11_mask);
 
675
        struct wl_keyboard *keyboard = &c->base.seat->keyboard;
 
676
 
 
677
        xkb_state_update_mask(c->base.seat->xkb_state.state,
 
678
                              keyboard->modifiers.mods_depressed & mask,
 
679
                              keyboard->modifiers.mods_latched & mask,
 
680
                              keyboard->modifiers.mods_locked & mask,
 
681
                              0,
 
682
                              0,
 
683
                              (x11_mask >> 13) & 3);
 
684
        notify_modifiers(&c->base.seat->seat,
 
685
                         wl_display_next_serial(c->base.wl_display));
 
686
}
 
687
 
489
688
static void
490
689
x11_compositor_deliver_button_event(struct x11_compositor *c,
491
690
                                    xcb_generic_event_t *event, int state)
492
691
{
493
692
        xcb_button_press_event_t *button_event =
494
693
                (xcb_button_press_event_t *) event;
495
 
        int button;
 
694
        uint32_t button;
 
695
 
 
696
        if (!c->has_xkb)
 
697
                update_xkb_state_from_core(c, button_event->state);
496
698
 
497
699
        switch (button_event->detail) {
498
700
        default:
505
707
                button = BTN_RIGHT;
506
708
                break;
507
709
        case 4:
 
710
                if (state)
 
711
                        notify_axis(&c->base.seat->seat,
 
712
                                      weston_compositor_get_time(),
 
713
                                      WL_POINTER_AXIS_VERTICAL_SCROLL,
 
714
                                      wl_fixed_from_int(1));
 
715
                return;
508
716
        case 5:
 
717
                if (state)
 
718
                        notify_axis(&c->base.seat->seat,
 
719
                                      weston_compositor_get_time(),
 
720
                                      WL_POINTER_AXIS_VERTICAL_SCROLL,
 
721
                                      wl_fixed_from_int(-1));
 
722
                return;
509
723
        case 6:
 
724
                if (state)
 
725
                        notify_axis(&c->base.seat->seat,
 
726
                                      weston_compositor_get_time(),
 
727
                                      WL_POINTER_AXIS_HORIZONTAL_SCROLL,
 
728
                                      wl_fixed_from_int(1));
 
729
                return;
510
730
        case 7:
511
 
                /* X11 sends wheel events as buttons events.  But
512
 
                 * linux input treats as REL_WHEEL, therefore not
513
 
                 * button type at all. When we update the input
514
 
                 * protocol and get the 'axis' event, we'll send
515
 
                 * scroll events as axis events. */
 
731
                if (state)
 
732
                        notify_axis(&c->base.seat->seat,
 
733
                                      weston_compositor_get_time(),
 
734
                                      WL_POINTER_AXIS_HORIZONTAL_SCROLL,
 
735
                                      wl_fixed_from_int(-1));
516
736
                return;
517
737
        }
518
738
 
519
 
        notify_button(c->base.input_device,
520
 
                      weston_compositor_get_time(), button, state);
 
739
        notify_button(&c->base.seat->seat,
 
740
                      weston_compositor_get_time(), button,
 
741
                      state ? WL_POINTER_BUTTON_STATE_PRESSED :
 
742
                              WL_POINTER_BUTTON_STATE_RELEASED);
521
743
}
522
744
 
523
745
static int
549
771
        xcb_key_press_event_t *key_press, *key_release;
550
772
        xcb_keymap_notify_event_t *keymap_notify;
551
773
        xcb_focus_in_event_t *focus_in;
 
774
        xcb_expose_event_t *expose;
552
775
        xcb_atom_t atom;
553
776
        uint32_t *k;
554
 
        int i, set;
 
777
        uint32_t i, set;
 
778
        wl_fixed_t x, y;
 
779
        int count;
555
780
 
556
781
        prev = NULL;
 
782
        count = 0;
557
783
        while (x11_compositor_next_event(c, &event, mask)) {
558
784
                switch (prev ? prev->response_type & ~0x80 : 0x80) {
559
785
                case XCB_KEY_RELEASE:
 
786
                        /* Suppress key repeat events; this is only used if we
 
787
                         * don't have XCB XKB support. */
560
788
                        key_release = (xcb_key_press_event_t *) prev;
561
789
                        key_press = (xcb_key_press_event_t *) event;
562
790
                        if ((event->response_type & ~0x80) == XCB_KEY_PRESS &&
572
800
                                /* Deliver the held key release now
573
801
                                 * and fall through and handle the new
574
802
                                 * event below. */
575
 
                                notify_key(c->base.input_device,
 
803
                                update_xkb_state_from_core(c, key_release->state);
 
804
                                notify_key(&c->base.seat->seat,
576
805
                                           weston_compositor_get_time(),
577
 
                                           key_release->detail - 8, 0);
 
806
                                           key_release->detail - 8,
 
807
                                           WL_KEYBOARD_KEY_STATE_RELEASED,
 
808
                                           STATE_UPDATE_AUTOMATIC);
578
809
                                free(prev);
579
810
                                prev = NULL;
580
811
                                break;
595
826
                        }
596
827
 
597
828
                        output = x11_compositor_find_output(c, focus_in->event);
598
 
                        notify_keyboard_focus(c->base.input_device,
599
 
                                              weston_compositor_get_time(),
600
 
                                              &output->base, &c->keys);
 
829
                        /* Unfortunately the state only comes with the enter
 
830
                         * event, rather than with the focus event.  I'm not
 
831
                         * sure of the exact semantics around it and whether
 
832
                         * we can ensure that we get both? */
 
833
                        notify_keyboard_focus_in(&c->base.seat->seat, &c->keys,
 
834
                                                 STATE_UPDATE_AUTOMATIC);
601
835
 
602
836
                        free(prev);
603
837
                        prev = NULL;
611
845
                switch (event->response_type & ~0x80) {
612
846
                case XCB_KEY_PRESS:
613
847
                        key_press = (xcb_key_press_event_t *) event;
614
 
                        notify_key(c->base.input_device,
 
848
                        if (!c->has_xkb)
 
849
                                update_xkb_state_from_core(c, key_press->state);
 
850
                        notify_key(&c->base.seat->seat,
615
851
                                   weston_compositor_get_time(),
616
 
                                   key_press->detail - 8, 1);
 
852
                                   key_press->detail - 8,
 
853
                                   WL_KEYBOARD_KEY_STATE_PRESSED,
 
854
                                   c->has_xkb ? STATE_UPDATE_NONE :
 
855
                                                STATE_UPDATE_AUTOMATIC);
617
856
                        break;
618
857
                case XCB_KEY_RELEASE:
619
 
                        prev = event;
 
858
                        /* If we don't have XKB, we need to use the lame
 
859
                         * autorepeat detection above. */
 
860
                        if (!c->has_xkb) {
 
861
                                prev = event;
 
862
                                break;
 
863
                        }
 
864
                        key_release = (xcb_key_press_event_t *) event;
 
865
                        notify_key(&c->base.seat->seat,
 
866
                                   weston_compositor_get_time(),
 
867
                                   key_release->detail - 8,
 
868
                                   WL_KEYBOARD_KEY_STATE_RELEASED,
 
869
                                   STATE_UPDATE_NONE);
620
870
                        break;
621
871
                case XCB_BUTTON_PRESS:
622
872
                        x11_compositor_deliver_button_event(c, event, 1);
626
876
                        break;
627
877
                case XCB_MOTION_NOTIFY:
628
878
                        motion_notify = (xcb_motion_notify_event_t *) event;
 
879
                        if (!c->has_xkb)
 
880
                                update_xkb_state_from_core(c, motion_notify->state);
629
881
                        output = x11_compositor_find_output(c, motion_notify->event);
630
 
                        notify_motion(c->base.input_device,
631
 
                                      weston_compositor_get_time(),
632
 
                                      output->base.x + motion_notify->event_x,
633
 
                                      output->base.y + motion_notify->event_y);
 
882
                        x = wl_fixed_from_int(output->base.x + motion_notify->event_x);
 
883
                        y = wl_fixed_from_int(output->base.y + motion_notify->event_y);
 
884
                        notify_motion(&c->base.seat->seat,
 
885
                                      weston_compositor_get_time(), x, y);
634
886
                        break;
635
887
 
636
888
                case XCB_EXPOSE:
637
 
                        /* FIXME: schedule output repaint */
638
 
                        /* output = x11_compositor_find_output(c, expose->window); */
639
 
 
640
 
                        weston_compositor_schedule_repaint(&c->base);
 
889
                        expose = (xcb_expose_event_t *) event;
 
890
                        output = x11_compositor_find_output(c, expose->window);
 
891
                        weston_output_schedule_repaint(&output->base);
641
892
                        break;
642
893
 
643
894
                case XCB_ENTER_NOTIFY:
644
895
                        enter_notify = (xcb_enter_notify_event_t *) event;
645
896
                        if (enter_notify->state >= Button1Mask)
646
897
                                break;
 
898
                        if (!c->has_xkb)
 
899
                                update_xkb_state_from_core(c, enter_notify->state);
647
900
                        output = x11_compositor_find_output(c, enter_notify->event);
648
 
                        notify_pointer_focus(c->base.input_device,
649
 
                                             weston_compositor_get_time(),
650
 
                                             &output->base,
651
 
                                             output->base.x + enter_notify->event_x,
652
 
                                             output->base.y + enter_notify->event_y);
 
901
                        x = wl_fixed_from_int(output->base.x + enter_notify->event_x);
 
902
                        y = wl_fixed_from_int(output->base.y + enter_notify->event_y);
 
903
 
 
904
                        notify_pointer_focus(&c->base.seat->seat,
 
905
                                             &output->base, x, y);
653
906
                        break;
654
907
 
655
908
                case XCB_LEAVE_NOTIFY:
656
909
                        enter_notify = (xcb_enter_notify_event_t *) event;
657
910
                        if (enter_notify->state >= Button1Mask)
658
911
                                break;
 
912
                        if (!c->has_xkb)
 
913
                                update_xkb_state_from_core(c, enter_notify->state);
659
914
                        output = x11_compositor_find_output(c, enter_notify->event);
660
 
                        notify_pointer_focus(c->base.input_device,
661
 
                                             weston_compositor_get_time(),
662
 
                                             NULL,
663
 
                                             output->base.x + enter_notify->event_x,
664
 
                                             output->base.y + enter_notify->event_y);
 
915
                        notify_pointer_focus(&c->base.seat->seat, NULL, 0, 0);
665
916
                        break;
666
917
 
667
918
                case XCB_CLIENT_MESSAGE:
684
935
                        if (focus_in->mode == XCB_NOTIFY_MODE_WHILE_GRABBED ||
685
936
                            focus_in->mode == XCB_NOTIFY_MODE_UNGRAB)
686
937
                                break;
687
 
                        notify_keyboard_focus(c->base.input_device,
688
 
                                              weston_compositor_get_time(),
689
 
                                              NULL, NULL);
 
938
                        notify_keyboard_focus_out(&c->base.seat->seat);
690
939
                        break;
691
940
 
692
941
                default:
693
942
                        break;
694
943
                }
695
944
 
 
945
#ifdef HAVE_XCB_XKB
 
946
                if (c->has_xkb &&
 
947
                    (event->response_type & ~0x80) == c->xkb_event_base) {
 
948
                        xcb_xkb_state_notify_event_t *state =
 
949
                                (xcb_xkb_state_notify_event_t *) event;
 
950
                        if (state->xkbType == XCB_XKB_STATE_NOTIFY)
 
951
                                update_xkb_state(c, state);
 
952
                }
 
953
#endif
 
954
 
 
955
                count++;
696
956
                if (prev != event)
697
957
                        free (event);
698
958
        }
700
960
        switch (prev ? prev->response_type & ~0x80 : 0x80) {
701
961
        case XCB_KEY_RELEASE:
702
962
                key_release = (xcb_key_press_event_t *) prev;
703
 
                notify_key(c->base.input_device,
 
963
                update_xkb_state_from_core(c, key_release->state);
 
964
                notify_key(&c->base.seat->seat,
704
965
                           weston_compositor_get_time(),
705
 
                           key_release->detail - 8, 0);
 
966
                           key_release->detail - 8,
 
967
                           WL_KEYBOARD_KEY_STATE_RELEASED,
 
968
                           STATE_UPDATE_AUTOMATIC);
706
969
                free(prev);
707
970
                prev = NULL;
708
971
                break;
710
973
                break;
711
974
        }
712
975
 
713
 
        return event != NULL;
 
976
        return count;
714
977
}
715
978
 
716
979
#define F(field) offsetof(struct x11_compositor, field)
731
994
                { "STRING",             F(atom.string) },
732
995
                { "UTF8_STRING",        F(atom.utf8_string) },
733
996
                { "CARDINAL",           F(atom.cardinal) },
 
997
                { "_XKB_RULES_NAMES",   F(atom.xkb_names) },
734
998
        };
735
999
 
736
1000
        xcb_intern_atom_cookie_t cookies[ARRAY_LENGTH(atoms)];
737
1001
        xcb_intern_atom_reply_t *reply;
738
1002
        xcb_pixmap_t pixmap;
739
1003
        xcb_gc_t gc;
740
 
        int i;
 
1004
        unsigned int i;
741
1005
        uint8_t data[] = { 0, 0, 0, 0 };
742
1006
 
743
1007
        for (i = 0; i < ARRAY_LENGTH(atoms); i++)
782
1046
 
783
1047
static struct weston_compositor *
784
1048
x11_compositor_create(struct wl_display *display,
785
 
                      int width, int height, int count, int fullscreen)
 
1049
                      int width, int height, int count, int fullscreen,
 
1050
                      int no_input,
 
1051
                      int argc, char *argv[], const char *config_file)
786
1052
{
787
1053
        struct x11_compositor *c;
788
 
        struct wl_event_loop *loop;
789
1054
        xcb_screen_iterator_t s;
790
1055
        int i, x;
791
1056
 
 
1057
        weston_log("initializing x11 backend\n");
 
1058
 
792
1059
        c = malloc(sizeof *c);
793
1060
        if (c == NULL)
794
1061
                return NULL;
795
1062
 
796
1063
        memset(c, 0, sizeof *c);
797
1064
 
 
1065
        if (weston_compositor_init(&c->base, display, argc, argv,
 
1066
                                   config_file) < 0)
 
1067
                goto err_free;
 
1068
 
798
1069
        c->dpy = XOpenDisplay(NULL);
799
1070
        if (c->dpy == NULL)
800
 
                return NULL;
 
1071
                goto err_free;
801
1072
 
802
1073
        c->conn = XGetXCBConnection(c->dpy);
803
1074
        XSetEventQueueOwner(c->dpy, XCBOwnsEventQueue);
804
1075
 
805
1076
        if (xcb_connection_has_error(c->conn))
806
 
                return NULL;
 
1077
                goto err_xdisplay;
807
1078
 
808
1079
        s = xcb_setup_roots_iterator(xcb_get_setup(c->conn));
809
1080
        c->screen = s.data;
813
1084
 
814
1085
        c->base.wl_display = display;
815
1086
        if (x11_compositor_init_egl(c) < 0)
816
 
                return NULL;
 
1087
                goto err_xdisplay;
817
1088
 
818
1089
        c->base.destroy = x11_destroy;
819
1090
 
820
 
        /* Can't init base class until we have a current egl context */
821
 
        if (weston_compositor_init(&c->base, display) < 0)
822
 
                return NULL;
 
1091
        if (weston_compositor_init_gl(&c->base) < 0)
 
1092
                goto err_egl;
 
1093
 
 
1094
        if (x11_input_create(c, no_input) < 0)
 
1095
                goto err_egl;
823
1096
 
824
1097
        for (i = 0, x = 0; i < count; i++) {
825
1098
                if (x11_compositor_create_output(c, x, 0, width, height,
826
 
                                                 fullscreen) < 0)
827
 
                        return NULL;
 
1099
                                                 fullscreen, no_input) < 0)
 
1100
                        goto err_x11_input;
828
1101
                x += width;
829
1102
        }
830
1103
 
831
 
        if (x11_input_create(c) < 0)
832
 
                return NULL;
833
 
 
834
 
        loop = wl_display_get_event_loop(c->base.wl_display);
835
 
 
836
1104
        c->xcb_source =
837
 
                wl_event_loop_add_fd(loop, xcb_get_file_descriptor(c->conn),
 
1105
                wl_event_loop_add_fd(c->base.input_loop,
 
1106
                                     xcb_get_file_descriptor(c->conn),
838
1107
                                     WL_EVENT_READABLE,
839
1108
                                     x11_compositor_handle_event, c);
840
1109
        wl_event_source_check(c->xcb_source);
841
1110
 
842
1111
        return &c->base;
 
1112
 
 
1113
err_x11_input:
 
1114
        x11_input_destroy(c);
 
1115
err_egl:
 
1116
        x11_compositor_fini_egl(c);
 
1117
err_xdisplay:
 
1118
        XCloseDisplay(c->dpy);
 
1119
err_free:
 
1120
        free(c);
 
1121
        return NULL;
843
1122
}
844
1123
 
845
 
struct weston_compositor *
846
 
backend_init(struct wl_display *display, char *options);
847
 
 
848
1124
WL_EXPORT struct weston_compositor *
849
 
backend_init(struct wl_display *display, char *options)
 
1125
backend_init(struct wl_display *display, int argc, char *argv[],
 
1126
             const char *config_file)
850
1127
{
851
 
        int width = 1024, height = 640, fullscreen = 0, count = 1, i;
852
 
        char *p, *value;
 
1128
        int width = 1024, height = 640, fullscreen = 0, count = 1;
 
1129
        int no_input = 0;
853
1130
 
854
 
        static char * const tokens[] = {
855
 
                "width", "height", "fullscreen", "output-count", NULL
 
1131
        const struct weston_option x11_options[] = {
 
1132
                { WESTON_OPTION_INTEGER, "width", 0, &width },
 
1133
                { WESTON_OPTION_INTEGER, "height", 0, &height },
 
1134
                { WESTON_OPTION_BOOLEAN, "fullscreen", 0, &fullscreen },
 
1135
                { WESTON_OPTION_INTEGER, "output-count", 0, &count },
 
1136
                { WESTON_OPTION_BOOLEAN, "no-input", 0, &no_input },
856
1137
        };
857
 
        
858
 
        p = options;
859
 
        while (i = getsubopt(&p, tokens, &value), i != -1) {
860
 
                switch (i) {
861
 
                case 0:
862
 
                        width = strtol(value, NULL, 0);
863
 
                        break;
864
 
                case 1:
865
 
                        height = strtol(value, NULL, 0);
866
 
                        break;
867
 
                case 2:
868
 
                        fullscreen = 1;
869
 
                        break;
870
 
                case 3:
871
 
                        count = strtol(value, NULL, 0);
872
 
                        break;
873
 
                }
874
 
        }
 
1138
 
 
1139
        parse_options(x11_options, ARRAY_LENGTH(x11_options), argc, argv);
875
1140
 
876
1141
        return x11_compositor_create(display,
877
 
                                     width, height, count, fullscreen);
 
1142
                                     width, height, count, fullscreen,
 
1143
                                     no_input,
 
1144
                                     argc, argv, config_file);
878
1145
}