src/video/wincommon/SDL_sysmouse.c
branchSDL-1.3
changeset 1668 4da1ee79c9af
parent 1662 782fd950bd46
equal deleted inserted replaced
1667:1fddae038bc8 1668:4da1ee79c9af
    53 /* Convert bits to padded bytes */
    53 /* Convert bits to padded bytes */
    54 #define PAD_BITS(bits)	((bits+7)/8)
    54 #define PAD_BITS(bits)	((bits+7)/8)
    55 
    55 
    56 #ifdef CURSOR_DEBUG
    56 #ifdef CURSOR_DEBUG
    57 static void
    57 static void
    58 PrintBITMAP (FILE * out, char *bits, int w, int h)
    58 PrintBITMAP(FILE * out, char *bits, int w, int h)
    59 {
    59 {
    60     int i;
    60     int i;
    61     unsigned char ch;
    61     unsigned char ch;
    62 
    62 
    63     while (h-- > 0) {
    63     while (h-- > 0) {
    64         for (i = 0; i < w; ++i) {
    64         for (i = 0; i < w; ++i) {
    65             if ((i % 8) == 0)
    65             if ((i % 8) == 0)
    66                 ch = *bits++;
    66                 ch = *bits++;
    67             if (ch & 0x80)
    67             if (ch & 0x80)
    68                 fprintf (out, "X");
    68                 fprintf(out, "X");
    69             else
    69             else
    70                 fprintf (out, " ");
    70                 fprintf(out, " ");
    71             ch <<= 1;
    71             ch <<= 1;
    72         }
    72         }
    73         fprintf (out, "\n");
    73         fprintf(out, "\n");
    74     }
    74     }
    75 }
    75 }
    76 #endif
    76 #endif
    77 
    77 
    78 #ifndef USE_STATIC_CURSOR
    78 #ifndef USE_STATIC_CURSOR
    79 /* Local functions to convert the SDL cursor mask into Windows format */
    79 /* Local functions to convert the SDL cursor mask into Windows format */
    80 static void
    80 static void
    81 memnot (Uint8 * dst, Uint8 * src, int len)
    81 memnot(Uint8 * dst, Uint8 * src, int len)
    82 {
    82 {
    83     while (len-- > 0)
    83     while (len-- > 0)
    84         *dst++ = ~*src++;
    84         *dst++ = ~*src++;
    85 }
    85 }
    86 static void
    86 static void
    87 memxor (Uint8 * dst, Uint8 * src1, Uint8 * src2, int len)
    87 memxor(Uint8 * dst, Uint8 * src1, Uint8 * src2, int len)
    88 {
    88 {
    89     while (len-- > 0)
    89     while (len-- > 0)
    90         *dst++ = (*src1++) ^ (*src2++);
    90         *dst++ = (*src1++) ^ (*src2++);
    91 }
    91 }
    92 #endif /* !USE_STATIC_CURSOR */
    92 #endif /* !USE_STATIC_CURSOR */
    93 
    93 
    94 void
    94 void
    95 WIN_FreeWMCursor (_THIS, WMcursor * cursor)
    95 WIN_FreeWMCursor(_THIS, WMcursor * cursor)
    96 {
    96 {
    97 #ifndef USE_STATIC_CURSOR
    97 #ifndef USE_STATIC_CURSOR
    98     if (cursor->curs == GetCursor ())
    98     if (cursor->curs == GetCursor())
    99         SetCursor (NULL);
    99         SetCursor(NULL);
   100     if (cursor->curs != NULL)
   100     if (cursor->curs != NULL)
   101         DestroyCursor (cursor->curs);
   101         DestroyCursor(cursor->curs);
   102     if (cursor->ands != NULL)
   102     if (cursor->ands != NULL)
   103         SDL_free (cursor->ands);
   103         SDL_free(cursor->ands);
   104     if (cursor->xors != NULL)
   104     if (cursor->xors != NULL)
   105         SDL_free (cursor->xors);
   105         SDL_free(cursor->xors);
   106 #endif /* !USE_STATIC_CURSOR */
   106 #endif /* !USE_STATIC_CURSOR */
   107     SDL_free (cursor);
   107     SDL_free(cursor);
   108 }
   108 }
   109 
   109 
   110 WMcursor *
   110 WMcursor *
   111 WIN_CreateWMCursor (_THIS,
   111 WIN_CreateWMCursor(_THIS,
   112                     Uint8 * data, Uint8 * mask, int w, int h, int hot_x,
   112                    Uint8 * data, Uint8 * mask, int w, int h, int hot_x,
   113                     int hot_y)
   113                    int hot_y)
   114 {
   114 {
   115 #ifdef USE_STATIC_CURSOR
   115 #ifdef USE_STATIC_CURSOR
   116     WMcursor *cursor;
   116     WMcursor *cursor;
   117 
   117 
   118     /* Allocate the cursor */
   118     /* Allocate the cursor */
   119     cursor = (WMcursor *) SDL_malloc (sizeof (*cursor));
   119     cursor = (WMcursor *) SDL_malloc(sizeof(*cursor));
   120     if (cursor) {
   120     if (cursor) {
   121         cursor->curs = LoadCursor (NULL, IDC_ARROW);
   121         cursor->curs = LoadCursor(NULL, IDC_ARROW);
   122     }
   122     }
   123     return (cursor);
   123     return (cursor);
   124 #else
   124 #else
   125     WMcursor *cursor;
   125     WMcursor *cursor;
   126     int allowed_x;
   126     int allowed_x;
   127     int allowed_y;
   127     int allowed_y;
   128     int run, pad, i;
   128     int run, pad, i;
   129     Uint8 *aptr, *xptr;
   129     Uint8 *aptr, *xptr;
   130 
   130 
   131     /* Check to make sure the cursor size is okay */
   131     /* Check to make sure the cursor size is okay */
   132     allowed_x = GetSystemMetrics (SM_CXCURSOR);
   132     allowed_x = GetSystemMetrics(SM_CXCURSOR);
   133     allowed_y = GetSystemMetrics (SM_CYCURSOR);
   133     allowed_y = GetSystemMetrics(SM_CYCURSOR);
   134     if ((w > allowed_x) || (h > allowed_y)) {
   134     if ((w > allowed_x) || (h > allowed_y)) {
   135         SDL_SetError ("Only cursors of dimension (%dx%d) are allowed",
   135         SDL_SetError("Only cursors of dimension (%dx%d) are allowed",
   136                       allowed_x, allowed_y);
   136                      allowed_x, allowed_y);
   137         return (NULL);
   137         return (NULL);
   138     }
   138     }
   139 
   139 
   140     /* Allocate the cursor */
   140     /* Allocate the cursor */
   141     cursor = (WMcursor *) SDL_malloc (sizeof (*cursor));
   141     cursor = (WMcursor *) SDL_malloc(sizeof(*cursor));
   142     if (cursor == NULL) {
   142     if (cursor == NULL) {
   143         SDL_SetError ("Out of memory");
   143         SDL_SetError("Out of memory");
   144         return (NULL);
   144         return (NULL);
   145     }
   145     }
   146     cursor->curs = NULL;
   146     cursor->curs = NULL;
   147     cursor->ands = NULL;
   147     cursor->ands = NULL;
   148     cursor->xors = NULL;
   148     cursor->xors = NULL;
   149 
   149 
   150     /* Pad out to the normal cursor size */
   150     /* Pad out to the normal cursor size */
   151     run = PAD_BITS (w);
   151     run = PAD_BITS(w);
   152     pad = PAD_BITS (allowed_x) - run;
   152     pad = PAD_BITS(allowed_x) - run;
   153     aptr = cursor->ands = (Uint8 *) SDL_malloc ((run + pad) * allowed_y);
   153     aptr = cursor->ands = (Uint8 *) SDL_malloc((run + pad) * allowed_y);
   154     xptr = cursor->xors = (Uint8 *) SDL_malloc ((run + pad) * allowed_y);
   154     xptr = cursor->xors = (Uint8 *) SDL_malloc((run + pad) * allowed_y);
   155     if ((aptr == NULL) || (xptr == NULL)) {
   155     if ((aptr == NULL) || (xptr == NULL)) {
   156         WIN_FreeWMCursor (NULL, cursor);
   156         WIN_FreeWMCursor(NULL, cursor);
   157         SDL_OutOfMemory ();
   157         SDL_OutOfMemory();
   158         return (NULL);
   158         return (NULL);
   159     }
   159     }
   160     for (i = 0; i < h; ++i) {
   160     for (i = 0; i < h; ++i) {
   161         memxor (xptr, data, mask, run);
   161         memxor(xptr, data, mask, run);
   162         xptr += run;
   162         xptr += run;
   163         data += run;
   163         data += run;
   164         memnot (aptr, mask, run);
   164         memnot(aptr, mask, run);
   165         mask += run;
   165         mask += run;
   166         aptr += run;
   166         aptr += run;
   167         SDL_memset (xptr, 0, pad);
   167         SDL_memset(xptr, 0, pad);
   168         xptr += pad;
   168         xptr += pad;
   169         SDL_memset (aptr, ~0, pad);
   169         SDL_memset(aptr, ~0, pad);
   170         aptr += pad;
   170         aptr += pad;
   171     }
   171     }
   172     pad += run;
   172     pad += run;
   173     for (; i < allowed_y; ++i) {
   173     for (; i < allowed_y; ++i) {
   174         SDL_memset (xptr, 0, pad);
   174         SDL_memset(xptr, 0, pad);
   175         xptr += pad;
   175         xptr += pad;
   176         SDL_memset (aptr, ~0, pad);
   176         SDL_memset(aptr, ~0, pad);
   177         aptr += pad;
   177         aptr += pad;
   178     }
   178     }
   179 
   179 
   180     /* Create the cursor */
   180     /* Create the cursor */
   181     cursor->curs = CreateCursor ((HINSTANCE)
   181     cursor->curs = CreateCursor((HINSTANCE)
   182                                  GetWindowLongPtr (SDL_Window,
   182                                 GetWindowLongPtr(SDL_Window,
   183                                                    GWLP_HINSTANCE), hot_x,
   183                                                  GWLP_HINSTANCE), hot_x,
   184                                  hot_y, allowed_x, allowed_y, cursor->ands,
   184                                 hot_y, allowed_x, allowed_y, cursor->ands,
   185                                  cursor->xors);
   185                                 cursor->xors);
   186     if (cursor->curs == NULL) {
   186     if (cursor->curs == NULL) {
   187         WIN_FreeWMCursor (NULL, cursor);
   187         WIN_FreeWMCursor(NULL, cursor);
   188         SDL_SetError ("Windows couldn't create the requested cursor");
   188         SDL_SetError("Windows couldn't create the requested cursor");
   189         return (NULL);
   189         return (NULL);
   190     }
   190     }
   191     return (cursor);
   191     return (cursor);
   192 #endif /* USE_STATIC_CURSOR */
   192 #endif /* USE_STATIC_CURSOR */
   193 }
   193 }
   194 
   194 
   195 int
   195 int
   196 WIN_ShowWMCursor (_THIS, WMcursor * cursor)
   196 WIN_ShowWMCursor(_THIS, WMcursor * cursor)
   197 {
   197 {
   198     POINT mouse_pos;
   198     POINT mouse_pos;
   199 
   199 
   200     /* The fullscreen cursor must be done in software with DirectInput */
   200     /* The fullscreen cursor must be done in software with DirectInput */
   201     if (!this->screen || DDRAW_FULLSCREEN ()) {
   201     if (!this->screen || DDRAW_FULLSCREEN()) {
   202         return (0);
   202         return (0);
   203     }
   203     }
   204 
   204 
   205     /* Set the window cursor to our cursor, if applicable */
   205     /* Set the window cursor to our cursor, if applicable */
   206     if (cursor != NULL) {
   206     if (cursor != NULL) {
   207         SDL_hcursor = cursor->curs;
   207         SDL_hcursor = cursor->curs;
   208     } else {
   208     } else {
   209         SDL_hcursor = NULL;
   209         SDL_hcursor = NULL;
   210     }
   210     }
   211     GetCursorPos (&mouse_pos);
   211     GetCursorPos(&mouse_pos);
   212     if (PtInRect (&SDL_bounds, mouse_pos)) {
   212     if (PtInRect(&SDL_bounds, mouse_pos)) {
   213         SetCursor (SDL_hcursor);
   213         SetCursor(SDL_hcursor);
   214     }
   214     }
   215     return (1);
   215     return (1);
   216 }
   216 }
   217 
   217 
   218 void
   218 void
   219 WIN_WarpWMCursor (_THIS, Uint16 x, Uint16 y)
   219 WIN_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
   220 {
   220 {
   221     if (DDRAW_FULLSCREEN ()) {
   221     if (DDRAW_FULLSCREEN()) {
   222         SDL_PrivateMouseMotion (0, 0, x, y);
   222         SDL_PrivateMouseMotion(0, 0, x, y);
   223     } else if (mouse_relative) {
   223     } else if (mouse_relative) {
   224         /*      RJR: March 28, 2000
   224         /*      RJR: March 28, 2000
   225            leave physical cursor at center of screen if
   225            leave physical cursor at center of screen if
   226            mouse hidden and grabbed */
   226            mouse hidden and grabbed */
   227         SDL_PrivateMouseMotion (0, 0, x, y);
   227         SDL_PrivateMouseMotion(0, 0, x, y);
   228     } else {
   228     } else {
   229         POINT pt;
   229         POINT pt;
   230         pt.x = x;
   230         pt.x = x;
   231         pt.y = y;
   231         pt.y = y;
   232         ClientToScreen (SDL_Window, &pt);
   232         ClientToScreen(SDL_Window, &pt);
   233         SetCursorPos (pt.x, pt.y);
   233         SetCursorPos(pt.x, pt.y);
   234     }
   234     }
   235 }
   235 }
   236 
   236 
   237 /* Update the current mouse state and position */
   237 /* Update the current mouse state and position */
   238 void
   238 void
   239 WIN_UpdateMouse (_THIS)
   239 WIN_UpdateMouse(_THIS)
   240 {
   240 {
   241     RECT rect;
   241     RECT rect;
   242     POINT pt;
   242     POINT pt;
   243 
   243 
   244     if (!DDRAW_FULLSCREEN ()) {
   244     if (!DDRAW_FULLSCREEN()) {
   245         GetClientRect (SDL_Window, &rect);
   245         GetClientRect(SDL_Window, &rect);
   246         GetCursorPos (&pt);
   246         GetCursorPos(&pt);
   247         MapWindowPoints (NULL, SDL_Window, &pt, 1);
   247         MapWindowPoints(NULL, SDL_Window, &pt, 1);
   248         if (PtInRect (&rect, pt) && (WindowFromPoint (pt) == SDL_Window)) {
   248         if (PtInRect(&rect, pt) && (WindowFromPoint(pt) == SDL_Window)) {
   249             SDL_PrivateAppActive (1, SDL_APPMOUSEFOCUS);
   249             SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
   250             SDL_PrivateMouseMotion (0, 0, (Sint16) pt.x, (Sint16) pt.y);
   250             SDL_PrivateMouseMotion(0, 0, (Sint16) pt.x, (Sint16) pt.y);
   251         } else {
   251         } else {
   252             SDL_PrivateAppActive (0, SDL_APPMOUSEFOCUS);
   252             SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
   253         }
   253         }
   254     }
   254     }
   255 }
   255 }
   256 
   256 
   257 /* Check to see if we need to enter or leave mouse relative mode */
   257 /* Check to see if we need to enter or leave mouse relative mode */
   258 void
   258 void
   259 WIN_CheckMouseMode (_THIS)
   259 WIN_CheckMouseMode(_THIS)
   260 {
   260 {
   261 #ifndef _WIN32_WCE
   261 #ifndef _WIN32_WCE
   262     /* If the mouse is hidden and input is grabbed, we use relative mode */
   262     /* If the mouse is hidden and input is grabbed, we use relative mode */
   263     if (!(SDL_cursorstate & CURSOR_VISIBLE) &&
   263     if (!(SDL_cursorstate & CURSOR_VISIBLE) &&
   264         (this->input_grab != SDL_GRAB_OFF)) {
   264         (this->input_grab != SDL_GRAB_OFF)) {