diff options
author | Kristian Høgsberg <krh@redhat.com> | 2009-09-12 22:44:26 -0400 |
---|---|---|
committer | Kristian Høgsberg <krh@redhat.com> | 2009-09-12 22:44:37 -0400 |
commit | dd5ba49e035f68439a9c15a3e591d1bf30ecf4d9 (patch) | |
tree | 63bb0b5df1b1a75acaa55fb89b9734842e35f1dd /src | |
parent | efbcf29dd1a1ca058b7a2a93f0685102c06c9369 (diff) |
Revive wayland patch
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 16 | ||||
-rw-r--r-- | src/i830.h | 11 | ||||
-rw-r--r-- | src/i830_driver.c | 12 | ||||
-rw-r--r-- | src/wayland.c | 590 |
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 @@ -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); +} |