src/video/haiku/SDL_bmodes.cc
author Ryan C. Gordon <icculus@icculus.org>
Tue, 07 Aug 2018 18:07:11 -0400
changeset 12082 09999a0e8f9a
parent 11811 5d94cb6b24d3
child 12201 8bdc4d340419
permissions -rw-r--r--
haiku: Rename internal functions from BE_* to HAIKU_*

Fixes Bugzilla #2349.
nathanheisey@5918
     1
/*
nathanheisey@5918
     2
  Simple DirectMedia Layer
slouken@11811
     3
  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
nathanheisey@5918
     4
nathanheisey@5918
     5
  This software is provided 'as-is', without any express or implied
nathanheisey@5918
     6
  warranty.  In no event will the authors be held liable for any damages
nathanheisey@5918
     7
  arising from the use of this software.
nathanheisey@5918
     8
nathanheisey@5918
     9
  Permission is granted to anyone to use this software for any purpose,
nathanheisey@5918
    10
  including commercial applications, and to alter it and redistribute it
nathanheisey@5918
    11
  freely, subject to the following restrictions:
nathanheisey@5918
    12
nathanheisey@5918
    13
  1. The origin of this software must not be misrepresented; you must not
nathanheisey@5918
    14
     claim that you wrote the original software. If you use this software
nathanheisey@5918
    15
     in a product, an acknowledgment in the product documentation would be
nathanheisey@5918
    16
     appreciated but is not required.
nathanheisey@5918
    17
  2. Altered source versions must be plainly marked as such, and must not be
nathanheisey@5918
    18
     misrepresented as being the original software.
nathanheisey@5918
    19
  3. This notice may not be removed or altered from any source distribution.
nathanheisey@5918
    20
*/
icculus@8093
    21
#include "../../SDL_internal.h"
nathanheisey@5918
    22
icculus@7981
    23
#if SDL_VIDEO_DRIVER_HAIKU
nathanheisey@5921
    24
nathanheisey@5921
    25
#include <AppKit.h>
nathanheisey@5921
    26
#include <InterfaceKit.h>
nathanheisey@5921
    27
#include "SDL_bmodes.h"
nathanheisey@5922
    28
#include "SDL_BWin.h"
nathanheisey@5921
    29
nathanheisey@5938
    30
#if SDL_VIDEO_OPENGL
nathanheisey@5938
    31
#include "SDL_bopengl.h"
nathanheisey@5938
    32
#endif
nathanheisey@5938
    33
icculus@7981
    34
#include "../../main/haiku/SDL_BApp.h"
nathanheisey@5921
    35
nathanheisey@5921
    36
#ifdef __cplusplus
nathanheisey@5921
    37
extern "C" {
nathanheisey@5921
    38
#endif
nathanheisey@5921
    39
nathanheisey@5938
    40
nathanheisey@5939
    41
#define WRAP_BMODE 1 /* FIXME: Some debate as to whether this is necessary */
nathanheisey@5938
    42
nathanheisey@5938
    43
#if WRAP_BMODE
nathanheisey@5939
    44
/* This wrapper is here so that the driverdata can be freed without freeing
nathanheisey@5939
    45
   the display_mode structure */
icculus@11198
    46
struct SDL_DisplayModeData {
nathanheisey@5926
    47
	display_mode *bmode;
nathanheisey@5926
    48
};
nathanheisey@5937
    49
#endif
nathanheisey@5926
    50
slouken@7860
    51
static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) {
nathanheisey@5922
    52
	return ((SDL_BWin*)(window->driverdata));
nathanheisey@5922
    53
}
nathanheisey@5921
    54
slouken@7860
    55
static SDL_INLINE SDL_BApp *_GetBeApp() {
nathanheisey@5921
    56
	return ((SDL_BApp*)be_app);
nathanheisey@5921
    57
}
nathanheisey@5921
    58
slouken@7860
    59
static SDL_INLINE display_mode * _ExtractBMode(SDL_DisplayMode *mode) {
nathanheisey@5939
    60
#if WRAP_BMODE
nathanheisey@5939
    61
	return ((SDL_DisplayModeData*)mode->driverdata)->bmode;
nathanheisey@5939
    62
#else
nathanheisey@5937
    63
	return (display_mode*)(mode->driverdata);
nathanheisey@5937
    64
#endif
nathanheisey@5937
    65
}
nathanheisey@5921
    66
