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