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> 1271b55088SAxel Dörfler 13cafaa5aaSStefano Ceccherini #include <clipping.h> 1471b55088SAxel Dörfler #include <DirectWindowPrivate.h> 150b4a36abSbeveloper 16764ac9e5SAxel Dörfler #ifdef HAIKU_TARGET_PLATFORM_BEOS 17cafaa5aaSStefano Ceccherini # include <R5_AppServerLink.h> 18cafaa5aaSStefano Ceccherini # include <R5_Session.h> 19feee8cf2SStefano Ceccherini # define DW_GET_SYNC_DATA 0x880 20feee8cf2SStefano Ceccherini # define DW_SET_FULLSCREEN 0x881 21feee8cf2SStefano Ceccherini # define DW_SUPPORTS_WINDOW_MODE 0xF2C 22764ac9e5SAxel Dörfler #else 23feee8cf2SStefano Ceccherini # include <AppServerLink.h> 24feee8cf2SStefano Ceccherini # include <ServerProtocol.h> 25feee8cf2SStefano Ceccherini #endif 26366fdcdfSMarcus Overhagen 27764ac9e5SAxel Dörfler // Compiling for Dano/Zeta is broken as it doesn't have BRegion::set_size() 28764ac9e5SAxel Dörfler #ifdef HAIKU_TARGET_PLATFORM_DANO 29764ac9e5SAxel Dörfler # warning "##### Building BDirectWindow for TARGET_PLATFORM=dano (DANO/Zeta) is broken #####" 30764ac9e5SAxel Dörfler #endif 31764ac9e5SAxel Dörfler 32764ac9e5SAxel Dörfler 33cafaa5aaSStefano Ceccherini // We don't need this kind of locking, since the directDeamonFunc 34cafaa5aaSStefano Ceccherini // doesn't access critical shared data. 35cafaa5aaSStefano Ceccherini #define DW_NEEDS_LOCKING 0 36cafaa5aaSStefano Ceccherini 37cafaa5aaSStefano Ceccherini enum dw_status_bits { 3817495d0bSStefano Ceccherini DW_STATUS_AREA_CLONED = 0x1, 3917495d0bSStefano Ceccherini DW_STATUS_THREAD_STARTED = 0x2, 4017495d0bSStefano Ceccherini DW_STATUS_SEM_CREATED = 0x4 41cafaa5aaSStefano Ceccherini }; 42cafaa5aaSStefano Ceccherini 43cafaa5aaSStefano Ceccherini 44764ac9e5SAxel Dörfler BDirectWindow::BDirectWindow(BRect frame, const char *title, window_type type, 45764ac9e5SAxel Dörfler uint32 flags, uint32 workspace) 46cafaa5aaSStefano Ceccherini : BWindow(frame, title, type, flags, workspace) 47cafaa5aaSStefano Ceccherini { 48cafaa5aaSStefano Ceccherini InitData(); 490b4a36abSbeveloper } 500b4a36abSbeveloper 510b4a36abSbeveloper 52764ac9e5SAxel Dörfler BDirectWindow::BDirectWindow(BRect frame, const char *title, window_look look, 53764ac9e5SAxel Dörfler window_feel feel, uint32 flags, uint32 workspace) 54cafaa5aaSStefano Ceccherini : BWindow(frame, title, look, feel, flags, workspace) 550b4a36abSbeveloper { 56cafaa5aaSStefano Ceccherini InitData(); 570b4a36abSbeveloper } 580b4a36abSbeveloper 590b4a36abSbeveloper 600b4a36abSbeveloper BDirectWindow::~BDirectWindow() 610b4a36abSbeveloper { 62cafaa5aaSStefano Ceccherini DisposeData(); 630b4a36abSbeveloper } 640b4a36abSbeveloper 650b4a36abSbeveloper 66cafaa5aaSStefano Ceccherini // start of regular BWindow API 670b4a36abSbeveloper BArchivable * 680b4a36abSbeveloper BDirectWindow::Instantiate(BMessage *data) 690b4a36abSbeveloper { 700b4a36abSbeveloper return NULL; 710b4a36abSbeveloper } 720b4a36abSbeveloper 730b4a36abSbeveloper 740b4a36abSbeveloper status_t 75cafaa5aaSStefano Ceccherini BDirectWindow::Archive(BMessage *data, bool deep) const 760b4a36abSbeveloper { 77cafaa5aaSStefano Ceccherini return inherited::Archive(data, deep); 780b4a36abSbeveloper } 790b4a36abSbeveloper 800b4a36abSbeveloper 810b4a36abSbeveloper void 82cafaa5aaSStefano Ceccherini BDirectWindow::Quit() 830b4a36abSbeveloper { 84cafaa5aaSStefano Ceccherini inherited::Quit(); 850b4a36abSbeveloper } 860b4a36abSbeveloper 870b4a36abSbeveloper 880b4a36abSbeveloper void 89cafaa5aaSStefano Ceccherini BDirectWindow::DispatchMessage(BMessage *message, BHandler *handler) 900b4a36abSbeveloper { 91cafaa5aaSStefano Ceccherini inherited::DispatchMessage(message, handler); 920b4a36abSbeveloper } 930b4a36abSbeveloper 940b4a36abSbeveloper 950b4a36abSbeveloper void 960b4a36abSbeveloper BDirectWindow::MessageReceived(BMessage *message) 970b4a36abSbeveloper { 98cafaa5aaSStefano Ceccherini inherited::MessageReceived(message); 990b4a36abSbeveloper } 1000b4a36abSbeveloper 1010b4a36abSbeveloper 1020b4a36abSbeveloper void 1030b4a36abSbeveloper BDirectWindow::FrameMoved(BPoint new_position) 1040b4a36abSbeveloper { 105cafaa5aaSStefano Ceccherini inherited::FrameMoved(new_position); 1060b4a36abSbeveloper } 1070b4a36abSbeveloper 1080b4a36abSbeveloper 1090b4a36abSbeveloper void 110cafaa5aaSStefano Ceccherini BDirectWindow::WorkspacesChanged(uint32 old_ws, uint32 new_ws) 1110b4a36abSbeveloper { 112cafaa5aaSStefano Ceccherini inherited::WorkspacesChanged(old_ws, new_ws); 1130b4a36abSbeveloper } 1140b4a36abSbeveloper 1150b4a36abSbeveloper 1160b4a36abSbeveloper void 117cafaa5aaSStefano Ceccherini BDirectWindow::WorkspaceActivated(int32 ws, bool state) 1180b4a36abSbeveloper { 119cafaa5aaSStefano Ceccherini inherited::WorkspaceActivated(ws, state); 1200b4a36abSbeveloper } 1210b4a36abSbeveloper 1220b4a36abSbeveloper 1230b4a36abSbeveloper void 124cafaa5aaSStefano Ceccherini BDirectWindow::FrameResized(float new_width, float new_height) 1250b4a36abSbeveloper { 126cafaa5aaSStefano Ceccherini inherited::FrameResized(new_width, new_height); 1270b4a36abSbeveloper } 1280b4a36abSbeveloper 1290b4a36abSbeveloper 1300b4a36abSbeveloper void 1310b4a36abSbeveloper BDirectWindow::Minimize(bool minimize) 1320b4a36abSbeveloper { 133cafaa5aaSStefano Ceccherini inherited::Minimize(minimize); 1340b4a36abSbeveloper } 1350b4a36abSbeveloper 1360b4a36abSbeveloper 1370b4a36abSbeveloper void 138cafaa5aaSStefano Ceccherini BDirectWindow::Zoom(BPoint rec_position, float rec_width, float rec_height) 1390b4a36abSbeveloper { 140cafaa5aaSStefano Ceccherini inherited::Zoom(rec_position, rec_width, rec_height); 1410b4a36abSbeveloper } 1420b4a36abSbeveloper 1430b4a36abSbeveloper 1440b4a36abSbeveloper void 145cafaa5aaSStefano Ceccherini BDirectWindow::ScreenChanged(BRect screen_size, color_space depth) 1460b4a36abSbeveloper { 147cafaa5aaSStefano Ceccherini inherited::ScreenChanged(screen_size, depth); 1480b4a36abSbeveloper } 1490b4a36abSbeveloper 1500b4a36abSbeveloper 1510b4a36abSbeveloper void 1520b4a36abSbeveloper BDirectWindow::MenusBeginning() 1530b4a36abSbeveloper { 154cafaa5aaSStefano Ceccherini inherited::MenusBeginning(); 1550b4a36abSbeveloper } 1560b4a36abSbeveloper 1570b4a36abSbeveloper 1580b4a36abSbeveloper void 1590b4a36abSbeveloper BDirectWindow::MenusEnded() 1600b4a36abSbeveloper { 161cafaa5aaSStefano Ceccherini inherited::MenusEnded(); 1620b4a36abSbeveloper } 1630b4a36abSbeveloper 1640b4a36abSbeveloper 1650b4a36abSbeveloper void 1660b4a36abSbeveloper BDirectWindow::WindowActivated(bool state) 1670b4a36abSbeveloper { 168cafaa5aaSStefano Ceccherini inherited::WindowActivated(state); 1690b4a36abSbeveloper } 1700b4a36abSbeveloper 1710b4a36abSbeveloper 1720b4a36abSbeveloper void 1730b4a36abSbeveloper BDirectWindow::Show() 1740b4a36abSbeveloper { 175cafaa5aaSStefano Ceccherini inherited::Show(); 1760b4a36abSbeveloper } 1770b4a36abSbeveloper 1780b4a36abSbeveloper 1790b4a36abSbeveloper void 1800b4a36abSbeveloper BDirectWindow::Hide() 1810b4a36abSbeveloper { 182cafaa5aaSStefano Ceccherini inherited::Hide(); 1830b4a36abSbeveloper } 1840b4a36abSbeveloper 1850b4a36abSbeveloper 1860b4a36abSbeveloper BHandler * 187cafaa5aaSStefano Ceccherini BDirectWindow::ResolveSpecifier(BMessage *msg, int32 index, 188cafaa5aaSStefano Ceccherini BMessage *specifier, int32 form, const char *property) 1890b4a36abSbeveloper { 190cafaa5aaSStefano Ceccherini return inherited::ResolveSpecifier(msg, index, specifier, form, property); 1910b4a36abSbeveloper } 1920b4a36abSbeveloper 1930b4a36abSbeveloper 1940b4a36abSbeveloper status_t 1950b4a36abSbeveloper BDirectWindow::GetSupportedSuites(BMessage *data) 1960b4a36abSbeveloper { 197cafaa5aaSStefano Ceccherini return inherited::GetSupportedSuites(data); 1980b4a36abSbeveloper } 1990b4a36abSbeveloper 2000b4a36abSbeveloper 2010b4a36abSbeveloper status_t 202cafaa5aaSStefano Ceccherini BDirectWindow::Perform(perform_code d, void *arg) 2030b4a36abSbeveloper { 204cafaa5aaSStefano Ceccherini return inherited::Perform(d, arg); 2050b4a36abSbeveloper } 2060b4a36abSbeveloper 2070b4a36abSbeveloper 208b816dc1eSIngo Weinhold void 209b816dc1eSIngo Weinhold BDirectWindow::task_looper() 210b816dc1eSIngo Weinhold { 211cafaa5aaSStefano Ceccherini inherited::task_looper(); 212b816dc1eSIngo Weinhold } 213b816dc1eSIngo Weinhold 214cafaa5aaSStefano Ceccherini 215b816dc1eSIngo Weinhold BMessage * 216b816dc1eSIngo Weinhold BDirectWindow::ConvertToMessage(void *raw, int32 code) 217b816dc1eSIngo Weinhold { 218cafaa5aaSStefano Ceccherini return inherited::ConvertToMessage(raw, code); 219b816dc1eSIngo Weinhold } 2200b4a36abSbeveloper 2210b4a36abSbeveloper 222764ac9e5SAxel Dörfler // #pragma mark - BDirectWindow specific API 223764ac9e5SAxel Dörfler 224764ac9e5SAxel Dörfler 2250b4a36abSbeveloper void 2260b4a36abSbeveloper BDirectWindow::DirectConnected(direct_buffer_info *info) 2270b4a36abSbeveloper { 228cafaa5aaSStefano Ceccherini // implemented in subclasses 2290b4a36abSbeveloper } 2300b4a36abSbeveloper 2310b4a36abSbeveloper 2320b4a36abSbeveloper status_t 233cafaa5aaSStefano Ceccherini BDirectWindow::GetClippingRegion(BRegion *region, BPoint *origin) const 2340b4a36abSbeveloper { 235cafaa5aaSStefano Ceccherini if (region == NULL) 236cafaa5aaSStefano Ceccherini return B_BAD_VALUE; 237cafaa5aaSStefano Ceccherini 2384f6f70e0SStefano Ceccherini if (IsLocked() || !LockDirect()) 2395fdea13fSStefano Ceccherini return B_ERROR; 2405fdea13fSStefano Ceccherini 241cafaa5aaSStefano Ceccherini if (in_direct_connect) { 242cafaa5aaSStefano Ceccherini UnlockDirect(); 243cafaa5aaSStefano Ceccherini return B_ERROR; 244cafaa5aaSStefano Ceccherini } 245cafaa5aaSStefano Ceccherini 246cafaa5aaSStefano Ceccherini // BPoint's coordinates are floats. We can only work 247cafaa5aaSStefano Ceccherini // with integers. 248cafaa5aaSStefano Ceccherini int32 originX, originY; 249cafaa5aaSStefano Ceccherini if (origin == NULL) { 250cafaa5aaSStefano Ceccherini originX = 0; 251cafaa5aaSStefano Ceccherini originY = 0; 252cafaa5aaSStefano Ceccherini } else { 253cafaa5aaSStefano Ceccherini originX = (int32)origin->x; 254cafaa5aaSStefano Ceccherini originY = (int32)origin->y; 255cafaa5aaSStefano Ceccherini } 256cafaa5aaSStefano Ceccherini 257764ac9e5SAxel Dörfler #ifndef HAIKU_TARGET_PLATFORM_DANO 258cafaa5aaSStefano Ceccherini // Since we are friend of BRegion, we can access its private members. 259cafaa5aaSStefano Ceccherini // Otherwise, we would need to call BRegion::Include(clipping_rect) 260cafaa5aaSStefano Ceccherini // for every clipping_rect in our clip_list, and that would be much 2615fdea13fSStefano Ceccherini // more overkill than this (tested ). 262cafaa5aaSStefano Ceccherini region->set_size(buffer_desc->clip_list_count); 263cafaa5aaSStefano Ceccherini region->count = buffer_desc->clip_list_count; 264cafaa5aaSStefano Ceccherini region->bound = buffer_desc->clip_bounds; 2654f6f70e0SStefano Ceccherini for (uint32 c = 0; c < buffer_desc->clip_list_count; c++) 2664f6f70e0SStefano Ceccherini region->data[c] = buffer_desc->clip_list[c]; 267cafaa5aaSStefano Ceccherini 268cafaa5aaSStefano Ceccherini // adjust bounds by the given origin point 2694f6f70e0SStefano Ceccherini region->OffsetBy(-originX, -originY); 270366fdcdfSMarcus Overhagen #endif 271366fdcdfSMarcus Overhagen 272cafaa5aaSStefano Ceccherini UnlockDirect(); 273cafaa5aaSStefano Ceccherini 274cafaa5aaSStefano Ceccherini return B_OK; 275cafaa5aaSStefano Ceccherini 2760b4a36abSbeveloper } 2770b4a36abSbeveloper 2780b4a36abSbeveloper 2790b4a36abSbeveloper status_t 2800b4a36abSbeveloper BDirectWindow::SetFullScreen(bool enable) 2810b4a36abSbeveloper { 282cafaa5aaSStefano Ceccherini status_t status = B_ERROR; 28309ea3092SStefano Ceccherini if (Lock()) { 284764ac9e5SAxel Dörfler #ifdef HAIKU_TARGET_PLATFORM_BEOS 28509ea3092SStefano Ceccherini a_session->swrite_l(DW_SET_FULLSCREEN); 28609ea3092SStefano Ceccherini a_session->swrite_l(server_token); 28717495d0bSStefano Ceccherini a_session->swrite_l((int32)enable); 28809ea3092SStefano Ceccherini Flush(); 28909ea3092SStefano Ceccherini 290bfc3bb18SStefano Ceccherini status_t fullScreen; 291bfc3bb18SStefano Ceccherini a_session->sread(sizeof(status_t), &fullScreen); 292bfc3bb18SStefano Ceccherini a_session->sread(sizeof(status_t), &status); 293feee8cf2SStefano Ceccherini full_screen_enable = enable; 294764ac9e5SAxel Dörfler #else 295ab6a6bedSAxel Dörfler fLink->StartMessage(AS_DIRECT_WINDOW_SET_FULLSCREEN); 296feee8cf2SStefano Ceccherini fLink->Attach<bool>(enable); 297feee8cf2SStefano Ceccherini 298ab6a6bedSAxel Dörfler status_t status = B_ERROR; 299ab6a6bedSAxel Dörfler if (fLink->FlushWithReply(status) == B_OK 300ab6a6bedSAxel Dörfler && status == B_OK) 301feee8cf2SStefano Ceccherini full_screen_enable = enable; 3028575beb8SJérôme Duval #endif 30309ea3092SStefano Ceccherini Unlock(); 304bfc3bb18SStefano Ceccherini 30509ea3092SStefano Ceccherini } 306cafaa5aaSStefano Ceccherini return status; 3070b4a36abSbeveloper } 3080b4a36abSbeveloper 3090b4a36abSbeveloper 3100b4a36abSbeveloper bool 3110b4a36abSbeveloper BDirectWindow::IsFullScreen() const 3120b4a36abSbeveloper { 313cafaa5aaSStefano Ceccherini return full_screen_enable; 3140b4a36abSbeveloper } 3150b4a36abSbeveloper 3160b4a36abSbeveloper 317*0f4fb801SAxel Dörfler /*static*/ 3180b4a36abSbeveloper bool 319cafaa5aaSStefano Ceccherini BDirectWindow::SupportsWindowMode(screen_id id) 3200b4a36abSbeveloper { 321764ac9e5SAxel Dörfler #ifdef HAIKU_TARGET_PLATFORM_BEOS 322feee8cf2SStefano Ceccherini int32 result = 0; 323cafaa5aaSStefano Ceccherini _BAppServerLink_ link; 324cafaa5aaSStefano Ceccherini link.fSession->swrite_l(DW_SUPPORTS_WINDOW_MODE); 325cafaa5aaSStefano Ceccherini link.fSession->swrite_l(id.id); 326cafaa5aaSStefano Ceccherini link.fSession->sync(); 327cafaa5aaSStefano Ceccherini link.fSession->sread(sizeof(result), &result); 328feee8cf2SStefano Ceccherini return result & true; 329764ac9e5SAxel Dörfler #else 330feee8cf2SStefano Ceccherini BPrivate::AppServerLink link; 331ab6a6bedSAxel Dörfler link.StartMessage(AS_DIRECT_WINDOW_SUPPORTS_WINDOW_MODE); 332feee8cf2SStefano Ceccherini link.Attach<screen_id>(id); 333ab6a6bedSAxel Dörfler 334feee8cf2SStefano Ceccherini int32 reply; 335feee8cf2SStefano Ceccherini if (link.FlushWithReply(reply) == B_OK 336ab6a6bedSAxel Dörfler && reply == B_OK) 337feee8cf2SStefano Ceccherini return true; 338feee8cf2SStefano Ceccherini #endif 339feee8cf2SStefano Ceccherini 340feee8cf2SStefano Ceccherini return false; 341cafaa5aaSStefano Ceccherini } 342cafaa5aaSStefano Ceccherini 343cafaa5aaSStefano Ceccherini 344*0f4fb801SAxel Dörfler // #pragma mark - Private methods 345*0f4fb801SAxel Dörfler 346*0f4fb801SAxel Dörfler 347cafaa5aaSStefano Ceccherini int32 348cafaa5aaSStefano Ceccherini BDirectWindow::DirectDeamonFunc(void *arg) 349cafaa5aaSStefano Ceccherini { 350cafaa5aaSStefano Ceccherini BDirectWindow *object = static_cast<BDirectWindow *>(arg); 351cafaa5aaSStefano Ceccherini 352cafaa5aaSStefano Ceccherini while (!object->deamon_killer) { 353cafaa5aaSStefano Ceccherini // This sem is released by the app_server when our 354cafaa5aaSStefano Ceccherini // clipping region changes, or when our window is moved, 355cafaa5aaSStefano Ceccherini // resized, etc. etc. 356*0f4fb801SAxel Dörfler status_t status; 357*0f4fb801SAxel Dörfler do { 358*0f4fb801SAxel Dörfler status = acquire_sem(object->disable_sem); 359*0f4fb801SAxel Dörfler } while (status == B_INTERRUPTED); 360*0f4fb801SAxel Dörfler 361*0f4fb801SAxel Dörfler if (status < B_OK) 362*0f4fb801SAxel Dörfler return -1; 363cafaa5aaSStefano Ceccherini 364cafaa5aaSStefano Ceccherini if (object->LockDirect()) { 365cafaa5aaSStefano Ceccherini if ((object->buffer_desc->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_START) 366cafaa5aaSStefano Ceccherini object->connection_enable = true; 367cafaa5aaSStefano Ceccherini 368cafaa5aaSStefano Ceccherini object->in_direct_connect = true; 369cafaa5aaSStefano Ceccherini object->DirectConnected(object->buffer_desc); 370cafaa5aaSStefano Ceccherini object->in_direct_connect = false; 371cafaa5aaSStefano Ceccherini 372cafaa5aaSStefano Ceccherini if ((object->buffer_desc->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_STOP) 373cafaa5aaSStefano Ceccherini object->connection_enable = false; 374cafaa5aaSStefano Ceccherini 375cafaa5aaSStefano Ceccherini object->UnlockDirect(); 376cafaa5aaSStefano Ceccherini } 377cafaa5aaSStefano Ceccherini 378cafaa5aaSStefano Ceccherini // The app_server then waits (with a timeout) on this sem. 379cafaa5aaSStefano Ceccherini // If we aren't quick enough to release this sem, our app 380cafaa5aaSStefano Ceccherini // will be terminated by the app_server 381*0f4fb801SAxel Dörfler if (release_sem(object->disable_sem_ack) != B_OK) 382*0f4fb801SAxel Dörfler return -1; 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 45271b55088SAxel Dörfler struct direct_window_sync_data syncData; 4538575beb8SJérôme Duval status_t status = B_ERROR; 4548575beb8SJérôme Duval 455764ac9e5SAxel 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 46171b55088SAxel Dörfler a_session->sread(sizeof(syncData), &syncData); 4628575beb8SJérôme Duval a_session->sread(sizeof(status), &status); 463764ac9e5SAxel Dörfler #else 464ab6a6bedSAxel Dörfler fLink->StartMessage(AS_DIRECT_WINDOW_GET_SYNC_DATA); 465feee8cf2SStefano Ceccherini 466feee8cf2SStefano Ceccherini int32 reply; 467feee8cf2SStefano Ceccherini if (fLink->FlushWithReply(reply) == B_OK 468764ac9e5SAxel Dörfler && reply == B_OK) { 46971b55088SAxel Dörfler fLink->Read<direct_window_sync_data>(&syncData); 470feee8cf2SStefano Ceccherini status = B_OK; 471feee8cf2SStefano Ceccherini } 472feee8cf2SStefano Ceccherini #endif 473feee8cf2SStefano Ceccherini 474cafaa5aaSStefano Ceccherini Unlock(); 475cafaa5aaSStefano Ceccherini 4765fdea13fSStefano Ceccherini if (status < B_OK) 4775fdea13fSStefano Ceccherini return; 478cafaa5aaSStefano Ceccherini 479cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING 480cafaa5aaSStefano Ceccherini direct_lock = 0; 481cafaa5aaSStefano Ceccherini direct_lock_count = 0; 4825fdea13fSStefano Ceccherini direct_lock_owner = -1; 483cafaa5aaSStefano Ceccherini direct_lock_stack = NULL; 484cafaa5aaSStefano Ceccherini direct_sem = create_sem(1, "direct sem"); 485cafaa5aaSStefano Ceccherini if (direct_sem > 0) 486cafaa5aaSStefano Ceccherini dw_init_status |= DW_STATUS_SEM_CREATED; 487cafaa5aaSStefano Ceccherini #endif 488cafaa5aaSStefano Ceccherini 48971b55088SAxel Dörfler source_clipping_area = syncData.area; 49071b55088SAxel Dörfler disable_sem = syncData.disable_sem; 49171b55088SAxel Dörfler disable_sem_ack = syncData.disable_sem_ack; 492cafaa5aaSStefano Ceccherini 493cafaa5aaSStefano Ceccherini cloned_clipping_area = clone_area("Clone direct area", (void**)&buffer_desc, 494cafaa5aaSStefano Ceccherini B_ANY_ADDRESS, B_READ_AREA, source_clipping_area); 4955fdea13fSStefano Ceccherini 496cafaa5aaSStefano Ceccherini if (cloned_clipping_area > 0) { 497cafaa5aaSStefano Ceccherini dw_init_status |= DW_STATUS_AREA_CLONED; 498cafaa5aaSStefano Ceccherini 499cafaa5aaSStefano Ceccherini direct_deamon_id = spawn_thread(DirectDeamonFunc, "direct deamon", 500cafaa5aaSStefano Ceccherini B_DISPLAY_PRIORITY, this); 501cafaa5aaSStefano Ceccherini 502cafaa5aaSStefano Ceccherini if (direct_deamon_id > 0) { 503cafaa5aaSStefano Ceccherini deamon_killer = false; 504cafaa5aaSStefano Ceccherini if (resume_thread(direct_deamon_id) == B_OK) 505cafaa5aaSStefano Ceccherini dw_init_status |= DW_STATUS_THREAD_STARTED; 506cafaa5aaSStefano Ceccherini else 507cafaa5aaSStefano Ceccherini kill_thread(direct_deamon_id); 508cafaa5aaSStefano Ceccherini } 509cafaa5aaSStefano Ceccherini } 510cafaa5aaSStefano Ceccherini } 5110b4a36abSbeveloper 5120b4a36abSbeveloper 5130b4a36abSbeveloper void 514cafaa5aaSStefano Ceccherini BDirectWindow::DisposeData() 5150b4a36abSbeveloper { 516cafaa5aaSStefano Ceccherini // wait until the connection terminates: we can't destroy 517cafaa5aaSStefano Ceccherini // the object until the client receives the B_DIRECT_STOP 518cafaa5aaSStefano Ceccherini // notification, or bad things will happen 519cafaa5aaSStefano Ceccherini while (connection_enable) 520cafaa5aaSStefano Ceccherini snooze(50000); 521cafaa5aaSStefano Ceccherini 522cafaa5aaSStefano Ceccherini LockDirect(); 523cafaa5aaSStefano Ceccherini 524cafaa5aaSStefano Ceccherini if (dw_init_status & DW_STATUS_THREAD_STARTED) { 525cafaa5aaSStefano Ceccherini deamon_killer = true; 526cafaa5aaSStefano Ceccherini // Release this sem, otherwise the Direct deamon thread 527cafaa5aaSStefano Ceccherini // will wait forever on it 528cafaa5aaSStefano Ceccherini release_sem(disable_sem); 529cafaa5aaSStefano Ceccherini status_t retVal; 530cafaa5aaSStefano Ceccherini wait_for_thread(direct_deamon_id, &retVal); 531cafaa5aaSStefano Ceccherini } 532cafaa5aaSStefano Ceccherini 533cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING 534cafaa5aaSStefano Ceccherini if (dw_init_status & DW_STATUS_SEM_CREATED) 535cafaa5aaSStefano Ceccherini delete_sem(direct_sem); 536cafaa5aaSStefano Ceccherini #endif 537cafaa5aaSStefano Ceccherini 538cafaa5aaSStefano Ceccherini if (dw_init_status & DW_STATUS_AREA_CLONED) 539cafaa5aaSStefano Ceccherini delete_area(cloned_clipping_area); 5400b4a36abSbeveloper } 5410b4a36abSbeveloper 5420b4a36abSbeveloper 543cafaa5aaSStefano Ceccherini status_t 544cafaa5aaSStefano Ceccherini BDirectWindow::DriverSetup() const 5450b4a36abSbeveloper { 54617495d0bSStefano Ceccherini // Unimplemented in R5. 54709ea3092SStefano Ceccherini // This function is probably here because they wanted, in a future time, 54809ea3092SStefano Ceccherini // to implement graphic acceleration within BDirectWindow 54909ea3092SStefano Ceccherini // (in fact, there is also a BDirectDriver member in BDirectWindow, 55017495d0bSStefano Ceccherini // though it's not used). 55109ea3092SStefano Ceccherini 552cafaa5aaSStefano Ceccherini return B_OK; 5530b4a36abSbeveloper } 5540b4a36abSbeveloper 5550b4a36abSbeveloper 556cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow1() {} 557cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow2() {} 558cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow3() {} 559cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow4() {} 560