nathanheisey@5921
    67
/* Copied from haiku/trunk/src/preferences/screen/ScreenMode.cpp */
nathanheisey@5921
    68
static float get_refresh_rate(display_mode &mode) {
nathanheisey@5923
    69
	return float(mode.timing.pixel_clock * 1000)
nathanheisey@5923
    70
		/ float(mode.timing.h_total * mode.timing.v_total);
nathanheisey@5921
    71
}
nathanheisey@5921
    72
nathanheisey@5939
    73
nathanheisey@5939
    74
#if 0
nathanheisey@5939
    75
/* TODO:
nathanheisey@5939
    76
 * This is a useful debugging tool.  Uncomment and insert into code as needed.
nathanheisey@5939
    77
 */
nathanheisey@5939
    78
void _SpoutModeData(display_mode *bmode) {
nathanheisey@5939
    79
	printf("BMode:\n");
nathanheisey@5939
    80
	printf("\tw,h = (%i,%i)\n", bmode->virtual_width, bmode->virtual_height);
nathanheisey@5939
    81
	printf("\th,v = (%i,%i)\n", bmode->h_display_start, 
nathanheisey@5939
    82
			bmode->v_display_start);
nathanheisey@5939
    83
	if(bmode->flags) {
nathanheisey@5939
    84
		printf("\tFlags:\n");
nathanheisey@5939
    85
		if(bmode->flags & B_SCROLL) {
nathanheisey@5939
    86
			printf("\t\tB_SCROLL\n");
nathanheisey@5939
    87
		}
nathanheisey@5939
    88
		if(bmode->flags & B_8_BIT_DAC) {
nathanheisey@5939
    89
			printf("\t\tB_8_BIT_DAC\n");
nathanheisey@5939
    90
		}
nathanheisey@5939
    91
		if(bmode->flags & B_HARDWARE_CURSOR) {
nathanheisey@5939
    92
			printf("\t\tB_HARDWARE_CURSOR\n");
nathanheisey@5939
    93
		}
nathanheisey@5939
    94
		if(bmode->flags & B_PARALLEL_ACCESS) {
nathanheisey@5939
    95
			printf("\t\tB_PARALLEL_ACCESS\n");
nathanheisey@5939
    96
		}
nathanheisey@5939
    97
		if(bmode->flags & B_DPMS) {
nathanheisey@5939
    98
			printf("\t\tB_DPMS\n");
nathanheisey@5939
    99
		}
nathanheisey@5939
   100
		if(bmode->flags & B_IO_FB_NA) {
nathanheisey@5939
   101
			printf("\t\tB_IO_FB_NA\n");
nathanheisey@5939
   102
		}
nathanheisey@5939
   103
	}
nathanheisey@5939
   104
	printf("\tTiming:\n");
nathanheisey@5939
   105
	printf("\t\tpx clock: %i\n", bmode->timing.pixel_clock);
nathanheisey@5939
   106
	printf("\t\th - display: %i sync start: %i sync end: %i total: %i\n",
nathanheisey@5939
   107
		bmode->timing.h_display, bmode->timing.h_sync_start,
nathanheisey@5939
   108
		bmode->timing.h_sync_end, bmode->timing.h_total);
nathanheisey@5939
   109
	printf("\t\tv - display: %i sync start: %i sync end: %i total: %i\n",
nathanheisey@5939
   110
		bmode->timing.v_display, bmode->timing.v_sync_start,
nathanheisey@5939
   111
		bmode->timing.v_sync_end, bmode->timing.v_total);
nathanheisey@5939
   112
	if(bmode->timing.flags) {
nathanheisey@5939
   113
		printf("\t\tFlags:\n");
nathanheisey@5939
   114
		if(bmode->timing.flags & B_BLANK_PEDESTAL) {
nathanheisey@5939
   115
			printf("\t\t\tB_BLANK_PEDESTAL\n");
nathanheisey@5939
   116
		}
nathanheisey@5939
   117
		if(bmode->timing.flags & B_TIMING_INTERLACED) {
nathanheisey@5939
   118
			printf("\t\t\tB_TIMING_INTERLACED\n");
nathanheisey@5939
   119
		}
nathanheisey@5939
   120
		if(bmode->timing.flags & B_POSITIVE_HSYNC) {
nathanheisey@5939
   121
			printf("\t\t\tB_POSITIVE_HSYNC\n");
nathanheisey@5939
   122
		}
nathanheisey@5939
   123
		if(bmode->timing.flags & B_POSITIVE_VSYNC) {
nathanheisey@5939
   124
			printf("\t\t\tB_POSITIVE_VSYNC\n");
nathanheisey@5939
   125
		}
nathanheisey@5939
   126
		if(bmode->timing.flags & B_SYNC_ON_GREEN) {
nathanheisey@5939
   127
			printf("\t\t\tB_SYNC_ON_GREEN\n");
nathanheisey@5939
   128
		}
nathanheisey@5939
   129
	}
nathanheisey@5939
   130
}
nathanheisey@5939
   131
