| @@ -865,26 +865,27 @@ WsfbShadowInit(ScreenPtr pScreen) | | | @@ -865,26 +865,27 @@ WsfbShadowInit(ScreenPtr pScreen) |
865 | | | 865 | |
866 | return TRUE; | | 866 | return TRUE; |
867 | } | | 867 | } |
868 | | | 868 | |
869 | static Bool | | 869 | static Bool |
870 | WsfbScreenInit(SCREEN_INIT_ARGS_DECL) | | 870 | WsfbScreenInit(SCREEN_INIT_ARGS_DECL) |
871 | { | | 871 | { |
872 | ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; | | 872 | ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; |
873 | WsfbPtr fPtr = WSFBPTR(pScrn); | | 873 | WsfbPtr fPtr = WSFBPTR(pScrn); |
874 | VisualPtr visual; | | 874 | VisualPtr visual; |
875 | int ret, flags, ncolors; | | 875 | int ret, flags, ncolors; |
876 | int wsmode = WSDISPLAYIO_MODE_DUMBFB; | | 876 | int wsmode = WSDISPLAYIO_MODE_DUMBFB; |
877 | int wstype; | | 877 | int wstype; |
| | | 878 | int width; |
878 | size_t len; | | 879 | size_t len; |
879 | | | 880 | |
880 | TRACE_ENTER("WsfbScreenInit"); | | 881 | TRACE_ENTER("WsfbScreenInit"); |
881 | #if DEBUG | | 882 | #if DEBUG |
882 | ErrorF("\tbitsPerPixel=%d, depth=%d, defaultVisual=%s\n" | | 883 | ErrorF("\tbitsPerPixel=%d, depth=%d, defaultVisual=%s\n" |
883 | "\tmask: %x,%x,%x, offset: %u,%u,%u\n", | | 884 | "\tmask: %x,%x,%x, offset: %u,%u,%u\n", |
884 | pScrn->bitsPerPixel, | | 885 | pScrn->bitsPerPixel, |
885 | pScrn->depth, | | 886 | pScrn->depth, |
886 | xf86GetVisualName(pScrn->defaultVisual), | | 887 | xf86GetVisualName(pScrn->defaultVisual), |
887 | pScrn->mask.red,pScrn->mask.green,pScrn->mask.blue, | | 888 | pScrn->mask.red,pScrn->mask.green,pScrn->mask.blue, |
888 | pScrn->offset.red,pScrn->offset.green,pScrn->offset.blue); | | 889 | pScrn->offset.red,pScrn->offset.green,pScrn->offset.blue); |
889 | #endif | | 890 | #endif |
890 | switch (fPtr->fbi.fbi_bitsperpixel) { | | 891 | switch (fPtr->fbi.fbi_bitsperpixel) { |
| @@ -969,54 +970,79 @@ WsfbScreenInit(SCREEN_INIT_ARGS_DECL) | | | @@ -969,54 +970,79 @@ WsfbScreenInit(SCREEN_INIT_ARGS_DECL) |
969 | || fPtr->rotate == WSFB_ROTATE_CCW) { | | 970 | || fPtr->rotate == WSFB_ROTATE_CCW) { |
970 | int tmp = pScrn->virtualX; | | 971 | int tmp = pScrn->virtualX; |
971 | pScrn->virtualX = pScrn->displayWidth = pScrn->virtualY; | | 972 | pScrn->virtualX = pScrn->displayWidth = pScrn->virtualY; |
972 | pScrn->virtualY = tmp; | | 973 | pScrn->virtualY = tmp; |
973 | } | | 974 | } |
974 | if (fPtr->rotate && !fPtr->PointerMoved) { | | 975 | if (fPtr->rotate && !fPtr->PointerMoved) { |
975 | fPtr->PointerMoved = pScrn->PointerMoved; | | 976 | fPtr->PointerMoved = pScrn->PointerMoved; |
976 | pScrn->PointerMoved = WsfbPointerMoved; | | 977 | pScrn->PointerMoved = WsfbPointerMoved; |
977 | } | | 978 | } |
978 | | | 979 | |
979 | fPtr->fbstart = fPtr->fbmem + fPtr->fbi.fbi_fboffset; | | 980 | fPtr->fbstart = fPtr->fbmem + fPtr->fbi.fbi_fboffset; |
980 | | | 981 | |
981 | if (fPtr->shadowFB) { | | 982 | if (fPtr->shadowFB) { |
982 | fPtr->shadow = calloc(1, fPtr->fbi.fbi_stride * pScrn->virtualY); | | 983 | if (fPtr->rotate) { |
| | | 984 | /* |
| | | 985 | * Note Rotate and Shadow FB options are valid |
| | | 986 | * only on depth >= 8. |
| | | 987 | */ |
| | | 988 | len = pScrn->virtualX * pScrn->virtualY * |
| | | 989 | (pScrn->bitsPerPixel >> 3); |
| | | 990 | } else { |
| | | 991 | len = fPtr->fbi.fbi_stride * pScrn->virtualY; |
| | | 992 | } |
| | | 993 | fPtr->shadow = calloc(1, len); |
983 | | | 994 | |
984 | if (!fPtr->shadow) { | | 995 | if (!fPtr->shadow) { |
985 | xf86DrvMsg(pScrn->scrnIndex, X_ERROR, | | 996 | xf86DrvMsg(pScrn->scrnIndex, X_ERROR, |
986 | "Failed to allocate shadow framebuffer\n"); | | 997 | "Failed to allocate shadow framebuffer\n"); |
987 | return FALSE; | | 998 | return FALSE; |
988 | } | | 999 | } |
989 | } | | 1000 | } |
990 | | | 1001 | |
| | | 1002 | /* |
| | | 1003 | * fbScreenInit() seems to require "pixel width of frame buffer" |
| | | 1004 | * but it is actually "stride in pixel" of frame buffer, |
| | | 1005 | * per xorg/xserver/tree/fb/fbscreen.c. |
| | | 1006 | */ |
| | | 1007 | if (fPtr->rotate) { |
| | | 1008 | width = pScrn->displayWidth; |
| | | 1009 | } else { |
| | | 1010 | if (pScrn->bitsPerPixel > 8) { |
| | | 1011 | width = |
| | | 1012 | fPtr->fbi.fbi_stride / (pScrn->bitsPerPixel >> 3); |
| | | 1013 | } else { |
| | | 1014 | width = |
| | | 1015 | fPtr->fbi.fbi_stride * (8 / pScrn->bitsPerPixel); |
| | | 1016 | } |
| | | 1017 | } |
991 | switch (pScrn->bitsPerPixel) { | | 1018 | switch (pScrn->bitsPerPixel) { |
992 | case 1: | | 1019 | case 1: |
993 | ret = fbScreenInit(pScreen, | | 1020 | ret = fbScreenInit(pScreen, |
994 | fPtr->fbstart, | | 1021 | fPtr->fbstart, |
995 | pScrn->virtualX, pScrn->virtualY, | | 1022 | pScrn->virtualX, pScrn->virtualY, |
996 | pScrn->xDpi, pScrn->yDpi, | | 1023 | pScrn->xDpi, pScrn->yDpi, |
997 | fPtr->fbi.fbi_stride * 8, pScrn->bitsPerPixel); | | 1024 | width, pScrn->bitsPerPixel); |
998 | break; | | 1025 | break; |
999 | case 4: | | 1026 | case 4: |
1000 | case 8: | | 1027 | case 8: |
1001 | case 16: | | 1028 | case 16: |
1002 | case 24: | | 1029 | case 24: |
1003 | case 32: | | 1030 | case 32: |
1004 | ret = fbScreenInit(pScreen, | | 1031 | ret = fbScreenInit(pScreen, |
1005 | fPtr->shadowFB ? fPtr->shadow : fPtr->fbstart, | | 1032 | fPtr->shadowFB ? fPtr->shadow : fPtr->fbstart, |
1006 | pScrn->virtualX, pScrn->virtualY, | | 1033 | pScrn->virtualX, pScrn->virtualY, |
1007 | pScrn->xDpi, pScrn->yDpi, | | 1034 | pScrn->xDpi, pScrn->yDpi, |
1008 | /* apparently fb wants stride in pixels, not bytes */ | | 1035 | width, |
1009 | fPtr->fbi.fbi_stride / (pScrn->bitsPerPixel >> 3), | | | |
1010 | pScrn->bitsPerPixel); | | 1036 | pScrn->bitsPerPixel); |
1011 | break; | | 1037 | break; |
1012 | default: | | 1038 | default: |
1013 | xf86DrvMsg(pScrn->scrnIndex, X_ERROR, | | 1039 | xf86DrvMsg(pScrn->scrnIndex, X_ERROR, |
1014 | "Unsupported bpp: %d", pScrn->bitsPerPixel); | | 1040 | "Unsupported bpp: %d", pScrn->bitsPerPixel); |
1015 | return FALSE; | | 1041 | return FALSE; |
1016 | } /* case */ | | 1042 | } /* case */ |
1017 | | | 1043 | |
1018 | if (!ret) | | 1044 | if (!ret) |
1019 | return FALSE; | | 1045 | return FALSE; |
1020 | | | 1046 | |
1021 | if (pScrn->bitsPerPixel > 8) { | | 1047 | if (pScrn->bitsPerPixel > 8) { |
1022 | /* Fixup RGB ordering. */ | | 1048 | /* Fixup RGB ordering. */ |