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> 124fbc3f58SStefano Ceccherini #include <Screen.h> 1371b55088SAxel Dörfler 14cafaa5aaSStefano Ceccherini #include <clipping.h> 15feee8cf2SStefano Ceccherini #include <AppServerLink.h> 162b6ac345SStefano Ceccherini #include <DirectWindowPrivate.h> 17feee8cf2SStefano Ceccherini #include <ServerProtocol.h> 18764ac9e5SAxel Dörfler 19764ac9e5SAxel Dörfler 20*af294326SPhilippe Houdoin // We don't need this kind of locking, since the directDaemonFunc 21cafaa5aaSStefano Ceccherini // doesn't access critical shared data. 22cafaa5aaSStefano Ceccherini #define DW_NEEDS_LOCKING 0 23cafaa5aaSStefano Ceccherini 24cafaa5aaSStefano Ceccherini enum dw_status_bits { 2517495d0bSStefano Ceccherini DW_STATUS_AREA_CLONED = 0x1, 2617495d0bSStefano Ceccherini DW_STATUS_THREAD_STARTED = 0x2, 2717495d0bSStefano Ceccherini DW_STATUS_SEM_CREATED = 0x4 28cafaa5aaSStefano Ceccherini }; 29cafaa5aaSStefano Ceccherini 30cafaa5aaSStefano Ceccherini 31764ac9e5SAxel Dörfler BDirectWindow::BDirectWindow(BRect frame, const char *title, window_type type, 32764ac9e5SAxel Dörfler uint32 flags, uint32 workspace) 33cafaa5aaSStefano Ceccherini : BWindow(frame, title, type, flags, workspace) 34cafaa5aaSStefano Ceccherini { 35cafaa5aaSStefano Ceccherini InitData(); 360b4a36abSbeveloper } 370b4a36abSbeveloper 380b4a36abSbeveloper 39764ac9e5SAxel Dörfler BDirectWindow::BDirectWindow(BRect frame, const char *title, window_look look, 40764ac9e5SAxel Dörfler window_feel feel, uint32 flags, uint32 workspace) 41cafaa5aaSStefano Ceccherini : BWindow(frame, title, look, feel, flags, workspace) 420b4a36abSbeveloper { 43cafaa5aaSStefano Ceccherini InitData(); 440b4a36abSbeveloper } 450b4a36abSbeveloper 460b4a36abSbeveloper 470b4a36abSbeveloper BDirectWindow::~BDirectWindow() 480b4a36abSbeveloper { 49cafaa5aaSStefano Ceccherini DisposeData(); 500b4a36abSbeveloper } 510b4a36abSbeveloper 520b4a36abSbeveloper 53cafaa5aaSStefano Ceccherini // start of regular BWindow API 540b4a36abSbeveloper BArchivable * 550b4a36abSbeveloper BDirectWindow::Instantiate(BMessage *data) 560b4a36abSbeveloper { 570b4a36abSbeveloper return NULL; 580b4a36abSbeveloper } 590b4a36abSbeveloper 600b4a36abSbeveloper 610b4a36abSbeveloper status_t 62cafaa5aaSStefano Ceccherini BDirectWindow::Archive(BMessage *data, bool deep) const 630b4a36abSbeveloper { 64cafaa5aaSStefano Ceccherini return inherited::Archive(data, deep); 650b4a36abSbeveloper } 660b4a36abSbeveloper 670b4a36abSbeveloper 680b4a36abSbeveloper void 69cafaa5aaSStefano Ceccherini BDirectWindow::Quit() 700b4a36abSbeveloper { 71cafaa5aaSStefano Ceccherini inherited::Quit(); 720b4a36abSbeveloper } 730b4a36abSbeveloper 740b4a36abSbeveloper 750b4a36abSbeveloper void 76cafaa5aaSStefano Ceccherini BDirectWindow::DispatchMessage(BMessage *message, BHandler *handler) 770b4a36abSbeveloper { 78cafaa5aaSStefano Ceccherini inherited::DispatchMessage(message, handler); 790b4a36abSbeveloper } 800b4a36abSbeveloper 810b4a36abSbeveloper 820b4a36abSbeveloper void 830b4a36abSbeveloper BDirectWindow::MessageReceived(BMessage *message) 840b4a36abSbeveloper { 85cafaa5aaSStefano Ceccherini inherited::MessageReceived(message); 860b4a36abSbeveloper } 870b4a36abSbeveloper 880b4a36abSbeveloper 890b4a36abSbeveloper void 900b4a36abSbeveloper BDirectWindow::FrameMoved(BPoint new_position) 910b4a36abSbeveloper { 92cafaa5aaSStefano Ceccherini inherited::FrameMoved(new_position); 930b4a36abSbeveloper } 940b4a36abSbeveloper 950b4a36abSbeveloper 960b4a36abSbeveloper void 97cafaa5aaSStefano Ceccherini BDirectWindow::WorkspacesChanged(uint32 old_ws, uint32 new_ws) 980b4a36abSbeveloper { 99cafaa5aaSStefano Ceccherini inherited::WorkspacesChanged(old_ws, new_ws); 1000b4a36abSbeveloper } 1010b4a36abSbeveloper 1020b4a36abSbeveloper 1030b4a36abSbeveloper void 104cafaa5aaSStefano Ceccherini BDirectWindow::WorkspaceActivated(int32 ws, bool state) 1050b4a36abSbeveloper { 106cafaa5aaSStefano Ceccherini inherited::WorkspaceActivated(ws, state); 1070b4a36abSbeveloper } 1080b4a36abSbeveloper 1090b4a36abSbeveloper 1100b4a36abSbeveloper void 111cafaa5aaSStefano Ceccherini BDirectWindow::FrameResized(float new_width, float new_height) 1120b4a36abSbeveloper { 113cafaa5aaSStefano Ceccherini inherited::FrameResized(new_width, new_height); 1140b4a36abSbeveloper } 1150b4a36abSbeveloper 1160b4a36abSbeveloper 1170b4a36abSbeveloper void 1180b4a36abSbeveloper BDirectWindow::Minimize(bool minimize) 1190b4a36abSbeveloper { 120cafaa5aaSStefano Ceccherini inherited::Minimize(minimize); 1210b4a36abSbeveloper } 1220b4a36abSbeveloper 1230b4a36abSbeveloper 1240b4a36abSbeveloper void 125cafaa5aaSStefano Ceccherini BDirectWindow::Zoom(BPoint rec_position, float rec_width, float rec_height) 1260b4a36abSbeveloper { 127cafaa5aaSStefano Ceccherini inherited::Zoom(rec_position, rec_width, rec_height); 1280b4a36abSbeveloper } 1290b4a36abSbeveloper 1300b4a36abSbeveloper 1310b4a36abSbeveloper void 132cafaa5aaSStefano Ceccherini BDirectWindow::ScreenChanged(BRect screen_size, color_space depth) 1330b4a36abSbeveloper { 134cafaa5aaSStefano Ceccherini inherited::ScreenChanged(screen_size, depth); 1350b4a36abSbeveloper } 1360b4a36abSbeveloper 1370b4a36abSbeveloper 1380b4a36abSbeveloper void 1390b4a36abSbeveloper BDirectWindow::MenusBeginning() 1400b4a36abSbeveloper { 141cafaa5aaSStefano Ceccherini inherited::MenusBeginning(); 1420b4a36abSbeveloper } 1430b4a36abSbeveloper 1440b4a36abSbeveloper 1450b4a36abSbeveloper void 1460b4a36abSbeveloper BDirectWindow::MenusEnded() 1470b4a36abSbeveloper { 148cafaa5aaSStefano Ceccherini inherited::MenusEnded(); 1490b4a36abSbeveloper } 1500b4a36abSbeveloper 1510b4a36abSbeveloper 1520b4a36abSbeveloper void 1530b4a36abSbeveloper BDirectWindow::WindowActivated(bool state) 1540b4a36abSbeveloper { 155cafaa5aaSStefano Ceccherini inherited::WindowActivated(state); 1560b4a36abSbeveloper } 1570b4a36abSbeveloper 1580b4a36abSbeveloper 1590b4a36abSbeveloper void 1600b4a36abSbeveloper BDirectWindow::Show() 1610b4a36abSbeveloper { 162cafaa5aaSStefano Ceccherini inherited::Show(); 1630b4a36abSbeveloper } 1640b4a36abSbeveloper 1650b4a36abSbeveloper 1660b4a36abSbeveloper void 1670b4a36abSbeveloper BDirectWindow::Hide() 1680b4a36abSbeveloper { 169cafaa5aaSStefano Ceccherini inherited::Hide(); 1700b4a36abSbeveloper } 1710b4a36abSbeveloper 1720b4a36abSbeveloper 1730b4a36abSbeveloper BHandler * 174cafaa5aaSStefano Ceccherini BDirectWindow::ResolveSpecifier(BMessage *msg, int32 index, 175cafaa5aaSStefano Ceccherini BMessage *specifier, int32 form, const char *property) 1760b4a36abSbeveloper { 177cafaa5aaSStefano Ceccherini return inherited::ResolveSpecifier(msg, index, specifier, form, property); 1780b4a36abSbeveloper } 1790b4a36abSbeveloper 1800b4a36abSbeveloper 1810b4a36abSbeveloper status_t 1820b4a36abSbeveloper BDirectWindow::GetSupportedSuites(BMessage *data) 1830b4a36abSbeveloper { 184cafaa5aaSStefano Ceccherini return inherited::GetSupportedSuites(data); 1850b4a36abSbeveloper } 1860b4a36abSbeveloper 1870b4a36abSbeveloper 1880b4a36abSbeveloper status_t 189cafaa5aaSStefano Ceccherini BDirectWindow::Perform(perform_code d, void *arg) 1900b4a36abSbeveloper { 191cafaa5aaSStefano Ceccherini return inherited::Perform(d, arg); 1920b4a36abSbeveloper } 1930b4a36abSbeveloper 1940b4a36abSbeveloper 195b816dc1eSIngo Weinhold void 196b816dc1eSIngo Weinhold BDirectWindow::task_looper() 197b816dc1eSIngo Weinhold { 198cafaa5aaSStefano Ceccherini inherited::task_looper(); 199b816dc1eSIngo Weinhold } 200b816dc1eSIngo Weinhold 201cafaa5aaSStefano Ceccherini 202b816dc1eSIngo Weinhold BMessage * 203b816dc1eSIngo Weinhold BDirectWindow::ConvertToMessage(void *raw, int32 code) 204b816dc1eSIngo Weinhold { 205cafaa5aaSStefano Ceccherini return inherited::ConvertToMessage(raw, code); 206b816dc1eSIngo Weinhold } 2070b4a36abSbeveloper 2080b4a36abSbeveloper 209764ac9e5SAxel Dörfler // #pragma mark - BDirectWindow specific API 210764ac9e5SAxel Dörfler 211764ac9e5SAxel Dörfler 2120b4a36abSbeveloper void 2130b4a36abSbeveloper BDirectWindow::DirectConnected(direct_buffer_info *info) 2140b4a36abSbeveloper { 215cafaa5aaSStefano Ceccherini // implemented in subclasses 2160b4a36abSbeveloper } 2170b4a36abSbeveloper 2180b4a36abSbeveloper 2190b4a36abSbeveloper status_t 220cafaa5aaSStefano Ceccherini BDirectWindow::GetClippingRegion(BRegion *region, BPoint *origin) const 2210b4a36abSbeveloper { 222cafaa5aaSStefano Ceccherini if (region == NULL) 223cafaa5aaSStefano Ceccherini return B_BAD_VALUE; 224cafaa5aaSStefano Ceccherini 2254f6f70e0SStefano Ceccherini if (IsLocked() || !LockDirect()) 2265fdea13fSStefano Ceccherini return B_ERROR; 2275fdea13fSStefano Ceccherini 228cafaa5aaSStefano Ceccherini if (in_direct_connect) { 229cafaa5aaSStefano Ceccherini UnlockDirect(); 230cafaa5aaSStefano Ceccherini return B_ERROR; 231cafaa5aaSStefano Ceccherini } 232cafaa5aaSStefano Ceccherini 233cafaa5aaSStefano Ceccherini // BPoint's coordinates are floats. We can only work 234cafaa5aaSStefano Ceccherini // with integers. 235cafaa5aaSStefano Ceccherini int32 originX, originY; 236cafaa5aaSStefano Ceccherini if (origin == NULL) { 237cafaa5aaSStefano Ceccherini originX = 0; 238cafaa5aaSStefano Ceccherini originY = 0; 239cafaa5aaSStefano Ceccherini } else { 240cafaa5aaSStefano Ceccherini originX = (int32)origin->x; 241cafaa5aaSStefano Ceccherini originY = (int32)origin->y; 242cafaa5aaSStefano Ceccherini } 243cafaa5aaSStefano Ceccherini 244764ac9e5SAxel Dörfler #ifndef HAIKU_TARGET_PLATFORM_DANO 245cafaa5aaSStefano Ceccherini // Since we are friend of BRegion, we can access its private members. 246cafaa5aaSStefano Ceccherini // Otherwise, we would need to call BRegion::Include(clipping_rect) 247cafaa5aaSStefano Ceccherini // for every clipping_rect in our clip_list, and that would be much 2485fdea13fSStefano Ceccherini // more overkill than this (tested ). 249cafaa5aaSStefano Ceccherini region->set_size(buffer_desc->clip_list_count); 250cafaa5aaSStefano Ceccherini region->count = buffer_desc->clip_list_count; 251cafaa5aaSStefano Ceccherini region->bound = buffer_desc->clip_bounds; 2524f6f70e0SStefano Ceccherini for (uint32 c = 0; c < buffer_desc->clip_list_count; c++) 2534f6f70e0SStefano Ceccherini region->data[c] = buffer_desc->clip_list[c]; 254cafaa5aaSStefano Ceccherini 255cafaa5aaSStefano Ceccherini // adjust bounds by the given origin point 2564f6f70e0SStefano Ceccherini region->OffsetBy(-originX, -originY); 257366fdcdfSMarcus Overhagen #endif 258366fdcdfSMarcus Overhagen 259cafaa5aaSStefano Ceccherini UnlockDirect(); 260cafaa5aaSStefano Ceccherini 261cafaa5aaSStefano Ceccherini return B_OK; 262cafaa5aaSStefano Ceccherini 2630b4a36abSbeveloper } 2640b4a36abSbeveloper 2650b4a36abSbeveloper 2660b4a36abSbeveloper status_t 2670b4a36abSbeveloper BDirectWindow::SetFullScreen(bool enable) 2680b4a36abSbeveloper { 269cafaa5aaSStefano Ceccherini status_t status = B_ERROR; 27009ea3092SStefano Ceccherini if (Lock()) { 271ab6a6bedSAxel Dörfler fLink->StartMessage(AS_DIRECT_WINDOW_SET_FULLSCREEN); 272feee8cf2SStefano Ceccherini fLink->Attach<bool>(enable); 273feee8cf2SStefano Ceccherini 274ab6a6bedSAxel Dörfler if (fLink->FlushWithReply(status) == B_OK 275ab6a6bedSAxel Dörfler && status == B_OK) 276feee8cf2SStefano Ceccherini full_screen_enable = enable; 27709ea3092SStefano Ceccherini Unlock(); 27809ea3092SStefano Ceccherini } 279cafaa5aaSStefano Ceccherini return status; 2800b4a36abSbeveloper } 2810b4a36abSbeveloper 2820b4a36abSbeveloper 2830b4a36abSbeveloper bool 2840b4a36abSbeveloper BDirectWindow::IsFullScreen() const 2850b4a36abSbeveloper { 286cafaa5aaSStefano Ceccherini return full_screen_enable; 2870b4a36abSbeveloper } 2880b4a36abSbeveloper 2890b4a36abSbeveloper 2900f4fb801SAxel Dörfler /*static*/ 2910b4a36abSbeveloper bool 292cafaa5aaSStefano Ceccherini BDirectWindow::SupportsWindowMode(screen_id id) 2930b4a36abSbeveloper { 294bf9071eeSStefano Ceccherini /* display_mode mode; 2954fbc3f58SStefano Ceccherini status_t status = BScreen(id).GetMode(&mode); 2964fbc3f58SStefano Ceccherini if (status == B_OK) 2974fbc3f58SStefano Ceccherini return mode.flags & B_PARALLEL_ACCESS; 298feee8cf2SStefano Ceccherini 299bf9071eeSStefano Ceccherini return false;*/ 300bf9071eeSStefano Ceccherini // TODO: Apparently, the above is false for the vesa driver, 301bf9071eeSStefano Ceccherini // but enabling it doesn't do any harm... maybe we should just return always true. 302bf9071eeSStefano Ceccherini // At least, I can't see why window mode shouldn't be supported. 303bf9071eeSStefano Ceccherini return true; 304cafaa5aaSStefano Ceccherini } 305cafaa5aaSStefano Ceccherini 306cafaa5aaSStefano Ceccherini 3070f4fb801SAxel Dörfler // #pragma mark - Private methods 3080f4fb801SAxel Dörfler 3090f4fb801SAxel Dörfler 310cafaa5aaSStefano Ceccherini int32 311*af294326SPhilippe Houdoin BDirectWindow::DirectDaemonFunc(void *arg) 312cafaa5aaSStefano Ceccherini { 313cafaa5aaSStefano Ceccherini BDirectWindow *object = static_cast<BDirectWindow *>(arg); 314cafaa5aaSStefano Ceccherini 315*af294326SPhilippe Houdoin while (!object->daemon_killer) { 316cafaa5aaSStefano Ceccherini // This sem is released by the app_server when our 317cafaa5aaSStefano Ceccherini // clipping region changes, or when our window is moved, 318cafaa5aaSStefano Ceccherini // resized, etc. etc. 3190f4fb801SAxel Dörfler status_t status; 3200f4fb801SAxel Dörfler do { 3210f4fb801SAxel Dörfler status = acquire_sem(object->disable_sem); 3220f4fb801SAxel Dörfler } while (status == B_INTERRUPTED); 3230f4fb801SAxel Dörfler 3240f4fb801SAxel Dörfler if (status < B_OK) 3250f4fb801SAxel Dörfler return -1; 326cafaa5aaSStefano Ceccherini 327cafaa5aaSStefano Ceccherini if (object->LockDirect()) { 328cafaa5aaSStefano Ceccherini if ((object->buffer_desc->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_START) 329cafaa5aaSStefano Ceccherini object->connection_enable = true; 330cafaa5aaSStefano Ceccherini 331cafaa5aaSStefano Ceccherini object->in_direct_connect = true; 332cafaa5aaSStefano Ceccherini object->DirectConnected(object->buffer_desc); 333cafaa5aaSStefano Ceccherini object->in_direct_connect = false; 334cafaa5aaSStefano Ceccherini 335cafaa5aaSStefano Ceccherini if ((object->buffer_desc->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_STOP) 336cafaa5aaSStefano Ceccherini object->connection_enable = false; 337cafaa5aaSStefano Ceccherini 338cafaa5aaSStefano Ceccherini object->UnlockDirect(); 339cafaa5aaSStefano Ceccherini } 340cafaa5aaSStefano Ceccherini 341cafaa5aaSStefano Ceccherini // The app_server then waits (with a timeout) on this sem. 342cafaa5aaSStefano Ceccherini // If we aren't quick enough to release this sem, our app 343cafaa5aaSStefano Ceccherini // will be terminated by the app_server 3440f4fb801SAxel Dörfler if (release_sem(object->disable_sem_ack) != B_OK) 3450f4fb801SAxel Dörfler return -1; 346cafaa5aaSStefano Ceccherini } 347cafaa5aaSStefano Ceccherini 348cafaa5aaSStefano Ceccherini return 0; 349cafaa5aaSStefano Ceccherini } 350cafaa5aaSStefano Ceccherini 351cafaa5aaSStefano Ceccherini 35217495d0bSStefano Ceccherini // LockDirect() and UnlockDirect() are no-op on R5. I tried to call (R5's) LockDirect() 35317495d0bSStefano Ceccherini // repeatedly, from the same thread and from different threads, nothing happened. 35417495d0bSStefano Ceccherini // I implemented them anyway, as they were the first methods I wrote 35517495d0bSStefano Ceccherini // in this class (As you can see, I even needed to cast away their constness 35617495d0bSStefano Ceccherini // to make them do something useful). 357*af294326SPhilippe Houdoin // They're not needed though, as the direct_daemon_thread doesn't change 35817495d0bSStefano Ceccherini // any shared data. They are probably here for future enhancements (see also the 35917495d0bSStefano Ceccherini // comment in DriverSetup() 360cafaa5aaSStefano Ceccherini bool 361cafaa5aaSStefano Ceccherini BDirectWindow::LockDirect() const 362cafaa5aaSStefano Ceccherini { 363cafaa5aaSStefano Ceccherini status_t status = B_OK; 364cafaa5aaSStefano Ceccherini 365cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING 366cafaa5aaSStefano Ceccherini BDirectWindow *casted = const_cast<BDirectWindow *>(this); 367cafaa5aaSStefano Ceccherini 3685fdea13fSStefano Ceccherini if (atomic_add(&casted->direct_lock, 1) > 0) { 369cafaa5aaSStefano Ceccherini do { 370cafaa5aaSStefano Ceccherini status = acquire_sem(direct_sem); 371cafaa5aaSStefano Ceccherini } while (status == B_INTERRUPTED); 3725fdea13fSStefano Ceccherini } 373cafaa5aaSStefano Ceccherini 374cafaa5aaSStefano Ceccherini if (status == B_OK) { 375cafaa5aaSStefano Ceccherini casted->direct_lock_owner = find_thread(NULL); 376cafaa5aaSStefano Ceccherini casted->direct_lock_count++; 377cafaa5aaSStefano Ceccherini } 378cafaa5aaSStefano Ceccherini #endif 379cafaa5aaSStefano Ceccherini 380cafaa5aaSStefano Ceccherini return status == B_OK; 3810b4a36abSbeveloper } 3820b4a36abSbeveloper 3830b4a36abSbeveloper 3840b4a36abSbeveloper void 385cafaa5aaSStefano Ceccherini BDirectWindow::UnlockDirect() const 3860b4a36abSbeveloper { 387cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING 388cafaa5aaSStefano Ceccherini BDirectWindow *casted = const_cast<BDirectWindow *>(this); 389cafaa5aaSStefano Ceccherini 390cafaa5aaSStefano Ceccherini if (atomic_add(&casted->direct_lock, -1) > 1) 391cafaa5aaSStefano Ceccherini release_sem(direct_sem); 392cafaa5aaSStefano Ceccherini 393cafaa5aaSStefano Ceccherini casted->direct_lock_count--; 394cafaa5aaSStefano Ceccherini #endif 3950b4a36abSbeveloper } 3960b4a36abSbeveloper 3970b4a36abSbeveloper 3980b4a36abSbeveloper void 399cafaa5aaSStefano Ceccherini BDirectWindow::InitData() 4000b4a36abSbeveloper { 401cafaa5aaSStefano Ceccherini connection_enable = false; 402cafaa5aaSStefano Ceccherini full_screen_enable = false; 403cafaa5aaSStefano Ceccherini in_direct_connect = false; 404cafaa5aaSStefano Ceccherini 405cafaa5aaSStefano Ceccherini dw_init_status = 0; 406cafaa5aaSStefano Ceccherini 407cafaa5aaSStefano Ceccherini direct_driver_ready = false; 408cafaa5aaSStefano Ceccherini direct_driver_type = 0; 409cafaa5aaSStefano Ceccherini direct_driver_token = 0; 410cafaa5aaSStefano Ceccherini direct_driver = NULL; 411cafaa5aaSStefano Ceccherini 4125fdea13fSStefano Ceccherini if (!Lock()) 4135fdea13fSStefano Ceccherini return; 4145fdea13fSStefano Ceccherini 41571b55088SAxel Dörfler struct direct_window_sync_data syncData; 4168575beb8SJérôme Duval 417ab6a6bedSAxel Dörfler fLink->StartMessage(AS_DIRECT_WINDOW_GET_SYNC_DATA); 418feee8cf2SStefano Ceccherini 4192b6ac345SStefano Ceccherini status_t status = B_ERROR; 4202b6ac345SStefano Ceccherini if (fLink->FlushWithReply(status) == B_OK 4212b6ac345SStefano Ceccherini && status == B_OK) { 42271b55088SAxel Dörfler fLink->Read<direct_window_sync_data>(&syncData); 423feee8cf2SStefano Ceccherini } 424feee8cf2SStefano Ceccherini 425cafaa5aaSStefano Ceccherini Unlock(); 426cafaa5aaSStefano Ceccherini 4275fdea13fSStefano Ceccherini if (status < B_OK) 4285fdea13fSStefano Ceccherini return; 429cafaa5aaSStefano Ceccherini 430cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING 431cafaa5aaSStefano Ceccherini direct_lock = 0; 432cafaa5aaSStefano Ceccherini direct_lock_count = 0; 4335fdea13fSStefano Ceccherini direct_lock_owner = -1; 434cafaa5aaSStefano Ceccherini direct_lock_stack = NULL; 435cafaa5aaSStefano Ceccherini direct_sem = create_sem(1, "direct sem"); 436cafaa5aaSStefano Ceccherini if (direct_sem > 0) 437cafaa5aaSStefano Ceccherini dw_init_status |= DW_STATUS_SEM_CREATED; 438cafaa5aaSStefano Ceccherini #endif 439cafaa5aaSStefano Ceccherini 44071b55088SAxel Dörfler source_clipping_area = syncData.area; 44171b55088SAxel Dörfler disable_sem = syncData.disable_sem; 44271b55088SAxel Dörfler disable_sem_ack = syncData.disable_sem_ack; 443cafaa5aaSStefano Ceccherini 444cafaa5aaSStefano Ceccherini cloned_clipping_area = clone_area("Clone direct area", (void**)&buffer_desc, 445cafaa5aaSStefano Ceccherini B_ANY_ADDRESS, B_READ_AREA, source_clipping_area); 4465fdea13fSStefano Ceccherini 447cafaa5aaSStefano Ceccherini if (cloned_clipping_area > 0) { 448cafaa5aaSStefano Ceccherini dw_init_status |= DW_STATUS_AREA_CLONED; 449cafaa5aaSStefano Ceccherini 450*af294326SPhilippe Houdoin direct_daemon_id = spawn_thread(DirectDaemonFunc, "direct daemon", 451cafaa5aaSStefano Ceccherini B_DISPLAY_PRIORITY, this); 452cafaa5aaSStefano Ceccherini 453*af294326SPhilippe Houdoin if (direct_daemon_id > 0) { 454*af294326SPhilippe Houdoin daemon_killer = false; 455*af294326SPhilippe Houdoin if (resume_thread(direct_daemon_id) == B_OK) 456cafaa5aaSStefano Ceccherini dw_init_status |= DW_STATUS_THREAD_STARTED; 457cafaa5aaSStefano Ceccherini else 458*af294326SPhilippe Houdoin kill_thread(direct_daemon_id); 459cafaa5aaSStefano Ceccherini } 460cafaa5aaSStefano Ceccherini } 461cafaa5aaSStefano Ceccherini } 4620b4a36abSbeveloper 4630b4a36abSbeveloper 4640b4a36abSbeveloper void 465cafaa5aaSStefano Ceccherini BDirectWindow::DisposeData() 4660b4a36abSbeveloper { 467cafaa5aaSStefano Ceccherini // wait until the connection terminates: we can't destroy 468cafaa5aaSStefano Ceccherini // the object until the client receives the B_DIRECT_STOP 469cafaa5aaSStefano Ceccherini // notification, or bad things will happen 470cafaa5aaSStefano Ceccherini while (connection_enable) 471cafaa5aaSStefano Ceccherini snooze(50000); 472cafaa5aaSStefano Ceccherini 473cafaa5aaSStefano Ceccherini LockDirect(); 474cafaa5aaSStefano Ceccherini 475cafaa5aaSStefano Ceccherini if (dw_init_status & DW_STATUS_THREAD_STARTED) { 476*af294326SPhilippe Houdoin daemon_killer = true; 477*af294326SPhilippe Houdoin // Release this sem, otherwise the Direct daemon thread 478cafaa5aaSStefano Ceccherini // will wait forever on it 479cafaa5aaSStefano Ceccherini release_sem(disable_sem); 480cafaa5aaSStefano Ceccherini status_t retVal; 481*af294326SPhilippe Houdoin wait_for_thread(direct_daemon_id, &retVal); 482cafaa5aaSStefano Ceccherini } 483cafaa5aaSStefano Ceccherini 484cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING 485cafaa5aaSStefano Ceccherini if (dw_init_status & DW_STATUS_SEM_CREATED) 486cafaa5aaSStefano Ceccherini delete_sem(direct_sem); 487cafaa5aaSStefano Ceccherini #endif 488cafaa5aaSStefano Ceccherini 489cafaa5aaSStefano Ceccherini if (dw_init_status & DW_STATUS_AREA_CLONED) 490cafaa5aaSStefano Ceccherini delete_area(cloned_clipping_area); 4910b4a36abSbeveloper } 4920b4a36abSbeveloper 4930b4a36abSbeveloper 494cafaa5aaSStefano Ceccherini status_t 495cafaa5aaSStefano Ceccherini BDirectWindow::DriverSetup() const 4960b4a36abSbeveloper { 49717495d0bSStefano Ceccherini // Unimplemented in R5. 49809ea3092SStefano Ceccherini // This function is probably here because they wanted, in a future time, 49909ea3092SStefano Ceccherini // to implement graphic acceleration within BDirectWindow 50009ea3092SStefano Ceccherini // (in fact, there is also a BDirectDriver member in BDirectWindow, 50117495d0bSStefano Ceccherini // though it's not used). 50209ea3092SStefano Ceccherini 503cafaa5aaSStefano Ceccherini return B_OK; 5040b4a36abSbeveloper } 5050b4a36abSbeveloper 5060b4a36abSbeveloper 507cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow1() {} 508cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow2() {} 509cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow3() {} 510cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow4() {} 511