Add glib main loop integration, use it in flower client.

dev
Kristian Høgsberg 16 years ago
parent 7f77bd8fbe
commit fb59084fbf
  1. 5
      Makefile
  2. 17
      background.c
  3. 95
      flower.c
  4. 16
      pointer.c
  5. 32
      wayland-client.c
  6. 14
      wayland-client.h
  7. 83
      wayland-glib.c
  8. 10
      wayland-glib.h
  9. 17
      window.c

@ -42,7 +42,7 @@ glx-compositor.so : $(glx_compositor_objs)
libwayland.so $(compositors) : libwayland.so $(compositors) :
gcc -o $@ $^ $(LDLIBS) -shared gcc -o $@ $^ $(LDLIBS) -shared
flower_objs = flower.o flower_objs = flower.o wayland-glib.o
pointer_objs = pointer.o pointer_objs = pointer.o
background_objs = background.o background_objs = background.o
window_objs = window.o gears.o window_objs = window.o gears.o
@ -53,6 +53,9 @@ $(clients) : LDLIBS += $(shell pkg-config --libs cairo) -lrt
background : CFLAGS += $(shell pkg-config --cflags gdk-pixbuf-2.0) background : CFLAGS += $(shell pkg-config --cflags gdk-pixbuf-2.0)
background : LDLIBS += $(shell pkg-config --libs gdk-pixbuf-2.0) background : LDLIBS += $(shell pkg-config --libs gdk-pixbuf-2.0)
flower : CFLAGS += $(shell pkg-config --cflags glib-2.0)
flower : LDLIBS += $(shell pkg-config --libs glib-2.0)
window : CFLAGS += $(EAGLE_CFLAGS) window : CFLAGS += $(EAGLE_CFLAGS)
window : LDLIBS += $(EAGLE_LDLIBS) window : LDLIBS += $(EAGLE_LDLIBS)

@ -94,15 +94,14 @@ static uint32_t name_pixbuf(int fd, GdkPixbuf *pixbuf)
} }
static int static int
connection_update(struct wl_connection *connection, connection_update(uint32_t mask, void *data)
uint32_t mask, void *data)
{ {
struct pollfd *p = data; struct pollfd *p = data;
p->events = 0; p->events = 0;
if (mask & WL_CONNECTION_READABLE) if (mask & WL_DISPLAY_READABLE)
p->events |= POLLIN; p->events |= POLLIN;
if (mask & WL_CONNECTION_WRITABLE) if (mask & WL_DISPLAY_WRITABLE)
p->events |= POLLOUT; p->events |= POLLOUT;
return 0; return 0;
@ -124,13 +123,13 @@ int main(int argc, char *argv[])
return -1; return -1;
} }
display = wl_display_create(socket_name, display = wl_display_create(socket_name);
connection_update, &p[0]);
if (display == NULL) { if (display == NULL) {
fprintf(stderr, "failed to create display: %m\n"); fprintf(stderr, "failed to create display: %m\n");
return -1; return -1;
} }
p[0].fd = wl_display_get_fd(display); p[0].fd = wl_display_get_fd(display,
connection_update, &p[0]);
surface = wl_display_create_surface(display); surface = wl_display_create_surface(display);
@ -153,9 +152,9 @@ int main(int argc, char *argv[])
poll(p, 1, -1); poll(p, 1, -1);
mask = 0; mask = 0;
if (p[0].revents & POLLIN) if (p[0].revents & POLLIN)
mask |= WL_CONNECTION_READABLE; mask |= WL_DISPLAY_READABLE;
if (p[0].revents & POLLOUT) if (p[0].revents & POLLOUT)
mask |= WL_CONNECTION_WRITABLE; mask |= WL_DISPLAY_WRITABLE;
wl_display_iterate(display, mask); wl_display_iterate(display, mask);
} }

