#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_HAIKU
#include <AppKit.h>
#include <InterfaceKit.h>
#include "SDL_bmodes.h"
#include "SDL_BWin.h"
#if SDL_VIDEO_OPENGL
#include "SDL_bopengl.h"
#endif
#include "../../main/haiku/SDL_BApp.h"
#ifdef __cplusplus
extern "C" {
#endif
#define WRAP_BMODE 1
#if WRAP_BMODE
struct SDL_DisplayModeData {
display_mode *bmode;
};
#endif
static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) {
return ((SDL_BWin*)(window->driverdata));
}
static SDL_INLINE SDL_BApp *_GetBeApp() {
return ((SDL_BApp*)be_app);
}
static SDL_INLINE display_mode * _ExtractBMode(SDL_DisplayMode *mode) {
#if WRAP_BMODE
return ((SDL_DisplayModeData*)mode->driverdata)->bmode;
#else
return (display_mode*)(mode->driverdata);
#endif
}
static float get_refresh_rate(display_mode &mode) {
return float(mode.timing.pixel_clock * 1000)
/ float(mode.timing.h_total * mode.timing.v_total);
}
#if 0#endif
int32 HAIKU_ColorSpaceToSDLPxFormat(uint32 colorspace)
{
switch (colorspace) {
case B_CMAP8:
return SDL_PIXELFORMAT_INDEX8;
break;
case B_RGB15:
case B_RGBA15:
case B_RGB15_BIG:
case B_RGBA15_BIG:
return SDL_PIXELFORMAT_RGB555;
break;
case B_RGB16:
case B_RGB16_BIG:
return SDL_PIXELFORMAT_RGB565;
break;
case B_RGB24:
case B_RGB24_BIG:
return SDL_PIXELFORMAT_BGR24;
break;
case B_RGB32:
case B_RGBA32:
case B_RGB32_BIG:
case B_RGBA32_BIG:
return SDL_PIXELFORMAT_RGB888;
break;
}
SDL_SetError("Invalid color space");
return 0;
}
static void _BDisplayModeToSdlDisplayMode(display_mode *bmode,
SDL_DisplayMode *mode) {
mode->w = bmode->virtual_width;
mode->h = bmode->virtual_height;
mode->refresh_rate = (int)get_refresh_rate(*bmode);
#if WRAP_BMODE
SDL_DisplayModeData *data = (SDL_DisplayModeData*)SDL_calloc(1,
sizeof(SDL_DisplayModeData));
data->bmode = bmode;
mode->driverdata = data;
#else
mode->driverdata = bmode;
#endif
mode->format = HAIKU_ColorSpaceToSDLPxFormat(bmode->space);
}
static void _AddDisplay(BScreen *screen) {
SDL_VideoDisplay display;
SDL_DisplayMode *mode = (SDL_DisplayMode*)SDL_calloc(1,
sizeof(SDL_DisplayMode));
display_mode *bmode = (display_mode*)SDL_calloc(1, sizeof(display_mode));
screen->GetMode(bmode);
_BDisplayModeToSdlDisplayMode(bmode, mode);
SDL_zero(display);
display.desktop_mode = *mode;
display.current_mode = *mode;
SDL_AddVideoDisplay(&display, SDL_FALSE);
}
int HAIKU_InitModes(_THIS) {
BScreen screen;
_AddDisplay(&screen);
return 0;
}
int HAIKU_QuitModes(_THIS) {
return 0;
}
int HAIKU_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect) {
BScreen bscreen;
BRect rc = bscreen.Frame();
rect->x = (int)rc.left;
rect->y = (int)rc.top;
rect->w = (int)rc.Width() + 1;
rect->h = (int)rc.Height() + 1;
return 0;
}
void HAIKU_GetDisplayModes(_THIS, SDL_VideoDisplay *display) {
BScreen bscreen;
SDL_DisplayMode mode;
display_mode this_bmode;
display_mode *bmodes;
uint32 count, i;
bscreen.GetModeList(&bmodes, &count);
bscreen.GetMode(&this_bmode);
for(i = 0; i < count; ++i) {
if (bmodes[i].space == this_bmode.space) {
_BDisplayModeToSdlDisplayMode(&bmodes[i], &mode);
SDL_AddDisplayMode(display, &mode);
}
}
free(bmodes);
}
int HAIKU_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode){
BScreen bscreen;
if(!bscreen.IsValid()) {
printf(__FILE__": %d - ERROR: BAD SCREEN\n", __LINE__);
}
display_mode *bmode = _ExtractBMode(mode);
uint32 c = 0, i;
display_mode *bmode_list;
bscreen.GetModeList(&bmode_list, &c);
for(i = 0; i < c; ++i) {
if( bmode_list[i].space == bmode->space &&
bmode_list[i].virtual_width == bmode->virtual_width &&
bmode_list[i].virtual_height == bmode->virtual_height ) {
bmode = &bmode_list[i];
break;
}
}
if(bscreen.SetMode(bmode) != B_OK) {
return SDL_SetError("Bad video mode");
}
free(bmode_list);
#if SDL_VIDEO_OPENGL
#endif
return 0;
}
#ifdef __cplusplus
}
#endif
#endif