xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

xprCursor.c (11016B)


      1 /**************************************************************
      2  *
      3  * Xplugin cursor support
      4  *
      5  * Copyright (c) 2001 Torrey T. Lyons and Greg Parker.
      6  * Copyright (c) 2002 Apple Computer, Inc.
      7  *                 All Rights Reserved.
      8  *
      9  * Permission is hereby granted, free of charge, to any person obtaining a
     10  * copy of this software and associated documentation files (the "Software"),
     11  * to deal in the Software without restriction, including without limitation
     12  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     13  * and/or sell copies of the Software, and to permit persons to whom the
     14  * Software is furnished to do so, subject to the following conditions:
     15  *
     16  * The above copyright notice and this permission notice shall be included in
     17  * all copies or substantial portions of the Software.
     18  *
     19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     22  * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     23  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     24  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     25  * DEALINGS IN THE SOFTWARE.
     26  *
     27  * Except as contained in this notice, the name(s) of the above copyright
     28  * holders shall not be used in advertising or otherwise to promote the sale,
     29  * use or other dealings in this Software without prior written authorization.
     30  */
     31 
     32 #include "sanitizedCarbon.h"
     33 
     34 #ifdef HAVE_DIX_CONFIG_H
     35 #include <dix-config.h>
     36 #endif
     37 
     38 #include "quartz.h"
     39 #include "xpr.h"
     40 #include "darwinEvents.h"
     41 #include <Xplugin.h>
     42 
     43 #include "mi.h"
     44 #include "scrnintstr.h"
     45 #include "cursorstr.h"
     46 #include "mipointrst.h"
     47 #include "windowstr.h"
     48 #include "globals.h"
     49 #include "servermd.h"
     50 #include "dixevents.h"
     51 #include "x-hash.h"
     52 
     53 typedef struct {
     54     int cursorVisible;
     55     QueryBestSizeProcPtr QueryBestSize;
     56     miPointerSpriteFuncPtr spriteFuncs;
     57 } QuartzCursorScreenRec, *QuartzCursorScreenPtr;
     58 
     59 static DevPrivateKeyRec darwinCursorScreenKeyRec;
     60 #define darwinCursorScreenKey (&darwinCursorScreenKeyRec)
     61 
     62 #define CURSOR_PRIV(pScreen) ((QuartzCursorScreenPtr) \
     63                               dixLookupPrivate(&pScreen->devPrivates, \
     64                                                darwinCursorScreenKey))
     65 
     66 static Bool
     67 load_cursor(CursorPtr src, int screen)
     68 {
     69     uint32_t *data;
     70     Bool free_data = FALSE;
     71     uint32_t rowbytes;
     72     int width, height;
     73     int hot_x, hot_y;
     74 
     75     uint32_t fg_color, bg_color;
     76     uint8_t *srow, *sptr;
     77     uint8_t *mrow, *mptr;
     78     uint32_t *drow, *dptr;
     79     unsigned xcount, ycount;
     80 
     81     xp_error err;
     82 
     83     width = src->bits->width;
     84     height = src->bits->height;
     85     hot_x = src->bits->xhot;
     86     hot_y = src->bits->yhot;
     87 
     88     if (src->bits->argb != NULL) {
     89 #if BITMAP_BIT_ORDER == MSBFirst
     90         rowbytes = src->bits->width * sizeof(CARD32);
     91         data = (uint32_t *)src->bits->argb;
     92 #else
     93         const uint32_t *be_data = (uint32_t *)src->bits->argb;
     94         unsigned i;
     95         rowbytes = src->bits->width * sizeof(CARD32);
     96         data = malloc(rowbytes * src->bits->height);
     97         free_data = TRUE;
     98         if (!data) {
     99             FatalError("Failed to allocate memory in %s\n", __func__);
    100         }
    101         for (i = 0; i < (src->bits->width * src->bits->height); i++)
    102             data[i] = ntohl(be_data[i]);
    103 #endif
    104     }
    105     else
    106     {
    107         fg_color = 0xFF00 | (src->foreRed >> 8);
    108         fg_color <<= 16;
    109         fg_color |= src->foreGreen & 0xFF00;
    110         fg_color |= src->foreBlue >> 8;
    111 
    112         bg_color = 0xFF00 | (src->backRed >> 8);
    113         bg_color <<= 16;
    114         bg_color |= src->backGreen & 0xFF00;
    115         bg_color |= src->backBlue >> 8;
    116 
    117         fg_color = htonl(fg_color);
    118         bg_color = htonl(bg_color);
    119 
    120         /* round up to 8 pixel boundary so we can convert whole bytes */
    121         rowbytes = ((src->bits->width * 4) + 31) & ~31;
    122         data = malloc(rowbytes * src->bits->height);
    123         free_data = TRUE;
    124         if (!data) {
    125             FatalError("Failed to allocate memory in %s\n", __func__);
    126         }
    127 
    128         if (!src->bits->emptyMask) {
    129             ycount = src->bits->height;
    130             srow = src->bits->source;
    131             mrow = src->bits->mask;
    132             drow = data;
    133 
    134             while (ycount-- > 0)
    135             {
    136                 xcount = bits_to_bytes(src->bits->width);
    137                 sptr = srow;
    138                 mptr = mrow;
    139                 dptr = drow;
    140 
    141                 while (xcount-- > 0)
    142                 {
    143                     uint8_t s, m;
    144                     int i;
    145 
    146                     s = *sptr++;
    147                     m = *mptr++;
    148                     for (i = 0; i < 8; i++) {
    149 #if BITMAP_BIT_ORDER == MSBFirst
    150                         if (m & 128)
    151                             *dptr++ = (s & 128) ? fg_color : bg_color;
    152                         else
    153                             *dptr++ = 0;
    154                         s <<= 1;
    155                         m <<= 1;
    156 #else
    157                         if (m & 1)
    158                             *dptr++ = (s & 1) ? fg_color : bg_color;
    159                         else
    160                             *dptr++ = 0;
    161                         s >>= 1;
    162                         m >>= 1;
    163 #endif
    164                     }
    165                 }
    166 
    167                 srow += BitmapBytePad(src->bits->width);
    168                 mrow += BitmapBytePad(src->bits->width);
    169                 drow = (uint32_t *)((char *)drow + rowbytes);
    170             }
    171         }
    172         else {
    173             memset(data, 0, src->bits->height * rowbytes);
    174         }
    175     }
    176 
    177     err = xp_set_cursor(width, height, hot_x, hot_y, data, rowbytes);
    178     if (free_data)
    179         free(data);
    180     return err == Success;
    181 }
    182 
    183 /*
    184    ===========================================================================
    185 
    186    Pointer sprite functions
    187 
    188    ===========================================================================
    189  */
    190 
    191 /*
    192  * QuartzRealizeCursor
    193  *  Convert the X cursor representation to native format if possible.
    194  */
    195 static Bool
    196 QuartzRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
    197 {
    198     if (pCursor == NULL || pCursor->bits == NULL)
    199         return FALSE;
    200 
    201     /* FIXME: cache ARGB8888 representation? */
    202 
    203     return TRUE;
    204 }
    205 
    206 /*
    207  * QuartzUnrealizeCursor
    208  *  Free the storage space associated with a realized cursor.
    209  */
    210 static Bool
    211 QuartzUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
    212 {
    213     return TRUE;
    214 }
    215 
    216 /*
    217  * QuartzSetCursor
    218  *  Set the cursor sprite and position.
    219  */
    220 static void
    221 QuartzSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor,
    222                 int x,
    223                 int y)
    224 {
    225     QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
    226 
    227     if (!XQuartzServerVisible)
    228         return;
    229 
    230     if (pCursor == NULL) {
    231         if (ScreenPriv->cursorVisible) {
    232             xp_hide_cursor();
    233             ScreenPriv->cursorVisible = FALSE;
    234         }
    235     }
    236     else {
    237         load_cursor(pCursor, pScreen->myNum);
    238 
    239         if (!ScreenPriv->cursorVisible) {
    240             xp_show_cursor();
    241             ScreenPriv->cursorVisible = TRUE;
    242         }
    243     }
    244 }
    245 
    246 /*
    247  * QuartzMoveCursor
    248  *  Move the cursor. This is a noop for us.
    249  */
    250 static void
    251 QuartzMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
    252 {}
    253 
    254 /*
    255    ===========================================================================
    256 
    257    Pointer screen functions
    258 
    259    ===========================================================================
    260  */
    261 
    262 /*
    263  * QuartzCursorOffScreen
    264  */
    265 static Bool
    266 QuartzCursorOffScreen(ScreenPtr *pScreen, int *x, int *y)
    267 {
    268     return FALSE;
    269 }
    270 
    271 /*
    272  * QuartzCrossScreen
    273  */
    274 static void
    275 QuartzCrossScreen(ScreenPtr pScreen, Bool entering)
    276 {
    277     return;
    278 }
    279 
    280 /*
    281  * QuartzWarpCursor
    282  *  Change the cursor position without generating an event or motion history.
    283  *  The input coordinates (x,y) are in pScreen-local X11 coordinates.
    284  *
    285  */
    286 static void
    287 QuartzWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
    288 {
    289     if (XQuartzServerVisible) {
    290         int sx, sy;
    291 
    292         sx = pScreen->x + darwinMainScreenX;
    293         sy = pScreen->y + darwinMainScreenY;
    294 
    295         CGWarpMouseCursorPosition(CGPointMake(sx + x, sy + y));
    296     }
    297 
    298     miPointerWarpCursor(pDev, pScreen, x, y);
    299     miPointerUpdateSprite(pDev);
    300 }
    301 
    302 static miPointerScreenFuncRec quartzScreenFuncsRec = {
    303     QuartzCursorOffScreen,
    304     QuartzCrossScreen,
    305     QuartzWarpCursor,
    306 };
    307 
    308 /*
    309    ===========================================================================
    310 
    311    Other screen functions
    312 
    313    ===========================================================================
    314  */
    315 
    316 /*
    317  * QuartzCursorQueryBestSize
    318  *  Handle queries for best cursor size
    319  */
    320 static void
    321 QuartzCursorQueryBestSize(int class, unsigned short *width,
    322                           unsigned short *height, ScreenPtr pScreen)
    323 {
    324     QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
    325 
    326     if (class == CursorShape) {
    327         /* FIXME: query window server? */
    328         *width = 32;
    329         *height = 32;
    330     }
    331     else {
    332         (*ScreenPriv->QueryBestSize)(class, width, height, pScreen);
    333     }
    334 }
    335 
    336 /*
    337  * QuartzInitCursor
    338  *  Initialize cursor support
    339  */
    340 Bool
    341 QuartzInitCursor(ScreenPtr pScreen)
    342 {
    343     QuartzCursorScreenPtr ScreenPriv;
    344     miPointerScreenPtr PointPriv;
    345 
    346     /* initialize software cursor handling (always needed as backup) */
    347     if (!miDCInitialize(pScreen, &quartzScreenFuncsRec))
    348         return FALSE;
    349 
    350     if (!dixRegisterPrivateKey(&darwinCursorScreenKeyRec, PRIVATE_SCREEN, 0))
    351         return FALSE;
    352 
    353     ScreenPriv = calloc(1, sizeof(QuartzCursorScreenRec));
    354     if (ScreenPriv == NULL)
    355         return FALSE;
    356 
    357     /* CURSOR_PRIV(pScreen) = ScreenPriv; */
    358     dixSetPrivate(&pScreen->devPrivates, darwinCursorScreenKey, ScreenPriv);
    359 
    360     /* override some screen procedures */
    361     ScreenPriv->QueryBestSize = pScreen->QueryBestSize;
    362     pScreen->QueryBestSize = QuartzCursorQueryBestSize;
    363 
    364     PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
    365 
    366     ScreenPriv->spriteFuncs = PointPriv->spriteFuncs;
    367 
    368     PointPriv->spriteFuncs->RealizeCursor = QuartzRealizeCursor;
    369     PointPriv->spriteFuncs->UnrealizeCursor = QuartzUnrealizeCursor;
    370     PointPriv->spriteFuncs->SetCursor = QuartzSetCursor;
    371     PointPriv->spriteFuncs->MoveCursor = QuartzMoveCursor;
    372 
    373     ScreenPriv->cursorVisible = TRUE;
    374     return TRUE;
    375 }
    376 
    377 /*
    378  * QuartzSuspendXCursor
    379  *  X server is hiding. Restore the Aqua cursor.
    380  */
    381 void
    382 QuartzSuspendXCursor(ScreenPtr pScreen)
    383 {
    384     xp_show_cursor();
    385 }
    386 
    387 /*
    388  * QuartzResumeXCursor
    389  *  X server is showing. Restore the X cursor.
    390  */
    391 void
    392 QuartzResumeXCursor(ScreenPtr pScreen)
    393 {
    394     WindowPtr pWin;
    395     CursorPtr pCursor;
    396 
    397     /* TODO: Tablet? */
    398 
    399     pWin = GetSpriteWindow(darwinPointer);
    400     if (pWin->drawable.pScreen != pScreen)
    401         return;
    402 
    403     pCursor = GetSpriteCursor(darwinPointer);
    404     if (pCursor == NULL)
    405         return;
    406 
    407     QuartzSetCursor(darwinPointer, pScreen, pCursor, /* x */ 0, /* y */ 0);
    408 }