@ -12,8 +12,10 @@
#include <math.h> #include <math.h>
#include <time.h> #include <time.h>
#include <cairo.h> #include <cairo.h>
#include <glib.h>
#include "wayland-client.h" #include "wayland-client.h"
#include "wayland-glib.h"
static const char gem_device[] = "/dev/dri/card0"; static const char gem_device[] = "/dev/dri/card0";
static const char socket_name[] = "\0wayland"; static const char socket_name[] = "\0wayland";
@ -131,33 +133,36 @@ draw_stuff(int width, int height)
return surface; return surface;
} }
static int struct flower {
connection_update(struct wl_connection *connection, struct wl_surface *surface;
uint32_t mask, void *data) int i;
int x, y, width, height;
};
static gboolean
move_flower(gpointer data)
{ {
struct pollfd *p = data; struct flower *flower = data;
p->events = 0; wl_surface_map(flower->surface,
if (mask & WL_CONNECTION_READABLE) flower->x + cos(flower->i / 31.0) * 400 - flower->width / 2,
p->events |= POLLIN; flower->y + sin(flower->i / 27.0) * 300 - flower->height / 2,
if (mask & WL_CONNECTION_WRITABLE) flower->width, flower->height);
p->events |= POLLOUT; flower->i++;
return 0; return TRUE;
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
struct wl_display *display; struct wl_display *display;
struct wl_surface *surface; int fd;
const int x = 512, y = 384, width = 200, height = 200; uint32_t name;
int fd, i, ret;
uint32_t name, mask;
cairo_surface_t *s; cairo_surface_t *s;
struct pollfd p[2];
struct timespec ts; struct timespec ts;
struct itimerspec its; GMainLoop *loop;
uint64_t expires; GSource *source;
struct flower flower;
fd = open(gem_device, O_RDWR); fd = open(gem_device, O_RDWR);
if (fd < 0) { if (fd < 0) {
@ -165,60 +170,36 @@ int main(int argc, char *argv[])
return -1; return -1;
} }
display = wl_display_create(socket_name, loop = g_main_loop_new(NULL, FALSE);
connection_update, &p[0]);
display = wl_display_create(socket_name);
if (display == NULL) { if (display == NULL) {
fprintf(stderr, "failed to create display: %m\n"); fprintf(stderr, "failed to create display: %m\n");
return -1; return -1;
} }
p[0].fd = wl_display_get_fd(display);
surface = wl_display_create_surface(display); source = wayland_source_new(display);
g_source_attach(source, NULL);
p[1].fd = timerfd_create(CLOCK_MONOTONIC, 0); flower.x = 512;
if (p[1].fd < 0) { flower.y = 384;
fprintf(stderr, "could not create timerfd\n: %m"); flower.width = 200;
return -1; flower.height = 200;
} flower.surface = wl_display_create_surface(display);
p[1].events = POLLIN;
clock_gettime(CLOCK_MONOTONIC, &ts); clock_gettime(CLOCK_MONOTONIC, &ts);
its.it_value = ts;
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = 20 * 1000000;
if (timerfd_settime(p[1].fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) {
fprintf(stderr, "could not set timerfd\n: %m");
return -1;
}
srandom(ts.tv_nsec); srandom(ts.tv_nsec);
flower.i = ts.tv_nsec;
s = draw_stuff(width, height); s = draw_stuff(flower.width, flower.height);
name = name_cairo_surface(fd, s); name = name_cairo_surface(fd, s);
wl_surface_attach(surface, name, width, height, wl_surface_attach(flower.surface, name, flower.width, flower.height,
cairo_image_surface_get_stride(s)); cairo_image_surface_get_stride(s));
i = ts.tv_nsec; g_timeout_add(20, move_flower, &flower);
while (ret = poll(p, 2, -1), ret >= 0) {
if (p[1].revents & POLLIN) { g_main_loop_run(loop);
read(p[1].fd, &expires, sizeof expires);
wl_surface_map(surface,
x + cos(i / 31.0) * 400 - width / 2,
y + sin(i / 27.0) * 300 - height / 2,
width, height);
i++;
continue;
}
mask = 0;
if (p[0].revents & POLLIN)
mask |= WL_CONNECTION_READABLE;
if (p[0].revents & POLLOUT)
mask |= WL_CONNECTION_WRITABLE;
if (mask)
wl_display_iterate(display, mask);
}
return 0; return 0;
} }

@ -98,15 +98,14 @@ draw_pointer(int width, int height)
} }
static int static int
connection_update(struct wl_connection *connection, connection_update(uint32_t mask, void *data)
uint32_t mask, void *data)
{ {
struct pollfd *p = data; struct pollfd *p = data;
p->events = 0; p->events = 0;
if (mask & WL_CONNECTION_READABLE) if (mask & WL_DISPLAY_READABLE)
p->events |= POLLIN; p->events |= POLLIN;
if (mask & WL_CONNECTION_WRITABLE) if (mask & WL_DISPLAY_WRITABLE)
p->events |= POLLOUT; p->events |= POLLOUT;
return 0; return 0;
@ -142,13 +141,12 @@ int main(int argc, char *argv[])
return -1; return -1;
} }
display = wl_display_create(socket_name, display = wl_display_create(socket_name);
connection_update, &p[0]);
if (display == NULL) { if (display == NULL) {
fprintf(stderr, "failed to create display: %m\n"); fprintf(stderr, "failed to create display: %m\n");
return -1; return -1;
} }
p[0].fd = wl_display_get_fd(display); p[0].fd = wl_display_get_fd(display, connection_update, &p[0]);
pointer.width = 16; pointer.width = 16;
pointer.height = 16; pointer.height = 16;
@ -168,9 +166,9 @@ int main(int argc, char *argv[])
poll(p, 1, -1); poll(p, 1, -1);
mask = 0; mask = 0;
if (p[0].revents & POLLIN) if (p[0].revents & POLLIN)
mask |= WL_CONNECTION_READABLE; mask |= WL_DISPLAY_READABLE;
if (p[0].revents & POLLOUT) if (p[0].revents & POLLOUT)
mask |= WL_CONNECTION_WRITABLE; mask |= WL_DISPLAY_WRITABLE;
wl_display_iterate(display, mask); wl_display_iterate(display, mask);
} }

