* 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:
parent
0e836b16bd
commit
3df31bf306
@ -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(¤tMode);
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user