#endif
nathanheisey@5939
   132
nathanheisey@5939
   133
nathanheisey@5939
   134
icculus@12082
   135
int32 HAIKU_ColorSpaceToBitsPerPixel(uint32 colorspace)
nathanheisey@5921
   136
{
nathanheisey@5921
   137
	int bitsperpixel;
nathanheisey@5921
   138
nathanheisey@5921
   139
	bitsperpixel = 0;
nathanheisey@5921
   140
	switch (colorspace) {
nathanheisey@5921
   141
	    case B_CMAP8:
nathanheisey@5921
   142
		bitsperpixel = 8;
nathanheisey@5921
   143
		break;
nathanheisey@5921
   144
	    case B_RGB15:
nathanheisey@5921
   145
	    case B_RGBA15:
nathanheisey@5921
   146
	    case B_RGB15_BIG:
nathanheisey@5921
   147
	    case B_RGBA15_BIG:
nathanheisey@5921
   148
		bitsperpixel = 15;
nathanheisey@5921
   149
		break;
nathanheisey@5921
   150
	    case B_RGB16:
nathanheisey@5921
   151
	    case B_RGB16_BIG:
nathanheisey@5921
   152
		bitsperpixel = 16;
nathanheisey@5921
   153
		break;
nathanheisey@5921
   154
	    case B_RGB32:
nathanheisey@5921
   155
	    case B_RGBA32:
nathanheisey@5921
   156
	    case B_RGB32_BIG:
nathanheisey@5921
   157
	    case B_RGBA32_BIG:
nathanheisey@5921
   158
		bitsperpixel = 32;
nathanheisey@5921
   159
		break;
nathanheisey@5921
   160
	    default:
nathanheisey@5921
   161
		break;
nathanheisey@5921
   162
	}
nathanheisey@5921
   163
	return(bitsperpixel);
nathanheisey@5921
   164
}
nathanheisey@5921
   165
icculus@12082
   166
int32 HAIKU_BPPToSDLPxFormat(int32 bpp) {
nathanheisey@5921
   167
	/* Translation taken from SDL_windowsmodes.c */
nathanheisey@5921
   168
	switch (bpp) {
nathanheisey@5921
   169
	case 32:
nathanheisey@5921
   170
		return SDL_PIXELFORMAT_RGB888;
nathanheisey@5921
   171
		break;
nathanheisey@5921
   172
	case 24:	/* May not be supported by Haiku */
nathanheisey@5921
   173
		return SDL_PIXELFORMAT_RGB24;
nathanheisey@5921
   174
		break;
nathanheisey@5921
   175
	case 16:
nathanheisey@5921
   176
		return SDL_PIXELFORMAT_RGB565;
nathanheisey@5921
   177
		break;
nathanheisey@5921
   178
	case 15:
nathanheisey@5921
   179
		return SDL_PIXELFORMAT_RGB555;
nathanheisey@5921
   180
		break;
nathanheisey@5921
   181
	case 8:
nathanheisey@5921
   182
		return SDL_PIXELFORMAT_INDEX8;
nathanheisey@5921
   183
		break;
nathanheisey@5921
   184
	case 4:		/* May not be supported by Haiku */
nathanheisey@5921
   185
		return SDL_PIXELFORMAT_INDEX4LSB;
nathanheisey@5921
   186
		break;
nathanheisey@5921
   187
	}
aschiffler@6037
   188
aschiffler@6037
   189
	/* May never get here, but safer and needed to shut up compiler */
aschiffler@6037
   190
	SDL_SetError("Invalid bpp value");
aschiffler@6037
   191
	return 0;       
nathanheisey@5921
   192
}
nathanheisey@5921
   193
nathanheisey@5940
   194
