109ea3092SStefano Ceccherini /* 28575beb8SJérôme Duval * Copyright 2003-2005, Haiku Inc. 317495d0bSStefano Ceccherini * Authors: 409ea3092SStefano Ceccherini * Stefano Ceccherini (burton666@libero.it). 509ea3092SStefano Ceccherini * Carwyn Jones (turok2@currantbun.com) 617495d0bSStefano Ceccherini * 709ea3092SStefano Ceccherini * Distributed under the terms of the MIT License. 809ea3092SStefano Ceccherini */ 90b4a36abSbeveloper 10366fdcdfSMarcus Overhagen 11cafaa5aaSStefano Ceccherini #include <DirectWindow.h> 12cafaa5aaSStefano Ceccherini #include <clipping.h> 130b4a36abSbeveloper 14*764ac9e5SAxel Dörfler #ifdef HAIKU_TARGET_PLATFORM_BEOS 15cafaa5aaSStefano Ceccherini # include <R5_AppServerLink.h> 16cafaa5aaSStefano Ceccherini # include <R5_Session.h> 17feee8cf2SStefano Ceccherini # define DW_GET_SYNC_DATA 0x880 18feee8cf2SStefano Ceccherini # define DW_SET_FULLSCREEN 0x881 19feee8cf2SStefano Ceccherini # define DW_SUPPORTS_WINDOW_MODE 0xF2C 20*764ac9e5SAxel Dörfler #else 21feee8cf2SStefano Ceccherini # include <AppServerLink.h> 22feee8cf2SStefano Ceccherini # include <ServerProtocol.h> 23feee8cf2SStefano Ceccherini #endif 24366fdcdfSMarcus Overhagen 25*764ac9e5SAxel Dörfler // Compiling for Dano/Zeta is broken as it doesn't have BRegion::set_size() 26*764ac9e5SAxel Dörfler #ifdef HAIKU_TARGET_PLATFORM_DANO 27*764ac9e5SAxel Dörfler # warning "##### Building BDirectWindow for TARGET_PLATFORM=dano (DANO/Zeta) is broken #####" 28*764ac9e5SAxel Dörfler #endif 29*764ac9e5SAxel Dörfler 30*764ac9e5SAxel Dörfler 31cafaa5aaSStefano Ceccherini // TODO: We'll want to move this to a private header, 32cafaa5aaSStefano Ceccherini // accessible by the app server. 33*764ac9e5SAxel Dörfler struct dw_sync_data { 34cafaa5aaSStefano Ceccherini area_id area; 35cafaa5aaSStefano Ceccherini sem_id disableSem; 36cafaa5aaSStefano Ceccherini sem_id disableSemAck; 37cafaa5aaSStefano Ceccherini }; 38cafaa5aaSStefano Ceccherini 39cafaa5aaSStefano Ceccherini 40cafaa5aaSStefano Ceccherini // We don't need this kind of locking, since the directDeamonFunc 41cafaa5aaSStefano Ceccherini // doesn't access critical shared data. 42cafaa5aaSStefano Ceccherini #define DW_NEEDS_LOCKING 0 43cafaa5aaSStefano Ceccherini 44cafaa5aaSStefano Ceccherini enum dw_status_bits { 4517495d0bSStefano Ceccherini DW_STATUS_AREA_CLONED = 0x1, 4617495d0bSStefano Ceccherini DW_STATUS_THREAD_STARTED = 0x2, 4717495d0bSStefano Ceccherini DW_STATUS_SEM_CREATED = 0x4 48cafaa5aaSStefano Ceccherini }; 49cafaa5aaSStefano Ceccherini 50cafaa5aaSStefano Ceccherini 51*764ac9e5SAxel Dörfler BDirectWindow::BDirectWindow(BRect frame, const char *title, window_type type, 52*764ac9e5SAxel Dörfler uint32 flags, uint32 workspace) 53cafaa5aaSStefano Ceccherini : BWindow(frame, title, type, flags, workspace) 54cafaa5aaSStefano Ceccherini { 55cafaa5aaSStefano Ceccherini InitData(); 560b4a36abSbeveloper } 570b4a36abSbeveloper 580b4a36abSbeveloper 59*764ac9e5SAxel Dörfler BDirectWindow::BDirectWindow(BRect frame, const char *title, window_look look, 60*764ac9e5SAxel Dörfler window_feel feel, uint32 flags, uint32 workspace) 61cafaa5aaSStefano Ceccherini : BWindow(frame, title, look, feel, flags, workspace) 620b4a36abSbeveloper { 63cafaa5aaSStefano Ceccherini InitData(); 640b4a36abSbeveloper } 650b4a36abSbeveloper 660b4a36abSbeveloper 670b4a36abSbeveloper BDirectWindow::~BDirectWindow() 680b4a36abSbeveloper { 69cafaa5aaSStefano Ceccherini DisposeData(); 700b4a36abSbeveloper } 710b4a36abSbeveloper 720b4a36abSbeveloper 73cafaa5aaSStefano Ceccherini // start of regular BWindow API 740b4a36abSbeveloper BArchivable * 750b4a36abSbeveloper BDirectWindow::Instantiate(BMessage *data) 760b4a36abSbeveloper { 770b4a36abSbeveloper return NULL; 780b4a36abSbeveloper } 790b4a36abSbeveloper 800b4a36abSbeveloper 810b4a36abSbeveloper status_t 82cafaa5aaSStefano Ceccherini BDirectWindow::Archive(BMessage *data, bool deep) const 830b4a36abSbeveloper { 84cafaa5aaSStefano Ceccherini return inherited::Archive(data, deep); 850b4a36abSbeveloper } 860b4a36abSbeveloper 870b4a36abSbeveloper 880b4a36abSbeveloper void 89cafaa5aaSStefano Ceccherini BDirectWindow::Quit() 900b4a36abSbeveloper { 91cafaa5aaSStefano Ceccherini inherited::Quit(); 920b4a36abSbeveloper } 930b4a36abSbeveloper 940b4a36abSbeveloper 950b4a36abSbeveloper void 96cafaa5aaSStefano Ceccherini BDirectWindow::DispatchMessage(BMessage *message, BHandler *handler) 970b4a36abSbeveloper { 98cafaa5aaSStefano Ceccherini inherited::DispatchMessage(message, handler); 990b4a36abSbeveloper } 1000b4a36abSbeveloper 1010b4a36abSbeveloper 1020b4a36abSbeveloper void 1030b4a36abSbeveloper BDirectWindow::MessageReceived(BMessage *message) 1040b4a36abSbeveloper { 105cafaa5aaSStefano Ceccherini inherited::MessageReceived(message); 1060b4a36abSbeveloper } 1070b4a36abSbeveloper 1080b4a36abSbeveloper 1090b4a36abSbeveloper void 1100b4a36abSbeveloper BDirectWindow::FrameMoved(BPoint new_position) 1110b4a36abSbeveloper { 112cafaa5aaSStefano Ceccherini inherited::FrameMoved(new_position); 1130b4a36abSbeveloper } 1140b4a36abSbeveloper 1150b4a36abSbeveloper 1160b4a36abSbeveloper void 117cafaa5aaSStefano Ceccherini BDirectWindow::WorkspacesChanged(uint32 old_ws, uint32 new_ws) 1180b4a36abSbeveloper { 119cafaa5aaSStefano Ceccherini inherited::WorkspacesChanged(old_ws, new_ws); 1200b4a36abSbeveloper } 1210b4a36abSbeveloper 1220b4a36abSbeveloper 1230b4a36abSbeveloper void 124cafaa5aaSStefano Ceccherini BDirectWindow::WorkspaceActivated(int32 ws, bool state) 1250b4a36abSbeveloper { 126cafaa5aaSStefano Ceccherini inherited::WorkspaceActivated(ws, state); 1270b4a36abSbeveloper } 1280b4a36abSbeveloper 1290b4a36abSbeveloper 1300b4a36abSbeveloper void 131cafaa5aaSStefano Ceccherini BDirectWindow::FrameResized(float new_width, float new_height) 1320b4a36abSbeveloper { 133cafaa5aaSStefano Ceccherini inherited::FrameResized(new_width, new_height); 1340b4a36abSbeveloper } 1350b4a36abSbeveloper 1360b4a36abSbeveloper 1370b4a36abSbeveloper void 1380b4a36abSbeveloper BDirectWindow::Minimize(bool minimize) 1390b4a36abSbeveloper { 140cafaa5aaSStefano Ceccherini inherited::Minimize(minimize); 1410b4a36abSbeveloper } 1420b4a36abSbeveloper 1430b4a36abSbeveloper 1440b4a36abSbeveloper void 145cafaa5aaSStefano Ceccherini BDirectWindow::Zoom(BPoint rec_position, float rec_width, float rec_height) 1460b4a36abSbeveloper { 147cafaa5aaSStefano Ceccherini inherited::Zoom(rec_position, rec_width, rec_height); 1480b4a36abSbeveloper } 1490b4a36abSbeveloper 1500b4a36abSbeveloper 1510b4a36abSbeveloper void 152cafaa5aaSStefano Ceccherini BDirectWindow::ScreenChanged(BRect screen_size, color_space depth) 1530b4a36abSbeveloper { 154cafaa5aaSStefano Ceccherini inherited::ScreenChanged(screen_size, depth); 1550b4a36abSbeveloper } 1560b4a36abSbeveloper 1570b4a36abSbeveloper 1580b4a36abSbeveloper void 1590b4a36abSbeveloper BDirectWindow::MenusBeginning() 1600b4a36abSbeveloper { 161cafaa5aaSStefano Ceccherini inherited::MenusBeginning(); 1620b4a36abSbeveloper } 1630b4a36abSbeveloper 1640b4a36abSbeveloper 1650b4a36abSbeveloper void 1660b4a36abSbeveloper BDirectWindow::MenusEnded() 1670b4a36abSbeveloper { 168cafaa5aaSStefano Ceccherini inherited::MenusEnded(); 1690b4a36abSbeveloper } 1700b4a36abSbeveloper 1710b4a36abSbeveloper 1720b4a36abSbeveloper void 1730b4a36abSbeveloper BDirectWindow::WindowActivated(bool state) 1740b4a36abSbeveloper { 175cafaa5aaSStefano Ceccherini inherited::WindowActivated(state); 1760b4a36abSbeveloper } 1770b4a36abSbeveloper 1780b4a36abSbeveloper 1790b4a36abSbeveloper void 1800b4a36abSbeveloper BDirectWindow::Show() 1810b4a36abSbeveloper { 182cafaa5aaSStefano Ceccherini inherited::Show(); 1830b4a36abSbeveloper } 1840b4a36abSbeveloper 1850b4a36abSbeveloper 1860b4a36abSbeveloper void 1870b4a36abSbeveloper BDirectWindow::Hide() 1880b4a36abSbeveloper { 189cafaa5aaSStefano Ceccherini inherited::Hide(); 1900b4a36abSbeveloper } 1910b4a36abSbeveloper 1920b4a36abSbeveloper 1930b4a36abSbeveloper BHandler * 194cafaa5aaSStefano Ceccherini BDirectWindow::ResolveSpecifier(BMessage *msg, int32 index, 195cafaa5aaSStefano Ceccherini BMessage *specifier, int32 form, const char *property) 1960b4a36abSbeveloper { 197cafaa5aaSStefano Ceccherini return inherited::ResolveSpecifier(msg, index, specifier, form, property); 1980b4a36abSbeveloper } 1990b4a36abSbeveloper 2000b4a36abSbeveloper 2010b4a36abSbeveloper status_t 2020b4a36abSbeveloper BDirectWindow::GetSupportedSuites(BMessage *data) 2030b4a36abSbeveloper { 204cafaa5aaSStefano Ceccherini return inherited::GetSupportedSuites(data); 2050b4a36abSbeveloper } 2060b4a36abSbeveloper 2070b4a36abSbeveloper 2080b4a36abSbeveloper status_t 209cafaa5aaSStefano Ceccherini BDirectWindow::Perform(perform_code d, void *arg) 2100b4a36abSbeveloper { 211cafaa5aaSStefano Ceccherini return inherited::Perform(d, arg); 2120b4a36abSbeveloper } 2130b4a36abSbeveloper 2140b4a36abSbeveloper 215b816dc1eSIngo Weinhold void 216b816dc1eSIngo Weinhold BDirectWindow::task_looper() 217b816dc1eSIngo Weinhold { 218cafaa5aaSStefano Ceccherini inherited::task_looper(); 219b816dc1eSIngo Weinhold } 220b816dc1eSIngo Weinhold 221cafaa5aaSStefano Ceccherini 222b816dc1eSIngo Weinhold BMessage * 223b816dc1eSIngo Weinhold BDirectWindow::ConvertToMessage(void *raw, int32 code) 224b816dc1eSIngo Weinhold { 225cafaa5aaSStefano Ceccherini return inherited::ConvertToMessage(raw, code); 226b816dc1eSIngo Weinhold } 2270b4a36abSbeveloper 2280b4a36abSbeveloper 229*764ac9e5SAxel Dörfler // #pragma mark - BDirectWindow specific API 230*764ac9e5SAxel Dörfler 231*764ac9e5SAxel Dörfler 2320b4a36abSbeveloper void 2330b4a36abSbeveloper BDirectWindow::DirectConnected(direct_buffer_info *info) 2340b4a36abSbeveloper { 235cafaa5aaSStefano Ceccherini // implemented in subclasses 2360b4a36abSbeveloper } 2370b4a36abSbeveloper 2380b4a36abSbeveloper 2390b4a36abSbeveloper status_t 240cafaa5aaSStefano Ceccherini BDirectWindow::GetClippingRegion(BRegion *region, BPoint *origin) const 2410b4a36abSbeveloper { 242cafaa5aaSStefano Ceccherini if (region == NULL) 243cafaa5aaSStefano Ceccherini return B_BAD_VALUE; 244cafaa5aaSStefano Ceccherini 2454f6f70e0SStefano Ceccherini if (IsLocked() || !LockDirect()) 2465fdea13fSStefano Ceccherini return B_ERROR; 2475fdea13fSStefano Ceccherini 248cafaa5aaSStefano Ceccherini if (in_direct_connect) { 249cafaa5aaSStefano Ceccherini UnlockDirect(); 250cafaa5aaSStefano Ceccherini return B_ERROR; 251cafaa5aaSStefano Ceccherini } 252cafaa5aaSStefano Ceccherini 253cafaa5aaSStefano Ceccherini // BPoint's coordinates are floats. We can only work 254cafaa5aaSStefano Ceccherini // with integers. 255cafaa5aaSStefano Ceccherini int32 originX, originY; 256cafaa5aaSStefano Ceccherini if (origin == NULL) { 257cafaa5aaSStefano Ceccherini originX = 0; 258cafaa5aaSStefano Ceccherini originY = 0; 259cafaa5aaSStefano Ceccherini } else { 260cafaa5aaSStefano Ceccherini originX = (int32)origin->x; 261cafaa5aaSStefano Ceccherini originY = (int32)origin->y; 262cafaa5aaSStefano Ceccherini } 263cafaa5aaSStefano Ceccherini 264*764ac9e5SAxel Dörfler #ifndef HAIKU_TARGET_PLATFORM_DANO 265cafaa5aaSStefano Ceccherini // Since we are friend of BRegion, we can access its private members. 266cafaa5aaSStefano Ceccherini // Otherwise, we would need to call BRegion::Include(clipping_rect) 267cafaa5aaSStefano Ceccherini // for every clipping_rect in our clip_list, and that would be much 2685fdea13fSStefano Ceccherini // more overkill than this (tested ). 269cafaa5aaSStefano Ceccherini region->set_size(buffer_desc->clip_list_count); 270cafaa5aaSStefano Ceccherini region->count = buffer_desc->clip_list_count; 271cafaa5aaSStefano Ceccherini region->bound = buffer_desc->clip_bounds; 2724f6f70e0SStefano Ceccherini for (uint32 c = 0; c < buffer_desc->clip_list_count; c++) 2734f6f70e0SStefano Ceccherini region->data[c] = buffer_desc->clip_list[c]; 274cafaa5aaSStefano Ceccherini 275cafaa5aaSStefano Ceccherini // adjust bounds by the given origin point 2764f6f70e0SStefano Ceccherini region->OffsetBy(-originX, -originY); 277366fdcdfSMarcus Overhagen #endif 278366fdcdfSMarcus Overhagen 279cafaa5aaSStefano Ceccherini UnlockDirect(); 280cafaa5aaSStefano Ceccherini 281cafaa5aaSStefano Ceccherini return B_OK; 282cafaa5aaSStefano Ceccherini 2830b4a36abSbeveloper } 2840b4a36abSbeveloper 2850b4a36abSbeveloper 2860b4a36abSbeveloper status_t 2870b4a36abSbeveloper BDirectWindow::SetFullScreen(bool enable) 2880b4a36abSbeveloper { 289cafaa5aaSStefano Ceccherini status_t status = B_ERROR; 29009ea3092SStefano Ceccherini if (Lock()) { 291*764ac9e5SAxel Dörfler #ifdef HAIKU_TARGET_PLATFORM_BEOS 29209ea3092SStefano Ceccherini a_session->swrite_l(DW_SET_FULLSCREEN); 29309ea3092SStefano Ceccherini a_session->swrite_l(server_token); 29417495d0bSStefano Ceccherini a_session->swrite_l((int32)enable); 29509ea3092SStefano Ceccherini Flush(); 29609ea3092SStefano Ceccherini 297bfc3bb18SStefano Ceccherini status_t fullScreen; 298bfc3bb18SStefano Ceccherini a_session->sread(sizeof(status_t), &fullScreen); 299bfc3bb18SStefano Ceccherini a_session->sread(sizeof(status_t), &status); 300feee8cf2SStefano Ceccherini full_screen_enable = enable; 301*764ac9e5SAxel Dörfler #else 302feee8cf2SStefano Ceccherini fLink->StartMessage(AS_DW_SET_FULLSCREEN); 303feee8cf2SStefano Ceccherini fLink->Attach<int32>(server_token); // useless ? 304feee8cf2SStefano Ceccherini fLink->Attach<bool>(enable); 305feee8cf2SStefano Ceccherini 306feee8cf2SStefano Ceccherini int32 code; 307feee8cf2SStefano Ceccherini if (fLink->FlushWithReply(code) == B_OK 308feee8cf2SStefano Ceccherini && code == SERVER_TRUE) { 309feee8cf2SStefano Ceccherini status = B_OK; 310feee8cf2SStefano Ceccherini full_screen_enable = enable; 311feee8cf2SStefano Ceccherini } 3128575beb8SJérôme Duval #endif 31309ea3092SStefano Ceccherini Unlock(); 314bfc3bb18SStefano Ceccherini 31509ea3092SStefano Ceccherini } 316cafaa5aaSStefano Ceccherini return status; 3170b4a36abSbeveloper } 3180b4a36abSbeveloper 3190b4a36abSbeveloper 3200b4a36abSbeveloper bool 3210b4a36abSbeveloper BDirectWindow::IsFullScreen() const 3220b4a36abSbeveloper { 323cafaa5aaSStefano Ceccherini return full_screen_enable; 3240b4a36abSbeveloper } 3250b4a36abSbeveloper 3260b4a36abSbeveloper 3270b4a36abSbeveloper bool 328cafaa5aaSStefano Ceccherini BDirectWindow::SupportsWindowMode(screen_id id) 3290b4a36abSbeveloper { 330*764ac9e5SAxel Dörfler #ifdef HAIKU_TARGET_PLATFORM_BEOS 331feee8cf2SStefano Ceccherini int32 result = 0; 332cafaa5aaSStefano Ceccherini _BAppServerLink_ link; 333cafaa5aaSStefano Ceccherini link.fSession->swrite_l(DW_SUPPORTS_WINDOW_MODE); 334cafaa5aaSStefano Ceccherini link.fSession->swrite_l(id.id); 335cafaa5aaSStefano Ceccherini link.fSession->sync(); 336cafaa5aaSStefano Ceccherini link.fSession->sread(sizeof(result), &result); 337feee8cf2SStefano Ceccherini return result & true; 338*764ac9e5SAxel Dörfler #else 339feee8cf2SStefano Ceccherini BPrivate::AppServerLink link; 340feee8cf2SStefano Ceccherini link.StartMessage(AS_DW_SUPPORTS_WINDOW_MODE); 341feee8cf2SStefano Ceccherini link.Attach<screen_id>(id); 342feee8cf2SStefano Ceccherini int32 reply; 343feee8cf2SStefano Ceccherini if (link.FlushWithReply(reply) == B_OK 344feee8cf2SStefano Ceccherini && reply == SERVER_TRUE) 345feee8cf2SStefano Ceccherini return true; 346feee8cf2SStefano Ceccherini #endif 347feee8cf2SStefano Ceccherini 348feee8cf2SStefano Ceccherini return false; 349cafaa5aaSStefano Ceccherini } 350cafaa5aaSStefano Ceccherini 351cafaa5aaSStefano Ceccherini 352cafaa5aaSStefano Ceccherini // Private methods 353cafaa5aaSStefano Ceccherini int32 354cafaa5aaSStefano Ceccherini BDirectWindow::DirectDeamonFunc(void *arg) 355cafaa5aaSStefano Ceccherini { 356cafaa5aaSStefano Ceccherini BDirectWindow *object = static_cast<BDirectWindow *>(arg); 357cafaa5aaSStefano Ceccherini 358cafaa5aaSStefano Ceccherini while (!object->deamon_killer) { 359cafaa5aaSStefano Ceccherini // This sem is released by the app_server when our 360cafaa5aaSStefano Ceccherini // clipping region changes, or when our window is moved, 361cafaa5aaSStefano Ceccherini // resized, etc. etc. 362cafaa5aaSStefano Ceccherini while (acquire_sem(object->disable_sem) == B_INTERRUPTED) 363cafaa5aaSStefano Ceccherini ; 364cafaa5aaSStefano Ceccherini 365cafaa5aaSStefano Ceccherini if (object->LockDirect()) { 366cafaa5aaSStefano Ceccherini if ((object->buffer_desc->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_START) 367cafaa5aaSStefano Ceccherini object->connection_enable = true; 368cafaa5aaSStefano Ceccherini 369cafaa5aaSStefano Ceccherini object->in_direct_connect = true; 370cafaa5aaSStefano Ceccherini object->DirectConnected(object->buffer_desc); 371cafaa5aaSStefano Ceccherini object->in_direct_connect = false; 372cafaa5aaSStefano Ceccherini 373cafaa5aaSStefano Ceccherini if ((object->buffer_desc->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_STOP) 374cafaa5aaSStefano Ceccherini object->connection_enable = false; 375cafaa5aaSStefano Ceccherini 376cafaa5aaSStefano Ceccherini object->UnlockDirect(); 377cafaa5aaSStefano Ceccherini } 378cafaa5aaSStefano Ceccherini 379cafaa5aaSStefano Ceccherini // The app_server then waits (with a timeout) on this sem. 380cafaa5aaSStefano Ceccherini // If we aren't quick enough to release this sem, our app 381cafaa5aaSStefano Ceccherini // will be terminated by the app_server 382cafaa5aaSStefano Ceccherini release_sem(object->disable_sem_ack); 383cafaa5aaSStefano Ceccherini } 384cafaa5aaSStefano Ceccherini 385cafaa5aaSStefano Ceccherini return 0; 386cafaa5aaSStefano Ceccherini } 387cafaa5aaSStefano Ceccherini 388cafaa5aaSStefano Ceccherini 38917495d0bSStefano Ceccherini // LockDirect() and UnlockDirect() are no-op on R5. I tried to call (R5's) LockDirect() 39017495d0bSStefano Ceccherini // repeatedly, from the same thread and from different threads, nothing happened. 39117495d0bSStefano Ceccherini // I implemented them anyway, as they were the first methods I wrote 39217495d0bSStefano Ceccherini // in this class (As you can see, I even needed to cast away their constness 39317495d0bSStefano Ceccherini // to make them do something useful). 39417495d0bSStefano Ceccherini // They're not needed though, as the direct_deamon_thread doesn't change 39517495d0bSStefano Ceccherini // any shared data. They are probably here for future enhancements (see also the 39617495d0bSStefano Ceccherini // comment in DriverSetup() 397cafaa5aaSStefano Ceccherini bool 398cafaa5aaSStefano Ceccherini BDirectWindow::LockDirect() const 399cafaa5aaSStefano Ceccherini { 400cafaa5aaSStefano Ceccherini status_t status = B_OK; 401cafaa5aaSStefano Ceccherini 402cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING 403cafaa5aaSStefano Ceccherini BDirectWindow *casted = const_cast<BDirectWindow *>(this); 404cafaa5aaSStefano Ceccherini 4055fdea13fSStefano Ceccherini if (atomic_add(&casted->direct_lock, 1) > 0) { 406cafaa5aaSStefano Ceccherini do { 407cafaa5aaSStefano Ceccherini status = acquire_sem(direct_sem); 408cafaa5aaSStefano Ceccherini } while (status == B_INTERRUPTED); 4095fdea13fSStefano Ceccherini } 410cafaa5aaSStefano Ceccherini 411cafaa5aaSStefano Ceccherini if (status == B_OK) { 412cafaa5aaSStefano Ceccherini casted->direct_lock_owner = find_thread(NULL); 413cafaa5aaSStefano Ceccherini casted->direct_lock_count++; 414cafaa5aaSStefano Ceccherini } 415cafaa5aaSStefano Ceccherini #endif 416cafaa5aaSStefano Ceccherini 417cafaa5aaSStefano Ceccherini return status == B_OK; 4180b4a36abSbeveloper } 4190b4a36abSbeveloper 4200b4a36abSbeveloper 4210b4a36abSbeveloper void 422cafaa5aaSStefano Ceccherini BDirectWindow::UnlockDirect() const 4230b4a36abSbeveloper { 424cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING 425cafaa5aaSStefano Ceccherini BDirectWindow *casted = const_cast<BDirectWindow *>(this); 426cafaa5aaSStefano Ceccherini 427cafaa5aaSStefano Ceccherini if (atomic_add(&casted->direct_lock, -1) > 1) 428cafaa5aaSStefano Ceccherini release_sem(direct_sem); 429cafaa5aaSStefano Ceccherini 430cafaa5aaSStefano Ceccherini casted->direct_lock_count--; 431cafaa5aaSStefano Ceccherini #endif 4320b4a36abSbeveloper } 4330b4a36abSbeveloper 4340b4a36abSbeveloper 4350b4a36abSbeveloper void 436cafaa5aaSStefano Ceccherini BDirectWindow::InitData() 4370b4a36abSbeveloper { 438cafaa5aaSStefano Ceccherini connection_enable = false; 439cafaa5aaSStefano Ceccherini full_screen_enable = false; 440cafaa5aaSStefano Ceccherini in_direct_connect = false; 441cafaa5aaSStefano Ceccherini 442cafaa5aaSStefano Ceccherini dw_init_status = 0; 443cafaa5aaSStefano Ceccherini 444cafaa5aaSStefano Ceccherini direct_driver_ready = false; 445cafaa5aaSStefano Ceccherini direct_driver_type = 0; 446cafaa5aaSStefano Ceccherini direct_driver_token = 0; 447cafaa5aaSStefano Ceccherini direct_driver = NULL; 448cafaa5aaSStefano Ceccherini 4495fdea13fSStefano Ceccherini if (!Lock()) 4505fdea13fSStefano Ceccherini return; 4515fdea13fSStefano Ceccherini 4528575beb8SJérôme Duval struct dw_sync_data sync_data; 4538575beb8SJérôme Duval status_t status = B_ERROR; 4548575beb8SJérôme Duval 455*764ac9e5SAxel Dörfler #ifdef HAIKU_TARGET_PLATFORM_BEOS 456cafaa5aaSStefano Ceccherini a_session->swrite_l(DW_GET_SYNC_DATA); 457cafaa5aaSStefano Ceccherini a_session->swrite_l(server_token); 4588575beb8SJérôme Duval 459cafaa5aaSStefano Ceccherini Flush(); 460cafaa5aaSStefano Ceccherini 461cafaa5aaSStefano Ceccherini a_session->sread(sizeof(sync_data), &sync_data); 4628575beb8SJérôme Duval a_session->sread(sizeof(status), &status); 463*764ac9e5SAxel Dörfler #else 464feee8cf2SStefano Ceccherini fLink->StartMessage(AS_DW_GET_SYNC_DATA); 465feee8cf2SStefano Ceccherini fLink->Attach<int32>(server_token); 466feee8cf2SStefano Ceccherini 467feee8cf2SStefano Ceccherini int32 reply; 468feee8cf2SStefano Ceccherini if (fLink->FlushWithReply(reply) == B_OK 469*764ac9e5SAxel Dörfler && reply == B_OK) { 470feee8cf2SStefano Ceccherini fLink->Read<dw_sync_data>(&sync_data); 471feee8cf2SStefano Ceccherini status = B_OK; 472feee8cf2SStefano Ceccherini } 473feee8cf2SStefano Ceccherini #endif 474feee8cf2SStefano Ceccherini 475cafaa5aaSStefano Ceccherini Unlock(); 476cafaa5aaSStefano Ceccherini 4775fdea13fSStefano Ceccherini if (status < B_OK) 4785fdea13fSStefano Ceccherini return; 479cafaa5aaSStefano Ceccherini 480cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING 481cafaa5aaSStefano Ceccherini direct_lock = 0; 482cafaa5aaSStefano Ceccherini direct_lock_count = 0; 4835fdea13fSStefano Ceccherini direct_lock_owner = -1; 484cafaa5aaSStefano Ceccherini direct_lock_stack = NULL; 485cafaa5aaSStefano Ceccherini direct_sem = create_sem(1, "direct sem"); 486cafaa5aaSStefano Ceccherini if (direct_sem > 0) 487cafaa5aaSStefano Ceccherini dw_init_status |= DW_STATUS_SEM_CREATED; 488cafaa5aaSStefano Ceccherini #endif 489cafaa5aaSStefano Ceccherini 490cafaa5aaSStefano Ceccherini source_clipping_area = sync_data.area; 491cafaa5aaSStefano Ceccherini disable_sem = sync_data.disableSem; 492cafaa5aaSStefano Ceccherini disable_sem_ack = sync_data.disableSemAck; 493cafaa5aaSStefano Ceccherini 494cafaa5aaSStefano Ceccherini cloned_clipping_area = clone_area("Clone direct area", (void**)&buffer_desc, 495cafaa5aaSStefano Ceccherini B_ANY_ADDRESS, B_READ_AREA, source_clipping_area); 4965fdea13fSStefano Ceccherini 497cafaa5aaSStefano Ceccherini if (cloned_clipping_area > 0) { 498cafaa5aaSStefano Ceccherini dw_init_status |= DW_STATUS_AREA_CLONED; 499cafaa5aaSStefano Ceccherini 500cafaa5aaSStefano Ceccherini direct_deamon_id = spawn_thread(DirectDeamonFunc, "direct deamon", 501cafaa5aaSStefano Ceccherini B_DISPLAY_PRIORITY, this); 502cafaa5aaSStefano Ceccherini 503cafaa5aaSStefano Ceccherini if (direct_deamon_id > 0) { 504cafaa5aaSStefano Ceccherini deamon_killer = false; 505cafaa5aaSStefano Ceccherini if (resume_thread(direct_deamon_id) == B_OK) 506cafaa5aaSStefano Ceccherini dw_init_status |= DW_STATUS_THREAD_STARTED; 507cafaa5aaSStefano Ceccherini else 508cafaa5aaSStefano Ceccherini kill_thread(direct_deamon_id); 509cafaa5aaSStefano Ceccherini } 510cafaa5aaSStefano Ceccherini } 511cafaa5aaSStefano Ceccherini } 5120b4a36abSbeveloper 5130b4a36abSbeveloper 5140b4a36abSbeveloper void 515cafaa5aaSStefano Ceccherini BDirectWindow::DisposeData() 5160b4a36abSbeveloper { 517cafaa5aaSStefano Ceccherini // wait until the connection terminates: we can't destroy 518cafaa5aaSStefano Ceccherini // the object until the client receives the B_DIRECT_STOP 519cafaa5aaSStefano Ceccherini // notification, or bad things will happen 520cafaa5aaSStefano Ceccherini while (connection_enable) 521cafaa5aaSStefano Ceccherini snooze(50000); 522cafaa5aaSStefano Ceccherini 523cafaa5aaSStefano Ceccherini LockDirect(); 524cafaa5aaSStefano Ceccherini 525cafaa5aaSStefano Ceccherini if (dw_init_status & DW_STATUS_THREAD_STARTED) { 526cafaa5aaSStefano Ceccherini deamon_killer = true; 527cafaa5aaSStefano Ceccherini // Release this sem, otherwise the Direct deamon thread 528cafaa5aaSStefano Ceccherini // will wait forever on it 529cafaa5aaSStefano Ceccherini release_sem(disable_sem); 530cafaa5aaSStefano Ceccherini status_t retVal; 531cafaa5aaSStefano Ceccherini wait_for_thread(direct_deamon_id, &retVal); 532cafaa5aaSStefano Ceccherini } 533cafaa5aaSStefano Ceccherini 534cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING 535cafaa5aaSStefano Ceccherini if (dw_init_status & DW_STATUS_SEM_CREATED) 536cafaa5aaSStefano Ceccherini delete_sem(direct_sem); 537cafaa5aaSStefano Ceccherini #endif 538cafaa5aaSStefano Ceccherini 539cafaa5aaSStefano Ceccherini if (dw_init_status & DW_STATUS_AREA_CLONED) 540cafaa5aaSStefano Ceccherini delete_area(cloned_clipping_area); 5410b4a36abSbeveloper } 5420b4a36abSbeveloper 5430b4a36abSbeveloper 544cafaa5aaSStefano Ceccherini status_t 545cafaa5aaSStefano Ceccherini BDirectWindow::DriverSetup() const 5460b4a36abSbeveloper { 54717495d0bSStefano Ceccherini // Unimplemented in R5. 54809ea3092SStefano Ceccherini // This function is probably here because they wanted, in a future time, 54909ea3092SStefano Ceccherini // to implement graphic acceleration within BDirectWindow 55009ea3092SStefano Ceccherini // (in fact, there is also a BDirectDriver member in BDirectWindow, 55117495d0bSStefano Ceccherini // though it's not used). 55209ea3092SStefano Ceccherini 553cafaa5aaSStefano Ceccherini return B_OK; 5540b4a36abSbeveloper } 5550b4a36abSbeveloper 5560b4a36abSbeveloper 557cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow1() {} 558cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow2() {} 559cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow3() {} 560cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow4() {} 561