diff options
author | Kristian Høgsberg <krh@bitplanet.net> | 2013-05-16 09:22:03 -0400 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2013-05-16 09:22:03 -0400 |
commit | 5f01f72d9a23217e87134c085ef84490d5154f88 (patch) | |
tree | 4af08c1f841bc536d6927302d535c31a70234eab |
Initial commit
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | NOTES | 14 | ||||
-rw-r--r-- | configure.ac | 33 | ||||
-rw-r--r-- | src/Makefile.am | 13 | ||||
-rw-r--r-- | src/Xlib-wayland.h | 616 | ||||
-rw-r--r-- | src/display.c | 128 | ||||
-rw-r--r-- | src/event.c | 14 | ||||
-rw-r--r-- | src/pixmap.c | 147 | ||||
-rw-r--r-- | src/private.h | 77 | ||||
-rw-r--r-- | src/resource.c | 67 | ||||
-rw-r--r-- | src/window.c | 197 | ||||
-rw-r--r-- | src/xlib-wayland-test.c | 28 |
12 files changed, 1337 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..3a7ce7e --- /dev/null +++ b/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS = src + +ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} @@ -0,0 +1,14 @@ + + - GLX and EGL? How? + + - GTK+ does some weird xlib stuff to acheive multiple async requests + or something... + + - Something like this: + + struct csx_wm { + void (*map_notify)(struct csx_window *window); + }; + + but we'll also need full substructure redirect since apps can do + that on their own windows. diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..dfef254 --- /dev/null +++ b/configure.ac @@ -0,0 +1,33 @@ +AC_PREREQ([2.64]) + +AC_INIT([libX11-wayland], + [0.1], + [no bugs], + [libX11-wayland], + [http://wayland.freedesktop.org/]) + +AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_MACRO_DIR([m4]) + +AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz]) + +AM_SILENT_RULES([yes]) + +# Check for programs +AC_PROG_CC + +# Initialize libtool +LT_PREREQ([2.2]) +LT_INIT + +PKG_PROG_PKG_CONFIG() +PKG_CHECK_MODULES(CSX, [wayland-client pixman-1]) + +if test "x$GCC" = "xyes"; then + GCC_CFLAGS="-Wall -Wextra -Wno-unused-parameter -g -Wstrict-prototypes -Wmissing-prototypes -fvisibility=hidden" +fi +AC_SUBST(GCC_CFLAGS) + +AC_CONFIG_FILES([Makefile + src/Makefile]) +AC_OUTPUT diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..100ed0c --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,13 @@ +lib_LTLIBRARIES = libX11-wayland.la + +include_HEADERS = Xlib-wayland.h + +libX11_wayland_la_LIBADD = $(CSX_LIBS) +libX11_wayland_la_CPPFLAGS = $(CSX_CFLAGS) +libX11_wayland_la_SOURCES = \ + display.c resource.c window.c pixmap.c event.c private.h + +noinst_PROGRAMS = xlib-wayland-test + +xlib_wayland_test_SOURCES = xlib-wayland-test.c +xlib_wayland_test_LDADD = libX11-wayland.la diff --git a/src/Xlib-wayland.h b/src/Xlib-wayland.h new file mode 100644 index 0000000..3b87373 --- /dev/null +++ b/src/Xlib-wayland.h @@ -0,0 +1,616 @@ +#include <stdint.h> + +#define Bool int +#define Status int +#define True 1 +#define False 0 + +typedef uint32_t XID; +typedef uint32_t Mask; +typedef uint32_t Atom; +typedef uint32_t VisualID; +typedef uint32_t Time; + +typedef XID Window; +typedef XID Drawable; +typedef XID Font; +typedef XID Pixmap; +typedef XID Cursor; +typedef XID Colormap; +typedef XID GContext; +typedef XID KeySym; + +typedef unsigned char KeyCode; +typedef char *XPointer; + +#define None 0L /* universal null resource or null atom */ + +/* Window classes used by CreateWindow */ +/* Note that CopyFromParent is already defined as 0 above */ + +#define InputOutput 1 +#define InputOnly 2 + +/* Window attributes for CreateWindow and ChangeWindowAttributes */ + +#define CWBackPixmap (1L<<0) +#define CWBackPixel (1L<<1) +#define CWBorderPixmap (1L<<2) +#define CWBorderPixel (1L<<3) +#define CWBitGravity (1L<<4) +#define CWWinGravity (1L<<5) +#define CWBackingStore (1L<<6) +#define CWBackingPlanes (1L<<7) +#define CWBackingPixel (1L<<8) +#define CWOverrideRedirect (1L<<9) +#define CWSaveUnder (1L<<10) +#define CWEventMask (1L<<11) +#define CWDontPropagate (1L<<12) +#define CWColormap (1L<<13) +#define CWCursor (1L<<14) + +/* + * Data structure for setting window attributes. + */ +typedef struct { + Pixmap background_pixmap; /* background or None or ParentRelative */ + unsigned long background_pixel; /* background pixel */ + Pixmap border_pixmap; /* border of the window */ + unsigned long border_pixel; /* border pixel value */ + int bit_gravity; /* one of bit gravity values */ + int win_gravity; /* one of the window gravity values */ + int backing_store; /* NotUseful, WhenMapped, Always */ + unsigned long backing_planes;/* planes to be preseved if possible */ + unsigned long backing_pixel;/* value to use in restoring planes */ + Bool save_under; /* should bits under be saved? (popups) */ + long event_mask; /* set of events that should be saved */ + long do_not_propagate_mask; /* set of events that should not propagate */ + Bool override_redirect; /* boolean value for override-redirect */ + Colormap colormap; /* color map to be associated with window */ + Cursor cursor; /* cursor to be displayed (or None) */ +} XSetWindowAttributes; + +/* + * Extensions need a way to hang private data on some structures. + */ +typedef struct _XExtData { + int number; /* number returned by XRegisterExtension */ + struct _XExtData *next; /* next item on list of data for structure */ + int (*free_private)( /* called to free private storage */ + struct _XExtData *extension + ); + XPointer private_data; /* data private to this extension. */ +} XExtData; + +typedef struct { + XExtData *ext_data; /* hook for extension to hang data */ + VisualID visualid; /* visual id of this visual */ +#if defined(__cplusplus) || defined(c_plusplus) + int c_class; /* C++ class of screen (monochrome, etc.) */ +#else + int class; /* class of screen (monochrome, etc.) */ +#endif + unsigned long red_mask, green_mask, blue_mask; /* mask values */ + int bits_per_rgb; /* log base 2 of distinct color values */ + int map_entries; /* color map entries */ +} Visual; + +typedef struct _XDisplay Display; + +struct _XDisplay { + struct csx_display *csx_display; +}; + +/* Event names. Used in "type" field in XEvent structures. Not to be +confused with event masks above. They start from 2 because 0 and 1 +are reserved in the protocol for errors and replies. */ + +#define KeyPress 2 +#define KeyRelease 3 +#define ButtonPress 4 +#define ButtonRelease 5 +#define MotionNotify 6 +#define EnterNotify 7 +#define LeaveNotify 8 +#define FocusIn 9 +#define FocusOut 10 +#define KeymapNotify 11 +#define Expose 12 +#define GraphicsExpose 13 +#define NoExpose 14 +#define VisibilityNotify 15 +#define CreateNotify 16 +#define DestroyNotify 17 +#define UnmapNotify 18 +#define MapNotify 19 +#define MapRequest 20 +#define ReparentNotify 21 +#define ConfigureNotify 22 +#define ConfigureRequest 23 +#define GravityNotify 24 +#define ResizeRequest 25 +#define CirculateNotify 26 +#define CirculateRequest 27 +#define PropertyNotify 28 +#define SelectionClear 29 +#define SelectionRequest 30 +#define SelectionNotify 31 +#define ColormapNotify 32 +#define ClientMessage 33 +#define MappingNotify 34 +#define GenericEvent 35 +#define LASTEvent 36 /* must be bigger than any event # */ + +/* + * Definitions of specific events. + */ +typedef struct { + int type; /* of event */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* "event" window it is reported relative to */ + Window root; /* root window that the event occurred on */ + Window subwindow; /* child window */ + Time time; /* milliseconds */ + int x, y; /* pointer x, y coordinates in event window */ + int x_root, y_root; /* coordinates relative to root */ + unsigned int state; /* key or button mask */ + unsigned int keycode; /* detail */ + Bool same_screen; /* same screen flag */ +} XKeyEvent; +typedef XKeyEvent XKeyPressedEvent; +typedef XKeyEvent XKeyReleasedEvent; + +typedef struct { + int type; /* of event */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* "event" window it is reported relative to */ + Window root; /* root window that the event occurred on */ + Window subwindow; /* child window */ + Time time; /* milliseconds */ + int x, y; /* pointer x, y coordinates in event window */ + int x_root, y_root; /* coordinates relative to root */ + unsigned int state; /* key or button mask */ + unsigned int button; /* detail */ + Bool same_screen; /* same screen flag */ +} XButtonEvent; +typedef XButtonEvent XButtonPressedEvent; +typedef XButtonEvent XButtonReleasedEvent; + +typedef struct { + int type; /* of event */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* "event" window reported relative to */ + Window root; /* root window that the event occurred on */ + Window subwindow; /* child window */ + Time time; /* milliseconds */ + int x, y; /* pointer x, y coordinates in event window */ + int x_root, y_root; /* coordinates relative to root */ + unsigned int state; /* key or button mask */ + char is_hint; /* detail */ + Bool same_screen; /* same screen flag */ +} XMotionEvent; +typedef XMotionEvent XPointerMovedEvent; + +typedef struct { + int type; /* of event */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* "event" window reported relative to */ + Window root; /* root window that the event occurred on */ + Window subwindow; /* child window */ + Time time; /* milliseconds */ + int x, y; /* pointer x, y coordinates in event window */ + int x_root, y_root; /* coordinates relative to root */ + int mode; /* NotifyNormal, NotifyGrab, NotifyUngrab */ + int detail; + /* + * NotifyAncestor, NotifyVirtual, NotifyInferior, + * NotifyNonlinear,NotifyNonlinearVirtual + */ + Bool same_screen; /* same screen flag */ + Bool focus; /* boolean focus */ + unsigned int state; /* key or button mask */ +} XCrossingEvent; +typedef XCrossingEvent XEnterWindowEvent; +typedef XCrossingEvent XLeaveWindowEvent; + +typedef struct { + int type; /* FocusIn or FocusOut */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* window of event */ + int mode; /* NotifyNormal, NotifyWhileGrabbed, + NotifyGrab, NotifyUngrab */ + int detail; + /* + * NotifyAncestor, NotifyVirtual, NotifyInferior, + * NotifyNonlinear,NotifyNonlinearVirtual, NotifyPointer, + * NotifyPointerRoot, NotifyDetailNone + */ +} XFocusChangeEvent; +typedef XFocusChangeEvent XFocusInEvent; +typedef XFocusChangeEvent XFocusOutEvent; + +/* generated on EnterWindow and FocusIn when KeyMapState selected */ +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; + char key_vector[32]; +} XKeymapEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; + int x, y; + int width, height; + int count; /* if non-zero, at least this many more */ +} XExposeEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Drawable drawable; + int x, y; + int width, height; + int count; /* if non-zero, at least this many more */ + int major_code; /* core is CopyArea or CopyPlane */ + int minor_code; /* not defined in the core */ +} XGraphicsExposeEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Drawable drawable; + int major_code; /* core is CopyArea or CopyPlane */ + int minor_code; /* not defined in the core */ +} XNoExposeEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; + int state; /* Visibility state */ +} XVisibilityEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window parent; /* parent of the window */ + Window window; /* window id of window created */ + int x, y; /* window location */ + int width, height; /* size of window */ + int border_width; /* border width */ + Bool override_redirect; /* creation should be overridden */ +} XCreateWindowEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window event; + Window window; +} XDestroyWindowEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window event; + Window window; + Bool from_configure; +} XUnmapEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window event; + Window window; + Bool override_redirect; /* boolean, is override set... */ +} XMapEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window parent; + Window window; +} XMapRequestEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window event; + Window window; + Window parent; + int x, y; + Bool override_redirect; +} XReparentEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window event; + Window window; + int x, y; + int width, height; + int border_width; + Window above; + Bool override_redirect; +} XConfigureEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window event; + Window window; + int x, y; +} XGravityEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; + int width, height; +} XResizeRequestEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window parent; + Window window; + int x, y; + int width, height; + int border_width; + Window above; + int detail; /* Above, Below, TopIf, BottomIf, Opposite */ + unsigned long value_mask; +} XConfigureRequestEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window event; + Window window; + int place; /* PlaceOnTop, PlaceOnBottom */ +} XCirculateEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window parent; + Window window; + int place; /* PlaceOnTop, PlaceOnBottom */ +} XCirculateRequestEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; + Atom atom; + Time time; + int state; /* NewValue, Deleted */ +} XPropertyEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; + Atom selection; + Time time; +} XSelectionClearEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window owner; + Window requestor; + Atom selection; + Atom target; + Atom property; + Time time; +} XSelectionRequestEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window requestor; + Atom selection; + Atom target; + Atom property; /* ATOM or None */ + Time time; +} XSelectionEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; + Colormap colormap; /* COLORMAP or None */ +#if defined(__cplusplus) || defined(c_plusplus) + Bool c_new; /* C++ */ +#else + Bool new; +#endif + int state; /* ColormapInstalled, ColormapUninstalled */ +} XColormapEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; + Atom message_type; + int format; + union { + char b[20]; + short s[10]; + long l[5]; + } data; +} XClientMessageEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* unused */ + int request; /* one of MappingModifier, MappingKeyboard, + MappingPointer */ + int first_keycode; /* first keycode */ + int count; /* defines range of change w. first_keycode*/ +} XMappingEvent; + +typedef struct { + int type; + Display *display; /* Display the event was read from */ + XID resourceid; /* resource id */ + unsigned long serial; /* serial number of failed request */ + unsigned char error_code; /* error code of failed request */ + unsigned char request_code; /* Major op-code of failed request */ + unsigned char minor_code; /* Minor op-code of failed request */ +} XErrorEvent; + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display;/* Display the event was read from */ + Window window; /* window on which event was requested in event mask */ +} XAnyEvent; + + +/*************************************************************** + * + * GenericEvent. This event is the standard event for all newer extensions. + */ + +typedef struct + { + int type; /* of event. Always GenericEvent */ + unsigned long serial; /* # of last request processed */ + Bool send_event; /* true if from SendEvent request */ + Display *display; /* Display the event was read from */ + int extension; /* major opcode of extension that caused the event */ + int evtype; /* actual event type. */ + } XGenericEvent; + +typedef struct { + int type; /* of event. Always GenericEvent */ + unsigned long serial; /* # of last request processed */ + Bool send_event; /* true if from SendEvent request */ + Display *display; /* Display the event was read from */ + int extension; /* major opcode of extension that caused the event */ + int evtype; /* actual event type. */ + unsigned int cookie; + void *data; +} XGenericEventCookie; + +/* + * this union is defined so Xlib can always use the same sized + * event structure internally, to avoid memory fragmentation. + */ +typedef union _XEvent { + int type; /* must not be changed; first element */ + XAnyEvent xany; + XKeyEvent xkey; + XButtonEvent xbutton; + XMotionEvent xmotion; + XCrossingEvent xcrossing; + XFocusChangeEvent xfocus; + XExposeEvent xexpose; + XGraphicsExposeEvent xgraphicsexpose; + XNoExposeEvent xnoexpose; + XVisibilityEvent xvisibility; + XCreateWindowEvent xcreatewindow; + XDestroyWindowEvent xdestroywindow; + XUnmapEvent xunmap; + XMapEvent xmap; + XMapRequestEvent xmaprequest; + XReparentEvent xreparent; + XConfigureEvent xconfigure; + XGravityEvent xgravity; + XResizeRequestEvent xresizerequest; + XConfigureRequestEvent xconfigurerequest; + XCirculateEvent xcirculate; + XCirculateRequestEvent xcirculaterequest; + XPropertyEvent xproperty; + XSelectionClearEvent xselectionclear; + XSelectionRequestEvent xselectionrequest; + XSelectionEvent xselection; + XColormapEvent xcolormap; + XClientMessageEvent xclient; + XMappingEvent xmapping; + XErrorEvent xerror; + XKeymapEvent xkeymap; + XGenericEvent xgeneric; + XGenericEventCookie xcookie; + long pad[24]; +} XEvent; + +Display *XOpenDisplay(const char *display_name); +int XConnectionNumber(Display *display); +int XCloseDisplay(Display *display); + +#if defined(__cplusplus) || defined(c_plusplus) +#define CLASS c_class +#else +#define CLASS class +#endif + +Window XCreateWindow(Display *display, Window parent, int x, int y, + unsigned int width, unsigned int height, + unsigned int border_width, int depth, + unsigned int CLASS, Visual *visual, + unsigned long valuemask, + XSetWindowAttributes *attributes); diff --git a/src/display.c b/src/display.c new file mode 100644 index 0000000..9010c31 --- /dev/null +++ b/src/display.c @@ -0,0 +1,128 @@ + +#include <stdint.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <wayland-client.h> + +#include "Xlib-wayland.h" + +#include "private.h" + +void +csx_display_bad_alloc(struct csx_display *display) +{ + fprintf(stderr, "error bad alloc\n"); + exit(1); +} + +static void +shm_format(void *data, struct wl_shm *wl_shm, uint32_t format) +{ + struct csx_display *display = data; + + display->shm_formats |= (1 << format); +} + +struct wl_shm_listener shm_listenter = { + shm_format +}; + +static void +registry_handle_global(void *data, struct wl_registry *registry, + uint32_t id, const char *interface, uint32_t version) +{ + struct csx_display *display = data; + + if (strcmp(interface, "wl_compositor") == 0) { + display->compositor = + wl_registry_bind(registry, + id, &wl_compositor_interface, 1); + } else if (strcmp(interface, "wl_shell") == 0) { + display->shell = wl_registry_bind(registry, + id, &wl_shell_interface, 1); + } else if (strcmp(interface, "wl_shm") == 0) { + display->shm = wl_registry_bind(registry, + id, &wl_shm_interface, 1); + wl_shm_add_listener(display->shm, &shm_listenter, display); + } +} + +static void +registry_handle_global_remove(void *data, struct wl_registry *registry, + uint32_t name) +{ +} + +static const struct wl_registry_listener registry_listener = { + registry_handle_global, + registry_handle_global_remove +}; + +WL_EXPORT Display * +XOpenDisplay(const char *display_name) +{ + Display *xdisplay; + struct csx_display *display; + + xdisplay = malloc(sizeof *xdisplay + sizeof *display); + if (!xdisplay) + return NULL; + + memset(xdisplay, 0, sizeof *xdisplay); + display = xdisplay->csx_display = (void *) (xdisplay + 1); + display->display = wl_display_connect(display_name); + if (!display->display) { + free(display); + return NULL; + } + + display->registry = wl_display_get_registry(display->display); + wl_registry_add_listener(display->registry, + ®istry_listener, display); + wl_display_roundtrip(display->display); + if (display->shm == NULL) { + fprintf(stderr, "No wl_shm global\n"); + exit(1); + } + + wl_display_roundtrip(display->display); + + if (display->shm_formats == 0) { + fprintf(stderr, "no shm formats available\n"); + exit(1); + } + + csx_display_add_resource(display, NULL); /* None resource */ + display->root = csx_window_create(display, NULL); + + fprintf(stderr, "root window is id %d\n", display->root->id); + + return xdisplay; +} + +WL_EXPORT int +XConnectionNumber(Display *display) +{ + return wl_display_get_fd(display->csx_display->display); +} + +WL_EXPORT int +XCloseDisplay(Display *xdisplay) +{ + struct csx_display *display = xdisplay->csx_display; + + if (display->shm) + wl_shm_destroy(display->shm); + + if (display->shell) + wl_shell_destroy(display->shell); + + if (display->compositor) + wl_compositor_destroy(display->compositor); + + wl_registry_destroy(display->registry); + + wl_display_disconnect(display->display); + free(xdisplay); +} diff --git a/src/event.c b/src/event.c new file mode 100644 index 0000000..5344956 --- /dev/null +++ b/src/event.c @@ -0,0 +1,14 @@ +#include "Xlib-wayland.h" + +#include "private.h" + +WL_EXPORT int +XNextEvent(Display *xdisplay, XEvent *xevent) +{ + struct csx_display *display = xdisplay->csx_display; + + wl_display_dispatch(display->display); + + return 0; +} + diff --git a/src/pixmap.c b/src/pixmap.c new file mode 100644 index 0000000..820c023 --- /dev/null +++ b/src/pixmap.c @@ -0,0 +1,147 @@ +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <limits.h> +#include <sys/mman.h> + +#include "Xlib-wayland.h" + +#include "private.h" + +static void +buffer_release(void *data, struct wl_buffer *buffer) +{ + struct csx_pixmap *pixmap = data; +} + +static const struct wl_buffer_listener buffer_listener = { + buffer_release +}; + +static int +create_shm_buffer(struct csx_display *display, struct csx_pixmap *pixmap) +{ + struct wl_shm_pool *pool; + int fd, size, stride; + void *data; + const char *path; + char name[PATH_MAX]; + + stride = pixmap->width * 4; + size = stride * pixmap->height; + + path = getenv("XDG_RUNTIME_DIR"); + if (!path) { + errno = ENOENT; + return -1; + } + + snprintf(name, sizeof name, "%s/csx-pixmap-XXXXXX", path); + fd = mkostemp(name, O_CLOEXEC); + if (fd < 0) + return -1; + + unlink(name); + if (ftruncate(fd, size) < 0) { + close(fd); + return -1; + } + + pixmap->data = + mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (data == MAP_FAILED) { + fprintf(stderr, "mmap failed: %m\n"); + close(fd); + return -1; + } + + pool = wl_shm_create_pool(display->shm, fd, size); + pixmap->buffer = wl_shm_pool_create_buffer(pool, 0, + pixmap->width, + pixmap->height, + stride, + WL_SHM_FORMAT_ARGB8888); + wl_buffer_add_listener(pixmap->buffer, &buffer_listener, pixmap); + wl_shm_pool_destroy(pool); + close(fd); + + memset(pixmap->data, 55, size); + + return 0; +} + +struct csx_pixmap * +csx_pixmap_create(struct csx_display *display, + unsigned int width, unsigned int height, unsigned int depth) +{ + struct csx_pixmap *pixmap; + + pixmap = malloc(sizeof *pixmap); + if (pixmap == NULL) + /* BadAlloc */; + + memset(pixmap, 0, sizeof pixmap); + pixmap->width = width; + pixmap->height = height; + pixmap->depth = depth; + pixmap->refcount = 1; + + create_shm_buffer(display, pixmap); + + return pixmap; +} + +void +csx_pixmap_unref(struct csx_pixmap *pixmap) +{ + int size; + + pixmap->refcount--; + if (pixmap->refcount == 0) { + if (pixmap->buffer) { + size = pixmap->width * 4 * pixmap->height; + wl_buffer_destroy(pixmap->buffer); + munmap(pixmap->data, size); + } else { + free(pixmap->data); + } + free(pixmap); + } +} + +WL_EXPORT Pixmap +XCreatePixmap(Display *xdisplay, Drawable drawable, + unsigned int width, unsigned int height, unsigned int depth) +{ + struct csx_display *display = xdisplay->csx_display; + struct csx_pixmap *pixmap; + void *resource; + Pixmap id; + + resource = csx_display_lookup_resource(display, drawable); + /* FIXME: Need to check resource type too */ + if (resource == NULL) { + /* Raise error */; + return 0; /* need to return valid id */ + } + + id = csx_display_add_resource(display, pixmap); + + return id; +} + +WL_EXPORT int +XFreePixmap(Display *xdisplay, Pixmap xpixmap) +{ + struct csx_display *display = xdisplay->csx_display; + struct csx_pixmap *pixmap; + + pixmap = csx_display_lookup_resource(display, xpixmap); + csx_display_remove_resource(display, xpixmap); + csx_pixmap_unref(pixmap); + + return 0 /* return what? */; +} diff --git a/src/private.h b/src/private.h new file mode 100644 index 0000000..b3abf87 --- /dev/null +++ b/src/private.h @@ -0,0 +1,77 @@ +#include <pixman.h> +#include <wayland-client.h> + +struct csx_event { + XEvent event; + struct wl_list link; +}; + +struct csx_display { + struct wl_display *display; + struct wl_registry *registry; + struct wl_compositor *compositor; + struct wl_shm *shm; + struct wl_shell *shell; + uint32_t shm_formats; + + union entry *resource_map; + int resource_size; + int resource_count, free_resource; + + struct wl_list event_list; + + struct csx_window *root; +}; + +XID cxs_display_add_resource(struct csx_display *display, void *p); +void csx_display_remove_resource(struct csx_display *display, XID id); +void *csx_display_lookup_resource(struct csx_display *display, XID id); +void csx_display_bad_alloc(struct csx_display *display); + +struct csx_window { + XID id; + struct csx_window *parent; + int x; + int y; + unsigned int width; + unsigned int height; + unsigned int border_width; + int depth; + unsigned int class; + Visual *visual; + unsigned long valuemask; + + struct csx_display *display; + int mapped; + struct wl_list link; + struct wl_list child_list; + pixman_region32_t output_clip; + struct csx_pixmap *pixmap; /* viewable iff has pixmap */ + struct wl_surface *surface; + struct wl_shell_surface *shell_surface; + + /* attrs */ +}; + +struct csx_window * +csx_window_create(struct csx_display *display, struct csx_window *parent); +void +csx_window_destroy(struct csx_window *window); + +struct csx_pixmap { + unsigned int width; + unsigned int height; + unsigned int depth; + pixman_image_t *image; + void *data; + struct wl_buffer *buffer; + int refcount; +}; + +struct csx_pixmap * +csx_pixmap_create(struct csx_display *display, + unsigned int width, unsigned int height, + unsigned int depth); + +void +csx_pixmap_unref(struct csx_pixmap *pixmap); diff --git a/src/resource.c b/src/resource.c new file mode 100644 index 0000000..8d28f64 --- /dev/null +++ b/src/resource.c @@ -0,0 +1,67 @@ + +#include <stdint.h> +#include <stdlib.h> +#include <wayland-client.h> + +#include "Xlib-wayland.h" + +#include "private.h" + +union entry { + uintptr_t next; + void *data; +}; + +XID +csx_display_add_resource(struct csx_display *display, void *p) +{ + union entry *e, *map; + int size; + + if (display->free_resource > 0) { + e = display->resource_map + display->free_resource; + display->free_resource = e->next; + } else { + if (display->resource_count == display->resource_size) { + if (display->resource_size == 0) + size = 256; + else + size = display->resource_size * 2; + map = realloc(display->resource_map, + size * sizeof *e); + if (map == NULL) + abort(); /* FIXME: how do we handle OOM? */ + display->resource_map = map; + display->resource_size = size; + } + + e = display->resource_map + display->resource_count; + display->resource_count++; + } + + e->data = p; + + return e - display->resource_map; +} + +void +csx_display_remove_resource(struct csx_display *display, XID id) +{ + union entry *e; + + e = display->resource_map + id; + e->next = display->free_resource; + display->free_resource = id; +} + +void * +csx_display_lookup_resource(struct csx_display *display, XID id) +{ + /* FIXME: verify that we're looking up a valid resource: + * inside valid range and not in free-list. */ + + if (id >= display->resource_size) + return NULL; + + return display->resource_map[id].data; +} diff --git a/src/window.c b/src/window.c new file mode 100644 index 0000000..1f5df1b --- /dev/null +++ b/src/window.c @@ -0,0 +1,197 @@ +#include <stdint.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "Xlib-wayland.h" + +#include "private.h" + +struct csx_window * +csx_window_create(struct csx_display *display, struct csx_window *parent) +{ + struct csx_window *window; + + window = malloc(sizeof *window); + if (window == NULL) + return 0; /* FIXME: BadAlloc */ + + memset(window, 0, sizeof *window); + window->id = csx_display_add_resource(display, window); + window->parent = parent; + + window->display = display; + wl_list_init(&window->child_list); + if (parent) + wl_list_insert(&parent->child_list, &window->link); + pixman_region32_init(&window->output_clip); + + return window; +} + +WL_EXPORT Window +XCreateWindow(Display *xdisplay, Window xparent, int x, int y, + unsigned int width, unsigned int height, + unsigned int border_width, int depth, + unsigned int class, Visual *visual, + unsigned long valuemask, + XSetWindowAttributes *attributes) +{ + struct csx_display *display = xdisplay->csx_display; + struct csx_window *window, *parent; + int i; + + parent = csx_display_lookup_resource(display, xparent); + if (parent == NULL) + /* do something, really */; + + window = csx_window_create(display, parent); + if (window == NULL) { + csx_display_bad_alloc(display); + return None; + } + + window->x = x; + window->y = y; + window->width = width; + window->height = height; + window->border_width = border_width; + window->depth = depth; + window->class = class; + window->visual = visual; + + for (i = 0; i < 15; i++) { + switch (valuemask & (1 << i)) { + case CWBackPixmap: + case CWBackPixel: + case CWBorderPixmap: + case CWBorderPixel: + case CWBitGravity: + case CWWinGravity: + case CWBackingStore: + case CWBackingPlanes: + case CWBackingPixel: + case CWOverrideRedirect: + case CWSaveUnder: + case CWEventMask: + case CWDontPropagate: + case CWColormap: + case CWCursor: + break; + } + } + + return window->id; +} + +void +csx_display_send_map_notify(struct csx_display *display, + struct csx_window *window) +{ +} + +void +csx_window_map_tree(struct csx_window *window, struct csx_pixmap *pixmap) +{ + struct csx_window *child; + + wl_list_for_each(child, &window->child_list, link) + csx_window_map_tree(child, pixmap); + + window->pixmap = pixmap; +} + +void +csx_window_map_toplevel(struct csx_window *window) +{ + struct csx_display *display = window->display; + struct csx_pixmap *pixmap; + + pixmap = csx_pixmap_create(window->display, + window->width, window->height, 32); + csx_window_map_tree(window, pixmap); + + window->surface = wl_compositor_create_surface(display->compositor); + wl_surface_attach(window->surface, window->pixmap->buffer, 0, 0); + window->shell_surface = + wl_shell_get_shell_surface(display->shell, window->surface); + wl_shell_surface_set_toplevel(window->shell_surface); + wl_surface_commit(window->surface); +} + +WL_EXPORT int +XMapWindow(Display *xdisplay, Window xwindow) +{ + struct csx_display *display = xdisplay->csx_display; + struct csx_window *window; + struct csx_pixmap *pixmap; + + window = csx_display_lookup_resource(display, xwindow); + if (window == NULL) { + csx_display_bad_alloc(display); + return 0; /* what's the return value? */ + } + + if (window->mapped) + /* Already mapped */ + return 0; + + window->mapped = 1; + if (window->parent == display->root) { + csx_window_map_toplevel(window); + } else if (window->parent->mapped) { + window->pixmap = window->parent->pixmap; + csx_display_send_map_notify(display, window); + } + +} + +void +csx_window_destroy(struct csx_window *window) +{ + struct csx_window *child, *next; + struct csx_event *event; + + wl_list_for_each_safe(child, next, &window->child_list, link) + csx_window_destroy(child); + +#if 0 + event = csx_display_create_event(display); + event->xevent.type = DestroyNotify; +#endif + + csx_display_remove_resource(window->display, window->id); + wl_list_remove(&window->link); + free(window); +} + +WL_EXPORT int +XDestroyWindow(Display *xdisplay, Window xwindow) +{ + struct csx_display *display = xdisplay->csx_display; + struct csx_window *window; + + window = csx_display_lookup_resource(display, xwindow); + if (window == NULL) + /* BadWindow */; + if (window == display->root) + return; + + csx_window_destroy(window); + + return 0; /* return what? */ +} + +WL_EXPORT int +XDestroySubwindows(Display *xdisplay, Window xwindow) +{ + struct csx_display *display = xdisplay->csx_display; + struct csx_window *window, *child, *next; + + window = csx_display_lookup_resource(display, xwindow); + if (window == NULL) + /* BadWindow */; + + wl_list_for_each_reverse_safe(child, next, &window->child_list, link) + csx_window_destroy(child); +} diff --git a/src/xlib-wayland-test.c b/src/xlib-wayland-test.c new file mode 100644 index 0000000..0eb0452 --- /dev/null +++ b/src/xlib-wayland-test.c @@ -0,0 +1,28 @@ +#include <stdlib.h> +#include <stdio.h> + +#include "Xlib-wayland.h" + +int main(int argc, char *argv[]) +{ + Display *display; + Window win; + XID root = 1; /* FIXME */ + + display = XOpenDisplay(NULL); + printf("opened display %p\n", display); + win = XCreateWindow(display, root, + 100, 100, 200, 200, 0, 24, + InputOutput, NULL, 0, NULL); + + printf("created window %d\n", win); + + XMapWindow(display, win); + + while (1) + XNextEvent(display, NULL); + + XCloseDisplay(display); + + return 0; +} |