debian/changelog | 7 debian/patches/xmir.patch | 1047 ++++++++++++++++++++++++++++++++-------------- debian/serverminver | 2 3 files changed, 739 insertions(+), 317 deletions(-)
New commits: commit 1b6eccb015856b1e0c3b9219fa22f7c61b74491d Author: Christopher James Halse Rogers <[email protected]> Date: Thu Aug 29 19:47:40 2013 +1000 Add XMir RANDR support diff --git a/debian/changelog b/debian/changelog index 79bdfde..7b907ee 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +xorg-server (2:1.14.2.901-2ubuntu4) saucy; urgency=low + + * xmir.patch: Add XRandR support + * Bump serverminver for XMir API changes + + -- Christopher James Halse Rogers <[email protected]> Thu, 29 Aug 2013 19:42:41 +1000 + xorg-server (2:1.14.2.901-2ubuntu3) saucy; urgency=low * xmir.patch: Use the API we have, not the API we've documented diff --git a/debian/patches/xmir.patch b/debian/patches/xmir.patch index 6e5dab8..746fba3 100644 --- a/debian/patches/xmir.patch +++ b/debian/patches/xmir.patch @@ -1,8 +1,8 @@ -Index: xserver/configure.ac -=================================================================== ---- xserver.orig/configure.ac 2013-08-22 15:18:34.437916132 +1000 -+++ xserver/configure.ac 2013-08-22 15:18:34.425916132 +1000 -@@ -639,6 +639,7 @@ +diff --git a/configure.ac b/configure.ac +index c6ecba4..cbba229 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -635,6 +635,7 @@ AC_ARG_ENABLE(windowswm, AS_HELP_STRING([--enable-windowswm], [Build XWin w AC_ARG_ENABLE(libdrm, AS_HELP_STRING([--enable-libdrm], [Build Xorg with libdrm support (default: enabled)]), [DRM=$enableval],[DRM=yes]) AC_ARG_ENABLE(clientids, AS_HELP_STRING([--disable-clientids], [Build Xorg with client ID tracking (default: enabled)]), [CLIENTIDS=$enableval], [CLIENTIDS=yes]) AC_ARG_ENABLE(pciaccess, AS_HELP_STRING([--enable-pciaccess], [Build Xorg with pciaccess library (default: enabled)]), [PCI=$enableval], [PCI=yes]) @@ -10,7 +10,7 @@ Index: xserver/configure.ac dnl DDXes. AC_ARG_ENABLE(xorg, AS_HELP_STRING([--enable-xorg], [Build Xorg server (default: auto)]), [XORG=$enableval], [XORG=auto]) -@@ -1152,6 +1153,15 @@ +@@ -1148,6 +1149,15 @@ if test "x$XINERAMA" = xyes; then SDK_REQUIRED_MODULES="$SDK_REQUIRED_MODULES $XINERAMAPROTO" fi @@ -26,7 +26,7 @@ Index: xserver/configure.ac AM_CONDITIONAL(XACE, [test "x$XACE" = xyes]) if test "x$XACE" = xyes; then AC_DEFINE(XACE, 1, [Build X-ACE extension]) -@@ -2300,6 +2310,7 @@ +@@ -2299,6 +2309,7 @@ hw/xfree86/utils/Makefile hw/xfree86/utils/man/Makefile hw/xfree86/utils/cvt/Makefile hw/xfree86/utils/gtf/Makefile @@ -34,11 +34,11 @@ Index: xserver/configure.ac hw/dmx/config/Makefile hw/dmx/config/man/Makefile hw/dmx/doc/Makefile -Index: xserver/hw/xfree86/Makefile.am -=================================================================== ---- xserver.orig/hw/xfree86/Makefile.am 2013-08-22 15:18:34.437916132 +1000 -+++ xserver/hw/xfree86/Makefile.am 2013-08-22 15:18:34.425916132 +1000 -@@ -25,15 +25,20 @@ +diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am +index c3899b5..6821198 100644 +--- a/hw/xfree86/Makefile.am ++++ b/hw/xfree86/Makefile.am +@@ -25,15 +25,20 @@ if INT10MODULE INT10_SUBDIR = int10 endif @@ -61,11 +61,11 @@ Index: xserver/hw/xfree86/Makefile.am bin_PROGRAMS = Xorg nodist_Xorg_SOURCES = sdksyms.c -Index: xserver/hw/xfree86/common/xf86Config.c -=================================================================== ---- xserver.orig/hw/xfree86/common/xf86Config.c 2013-08-22 15:18:34.437916132 +1000 -+++ xserver/hw/xfree86/common/xf86Config.c 2013-08-22 15:18:34.429916132 +1000 -@@ -117,6 +117,7 @@ +diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c +index 74d5ed3..538ba4b 100644 +--- a/hw/xfree86/common/xf86Config.c ++++ b/hw/xfree86/common/xf86Config.c +@@ -118,6 +118,7 @@ static ModuleDefault ModuleDefaults[] = { {.name = "fb",.toLoad = TRUE,.load_opt = NULL}, {.name = "shadow",.toLoad = TRUE,.load_opt = NULL}, #endif @@ -73,7 +73,7 @@ Index: xserver/hw/xfree86/common/xf86Config.c {.name = NULL,.toLoad = FALSE,.load_opt = NULL} }; -@@ -259,6 +260,17 @@ +@@ -260,6 +261,17 @@ xf86ModulelistFromConfig(pointer **optlist) return NULL; } @@ -91,22 +91,42 @@ Index: xserver/hw/xfree86/common/xf86Config.c if (xf86configptr->conf_modules) { /* Walk the disable list and let people know what we've parsed to * not be loaded -Index: xserver/hw/xfree86/common/xf86Globals.c -=================================================================== ---- xserver.orig/hw/xfree86/common/xf86Globals.c 2013-08-22 15:18:34.437916132 +1000 -+++ xserver/hw/xfree86/common/xf86Globals.c 2013-08-22 15:18:34.429916132 +1000 -@@ -206,3 +206,6 @@ +diff --git a/hw/xfree86/common/xf86Globals.c b/hw/xfree86/common/xf86Globals.c +index 7df7a80..17ed7c6 100644 +--- a/hw/xfree86/common/xf86Globals.c ++++ b/hw/xfree86/common/xf86Globals.c +@@ -204,3 +204,6 @@ Bool xf86VidModeAllowNonLocal = FALSE; #endif RootWinPropPtr *xf86RegisteredPropertiesTable = NULL; Bool xorgHWAccess = FALSE; +Bool xorgMir = FALSE; +const char *mirID = NULL; +const char *mirSocket = NULL; -Index: xserver/hw/xfree86/common/xf86Init.c -=================================================================== ---- xserver.orig/hw/xfree86/common/xf86Init.c 2013-08-22 15:18:34.437916132 +1000 -+++ xserver/hw/xfree86/common/xf86Init.c 2013-08-22 15:18:34.429916132 +1000 -@@ -554,7 +554,7 @@ +diff --git a/hw/xfree86/common/xf86Helper.c b/hw/xfree86/common/xf86Helper.c +index 721159d..d319e0c 100644 +--- a/hw/xfree86/common/xf86Helper.c ++++ b/hw/xfree86/common/xf86Helper.c +@@ -100,7 +100,14 @@ xf86DeleteDriver(int drvIndex) + if (xf86DriverList[drvIndex]->module) + UnloadModule(xf86DriverList[drvIndex]->module); + free(xf86DriverList[drvIndex]); +- xf86DriverList[drvIndex] = NULL; ++ ++ /* Compact xf86DriverList array, update xf86NumDrivers */ ++ xf86NumDrivers--; ++ if(drvIndex != xf86NumDrivers) ++ memmove(xf86DriverList + drvIndex, ++ xf86DriverList + drvIndex + 1, ++ sizeof(DriverPtr) * (xf86NumDrivers - drvIndex)); ++ xf86DriverList = realloc(xf86DriverList, xf86NumDrivers * sizeof(DriverPtr)); + } + } + +diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c +index 91ec4c8..0508e8d 100644 +--- a/hw/xfree86/common/xf86Init.c ++++ b/hw/xfree86/common/xf86Init.c +@@ -530,7 +530,7 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv) * needed at this early stage. */ @@ -115,7 +135,7 @@ Index: xserver/hw/xfree86/common/xf86Init.c xorgHWFlags flags = HW_IO; if (xf86DriverList[i]->Identify != NULL) -@@ -565,11 +565,20 @@ +@@ -541,11 +541,20 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv) GET_REQUIRED_HW_INTERFACES, &flags); @@ -136,7 +156,7 @@ Index: xserver/hw/xfree86/common/xf86Init.c } if (xorgHWOpenConsole) -@@ -662,9 +671,13 @@ +@@ -631,9 +640,13 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv) } /* Remove (unload) drivers that are not required */ @@ -144,15 +164,15 @@ Index: xserver/hw/xfree86/common/xf86Init.c - if (xf86DriverList[i] && xf86DriverList[i]->refCount <= 0) + for (i = 0; i < xf86NumDrivers; ) + if (xf86DriverList[i] && -+ !xf86DriverHasEntities(xf86DriverList[i]) && -+ xf86DriverList[i]->refCount <= 0) ++ !xf86DriverHasEntities(xf86DriverList[i]) && ++ xf86DriverList[i]->refCount <= 0) xf86DeleteDriver(i); + else + i++; /* * At this stage we know how many screens there are. -@@ -1490,6 +1503,17 @@ +@@ -1454,6 +1467,17 @@ ddxProcessArgument(int argc, char **argv, int i) xf86Info.ShareVTs = TRUE; return 1; } @@ -170,7 +190,7 @@ Index: xserver/hw/xfree86/common/xf86Init.c /* OS-specific processing */ return xf86ProcessArgument(argc, argv, i); -@@ -1563,6 +1587,8 @@ +@@ -1527,6 +1551,8 @@ ddxUseMsg(void) ErrorF ("-novtswitch don't automatically switch VT at reset & exit\n"); ErrorF("-sharevts share VTs with another X server\n"); @@ -179,11 +199,11 @@ Index: xserver/hw/xfree86/common/xf86Init.c /* OS-specific usage */ xf86UseMsg(); ErrorF("\n"); -Index: xserver/hw/xfree86/common/xf86Priv.h -=================================================================== ---- xserver.orig/hw/xfree86/common/xf86Priv.h 2013-08-22 15:18:34.437916132 +1000 -+++ xserver/hw/xfree86/common/xf86Priv.h 2013-08-22 15:18:34.429916132 +1000 -@@ -93,6 +93,9 @@ +diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h +index 58cfe0a..4630e9e 100644 +--- a/hw/xfree86/common/xf86Priv.h ++++ b/hw/xfree86/common/xf86Priv.h +@@ -91,6 +91,9 @@ extern _X_EXPORT int xf86NumScreens; extern _X_EXPORT const char *xf86VisualNames[]; extern _X_EXPORT int xf86Verbose; /* verbosity level */ extern _X_EXPORT int xf86LogVerbose; /* log file verbosity level */ @@ -193,10 +213,42 @@ Index: xserver/hw/xfree86/common/xf86Priv.h extern _X_EXPORT RootWinPropPtr *xf86RegisteredPropertiesTable; -Index: xserver/hw/xfree86/xmir/Makefile.am -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ xserver/hw/xfree86/xmir/Makefile.am 2013-08-22 15:18:34.429916132 +1000 +diff --git a/hw/xfree86/ramdac/xf86Cursor.c b/hw/xfree86/ramdac/xf86Cursor.c +index 860704e..5277c94 100644 +--- a/hw/xfree86/ramdac/xf86Cursor.c ++++ b/hw/xfree86/ramdac/xf86Cursor.c +@@ -58,7 +58,12 @@ xf86InitCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr) + xf86CursorScreenPtr ScreenPriv; + miPointerScreenPtr PointPriv; + +- if (!xf86InitHardwareCursor(pScreen, infoPtr)) ++ infoPtr->pScrn = xf86ScreenToScrn(pScreen); ++ ++ /* If we can't create a hardware cursor don't bother initialising HW cursor support */ ++ if (infoPtr->MaxWidth != 0 && ++ infoPtr->MaxHeight != 0 && ++ !xf86InitHardwareCursor(pScreen, infoPtr)) + return FALSE; + + if (!dixRegisterPrivateKey(&xf86CursorScreenKeyRec, PRIVATE_SCREEN, 0)) +diff --git a/hw/xfree86/ramdac/xf86HWCurs.c b/hw/xfree86/ramdac/xf86HWCurs.c +index 197abff..399bfb9 100644 +--- a/hw/xfree86/ramdac/xf86HWCurs.c ++++ b/hw/xfree86/ramdac/xf86HWCurs.c +@@ -114,8 +114,6 @@ xf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr) + infoPtr->RealizeCursor = RealizeCursorInterleave0; + } + +- infoPtr->pScrn = xf86ScreenToScrn(pScreen); +- + return TRUE; + } + +diff --git a/hw/xfree86/xmir/Makefile.am b/hw/xfree86/xmir/Makefile.am +new file mode 100644 +index 0000000..80715f8 +--- /dev/null ++++ b/hw/xfree86/xmir/Makefile.am @@ -0,0 +1,26 @@ +INCLUDES = \ + $(XORG_INCS) \ @@ -224,11 +276,12 @@ Index: xserver/hw/xfree86/xmir/Makefile.am + xmir-private.h + +sdk_HEADERS = xmir.h -Index: xserver/hw/xfree86/xmir/xmir-output.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ xserver/hw/xfree86/xmir/xmir-output.c 2013-08-22 15:18:34.429916132 +1000 -@@ -0,0 +1,225 @@ +diff --git a/hw/xfree86/xmir/xmir-output.c b/hw/xfree86/xmir/xmir-output.c +new file mode 100644 +index 0000000..b461651 +--- /dev/null ++++ b/hw/xfree86/xmir/xmir-output.c +@@ -0,0 +1,559 @@ +/* + * Copyright © 2012 Canonical, Inc + * @@ -262,20 +315,224 @@ Index: xserver/hw/xfree86/xmir/xmir-output.c + */ + +#include <stdlib.h> ++#include <stdio.h> ++#include <math.h> + ++#include <xorg-config.h> ++#include "xmir.h" +#include "xmir-private.h" +#include "xf86Crtc.h" + ++struct xmir_crtc { ++ xmir_screen *xmir; ++ xmir_window *root_fragment; ++ MirDisplayConfiguration *config; ++}; ++ +static void +crtc_dpms(xf86CrtcPtr drmmode_crtc, int mode) +{ +} + ++static void ++xmir_output_populate(xf86OutputPtr xf86output, MirDisplayOutput *output) ++{ ++ /* We can always arbitrarily clone and output */ ++ xf86output->possible_crtcs = 0xffffffff; ++ xf86output->possible_clones = 0xffffffff; ++ ++ xf86output->driver_private = output; ++ ++ xf86output->interlaceAllowed = FALSE; ++ xf86output->doubleScanAllowed = FALSE; ++ xf86output->mm_width = output->physical_width_mm; ++ xf86output->mm_height = output->physical_height_mm; ++ /* TODO: Subpixel order from Mir */ ++ xf86output->subpixel_order = SubPixelUnknown; ++} ++ ++static Bool ++xmir_mir_mode_matches(MirDisplayMode *mir_mode, DisplayModePtr X_mode) ++{ ++ return (mir_mode->vertical_resolution == X_mode->VDisplay && ++ mir_mode->horizontal_resolution == X_mode->HDisplay /*&& ++ fabs(mir_mode->refresh_rate - X_mode->VRefresh) < 0.01*/); ++} ++ ++static Bool ++xmir_set_mode_for_output(MirDisplayOutput *output, ++ DisplayModePtr mode) ++{ ++ for (int i = 0; i < output->num_modes; i++) { ++ xf86Msg(X_INFO, "Checking against mode (%dx%d)\n", ++ output->modes[i].horizontal_resolution, ++ output->modes[i].vertical_resolution); ++ if (xmir_mir_mode_matches(&output->modes[i], mode)) { ++ output->current_mode = i; ++ output->used = 1; ++ xf86Msg(X_INFO, "Matched mode %d\n", i); ++ return TRUE; ++ } ++ } ++ return FALSE; ++} ++ ++static uint32_t ++xmir_update_outputs_for_crtc(xf86CrtcPtr crtc, DisplayModePtr mode, int x, int y) ++{ ++ xf86CrtcConfigPtr crtc_cfg = XF86_CRTC_CONFIG_PTR(crtc->scrn); ++ uint32_t representative_output_id = mir_display_output_id_invalid; ++ ++ for (int i = 0; i < crtc_cfg->num_output; i++) { ++ /* If this output should be driven by our "CRTC", set its mode */ ++ if (crtc_cfg->output[i]->crtc == crtc) { ++ MirDisplayOutput *output = crtc_cfg->output[i]->driver_private; ++ xmir_set_mode_for_output(output, mode); ++ output->position_x = x; ++ output->position_y = y; ++ representative_output_id = output->output_id; ++ } ++ } ++ return representative_output_id; ++} ++ ++static void ++xmir_disable_unused_outputs(xf86CrtcPtr crtc) ++{ ++ xf86CrtcConfigPtr crtc_cfg = XF86_CRTC_CONFIG_PTR(crtc->scrn); ++ ++ for (int i = 0; i < crtc_cfg->num_output; i++) ++ /* If any outputs are no longer associated with a CRTC, disable them */ ++ if (crtc_cfg->output[i]->crtc == NULL) ++ ((MirDisplayOutput*)crtc_cfg->output[i]->driver_private)->used = 0; ++} ++ ++static void ++xmir_stupid_callback(MirSurface *surf, void *ctx) ++{ ++} ++ ++static void ++xmir_dump_config(MirDisplayConfiguration *config) ++{ ++ for (int i = 0; i < config->num_outputs; i++) ++ { ++ xf86Msg(X_INFO, "Output %d (%s, %s) has mode %d (%d x %d @ %.2f), position (%d,%d)\n", ++ config->outputs[i].output_id, ++ config->outputs[i].connected ? "connected" : "disconnected", ++ config->outputs[i].used ? "enabled" : "disabled", ++ config->outputs[i].current_mode, ++ config->outputs[i].used ? config->outputs[i].modes[config->outputs[i].current_mode].horizontal_resolution : 0, ++ config->outputs[i].used ? config->outputs[i].modes[config->outputs[i].current_mode].vertical_resolution : 0, ++ config->outputs[i].used ? config->outputs[i].modes[config->outputs[i].current_mode].refresh_rate : 0, ++ config->outputs[i].position_x, ++ config->outputs[i].position_y); ++ } ++} ++ ++static void ++xmir_update_config(xf86CrtcConfigPtr crtc_cfg) ++{ ++ MirDisplayConfiguration *new_config; ++ struct xmir_crtc *xmir_crtc = crtc_cfg->crtc[0]->driver_private; ++ ++ mir_display_config_destroy(xmir_crtc->config); ++ ++ new_config = mir_connection_create_display_config(xmir_connection_get()); ++ for (int i = 0; i < crtc_cfg->num_crtc; i++) { ++ xmir_crtc = crtc_cfg->crtc[i]->driver_private; ++ xmir_crtc-> config = new_config; ++ } ++ ++ if (crtc_cfg->num_output != new_config->num_outputs) ++ FatalError("[xmir] New Mir config has different number of outputs?"); ++ ++ for (int i = 0; i < crtc_cfg->num_output ; i++) { ++ /* TODO: Ensure that the order actually matches up */ ++ xmir_output_populate(crtc_cfg->output[i], new_config->outputs + i); ++ } ++} ++ +static Bool -+crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, -+ Rotation rotation, int x, int y) ++xmir_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, ++ Rotation rotation, int x, int y) +{ -+ return TRUE; ++ MirSurfaceParameters params = { ++ .name = "Xorg", ++ .width = mode->HDisplay, ++ .height = mode->VDisplay, ++ .pixel_format = mir_pixel_format_xrgb_8888, ++ .buffer_usage = mir_buffer_usage_hardware, ++ .output_id = mir_display_output_id_invalid ++ }; ++ BoxRec output_bounds = { ++ .x1 = x, ++ .y1 = y, ++ .x2 = x + mode->HDisplay, ++ .y2 = y + mode->VDisplay ++ }; ++ struct xmir_crtc *xmir_crtc = crtc->driver_private; ++ uint32_t output_id = mir_display_output_id_invalid; ++ MirSurface *surface; ++ const char *error_msg; ++ ++ if (mode->HDisplay == 0 || mode->VDisplay == 0) ++ return FALSE; ++ ++ xf86Msg(X_INFO, "Initial configuration:\n"); ++ xmir_dump_config(xmir_crtc->config); ++ ++ xf86Msg(X_INFO, "Setting mode to %dx%d (%.2f)", mode->HDisplay, mode->VDisplay, mode->VRefresh); ++ output_id = xmir_update_outputs_for_crtc(crtc, mode, x, y); ++ xmir_disable_unused_outputs(crtc); ++ ++ xf86Msg(X_INFO, "Updated configuration:\n"); ++ ++ xmir_dump_config(xmir_crtc->config); ++ mir_wait_for(mir_connection_apply_display_config(xmir_connection_get(), ++ xmir_crtc->config)); ++ error_msg = mir_connection_get_error_message(xmir_connection_get()); ++ if (*error_msg != '\0') { ++ xf86Msg(X_ERROR, "[xmir] Failed to set new display config: %s\n", ++ error_msg); ++ return FALSE; ++ /* TODO: Restore correct config cache */ ++ } ++ ++ xmir_update_config(XF86_CRTC_CONFIG_PTR(crtc->scrn)); ++ ++ xf86Msg(X_INFO, "Post-modeset config:\n"); ++ xmir_dump_config(xmir_crtc->config); ++ ++ if (xmir_crtc->root_fragment->surface != NULL) ++ mir_wait_for(mir_surface_release(xmir_crtc->root_fragment->surface, xmir_stupid_callback, NULL)); ++ ++ if (output_id == mir_display_output_id_invalid) { ++ xmir_crtc->root_fragment->surface = NULL; ++ return TRUE; ++ } ++ ++ params.output_id = output_id; ++ xf86Msg(X_INFO, "Putting surface on output %d\n", output_id); ++ surface = mir_connection_create_surface_sync(xmir_connection_get(), ++ ¶ms); ++ if (!mir_surface_is_valid(surface)) { ++ xf86Msg(X_ERROR, ++ "[xmir] Failed to create surface for %dx%d mode: %s\n", ++ mode->HDisplay, mode->VDisplay, ++ mir_surface_get_error_message(surface)); ++ return FALSE; ++ } ++ xmir_crtc->root_fragment->surface = surface; ++ ++ /* During X server init this will be NULL. ++ This is fixed up in xmir_window_create */ ++ xmir_crtc->root_fragment->win = xf86ScrnToScreen(crtc->scrn)->root; ++ ++ RegionInit(&xmir_crtc->root_fragment->region, &output_bounds, 0); ++ xmir_crtc->root_fragment->has_free_buffer = TRUE; ++ ++ return TRUE; +} + +static void @@ -306,13 +563,13 @@ Index: xserver/hw/xfree86/xmir/xmir-output.c +static PixmapPtr +crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) +{ -+ return NULL; ++ return NULL; +} + +static void * +crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) +{ -+ return NULL; ++ return NULL; +} + +static void @@ -320,9 +577,20 @@ Index: xserver/hw/xfree86/xmir/xmir-output.c +{ +} + ++static void ++xmir_crtc_destroy(xf86CrtcPtr crtc) ++{ ++ struct xmir_crtc *xmir_crtc = crtc->driver_private; ++ ++ if (xmir_crtc->root_fragment->surface != NULL) ++ mir_surface_release(xmir_crtc->root_fragment->surface, NULL, NULL); ++ ++ free(xmir_crtc); ++} ++ +static const xf86CrtcFuncsRec crtc_funcs = { + .dpms = crtc_dpms, -+ .set_mode_major = crtc_set_mode_major, ++ .set_mode_major = xmir_crtc_set_mode_major, + .set_cursor_colors = crtc_set_cursor_colors, + .set_cursor_position = crtc_set_cursor_position, + .show_cursor = crtc_show_cursor, @@ -331,134 +599,254 @@ Index: xserver/hw/xfree86/xmir/xmir-output.c + .shadow_create = crtc_shadow_create, + .shadow_allocate = crtc_shadow_allocate, + .shadow_destroy = crtc_shadow_destroy, -+ .destroy = NULL, /* XXX */ ++ .destroy = xmir_crtc_destroy, +}; + +static void -+output_dpms(xf86OutputPtr output, int mode) ++xmir_output_dpms(xf86OutputPtr output, int mode) +{ -+ return; ++ return; +} + +static xf86OutputStatus -+output_detect(xf86OutputPtr output) ++xmir_output_detect(xf86OutputPtr output) +{ -+ return XF86OutputStatusConnected; ++ MirDisplayOutput *mir_output = output->driver_private; ++ return mir_output->connected ? XF86OutputStatusConnected : XF86OutputStatusDisconnected; +} + +static Bool -+output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes) ++xmir_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes) +{ -+ return MODE_OK; ++ return MODE_OK; +} + -+struct mir_output { -+ int width; -+ int height; -+ xf86Monitor monitor; -+}; -+ +static DisplayModePtr -+output_get_modes(xf86OutputPtr xf86output) -+{ -+ struct mir_output *output = xf86output->driver_private; -+ struct monitor_ranges *ranges; -+ DisplayModePtr modes; -+ -+ modes = xf86CVTMode(output->width, output->height, 60, TRUE, FALSE); -+ /* And now, because CVT the CVT standard doesn't support such common resolutions as 1366x768... */ -+ /* TODO: We should really get Mir to just send us an EDID or at least enough info to generate one */ -+ modes->VDisplay = output->height; -+ modes->HDisplay = output->width; -+ -+ 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; -+ output->monitor.no_sections = 0; -+ modes->type = M_T_PREFERRED | M_T_DRIVER; -+ -+ modes->name = strdup("XMIR mode of death"); -+ -+ xf86output->MonInfo = &output->monitor; ++xmir_output_get_modes(xf86OutputPtr xf86output) ++{ ++ MirDisplayOutput *mir_output = xf86output->driver_private; ++ DisplayModePtr modes = NULL, mode = NULL; ++ ++ for (int i = 0; i < mir_output->num_modes; i++) { ++ /* Check if mode differs only by refresh rate from previous mode and reject */ ++ /* TODO: Remove this check and instead handle refresh rate correctly */ ++ if (mode != NULL) ++ if (xmir_mir_mode_matches((mir_output->modes + i), mode)) ++ continue; ++ ++ char *mode_name = malloc(32); ++ mode = xf86CVTMode(mir_output->modes[i].horizontal_resolution, ++ mir_output->modes[i].vertical_resolution, ++ 60.0f, ++ FALSE, FALSE); ++ /* And now, because the CVT standard doesn't support such common resolutions as 1366x768... */ ++ mode->VDisplay = mir_output->modes[i].vertical_resolution; ++ mode->HDisplay = mir_output->modes[i].horizontal_resolution; ++ ++ mode->type = M_T_DRIVER; ++ /* TODO: Get preferred mode from Mir, or get a guarantee that the first mode is preferred */ ++ if (i == 0) ++ mode->type |= M_T_PREFERRED; ++ ++ snprintf(mode_name, 32, "%dx%d", mode->HDisplay, mode->VDisplay); ++ mode->name = mode_name; ++ modes = xf86ModesAdd(modes, mode); ++ } ++ /* TODO: Get Mir to send us the EDID blob and add that */ + + return modes; +} + +static void -+output_destroy(xf86OutputPtr xf86output) ++xmir_output_destroy(xf86OutputPtr xf86output) +{ -+ struct mir_output *output = xf86output->driver_private; -+ -+ free(output); ++ /* The MirDisplayOutput* in driver_private gets cleaned up by ++ mir_display_config_destroy() */ +} + -+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 const xf86OutputFuncsRec xmir_output_funcs = { ++ .dpms = xmir_output_dpms, ++ .detect = xmir_output_detect, ++ .mode_valid = xmir_output_mode_valid, ++ .get_modes = xmir_output_get_modes, ++ .destroy = xmir_output_destroy ++}; ++ ++ ++struct xmir_visit_set_pixmap_window { ++ PixmapPtr old, new; +}; + ++static int ++xmir_visit_set_window_pixmap(WindowPtr window, pointer data) ++{ ++ struct xmir_visit_set_pixmap_window *visit = data; ++ ++ if (window->drawable.pScreen->GetWindowPixmap(window) == visit->old) { ++ window->drawable.pScreen->SetWindowPixmap(window, visit->new); ++ return WT_WALKCHILDREN; ++ } ++ ++ return WT_DONTWALKCHILDREN; ++} ++ ++static void ++xmir_set_screen_pixmap(PixmapPtr old_front, PixmapPtr new_front) ++{ ++ struct xmir_visit_set_pixmap_window visit = { ++ .old = old_front, ++ .new = new_front ++ }; ++ (old_front->drawable.pScreen->SetScreenPixmap)(new_front); ++ ++ TraverseTree(old_front->drawable.pScreen->root, &xmir_visit_set_window_pixmap, &visit); ++} ++ +static Bool -+resize(ScrnInfoPtr scrn, int width, int height) ++xmir_resize(ScrnInfoPtr scrn, int width, int height) +{ ++ xf86CrtcConfigPtr crtc_cfg = XF86_CRTC_CONFIG_PTR(scrn); ++ ScreenPtr screen = xf86ScrnToScreen(scrn); ++ PixmapPtr old_screen_pixmap, new_screen_pixmap; ++ + if (scrn->virtualX == width && scrn->virtualY == height) + return TRUE; -+ /* We don't handle resize at all, we must match the compositor size */ -+ return FALSE; ++ ++ old_screen_pixmap = screen->GetScreenPixmap(screen); ++ new_screen_pixmap = screen->CreatePixmap(screen, width, height, scrn->depth, ++ CREATE_PIXMAP_USAGE_BACKING_PIXMAP); ++ ++ if (!new_screen_pixmap) ++ return FALSE; ++ ++ scrn->virtualX = width; ++ scrn->virtualY = height; ++ scrn->displayWidth = width; ++ ++ for (int i = 0; i < crtc_cfg->num_crtc; i++) { ++ xf86CrtcPtr crtc = crtc_cfg->crtc[i]; ++ ++ if (!crtc->enabled) ++ continue; ++ ++ xmir_crtc_set_mode_major(crtc, &crtc->mode, ++ crtc->rotation, crtc->x, crtc->y); ++ } ++ ++ xmir_set_screen_pixmap(old_screen_pixmap, new_screen_pixmap); ++ screen->DestroyPixmap(old_screen_pixmap); ++ ++ xf86_reload_cursors(screen); ++ ++ return TRUE; +} + +static const xf86CrtcConfigFuncsRec config_funcs = { -+ resize ++ xmir_resize +}; + ++static void ++xmir_handle_hotplug(void *ctx) ++{ ++ ScrnInfoPtr scrn = *(ScrnInfoPtr *)ctx; ++ xf86CrtcConfigPtr crtc_config = XF86_CRTC_CONFIG_PTR(scrn); ++ ++ if (crtc_config->num_crtc == 0) ++ FatalError("[xmir] Received hotplug event, but have no CRTCs?\n"); ++ ++ xmir_update_config(crtc_config); ++ ++ /* Trigger RANDR refresh */ ++ RRGetInfo(xf86ScrnToScreen(scrn), TRUE); ++} ++ ++static void ++xmir_display_config_callback(MirConnection *unused, void *ctx) ++{ ++ xmir_screen *xmir = ctx; ++ ++ xmir_post_to_eventloop(xmir->hotplug_event_handler, &xmir->scrn); ++} ++ +Bool +xmir_mode_pre_init(ScrnInfoPtr scrn, xmir_screen *xmir) +{ -+ MirDisplayInfo display_info; -+ xf86OutputPtr xf86output; ++ int i; ++ MirDisplayConfiguration *display_config; + xf86CrtcPtr xf86crtc; -+ struct mir_output *output; + -+ mir_connection_get_display_info(xmir_connection_get(), &display_info); -+ + /* Set up CRTC config functions */ + xf86CrtcConfigInit(scrn, &config_funcs); + -+ /* We don't support resizing whatsoever */ ++ /* We don't scanout of a single surface, so we don't have a scanout limit */ + xf86CrtcSetSizeRange(scrn, + 320, 320, -+ 8192, 8192); ++ INT16_MAX, INT16_MAX); + -+ output = malloc(sizeof *output); -+ output->width = display_info.width; -+ output->height = display_info.height; -+ -+ xf86output = xf86OutputCreate(scrn, &output_funcs, "XMIR-1"); -+ xf86output->possible_crtcs = 1; -+ xf86output->possible_clones = 1; -+ xf86output->driver_private = output; + -+ xf86crtc = xf86CrtcCreate(scrn, &crtc_funcs); -+ xf86crtc->driver_private = NULL; ++ /* Hook up hotplug notification */ ++ xmir->hotplug_event_handler = ++ xmir_register_handler(&xmir_handle_hotplug, ++ sizeof (ScreenPtr)); ++ ++ mir_connection_set_display_config_change_callback( ++ xmir_connection_get(), ++ &xmir_display_config_callback, xmir); ++ ++ display_config = ++ mir_connection_create_display_config(xmir_connection_get()); ++ ++ xmir->root_window_fragments = malloc((display_config->num_outputs + 1) * ++ sizeof(xmir_window *)); ++ xmir->root_window_fragments[display_config->num_outputs] = NULL; ++ ++ if (xmir->root_window_fragments == NULL) ++ return FALSE; ++ ++ for (i = 0; i < display_config->num_outputs; i++) { ++ xf86OutputPtr xf86output; ++ char name[32]; ++ ++ snprintf(name, sizeof name, "XMIR-%d", i); ++ ++ xf86output = xf86OutputCreate(scrn, &xmir_output_funcs, name); ++ ++ xmir_output_populate(xf86output, display_config->outputs + i); ++ } ++ ++ /* TODO: Get the number of CRTCs from Mir */ ++ for (i = 0; i < display_config->num_outputs; i++) { ++ struct xmir_crtc *xmir_crtc = malloc(sizeof *xmir_crtc); ++ if (xmir_crtc == NULL) ++ return FALSE; ++ ++ xmir_crtc->xmir = xmir; ++ xmir_crtc->root_fragment = calloc(1, sizeof *xmir_crtc->root_fragment); ++ xmir_crtc->config = display_config; + ++ if (xmir_crtc->root_fragment == NULL) ++ return FALSE; ++ ++ xmir->root_window_fragments[i] = xmir_crtc->root_fragment; ++ RegionNull(&xmir_crtc->root_fragment->region); ++ ++ xf86crtc = xf86CrtcCreate(scrn, &crtc_funcs); ++ xf86crtc->driver_private = xmir_crtc; ++ } ++ ++ xf86SetScrnInfoModes(scrn); ++ ++ /* TODO: Use initial Mir state rather than setting up our own */ + xf86InitialConfiguration(scrn, TRUE); + + return TRUE; +} -Index: xserver/hw/xfree86/xmir/xmir-private.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ xserver/hw/xfree86/xmir/xmir-private.h 2013-08-22 15:18:34.429916132 +1000 -@@ -0,0 +1,90 @@ +diff --git a/hw/xfree86/xmir/xmir-private.h b/hw/xfree86/xmir/xmir-private.h +new file mode 100644 +index 0000000..a24afbf +--- /dev/null ++++ b/hw/xfree86/xmir/xmir-private.h +@@ -0,0 +1,104 @@ +/* + * Copyright © 2012 Canonical, Inc + * @@ -506,23 +894,27 @@ Index: xserver/hw/xfree86/xmir/xmir-private.h +typedef struct xmir_marshall_handler xmir_marshall_handler; + +struct xmir_screen { ++ ScrnInfoPtr scrn; + CreateWindowProcPtr CreateWindow; + DestroyWindowProcPtr DestroyWindow; + xmir_driver * driver; + xmir_marshall_handler *submit_rendering_handler; ++ xmir_marshall_handler *hotplug_event_handler; + struct xorg_list damage_list; ++ struct xmir_window **root_window_fragments; /* NULL terminated array of xmir_window * */ +}; + -+typedef struct { ++struct xmir_window { + WindowPtr win; + MirSurface *surface; -+ DamagePtr damage; ++ RegionRec region; + RegionRec past_damage[MIR_MAX_BUFFER_AGE]; ++ DamagePtr damage; + int damage_index; + struct xorg_list link_damage; + unsigned int has_free_buffer:1; + unsigned int damaged:1; -+} xmir_window; ++}; + +MirConnection * +xmir_connection_get(void); @@ -530,6 +922,16 @@ Index: xserver/hw/xfree86/xmir/xmir-private.h +xmir_screen * +xmir_screen_get(ScreenPtr screen); + ++xmir_window * ++xmir_window_get(WindowPtr win); ++ ++void ++xmir_window_enable_damage_tracking(xmir_window *xmir_win); ++ ++void ++xmir_window_disable_damage_tracking(xmir_window *xmir_win); ++ ++ +Bool +xmir_screen_init_window(ScreenPtr screen, xmir_screen *xmir); + @@ -549,10 +951,11 @@ Index: xserver/hw/xfree86/xmir/xmir-private.h +xmir_process_from_eventloop(void); + + #endif /* _MIR_PRIVATE_H */ -Index: xserver/hw/xfree86/xmir/xmir-thread-proxy.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ xserver/hw/xfree86/xmir/xmir-thread-proxy.c 2013-08-22 15:18:34.433916132 +1000 +diff --git a/hw/xfree86/xmir/xmir-thread-proxy.c b/hw/xfree86/xmir/xmir-thread-proxy.c +new file mode 100644 +index 0000000..7464644 +--- /dev/null ++++ b/hw/xfree86/xmir/xmir-thread-proxy.c @@ -0,0 +1,117 @@ +/* + * Copyright © 2012 Canonical, Inc @@ -671,11 +1074,12 @@ Index: xserver/hw/xfree86/xmir/xmir-thread-proxy.c + } +} + -Index: xserver/hw/xfree86/xmir/xmir-window.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ xserver/hw/xfree86/xmir/xmir-window.c 2013-08-22 15:19:20.877917729 +1000 -@@ -0,0 +1,326 @@ +diff --git a/hw/xfree86/xmir/xmir-window.c b/hw/xfree86/xmir/xmir-window.c +new file mode 100644 +index 0000000..89c5448 +--- /dev/null ++++ b/hw/xfree86/xmir/xmir-window.c +@@ -0,0 +1,340 @@ +/* + * Copyright © 2012 Canonical, Inc + * @@ -722,26 +1126,31 @@ Index: xserver/hw/xfree86/xmir/xmir-window.c +#include "xf86.h" + +#include <stdlib.h> ++#include <unistd.h> + +static DevPrivateKeyRec xmir_window_private_key; +static const RegionRec xmir_empty_region = { {0, 0, 0, 0}, &RegionBrokenData }; + -+static xmir_window * ++xmir_window * +xmir_window_get(WindowPtr win) +{ ++ /* The root window is handled specially */ ++ assert(win->parent != NULL); ++ + return dixGetPrivate(&win->devPrivates, &xmir_window_private_key); +} + +_X_EXPORT int -+xmir_prime_fd_for_window(WindowPtr win) ++xmir_window_get_fd(xmir_window *xmir_win) +{ -+ xmir_window *xmir_win = xmir_window_get(win); + MirBufferPackage *package; + -+ assert(mir_platform_type_gbm == mir_surface_get_platform_type(xmir_win->surface)); ++ if (mir_platform_type_gbm != mir_surface_get_platform_type(xmir_win->surface)) ++ FatalError("[xmir] Only supported on DRM Mir platform\n"); + + mir_surface_get_current_buffer(xmir_win->surface, &package); -+ assert(package->fd_items == 1); ++ if (package->fd_items != 1) -- To UNSUBSCRIBE, email to [email protected] with a subject of "unsubscribe". Trouble? Contact [email protected] Archive: http://lists.debian.org/[email protected]

