1624df6c6SStefano Ceccherini //------------------------------------------------------------------------------ 21f41d635SStefano Ceccherini // Copyright (c) 2002-2005, Haiku 3624df6c6SStefano Ceccherini // 4624df6c6SStefano Ceccherini // Permission is hereby granted, free of charge, to any person obtaining a 5624df6c6SStefano Ceccherini // copy of this software and associated documentation files (the "Software"), 6624df6c6SStefano Ceccherini // to deal in the Software without restriction, including without limitation 7624df6c6SStefano Ceccherini // the rights to use, copy, modify, merge, publish, distribute, sublicense, 8624df6c6SStefano Ceccherini // and/or sell copies of the Software, and to permit persons to whom the 9624df6c6SStefano Ceccherini // Software is furnished to do so, subject to the following conditions: 10624df6c6SStefano Ceccherini // 11624df6c6SStefano Ceccherini // The above copyright notice and this permission notice shall be included in 12624df6c6SStefano Ceccherini // all copies or substantial portions of the Software. 13624df6c6SStefano Ceccherini // 14624df6c6SStefano Ceccherini // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15624df6c6SStefano Ceccherini // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16624df6c6SStefano Ceccherini // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17624df6c6SStefano Ceccherini // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18624df6c6SStefano Ceccherini // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19624df6c6SStefano Ceccherini // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20624df6c6SStefano Ceccherini // DEALINGS IN THE SOFTWARE. 21624df6c6SStefano Ceccherini // 22624df6c6SStefano Ceccherini // File Name: PrivateScreen.cpp 23624df6c6SStefano Ceccherini // Author: Stefano Ceccherini (burton666@libero.it) 24624df6c6SStefano Ceccherini // Description: BPrivateScreen is the class which does the real work 25624df6c6SStefano Ceccherini // for the proxy class BScreen (it interacts with the app server). 26624df6c6SStefano Ceccherini //------------------------------------------------------------------------------ 27*466871ccSAxel Dörfler #include "AppServerLink.h" 28*466871ccSAxel Dörfler #include "PrivateScreen.h" 29*466871ccSAxel Dörfler #include "ServerProtocol.h" 30*466871ccSAxel Dörfler 3116046321SStefano Ceccherini #include <Bitmap.h> 328eae8b05SStefano Ceccherini #include <Locker.h> 33624df6c6SStefano Ceccherini #include <Window.h> 34314a1024SStefano Ceccherini 35*466871ccSAxel Dörfler #include <new> 36624df6c6SStefano Ceccherini 37*466871ccSAxel Dörfler #include <stdlib.h> 3839ffb980SStefano Ceccherini 39624df6c6SStefano Ceccherini 40624df6c6SStefano Ceccherini // TODO: We should define this somewhere else 41624df6c6SStefano Ceccherini // We could find how R5 defines this, though it's not strictly necessary 4239ffb980SStefano Ceccherini // AFAIK, R5 here keeps also the screen width, height, colorspace, and some other things 4339ffb980SStefano Ceccherini // (it's 48 bytes big) 44624df6c6SStefano Ceccherini struct screen_desc { 45624df6c6SStefano Ceccherini void *base_address; 46624df6c6SStefano Ceccherini uint32 bytes_per_row; 47624df6c6SStefano Ceccherini }; 48624df6c6SStefano Ceccherini 49624df6c6SStefano Ceccherini 508eae8b05SStefano Ceccherini static BPrivateScreen *sScreen; 518eae8b05SStefano Ceccherini 528eae8b05SStefano Ceccherini // used to synchronize creation/deletion of the sScreen object 538eae8b05SStefano Ceccherini static BLocker sScreenLock("screen lock"); 54624df6c6SStefano Ceccherini 55624df6c6SStefano Ceccherini 56ca8ed922SStefano Ceccherini using namespace BPrivate; 57ca8ed922SStefano Ceccherini 58624df6c6SStefano Ceccherini BPrivateScreen * 59624df6c6SStefano Ceccherini BPrivateScreen::CheckOut(BWindow *win) 60624df6c6SStefano Ceccherini { 618eae8b05SStefano Ceccherini sScreenLock.Lock(); 628eae8b05SStefano Ceccherini 63e93cd650SStefano Ceccherini if (sScreen == NULL) { 6439ffb980SStefano Ceccherini // TODO: If we start supporting multiple monitors, we 6539ffb980SStefano Ceccherini // should return the right screen for the passed BWindow 668eae8b05SStefano Ceccherini sScreen = new BPrivateScreen(); 678eae8b05SStefano Ceccherini } 688eae8b05SStefano Ceccherini 698eae8b05SStefano Ceccherini sScreenLock.Unlock(); 708eae8b05SStefano Ceccherini 718eae8b05SStefano Ceccherini return sScreen; 72624df6c6SStefano Ceccherini } 73624df6c6SStefano Ceccherini 74624df6c6SStefano Ceccherini 75624df6c6SStefano Ceccherini BPrivateScreen * 76624df6c6SStefano Ceccherini BPrivateScreen::CheckOut(screen_id id) 77624df6c6SStefano Ceccherini { 788eae8b05SStefano Ceccherini sScreenLock.Lock(); 798eae8b05SStefano Ceccherini 80e93cd650SStefano Ceccherini if (sScreen == NULL) { 8139ffb980SStefano Ceccherini // TODO: If we start supporting multiple monitors, we 8239ffb980SStefano Ceccherini // should return the right object for the given screen_id 838eae8b05SStefano Ceccherini sScreen = new BPrivateScreen(); 848eae8b05SStefano Ceccherini } 858eae8b05SStefano Ceccherini 868eae8b05SStefano Ceccherini sScreenLock.Unlock(); 878eae8b05SStefano Ceccherini 888eae8b05SStefano Ceccherini return sScreen; 89624df6c6SStefano Ceccherini } 90624df6c6SStefano Ceccherini 91624df6c6SStefano Ceccherini 92624df6c6SStefano Ceccherini void 93624df6c6SStefano Ceccherini BPrivateScreen::Return(BPrivateScreen *screen) 94624df6c6SStefano Ceccherini { 95e93cd650SStefano Ceccherini // Never delete the sScreen object. 96e93cd650SStefano Ceccherini // system_colors() expects the colormap to be 97e93cd650SStefano Ceccherini // permanently stored within libbe. 98624df6c6SStefano Ceccherini } 99624df6c6SStefano Ceccherini 100624df6c6SStefano Ceccherini 101624df6c6SStefano Ceccherini status_t 102624df6c6SStefano Ceccherini BPrivateScreen::SetToNext() 103624df6c6SStefano Ceccherini { 104624df6c6SStefano Ceccherini // This function always returns B_ERROR 105624df6c6SStefano Ceccherini return B_ERROR; 106624df6c6SStefano Ceccherini } 107624df6c6SStefano Ceccherini 108624df6c6SStefano Ceccherini 109624df6c6SStefano Ceccherini color_space 110624df6c6SStefano Ceccherini BPrivateScreen::ColorSpace() 111624df6c6SStefano Ceccherini { 112624df6c6SStefano Ceccherini display_mode mode; 1131f41d635SStefano Ceccherini if (GetMode(B_CURRENT_WORKSPACE, &mode) == B_OK) 114624df6c6SStefano Ceccherini return (color_space)mode.space; 115624df6c6SStefano Ceccherini 116624df6c6SStefano Ceccherini return B_NO_COLOR_SPACE; 117624df6c6SStefano Ceccherini } 118624df6c6SStefano Ceccherini 119624df6c6SStefano Ceccherini 120624df6c6SStefano Ceccherini BRect 121624df6c6SStefano Ceccherini BPrivateScreen::Frame() 122624df6c6SStefano Ceccherini { 12339ffb980SStefano Ceccherini // If something goes wrong, we just return this rectangle. 12439ffb980SStefano Ceccherini BRect rect(0, 0, 0, 0); 125624df6c6SStefano Ceccherini display_mode mode; 12634c39bf0SStefano Ceccherini if (GetMode(B_CURRENT_WORKSPACE, &mode) == B_OK) 12739ffb980SStefano Ceccherini rect.Set(0, 0, (float)mode.virtual_width - 1, (float)mode.virtual_height - 1); 12839ffb980SStefano Ceccherini 12939ffb980SStefano Ceccherini return rect; 130624df6c6SStefano Ceccherini } 131624df6c6SStefano Ceccherini 132624df6c6SStefano Ceccherini 133624df6c6SStefano Ceccherini screen_id 134624df6c6SStefano Ceccherini BPrivateScreen::ID() 135624df6c6SStefano Ceccherini { 13639ffb980SStefano Ceccherini // TODO: Change this if we start supporting multiple screens 137624df6c6SStefano Ceccherini return B_MAIN_SCREEN_ID; 138624df6c6SStefano Ceccherini } 139624df6c6SStefano Ceccherini 140624df6c6SStefano Ceccherini 141624df6c6SStefano Ceccherini status_t 142624df6c6SStefano Ceccherini BPrivateScreen::WaitForRetrace(bigtime_t timeout) 143624df6c6SStefano Ceccherini { 144624df6c6SStefano Ceccherini // Get the retrace semaphore if it's the first time 145624df6c6SStefano Ceccherini // we are called. Cache the value then. 146624df6c6SStefano Ceccherini status_t status; 14710c5dab8SStefano Ceccherini if (fRetraceSem < 0) 148624df6c6SStefano Ceccherini fRetraceSem = RetraceSemaphore(); 149624df6c6SStefano Ceccherini 150624df6c6SStefano Ceccherini do { 151624df6c6SStefano Ceccherini status = acquire_sem_etc(fRetraceSem, 1, B_RELATIVE_TIMEOUT, timeout); 152624df6c6SStefano Ceccherini } while (status == B_INTERRUPTED); 153624df6c6SStefano Ceccherini 154624df6c6SStefano Ceccherini return status; 155624df6c6SStefano Ceccherini } 156624df6c6SStefano Ceccherini 157624df6c6SStefano Ceccherini 158624df6c6SStefano Ceccherini uint8 159624df6c6SStefano Ceccherini BPrivateScreen::IndexForColor(uint8 red, uint8 green, uint8 blue, uint8 alpha) 160624df6c6SStefano Ceccherini { 161624df6c6SStefano Ceccherini // Looks like this check is necessary 162624df6c6SStefano Ceccherini if (red == B_TRANSPARENT_COLOR.red && green == B_TRANSPARENT_COLOR.green && 163624df6c6SStefano Ceccherini blue == B_TRANSPARENT_COLOR.blue && alpha == B_TRANSPARENT_COLOR.alpha) 164624df6c6SStefano Ceccherini return B_TRANSPARENT_8_BIT; 165624df6c6SStefano Ceccherini 1662e6a5805SStephan Aßmus uint16 index = ((blue & 0xf8) << 7) | ((green & 0xf8) << 2) | (red >> 3); 167624df6c6SStefano Ceccherini if (fColorMap) 1682ed35bc8SStefano Ceccherini return fColorMap->index_map[index]; 169624df6c6SStefano Ceccherini 170624df6c6SStefano Ceccherini return 0; 171624df6c6SStefano Ceccherini } 172624df6c6SStefano Ceccherini 173624df6c6SStefano Ceccherini 174624df6c6SStefano Ceccherini rgb_color 175624df6c6SStefano Ceccherini BPrivateScreen::ColorForIndex(const uint8 index) 176624df6c6SStefano Ceccherini { 177624df6c6SStefano Ceccherini if (fColorMap) 178624df6c6SStefano Ceccherini return fColorMap->color_list[index]; 179624df6c6SStefano Ceccherini 180624df6c6SStefano Ceccherini return rgb_color(); 181624df6c6SStefano Ceccherini } 182624df6c6SStefano Ceccherini 183624df6c6SStefano Ceccherini 184624df6c6SStefano Ceccherini uint8 185624df6c6SStefano Ceccherini BPrivateScreen::InvertIndex(uint8 index) 186624df6c6SStefano Ceccherini { 187624df6c6SStefano Ceccherini if (fColorMap) 188624df6c6SStefano Ceccherini return fColorMap->inversion_map[index]; 189624df6c6SStefano Ceccherini 190624df6c6SStefano Ceccherini return 0; 191624df6c6SStefano Ceccherini } 192624df6c6SStefano Ceccherini 193624df6c6SStefano Ceccherini 194624df6c6SStefano Ceccherini const color_map * 195624df6c6SStefano Ceccherini BPrivateScreen::ColorMap() 196624df6c6SStefano Ceccherini { 197624df6c6SStefano Ceccherini return fColorMap; 198624df6c6SStefano Ceccherini } 199624df6c6SStefano Ceccherini 200624df6c6SStefano Ceccherini 201624df6c6SStefano Ceccherini status_t 202*466871ccSAxel Dörfler BPrivateScreen::GetBitmap(BBitmap **_bitmap, bool drawCursor, BRect *bounds) 203624df6c6SStefano Ceccherini { 204*466871ccSAxel Dörfler if (_bitmap == NULL) 20516046321SStefano Ceccherini return B_BAD_VALUE; 20616046321SStefano Ceccherini 207*466871ccSAxel Dörfler BBitmap* bitmap = new (std::nothrow) BBitmap(Frame(), ColorSpace()); 208*466871ccSAxel Dörfler if (bitmap == NULL) 209*466871ccSAxel Dörfler return B_NO_MEMORY; 210*466871ccSAxel Dörfler 211*466871ccSAxel Dörfler status_t status = bitmap->InitCheck(); 212*466871ccSAxel Dörfler if (status == B_OK) 213*466871ccSAxel Dörfler status = ReadBitmap(bitmap, drawCursor, bounds); 214*466871ccSAxel Dörfler if (status != B_OK) { 215*466871ccSAxel Dörfler delete bitmap; 216*466871ccSAxel Dörfler return status; 217*466871ccSAxel Dörfler } 218*466871ccSAxel Dörfler 219*466871ccSAxel Dörfler *_bitmap = bitmap; 220*466871ccSAxel Dörfler return B_OK; 221624df6c6SStefano Ceccherini } 222624df6c6SStefano Ceccherini 223624df6c6SStefano Ceccherini 224624df6c6SStefano Ceccherini status_t 225624df6c6SStefano Ceccherini BPrivateScreen::ReadBitmap(BBitmap *bitmap, bool drawCursor, BRect *bound) 226624df6c6SStefano Ceccherini { 22716046321SStefano Ceccherini if (bitmap == NULL) 22816046321SStefano Ceccherini return B_BAD_VALUE; 22916046321SStefano Ceccherini 23016046321SStefano Ceccherini BRect rect; 23116046321SStefano Ceccherini if (bound != NULL) 23216046321SStefano Ceccherini rect = *bound; 23316046321SStefano Ceccherini else 23416046321SStefano Ceccherini rect = Frame(); 23516046321SStefano Ceccherini 23616046321SStefano Ceccherini BPrivate::AppServerLink link; 23716046321SStefano Ceccherini link.StartMessage(AS_READ_BITMAP); 23816046321SStefano Ceccherini link.Attach<int32>(bitmap->get_server_token()); 23916046321SStefano Ceccherini link.Attach<bool>(drawCursor); 24016046321SStefano Ceccherini link.Attach<BRect>(rect); 24116046321SStefano Ceccherini 24216046321SStefano Ceccherini int32 code; 24316046321SStefano Ceccherini if (link.FlushWithReply(code) < B_OK || code != SERVER_TRUE) 244624df6c6SStefano Ceccherini return B_ERROR; 24516046321SStefano Ceccherini 24616046321SStefano Ceccherini return B_OK; 247624df6c6SStefano Ceccherini } 248624df6c6SStefano Ceccherini 249624df6c6SStefano Ceccherini 250624df6c6SStefano Ceccherini rgb_color 25139ffb980SStefano Ceccherini BPrivateScreen::DesktopColor(uint32 workspace) 252624df6c6SStefano Ceccherini { 2533ba7d6f3SAxel Dörfler rgb_color color = { 51, 102, 152, 255 }; 254dd10337fSAxel Dörfler BPrivate::AppServerLink link; 2553ba7d6f3SAxel Dörfler 2563ba7d6f3SAxel Dörfler link.StartMessage(AS_GET_DESKTOP_COLOR); 2573f319b33SMichael Lotz link.Attach<uint32>(workspace); 2583ba7d6f3SAxel Dörfler 2593ba7d6f3SAxel Dörfler int32 code; 260dd10337fSAxel Dörfler if (link.FlushWithReply(code) == B_OK 2613ba7d6f3SAxel Dörfler && code == SERVER_TRUE) 2623ba7d6f3SAxel Dörfler link.Read<rgb_color>(&color); 2633ba7d6f3SAxel Dörfler 26439ffb980SStefano Ceccherini return color; 265624df6c6SStefano Ceccherini } 266624df6c6SStefano Ceccherini 267624df6c6SStefano Ceccherini 268624df6c6SStefano Ceccherini void 26939ffb980SStefano Ceccherini BPrivateScreen::SetDesktopColor(rgb_color color, uint32 workspace, bool makeDefault) 270624df6c6SStefano Ceccherini { 271dd10337fSAxel Dörfler BPrivate::AppServerLink link; 2723ba7d6f3SAxel Dörfler 2733ba7d6f3SAxel Dörfler link.StartMessage(AS_SET_DESKTOP_COLOR); 27439ffb980SStefano Ceccherini link.Attach<rgb_color>(color); 27539ffb980SStefano Ceccherini link.Attach<int32>(workspace); 27639ffb980SStefano Ceccherini link.Attach<bool>(makeDefault); 27739ffb980SStefano Ceccherini link.Flush(); 278624df6c6SStefano Ceccherini } 279624df6c6SStefano Ceccherini 280624df6c6SStefano Ceccherini 281624df6c6SStefano Ceccherini status_t 282c6418981SStefano Ceccherini BPrivateScreen::ProposeMode(display_mode *target, 283c6418981SStefano Ceccherini const display_mode *low, const display_mode *high) 284624df6c6SStefano Ceccherini { 285c6418981SStefano Ceccherini // We can't return B_BAD_VALUE here, because it's used to indicate 286c6418981SStefano Ceccherini // that the mode returned is supported, but it doesn't fall 287c6418981SStefano Ceccherini // within the limit (see ProposeMode() documentation) 288c6418981SStefano Ceccherini if (target == NULL || low == NULL || high == NULL) 289624df6c6SStefano Ceccherini return B_ERROR; 290c6418981SStefano Ceccherini 291c6418981SStefano Ceccherini BPrivate::AppServerLink link; 292c6418981SStefano Ceccherini link.StartMessage(AS_PROPOSE_MODE); 293c6418981SStefano Ceccherini link.Attach<screen_id>(ID()); 294583f6c3eSStefano Ceccherini link.Attach<display_mode>(*target); 295583f6c3eSStefano Ceccherini link.Attach<display_mode>(*low); 296583f6c3eSStefano Ceccherini link.Attach<display_mode>(*high); 297583f6c3eSStefano Ceccherini 298c6418981SStefano Ceccherini int32 reply; 299c6418981SStefano Ceccherini status_t status = B_ERROR; 300c6418981SStefano Ceccherini if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE) { 301c6418981SStefano Ceccherini link.Read<display_mode>(target); 302c6418981SStefano Ceccherini // The status is important here. See documentation 303c6418981SStefano Ceccherini link.Read<status_t>(&status); 304c6418981SStefano Ceccherini } 305c6418981SStefano Ceccherini 306c6418981SStefano Ceccherini return status; 307624df6c6SStefano Ceccherini } 308624df6c6SStefano Ceccherini 309624df6c6SStefano Ceccherini 310624df6c6SStefano Ceccherini status_t 31110c5dab8SStefano Ceccherini BPrivateScreen::GetModeList(display_mode **modeList, uint32 *count) 312624df6c6SStefano Ceccherini { 31310c5dab8SStefano Ceccherini if (modeList == NULL || count == NULL) 31410c5dab8SStefano Ceccherini return B_BAD_VALUE; 31510c5dab8SStefano Ceccherini 31610c5dab8SStefano Ceccherini status_t status = B_ERROR; 31710c5dab8SStefano Ceccherini BPrivate::AppServerLink link; 31810c5dab8SStefano Ceccherini link.StartMessage(AS_GET_MODE_LIST); 31910c5dab8SStefano Ceccherini link.Attach<screen_id>(ID()); 32010c5dab8SStefano Ceccherini int32 reply; 32110c5dab8SStefano Ceccherini if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE) { 32210c5dab8SStefano Ceccherini link.Read<uint32>(count); 32310c5dab8SStefano Ceccherini int32 size = *count * sizeof(display_mode); 32410c5dab8SStefano Ceccherini *modeList = (display_mode *)malloc(size); 32510c5dab8SStefano Ceccherini link.Read(*modeList, size); 32610c5dab8SStefano Ceccherini // TODO: get status from app_server 32710c5dab8SStefano Ceccherini status = B_OK; 32810c5dab8SStefano Ceccherini } 32910c5dab8SStefano Ceccherini 33010c5dab8SStefano Ceccherini return status; 331624df6c6SStefano Ceccherini } 332624df6c6SStefano Ceccherini 333624df6c6SStefano Ceccherini 334624df6c6SStefano Ceccherini status_t 335624df6c6SStefano Ceccherini BPrivateScreen::GetMode(uint32 workspace, display_mode *mode) 336624df6c6SStefano Ceccherini { 337314a1024SStefano Ceccherini if (mode == NULL) 338314a1024SStefano Ceccherini return B_BAD_VALUE; 339314a1024SStefano Ceccherini 340dd10337fSAxel Dörfler BPrivate::AppServerLink link; 34134c39bf0SStefano Ceccherini link.StartMessage(AS_SCREEN_GET_MODE); 34234c39bf0SStefano Ceccherini link.Attach<screen_id>(ID()); 34339ffb980SStefano Ceccherini link.Attach<uint32>(workspace); 344fca6492fSStefano Ceccherini 345dd10337fSAxel Dörfler int32 code; 346dd10337fSAxel Dörfler if (link.FlushWithReply(code) != B_OK 347dd10337fSAxel Dörfler || code != SERVER_TRUE) 348fca6492fSStefano Ceccherini return B_ERROR; 34939ffb980SStefano Ceccherini 35034c39bf0SStefano Ceccherini display_mode currentMode; 35134c39bf0SStefano Ceccherini link.Read<display_mode>(¤tMode); 35234c39bf0SStefano Ceccherini 35334c39bf0SStefano Ceccherini status_t status = B_ERROR; 35434c39bf0SStefano Ceccherini link.Read<status_t>(&status); 35539ffb980SStefano Ceccherini if (status == B_OK && mode) 35639ffb980SStefano Ceccherini *mode = currentMode; 35734c39bf0SStefano Ceccherini 35839ffb980SStefano Ceccherini return status; 359624df6c6SStefano Ceccherini } 360624df6c6SStefano Ceccherini 361624df6c6SStefano Ceccherini 362624df6c6SStefano Ceccherini status_t 363624df6c6SStefano Ceccherini BPrivateScreen::SetMode(uint32 workspace, display_mode *mode, bool makeDefault) 364624df6c6SStefano Ceccherini { 365314a1024SStefano Ceccherini if (mode == NULL) 366314a1024SStefano Ceccherini return B_BAD_VALUE; 367314a1024SStefano Ceccherini 368dd10337fSAxel Dörfler BPrivate::AppServerLink link; 369314a1024SStefano Ceccherini link.StartMessage(AS_SCREEN_SET_MODE); 370314a1024SStefano Ceccherini link.Attach<screen_id>(ID()); 37139ffb980SStefano Ceccherini link.Attach<uint32>(workspace); 37239ffb980SStefano Ceccherini link.Attach<display_mode>(*mode); 37339ffb980SStefano Ceccherini link.Attach<bool>(makeDefault); 374314a1024SStefano Ceccherini 375314a1024SStefano Ceccherini status_t status = B_ERROR; 376dd10337fSAxel Dörfler int32 code; 377dd10337fSAxel Dörfler if (link.FlushWithReply(code) == B_OK && code == SERVER_TRUE) 378314a1024SStefano Ceccherini link.Read<status_t>(&status); 379314a1024SStefano Ceccherini 38039ffb980SStefano Ceccherini return status; 381624df6c6SStefano Ceccherini } 382624df6c6SStefano Ceccherini 383624df6c6SStefano Ceccherini 384624df6c6SStefano Ceccherini status_t 385624df6c6SStefano Ceccherini BPrivateScreen::GetDeviceInfo(accelerant_device_info *info) 386624df6c6SStefano Ceccherini { 387c6418981SStefano Ceccherini if (info == NULL) 388c6418981SStefano Ceccherini return B_BAD_VALUE; 389c6418981SStefano Ceccherini 390c6418981SStefano Ceccherini BPrivate::AppServerLink link; 391c6418981SStefano Ceccherini link.StartMessage(AS_GET_ACCELERANT_INFO); 392c6418981SStefano Ceccherini link.Attach<screen_id>(ID()); 393c6418981SStefano Ceccherini int32 code; 394c6418981SStefano Ceccherini if (link.FlushWithReply(code) == B_OK && code == SERVER_TRUE) { 395c6418981SStefano Ceccherini link.Read<accelerant_device_info>(info); 396c6418981SStefano Ceccherini return B_OK; 397c6418981SStefano Ceccherini } 398c6418981SStefano Ceccherini 399624df6c6SStefano Ceccherini return B_ERROR; 400624df6c6SStefano Ceccherini } 401624df6c6SStefano Ceccherini 402624df6c6SStefano Ceccherini 403624df6c6SStefano Ceccherini status_t 404624df6c6SStefano Ceccherini BPrivateScreen::GetPixelClockLimits(display_mode *mode, uint32 *low, uint32 *high) 405624df6c6SStefano Ceccherini { 40675de27f8SStefano Ceccherini if (mode == NULL || low == NULL || high == NULL) 40775de27f8SStefano Ceccherini return B_BAD_VALUE; 40875de27f8SStefano Ceccherini 40975de27f8SStefano Ceccherini BPrivate::AppServerLink link; 41075de27f8SStefano Ceccherini link.StartMessage(AS_GET_PIXEL_CLOCK_LIMITS); 41175de27f8SStefano Ceccherini link.Attach<screen_id>(ID()); 41275de27f8SStefano Ceccherini link.Attach<display_mode>(*mode); 41375de27f8SStefano Ceccherini 41475de27f8SStefano Ceccherini int32 code; 41575de27f8SStefano Ceccherini if (link.FlushWithReply(code) == B_OK && code == SERVER_TRUE) { 41675de27f8SStefano Ceccherini link.Read<uint32>(low); 41775de27f8SStefano Ceccherini link.Read<uint32>(high); 41875de27f8SStefano Ceccherini 41975de27f8SStefano Ceccherini return B_OK; 42075de27f8SStefano Ceccherini } 42175de27f8SStefano Ceccherini 422624df6c6SStefano Ceccherini return B_ERROR; 423624df6c6SStefano Ceccherini } 424624df6c6SStefano Ceccherini 425624df6c6SStefano Ceccherini 426624df6c6SStefano Ceccherini status_t 427624df6c6SStefano Ceccherini BPrivateScreen::GetTimingConstraints(display_timing_constraints *dtc) 428624df6c6SStefano Ceccherini { 42955b222b0SStefano Ceccherini if (dtc == NULL) 43055b222b0SStefano Ceccherini return B_BAD_VALUE; 43155b222b0SStefano Ceccherini 43275de27f8SStefano Ceccherini BPrivate::AppServerLink link; 43375de27f8SStefano Ceccherini link.StartMessage(AS_GET_TIMING_CONSTRAINTS); 43475de27f8SStefano Ceccherini link.Attach<screen_id>(ID()); 43575de27f8SStefano Ceccherini 43675de27f8SStefano Ceccherini int32 code; 43775de27f8SStefano Ceccherini if (link.FlushWithReply(code) == B_OK && code == SERVER_TRUE) { 43875de27f8SStefano Ceccherini link.Read<display_timing_constraints>(dtc); 43975de27f8SStefano Ceccherini return B_OK; 44075de27f8SStefano Ceccherini } 44175de27f8SStefano Ceccherini 442624df6c6SStefano Ceccherini return B_ERROR; 443624df6c6SStefano Ceccherini } 444624df6c6SStefano Ceccherini 445624df6c6SStefano Ceccherini 446624df6c6SStefano Ceccherini status_t 447624df6c6SStefano Ceccherini BPrivateScreen::SetDPMS(uint32 dpmsState) 448624df6c6SStefano Ceccherini { 449dd10337fSAxel Dörfler BPrivate::AppServerLink link; 45055b222b0SStefano Ceccherini link.StartMessage(AS_SET_DPMS); 45139ffb980SStefano Ceccherini link.Attach<screen_id>(ID()); 45239ffb980SStefano Ceccherini link.Attach<uint32>(dpmsState); 45355b222b0SStefano Ceccherini int32 reply; 45455b222b0SStefano Ceccherini if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE) 45555b222b0SStefano Ceccherini return B_OK; 45655b222b0SStefano Ceccherini 45755b222b0SStefano Ceccherini return B_ERROR; 458624df6c6SStefano Ceccherini } 459624df6c6SStefano Ceccherini 460624df6c6SStefano Ceccherini 461624df6c6SStefano Ceccherini uint32 462624df6c6SStefano Ceccherini BPrivateScreen::DPMSState() 463624df6c6SStefano Ceccherini { 46439ffb980SStefano Ceccherini uint32 state = 0; 46555b222b0SStefano Ceccherini 466dd10337fSAxel Dörfler BPrivate::AppServerLink link; 46755b222b0SStefano Ceccherini link.StartMessage(AS_GET_DPMS_STATE); 46839ffb980SStefano Ceccherini link.Attach<screen_id>(ID()); 46955b222b0SStefano Ceccherini int32 reply; 47055b222b0SStefano Ceccherini if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE) 47155b222b0SStefano Ceccherini link.Read<uint32>(&state); 47255b222b0SStefano Ceccherini 47339ffb980SStefano Ceccherini return state; 474624df6c6SStefano Ceccherini } 475624df6c6SStefano Ceccherini 476624df6c6SStefano Ceccherini 477624df6c6SStefano Ceccherini uint32 478624df6c6SStefano Ceccherini BPrivateScreen::DPMSCapabilites() 479624df6c6SStefano Ceccherini { 48039ffb980SStefano Ceccherini uint32 capabilities = 0; 48155b222b0SStefano Ceccherini 482dd10337fSAxel Dörfler BPrivate::AppServerLink link; 48355b222b0SStefano Ceccherini link.StartMessage(AS_GET_DPMS_CAPABILITIES); 48439ffb980SStefano Ceccherini link.Attach<screen_id>(ID()); 48555b222b0SStefano Ceccherini int32 reply; 48655b222b0SStefano Ceccherini if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE) 48755b222b0SStefano Ceccherini link.Read<uint32>(&capabilities); 48855b222b0SStefano Ceccherini 48939ffb980SStefano Ceccherini return capabilities; 490624df6c6SStefano Ceccherini } 491624df6c6SStefano Ceccherini 492624df6c6SStefano Ceccherini 493624df6c6SStefano Ceccherini void * 494624df6c6SStefano Ceccherini BPrivateScreen::BaseAddress() 495624df6c6SStefano Ceccherini { 496624df6c6SStefano Ceccherini screen_desc desc; 497624df6c6SStefano Ceccherini if (get_screen_desc(&desc) == B_OK) 498624df6c6SStefano Ceccherini return desc.base_address; 499624df6c6SStefano Ceccherini 500624df6c6SStefano Ceccherini return NULL; 501624df6c6SStefano Ceccherini } 502624df6c6SStefano Ceccherini 503624df6c6SStefano Ceccherini 504624df6c6SStefano Ceccherini uint32 505624df6c6SStefano Ceccherini BPrivateScreen::BytesPerRow() 506624df6c6SStefano Ceccherini { 507624df6c6SStefano Ceccherini screen_desc desc; 508624df6c6SStefano Ceccherini if (get_screen_desc(&desc) == B_OK) 509624df6c6SStefano Ceccherini return desc.bytes_per_row; 510624df6c6SStefano Ceccherini return 0; 511624df6c6SStefano Ceccherini } 512624df6c6SStefano Ceccherini 513624df6c6SStefano Ceccherini 514624df6c6SStefano Ceccherini status_t 515624df6c6SStefano Ceccherini BPrivateScreen::get_screen_desc(screen_desc *desc) 516624df6c6SStefano Ceccherini { 51739ffb980SStefano Ceccherini status_t status = B_ERROR; 51839ffb980SStefano Ceccherini /* 519dd10337fSAxel Dörfler BPrivate::AppServerLink link; 52039ffb980SStefano Ceccherini PortMessage reply; 52139ffb980SStefano Ceccherini link.SetOpCode(AS_GET_SCREEN_DESC); 52239ffb980SStefano Ceccherini link.Attach<screen_id>(ID()); 52339ffb980SStefano Ceccherini link.FlushWithReply(&reply); 52439ffb980SStefano Ceccherini reply.Read<screen_desc>(*desc); 52539ffb980SStefano Ceccherini reply.Read<status_t>(&status); 52639ffb980SStefano Ceccherini */ 52739ffb980SStefano Ceccherini return status; 528624df6c6SStefano Ceccherini } 529624df6c6SStefano Ceccherini 530624df6c6SStefano Ceccherini 53175de27f8SStefano Ceccherini // private methods 53275de27f8SStefano Ceccherini sem_id 53375de27f8SStefano Ceccherini BPrivateScreen::RetraceSemaphore() 53475de27f8SStefano Ceccherini { 53575de27f8SStefano Ceccherini sem_id id = B_BAD_SEM_ID; 53675de27f8SStefano Ceccherini 53775de27f8SStefano Ceccherini BPrivate::AppServerLink link; 53875de27f8SStefano Ceccherini link.StartMessage(AS_GET_RETRACE_SEMAPHORE); 53975de27f8SStefano Ceccherini link.Attach<screen_id>(ID()); 54075de27f8SStefano Ceccherini int32 reply; 54175de27f8SStefano Ceccherini if (link.FlushWithReply(reply) == B_OK 54275de27f8SStefano Ceccherini && reply == SERVER_TRUE) 54375de27f8SStefano Ceccherini link.Read<sem_id>(&id); 54475de27f8SStefano Ceccherini 54575de27f8SStefano Ceccherini return id; 54675de27f8SStefano Ceccherini } 54775de27f8SStefano Ceccherini 54875de27f8SStefano Ceccherini 549624df6c6SStefano Ceccherini BPrivateScreen::BPrivateScreen() 550624df6c6SStefano Ceccherini : 551624df6c6SStefano Ceccherini fColorMap(NULL), 552624df6c6SStefano Ceccherini fRetraceSem(-1), 553624df6c6SStefano Ceccherini fOwnsColorMap(false) 554624df6c6SStefano Ceccherini { 5557475dcdfSStefano Ceccherini // TODO: BeOS R5 here gets the colormap pointer 5567475dcdfSStefano Ceccherini // (with BApplication::ro_offset_to_ptr() ?) 5577475dcdfSStefano Ceccherini // which is contained in a shared area created by the server. 558dd10337fSAxel Dörfler BPrivate::AppServerLink link; 5597475dcdfSStefano Ceccherini link.StartMessage(AS_SCREEN_GET_COLORMAP); 5607475dcdfSStefano Ceccherini link.Attach<screen_id>(ID()); 561dd10337fSAxel Dörfler 5627475dcdfSStefano Ceccherini int32 reply; 563dd10337fSAxel Dörfler if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE) { 5647475dcdfSStefano Ceccherini fColorMap = (color_map *)malloc(sizeof(color_map)); 5657475dcdfSStefano Ceccherini fOwnsColorMap = true; 5662ed35bc8SStefano Ceccherini link.Read<color_map>(fColorMap); 5677475dcdfSStefano Ceccherini } 568624df6c6SStefano Ceccherini } 569624df6c6SStefano Ceccherini 570624df6c6SStefano Ceccherini 571624df6c6SStefano Ceccherini BPrivateScreen::~BPrivateScreen() 572624df6c6SStefano Ceccherini { 573624df6c6SStefano Ceccherini if (fOwnsColorMap) 574624df6c6SStefano Ceccherini free(fColorMap); 575624df6c6SStefano Ceccherini } 576