117 lines
2.9 KiB
C
117 lines
2.9 KiB
C
|
|
#include "window.h"
|
||
|
|
#include "../application_context.h"
|
||
|
|
#include <stdlib.h>
|
||
|
|
#include <stdio.h>
|
||
|
|
|
||
|
|
#include <wayland-egl.h>
|
||
|
|
|
||
|
|
|
||
|
|
/******************************/
|
||
|
|
/********XDG surface **********/
|
||
|
|
/******************************/
|
||
|
|
|
||
|
|
/* listener bound to the various xdg_surfaces for listening to "configure" events
|
||
|
|
the client should rearrange its surfaces to accomodate the new state
|
||
|
|
the client should answer to (ACK) the event
|
||
|
|
*/
|
||
|
|
void surface_configure(void *data, struct xdg_surface *xdg_surface,
|
||
|
|
uint32_t serial) {
|
||
|
|
(void) data;
|
||
|
|
|
||
|
|
xdg_surface_ack_configure(xdg_surface, serial);
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
listener to be bound on XDG surfaces
|
||
|
|
|
||
|
|
the only event declared by the xdg_surface is the "configure" one
|
||
|
|
indicates the hint for the client to update the arrangement of surfaces ( i.e. change of resolution )
|
||
|
|
*/
|
||
|
|
const struct xdg_surface_listener surface_listener = {
|
||
|
|
surface_configure
|
||
|
|
};
|
||
|
|
|
||
|
|
/******************************/
|
||
|
|
/********XDG Toplevel**********/
|
||
|
|
/******************************/
|
||
|
|
|
||
|
|
/* listener bound to the toplevel surface
|
||
|
|
the toplevel may raise a "configure" event, which hints the client about reconfiguring its state
|
||
|
|
|
||
|
|
here we propagate the new width and height to the EGL window ( probably for readjusting buffers )
|
||
|
|
*/
|
||
|
|
void toplevel_configure(
|
||
|
|
void *data,
|
||
|
|
struct xdg_toplevel *xdg_toplevel,
|
||
|
|
int32_t width,
|
||
|
|
int32_t height,
|
||
|
|
struct wl_array *states
|
||
|
|
) {
|
||
|
|
(void) states;
|
||
|
|
window *win = data;
|
||
|
|
|
||
|
|
if( ! win || win->xdg_toplevel != xdg_toplevel){
|
||
|
|
fprintf(stderr, "inconsistency during toplevel configure\n");
|
||
|
|
fprintf(stderr, "window->xdg_toplevel %p\nxdg_toplevel %p\n",
|
||
|
|
(void*) win->xdg_toplevel,
|
||
|
|
(void*) xdg_toplevel
|
||
|
|
);
|
||
|
|
exit(EXIT_FAILURE);
|
||
|
|
}
|
||
|
|
|
||
|
|
if(!width && !height) return;
|
||
|
|
|
||
|
|
if( win->dimensions->w != width || win->dimensions->h != height) {
|
||
|
|
win->dimensions->w = width;
|
||
|
|
win->dimensions->h = height;
|
||
|
|
|
||
|
|
wl_egl_window_resize(win->egl_window, width, height, 0, 0);
|
||
|
|
wl_surface_commit(win->surface);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void toplevel_close( void *data, struct xdg_toplevel *xdg_toplevel) {
|
||
|
|
(void) xdg_toplevel;
|
||
|
|
|
||
|
|
application_context *app = data;
|
||
|
|
|
||
|
|
app->running = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
const struct xdg_toplevel_listener toplevel_listener = {
|
||
|
|
toplevel_configure,
|
||
|
|
toplevel_close
|
||
|
|
};
|
||
|
|
|
||
|
|
/******************************/
|
||
|
|
/************APIs**************/
|
||
|
|
/******************************/
|
||
|
|
|
||
|
|
window* window_malloc(){
|
||
|
|
return malloc( sizeof( window));
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
window* window_new(
|
||
|
|
const char *title,
|
||
|
|
ui_dimensions *dim,
|
||
|
|
wl_context *w,
|
||
|
|
void *app
|
||
|
|
){
|
||
|
|
window *win = window_malloc();
|
||
|
|
|
||
|
|
win->egl_window = NULL;
|
||
|
|
win->egl_surface = NULL;
|
||
|
|
|
||
|
|
win->dimensions = dim;
|
||
|
|
|
||
|
|
win->surface = wl_compositor_create_surface( w->builders->compositor);
|
||
|
|
win->xdg_surface = xdg_wm_base_get_xdg_surface( w->builders->xdg_wm_base, win->surface);
|
||
|
|
xdg_surface_add_listener( win->xdg_surface, &surface_listener, NULL);
|
||
|
|
win->xdg_toplevel = xdg_surface_get_toplevel( win->xdg_surface);
|
||
|
|
xdg_toplevel_set_title( win->xdg_toplevel, title);
|
||
|
|
xdg_toplevel_add_listener( win->xdg_toplevel, &toplevel_listener, win);
|
||
|
|
wl_surface_commit( win->surface);
|
||
|
|
return win;
|
||
|
|
}
|