1a817d6adSAxel Dörfler /* 2a817d6adSAxel Dörfler * Copyright 2002-2005, Haiku Inc. 3a817d6adSAxel Dörfler * Distributed under the terms of the MIT License. 4a817d6adSAxel Dörfler * 5a817d6adSAxel Dörfler * Authors: 6a817d6adSAxel Dörfler * Stefano Ceccherini (burton666@libero.it) 7a817d6adSAxel Dörfler * Axel Dörfler, axeld@pinc-software.de 8a817d6adSAxel Dörfler */ 9a817d6adSAxel Dörfler 10a817d6adSAxel Dörfler /** BPrivateScreen is the class which does the real work for 11a817d6adSAxel Dörfler * the proxy class BScreen (it interacts with the app server). 12a817d6adSAxel Dörfler */ 13a817d6adSAxel Dörfler 14a817d6adSAxel Dörfler 15*d9525baaSAxel Dörfler #include "AppMisc.h" 16466871ccSAxel Dörfler #include "AppServerLink.h" 17466871ccSAxel Dörfler #include "PrivateScreen.h" 18466871ccSAxel Dörfler #include "ServerProtocol.h" 19466871ccSAxel Dörfler 20a817d6adSAxel Dörfler #include <Autolock.h> 2116046321SStefano Ceccherini #include <Bitmap.h> 228eae8b05SStefano Ceccherini #include <Locker.h> 23624df6c6SStefano Ceccherini #include <Window.h> 24314a1024SStefano Ceccherini 25466871ccSAxel Dörfler #include <new> 26624df6c6SStefano Ceccherini 27466871ccSAxel Dörfler #include <stdlib.h> 2839ffb980SStefano Ceccherini 29624df6c6SStefano Ceccherini 30624df6c6SStefano Ceccherini // TODO: We should define this somewhere else 31624df6c6SStefano Ceccherini // We could find how R5 defines this, though it's not strictly necessary 3239ffb980SStefano Ceccherini // AFAIK, R5 here keeps also the screen width, height, colorspace, and some other things 3339ffb980SStefano Ceccherini // (it's 48 bytes big) 34624df6c6SStefano Ceccherini struct screen_desc { 35624df6c6SStefano Ceccherini void *base_address; 36624df6c6SStefano Ceccherini uint32 bytes_per_row; 37624df6c6SStefano Ceccherini }; 38624df6c6SStefano Ceccherini 39624df6c6SStefano Ceccherini 408eae8b05SStefano Ceccherini static BPrivateScreen *sScreen; 418eae8b05SStefano Ceccherini 428eae8b05SStefano Ceccherini // used to synchronize creation/deletion of the sScreen object 438eae8b05SStefano Ceccherini static BLocker sScreenLock("screen lock"); 44624df6c6SStefano Ceccherini 45624df6c6SStefano Ceccherini 46ca8ed922SStefano Ceccherini using namespace BPrivate; 47ca8ed922SStefano Ceccherini 48624df6c6SStefano Ceccherini BPrivateScreen * 49a817d6adSAxel Dörfler BPrivateScreen::CheckOut(BWindow *window) 50624df6c6SStefano Ceccherini { 51*d9525baaSAxel Dörfler screen_id id = B_MAIN_SCREEN_ID; 52*d9525baaSAxel Dörfler 53*d9525baaSAxel Dörfler if (window != NULL) { 54*d9525baaSAxel Dörfler BPrivate::AppServerLink link; 55*d9525baaSAxel Dörfler link.StartMessage(AS_GET_SCREEN_ID_FROM_WINDOW); 56*d9525baaSAxel Dörfler link.Attach<int32>(_get_object_token_(window)); 57*d9525baaSAxel Dörfler 58*d9525baaSAxel Dörfler status_t status; 59*d9525baaSAxel Dörfler if (link.FlushWithReply(status) == B_OK && status == B_OK) 60*d9525baaSAxel Dörfler link.Read<screen_id>(&id); 61*d9525baaSAxel Dörfler } 62*d9525baaSAxel Dörfler 63*d9525baaSAxel Dörfler return CheckOut(id); 64624df6c6SStefano Ceccherini } 65624df6c6SStefano Ceccherini 66624df6c6SStefano Ceccherini 67624df6c6SStefano Ceccherini BPrivateScreen * 68624df6c6SStefano Ceccherini BPrivateScreen::CheckOut(screen_id id) 69624df6c6SStefano Ceccherini { 70a817d6adSAxel Dörfler BAutolock locker(sScreenLock); 718eae8b05SStefano Ceccherini 72e93cd650SStefano Ceccherini if (sScreen == NULL) { 7339ffb980SStefano Ceccherini // TODO: If we start supporting multiple monitors, we 7439ffb980SStefano Ceccherini // should return the right object for the given screen_id 758eae8b05SStefano Ceccherini sScreen = new BPrivateScreen(); 768eae8b05SStefano Ceccherini } 778eae8b05SStefano Ceccherini 788eae8b05SStefano Ceccherini return sScreen; 79624df6c6SStefano Ceccherini } 80624df6c6SStefano Ceccherini 81624df6c6SStefano Ceccherini 82624df6c6SStefano Ceccherini void 83624df6c6SStefano Ceccherini BPrivateScreen::Return(BPrivateScreen *screen) 84624df6c6SStefano Ceccherini { 85e93cd650SStefano Ceccherini // Never delete the sScreen object. 86e93cd650SStefano Ceccherini // system_colors() expects the colormap to be 87e93cd650SStefano Ceccherini // permanently stored within libbe. 88624df6c6SStefano Ceccherini } 89624df6c6SStefano Ceccherini 90624df6c6SStefano Ceccherini 91624df6c6SStefano Ceccherini status_t 92624df6c6SStefano Ceccherini BPrivateScreen::SetToNext() 93624df6c6SStefano Ceccherini { 94624df6c6SStefano Ceccherini // This function always returns B_ERROR 95624df6c6SStefano Ceccherini return B_ERROR; 96624df6c6SStefano Ceccherini } 97624df6c6SStefano Ceccherini 98624df6c6SStefano Ceccherini 99624df6c6SStefano Ceccherini color_space 100624df6c6SStefano Ceccherini BPrivateScreen::ColorSpace() 101624df6c6SStefano Ceccherini { 102624df6c6SStefano Ceccherini display_mode mode; 1031f41d635SStefano Ceccherini if (GetMode(B_CURRENT_WORKSPACE, &mode) == B_OK) 104624df6c6SStefano Ceccherini return (color_space)mode.space; 105624df6c6SStefano Ceccherini 106624df6c6SStefano Ceccherini return B_NO_COLOR_SPACE; 107624df6c6SStefano Ceccherini } 108624df6c6SStefano Ceccherini 109624df6c6SStefano Ceccherini 110624df6c6SStefano Ceccherini BRect 111624df6c6SStefano Ceccherini BPrivateScreen::Frame() 112624df6c6SStefano Ceccherini { 11339ffb980SStefano Ceccherini // If something goes wrong, we just return this rectangle. 11439ffb980SStefano Ceccherini BRect rect(0, 0, 0, 0); 115624df6c6SStefano Ceccherini display_mode mode; 11634c39bf0SStefano Ceccherini if (GetMode(B_CURRENT_WORKSPACE, &mode) == B_OK) 11739ffb980SStefano Ceccherini rect.Set(0, 0, (float)mode.virtual_width - 1, (float)mode.virtual_height - 1); 11839ffb980SStefano Ceccherini 11939ffb980SStefano Ceccherini return rect; 120624df6c6SStefano Ceccherini } 121624df6c6SStefano Ceccherini 122624df6c6SStefano Ceccherini 123624df6c6SStefano Ceccherini screen_id 124624df6c6SStefano Ceccherini BPrivateScreen::ID() 125624df6c6SStefano Ceccherini { 12639ffb980SStefano Ceccherini // TODO: Change this if we start supporting multiple screens 127624df6c6SStefano Ceccherini return B_MAIN_SCREEN_ID; 128624df6c6SStefano Ceccherini } 129624df6c6SStefano Ceccherini 130624df6c6SStefano Ceccherini 131624df6c6SStefano Ceccherini status_t 132624df6c6SStefano Ceccherini BPrivateScreen::WaitForRetrace(bigtime_t timeout) 133624df6c6SStefano Ceccherini { 134624df6c6SStefano Ceccherini // Get the retrace semaphore if it's the first time 135624df6c6SStefano Ceccherini // we are called. Cache the value then. 136624df6c6SStefano Ceccherini status_t status; 13710c5dab8SStefano Ceccherini if (fRetraceSem < 0) 138a817d6adSAxel Dörfler fRetraceSem = _RetraceSemaphore(); 139624df6c6SStefano Ceccherini 140624df6c6SStefano Ceccherini do { 141624df6c6SStefano Ceccherini status = acquire_sem_etc(fRetraceSem, 1, B_RELATIVE_TIMEOUT, timeout); 142624df6c6SStefano Ceccherini } while (status == B_INTERRUPTED); 143624df6c6SStefano Ceccherini 144624df6c6SStefano Ceccherini return status; 145624df6c6SStefano Ceccherini } 146624df6c6SStefano Ceccherini 147624df6c6SStefano Ceccherini 148624df6c6SStefano Ceccherini uint8 149624df6c6SStefano Ceccherini BPrivateScreen::IndexForColor(uint8 red, uint8 green, uint8 blue, uint8 alpha) 150624df6c6SStefano Ceccherini { 151624df6c6SStefano Ceccherini // Looks like this check is necessary 152a817d6adSAxel Dörfler if (red == B_TRANSPARENT_COLOR.red 153a817d6adSAxel Dörfler && green == B_TRANSPARENT_COLOR.green 154a817d6adSAxel Dörfler && blue == B_TRANSPARENT_COLOR.blue 155a817d6adSAxel Dörfler && alpha == B_TRANSPARENT_COLOR.alpha) 156624df6c6SStefano Ceccherini return B_TRANSPARENT_8_BIT; 157624df6c6SStefano Ceccherini 1582e6a5805SStephan Aßmus uint16 index = ((blue & 0xf8) << 7) | ((green & 0xf8) << 2) | (red >> 3); 159a817d6adSAxel Dörfler if (ColorMap()) 1602ed35bc8SStefano Ceccherini return fColorMap->index_map[index]; 161624df6c6SStefano Ceccherini 162624df6c6SStefano Ceccherini return 0; 163624df6c6SStefano Ceccherini } 164624df6c6SStefano Ceccherini 165624df6c6SStefano Ceccherini 166624df6c6SStefano Ceccherini rgb_color 167624df6c6SStefano Ceccherini BPrivateScreen::ColorForIndex(const uint8 index) 168624df6c6SStefano Ceccherini { 169a817d6adSAxel Dörfler if (ColorMap()) 170624df6c6SStefano Ceccherini return fColorMap->color_list[index]; 171624df6c6SStefano Ceccherini 172624df6c6SStefano Ceccherini return rgb_color(); 173624df6c6SStefano Ceccherini } 174624df6c6SStefano Ceccherini 175624df6c6SStefano Ceccherini 176624df6c6SStefano Ceccherini uint8 177624df6c6SStefano Ceccherini BPrivateScreen::InvertIndex(uint8 index) 178624df6c6SStefano Ceccherini { 179a817d6adSAxel Dörfler if (ColorMap()) 180624df6c6SStefano Ceccherini return fColorMap->inversion_map[index]; 181624df6c6SStefano Ceccherini 182624df6c6SStefano Ceccherini return 0; 183624df6c6SStefano Ceccherini } 184624df6c6SStefano Ceccherini 185624df6c6SStefano Ceccherini 186624df6c6SStefano Ceccherini const color_map * 187624df6c6SStefano Ceccherini BPrivateScreen::ColorMap() 188624df6c6SStefano Ceccherini { 189a817d6adSAxel Dörfler if (fColorMap == NULL) { 190a817d6adSAxel Dörfler BAutolock locker(sScreenLock); 191a817d6adSAxel Dörfler 192a817d6adSAxel Dörfler if (fColorMap != NULL) { 193a817d6adSAxel Dörfler // someone could have been faster than us 194a817d6adSAxel Dörfler return fColorMap; 195a817d6adSAxel Dörfler } 196a817d6adSAxel Dörfler 197a817d6adSAxel Dörfler // TODO: BeOS R5 here gets the colormap pointer 198a817d6adSAxel Dörfler // (with BApplication::ro_offset_to_ptr() ?) 199a817d6adSAxel Dörfler // which is contained in a shared area created by the server. 200a817d6adSAxel Dörfler BPrivate::AppServerLink link; 201a817d6adSAxel Dörfler link.StartMessage(AS_SCREEN_GET_COLORMAP); 202a817d6adSAxel Dörfler link.Attach<screen_id>(ID()); 203a817d6adSAxel Dörfler 204a817d6adSAxel Dörfler status_t status; 205a817d6adSAxel Dörfler if (link.FlushWithReply(status) == B_OK && status == B_OK) { 206a817d6adSAxel Dörfler fColorMap = (color_map *)malloc(sizeof(color_map)); 207a817d6adSAxel Dörfler fOwnsColorMap = true; 208a817d6adSAxel Dörfler link.Read<color_map>(fColorMap); 209a817d6adSAxel Dörfler } 210a817d6adSAxel Dörfler } 211a817d6adSAxel Dörfler 212624df6c6SStefano Ceccherini return fColorMap; 213624df6c6SStefano Ceccherini } 214624df6c6SStefano Ceccherini 215624df6c6SStefano Ceccherini 216624df6c6SStefano Ceccherini status_t 217466871ccSAxel Dörfler BPrivateScreen::GetBitmap(BBitmap **_bitmap, bool drawCursor, BRect *bounds) 218624df6c6SStefano Ceccherini { 219466871ccSAxel Dörfler if (_bitmap == NULL) 22016046321SStefano Ceccherini return B_BAD_VALUE; 22116046321SStefano Ceccherini 222a817d6adSAxel Dörfler BRect rect; 223a817d6adSAxel Dörfler if (bounds != NULL) 224a817d6adSAxel Dörfler rect = *bounds; 225a817d6adSAxel Dörfler else 226a817d6adSAxel Dörfler rect = Frame(); 227a817d6adSAxel Dörfler 228a817d6adSAxel Dörfler BBitmap* bitmap = new (std::nothrow) BBitmap(rect, ColorSpace()); 229466871ccSAxel Dörfler if (bitmap == NULL) 230466871ccSAxel Dörfler return B_NO_MEMORY; 231466871ccSAxel Dörfler 232466871ccSAxel Dörfler status_t status = bitmap->InitCheck(); 233466871ccSAxel Dörfler if (status == B_OK) 234a817d6adSAxel Dörfler status = ReadBitmap(bitmap, drawCursor, &rect); 235466871ccSAxel Dörfler if (status != B_OK) { 236466871ccSAxel Dörfler delete bitmap; 237466871ccSAxel Dörfler return status; 238466871ccSAxel Dörfler } 239466871ccSAxel Dörfler 240466871ccSAxel Dörfler *_bitmap = bitmap; 241466871ccSAxel Dörfler return B_OK; 242624df6c6SStefano Ceccherini } 243624df6c6SStefano Ceccherini 244624df6c6SStefano Ceccherini 245624df6c6SStefano Ceccherini status_t 246a817d6adSAxel Dörfler BPrivateScreen::ReadBitmap(BBitmap *bitmap, bool drawCursor, BRect *bounds) 247624df6c6SStefano Ceccherini { 24816046321SStefano Ceccherini if (bitmap == NULL) 24916046321SStefano Ceccherini return B_BAD_VALUE; 25016046321SStefano Ceccherini 25116046321SStefano Ceccherini BRect rect; 252a817d6adSAxel Dörfler if (bounds != NULL) 253a817d6adSAxel Dörfler rect = *bounds; 25416046321SStefano Ceccherini else 25516046321SStefano Ceccherini rect = Frame(); 25616046321SStefano Ceccherini 25716046321SStefano Ceccherini BPrivate::AppServerLink link; 25816046321SStefano Ceccherini link.StartMessage(AS_READ_BITMAP); 25916046321SStefano Ceccherini link.Attach<int32>(bitmap->get_server_token()); 26016046321SStefano Ceccherini link.Attach<bool>(drawCursor); 26116046321SStefano Ceccherini link.Attach<BRect>(rect); 26216046321SStefano Ceccherini 263a817d6adSAxel Dörfler status_t status = B_ERROR; 264a817d6adSAxel Dörfler if (link.FlushWithReply(status) < B_OK || status != B_OK) 265a817d6adSAxel Dörfler return status; 26616046321SStefano Ceccherini 26716046321SStefano Ceccherini return B_OK; 268624df6c6SStefano Ceccherini } 269624df6c6SStefano Ceccherini 270624df6c6SStefano Ceccherini 271624df6c6SStefano Ceccherini rgb_color 27239ffb980SStefano Ceccherini BPrivateScreen::DesktopColor(uint32 workspace) 273624df6c6SStefano Ceccherini { 2743ba7d6f3SAxel Dörfler rgb_color color = { 51, 102, 152, 255 }; 275dd10337fSAxel Dörfler BPrivate::AppServerLink link; 2763ba7d6f3SAxel Dörfler 2773ba7d6f3SAxel Dörfler link.StartMessage(AS_GET_DESKTOP_COLOR); 2783f319b33SMichael Lotz link.Attach<uint32>(workspace); 2793ba7d6f3SAxel Dörfler 2803ba7d6f3SAxel Dörfler int32 code; 281dd10337fSAxel Dörfler if (link.FlushWithReply(code) == B_OK 282a817d6adSAxel Dörfler && code == B_OK) 2833ba7d6f3SAxel Dörfler link.Read<rgb_color>(&color); 2843ba7d6f3SAxel Dörfler 28539ffb980SStefano Ceccherini return color; 286624df6c6SStefano Ceccherini } 287624df6c6SStefano Ceccherini 288624df6c6SStefano Ceccherini 289624df6c6SStefano Ceccherini void 290a817d6adSAxel Dörfler BPrivateScreen::SetDesktopColor(rgb_color color, uint32 workspace, 291a817d6adSAxel Dörfler bool makeDefault) 292624df6c6SStefano Ceccherini { 293dd10337fSAxel Dörfler BPrivate::AppServerLink link; 2943ba7d6f3SAxel Dörfler 2953ba7d6f3SAxel Dörfler link.StartMessage(AS_SET_DESKTOP_COLOR); 29639ffb980SStefano Ceccherini link.Attach<rgb_color>(color); 29739ffb980SStefano Ceccherini link.Attach<int32>(workspace); 29839ffb980SStefano Ceccherini link.Attach<bool>(makeDefault); 29939ffb980SStefano Ceccherini link.Flush(); 300624df6c6SStefano Ceccherini } 301624df6c6SStefano Ceccherini 302624df6c6SStefano Ceccherini 303624df6c6SStefano Ceccherini status_t 304c6418981SStefano Ceccherini BPrivateScreen::ProposeMode(display_mode *target, 305c6418981SStefano Ceccherini const display_mode *low, const display_mode *high) 306624df6c6SStefano Ceccherini { 307c6418981SStefano Ceccherini // We can't return B_BAD_VALUE here, because it's used to indicate 308c6418981SStefano Ceccherini // that the mode returned is supported, but it doesn't fall 309c6418981SStefano Ceccherini // within the limit (see ProposeMode() documentation) 310c6418981SStefano Ceccherini if (target == NULL || low == NULL || high == NULL) 311624df6c6SStefano Ceccherini return B_ERROR; 312c6418981SStefano Ceccherini 313c6418981SStefano Ceccherini BPrivate::AppServerLink link; 314c6418981SStefano Ceccherini link.StartMessage(AS_PROPOSE_MODE); 315c6418981SStefano Ceccherini link.Attach<screen_id>(ID()); 316583f6c3eSStefano Ceccherini link.Attach<display_mode>(*target); 317583f6c3eSStefano Ceccherini link.Attach<display_mode>(*low); 318583f6c3eSStefano Ceccherini link.Attach<display_mode>(*high); 319583f6c3eSStefano Ceccherini 320c6418981SStefano Ceccherini status_t status = B_ERROR; 321a817d6adSAxel Dörfler if (link.FlushWithReply(status) == B_OK && status == B_OK) { 322c6418981SStefano Ceccherini link.Read<display_mode>(target); 323a817d6adSAxel Dörfler 324a817d6adSAxel Dörfler bool withinLimits; 325a817d6adSAxel Dörfler link.Read<bool>(&withinLimits); 326a817d6adSAxel Dörfler if (!withinLimits) 327a817d6adSAxel Dörfler status = B_BAD_VALUE; 328c6418981SStefano Ceccherini } 329c6418981SStefano Ceccherini 330c6418981SStefano Ceccherini return status; 331624df6c6SStefano Ceccherini } 332624df6c6SStefano Ceccherini 333624df6c6SStefano Ceccherini 334624df6c6SStefano Ceccherini status_t 335a817d6adSAxel Dörfler BPrivateScreen::GetModeList(display_mode **_modeList, uint32 *_count) 336624df6c6SStefano Ceccherini { 337a817d6adSAxel Dörfler if (_modeList == NULL || _count == NULL) 33810c5dab8SStefano Ceccherini return B_BAD_VALUE; 33910c5dab8SStefano Ceccherini 34010c5dab8SStefano Ceccherini BPrivate::AppServerLink link; 34110c5dab8SStefano Ceccherini link.StartMessage(AS_GET_MODE_LIST); 34210c5dab8SStefano Ceccherini link.Attach<screen_id>(ID()); 343a817d6adSAxel Dörfler 344a817d6adSAxel Dörfler status_t status = B_ERROR; 345a817d6adSAxel Dörfler if (link.FlushWithReply(status) == B_OK && status == B_OK) { 346a817d6adSAxel Dörfler link.Read<uint32>(_count); 347a817d6adSAxel Dörfler // TODO: this could get too big for the link 348a817d6adSAxel Dörfler int32 size = *_count * sizeof(display_mode); 349a817d6adSAxel Dörfler *_modeList = (display_mode *)malloc(size); 350a817d6adSAxel Dörfler if (_modeList == NULL) 351a817d6adSAxel Dörfler return B_NO_MEMORY; 352a817d6adSAxel Dörfler 353a817d6adSAxel Dörfler link.Read(*_modeList, size); 35410c5dab8SStefano Ceccherini } 35510c5dab8SStefano Ceccherini 35610c5dab8SStefano Ceccherini return status; 357624df6c6SStefano Ceccherini } 358624df6c6SStefano Ceccherini 359624df6c6SStefano Ceccherini 360624df6c6SStefano Ceccherini status_t 361624df6c6SStefano Ceccherini BPrivateScreen::GetMode(uint32 workspace, display_mode *mode) 362624df6c6SStefano Ceccherini { 363314a1024SStefano Ceccherini if (mode == NULL) 364314a1024SStefano Ceccherini return B_BAD_VALUE; 365314a1024SStefano Ceccherini 366dd10337fSAxel Dörfler BPrivate::AppServerLink link; 36734c39bf0SStefano Ceccherini link.StartMessage(AS_SCREEN_GET_MODE); 36834c39bf0SStefano Ceccherini link.Attach<screen_id>(ID()); 36939ffb980SStefano Ceccherini link.Attach<uint32>(workspace); 370fca6492fSStefano Ceccherini 37134c39bf0SStefano Ceccherini status_t status = B_ERROR; 372a817d6adSAxel Dörfler if (link.FlushWithReply(status) != B_OK 373a817d6adSAxel Dörfler || status != B_OK) 37439ffb980SStefano Ceccherini return status; 375a817d6adSAxel Dörfler 376a817d6adSAxel Dörfler link.Read<display_mode>(mode); 377a817d6adSAxel Dörfler return B_OK; 378624df6c6SStefano Ceccherini } 379624df6c6SStefano Ceccherini 380624df6c6SStefano Ceccherini 381624df6c6SStefano Ceccherini status_t 382624df6c6SStefano Ceccherini BPrivateScreen::SetMode(uint32 workspace, display_mode *mode, bool makeDefault) 383624df6c6SStefano Ceccherini { 384314a1024SStefano Ceccherini if (mode == NULL) 385314a1024SStefano Ceccherini return B_BAD_VALUE; 386314a1024SStefano Ceccherini 387dd10337fSAxel Dörfler BPrivate::AppServerLink link; 388314a1024SStefano Ceccherini link.StartMessage(AS_SCREEN_SET_MODE); 389314a1024SStefano Ceccherini link.Attach<screen_id>(ID()); 39039ffb980SStefano Ceccherini link.Attach<uint32>(workspace); 39139ffb980SStefano Ceccherini link.Attach<display_mode>(*mode); 39239ffb980SStefano Ceccherini link.Attach<bool>(makeDefault); 393314a1024SStefano Ceccherini 394314a1024SStefano Ceccherini status_t status = B_ERROR; 395a817d6adSAxel Dörfler link.FlushWithReply(status); 396314a1024SStefano Ceccherini 39739ffb980SStefano Ceccherini return status; 398624df6c6SStefano Ceccherini } 399624df6c6SStefano Ceccherini 400624df6c6SStefano Ceccherini 401624df6c6SStefano Ceccherini status_t 402624df6c6SStefano Ceccherini BPrivateScreen::GetDeviceInfo(accelerant_device_info *info) 403624df6c6SStefano Ceccherini { 404c6418981SStefano Ceccherini if (info == NULL) 405c6418981SStefano Ceccherini return B_BAD_VALUE; 406c6418981SStefano Ceccherini 407c6418981SStefano Ceccherini BPrivate::AppServerLink link; 408c6418981SStefano Ceccherini link.StartMessage(AS_GET_ACCELERANT_INFO); 409c6418981SStefano Ceccherini link.Attach<screen_id>(ID()); 410a817d6adSAxel Dörfler 411a817d6adSAxel Dörfler status_t status = B_ERROR; 412a817d6adSAxel Dörfler if (link.FlushWithReply(status) == B_OK && status == B_OK) { 413c6418981SStefano Ceccherini link.Read<accelerant_device_info>(info); 414c6418981SStefano Ceccherini return B_OK; 415c6418981SStefano Ceccherini } 416c6418981SStefano Ceccherini 417a817d6adSAxel Dörfler return status; 418624df6c6SStefano Ceccherini } 419624df6c6SStefano Ceccherini 420624df6c6SStefano Ceccherini 421624df6c6SStefano Ceccherini status_t 422624df6c6SStefano Ceccherini BPrivateScreen::GetPixelClockLimits(display_mode *mode, uint32 *low, uint32 *high) 423624df6c6SStefano Ceccherini { 42475de27f8SStefano Ceccherini if (mode == NULL || low == NULL || high == NULL) 42575de27f8SStefano Ceccherini return B_BAD_VALUE; 42675de27f8SStefano Ceccherini 42775de27f8SStefano Ceccherini BPrivate::AppServerLink link; 42875de27f8SStefano Ceccherini link.StartMessage(AS_GET_PIXEL_CLOCK_LIMITS); 42975de27f8SStefano Ceccherini link.Attach<screen_id>(ID()); 43075de27f8SStefano Ceccherini link.Attach<display_mode>(*mode); 43175de27f8SStefano Ceccherini 432a817d6adSAxel Dörfler status_t status; 433a817d6adSAxel Dörfler if (link.FlushWithReply(status) == B_OK && status == B_OK) { 43475de27f8SStefano Ceccherini link.Read<uint32>(low); 43575de27f8SStefano Ceccherini link.Read<uint32>(high); 43675de27f8SStefano Ceccherini return B_OK; 43775de27f8SStefano Ceccherini } 43875de27f8SStefano Ceccherini 439a817d6adSAxel Dörfler return status; 440624df6c6SStefano Ceccherini } 441624df6c6SStefano Ceccherini 442624df6c6SStefano Ceccherini 443624df6c6SStefano Ceccherini status_t 444a817d6adSAxel Dörfler BPrivateScreen::GetTimingConstraints(display_timing_constraints *constraints) 445624df6c6SStefano Ceccherini { 446a817d6adSAxel Dörfler if (constraints == NULL) 44755b222b0SStefano Ceccherini return B_BAD_VALUE; 44855b222b0SStefano Ceccherini 44975de27f8SStefano Ceccherini BPrivate::AppServerLink link; 45075de27f8SStefano Ceccherini link.StartMessage(AS_GET_TIMING_CONSTRAINTS); 45175de27f8SStefano Ceccherini link.Attach<screen_id>(ID()); 45275de27f8SStefano Ceccherini 453a817d6adSAxel Dörfler status_t status = B_ERROR; 454a817d6adSAxel Dörfler if (link.FlushWithReply(status) == B_OK && status == B_OK) { 455a817d6adSAxel Dörfler link.Read<display_timing_constraints>(constraints); 45675de27f8SStefano Ceccherini return B_OK; 45775de27f8SStefano Ceccherini } 45875de27f8SStefano Ceccherini 459a817d6adSAxel Dörfler return status; 460624df6c6SStefano Ceccherini } 461624df6c6SStefano Ceccherini 462624df6c6SStefano Ceccherini 463624df6c6SStefano Ceccherini status_t 464624df6c6SStefano Ceccherini BPrivateScreen::SetDPMS(uint32 dpmsState) 465624df6c6SStefano Ceccherini { 466dd10337fSAxel Dörfler BPrivate::AppServerLink link; 46755b222b0SStefano Ceccherini link.StartMessage(AS_SET_DPMS); 46839ffb980SStefano Ceccherini link.Attach<screen_id>(ID()); 46939ffb980SStefano Ceccherini link.Attach<uint32>(dpmsState); 47055b222b0SStefano Ceccherini 471a817d6adSAxel Dörfler status_t status = B_ERROR; 472a817d6adSAxel Dörfler link.FlushWithReply(status); 473a817d6adSAxel Dörfler 474a817d6adSAxel Dörfler return status; 475624df6c6SStefano Ceccherini } 476624df6c6SStefano Ceccherini 477624df6c6SStefano Ceccherini 478624df6c6SStefano Ceccherini uint32 479624df6c6SStefano Ceccherini BPrivateScreen::DPMSState() 480624df6c6SStefano Ceccherini { 48139ffb980SStefano Ceccherini uint32 state = 0; 48255b222b0SStefano Ceccherini 483dd10337fSAxel Dörfler BPrivate::AppServerLink link; 48455b222b0SStefano Ceccherini link.StartMessage(AS_GET_DPMS_STATE); 48539ffb980SStefano Ceccherini link.Attach<screen_id>(ID()); 486a817d6adSAxel Dörfler 487a817d6adSAxel Dörfler status_t status; 488a817d6adSAxel Dörfler if (link.FlushWithReply(status) == B_OK && status == B_OK) 48955b222b0SStefano Ceccherini link.Read<uint32>(&state); 49055b222b0SStefano Ceccherini 49139ffb980SStefano Ceccherini return state; 492624df6c6SStefano Ceccherini } 493624df6c6SStefano Ceccherini 494624df6c6SStefano Ceccherini 495624df6c6SStefano Ceccherini uint32 496624df6c6SStefano Ceccherini BPrivateScreen::DPMSCapabilites() 497624df6c6SStefano Ceccherini { 49839ffb980SStefano Ceccherini uint32 capabilities = 0; 49955b222b0SStefano Ceccherini 500dd10337fSAxel Dörfler BPrivate::AppServerLink link; 50155b222b0SStefano Ceccherini link.StartMessage(AS_GET_DPMS_CAPABILITIES); 50239ffb980SStefano Ceccherini link.Attach<screen_id>(ID()); 503a817d6adSAxel Dörfler 504a817d6adSAxel Dörfler status_t status; 505a817d6adSAxel Dörfler if (link.FlushWithReply(status) == B_OK && status == B_OK) 50655b222b0SStefano Ceccherini link.Read<uint32>(&capabilities); 50755b222b0SStefano Ceccherini 50839ffb980SStefano Ceccherini return capabilities; 509624df6c6SStefano Ceccherini } 510624df6c6SStefano Ceccherini 511624df6c6SStefano Ceccherini 512624df6c6SStefano Ceccherini void * 513624df6c6SStefano Ceccherini BPrivateScreen::BaseAddress() 514624df6c6SStefano Ceccherini { 515624df6c6SStefano Ceccherini screen_desc desc; 516624df6c6SStefano Ceccherini if (get_screen_desc(&desc) == B_OK) 517624df6c6SStefano Ceccherini return desc.base_address; 518624df6c6SStefano Ceccherini 519624df6c6SStefano Ceccherini return NULL; 520624df6c6SStefano Ceccherini } 521624df6c6SStefano Ceccherini 522624df6c6SStefano Ceccherini 523624df6c6SStefano Ceccherini uint32 524624df6c6SStefano Ceccherini BPrivateScreen::BytesPerRow() 525624df6c6SStefano Ceccherini { 526624df6c6SStefano Ceccherini screen_desc desc; 527624df6c6SStefano Ceccherini if (get_screen_desc(&desc) == B_OK) 528624df6c6SStefano Ceccherini return desc.bytes_per_row; 529a817d6adSAxel Dörfler 530624df6c6SStefano Ceccherini return 0; 531624df6c6SStefano Ceccherini } 532624df6c6SStefano Ceccherini 533624df6c6SStefano Ceccherini 534624df6c6SStefano Ceccherini status_t 535624df6c6SStefano Ceccherini BPrivateScreen::get_screen_desc(screen_desc *desc) 536624df6c6SStefano Ceccherini { 53739ffb980SStefano Ceccherini status_t status = B_ERROR; 53839ffb980SStefano Ceccherini /* 539dd10337fSAxel Dörfler BPrivate::AppServerLink link; 54039ffb980SStefano Ceccherini PortMessage reply; 54139ffb980SStefano Ceccherini link.SetOpCode(AS_GET_SCREEN_DESC); 54239ffb980SStefano Ceccherini link.Attach<screen_id>(ID()); 54339ffb980SStefano Ceccherini link.FlushWithReply(&reply); 54439ffb980SStefano Ceccherini reply.Read<screen_desc>(*desc); 54539ffb980SStefano Ceccherini reply.Read<status_t>(&status); 54639ffb980SStefano Ceccherini */ 54739ffb980SStefano Ceccherini return status; 548624df6c6SStefano Ceccherini } 549624df6c6SStefano Ceccherini 550624df6c6SStefano Ceccherini 551a817d6adSAxel Dörfler // #pragma mark - private methods 55275de27f8SStefano Ceccherini 553a817d6adSAxel Dörfler 554a817d6adSAxel Dörfler sem_id 555a817d6adSAxel Dörfler BPrivateScreen::_RetraceSemaphore() 556a817d6adSAxel Dörfler { 55775de27f8SStefano Ceccherini BPrivate::AppServerLink link; 55875de27f8SStefano Ceccherini link.StartMessage(AS_GET_RETRACE_SEMAPHORE); 55975de27f8SStefano Ceccherini link.Attach<screen_id>(ID()); 560a817d6adSAxel Dörfler 561a817d6adSAxel Dörfler sem_id id = B_BAD_SEM_ID; 562a817d6adSAxel Dörfler link.FlushWithReply(id); 56375de27f8SStefano Ceccherini 56475de27f8SStefano Ceccherini return id; 56575de27f8SStefano Ceccherini } 56675de27f8SStefano Ceccherini 56775de27f8SStefano Ceccherini 568624df6c6SStefano Ceccherini BPrivateScreen::BPrivateScreen() 569624df6c6SStefano Ceccherini : 570624df6c6SStefano Ceccherini fColorMap(NULL), 571624df6c6SStefano Ceccherini fRetraceSem(-1), 572624df6c6SStefano Ceccherini fOwnsColorMap(false) 573624df6c6SStefano Ceccherini { 574624df6c6SStefano Ceccherini } 575624df6c6SStefano Ceccherini 576624df6c6SStefano Ceccherini 577624df6c6SStefano Ceccherini BPrivateScreen::~BPrivateScreen() 578624df6c6SStefano Ceccherini { 579624df6c6SStefano Ceccherini if (fOwnsColorMap) 580624df6c6SStefano Ceccherini free(fColorMap); 581624df6c6SStefano Ceccherini } 582