@ -25,6 +25,10 @@ struct wl_display {
struct wl_connection *connection; struct wl_connection *connection;
int fd; int fd;
uint32_t id; uint32_t id;
uint32_t mask;
wl_display_update_func_t update;
void *update_data;
wl_display_event_func_t event_handler; wl_display_event_func_t event_handler;
void *event_handler_data; void *event_handler_data;
@ -34,9 +38,22 @@ struct wl_surface {
struct wl_proxy proxy; struct wl_proxy proxy;
}; };
static int
connection_update(struct wl_connection *connection,
uint32_t mask, void *data)
{
struct wl_display *display = data;
display->mask = mask;
if (display->update)
return display->update(display->mask,
display->update_data);
return 0;
}
struct wl_display * struct wl_display *
wl_display_create(const char *address, wl_display_create(const char *address)
wl_connection_update_func_t update, void *data)
{ {
struct wl_display *display; struct wl_display *display;
struct sockaddr_un name; struct sockaddr_un name;
@ -79,7 +96,8 @@ wl_display_create(const char *address,
display->proxy.id = id; display->proxy.id = id;
display->connection = wl_connection_create(display->fd, display->connection = wl_connection_create(display->fd,
update, data); connection_update,
display);
return display; return display;
} }
@ -93,8 +111,14 @@ wl_display_destroy(struct wl_display *display)
} }
int int
wl_display_get_fd(struct wl_display *display) wl_display_get_fd(struct wl_display *display,
wl_display_update_func_t update, void *data)
{ {
display->update = update;
display->update_data = data;
display->update(display->mask, display->update_data);
return display->fd; return display->fd;
} }

