summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2009-09-12 22:44:26 -0400
committerKristian Høgsberg <krh@redhat.com>2009-09-12 22:44:37 -0400
commitdd5ba49e035f68439a9c15a3e591d1bf30ecf4d9 (patch)
tree63bb0b5df1b1a75acaa55fb89b9734842e35f1dd /src
parentefbcf29dd1a1ca058b7a2a93f0685102c06c9369 (diff)
Revive wayland patch
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am16
-rw-r--r--src/i830.h11
-rw-r--r--src/i830_driver.c12
-rw-r--r--src/wayland.c590
4 files changed, 626 insertions, 3 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index ea52fcb8..f9223d11 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -27,7 +27,8 @@ SUBDIRS = xvmc bios_reader ch7017 ch7xxx ivch sil164 tfp410 reg_dumper render_pr
# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
AM_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRM_CFLAGS@ @DRI_CFLAGS@ \
- @PCIACCESS_CFLAGS@ -I$(top_srcdir)/uxa -I$(top_srcdir)/src/render_program
+ @PCIACCESS_CFLAGS@ @WAYLAND_CFLAGS@ \
+ -I$(top_srcdir)/uxa -I$(top_srcdir)/src/render_program
intel_drv_la_LTLIBRARIES = intel_drv.la
intel_drv_la_LDFLAGS = -module -avoid-version
@@ -51,6 +52,9 @@ INTEL_XVMC_SRCS = \
i965_hwmc.h
+INTEL_WAYLAND_SRCS = \
+ wayland.c
+
intel_drv_la_SOURCES = \
brw_defines.h \
brw_structs.h \
@@ -113,7 +117,8 @@ intel_drv_la_SOURCES = \
EXTRA_DIST = \
$(XMODE_SRCS) \
$(INTEL_DRI_SRCS) \
- $(INTEL_XVMC_SRCS)
+ $(INTEL_XVMC_SRCS) \
+ $(INTEL_WAYLAND_SRCS)
if DRI
intel_drv_la_SOURCES += \
@@ -126,3 +131,10 @@ if XVMC
intel_drv_la_SOURCES += \
$(INTEL_XVMC_SRCS)
endif
+
+if WAYLAND
+intel_drv_la_SOURCES += \
+ $(INTEL_WAYLAND_SRCS)
+intel_drv_la_LIBADD += \
+ $(WAYLAND_LIBS)
+endif
diff --git a/src/i830.h b/src/i830.h
index c3b0d022..912a77dc 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -615,8 +615,18 @@ typedef struct _I830Rec {
/** User option to print acceleration fallback info to the server log. */
Bool fallback_debug;
struct sdvo_device_mapping sdvo_mappings[2];
+
+#ifdef WAYLAND
+ void *wayland_data;
+#endif
+
} I830Rec;
+#ifdef WAYLAND
+extern Bool wayland_pre_init(ScrnInfoPtr pScrn);
+extern void wayland_post_damage(I830Ptr pI830);
+#endif
+
#define I830PTR(p) ((I830Ptr)((p)->driverPrivate))
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
@@ -690,6 +700,7 @@ i830_pipe_a_require_deactivate (ScrnInfoPtr scrn);
Bool I830DRI2ScreenInit(ScreenPtr pScreen);
void I830DRI2CloseScreen(ScreenPtr pScreen);
+extern int i830_name_buffer (ScrnInfoPtr pScrn, i830_memory *mem);
extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp);
extern int drmmode_get_pipe_from_crtc_id(drm_intel_bufmgr *bufmgr, xf86CrtcPtr crtc);
diff --git a/src/i830_driver.c b/src/i830_driver.c
index e3e1ed20..1d900e39 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1392,6 +1392,7 @@ i830_open_drm_master(ScrnInfoPtr scrn)
xfree(busid);
+#if 0
/* Check that what we opened was a master or a master-capable FD,
* by setting the version of the interface we'll use to talk to it.
* (see DRIOpenDRMMaster() in DRI1)
@@ -1408,6 +1409,7 @@ i830_open_drm_master(ScrnInfoPtr scrn)
i830->drmSubFD = -1;
return FALSE;
}
+#endif
has_gem = FALSE;
gp.param = I915_PARAM_HAS_GEM;
@@ -1586,7 +1588,10 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
i830_check_dri_option(pScrn);
- if (pI830->use_drm_mode) {
+ if (xorgWayland) {
+ if (!wayland_pre_init(pScrn))
+ return FALSE;
+ } else if (pI830->use_drm_mode) {
if (!I830DrmModeInit(pScrn))
return FALSE;
} else {
@@ -2221,6 +2226,11 @@ I830BlockHandler(int i,
if (pI830->have_gem)
drmCommandNone(pI830->drmSubFD, DRM_I915_GEM_THROTTLE);
+#ifdef WAYLAND
+ if (flushed && xorgWayland)
+ wayland_post_damage(pI830);
+#endif
+
pI830->need_mi_flush = FALSE;
}
diff --git a/src/wayland.c b/src/wayland.c
new file mode 100644
index 00000000..fd0edda3
--- /dev/null
+++ b/src/wayland.c
@@ -0,0 +1,590 @@
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <linux/input.h>
+
+#include <extinit.h>
+#include <input.h>
+#include <inputstr.h>
+#include <exevents.h>
+#include <xkbsrv.h>
+#include <xf86Xinput.h>
+#include "i830.h"
+#include <wayland-client.h>
+
+struct xwl_context {
+ ScrnInfoPtr pScrn;
+ int fd;
+ struct wl_display *display;
+ struct wl_compositor *compositor;
+ struct wl_surface *surface;
+ uint32_t mask;
+
+ /* FIXME: Hack. */
+ int32_t width, height;
+
+ DeviceIntPtr pointer;
+ DeviceIntPtr keyboard;
+};
+
+struct xwl_output {
+ struct wl_output *output;
+ struct xwl_context *context;
+ struct wl_surface *surface;
+ int32_t x, y, width, height;
+ xf86Monitor monitor;
+};
+
+/* OMG the horror of the xf86 input wrapper... Fortunately, we don't
+ * have to use that. */
+
+static int
+wayland_input_proc(DeviceIntPtr device, int event)
+{
+ switch (event) {
+ case DEVICE_INIT:
+ break;
+ case DEVICE_ON:
+ break;
+ case DEVICE_OFF:
+ break;
+ case DEVICE_CLOSE:
+ break;
+ }
+
+ return Success;
+}
+
+static void
+wayland_input_ptr_ctrl_proc(DeviceIntPtr device, PtrCtrl *ctrl)
+{
+ /* Nothing to do, dix handles all settings */
+}
+
+static void
+wayland_input_post_motion_event(struct xwl_context *context, int x, int y)
+{
+ xf86PostMotionEvent(context->pointer, TRUE, 0, 2, x, y);
+}
+
+static void
+wayland_input_post_button_event(struct xwl_context *context, int button, int state)
+{
+ int index;
+
+ switch (button) {
+ case BTN_MIDDLE:
+ index = 2;
+ break;
+ case BTN_RIGHT:
+ index = 3;
+ break;
+ default:
+ index = button - BTN_LEFT + 1;
+ break;
+ }
+
+ xf86PostButtonEvent(context->pointer, TRUE, index, state, 0, 0);
+}
+
+static void
+wayland_input_post_key_event(struct xwl_context *context, int key, int state)
+{
+ xf86PostKeyboardEvent(context->pointer, key + 8, state);
+}
+
+static void
+wayland_input_kbd_ctrl(DeviceIntPtr device, KeybdCtrl *ctrl)
+{
+ /* FIXME: Set keyboard leds based on CAPSFLAG etc being set in
+ * ctrl->leds */
+}
+
+static int
+wayland_input_init_pointer(struct xwl_context *context)
+{
+ DeviceIntPtr device;
+ int min_x = 0, min_y = 0, max_x = context->width, max_y = context->height;
+ static unsigned char map[] = { 1, 2, 3 };
+ CARD32 atom;
+ char *name = "wayland";
+ Atom labels[3];
+
+ device = AddInputDevice(serverClient, wayland_input_proc, TRUE);
+ context->pointer = device;
+
+ atom = MakeAtom(name, strlen(name), TRUE);
+ AssignTypeAndName(device, atom, name);
+
+ device->coreEvents = TRUE;
+ device->type = SLAVE;
+ device->spriteInfo->spriteOwner = FALSE;
+
+ labels[0] = MakeAtom("x", 1, TRUE);
+ labels[1] = MakeAtom("y", 1, TRUE);
+
+ if (!InitValuatorClassDeviceStruct(device, 2, labels,
+ GetMotionHistorySize(), Absolute))
+ return !Success;
+
+ /* Valuators */
+ InitValuatorAxisStruct(device, labels[0], 0, min_x, max_x, 10000, 0, 10000);
+ InitValuatorAxisStruct(device, labels[1], 1, min_y, max_y, 10000, 0, 10000);
+
+ if (!InitPtrFeedbackClassDeviceStruct(device, wayland_input_ptr_ctrl_proc))
+ return !Success;
+
+ /* FIXME: count number of actual buttons */
+ labels[0] = MakeAtom("left", 4, TRUE);
+ labels[1] = MakeAtom("middle", 6, TRUE);
+ labels[2] = MakeAtom("right", 5, TRUE);
+ if (!InitButtonClassDeviceStruct(device, 3, labels, map))
+ return !Success;
+
+ return Success;
+}
+
+static int
+wayland_input_init_keyboard(struct xwl_context *context)
+{
+ DeviceIntPtr device;
+ CARD32 atom;
+ char *name = "wayland";
+ KeySymsRec key_syms;
+ XkbRMLVOSet rmlvo;
+
+ device = AddInputDevice(serverClient, wayland_input_proc, TRUE);
+ context->keyboard = device;
+
+ atom = MakeAtom(name, strlen(name), TRUE);
+ AssignTypeAndName(device, atom, name);
+
+ device->coreEvents = TRUE;
+ device->type = SLAVE;
+ device->spriteInfo->spriteOwner = FALSE;
+
+ key_syms.map = malloc(4 * 248 * sizeof(KeySym));
+ key_syms.mapWidth = 4;
+ key_syms.minKeyCode = 8;
+ key_syms.maxKeyCode = 254;
+
+ rmlvo.rules = "evdev";
+ rmlvo.model = "evdev";
+ rmlvo.layout = "us";
+ rmlvo.variant = NULL;
+ rmlvo.options = NULL;
+ if (!InitKeyboardDeviceStruct(device, &rmlvo,
+ NULL, wayland_input_kbd_ctrl))
+ return !Success;
+
+ RegisterOtherDevice(device);
+ ActivateDevice(device, FALSE);
+
+ return Success;
+}
+
+static int
+source_update(uint32_t mask, void *data)
+{
+ struct xwl_context *context = data;
+
+ context->mask = mask;
+
+ return 0;
+}
+
+static void
+wakeup_handler(pointer data, int err, pointer read_mask)
+{
+ struct xwl_context *context = data;
+
+ if (err >= 0 && FD_ISSET(context->fd, (fd_set *) read_mask)) {
+ wl_display_iterate(context->display,
+ WL_DISPLAY_READABLE);
+ }
+}
+
+static void
+block_handler(pointer data, struct timeval **tv, pointer read_mask)
+{
+ struct xwl_context *context = data;
+
+ /* The X servers "main loop" doesn't let us select for
+ * writable, so let's just do a blocking write here. */
+
+ while (context->mask & WL_DISPLAY_WRITABLE)
+ wl_display_iterate(context->display,
+ WL_DISPLAY_WRITABLE);
+}
+
+static void
+handle_motion(void *data, struct wl_input_device *input_device,
+ int32_t x, int32_t y, int32_t sx, int32_t sy)
+{
+ struct xwl_context *context = data;
+
+ wayland_input_post_motion_event(context, sx, sy);
+}
+
+static void
+handle_button(void *data, struct wl_input_device *input_device,
+ uint32_t button, uint32_t state,
+ int32_t x, int32_t y, int32_t sx, int32_t sy)
+{
+ struct xwl_context *context = data;
+
+ wayland_input_post_button_event(context, button, state);
+}
+
+static void
+handle_key(void *data, struct wl_input_device *input_device,
+ uint32_t key, uint32_t state)
+{
+ struct xwl_context *context = data;
+
+ wayland_input_post_key_event(context, key, state);
+}
+
+
+static void
+handle_pointer_focus(void *data,
+ struct wl_input_device *input_device,
+ struct wl_surface *surface)
+{
+}
+
+static void
+handle_keyboard_focus(void *data,
+ struct wl_input_device *input_device,
+ struct wl_surface *surface,
+ struct wl_array *keys)
+{
+ /* FIXME: Restore X modifiers here. */
+}
+
+static const struct wl_input_device_listener input_device_listener = {
+ handle_motion,
+ handle_button,
+ handle_key,
+ handle_pointer_focus,
+ handle_keyboard_focus,
+};
+
+static void
+display_handle_geometry(void *data,
+ struct wl_output *output,
+ int32_t width, int32_t height)
+{
+ struct xwl_output *xwl_output = data;
+
+ xwl_output->x = 0;
+ xwl_output->y = 0;
+ xwl_output->width = width;
+ xwl_output->height = height;
+
+ xwl_output->context->width = width;
+ xwl_output->context->height = height;
+}
+
+static const struct wl_output_listener output_listener = {
+ display_handle_geometry,
+};
+
+static void
+crtc_dpms(xf86CrtcPtr drmmode_crtc, int mode)
+{
+}
+
+static Bool
+crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
+ Rotation rotation, int x, int y)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ struct xwl_context *context = pI830->wayland_data;
+ uint32_t name;
+ struct wl_visual *visual;
+
+ visual = wl_display_get_rgb_visual(context->display);
+
+ if (dri_bo_flink(pI830->front_buffer->bo, &name) != 0)
+ /* failed to name buffer */
+ return FALSE;
+
+ wl_surface_attach(context->surface, name,
+ mode->HDisplay, mode->VDisplay,
+ pScrn->displayWidth * pI830->cpp, visual);
+ wl_surface_map(context->surface, 0, 0,
+ mode->HDisplay, mode->VDisplay);
+ wl_compositor_commit(context->compositor, 0);
+
+ return TRUE;
+}
+
+static void
+crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg)
+{
+}
+
+static void
+crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
+{
+}
+
+static void
+crtc_show_cursor (xf86CrtcPtr crtc)
+{
+}
+
+static void
+crtc_hide_cursor (xf86CrtcPtr crtc)
+{
+}
+
+static void
+crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
+{
+}
+
+static PixmapPtr
+crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
+{
+ return NULL;
+}
+
+static void *
+crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
+{
+ return NULL;
+}
+
+static void
+crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
+{
+}
+
+static const xf86CrtcFuncsRec crtc_funcs = {
+ .dpms = crtc_dpms,
+ .set_mode_major = crtc_set_mode_major,
+ .set_cursor_colors = crtc_set_cursor_colors,
+ .set_cursor_position = crtc_set_cursor_position,
+ .show_cursor = crtc_show_cursor,
+ .hide_cursor = crtc_hide_cursor,
+ .load_cursor_argb = crtc_load_cursor_argb,
+ .shadow_create = crtc_shadow_create,
+ .shadow_allocate = crtc_shadow_allocate,
+ .shadow_destroy = crtc_shadow_destroy,
+ .destroy = NULL, /* XXX */
+};
+
+static void
+output_dpms(xf86OutputPtr output, int mode)
+{
+ return;
+}
+
+static xf86OutputStatus
+output_detect(xf86OutputPtr output)
+{
+ return XF86OutputStatusConnected;
+}
+
+static Bool
+output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes)
+{
+ return MODE_OK;
+}
+
+static DisplayModePtr
+output_get_modes(xf86OutputPtr xf86output)
+{
+ struct xwl_output *output = xf86output->driver_private;
+ struct monitor_ranges *ranges;
+ DisplayModePtr modes;
+
+ modes = xf86CVTMode(output->width, output->height, 60, TRUE, FALSE);
+ output->monitor.det_mon[0].type = DS_RANGES;
+ ranges = &output->monitor.det_mon[0].section.ranges;
+ ranges->min_h = modes->HSync - 10;
+ ranges->max_h = modes->HSync + 10;
+ ranges->min_v = modes->VRefresh - 10;
+ ranges->max_v = modes->VRefresh + 10;
+ ranges->max_clock = modes->Clock + 100;
+ output->monitor.det_mon[1].type = DT;
+ output->monitor.det_mon[2].type = DT;
+ output->monitor.det_mon[3].type = DT;
+
+ xf86output->MonInfo = &output->monitor;
+
+ return modes;
+}
+
+static void
+output_destroy(xf86OutputPtr xf86output)
+{
+ struct xwl_output *output = xf86output->driver_private;
+
+ free(output);
+}
+
+static const xf86OutputFuncsRec output_funcs = {
+ .dpms = output_dpms,
+ .detect = output_detect,
+ .mode_valid = output_mode_valid,
+ .get_modes = output_get_modes,
+ .destroy = output_destroy
+};
+
+static void
+create_output(struct xwl_context *context, struct wl_object *object)
+{
+ struct xwl_output *output;
+ xf86OutputPtr xf86output;
+ xf86CrtcPtr xf86crtc;
+
+ output = malloc(sizeof *output);
+ output->context = context;
+ output->output = (struct wl_output *) object;
+
+ output->surface = wl_compositor_create_surface(context->compositor);
+ if (output->surface == NULL) {
+ ErrorF("wl_display_create_surface failed\n");
+ return;
+ }
+ wl_output_add_listener(output->output, &output_listener, output);
+ context->surface = output->surface;
+
+ xf86output = xf86OutputCreate(context->pScrn, &output_funcs, "WAYLAND-1");
+ xf86output->driver_private = output;
+ xf86output->mm_width = 300;
+ xf86output->mm_height = 240;
+ xf86output->subpixel_order = SubPixelHorizontalRGB;
+ xf86output->possible_crtcs = 1;
+ xf86output->possible_clones = 1;
+
+ xf86crtc = xf86CrtcCreate(context->pScrn, &crtc_funcs);
+ xf86crtc->driver_private = output;
+
+ return;
+
+}
+
+static void
+global_handler(struct wl_display *display,
+ struct wl_object *object, void *data)
+{
+ struct xwl_context *context = data;
+
+ if (wl_object_implements(object, "compositor", 1)) {
+ context->compositor = (struct wl_compositor *) object;
+ } else if (wl_object_implements(object, "output", 1)) {
+ create_output(context, object);
+ } else if (wl_object_implements(object, "input_device", 1)) {
+ struct wl_input_device *device =
+ (struct wl_input_device *) object;
+ wl_input_device_add_listener(device,
+ &input_device_listener, context);
+ }
+}
+
+static Bool
+resize (ScrnInfoPtr scrn, int width, int height)
+{
+ if (scrn->virtualX == width && scrn->virtualY == height)
+ return TRUE;
+
+ scrn->virtualX = width;
+ scrn->virtualY = height;
+
+ return TRUE;
+}
+
+static const xf86CrtcConfigFuncsRec config_funcs = {
+ resize
+};
+
+static const char socket_name[] = "\0wayland";
+
+Bool
+wayland_pre_init(ScrnInfoPtr pScrn)
+{
+ struct xwl_context *context;
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ pI830->have_gem = TRUE;
+ i830_init_bufmgr(pScrn);
+
+ context = malloc(sizeof *context);
+ if (context == NULL) {
+ ErrorF("malloc failed\n");
+ return FALSE;
+ }
+
+ memset(context, 0, sizeof *context);
+ context->pScrn = pScrn;
+ context->display = wl_display_create(socket_name, sizeof socket_name);
+ if (context->display == NULL) {
+ ErrorF("wl_display_create failed\n");
+ return FALSE;
+ }
+
+ xf86CrtcConfigInit(pScrn, &config_funcs);
+
+ xf86CrtcSetSizeRange(pScrn, 320, 200, 8192, 8192);
+
+ /* Set up listener so we'll catch all events. */
+ wl_display_add_global_listener(context->display,
+ global_handler, context);
+
+ /* Process connection events. */
+ wl_display_iterate(context->display, WL_DISPLAY_READABLE);
+
+ context->fd = wl_display_get_fd(context->display,
+ source_update, context);
+
+ pI830->wayland_data = context;
+ AddGeneralSocket(context->fd);
+ RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, context);
+
+ xf86InitialConfiguration(pScrn, TRUE);
+
+ wayland_input_init_pointer(context);
+ wayland_input_init_keyboard(context);
+
+ return TRUE;
+}
+
+void wayland_post_damage(I830Ptr pI830)
+{
+ struct xwl_context *context = pI830->wayland_data;
+
+ wl_surface_damage(context->surface, 0, 0, 10, 10);
+ wl_compositor_commit(context->compositor, 0);
+
+ while (context->mask & WL_DISPLAY_WRITABLE)
+ wl_display_iterate(context->display,
+ WL_DISPLAY_WRITABLE);
+}