static void _BDisplayModeToSdlDisplayMode(display_mode *bmode,
nathanheisey@5921
   195
		SDL_DisplayMode *mode) {
nathanheisey@5921
   196
	mode->w = bmode->virtual_width;
nathanheisey@5921
   197
	mode->h = bmode->virtual_height;
nathanheisey@5921
   198
	mode->refresh_rate = (int)get_refresh_rate(*bmode);
nathanheisey@5939
   199
nathanheisey@5938
   200
#if WRAP_BMODE
nathanheisey@5939
   201
	SDL_DisplayModeData *data = (SDL_DisplayModeData*)SDL_calloc(1,
nathanheisey@5939
   202
		sizeof(SDL_DisplayModeData));
nathanheisey@5926
   203
	data->bmode = bmode;
nathanheisey@5937
   204
	
nathanheisey@5926
   205
	mode->driverdata = data;
nathanheisey@5939
   206
nathanheisey@5937
   207
#else
nathanheisey@5939
   208
nathanheisey@5937
   209
	mode->driverdata = bmode;
nathanheisey@5937
   210
#endif
nathanheisey@5921
   211
nathanheisey@5921
   212
	/* Set the format */
icculus@12082
   213
	int32 bpp = HAIKU_ColorSpaceToBitsPerPixel(bmode->space);
icculus@12082
   214
	mode->format = HAIKU_BPPToSDLPxFormat(bpp);
nathanheisey@5921
   215
}
nathanheisey@5921
   216
nathanheisey@5921
   217
/* Later, there may be more than one monitor available */
nathanheisey@5940
   218
static void _AddDisplay(BScreen *screen) {
nathanheisey@5921
   219
	SDL_VideoDisplay display;
nathanheisey@5939
   220
	SDL_DisplayMode *mode = (SDL_DisplayMode*)SDL_calloc(1,
nathanheisey@5939
   221
		sizeof(SDL_DisplayMode));
nathanheisey@5937
   222
	display_mode *bmode = (display_mode*)SDL_calloc(1, sizeof(display_mode));
nathanheisey@5937
   223
	screen->GetMode(bmode);
nathanheisey@5921
   224
nathanheisey@5939
   225
	_BDisplayModeToSdlDisplayMode(bmode, mode);
nathanheisey@5921
   226
	
nathanheisey@5921
   227
	SDL_zero(display);
nathanheisey@5925
   228
	display.desktop_mode = *mode;
nathanheisey@5925
   229
	display.current_mode = *mode;
nathanheisey@5937
   230
	
nathanheisey@5921
   231
	SDL_AddVideoDisplay(&display);
nathanheisey@5921
   232
}
nathanheisey@5918
   233
nathanheisey@5939
   234
/*
nathanheisey@5939
   235
 * Functions called by SDL
nathanheisey@5939
   236
 */
nathanheisey@5939
   237
icculus@12082
   238
int HAIKU_InitModes(_THIS) {
nathanheisey@5921
   239
	BScreen screen;
nathanheisey@5918
   240
nathanheisey@5939
   241
	/* TODO: When Haiku supports multiple display screens, call
nathanheisey@5939
   242
	   _AddDisplayScreen() for each of them. */
nathanheisey@5939
   243
	_AddDisplay(&screen);
aschiffler@6037
   244
	return 0;
nathanheisey@5918
   245
}
nathanheisey@5918
   246
icculus@12082
   247
int HAIKU_QuitModes(_THIS) {
nathanheisey@5939
   248
	/* FIXME: Nothing really needs to be done here at the moment? */
nathanheisey@5921
   249
	return 0;
nathanheisey@5921
   250
}
nathanheisey@5921
   251
nathanheisey@5921
   252
icculus@12082
   253
int HAIKU_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect) {
nathanheisey@5921
   254
	BScreen bscreen;
nathanheisey@5921
   255
	BRect rc = bscreen.Frame();
nathanheisey@5921
   256
	rect->x = (int)rc.left;
nathanheisey@5921
   257
	rect->y = (int)rc.top;
nathanheisey@5921
   258
	rect->w = (int)rc.Width() + 1;
nathanheisey@5921
   259
	rect->h = (int)rc.Height() + 1;
nathanheisey@5921
   260
	return 0;
nathanheisey@5921
   261
}
nathanheisey@5921
   262
icculus@12082
   263
