* Fixed SetColorList(): it set the color table as array of rgb_colors, but it's

an array with 3 byte per color only - this fixes the page_flip demo as part of
  the sample code.
* Renamed mode2parms() to get_mode_parameter(). Also, it will now return "false"
  on unknown mode values so that SetSpace() will fail instead of setting some
  random mode.
* Cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17348 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2006-05-06 13:56:15 +00:00
parent 0e836b16bd
commit 3df31bf306

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2005,
* Copyright 2002-2006,
* Marcus Overhagen,
* Stefano Ceccherini (burton666@libero.it),
* Carwyn Jones (turok2@currantbun.com)
@ -163,107 +163,100 @@ draw_rect_32(int32 sx, int32 sy, int32 sw, int32 sh, uint32 color)
}
static void
mode2parms(uint32 space, uint32 *out_space, int32 *width, int32 *height)
/*!
Fills the \a width, \a height, and \a colorSpace parameters according
to the window screen's mode.
Returns \c true if the mode is known.
*/
static bool
get_mode_parameter(uint32 mode, int32& width, int32& height, uint32& colorSpace)
{
switch (space) {
switch (mode) {
case B_8_BIT_640x480:
*out_space = B_CMAP8;
*width = 640; *height = 480;
break;
case B_8_BIT_800x600:
*out_space = B_CMAP8;
*width = 800; *height = 600;
break;
case B_8_BIT_1024x768:
*out_space = B_CMAP8;
*width = 1024; *height = 768;
break;
case B_8_BIT_1152x900:
case B_8_BIT_1280x1024:
*out_space = B_CMAP8;
*width = 1280; *height = 1024;
break;
case B_8_BIT_1600x1200:
*out_space = B_CMAP8;
*width = 1600; *height = 1200;
colorSpace = B_CMAP8;
break;
case B_16_BIT_640x480:
*out_space = B_RGB16;
*width = 640; *height = 480;
break;
case B_16_BIT_800x600:
*out_space = B_RGB16;
*width = 800; *height = 600;
break;
case B_16_BIT_1024x768:
*out_space = B_RGB16;
*width = 1024; *height = 768;
break;
case B_16_BIT_1280x1024:
*out_space = B_RGB16;
*width = 1280; *height = 1024;
break;
case B_16_BIT_1600x1200:
*out_space = B_RGB16;
*width = 1600; *height = 1200;
break;
case B_32_BIT_640x480:
*out_space = B_RGB32;
*width = 640; *height = 480;
break;
case B_32_BIT_800x600:
*out_space = B_RGB32;
*width = 800; *height = 600;
break;
case B_32_BIT_1024x768:
*out_space = B_RGB32;
*width = 1024; *height = 768;
break;
case B_32_BIT_1280x1024:
*out_space = B_RGB32;
*width = 1280; *height = 1024;
break;
case B_32_BIT_1600x1200:
*out_space = B_RGB32;
*width = 1600; *height = 1200;
break;
case B_8_BIT_1152x900:
*out_space = B_CMAP8;
*width = 1152; *height = 900;
break;
case B_16_BIT_1152x900:
*out_space = B_RGB16;
*width = 1152; *height = 900;
break;
case B_32_BIT_1152x900:
*out_space = B_RGB32;
*width = 1152; *height = 900;
break;
case B_15_BIT_640x480:
*out_space = B_RGB15;
*width = 640; *height = 480;
break;
case B_15_BIT_800x600:
*out_space = B_RGB15;
*width = 800; *height = 600;
break;
case B_15_BIT_1024x768:
*out_space = B_RGB15;
*width = 1024; *height = 768;
break;
case B_15_BIT_1152x900:
case B_15_BIT_1280x1024:
*out_space = B_RGB15;
*width = 1280; *height = 1024;
break;
case B_15_BIT_1600x1200:
*out_space = B_RGB15;
*width = 1600; *height = 1200;
colorSpace = B_RGB15;
break;
case B_16_BIT_640x480:
case B_16_BIT_800x600:
case B_16_BIT_1024x768:
case B_16_BIT_1152x900:
case B_16_BIT_1280x1024:
case B_16_BIT_1600x1200:
colorSpace = B_RGB16;
break;
case B_15_BIT_1152x900:
*out_space = B_RGB15;
*width = 1152; *height = 900;
break;
case B_32_BIT_640x480:
case B_32_BIT_800x600:
case B_32_BIT_1024x768:
case B_32_BIT_1152x900:
case B_32_BIT_1280x1024:
case B_32_BIT_1600x1200:
colorSpace = B_RGB32;
break;
default:
return false;
}
switch (mode) {
case B_8_BIT_640x480:
case B_15_BIT_640x480:
case B_16_BIT_640x480:
case B_32_BIT_640x480:
width = 640; height = 480;
break;
case B_8_BIT_800x600:
case B_15_BIT_800x600:
case B_16_BIT_800x600:
case B_32_BIT_800x600:
width = 800; height = 600;
break;
case B_8_BIT_1024x768:
case B_15_BIT_1024x768:
case B_16_BIT_1024x768:
case B_32_BIT_1024x768:
width = 1024; height = 768;
break;
case B_8_BIT_1152x900:
case B_15_BIT_1152x900:
case B_16_BIT_1152x900:
case B_32_BIT_1152x900:
width = 1152; height = 900;
break;
case B_8_BIT_1280x1024:
case B_15_BIT_1280x1024:
case B_16_BIT_1280x1024:
case B_32_BIT_1280x1024:
width = 1280; height = 1024;
break;
case B_8_BIT_1600x1200:
case B_15_BIT_1600x1200:
case B_16_BIT_1600x1200:
case B_32_BIT_1600x1200:
width = 1600; height = 1200;
break;
}
return true;
}
@ -285,7 +278,7 @@ set_mouse_position(int32 x, int32 y)
BWindowScreen::BWindowScreen(const char *title, uint32 space,
status_t *error, bool debug_enable)
status_t *error, bool debug_enable)
: BWindow(BScreen().Frame(), title, B_TITLED_WINDOW,
kWindowScreenFlag | B_NOT_MINIMIZABLE | B_NOT_CLOSABLE
| B_NOT_ZOOMABLE | B_NOT_MOVABLE | B_NOT_RESIZABLE, B_CURRENT_WORKSPACE)
@ -302,7 +295,7 @@ BWindowScreen::BWindowScreen(const char *title, uint32 space,
BWindowScreen::BWindowScreen(const char *title, uint32 space,
uint32 attributes, status_t *error)
uint32 attributes, status_t *error)
: BWindow(BScreen().Frame(), title, B_TITLED_WINDOW,
kWindowScreenFlag | B_NOT_MINIMIZABLE | B_NOT_CLOSABLE
| B_NOT_ZOOMABLE | B_NOT_MOVABLE | B_NOT_RESIZABLE, B_CURRENT_WORKSPACE)
@ -418,37 +411,45 @@ BWindowScreen::Show()
void
BWindowScreen::SetColorList(rgb_color *list, int32 first_index, int32 last_index)
BWindowScreen::SetColorList(rgb_color *list, int32 firstIndex, int32 lastIndex)
{
CALLED();
if (first_index < 0 || last_index > 255 || first_index > last_index)
if (firstIndex < 0 || lastIndex > 255 || firstIndex > lastIndex)
return;
if (Lock()) {
if (!fActivateState) {
//If we aren't active, we just change our local palette
for (int32 x = first_index; x <= last_index; x++)
// If we aren't active, we just change our local palette
for (int32 x = firstIndex; x <= lastIndex; x++) {
fColorList[x] = list[x];
} else {
uint32 colorCount = last_index - first_index + 1;
if (fAddonImage >= 0) {
set_indexed_colors sic = (set_indexed_colors)fGetAccelerantHook(B_SET_INDEXED_COLORS, NULL);
if (sic != NULL)
sic(colorCount, first_index, (uint8 *)fColorList, 0);
}
BScreen screen(this);
screen.WaitForRetrace();
// Update our local palette too. We're doing this between two
// WaitForRetrace() calls so nobody will notice.
for (int32 x = first_index; x <= last_index; x++)
} else {
uint8 colors[3 * 256];
// the color table has 3 bytes per color
int32 j = 0;
for (int32 x = firstIndex; x <= lastIndex; x++) {
fColorList[x] = list[x];
// update our local palette as well
colors[j++] = list[x].red;
colors[j++] = list[x].green;
colors[j++] = list[x].blue;
}
if (fAddonImage >= 0) {
set_indexed_colors setIndexedColors =
(set_indexed_colors)fGetAccelerantHook(B_SET_INDEXED_COLORS, NULL);
if (setIndexedColors != NULL)
setIndexedColors(lastIndex - firstIndex + 1, firstIndex, colors, 0);
}
// TODO: Tell the app_server about our changes
BScreen screen(this);
screen.WaitForRetrace();
}
Unlock();
}
}
@ -479,7 +480,7 @@ BWindowScreen::SetFrameBuffer(int32 width, int32 height)
CALLED();
display_mode highMode = *fDisplayMode;
highMode.flags |= B_SCROLL;
highMode.virtual_height = (int16)height;
highMode.virtual_width = (int16)width;
@ -541,9 +542,9 @@ BWindowScreen::CardHookAt(int32 index)
CALLED();
if (fAddonImage < 0)
return NULL;
graphics_card_hook hook = NULL;
switch (index) {
case 5: // 8 bit fill rect
hook = (graphics_card_hook)draw_rect_8;
@ -566,7 +567,7 @@ BWindowScreen::CardHookAt(int32 index)
default:
break;
}
return hook;
}
@ -583,8 +584,15 @@ void
BWindowScreen::RegisterThread(thread_id id)
{
CALLED();
while (acquire_sem(fDebugSem) == B_INTERRUPTED)
;
status_t status;
do {
status = acquire_sem(fDebugSem);
} while (status == B_INTERRUPTED);
if (status < B_OK)
return;
void *newDebugList = realloc(fDebugList, (fDebugListCount + 1) * sizeof(thread_id));
if (newDebugList != NULL) {
fDebugList = (thread_id *)newDebugList;
@ -646,12 +654,13 @@ void BWindowScreen::_ReservedWindowScreen4() {}
BRect
BWindowScreen::CalcFrame(int32 index, int32 space, display_mode *dmode)
BWindowScreen::CalcFrame(int32 index, int32 space, display_mode* mode)
{
CALLED();
BScreen screen;
if (dmode)
screen.GetMode(dmode);
BScreen screen;
if (mode != NULL)
screen.GetMode(mode);
return screen.Frame();
}
@ -729,10 +738,14 @@ BWindowScreen::SetActiveState(int32 state)
status = AssertDisplayMode(fDisplayMode);
if (status == B_OK && (status = SetupAccelerantHooks(true)) == B_OK) {
if (!fActivateState) {
while (acquire_sem(fActivateSem) == B_INTERRUPTED)
;
do {
status = acquire_sem(fActivateSem);
} while (status == B_INTERRUPTED);
if (status < B_OK)
return status;
}
SetColorList(fColorList);
if (fDebugState && !fDebugFirst) {
SuspensionHook(true);
@ -741,13 +754,12 @@ BWindowScreen::SetActiveState(int32 state)
fDebugFirst = true;
ScreenConnected(true);
}
if (status == B_OK)
return status;
} else
SetupAccelerantHooks(false);
be_app->ShowCursor();
} else {
AssertDisplayMode(fOldDisplayMode);
@ -756,7 +768,7 @@ BWindowScreen::SetActiveState(int32 state)
SuspensionHook(false);
} else
ScreenConnected(false);
status = SetupAccelerantHooks(false);
if (status == B_OK) {
be_app->ShowCursor();
@ -765,7 +777,7 @@ BWindowScreen::SetActiveState(int32 state)
}
}
}
return status;
}
@ -786,11 +798,8 @@ BWindowScreen::SetupAccelerantHooks(bool enable)
sReleaseEngineHook = NULL;
}
if (enable)
fLockState = 1;
else
fLockState = 0;
fLockState = enable ? 1 : 0;
status_t status = B_OK;
if (enable) {
if (fAddonImage < 0) {
@ -826,18 +835,21 @@ status_t
BWindowScreen::GetCardInfo()
{
CALLED();
BScreen screen(this);
display_mode mode;
status_t status = screen.GetMode(&mode);
if (status < B_OK)
return status;
uint32 bitsPerPixel;
switch(mode.space & 0x0fff) {
case B_CMAP8:
bitsPerPixel = 8;
break;
case B_RGB15:
bitsPerPixel = 15;
break;
case B_RGB16:
bitsPerPixel = 16;
break;
@ -848,32 +860,32 @@ BWindowScreen::GetCardInfo()
bitsPerPixel = 0;
break;
}
fCardInfo.version = 2;
fCardInfo.id = screen.ID().id;
fCardInfo.bits_per_pixel = bitsPerPixel;
fCardInfo.width = mode.virtual_width;
fCardInfo.height = mode.virtual_height;
if (mode.space & 0x10)
strncpy(fCardInfo.rgba_order, "rgba", 4);
else
strncpy(fCardInfo.rgba_order, "bgra", 4);
fCardInfo.flags = 0;
if (mode.flags & B_SCROLL)
fCardInfo.flags |= B_FRAME_BUFFER_CONTROL;
if (mode.flags & B_PARALLEL_ACCESS)
fCardInfo.flags |= B_PARALLEL_BUFFER_ACCESS;
AppServerLink link;
link.StartMessage(AS_GET_FRAME_BUFFER_CONFIG);
link.Attach<screen_id>(screen.ID());
status_t result = B_ERROR;
if (link.FlushWithReply(result) < B_OK || result < B_OK)
return result;
frame_buffer_config config;
link.Read<frame_buffer_config>(&config);
@ -888,9 +900,14 @@ void
BWindowScreen::Suspend()
{
CALLED();
while (acquire_sem(fDebugSem) == B_INTERRUPTED)
;
status_t status;
do {
status = acquire_sem(fDebugSem);
} while (status == B_INTERRUPTED);
if (status < B_OK)
return;
// Suspend all the registered threads
for (int32 i = 0; i < fDebugListCount; i++) {
@ -912,14 +929,15 @@ BWindowScreen::Resume()
{
CALLED();
graphics_card_info *info = CardInfo();
// Copy the content of the debug_buffer back into the frame buffer.
memcpy(info->frame_buffer, fDebugBuffer, info->bytes_per_row * info->height);
free(fDebugBuffer);
// Resume all the registered threads
for (int32 i = 0; i < fDebugListCount; i++)
for (int32 i = 0; i < fDebugListCount; i++) {
resume_thread(fDebugList[i]);
}
release_sem(fDebugSem);
}
@ -929,25 +947,21 @@ status_t
BWindowScreen::GetModeFromSpace(uint32 space, display_mode *dmode)
{
CALLED();
uint32 destSpace;
int32 width, height;
status_t status = B_ERROR;
mode2parms(space, &destSpace, &width, &height);
// mode2parms converts the space to actual width, height and color_space, e.g B_8_BIT_640x480
uint32 colorSpace;
if (!get_mode_parameter(space, width, height, colorSpace))
return B_BAD_VALUE;
for (uint32 i = 0; i < fModeCount; i++) {
if (fModeList[i].space == destSpace && fModeList[i].virtual_width == width
if (fModeList[i].space == colorSpace && fModeList[i].virtual_width == width
&& fModeList[i].virtual_height == height) {
memcpy(dmode, &fModeList[i], sizeof(display_mode));
status = B_OK;
break;
return B_OK;
}
}
return status;
return B_ERROR;
}
@ -976,7 +990,7 @@ BWindowScreen::InitClone()
}
status = get_image_symbol(fAddonImage, B_ACCELERANT_ENTRY_POINT,
B_SYMBOL_TYPE_TEXT, (void **)&fGetAccelerantHook);
B_SYMBOL_TYPE_TEXT, (void **)&fGetAccelerantHook);
if (status < B_OK) {
printf("InitClone: cannot get accelerant entry point\n");
unload_add_on(fAddonImage);
@ -1012,24 +1026,28 @@ BWindowScreen::InitClone()
status_t
BWindowScreen::AssertDisplayMode(display_mode *dmode)
BWindowScreen::AssertDisplayMode(display_mode* displayMode)
{
CALLED();
status_t status = B_ERROR;
BScreen screen(this);
display_mode mode;
status = screen.GetMode(&mode);
display_mode currentMode;
status_t status = screen.GetMode(&currentMode);
if (status < B_OK)
return status;
if (mode.virtual_height != dmode->virtual_height || mode.virtual_width != dmode->virtual_width
|| mode.space != dmode->space || mode.flags != dmode->flags) {
status = screen.SetMode(dmode);
if (currentMode.virtual_height != displayMode->virtual_height
|| currentMode.virtual_width != displayMode->virtual_width
|| currentMode.space != displayMode->space
|| currentMode.flags != displayMode->flags) {
status = screen.SetMode(displayMode);
if (status < B_OK) {
printf("AssertDisplayMode: Setting mode failed: %s\n", strerror(status));
return status;
}
memcpy(fDisplayMode, dmode, sizeof(display_mode));
memcpy(fDisplayMode, displayMode, sizeof(display_mode));
space_mode = 1;
}
@ -1045,6 +1063,6 @@ BWindowScreen::AssertDisplayMode(display_mode *dmode)
fFrameBufferInfo.display_height = fCardInfo.height;
fFrameBufferInfo.display_x = 0;
fFrameBufferInfo.display_y = 0;
return status;
return B_OK;
}