Don't track globals in the client lib, just send out events

Users of the client library must install an global handler to get access
to globals.
dev
Kristian Høgsberg 15 years ago
parent ccb75867ac
commit 4fe1a3ed3a
  1. 3
      TODO
  2. 65
      clients/screenshot.c
  3. 31
      clients/window.c
  4. 45
      scanner.c
  5. 149
      wayland-client.c
  6. 49
      wayland-client.h

@ -3,9 +3,6 @@ Core wayland protocol
- generate pointer_focus on raise/lower, move windows, all kinds of
changes in surface stacking.
- don't store globals on client side, require global_handler like
everything else.
- glyph cache
- dnd, figure out large object transfer: through wayland protocol or

@ -36,45 +36,36 @@
static const char socket_name[] = "\0wayland";
struct screenshooter {
uint32_t id;
struct wl_display *display;
};
static struct screenshooter *
screenshooter_create(struct wl_display *display)
{
struct screenshooter *screenshooter;
uint32_t id;
#define SCREENSHOOTER_SHOOT 0
id = wl_display_get_object_id(display, "screenshooter", 1);
if (id == 0) {
fprintf(stderr, "server doesn't support screenshooter interface\n");
return NULL;
}
struct screenshooter;
screenshooter = malloc(sizeof screenshooter);
if (screenshooter == NULL)
return NULL;
static const struct wl_message screenshooter_requests[] = {
{ "shoot", "" },
};
screenshooter->id = id;
screenshooter->display = display;
static const struct wl_interface screenshooter_interface = {
"screenshooter", 1,
ARRAY_LENGTH(screenshooter_requests), screenshooter_requests,
0, NULL
};
return screenshooter;
static inline void
screenshooter_shoot(struct screenshooter *shooter)
{
wl_proxy_marshal((struct wl_proxy *) shooter, SCREENSHOOTER_SHOOT);
}
#define SCREENSHOOTER_SHOOT 0
static void
screenshooter_shoot(struct screenshooter *screenshooter)
handle_global(struct wl_display *display, uint32_t id,
const char *interface, uint32_t version, void *data)
{
uint32_t request[2];
request[0] = screenshooter->id;
request[1] = SCREENSHOOTER_SHOOT | ((sizeof request) << 16);
struct screenshooter **screenshooter = data;
wl_display_write(screenshooter->display,
request, sizeof request);
if (strcmp(interface, "screenshooter") == 0)
*screenshooter = (struct screenshooter *)
wl_proxy_create_for_id(display,
&screenshooter_interface, id);
}
int main(int argc, char *argv[])
@ -82,7 +73,7 @@ int main(int argc, char *argv[])
struct wl_display *display;
GMainLoop *loop;
GSource *source;
struct screenshooter *s;
struct screenshooter *screenshooter;
display = wl_display_create(socket_name, sizeof socket_name);
if (display == NULL) {
@ -90,16 +81,20 @@ int main(int argc, char *argv[])
return -1;
}
screenshooter = NULL;
wl_display_add_global_listener(display, handle_global, &screenshooter);
wl_display_iterate(display, WL_DISPLAY_READABLE);
if (screenshooter == NULL) {
fprintf(stderr, "display doesn't support screenshooter\n");
return -1;
}
loop = g_main_loop_new(NULL, FALSE);
source = wl_glib_source_new(display);
g_source_attach(source, NULL);
s = screenshooter_create(display);
if (s == NULL)
exit(-1);
screenshooter_shoot(screenshooter);
screenshooter_shoot(s);
g_idle_add((GSourceFunc) g_main_loop_quit, loop);
g_main_loop_run(loop);

@ -766,7 +766,7 @@ static const struct wl_output_listener output_listener = {
};
static void
display_add_input(struct display *d, struct wl_object *object)
display_add_input(struct display *d, uint32_t id)
{
struct input *input;
@ -776,7 +776,7 @@ display_add_input(struct display *d, struct wl_object *object)
memset(input, 0, sizeof *input);
input->display = d;
input->input_device = (struct wl_input_device *) object;
input->input_device = wl_input_device_create(d->display, id);
input->pointer_focus = NULL;
input->keyboard_focus = NULL;
wl_list_insert(d->input_list.prev, &input->link);
@ -786,24 +786,25 @@ display_add_input(struct display *d, struct wl_object *object)
}
static void
display_handle_global(struct wl_display *display,
struct wl_object *object, void *data)
display_handle_global(struct wl_display *display, uint32_t id,
const char *interface, uint32_t version, void *data)
{
struct display *d = data;
if (wl_object_implements(object, "compositor", 1)) {
d->compositor = (struct wl_compositor *) object;
wl_compositor_add_listener(d->compositor, &compositor_listener, d);
} else if (wl_object_implements(object, "output", 1)) {
d->output = (struct wl_output *) object;
if (strcmp(interface, "compositor") == 0) {
d->compositor = wl_compositor_create(display, id);
wl_compositor_add_listener(d->compositor,
&compositor_listener, d);
} else if (strcmp(interface, "output") == 0) {
d->output = wl_output_create(display, id);
wl_output_add_listener(d->output, &output_listener, d);
} else if (wl_object_implements(object, "input_device", 1)) {
display_add_input(d, object);
} else if (wl_object_implements(object, "shell", 1)) {
d->shell = (struct wl_shell *) object;
} else if (strcmp(interface, "input_device") == 0) {
display_add_input(d, id);
} else if (strcmp(interface, "shell") == 0) {
d->shell = wl_shell_create(display, id);
wl_shell_add_listener(d->shell, &shell_listener, d);
} else if (wl_object_implements(object, "drm", 1)) {
d->drm = (struct wl_drm *) object;
} else if (strcmp(interface, "drm") == 0) {
d->drm = wl_drm_create(display, id);
wl_drm_add_listener(d->drm, &drm_listener, d);
}
}

@ -260,6 +260,19 @@ emit_stubs(struct wl_list *message_list, struct interface *interface)
struct message *m;
struct arg *a, *ret;
/* We provide a hand written constructor for the display object */
if (strcmp(interface->name, "display") != 0)
printf("static inline struct wl_%s *\n"
"wl_%s_create(struct wl_display *display, uint32_t id)\n"
"{\n"
"\treturn (struct wl_%s *)\n"
"\t\twl_proxy_create_for_id(display, &wl_%s_interface, id);\n"
"}\n\n",
interface->name,
interface->name,
interface->name,
interface->name);
if (wl_list_empty(message_list))
return;
@ -395,6 +408,24 @@ emit_structs(struct wl_list *message_list, struct interface *interface)
}
}
static const char client_prototypes[] =
"struct wl_proxy;\n\n"
"extern void\n"
"wl_proxy_marshal(struct wl_proxy *p, uint32_t opcode, ...);\n"
"extern struct wl_proxy *\n"
"wl_proxy_create(struct wl_proxy *factory,\n"
"\t\tconst struct wl_interface *interface);\n"
"extern struct wl_proxy *\n"
"wl_proxy_create_for_id(struct wl_display *display,\n"
"\t\t const struct wl_interface *interface, uint32_t id);\n"
"extern int\n"
"wl_proxy_add_listener(struct wl_proxy *proxy,\n"
"\t\t void (**implementation)(void), void *data);\n\n";
static void
emit_header(struct protocol *protocol, int server)
{
@ -417,19 +448,7 @@ emit_header(struct protocol *protocol, int server)
printf("\n");
if (!server)
printf("struct wl_proxy;\n\n"
"extern void\n"
"wl_proxy_marshal(struct wl_proxy *p, "
"uint32_t opcode, ...);\n"
"extern struct wl_proxy *\n"
"wl_proxy_create(struct wl_proxy *factory,\n"
"\t\tconst struct wl_interface *interface);\n"
"extern int\n"
"wl_proxy_add_listener(struct wl_proxy *proxy,\n"
"\t\t void (**implementation)(void), "
"void *data);\n\n");
printf(client_prototypes);
wl_list_for_each(i, &protocol->interface_list, link) {
printf("extern const struct wl_interface "

@ -40,14 +40,6 @@
static const char socket_name[] = "\0wayland";
struct wl_global {
uint32_t id;
char *interface;
uint32_t version;
struct wl_proxy *proxy;
struct wl_list link;
};
struct wl_global_listener {
wl_display_global_func_t handler;
void *data;
@ -67,18 +59,6 @@ struct wl_proxy {
void *user_data;
};
struct wl_compositor {
struct wl_proxy proxy;
};
struct wl_surface {
struct wl_proxy proxy;
};
struct wl_visual {
struct wl_proxy proxy;
};
struct wl_display {
struct wl_proxy proxy;
struct wl_connection *connection;
@ -86,7 +66,6 @@ struct wl_display {
uint32_t id, id_count, next_range;
uint32_t mask;
struct wl_hash_table *objects;
struct wl_list global_list;
struct wl_listener listener;
struct wl_list global_listener_list;
@ -99,8 +78,6 @@ struct wl_display {
wl_display_global_func_t global_handler;
void *global_handler_data;
struct wl_compositor *compositor;
};
static int
@ -117,20 +94,11 @@ connection_update(struct wl_connection *connection,
return 0;
}
WL_EXPORT int
wl_object_implements(struct wl_object *object,
const char *interface, int version)
{
return strcmp(object->interface->name, interface) == 0 &&
object->interface->version >= version;
}
WL_EXPORT struct wl_global_listener *
wl_display_add_global_listener(struct wl_display *display,
wl_display_global_func_t handler, void *data)
{
struct wl_global_listener *listener;
struct wl_global *global;
listener = malloc(sizeof *listener);
if (listener == NULL)
@ -140,12 +108,6 @@ wl_display_add_global_listener(struct wl_display *display,
listener->data = data;
wl_list_insert(display->global_listener_list.prev, &listener->link);
/* FIXME: Need a destructor for void *data? */
wl_list_for_each(global, &display->global_list, link)
if (global->proxy != NULL)
(*handler)(display, &global->proxy->base, data);
return listener;
}
@ -157,50 +119,36 @@ wl_display_remove_global_listener(struct wl_display *display,
free(listener);
}
static struct wl_proxy *
wl_proxy_create_for_global(struct wl_display *display,
struct wl_global *global,
const struct wl_interface *interface)
WL_EXPORT struct wl_proxy *
wl_proxy_create_for_id(struct wl_display *display,
const struct wl_interface *interface, uint32_t id)
{
struct wl_proxy *proxy;
struct wl_global_listener *listener;
proxy = malloc(sizeof *proxy);
if (proxy == NULL)
return NULL;
proxy->base.interface = interface;
proxy->base.id = global->id;
proxy->base.id = id;
proxy->display = display;
global->proxy = proxy;
wl_list_init(&proxy->listener_list);
wl_hash_table_insert(display->objects, proxy->base.id, proxy);
wl_list_for_each(listener, &display->global_listener_list, link)
(*listener->handler)(display, &proxy->base, listener->data);
return proxy;
}
WL_EXPORT struct wl_proxy *
wl_proxy_create(struct wl_proxy *factory, const struct wl_interface *interface)
wl_proxy_create(struct wl_proxy *factory,
const struct wl_interface *interface)
{
struct wl_proxy *proxy;
proxy = malloc(sizeof *proxy);
if (proxy == NULL)
return NULL;
proxy->base.interface = interface;
proxy->base.id = wl_display_allocate_id(factory->display);
proxy->display = factory->display;
wl_hash_table_insert(factory->display->objects, proxy->base.id, proxy);
return proxy;
return wl_proxy_create_for_id(factory->display, interface,
wl_display_allocate_id(factory->display));
}
WL_EXPORT int
wl_proxy_add_listener(struct wl_proxy *proxy, void (**implementation)(void), void *data)
wl_proxy_add_listener(struct wl_proxy *proxy,
void (**implementation)(void), void *data)
{
struct wl_listener *listener;
@ -228,13 +176,12 @@ wl_proxy_marshal(struct wl_proxy *proxy, uint32_t opcode, ...)
}
static void
add_visual(struct wl_display *display, struct wl_global *global)
add_visual(struct wl_display *display, uint32_t id)
{
struct wl_visual *visual;
visual = (struct wl_visual *)
wl_proxy_create_for_global(display, global,
&wl_visual_interface);
wl_proxy_create_for_id(display, &wl_visual_interface, id);
if (display->argb_visual == NULL)
display->argb_visual = visual;
else if (display->premultiplied_argb_visual == NULL)
@ -291,38 +238,17 @@ display_handle_global(void *data,
struct wl_display *display,
uint32_t id, const char *interface, uint32_t version)
{
struct wl_global *global;
global = malloc(sizeof *global);
if (global == NULL)
return;
global->id = id;
global->interface = strdup(interface);
global->version = version;
wl_list_insert(display->global_list.prev, &global->link);
struct wl_global_listener *listener;
if (strcmp(global->interface, "display") == 0)
if (strcmp(interface, "display") == 0)
wl_hash_table_insert(display->objects,
id, &display->proxy.base);
else if (strcmp(global->interface, "compositor") == 0)
display->compositor = (struct wl_compositor *)
wl_proxy_create_for_global(display, global,
&wl_compositor_interface);
else if (strcmp(global->interface, "visual") == 0)
add_visual(display, global);
else if (strcmp(global->interface, "output") == 0)
wl_proxy_create_for_global(display, global,
&wl_output_interface);
else if (strcmp(global->interface, "input_device") == 0)
wl_proxy_create_for_global(display, global,
&wl_input_device_interface);
else if (strcmp(global->interface, "shell") == 0)
wl_proxy_create_for_global(display, global,
&wl_shell_interface);
else if (strcmp(global->interface, "drm") == 0)
wl_proxy_create_for_global(display, global,
&wl_drm_interface);
else if (strcmp(interface, "visual") == 0)
add_visual(display, id);
wl_list_for_each(listener, &display->global_listener_list, link)
(*listener->handler)(display,
id, interface, version, listener->data);
}
static void
@ -370,7 +296,6 @@ wl_display_create(const char *name, size_t name_size)
}
display->objects = wl_hash_table_create();
wl_list_init(&display->global_list);
wl_list_init(&display->global_listener_list);
display->proxy.base.interface = &wl_display_interface;
@ -396,20 +321,6 @@ wl_display_destroy(struct wl_display *display)
free(display);
}
WL_EXPORT uint32_t
wl_display_get_object_id(struct wl_display *display,
const char *interface, uint32_t version)
{
struct wl_global *global;
wl_list_for_each(global, &display->global_list, link)
if (strcmp(global->interface, interface) == 0 &&
global->version >= version)
return global->id;
return 0;
}
WL_EXPORT int
wl_display_get_fd(struct wl_display *display,
wl_display_update_func_t update, void *data)
@ -498,26 +409,18 @@ wl_display_allocate_id(struct wl_display *display)
return display->id++;
}
WL_EXPORT void
wl_display_write(struct wl_display *display, const void *data, size_t count)
{
wl_connection_write(display->connection, data, count);
}
WL_EXPORT struct wl_compositor *
wl_display_get_compositor(struct wl_display *display)
{
return display->compositor;
}
WL_EXPORT void
wl_surface_set_user_data(struct wl_surface *surface, void *user_data)
{
surface->proxy.user_data = user_data;
struct wl_proxy *proxy = (struct wl_proxy *) surface;
proxy->user_data = user_data;
}
WL_EXPORT void *
wl_surface_get_user_data(struct wl_surface *surface)
{
return surface->proxy.user_data;
struct wl_proxy *proxy = (struct wl_proxy *) surface;
return proxy->user_data;
}

@ -33,22 +33,20 @@ extern "C" {
#define WL_DISPLAY_READABLE 0x01
#define WL_DISPLAY_WRITABLE 0x02
int
wl_object_implements(struct wl_object *object,
const char *interface, int version);
typedef int (*wl_display_update_func_t)(uint32_t mask, void *data);
struct wl_display *wl_display_create(const char *name, size_t name_size);
void wl_display_destroy(struct wl_display *display);
int wl_display_get_fd(struct wl_display *display,
wl_display_update_func_t update, void *data);
uint32_t wl_display_allocate_id(struct wl_display *display);
void wl_display_iterate(struct wl_display *display, uint32_t mask);
struct wl_global_listener;
typedef void (*wl_display_global_func_t)(struct wl_display *display,
struct wl_object *object,
uint32_t id,
const char *interface,
uint32_t version,
void *data);
void
wl_display_remove_global_listener(struct wl_display *display,
@ -57,8 +55,6 @@ wl_display_remove_global_listener(struct wl_display *display,
struct wl_global_listener *
wl_display_add_global_listener(struct wl_display *display,
wl_display_global_func_t handler, void *data);
struct wl_compositor *
wl_display_get_compositor(struct wl_display *display);
struct wl_visual *
wl_display_get_argb_visual(struct wl_display *display);
struct wl_visual *
@ -66,46 +62,9 @@ wl_display_get_premultiplied_argb_visual(struct wl_display *display);
struct wl_visual *
wl_display_get_rgb_visual(struct wl_display *display);
int
wl_compositor_add_listener(struct wl_compositor *compostior,
const struct wl_compositor_listener *listener,
void *data);
int
wl_shell_add_listener(struct wl_shell *shell,
const struct wl_shell_listener *listener,
void *data);
int
wl_drm_add_listener(struct wl_drm *drm,
const struct wl_drm_listener *listener,
void *data);
void wl_surface_set_user_data(struct wl_surface *surface, void *user_data);
void *wl_surface_get_user_data(struct wl_surface *surface);
int
wl_output_add_listener(struct wl_output *output,
const struct wl_output_listener *listener,
void *data);
int
wl_input_device_add_listener(struct wl_input_device *input_device,
const struct wl_input_device_listener *listener,
void *data);
/* These entry points are for client side implementation of custom
* objects. */
uint32_t wl_display_get_object_id(struct wl_display *display,
const char *interface, uint32_t version);
uint32_t wl_display_allocate_id(struct wl_display *display);
void wl_display_write(struct wl_display *display,
const void *data,
size_t count);
void wl_display_advertise_global(struct wl_display *display,
struct wl_object *object);
#ifdef __cplusplus
}
#endif

Loading…
Cancel
Save