diff options
Diffstat (limited to 'xorg-server')
31 files changed, 3368 insertions, 2516 deletions
diff --git a/xorg-server/configure.ac b/xorg-server/configure.ac index 655c0e4ba..22566c9ef 100644 --- a/xorg-server/configure.ac +++ b/xorg-server/configure.ac @@ -26,16 +26,16 @@ dnl dnl Process this file with autoconf to create configure. AC_PREREQ(2.57) -AC_INIT([xorg-server], 1.10.99.1, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server) -RELEASE_DATE="unreleased" +AC_INIT([xorg-server], 1.10.99.901, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server) +RELEASE_DATE="2011-06-01" AC_CONFIG_SRCDIR([Makefile.am]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) AM_MAINTAINER_MODE -# Require xorg-macros minimum of 1.13 for XORG_ENABLE_UNIT_TESTS +# Require xorg-macros minimum of 1.14 for XORG_COMPILER_BRAND in XORG_DEFAULT_OPTIONS m4_ifndef([XORG_MACROS_VERSION], - [m4_fatal([must install xorg-macros 1.13 or later before running autoconf/autogen])]) -XORG_MACROS_VERSION(1.13) + [m4_fatal([must install xorg-macros 1.14 or later before running autoconf/autogen])]) +XORG_MACROS_VERSION(1.14) XORG_DEFAULT_OPTIONS XORG_WITH_DOXYGEN(1.6.1) XORG_CHECK_SGML_DOCTOOLS(1.7) @@ -810,7 +810,7 @@ dnl specific modules against it PKG_CHECK_MODULES(PIXMAN, $LIBPIXMAN) REQUIRED_LIBS="$REQUIRED_LIBS $LIBPIXMAN $LIBXFONT xau" -REQUIRED_MODULES="[fixesproto >= 4.1] [damageproto >= 1.1] [xcmiscproto >= 1.2.0] [xtrans >= 1.2.2] [bigreqsproto >= 1.1.0] $SDK_REQUIRED_MODULES" +REQUIRED_MODULES="[fixesproto >= 5.0] [damageproto >= 1.1] [xcmiscproto >= 1.2.0] [xtrans >= 1.2.2] [bigreqsproto >= 1.1.0] $SDK_REQUIRED_MODULES" if test "x$CONFIG_UDEV" = xyes && { test "x$CONFIG_DBUS_API" = xyes || test "x$CONFIG_HAL" = xyes; }; then @@ -1522,7 +1522,6 @@ if test "x$XORG" = xyes; then if test x$GCC = xyes; then VISIBILITY_CFLAGS="-fvisibility=hidden" else - AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"]) if test x$SUNCC = xyes; then VISIBILITY_CFLAGS="-xldscope=hidden" else @@ -1631,7 +1630,6 @@ if test "x$XORG" = xyes; then if test "${OS_MINOR}" -lt 8 ; then AC_MSG_ERROR([This release no longer supports Solaris versions older than Solaris 8.]) fi - AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"]) if test "x$SUNCC" = "xyes"; then solaris_asm_inline="yes" fi diff --git a/xorg-server/dix/main.c b/xorg-server/dix/main.c index bc958b896..955b7ea9e 100644 --- a/xorg-server/dix/main.c +++ b/xorg-server/dix/main.c @@ -139,8 +139,6 @@ int main(int argc, char *argv[], char *envp[]) InitRegions(); - pixman_disable_out_of_bounds_workaround(); - CheckUserParameters(argc, argv, envp); CheckUserAuthorization(); diff --git a/xorg-server/dix/window.c b/xorg-server/dix/window.c index cd28d054a..5defe5849 100644 --- a/xorg-server/dix/window.c +++ b/xorg-server/dix/window.c @@ -475,6 +475,7 @@ InitRootWindow(WindowPtr pWin) pWin->background.pixel = pScreen->whitePixel; backFlag |= CWBackPixmap; } else { + pWin->backgroundState = BackgroundPixel; if (whiteRoot) pWin->background.pixel = pScreen->whitePixel; else @@ -973,6 +974,7 @@ SetRootWindowBackground(WindowPtr pWin, ScreenPtr pScreen, Mask *index2) else if (party_like_its_1989) MakeRootTile(pWin); else { + pWin->backgroundState = BackgroundPixel; if (whiteRoot) pWin->background.pixel = pScreen->whitePixel; else diff --git a/xorg-server/hw/xquartz/GL/indirect.c b/xorg-server/hw/xquartz/GL/indirect.c index 6da27c78a..c41840bee 100644 --- a/xorg-server/hw/xquartz/GL/indirect.c +++ b/xorg-server/hw/xquartz/GL/indirect.c @@ -155,12 +155,8 @@ typedef long long GLint64EXT; __GLXprovider * GlxGetDRISWrastProvider (void); -// Write debugging output, or not -#ifdef GLAQUA_DEBUG -#define GLAQUA_DEBUG_MSG ErrorF -#else -#define GLAQUA_DEBUG_MSG(a, ...) -#endif +#include "darwin.h" +#define GLAQUA_DEBUG_MSG(msg, args...) ASL_LOG(ASL_LEVEL_DEBUG, "GLXAqua", msg, ##args) static void setup_dispatch_table(void); GLuint __glFloorLog2(GLuint val); @@ -666,7 +662,15 @@ GLuint __glFloorLog2(GLuint val) } static void setup_dispatch_table(void) { - struct _glapi_table *disp=_glapi_get_dispatch(); + static struct _glapi_table *disp = NULL; + + if(disp) { + _glapi_set_dispatch(disp); + return; + } + + disp=calloc(1,sizeof(struct _glapi_table)); + assert(disp); /* to update: * for f in $(grep 'define SET_' ../../../glx/dispatch.h | cut -f2 -d' ' | cut -f1 -d\( | sort -u); do grep -q $f indirect.c || echo $f ; done | grep -v by_offset | sed 's:SET_\(.*\)$:SET_\1(disp, gl\1)\;:' | pbcopy @@ -1610,4 +1614,6 @@ static void setup_dispatch_table(void) { SET_PixelTexGenParameterivSGIS(disp, glPixelTexGenParameterivSGIS); SET_PixelTexGenSGIX(disp, glPixelTexGenSGIX); #endif + + _glapi_set_dispatch(disp); } diff --git a/xorg-server/hw/xquartz/X11Application.m b/xorg-server/hw/xquartz/X11Application.m index 7c41cbcb5..a51ee828d 100644 --- a/xorg-server/hw/xquartz/X11Application.m +++ b/xorg-server/hw/xquartz/X11Application.m @@ -188,7 +188,7 @@ static void message_kit_thread (SEL selector, NSObject *arg) { - (void) activateX:(OSX_BOOL)state { size_t i; - DEBUG_LOG("state=%d, _x_active=%d, \n", state, _x_active) + DEBUG_LOG("state=%d, _x_active=%d, \n", state, _x_active); if (state) { if(bgMouseLocationUpdated) { DarwinSendPointerEvents(darwinPointer, MotionNotify, 0, bgMouseLocation.x, bgMouseLocation.y, 0.0, 0.0, 0.0); diff --git a/xorg-server/hw/xquartz/darwin.c b/xorg-server/hw/xquartz/darwin.c index fa8d4ced2..29ab83677 100644 --- a/xorg-server/hw/xquartz/darwin.c +++ b/xorg-server/hw/xquartz/darwin.c @@ -79,7 +79,7 @@ aslclient aslc; -void debug_asl (const char *file, const char *function, int line, const char *fmt, ...) { +void xq_asl_log (int level, const char *subsystem, const char *file, const char *function, int line, const char *fmt, ...) { va_list args; aslmsg msg = asl_new(ASL_TYPE_MSG); @@ -93,10 +93,12 @@ void debug_asl (const char *file, const char *function, int line, const char *fm asl_set(msg, "Line", _line); free(_line); } + if(subsystem) + asl_set(msg, "Subsystem", subsystem); } va_start(args, fmt); - asl_vlog(aslc, msg, ASL_LEVEL_DEBUG, fmt, args); + asl_vlog(aslc, msg, level, fmt, args); va_end(args); if(msg) diff --git a/xorg-server/hw/xquartz/darwin.h b/xorg-server/hw/xquartz/darwin.h index 659de432c..aafc12fbf 100644 --- a/xorg-server/hw/xquartz/darwin.h +++ b/xorg-server/hw/xquartz/darwin.h @@ -76,9 +76,11 @@ extern int darwinMainScreenY; // bundle-main.c extern char *bundle_id_prefix; -extern void debug_asl (const char *file, const char *function, int line, const char *fmt, ...) _X_ATTRIBUTE_PRINTF(4,5); +_X_ATTRIBUTE_PRINTF(6,7) +extern void xq_asl_log (int level, const char *subsystem, const char *file, const char *function, int line, const char *fmt, ...); -#define DEBUG_LOG(msg, args...) debug_asl(__FILE__, __FUNCTION__, __LINE__, msg, ##args); +#define ASL_LOG(level, subsystem, msg, args...) xq_asl_log(level, subsystem, __FILE__, __FUNCTION__, __LINE__, msg, ##args) +#define DEBUG_LOG(msg, args...) ASL_LOG(ASL_LEVEL_DEBUG, "XQuartz", msg, ##args) #define TRACE() DEBUG_LOG("TRACE") #endif /* _DARWIN_H */ diff --git a/xorg-server/hw/xquartz/mach-startup/Makefile.am b/xorg-server/hw/xquartz/mach-startup/Makefile.am index 1ce54ad86..4b7b2bce3 100644 --- a/xorg-server/hw/xquartz/mach-startup/Makefile.am +++ b/xorg-server/hw/xquartz/mach-startup/Makefile.am @@ -22,9 +22,10 @@ X11_bin_LDADD = \ $(top_builddir)/dix/dixfonts.lo \ $(top_builddir)/miext/rootless/librootless.la \ $(top_builddir)/hw/xquartz/pbproxy/libxpbproxy.la \ - $(DARWIN_LIBS) $(MAIN_LIB) $(XSERVER_LIBS) $(XSERVER_SYS_LIBS) -lXplugin + $(DARWIN_LIBS) $(MAIN_LIB) $(XSERVER_LIBS) X11_bin_LDFLAGS = \ + $(XSERVER_SYS_LIBS) -lXplugin \ -XCClinker -Objc \ -Wl,-u,_miDCInitialize \ -Wl,-framework,Carbon \ diff --git a/xorg-server/hw/xquartz/pbproxy/app-main.m b/xorg-server/hw/xquartz/pbproxy/app-main.m index a8c3a6055..772c458a1 100644 --- a/xorg-server/hw/xquartz/pbproxy/app-main.m +++ b/xorg-server/hw/xquartz/pbproxy/app-main.m @@ -63,6 +63,17 @@ ErrorF(const char * f, ...) va_end(args); } +/* TODO: Have this actually log to ASL */ +void xq_asl_log (int level, const char *subsystem, const char *file, const char *function, int line, const char *fmt, ...) { +#ifdef DEBUG + va_list args; + + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); +#endif +} + int main (int argc, const char *argv[]) { const char *s; int i; diff --git a/xorg-server/hw/xquartz/pbproxy/pbproxy.h b/xorg-server/hw/xquartz/pbproxy/pbproxy.h index fcbf4c4ba..c80a660cc 100644 --- a/xorg-server/hw/xquartz/pbproxy/pbproxy.h +++ b/xorg-server/hw/xquartz/pbproxy/pbproxy.h @@ -32,6 +32,8 @@ #import <Foundation/Foundation.h> +#include <asl.h> + #include <AvailabilityMacros.h> #if MAC_OS_X_VERSION_MIN_REQUIRED < 1050 #if __LP64__ || NS_BUILD_32_LIKE_64 @@ -80,13 +82,12 @@ extern BOOL xpbproxy_input_register (void); /* os/log.c or app-main.m */ extern void ErrorF(const char *f, ...) _X_ATTRIBUTE_PRINTF(1,2); -#ifdef DEBUG -/* BEWARE: this can cause a string memory leak, according to the leaks program. */ -# define DebugF(msg, args...) ErrorF("%s:%s:%d " msg, __FILE__, __FUNCTION__, __LINE__, ##args) -#else -# define DebugF(...) /* */ -#endif +/* from darwin.h */ +_X_ATTRIBUTE_PRINTF(6,7) +extern void xq_asl_log (int level, const char *subsystem, const char *file, const char *function, int line, const char *fmt, ...); -#define TRACE() DebugF("TRACE\n") +#define ASL_LOG(level, subsystem, msg, args...) xq_asl_log(level, subsystem, __FILE__, __FUNCTION__, __LINE__, msg, ##args) +#define DebugF(msg, args...) ASL_LOG(ASL_LEVEL_DEBUG, "xpbproxy", msg, ##args) +#define TRACE() DebugF("TRACE") #endif /* PBPROXY_H */ diff --git a/xorg-server/hw/xquartz/pbproxy/x-selection.m b/xorg-server/hw/xquartz/pbproxy/x-selection.m index 7964f5193..b5f4dde5c 100644 --- a/xorg-server/hw/xquartz/pbproxy/x-selection.m +++ b/xorg-server/hw/xquartz/pbproxy/x-selection.m @@ -683,7 +683,11 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato return; } +#ifdef __LP64__ + DebugF ("pbtypes retainCount after containsObject: %lu\n", [pbtypes retainCount]); +#else DebugF ("pbtypes retainCount after containsObject: %u\n", [pbtypes retainCount]); +#endif data = [pb stringForType:NSStringPboardType]; @@ -704,7 +708,11 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato if (length < 50) { DebugF ("UTF-8: %s\n", bytes); +#ifdef __LP64__ + DebugF ("UTF-8 length: %lu\n", length); +#else DebugF ("UTF-8 length: %u\n", length); +#endif } } else @@ -1223,8 +1231,13 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato return; } +#ifdef __LP64__ + DebugF ("data retainCount before NSBitmapImageRep initWithData: %lu\n", + [data retainCount]); +#else DebugF ("data retainCount before NSBitmapImageRep initWithData: %u\n", [data retainCount]); +#endif bmimage = [[NSBitmapImageRep alloc] initWithData:data]; @@ -1235,8 +1248,13 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato return; } +#ifdef __LP64__ + DebugF ("data retainCount after NSBitmapImageRep initWithData: %lu\n", + [data retainCount]); +#else DebugF ("data retainCount after NSBitmapImageRep initWithData: %u\n", [data retainCount]); +#endif @try { @@ -1251,7 +1269,11 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato return; } +#ifdef __LP64__ + DebugF ("bmimage retainCount after TIFFRepresentation %lu\n", [bmimage retainCount]); +#else DebugF ("bmimage retainCount after TIFFRepresentation %u\n", [bmimage retainCount]); +#endif pbtypes = [NSArray arrayWithObjects:NSTIFFPboardType, nil]; @@ -1270,7 +1292,12 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato [data autorelease]; +#ifdef __LP64__ + DebugF ("bmimage retainCount before release %lu\n", [bmimage retainCount]); +#else DebugF ("bmimage retainCount before release %u\n", [bmimage retainCount]); +#endif + [bmimage autorelease]; } diff --git a/xorg-server/hw/xquartz/xpr/xpr.h b/xorg-server/hw/xquartz/xpr/xpr.h index ebd89de3a..0b138ddd7 100644 --- a/xorg-server/hw/xquartz/xpr/xpr.h +++ b/xorg-server/hw/xquartz/xpr/xpr.h @@ -33,6 +33,11 @@ #include "screenint.h" #include <Xplugin.h> +#include "darwin.h" + +#undef DEBUG_LOG +#define DEBUG_LOG(msg, args...) ASL_LOG(ASL_LEVEL_DEBUG, "xpr", msg, ##args) + Bool QuartzModeBundleInit(void); void AppleDRIExtensionInit(void); diff --git a/xorg-server/hw/xquartz/xpr/xprCursor.c b/xorg-server/hw/xquartz/xpr/xprCursor.c index 4a789cef4..2b31865a5 100644 --- a/xorg-server/hw/xquartz/xpr/xprCursor.c +++ b/xorg-server/hw/xquartz/xpr/xprCursor.c @@ -1,424 +1,423 @@ -/**************************************************************
- *
- * Xplugin cursor support
- *
- * Copyright (c) 2001 Torrey T. Lyons and Greg Parker.
- * Copyright (c) 2002 Apple Computer, Inc.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name(s) of the above copyright
- * holders shall not be used in advertising or otherwise to promote the sale,
- * use or other dealings in this Software without prior written authorization.
- */
-
-#include "sanitizedCarbon.h"
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "quartz.h"
-#include "xpr.h"
-#include "darwin.h"
-#include "darwinEvents.h"
-#include <Xplugin.h>
-
-#include "mi.h"
-#include "scrnintstr.h"
-#include "cursorstr.h"
-#include "mipointrst.h"
-#include "windowstr.h"
-#include "globals.h"
-#include "servermd.h"
-#include "dixevents.h"
-#include "x-hash.h"
-
-typedef struct {
- int cursorVisible;
- QueryBestSizeProcPtr QueryBestSize;
- miPointerSpriteFuncPtr spriteFuncs;
-} QuartzCursorScreenRec, *QuartzCursorScreenPtr;
-
-static DevPrivateKeyRec darwinCursorScreenKeyRec;
-#define darwinCursorScreenKey (&darwinCursorScreenKeyRec)
-
-#define CURSOR_PRIV(pScreen) ((QuartzCursorScreenPtr) \
- dixLookupPrivate(&pScreen->devPrivates, darwinCursorScreenKey))
-
-static Bool
-load_cursor(CursorPtr src, int screen)
-{
- uint32_t *data;
- Bool free_data = FALSE;
- uint32_t rowbytes;
- int width, height;
- int hot_x, hot_y;
-
- uint32_t fg_color, bg_color;
- uint8_t *srow, *sptr;
- uint8_t *mrow, *mptr;
- uint32_t *drow, *dptr;
- unsigned xcount, ycount;
-
- xp_error err;
-
- width = src->bits->width;
- height = src->bits->height;
- hot_x = src->bits->xhot;
- hot_y = src->bits->yhot;
-
-#ifdef ARGB_CURSOR
- if (src->bits->argb != NULL)
- {
-#if BITMAP_BIT_ORDER == MSBFirst
- rowbytes = src->bits->width * sizeof (CARD32);
- data = (uint32_t *) src->bits->argb;
-#else
- const uint32_t *be_data=(uint32_t *) src->bits->argb;
- unsigned i;
- rowbytes = src->bits->width * sizeof (CARD32);
- data = malloc(rowbytes * src->bits->height);
- free_data = TRUE;
- if(!data) {
- FatalError("Failed to allocate memory in %s\n", __func__);
- }
- for(i=0;i<(src->bits->width*src->bits->height);i++)
- data[i]=ntohl(be_data[i]);
-#endif
- }
- else
-#endif
- {
- fg_color = 0xFF00 | (src->foreRed >> 8);
- fg_color <<= 16;
- fg_color |= src->foreGreen & 0xFF00;
- fg_color |= src->foreBlue >> 8;
-
- bg_color = 0xFF00 | (src->backRed >> 8);
- bg_color <<= 16;
- bg_color |= src->backGreen & 0xFF00;
- bg_color |= src->backBlue >> 8;
-
- fg_color = htonl(fg_color);
- bg_color = htonl(bg_color);
-
- /* round up to 8 pixel boundary so we can convert whole bytes */
- rowbytes = ((src->bits->width * 4) + 31) & ~31;
- data = malloc(rowbytes * src->bits->height);
- free_data = TRUE;
- if(!data) {
- FatalError("Failed to allocate memory in %s\n", __func__);
- }
-
- if (!src->bits->emptyMask)
- {
- ycount = src->bits->height;
- srow = src->bits->source; mrow = src->bits->mask;
- drow = data;
-
- while (ycount-- > 0)
- {
- xcount = bits_to_bytes(src->bits->width);
- sptr = srow; mptr = mrow;
- dptr = drow;
-
- while (xcount-- > 0)
- {
- uint8_t s, m;
- int i;
-
- s = *sptr++; m = *mptr++;
- for (i = 0; i < 8; i++)
- {
-#if BITMAP_BIT_ORDER == MSBFirst
- if (m & 128)
- *dptr++ = (s & 128) ? fg_color : bg_color;
- else
- *dptr++ = 0;
- s <<= 1; m <<= 1;
-#else
- if (m & 1)
- *dptr++ = (s & 1) ? fg_color : bg_color;
- else
- *dptr++ = 0;
- s >>= 1; m >>= 1;
-#endif
- }
- }
-
- srow += BitmapBytePad(src->bits->width);
- mrow += BitmapBytePad(src->bits->width);
- drow = (uint32_t *) ((char *) drow + rowbytes);
- }
- }
- else
- {
- memset(data, 0, src->bits->height * rowbytes);
- }
- }
-
- err = xp_set_cursor(width, height, hot_x, hot_y, data, rowbytes);
- if(free_data)
- free(data);
- return err == Success;
-}
-
-
-/*
-===========================================================================
-
- Pointer sprite functions
-
-===========================================================================
-*/
-
-/*
- * QuartzRealizeCursor
- * Convert the X cursor representation to native format if possible.
- */
-static Bool
-QuartzRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
-{
- if(pCursor == NULL || pCursor->bits == NULL)
- return FALSE;
-
- /* FIXME: cache ARGB8888 representation? */
-
- return TRUE;
-}
-
-
-/*
- * QuartzUnrealizeCursor
- * Free the storage space associated with a realized cursor.
- */
-static Bool
-QuartzUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
-{
- return TRUE;
-}
-
-
-/*
- * QuartzSetCursor
- * Set the cursor sprite and position.
- */
-static void
-QuartzSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
-{
- QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
-
- if (!XQuartzServerVisible)
- return;
-
- if (pCursor == NULL)
- {
- if (ScreenPriv->cursorVisible)
- {
- xp_hide_cursor();
- ScreenPriv->cursorVisible = FALSE;
- }
- }
- else
- {
- load_cursor(pCursor, pScreen->myNum);
-
- if (!ScreenPriv->cursorVisible)
- {
- xp_show_cursor();
- ScreenPriv->cursorVisible = TRUE;
- }
- }
-}
-
-/*
- * QuartzMoveCursor
- * Move the cursor. This is a noop for us.
- */
-static void
-QuartzMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
-{
-}
-
-/*
-===========================================================================
-
- Pointer screen functions
-
-===========================================================================
-*/
-
-/*
- * QuartzCursorOffScreen
- */
-static Bool
-QuartzCursorOffScreen(ScreenPtr *pScreen, int *x, int *y)
-{
- return FALSE;
-}
-
-
-/*
- * QuartzCrossScreen
- */
-static void
-QuartzCrossScreen(ScreenPtr pScreen, Bool entering)
-{
- return;
-}
-
-
-/*
- * QuartzWarpCursor
- * Change the cursor position without generating an event or motion history.
- * The input coordinates (x,y) are in pScreen-local X11 coordinates.
- *
- */
-static void
-QuartzWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
-{
- if (XQuartzServerVisible)
- {
- int sx, sy;
-
- sx = pScreen->x + darwinMainScreenX;
- sy = pScreen->y + darwinMainScreenY;
-
- CGWarpMouseCursorPosition(CGPointMake(sx + x, sy + y));
- }
-
- miPointerWarpCursor(pDev, pScreen, x, y);
- miPointerUpdateSprite(pDev);
-}
-
-
-static miPointerScreenFuncRec quartzScreenFuncsRec = {
- QuartzCursorOffScreen,
- QuartzCrossScreen,
- QuartzWarpCursor,
- NULL,
- NULL
-};
-
-
-/*
-===========================================================================
-
- Other screen functions
-
-===========================================================================
-*/
-
-/*
- * QuartzCursorQueryBestSize
- * Handle queries for best cursor size
- */
-static void
-QuartzCursorQueryBestSize(int class, unsigned short *width,
- unsigned short *height, ScreenPtr pScreen)
-{
- QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
-
- if (class == CursorShape)
- {
- /* FIXME: query window server? */
- *width = 32;
- *height = 32;
- }
- else
- {
- (*ScreenPriv->QueryBestSize)(class, width, height, pScreen);
- }
-}
-
-/*
- * QuartzInitCursor
- * Initialize cursor support
- */
-Bool
-QuartzInitCursor(ScreenPtr pScreen)
-{
- QuartzCursorScreenPtr ScreenPriv;
- miPointerScreenPtr PointPriv;
-
- /* initialize software cursor handling (always needed as backup) */
- if (!miDCInitialize(pScreen, &quartzScreenFuncsRec))
- return FALSE;
-
- if (!dixRegisterPrivateKey(&darwinCursorScreenKeyRec, PRIVATE_SCREEN, 0))
- return FALSE;
-
- ScreenPriv = calloc(1, sizeof(QuartzCursorScreenRec));
- if (ScreenPriv == NULL)
- return FALSE;
-
- /* CURSOR_PRIV(pScreen) = ScreenPriv; */
- dixSetPrivate(&pScreen->devPrivates, darwinCursorScreenKey, ScreenPriv);
-
- /* override some screen procedures */
- ScreenPriv->QueryBestSize = pScreen->QueryBestSize;
- pScreen->QueryBestSize = QuartzCursorQueryBestSize;
-
- PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
-
- ScreenPriv->spriteFuncs = PointPriv->spriteFuncs;
-
- PointPriv->spriteFuncs->RealizeCursor = QuartzRealizeCursor;
- PointPriv->spriteFuncs->UnrealizeCursor = QuartzUnrealizeCursor;
- PointPriv->spriteFuncs->SetCursor = QuartzSetCursor;
- PointPriv->spriteFuncs->MoveCursor = QuartzMoveCursor;
-
- ScreenPriv->cursorVisible = TRUE;
- return TRUE;
-}
-
-/*
- * QuartzSuspendXCursor
- * X server is hiding. Restore the Aqua cursor.
- */
-void
-QuartzSuspendXCursor(ScreenPtr pScreen)
-{
-}
-
-
-/*
- * QuartzResumeXCursor
- * X server is showing. Restore the X cursor.
- */
-void
-QuartzResumeXCursor(ScreenPtr pScreen)
-{
- WindowPtr pWin;
- CursorPtr pCursor;
-
- /* TODO: Tablet? */
-
- pWin = GetSpriteWindow(darwinPointer);
- if (pWin->drawable.pScreen != pScreen)
- return;
-
- pCursor = GetSpriteCursor(darwinPointer);
- if (pCursor == NULL)
- return;
-
- QuartzSetCursor(darwinPointer, pScreen, pCursor, /* x */ 0, /* y */ 0);
-}
+/************************************************************** + * + * Xplugin cursor support + * + * Copyright (c) 2001 Torrey T. Lyons and Greg Parker. + * Copyright (c) 2002 Apple Computer, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name(s) of the above copyright + * holders shall not be used in advertising or otherwise to promote the sale, + * use or other dealings in this Software without prior written authorization. + */ + +#include "sanitizedCarbon.h" + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "quartz.h" +#include "xpr.h" +#include "darwinEvents.h" +#include <Xplugin.h> + +#include "mi.h" +#include "scrnintstr.h" +#include "cursorstr.h" +#include "mipointrst.h" +#include "windowstr.h" +#include "globals.h" +#include "servermd.h" +#include "dixevents.h" +#include "x-hash.h" + +typedef struct { + int cursorVisible; + QueryBestSizeProcPtr QueryBestSize; + miPointerSpriteFuncPtr spriteFuncs; +} QuartzCursorScreenRec, *QuartzCursorScreenPtr; + +static DevPrivateKeyRec darwinCursorScreenKeyRec; +#define darwinCursorScreenKey (&darwinCursorScreenKeyRec) + +#define CURSOR_PRIV(pScreen) ((QuartzCursorScreenPtr) \ + dixLookupPrivate(&pScreen->devPrivates, darwinCursorScreenKey)) + +static Bool +load_cursor(CursorPtr src, int screen) +{ + uint32_t *data; + Bool free_data = FALSE; + uint32_t rowbytes; + int width, height; + int hot_x, hot_y; + + uint32_t fg_color, bg_color; + uint8_t *srow, *sptr; + uint8_t *mrow, *mptr; + uint32_t *drow, *dptr; + unsigned xcount, ycount; + + xp_error err; + + width = src->bits->width; + height = src->bits->height; + hot_x = src->bits->xhot; + hot_y = src->bits->yhot; + +#ifdef ARGB_CURSOR + if (src->bits->argb != NULL) + { +#if BITMAP_BIT_ORDER == MSBFirst + rowbytes = src->bits->width * sizeof (CARD32); + data = (uint32_t *) src->bits->argb; +#else + const uint32_t *be_data=(uint32_t *) src->bits->argb; + unsigned i; + rowbytes = src->bits->width * sizeof (CARD32); + data = malloc(rowbytes * src->bits->height); + free_data = TRUE; + if(!data) { + FatalError("Failed to allocate memory in %s\n", __func__); + } + for(i=0;i<(src->bits->width*src->bits->height);i++) + data[i]=ntohl(be_data[i]); +#endif + } + else +#endif + { + fg_color = 0xFF00 | (src->foreRed >> 8); + fg_color <<= 16; + fg_color |= src->foreGreen & 0xFF00; + fg_color |= src->foreBlue >> 8; + + bg_color = 0xFF00 | (src->backRed >> 8); + bg_color <<= 16; + bg_color |= src->backGreen & 0xFF00; + bg_color |= src->backBlue >> 8; + + fg_color = htonl(fg_color); + bg_color = htonl(bg_color); + + /* round up to 8 pixel boundary so we can convert whole bytes */ + rowbytes = ((src->bits->width * 4) + 31) & ~31; + data = malloc(rowbytes * src->bits->height); + free_data = TRUE; + if(!data) { + FatalError("Failed to allocate memory in %s\n", __func__); + } + + if (!src->bits->emptyMask) + { + ycount = src->bits->height; + srow = src->bits->source; mrow = src->bits->mask; + drow = data; + + while (ycount-- > 0) + { + xcount = bits_to_bytes(src->bits->width); + sptr = srow; mptr = mrow; + dptr = drow; + + while (xcount-- > 0) + { + uint8_t s, m; + int i; + + s = *sptr++; m = *mptr++; + for (i = 0; i < 8; i++) + { +#if BITMAP_BIT_ORDER == MSBFirst + if (m & 128) + *dptr++ = (s & 128) ? fg_color : bg_color; + else + *dptr++ = 0; + s <<= 1; m <<= 1; +#else + if (m & 1) + *dptr++ = (s & 1) ? fg_color : bg_color; + else + *dptr++ = 0; + s >>= 1; m >>= 1; +#endif + } + } + + srow += BitmapBytePad(src->bits->width); + mrow += BitmapBytePad(src->bits->width); + drow = (uint32_t *) ((char *) drow + rowbytes); + } + } + else + { + memset(data, 0, src->bits->height * rowbytes); + } + } + + err = xp_set_cursor(width, height, hot_x, hot_y, data, rowbytes); + if(free_data) + free(data); + return err == Success; +} + + +/* +=========================================================================== + + Pointer sprite functions + +=========================================================================== +*/ + +/* + * QuartzRealizeCursor + * Convert the X cursor representation to native format if possible. + */ +static Bool +QuartzRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) +{ + if(pCursor == NULL || pCursor->bits == NULL) + return FALSE; + + /* FIXME: cache ARGB8888 representation? */ + + return TRUE; +} + + +/* + * QuartzUnrealizeCursor + * Free the storage space associated with a realized cursor. + */ +static Bool +QuartzUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) +{ + return TRUE; +} + + +/* + * QuartzSetCursor + * Set the cursor sprite and position. + */ +static void +QuartzSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x, int y) +{ + QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen); + + if (!XQuartzServerVisible) + return; + + if (pCursor == NULL) + { + if (ScreenPriv->cursorVisible) + { + xp_hide_cursor(); + ScreenPriv->cursorVisible = FALSE; + } + } + else + { + load_cursor(pCursor, pScreen->myNum); + + if (!ScreenPriv->cursorVisible) + { + xp_show_cursor(); + ScreenPriv->cursorVisible = TRUE; + } + } +} + +/* + * QuartzMoveCursor + * Move the cursor. This is a noop for us. + */ +static void +QuartzMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) +{ +} + +/* +=========================================================================== + + Pointer screen functions + +=========================================================================== +*/ + +/* + * QuartzCursorOffScreen + */ +static Bool +QuartzCursorOffScreen(ScreenPtr *pScreen, int *x, int *y) +{ + return FALSE; +} + + +/* + * QuartzCrossScreen + */ +static void +QuartzCrossScreen(ScreenPtr pScreen, Bool entering) +{ + return; +} + + +/* + * QuartzWarpCursor + * Change the cursor position without generating an event or motion history. + * The input coordinates (x,y) are in pScreen-local X11 coordinates. + * + */ +static void +QuartzWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) +{ + if (XQuartzServerVisible) + { + int sx, sy; + + sx = pScreen->x + darwinMainScreenX; + sy = pScreen->y + darwinMainScreenY; + + CGWarpMouseCursorPosition(CGPointMake(sx + x, sy + y)); + } + + miPointerWarpCursor(pDev, pScreen, x, y); + miPointerUpdateSprite(pDev); +} + + +static miPointerScreenFuncRec quartzScreenFuncsRec = { + QuartzCursorOffScreen, + QuartzCrossScreen, + QuartzWarpCursor, + NULL, + NULL +}; + + +/* +=========================================================================== + + Other screen functions + +=========================================================================== +*/ + +/* + * QuartzCursorQueryBestSize + * Handle queries for best cursor size + */ +static void +QuartzCursorQueryBestSize(int class, unsigned short *width, + unsigned short *height, ScreenPtr pScreen) +{ + QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen); + + if (class == CursorShape) + { + /* FIXME: query window server? */ + *width = 32; + *height = 32; + } + else + { + (*ScreenPriv->QueryBestSize)(class, width, height, pScreen); + } +} + +/* + * QuartzInitCursor + * Initialize cursor support + */ +Bool +QuartzInitCursor(ScreenPtr pScreen) +{ + QuartzCursorScreenPtr ScreenPriv; + miPointerScreenPtr PointPriv; + + /* initialize software cursor handling (always needed as backup) */ + if (!miDCInitialize(pScreen, &quartzScreenFuncsRec)) + return FALSE; + + if (!dixRegisterPrivateKey(&darwinCursorScreenKeyRec, PRIVATE_SCREEN, 0)) + return FALSE; + + ScreenPriv = calloc(1, sizeof(QuartzCursorScreenRec)); + if (ScreenPriv == NULL) + return FALSE; + + /* CURSOR_PRIV(pScreen) = ScreenPriv; */ + dixSetPrivate(&pScreen->devPrivates, darwinCursorScreenKey, ScreenPriv); + + /* override some screen procedures */ + ScreenPriv->QueryBestSize = pScreen->QueryBestSize; + pScreen->QueryBestSize = QuartzCursorQueryBestSize; + + PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey); + + ScreenPriv->spriteFuncs = PointPriv->spriteFuncs; + + PointPriv->spriteFuncs->RealizeCursor = QuartzRealizeCursor; + PointPriv->spriteFuncs->UnrealizeCursor = QuartzUnrealizeCursor; + PointPriv->spriteFuncs->SetCursor = QuartzSetCursor; + PointPriv->spriteFuncs->MoveCursor = QuartzMoveCursor; + + ScreenPriv->cursorVisible = TRUE; + return TRUE; +} + +/* + * QuartzSuspendXCursor + * X server is hiding. Restore the Aqua cursor. + */ +void +QuartzSuspendXCursor(ScreenPtr pScreen) +{ +} + + +/* + * QuartzResumeXCursor + * X server is showing. Restore the X cursor. + */ +void +QuartzResumeXCursor(ScreenPtr pScreen) +{ + WindowPtr pWin; + CursorPtr pCursor; + + /* TODO: Tablet? */ + + pWin = GetSpriteWindow(darwinPointer); + if (pWin->drawable.pScreen != pScreen) + return; + + pCursor = GetSpriteCursor(darwinPointer); + if (pCursor == NULL) + return; + + QuartzSetCursor(darwinPointer, pScreen, pCursor, /* x */ 0, /* y */ 0); +} diff --git a/xorg-server/hw/xquartz/xpr/xprEvent.c b/xorg-server/hw/xquartz/xpr/xprEvent.c index cc86c473d..4e7ece64f 100644 --- a/xorg-server/hw/xquartz/xpr/xprEvent.c +++ b/xorg-server/hw/xquartz/xpr/xprEvent.c @@ -44,7 +44,6 @@ #include "scrnintstr.h" #include "mipointer.h" -#include "darwin.h" #include "quartz.h" #include "quartzKeyboard.h" #include "darwinEvents.h" diff --git a/xorg-server/hw/xquartz/xpr/xprScreen.c b/xorg-server/hw/xquartz/xpr/xprScreen.c index 98250e641..002355eca 100644 --- a/xorg-server/hw/xquartz/xpr/xprScreen.c +++ b/xorg-server/hw/xquartz/xpr/xprScreen.c @@ -40,7 +40,6 @@ #include "xpr.h" #include "xprEvent.h" #include "pseudoramiX.h" -#include "darwin.h" #include "darwinEvents.h" #include "rootless.h" #include "dri.h" diff --git a/xorg-server/include/privates.h b/xorg-server/include/privates.h index e6c427fab..2b0040cba 100644 --- a/xorg-server/include/privates.h +++ b/xorg-server/include/privates.h @@ -1,298 +1,298 @@ -/***********************************************************
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-******************************************************************/
-
-#ifndef PRIVATES_H
-#define PRIVATES_H 1
-
-#include <X11/Xdefs.h>
-#include <X11/Xosdefs.h>
-#include <X11/Xfuncproto.h>
-#include "misc.h"
-
-/*****************************************************************
- * STUFF FOR PRIVATES
- *****************************************************************/
-
-typedef struct _Private PrivateRec, *PrivatePtr;
-
-typedef enum {
- /* XSELinux uses the same private keys for numerous objects */
- PRIVATE_XSELINUX,
-
- /* Otherwise, you get a private in just the requested structure
- */
- /* These can have objects created before all of the keys are registered */
- PRIVATE_SCREEN,
- PRIVATE_EXTENSION,
- PRIVATE_COLORMAP,
-
- /* These cannot have any objects before all relevant keys are registered */
- PRIVATE_DEVICE,
- PRIVATE_CLIENT,
- PRIVATE_PROPERTY,
- PRIVATE_SELECTION,
- PRIVATE_WINDOW,
- PRIVATE_PIXMAP,
- PRIVATE_GC,
- PRIVATE_CURSOR,
- PRIVATE_CURSOR_BITS,
-
- /* extension privates */
- PRIVATE_DBE_WINDOW,
- PRIVATE_DAMAGE,
- PRIVATE_GLYPH,
- PRIVATE_GLYPHSET,
- PRIVATE_PICTURE,
- PRIVATE_SYNC_FENCE,
-
- /* last private type */
- PRIVATE_LAST,
-} DevPrivateType;
-
-typedef struct _DevPrivateKeyRec {
- int offset;
- int size;
- Bool initialized;
- Bool allocated;
- DevPrivateType type;
- struct _DevPrivateKeyRec *next;
-} DevPrivateKeyRec, *DevPrivateKey;
-
-typedef struct _DevScreenPrivateKeyRec {
- DevPrivateKeyRec screenKey;
-} DevScreenPrivateKeyRec, *DevScreenPrivateKey;
-
-/*
- * Let drivers know how to initialize private keys
- */
-
-#define HAS_DEVPRIVATEKEYREC 1
-#define HAS_DIXREGISTERPRIVATEKEY 1
-
-/*
- * Register a new private index for the private type.
- *
- * This initializes the specified key and optionally requests pre-allocated
- * private space for your driver/module. If you request no extra space, you
- * may set and get a single pointer value using this private key. Otherwise,
- * you can get the address of the extra space and store whatever data you like
- * there.
- *
- * You may call dixRegisterPrivateKey more than once on the same key, but the
- * size and type must match or the server will abort.
- *
- * dixRegisterPrivateKey returns FALSE if it fails to allocate memory
- * during its operation.
- */
-extern _X_EXPORT Bool
-dixRegisterPrivateKey(DevPrivateKey key, DevPrivateType type, unsigned size);
-
-/*
- * Check whether a private key has been registered
- */
-static inline Bool
-dixPrivateKeyRegistered(DevPrivateKey key)
-{
- return key->initialized;
-}
-
-/*
- * Get the address of the private storage.
- *
- * For keys with pre-defined storage, this gets the base of that storage
- * Otherwise, it returns the place where the private pointer is stored.
- */
-static inline void *
-dixGetPrivateAddr(PrivatePtr *privates, const DevPrivateKey key)
-{
- assert(key->initialized);
- return (char *) (*privates) + key->offset;
-}
-
-/*
- * Fetch a private pointer stored in the object
- *
- * Returns the pointer stored with dixSetPrivate.
- * This must only be used with keys that have
- * no pre-defined storage
- */
-static inline void *
-dixGetPrivate(PrivatePtr *privates, const DevPrivateKey key)
-{
- assert (key->size == 0);
- return *(void **) dixGetPrivateAddr(privates, key);
-}
-
-/*
- * Associate 'val' with 'key' in 'privates' so that later calls to
- * dixLookupPrivate(privates, key) will return 'val'.
- */
-static inline void
-dixSetPrivate(PrivatePtr *privates, const DevPrivateKey key, pointer val)
-{
- assert (key->size == 0);
- *(pointer *) dixGetPrivateAddr(privates, key) = val;
-}
-
-#include "dix.h"
-#include "resource.h"
-
-/*
- * Lookup a pointer to the private record.
- *
- * For privates with defined storage, return the address of the
- * storage. For privates without defined storage, return the pointer
- * contents
- */
-static inline pointer
-dixLookupPrivate(PrivatePtr *privates, const DevPrivateKey key)
-{
- if (key->size)
- return dixGetPrivateAddr(privates, key);
- else
- return dixGetPrivate(privates, key);
-}
-
-/*
- * Look up the address of the pointer to the storage
- *
- * This returns the place where the private pointer is stored,
- * which is only valid for privates without predefined storage.
- */
-static inline pointer *
-dixLookupPrivateAddr(PrivatePtr *privates, const DevPrivateKey key)
-{
- assert (key->size == 0);
- return (pointer *)dixGetPrivateAddr(privates, key);
-}
-
-extern _X_EXPORT Bool
-dixRegisterScreenPrivateKey(DevScreenPrivateKey key, ScreenPtr pScreen, DevPrivateType type, unsigned size);
-
-extern _X_EXPORT DevPrivateKey
-_dixGetScreenPrivateKey(const DevScreenPrivateKey key, ScreenPtr pScreen);
-
-static inline void *
-dixGetScreenPrivateAddr(PrivatePtr *privates, const DevScreenPrivateKey key, ScreenPtr pScreen)
-{
- return dixGetPrivateAddr(privates, _dixGetScreenPrivateKey(key, pScreen));
-}
-
-static inline void *
-dixGetScreenPrivate(PrivatePtr *privates, const DevScreenPrivateKey key, ScreenPtr pScreen)
-{
- return dixGetPrivate(privates, _dixGetScreenPrivateKey(key, pScreen));
-}
-
-static inline void
-dixSetScreenPrivate(PrivatePtr *privates, const DevScreenPrivateKey key, ScreenPtr pScreen, pointer val)
-{
- return dixSetPrivate(privates, _dixGetScreenPrivateKey(key, pScreen), val);
-}
-
-static inline pointer
-dixLookupScreenPrivate(PrivatePtr *privates, const DevScreenPrivateKey key, ScreenPtr pScreen)
-{
- return dixLookupPrivate(privates, _dixGetScreenPrivateKey(key, pScreen));
-}
-
-static inline pointer *
-dixLookupScreenPrivateAddr(PrivatePtr *privates, const DevScreenPrivateKey key, ScreenPtr pScreen)
-{
- return dixLookupPrivateAddr(privates, _dixGetScreenPrivateKey(key, pScreen));
-}
-
-/*
- * Allocates private data separately from main object.
- *
- * For objects created during server initialization, this allows those
- * privates to be re-allocated as new private keys are registered.
- *
- * This includes screens, the serverClient, default colormaps and
- * extensions entries.
- */
-extern _X_EXPORT Bool
-dixAllocatePrivates(PrivatePtr *privates, DevPrivateType type);
-
-/*
- * Frees separately allocated private data
- */
-extern _X_EXPORT void
-dixFreePrivates(PrivatePtr privates, DevPrivateType type);
-
-/*
- * Initialize privates by zeroing them
- */
-extern _X_EXPORT void
-_dixInitPrivates(PrivatePtr *privates, void *addr, DevPrivateType type);
-
-#define dixInitPrivates(o, v, type) _dixInitPrivates(&(o)->devPrivates, (v), type);
-
-/*
- * Clean up privates
- */
-extern _X_EXPORT void
-_dixFiniPrivates(PrivatePtr privates, DevPrivateType type);
-
-#define dixFiniPrivates(o,t) _dixFiniPrivates((o)->devPrivates,t)
-
-/*
- * Allocates private data at object creation time. Required
- * for almost all objects, except for the list described
- * above for dixAllocatePrivates.
- */
-extern _X_EXPORT void *
-_dixAllocateObjectWithPrivates(unsigned size, unsigned clear, unsigned offset, DevPrivateType type);
-
-#define dixAllocateObjectWithPrivates(t, type) (t *) _dixAllocateObjectWithPrivates(sizeof(t), sizeof(t), offsetof(t, devPrivates), type)
-
-extern _X_EXPORT void
-_dixFreeObjectWithPrivates(void *object, PrivatePtr privates, DevPrivateType type);
-
-#define dixFreeObjectWithPrivates(o,t) _dixFreeObjectWithPrivates(o, (o)->devPrivates, t)
-
-/*
- * Return size of privates for the specified type
- */
-extern _X_EXPORT int
-dixPrivatesSize(DevPrivateType type);
-
-/*
- * Dump out private stats to ErrorF
- */
-extern void
-dixPrivateUsage(void);
-
-/*
- * Resets the privates subsystem. dixResetPrivates is called from the main loop
- * before each server generation. This function must only be called by main().
- */
-extern _X_EXPORT void
-dixResetPrivates(void);
-
-/*
- * Looks up the offset where the devPrivates field is located.
- *
- * Returns -1 if the specified resource has no dev privates.
- * The position of the devPrivates field varies by structure
- * and calling code might only know the resource type, not the
- * structure definition.
- */
-extern _X_EXPORT int
-dixLookupPrivateOffset(RESTYPE type);
-
-/*
- * Convenience macro for adding an offset to an object pointer
- * when making a call to one of the devPrivates functions
- */
-#define DEVPRIV_AT(ptr, offset) ((PrivatePtr *)((char *)(ptr) + offset))
-
-#endif /* PRIVATES_H */
+/*********************************************************** + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +******************************************************************/ + +#ifndef PRIVATES_H +#define PRIVATES_H 1 + +#include <X11/Xdefs.h> +#include <X11/Xosdefs.h> +#include <X11/Xfuncproto.h> +#include "misc.h" + +/***************************************************************** + * STUFF FOR PRIVATES + *****************************************************************/ + +typedef struct _Private PrivateRec, *PrivatePtr; + +typedef enum { + /* XSELinux uses the same private keys for numerous objects */ + PRIVATE_XSELINUX, + + /* Otherwise, you get a private in just the requested structure + */ + /* These can have objects created before all of the keys are registered */ + PRIVATE_SCREEN, + PRIVATE_EXTENSION, + PRIVATE_COLORMAP, + + /* These cannot have any objects before all relevant keys are registered */ + PRIVATE_DEVICE, + PRIVATE_CLIENT, + PRIVATE_PROPERTY, + PRIVATE_SELECTION, + PRIVATE_WINDOW, + PRIVATE_PIXMAP, + PRIVATE_GC, + PRIVATE_CURSOR, + PRIVATE_CURSOR_BITS, + + /* extension privates */ + PRIVATE_DBE_WINDOW, + PRIVATE_DAMAGE, + PRIVATE_GLYPH, + PRIVATE_GLYPHSET, + PRIVATE_PICTURE, + PRIVATE_SYNC_FENCE, + + /* last private type */ + PRIVATE_LAST, +} DevPrivateType; + +typedef struct _DevPrivateKeyRec { + int offset; + int size; + Bool initialized; + Bool allocated; + DevPrivateType type; + struct _DevPrivateKeyRec *next; +} DevPrivateKeyRec, *DevPrivateKey; + +typedef struct _DevScreenPrivateKeyRec { + DevPrivateKeyRec screenKey; +} DevScreenPrivateKeyRec, *DevScreenPrivateKey; + +/* + * Let drivers know how to initialize private keys + */ + +#define HAS_DEVPRIVATEKEYREC 1 +#define HAS_DIXREGISTERPRIVATEKEY 1 + +/* + * Register a new private index for the private type. + * + * This initializes the specified key and optionally requests pre-allocated + * private space for your driver/module. If you request no extra space, you + * may set and get a single pointer value using this private key. Otherwise, + * you can get the address of the extra space and store whatever data you like + * there. + * + * You may call dixRegisterPrivateKey more than once on the same key, but the + * size and type must match or the server will abort. + * + * dixRegisterPrivateKey returns FALSE if it fails to allocate memory + * during its operation. + */ +extern _X_EXPORT Bool +dixRegisterPrivateKey(DevPrivateKey key, DevPrivateType type, unsigned size); + +/* + * Check whether a private key has been registered + */ +static inline Bool +dixPrivateKeyRegistered(DevPrivateKey key) +{ + return key->initialized; +} + +/* + * Get the address of the private storage. + * + * For keys with pre-defined storage, this gets the base of that storage + * Otherwise, it returns the place where the private pointer is stored. + */ +static inline void * +dixGetPrivateAddr(PrivatePtr *privates, const DevPrivateKey key) +{ + assert(key->initialized); + return (char *) (*privates) + key->offset; +} + +/* + * Fetch a private pointer stored in the object + * + * Returns the pointer stored with dixSetPrivate. + * This must only be used with keys that have + * no pre-defined storage + */ +static inline void * +dixGetPrivate(PrivatePtr *privates, const DevPrivateKey key) +{ + assert (key->size == 0); + return *(void **) dixGetPrivateAddr(privates, key); +} + +/* + * Associate 'val' with 'key' in 'privates' so that later calls to + * dixLookupPrivate(privates, key) will return 'val'. + */ +static inline void +dixSetPrivate(PrivatePtr *privates, const DevPrivateKey key, pointer val) +{ + assert (key->size == 0); + *(pointer *) dixGetPrivateAddr(privates, key) = val; +} + +#include "dix.h" +#include "resource.h" + +/* + * Lookup a pointer to the private record. + * + * For privates with defined storage, return the address of the + * storage. For privates without defined storage, return the pointer + * contents + */ +static inline pointer +dixLookupPrivate(PrivatePtr *privates, const DevPrivateKey key) +{ + if (key->size) + return dixGetPrivateAddr(privates, key); + else + return dixGetPrivate(privates, key); +} + +/* + * Look up the address of the pointer to the storage + * + * This returns the place where the private pointer is stored, + * which is only valid for privates without predefined storage. + */ +static inline pointer * +dixLookupPrivateAddr(PrivatePtr *privates, const DevPrivateKey key) +{ + assert (key->size == 0); + return (pointer *)dixGetPrivateAddr(privates, key); +} + +extern _X_EXPORT Bool +dixRegisterScreenPrivateKey(DevScreenPrivateKey key, ScreenPtr pScreen, DevPrivateType type, unsigned size); + +extern _X_EXPORT DevPrivateKey +_dixGetScreenPrivateKey(const DevScreenPrivateKey key, ScreenPtr pScreen); + +static inline void * +dixGetScreenPrivateAddr(PrivatePtr *privates, const DevScreenPrivateKey key, ScreenPtr pScreen) +{ + return dixGetPrivateAddr(privates, _dixGetScreenPrivateKey(key, pScreen)); +} + +static inline void * +dixGetScreenPrivate(PrivatePtr *privates, const DevScreenPrivateKey key, ScreenPtr pScreen) +{ + return dixGetPrivate(privates, _dixGetScreenPrivateKey(key, pScreen)); +} + +static inline void +dixSetScreenPrivate(PrivatePtr *privates, const DevScreenPrivateKey key, ScreenPtr pScreen, pointer val) +{ + dixSetPrivate(privates, _dixGetScreenPrivateKey(key, pScreen), val); +} + +static inline pointer +dixLookupScreenPrivate(PrivatePtr *privates, const DevScreenPrivateKey key, ScreenPtr pScreen) +{ + return dixLookupPrivate(privates, _dixGetScreenPrivateKey(key, pScreen)); +} + +static inline pointer * +dixLookupScreenPrivateAddr(PrivatePtr *privates, const DevScreenPrivateKey key, ScreenPtr pScreen) +{ + return dixLookupPrivateAddr(privates, _dixGetScreenPrivateKey(key, pScreen)); +} + +/* + * Allocates private data separately from main object. + * + * For objects created during server initialization, this allows those + * privates to be re-allocated as new private keys are registered. + * + * This includes screens, the serverClient, default colormaps and + * extensions entries. + */ +extern _X_EXPORT Bool +dixAllocatePrivates(PrivatePtr *privates, DevPrivateType type); + +/* + * Frees separately allocated private data + */ +extern _X_EXPORT void +dixFreePrivates(PrivatePtr privates, DevPrivateType type); + +/* + * Initialize privates by zeroing them + */ +extern _X_EXPORT void +_dixInitPrivates(PrivatePtr *privates, void *addr, DevPrivateType type); + +#define dixInitPrivates(o, v, type) _dixInitPrivates(&(o)->devPrivates, (v), type); + +/* + * Clean up privates + */ +extern _X_EXPORT void +_dixFiniPrivates(PrivatePtr privates, DevPrivateType type); + +#define dixFiniPrivates(o,t) _dixFiniPrivates((o)->devPrivates,t) + +/* + * Allocates private data at object creation time. Required + * for almost all objects, except for the list described + * above for dixAllocatePrivates. + */ +extern _X_EXPORT void * +_dixAllocateObjectWithPrivates(unsigned size, unsigned clear, unsigned offset, DevPrivateType type); + +#define dixAllocateObjectWithPrivates(t, type) (t *) _dixAllocateObjectWithPrivates(sizeof(t), sizeof(t), offsetof(t, devPrivates), type) + +extern _X_EXPORT void +_dixFreeObjectWithPrivates(void *object, PrivatePtr privates, DevPrivateType type); + +#define dixFreeObjectWithPrivates(o,t) _dixFreeObjectWithPrivates(o, (o)->devPrivates, t) + +/* + * Return size of privates for the specified type + */ +extern _X_EXPORT int +dixPrivatesSize(DevPrivateType type); + +/* + * Dump out private stats to ErrorF + */ +extern void +dixPrivateUsage(void); + +/* + * Resets the privates subsystem. dixResetPrivates is called from the main loop + * before each server generation. This function must only be called by main(). + */ +extern _X_EXPORT void +dixResetPrivates(void); + +/* + * Looks up the offset where the devPrivates field is located. + * + * Returns -1 if the specified resource has no dev privates. + * The position of the devPrivates field varies by structure + * and calling code might only know the resource type, not the + * structure definition. + */ +extern _X_EXPORT int +dixLookupPrivateOffset(RESTYPE type); + +/* + * Convenience macro for adding an offset to an object pointer + * when making a call to one of the devPrivates functions + */ +#define DEVPRIV_AT(ptr, offset) ((PrivatePtr *)((char *)(ptr) + offset)) + +#endif /* PRIVATES_H */ diff --git a/xorg-server/include/protocol-versions.h b/xorg-server/include/protocol-versions.h index 8692ded8a..7b7a9f53c 100644 --- a/xorg-server/include/protocol-versions.h +++ b/xorg-server/include/protocol-versions.h @@ -122,7 +122,7 @@ #define SERVER_XF86VIDMODE_MINOR_VERSION 2 /* Fixes */ -#define SERVER_XFIXES_MAJOR_VERSION 4 +#define SERVER_XFIXES_MAJOR_VERSION 5 #define SERVER_XFIXES_MINOR_VERSION 0 /* X Input */ diff --git a/xorg-server/m4/xorg-tls.m4 b/xorg-server/m4/xorg-tls.m4 index 563850420..237fdcd9e 100644 --- a/xorg-server/m4/xorg-tls.m4 +++ b/xorg-server/m4/xorg-tls.m4 @@ -22,6 +22,7 @@ dnl dnl Authors: Jeremy Huddleston <jeremyhu@apple.com> AC_DEFUN([XORG_TLS], [ + AC_REQUIRE([XORG_STRICT_OPTION]) AC_MSG_CHECKING(for thread local storage (TLS) support) AC_CACHE_VAL(ac_cv_tls, [ ac_cv_tls=none @@ -36,10 +37,7 @@ AC_DEFUN([XORG_TLS], [ AC_MSG_CHECKING(for tls_model attribute support) AC_CACHE_VAL(ac_cv_tls_model, [ save_CFLAGS="$CFLAGS" - dnl -Werror causes clang's default -Wunknown-attributes to become an error - dnl We can't use -Werror=unknown-attributes because gcc doesn't understand it - dnl -Werror=attributes is for gcc, clang seems to ignore it - CFLAGS="$CFLAGS -Werror -Werror=attributes" + CFLAGS="$CFLAGS $STRICT_CFLAGS" AC_TRY_COMPILE([int $ac_cv_tls __attribute__((tls_model("initial-exec"))) test;], [], ac_cv_tls_model=yes, ac_cv_tls_model=no) CFLAGS="$save_CFLAGS" diff --git a/xorg-server/test/Makefile.am b/xorg-server/test/Makefile.am index b7ee070a1..5574e7d1e 100644 --- a/xorg-server/test/Makefile.am +++ b/xorg-server/test/Makefile.am @@ -1,7 +1,7 @@ if ENABLE_UNIT_TESTS if HAVE_LD_WRAP SUBDIRS= . xi2 -noinst_PROGRAMS = xkb input xtest list misc +noinst_PROGRAMS = xkb input xtest list misc fixes check_LTLIBRARIES = libxservertest.la TESTS=$(noinst_PROGRAMS) @@ -19,6 +19,7 @@ input_LDADD=$(TEST_LDADD) xtest_LDADD=$(TEST_LDADD) list_LDADD=$(TEST_LDADD) misc_LDADD=$(TEST_LDADD) +fixes_LDADD=$(TEST_LDADD) libxservertest_la_LIBADD = \ $(XSERVER_LIBS) \ diff --git a/xorg-server/test/fixes.c b/xorg-server/test/fixes.c new file mode 100644 index 000000000..8c804ba26 --- /dev/null +++ b/xorg-server/test/fixes.c @@ -0,0 +1,327 @@ +/** + * Copyright © 2011 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <X11/X.h> +#include <xfixesint.h> +#include <X11/extensions/xfixeswire.h> + +static void +_fixes_test_direction(struct PointerBarrier *barrier, int d[4], int permitted) +{ + BOOL blocking; + int i, j; + int dir = barrier_get_direction(d[0], d[1], d[2], d[3]); + + barrier->directions = 0; + blocking = barrier_is_blocking_direction(barrier, dir); + assert(blocking); + + for (j = 0; j <= BarrierNegativeY; j++) + { + for (i = 0; i <= BarrierNegativeY; i++) + { + barrier->directions |= 1 << i; + blocking = barrier_is_blocking_direction(barrier, dir); + assert((barrier->directions & permitted) == permitted ? !blocking : blocking); + } + } + +} + +static void +fixes_pointer_barrier_direction_test(void) +{ + struct PointerBarrier barrier; + + int x = 100; + int y = 100; + + int directions[8][4] = { + { x, y, x, y + 100}, /* S */ + { x + 50, y, x - 50, y + 100}, /* SW */ + { x + 100, y, x, y}, /* W */ + { x + 100, y + 50, x, y - 50}, /* NW */ + { x, y + 100, x, y}, /* N */ + { x - 50, y + 100, x + 50, y}, /* NE */ + { x, y, x + 100, y}, /* E */ + { x, y - 50, x + 100, y + 50}, /* SE */ + }; + + barrier.x1 = x; + barrier.x2 = x; + barrier.y1 = y - 50; + barrier.y2 = y + 49; + + + _fixes_test_direction(&barrier, directions[0], BarrierPositiveY); + _fixes_test_direction(&barrier, directions[1], BarrierPositiveY | BarrierNegativeX); + _fixes_test_direction(&barrier, directions[2], BarrierNegativeX); + _fixes_test_direction(&barrier, directions[3], BarrierNegativeY | BarrierNegativeX); + _fixes_test_direction(&barrier, directions[4], BarrierNegativeY); + _fixes_test_direction(&barrier, directions[5], BarrierPositiveX | BarrierNegativeY); + _fixes_test_direction(&barrier, directions[6], BarrierPositiveX); + _fixes_test_direction(&barrier, directions[7], BarrierPositiveY | BarrierPositiveX); + + +} + + +static void +fixes_pointer_barriers_test(void) +{ + struct PointerBarrier barrier; + int x1, y1, x2, y2; + double distance; + + int x = 100; + int y = 100; + + /* vert barrier */ + barrier.x1 = x; + barrier.x2 = x; + barrier.y1 = y - 50; + barrier.y2 = y + 50; + + /* across at half-way */ + x1 = x + 1; + x2 = x - 1; + y1 = y; + y2 = y; + assert(barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); + assert(distance == 1); + + /* definitely not across */ + x1 = x + 10; + x2 = x + 5; + assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); + + /* across, but outside of y range */ + x1 = x + 1; + x2 = x -1; + y1 = y + 100; + y2 = y + 100; + assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); + + /* across, diagonally */ + x1 = x + 5; + x2 = x - 5; + y1 = y + 5; + y2 = y - 5; + assert(barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); + + /* across but outside boundary, diagonally */ + x1 = x + 5; + x2 = x - 5; + y1 = y + 100; + y2 = y + 50; + assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); + + /* edge case: startpoint of movement on barrier → blocking */ + x1 = x; + x2 = x - 1; + y1 = y; + y2 = y; + assert(barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); + + /* edge case: startpoint of movement on barrier → not blocking, positive */ + x1 = x; + x2 = x + 1; + y1 = y; + y2 = y; + assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); + + /* edge case: startpoint of movement on barrier → not blocking, negative */ + x1 = x - 1; + x2 = x - 2; + y1 = y; + y2 = y; + assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); + + /* edge case: endpoint of movement on barrier → blocking */ + x1 = x + 1; + x2 = x; + y1 = y; + y2 = y; + assert(barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); + + /* startpoint on barrier but outside y range */ + x1 = x; + x2 = x - 1; + y1 = y + 100; + y2 = y + 100; + assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); + + /* endpoint on barrier but outside y range */ + x1 = x + 1; + x2 = x; + y1 = y + 100; + y2 = y + 100; + assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); + + + /* horizontal barrier */ + barrier.x1 = x - 50; + barrier.x2 = x + 50; + barrier.y1 = y; + barrier.y2 = y; + + /* across at half-way */ + x1 = x; + x2 = x; + y1 = y - 1; + y2 = y + 1; + assert(barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); + + /* definitely not across */ + y1 = y + 10; + y2 = y + 5; + assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); + + /* across, but outside of y range */ + x1 = x + 100; + x2 = x + 100; + y1 = y + 1; + y2 = y -1; + assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); + + /* across, diagonally */ + y1 = y + 5; + y2 = y - 5; + x1 = x + 5; + x2 = x - 5; + assert(barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); + + /* across but outside boundary, diagonally */ + y1 = y + 5; + y2 = y - 5; + x1 = x + 100; + x2 = x + 50; + assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); + + /* edge case: startpoint of movement on barrier → blocking */ + y1 = y; + y2 = y - 1; + x1 = x; + x2 = x; + assert(barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); + + /* edge case: startpoint of movement on barrier → not blocking, positive */ + y1 = y; + y2 = y + 1; + x1 = x; + x2 = x; + assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); + + /* edge case: startpoint of movement on barrier → not blocking, negative */ + y1 = y - 1; + y2 = y - 2; + x1 = x; + x2 = x; + assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); + + /* edge case: endpoint of movement on barrier → blocking */ + y1 = y + 1; + y2 = y; + x1 = x; + x2 = x; + assert(barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); + + /* startpoint on barrier but outside y range */ + y1 = y; + y2 = y - 1; + x1 = x + 100; + x2 = x + 100; + assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); + + /* endpoint on barrier but outside y range */ + y1 = y + 1; + y2 = y; + x1 = x + 100; + x2 = x + 100; + assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); + +} + +static void fixes_pointer_barrier_clamp_test(void) +{ + struct PointerBarrier barrier; + + int x = 100; + int y = 100; + + int cx, cy; /* clamped */ + + /* vert barrier */ + barrier.x1 = x; + barrier.x2 = x; + barrier.y1 = y - 50; + barrier.y2 = y + 49; + barrier.directions = 0; + + cx = INT_MAX; + cy = INT_MAX; + barrier_clamp_to_barrier(&barrier, BarrierPositiveX, &cx, &cy); + assert(cx == barrier.x1 - 1); + assert(cy == INT_MAX); + + cx = 0; + cy = INT_MAX; + barrier_clamp_to_barrier(&barrier, BarrierNegativeX, &cx, &cy); + assert(cx == barrier.x1); + assert(cy == INT_MAX); + + /* horiz barrier */ + barrier.x1 = x - 50; + barrier.x2 = x + 49; + barrier.y1 = y; + barrier.y2 = y; + barrier.directions = 0; + + cx = INT_MAX; + cy = INT_MAX; + barrier_clamp_to_barrier(&barrier, BarrierPositiveY, &cx, &cy); + assert(cx == INT_MAX); + assert(cy == barrier.y1 - 1); + + cx = INT_MAX; + cy = 0; + barrier_clamp_to_barrier(&barrier, BarrierNegativeY, &cx, &cy); + assert(cx == INT_MAX); + assert(cy == barrier.y1); +} + +int main(int argc, char** argv) +{ + + fixes_pointer_barriers_test(); + fixes_pointer_barrier_direction_test(); + fixes_pointer_barrier_clamp_test(); + + return 0; +} diff --git a/xorg-server/xfixes/cursor.c b/xorg-server/xfixes/cursor.c index 2cafb3087..01eb70d92 100644 --- a/xorg-server/xfixes/cursor.c +++ b/xorg-server/xfixes/cursor.c @@ -1,1065 +1,1462 @@ -/*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright © 2002 Keith Packard
- *
- * 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 Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD 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_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "xfixesint.h"
-#include "scrnintstr.h"
-#include "cursorstr.h"
-#include "dixevents.h"
-#include "servermd.h"
-#include "inputstr.h"
-#include "windowstr.h"
-#include "xace.h"
-
-static RESTYPE CursorClientType;
-static RESTYPE CursorHideCountType;
-static RESTYPE CursorWindowType;
-static CursorPtr CursorCurrent[MAXDEVICES];
-
-static DevPrivateKeyRec CursorScreenPrivateKeyRec;
-#define CursorScreenPrivateKey (&CursorScreenPrivateKeyRec)
-
-static void deleteCursorHideCountsForScreen (ScreenPtr pScreen);
-
-#define VERIFY_CURSOR(pCursor, cursor, client, access) \
- do { \
- int err; \
- err = dixLookupResourceByType((pointer *) &pCursor, cursor, \
- RT_CURSOR, client, access); \
- if (err != Success) { \
- client->errorValue = cursor; \
- return err; \
- } \
- } while (0)
-
-/*
- * There is a global list of windows selecting for cursor events
- */
-
-typedef struct _CursorEvent *CursorEventPtr;
-
-typedef struct _CursorEvent {
- CursorEventPtr next;
- CARD32 eventMask;
- ClientPtr pClient;
- WindowPtr pWindow;
- XID clientResource;
-} CursorEventRec;
-
-static CursorEventPtr cursorEvents;
-
-/*
- * Each screen has a list of clients which have requested
- * that the cursor be hid, and the number of times each
- * client has requested.
-*/
-
-typedef struct _CursorHideCountRec *CursorHideCountPtr;
-
-typedef struct _CursorHideCountRec {
- CursorHideCountPtr pNext;
- ClientPtr pClient;
- ScreenPtr pScreen;
- int hideCount;
- XID resource;
-} CursorHideCountRec;
-
-/*
- * Wrap DisplayCursor to catch cursor change events
- */
-
-typedef struct _CursorScreen {
- DisplayCursorProcPtr DisplayCursor;
- CloseScreenProcPtr CloseScreen;
- CursorHideCountPtr pCursorHideCounts;
-} CursorScreenRec, *CursorScreenPtr;
-
-#define GetCursorScreen(s) ((CursorScreenPtr)dixLookupPrivate(&(s)->devPrivates, CursorScreenPrivateKey))
-#define GetCursorScreenIfSet(s) GetCursorScreen(s)
-#define SetCursorScreen(s,p) dixSetPrivate(&(s)->devPrivates, CursorScreenPrivateKey, p)
-#define Wrap(as,s,elt,func) (((as)->elt = (s)->elt), (s)->elt = func)
-#define Unwrap(as,s,elt,backup) (((backup) = (s)->elt), (s)->elt = (as)->elt)
-
-/* The cursor doesn't show up until the first XDefineCursor() */
-static Bool CursorVisible = FALSE;
-
-Bool EnableCursor = TRUE;
-
-static Bool
-CursorDisplayCursor (DeviceIntPtr pDev,
- ScreenPtr pScreen,
- CursorPtr pCursor)
-{
- CursorScreenPtr cs = GetCursorScreen(pScreen);
- Bool ret;
- DisplayCursorProcPtr backupProc;
-
- Unwrap (cs, pScreen, DisplayCursor, backupProc);
-
- /*
- * Have to check ConnectionInfo to distinguish client requests from
- * initial root window setup. Not a great way to do it, I admit.
- */
- if (ConnectionInfo)
- CursorVisible = EnableCursor;
-
- if (cs->pCursorHideCounts != NULL || !CursorVisible) {
- ret = (*pScreen->DisplayCursor) (pDev, pScreen, NullCursor);
- } else {
- ret = (*pScreen->DisplayCursor) (pDev, pScreen, pCursor);
- }
-
- if (pCursor != CursorCurrent[pDev->id])
- {
- CursorEventPtr e;
-
- CursorCurrent[pDev->id] = pCursor;
- for (e = cursorEvents; e; e = e->next)
- {
- if ((e->eventMask & XFixesDisplayCursorNotifyMask))
- {
- xXFixesCursorNotifyEvent ev;
- ev.type = XFixesEventBase + XFixesCursorNotify;
- ev.subtype = XFixesDisplayCursorNotify;
- ev.window = e->pWindow->drawable.id;
- ev.cursorSerial = pCursor->serialNumber;
- ev.timestamp = currentTime.milliseconds;
- ev.name = pCursor->name;
- WriteEventsToClient (e->pClient, 1, (xEvent *) &ev);
- }
- }
- }
- Wrap (cs, pScreen, DisplayCursor, backupProc);
-
- return ret;
-}
-
-static Bool
-CursorCloseScreen (int index, ScreenPtr pScreen)
-{
- CursorScreenPtr cs = GetCursorScreen (pScreen);
- Bool ret;
- CloseScreenProcPtr close_proc;
- DisplayCursorProcPtr display_proc;
-
- Unwrap (cs, pScreen, CloseScreen, close_proc);
- Unwrap (cs, pScreen, DisplayCursor, display_proc);
- deleteCursorHideCountsForScreen(pScreen);
- ret = (*pScreen->CloseScreen) (index, pScreen);
- free(cs);
- return ret;
-}
-
-#define CursorAllEvents (XFixesDisplayCursorNotifyMask)
-
-static int
-XFixesSelectCursorInput (ClientPtr pClient,
- WindowPtr pWindow,
- CARD32 eventMask)
-{
- CursorEventPtr *prev, e;
- pointer val;
- int rc;
-
- for (prev = &cursorEvents; (e = *prev); prev = &e->next)
- {
- if (e->pClient == pClient &&
- e->pWindow == pWindow)
- {
- break;
- }
- }
- if (!eventMask)
- {
- if (e)
- {
- FreeResource (e->clientResource, 0);
- }
- return Success;
- }
- if (!e)
- {
- e = (CursorEventPtr) malloc(sizeof (CursorEventRec));
- if (!e)
- return BadAlloc;
-
- e->next = 0;
- e->pClient = pClient;
- e->pWindow = pWindow;
- e->clientResource = FakeClientID(pClient->index);
-
- /*
- * Add a resource hanging from the window to
- * catch window destroy
- */
- rc = dixLookupResourceByType( &val, pWindow->drawable.id,
- CursorWindowType, serverClient,
- DixGetAttrAccess);
- if (rc != Success)
- if (!AddResource (pWindow->drawable.id, CursorWindowType,
- (pointer) pWindow))
- {
- free(e);
- return BadAlloc;
- }
-
- if (!AddResource (e->clientResource, CursorClientType, (pointer) e))
- return BadAlloc;
-
- *prev = e;
- }
- e->eventMask = eventMask;
- return Success;
-}
-
-int
-ProcXFixesSelectCursorInput (ClientPtr client)
-{
- REQUEST (xXFixesSelectCursorInputReq);
- WindowPtr pWin;
- int rc;
-
- REQUEST_SIZE_MATCH (xXFixesSelectCursorInputReq);
- rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
- if (rc != Success)
- return rc;
- if (stuff->eventMask & ~CursorAllEvents)
- {
- client->errorValue = stuff->eventMask;
- return BadValue;
- }
- return XFixesSelectCursorInput (client, pWin, stuff->eventMask);
-}
-
-static int
-GetBit (unsigned char *line, int x)
-{
- unsigned char mask;
-
- if (screenInfo.bitmapBitOrder == LSBFirst)
- mask = (1 << (x & 7));
- else
- mask = (0x80 >> (x & 7));
- /* XXX assumes byte order is host byte order */
- line += (x >> 3);
- if (*line & mask)
- return 1;
- return 0;
-}
-
-int
-SProcXFixesSelectCursorInput (ClientPtr client)
-{
- register int n;
- REQUEST(xXFixesSelectCursorInputReq);
-
- swaps(&stuff->length, n);
- swapl(&stuff->window, n);
- swapl(&stuff->eventMask, n);
- return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
-}
-
-void
-SXFixesCursorNotifyEvent (xXFixesCursorNotifyEvent *from,
- xXFixesCursorNotifyEvent *to)
-{
- to->type = from->type;
- cpswaps (from->sequenceNumber, to->sequenceNumber);
- cpswapl (from->window, to->window);
- cpswapl (from->cursorSerial, to->cursorSerial);
- cpswapl (from->timestamp, to->timestamp);
- cpswapl (from->name, to->name);
-}
-
-static void
-CopyCursorToImage (CursorPtr pCursor, CARD32 *image)
-{
- int width = pCursor->bits->width;
- int height = pCursor->bits->height;
- int npixels = width * height;
-
-#ifdef ARGB_CURSOR
- if (pCursor->bits->argb)
- memcpy (image, pCursor->bits->argb, npixels * sizeof (CARD32));
- else
-#endif
- {
- unsigned char *srcLine = pCursor->bits->source;
- unsigned char *mskLine = pCursor->bits->mask;
- int stride = BitmapBytePad (width);
- int x, y;
- CARD32 fg, bg;
-
- fg = (0xff000000 |
- ((pCursor->foreRed & 0xff00) << 8) |
- (pCursor->foreGreen & 0xff00) |
- (pCursor->foreBlue >> 8));
- bg = (0xff000000 |
- ((pCursor->backRed & 0xff00) << 8) |
- (pCursor->backGreen & 0xff00) |
- (pCursor->backBlue >> 8));
- for (y = 0; y < height; y++)
- {
- for (x = 0; x < width; x++)
- {
- if (GetBit (mskLine, x))
- {
- if (GetBit (srcLine, x))
- *image++ = fg;
- else
- *image++ = bg;
- }
- else
- *image++ = 0;
- }
- srcLine += stride;
- mskLine += stride;
- }
- }
-}
-
-int
-ProcXFixesGetCursorImage (ClientPtr client)
-{
-/* REQUEST(xXFixesGetCursorImageReq); */
- xXFixesGetCursorImageReply *rep;
- CursorPtr pCursor;
- CARD32 *image;
- int npixels, width, height, rc, x, y;
-
- REQUEST_SIZE_MATCH(xXFixesGetCursorImageReq);
- pCursor = CursorCurrent[PickPointer(client)->id];
- if (!pCursor)
- return BadCursor;
- rc = XaceHook(XACE_RESOURCE_ACCESS, client, pCursor->id, RT_CURSOR,
- pCursor, RT_NONE, NULL, DixReadAccess);
- if (rc != Success)
- return rc;
- GetSpritePosition (PickPointer(client), &x, &y);
- width = pCursor->bits->width;
- height = pCursor->bits->height;
- npixels = width * height;
- rep = malloc(sizeof (xXFixesGetCursorImageReply) +
- npixels * sizeof (CARD32));
- if (!rep)
- return BadAlloc;
-
- rep->type = X_Reply;
- rep->sequenceNumber = client->sequence;
- rep->length = npixels;
- rep->width = width;
- rep->height = height;
- rep->x = x;
- rep->y = y;
- rep->xhot = pCursor->bits->xhot;
- rep->yhot = pCursor->bits->yhot;
- rep->cursorSerial = pCursor->serialNumber;
-
- image = (CARD32 *) (rep + 1);
- CopyCursorToImage (pCursor, image);
- if (client->swapped)
- {
- int n;
- swaps (&rep->sequenceNumber, n);
- swapl (&rep->length, n);
- swaps (&rep->x, n);
- swaps (&rep->y, n);
- swaps (&rep->width, n);
- swaps (&rep->height, n);
- swaps (&rep->xhot, n);
- swaps (&rep->yhot, n);
- swapl (&rep->cursorSerial, n);
- SwapLongs (image, npixels);
- }
- WriteToClient(client, sizeof (xXFixesGetCursorImageReply) +
- (npixels << 2), (char *) rep);
- free(rep);
- return Success;
-}
-
-int
-SProcXFixesGetCursorImage (ClientPtr client)
-{
- int n;
- REQUEST(xXFixesGetCursorImageReq);
- swaps (&stuff->length, n);
- return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
-}
-
-int
-ProcXFixesSetCursorName (ClientPtr client)
-{
- CursorPtr pCursor;
- char *tchar;
- REQUEST(xXFixesSetCursorNameReq);
- Atom atom;
-
- REQUEST_AT_LEAST_SIZE(xXFixesSetCursorNameReq);
- VERIFY_CURSOR(pCursor, stuff->cursor, client, DixSetAttrAccess);
- tchar = (char *) &stuff[1];
- atom = MakeAtom (tchar, stuff->nbytes, TRUE);
- if (atom == BAD_RESOURCE)
- return BadAlloc;
-
- pCursor->name = atom;
- return Success;
-}
-
-int
-SProcXFixesSetCursorName (ClientPtr client)
-{
- int n;
- REQUEST(xXFixesSetCursorNameReq);
-
- swaps (&stuff->length, n);
- REQUEST_AT_LEAST_SIZE(xXFixesSetCursorNameReq);
- swapl (&stuff->cursor, n);
- swaps (&stuff->nbytes, n);
- return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
-}
-
-int
-ProcXFixesGetCursorName (ClientPtr client)
-{
- CursorPtr pCursor;
- xXFixesGetCursorNameReply reply;
- REQUEST(xXFixesGetCursorNameReq);
- const char *str;
- int len;
-
- REQUEST_SIZE_MATCH(xXFixesGetCursorNameReq);
- VERIFY_CURSOR(pCursor, stuff->cursor, client, DixGetAttrAccess);
- if (pCursor->name)
- str = NameForAtom (pCursor->name);
- else
- str = "";
- len = strlen (str);
-
- reply.type = X_Reply;
- reply.length = bytes_to_int32(len);
- reply.sequenceNumber = client->sequence;
- reply.atom = pCursor->name;
- reply.nbytes = len;
- if (client->swapped)
- {
- int n;
- swaps (&reply.sequenceNumber, n);
- swapl (&reply.length, n);
- swapl (&reply.atom, n);
- swaps (&reply.nbytes, n);
- }
- WriteReplyToClient(client, sizeof(xXFixesGetCursorNameReply), &reply);
- WriteToClient(client, len, str);
-
- return Success;
-}
-
-int
-SProcXFixesGetCursorName (ClientPtr client)
-{
- int n;
- REQUEST(xXFixesGetCursorNameReq);
-
- swaps (&stuff->length, n);
- REQUEST_SIZE_MATCH(xXFixesGetCursorNameReq);
- swapl (&stuff->cursor, n);
- return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
-}
-
-int
-ProcXFixesGetCursorImageAndName (ClientPtr client)
-{
-/* REQUEST(xXFixesGetCursorImageAndNameReq); */
- xXFixesGetCursorImageAndNameReply *rep;
- CursorPtr pCursor;
- CARD32 *image;
- int npixels;
- const char *name;
- int nbytes, nbytesRound;
- int width, height;
- int rc, x, y;
-
- REQUEST_SIZE_MATCH(xXFixesGetCursorImageAndNameReq);
- pCursor = CursorCurrent[PickPointer(client)->id];
- if (!pCursor)
- return BadCursor;
- rc = XaceHook(XACE_RESOURCE_ACCESS, client, pCursor->id, RT_CURSOR,
- pCursor, RT_NONE, NULL, DixReadAccess|DixGetAttrAccess);
- if (rc != Success)
- return rc;
- GetSpritePosition (PickPointer(client), &x, &y);
- width = pCursor->bits->width;
- height = pCursor->bits->height;
- npixels = width * height;
- name = pCursor->name ? NameForAtom (pCursor->name) : "";
- nbytes = strlen (name);
- nbytesRound = pad_to_int32(nbytes);
- rep = malloc(sizeof (xXFixesGetCursorImageAndNameReply) +
- npixels * sizeof (CARD32) + nbytesRound);
- if (!rep)
- return BadAlloc;
-
- rep->type = X_Reply;
- rep->sequenceNumber = client->sequence;
- rep->length = npixels + bytes_to_int32(nbytesRound);
- rep->width = width;
- rep->height = height;
- rep->x = x;
- rep->y = y;
- rep->xhot = pCursor->bits->xhot;
- rep->yhot = pCursor->bits->yhot;
- rep->cursorSerial = pCursor->serialNumber;
- rep->cursorName = pCursor->name;
- rep->nbytes = nbytes;
-
- image = (CARD32 *) (rep + 1);
- CopyCursorToImage (pCursor, image);
- memcpy ((image + npixels), name, nbytes);
- if (client->swapped)
- {
- int n;
- swaps (&rep->sequenceNumber, n);
- swapl (&rep->length, n);
- swaps (&rep->x, n);
- swaps (&rep->y, n);
- swaps (&rep->width, n);
- swaps (&rep->height, n);
- swaps (&rep->xhot, n);
- swaps (&rep->yhot, n);
- swapl (&rep->cursorSerial, n);
- swapl (&rep->cursorName, n);
- swaps (&rep->nbytes, n);
- SwapLongs (image, npixels);
- }
- WriteToClient(client, sizeof (xXFixesGetCursorImageAndNameReply) +
- (npixels << 2) + nbytesRound, (char *) rep);
- free(rep);
- return Success;
-}
-
-int
-SProcXFixesGetCursorImageAndName (ClientPtr client)
-{
- int n;
- REQUEST(xXFixesGetCursorImageAndNameReq);
- swaps (&stuff->length, n);
- return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
-}
-
-/*
- * Find every cursor reference in the system, ask testCursor
- * whether it should be replaced with a reference to pCursor.
- */
-
-typedef Bool (*TestCursorFunc) (CursorPtr pOld, pointer closure);
-
-typedef struct {
- RESTYPE type;
- TestCursorFunc testCursor;
- CursorPtr pNew;
- pointer closure;
-} ReplaceCursorLookupRec, *ReplaceCursorLookupPtr;
-
-static const RESTYPE CursorRestypes[] = {
- RT_WINDOW, RT_PASSIVEGRAB, RT_CURSOR
-};
-
-#define NUM_CURSOR_RESTYPES (sizeof (CursorRestypes) / sizeof (CursorRestypes[0]))
-
-static Bool
-ReplaceCursorLookup (pointer value, XID id, pointer closure)
-{
- ReplaceCursorLookupPtr rcl = (ReplaceCursorLookupPtr) closure;
- WindowPtr pWin;
- GrabPtr pGrab;
- CursorPtr pCursor = 0, *pCursorRef = 0;
- XID cursor = 0;
-
- switch (rcl->type) {
- case RT_WINDOW:
- pWin = (WindowPtr) value;
- if (pWin->optional)
- {
- pCursorRef = &pWin->optional->cursor;
- pCursor = *pCursorRef;
- }
- break;
- case RT_PASSIVEGRAB:
- pGrab = (GrabPtr) value;
- pCursorRef = &pGrab->cursor;
- pCursor = *pCursorRef;
- break;
- case RT_CURSOR:
- pCursorRef = 0;
- pCursor = (CursorPtr) value;
- cursor = id;
- break;
- }
- if (pCursor && pCursor != rcl->pNew)
- {
- if ((*rcl->testCursor) (pCursor, rcl->closure))
- {
- rcl->pNew->refcnt++;
- /* either redirect reference or update resource database */
- if (pCursorRef)
- *pCursorRef = rcl->pNew;
- else
- ChangeResourceValue (id, RT_CURSOR, rcl->pNew);
- FreeCursor (pCursor, cursor);
- }
- }
- return FALSE; /* keep walking */
-}
-
-static void
-ReplaceCursor (CursorPtr pCursor,
- TestCursorFunc testCursor,
- pointer closure)
-{
- int clientIndex;
- int resIndex;
- ReplaceCursorLookupRec rcl;
-
- /*
- * Cursors exist only in the resource database, windows and grabs.
- * All of these are always pointed at by the resource database. Walk
- * the whole thing looking for cursors
- */
- rcl.testCursor = testCursor;
- rcl.pNew = pCursor;
- rcl.closure = closure;
-
- /* for each client */
- for (clientIndex = 0; clientIndex < currentMaxClients; clientIndex++)
- {
- if (!clients[clientIndex])
- continue;
- for (resIndex = 0; resIndex < NUM_CURSOR_RESTYPES; resIndex++)
- {
- rcl.type = CursorRestypes[resIndex];
- /*
- * This function walks the entire client resource database
- */
- LookupClientResourceComplex (clients[clientIndex],
- rcl.type,
- ReplaceCursorLookup,
- (pointer) &rcl);
- }
- }
- /* this "knows" that WindowHasNewCursor doesn't depend on it's argument */
- WindowHasNewCursor (screenInfo.screens[0]->root);
-}
-
-static Bool
-TestForCursor (CursorPtr pCursor, pointer closure)
-{
- return (pCursor == (CursorPtr) closure);
-}
-
-int
-ProcXFixesChangeCursor (ClientPtr client)
-{
- CursorPtr pSource, pDestination;
- REQUEST(xXFixesChangeCursorReq);
-
- REQUEST_SIZE_MATCH(xXFixesChangeCursorReq);
- VERIFY_CURSOR (pSource, stuff->source, client,
- DixReadAccess|DixGetAttrAccess);
- VERIFY_CURSOR (pDestination, stuff->destination, client,
- DixWriteAccess|DixSetAttrAccess);
-
- ReplaceCursor (pSource, TestForCursor, (pointer) pDestination);
- return Success;
-}
-
-int
-SProcXFixesChangeCursor (ClientPtr client)
-{
- int n;
- REQUEST(xXFixesChangeCursorReq);
-
- swaps (&stuff->length, n);
- REQUEST_SIZE_MATCH(xXFixesChangeCursorReq);
- swapl (&stuff->source, n);
- swapl (&stuff->destination, n);
- return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
-}
-
-static Bool
-TestForCursorName (CursorPtr pCursor, pointer closure)
-{
- Atom *pName = closure;
- return pCursor->name == *pName;
-}
-
-int
-ProcXFixesChangeCursorByName (ClientPtr client)
-{
- CursorPtr pSource;
- Atom name;
- char *tchar;
- REQUEST(xXFixesChangeCursorByNameReq);
-
- REQUEST_FIXED_SIZE(xXFixesChangeCursorByNameReq, stuff->nbytes);
- VERIFY_CURSOR(pSource, stuff->source, client,
- DixReadAccess|DixGetAttrAccess);
- tchar = (char *) &stuff[1];
- name = MakeAtom (tchar, stuff->nbytes, FALSE);
- if (name)
- ReplaceCursor (pSource, TestForCursorName, &name);
- return Success;
-}
-
-int
-SProcXFixesChangeCursorByName (ClientPtr client)
-{
- int n;
- REQUEST(xXFixesChangeCursorByNameReq);
-
- swaps (&stuff->length, n);
- REQUEST_AT_LEAST_SIZE (xXFixesChangeCursorByNameReq);
- swapl (&stuff->source, n);
- swaps (&stuff->nbytes, n);
- return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
-}
-
-/*
- * Routines for manipulating the per-screen hide counts list.
- * This list indicates which clients have requested cursor hiding
- * for that screen.
- */
-
-/* Return the screen's hide-counts list element for the given client */
-static CursorHideCountPtr
-findCursorHideCount (ClientPtr pClient, ScreenPtr pScreen)
-{
- CursorScreenPtr cs = GetCursorScreen(pScreen);
- CursorHideCountPtr pChc;
-
- for (pChc = cs->pCursorHideCounts; pChc != NULL; pChc = pChc->pNext) {
- if (pChc->pClient == pClient) {
- return pChc;
- }
- }
-
- return NULL;
-}
-
-static int
-createCursorHideCount (ClientPtr pClient, ScreenPtr pScreen)
-{
- CursorScreenPtr cs = GetCursorScreen(pScreen);
- CursorHideCountPtr pChc;
-
- pChc = (CursorHideCountPtr) malloc(sizeof(CursorHideCountRec));
- if (pChc == NULL) {
- return BadAlloc;
- }
- pChc->pClient = pClient;
- pChc->pScreen = pScreen;
- pChc->hideCount = 1;
- pChc->resource = FakeClientID(pClient->index);
- pChc->pNext = cs->pCursorHideCounts;
- cs->pCursorHideCounts = pChc;
-
- /*
- * Create a resource for this element so it can be deleted
- * when the client goes away.
- */
- if (!AddResource (pChc->resource, CursorHideCountType,
- (pointer) pChc)) {
- free(pChc);
- return BadAlloc;
- }
-
- return Success;
-}
-
-/*
- * Delete the given hide-counts list element from its screen list.
- */
-static void
-deleteCursorHideCount (CursorHideCountPtr pChcToDel, ScreenPtr pScreen)
-{
- CursorScreenPtr cs = GetCursorScreen(pScreen);
- CursorHideCountPtr pChc, pNext;
- CursorHideCountPtr pChcLast = NULL;
-
- pChc = cs->pCursorHideCounts;
- while (pChc != NULL) {
- pNext = pChc->pNext;
- if (pChc == pChcToDel) {
- free(pChc);
- if (pChcLast == NULL) {
- cs->pCursorHideCounts = pNext;
- } else {
- pChcLast->pNext = pNext;
- }
- return;
- }
- pChcLast = pChc;
- pChc = pNext;
- }
-}
-
-/*
- * Delete all the hide-counts list elements for this screen.
- */
-static void
-deleteCursorHideCountsForScreen (ScreenPtr pScreen)
-{
- CursorScreenPtr cs = GetCursorScreen(pScreen);
- CursorHideCountPtr pChc, pTmp;
-
- pChc = cs->pCursorHideCounts;
- while (pChc != NULL) {
- pTmp = pChc->pNext;
- FreeResource(pChc->resource, 0);
- pChc = pTmp;
- }
- cs->pCursorHideCounts = NULL;
-}
-
-int
-ProcXFixesHideCursor (ClientPtr client)
-{
- WindowPtr pWin;
- CursorHideCountPtr pChc;
- REQUEST(xXFixesHideCursorReq);
- int ret;
-
- REQUEST_SIZE_MATCH (xXFixesHideCursorReq);
-
- ret = dixLookupResourceByType((pointer *)&pWin, stuff->window, RT_WINDOW,
- client, DixGetAttrAccess);
- if (ret != Success) {
- client->errorValue = stuff->window;
- return ret;
- }
-
- /*
- * Has client hidden the cursor before on this screen?
- * If so, just increment the count.
- */
-
- pChc = findCursorHideCount(client, pWin->drawable.pScreen);
- if (pChc != NULL) {
- pChc->hideCount++;
- return Success;
- }
-
- /*
- * This is the first time this client has hid the cursor
- * for this screen.
- */
- ret = XaceHook(XACE_SCREEN_ACCESS, client, pWin->drawable.pScreen,
- DixHideAccess);
- if (ret != Success)
- return ret;
-
- ret = createCursorHideCount(client, pWin->drawable.pScreen);
-
- if (ret == Success) {
- DeviceIntPtr dev;
- for (dev = inputInfo.devices; dev; dev = dev->next)
- {
- if (IsMaster(dev) && IsPointerDevice(dev))
- CursorDisplayCursor(dev, pWin->drawable.pScreen, CursorCurrent[dev->id]);
- }
- }
-
- return ret;
-}
-
-int
-SProcXFixesHideCursor (ClientPtr client)
-{
- int n;
- REQUEST(xXFixesHideCursorReq);
-
- swaps (&stuff->length, n);
- REQUEST_SIZE_MATCH (xXFixesHideCursorReq);
- swapl (&stuff->window, n);
- return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
-}
-
-int
-ProcXFixesShowCursor (ClientPtr client)
-{
- WindowPtr pWin;
- CursorHideCountPtr pChc;
- int rc;
- REQUEST(xXFixesShowCursorReq);
-
- REQUEST_SIZE_MATCH (xXFixesShowCursorReq);
-
- rc = dixLookupResourceByType((pointer *)&pWin, stuff->window, RT_WINDOW,
- client, DixGetAttrAccess);
- if (rc != Success) {
- client->errorValue = stuff->window;
- return rc;
- }
-
- /*
- * Has client hidden the cursor on this screen?
- * If not, generate an error.
- */
- pChc = findCursorHideCount(client, pWin->drawable.pScreen);
- if (pChc == NULL) {
- return BadMatch;
- }
-
- rc = XaceHook(XACE_SCREEN_ACCESS, client, pWin->drawable.pScreen,
- DixShowAccess);
- if (rc != Success)
- return rc;
-
- pChc->hideCount--;
- if (pChc->hideCount <= 0) {
- FreeResource(pChc->resource, 0);
- }
-
- return Success;
-}
-
-int
-SProcXFixesShowCursor (ClientPtr client)
-{
- int n;
- REQUEST(xXFixesShowCursorReq);
-
- swaps (&stuff->length, n);
- REQUEST_SIZE_MATCH (xXFixesShowCursorReq);
- swapl (&stuff->window, n);
- return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
-}
-
-static int
-CursorFreeClient (pointer data, XID id)
-{
- CursorEventPtr old = (CursorEventPtr) data;
- CursorEventPtr *prev, e;
-
- for (prev = &cursorEvents; (e = *prev); prev = &e->next)
- {
- if (e == old)
- {
- *prev = e->next;
- free(e);
- break;
- }
- }
- return 1;
-}
-
-static int
-CursorFreeHideCount (pointer data, XID id)
-{
- CursorHideCountPtr pChc = (CursorHideCountPtr) data;
- ScreenPtr pScreen = pChc->pScreen;
- DeviceIntPtr dev;
-
- deleteCursorHideCount(pChc, pChc->pScreen);
- for (dev = inputInfo.devices; dev; dev = dev->next)
- {
- if (IsMaster(dev) && IsPointerDevice(dev))
- CursorDisplayCursor(dev, pScreen, CursorCurrent[dev->id]);
- }
-
- return 1;
-}
-
-static int
-CursorFreeWindow (pointer data, XID id)
-{
- WindowPtr pWindow = (WindowPtr) data;
- CursorEventPtr e, next;
-
- for (e = cursorEvents; e; e = next)
- {
- next = e->next;
- if (e->pWindow == pWindow)
- {
- FreeResource (e->clientResource, 0);
- }
- }
- return 1;
-}
-
-Bool
-XFixesCursorInit (void)
-{
- int i;
-
- if (party_like_its_1989)
- CursorVisible = EnableCursor;
-
- if (!dixRegisterPrivateKey(&CursorScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
- return FALSE;
-
- for (i = 0; i < screenInfo.numScreens; i++)
- {
- ScreenPtr pScreen = screenInfo.screens[i];
- CursorScreenPtr cs;
-
- cs = (CursorScreenPtr) calloc(1, sizeof (CursorScreenRec));
- if (!cs)
- return FALSE;
- Wrap (cs, pScreen, CloseScreen, CursorCloseScreen);
- Wrap (cs, pScreen, DisplayCursor, CursorDisplayCursor);
- cs->pCursorHideCounts = NULL;
- SetCursorScreen (pScreen, cs);
- }
- CursorClientType = CreateNewResourceType(CursorFreeClient,
- "XFixesCursorClient");
- CursorHideCountType = CreateNewResourceType(CursorFreeHideCount,
- "XFixesCursorHideCount");
- CursorWindowType = CreateNewResourceType(CursorFreeWindow,
- "XFixesCursorWindow");
-
- return CursorClientType && CursorHideCountType && CursorWindowType;
-}
-
+/* + * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright 2010 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright © 2002 Keith Packard + * + * 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 Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD 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_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "xfixesint.h" +#include "scrnintstr.h" +#include "cursorstr.h" +#include "dixevents.h" +#include "servermd.h" +#include "mipointer.h" +#include "inputstr.h" +#include "windowstr.h" +#include "xace.h" +#include "list.h" + +static RESTYPE CursorClientType; +static RESTYPE CursorHideCountType; +static RESTYPE CursorWindowType; +RESTYPE PointerBarrierType; +static CursorPtr CursorCurrent[MAXDEVICES]; + +static DevPrivateKeyRec CursorScreenPrivateKeyRec; +#define CursorScreenPrivateKey (&CursorScreenPrivateKeyRec) + +static void deleteCursorHideCountsForScreen (ScreenPtr pScreen); + +#define VERIFY_CURSOR(pCursor, cursor, client, access) \ + do { \ + int err; \ + err = dixLookupResourceByType((pointer *) &pCursor, cursor, \ + RT_CURSOR, client, access); \ + if (err != Success) { \ + client->errorValue = cursor; \ + return err; \ + } \ + } while (0) + +/* + * There is a global list of windows selecting for cursor events + */ + +typedef struct _CursorEvent *CursorEventPtr; + +typedef struct _CursorEvent { + CursorEventPtr next; + CARD32 eventMask; + ClientPtr pClient; + WindowPtr pWindow; + XID clientResource; +} CursorEventRec; + +static CursorEventPtr cursorEvents; + +/* + * Each screen has a list of clients which have requested + * that the cursor be hid, and the number of times each + * client has requested. +*/ + +typedef struct _CursorHideCountRec *CursorHideCountPtr; + +typedef struct _CursorHideCountRec { + CursorHideCountPtr pNext; + ClientPtr pClient; + ScreenPtr pScreen; + int hideCount; + XID resource; +} CursorHideCountRec; + +typedef struct PointerBarrierClient *PointerBarrierClientPtr; + +struct PointerBarrierClient { + ScreenPtr screen; + struct PointerBarrier barrier; + struct list entry; +}; + +/* + * Wrap DisplayCursor to catch cursor change events + */ + +typedef struct _CursorScreen { + DisplayCursorProcPtr DisplayCursor; + CloseScreenProcPtr CloseScreen; + ConstrainCursorHarderProcPtr ConstrainCursorHarder; + CursorHideCountPtr pCursorHideCounts; + struct list barriers; +} CursorScreenRec, *CursorScreenPtr; + +#define GetCursorScreen(s) ((CursorScreenPtr)dixLookupPrivate(&(s)->devPrivates, CursorScreenPrivateKey)) +#define GetCursorScreenIfSet(s) GetCursorScreen(s) +#define SetCursorScreen(s,p) dixSetPrivate(&(s)->devPrivates, CursorScreenPrivateKey, p) +#define Wrap(as,s,elt,func) (((as)->elt = (s)->elt), (s)->elt = func) +#define Unwrap(as,s,elt,backup) (((backup) = (s)->elt), (s)->elt = (as)->elt) + +/* The cursor doesn't show up until the first XDefineCursor() */ +static Bool CursorVisible = FALSE; + +Bool EnableCursor = TRUE; + +static Bool +CursorDisplayCursor (DeviceIntPtr pDev, + ScreenPtr pScreen, + CursorPtr pCursor) +{ + CursorScreenPtr cs = GetCursorScreen(pScreen); + Bool ret; + DisplayCursorProcPtr backupProc; + + Unwrap (cs, pScreen, DisplayCursor, backupProc); + + /* + * Have to check ConnectionInfo to distinguish client requests from + * initial root window setup. Not a great way to do it, I admit. + */ + if (ConnectionInfo) + CursorVisible = EnableCursor; + + if (cs->pCursorHideCounts != NULL || !CursorVisible) { + ret = (*pScreen->DisplayCursor) (pDev, pScreen, NullCursor); + } else { + ret = (*pScreen->DisplayCursor) (pDev, pScreen, pCursor); + } + + if (pCursor != CursorCurrent[pDev->id]) + { + CursorEventPtr e; + + CursorCurrent[pDev->id] = pCursor; + for (e = cursorEvents; e; e = e->next) + { + if ((e->eventMask & XFixesDisplayCursorNotifyMask)) + { + xXFixesCursorNotifyEvent ev; + ev.type = XFixesEventBase + XFixesCursorNotify; + ev.subtype = XFixesDisplayCursorNotify; + ev.window = e->pWindow->drawable.id; + ev.cursorSerial = pCursor->serialNumber; + ev.timestamp = currentTime.milliseconds; + ev.name = pCursor->name; + WriteEventsToClient (e->pClient, 1, (xEvent *) &ev); + } + } + } + Wrap (cs, pScreen, DisplayCursor, backupProc); + + return ret; +} + +static Bool +CursorCloseScreen (int index, ScreenPtr pScreen) +{ + CursorScreenPtr cs = GetCursorScreen (pScreen); + Bool ret; + CloseScreenProcPtr close_proc; + DisplayCursorProcPtr display_proc; + ConstrainCursorHarderProcPtr constrain_proc; + + Unwrap (cs, pScreen, CloseScreen, close_proc); + Unwrap (cs, pScreen, DisplayCursor, display_proc); + Unwrap (cs, pScreen, ConstrainCursorHarder, constrain_proc); + deleteCursorHideCountsForScreen(pScreen); + ret = (*pScreen->CloseScreen) (index, pScreen); + free(cs); + return ret; +} + +#define CursorAllEvents (XFixesDisplayCursorNotifyMask) + +static int +XFixesSelectCursorInput (ClientPtr pClient, + WindowPtr pWindow, + CARD32 eventMask) +{ + CursorEventPtr *prev, e; + pointer val; + int rc; + + for (prev = &cursorEvents; (e = *prev); prev = &e->next) + { + if (e->pClient == pClient && + e->pWindow == pWindow) + { + break; + } + } + if (!eventMask) + { + if (e) + { + FreeResource (e->clientResource, 0); + } + return Success; + } + if (!e) + { + e = (CursorEventPtr) malloc(sizeof (CursorEventRec)); + if (!e) + return BadAlloc; + + e->next = 0; + e->pClient = pClient; + e->pWindow = pWindow; + e->clientResource = FakeClientID(pClient->index); + + /* + * Add a resource hanging from the window to + * catch window destroy + */ + rc = dixLookupResourceByType( &val, pWindow->drawable.id, + CursorWindowType, serverClient, + DixGetAttrAccess); + if (rc != Success) + if (!AddResource (pWindow->drawable.id, CursorWindowType, + (pointer) pWindow)) + { + free(e); + return BadAlloc; + } + + if (!AddResource (e->clientResource, CursorClientType, (pointer) e)) + return BadAlloc; + + *prev = e; + } + e->eventMask = eventMask; + return Success; +} + +int +ProcXFixesSelectCursorInput (ClientPtr client) +{ + REQUEST (xXFixesSelectCursorInputReq); + WindowPtr pWin; + int rc; + + REQUEST_SIZE_MATCH (xXFixesSelectCursorInputReq); + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); + if (rc != Success) + return rc; + if (stuff->eventMask & ~CursorAllEvents) + { + client->errorValue = stuff->eventMask; + return BadValue; + } + return XFixesSelectCursorInput (client, pWin, stuff->eventMask); +} + +static int +GetBit (unsigned char *line, int x) +{ + unsigned char mask; + + if (screenInfo.bitmapBitOrder == LSBFirst) + mask = (1 << (x & 7)); + else + mask = (0x80 >> (x & 7)); + /* XXX assumes byte order is host byte order */ + line += (x >> 3); + if (*line & mask) + return 1; + return 0; +} + +int +SProcXFixesSelectCursorInput (ClientPtr client) +{ + register int n; + REQUEST(xXFixesSelectCursorInputReq); + + swaps(&stuff->length, n); + swapl(&stuff->window, n); + swapl(&stuff->eventMask, n); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + +void +SXFixesCursorNotifyEvent (xXFixesCursorNotifyEvent *from, + xXFixesCursorNotifyEvent *to) +{ + to->type = from->type; + cpswaps (from->sequenceNumber, to->sequenceNumber); + cpswapl (from->window, to->window); + cpswapl (from->cursorSerial, to->cursorSerial); + cpswapl (from->timestamp, to->timestamp); + cpswapl (from->name, to->name); +} + +static void +CopyCursorToImage (CursorPtr pCursor, CARD32 *image) +{ + int width = pCursor->bits->width; + int height = pCursor->bits->height; + int npixels = width * height; + +#ifdef ARGB_CURSOR + if (pCursor->bits->argb) + memcpy (image, pCursor->bits->argb, npixels * sizeof (CARD32)); + else +#endif + { + unsigned char *srcLine = pCursor->bits->source; + unsigned char *mskLine = pCursor->bits->mask; + int stride = BitmapBytePad (width); + int x, y; + CARD32 fg, bg; + + fg = (0xff000000 | + ((pCursor->foreRed & 0xff00) << 8) | + (pCursor->foreGreen & 0xff00) | + (pCursor->foreBlue >> 8)); + bg = (0xff000000 | + ((pCursor->backRed & 0xff00) << 8) | + (pCursor->backGreen & 0xff00) | + (pCursor->backBlue >> 8)); + for (y = 0; y < height; y++) + { + for (x = 0; x < width; x++) + { + if (GetBit (mskLine, x)) + { + if (GetBit (srcLine, x)) + *image++ = fg; + else + *image++ = bg; + } + else + *image++ = 0; + } + srcLine += stride; + mskLine += stride; + } + } +} + +int +ProcXFixesGetCursorImage (ClientPtr client) +{ +/* REQUEST(xXFixesGetCursorImageReq); */ + xXFixesGetCursorImageReply *rep; + CursorPtr pCursor; + CARD32 *image; + int npixels, width, height, rc, x, y; + + REQUEST_SIZE_MATCH(xXFixesGetCursorImageReq); + pCursor = CursorCurrent[PickPointer(client)->id]; + if (!pCursor) + return BadCursor; + rc = XaceHook(XACE_RESOURCE_ACCESS, client, pCursor->id, RT_CURSOR, + pCursor, RT_NONE, NULL, DixReadAccess); + if (rc != Success) + return rc; + GetSpritePosition (PickPointer(client), &x, &y); + width = pCursor->bits->width; + height = pCursor->bits->height; + npixels = width * height; + rep = malloc(sizeof (xXFixesGetCursorImageReply) + + npixels * sizeof (CARD32)); + if (!rep) + return BadAlloc; + + rep->type = X_Reply; + rep->sequenceNumber = client->sequence; + rep->length = npixels; + rep->width = width; + rep->height = height; + rep->x = x; + rep->y = y; + rep->xhot = pCursor->bits->xhot; + rep->yhot = pCursor->bits->yhot; + rep->cursorSerial = pCursor->serialNumber; + + image = (CARD32 *) (rep + 1); + CopyCursorToImage (pCursor, image); + if (client->swapped) + { + int n; + swaps (&rep->sequenceNumber, n); + swapl (&rep->length, n); + swaps (&rep->x, n); + swaps (&rep->y, n); + swaps (&rep->width, n); + swaps (&rep->height, n); + swaps (&rep->xhot, n); + swaps (&rep->yhot, n); + swapl (&rep->cursorSerial, n); + SwapLongs (image, npixels); + } + WriteToClient(client, sizeof (xXFixesGetCursorImageReply) + + (npixels << 2), (char *) rep); + free(rep); + return Success; +} + +int +SProcXFixesGetCursorImage (ClientPtr client) +{ + int n; + REQUEST(xXFixesGetCursorImageReq); + swaps (&stuff->length, n); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + +int +ProcXFixesSetCursorName (ClientPtr client) +{ + CursorPtr pCursor; + char *tchar; + REQUEST(xXFixesSetCursorNameReq); + Atom atom; + + REQUEST_AT_LEAST_SIZE(xXFixesSetCursorNameReq); + VERIFY_CURSOR(pCursor, stuff->cursor, client, DixSetAttrAccess); + tchar = (char *) &stuff[1]; + atom = MakeAtom (tchar, stuff->nbytes, TRUE); + if (atom == BAD_RESOURCE) + return BadAlloc; + + pCursor->name = atom; + return Success; +} + +int +SProcXFixesSetCursorName (ClientPtr client) +{ + int n; + REQUEST(xXFixesSetCursorNameReq); + + swaps (&stuff->length, n); + REQUEST_AT_LEAST_SIZE(xXFixesSetCursorNameReq); + swapl (&stuff->cursor, n); + swaps (&stuff->nbytes, n); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + +int +ProcXFixesGetCursorName (ClientPtr client) +{ + CursorPtr pCursor; + xXFixesGetCursorNameReply reply; + REQUEST(xXFixesGetCursorNameReq); + const char *str; + int len; + + REQUEST_SIZE_MATCH(xXFixesGetCursorNameReq); + VERIFY_CURSOR(pCursor, stuff->cursor, client, DixGetAttrAccess); + if (pCursor->name) + str = NameForAtom (pCursor->name); + else + str = ""; + len = strlen (str); + + reply.type = X_Reply; + reply.length = bytes_to_int32(len); + reply.sequenceNumber = client->sequence; + reply.atom = pCursor->name; + reply.nbytes = len; + if (client->swapped) + { + int n; + swaps (&reply.sequenceNumber, n); + swapl (&reply.length, n); + swapl (&reply.atom, n); + swaps (&reply.nbytes, n); + } + WriteReplyToClient(client, sizeof(xXFixesGetCursorNameReply), &reply); + WriteToClient(client, len, str); + + return Success; +} + +int +SProcXFixesGetCursorName (ClientPtr client) +{ + int n; + REQUEST(xXFixesGetCursorNameReq); + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xXFixesGetCursorNameReq); + swapl (&stuff->cursor, n); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + +int +ProcXFixesGetCursorImageAndName (ClientPtr client) +{ +/* REQUEST(xXFixesGetCursorImageAndNameReq); */ + xXFixesGetCursorImageAndNameReply *rep; + CursorPtr pCursor; + CARD32 *image; + int npixels; + const char *name; + int nbytes, nbytesRound; + int width, height; + int rc, x, y; + + REQUEST_SIZE_MATCH(xXFixesGetCursorImageAndNameReq); + pCursor = CursorCurrent[PickPointer(client)->id]; + if (!pCursor) + return BadCursor; + rc = XaceHook(XACE_RESOURCE_ACCESS, client, pCursor->id, RT_CURSOR, + pCursor, RT_NONE, NULL, DixReadAccess|DixGetAttrAccess); + if (rc != Success) + return rc; + GetSpritePosition (PickPointer(client), &x, &y); + width = pCursor->bits->width; + height = pCursor->bits->height; + npixels = width * height; + name = pCursor->name ? NameForAtom (pCursor->name) : ""; + nbytes = strlen (name); + nbytesRound = pad_to_int32(nbytes); + rep = malloc(sizeof (xXFixesGetCursorImageAndNameReply) + + npixels * sizeof (CARD32) + nbytesRound); + if (!rep) + return BadAlloc; + + rep->type = X_Reply; + rep->sequenceNumber = client->sequence; + rep->length = npixels + bytes_to_int32(nbytesRound); + rep->width = width; + rep->height = height; + rep->x = x; + rep->y = y; + rep->xhot = pCursor->bits->xhot; + rep->yhot = pCursor->bits->yhot; + rep->cursorSerial = pCursor->serialNumber; + rep->cursorName = pCursor->name; + rep->nbytes = nbytes; + + image = (CARD32 *) (rep + 1); + CopyCursorToImage (pCursor, image); + memcpy ((image + npixels), name, nbytes); + if (client->swapped) + { + int n; + swaps (&rep->sequenceNumber, n); + swapl (&rep->length, n); + swaps (&rep->x, n); + swaps (&rep->y, n); + swaps (&rep->width, n); + swaps (&rep->height, n); + swaps (&rep->xhot, n); + swaps (&rep->yhot, n); + swapl (&rep->cursorSerial, n); + swapl (&rep->cursorName, n); + swaps (&rep->nbytes, n); + SwapLongs (image, npixels); + } + WriteToClient(client, sizeof (xXFixesGetCursorImageAndNameReply) + + (npixels << 2) + nbytesRound, (char *) rep); + free(rep); + return Success; +} + +int +SProcXFixesGetCursorImageAndName (ClientPtr client) +{ + int n; + REQUEST(xXFixesGetCursorImageAndNameReq); + swaps (&stuff->length, n); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + +/* + * Find every cursor reference in the system, ask testCursor + * whether it should be replaced with a reference to pCursor. + */ + +typedef Bool (*TestCursorFunc) (CursorPtr pOld, pointer closure); + +typedef struct { + RESTYPE type; + TestCursorFunc testCursor; + CursorPtr pNew; + pointer closure; +} ReplaceCursorLookupRec, *ReplaceCursorLookupPtr; + +static const RESTYPE CursorRestypes[] = { + RT_WINDOW, RT_PASSIVEGRAB, RT_CURSOR +}; + +#define NUM_CURSOR_RESTYPES (sizeof (CursorRestypes) / sizeof (CursorRestypes[0])) + +static Bool +ReplaceCursorLookup (pointer value, XID id, pointer closure) +{ + ReplaceCursorLookupPtr rcl = (ReplaceCursorLookupPtr) closure; + WindowPtr pWin; + GrabPtr pGrab; + CursorPtr pCursor = 0, *pCursorRef = 0; + XID cursor = 0; + + switch (rcl->type) { + case RT_WINDOW: + pWin = (WindowPtr) value; + if (pWin->optional) + { + pCursorRef = &pWin->optional->cursor; + pCursor = *pCursorRef; + } + break; + case RT_PASSIVEGRAB: + pGrab = (GrabPtr) value; + pCursorRef = &pGrab->cursor; + pCursor = *pCursorRef; + break; + case RT_CURSOR: + pCursorRef = 0; + pCursor = (CursorPtr) value; + cursor = id; + break; + } + if (pCursor && pCursor != rcl->pNew) + { + if ((*rcl->testCursor) (pCursor, rcl->closure)) + { + rcl->pNew->refcnt++; + /* either redirect reference or update resource database */ + if (pCursorRef) + *pCursorRef = rcl->pNew; + else + ChangeResourceValue (id, RT_CURSOR, rcl->pNew); + FreeCursor (pCursor, cursor); + } + } + return FALSE; /* keep walking */ +} + +static void +ReplaceCursor (CursorPtr pCursor, + TestCursorFunc testCursor, + pointer closure) +{ + int clientIndex; + int resIndex; + ReplaceCursorLookupRec rcl; + + /* + * Cursors exist only in the resource database, windows and grabs. + * All of these are always pointed at by the resource database. Walk + * the whole thing looking for cursors + */ + rcl.testCursor = testCursor; + rcl.pNew = pCursor; + rcl.closure = closure; + + /* for each client */ + for (clientIndex = 0; clientIndex < currentMaxClients; clientIndex++) + { + if (!clients[clientIndex]) + continue; + for (resIndex = 0; resIndex < NUM_CURSOR_RESTYPES; resIndex++) + { + rcl.type = CursorRestypes[resIndex]; + /* + * This function walks the entire client resource database + */ + LookupClientResourceComplex (clients[clientIndex], + rcl.type, + ReplaceCursorLookup, + (pointer) &rcl); + } + } + /* this "knows" that WindowHasNewCursor doesn't depend on it's argument */ + WindowHasNewCursor (screenInfo.screens[0]->root); +} + +static Bool +TestForCursor (CursorPtr pCursor, pointer closure) +{ + return (pCursor == (CursorPtr) closure); +} + +int +ProcXFixesChangeCursor (ClientPtr client) +{ + CursorPtr pSource, pDestination; + REQUEST(xXFixesChangeCursorReq); + + REQUEST_SIZE_MATCH(xXFixesChangeCursorReq); + VERIFY_CURSOR (pSource, stuff->source, client, + DixReadAccess|DixGetAttrAccess); + VERIFY_CURSOR (pDestination, stuff->destination, client, + DixWriteAccess|DixSetAttrAccess); + + ReplaceCursor (pSource, TestForCursor, (pointer) pDestination); + return Success; +} + +int +SProcXFixesChangeCursor (ClientPtr client) +{ + int n; + REQUEST(xXFixesChangeCursorReq); + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xXFixesChangeCursorReq); + swapl (&stuff->source, n); + swapl (&stuff->destination, n); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + +static Bool +TestForCursorName (CursorPtr pCursor, pointer closure) +{ + Atom *pName = closure; + return pCursor->name == *pName; +} + +int +ProcXFixesChangeCursorByName (ClientPtr client) +{ + CursorPtr pSource; + Atom name; + char *tchar; + REQUEST(xXFixesChangeCursorByNameReq); + + REQUEST_FIXED_SIZE(xXFixesChangeCursorByNameReq, stuff->nbytes); + VERIFY_CURSOR(pSource, stuff->source, client, + DixReadAccess|DixGetAttrAccess); + tchar = (char *) &stuff[1]; + name = MakeAtom (tchar, stuff->nbytes, FALSE); + if (name) + ReplaceCursor (pSource, TestForCursorName, &name); + return Success; +} + +int +SProcXFixesChangeCursorByName (ClientPtr client) +{ + int n; + REQUEST(xXFixesChangeCursorByNameReq); + + swaps (&stuff->length, n); + REQUEST_AT_LEAST_SIZE (xXFixesChangeCursorByNameReq); + swapl (&stuff->source, n); + swaps (&stuff->nbytes, n); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + +/* + * Routines for manipulating the per-screen hide counts list. + * This list indicates which clients have requested cursor hiding + * for that screen. + */ + +/* Return the screen's hide-counts list element for the given client */ +static CursorHideCountPtr +findCursorHideCount (ClientPtr pClient, ScreenPtr pScreen) +{ + CursorScreenPtr cs = GetCursorScreen(pScreen); + CursorHideCountPtr pChc; + + for (pChc = cs->pCursorHideCounts; pChc != NULL; pChc = pChc->pNext) { + if (pChc->pClient == pClient) { + return pChc; + } + } + + return NULL; +} + +static int +createCursorHideCount (ClientPtr pClient, ScreenPtr pScreen) +{ + CursorScreenPtr cs = GetCursorScreen(pScreen); + CursorHideCountPtr pChc; + + pChc = (CursorHideCountPtr) malloc(sizeof(CursorHideCountRec)); + if (pChc == NULL) { + return BadAlloc; + } + pChc->pClient = pClient; + pChc->pScreen = pScreen; + pChc->hideCount = 1; + pChc->resource = FakeClientID(pClient->index); + pChc->pNext = cs->pCursorHideCounts; + cs->pCursorHideCounts = pChc; + + /* + * Create a resource for this element so it can be deleted + * when the client goes away. + */ + if (!AddResource (pChc->resource, CursorHideCountType, + (pointer) pChc)) { + free(pChc); + return BadAlloc; + } + + return Success; +} + +/* + * Delete the given hide-counts list element from its screen list. + */ +static void +deleteCursorHideCount (CursorHideCountPtr pChcToDel, ScreenPtr pScreen) +{ + CursorScreenPtr cs = GetCursorScreen(pScreen); + CursorHideCountPtr pChc, pNext; + CursorHideCountPtr pChcLast = NULL; + + pChc = cs->pCursorHideCounts; + while (pChc != NULL) { + pNext = pChc->pNext; + if (pChc == pChcToDel) { + free(pChc); + if (pChcLast == NULL) { + cs->pCursorHideCounts = pNext; + } else { + pChcLast->pNext = pNext; + } + return; + } + pChcLast = pChc; + pChc = pNext; + } +} + +/* + * Delete all the hide-counts list elements for this screen. + */ +static void +deleteCursorHideCountsForScreen (ScreenPtr pScreen) +{ + CursorScreenPtr cs = GetCursorScreen(pScreen); + CursorHideCountPtr pChc, pTmp; + + pChc = cs->pCursorHideCounts; + while (pChc != NULL) { + pTmp = pChc->pNext; + FreeResource(pChc->resource, 0); + pChc = pTmp; + } + cs->pCursorHideCounts = NULL; +} + +int +ProcXFixesHideCursor (ClientPtr client) +{ + WindowPtr pWin; + CursorHideCountPtr pChc; + REQUEST(xXFixesHideCursorReq); + int ret; + + REQUEST_SIZE_MATCH (xXFixesHideCursorReq); + + ret = dixLookupResourceByType((pointer *)&pWin, stuff->window, RT_WINDOW, + client, DixGetAttrAccess); + if (ret != Success) { + client->errorValue = stuff->window; + return ret; + } + + /* + * Has client hidden the cursor before on this screen? + * If so, just increment the count. + */ + + pChc = findCursorHideCount(client, pWin->drawable.pScreen); + if (pChc != NULL) { + pChc->hideCount++; + return Success; + } + + /* + * This is the first time this client has hid the cursor + * for this screen. + */ + ret = XaceHook(XACE_SCREEN_ACCESS, client, pWin->drawable.pScreen, + DixHideAccess); + if (ret != Success) + return ret; + + ret = createCursorHideCount(client, pWin->drawable.pScreen); + + if (ret == Success) { + DeviceIntPtr dev; + for (dev = inputInfo.devices; dev; dev = dev->next) + { + if (IsMaster(dev) && IsPointerDevice(dev)) + CursorDisplayCursor(dev, pWin->drawable.pScreen, CursorCurrent[dev->id]); + } + } + + return ret; +} + +int +SProcXFixesHideCursor (ClientPtr client) +{ + int n; + REQUEST(xXFixesHideCursorReq); + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH (xXFixesHideCursorReq); + swapl (&stuff->window, n); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + +int +ProcXFixesShowCursor (ClientPtr client) +{ + WindowPtr pWin; + CursorHideCountPtr pChc; + int rc; + REQUEST(xXFixesShowCursorReq); + + REQUEST_SIZE_MATCH (xXFixesShowCursorReq); + + rc = dixLookupResourceByType((pointer *)&pWin, stuff->window, RT_WINDOW, + client, DixGetAttrAccess); + if (rc != Success) { + client->errorValue = stuff->window; + return rc; + } + + /* + * Has client hidden the cursor on this screen? + * If not, generate an error. + */ + pChc = findCursorHideCount(client, pWin->drawable.pScreen); + if (pChc == NULL) { + return BadMatch; + } + + rc = XaceHook(XACE_SCREEN_ACCESS, client, pWin->drawable.pScreen, + DixShowAccess); + if (rc != Success) + return rc; + + pChc->hideCount--; + if (pChc->hideCount <= 0) { + FreeResource(pChc->resource, 0); + } + + return Success; +} + +int +SProcXFixesShowCursor (ClientPtr client) +{ + int n; + REQUEST(xXFixesShowCursorReq); + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH (xXFixesShowCursorReq); + swapl (&stuff->window, n); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + +static int +CursorFreeClient (pointer data, XID id) +{ + CursorEventPtr old = (CursorEventPtr) data; + CursorEventPtr *prev, e; + + for (prev = &cursorEvents; (e = *prev); prev = &e->next) + { + if (e == old) + { + *prev = e->next; + free(e); + break; + } + } + return 1; +} + +static int +CursorFreeHideCount (pointer data, XID id) +{ + CursorHideCountPtr pChc = (CursorHideCountPtr) data; + ScreenPtr pScreen = pChc->pScreen; + DeviceIntPtr dev; + + deleteCursorHideCount(pChc, pChc->pScreen); + for (dev = inputInfo.devices; dev; dev = dev->next) + { + if (IsMaster(dev) && IsPointerDevice(dev)) + CursorDisplayCursor(dev, pScreen, CursorCurrent[dev->id]); + } + + return 1; +} + +static int +CursorFreeWindow (pointer data, XID id) +{ + WindowPtr pWindow = (WindowPtr) data; + CursorEventPtr e, next; + + for (e = cursorEvents; e; e = next) + { + next = e->next; + if (e->pWindow == pWindow) + { + FreeResource (e->clientResource, 0); + } + } + return 1; +} + +static BOOL +barrier_is_horizontal(const struct PointerBarrier *barrier) +{ + return barrier->y1 == barrier->y2; +} + +static BOOL +barrier_is_vertical(const struct PointerBarrier *barrier) +{ + return barrier->x1 == barrier->x2; +} + +/** + * @return The set of barrier movement directions the movement vector + * x1/y1 → x2/y2 represents. + */ +int +barrier_get_direction(int x1, int y1, int x2, int y2) +{ + int direction = 0; + + /* which way are we trying to go */ + if (x2 > x1) + direction |= BarrierPositiveX; + if (x2 < x1) + direction |= BarrierNegativeX; + if (y2 > y1) + direction |= BarrierPositiveY; + if (y2 < y1) + direction |= BarrierNegativeY; + + return direction; +} + +/** + * Test if the barrier may block movement in the direction defined by + * x1/y1 → x2/y2. This function only tests whether the directions could be + * blocked, it does not test if the barrier actually blocks the movement. + * + * @return TRUE if the barrier blocks the direction of movement or FALSE + * otherwise. + */ +BOOL +barrier_is_blocking_direction(const struct PointerBarrier *barrier, int direction) +{ + /* Barriers define which way is ok, not which way is blocking */ + return (barrier->directions & direction) != direction; +} + +/** + * Test if the movement vector x1/y1 → x2/y2 is intersecting with the + * barrier. A movement vector with the startpoint or endpoint adjacent to + * the barrier itself counts as intersecting. + * + * @param x1 X start coordinate of movement vector + * @param y1 Y start coordinate of movement vector + * @param x2 X end coordinate of movement vector + * @param y2 Y end coordinate of movement vector + * @param[out] distance The distance between the start point and the + * intersection with the barrier (if applicable). + * @return TRUE if the barrier intersects with the given vector + */ +BOOL +barrier_is_blocking(const struct PointerBarrier *barrier, + int x1, int y1, int x2, int y2, + double *distance) +{ + BOOL rc = FALSE; + float ua, ub, ud; + int dir = barrier_get_direction(x1, y1, x2, y2); + + /* Algorithm below doesn't handle edge cases well, hence the extra + * checks. */ + if (barrier_is_vertical(barrier)) { + /* handle immediate barrier adjacency, moving away */ + if (dir & BarrierPositiveX && x1 == barrier->x1) + return FALSE; + if (dir & BarrierNegativeX && x1 == (barrier->x1 - 1)) + return FALSE; + /* startpoint adjacent to barrier, moving towards -> block */ + if (x1 == barrier->x1 && y1 >= barrier->y1 && y1 <= barrier->y2) { + *distance = 0; + return TRUE; + } + } else { + /* handle immediate barrier adjacency, moving away */ + if (dir & BarrierPositiveY && y1 == barrier->y1) + return FALSE; + if (dir & BarrierNegativeY && y1 == (barrier->y1 - 1)) + return FALSE; + /* startpoint adjacent to barrier, moving towards -> block */ + if (y1 == barrier->y1 && x1 >= barrier->x1 && x1 <= barrier->x2) { + *distance = 0; + return TRUE; + } + } + + /* not an edge case, compute distance */ + ua = 0; + ud = (barrier->y2 - barrier->y1) * (x2 - x1) - (barrier->x2 - barrier->x1) * (y2 - y1); + if (ud != 0) { + ua = ((barrier->x2 - barrier->x1) * (y1 - barrier->y1) - + (barrier->y2 - barrier->y1) * (x1 - barrier->x1)) / ud; + ub = ((x2 - x1) * (y1 - barrier->y1) - + (y2 - y1) * (x1 - barrier->x1)) / ud; + if (ua < 0 || ua > 1 || ub < 0 || ub > 1) + ua = 0; + } + + if (ua > 0 && ua <= 1) + { + double ix = barrier->x1 + ua * (barrier->x2 - barrier->x1); + double iy = barrier->y1 + ua * (barrier->y2 - barrier->y1); + + *distance = sqrt(pow(x1 - ix, 2) + pow(y1 - iy, 2)); + rc = TRUE; + } + + return rc; +} + +/** + * Find the nearest barrier that is blocking movement from x1/y1 to x2/y2. + * + * @param dir Only barriers blocking movement in direction dir are checked + * @param x1 X start coordinate of movement vector + * @param y1 Y start coordinate of movement vector + * @param x2 X end coordinate of movement vector + * @param y2 Y end coordinate of movement vector + * @return The barrier nearest to the movement origin that blocks this movement. + */ +static struct PointerBarrier* +barrier_find_nearest(CursorScreenPtr cs, int dir, + int x1, int y1, int x2, int y2) +{ + struct PointerBarrierClient *c; + struct PointerBarrier *nearest = NULL; + double min_distance = INT_MAX; /* can't get higher than that in X anyway */ + + list_for_each_entry(c, &cs->barriers, entry) { + struct PointerBarrier *b = &c->barrier; + double distance; + + if (!barrier_is_blocking_direction(b, dir)) + continue; + + if (barrier_is_blocking(b, x1, y1, x2, y2, &distance)) + { + if (min_distance > distance) + { + min_distance = distance; + nearest = b; + } + } + } + + return nearest; +} + +/** + * Clamp to the given barrier given the movement direction specified in dir. + * + * @param barrier The barrier to clamp to + * @param dir The movement direction + * @param[out] x The clamped x coordinate. + * @param[out] y The clamped x coordinate. + */ +void +barrier_clamp_to_barrier(struct PointerBarrier *barrier, int dir, int *x, int *y) +{ + if (barrier_is_vertical(barrier)) + { + if ((dir & BarrierNegativeX) & ~barrier->directions) + *x = barrier->x1; + if ((dir & BarrierPositiveX) & ~barrier->directions) + *x = barrier->x1 - 1; + } + if (barrier_is_horizontal(barrier)) + { + if ((dir & BarrierNegativeY) & ~barrier->directions) + *y = barrier->y1; + if ((dir & BarrierPositiveY) & ~barrier->directions) + *y = barrier->y1 - 1; + } +} + +static void +CursorConstrainCursorHarder(DeviceIntPtr dev, ScreenPtr screen, int mode, int *x, int *y) +{ + CursorScreenPtr cs = GetCursorScreen(screen); + + if (!list_is_empty(&cs->barriers) && !IsFloating(dev) && mode == Relative) { + int ox, oy; + int dir; + struct PointerBarrier *nearest = NULL; + + /* where are we coming from */ + miPointerGetPosition(dev, &ox, &oy); + + /* How this works: + * Given the origin and the movement vector, get the nearest barrier + * to the origin that is blocking the movement. + * Clamp to that barrier. + * Then, check from the clamped intersection to the original + * destination, again finding the nearest barrier and clamping. + */ + dir = barrier_get_direction(ox, oy, *x, *y); + + nearest = barrier_find_nearest(cs, dir, ox, oy, *x, *y); + if (nearest) { + barrier_clamp_to_barrier(nearest, dir, x, y); + + if (barrier_is_vertical(nearest)) { + dir &= ~(BarrierNegativeX | BarrierPositiveX); + ox = *x; + } else if (barrier_is_horizontal(nearest)) { + dir &= ~(BarrierNegativeY | BarrierPositiveY); + oy = *y; + } + + nearest = barrier_find_nearest(cs, dir, ox, oy, *x, *y); + if (nearest) { + barrier_clamp_to_barrier(nearest, dir, x, y); + } + } + } + + if (cs->ConstrainCursorHarder) { + screen->ConstrainCursorHarder = cs->ConstrainCursorHarder; + screen->ConstrainCursorHarder(dev, screen, mode, x, y); + screen->ConstrainCursorHarder = CursorConstrainCursorHarder; + } +} + +static struct PointerBarrierClient * +CreatePointerBarrierClient(ScreenPtr screen, ClientPtr client, + xXFixesCreatePointerBarrierReq *stuff) +{ + CursorScreenPtr cs = GetCursorScreen(screen); + struct PointerBarrierClient *ret = malloc(sizeof(*ret)); + + if (ret) { + ret->screen = screen; + ret->barrier.x1 = min(stuff->x1, stuff->x2); + ret->barrier.x2 = max(stuff->x1, stuff->x2); + ret->barrier.y1 = min(stuff->y1, stuff->y2); + ret->barrier.y2 = max(stuff->y1, stuff->y2); + ret->barrier.directions = stuff->directions & 0x0f; + if (barrier_is_horizontal(&ret->barrier)) + ret->barrier.directions &= ~(BarrierPositiveX | BarrierNegativeX); + if (barrier_is_vertical(&ret->barrier)) + ret->barrier.directions &= ~(BarrierPositiveY | BarrierNegativeY); + list_add(&ret->entry, &cs->barriers); + } + + return ret; +} + +int +ProcXFixesCreatePointerBarrier (ClientPtr client) +{ + int err; + WindowPtr pWin; + struct PointerBarrierClient *barrier; + struct PointerBarrier b; + REQUEST (xXFixesCreatePointerBarrierReq); + + REQUEST_SIZE_MATCH(xXFixesCreatePointerBarrierReq); + LEGAL_NEW_RESOURCE(stuff->barrier, client); + + err = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); + if (err != Success) { + client->errorValue = stuff->window; + return err; + } + + /* This sure does need fixing. */ + if (stuff->num_devices) + return BadImplementation; + + b.x1 = stuff->x1; + b.x2 = stuff->x2; + b.y1 = stuff->y1; + b.y2 = stuff->y2; + + if (!barrier_is_horizontal(&b) && !barrier_is_vertical(&b)) + return BadValue; + + /* no 0-sized barriers */ + if (barrier_is_horizontal(&b) && barrier_is_vertical(&b)) + return BadValue; + + if (!(barrier = CreatePointerBarrierClient(pWin->drawable.pScreen, + client, stuff))) + return BadAlloc; + + if (!AddResource(stuff->barrier, PointerBarrierType, &barrier->barrier)) + return BadAlloc; + + return Success; +} + +int +SProcXFixesCreatePointerBarrier (ClientPtr client) +{ + int n; + REQUEST(xXFixesCreatePointerBarrierReq); + + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xXFixesCreatePointerBarrierReq); + swapl(&stuff->barrier, n); + swapl(&stuff->window, n); + swaps(&stuff->x1, n); + swaps(&stuff->y1, n); + swaps(&stuff->x2, n); + swaps(&stuff->y2, n); + swapl(&stuff->directions, n); + return ProcXFixesVector[stuff->xfixesReqType](client); +} + +static int +CursorFreeBarrier(void *data, XID id) +{ + struct PointerBarrierClient *b = NULL, *barrier; + ScreenPtr screen; + CursorScreenPtr cs; + + barrier = container_of(data, struct PointerBarrierClient, barrier); + screen = barrier->screen; + cs = GetCursorScreen(screen); + + /* find and unlink from the screen private */ + list_for_each_entry(b, &cs->barriers, entry) { + if (b == barrier) { + list_del(&b->entry); + break; + } + } + + free(barrier); + return Success; +} + +int +ProcXFixesDestroyPointerBarrier (ClientPtr client) +{ + int err; + void *barrier; + REQUEST (xXFixesDestroyPointerBarrierReq); + + REQUEST_SIZE_MATCH(xXFixesDestroyPointerBarrierReq); + + err = dixLookupResourceByType((void **)&barrier, stuff->barrier, + PointerBarrierType, client, + DixDestroyAccess); + if (err != Success) { + client->errorValue = stuff->barrier; + return err; + } + + FreeResource(stuff->barrier, RT_NONE); + return Success; +} + +int +SProcXFixesDestroyPointerBarrier (ClientPtr client) +{ + int n; + REQUEST(xXFixesDestroyPointerBarrierReq); + + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xXFixesDestroyPointerBarrierReq); + swapl(&stuff->barrier, n); + return ProcXFixesVector[stuff->xfixesReqType](client); +} + +Bool +XFixesCursorInit (void) +{ + int i; + + if (party_like_its_1989) + CursorVisible = EnableCursor; + + if (!dixRegisterPrivateKey(&CursorScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) + return FALSE; + + for (i = 0; i < screenInfo.numScreens; i++) + { + ScreenPtr pScreen = screenInfo.screens[i]; + CursorScreenPtr cs; + + cs = (CursorScreenPtr) calloc(1, sizeof (CursorScreenRec)); + if (!cs) + return FALSE; + list_init(&cs->barriers); + Wrap (cs, pScreen, CloseScreen, CursorCloseScreen); + Wrap (cs, pScreen, DisplayCursor, CursorDisplayCursor); + Wrap (cs, pScreen, ConstrainCursorHarder, CursorConstrainCursorHarder); + cs->pCursorHideCounts = NULL; + SetCursorScreen (pScreen, cs); + } + CursorClientType = CreateNewResourceType(CursorFreeClient, + "XFixesCursorClient"); + CursorHideCountType = CreateNewResourceType(CursorFreeHideCount, + "XFixesCursorHideCount"); + CursorWindowType = CreateNewResourceType(CursorFreeWindow, + "XFixesCursorWindow"); + PointerBarrierType = CreateNewResourceType(CursorFreeBarrier, + "XFixesPointerBarrier"); + + return CursorClientType && CursorHideCountType && CursorWindowType && + PointerBarrierType; +} + diff --git a/xorg-server/xfixes/xfixes.c b/xorg-server/xfixes/xfixes.c index 54f0df341..e0ebedd80 100644 --- a/xorg-server/xfixes/xfixes.c +++ b/xorg-server/xfixes/xfixes.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright 2010 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -47,10 +48,6 @@ #include "xfixesint.h" #include "protocol-versions.h" -/* - * Must use these instead of the constants from xfixeswire.h. They advertise - * what we implement, not what the protocol headers define. - */ static unsigned char XFixesReqCode; int XFixesEventBase; @@ -97,11 +94,12 @@ ProcXFixesQueryVersion(ClientPtr client) /* Major version controls available requests */ static const int version_requests[] = { - X_XFixesQueryVersion, /* before client sends QueryVersion */ - X_XFixesGetCursorImage, /* Version 1 */ - X_XFixesChangeCursorByName, /* Version 2 */ - X_XFixesExpandRegion, /* Version 3 */ - X_XFixesShowCursor, /* Version 4 */ + X_XFixesQueryVersion, /* before client sends QueryVersion */ + X_XFixesGetCursorImage, /* Version 1 */ + X_XFixesChangeCursorByName, /* Version 2 */ + X_XFixesExpandRegion, /* Version 3 */ + X_XFixesShowCursor, /* Version 4 */ + X_XFixesDestroyPointerBarrier, /* Version 5 */ }; #define NUM_VERSION_REQUESTS (sizeof (version_requests) / sizeof (version_requests[0])) @@ -142,6 +140,9 @@ int (*ProcXFixesVector[XFixesNumberRequests])(ClientPtr) = { /*************** Version 4 ****************/ ProcXFixesHideCursor, ProcXFixesShowCursor, +/*************** Version 5 ****************/ + ProcXFixesCreatePointerBarrier, + ProcXFixesDestroyPointerBarrier, }; static int @@ -205,6 +206,9 @@ static int (*SProcXFixesVector[XFixesNumberRequests])(ClientPtr) = { /*************** Version 4 ****************/ SProcXFixesHideCursor, SProcXFixesShowCursor, +/*************** Version 5 ****************/ + SProcXFixesCreatePointerBarrier, + SProcXFixesDestroyPointerBarrier, }; static int @@ -260,6 +264,8 @@ XFixesExtensionInit(void) EventSwapVector[XFixesEventBase + XFixesCursorNotify] = (EventSwapPtr) SXFixesCursorNotifyEvent; SetResourceTypeErrorValue(RegionResType, XFixesErrorBase + BadRegion); + SetResourceTypeErrorValue(PointerBarrierType, + XFixesErrorBase + BadBarrier); } } diff --git a/xorg-server/xfixes/xfixes.h b/xorg-server/xfixes/xfixes.h index f834305bf..5765e64b5 100644 --- a/xorg-server/xfixes/xfixes.h +++ b/xorg-server/xfixes/xfixes.h @@ -1,55 +1,72 @@ -/*
- * Copyright © 2002 Keith Packard
- *
- * 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 Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD 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_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#ifndef _XFIXES_H_
-#define _XFIXES_H_
-
-#include "resource.h"
-
-extern _X_EXPORT RESTYPE RegionResType;
-extern _X_EXPORT int XFixesErrorBase;
-
-#define VERIFY_REGION(pRegion, rid, client, mode) \
- do { \
- int err; \
- err = dixLookupResourceByType((pointer *) &pRegion, rid, \
- RegionResType, client, mode); \
- if (err != Success) { \
- client->errorValue = rid; \
- return err; \
- } \
- } while (0)
-
-#define VERIFY_REGION_OR_NONE(pRegion, rid, client, mode) { \
- pRegion = 0; \
- if (rid) VERIFY_REGION(pRegion, rid, client, mode); \
-}
-
-extern _X_EXPORT RegionPtr
-XFixesRegionCopy (RegionPtr pRegion);
-
-
-#endif /* _XFIXES_H_ */
+/* + * Copyright © 2002 Keith Packard + * + * 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 Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD 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_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef _XFIXES_H_ +#define _XFIXES_H_ + +#include "resource.h" + +extern _X_EXPORT RESTYPE RegionResType; +extern _X_EXPORT RESTYPE PointerBarrierType; +extern _X_EXPORT int XFixesErrorBase; + +#define VERIFY_REGION(pRegion, rid, client, mode) \ + do { \ + int err; \ + err = dixLookupResourceByType((pointer *) &pRegion, rid, \ + RegionResType, client, mode); \ + if (err != Success) { \ + client->errorValue = rid; \ + return err; \ + } \ + } while (0) + +#define VERIFY_REGION_OR_NONE(pRegion, rid, client, mode) { \ + pRegion = 0; \ + if (rid) VERIFY_REGION(pRegion, rid, client, mode); \ +} + +extern _X_EXPORT RegionPtr +XFixesRegionCopy (RegionPtr pRegion); + +struct PointerBarrier { + CARD16 x1, x2, y1, y2; + CARD32 directions; +}; + + +extern int +barrier_get_direction(int, int, int, int); +extern BOOL +barrier_is_blocking(const struct PointerBarrier*, int, int, int, int, double*); +extern BOOL +barrier_is_blocking_direction(const struct PointerBarrier*, int); +extern void +barrier_clamp_to_barrier(struct PointerBarrier *barrier, int dir, int *x, int *y); + + + +#endif /* _XFIXES_H_ */ diff --git a/xorg-server/xfixes/xfixesint.h b/xorg-server/xfixes/xfixesint.h index a2a8e4163..6ba276e8c 100644 --- a/xorg-server/xfixes/xfixesint.h +++ b/xorg-server/xfixes/xfixesint.h @@ -1,285 +1,301 @@ -/*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright © 2002 Keith Packard
- *
- * 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 Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD 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_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#ifndef _XFIXESINT_H_
-#define _XFIXESINT_H_
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "os.h"
-#include "dixstruct.h"
-#include "extnsionst.h"
-#include <X11/extensions/xfixesproto.h>
-#include "windowstr.h"
-#include "selection.h"
-#include "xfixes.h"
-
-extern int XFixesEventBase;
-
-typedef struct _XFixesClient {
- CARD32 major_version;
- CARD32 minor_version;
-} XFixesClientRec, *XFixesClientPtr;
-
-#define GetXFixesClient(pClient) ((XFixesClientPtr)dixLookupPrivate(&(pClient)->devPrivates, XFixesClientPrivateKey))
-
-extern int (*ProcXFixesVector[XFixesNumberRequests])(ClientPtr);
-
-/* Initialize extension at server startup time */
-
-void
-XFixesExtensionInit(void);
-
-/* Save set */
-int
-ProcXFixesChangeSaveSet(ClientPtr client);
-
-int
-SProcXFixesChangeSaveSet(ClientPtr client);
-
-/* Selection events */
-int
-ProcXFixesSelectSelectionInput (ClientPtr client);
-
-int
-SProcXFixesSelectSelectionInput (ClientPtr client);
-
-void
-SXFixesSelectionNotifyEvent (xXFixesSelectionNotifyEvent *from,
- xXFixesSelectionNotifyEvent *to);
-Bool
-XFixesSelectionInit (void);
-
-/* Cursor notification */
-Bool
-XFixesCursorInit (void);
-
-int
-ProcXFixesSelectCursorInput (ClientPtr client);
-
-int
-SProcXFixesSelectCursorInput (ClientPtr client);
-
-void
-SXFixesCursorNotifyEvent (xXFixesCursorNotifyEvent *from,
- xXFixesCursorNotifyEvent *to);
-
-int
-ProcXFixesGetCursorImage (ClientPtr client);
-
-int
-SProcXFixesGetCursorImage (ClientPtr client);
-
-/* Cursor names (Version 2) */
-
-int
-ProcXFixesSetCursorName (ClientPtr client);
-
-int
-SProcXFixesSetCursorName (ClientPtr client);
-
-int
-ProcXFixesGetCursorName (ClientPtr client);
-
-int
-SProcXFixesGetCursorName (ClientPtr client);
-
-int
-ProcXFixesGetCursorImageAndName (ClientPtr client);
-
-int
-SProcXFixesGetCursorImageAndName (ClientPtr client);
-
-/* Cursor replacement (Version 2) */
-
-int
-ProcXFixesChangeCursor (ClientPtr client);
-
-int
-SProcXFixesChangeCursor (ClientPtr client);
-
-int
-ProcXFixesChangeCursorByName (ClientPtr client);
-
-int
-SProcXFixesChangeCursorByName (ClientPtr client);
-
-/* Region objects (Version 2* */
-Bool
-XFixesRegionInit (void);
-
-int
-ProcXFixesCreateRegion (ClientPtr client);
-
-int
-SProcXFixesCreateRegion (ClientPtr client);
-
-int
-ProcXFixesCreateRegionFromBitmap (ClientPtr client);
-
-int
-SProcXFixesCreateRegionFromBitmap (ClientPtr client);
-
-int
-ProcXFixesCreateRegionFromWindow (ClientPtr client);
-
-int
-SProcXFixesCreateRegionFromWindow (ClientPtr client);
-
-int
-ProcXFixesCreateRegionFromGC (ClientPtr client);
-
-int
-SProcXFixesCreateRegionFromGC (ClientPtr client);
-
-int
-ProcXFixesCreateRegionFromPicture (ClientPtr client);
-
-int
-SProcXFixesCreateRegionFromPicture (ClientPtr client);
-
-int
-ProcXFixesDestroyRegion (ClientPtr client);
-
-int
-SProcXFixesDestroyRegion (ClientPtr client);
-
-int
-ProcXFixesSetRegion (ClientPtr client);
-
-int
-SProcXFixesSetRegion (ClientPtr client);
-
-int
-ProcXFixesCopyRegion (ClientPtr client);
-
-int
-SProcXFixesCopyRegion (ClientPtr client);
-
-int
-ProcXFixesCombineRegion (ClientPtr client);
-
-int
-SProcXFixesCombineRegion (ClientPtr client);
-
-int
-ProcXFixesInvertRegion (ClientPtr client);
-
-int
-SProcXFixesInvertRegion (ClientPtr client);
-
-int
-ProcXFixesTranslateRegion (ClientPtr client);
-
-int
-SProcXFixesTranslateRegion (ClientPtr client);
-
-int
-ProcXFixesRegionExtents (ClientPtr client);
-
-int
-SProcXFixesRegionExtents (ClientPtr client);
-
-int
-ProcXFixesFetchRegion (ClientPtr client);
-
-int
-SProcXFixesFetchRegion (ClientPtr client);
-
-int
-ProcXFixesSetGCClipRegion (ClientPtr client);
-
-int
-SProcXFixesSetGCClipRegion (ClientPtr client);
-
-int
-ProcXFixesSetWindowShapeRegion (ClientPtr client);
-
-int
-SProcXFixesSetWindowShapeRegion (ClientPtr client);
-
-int
-ProcXFixesSetPictureClipRegion (ClientPtr client);
-
-int
-SProcXFixesSetPictureClipRegion (ClientPtr client);
-
-int
-ProcXFixesExpandRegion (ClientPtr client);
-
-int
-SProcXFixesExpandRegion (ClientPtr client);
-
-int
-PanoramiXFixesSetGCClipRegion (ClientPtr client);
-
-int
-PanoramiXFixesSetWindowShapeRegion (ClientPtr client);
-
-int
-PanoramiXFixesSetPictureClipRegion (ClientPtr client);
-
-/* Cursor Visibility (Version 4) */
-
-int
-ProcXFixesHideCursor (ClientPtr client);
-
-int
-SProcXFixesHideCursor (ClientPtr client);
-
-int
-ProcXFixesShowCursor (ClientPtr client);
-
-int
-SProcXFixesShowCursor (ClientPtr client);
-
-extern int (*PanoramiXSaveXFixesVector[XFixesNumberRequests])(ClientPtr);
-void PanoramiXFixesInit (void);
-void PanoramiXFixesReset (void);
-
-#endif /* _XFIXESINT_H_ */
+/* + * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright 2010 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright © 2002 Keith Packard + * + * 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 Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD 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_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef _XFIXESINT_H_ +#define _XFIXESINT_H_ + +#include <X11/X.h> +#include <X11/Xproto.h> +#include "misc.h" +#include "os.h" +#include "dixstruct.h" +#include "extnsionst.h" +#include <X11/extensions/xfixesproto.h> +#include "windowstr.h" +#include "selection.h" +#include "xfixes.h" + +extern int XFixesEventBase; + +typedef struct _XFixesClient { + CARD32 major_version; + CARD32 minor_version; +} XFixesClientRec, *XFixesClientPtr; + +#define GetXFixesClient(pClient) ((XFixesClientPtr)dixLookupPrivate(&(pClient)->devPrivates, XFixesClientPrivateKey)) + +extern int (*ProcXFixesVector[XFixesNumberRequests])(ClientPtr); + +/* Initialize extension at server startup time */ + +void +XFixesExtensionInit(void); + +/* Save set */ +int +ProcXFixesChangeSaveSet(ClientPtr client); + +int +SProcXFixesChangeSaveSet(ClientPtr client); + +/* Selection events */ +int +ProcXFixesSelectSelectionInput (ClientPtr client); + +int +SProcXFixesSelectSelectionInput (ClientPtr client); + +void +SXFixesSelectionNotifyEvent (xXFixesSelectionNotifyEvent *from, + xXFixesSelectionNotifyEvent *to); +Bool +XFixesSelectionInit (void); + +/* Cursor notification */ +Bool +XFixesCursorInit (void); + +int +ProcXFixesSelectCursorInput (ClientPtr client); + +int +SProcXFixesSelectCursorInput (ClientPtr client); + +void +SXFixesCursorNotifyEvent (xXFixesCursorNotifyEvent *from, + xXFixesCursorNotifyEvent *to); + +int +ProcXFixesGetCursorImage (ClientPtr client); + +int +SProcXFixesGetCursorImage (ClientPtr client); + +/* Cursor names (Version 2) */ + +int +ProcXFixesSetCursorName (ClientPtr client); + +int +SProcXFixesSetCursorName (ClientPtr client); + +int +ProcXFixesGetCursorName (ClientPtr client); + +int +SProcXFixesGetCursorName (ClientPtr client); + +int +ProcXFixesGetCursorImageAndName (ClientPtr client); + +int +SProcXFixesGetCursorImageAndName (ClientPtr client); + +/* Cursor replacement (Version 2) */ + +int +ProcXFixesChangeCursor (ClientPtr client); + +int +SProcXFixesChangeCursor (ClientPtr client); + +int +ProcXFixesChangeCursorByName (ClientPtr client); + +int +SProcXFixesChangeCursorByName (ClientPtr client); + +/* Region objects (Version 2* */ +Bool +XFixesRegionInit (void); + +int +ProcXFixesCreateRegion (ClientPtr client); + +int +SProcXFixesCreateRegion (ClientPtr client); + +int +ProcXFixesCreateRegionFromBitmap (ClientPtr client); + +int +SProcXFixesCreateRegionFromBitmap (ClientPtr client); + +int +ProcXFixesCreateRegionFromWindow (ClientPtr client); + +int +SProcXFixesCreateRegionFromWindow (ClientPtr client); + +int +ProcXFixesCreateRegionFromGC (ClientPtr client); + +int +SProcXFixesCreateRegionFromGC (ClientPtr client); + +int +ProcXFixesCreateRegionFromPicture (ClientPtr client); + +int +SProcXFixesCreateRegionFromPicture (ClientPtr client); + +int +ProcXFixesDestroyRegion (ClientPtr client); + +int +SProcXFixesDestroyRegion (ClientPtr client); + +int +ProcXFixesSetRegion (ClientPtr client); + +int +SProcXFixesSetRegion (ClientPtr client); + +int +ProcXFixesCopyRegion (ClientPtr client); + +int +SProcXFixesCopyRegion (ClientPtr client); + +int +ProcXFixesCombineRegion (ClientPtr client); + +int +SProcXFixesCombineRegion (ClientPtr client); + +int +ProcXFixesInvertRegion (ClientPtr client); + +int +SProcXFixesInvertRegion (ClientPtr client); + +int +ProcXFixesTranslateRegion (ClientPtr client); + +int +SProcXFixesTranslateRegion (ClientPtr client); + +int +ProcXFixesRegionExtents (ClientPtr client); + +int +SProcXFixesRegionExtents (ClientPtr client); + +int +ProcXFixesFetchRegion (ClientPtr client); + +int +SProcXFixesFetchRegion (ClientPtr client); + +int +ProcXFixesSetGCClipRegion (ClientPtr client); + +int +SProcXFixesSetGCClipRegion (ClientPtr client); + +int +ProcXFixesSetWindowShapeRegion (ClientPtr client); + +int +SProcXFixesSetWindowShapeRegion (ClientPtr client); + +int +ProcXFixesSetPictureClipRegion (ClientPtr client); + +int +SProcXFixesSetPictureClipRegion (ClientPtr client); + +int +ProcXFixesExpandRegion (ClientPtr client); + +int +SProcXFixesExpandRegion (ClientPtr client); + +int +PanoramiXFixesSetGCClipRegion (ClientPtr client); + +int +PanoramiXFixesSetWindowShapeRegion (ClientPtr client); + +int +PanoramiXFixesSetPictureClipRegion (ClientPtr client); + +/* Cursor Visibility (Version 4) */ + +int +ProcXFixesHideCursor (ClientPtr client); + +int +SProcXFixesHideCursor (ClientPtr client); + +int +ProcXFixesShowCursor (ClientPtr client); + +int +SProcXFixesShowCursor (ClientPtr client); + +/* Version 5 */ + +int +ProcXFixesCreatePointerBarrier (ClientPtr client); + +int +SProcXFixesCreatePointerBarrier (ClientPtr client); + +int +ProcXFixesDestroyPointerBarrier (ClientPtr client); + +int +SProcXFixesDestroyPointerBarrier (ClientPtr client); + +/* Xinerama */ +extern int (*PanoramiXSaveXFixesVector[XFixesNumberRequests])(ClientPtr); +void PanoramiXFixesInit (void); +void PanoramiXFixesReset (void); + +#endif /* _XFIXESINT_H_ */ diff --git a/xorg-server/xkeyboard-config/configure.in b/xorg-server/xkeyboard-config/configure.in index e4008a973..527e807bd 100644 --- a/xorg-server/xkeyboard-config/configure.in +++ b/xorg-server/xkeyboard-config/configure.in @@ -1,4 +1,4 @@ -AC_INIT(xkeyboard-config, 2.3) +AC_INIT(xkeyboard-config, 2.3.99) AC_CONFIG_SRCDIR(rules/base.xml.in) AM_INIT_AUTOMAKE([foreign dist-bzip2]) AM_MAINTAINER_MODE diff --git a/xorg-server/xkeyboard-config/rules/base.extras.xml.in b/xorg-server/xkeyboard-config/rules/base.extras.xml.in index a6b52f0ed..119636500 100644 --- a/xorg-server/xkeyboard-config/rules/base.extras.xml.in +++ b/xorg-server/xkeyboard-config/rules/base.extras.xml.in @@ -38,6 +38,27 @@ </layout> <layout> <configItem> + <name>de</name> + <_shortDescription>de</_shortDescription> + <_description>German</_description> + <languageList> + <iso639Id>ger</iso639Id> + </languageList> + </configItem> + <variantList> + <variant> + <configItem> + <name>us</name> + <_description>German (US keyboard with German letters)</_description> + <languageList> + <iso639Id>eng</iso639Id> + </languageList> + </configItem> + </variant> + </variantList> + </layout> + <layout> + <configItem> <name>ir</name> <_shortDescription>fa</_shortDescription> <_description>Persian</_description> @@ -241,7 +262,7 @@ <configItem> <name>ruu</name> <_shortDescription>ru</_shortDescription> - <_description>Russian (with UKR and BEL layout)</_description> + <_description>Russian (with Ukrainian-Belorussian layout)</_description> <languageList><iso639Id>rus</iso639Id> <iso639Id>ukr</iso639Id> <iso639Id>bel</iso639Id></languageList> diff --git a/xorg-server/xkeyboard-config/rules/base.xml.in b/xorg-server/xkeyboard-config/rules/base.xml.in index 9f117cf34..7d4e2b9c9 100644 --- a/xorg-server/xkeyboard-config/rules/base.xml.in +++ b/xorg-server/xkeyboard-config/rules/base.xml.in @@ -2132,7 +2132,7 @@ <variant> <configItem> <name>qwerty</name> - <_description>English (Cameroon qwerty)</_description> + <_description>Cameroon Multilingual (qwerty)</_description> <languageList> <iso639Id>eng</iso639Id> <iso639Id>bas</iso639Id> @@ -2169,7 +2169,7 @@ <variant> <configItem> <name>azerty</name> - <_description>French (Cameroon azerty)</_description> + <_description>Cameroon Multilingual (azerty)</_description> <languageList> <iso639Id>fra</iso639Id> <iso639Id>bas</iso639Id> @@ -4453,7 +4453,7 @@ <configItem> <name>lk</name> <_shortDescription>si</_shortDescription> - <_description>Sinhala</_description> + <_description>Sinhala (phonetic)</_description> <languageList> <iso639Id>sin</iso639Id> </languageList> diff --git a/xorg-server/xkeyboard-config/symbols/cm b/xorg-server/xkeyboard-config/symbols/cm index 1757ae05b..0bca38ef7 100644 --- a/xorg-server/xkeyboard-config/symbols/cm +++ b/xorg-server/xkeyboard-config/symbols/cm @@ -1,331 +1,331 @@ -// ========== Cameroon Keyboards ==========
-// ****** For Instructions, see "Use of Cameroon Keyboards" section below ******
-
-
-// The XKB versions of these keyboards were developed by Matthew Lee, Jenni Beadle, and Bruce Cox of SIL Cameroon in association with Going Komputya, Uwe Yung of the Goethe Institute, Yaoundé, and Centre ANACLAC.
-
-// Cameroon is officially a bilingual country, using French and English, but there are over 270 minority languages.
-
-// * Cameroon Français is an exact copy of the French France keyboard intended for AZERTY users.
-// * Cameroon is an exact copy of the Basic US Keyboard. I can not currently name this "Cameroon English" due to a limitation of XKB.
-// * Cameroon QWERTY and Cameroon AZERTY are based largely on SIL Cameroon's Keyman and Microsoft keyboards of the same style already in wide use. These keyboards are designed to allow the user to type any of Cameroon's 270+ languages and dialects that use the approved orthography. This Approved Orthography was adopted in 1979 by the National Committee for the Unification and Harmonisation of Alphabets of Camerooninan Languages.
-// * Cameroon Dvorak is described below.
-
-// ===== Use of Cameroon Keyboards =====
-
-// == Fonts ==
-// These keyboards are fully Unicode (5.1), so we recommend using a good unicode font for diacritics to position correctly. Recommended fonts are: ttf-sil-charis, ttf-sil-doulos, ttf-sil-gentium and ttf-sil-andika (All of which are free for Linux, Mac, and Windows).
-
-
-// == Cameroon AZERTY ==
-// Cameroon AZERTY uses the French France (AZERTY) layout, as french keyboards are widely used here. While this keyboard is designed for Cameroonian orthography, it still is possible but not recommended, to type French with minimal discomfort using this keyboard.
-// Cameroon AZERTY uses the "!" (exclamation) key as the "Cameroon" key. Pressing this key before another key allows you to access the special letters and diacritics needed in Cameroonian orthography.
-// For example, press "!" then "a" and get "ɛ" (small epsilon). "!" then "Shift" + "a" (A) will get an "Ɛ" (capital epsilon). Press the "!" key twice to get a "!".
-// If you prefer, you can hold the AltGr (and/or Shift) key to access the same letters, but we have found this to be much more awkward in practice. If you really don't like our Cameroon key, simply comment out "include "cm(exclamation_switch)"" and the exclamation key will return to normal.
-// All Diacritics (with the exception of French Trema and Circumflex) must be typed (in order of stacking) after the letter.
-
-
-// == Cameroon QWERTY ==
-// Cameroon QWERTY uses the US QWERTY layout, as US keyboards are also widely used here. While this keyboard is designed for Cameroonian orthography, it is possible, but not recommended, to type English with minimal discomfort using this keyboard.
-// Cameroon QWERTY uses the ";" (semicolon) key as the "Cameroon" key. Pressing this key before another key allows you to access the special letters and diacritics needed in Cameroonian orthography.
-// For example, press ";" then "a" and get "ɛ" (small epsilon). ";" then "Shift" + "a" (A) will get an "Ɛ" (capital epsilon). Press ";" twice to get a ";", or press Shift + ; (:) twice to get a ":" (colon).
-// If you prefer, you can hold the AltGr (and/or Shift) key to access the same letters, but we have found this to be much more awkward in practice. If you really don't like our Cameroon key, simply comment out "include "cm(semicolon_switch)"" and the semicolon key will return to normal.
-// All Diacritics must be typed (in order of stacking) after the letter.
-
-
-// == Cameroon Dvorak ==
-// Cameroon Dvorak is uses a similar system to Cameroon QWERTY.
-
-default
-partial alphanumeric_keys
-xkb_symbols "basic" {
-
- name[Group1]="English (Cameroon)";
-
- // Alphanumeric section
- key <TLDE> { [ grave, asciitilde ] };
- key <AE01> { [ 1, exclam ] };
- key <AE02> { [ 2, at ] };
- key <AE03> { [ 3, numbersign ] };
- key <AE04> { [ 4, dollar ] };
- key <AE05> { [ 5, percent ] };
- key <AE06> { [ 6, asciicircum ] };
- key <AE07> { [ 7, ampersand ] };
- key <AE08> { [ 8, asterisk ] };
- key <AE09> { [ 9, parenleft ] };
- key <AE10> { [ 0, parenright ] };
- key <AE11> { [ minus, underscore ] };
- key <AE12> { [ equal, plus ] };
-
- key <AD01> { [ q, Q ] };
- key <AD02> { [ w, W ] };
- key <AD03> { [ e, E ] };
- key <AD04> { [ r, R ] };
- key <AD05> { [ t, T ] };
- key <AD06> { [ y, Y ] };
- key <AD07> { [ u, U ] };
- key <AD08> { [ i, I ] };
- key <AD09> { [ o, O ] };
- key <AD10> { [ p, P ] };
- key <AD11> { [ bracketleft, braceleft ] };
- key <AD12> { [ bracketright, braceright ] };
- key <AC01> { [ a, A ] };
- key <AC02> { [ s, S ] };
- key <AC03> { [ d, D ] };
- key <AC04> { [ f, F ] };
- key <AC05> { [ g, G ] };
- key <AC06> { [ h, H ] };
- key <AC07> { [ j, J ] };
- key <AC08> { [ k, K ] };
- key <AC09> { [ l, L ] };
- key <AC10> { [ semicolon, colon ] };
- key <AC11> { [ apostrophe, quotedbl ] };
-
- key <AB01> { [ z, Z ] };
- key <AB02> { [ x, X ] };
- key <AB03> { [ c, C ] };
- key <AB04> { [ v, V ] };
- key <AB05> { [ b, B ] };
- key <AB06> { [ n, N ] };
- key <AB07> { [ m, M ] };
- key <AB08> { [ comma, less ] };
- key <AB09> { [ period, greater ] };
- key <AB10> { [ slash, U003F ] };
-
- key <BKSL> { [ backslash, bar ] };
- // End alphanumeric section
-};
-
-partial alphanumeric_keys
-xkb_symbols "french"
-{
- name[Group1]="French (Cameroon)";
- include "latin"
-
- key <AE01> { [ ampersand, 1, onesuperior, exclamdown ] };
- key <AE02> { [ eacute, 2, asciitilde, oneeighth ] };
- key <AE03> { [ quotedbl, 3, numbersign, sterling ] };
- key <AE04> { [apostrophe, 4, braceleft, dollar ] };
- key <AE05> { [ parenleft, 5, bracketleft, threeeighths ] };
- key <AE06> { [ minus, 6, bar, fiveeighths ] };
- key <AE07> { [ egrave, 7, grave, seveneighths ] };
- key <AE08> { [underscore, 8, backslash, trademark ] };
- key <AE09> { [ ccedilla, 9, asciicircum, plusminus ] };
- key <AE10> { [ agrave, 0, at, degree ] };
- key <AE11> { [parenright, degree, bracketright, questiondown ] };
- key <AE12> { [ equal, plus, braceright, dead_ogonek ] };
-
- key <AD01> { [ a, A, ae, AE ] };
- key <AD02> { [ z, Z, guillemotleft, less ] };
- key <AD03> { [ e, E, EuroSign, cent ] };
- key <AD11> { [dead_circumflex, dead_diaeresis, dead_diaeresis, dead_abovering ] };
- key <AD12> { [ dollar, sterling, currency, dead_macron ] };
-
- key <AC01> { [ q, Q, at, Greek_OMEGA ] };
- key <AC10> { [ m, M, mu, masculine ] };
- key <AC11> { [ ugrave, percent, dead_circumflex, dead_caron] };
- key <TLDE> { [twosuperior, asciitilde, notsign, notsign ] };
-
- key <BKSL> { [ asterisk, mu, dead_grave, dead_breve ] };
- key <AB01> { [ w, W, lstroke, Lstroke ] };
- key <AB07> { [ comma, U003F, dead_acute, dead_doubleacute ] };
- key <AB08> { [ semicolon, period, horizconnector, multiply ] };
- key <AB09> { [ colon, slash, periodcentered, division ] };
- key <AB10> { [ exclam, section, dead_belowdot, dead_abovedot ] };
-
- include "level3(ralt_switch)"
-};
-
-
-partial alphanumeric_keys
-xkb_symbols "azerty"
-{
- name[Group1] = "French (Cameroon azerty)";
- include "level3(ralt_switch)"
- include "cm(basic)"
- key <AB01> { [ w, W, U1E85, U1E84 ] }; // SMALL LETTER W, CAPITAL LETTER W, SMALL LETTER W WITH DIAERESIS, CAPITAL LETTER W WITH DIAERESIS
- key <AB02> { [ x, X, U2039, U203A ] }; // SMALL LETTER X, CAPITAL LETTER X, SINGLE LEFT-POINTING ANGLE QUOTATION MARK, SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
- key <AB03> { [ c, C, U0327, copyright ] }; // SMALL LETTER C, CAPITAL LETTER C, COMBINING CEDILLA, COPYRIGHT SIGN
- key <AB04> { [ v, V, U25CC, NoSymbol ] }; // SMALL LETTER V, CAPITAL LETTER V, PLACEHOLDER CHARACTER
- key <AB05> { [ b, B, U0253, U0181 ] }; // SMALL LETTER B, CAPITAL LETTER B, SMALL LETTER B WITH HOOK, CAPITAL LETTER B WITH HOOK
- key <AB06> { [ n, N, U014B, U014A ] }; // SMALL LETTER N, CAPITAL LETTER N, SMALL LETTER ENG, CAPITAL LETTER ENG
- key <AB07> { [ U002C, U003F, NoSymbol, U00D7 ] }; // COMMA, QUESTION MARK, , MULTIPLY
- key <AB08> { [ semicolon, period, dead_acute, dead_grave ] }; // SEMICOLON, PERIOD
- key <AB09> { [ colon, slash, U0323 ] }; // COLON, SLASH, COMBINING DOT BELOW
- key <AB10> { [ exclam, U00A7 ] }; // EXCLAMATION MARK, SECTION SIGN
- key <AC01> { [ q, Q, U2014, U2013 ] }; // SMALL LETTER Q, CAPITAL LETTER Q, EM DASH, EN DASH
- key <AC02> { [ s, S, U201C, U201D ] }; // SMALL LETTER S, CAPITAL LETTER S, LEFT DOUBLE QUOTES, RIGHT DOUBLE QUOTES
- key <AC03> { [ d, D, U0257, U018A ] }; // SMALL LETTER D, CAPITAL LETTER D, SMALL LETTER D WITH HOOK, CAPITAL LETTER D WITH HOOK
- key <AC04> { [ f, F, U00E6, U00C6 ] }; // SMALL LETTER F, CAPITAL LETTER F, SMALL LIGATURE AE, CAPITAL LIGATURE AE
- key <AC05> { [ g, G, UA78C, UA78B ] }; // SMALL LETTER G, CAPITAL LETTER G, SMALL LETTER GLOTTAL (SALTILLO), CAPITAL LETTER GLOTTAL (SALTILLO)
- key <AC06> { [ h, H, U0251, U2C6D ] }; // SMALL LETTER H, CAPITAL LETTER H, SMALL LETTER ALPHA, CAPITAL LETTER ALPHA
- key <AC07> { [ j, J, leftarrow, U2122 ] }; //SMALL LETTER J, CAPITAL LETTER J, LEFT ARROW, TRADE MARK SIGN
- key <AC08> { [ k, K, downarrow, uparrow ] }; // SMALL LETTER K, CAPITAL LETTER K, DOWN ARROW, UP ARROW
- key <AC09> { [ l, L, rightarrow, U00A3 ] }; // SMALL LETTER L, CAPITAL LETTER L, RIGHT ARROW, POUND STERLING
- key <AC10> { [ m, M, U00F9, U00B5 ] }; // SMALL LETTER M, CAPITAL LETTER M, SMALL LETTER U WITH GRAVE, MICRO SYMBOL
- key <AC11> { [ U0300, U0302, U1DC5, U1DC4 ] }; // COMBINING LOW TONE, COMBINING FALLING TONE, COMBINING LOW-MID TONE, COMBINING MID-HIGH TONE
- key <AD01> { [ a, A, U025B, U0190 ] }; // SMALL LETTER A, CAPITAL LETTER A, SMALL LETTER OPEN E, CAPITAL LETTER OPEN E
- key <AD02> { [ z, Z, U2026, U2020 ] }; // SMALL LETTER Z, CAPITAL LETTER Z, ELLIPSIS, DAGGER
- key <AD03> { [ e, E, U0259, U018F ] }; // SMALL LETTER E, CAPITAL LETTER E, SMALL LETTER SCHWA, CAPITAL LETTER SCHWA
- key <AD04> { [ r, R, NoSymbol, U00AE ] }; // SMALL LETTER R, CAPITAL LETTER R, , REGISTERED SIGN
- key <AD05> { [ t, T, U0153, U0152 ] }; // SMALL LETTER T, CAPITAL LETTER T, SMALL LIGATURE OE, CAPITAL LIGATURE OE
- key <AD06> { [ y, Y, U01B4, U01B3 ] }; // SMALL LETTER Y, CAPITAL LETTER Y, SMALL LETTER Y WITH HOOK, CAPITAL LETTER Y WITH HOOK
- key <AD07> { [ u, U, U0289, U0244 ] }; // SMALL LETTER U, CAPITAL LETTER U, SMALL LETTER U BAR, CAPITAL LETTER U BAR
- key <AD08> { [ i, I, U0268, U0197 ] }; // SMALL LETTER I, CAPITAL LETTER I, SMALL LETTER I BAR, CAPITAL LETTER I BAR
- key <AD09> { [ o, O, U0254, U0186 ] }; // SMALL LETTER O, CAPITAL LETTER O, SMALL LETTER OPEN O, CAPITAL LETTER OPEN O
- key <AD10> { [ p, P, U00F8, U00D8 ] }; // SMALL LETTER P, CAPITAL LETTER P, SMALL LETTER O BAR, CAPITAL LETTER O BAR
- key <AD11> { [ U0301, U030C, dead_circumflex, dead_diaeresis ] }; // COMBINING HIGH TONE, COMBINING RISING TONE, DEAD CIRCUMFLEX, DEAD DIAERESIS
- key <AD12> { [ U0330, U0303, U0304, U030D ] }; // COMBINING TILDE (NASAL) BELOW, COMBINING TILDE (NASAL), COMBINING MID TONE, COMBINING VERTICAL LINE ABOVE
- key <AE01> { [ U0026, KP_1, U00B9, U2018 ] }; // AMPERSAND, 1, SUPERSCRIPT 1, LEFT SINGLE QUOTE
- key <AE02> { [ eacute, KP_2, asciitilde, U2019 ] }; // SMALL LETTER E WITH ACUTE, 2, TILDE, RIGHT SINGLE QUOTE
- key <AE03> { [ U0022, KP_3, U0025 ] }; // QUOTATION MARK, 3, PERCENT SIGN
- key <AE04> { [ U0027, KP_4, U007B ] }; // APOSTROPHE, 4, LEFT CURLY BRACKET
- key <AE05> { [ U0028, KP_5, U005B, numbersign ] }; // LEFT PARENTHESIS, 5, LEFT SQUARE BRACKET, NUMBER SIGN
- key <AE06> { [ U002D, KP_6, U007C ] }; // HYPHEN/MINUS, 6, BAR
- key <AE07> { [ U00E8, KP_7, U0300 ] }; // SMALL LETTER E WITH GRAVE, 7, COMBINING GRAVE
- key <AE08> { [ underscore, KP_8, backslash, U20D6 ] }; // UNDERSCORE, 8, BACKSLASH, COMBINING LEFT ARROW ABOVE
- key <AE09> { [ ccedilla, KP_9, U005E] }; // SMALL LETTER C WITH CEDILLA, 9, CIRCUMFLEX
- key <AE10> { [ U00E0, KP_0, at, U20D7 ] }; // SMALL LETTER A WITH GRAVE
- key <AE11> { [ U0029, U00B0, U005D ] }; // RIGHT PARENTHESIS, DEGREE, RIGHT SQUARE BRACKET
- key <AE12> { [ U003D, U002B, U007D, U00B1 ] }; // EQUAL SIGN, PLUS SIGN, RIGHT CURLY BRACKET, PLUS-MINUS SIGN
- key <BKSL> { [ U1DC6, U1DC7, KP_Multiply, U00A4 ] }; // COMBINING MID-LOW, COMBINING HIGH-MID, MULTIPLY, CURRENCY SIGN
- key <LSGT> { [ U003C, U003E, U00AB, U00BB ] }; // LESS THAN, GREATER THAN, LEFT GUILLEMET, RIGHT GUILLEMET
- key <TLDE> { [ U0024, U20AC, U00B2, U00B3 ] }; // DOLLAR, EURO, SUPERSCRIPT 2, SUPERSCRIPT 3
- include "cm(exclamation_switch)"
-};
-
-partial alphanumeric_keys
-xkb_symbols "qwerty"
-{
- name[Group1] = "English (Cameroon qwerty)";
- include "level3(ralt_switch)"
- include "cm(basic)"
- key <AB01> { [ z, Z, U2026, U2020 ] }; // SMALL LETTER Z, CAPITAL LETTER Z, ELLIPSIS, DAGGER
- key <AB02> { [ x, X ] }; // SMALL LETTER X, CAPITAL LETTER X
- key <AB03> { [ c, C, NoSymbol, U00A9 ] }; // SMALL LETTER C, CAPITAL LETTER C, , COPYRIGHT
- key <AB04> { [ v, V, U25CC, NoSymbol ] }; // SMALL LETTER V, CAPITAL LETTER V, PLACEHOLDER CHARACTER
- key <AB05> { [ b, B, U0253, U0181 ] }; // SMALL LETTER B, CAPITAL LETTER B, SMALL LETTER B WITH HOOK, CAPITAL LETTER B WITH HOOK
- key <AB06> { [ n, N, U014B, U014A ] }; // SMALL LETTER N, CAPITAL LETTER N, SMALL LETTER ENG, CAPITAL LETTER ENG
- key <AB07> { [ m, M, NoSymbol, U2122 ] }; // SMALL LETTER M, CAPITAL LETTER M, , TRADEMARK SIGN
- key <AB08> { [ U002C, U003C, U2039, U00AB ] }; // COMMA, LESS THAN SIGN, LEFT SINGLE GUILLEMET, LEFT DOUBLE GUILLEMET
- key <AB09> { [ U002E, U003E, U203A, U00BB ] }; // PERIOD, GREATER THAN SIGN, RIGHT SINGLE GUILLEMET, RIGHT DOUBLE GUILLEMET
- key <AB10> { [ U002F, U003F, U00F7 ] }; // SLASH, QUESTION MARK, DIVISION SIGN
- key <AC01> { [ a, A, U025B, U0190 ] }; // SMALL LETTER A, CAPITAL LETTER A, SMALL LETTER OPEN E, CAPITAL LETTER OPEN E
- key <AC02> { [ s, S ] }; // SMALL LETTER S, CAPITAL LETTER S
- key <AC03> { [ d, D, U0257, U018A ] }; // SMALL LETTER D, CAPITAL LETTER D, SMALL LETTER D WITH HOOK, CAPITAL LETTER D WITH HOOK
- key <AC04> { [ f, F, U00E6, U00C6 ] }; // SMALL LETTER F, CAPITAL LETTER F, SMALL LIGATURE AE, CAPITAL LIGATURE AE
- key <AC05> { [ g, G, UA78C, UA78B ] }; // SMALL LETTER G, CAPITAL LETTER G, SMALL LETTER GLOTTAL (SALTILLO), CAPITAL LETTER GLOTTAL (SALTILLO)
- key <AC06> { [ h, H, U0251, U2C6D ] }; // SMALL LETTER H, CAPITAL LETTER H, SMALL LETTER ALPHA, CAPITAL LETTER ALPHA
- key <AC07> { [ j, J, U0330, U0323 ] }; // SMALL LETTER J, CAPITAL LETTER J, COMBINING TILDE (NASAL) BELOW, COMBINING DOT BELOW
- key <AC08> { [ k, K, U1DC5, U1DC7 ] }; // SMALL LETTER K, CAPITAL LETTER K, COMBINING LOW-MID TONE, COMBINING HIGH-MID
- key <AC09> { [ l, L, U1DC6, U1DC4 ] }; // SMALL LETTER L, CAPITAL LETTER L, COMBINING MID-LOW, COMBINING MID-HIGH TONE
- key <AC10> { [ U003B, U003A ] }; // SEMICOLON, COLON
- key <AC11> { [ U0300, U0302, U0027, U0022 ] }; // COMBINING LOW TONE, COMBINING FALLING TONE, APOSTROPHE, QUOTATION MARK
- key <AD01> { [ q, Q, U2014, U2013 ] }; // SMALL LETTER Q, CAPITAL LETTER Q, EM DASH, EN DASH
- key <AD02> { [ w, W, U1E85, U1E84 ] }; // SMALL LETTER W, CAPITAL LETTER W, SMALL LETTER W WITH DIAERESIS, CAPITAL LETTER W WITH DIAERESIS
- key <AD03> { [ e, E, U0259, U018F ] }; // SMALL LETTER E, CAPITAL LETTER E, SMALL LETTER SCHWA, CAPITAL LETTER SCHWA
- key <AD04> { [ r, R, NoSymbol, U00AE ] }; // SMALL LETTER R, CAPITAL LETTER R, , REGISTERED SIGN
- key <AD05> { [ t, T, U0153, U0152 ] }; // SMALL LETTER T, CAPITAL LETTER T, SMALL LIGATURE OE, CAPITAL LIGATURE OE
- key <AD06> { [ y, Y, U01B4, U01B3 ] }; // SMALL LETTER Y, CAPITAL LETTER Y, SMALL LETTER Y WITH HOOK, CAPITAL LETTER Y WITH HOOK
- key <AD07> { [ u, U, U0289, U0244 ] }; // SMALL LETTER U, CAPITAL LETTER U, SMALL LETTER U BAR, CAPITAL LETTER U BAR
- key <AD08> { [ i, I, U0268, U0197 ] }; // SMALL LETTER I, CAPITAL LETTER I, SMALL LETTER I BAR, CAPITAL LETTER I BAR
- key <AD09> { [ o, O, U0254, U0186 ] }; // SMALL LETTER O, CAPITAL LETTER O, SMALL LETTER OPEN O, CAPITAL LETTER OPEN O
- key <AD10> { [ p, P, U00F8, U00D8 ] }; // SMALL LETTER P, CAPITAL LETTER P, SMALL LETTER O BAR, CAPITAL LETTER O BAR
- key <AD11> { [ U0301, U030C, U005B, U007B ] }; // COMBINING HIGH TONE, COMBINING RISING TONE, LEFT SQUARE BRACKET, LEFT CURLY BRACKET
- key <AD12> { [ U0327, U0308, U005D, U007D ] }; // COMBINING CEDILLA, COMBINING DIAERESIS, RIGHT SQUARE BRACKET, RIGHT CURLY BRACKET
- key <AE01> { [ U0031, U0021, U00BC ] }; // 1, EXCLAMATION POINT, ONE QUARTER
- key <AE02> { [ U0032, U0040, U00BD ] }; //2, AT SYMBOL, ONE HALF
- key <AE03> { [ U0033, U0023, U00BE ] }; // 3, NUMBER SIGN, THREE QUARTERS
- key <AE04> { [ U0034, U0024, NoSymbol, U20AC ] }; // 4, DOLLAR, , EURO SIGN
- key <AE08> { [ U0038, U002A, NoSymbol, U00D7 ] }; // 8, ASTERISK, , MATH MULTIPLY
- key <AE09> { [ U0039, U0028, U2018, U201C ] }; // 9, LEFT PARENTHESIS, LEFT SINGLE QUOTE MARK, LEFT DOUBLE QUOTE MARK
- key <AE10> { [ U0030, U0029, U2019, U201D ] }; // 0, RIGHT PARENTHESIS, RIGHT SINGLE QUOTE MARK, LEFT DOUBLE QUOTE MARK
- key <AE11> { [ U002D, U005F, U0304 ] }; // MINUS, UNDERSCORE, COMBINING MID TONE, COMBINING MID TONE
- key <AE12> { [ U003D, U002B, NoSymbol, U00B1 ] }; // EQUAL, PLUS, , PLUS-MINUS
- key <BKSL> { [ U005C, U007C ] }; // BACKSLASH, BAR
- key <TLDE> { [ U030D, U0303, U0060, U007E ] }; // COMBINING VERTICAL LINE ABOVE, COMBINING TILDE ABOVE, GRAVE ACCENT, TILDE
- include "cm(semicolon_switch)"
-};
-
-
-partial alphanumeric_keys
-xkb_symbols "dvorak"
-{
- name[Group1] = "English (Cameroon Dvorak)";
- include "level3(ralt_switch)"
- include "us(dvorak)"
- key <AB01> { [ semicolon, colon ] }; // SEMICOLON, COLON
- key <AB02> { [ q, Q, U2014, U2013 ] }; // SMALL LETTER Q, CAPITAL LETTER Q, EM DASH, EN DASH
- key <AB03> { [ j, J, U0330, U0323 ] }; // SMALL LETTER J, CAPITAL LETTER J, COMBINING TILDE (NASAL) BELOW, COMBINING DOT BELOW
- key <AB04> { [ k, K, U1DC5, U1DC7 ] }; // SMALL LETTER K, CAPITAL LETTER K, COMBINING LOW-MID TONE, COMBINING HIGH-MID
- key <AB05> { [ x, X ] }; // SMALL LETTER X, CAPITAL LETTER X
- key <AB06> { [ b, B, U0253, U0181 ] }; // SMALL LETTER B, CAPITAL LETTER B, SMALL LETTER B WITH HOOK, CAPITAL LETTER B WITH HOOK
- key <AB07> { [ m, M, NoSymbol, U2122 ] }; // SMALL LETTER M, CAPITAL LETTER M, , TRADEMARK SIGN
- key <AB08> { [ w, W, U1E85, U1E84 ] }; // SMALL LETTER W, CAPITAL LETTER W, SMALL LETTER W WITH DIAERESIS, CAPITAL LETTER W WITH DIAERESIS
- key <AB09> { [ v, V, U25CC, NoSymbol ] }; // SMALL LETTER V, CAPITAL LETTER V, PLACEHOLDER CHARACTER
- key <AB10> { [ z, Z, U2026, U2020 ] }; // SMALL LETTER Z, CAPITAL LETTER Z, ELLIPSIS, DAGGER
- key <AC01> { [ a, A, U025B, U0190 ] }; // SMALL LETTER A, CAPITAL LETTER A, SMALL LETTER OPEN E, CAPITAL LETTER OPEN E
- key <AC02> { [ o, O, U0254, U0186 ] }; // SMALL LETTER O, CAPITAL LETTER O, SMALL LETTER OPEN O, CAPITAL LETTER OPEN O
- key <AC03> { [ e, E, U0259, U018F ] }; // SMALL LETTER E, CAPITAL LETTER E, SMALL LETTER SCHWA, CAPITAL LETTER SCHWA
- key <AC04> { [ u, U, U0289, U0244 ] }; // SMALL LETTER U, CAPITAL LETTER U, SMALL LETTER U BAR, CAPITAL LETTER U BAR
- key <AC05> { [ i, I, U0268, U0197 ] }; // SMALL LETTER I, CAPITAL LETTER I, SMALL LETTER I BAR, CAPITAL LETTER I BAR
- key <AC06> { [ d, D, U0257, U018A ] }; // SMALL LETTER D, CAPITAL LETTER D, SMALL LETTER D WITH HOOK, CAPITAL LETTER D WITH HOOK
- key <AC07> { [ h, H, U0251, U2C6D ] }; // SMALL LETTER H, CAPITAL LETTER H, SMALL LETTER ALPHA, CAPITAL LETTER ALPHA
- key <AC08> { [ t, T, U0153, U0152 ] }; // SMALL LETTER T, CAPITAL LETTER T, SMALL LIGATURE OE, CAPITAL LIGATURE OE
- key <AC09> { [ n, N, U014B, U014A ] }; // SMALL LETTER N, CAPITAL LETTER N, SMALL LETTER ENG, CAPITAL LETTER ENG
- key <AC10> { [ s, S ] }; // SMALL LETTER S, CAPITAL LETTER S
- key <AC11> { [ minus, underscore, U0304 ] }; // MINUS, UNDERSCORE, COMBINING MID TONE
- key <AD01> { [ U0300, U0302, U0027, U0022 ] }; // COMBINING LOW TONE, COMBINING FALLING TONE, APOSTROPHE, QUOTATION MARK
- key <AD02> { [ comma, less, U2039, U00AB ] }; // COMMA, LESS THAN SIGN, LEFT SINGLE GUILLEMET, LEFT DOUBLE GUILLEMET
- key <AD03> { [ period, greater, U203A, U00BB ] }; // PERIOD, GREATER THAN SIGN, RIGHT SINGLE GUILLEMET, RIGHT DOUBLE GUILLEMET
- key <AD04> { [ p, P, U00F8, U00D8 ] }; // SMALL LETTER P, CAPITAL LETTER P, SMALL LETTER O BAR, CAPITAL LETTER O BAR
- key <AD05> { [ y, Y, U01B4, U01B3 ] }; // SMALL LETTER Y, CAPITAL LETTER Y, SMALL LETTER Y WITH HOOK, CAPITAL LETTER Y WITH HOOK
- key <AD06> { [ f, F, U00E6, U00C6 ] }; // SMALL LETTER F, CAPITAL LETTER F, SMALL LIGATURE AE, CAPITAL LIGATURE AE
- key <AD07> { [ g, G, UA78C, UA78B ] }; // SMALL LETTER G, CAPITAL LETTER G, SMALL LETTER GLOTTAL (SALTILLO), CAPITAL LETTER GLOTTAL (SALTILLO)
- key <AD08> { [ c, C, NoSymbol, U00A9 ] }; // SMALL LETTER C, CAPITAL LETTER C, , COPYRIGHT
- key <AD09> { [ r, R, NoSymbol, U00AE ] }; // SMALL LETTER R, CAPITAL LETTER R, , REGISTERED SIGN
- key <AD10> { [ l, L, U1DC6, U1DC4 ] }; // SMALL LETTER L, CAPITAL LETTER L, COMBINING MID-LOW, COMBINING MID-HIGH TONE
- key <AD11> { [ slash, U003F, U00F7, U0294 ] }; // SLASH, QUESTION MARK, DIVISION SIGN, GLOTTAL STOP
- key <AD12> { [ equal, plus, NoSymbol, plusminus ] }; // EQUAL, PLUS, , PLUS-MINUS
- key <AE01> { [ KP_1, exclam, U00BC ] }; // 1, EXCLAMATION POINT, ONE QUARTER
- key <AE02> { [ KP_2, at, U00BD ] }; // 2, AT SYMBOL, ONE HALF
- key <AE03> { [ KP_3, numbersign, U00BE ] }; // 3, NUMBER SIGN, THREE QUARTERS
- key <AE04> { [ KP_4, dollar, NoSymbol, U20AC ] }; // 4, DOLLAR, , EURO SIGN
- key <AE05> { [ KP_5, percent ] }; // 5, PERCENT
- key <AE06> { [ KP_6, asciicircum ] }; // 6, CARET
- key <AE07> { [ KP_7, ampersand ] }; // 7, AMPERSAND
- key <AE08> { [ KP_8, asterisk, NoSymbol, multiply ] }; // 8, ASTERISK, , MULTIPLY
- key <AE09> { [ KP_9, parenleft, leftsinglequotemark, leftdoublequotemark ] }; // 9, LEFT PARENTHESIS, LEFT SINGLE QUOTE MARK, LEFT DOUBLE QUOTE MARK
- key <AE10> { [ KP_0, parenright, rightsinglequotemark, rightdoublequotemark ] }; // 0, RIGHT PARENTHESIS, RIGHT SINGLE QUOTE MARK, LEFT DOUBLE QUOTE MARK
- key <AE11> { [ U0301, U030C, U005B, U007B ] }; // COMBINING HIGH TONE, COMBINING RISING TONE, LEFT SQUARE BRACKET, LEFT CURLY BRACKET
- key <AE12> { [ U0327, dead_diaeresis, U005D, braceright ] }; // COMBINING CEDILLA, DEAD DIAERESIS, RIGHT SQUARE BRACKET, RIGHT CURLY BRACKET
- key <BKSL> { [ backslash, bar ] }; // BACKSLASH, BAR
- key <TLDE> { [ U030D, U0303, U0060, U007E ] }; // COMBINING VERTICAL LINE ABOVE, COMBINING TILDE ABOVE, GRAVE ACCENT, TILDE
- include "cm(semicolon_switch_dvorak)"
-};
-
-// The following code creates the "Cameroon key" phenomenon.
-
-partial modifier_keys
-xkb_symbols "semicolon_switch" {
- key <AC10> {
- symbols[Group1] = [ ISO_Level3_Latch, colon, semicolon, colon ]};
- modifier_map Mod5 { ISO_Level3_Latch };
-};
-
-partial modifier_keys
-xkb_symbols "exclamation_switch" {
- key <AB10> {
- symbols[Group1] = [ ISO_Level3_Latch, U00A7, exclam, U00A7 ]
- };
- modifier_map Mod5 { ISO_Level3_Latch };
-};
-
-partial modifier_keys
-xkb_symbols "semicolon_switch_dvorak" {
- key <AB01> {
- symbols[Group1] = [ ISO_Level3_Latch, colon, semicolon, colon ]
- };
-modifier_map Mod5 { ISO_Level3_Latch };
-};
-
+// ========== Cameroon Keyboards ========== +// ****** For Instructions, see "Use of Cameroon Keyboards" section below ****** + + +// The XKB versions of these keyboards were developed by Matthew Lee, Jenni Beadle, and Bruce Cox of SIL Cameroon in association with Going Komputya, Uwe Yung of the Goethe Institute, Yaoundé, and Centre ANACLAC. + +// Cameroon is officially a bilingual country, using French and English, but there are over 270 minority languages. + +// * Cameroon Français is an exact copy of the French France keyboard intended for AZERTY users. +// * Cameroon is an exact copy of the Basic US Keyboard. I can not currently name this "Cameroon English" due to a limitation of XKB. +// * Cameroon QWERTY and Cameroon AZERTY are based largely on SIL Cameroon's Keyman and Microsoft keyboards of the same style already in wide use. These keyboards are designed to allow the user to type any of Cameroon's 270+ languages and dialects that use the approved orthography. This Approved Orthography was adopted in 1979 by the National Committee for the Unification and Harmonisation of Alphabets of Camerooninan Languages. +// * Cameroon Dvorak is described below. + +// ===== Use of Cameroon Keyboards ===== + +// == Fonts == +// These keyboards are fully Unicode (5.1), so we recommend using a good unicode font for diacritics to position correctly. Recommended fonts are: ttf-sil-charis, ttf-sil-doulos, ttf-sil-gentium and ttf-sil-andika (All of which are free for Linux, Mac, and Windows). + + +// == Cameroon AZERTY == +// Cameroon AZERTY uses the French France (AZERTY) layout, as french keyboards are widely used here. While this keyboard is designed for Cameroonian orthography, it still is possible but not recommended, to type French with minimal discomfort using this keyboard. +// Cameroon AZERTY uses the "!" (exclamation) key as the "Cameroon" key. Pressing this key before another key allows you to access the special letters and diacritics needed in Cameroonian orthography. +// For example, press "!" then "a" and get "ɛ" (small epsilon). "!" then "Shift" + "a" (A) will get an "Ɛ" (capital epsilon). Press the "!" key twice to get a "!". +// If you prefer, you can hold the AltGr (and/or Shift) key to access the same letters, but we have found this to be much more awkward in practice. If you really don't like our Cameroon key, simply comment out "include "cm(exclamation_switch)"" and the exclamation key will return to normal. +// All Diacritics (with the exception of French Trema and Circumflex) must be typed (in order of stacking) after the letter. + + +// == Cameroon QWERTY == +// Cameroon QWERTY uses the US QWERTY layout, as US keyboards are also widely used here. While this keyboard is designed for Cameroonian orthography, it is possible, but not recommended, to type English with minimal discomfort using this keyboard. +// Cameroon QWERTY uses the ";" (semicolon) key as the "Cameroon" key. Pressing this key before another key allows you to access the special letters and diacritics needed in Cameroonian orthography. +// For example, press ";" then "a" and get "ɛ" (small epsilon). ";" then "Shift" + "a" (A) will get an "Ɛ" (capital epsilon). Press ";" twice to get a ";", or press Shift + ; (:) twice to get a ":" (colon). +// If you prefer, you can hold the AltGr (and/or Shift) key to access the same letters, but we have found this to be much more awkward in practice. If you really don't like our Cameroon key, simply comment out "include "cm(semicolon_switch)"" and the semicolon key will return to normal. +// All Diacritics must be typed (in order of stacking) after the letter. + + +// == Cameroon Dvorak == +// Cameroon Dvorak is uses a similar system to Cameroon QWERTY. + +default +partial alphanumeric_keys +xkb_symbols "basic" { + + name[Group1]="English (Cameroon)"; + + // Alphanumeric section + key <TLDE> { [ grave, asciitilde ] }; + key <AE01> { [ 1, exclam ] }; + key <AE02> { [ 2, at ] }; + key <AE03> { [ 3, numbersign ] }; + key <AE04> { [ 4, dollar ] }; + key <AE05> { [ 5, percent ] }; + key <AE06> { [ 6, asciicircum ] }; + key <AE07> { [ 7, ampersand ] }; + key <AE08> { [ 8, asterisk ] }; + key <AE09> { [ 9, parenleft ] }; + key <AE10> { [ 0, parenright ] }; + key <AE11> { [ minus, underscore ] }; + key <AE12> { [ equal, plus ] }; + + key <AD01> { [ q, Q ] }; + key <AD02> { [ w, W ] }; + key <AD03> { [ e, E ] }; + key <AD04> { [ r, R ] }; + key <AD05> { [ t, T ] }; + key <AD06> { [ y, Y ] }; + key <AD07> { [ u, U ] }; + key <AD08> { [ i, I ] }; + key <AD09> { [ o, O ] }; + key <AD10> { [ p, P ] }; + key <AD11> { [ bracketleft, braceleft ] }; + key <AD12> { [ bracketright, braceright ] }; + key <AC01> { [ a, A ] }; + key <AC02> { [ s, S ] }; + key <AC03> { [ d, D ] }; + key <AC04> { [ f, F ] }; + key <AC05> { [ g, G ] }; + key <AC06> { [ h, H ] }; + key <AC07> { [ j, J ] }; + key <AC08> { [ k, K ] }; + key <AC09> { [ l, L ] }; + key <AC10> { [ semicolon, colon ] }; + key <AC11> { [ apostrophe, quotedbl ] }; + + key <AB01> { [ z, Z ] }; + key <AB02> { [ x, X ] }; + key <AB03> { [ c, C ] }; + key <AB04> { [ v, V ] }; + key <AB05> { [ b, B ] }; + key <AB06> { [ n, N ] }; + key <AB07> { [ m, M ] }; + key <AB08> { [ comma, less ] }; + key <AB09> { [ period, greater ] }; + key <AB10> { [ slash, U003F ] }; + + key <BKSL> { [ backslash, bar ] }; + // End alphanumeric section +}; + +partial alphanumeric_keys +xkb_symbols "french" +{ + name[Group1]="French (Cameroon)"; + include "latin" + + key <AE01> { [ ampersand, 1, onesuperior, exclamdown ] }; + key <AE02> { [ eacute, 2, asciitilde, oneeighth ] }; + key <AE03> { [ quotedbl, 3, numbersign, sterling ] }; + key <AE04> { [apostrophe, 4, braceleft, dollar ] }; + key <AE05> { [ parenleft, 5, bracketleft, threeeighths ] }; + key <AE06> { [ minus, 6, bar, fiveeighths ] }; + key <AE07> { [ egrave, 7, grave, seveneighths ] }; + key <AE08> { [underscore, 8, backslash, trademark ] }; + key <AE09> { [ ccedilla, 9, asciicircum, plusminus ] }; + key <AE10> { [ agrave, 0, at, degree ] }; + key <AE11> { [parenright, degree, bracketright, questiondown ] }; + key <AE12> { [ equal, plus, braceright, dead_ogonek ] }; + + key <AD01> { [ a, A, ae, AE ] }; + key <AD02> { [ z, Z, guillemotleft, less ] }; + key <AD03> { [ e, E, EuroSign, cent ] }; + key <AD11> { [dead_circumflex, dead_diaeresis, dead_diaeresis, dead_abovering ] }; + key <AD12> { [ dollar, sterling, currency, dead_macron ] }; + + key <AC01> { [ q, Q, at, Greek_OMEGA ] }; + key <AC10> { [ m, M, mu, masculine ] }; + key <AC11> { [ ugrave, percent, dead_circumflex, dead_caron] }; + key <TLDE> { [twosuperior, asciitilde, notsign, notsign ] }; + + key <BKSL> { [ asterisk, mu, dead_grave, dead_breve ] }; + key <AB01> { [ w, W, lstroke, Lstroke ] }; + key <AB07> { [ comma, U003F, dead_acute, dead_doubleacute ] }; + key <AB08> { [ semicolon, period, horizconnector, multiply ] }; + key <AB09> { [ colon, slash, periodcentered, division ] }; + key <AB10> { [ exclam, section, dead_belowdot, dead_abovedot ] }; + + include "level3(ralt_switch)" +}; + + +partial alphanumeric_keys +xkb_symbols "azerty" +{ + name[Group1] = "Cameroon Multilingual (azerty)"; + include "level3(ralt_switch)" + include "cm(basic)" + key <AB01> { [ w, W, U1E85, U1E84 ] }; // SMALL LETTER W, CAPITAL LETTER W, SMALL LETTER W WITH DIAERESIS, CAPITAL LETTER W WITH DIAERESIS + key <AB02> { [ x, X, U2039, U203A ] }; // SMALL LETTER X, CAPITAL LETTER X, SINGLE LEFT-POINTING ANGLE QUOTATION MARK, SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + key <AB03> { [ c, C, U0327, copyright ] }; // SMALL LETTER C, CAPITAL LETTER C, COMBINING CEDILLA, COPYRIGHT SIGN + key <AB04> { [ v, V, U25CC, NoSymbol ] }; // SMALL LETTER V, CAPITAL LETTER V, PLACEHOLDER CHARACTER + key <AB05> { [ b, B, U0253, U0181 ] }; // SMALL LETTER B, CAPITAL LETTER B, SMALL LETTER B WITH HOOK, CAPITAL LETTER B WITH HOOK + key <AB06> { [ n, N, U014B, U014A ] }; // SMALL LETTER N, CAPITAL LETTER N, SMALL LETTER ENG, CAPITAL LETTER ENG + key <AB07> { [ U002C, U003F, NoSymbol, U00D7 ] }; // COMMA, QUESTION MARK, , MULTIPLY + key <AB08> { [ semicolon, period, dead_acute, dead_grave ] }; // SEMICOLON, PERIOD + key <AB09> { [ colon, slash, U0323 ] }; // COLON, SLASH, COMBINING DOT BELOW + key <AB10> { [ exclam, U00A7 ] }; // EXCLAMATION MARK, SECTION SIGN + key <AC01> { [ q, Q, U2014, U2013 ] }; // SMALL LETTER Q, CAPITAL LETTER Q, EM DASH, EN DASH + key <AC02> { [ s, S, U201C, U201D ] }; // SMALL LETTER S, CAPITAL LETTER S, LEFT DOUBLE QUOTES, RIGHT DOUBLE QUOTES + key <AC03> { [ d, D, U0257, U018A ] }; // SMALL LETTER D, CAPITAL LETTER D, SMALL LETTER D WITH HOOK, CAPITAL LETTER D WITH HOOK + key <AC04> { [ f, F, U00E6, U00C6 ] }; // SMALL LETTER F, CAPITAL LETTER F, SMALL LIGATURE AE, CAPITAL LIGATURE AE + key <AC05> { [ g, G, UA78C, UA78B ] }; // SMALL LETTER G, CAPITAL LETTER G, SMALL LETTER GLOTTAL (SALTILLO), CAPITAL LETTER GLOTTAL (SALTILLO) + key <AC06> { [ h, H, U0251, U2C6D ] }; // SMALL LETTER H, CAPITAL LETTER H, SMALL LETTER ALPHA, CAPITAL LETTER ALPHA + key <AC07> { [ j, J, leftarrow, U2122 ] }; //SMALL LETTER J, CAPITAL LETTER J, LEFT ARROW, TRADE MARK SIGN + key <AC08> { [ k, K, downarrow, uparrow ] }; // SMALL LETTER K, CAPITAL LETTER K, DOWN ARROW, UP ARROW + key <AC09> { [ l, L, rightarrow, U00A3 ] }; // SMALL LETTER L, CAPITAL LETTER L, RIGHT ARROW, POUND STERLING + key <AC10> { [ m, M, U00F9, U00B5 ] }; // SMALL LETTER M, CAPITAL LETTER M, SMALL LETTER U WITH GRAVE, MICRO SYMBOL + key <AC11> { [ U0300, U0302, U1DC5, U1DC4 ] }; // COMBINING LOW TONE, COMBINING FALLING TONE, COMBINING LOW-MID TONE, COMBINING MID-HIGH TONE + key <AD01> { [ a, A, U025B, U0190 ] }; // SMALL LETTER A, CAPITAL LETTER A, SMALL LETTER OPEN E, CAPITAL LETTER OPEN E + key <AD02> { [ z, Z, U2026, U2020 ] }; // SMALL LETTER Z, CAPITAL LETTER Z, ELLIPSIS, DAGGER + key <AD03> { [ e, E, U0259, U018F ] }; // SMALL LETTER E, CAPITAL LETTER E, SMALL LETTER SCHWA, CAPITAL LETTER SCHWA + key <AD04> { [ r, R, NoSymbol, U00AE ] }; // SMALL LETTER R, CAPITAL LETTER R, , REGISTERED SIGN + key <AD05> { [ t, T, U0153, U0152 ] }; // SMALL LETTER T, CAPITAL LETTER T, SMALL LIGATURE OE, CAPITAL LIGATURE OE + key <AD06> { [ y, Y, U01B4, U01B3 ] }; // SMALL LETTER Y, CAPITAL LETTER Y, SMALL LETTER Y WITH HOOK, CAPITAL LETTER Y WITH HOOK + key <AD07> { [ u, U, U0289, U0244 ] }; // SMALL LETTER U, CAPITAL LETTER U, SMALL LETTER U BAR, CAPITAL LETTER U BAR + key <AD08> { [ i, I, U0268, U0197 ] }; // SMALL LETTER I, CAPITAL LETTER I, SMALL LETTER I BAR, CAPITAL LETTER I BAR + key <AD09> { [ o, O, U0254, U0186 ] }; // SMALL LETTER O, CAPITAL LETTER O, SMALL LETTER OPEN O, CAPITAL LETTER OPEN O + key <AD10> { [ p, P, U00F8, U00D8 ] }; // SMALL LETTER P, CAPITAL LETTER P, SMALL LETTER O BAR, CAPITAL LETTER O BAR + key <AD11> { [ U0301, U030C, dead_circumflex, dead_diaeresis ] }; // COMBINING HIGH TONE, COMBINING RISING TONE, DEAD CIRCUMFLEX, DEAD DIAERESIS + key <AD12> { [ U0330, U0303, U0304, U030D ] }; // COMBINING TILDE (NASAL) BELOW, COMBINING TILDE (NASAL), COMBINING MID TONE, COMBINING VERTICAL LINE ABOVE + key <AE01> { [ U0026, KP_1, U00B9, U2018 ] }; // AMPERSAND, 1, SUPERSCRIPT 1, LEFT SINGLE QUOTE + key <AE02> { [ eacute, KP_2, asciitilde, U2019 ] }; // SMALL LETTER E WITH ACUTE, 2, TILDE, RIGHT SINGLE QUOTE + key <AE03> { [ U0022, KP_3, U0025 ] }; // QUOTATION MARK, 3, PERCENT SIGN + key <AE04> { [ U0027, KP_4, U007B ] }; // APOSTROPHE, 4, LEFT CURLY BRACKET + key <AE05> { [ U0028, KP_5, U005B, numbersign ] }; // LEFT PARENTHESIS, 5, LEFT SQUARE BRACKET, NUMBER SIGN + key <AE06> { [ U002D, KP_6, U007C ] }; // HYPHEN/MINUS, 6, BAR + key <AE07> { [ U00E8, KP_7, U0300 ] }; // SMALL LETTER E WITH GRAVE, 7, COMBINING GRAVE + key <AE08> { [ underscore, KP_8, backslash, U20D6 ] }; // UNDERSCORE, 8, BACKSLASH, COMBINING LEFT ARROW ABOVE + key <AE09> { [ ccedilla, KP_9, U005E] }; // SMALL LETTER C WITH CEDILLA, 9, CIRCUMFLEX + key <AE10> { [ U00E0, KP_0, at, U20D7 ] }; // SMALL LETTER A WITH GRAVE + key <AE11> { [ U0029, U00B0, U005D ] }; // RIGHT PARENTHESIS, DEGREE, RIGHT SQUARE BRACKET + key <AE12> { [ U003D, U002B, U007D, U00B1 ] }; // EQUAL SIGN, PLUS SIGN, RIGHT CURLY BRACKET, PLUS-MINUS SIGN + key <BKSL> { [ U1DC6, U1DC7, KP_Multiply, U00A4 ] }; // COMBINING MID-LOW, COMBINING HIGH-MID, MULTIPLY, CURRENCY SIGN + key <LSGT> { [ U003C, U003E, U00AB, U00BB ] }; // LESS THAN, GREATER THAN, LEFT GUILLEMET, RIGHT GUILLEMET + key <TLDE> { [ U0024, U20AC, U00B2, U00B3 ] }; // DOLLAR, EURO, SUPERSCRIPT 2, SUPERSCRIPT 3 + include "cm(exclamation_switch)" +}; + +partial alphanumeric_keys +xkb_symbols "qwerty" +{ + name[Group1] = "Cameroon Multilingual (qwerty)"; + include "level3(ralt_switch)" + include "cm(basic)" + key <AB01> { [ z, Z, U2026, U2020 ] }; // SMALL LETTER Z, CAPITAL LETTER Z, ELLIPSIS, DAGGER + key <AB02> { [ x, X ] }; // SMALL LETTER X, CAPITAL LETTER X + key <AB03> { [ c, C, NoSymbol, U00A9 ] }; // SMALL LETTER C, CAPITAL LETTER C, , COPYRIGHT + key <AB04> { [ v, V, U25CC, NoSymbol ] }; // SMALL LETTER V, CAPITAL LETTER V, PLACEHOLDER CHARACTER + key <AB05> { [ b, B, U0253, U0181 ] }; // SMALL LETTER B, CAPITAL LETTER B, SMALL LETTER B WITH HOOK, CAPITAL LETTER B WITH HOOK + key <AB06> { [ n, N, U014B, U014A ] }; // SMALL LETTER N, CAPITAL LETTER N, SMALL LETTER ENG, CAPITAL LETTER ENG + key <AB07> { [ m, M, NoSymbol, U2122 ] }; // SMALL LETTER M, CAPITAL LETTER M, , TRADEMARK SIGN + key <AB08> { [ U002C, U003C, U2039, U00AB ] }; // COMMA, LESS THAN SIGN, LEFT SINGLE GUILLEMET, LEFT DOUBLE GUILLEMET + key <AB09> { [ U002E, U003E, U203A, U00BB ] }; // PERIOD, GREATER THAN SIGN, RIGHT SINGLE GUILLEMET, RIGHT DOUBLE GUILLEMET + key <AB10> { [ U002F, U003F, U00F7 ] }; // SLASH, QUESTION MARK, DIVISION SIGN + key <AC01> { [ a, A, U025B, U0190 ] }; // SMALL LETTER A, CAPITAL LETTER A, SMALL LETTER OPEN E, CAPITAL LETTER OPEN E + key <AC02> { [ s, S ] }; // SMALL LETTER S, CAPITAL LETTER S + key <AC03> { [ d, D, U0257, U018A ] }; // SMALL LETTER D, CAPITAL LETTER D, SMALL LETTER D WITH HOOK, CAPITAL LETTER D WITH HOOK + key <AC04> { [ f, F, U00E6, U00C6 ] }; // SMALL LETTER F, CAPITAL LETTER F, SMALL LIGATURE AE, CAPITAL LIGATURE AE + key <AC05> { [ g, G, UA78C, UA78B ] }; // SMALL LETTER G, CAPITAL LETTER G, SMALL LETTER GLOTTAL (SALTILLO), CAPITAL LETTER GLOTTAL (SALTILLO) + key <AC06> { [ h, H, U0251, U2C6D ] }; // SMALL LETTER H, CAPITAL LETTER H, SMALL LETTER ALPHA, CAPITAL LETTER ALPHA + key <AC07> { [ j, J, U0330, U0323 ] }; // SMALL LETTER J, CAPITAL LETTER J, COMBINING TILDE (NASAL) BELOW, COMBINING DOT BELOW + key <AC08> { [ k, K, U1DC5, U1DC7 ] }; // SMALL LETTER K, CAPITAL LETTER K, COMBINING LOW-MID TONE, COMBINING HIGH-MID + key <AC09> { [ l, L, U1DC6, U1DC4 ] }; // SMALL LETTER L, CAPITAL LETTER L, COMBINING MID-LOW, COMBINING MID-HIGH TONE + key <AC10> { [ U003B, U003A ] }; // SEMICOLON, COLON + key <AC11> { [ U0300, U0302, U0027, U0022 ] }; // COMBINING LOW TONE, COMBINING FALLING TONE, APOSTROPHE, QUOTATION MARK + key <AD01> { [ q, Q, U2014, U2013 ] }; // SMALL LETTER Q, CAPITAL LETTER Q, EM DASH, EN DASH + key <AD02> { [ w, W, U1E85, U1E84 ] }; // SMALL LETTER W, CAPITAL LETTER W, SMALL LETTER W WITH DIAERESIS, CAPITAL LETTER W WITH DIAERESIS + key <AD03> { [ e, E, U0259, U018F ] }; // SMALL LETTER E, CAPITAL LETTER E, SMALL LETTER SCHWA, CAPITAL LETTER SCHWA + key <AD04> { [ r, R, NoSymbol, U00AE ] }; // SMALL LETTER R, CAPITAL LETTER R, , REGISTERED SIGN + key <AD05> { [ t, T, U0153, U0152 ] }; // SMALL LETTER T, CAPITAL LETTER T, SMALL LIGATURE OE, CAPITAL LIGATURE OE + key <AD06> { [ y, Y, U01B4, U01B3 ] }; // SMALL LETTER Y, CAPITAL LETTER Y, SMALL LETTER Y WITH HOOK, CAPITAL LETTER Y WITH HOOK + key <AD07> { [ u, U, U0289, U0244 ] }; // SMALL LETTER U, CAPITAL LETTER U, SMALL LETTER U BAR, CAPITAL LETTER U BAR + key <AD08> { [ i, I, U0268, U0197 ] }; // SMALL LETTER I, CAPITAL LETTER I, SMALL LETTER I BAR, CAPITAL LETTER I BAR + key <AD09> { [ o, O, U0254, U0186 ] }; // SMALL LETTER O, CAPITAL LETTER O, SMALL LETTER OPEN O, CAPITAL LETTER OPEN O + key <AD10> { [ p, P, U00F8, U00D8 ] }; // SMALL LETTER P, CAPITAL LETTER P, SMALL LETTER O BAR, CAPITAL LETTER O BAR + key <AD11> { [ U0301, U030C, U005B, U007B ] }; // COMBINING HIGH TONE, COMBINING RISING TONE, LEFT SQUARE BRACKET, LEFT CURLY BRACKET + key <AD12> { [ U0327, U0308, U005D, U007D ] }; // COMBINING CEDILLA, COMBINING DIAERESIS, RIGHT SQUARE BRACKET, RIGHT CURLY BRACKET + key <AE01> { [ U0031, U0021, U00BC ] }; // 1, EXCLAMATION POINT, ONE QUARTER + key <AE02> { [ U0032, U0040, U00BD ] }; //2, AT SYMBOL, ONE HALF + key <AE03> { [ U0033, U0023, U00BE ] }; // 3, NUMBER SIGN, THREE QUARTERS + key <AE04> { [ U0034, U0024, NoSymbol, U20AC ] }; // 4, DOLLAR, , EURO SIGN + key <AE08> { [ U0038, U002A, NoSymbol, U00D7 ] }; // 8, ASTERISK, , MATH MULTIPLY + key <AE09> { [ U0039, U0028, U2018, U201C ] }; // 9, LEFT PARENTHESIS, LEFT SINGLE QUOTE MARK, LEFT DOUBLE QUOTE MARK + key <AE10> { [ U0030, U0029, U2019, U201D ] }; // 0, RIGHT PARENTHESIS, RIGHT SINGLE QUOTE MARK, LEFT DOUBLE QUOTE MARK + key <AE11> { [ U002D, U005F, U0304 ] }; // MINUS, UNDERSCORE, COMBINING MID TONE, COMBINING MID TONE + key <AE12> { [ U003D, U002B, NoSymbol, U00B1 ] }; // EQUAL, PLUS, , PLUS-MINUS + key <BKSL> { [ U005C, U007C ] }; // BACKSLASH, BAR + key <TLDE> { [ U030D, U0303, U0060, U007E ] }; // COMBINING VERTICAL LINE ABOVE, COMBINING TILDE ABOVE, GRAVE ACCENT, TILDE + include "cm(semicolon_switch)" +}; + + +partial alphanumeric_keys +xkb_symbols "dvorak" +{ + name[Group1] = "English (Cameroon Dvorak)"; + include "level3(ralt_switch)" + include "us(dvorak)" + key <AB01> { [ semicolon, colon ] }; // SEMICOLON, COLON + key <AB02> { [ q, Q, U2014, U2013 ] }; // SMALL LETTER Q, CAPITAL LETTER Q, EM DASH, EN DASH + key <AB03> { [ j, J, U0330, U0323 ] }; // SMALL LETTER J, CAPITAL LETTER J, COMBINING TILDE (NASAL) BELOW, COMBINING DOT BELOW + key <AB04> { [ k, K, U1DC5, U1DC7 ] }; // SMALL LETTER K, CAPITAL LETTER K, COMBINING LOW-MID TONE, COMBINING HIGH-MID + key <AB05> { [ x, X ] }; // SMALL LETTER X, CAPITAL LETTER X + key <AB06> { [ b, B, U0253, U0181 ] }; // SMALL LETTER B, CAPITAL LETTER B, SMALL LETTER B WITH HOOK, CAPITAL LETTER B WITH HOOK + key <AB07> { [ m, M, NoSymbol, U2122 ] }; // SMALL LETTER M, CAPITAL LETTER M, , TRADEMARK SIGN + key <AB08> { [ w, W, U1E85, U1E84 ] }; // SMALL LETTER W, CAPITAL LETTER W, SMALL LETTER W WITH DIAERESIS, CAPITAL LETTER W WITH DIAERESIS + key <AB09> { [ v, V, U25CC, NoSymbol ] }; // SMALL LETTER V, CAPITAL LETTER V, PLACEHOLDER CHARACTER + key <AB10> { [ z, Z, U2026, U2020 ] }; // SMALL LETTER Z, CAPITAL LETTER Z, ELLIPSIS, DAGGER + key <AC01> { [ a, A, U025B, U0190 ] }; // SMALL LETTER A, CAPITAL LETTER A, SMALL LETTER OPEN E, CAPITAL LETTER OPEN E + key <AC02> { [ o, O, U0254, U0186 ] }; // SMALL LETTER O, CAPITAL LETTER O, SMALL LETTER OPEN O, CAPITAL LETTER OPEN O + key <AC03> { [ e, E, U0259, U018F ] }; // SMALL LETTER E, CAPITAL LETTER E, SMALL LETTER SCHWA, CAPITAL LETTER SCHWA + key <AC04> { [ u, U, U0289, U0244 ] }; // SMALL LETTER U, CAPITAL LETTER U, SMALL LETTER U BAR, CAPITAL LETTER U BAR + key <AC05> { [ i, I, U0268, U0197 ] }; // SMALL LETTER I, CAPITAL LETTER I, SMALL LETTER I BAR, CAPITAL LETTER I BAR + key <AC06> { [ d, D, U0257, U018A ] }; // SMALL LETTER D, CAPITAL LETTER D, SMALL LETTER D WITH HOOK, CAPITAL LETTER D WITH HOOK + key <AC07> { [ h, H, U0251, U2C6D ] }; // SMALL LETTER H, CAPITAL LETTER H, SMALL LETTER ALPHA, CAPITAL LETTER ALPHA + key <AC08> { [ t, T, U0153, U0152 ] }; // SMALL LETTER T, CAPITAL LETTER T, SMALL LIGATURE OE, CAPITAL LIGATURE OE + key <AC09> { [ n, N, U014B, U014A ] }; // SMALL LETTER N, CAPITAL LETTER N, SMALL LETTER ENG, CAPITAL LETTER ENG + key <AC10> { [ s, S ] }; // SMALL LETTER S, CAPITAL LETTER S + key <AC11> { [ minus, underscore, U0304 ] }; // MINUS, UNDERSCORE, COMBINING MID TONE + key <AD01> { [ U0300, U0302, U0027, U0022 ] }; // COMBINING LOW TONE, COMBINING FALLING TONE, APOSTROPHE, QUOTATION MARK + key <AD02> { [ comma, less, U2039, U00AB ] }; // COMMA, LESS THAN SIGN, LEFT SINGLE GUILLEMET, LEFT DOUBLE GUILLEMET + key <AD03> { [ period, greater, U203A, U00BB ] }; // PERIOD, GREATER THAN SIGN, RIGHT SINGLE GUILLEMET, RIGHT DOUBLE GUILLEMET + key <AD04> { [ p, P, U00F8, U00D8 ] }; // SMALL LETTER P, CAPITAL LETTER P, SMALL LETTER O BAR, CAPITAL LETTER O BAR + key <AD05> { [ y, Y, U01B4, U01B3 ] }; // SMALL LETTER Y, CAPITAL LETTER Y, SMALL LETTER Y WITH HOOK, CAPITAL LETTER Y WITH HOOK + key <AD06> { [ f, F, U00E6, U00C6 ] }; // SMALL LETTER F, CAPITAL LETTER F, SMALL LIGATURE AE, CAPITAL LIGATURE AE + key <AD07> { [ g, G, UA78C, UA78B ] }; // SMALL LETTER G, CAPITAL LETTER G, SMALL LETTER GLOTTAL (SALTILLO), CAPITAL LETTER GLOTTAL (SALTILLO) + key <AD08> { [ c, C, NoSymbol, U00A9 ] }; // SMALL LETTER C, CAPITAL LETTER C, , COPYRIGHT + key <AD09> { [ r, R, NoSymbol, U00AE ] }; // SMALL LETTER R, CAPITAL LETTER R, , REGISTERED SIGN + key <AD10> { [ l, L, U1DC6, U1DC4 ] }; // SMALL LETTER L, CAPITAL LETTER L, COMBINING MID-LOW, COMBINING MID-HIGH TONE + key <AD11> { [ slash, U003F, U00F7, U0294 ] }; // SLASH, QUESTION MARK, DIVISION SIGN, GLOTTAL STOP + key <AD12> { [ equal, plus, NoSymbol, plusminus ] }; // EQUAL, PLUS, , PLUS-MINUS + key <AE01> { [ KP_1, exclam, U00BC ] }; // 1, EXCLAMATION POINT, ONE QUARTER + key <AE02> { [ KP_2, at, U00BD ] }; // 2, AT SYMBOL, ONE HALF + key <AE03> { [ KP_3, numbersign, U00BE ] }; // 3, NUMBER SIGN, THREE QUARTERS + key <AE04> { [ KP_4, dollar, NoSymbol, U20AC ] }; // 4, DOLLAR, , EURO SIGN + key <AE05> { [ KP_5, percent ] }; // 5, PERCENT + key <AE06> { [ KP_6, asciicircum ] }; // 6, CARET + key <AE07> { [ KP_7, ampersand ] }; // 7, AMPERSAND + key <AE08> { [ KP_8, asterisk, NoSymbol, multiply ] }; // 8, ASTERISK, , MULTIPLY + key <AE09> { [ KP_9, parenleft, leftsinglequotemark, leftdoublequotemark ] }; // 9, LEFT PARENTHESIS, LEFT SINGLE QUOTE MARK, LEFT DOUBLE QUOTE MARK + key <AE10> { [ KP_0, parenright, rightsinglequotemark, rightdoublequotemark ] }; // 0, RIGHT PARENTHESIS, RIGHT SINGLE QUOTE MARK, LEFT DOUBLE QUOTE MARK + key <AE11> { [ U0301, U030C, U005B, U007B ] }; // COMBINING HIGH TONE, COMBINING RISING TONE, LEFT SQUARE BRACKET, LEFT CURLY BRACKET + key <AE12> { [ U0327, dead_diaeresis, U005D, braceright ] }; // COMBINING CEDILLA, DEAD DIAERESIS, RIGHT SQUARE BRACKET, RIGHT CURLY BRACKET + key <BKSL> { [ backslash, bar ] }; // BACKSLASH, BAR + key <TLDE> { [ U030D, U0303, U0060, U007E ] }; // COMBINING VERTICAL LINE ABOVE, COMBINING TILDE ABOVE, GRAVE ACCENT, TILDE + include "cm(semicolon_switch_dvorak)" +}; + +// The following code creates the "Cameroon key" phenomenon. + +partial modifier_keys +xkb_symbols "semicolon_switch" { + key <AC10> { + symbols[Group1] = [ ISO_Level3_Latch, colon, semicolon, colon ]}; + modifier_map Mod5 { ISO_Level3_Latch }; +}; + +partial modifier_keys +xkb_symbols "exclamation_switch" { + key <AB10> { + symbols[Group1] = [ ISO_Level3_Latch, U00A7, exclam, U00A7 ] + }; + modifier_map Mod5 { ISO_Level3_Latch }; +}; + +partial modifier_keys +xkb_symbols "semicolon_switch_dvorak" { + key <AB01> { + symbols[Group1] = [ ISO_Level3_Latch, colon, semicolon, colon ] + }; +modifier_map Mod5 { ISO_Level3_Latch }; +}; + diff --git a/xorg-server/xkeyboard-config/symbols/de b/xorg-server/xkeyboard-config/symbols/de index c30cb9f6a..616b91303 100644 --- a/xorg-server/xkeyboard-config/symbols/de +++ b/xorg-server/xkeyboard-config/symbols/de @@ -594,3 +594,23 @@ xkb_symbols "htcdream" { include "level3(alt_switch)" }; + +partial alphanumeric_keys +xkb_symbols "us" { + include "us" + + name[Group1]="German (US keyboard with German letters)"; + + key <AC01> { [ a, A, adiaeresis, Adiaeresis ] }; + key <AC02> { [ s, S, ssharp, ssharp ] }; + key <AC10> { [ semicolon, colon, odiaeresis, Odiaeresis ] }; + key <AC11> { [ apostrophe, quotedbl, adiaeresis, Adiaeresis ] }; + key <AD03> { [ e, E, EuroSign, EuroSign ] }; + key <AD07> { [ u, U, udiaeresis, Udiaeresis ] }; + key <AD09> { [ o, O, odiaeresis, Odiaeresis ] }; + key <AD11> { [ bracketleft, braceleft, udiaeresis, Udiaeresis ] }; + key <AE03> { [ 3, numbersign, section, section ] }; + key <AE11> { [ minus, underscore, ssharp, question ] }; + + include "level3(ralt_switch)" +}; diff --git a/xorg-server/xkeyboard-config/symbols/lk b/xorg-server/xkeyboard-config/symbols/lk index c1a16abdd..356e060fe 100644 --- a/xorg-server/xkeyboard-config/symbols/lk +++ b/xorg-server/xkeyboard-config/symbols/lk @@ -1,6 +1,6 @@ // X Keyboard Extension file for Sinhala (Sri Lanka) (2004-04-22) // Maintainer : Harshula Jayasuriya <harshula@gmail.com> -// Last Updated: 2011-03-20 +// Last Updated: 2011-05-25 // This is a phonetic static mapping for a standard US-English keyboard // (qwerty) // http://www.nongnu.org/sinhala/doc/keymaps/sinhala-keyboard_3.html @@ -32,8 +32,7 @@ partial default alphanumeric_keys xkb_symbols "sin_phonetic" { include "us" -// it is default - no details in the name - name[Group1] = "Sinhala"; + name[Group1] = "Sinhala (phonetic)"; key.type[Group1] = "FOUR_LEVEL"; // q - p diff --git a/xorg-server/xkeyboard-config/symbols/ru b/xorg-server/xkeyboard-config/symbols/ru index fdf82539d..408e40806 100644 --- a/xorg-server/xkeyboard-config/symbols/ru +++ b/xorg-server/xkeyboard-config/symbols/ru @@ -589,8 +589,8 @@ xkb_symbols "chu" // RUU (Russian-Ukrainian United keyboard layout). -// Modified Russian standart keyboard with third level contains ukrainian -// and belorusian alphabetic letters and commonly used Unicode symbols. +// Modified Russian standart keyboard with third level contains Ukrainian +// and Belorusian alphabetic letters and commonly used Unicode symbols. // Description http://wiki.opennet.ru/RUU [russian] // Vasyĺ V. Vercynśkyj <fuckel@ukr.net> // Last Changes 2011/05/11 @@ -618,7 +618,7 @@ partial alphanumeric_keys xkb_symbols "ruu" { include "ru(common)" - name[Group1]= "Russian (with UKR and BEL layout)"; + name[Group1]= "Russian (with Ukrainian-Belorussian layout)"; key <TLDE> { [ U2019, apostrophe, U0301, asciitilde ] }; // Apostrophe and Stress symbol key <AE01> { [ 1, exclam, U00F7, U2248 ] }; // Division Sign and Almost Equal To |