src/video/wincommon/SDL_sysmouse.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. PAD_BITS
  2. PrintBITMAP
  3. memnot
  4. memxor
  5. WIN_FreeWMCursor
  6. WIN_CreateWMCursor
  7. WIN_ShowWMCursor
  8. WIN_WarpWMCursor
  9. WIN_UpdateMouse
  10. WIN_CheckMouseMode

   1 /*
   2     SDL - Simple DirectMedia Layer
   3     Copyright (C) 1997, 1998, 1999  Sam Lantinga
   4 
   5     This library is free software; you can redistribute it and/or
   6     modify it under the terms of the GNU Library General Public
   7     License as published by the Free Software Foundation; either
   8     version 2 of the License, or (at your option) any later version.
   9 
  10     This library is distributed in the hope that it will be useful,
  11     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13     Library General Public License for more details.
  14 
  15     You should have received a copy of the GNU Library General Public
  16     License along with this library; if not, write to the Free
  17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18 
  19     Sam Lantinga
  20     slouken@devolution.com
  21 */
  22 
  23 #ifdef SAVE_RCSID
  24 static char rcsid =
  25  "@(#) $Id: SDL_sysmouse.c,v 1.5.2.11 2001/02/13 10:05:50 hercules Exp $";
  26 #endif
  27 
  28 #include <stdlib.h>
  29 #include <windows.h>
  30 
  31 #include "SDL_error.h"
  32 #include "SDL_mouse.h"
  33 #include "SDL_sysmouse_c.h"
  34 #include "SDL_events_c.h"
  35 #include "SDL_cursor_c.h"
  36 #include "SDL_lowvideo.h"
  37 
  38 #ifdef _WIN32_WCE
  39 #define USE_STATIC_CURSOR
  40 #endif
  41 
  42 HCURSOR SDL_hcursor = NULL;             /* Exported for SDL_eventloop.c */
  43 
  44 /* The implementation dependent data for the window manager cursor */
  45 /* For some reason when creating a windows cursor, the ands and xors memory
  46    is not copied, so we need to keep track of it and free it when we are done
  47    with the cursor.  If we free the memory prematurely, the app crashes. :-}
  48 */
  49 struct WMcursor {
  50         HCURSOR curs;
  51 #ifndef USE_STATIC_CURSOR
  52         Uint8 *ands;
  53         Uint8 *xors;
  54 #endif
  55 };
  56 
  57 /* Convert bits to padded bytes */
  58 #define PAD_BITS(bits)  ((bits+7)/8)
     /* [<][>][^][v][top][bottom][index][help] */
  59 
  60 #ifdef CURSOR_DEBUG
  61 static void PrintBITMAP(FILE *out, char *bits, int w, int h)
     /* [<][>][^][v][top][bottom][index][help] */
  62 {
  63         int i;
  64         unsigned char ch;
  65 
  66         while ( h-- > 0 ) {
  67                 for ( i=0; i<w; ++i ) {
  68                         if ( (i%8) == 0 )
  69                                 ch = *bits++;
  70                         if ( ch&0x80 )
  71                                 fprintf(out, "X");
  72                         else
  73                                 fprintf(out, " ");
  74                         ch <<= 1;
  75                 }
  76                 fprintf(out, "\n");
  77         }
  78 }
  79 #endif
  80 
  81 #ifndef USE_STATIC_CURSOR
  82 /* Local functions to convert the SDL cursor mask into Windows format */
  83 static void memnot(Uint8 *dst, Uint8 *src, int len)
     /* [<][>][^][v][top][bottom][index][help] */
  84 {
  85         while ( len-- > 0 )
  86                 *dst++ = ~*src++;
  87 }
  88 static void memxor(Uint8 *dst, Uint8 *src1, Uint8 *src2, int len)
     /* [<][>][^][v][top][bottom][index][help] */
  89 {
  90         while ( len-- > 0 )
  91                 *dst++ = (*src1++)^(*src2++);
  92 }
  93 #endif /* !USE_STATIC_CURSOR */
  94 
  95 void WIN_FreeWMCursor(_THIS, WMcursor *cursor)
     /* [<][>][^][v][top][bottom][index][help] */
  96 {
  97 #ifndef USE_STATIC_CURSOR
  98         if ( cursor->curs != NULL )
  99                 DestroyCursor(cursor->curs);
 100         if ( cursor->ands != NULL )
 101                 free(cursor->ands);
 102         if ( cursor->xors != NULL )
 103                 free(cursor->xors);
 104 #endif /* !USE_STATIC_CURSOR */
 105         free(cursor);
 106 }
 107 
 108 WMcursor *WIN_CreateWMCursor(_THIS,
     /* [<][>][^][v][top][bottom][index][help] */
 109                 Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y)
 110 {
 111 #ifdef USE_STATIC_CURSOR
 112         WMcursor *cursor;
 113 
 114         /* Allocate the cursor */
 115         cursor = (WMcursor *)malloc(sizeof(*cursor));
 116         if ( cursor ) {
 117                 cursor->curs = LoadCursor(NULL, IDC_ARROW);
 118         }
 119         return(cursor);
 120 #else
 121         WMcursor *cursor;
 122         int allowed_x;
 123         int allowed_y;
 124         int run, pad, i;
 125         Uint8 *aptr, *xptr;
 126 
 127         /* Check to make sure the cursor size is okay */
 128         allowed_x = GetSystemMetrics(SM_CXCURSOR);
 129         allowed_y = GetSystemMetrics(SM_CYCURSOR);
 130         if ( (w > allowed_x) || (h > allowed_y) ) {
 131                 SDL_SetError("Only cursors of dimension (%dx%d) are allowed",
 132                                                         allowed_x, allowed_y);
 133                 return(NULL);
 134         }
 135 
 136         /* Allocate the cursor */
 137         cursor = (WMcursor *)malloc(sizeof(*cursor));
 138         if ( cursor == NULL ) {
 139                 SDL_SetError("Out of memory");
 140                 return(NULL);
 141         }
 142         cursor->curs = NULL;
 143         cursor->ands = NULL;
 144         cursor->xors = NULL;
 145 
 146         /* Pad out to the normal cursor size */
 147         run = PAD_BITS(w);
 148         pad = PAD_BITS(allowed_x)-run;
 149         aptr = cursor->ands = (Uint8 *)malloc((run+pad)*allowed_y);
 150         xptr = cursor->xors = (Uint8 *)malloc((run+pad)*allowed_y);
 151         if ( (aptr == NULL) || (xptr == NULL) ) {
 152                 WIN_FreeWMCursor(NULL, cursor);
 153                 SDL_OutOfMemory();
 154                 return(NULL);
 155         }
 156         for ( i=0; i<h; ++i ) {
 157                 memxor(xptr, data, mask, run);
 158                 xptr += run;
 159                 data += run;
 160                 memnot(aptr, mask, run);
 161                 mask += run;
 162                 aptr += run;
 163                 memset(xptr,  0, pad);
 164                 xptr += pad;
 165                 memset(aptr, ~0, pad);
 166                 aptr += pad;
 167         }
 168         pad += run;
 169         for ( ; i<allowed_y; ++i ) {
 170                 memset(xptr,  0, pad);
 171                 xptr += pad;
 172                 memset(aptr, ~0, pad);
 173                 aptr += pad;
 174         }
 175 
 176         /* Create the cursor */
 177         cursor->curs = CreateCursor(
 178                         (HINSTANCE)GetWindowLong(SDL_Window, GWL_HINSTANCE),
 179                                         hot_x, hot_y, allowed_x, allowed_y, 
 180                                                 cursor->ands, cursor->xors);
 181         if ( cursor->curs == NULL ) {
 182                 WIN_FreeWMCursor(NULL, cursor);
 183                 SDL_SetError("Windows couldn't create the requested cursor");
 184                 return(NULL);
 185         }
 186         return(cursor);
 187 #endif /* USE_STATIC_CURSOR */
 188 }
 189 
 190 int WIN_ShowWMCursor(_THIS, WMcursor *cursor)
     /* [<][>][^][v][top][bottom][index][help] */
 191 {
 192         POINT mouse_pos;
 193 
 194         /* The fullscreen cursor must be done in software with DirectInput */
 195         if ( !this->screen || DIRECTX_FULLSCREEN() ) {
 196                 return(0);
 197         }
 198 
 199         /* Set the window cursor to our cursor, if applicable */
 200         if ( cursor != NULL ) {
 201                 SDL_hcursor = cursor->curs;
 202         } else {
 203                 SDL_hcursor = NULL;
 204         }
 205         GetCursorPos(&mouse_pos);
 206         if ( PtInRect(&SDL_bounds, mouse_pos) ) {
 207                 SetCursor(SDL_hcursor);
 208         }
 209         return(1);
 210 }
 211 
 212 void WIN_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
     /* [<][>][^][v][top][bottom][index][help] */
 213 {
 214         POINT pt;
 215 
 216         if ( DIRECTX_FULLSCREEN() ) {
 217                 x += (this->screen->offset % this->screen->pitch) /
 218                       this->screen->format->BytesPerPixel;
 219                 y += (this->screen->offset / this->screen->pitch);
 220                 SDL_PrivateMouseMotion(0, 0, x, y);
 221         } else if ( mouse_relative) {
 222                 /*      RJR: March 28, 2000
 223                         leave physical cursor at center of screen if
 224                         mouse hidden and grabbed */
 225                 SDL_PrivateMouseMotion(0, 0, x, y);
 226         } else {
 227                 pt.x = x;
 228                 pt.y = y;
 229                 ClientToScreen(SDL_Window, &pt);
 230                 SetCursorPos(pt.x, pt.y);
 231         }
 232 }
 233 
 234 /* Update the current mouse state and position */
 235 void WIN_UpdateMouse(_THIS)
     /* [<][>][^][v][top][bottom][index][help] */
 236 {
 237         RECT rect;
 238         POINT pt;
 239 
 240         if ( ! DIRECTX_FULLSCREEN() ) {
 241                 GetClientRect(SDL_Window, &rect);
 242                 GetCursorPos(&pt);
 243                 MapWindowPoints(NULL, SDL_Window, &pt, 1);
 244                 if (PtInRect(&rect, pt) && (WindowFromPoint(pt) == SDL_Window)){
 245                         SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
 246                         SDL_PrivateMouseMotion(0,0, (Sint16)pt.x, (Sint16)pt.y);
 247                 } else {
 248                         SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
 249                 }
 250         }
 251 }
 252 
 253 /* Check to see if we need to enter or leave mouse relative mode */
 254 void WIN_CheckMouseMode(_THIS)
     /* [<][>][^][v][top][bottom][index][help] */
 255 {
 256         /* If the mouse is hidden and input is grabbed, we use relative mode */
 257         if ( !(SDL_cursorstate & CURSOR_VISIBLE) &&
 258              (this->input_grab != SDL_GRAB_OFF) ) {
 259                 mouse_relative = 1;
 260         } else {
 261                 mouse_relative = 0;
 262         }
 263 }

/* [<][>][^][v][top][bottom][index][help] */