void HAIKU_GetDisplayModes(_THIS, SDL_VideoDisplay *display) {
nathanheisey@5921
   264
	/* Get the current screen */
nathanheisey@5921
   265
	BScreen bscreen;
nathanheisey@5925
   266
nathanheisey@5921
   267
	/* Iterate through all of the modes */
nathanheisey@5921
   268
	SDL_DisplayMode mode;
nathanheisey@5921
   269
	display_mode this_bmode;
nathanheisey@5921
   270
	display_mode *bmodes;
nathanheisey@5921
   271
	uint32 count, i;
nathanheisey@5921
   272
	
nathanheisey@5921
   273
	/* Get graphics-hardware supported modes */
nathanheisey@5921
   274
	bscreen.GetModeList(&bmodes, &count);
nathanheisey@5921
   275
	bscreen.GetMode(&this_bmode);
nathanheisey@5921
   276
	
nathanheisey@5921
   277
	for(i = 0; i < count; ++i) {
slouken@7191
   278
		// FIXME: Apparently there are errors with colorspace changes
nathanheisey@5921
   279
		if (bmodes[i].space == this_bmode.space) {
nathanheisey@5939
   280
			_BDisplayModeToSdlDisplayMode(&bmodes[i], &mode);
nathanheisey@5921
   281
			SDL_AddDisplayMode(display, &mode);
nathanheisey@5918
   282
		}
nathanheisey@5918
   283
	}
nathanheisey@5921
   284
	free(bmodes);
nathanheisey@5921
   285
}
nathanheisey@5918
   286
nathanheisey@5938
   287
icculus@12082
   288
int HAIKU_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode){
nathanheisey@5921
   289
	/* Get the current screen */
nathanheisey@5921
   290
	BScreen bscreen;
nathanheisey@5937
   291
	if(!bscreen.IsValid()) {
nathanheisey@5937
   292
		printf(__FILE__": %d - ERROR: BAD SCREEN\n", __LINE__);
nathanheisey@5937
   293
	}
nathanheisey@5937
   294
nathanheisey@5921
   295
	/* Set the mode using the driver data */
nathanheisey@5937
   296
	display_mode *bmode = _ExtractBMode(mode);
nathanheisey@5937
   297
nathanheisey@5938
   298
nathanheisey@5939
   299
	/* FIXME: Is the first option always going to be the right one? */
nathanheisey@5939
   300
	uint32 c = 0, i;
nathanheisey@5939
   301
	display_mode *bmode_list;
nathanheisey@5939
   302
	bscreen.GetModeList(&bmode_list, &c);
nathanheisey@5939
   303
	for(i = 0; i < c; ++i) {
nathanheisey@5939
   304
		if(	bmode_list[i].space == bmode->space &&
nathanheisey@5939
   305
			bmode_list[i].virtual_width == bmode->virtual_width &&
nathanheisey@5939
   306
			bmode_list[i].virtual_height == bmode->virtual_height ) {
nathanheisey@5938
   307
				bmode = &bmode_list[i];
nathanheisey@5939
   308
				break;
nathanheisey@5939
   309
		}
nathanheisey@5918
   310
	}
nathanheisey@5938
   311
nathanheisey@5938
   312
	if(bscreen.SetMode(bmode) != B_OK) {
philipp@10945
   313
		return SDL_SetError("Bad video mode");
nathanheisey@5937
   314
	}
nathanheisey@5940
   315
	
nathanheisey@5940
   316
	free(bmode_list);
nathanheisey@5938
   317
	
nathanheisey@5938
   318
#if SDL_VIDEO_OPENGL
nathanheisey@5939
   319
	/* FIXME: Is there some way to reboot the OpenGL context?  This doesn't
nathanheisey@5939
   320
	   help */
icculus@12082
   321
//	HAIKU_GL_RebootContexts(_this);
nathanheisey@5938
   322
#endif
nathanheisey@5938
   323
nathanheisey@5938
   324
	return 0;
nathanheisey@5921
   325
}
nathanheisey@5921
   326
nathanheisey@5921
   327
#ifdef __cplusplus
nathanheisey@5921
   328
}
nathanheisey@5918
   329
#endif
slouken@6044
   330
icculus@7981
   331
#endif /* SDL_VIDEO_DRIVER_HAIKU */
slouken@10690
   332
slouken@10690
   333
/* vi: set ts=4 sw=4 expandtab: */