window: Stop using glib mainloop in toy toolkit
This commit is contained in:
parent
1e164b9afd
commit
3a69627f43
@ -34,8 +34,6 @@ AM_CPPFLAGS = \
|
||||
libtoytoolkit_a_SOURCES = \
|
||||
window.c \
|
||||
window.h \
|
||||
wayland-glib.c \
|
||||
wayland-glib.h \
|
||||
cairo-util.c \
|
||||
cairo-util.h
|
||||
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include <linux/input.h>
|
||||
|
||||
#include "wayland-client.h"
|
||||
#include "wayland-glib.h"
|
||||
#include "window.h"
|
||||
|
||||
#include <desktop-shell-client-protocol.h>
|
||||
|
@ -29,11 +29,10 @@
|
||||
#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"
|
||||
|
||||
@ -60,9 +59,11 @@ struct dnd_offer {
|
||||
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 {
|
||||
@ -421,24 +422,21 @@ drag_offer_motion(void *data,
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
@ -449,15 +447,12 @@ drop_io_func(GIOChannel *source, GIOCondition condition, gpointer data)
|
||||
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) {
|
||||
@ -473,9 +468,10 @@ drag_offer_drop(void *data, struct wl_drag_offer *offer)
|
||||
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 = {
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include <glib.h>
|
||||
|
||||
#include "wayland-client.h"
|
||||
#include "wayland-glib.h"
|
||||
#include "window.h"
|
||||
|
||||
static void
|
||||
|
@ -38,7 +38,6 @@
|
||||
|
||||
#include "wayland-util.h"
|
||||
#include "wayland-client.h"
|
||||
#include "wayland-glib.h"
|
||||
|
||||
#include "window.h"
|
||||
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
#include "wayland-client.h"
|
||||
#include "wayland-glib.h"
|
||||
|
||||
#include "window.h"
|
||||
|
||||
|
@ -29,7 +29,6 @@
|
||||
|
||||
#include "wayland-util.h"
|
||||
#include "wayland-client.h"
|
||||
#include "wayland-glib.h"
|
||||
|
||||
#include "window.h"
|
||||
|
||||
|
@ -31,7 +31,6 @@
|
||||
#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
|
||||
|
@ -33,7 +33,6 @@
|
||||
#include <glib.h>
|
||||
|
||||
#include "wayland-client.h"
|
||||
#include "wayland-glib.h"
|
||||
#include "window.h"
|
||||
|
||||
struct smoke {
|
||||
|
@ -32,12 +32,12 @@
|
||||
#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"
|
||||
|
||||
@ -359,6 +359,7 @@ struct terminal {
|
||||
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;
|
||||
@ -375,7 +376,6 @@ struct terminal {
|
||||
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;
|
||||
@ -2326,25 +2326,22 @@ terminal_create(struct display *display, int fullscreen)
|
||||
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;
|
||||
struct terminal *terminal =
|
||||
container_of(task, struct terminal, io_task);
|
||||
char buffer[256];
|
||||
int len;
|
||||
|
||||
if(condition == G_IO_HUP)
|
||||
exit(0);
|
||||
if (events & EPOLLHUP)
|
||||
exit(0);
|
||||
|
||||
g_io_channel_read_chars(source, buffer, sizeof buffer,
|
||||
&bytes_read, &error);
|
||||
len = read(terminal->master, buffer, sizeof buffer);
|
||||
if (len < 0)
|
||||
exit(0);
|
||||
|
||||
terminal_data(terminal, buffer, bytes_read);
|
||||
|
||||
return TRUE;
|
||||
terminal_data(terminal, buffer, len);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -2367,10 +2364,10 @@ terminal_run(struct terminal *terminal, const char *path)
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -1,105 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* 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
|
100
clients/window.c
100
clients/window.c
@ -32,9 +32,9 @@
|
||||
#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>
|
||||
|
||||
@ -51,7 +51,6 @@
|
||||
#include <linux/input.h>
|
||||
#include "wayland-util.h"
|
||||
#include "wayland-client.h"
|
||||
#include "wayland-glib.h"
|
||||
#include "cairo-util.h"
|
||||
|
||||
#include "window.h"
|
||||
@ -68,9 +67,14 @@ struct display {
|
||||
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;
|
||||
@ -99,6 +103,7 @@ struct window {
|
||||
int x, y;
|
||||
int resize_edges;
|
||||
int redraw_scheduled;
|
||||
struct task redraw_task;
|
||||
int minimum_width, minimum_height;
|
||||
int margin;
|
||||
int type;
|
||||
@ -1374,23 +1379,22 @@ window_set_child_size(struct window *window, int32_t width, int32_t height)
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -1927,6 +1931,25 @@ init_egl(struct display *d)
|
||||
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)
|
||||
{
|
||||
@ -1967,6 +1990,12 @@ 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. */
|
||||
@ -1987,10 +2016,6 @@ display_create(int *argc, char **argv[], const GOptionEntry *option_entries)
|
||||
|
||||
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);
|
||||
@ -2060,7 +2085,46 @@ display_release(struct display *display)
|
||||
}
|
||||
|
||||
void
|
||||
display_run(struct display *d)
|
||||
display_defer(struct display *display, struct task *task)
|
||||
{
|
||||
g_main_loop_run(d->loop);
|
||||
wl_list_insert(&display->deferred_list, &task->link);
|
||||
}
|
||||
|
||||
void
|
||||
display_watch_fd(struct display *display,
|
||||
int fd, uint32_t events, struct task *task)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,11 @@
|
||||
|
||||
struct window;
|
||||
|
||||
struct task {
|
||||
void (*run)(struct task *task, uint32_t events);
|
||||
struct wl_list link;
|
||||
};
|
||||
|
||||
struct rectangle {
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
@ -98,6 +103,13 @@ display_add_drag_listener(struct display *display,
|
||||
void
|
||||
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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user