@ -1,15 +1,19 @@
#ifndef _WAYLAND_CLIENT_H #ifndef _WAYLAND_CLIENT_H
#define _WAYLAND_CLIENT_H #define _WAYLAND_CLIENT_H
#include "connection.h"
struct wl_display; struct wl_display;
struct wl_surface; struct wl_surface;
struct wl_display *wl_display_create(const char *address, #define WL_DISPLAY_READABLE 0x01
wl_connection_update_func_t update, void *data); #define WL_DISPLAY_WRITABLE 0x02
typedef int (*wl_display_update_func_t)(uint32_t mask, void *data);
struct wl_display *wl_display_create(const char *address);
void wl_display_destroy(struct wl_display *display); void wl_display_destroy(struct wl_display *display);
int wl_display_get_fd(struct wl_display *display); int wl_display_get_fd(struct wl_display *display,
wl_display_update_func_t update, void *data);
void wl_display_iterate(struct wl_display *display, uint32_t mask); void wl_display_iterate(struct wl_display *display, uint32_t mask);
typedef void (*wl_display_event_func_t)(struct wl_display *display, typedef void (*wl_display_event_func_t)(struct wl_display *display,

@ -0,0 +1,83 @@
#include <stdint.h>
#include <glib/giochannel.h>
#include "wayland-client.h"
#include "wayland-glib.h"
struct _WaylandSource {
GSource source;
GPollFD pfd;
uint32_t mask;
struct wl_display *display;
};
static gboolean
wayland_source_prepare(GSource *base, gint *timeout)
{
WaylandSource *source = (WaylandSource *) base;
*timeout = -1;
/* We have to add/remove the GPollFD if we want to update our
* poll event mask dynamically. Instead, let's just flush all
* write on idle instead, which is what this amounts to. */
while (source->mask & WL_DISPLAY_WRITABLE)
wl_display_iterate(source->display,
WL_DISPLAY_WRITABLE);
return FALSE;
}
static gboolean
wayland_source_check(GSource *base)
{
WaylandSource *source = (WaylandSource *) base;
return source->pfd.revents;
}
static gboolean
wayland_source_dispatch(GSource *base,
GSourceFunc callback,
gpointer data)
{
WaylandSource *source = (WaylandSource *) base;
wl_display_iterate(source->display,
WL_DISPLAY_READABLE | WL_DISPLAY_WRITABLE);
return TRUE;
}
static GSourceFuncs wayland_source_funcs = {
wayland_source_prepare,
wayland_source_check,
wayland_source_dispatch,
NULL
};
static int
wayland_source_update(uint32_t mask, void *data)
{
WaylandSource *source = data;
source->mask = mask;
return 0;
}
GSource *
wayland_source_new(struct wl_display *display)
{
WaylandSource *source;
source = (WaylandSource *) g_source_new(&wayland_source_funcs,
sizeof (WaylandSource));
source->display = display;
source->pfd.fd = wl_display_get_fd(display,
wayland_source_update, source);
source->pfd.events = G_IO_IN | G_IO_ERR;
g_source_add_poll(&source->source, &source->pfd);
return &source->source;
}

@ -0,0 +1,10 @@
#ifndef _WAYLAND_GLIB_H_
#define _WAYLAND_GLIB_H_
#include <glib/gmain.h>
typedef struct _WaylandSource WaylandSource;
GSource *wayland_source_new(struct wl_display *display);
#endif

@ -168,15 +168,14 @@ draw_window(struct window *window)
} }
static int static int
connection_update(struct wl_connection *connection, connection_update(uint32_t mask, void *data)
uint32_t mask, void *data)
{ {
struct pollfd *p = data; struct pollfd *p = data;
p->events = 0; p->events = 0;
if (mask & WL_CONNECTION_READABLE) if (mask & WL_DISPLAY_READABLE)
p->events |= POLLIN; p->events |= POLLIN;
if (mask & WL_CONNECTION_WRITABLE) if (mask & WL_DISPLAY_WRITABLE)
p->events |= POLLOUT; p->events |= POLLOUT;
return 0; return 0;
@ -302,13 +301,13 @@ int main(int argc, char *argv[])
return -1; return -1;
} }
display = wl_display_create(socket_name, display = wl_display_create(socket_name);
connection_update, &p[0]);
if (display == NULL) { if (display == NULL) {
fprintf(stderr, "failed to create display: %m\n"); fprintf(stderr, "failed to create display: %m\n");
return -1; return -1;
} }
p[0].fd = wl_display_get_fd(display); p[0].fd = wl_display_get_fd(display,
connection_update, &p[0]);
window.surface = wl_display_create_surface(display); window.surface = wl_display_create_surface(display);
window.x = 200; window.x = 200;
@ -333,9 +332,9 @@ int main(int argc, char *argv[])
window.width, window.height); window.width, window.height);
angle += 1; angle += 1;
if (p[0].revents & POLLIN) if (p[0].revents & POLLIN)
mask |= WL_CONNECTION_READABLE; mask |= WL_DISPLAY_READABLE;
if (p[0].revents & POLLOUT) if (p[0].revents & POLLOUT)
mask |= WL_CONNECTION_WRITABLE; mask |= WL_DISPLAY_WRITABLE;
if (mask) if (mask)
wl_display_iterate(display, mask); wl_display_iterate(display, mask);
if (window.need_redraw) { if (window.need_redraw) {

Loading…
Cancel
Save