comparison src/SDL_compat.c @ 1670:eef792d31de8 SDL-1.3

Work in progress. :)
author Sam Lantinga <slouken@libsdl.org>
date Wed, 07 Jun 2006 16:10:28 +0000
parents 9857d21967bb
children d33dcfc3fde7
comparison
equal deleted inserted replaced
1669:9857d21967bb 1670:eef792d31de8
49 if (name) { 49 if (name) {
50 SDL_strlcpy(namebuf, name, maxlen); 50 SDL_strlcpy(namebuf, name, maxlen);
51 return namebuf; 51 return namebuf;
52 } 52 }
53 return NULL; 53 return NULL;
54 }
55
56 const SDL_VideoInfo *
57 SDL_GetVideoInfo(void)
58 {
59 static SDL_VideoInfo info;
60
61 /* Memory leak, compatibility code, who cares? */
62 if (!info.vfmt && SDL_GetDesktopDisplayMode()) {
63 int bpp;
64 Uint32 Rmask, Gmask, Bmask, Amask;
65
66 SDL_PixelFormatEnumToMasks(SDL_GetDesktopDisplayMode()->format, &bpp,
67 &Rmask, &Gmask, &Bmask, &Amask);
68 info.vfmt = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask);
69 }
70 return &info;
54 } 71 }
55 72
56 int 73 int
57 SDL_VideoModeOK(int width, int height, int bpp, Uint32 flags) 74 SDL_VideoModeOK(int width, int height, int bpp, Uint32 flags)
58 { 75 {
294 /* Create the display surface */ 311 /* Create the display surface */
295 return SDL_CreateWindowSurface(window, desired_format, flags); 312 return SDL_CreateWindowSurface(window, desired_format, flags);
296 } 313 }
297 314
298 SDL_Surface * 315 SDL_Surface *
316 SDL_CreateWindowSurface(SDL_WindowID windowID, Uint32 format, Uint32 flags)
317 {
318 SDL_Window *window = SDL_GetWindowFromID(windowID);
319 Uint32 black;
320 SDL_Surface *surface;
321
322 if (!window) {
323 return NULL;
324 }
325
326 if (!_this->CreateWindowSurface) {
327 return NULL;
328 }
329
330 if (!window->surface) {
331 _this->CreateWindowSurface(_this, window, flags);
332 if (!window->surface) {
333 return NULL;
334 }
335 window->surface->flags |= SDL_SCREEN_SURFACE;
336
337 /* If we have a palettized surface, create a default palette */
338 if (window->surface->format->palette) {
339 SDL_Color colors[256];
340 SDL_PixelFormat *vf = window->surface->format;
341 SDL_DitherColors(colors, vf->BitsPerPixel);
342 SDL_SetColors(window->surface, colors, 0, vf->palette->ncolors);
343 }
344 }
345 surface = window->surface;
346
347 if (window->shadow) {
348 SDL_FreeSurface(window->shadow);
349 window->shadow = NULL;
350 }
351
352 /* Create a shadow surface if necessary */
353 if ((!(flags & SDL_ANYFORMAT)
354 && (format != SDL_GetCurrentDisplayMode()->format))
355 || ((flags & SDL_HWPALETTE)
356 && !(window->surface->flags & SDL_HWPALETTE))) {
357 int bpp;
358 Uint32 Rmask, Gmask, Bmask, Amask;
359
360 SDL_PixelFormatEnumToMasks(format, &bpp, &Amask, &Gmask, &Bmask,
361 &Amask);
362 window->shadow =
363 SDL_CreateRGBSurface(SDL_SWSURFACE, surface->w, surface->h, bpp,
364 Rmask, Gmask, Bmask, Amask);
365 if (window->shadow == NULL) {
366 return NULL;
367 }
368 window->shadow->flags |= SDL_SHADOW_SURFACE;
369
370 surface = window->shadow;
371
372 /* 8-bit shadow surfaces report that they have exclusive palette */
373 if (surface->format->palette) {
374 surface->flags |= SDL_HWPALETTE;
375 if (format == SDL_GetCurrentDisplayMode()->format) {
376 SDL_memcpy(surface->format->palette->colors,
377 window->surface->format->palette->colors,
378 window->surface->format->palette->ncolors *
379 sizeof(SDL_Color));
380 } else {
381 SDL_DitherColors(surface->format->palette->colors, bpp);
382 }
383 }
384 }
385
386 /* Clear the surface for display */
387 {
388 Uint32 black = SDL_MapRGB(surface->format, 0, 0, 0);
389 SDL_FillRect(surface, NULL, black);
390 if (surface->flags & SDL_DOUBLEBUF) {
391 SDL_Flip(surface);
392 SDL_FillRect(surface, NULL, black);
393 }
394 SDL_Flip(surface);
395 }
396
397 return surface;
398 }
399
400 SDL_Surface *
299 SDL_GetVideoSurface(void) 401 SDL_GetVideoSurface(void)
300 { 402 {
301 SDL_VideoDevice *_this = SDL_GetVideoDevice(); 403 SDL_VideoDevice *_this = SDL_GetVideoDevice();
302 404
303 return SDL_VideoSurface; 405 return SDL_VideoSurface;
406 }
407
408 SDL_Surface *
409 SDL_DisplayFormat(SDL_Surface * surface)
410 {
411 Uint32 flags;
412
413 if (!SDL_PublicSurface) {
414 SDL_SetError("No video mode has been set");
415 return (NULL);
416 }
417 /* Set the flags appropriate for copying to display surface */
418 if (((SDL_PublicSurface->flags & SDL_HWSURFACE) == SDL_HWSURFACE)
419 && _this->info.blit_hw)
420 flags = SDL_HWSURFACE;
421 else
422 flags = SDL_SWSURFACE;
423 #ifdef AUTORLE_DISPLAYFORMAT
424 flags |= (surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA));
425 flags |= SDL_RLEACCELOK;
426 #else
427 flags |=
428 surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA | SDL_RLEACCELOK);
429 #endif
430 return (SDL_ConvertSurface(surface, SDL_PublicSurface->format, flags));
431 }
432
433 SDL_Surface *
434 SDL_DisplayFormatAlpha(SDL_Surface * surface)
435 {
436 SDL_PixelFormat *vf;
437 SDL_PixelFormat *format;
438 SDL_Surface *converted;
439 Uint32 flags;
440 /* default to ARGB8888 */
441 Uint32 amask = 0xff000000;
442 Uint32 rmask = 0x00ff0000;
443 Uint32 gmask = 0x0000ff00;
444 Uint32 bmask = 0x000000ff;
445
446 if (!SDL_PublicSurface) {
447 SDL_SetError("No video mode has been set");
448 return (NULL);
449 }
450 vf = SDL_PublicSurface->format;
451
452 switch (vf->BytesPerPixel) {
453 case 2:
454 /* For XGY5[56]5, use, AXGY8888, where {X, Y} = {R, B}.
455 For anything else (like ARGB4444) it doesn't matter
456 since we have no special code for it anyway */
457 if ((vf->Rmask == 0x1f) &&
458 (vf->Bmask == 0xf800 || vf->Bmask == 0x7c00)) {
459 rmask = 0xff;
460 bmask = 0xff0000;
461 }
462 break;
463
464 case 3:
465 case 4:
466 /* Keep the video format, as long as the high 8 bits are
467 unused or alpha */
468 if ((vf->Rmask == 0xff) && (vf->Bmask == 0xff0000)) {
469 rmask = 0xff;
470 bmask = 0xff0000;
471 }
472 break;
473
474 default:
475 /* We have no other optimised formats right now. When/if a new
476 optimised alpha format is written, add the converter here */
477 break;
478 }
479 format = SDL_AllocFormat(32, rmask, gmask, bmask, amask);
480 flags = SDL_PublicSurface->flags & SDL_HWSURFACE;
481 flags |= surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
482 converted = SDL_ConvertSurface(surface, format, flags);
483 SDL_FreeFormat(format);
484 return (converted);
485 }
486
487 void
488 SDL_UpdateRect(SDL_Surface * screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h)
489 {
490 if (screen) {
491 SDL_Rect rect;
492
493 /* Perform some checking */
494 if (w == 0)
495 w = screen->w;
496 if (h == 0)
497 h = screen->h;
498 if ((int) (x + w) > screen->w)
499 return;
500 if ((int) (y + h) > screen->h)
501 return;
502
503 /* Fill the rectangle */
504 rect.x = (Sint16) x;
505 rect.y = (Sint16) y;
506 rect.w = (Uint16) w;
507 rect.h = (Uint16) h;
508 SDL_UpdateRects(screen, 1, &rect);
509 }
510 }
511 void
512 SDL_UpdateRects(SDL_Surface * screen, int numrects, SDL_Rect * rects)
513 {
514 int i;
515 SDL_Window *window;
516
517 /* Find the window corresponding to this surface */
518 window = SDL_GetWindowFromSurface(screen);
519 if (!window) {
520 SDL_SetError("Couldn't find window associated with surface");
521 return;
522 }
523
524 if (screen->flags & SDL_SHADOW_SURFACE) {
525 if (SHOULD_DRAWCURSOR(SDL_cursorstate)) {
526 SDL_LockCursor();
527 SDL_DrawCursor(screen);
528 for (i = 0; i < numrects; ++i) {
529 SDL_LowerBlit(screen, &rects[i], window->surface, &rects[i]);
530 }
531 SDL_EraseCursor(screen);
532 SDL_UnlockCursor();
533 } else {
534 for (i = 0; i < numrects; ++i) {
535 SDL_LowerBlit(screen, &rects[i], window->surface, &rects[i]);
536 }
537 }
538
539 /* Fall through to video surface update */
540 screen = window->surface;
541 }
542 if ((screen->flags & SDL_SCREEN_SURFACE) && _this->UpdateWindowSurface) {
543 /* Update the video surface */
544 if (screen->offset) {
545 int offset_y = screen->offset / screen->pitch;
546 int offset_x = screen->offset % screen->pitch;
547 for (i = 0; i < numrects; ++i) {
548 rects[i].x += offset_x;
549 rects[i].y += offset_y;
550 }
551 _this->UpdateWindowSurface(_this, window, numrects, rects);
552 for (i = 0; i < numrects; ++i) {
553 rects[i].x -= offset_x;
554 rects[i].y -= offset_y;
555 }
556 } else {
557 _this->UpdateWindowSurface(_this, window, numrects, rects);
558 }
559 }
560 }
561
562 int
563 SDL_Flip(SDL_Surface * screen)
564 {
565 SDL_Window *window;
566
567 /* Find the window corresponding to this surface */
568 window = SDL_GetWindowFromSurface(screen);
569 if (!window) {
570 SDL_SetError("Couldn't find window associated with surface");
571 return;
572 }
573
574 /* Copy the shadow surface to the video surface */
575 if (screen->flags & SDL_SHADOW_SURFACE) {
576 SDL_Rect rect;
577
578 rect.x = 0;
579 rect.y = 0;
580 rect.w = screen->w;
581 rect.h = screen->h;
582 if (SHOULD_DRAWCURSOR(SDL_cursorstate)) {
583 SDL_LockCursor();
584 SDL_DrawCursor(screen);
585 SDL_LowerBlit(screen, &rect, window->surface, &rect);
586 SDL_EraseCursor(screen);
587 SDL_UnlockCursor();
588 } else {
589 SDL_LowerBlit(screen, &rect, window->surface, &rect);
590 }
591
592 /* Fall through to video surface update */
593 screen = window->surface;
594 }
595 if (screen->flags & SDL_DOUBLEBUF) {
596 _this->FlipWindowSurface(_this, window);
597 } else {
598 SDL_UpdateRect(screen, 0, 0, 0, 0);
599 }
600 return (0);
304 } 601 }
305 602
306 void 603 void
307 SDL_WM_SetCaption(const char *title, const char *icon) 604 SDL_WM_SetCaption(const char *title, const char *icon)
308 { 605 {
385 { 682 {
386 SDL_SetColors(surface, colors, firstcolor, ncolors); 683 SDL_SetColors(surface, colors, firstcolor, ncolors);
387 } 684 }
388 685
389 int 686 int
687 SDL_SetScreenColors(SDL_Surface * screen, SDL_Color * colors, int firstcolor,
688 int ncolors)
689 {
690 SDL_Window *window = NULL;
691 SDL_Palette *pal;
692 int gotall;
693 int palsize;
694
695 /* Verify the parameters */
696 pal = screen->format->palette;
697 if (!pal) {
698 return 0; /* not a palettized surface */
699 }
700 gotall = 1;
701 palsize = 1 << screen->format->BitsPerPixel;
702 if (ncolors > (palsize - firstcolor)) {
703 ncolors = (palsize - firstcolor);
704 gotall = 0;
705 }
706
707 if (screen->flags & (SDL_SHADOW_SURFACE | SDL_SCREEN_SURFACE)) {
708 window = SDL_GetWindowFromSurface(screen);
709 if (!window) {
710 return 0;
711 }
712 }
713
714 if (screen->flags & SDL_SHADOW_SURFACE) {
715 SDL_Palette *vidpal;
716
717 vidpal = window->surface->format->palette;
718 if (vidpal && vidpal->ncolors == pal->ncolors) {
719 /* This is a shadow surface, and the physical
720 * framebuffer is also indexed. Propagate the
721 * changes to its logical palette so that
722 * updates are always identity blits
723 */
724 SDL_memcpy(vidpal->colors + firstcolor, colors,
725 ncolors * sizeof(*colors));
726 }
727 if (window->surface->flags & SDL_HWPALETTE) {
728 /* Set the physical palette */
729 screen = window->surface;
730 } else {
731 SDL_UpdateRect(screen, 0, 0, 0, 0);
732 }
733 }
734
735 if (screen->flags & SDL_SCREEN_SURFACE) {
736 if (_this->SetWindowColors) {
737 gotall =
738 _this->SetWindowColors(_this, window, firstcolor, ncolors,
739 colors);
740 if (!gotall) {
741 /* The video flags shouldn't have SDL_HWPALETTE, and
742 the video driver is responsible for copying back the
743 correct colors into the video surface palette.
744 */
745 ;
746 }
747 }
748 SDL_CursorPaletteChanged();
749 }
750
751 return gotall;
752 }
753
754 int
390 SDL_GetWMInfo(SDL_SysWMinfo * info) 755 SDL_GetWMInfo(SDL_SysWMinfo * info)
391 { 756 {
392 return SDL_GetWindowWMInfo(window, info); 757 return SDL_GetWindowWMInfo(window, info);
393 } 758 }
394 759
760 void
761 SDL_MoveCursor(int x, int y)
762 {
763 SDL_VideoDevice *_this = SDL_GetVideoDevice();
764
765 /* Erase and update the current mouse position */
766 if (SHOULD_DRAWCURSOR(SDL_cursorstate)) {
767 /* Erase and redraw mouse cursor in new position */
768 SDL_LockCursor();
769 SDL_EraseCursor(SDL_VideoSurface);
770 SDL_cursor->area.x = (x - SDL_cursor->hot_x);
771 SDL_cursor->area.y = (y - SDL_cursor->hot_y);
772 SDL_DrawCursor(SDL_VideoSurface);
773 SDL_UnlockCursor();
774 } else if (_this->MoveWMCursor) {
775 _this->MoveWMCursor(_this, x, y);
776 }
777 }
778
779 /* Keep track of the current cursor colors */
780 static int palette_changed = 1;
781 static Uint8 pixels8[2];
782
783 void
784 SDL_CursorPaletteChanged(void)
785 {
786 palette_changed = 1;
787 }
788
789 void
790 SDL_MouseRect(SDL_Rect * area)
791 {
792 SDL_VideoDevice *_this = SDL_GetVideoDevice();
793 int clip_diff;
794
795 *area = SDL_cursor->area;
796 if (area->x < 0) {
797 area->w += area->x;
798 area->x = 0;
799 }
800 if (area->y < 0) {
801 area->h += area->y;
802 area->y = 0;
803 }
804 clip_diff = (area->x + area->w) - SDL_VideoSurface->w;
805 if (clip_diff > 0) {
806 area->w = area->w < clip_diff ? 0 : area->w - clip_diff;
807 }
808 clip_diff = (area->y + area->h) - SDL_VideoSurface->h;
809 if (clip_diff > 0) {
810 area->h = area->h < clip_diff ? 0 : area->h - clip_diff;
811 }
812 }
813
814 static void
815 SDL_DrawCursorFast(SDL_Surface * screen, SDL_Rect * area)
816 {
817 const Uint32 pixels[2] = { 0xFFFFFFFF, 0x00000000 };
818 int i, w, h;
819 Uint8 *data, datab;
820 Uint8 *mask, maskb;
821
822 data = SDL_cursor->data + area->y * SDL_cursor->area.w / 8;
823 mask = SDL_cursor->mask + area->y * SDL_cursor->area.w / 8;
824 switch (screen->format->BytesPerPixel) {
825
826 case 1:
827 {
828 Uint8 *dst;
829 int dstskip;
830
831 if (palette_changed) {
832 pixels8[0] =
833 (Uint8) SDL_MapRGB(screen->format, 255, 255, 255);
834 pixels8[1] = (Uint8) SDL_MapRGB(screen->format, 0, 0, 0);
835 palette_changed = 0;
836 }
837 dst = (Uint8 *) screen->pixels +
838 (SDL_cursor->area.y + area->y) * screen->pitch +
839 SDL_cursor->area.x;
840 dstskip = screen->pitch - area->w;
841
842 for (h = area->h; h; h--) {
843 for (w = area->w / 8; w; w--) {
844 maskb = *mask++;
845 datab = *data++;
846 for (i = 0; i < 8; ++i) {
847 if (maskb & 0x80) {
848 *dst = pixels8[datab >> 7];
849 }
850 maskb <<= 1;
851 datab <<= 1;
852 dst++;
853 }
854 }
855 dst += dstskip;
856 }
857 }
858 break;
859
860 case 2:
861 {
862 Uint16 *dst;
863 int dstskip;
864
865 dst = (Uint16 *) screen->pixels +
866 (SDL_cursor->area.y + area->y) * screen->pitch / 2 +
867 SDL_cursor->area.x;
868 dstskip = (screen->pitch / 2) - area->w;
869
870 for (h = area->h; h; h--) {
871 for (w = area->w / 8; w; w--) {
872 maskb = *mask++;
873 datab = *data++;
874 for (i = 0; i < 8; ++i) {
875 if (maskb & 0x80) {
876 *dst = (Uint16) pixels[datab >> 7];
877 }
878 maskb <<= 1;
879 datab <<= 1;
880 dst++;
881 }
882 }
883 dst += dstskip;
884 }
885 }
886 break;
887
888 case 3:
889 {
890 Uint8 *dst;
891 int dstskip;
892
893 dst = (Uint8 *) screen->pixels +
894 (SDL_cursor->area.y + area->y) * screen->pitch +
895 SDL_cursor->area.x * 3;
896 dstskip = screen->pitch - area->w * 3;
897
898 for (h = area->h; h; h--) {
899 for (w = area->w / 8; w; w--) {
900 maskb = *mask++;
901 datab = *data++;
902 for (i = 0; i < 8; ++i) {
903 if (maskb & 0x80) {
904 SDL_memset(dst, pixels[datab >> 7], 3);
905 }
906 maskb <<= 1;
907 datab <<= 1;
908 dst += 3;
909 }
910 }
911 dst += dstskip;
912 }
913 }
914 break;
915
916 case 4:
917 {
918 Uint32 *dst;
919 int dstskip;
920
921 dst = (Uint32 *) screen->pixels +
922 (SDL_cursor->area.y + area->y) * screen->pitch / 4 +
923 SDL_cursor->area.x;
924 dstskip = (screen->pitch / 4) - area->w;
925
926 for (h = area->h; h; h--) {
927 for (w = area->w / 8; w; w--) {
928 maskb = *mask++;
929 datab = *data++;
930 for (i = 0; i < 8; ++i) {
931 if (maskb & 0x80) {
932 *dst = pixels[datab >> 7];
933 }
934 maskb <<= 1;
935 datab <<= 1;
936 dst++;
937 }
938 }
939 dst += dstskip;
940 }
941 }
942 break;
943 }
944 }
945
946 static void
947 SDL_DrawCursorSlow(SDL_Surface * screen, SDL_Rect * area)
948 {
949 const Uint32 pixels[2] = { 0xFFFFFF, 0x000000 };
950 int h;
951 int x, minx, maxx;
952 Uint8 *data, datab = 0;
953 Uint8 *mask, maskb = 0;
954 Uint8 *dst;
955 int dstbpp, dstskip;
956
957 data = SDL_cursor->data + area->y * SDL_cursor->area.w / 8;
958 mask = SDL_cursor->mask + area->y * SDL_cursor->area.w / 8;
959 dstbpp = screen->format->BytesPerPixel;
960 dst = (Uint8 *) screen->pixels +
961 (SDL_cursor->area.y + area->y) * screen->pitch +
962 SDL_cursor->area.x * dstbpp;
963 dstskip = screen->pitch - SDL_cursor->area.w * dstbpp;
964
965 minx = area->x;
966 maxx = area->x + area->w;
967 if (screen->format->BytesPerPixel == 1) {
968 if (palette_changed) {
969 pixels8[0] = (Uint8) SDL_MapRGB(screen->format, 255, 255, 255);
970 pixels8[1] = (Uint8) SDL_MapRGB(screen->format, 0, 0, 0);
971 palette_changed = 0;
972 }
973 for (h = area->h; h; h--) {
974 for (x = 0; x < SDL_cursor->area.w; ++x) {
975 if ((x % 8) == 0) {
976 maskb = *mask++;
977 datab = *data++;
978 }
979 if ((x >= minx) && (x < maxx)) {
980 if (maskb & 0x80) {
981 SDL_memset(dst, pixels8[datab >> 7], dstbpp);
982 }
983 }
984 maskb <<= 1;
985 datab <<= 1;
986 dst += dstbpp;
987 }
988 dst += dstskip;
989 }
990 } else {
991 for (h = area->h; h; h--) {
992 for (x = 0; x < SDL_cursor->area.w; ++x) {
993 if ((x % 8) == 0) {
994 maskb = *mask++;
995 datab = *data++;
996 }
997 if ((x >= minx) && (x < maxx)) {
998 if (maskb & 0x80) {
999 SDL_memset(dst, pixels[datab >> 7], dstbpp);
1000 }
1001 }
1002 maskb <<= 1;
1003 datab <<= 1;
1004 dst += dstbpp;
1005 }
1006 dst += dstskip;
1007 }
1008 }
1009 }
1010
1011 /* This handles the ugly work of converting the saved cursor background from
1012 the pixel format of the shadow surface to that of the video surface.
1013 This is only necessary when blitting from a shadow surface of a different
1014 pixel format than the video surface, and using a software rendered cursor.
1015 */
1016 static void
1017 SDL_ConvertCursorSave(SDL_Surface * screen, int w, int h)
1018 {
1019 SDL_VideoDevice *_this = SDL_GetVideoDevice();
1020 SDL_BlitInfo info;
1021 SDL_loblit RunBlit;
1022
1023 /* Make sure we can steal the blit mapping */
1024 if (screen->map->dst != SDL_VideoSurface) {
1025 return;
1026 }
1027
1028 /* Set up the blit information */
1029 info.s_pixels = SDL_cursor->save[1];
1030 info.s_width = w;
1031 info.s_height = h;
1032 info.s_skip = 0;
1033 info.d_pixels = SDL_cursor->save[0];
1034 info.d_width = w;
1035 info.d_height = h;
1036 info.d_skip = 0;
1037 info.aux_data = screen->map->sw_data->aux_data;
1038 info.src = screen->format;
1039 info.table = screen->map->table;
1040 info.dst = SDL_VideoSurface->format;
1041 RunBlit = screen->map->sw_data->blit;
1042
1043 /* Run the actual software blit */
1044 RunBlit(&info);
1045 }
1046
1047 void
1048 SDL_DrawCursorNoLock(SDL_Surface * screen)
1049 {
1050 SDL_VideoDevice *_this = SDL_GetVideoDevice();
1051 SDL_Rect area;
1052
1053 /* Get the mouse rectangle, clipped to the screen */
1054 SDL_MouseRect(&area);
1055 if ((area.w == 0) || (area.h == 0)) {
1056 return;
1057 }
1058
1059 /* Copy mouse background */
1060 {
1061 int w, h, screenbpp;
1062 Uint8 *src, *dst;
1063
1064 /* Set up the copy pointers */
1065 screenbpp = screen->format->BytesPerPixel;
1066 if ((screen == SDL_VideoSurface) ||
1067 FORMAT_EQUAL(screen->format, SDL_VideoSurface->format)) {
1068 dst = SDL_cursor->save[0];
1069 } else {
1070 dst = SDL_cursor->save[1];
1071 }
1072 src = (Uint8 *) screen->pixels + area.y * screen->pitch +
1073 area.x * screenbpp;
1074
1075 /* Perform the copy */
1076 w = area.w * screenbpp;
1077 h = area.h;
1078 while (h--) {
1079 SDL_memcpy(dst, src, w);
1080 dst += w;
1081 src += screen->pitch;
1082 }
1083 }
1084
1085 /* Draw the mouse cursor */
1086 area.x -= SDL_cursor->area.x;
1087 area.y -= SDL_cursor->area.y;
1088 if ((area.x == 0) && (area.w == SDL_cursor->area.w)) {
1089 SDL_DrawCursorFast(screen, &area);
1090 } else {
1091 SDL_DrawCursorSlow(screen, &area);
1092 }
1093 }
1094
1095 void
1096 SDL_DrawCursor(SDL_Surface * screen)
1097 {
1098 /* Lock the screen if necessary */
1099 if (screen == NULL) {
1100 return;
1101 }
1102 if (SDL_MUSTLOCK(screen)) {
1103 if (SDL_LockSurface(screen) < 0) {
1104 return;
1105 }
1106 }
1107
1108 SDL_DrawCursorNoLock(screen);
1109
1110 /* Unlock the screen and update if necessary */
1111 if (SDL_MUSTLOCK(screen)) {
1112 SDL_UnlockSurface(screen);
1113 }
1114 if ((screen->flags & SDL_SCREEN_SURFACE) &&
1115 !(screen->flags & SDL_HWSURFACE)) {
1116 SDL_VideoDevice *_this = SDL_GetVideoDevice();
1117 SDL_Window *window;
1118 SDL_Rect area;
1119
1120 window = SDL_GetWindowFromSurface(screen);
1121 if (!window) {
1122 return;
1123 }
1124
1125 SDL_MouseRect(&area);
1126
1127 if (_this->UpdateWindowSurface) {
1128 _this->UpdateWindowSurface(_this, window, 1, &area);
1129 }
1130 }
1131 }
1132
1133 void
1134 SDL_EraseCursorNoLock(SDL_Surface * screen)
1135 {
1136 SDL_VideoDevice *_this = SDL_GetVideoDevice();
1137 SDL_Window *window;
1138 SDL_Rect area;
1139
1140 /* Get the window associated with the surface */
1141 window = SDL_GetWindowFromSurface(screen);
1142 if (!window || !window->surface) {
1143 return;
1144 }
1145
1146 /* Get the mouse rectangle, clipped to the screen */
1147 SDL_MouseRect(&area);
1148 if ((area.w == 0) || (area.h == 0)) {
1149 return;
1150 }
1151
1152 /* Copy mouse background */
1153 {
1154 int w, h, screenbpp;
1155 Uint8 *src, *dst;
1156
1157 /* Set up the copy pointers */
1158 screenbpp = screen->format->BytesPerPixel;
1159 if ((screen->flags & SDL_SCREEN_SURFACE) ||
1160 FORMAT_EQUAL(screen->format, window->surface->format)) {
1161 src = SDL_cursor->save[0];
1162 } else {
1163 src = SDL_cursor->save[1];
1164 }
1165 dst = (Uint8 *) screen->pixels + area.y * screen->pitch +
1166 area.x * screenbpp;
1167
1168 /* Perform the copy */
1169 w = area.w * screenbpp;
1170 h = area.h;
1171 while (h--) {
1172 SDL_memcpy(dst, src, w);
1173 src += w;
1174 dst += screen->pitch;
1175 }
1176
1177 /* Perform pixel conversion on cursor background */
1178 if (src > SDL_cursor->save[1]) {
1179 SDL_ConvertCursorSave(screen, area.w, area.h);
1180 }
1181 }
1182 }
1183
1184 void
1185 SDL_EraseCursor(SDL_Surface * screen)
1186 {
1187 /* Lock the screen if necessary */
1188 if (screen == NULL) {
1189 return;
1190 }
1191 if (SDL_MUSTLOCK(screen)) {
1192 if (SDL_LockSurface(screen) < 0) {
1193 return;
1194 }
1195 }
1196
1197 SDL_EraseCursorNoLock(screen);
1198
1199 /* Unlock the screen and update if necessary */
1200 if (SDL_MUSTLOCK(screen)) {
1201 SDL_UnlockSurface(screen);
1202 }
1203 if ((screen->flags & SDL_SCREEN_SURFACE) &&
1204 !(screen->flags & SDL_HWSURFACE)) {
1205 SDL_VideoDevice *_this = SDL_GetVideoDevice();
1206 SDL_Window *window;
1207 SDL_Rect area;
1208
1209 window = SDL_GetWindowFromSurface(screen);
1210 if (!window) {
1211 return;
1212 }
1213
1214 SDL_MouseRect(&area);
1215
1216 if (_this->UpdateWindowSurface) {
1217 _this->UpdateWindowSurface(_this, window, 1, &area);
1218 }
1219 }
1220 }
1221
1222 /* Reset the cursor on video mode change
1223 FIXME: Keep track of all cursors, and reset them all.
1224 */
1225 void
1226 SDL_ResetCursor(void)
1227 {
1228 int savelen;
1229
1230 if (SDL_cursor) {
1231 savelen = SDL_cursor->area.w * 4 * SDL_cursor->area.h;
1232 SDL_cursor->area.x = 0;
1233 SDL_cursor->area.y = 0;
1234 SDL_memset(SDL_cursor->save[0], 0, savelen);
1235 }
1236 }
1237
395 /* vi: set ts=4 sw=4 expandtab: */ 1238 /* vi: set ts=4 sw=4 expandtab: */