static void frame_callback(void *data, struct wl_callback *callback, uint32_t time) { struct resizor *resizor = data; assert(!callback || callback == resizor->frame_callback); if (resizor->frame_callback) { wl_callback_destroy(resizor->frame_callback); resizor->frame_callback = NULL; } if (window_is_maximized(resizor->window)) return; spring_update(&resizor->width); spring_update(&resizor->height); widget_schedule_resize(resizor->widget, resizor->width.current + 0.5, resizor->height.current + 0.5); if (!spring_done(&resizor->width) || !spring_done(&resizor->height)) { resizor->frame_callback = wl_surface_frame( window_get_wl_surface(resizor->window)); wl_callback_add_listener(resizor->frame_callback, &listener, resizor); } }
static void locked_pointer_frame_callback(void *data, struct wl_callback *callback, uint32_t time) { struct resizor *resizor = data; struct wl_surface *surface; struct rectangle allocation; float x, y; if (resizor->pointer_locked) { widget_get_allocation(resizor->widget, &allocation); x = resizor->pointer_x + (allocation.width - allocation.x); y = resizor->pointer_y + (allocation.height - allocation.y); widget_set_locked_pointer_cursor_hint(resizor->widget, x, y); } wl_callback_destroy(callback); surface = window_get_wl_surface(resizor->window); callback = wl_surface_frame(surface); wl_callback_add_listener(callback, &locked_pointer_frame_listener, resizor); }
static void keyboard_create(struct output *output, struct virtual_keyboard *virtual_keyboard) { struct keyboard *keyboard; const struct layout *layout; struct wl_input_panel_surface *ips; layout = get_current_layout(virtual_keyboard); keyboard = xzalloc(sizeof *keyboard); keyboard->keyboard = virtual_keyboard; keyboard->window = window_create_custom(virtual_keyboard->display); keyboard->widget = window_add_widget(keyboard->window, keyboard); virtual_keyboard->keyboard = keyboard; window_set_title(keyboard->window, "Virtual keyboard"); window_set_user_data(keyboard->window, keyboard); widget_set_redraw_handler(keyboard->widget, redraw_handler); widget_set_resize_handler(keyboard->widget, resize_handler); widget_set_button_handler(keyboard->widget, button_handler); window_schedule_resize(keyboard->window, layout->columns * key_width, layout->rows * key_height); ips = wl_input_panel_get_input_panel_surface(virtual_keyboard->input_panel, window_get_wl_surface(keyboard->window)); wl_input_panel_surface_set_toplevel(ips, output_get_wl_output(output), WL_INPUT_PANEL_SURFACE_POSITION_CENTER_BOTTOM); }
static void keyboard_create(struct output *output, struct virtual_keyboard *virtual_keyboard) { struct keyboard *keyboard; keyboard = malloc(sizeof *keyboard); memset(keyboard, 0, sizeof *keyboard); keyboard->keyboard = virtual_keyboard; keyboard->window = window_create_custom(virtual_keyboard->display); keyboard->widget = window_add_widget(keyboard->window, keyboard); window_set_title(keyboard->window, "Virtual keyboard"); window_set_user_data(keyboard->window, keyboard); widget_set_redraw_handler(keyboard->widget, redraw_handler); widget_set_resize_handler(keyboard->widget, resize_handler); widget_set_button_handler(keyboard->widget, button_handler); window_schedule_resize(keyboard->window, columns * key_width, rows * key_height); input_panel_set_surface(virtual_keyboard->input_panel, window_get_wl_surface(keyboard->window), output_get_wl_output(output)); }
static void text_entry_activate(struct text_entry *entry, struct wl_seat *seat) { struct wl_surface *surface = window_get_wl_surface(entry->window); text_model_activate(entry->model, seat, surface); }
static void frame_callback(struct wl_surface *surface, void *data, uint32_t time) { struct gears *gears = data; gears->angle = (GLfloat) (time % 8192) * 360 / 8192.0; window_schedule_redraw(gears->window); wl_display_frame_callback(display_get_display(gears->d), window_get_wl_surface(gears->window), frame_callback, gears); }
static void redraw_handler(struct widget *widget, void *data) { struct smoke *smoke = data; uint32_t time = smoke->time; struct wl_callback *callback; cairo_surface_t *surface; diffuse(smoke, time / 30, smoke->b[0].u, smoke->b[1].u); diffuse(smoke, time / 30, smoke->b[0].v, smoke->b[1].v); project(smoke, time / 30, smoke->b[1].u, smoke->b[1].v, smoke->b[0].u, smoke->b[0].v); advect(smoke, time / 30, smoke->b[1].u, smoke->b[1].v, smoke->b[1].u, smoke->b[0].u); advect(smoke, time / 30, smoke->b[1].u, smoke->b[1].v, smoke->b[1].v, smoke->b[0].v); project(smoke, time / 30, smoke->b[0].u, smoke->b[0].v, smoke->b[1].u, smoke->b[1].v); diffuse(smoke, time / 30, smoke->b[0].d, smoke->b[1].d); advect(smoke, time / 30, smoke->b[0].u, smoke->b[0].v, smoke->b[1].d, smoke->b[0].d); surface = window_get_surface(smoke->window); render(smoke, surface); window_damage(smoke->window, 0, 0, smoke->width, smoke->height); cairo_surface_destroy(surface); callback = wl_surface_frame(window_get_wl_surface(smoke->window)); wl_callback_add_listener(callback, &listener, smoke); wl_surface_commit(window_get_wl_surface(smoke->window)); }
static void text_model_enter(void *data, struct text_model *text_model, struct wl_surface *surface) { struct text_entry *entry = data; if (surface != window_get_wl_surface(entry->window)) return; entry->active = 1; widget_schedule_redraw(entry->widget); }
static struct ModeInfo * create_wscreensaver_instance(struct wscreensaver *screensaver, struct wl_output *output, int width, int height) { static int instance; struct ModeInfo *mi; struct rectangle drawarea; mi = calloc(1, sizeof *mi); if (!mi) return NULL; if (demo_mode) mi->window = window_create(screensaver->display); else mi->window = window_create_custom(screensaver->display); if (!mi->window) { fprintf(stderr, "%s: creating a window failed.\n", progname); free(mi); return NULL; } window_set_title(mi->window, progname); if (screensaver->interface && !demo_mode) { mi->widget = window_add_widget(mi->window, mi); screensaver_set_surface(screensaver->interface, window_get_wl_surface(mi->window), output); } else { mi->widget = frame_create(mi->window, mi); } widget_set_redraw_handler(mi->widget, redraw_handler); mi->priv = screensaver; mi->eglctx = EGL_NO_CONTEXT; mi->instance_number = instance++; /* XXX */ widget_get_allocation(mi->widget, &drawarea); mi->width = drawarea.width; mi->height = drawarea.height; screensaver->plugin->init(mi); window_schedule_resize(mi->window, width, height); return mi; }
static void text_input_enter(void *data, struct wl_text_input *text_input, struct wl_surface *surface) { struct text_entry *entry = data; if (surface != window_get_wl_surface(entry->window)) return; entry->active = 1; text_entry_update(entry); entry->reset_serial = entry->serial; widget_schedule_redraw(entry->widget); }
static void button_handler(struct widget *widget, struct input *input, uint32_t time, uint32_t button, enum wl_pointer_button_state state, void *data) { struct resizor *resizor = data; struct rectangle allocation; struct wl_surface *surface; struct wl_callback *callback; if (button == BTN_RIGHT && state == WL_POINTER_BUTTON_STATE_PRESSED) { show_menu(resizor, input, time); } else if (button == BTN_LEFT && state == WL_POINTER_BUTTON_STATE_PRESSED) { window_get_allocation(resizor->window, &allocation); resizor->width.current = allocation.width; resizor->width.previous = allocation.width; resizor->width.target = allocation.width; resizor->height.current = allocation.height; resizor->height.previous = allocation.height; resizor->height.target = allocation.height; window_lock_pointer(resizor->window, input); window_set_pointer_locked_handler(resizor->window, handle_pointer_locked, handle_pointer_unlocked); resizor->locked_input = input; if (resizor->locked_frame_callback_registered) return; surface = window_get_wl_surface(resizor->window); callback = wl_surface_frame(surface); wl_callback_add_listener(callback, &locked_pointer_frame_listener, resizor); resizor->locked_frame_callback_registered = true; } else if (button == BTN_LEFT && state == WL_POINTER_BUTTON_STATE_RELEASED) { input_set_pointer_image(input, CURSOR_LEFT_PTR); window_unlock_pointer(resizor->window); } }
static void redraw_handler(struct widget *widget, void *data) { struct ModeInfo *mi = data; struct wscreensaver *wscr = mi->priv; struct rectangle drawarea; struct rectangle winarea; struct wl_callback *callback; int bottom; mi->swap_buffers = 0; widget_get_allocation(mi->widget, &drawarea); window_get_allocation(mi->window, &winarea); if (display_acquire_window_surface(wscr->display, mi->window, mi->eglctx) < 0) { fprintf(stderr, "%s: unable to acquire window surface", progname); return; } bottom = winarea.height - (drawarea.height + drawarea.y); glViewport(drawarea.x, bottom, drawarea.width, drawarea.height); glScissor(drawarea.x, bottom, drawarea.width, drawarea.height); glEnable(GL_SCISSOR_TEST); if (mi->width != drawarea.width || mi->height != drawarea.height) { mi->width = drawarea.width; mi->height = drawarea.height; wscr->plugin->reshape(mi, mi->width, mi->height); } wscr->plugin->draw(mi); if (mi->swap_buffers == 0) fprintf(stderr, "%s: swapBuffers not called\n", progname); display_release_window_surface(wscr->display, mi->window); callback = wl_surface_frame(window_get_wl_surface(mi->window)); wl_callback_add_listener(callback, &listener, mi); }
static void text_entry_activate(struct text_entry *entry, struct wl_seat *seat) { struct wl_surface *surface = window_get_wl_surface(entry->window); if (entry->click_to_show && entry->active) { wl_text_input_show_input_panel(entry->text_input); return; } if (!entry->click_to_show) wl_text_input_show_input_panel(entry->text_input); wl_text_input_activate(entry->text_input, seat, surface); }
static struct text_entry* text_entry_create(struct editor *editor, const char *text) { struct text_entry *entry; struct wl_surface *surface; entry = malloc(sizeof *entry); surface = window_get_wl_surface(editor->window); entry->widget = editor->widget; entry->window = editor->window; entry->text = strdup(text); entry->active = 0; entry->model = text_model_factory_create_text_model(editor->text_model_factory, surface); text_model_add_listener(entry->model, &text_model_listener, entry); return entry; }
static void redraw_handler(struct widget *widget, void *data) { struct rectangle window_allocation; struct rectangle allocation; struct wl_callback *callback; struct gears *gears = data; widget_get_allocation(gears->widget, &allocation); window_get_allocation(gears->window, &window_allocation); if (display_acquire_window_surface(gears->d, gears->window, gears->context) < 0) { die("Unable to acquire window surface, " "compiled without cairo-egl?\n"); } glViewport(allocation.x, window_allocation.height - allocation.height - allocation.y, allocation.width, allocation.height); glScissor(allocation.x, window_allocation.height - allocation.height - allocation.y, allocation.width, allocation.height); glEnable(GL_SCISSOR_TEST); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glTranslatef(0.0, 0.0, -50); glRotatef(gears->view.rotx, 1.0, 0.0, 0.0); glRotatef(gears->view.roty, 0.0, 1.0, 0.0); glPushMatrix(); glTranslatef(-3.0, -2.0, 0.0); glRotatef(gears->angle, 0.0, 0.0, 1.0); glCallList(gears->gear_list[0]); glPopMatrix(); glPushMatrix(); glTranslatef(3.1, -2.0, 0.0); glRotatef(-2.0 * gears->angle - 9.0, 0.0, 0.0, 1.0); glCallList(gears->gear_list[1]); glPopMatrix(); glPushMatrix(); glTranslatef(-3.1, 4.2, 0.0); glRotatef(-2.0 * gears->angle - 25.0, 0.0, 0.0, 1.0); glCallList(gears->gear_list[2]); glPopMatrix(); glPopMatrix(); glFlush(); display_release_window_surface(gears->d, gears->window); callback = wl_surface_frame(window_get_wl_surface(gears->window)); wl_callback_add_listener(callback, &listener, gears); }
static void key_handler(struct window *window, struct input *input, uint32_t time, uint32_t key, uint32_t sym, enum wl_keyboard_key_state state, void *data) { struct fullscreen *fullscreen = data; int transform, scale; static int current_size = 0; struct fs_output *fsout; struct wl_output *wl_output; int widths[] = { 640, 320, 800, 400 }; int heights[] = { 480, 240, 600, 300 }; if (state == WL_KEYBOARD_KEY_STATE_RELEASED) return; switch (sym) { case XKB_KEY_t: transform = window_get_buffer_transform (window); transform = (transform + 1) % 8; window_set_buffer_transform(window, transform); window_schedule_redraw(window); break; case XKB_KEY_s: scale = window_get_buffer_scale (window); if (scale == 1) scale = 2; else scale = 1; window_set_buffer_scale(window, scale); window_schedule_redraw(window); break; case XKB_KEY_z: current_size = (current_size + 1) % 4; fullscreen->width = widths[current_size]; fullscreen->height = heights[current_size]; window_schedule_resize(fullscreen->window, fullscreen->width, fullscreen->height); break; case XKB_KEY_m: if (!fullscreen->fshell) break; wl_output = NULL; if (fullscreen->current_output) wl_output = output_get_wl_output(fullscreen->current_output->output); fullscreen->present_method = (fullscreen->present_method + 1) % 5; _wl_fullscreen_shell_present_surface(fullscreen->fshell, window_get_wl_surface(fullscreen->window), fullscreen->present_method, wl_output); window_schedule_redraw(window); break; case XKB_KEY_o: if (!fullscreen->fshell) break; fsout = fullscreen->current_output; wl_output = fsout ? output_get_wl_output(fsout->output) : NULL; /* Clear the current presentation */ _wl_fullscreen_shell_present_surface(fullscreen->fshell, NULL, 0, wl_output); if (fullscreen->current_output) { if (fullscreen->current_output->link.next == &fullscreen->output_list) fsout = NULL; else fsout = wl_container_of(fullscreen->current_output->link.next, fsout, link); } else { fsout = wl_container_of(fullscreen->output_list.next, fsout, link); } fullscreen->current_output = fsout; wl_output = fsout ? output_get_wl_output(fsout->output) : NULL; _wl_fullscreen_shell_present_surface(fullscreen->fshell, window_get_wl_surface(fullscreen->window), fullscreen->present_method, wl_output); window_schedule_redraw(window); break; case XKB_KEY_w: if (!fullscreen->fshell || !fullscreen->current_output) break; wl_output = NULL; if (fullscreen->current_output) wl_output = output_get_wl_output(fullscreen->current_output->output); _wl_fullscreen_shell_mode_feedback_destroy( _wl_fullscreen_shell_present_surface_for_mode(fullscreen->fshell, window_get_wl_surface(fullscreen->window), wl_output, 0)); window_schedule_redraw(window); break; case XKB_KEY_f: if (fullscreen->fshell) break; fullscreen->fullscreen ^= 1; window_set_fullscreen(window, fullscreen->fullscreen); break; case XKB_KEY_q: exit (0); break; } }
static struct gears * gears_create(struct display *display) { const int width = 450, height = 500; struct gears *gears; int i; gears = malloc(sizeof *gears); memset(gears, 0, sizeof *gears); gears->d = display; gears->window = window_create(display, width, height); window_set_title(gears->window, "Wayland Gears"); gears->display = display_get_egl_display(gears->d); if (gears->display == NULL) die("failed to create egl display\n"); eglBindAPI(EGL_OPENGL_API); gears->config = display_get_egl_config(gears->d); gears->context = eglCreateContext(gears->display, gears->config, EGL_NO_CONTEXT, NULL); if (gears->context == NULL) die("failed to create context\n"); if (!eglMakeCurrent(gears->display, NULL, NULL, gears->context)) die("faile to make context current\n"); for (i = 0; i < 3; i++) { gears->gear_list[i] = glGenLists(1); glNewList(gears->gear_list[i], GL_COMPILE); make_gear(&gear_templates[i]); glEndList(); } glEnable(GL_NORMALIZE); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 200.0); glMatrixMode(GL_MODELVIEW); glLightfv(GL_LIGHT0, GL_POSITION, light_pos); glEnable(GL_CULL_FACE); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); glClearColor(0, 0, 0, 0.92); window_set_user_data(gears->window, gears); window_set_resize_handler(gears->window, resize_handler); window_set_keyboard_focus_handler(gears->window, keyboard_focus_handler); window_set_redraw_handler(gears->window, redraw_handler); draw_gears(gears); wl_display_frame_callback(display_get_display(gears->d), window_get_wl_surface(gears->window), frame_callback, gears); return gears; }
int main(int argc, char *argv[]) { struct fullscreen fullscreen; struct display *d; int i; fullscreen.width = 640; fullscreen.height = 480; fullscreen.fullscreen = 0; fullscreen.present_method = _WL_FULLSCREEN_SHELL_PRESENT_METHOD_DEFAULT; wl_list_init(&fullscreen.output_list); fullscreen.current_output = NULL; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-w") == 0) { if (++i >= argc) usage(EXIT_FAILURE); fullscreen.width = atol(argv[i]); } else if (strcmp(argv[i], "-h") == 0) { if (++i >= argc) usage(EXIT_FAILURE); fullscreen.height = atol(argv[i]); } else if (strcmp(argv[i], "--help") == 0) usage(EXIT_SUCCESS); else usage(EXIT_FAILURE); } d = display_create(&argc, argv); if (d == NULL) { fprintf(stderr, "failed to create display: %m\n"); return -1; } fullscreen.display = d; fullscreen.fshell = NULL; display_set_user_data(fullscreen.display, &fullscreen); display_set_global_handler(fullscreen.display, global_handler); display_set_output_configure_handler(fullscreen.display, output_handler); if (fullscreen.fshell) { fullscreen.window = window_create_custom(d); _wl_fullscreen_shell_present_surface(fullscreen.fshell, window_get_wl_surface(fullscreen.window), fullscreen.present_method, NULL); /* If we get the CURSOR_PLANE capability, we'll change this */ fullscreen.draw_cursor = 1; } else { fullscreen.window = window_create(d); fullscreen.draw_cursor = 0; } fullscreen.widget = window_add_widget(fullscreen.window, &fullscreen); window_set_title(fullscreen.window, "Fullscreen"); widget_set_transparent(fullscreen.widget, 0); widget_set_default_cursor(fullscreen.widget, CURSOR_LEFT_PTR); widget_set_redraw_handler(fullscreen.widget, redraw_handler); widget_set_button_handler(fullscreen.widget, button_handler); widget_set_motion_handler(fullscreen.widget, motion_handler); widget_set_enter_handler(fullscreen.widget, enter_handler); widget_set_touch_down_handler(fullscreen.widget, touch_handler); window_set_key_handler(fullscreen.window, key_handler); window_set_fullscreen_handler(fullscreen.window, fullscreen_handler); window_set_user_data(fullscreen.window, &fullscreen); /* Hack to set minimum allocation so we can shrink later */ window_schedule_resize(fullscreen.window, 1, 1); window_schedule_resize(fullscreen.window, fullscreen.width, fullscreen.height); display_run(d); return 0; }