* (tried to) implemented RootLayer::ResizeBy() and activated AS_SET_SCREEN_MODE again;

it works in the test environment, but I haven't yet tested it on real hardware.
* moved PrivateScreen.h to src/kits/interface/ - it's not used outside of that one.
* moved reading the color map from the BPrivateScreen constructor to the ColorMap()
  method.
* improved/cleaned server/client communication for the screen stuff a tiny bit.
* fixed the GetBitmap() method I implemented yesterday.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14908 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2005-11-14 11:01:02 +00:00
parent e84b16339c
commit a817d6ad5a
6 changed files with 438 additions and 429 deletions
-96
View File
@@ -1,96 +0,0 @@
//------------------------------------------------------------------------------
// Copyright (c) 2002-2005, Haiku
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File Name: PrivateScreen.h
// Author: Stefano Ceccherini ([email protected])
// Description: BPrivateScreen is the class which does the real work
// for the proxy class BScreen (it interacts with the app server).
//------------------------------------------------------------------------------
#ifndef __PRIVATESCREEN_H
#define __PRIVATESCREEN_H
#include <Accelerant.h>
#include <GraphicsDefs.h>
struct screen_desc;
class BApplication;
class BWindow;
class BPrivateScreen {
// Constructor and destructor are private. Use the static methods
// CheckOut() and Return() instead.
public:
static BPrivateScreen* CheckOut(BWindow *win);
static BPrivateScreen* CheckOut(screen_id id);
static void Return(BPrivateScreen *screen);
status_t SetToNext();
color_space ColorSpace();
BRect Frame();
screen_id ID();
status_t WaitForRetrace(bigtime_t timeout);
uint8 IndexForColor(uint8 red, uint8 green, uint8 blue, uint8 alpha);
rgb_color ColorForIndex(const uint8 index);
uint8 InvertIndex(uint8 index);
const color_map *ColorMap();
status_t GetBitmap(BBitmap **bitmap, bool drawCursor, BRect *bound);
status_t ReadBitmap(BBitmap *bitmap, bool drawCursor, BRect *bound);
rgb_color DesktopColor(uint32 index);
void SetDesktopColor(rgb_color, uint32, bool);
status_t ProposeMode(display_mode *target, const display_mode *low, const display_mode *high);
status_t GetModeList(display_mode **mode_list, uint32 *count);
status_t GetMode(uint32 workspace, display_mode *mode);
status_t SetMode(uint32 workspace, display_mode *mode, bool makeDefault);
status_t GetDeviceInfo(accelerant_device_info *info);
status_t GetPixelClockLimits(display_mode *mode, uint32 *low, uint32 *high);
status_t GetTimingConstraints(display_timing_constraints *dtc);
status_t SetDPMS(uint32 dpmsState);
uint32 DPMSState();
uint32 DPMSCapabilites();
void* BaseAddress();
uint32 BytesPerRow();
status_t get_screen_desc(screen_desc *desc);
private:
color_map *fColorMap;
sem_id fRetraceSem;
bool fOwnsColorMap;
sem_id RetraceSemaphore();
BPrivateScreen();
~BPrivateScreen();
};
#endif // __PRIVATESCREEN_H
+157 -163
View File
@@ -1,33 +1,22 @@
//------------------------------------------------------------------------------ /*
// Copyright (c) 2002-2005, Haiku * Copyright 2002-2005, Haiku Inc.
// * Distributed under the terms of the MIT License.
// Permission is hereby granted, free of charge, to any person obtaining a *
// copy of this software and associated documentation files (the "Software"), * Authors:
// to deal in the Software without restriction, including without limitation * Stefano Ceccherini ([email protected])
// the rights to use, copy, modify, merge, publish, distribute, sublicense, * Axel Dörfler, [email protected]
// and/or sell copies of the Software, and to permit persons to whom the */
// Software is furnished to do so, subject to the following conditions:
// /** BPrivateScreen is the class which does the real work for
// The above copyright notice and this permission notice shall be included in * the proxy class BScreen (it interacts with the app server).
// all copies or substantial portions of the Software. */
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File Name: PrivateScreen.cpp
// Author: Stefano Ceccherini ([email protected])
// Description: BPrivateScreen is the class which does the real work
// for the proxy class BScreen (it interacts with the app server).
//------------------------------------------------------------------------------
#include "AppServerLink.h" #include "AppServerLink.h"
#include "PrivateScreen.h" #include "PrivateScreen.h"
#include "ServerProtocol.h" #include "ServerProtocol.h"
#include <Autolock.h>
#include <Bitmap.h> #include <Bitmap.h>
#include <Locker.h> #include <Locker.h>
#include <Window.h> #include <Window.h>
@@ -56,35 +45,24 @@ static BLocker sScreenLock("screen lock");
using namespace BPrivate; using namespace BPrivate;
BPrivateScreen * BPrivateScreen *
BPrivateScreen::CheckOut(BWindow *win) BPrivateScreen::CheckOut(BWindow *window)
{ {
sScreenLock.Lock(); // TODO: get screen ID from window!
return CheckOut(B_MAIN_SCREEN_ID);
if (sScreen == NULL) {
// TODO: If we start supporting multiple monitors, we
// should return the right screen for the passed BWindow
sScreen = new BPrivateScreen();
}
sScreenLock.Unlock();
return sScreen;
} }
BPrivateScreen * BPrivateScreen *
BPrivateScreen::CheckOut(screen_id id) BPrivateScreen::CheckOut(screen_id id)
{ {
sScreenLock.Lock(); BAutolock locker(sScreenLock);
if (sScreen == NULL) { if (sScreen == NULL) {
// TODO: If we start supporting multiple monitors, we // TODO: If we start supporting multiple monitors, we
// should return the right object for the given screen_id // should return the right object for the given screen_id
sScreen = new BPrivateScreen(); sScreen = new BPrivateScreen();
} }
sScreenLock.Unlock();
return sScreen; return sScreen;
} }
@@ -136,8 +114,8 @@ BPrivateScreen::ID()
// TODO: Change this if we start supporting multiple screens // TODO: Change this if we start supporting multiple screens
return B_MAIN_SCREEN_ID; return B_MAIN_SCREEN_ID;
} }
status_t status_t
BPrivateScreen::WaitForRetrace(bigtime_t timeout) BPrivateScreen::WaitForRetrace(bigtime_t timeout)
{ {
@@ -145,7 +123,7 @@ BPrivateScreen::WaitForRetrace(bigtime_t timeout)
// we are called. Cache the value then. // we are called. Cache the value then.
status_t status; status_t status;
if (fRetraceSem < 0) if (fRetraceSem < 0)
fRetraceSem = RetraceSemaphore(); fRetraceSem = _RetraceSemaphore();
do { do {
status = acquire_sem_etc(fRetraceSem, 1, B_RELATIVE_TIMEOUT, timeout); status = acquire_sem_etc(fRetraceSem, 1, B_RELATIVE_TIMEOUT, timeout);
@@ -159,12 +137,14 @@ uint8
BPrivateScreen::IndexForColor(uint8 red, uint8 green, uint8 blue, uint8 alpha) BPrivateScreen::IndexForColor(uint8 red, uint8 green, uint8 blue, uint8 alpha)
{ {
// Looks like this check is necessary // Looks like this check is necessary
if (red == B_TRANSPARENT_COLOR.red && green == B_TRANSPARENT_COLOR.green && if (red == B_TRANSPARENT_COLOR.red
blue == B_TRANSPARENT_COLOR.blue && alpha == B_TRANSPARENT_COLOR.alpha) && green == B_TRANSPARENT_COLOR.green
&& blue == B_TRANSPARENT_COLOR.blue
&& alpha == B_TRANSPARENT_COLOR.alpha)
return B_TRANSPARENT_8_BIT; return B_TRANSPARENT_8_BIT;
uint16 index = ((blue & 0xf8) << 7) | ((green & 0xf8) << 2) | (red >> 3); uint16 index = ((blue & 0xf8) << 7) | ((green & 0xf8) << 2) | (red >> 3);
if (fColorMap) if (ColorMap())
return fColorMap->index_map[index]; return fColorMap->index_map[index];
return 0; return 0;
@@ -174,7 +154,7 @@ BPrivateScreen::IndexForColor(uint8 red, uint8 green, uint8 blue, uint8 alpha)
rgb_color rgb_color
BPrivateScreen::ColorForIndex(const uint8 index) BPrivateScreen::ColorForIndex(const uint8 index)
{ {
if (fColorMap) if (ColorMap())
return fColorMap->color_list[index]; return fColorMap->color_list[index];
return rgb_color(); return rgb_color();
@@ -184,7 +164,7 @@ BPrivateScreen::ColorForIndex(const uint8 index)
uint8 uint8
BPrivateScreen::InvertIndex(uint8 index) BPrivateScreen::InvertIndex(uint8 index)
{ {
if (fColorMap) if (ColorMap())
return fColorMap->inversion_map[index]; return fColorMap->inversion_map[index];
return 0; return 0;
@@ -194,6 +174,29 @@ BPrivateScreen::InvertIndex(uint8 index)
const color_map * const color_map *
BPrivateScreen::ColorMap() BPrivateScreen::ColorMap()
{ {
if (fColorMap == NULL) {
BAutolock locker(sScreenLock);
if (fColorMap != NULL) {
// someone could have been faster than us
return fColorMap;
}
// TODO: BeOS R5 here gets the colormap pointer
// (with BApplication::ro_offset_to_ptr() ?)
// which is contained in a shared area created by the server.
BPrivate::AppServerLink link;
link.StartMessage(AS_SCREEN_GET_COLORMAP);
link.Attach<screen_id>(ID());
status_t status;
if (link.FlushWithReply(status) == B_OK && status == B_OK) {
fColorMap = (color_map *)malloc(sizeof(color_map));
fOwnsColorMap = true;
link.Read<color_map>(fColorMap);
}
}
return fColorMap; return fColorMap;
} }
@@ -204,13 +207,19 @@ BPrivateScreen::GetBitmap(BBitmap **_bitmap, bool drawCursor, BRect *bounds)
if (_bitmap == NULL) if (_bitmap == NULL)
return B_BAD_VALUE; return B_BAD_VALUE;
BBitmap* bitmap = new (std::nothrow) BBitmap(Frame(), ColorSpace()); BRect rect;
if (bounds != NULL)
rect = *bounds;
else
rect = Frame();
BBitmap* bitmap = new (std::nothrow) BBitmap(rect, ColorSpace());
if (bitmap == NULL) if (bitmap == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
status_t status = bitmap->InitCheck(); status_t status = bitmap->InitCheck();
if (status == B_OK) if (status == B_OK)
status = ReadBitmap(bitmap, drawCursor, bounds); status = ReadBitmap(bitmap, drawCursor, &rect);
if (status != B_OK) { if (status != B_OK) {
delete bitmap; delete bitmap;
return status; return status;
@@ -222,27 +231,27 @@ BPrivateScreen::GetBitmap(BBitmap **_bitmap, bool drawCursor, BRect *bounds)
status_t status_t
BPrivateScreen::ReadBitmap(BBitmap *bitmap, bool drawCursor, BRect *bound) BPrivateScreen::ReadBitmap(BBitmap *bitmap, bool drawCursor, BRect *bounds)
{ {
if (bitmap == NULL) if (bitmap == NULL)
return B_BAD_VALUE; return B_BAD_VALUE;
BRect rect; BRect rect;
if (bound != NULL) if (bounds != NULL)
rect = *bound; rect = *bounds;
else else
rect = Frame(); rect = Frame();
BPrivate::AppServerLink link; BPrivate::AppServerLink link;
link.StartMessage(AS_READ_BITMAP); link.StartMessage(AS_READ_BITMAP);
link.Attach<int32>(bitmap->get_server_token()); link.Attach<int32>(bitmap->get_server_token());
link.Attach<bool>(drawCursor); link.Attach<bool>(drawCursor);
link.Attach<BRect>(rect); link.Attach<BRect>(rect);
int32 code; status_t status = B_ERROR;
if (link.FlushWithReply(code) < B_OK || code != SERVER_TRUE) if (link.FlushWithReply(status) < B_OK || status != B_OK)
return B_ERROR; return status;
return B_OK; return B_OK;
} }
@@ -258,7 +267,7 @@ BPrivateScreen::DesktopColor(uint32 workspace)
int32 code; int32 code;
if (link.FlushWithReply(code) == B_OK if (link.FlushWithReply(code) == B_OK
&& code == SERVER_TRUE) && code == B_OK)
link.Read<rgb_color>(&color); link.Read<rgb_color>(&color);
return color; return color;
@@ -266,7 +275,8 @@ BPrivateScreen::DesktopColor(uint32 workspace)
void void
BPrivateScreen::SetDesktopColor(rgb_color color, uint32 workspace, bool makeDefault) BPrivateScreen::SetDesktopColor(rgb_color color, uint32 workspace,
bool makeDefault)
{ {
BPrivate::AppServerLink link; BPrivate::AppServerLink link;
@@ -280,53 +290,57 @@ BPrivateScreen::SetDesktopColor(rgb_color color, uint32 workspace, bool makeDefa
status_t status_t
BPrivateScreen::ProposeMode(display_mode *target, BPrivateScreen::ProposeMode(display_mode *target,
const display_mode *low, const display_mode *high) const display_mode *low, const display_mode *high)
{ {
// We can't return B_BAD_VALUE here, because it's used to indicate // We can't return B_BAD_VALUE here, because it's used to indicate
// that the mode returned is supported, but it doesn't fall // that the mode returned is supported, but it doesn't fall
// within the limit (see ProposeMode() documentation) // within the limit (see ProposeMode() documentation)
if (target == NULL || low == NULL || high == NULL) if (target == NULL || low == NULL || high == NULL)
return B_ERROR; return B_ERROR;
BPrivate::AppServerLink link; BPrivate::AppServerLink link;
link.StartMessage(AS_PROPOSE_MODE); link.StartMessage(AS_PROPOSE_MODE);
link.Attach<screen_id>(ID()); link.Attach<screen_id>(ID());
link.Attach<display_mode>(*target); link.Attach<display_mode>(*target);
link.Attach<display_mode>(*low); link.Attach<display_mode>(*low);
link.Attach<display_mode>(*high); link.Attach<display_mode>(*high);
int32 reply;
status_t status = B_ERROR; status_t status = B_ERROR;
if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE) { if (link.FlushWithReply(status) == B_OK && status == B_OK) {
link.Read<display_mode>(target); link.Read<display_mode>(target);
// The status is important here. See documentation
link.Read<status_t>(&status); bool withinLimits;
link.Read<bool>(&withinLimits);
if (!withinLimits)
status = B_BAD_VALUE;
} }
return status; return status;
} }
status_t status_t
BPrivateScreen::GetModeList(display_mode **modeList, uint32 *count) BPrivateScreen::GetModeList(display_mode **_modeList, uint32 *_count)
{ {
if (modeList == NULL || count == NULL) if (_modeList == NULL || _count == NULL)
return B_BAD_VALUE; return B_BAD_VALUE;
status_t status = B_ERROR;
BPrivate::AppServerLink link; BPrivate::AppServerLink link;
link.StartMessage(AS_GET_MODE_LIST); link.StartMessage(AS_GET_MODE_LIST);
link.Attach<screen_id>(ID()); link.Attach<screen_id>(ID());
int32 reply;
if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE) { status_t status = B_ERROR;
link.Read<uint32>(count); if (link.FlushWithReply(status) == B_OK && status == B_OK) {
int32 size = *count * sizeof(display_mode); link.Read<uint32>(_count);
*modeList = (display_mode *)malloc(size); // TODO: this could get too big for the link
link.Read(*modeList, size); int32 size = *_count * sizeof(display_mode);
// TODO: get status from app_server *_modeList = (display_mode *)malloc(size);
status = B_OK; if (_modeList == NULL)
return B_NO_MEMORY;
link.Read(*_modeList, size);
} }
return status; return status;
} }
@@ -336,26 +350,19 @@ BPrivateScreen::GetMode(uint32 workspace, display_mode *mode)
{ {
if (mode == NULL) if (mode == NULL)
return B_BAD_VALUE; return B_BAD_VALUE;
BPrivate::AppServerLink link; BPrivate::AppServerLink link;
link.StartMessage(AS_SCREEN_GET_MODE); link.StartMessage(AS_SCREEN_GET_MODE);
link.Attach<screen_id>(ID()); link.Attach<screen_id>(ID());
link.Attach<uint32>(workspace); link.Attach<uint32>(workspace);
int32 code;
if (link.FlushWithReply(code) != B_OK
|| code != SERVER_TRUE)
return B_ERROR;
display_mode currentMode;
link.Read<display_mode>(&currentMode);
status_t status = B_ERROR; status_t status = B_ERROR;
link.Read<status_t>(&status); if (link.FlushWithReply(status) != B_OK
if (status == B_OK && mode) || status != B_OK)
*mode = currentMode; return status;
return status; link.Read<display_mode>(mode);
return B_OK;
} }
@@ -364,18 +371,16 @@ BPrivateScreen::SetMode(uint32 workspace, display_mode *mode, bool makeDefault)
{ {
if (mode == NULL) if (mode == NULL)
return B_BAD_VALUE; return B_BAD_VALUE;
BPrivate::AppServerLink link; BPrivate::AppServerLink link;
link.StartMessage(AS_SCREEN_SET_MODE); link.StartMessage(AS_SCREEN_SET_MODE);
link.Attach<screen_id>(ID()); link.Attach<screen_id>(ID());
link.Attach<uint32>(workspace); link.Attach<uint32>(workspace);
link.Attach<display_mode>(*mode); link.Attach<display_mode>(*mode);
link.Attach<bool>(makeDefault); link.Attach<bool>(makeDefault);
status_t status = B_ERROR; status_t status = B_ERROR;
int32 code; link.FlushWithReply(status);
if (link.FlushWithReply(code) == B_OK && code == SERVER_TRUE)
link.Read<status_t>(&status);
return status; return status;
} }
@@ -386,17 +391,18 @@ BPrivateScreen::GetDeviceInfo(accelerant_device_info *info)
{ {
if (info == NULL) if (info == NULL)
return B_BAD_VALUE; return B_BAD_VALUE;
BPrivate::AppServerLink link; BPrivate::AppServerLink link;
link.StartMessage(AS_GET_ACCELERANT_INFO); link.StartMessage(AS_GET_ACCELERANT_INFO);
link.Attach<screen_id>(ID()); link.Attach<screen_id>(ID());
int32 code;
if (link.FlushWithReply(code) == B_OK && code == SERVER_TRUE) { status_t status = B_ERROR;
if (link.FlushWithReply(status) == B_OK && status == B_OK) {
link.Read<accelerant_device_info>(info); link.Read<accelerant_device_info>(info);
return B_OK; return B_OK;
} }
return B_ERROR; return status;
} }
@@ -405,41 +411,40 @@ BPrivateScreen::GetPixelClockLimits(display_mode *mode, uint32 *low, uint32 *hig
{ {
if (mode == NULL || low == NULL || high == NULL) if (mode == NULL || low == NULL || high == NULL)
return B_BAD_VALUE; return B_BAD_VALUE;
BPrivate::AppServerLink link; BPrivate::AppServerLink link;
link.StartMessage(AS_GET_PIXEL_CLOCK_LIMITS); link.StartMessage(AS_GET_PIXEL_CLOCK_LIMITS);
link.Attach<screen_id>(ID()); link.Attach<screen_id>(ID());
link.Attach<display_mode>(*mode); link.Attach<display_mode>(*mode);
int32 code; status_t status;
if (link.FlushWithReply(code) == B_OK && code == SERVER_TRUE) { if (link.FlushWithReply(status) == B_OK && status == B_OK) {
link.Read<uint32>(low); link.Read<uint32>(low);
link.Read<uint32>(high); link.Read<uint32>(high);
return B_OK; return B_OK;
} }
return B_ERROR; return status;
} }
status_t status_t
BPrivateScreen::GetTimingConstraints(display_timing_constraints *dtc) BPrivateScreen::GetTimingConstraints(display_timing_constraints *constraints)
{ {
if (dtc == NULL) if (constraints == NULL)
return B_BAD_VALUE; return B_BAD_VALUE;
BPrivate::AppServerLink link; BPrivate::AppServerLink link;
link.StartMessage(AS_GET_TIMING_CONSTRAINTS); link.StartMessage(AS_GET_TIMING_CONSTRAINTS);
link.Attach<screen_id>(ID()); link.Attach<screen_id>(ID());
int32 code; status_t status = B_ERROR;
if (link.FlushWithReply(code) == B_OK && code == SERVER_TRUE) { if (link.FlushWithReply(status) == B_OK && status == B_OK) {
link.Read<display_timing_constraints>(dtc); link.Read<display_timing_constraints>(constraints);
return B_OK; return B_OK;
} }
return B_ERROR; return status;
} }
@@ -450,11 +455,11 @@ BPrivateScreen::SetDPMS(uint32 dpmsState)
link.StartMessage(AS_SET_DPMS); link.StartMessage(AS_SET_DPMS);
link.Attach<screen_id>(ID()); link.Attach<screen_id>(ID());
link.Attach<uint32>(dpmsState); link.Attach<uint32>(dpmsState);
int32 reply;
if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE) status_t status = B_ERROR;
return B_OK; link.FlushWithReply(status);
return B_ERROR; return status;
} }
@@ -462,14 +467,15 @@ uint32
BPrivateScreen::DPMSState() BPrivateScreen::DPMSState()
{ {
uint32 state = 0; uint32 state = 0;
BPrivate::AppServerLink link; BPrivate::AppServerLink link;
link.StartMessage(AS_GET_DPMS_STATE); link.StartMessage(AS_GET_DPMS_STATE);
link.Attach<screen_id>(ID()); link.Attach<screen_id>(ID());
int32 reply;
if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE) status_t status;
if (link.FlushWithReply(status) == B_OK && status == B_OK)
link.Read<uint32>(&state); link.Read<uint32>(&state);
return state; return state;
} }
@@ -478,14 +484,15 @@ uint32
BPrivateScreen::DPMSCapabilites() BPrivateScreen::DPMSCapabilites()
{ {
uint32 capabilities = 0; uint32 capabilities = 0;
BPrivate::AppServerLink link; BPrivate::AppServerLink link;
link.StartMessage(AS_GET_DPMS_CAPABILITIES); link.StartMessage(AS_GET_DPMS_CAPABILITIES);
link.Attach<screen_id>(ID()); link.Attach<screen_id>(ID());
int32 reply;
if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE) status_t status;
if (link.FlushWithReply(status) == B_OK && status == B_OK)
link.Read<uint32>(&capabilities); link.Read<uint32>(&capabilities);
return capabilities; return capabilities;
} }
@@ -496,7 +503,7 @@ BPrivateScreen::BaseAddress()
screen_desc desc; screen_desc desc;
if (get_screen_desc(&desc) == B_OK) if (get_screen_desc(&desc) == B_OK)
return desc.base_address; return desc.base_address;
return NULL; return NULL;
} }
@@ -507,6 +514,7 @@ BPrivateScreen::BytesPerRow()
screen_desc desc; screen_desc desc;
if (get_screen_desc(&desc) == B_OK) if (get_screen_desc(&desc) == B_OK)
return desc.bytes_per_row; return desc.bytes_per_row;
return 0; return 0;
} }
@@ -528,20 +536,19 @@ BPrivateScreen::get_screen_desc(screen_desc *desc)
} }
// private methods // #pragma mark - private methods
sem_id sem_id
BPrivateScreen::RetraceSemaphore() BPrivateScreen::_RetraceSemaphore()
{ {
sem_id id = B_BAD_SEM_ID;
BPrivate::AppServerLink link; BPrivate::AppServerLink link;
link.StartMessage(AS_GET_RETRACE_SEMAPHORE); link.StartMessage(AS_GET_RETRACE_SEMAPHORE);
link.Attach<screen_id>(ID()); link.Attach<screen_id>(ID());
int32 reply;
if (link.FlushWithReply(reply) == B_OK sem_id id = B_BAD_SEM_ID;
&& reply == SERVER_TRUE) link.FlushWithReply(id);
link.Read<sem_id>(&id);
return id; return id;
} }
@@ -552,19 +559,6 @@ BPrivateScreen::BPrivateScreen()
fRetraceSem(-1), fRetraceSem(-1),
fOwnsColorMap(false) fOwnsColorMap(false)
{ {
// TODO: BeOS R5 here gets the colormap pointer
// (with BApplication::ro_offset_to_ptr() ?)
// which is contained in a shared area created by the server.
BPrivate::AppServerLink link;
link.StartMessage(AS_SCREEN_GET_COLORMAP);
link.Attach<screen_id>(ID());
int32 reply;
if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE) {
fColorMap = (color_map *)malloc(sizeof(color_map));
fOwnsColorMap = true;
link.Read<color_map>(fColorMap);
}
} }
+85
View File
@@ -0,0 +1,85 @@
/*
* Copyright 2002-2005, Haiku Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stefano Ceccherini ([email protected])
* Axel Dörfler, [email protected]
*/
#ifndef _PRIVATE_SCREEN_H_
#define _PRIVATE_SCREEN_H_
#include <Accelerant.h>
#include <GraphicsDefs.h>
struct screen_desc;
struct color_map;
struct display_mode;
struct display_timing_constraints;
class BBitmap;
class BApplication;
class BWindow;
class BPrivateScreen {
// Constructor and destructor are private. Use the static methods
// CheckOut() and Return() instead.
public:
static BPrivateScreen* CheckOut(BWindow *window);
static BPrivateScreen* CheckOut(screen_id id);
static void Return(BPrivateScreen *screen);
status_t SetToNext();
color_space ColorSpace();
BRect Frame();
screen_id ID();
status_t WaitForRetrace(bigtime_t timeout);
uint8 IndexForColor(uint8 red, uint8 green, uint8 blue, uint8 alpha);
rgb_color ColorForIndex(const uint8 index);
uint8 InvertIndex(uint8 index);
const color_map *ColorMap();
status_t GetBitmap(BBitmap **bitmap, bool drawCursor, BRect *bounds);
status_t ReadBitmap(BBitmap *bitmap, bool drawCursor, BRect *bounds);
rgb_color DesktopColor(uint32 index);
void SetDesktopColor(rgb_color, uint32, bool);
status_t ProposeMode(display_mode *target, const display_mode *low,
const display_mode *high);
status_t GetModeList(display_mode **_modeList, uint32 *_count);
status_t GetMode(uint32 workspace, display_mode *mode);
status_t SetMode(uint32 workspace, display_mode *mode, bool makeDefault);
status_t GetDeviceInfo(accelerant_device_info *info);
status_t GetPixelClockLimits(display_mode *mode, uint32 *low, uint32 *high);
status_t GetTimingConstraints(display_timing_constraints *constraints);
status_t SetDPMS(uint32 dpmsState);
uint32 DPMSState();
uint32 DPMSCapabilites();
void* BaseAddress();
uint32 BytesPerRow();
status_t get_screen_desc(screen_desc *desc);
private:
BPrivateScreen();
~BPrivateScreen();
sem_id _RetraceSemaphore();
private:
color_map *fColorMap;
sem_id fRetraceSem;
bool fOwnsColorMap;
};
#endif // _PRIVATE_SCREEN_H_
+84 -95
View File
@@ -1,33 +1,20 @@
//------------------------------------------------------------------------------ /*
// Copyright (c) 2003-2005, Haiku, Inc. * Copyright 2003-2005, Haiku Inc.
// * Distributed under the terms of the MIT License.
// Permission is hereby granted, free of charge, to any person obtaining a *
// copy of this software and associated documentation files (the "Software"), * Authors:
// to deal in the Software without restriction, including without limitation * Stefano Ceccherini ([email protected])
// the rights to use, copy, modify, merge, publish, distribute, sublicense, * Axel Dörfler, [email protected]
// and/or sell copies of the Software, and to permit persons to whom the */
// Software is furnished to do so, subject to the following conditions:
// /** BScreen lets you retrieve and change the display settings. */
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// #include "PrivateScreen.h"
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File Name: Screen.cpp
// Author: Stefano Ceccherini ([email protected])
// Description: BScreen lets you retrieve and change the display settings.
//------------------------------------------------------------------------------
#include <Screen.h> #include <Screen.h>
#include <Window.h> #include <Window.h>
#include <PrivateScreen.h>
/*! \brief Creates a BScreen object which represents the display with the given screen_id /*! \brief Creates a BScreen object which represents the display with the given screen_id
\param id The screen_id of the screen to get. \param id The screen_id of the screen to get.
@@ -37,17 +24,17 @@
*/ */
BScreen::BScreen(screen_id id) BScreen::BScreen(screen_id id)
{ {
screen = BPrivateScreen::CheckOut(id); fScreen = BPrivateScreen::CheckOut(id);
} }
/*! \brief Creates a BScreen object which represents the display which contains /*! \brief Creates a BScreen object which represents the display which contains
the given BWindow. the given BWindow.
\param win A BWindow. \param window A BWindow.
*/ */
BScreen::BScreen(BWindow *win) BScreen::BScreen(BWindow *window)
{ {
screen = BPrivateScreen::CheckOut(win); fScreen = BPrivateScreen::CheckOut(window);
} }
@@ -55,8 +42,8 @@ BScreen::BScreen(BWindow *win)
*/ */
BScreen::~BScreen() BScreen::~BScreen()
{ {
if (screen != NULL) if (fScreen != NULL)
BPrivateScreen::Return(screen); BPrivateScreen::Return(fScreen);
} }
@@ -66,7 +53,7 @@ BScreen::~BScreen()
bool bool
BScreen::IsValid() BScreen::IsValid()
{ {
return (screen != NULL); return fScreen != NULL;
} }
@@ -76,8 +63,8 @@ BScreen::IsValid()
status_t status_t
BScreen::SetToNext() BScreen::SetToNext()
{ {
if (screen != NULL) if (fScreen != NULL)
return screen->SetToNext(); return fScreen->SetToNext();
return B_ERROR; return B_ERROR;
} }
@@ -89,8 +76,8 @@ BScreen::SetToNext()
color_space color_space
BScreen::ColorSpace() BScreen::ColorSpace()
{ {
if (screen != NULL) if (fScreen != NULL)
return screen->ColorSpace(); return fScreen->ColorSpace();
return B_NO_COLOR_SPACE; return B_NO_COLOR_SPACE;
} }
@@ -101,8 +88,8 @@ BScreen::ColorSpace()
BRect BRect
BScreen::Frame() BScreen::Frame()
{ {
if (screen != NULL) if (fScreen != NULL)
return screen->Frame(); return fScreen->Frame();
return BRect(0, 0, 0, 0); return BRect(0, 0, 0, 0);
} }
@@ -116,8 +103,8 @@ BScreen::Frame()
screen_id screen_id
BScreen::ID() BScreen::ID()
{ {
if (screen != NULL) if (fScreen != NULL)
return screen->ID(); return fScreen->ID();
return B_MAIN_SCREEN_ID; return B_MAIN_SCREEN_ID;
} }
@@ -128,8 +115,8 @@ BScreen::ID()
status_t status_t
BScreen::WaitForRetrace() BScreen::WaitForRetrace()
{ {
if (screen != NULL) if (fScreen != NULL)
return screen->WaitForRetrace(B_INFINITE_TIMEOUT); return fScreen->WaitForRetrace(B_INFINITE_TIMEOUT);
return B_ERROR; return B_ERROR;
} }
@@ -143,8 +130,8 @@ BScreen::WaitForRetrace()
status_t status_t
BScreen::WaitForRetrace(bigtime_t timeout) BScreen::WaitForRetrace(bigtime_t timeout)
{ {
if (screen != NULL) if (fScreen != NULL)
return screen->WaitForRetrace(timeout); return fScreen->WaitForRetrace(timeout);
return B_ERROR; return B_ERROR;
} }
@@ -160,8 +147,8 @@ BScreen::WaitForRetrace(bigtime_t timeout)
uint8 uint8
BScreen::IndexForColor(uint8 r, uint8 g, uint8 b, uint8 a) BScreen::IndexForColor(uint8 r, uint8 g, uint8 b, uint8 a)
{ {
if (screen != NULL) if (fScreen != NULL)
return screen->IndexForColor(r, g, b, a); return fScreen->IndexForColor(r, g, b, a);
return 0; return 0;
} }
@@ -173,8 +160,8 @@ BScreen::IndexForColor(uint8 r, uint8 g, uint8 b, uint8 a)
rgb_color rgb_color
BScreen::ColorForIndex(const uint8 index) BScreen::ColorForIndex(const uint8 index)
{ {
if (screen != NULL) if (fScreen != NULL)
return screen->ColorForIndex(index); return fScreen->ColorForIndex(index);
return rgb_color(); return rgb_color();
} }
@@ -186,8 +173,8 @@ BScreen::ColorForIndex(const uint8 index)
uint8 uint8
BScreen::InvertIndex(uint8 index) BScreen::InvertIndex(uint8 index)
{ {
if (screen != NULL) if (fScreen != NULL)
return screen->InvertIndex(index); return fScreen->InvertIndex(index);
return 0; return 0;
} }
@@ -198,8 +185,8 @@ BScreen::InvertIndex(uint8 index)
const color_map* const color_map*
BScreen::ColorMap() BScreen::ColorMap()
{ {
if (screen != NULL) if (fScreen != NULL)
return screen->ColorMap(); return fScreen->ColorMap();
return NULL; return NULL;
} }
@@ -213,8 +200,8 @@ BScreen::ColorMap()
status_t status_t
BScreen::GetBitmap(BBitmap **screen_shot, bool draw_cursor, BRect *bound) BScreen::GetBitmap(BBitmap **screen_shot, bool draw_cursor, BRect *bound)
{ {
if (screen != NULL) if (fScreen != NULL)
return screen->GetBitmap(screen_shot, draw_cursor, bound); return fScreen->GetBitmap(screen_shot, draw_cursor, bound);
return B_ERROR; return B_ERROR;
} }
@@ -231,8 +218,8 @@ BScreen::GetBitmap(BBitmap **screen_shot, bool draw_cursor, BRect *bound)
status_t status_t
BScreen::ReadBitmap(BBitmap *buffer, bool draw_cursor, BRect *bound) BScreen::ReadBitmap(BBitmap *buffer, bool draw_cursor, BRect *bound)
{ {
if (screen != NULL) if (fScreen != NULL)
return screen->ReadBitmap(buffer, draw_cursor, bound); return fScreen->ReadBitmap(buffer, draw_cursor, bound);
return B_ERROR; return B_ERROR;
} }
@@ -243,8 +230,9 @@ BScreen::ReadBitmap(BBitmap *buffer, bool draw_cursor, BRect *bound)
rgb_color rgb_color
BScreen::DesktopColor() BScreen::DesktopColor()
{ {
if (screen != NULL) if (fScreen != NULL)
return screen->DesktopColor(B_ALL_WORKSPACES); return fScreen->DesktopColor(B_ALL_WORKSPACES);
return rgb_color(); return rgb_color();
} }
@@ -256,8 +244,9 @@ BScreen::DesktopColor()
rgb_color rgb_color
BScreen::DesktopColor(uint32 workspace) BScreen::DesktopColor(uint32 workspace)
{ {
if (screen != NULL) if (fScreen != NULL)
return screen->DesktopColor(workspace); return fScreen->DesktopColor(workspace);
return rgb_color(); return rgb_color();
} }
@@ -269,8 +258,8 @@ BScreen::DesktopColor(uint32 workspace)
void void
BScreen::SetDesktopColor(rgb_color rgb, bool stick) BScreen::SetDesktopColor(rgb_color rgb, bool stick)
{ {
if (screen != NULL) if (fScreen != NULL)
screen->SetDesktopColor(rgb, B_ALL_WORKSPACES, stick); fScreen->SetDesktopColor(rgb, B_ALL_WORKSPACES, stick);
} }
@@ -282,8 +271,8 @@ BScreen::SetDesktopColor(rgb_color rgb, bool stick)
void void
BScreen::SetDesktopColor(rgb_color rgb, uint32 index, bool stick) BScreen::SetDesktopColor(rgb_color rgb, uint32 index, bool stick)
{ {
if (screen != NULL) if (fScreen != NULL)
screen->SetDesktopColor(rgb, index, stick); fScreen->SetDesktopColor(rgb, index, stick);
} }
@@ -299,8 +288,8 @@ BScreen::SetDesktopColor(rgb_color rgb, uint32 index, bool stick)
status_t status_t
BScreen::ProposeMode(display_mode *target, const display_mode *low, const display_mode *high) BScreen::ProposeMode(display_mode *target, const display_mode *low, const display_mode *high)
{ {
if (screen != NULL) if (fScreen != NULL)
return screen->ProposeMode(target, low, high); return fScreen->ProposeMode(target, low, high);
return B_ERROR; return B_ERROR;
} }
@@ -316,8 +305,8 @@ BScreen::ProposeMode(display_mode *target, const display_mode *low, const displa
status_t status_t
BScreen::GetModeList(display_mode **mode_list, uint32 *count) BScreen::GetModeList(display_mode **mode_list, uint32 *count)
{ {
if (screen != NULL) if (fScreen != NULL)
return screen->GetModeList(mode_list, count); return fScreen->GetModeList(mode_list, count);
return B_ERROR; return B_ERROR;
} }
@@ -330,8 +319,8 @@ BScreen::GetModeList(display_mode **mode_list, uint32 *count)
status_t status_t
BScreen::GetMode(display_mode *mode) BScreen::GetMode(display_mode *mode)
{ {
if (screen != NULL) if (fScreen != NULL)
return screen->GetMode(B_ALL_WORKSPACES, mode); return fScreen->GetMode(B_ALL_WORKSPACES, mode);
return B_ERROR; return B_ERROR;
} }
@@ -344,8 +333,8 @@ BScreen::GetMode(display_mode *mode)
status_t status_t
BScreen::GetMode(uint32 workspace, display_mode *mode) BScreen::GetMode(uint32 workspace, display_mode *mode)
{ {
if (screen != NULL) if (fScreen != NULL)
return screen->GetMode(workspace, mode); return fScreen->GetMode(workspace, mode);
return B_ERROR; return B_ERROR;
} }
@@ -358,8 +347,8 @@ BScreen::GetMode(uint32 workspace, display_mode *mode)
status_t status_t
BScreen::SetMode(display_mode *mode, bool makeDefault) BScreen::SetMode(display_mode *mode, bool makeDefault)
{ {
if (screen != NULL) if (fScreen != NULL)
return screen->SetMode(B_ALL_WORKSPACES, mode, makeDefault); return fScreen->SetMode(B_ALL_WORKSPACES, mode, makeDefault);
return B_ERROR; return B_ERROR;
} }
@@ -373,8 +362,8 @@ BScreen::SetMode(display_mode *mode, bool makeDefault)
status_t status_t
BScreen::SetMode(uint32 workspace, display_mode *mode, bool makeDefault) BScreen::SetMode(uint32 workspace, display_mode *mode, bool makeDefault)
{ {
if (screen != NULL) if (fScreen != NULL)
return screen->SetMode(workspace, mode, makeDefault); return fScreen->SetMode(workspace, mode, makeDefault);
return B_ERROR; return B_ERROR;
} }
@@ -386,8 +375,8 @@ BScreen::SetMode(uint32 workspace, display_mode *mode, bool makeDefault)
status_t status_t
BScreen::GetDeviceInfo(accelerant_device_info *info) BScreen::GetDeviceInfo(accelerant_device_info *info)
{ {
if (screen != NULL) if (fScreen != NULL)
return screen->GetDeviceInfo(info); return fScreen->GetDeviceInfo(info);
return B_ERROR; return B_ERROR;
} }
@@ -402,8 +391,8 @@ BScreen::GetDeviceInfo(accelerant_device_info *info)
status_t status_t
BScreen::GetPixelClockLimits(display_mode *mode, uint32 *low, uint32 *high) BScreen::GetPixelClockLimits(display_mode *mode, uint32 *low, uint32 *high)
{ {
if (screen != NULL) if (fScreen != NULL)
return screen->GetPixelClockLimits(mode, low, high); return fScreen->GetPixelClockLimits(mode, low, high);
return B_ERROR; return B_ERROR;
} }
@@ -416,8 +405,8 @@ BScreen::GetPixelClockLimits(display_mode *mode, uint32 *low, uint32 *high)
status_t status_t
BScreen::GetTimingConstraints(display_timing_constraints *dtc) BScreen::GetTimingConstraints(display_timing_constraints *dtc)
{ {
if (screen != NULL) if (fScreen != NULL)
return screen->GetTimingConstraints(dtc); return fScreen->GetTimingConstraints(dtc);
return B_ERROR; return B_ERROR;
} }
@@ -434,8 +423,8 @@ BScreen::GetTimingConstraints(display_timing_constraints *dtc)
status_t status_t
BScreen::SetDPMS(uint32 dpms_state) BScreen::SetDPMS(uint32 dpms_state)
{ {
if (screen != NULL) if (fScreen != NULL)
return screen->SetDPMS(dpms_state); return fScreen->SetDPMS(dpms_state);
return B_ERROR; return B_ERROR;
} }
@@ -445,8 +434,8 @@ BScreen::SetDPMS(uint32 dpms_state)
uint32 uint32
BScreen::DPMSState() BScreen::DPMSState()
{ {
if (screen != NULL) if (fScreen != NULL)
return screen->DPMSState(); return fScreen->DPMSState();
return B_ERROR; return B_ERROR;
} }
@@ -456,8 +445,8 @@ BScreen::DPMSState()
uint32 uint32
BScreen::DPMSCapabilites() BScreen::DPMSCapabilites()
{ {
if (screen != NULL) if (fScreen != NULL)
return screen->DPMSCapabilites(); return fScreen->DPMSCapabilites();
return B_ERROR; return B_ERROR;
} }
@@ -468,7 +457,7 @@ BScreen::DPMSCapabilites()
BPrivateScreen* BPrivateScreen*
BScreen::private_screen() BScreen::private_screen()
{ {
return screen; return fScreen;
} }
@@ -503,8 +492,8 @@ BScreen::BScreen(const BScreen &screen)
void* void*
BScreen::BaseAddress() BScreen::BaseAddress()
{ {
if (screen != NULL) if (fScreen != NULL)
return screen->BaseAddress(); return fScreen->BaseAddress();
return NULL; return NULL;
} }
@@ -514,7 +503,7 @@ BScreen::BaseAddress()
uint32 uint32
BScreen::BytesPerRow() BScreen::BytesPerRow()
{ {
if (screen != NULL) if (fScreen != NULL)
return screen->BytesPerRow(); return fScreen->BytesPerRow();
return 0; return 0;
} }
+21 -1
View File
@@ -295,7 +295,27 @@ RootLayer::MoveBy(float x, float y)
void void
RootLayer::ResizeBy(float x, float y) RootLayer::ResizeBy(float x, float y)
{ {
// TODO: implement if (x == 0 && y == 0)
return;
// TODO: we should be able to update less here
//BRect previous = fFrame;
fFrame.right += x;
fFrame.bottom += y;
fFullVisible2.Set(Bounds());
fVisible2.Set(Bounds());
BRegion region(fFrame);
MarkForRebuild(region);
TriggerRebuild();
//region.Exclude(previous);
MarkForRedraw(region);
TriggerRedraw();
} }
+91 -74
View File
@@ -2000,9 +2000,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
// actually this isn't still enough as different workspaces can // actually this isn't still enough as different workspaces can
// have different display_modes // have different display_modes
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
fLink.Attach<display_mode>(mode); fLink.Attach<display_mode>(mode);
fLink.Attach<status_t>(B_OK);
fLink.Flush(); fLink.Flush();
break; break;
} }
@@ -2030,11 +2029,17 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
// TODO: lock RootLayer, set mode and tell it to update it's frame and all clipping // TODO: lock RootLayer, set mode and tell it to update it's frame and all clipping
// optionally put this into a message and let the root layer thread handle it. // optionally put this into a message and let the root layer thread handle it.
// status_t ret = fDesktop->ScreenAt(0)->SetMode(mode); RootLayer* rootLayer = fDesktop->ActiveRootLayer();
status_t ret = B_ERROR; rootLayer->Lock();
status_t status = fDesktop->ScreenAt(0)->SetMode(mode);
if (status == B_OK) {
BRect bounds = rootLayer->Bounds();
rootLayer->ResizeBy(mode.virtual_width - 1 - bounds.Width(),
mode.virtual_height - 1 - bounds.Height());
}
rootLayer->Unlock();
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(status);
fLink.Attach<status_t>(ret);
fLink.Flush(); fLink.Flush();
break; break;
} }
@@ -2050,16 +2055,20 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
link.Read<display_mode>(&low); link.Read<display_mode>(&low);
link.Read<display_mode>(&high); link.Read<display_mode>(&high);
status_t status = fDesktop->GetHWInterface()->ProposeMode(&target, &low, &high); status_t status = fDesktop->GetHWInterface()->ProposeMode(&target, &low, &high);
// TODO: We always return SERVER_TRUE and put the real
// error code in the message. FIX this. // ProposeMode() returns B_BAD_VALUE to hint that the candidate is
fLink.StartMessage(SERVER_TRUE); // not within the given limits (but is supported)
fLink.Attach<display_mode>(target); if (status == B_OK || status == B_BAD_VALUE) {
fLink.Attach<status_t>(status); fLink.StartMessage(B_OK);
fLink.Attach<display_mode>(target);
fLink.Attach<bool>(status == B_OK);
} else
fLink.StartMessage(status);
fLink.Flush(); fLink.Flush();
break; break;
} }
case AS_GET_MODE_LIST: case AS_GET_MODE_LIST:
{ {
screen_id id; screen_id id;
@@ -2068,14 +2077,15 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
display_mode* modeList; display_mode* modeList;
uint32 count; uint32 count;
if (fDesktop->GetHWInterface()->GetModeList(&modeList, &count) == B_OK) { status_t status = fDesktop->GetHWInterface()->GetModeList(&modeList, &count);
fLink.StartMessage(SERVER_TRUE); if (status == B_OK) {
fLink.StartMessage(B_OK);
fLink.Attach<uint32>(count); fLink.Attach<uint32>(count);
fLink.Attach(modeList, sizeof(display_mode) * count); fLink.Attach(modeList, sizeof(display_mode) * count);
delete[] modeList; delete[] modeList;
} else } else
fLink.StartMessage(SERVER_FALSE); fLink.StartMessage(status);
fLink.Flush(); fLink.Flush();
break; break;
@@ -2087,14 +2097,14 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
screen_id id; screen_id id;
link.Read<screen_id>(&id); link.Read<screen_id>(&id);
const color_map *colorMap = SystemColorMap(); const color_map *colorMap = SystemColorMap();
if (colorMap != NULL) { if (colorMap != NULL) {
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
fLink.Attach<color_map>(*colorMap); fLink.Attach<color_map>(*colorMap);
} else } else
fLink.StartMessage(SERVER_FALSE); fLink.StartMessage(B_ERROR);
fLink.Flush(); fLink.Flush();
break; break;
} }
@@ -2103,82 +2113,89 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
{ {
STRACE(("ServerApp %s: get desktop color\n", Signature())); STRACE(("ServerApp %s: get desktop color\n", Signature()));
uint32 workspaceIndex = 0; uint32 workspaceIndex;
link.Read<uint32>(&workspaceIndex); link.Read<uint32>(&workspaceIndex);
// ToDo: for some reason, we currently get "1" as no. of workspace
workspaceIndex = 0;
// ToDo: locking is probably wrong - why the hell is there no (safe) // ToDo: locking is probably wrong - why the hell is there no (safe)
// way to get to the workspace object directly? // way to get to the workspace object directly?
RootLayer *root = fDesktop->ActiveRootLayer(); RootLayer *root = fDesktop->ActiveRootLayer();
root->Lock(); root->Lock();
Workspace *workspace = root->WorkspaceAt(workspaceIndex); Workspace *workspace;
// we're nice to our children (and also take the default case
// into account which asks for the current workspace)
if (workspaceIndex > (uint32)root->WorkspaceCount())
workspace = root->ActiveWorkspace();
else
workspace = root->WorkspaceAt(workspaceIndex);
if (workspace != NULL) { if (workspace != NULL) {
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
fLink.Attach<rgb_color>(workspace->BGColor().GetColor32()); fLink.Attach<rgb_color>(workspace->BGColor().GetColor32());
} else } else
fLink.StartMessage(SERVER_FALSE); fLink.StartMessage(B_ERROR);
fLink.Flush(); fLink.Flush();
root->Unlock(); root->Unlock();
break; break;
} }
case AS_GET_ACCELERANT_INFO: case AS_GET_ACCELERANT_INFO:
{ {
STRACE(("ServerApp %s: get accelerant info\n", Signature())); STRACE(("ServerApp %s: get accelerant info\n", Signature()));
// We aren't using the screen_id for now... // We aren't using the screen_id for now...
screen_id id; screen_id id;
link.Read<screen_id>(&id); link.Read<screen_id>(&id);
accelerant_device_info accelerantInfo; accelerant_device_info accelerantInfo;
// TODO: I wonder if there should be a "desktop" lock... // TODO: I wonder if there should be a "desktop" lock...
if (fDesktop->GetHWInterface()->GetDeviceInfo(&accelerantInfo) == B_OK) { status_t status = fDesktop->GetHWInterface()->GetDeviceInfo(&accelerantInfo);
fLink.StartMessage(SERVER_TRUE); if (status == B_OK) {
fLink.StartMessage(B_OK);
fLink.Attach<accelerant_device_info>(accelerantInfo); fLink.Attach<accelerant_device_info>(accelerantInfo);
} else } else
fLink.StartMessage(SERVER_FALSE); fLink.StartMessage(status);
fLink.Flush(); fLink.Flush();
break; break;
} }
case AS_GET_RETRACE_SEMAPHORE: case AS_GET_RETRACE_SEMAPHORE:
{ {
STRACE(("ServerApp %s: get retrace semaphore\n", Signature())); STRACE(("ServerApp %s: get retrace semaphore\n", Signature()));
// We aren't using the screen_id for now... // We aren't using the screen_id for now...
screen_id id; screen_id id;
link.Read<screen_id>(&id); link.Read<screen_id>(&id);
sem_id semaphore = fDesktop->GetHWInterface()->RetraceSemaphore(); sem_id semaphore = fDesktop->GetHWInterface()->RetraceSemaphore();
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(semaphore);
fLink.Attach<sem_id>(semaphore);
fLink.Flush(); fLink.Flush();
break; break;
} }
case AS_GET_TIMING_CONSTRAINTS: case AS_GET_TIMING_CONSTRAINTS:
{ {
STRACE(("ServerApp %s: get timing constraints\n", Signature())); STRACE(("ServerApp %s: get timing constraints\n", Signature()));
// We aren't using the screen_id for now... // We aren't using the screen_id for now...
screen_id id; screen_id id;
link.Read<screen_id>(&id); link.Read<screen_id>(&id);
display_timing_constraints constraints; display_timing_constraints constraints;
if (fDesktop->GetHWInterface()->GetTimingConstraints(&constraints) == B_OK) { status_t status = fDesktop->GetHWInterface()->GetTimingConstraints(
fLink.StartMessage(SERVER_TRUE); &constraints);
if (status == B_OK) {
fLink.StartMessage(B_OK);
fLink.Attach<display_timing_constraints>(constraints); fLink.Attach<display_timing_constraints>(constraints);
} else } else
fLink.StartMessage(SERVER_FALSE); fLink.StartMessage(status);
fLink.Flush(); fLink.Flush();
break; break;
} }
case AS_GET_PIXEL_CLOCK_LIMITS: case AS_GET_PIXEL_CLOCK_LIMITS:
{ {
STRACE(("ServerApp %s: get pixel clock limits\n", Signature())); STRACE(("ServerApp %s: get pixel clock limits\n", Signature()));
@@ -2187,87 +2204,87 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
link.Read<screen_id>(&id); link.Read<screen_id>(&id);
display_mode mode; display_mode mode;
link.Read<display_mode>(&mode); link.Read<display_mode>(&mode);
uint32 low, high; uint32 low, high;
if (fDesktop->GetHWInterface()->GetPixelClockLimits(&mode, &low, &high) == B_OK) { status_t status = fDesktop->GetHWInterface()->GetPixelClockLimits(&mode,
fLink.StartMessage(SERVER_TRUE); &low, &high);
if (status == B_OK) {
fLink.StartMessage(B_OK);
fLink.Attach<uint32>(low); fLink.Attach<uint32>(low);
fLink.Attach<uint32>(high); fLink.Attach<uint32>(high);
} else } else
fLink.StartMessage(SERVER_FALSE); fLink.StartMessage(status);
fLink.Flush(); fLink.Flush();
break; break;
} }
case AS_SET_DPMS: case AS_SET_DPMS:
{ {
STRACE(("ServerApp %s: AS_SET_DPMS\n", Signature())); STRACE(("ServerApp %s: AS_SET_DPMS\n", Signature()));
screen_id id; screen_id id;
link.Read<screen_id>(&id); link.Read<screen_id>(&id);
uint32 mode; uint32 mode;
link.Read<uint32>(&mode); link.Read<uint32>(&mode);
if (fDesktop->GetHWInterface()->SetDPMSMode(mode) == B_OK) status_t status = fDesktop->GetHWInterface()->SetDPMSMode(mode);
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(status);
else
fLink.StartMessage(SERVER_FALSE);
fLink.Flush(); fLink.Flush();
break; break;
} }
case AS_GET_DPMS_STATE: case AS_GET_DPMS_STATE:
{ {
STRACE(("ServerApp %s: AS_GET_DPMS_STATE\n", Signature())); STRACE(("ServerApp %s: AS_GET_DPMS_STATE\n", Signature()));
screen_id id; screen_id id;
link.Read<screen_id>(&id); link.Read<screen_id>(&id);
uint32 state = fDesktop->GetHWInterface()->DPMSMode(); uint32 state = fDesktop->GetHWInterface()->DPMSMode();
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
fLink.Attach<uint32>(state); fLink.Attach<uint32>(state);
fLink.Flush(); fLink.Flush();
break; break;
} }
case AS_GET_DPMS_CAPABILITIES: case AS_GET_DPMS_CAPABILITIES:
{ {
STRACE(("ServerApp %s: AS_GET_DPMS_CAPABILITIES\n", Signature())); STRACE(("ServerApp %s: AS_GET_DPMS_CAPABILITIES\n", Signature()));
screen_id id; screen_id id;
link.Read<screen_id>(&id); link.Read<screen_id>(&id);
uint32 capabilities = fDesktop->GetHWInterface()->DPMSCapabilities(); uint32 capabilities = fDesktop->GetHWInterface()->DPMSCapabilities();
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
fLink.Attach<uint32>(capabilities); fLink.Attach<uint32>(capabilities);
fLink.Flush(); fLink.Flush();
break; break;
} }
case AS_READ_BITMAP: case AS_READ_BITMAP:
{ {
STRACE(("ServerApp %s: AS_READ_BITMAP\n", Signature())); STRACE(("ServerApp %s: AS_READ_BITMAP\n", Signature()));
int32 bitmapToken; int32 bitmapToken;
link.Read<int32>(&bitmapToken); link.Read<int32>(&bitmapToken);
bool drawCursor = true; bool drawCursor = true;
link.Read<bool>(&drawCursor); link.Read<bool>(&drawCursor);
BRect bounds; BRect bounds;
link.Read<BRect>(&bounds); link.Read<BRect>(&bounds);
ServerBitmap *bitmap = FindBitmap(bitmapToken); ServerBitmap *bitmap = FindBitmap(bitmapToken);
if (bitmap != NULL) { if (bitmap != NULL) {
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
// TODO: Implement for real // TODO: Implement for real
} else } else
fLink.StartMessage(SERVER_FALSE); fLink.StartMessage(B_BAD_VALUE);
fLink.Flush(); fLink.Flush();
break; break;
} }
default: default:
printf("ServerApp %s received unhandled message code %ld\n", printf("ServerApp %s received unhandled message code %ld\n",
Signature(), code); Signature(), code);