libtoytoolkit_a_SOURCES = \
window.c \
window.h \
- wayland-glib.c \
- wayland-glib.h \
cairo-util.c \
cairo-util.h
#include <linux/input.h>
#include "wayland-client.h"
-#include "wayland-glib.h"
#include "window.h"
#include <desktop-shell-client-protocol.h>
#include <math.h>
#include <sys/time.h>
#include <cairo.h>
-#include <glib.h>
+#include <sys/epoll.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "wayland-client.h"
-#include "wayland-glib.h"
#include "window.h"
int refcount;
struct dnd *dnd;
struct wl_array types;
+ struct task io_task;
const char *drag_type;
uint32_t tag;
int x, y;
+ int fd;
};
struct item {
}
}
-static gboolean
-drop_io_func(GIOChannel *source, GIOCondition condition, gpointer data)
+static void
+drop_io_func(struct task *task, uint32_t events)
{
- struct dnd_offer *dnd_offer = data;
+ struct dnd_offer *dnd_offer =
+ container_of(task, struct dnd_offer, io_task);
struct dnd *dnd = dnd_offer->dnd;
struct dnd_flower_message dnd_flower_message;
- int fd;
unsigned int len;
struct item *item;
- fd = g_io_channel_unix_get_fd(source);
- len = read(fd, &dnd_flower_message, sizeof dnd_flower_message);
+ len = read(dnd_offer->fd,
+ &dnd_flower_message, sizeof dnd_flower_message);
fprintf(stderr, "read %d bytes\n", len);
- close(fd);
- g_source_remove(dnd_offer->tag);
-
- g_io_channel_unref(source);
+ close(dnd_offer->fd);
item = item_create(dnd->display,
dnd_offer->x - dnd_flower_message.x_offset - 26,
window_schedule_redraw(dnd->window);
dnd_offer_destroy(dnd_offer);
-
- return TRUE;
}
static void
drag_offer_drop(void *data, struct wl_drag_offer *offer)
{
struct dnd_offer *dnd_offer = data;
- GIOChannel *channel;
int p[2];
if (!dnd_offer->drag_type) {
wl_drag_offer_receive(offer, p[1]);
close(p[1]);
- channel = g_io_channel_unix_new(p[0]);
- dnd_offer->tag = g_io_add_watch(channel, G_IO_IN,
- drop_io_func, dnd_offer);
+ dnd_offer->io_task.run = drop_io_func;
+ dnd_offer->fd = p[0];
+ display_watch_fd(dnd_offer->dnd->display,
+ p[0], EPOLLIN, &dnd_offer->io_task);
}
static const struct wl_drag_offer_listener drag_offer_listener = {
#include <glib.h>
#include "wayland-client.h"
-#include "wayland-glib.h"
#include "window.h"
static void
#include "wayland-util.h"
#include "wayland-client.h"
-#include "wayland-glib.h"
#include "window.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "wayland-client.h"
-#include "wayland-glib.h"
#include "window.h"
#include "wayland-util.h"
#include "wayland-client.h"
-#include "wayland-glib.h"
#include "window.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "wayland-client.h"
-#include "wayland-glib.h"
#include "screenshooter-client-protocol.h"
/* The screenshooter is a good example of a custom object exposed by
#include <glib.h>
#include "wayland-client.h"
-#include "wayland-glib.h"
#include "window.h"
struct smoke {
#include <ctype.h>
#include <cairo.h>
#include <glib.h>
+#include <sys/epoll.h>
#include <X11/keysym.h>
#include "wayland-util.h"
#include "wayland-client.h"
-#include "wayland-glib.h"
#include "window.h"
struct window *window;
struct display *display;
union utf8_char *data;
+ struct task io_task;
char *tab_ruler;
struct attr *data_attr;
struct attr curr_attr;
int width, height, start, row, column;
int saved_row, saved_column;
int fd, master;
- GIOChannel *channel;
uint32_t modifiers;
char escape[MAX_ESCAPE+1];
int escape_length;
return terminal;
}
-static gboolean
-io_handler(GIOChannel *source,
- GIOCondition condition,
- gpointer data)
+static void
+io_handler(struct task *task, uint32_t events)
{
- struct terminal *terminal = data;
- gchar buffer[256];
- gsize bytes_read;
- GError *error = NULL;
-
- if(condition == G_IO_HUP)
- exit(0);
+ struct terminal *terminal =
+ container_of(task, struct terminal, io_task);
+ char buffer[256];
+ int len;
- g_io_channel_read_chars(source, buffer, sizeof buffer,
- &bytes_read, &error);
+ if (events & EPOLLHUP)
+ exit(0);
- terminal_data(terminal, buffer, bytes_read);
+ len = read(terminal->master, buffer, sizeof buffer);
+ if (len < 0)
+ exit(0);
- return TRUE;
+ terminal_data(terminal, buffer, len);
}
static int
}
terminal->master = master;
- terminal->channel = g_io_channel_unix_new(master);
fcntl(master, F_SETFL, O_NONBLOCK);
- g_io_add_watch(terminal->channel, G_IO_IN, io_handler, terminal);
- g_io_add_watch(terminal->channel, G_IO_HUP, io_handler, terminal);
+ terminal->io_task.run = io_handler;
+ display_watch_fd(terminal->display, terminal->master,
+ EPOLLIN | EPOLLHUP, &terminal->io_task);
window_set_fullscreen(terminal->window, terminal->fullscreen);
if (!terminal->fullscreen)
+++ /dev/null
-/*
- * Copyright © 2008 Kristian Høgsberg
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. The copyright holders make no representations
- * about the suitability of this software for any purpose. It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
-#include <stdint.h>
-#include <glib/giochannel.h>
-#include "wayland-client.h"
-#include "wayland-glib.h"
-
-typedef struct _WlSource {
- GSource source;
- GPollFD pfd;
- uint32_t mask;
- struct wl_display *display;
-} WlSource;
-
-static gboolean
-wl_glib_source_prepare(GSource *base, gint *timeout)
-{
- WlSource *source = (WlSource *) 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
-wl_glib_source_check(GSource *base)
-{
- WlSource *source = (WlSource *) base;
-
- return source->pfd.revents;
-}
-
-static gboolean
-wl_glib_source_dispatch(GSource *base,
- GSourceFunc callback,
- gpointer data)
-{
- WlSource *source = (WlSource *) base;
-
- wl_display_iterate(source->display,
- WL_DISPLAY_READABLE);
-
- return TRUE;
-}
-
-static GSourceFuncs wl_glib_source_funcs = {
- wl_glib_source_prepare,
- wl_glib_source_check,
- wl_glib_source_dispatch,
- NULL
-};
-
-static int
-wl_glib_source_update(uint32_t mask, void *data)
-{
- WlSource *source = data;
-
- source->mask = mask;
-
- return 0;
-}
-
-GSource *
-wl_glib_source_new(struct wl_display *display)
-{
- WlSource *source;
-
- source = (WlSource *) g_source_new(&wl_glib_source_funcs,
- sizeof (WlSource));
- source->display = display;
- source->pfd.fd = wl_display_get_fd(display,
- wl_glib_source_update, source);
- source->pfd.events = G_IO_IN | G_IO_ERR;
- g_source_add_poll(&source->source, &source->pfd);
-
- return &source->source;
-}
+++ /dev/null
-/*
- * Copyright © 2008 Kristian Høgsberg
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. The copyright holders make no representations
- * about the suitability of this software for any purpose. It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
-#ifndef _WAYLAND_GLIB_H_
-#define _WAYLAND_GLIB_H_
-
-#include <glib/gmain.h>
-#include <wayland-client.h>
-
-GSource *wl_glib_source_new(struct wl_display *display);
-
-
-#endif
#include <time.h>
#include <cairo.h>
#include <glib.h>
-#include <glib-object.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <sys/mman.h>
+#include <sys/epoll.h>
#include <wayland-egl.h>
#include <linux/input.h>
#include "wayland-util.h"
#include "wayland-client.h"
-#include "wayland-glib.h"
#include "cairo-util.h"
#include "window.h"
EGLConfig premultiplied_argb_config;
EGLContext ctx;
cairo_device_t *device;
- int fd;
- GMainLoop *loop;
- GSource *source;
+
+ int display_fd;
+ uint32_t mask;
+ struct task display_task;
+
+ int epoll_fd;
+ struct wl_list deferred_list;
+
struct wl_list window_list;
struct wl_list input_list;
char *device_name;
int x, y;
int resize_edges;
int redraw_scheduled;
+ struct task redraw_task;
int minimum_width, minimum_height;
int margin;
int type;
}
}
-static gboolean
-idle_redraw(void *data)
+static void
+idle_redraw(struct task *task, uint32_t events)
{
- struct window *window = data;
+ struct window *window =
+ container_of(task, struct window, redraw_task);
window->redraw_handler(window, window->user_data);
-
window->redraw_scheduled = 0;
-
- return FALSE;
}
void
window_schedule_redraw(struct window *window)
{
if (!window->redraw_scheduled) {
- g_idle_add(idle_redraw, window);
+ window->redraw_task.run = idle_redraw;
+ display_defer(window->display, &window->redraw_task);
window->redraw_scheduled = 1;
}
}
return 0;
}
+static int
+event_mask_update(uint32_t mask, void *data)
+{
+ struct display *d = data;
+
+ d->mask = mask;
+
+ return 0;
+}
+
+static void
+handle_display_data(struct task *task, uint32_t events)
+{
+ struct display *display =
+ container_of(task, struct display, display_task);
+
+ wl_display_iterate(display->display, display->mask);
+}
+
struct display *
display_create(int *argc, char **argv[], const GOptionEntry *option_entries)
{
return NULL;
}
+ d->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
+ d->display_fd = wl_display_get_fd(d->display, event_mask_update, d);
+ d->display_task.run = handle_display_data;
+ display_watch_fd(d, d->display_fd, EPOLLIN, &d->display_task);
+
+ wl_list_init(&d->deferred_list);
wl_list_init(&d->input_list);
/* Set up listener so we'll catch all events. */
display_render_frame(d);
- d->loop = g_main_loop_new(NULL, FALSE);
- d->source = wl_glib_source_new(d->display);
- g_source_attach(d->source, NULL);
-
wl_list_init(&d->window_list);
init_xkb(d);
}
void
-display_run(struct display *d)
+display_defer(struct display *display, struct task *task)
+{
+ wl_list_insert(&display->deferred_list, &task->link);
+}
+
+void
+display_watch_fd(struct display *display,
+ int fd, uint32_t events, struct task *task)
{
- g_main_loop_run(d->loop);
+ struct epoll_event ep;
+
+ ep.events = events;
+ ep.data.ptr = task;
+ epoll_ctl(display->epoll_fd, EPOLL_CTL_ADD, fd, &ep);
+}
+
+void
+display_run(struct display *display)
+{
+ struct task *task;
+ struct epoll_event ep[16];
+ int i, count;
+
+ while (1) {
+ while (display->mask & WL_DISPLAY_WRITABLE)
+ wl_display_iterate(display->display,
+ WL_DISPLAY_WRITABLE);
+
+ count = epoll_wait(display->epoll_fd,
+ ep, ARRAY_LENGTH(ep), -1);
+ for (i = 0; i < count; i++) {
+ task = ep[i].data.ptr;
+ task->run(task, ep[i].events);
+ }
+
+ while (!wl_list_empty(&display->deferred_list)) {
+ task = container_of(display->deferred_list.next,
+ struct task, link);
+ wl_list_remove(&task->link);
+ task->run(task, 0);
+ }
+ }
}
struct window;
+struct task {
+ void (*run)(struct task *task, uint32_t events);
+ struct wl_list link;
+};
+
struct rectangle {
int32_t x;
int32_t y;
display_flush_cairo_device(struct display *display);
void
+display_defer(struct display *display, struct task *task);
+
+void
+display_watch_fd(struct display *display,
+ int fd, uint32_t events, struct task *task);
+
+void
display_run(struct display *d);
enum pointer_type {