src/video/haiku/SDL_bmodes.cc
changeset 12201 8bdc4d340419
parent 12082 09999a0e8f9a
child 12503 806492103856
equal deleted inserted replaced
12200:c0b17b32b95e 12201:8bdc4d340419
    42 
    42 
    43 #if WRAP_BMODE
    43 #if WRAP_BMODE
    44 /* This wrapper is here so that the driverdata can be freed without freeing
    44 /* This wrapper is here so that the driverdata can be freed without freeing
    45    the display_mode structure */
    45    the display_mode structure */
    46 struct SDL_DisplayModeData {
    46 struct SDL_DisplayModeData {
    47 	display_mode *bmode;
    47     display_mode *bmode;
    48 };
    48 };
    49 #endif
    49 #endif
    50 
    50 
    51 static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) {
    51 static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) {
    52 	return ((SDL_BWin*)(window->driverdata));
    52     return ((SDL_BWin*)(window->driverdata));
    53 }
    53 }
    54 
    54 
    55 static SDL_INLINE SDL_BApp *_GetBeApp() {
    55 static SDL_INLINE SDL_BApp *_GetBeApp() {
    56 	return ((SDL_BApp*)be_app);
    56     return ((SDL_BApp*)be_app);
    57 }
    57 }
    58 
    58 
    59 static SDL_INLINE display_mode * _ExtractBMode(SDL_DisplayMode *mode) {
    59 static SDL_INLINE display_mode * _ExtractBMode(SDL_DisplayMode *mode) {
    60 #if WRAP_BMODE
    60 #if WRAP_BMODE
    61 	return ((SDL_DisplayModeData*)mode->driverdata)->bmode;
    61     return ((SDL_DisplayModeData*)mode->driverdata)->bmode;
    62 #else
    62 #else
    63 	return (display_mode*)(mode->driverdata);
    63     return (display_mode*)(mode->driverdata);
    64 #endif
    64 #endif
    65 }
    65 }
    66 
    66 
    67 /* Copied from haiku/trunk/src/preferences/screen/ScreenMode.cpp */
    67 /* Copied from haiku/trunk/src/preferences/screen/ScreenMode.cpp */
    68 static float get_refresh_rate(display_mode &mode) {
    68 static float get_refresh_rate(display_mode &mode) {
    69 	return float(mode.timing.pixel_clock * 1000)
    69     return float(mode.timing.pixel_clock * 1000)
    70 		/ float(mode.timing.h_total * mode.timing.v_total);
    70         / float(mode.timing.h_total * mode.timing.v_total);
    71 }
    71 }
    72 
    72 
    73 
    73 
    74 #if 0
    74 #if 0
    75 /* TODO:
    75 /* TODO:
    76  * This is a useful debugging tool.  Uncomment and insert into code as needed.
    76  * This is a useful debugging tool.  Uncomment and insert into code as needed.
    77  */
    77  */
    78 void _SpoutModeData(display_mode *bmode) {
    78 void _SpoutModeData(display_mode *bmode) {
    79 	printf("BMode:\n");
    79     printf("BMode:\n");
    80 	printf("\tw,h = (%i,%i)\n", bmode->virtual_width, bmode->virtual_height);
    80     printf("\tw,h = (%i,%i)\n", bmode->virtual_width, bmode->virtual_height);
    81 	printf("\th,v = (%i,%i)\n", bmode->h_display_start, 
    81     printf("\th,v = (%i,%i)\n", bmode->h_display_start, 
    82 			bmode->v_display_start);
    82             bmode->v_display_start);
    83 	if(bmode->flags) {
    83     if(bmode->flags) {
    84 		printf("\tFlags:\n");
    84         printf("\tFlags:\n");
    85 		if(bmode->flags & B_SCROLL) {
    85         if(bmode->flags & B_SCROLL) {
    86 			printf("\t\tB_SCROLL\n");
    86             printf("\t\tB_SCROLL\n");
    87 		}
    87         }
    88 		if(bmode->flags & B_8_BIT_DAC) {
    88         if(bmode->flags & B_8_BIT_DAC) {
    89 			printf("\t\tB_8_BIT_DAC\n");
    89             printf("\t\tB_8_BIT_DAC\n");
    90 		}
    90         }
    91 		if(bmode->flags & B_HARDWARE_CURSOR) {
    91         if(bmode->flags & B_HARDWARE_CURSOR) {
    92 			printf("\t\tB_HARDWARE_CURSOR\n");
    92             printf("\t\tB_HARDWARE_CURSOR\n");
    93 		}
    93         }
    94 		if(bmode->flags & B_PARALLEL_ACCESS) {
    94         if(bmode->flags & B_PARALLEL_ACCESS) {
    95 			printf("\t\tB_PARALLEL_ACCESS\n");
    95             printf("\t\tB_PARALLEL_ACCESS\n");
    96 		}
    96         }
    97 		if(bmode->flags & B_DPMS) {
    97         if(bmode->flags & B_DPMS) {
    98 			printf("\t\tB_DPMS\n");
    98             printf("\t\tB_DPMS\n");
    99 		}
    99         }
   100 		if(bmode->flags & B_IO_FB_NA) {
   100         if(bmode->flags & B_IO_FB_NA) {
   101 			printf("\t\tB_IO_FB_NA\n");
   101             printf("\t\tB_IO_FB_NA\n");
   102 		}
   102         }
   103 	}
   103     }
   104 	printf("\tTiming:\n");
   104     printf("\tTiming:\n");
   105 	printf("\t\tpx clock: %i\n", bmode->timing.pixel_clock);
   105     printf("\t\tpx clock: %i\n", bmode->timing.pixel_clock);
   106 	printf("\t\th - display: %i sync start: %i sync end: %i total: %i\n",
   106     printf("\t\th - display: %i sync start: %i sync end: %i total: %i\n",
   107 		bmode->timing.h_display, bmode->timing.h_sync_start,
   107         bmode->timing.h_display, bmode->timing.h_sync_start,
   108 		bmode->timing.h_sync_end, bmode->timing.h_total);
   108         bmode->timing.h_sync_end, bmode->timing.h_total);
   109 	printf("\t\tv - display: %i sync start: %i sync end: %i total: %i\n",
   109     printf("\t\tv - display: %i sync start: %i sync end: %i total: %i\n",
   110 		bmode->timing.v_display, bmode->timing.v_sync_start,
   110         bmode->timing.v_display, bmode->timing.v_sync_start,
   111 		bmode->timing.v_sync_end, bmode->timing.v_total);
   111         bmode->timing.v_sync_end, bmode->timing.v_total);
   112 	if(bmode->timing.flags) {
   112     if(bmode->timing.flags) {
   113 		printf("\t\tFlags:\n");
   113         printf("\t\tFlags:\n");
   114 		if(bmode->timing.flags & B_BLANK_PEDESTAL) {
   114         if(bmode->timing.flags & B_BLANK_PEDESTAL) {
   115 			printf("\t\t\tB_BLANK_PEDESTAL\n");
   115             printf("\t\t\tB_BLANK_PEDESTAL\n");
   116 		}
   116         }
   117 		if(bmode->timing.flags & B_TIMING_INTERLACED) {
   117         if(bmode->timing.flags & B_TIMING_INTERLACED) {
   118 			printf("\t\t\tB_TIMING_INTERLACED\n");
   118             printf("\t\t\tB_TIMING_INTERLACED\n");
   119 		}
   119         }
   120 		if(bmode->timing.flags & B_POSITIVE_HSYNC) {
   120         if(bmode->timing.flags & B_POSITIVE_HSYNC) {
   121 			printf("\t\t\tB_POSITIVE_HSYNC\n");
   121             printf("\t\t\tB_POSITIVE_HSYNC\n");
   122 		}
   122         }
   123 		if(bmode->timing.flags & B_POSITIVE_VSYNC) {
   123         if(bmode->timing.flags & B_POSITIVE_VSYNC) {
   124 			printf("\t\t\tB_POSITIVE_VSYNC\n");
   124             printf("\t\t\tB_POSITIVE_VSYNC\n");
   125 		}
   125         }
   126 		if(bmode->timing.flags & B_SYNC_ON_GREEN) {
   126         if(bmode->timing.flags & B_SYNC_ON_GREEN) {
   127 			printf("\t\t\tB_SYNC_ON_GREEN\n");
   127             printf("\t\t\tB_SYNC_ON_GREEN\n");
   128 		}
   128         }
   129 	}
   129     }
   130 }
   130 }
   131 #endif
   131 #endif
   132 
   132 
   133 
   133 
   134 
   134 
   135 int32 HAIKU_ColorSpaceToBitsPerPixel(uint32 colorspace)
   135 int32 HAIKU_ColorSpaceToBitsPerPixel(uint32 colorspace)
   136 {
   136 {
   137 	int bitsperpixel;
   137     int bitsperpixel;
   138 
   138 
   139 	bitsperpixel = 0;
   139     bitsperpixel = 0;
   140 	switch (colorspace) {
   140     switch (colorspace) {
   141 	    case B_CMAP8:
   141         case B_CMAP8:
   142 		bitsperpixel = 8;
   142         bitsperpixel = 8;
   143 		break;
   143         break;
   144 	    case B_RGB15:
   144         case B_RGB15:
   145 	    case B_RGBA15:
   145         case B_RGBA15:
   146 	    case B_RGB15_BIG:
   146         case B_RGB15_BIG:
   147 	    case B_RGBA15_BIG:
   147         case B_RGBA15_BIG:
   148 		bitsperpixel = 15;
   148         bitsperpixel = 15;
   149 		break;
   149         break;
   150 	    case B_RGB16:
   150         case B_RGB16:
   151 	    case B_RGB16_BIG:
   151         case B_RGB16_BIG:
   152 		bitsperpixel = 16;
   152         bitsperpixel = 16;
   153 		break;
   153         break;
   154 	    case B_RGB32:
   154         case B_RGB32:
   155 	    case B_RGBA32:
   155         case B_RGBA32:
   156 	    case B_RGB32_BIG:
   156         case B_RGB32_BIG:
   157 	    case B_RGBA32_BIG:
   157         case B_RGBA32_BIG:
   158 		bitsperpixel = 32;
   158         bitsperpixel = 32;
   159 		break;
   159         break;
   160 	    default:
   160         default:
   161 		break;
   161         break;
   162 	}
   162     }
   163 	return(bitsperpixel);
   163     return(bitsperpixel);
   164 }
   164 }
   165 
   165 
   166 int32 HAIKU_BPPToSDLPxFormat(int32 bpp) {
   166 int32 HAIKU_BPPToSDLPxFormat(int32 bpp) {
   167 	/* Translation taken from SDL_windowsmodes.c */
   167     /* Translation taken from SDL_windowsmodes.c */
   168 	switch (bpp) {
   168     switch (bpp) {
   169 	case 32:
   169     case 32:
   170 		return SDL_PIXELFORMAT_RGB888;
   170         return SDL_PIXELFORMAT_RGB888;
   171 		break;
   171         break;
   172 	case 24:	/* May not be supported by Haiku */
   172     case 24:    /* May not be supported by Haiku */
   173 		return SDL_PIXELFORMAT_RGB24;
   173         return SDL_PIXELFORMAT_RGB24;
   174 		break;
   174         break;
   175 	case 16:
   175     case 16:
   176 		return SDL_PIXELFORMAT_RGB565;
   176         return SDL_PIXELFORMAT_RGB565;
   177 		break;
   177         break;
   178 	case 15:
   178     case 15:
   179 		return SDL_PIXELFORMAT_RGB555;
   179         return SDL_PIXELFORMAT_RGB555;
   180 		break;
   180         break;
   181 	case 8:
   181     case 8:
   182 		return SDL_PIXELFORMAT_INDEX8;
   182         return SDL_PIXELFORMAT_INDEX8;
   183 		break;
   183         break;
   184 	case 4:		/* May not be supported by Haiku */
   184     case 4:        /* May not be supported by Haiku */
   185 		return SDL_PIXELFORMAT_INDEX4LSB;
   185         return SDL_PIXELFORMAT_INDEX4LSB;
   186 		break;
   186         break;
   187 	}
   187     }
   188 
   188 
   189 	/* May never get here, but safer and needed to shut up compiler */
   189     /* May never get here, but safer and needed to shut up compiler */
   190 	SDL_SetError("Invalid bpp value");
   190     SDL_SetError("Invalid bpp value");
   191 	return 0;       
   191     return 0;       
   192 }
   192 }
   193 
   193 
   194 static void _BDisplayModeToSdlDisplayMode(display_mode *bmode,
   194 static void _BDisplayModeToSdlDisplayMode(display_mode *bmode,
   195 		SDL_DisplayMode *mode) {
   195         SDL_DisplayMode *mode) {
   196 	mode->w = bmode->virtual_width;
   196     mode->w = bmode->virtual_width;
   197 	mode->h = bmode->virtual_height;
   197     mode->h = bmode->virtual_height;
   198 	mode->refresh_rate = (int)get_refresh_rate(*bmode);
   198     mode->refresh_rate = (int)get_refresh_rate(*bmode);
   199 
   199 
   200 #if WRAP_BMODE
   200 #if WRAP_BMODE
   201 	SDL_DisplayModeData *data = (SDL_DisplayModeData*)SDL_calloc(1,
   201     SDL_DisplayModeData *data = (SDL_DisplayModeData*)SDL_calloc(1,
   202 		sizeof(SDL_DisplayModeData));
   202         sizeof(SDL_DisplayModeData));
   203 	data->bmode = bmode;
   203     data->bmode = bmode;
   204 	
   204     
   205 	mode->driverdata = data;
   205     mode->driverdata = data;
   206 
   206 
   207 #else
   207 #else
   208 
   208 
   209 	mode->driverdata = bmode;
   209     mode->driverdata = bmode;
   210 #endif
   210 #endif
   211 
   211 
   212 	/* Set the format */
   212     /* Set the format */
   213 	int32 bpp = HAIKU_ColorSpaceToBitsPerPixel(bmode->space);
   213     int32 bpp = HAIKU_ColorSpaceToBitsPerPixel(bmode->space);
   214 	mode->format = HAIKU_BPPToSDLPxFormat(bpp);
   214     mode->format = HAIKU_BPPToSDLPxFormat(bpp);
   215 }
   215 }
   216 
   216 
   217 /* Later, there may be more than one monitor available */
   217 /* Later, there may be more than one monitor available */
   218 static void _AddDisplay(BScreen *screen) {
   218 static void _AddDisplay(BScreen *screen) {
   219 	SDL_VideoDisplay display;
   219     SDL_VideoDisplay display;
   220 	SDL_DisplayMode *mode = (SDL_DisplayMode*)SDL_calloc(1,
   220     SDL_DisplayMode *mode = (SDL_DisplayMode*)SDL_calloc(1,
   221 		sizeof(SDL_DisplayMode));
   221         sizeof(SDL_DisplayMode));
   222 	display_mode *bmode = (display_mode*)SDL_calloc(1, sizeof(display_mode));
   222     display_mode *bmode = (display_mode*)SDL_calloc(1, sizeof(display_mode));
   223 	screen->GetMode(bmode);
   223     screen->GetMode(bmode);
   224 
   224 
   225 	_BDisplayModeToSdlDisplayMode(bmode, mode);
   225     _BDisplayModeToSdlDisplayMode(bmode, mode);
   226 	
   226     
   227 	SDL_zero(display);
   227     SDL_zero(display);
   228 	display.desktop_mode = *mode;
   228     display.desktop_mode = *mode;
   229 	display.current_mode = *mode;
   229     display.current_mode = *mode;
   230 	
   230     
   231 	SDL_AddVideoDisplay(&display);
   231     SDL_AddVideoDisplay(&display);
   232 }
   232 }
   233 
   233 
   234 /*
   234 /*
   235  * Functions called by SDL
   235  * Functions called by SDL
   236  */
   236  */
   237 
   237 
   238 int HAIKU_InitModes(_THIS) {
   238 int HAIKU_InitModes(_THIS) {
   239 	BScreen screen;
   239     BScreen screen;
   240 
   240 
   241 	/* TODO: When Haiku supports multiple display screens, call
   241     /* TODO: When Haiku supports multiple display screens, call
   242 	   _AddDisplayScreen() for each of them. */
   242        _AddDisplayScreen() for each of them. */
   243 	_AddDisplay(&screen);
   243     _AddDisplay(&screen);
   244 	return 0;
   244     return 0;
   245 }
   245 }
   246 
   246 
   247 int HAIKU_QuitModes(_THIS) {
   247 int HAIKU_QuitModes(_THIS) {
   248 	/* FIXME: Nothing really needs to be done here at the moment? */
   248     /* FIXME: Nothing really needs to be done here at the moment? */
   249 	return 0;
   249     return 0;
   250 }
   250 }
   251 
   251 
   252 
   252 
   253 int HAIKU_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect) {
   253 int HAIKU_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect) {
   254 	BScreen bscreen;
   254     BScreen bscreen;
   255 	BRect rc = bscreen.Frame();
   255     BRect rc = bscreen.Frame();
   256 	rect->x = (int)rc.left;
   256     rect->x = (int)rc.left;
   257 	rect->y = (int)rc.top;
   257     rect->y = (int)rc.top;
   258 	rect->w = (int)rc.Width() + 1;
   258     rect->w = (int)rc.Width() + 1;
   259 	rect->h = (int)rc.Height() + 1;
   259     rect->h = (int)rc.Height() + 1;
   260 	return 0;
   260     return 0;
   261 }
   261 }
   262 
   262 
   263 void HAIKU_GetDisplayModes(_THIS, SDL_VideoDisplay *display) {
   263 void HAIKU_GetDisplayModes(_THIS, SDL_VideoDisplay *display) {
   264 	/* Get the current screen */
   264     /* Get the current screen */
   265 	BScreen bscreen;
   265     BScreen bscreen;
   266 
   266 
   267 	/* Iterate through all of the modes */
   267     /* Iterate through all of the modes */
   268 	SDL_DisplayMode mode;
   268     SDL_DisplayMode mode;
   269 	display_mode this_bmode;
   269     display_mode this_bmode;
   270 	display_mode *bmodes;
   270     display_mode *bmodes;
   271 	uint32 count, i;
   271     uint32 count, i;
   272 	
   272     
   273 	/* Get graphics-hardware supported modes */
   273     /* Get graphics-hardware supported modes */
   274 	bscreen.GetModeList(&bmodes, &count);
   274     bscreen.GetModeList(&bmodes, &count);
   275 	bscreen.GetMode(&this_bmode);
   275     bscreen.GetMode(&this_bmode);
   276 	
   276     
   277 	for(i = 0; i < count; ++i) {
   277     for(i = 0; i < count; ++i) {
   278 		// FIXME: Apparently there are errors with colorspace changes
   278         // FIXME: Apparently there are errors with colorspace changes
   279 		if (bmodes[i].space == this_bmode.space) {
   279         if (bmodes[i].space == this_bmode.space) {
   280 			_BDisplayModeToSdlDisplayMode(&bmodes[i], &mode);
   280             _BDisplayModeToSdlDisplayMode(&bmodes[i], &mode);
   281 			SDL_AddDisplayMode(display, &mode);
   281             SDL_AddDisplayMode(display, &mode);
   282 		}
   282         }
   283 	}
   283     }
   284 	free(bmodes);
   284     free(bmodes);
   285 }
   285 }
   286 
   286 
   287 
   287 
   288 int HAIKU_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode){
   288 int HAIKU_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode){
   289 	/* Get the current screen */
   289     /* Get the current screen */
   290 	BScreen bscreen;
   290     BScreen bscreen;
   291 	if(!bscreen.IsValid()) {
   291     if(!bscreen.IsValid()) {
   292 		printf(__FILE__": %d - ERROR: BAD SCREEN\n", __LINE__);
   292         printf(__FILE__": %d - ERROR: BAD SCREEN\n", __LINE__);
   293 	}
   293     }
   294 
   294 
   295 	/* Set the mode using the driver data */
   295     /* Set the mode using the driver data */
   296 	display_mode *bmode = _ExtractBMode(mode);
   296     display_mode *bmode = _ExtractBMode(mode);
   297 
   297 
   298 
   298 
   299 	/* FIXME: Is the first option always going to be the right one? */
   299     /* FIXME: Is the first option always going to be the right one? */
   300 	uint32 c = 0, i;
   300     uint32 c = 0, i;
   301 	display_mode *bmode_list;
   301     display_mode *bmode_list;
   302 	bscreen.GetModeList(&bmode_list, &c);
   302     bscreen.GetModeList(&bmode_list, &c);
   303 	for(i = 0; i < c; ++i) {
   303     for(i = 0; i < c; ++i) {
   304 		if(	bmode_list[i].space == bmode->space &&
   304         if(    bmode_list[i].space == bmode->space &&
   305 			bmode_list[i].virtual_width == bmode->virtual_width &&
   305             bmode_list[i].virtual_width == bmode->virtual_width &&
   306 			bmode_list[i].virtual_height == bmode->virtual_height ) {
   306             bmode_list[i].virtual_height == bmode->virtual_height ) {
   307 				bmode = &bmode_list[i];
   307                 bmode = &bmode_list[i];
   308 				break;
   308                 break;
   309 		}
   309         }
   310 	}
   310     }
   311 
   311 
   312 	if(bscreen.SetMode(bmode) != B_OK) {
   312     if(bscreen.SetMode(bmode) != B_OK) {
   313 		return SDL_SetError("Bad video mode");
   313         return SDL_SetError("Bad video mode");
   314 	}
   314     }
   315 	
   315     
   316 	free(bmode_list);
   316     free(bmode_list);
   317 	
   317     
   318 #if SDL_VIDEO_OPENGL
   318 #if SDL_VIDEO_OPENGL
   319 	/* FIXME: Is there some way to reboot the OpenGL context?  This doesn't
   319     /* FIXME: Is there some way to reboot the OpenGL context?  This doesn't
   320 	   help */
   320        help */
   321 //	HAIKU_GL_RebootContexts(_this);
   321 //    HAIKU_GL_RebootContexts(_this);
   322 #endif
   322 #endif
   323 
   323 
   324 	return 0;
   324     return 0;
   325 }
   325 }
   326 
   326 
   327 #ifdef __cplusplus
   327 #ifdef __cplusplus
   328 }
   328 }
   329 #endif
   329 #endif