109ea3092SStefano Ceccherini /* 2*302f6260SStefano Ceccherini * Copyright 2003-2006, 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 20af294326SPhilippe 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 2282b73985eSStefano Ceccherini if (fInDirectConnect) { 229cafaa5aaSStefano Ceccherini UnlockDirect(); 230cafaa5aaSStefano Ceccherini return B_ERROR; 231cafaa5aaSStefano Ceccherini } 232cafaa5aaSStefano Ceccherini 233cafaa5aaSStefano Ceccherini // BPoint's coordinates are floats. We can only work 2342b73985eSStefano Ceccherini // with integers._DaemonStarter 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 ). 2492b73985eSStefano Ceccherini region->set_size(fBufferDesc->clip_list_count); 2502b73985eSStefano Ceccherini region->count = fBufferDesc->clip_list_count; 2512b73985eSStefano Ceccherini region->bound = fBufferDesc->clip_bounds; 2522b73985eSStefano Ceccherini for (uint32 c = 0; c < fBufferDesc->clip_list_count; c++) 2532b73985eSStefano Ceccherini region->data[c] = fBufferDesc->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 { 2692b73985eSStefano Ceccherini if (fIsFullScreen == enable) 2702b73985eSStefano Ceccherini return B_OK; 2712b73985eSStefano Ceccherini 272cafaa5aaSStefano Ceccherini status_t status = B_ERROR; 27309ea3092SStefano Ceccherini if (Lock()) { 274ab6a6bedSAxel Dörfler fLink->StartMessage(AS_DIRECT_WINDOW_SET_FULLSCREEN); 275feee8cf2SStefano Ceccherini fLink->Attach<bool>(enable); 276feee8cf2SStefano Ceccherini 277ab6a6bedSAxel Dörfler if (fLink->FlushWithReply(status) == B_OK 2789ecf9d1cSIngo Weinhold && status == B_OK) { 2792b73985eSStefano Ceccherini fIsFullScreen = enable; 2809ecf9d1cSIngo Weinhold } 28109ea3092SStefano Ceccherini Unlock(); 28209ea3092SStefano Ceccherini } 283cafaa5aaSStefano Ceccherini return status; 2840b4a36abSbeveloper } 2850b4a36abSbeveloper 2860b4a36abSbeveloper 2870b4a36abSbeveloper bool 2880b4a36abSbeveloper BDirectWindow::IsFullScreen() const 2890b4a36abSbeveloper { 2902b73985eSStefano Ceccherini return fIsFullScreen; 2910b4a36abSbeveloper } 2920b4a36abSbeveloper 2930b4a36abSbeveloper 2940f4fb801SAxel Dörfler /*static*/ 2950b4a36abSbeveloper bool 296cafaa5aaSStefano Ceccherini BDirectWindow::SupportsWindowMode(screen_id id) 2970b4a36abSbeveloper { 298bf9071eeSStefano Ceccherini /* display_mode mode; 2994fbc3f58SStefano Ceccherini status_t status = BScreen(id).GetMode(&mode); 3004fbc3f58SStefano Ceccherini if (status == B_OK) 3014fbc3f58SStefano Ceccherini return mode.flags & B_PARALLEL_ACCESS; 302feee8cf2SStefano Ceccherini 303bf9071eeSStefano Ceccherini return false;*/ 304bf9071eeSStefano Ceccherini // TODO: Apparently, the above is false for the vesa driver, 305bf9071eeSStefano Ceccherini // but enabling it doesn't do any harm... maybe we should just return always true. 306bf9071eeSStefano Ceccherini // At least, I can't see why window mode shouldn't be supported. 3079ecf9d1cSIngo Weinhold // additional NOTE: it probably depends on wether hardware cursor is supported or 3089ecf9d1cSIngo Weinhold // not 309bf9071eeSStefano Ceccherini return true; 310cafaa5aaSStefano Ceccherini } 311cafaa5aaSStefano Ceccherini 312cafaa5aaSStefano Ceccherini 3130f4fb801SAxel Dörfler // #pragma mark - Private methods 3140f4fb801SAxel Dörfler 3152b73985eSStefano Ceccherini /* static */ 3162b73985eSStefano Ceccherini int32 3172b73985eSStefano Ceccherini BDirectWindow::_DaemonStarter(void *arg) 3182b73985eSStefano Ceccherini { 3192b73985eSStefano Ceccherini return static_cast<BDirectWindow *>(arg)->DirectDaemonFunc(); 3202b73985eSStefano Ceccherini } 3212b73985eSStefano Ceccherini 3220f4fb801SAxel Dörfler 323cafaa5aaSStefano Ceccherini int32 3242b73985eSStefano Ceccherini BDirectWindow::DirectDaemonFunc() 325cafaa5aaSStefano Ceccherini { 3262b73985eSStefano Ceccherini while (!fDaemonKiller) { 327cafaa5aaSStefano Ceccherini // This sem is released by the app_server when our 328cafaa5aaSStefano Ceccherini // clipping region changes, or when our window is moved, 329cafaa5aaSStefano Ceccherini // resized, etc. etc. 3300f4fb801SAxel Dörfler status_t status; 3310f4fb801SAxel Dörfler do { 3322b73985eSStefano Ceccherini status = acquire_sem(fDisableSem); 3330f4fb801SAxel Dörfler } while (status == B_INTERRUPTED); 3340f4fb801SAxel Dörfler 3350f4fb801SAxel Dörfler if (status < B_OK) 3360f4fb801SAxel Dörfler return -1; 337cafaa5aaSStefano Ceccherini 3382b73985eSStefano Ceccherini if (LockDirect()) { 3392b73985eSStefano Ceccherini if ((fBufferDesc->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_START) 3402b73985eSStefano Ceccherini fConnectionEnable = true; 341cafaa5aaSStefano Ceccherini 3422b73985eSStefano Ceccherini fInDirectConnect = true; 3432b73985eSStefano Ceccherini DirectConnected(fBufferDesc); 3442b73985eSStefano Ceccherini fInDirectConnect = false; 345cafaa5aaSStefano Ceccherini 3462b73985eSStefano Ceccherini if ((fBufferDesc->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_STOP) 3472b73985eSStefano Ceccherini fConnectionEnable = false; 348cafaa5aaSStefano Ceccherini 3492b73985eSStefano Ceccherini UnlockDirect(); 350cafaa5aaSStefano Ceccherini } 351cafaa5aaSStefano Ceccherini 352cafaa5aaSStefano Ceccherini // The app_server then waits (with a timeout) on this sem. 353cafaa5aaSStefano Ceccherini // If we aren't quick enough to release this sem, our app 354cafaa5aaSStefano Ceccherini // will be terminated by the app_server 3552b73985eSStefano Ceccherini if (release_sem(fDisableSemAck) != B_OK) 3560f4fb801SAxel Dörfler return -1; 357cafaa5aaSStefano Ceccherini } 358cafaa5aaSStefano Ceccherini 359cafaa5aaSStefano Ceccherini return 0; 360cafaa5aaSStefano Ceccherini } 361cafaa5aaSStefano Ceccherini 362cafaa5aaSStefano Ceccherini 36317495d0bSStefano Ceccherini // LockDirect() and UnlockDirect() are no-op on R5. I tried to call (R5's) LockDirect() 36417495d0bSStefano Ceccherini // repeatedly, from the same thread and from different threads, nothing happened. 36517495d0bSStefano Ceccherini // I implemented them anyway, as they were the first methods I wrote 36617495d0bSStefano Ceccherini // in this class (As you can see, I even needed to cast away their constness 36717495d0bSStefano Ceccherini // to make them do something useful). 368af294326SPhilippe Houdoin // They're not needed though, as the direct_daemon_thread doesn't change 36917495d0bSStefano Ceccherini // any shared data. They are probably here for future enhancements (see also the 37017495d0bSStefano Ceccherini // comment in DriverSetup() 371cafaa5aaSStefano Ceccherini bool 372cafaa5aaSStefano Ceccherini BDirectWindow::LockDirect() const 373cafaa5aaSStefano Ceccherini { 374cafaa5aaSStefano Ceccherini status_t status = B_OK; 375cafaa5aaSStefano Ceccherini 376cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING 377cafaa5aaSStefano Ceccherini BDirectWindow *casted = const_cast<BDirectWindow *>(this); 378cafaa5aaSStefano Ceccherini 3792b73985eSStefano Ceccherini if (atomic_add(&casted->fDirectLock, 1) > 0) { 380cafaa5aaSStefano Ceccherini do { 3812b73985eSStefano Ceccherini status = acquire_sem(fDirectSem); 382cafaa5aaSStefano Ceccherini } while (status == B_INTERRUPTED); 3835fdea13fSStefano Ceccherini } 384cafaa5aaSStefano Ceccherini 385cafaa5aaSStefano Ceccherini if (status == B_OK) { 3862b73985eSStefano Ceccherini casted->fDirectLockOwner = find_thread(NULL); 3872b73985eSStefano Ceccherini casted->fDirectLockCount++; 388cafaa5aaSStefano Ceccherini } 389cafaa5aaSStefano Ceccherini #endif 390cafaa5aaSStefano Ceccherini 391cafaa5aaSStefano Ceccherini return status == B_OK; 3920b4a36abSbeveloper } 3930b4a36abSbeveloper 3940b4a36abSbeveloper 3950b4a36abSbeveloper void 396cafaa5aaSStefano Ceccherini BDirectWindow::UnlockDirect() const 3970b4a36abSbeveloper { 398cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING 399cafaa5aaSStefano Ceccherini BDirectWindow *casted = const_cast<BDirectWindow *>(this); 400cafaa5aaSStefano Ceccherini 4012b73985eSStefano Ceccherini if (atomic_add(&casted->fDirectLock, -1) > 1) 4022b73985eSStefano Ceccherini release_sem(casted->fDirectSem); 403cafaa5aaSStefano Ceccherini 4042b73985eSStefano Ceccherini casted->fDirectLockCount--; 405cafaa5aaSStefano Ceccherini #endif 4060b4a36abSbeveloper } 4070b4a36abSbeveloper 4080b4a36abSbeveloper 4090b4a36abSbeveloper void 410cafaa5aaSStefano Ceccherini BDirectWindow::InitData() 4110b4a36abSbeveloper { 4122b73985eSStefano Ceccherini fConnectionEnable = false; 4132b73985eSStefano Ceccherini fIsFullScreen = false; 4142b73985eSStefano Ceccherini fInDirectConnect = false; 415cafaa5aaSStefano Ceccherini 4162b73985eSStefano Ceccherini fInitStatus = 0; 417cafaa5aaSStefano Ceccherini 4182b73985eSStefano Ceccherini fDirectDriverReady = false; 4192b73985eSStefano Ceccherini fDirectDriverType = 0; 4202b73985eSStefano Ceccherini fDirectDriverToken = 0; 421cafaa5aaSStefano Ceccherini direct_driver = NULL; 422cafaa5aaSStefano Ceccherini 4232b6ac345SStefano Ceccherini status_t status = B_ERROR; 4242b73985eSStefano Ceccherini struct direct_window_sync_data syncData; 4252b73985eSStefano Ceccherini if (Lock()) { 4262b73985eSStefano Ceccherini fLink->StartMessage(AS_DIRECT_WINDOW_GET_SYNC_DATA); 4272b6ac345SStefano Ceccherini if (fLink->FlushWithReply(status) == B_OK 4282b6ac345SStefano Ceccherini && status == B_OK) { 42971b55088SAxel Dörfler fLink->Read<direct_window_sync_data>(&syncData); 430feee8cf2SStefano Ceccherini } 431cafaa5aaSStefano Ceccherini Unlock(); 4322b73985eSStefano Ceccherini } 4335fdea13fSStefano Ceccherini if (status < B_OK) 4345fdea13fSStefano Ceccherini return; 435cafaa5aaSStefano Ceccherini 436cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING 4372b73985eSStefano Ceccherini fDirectLock = 0; 4382b73985eSStefano Ceccherini fDirectLockCount = 0; 4392b73985eSStefano Ceccherini fDirectLockOwner = -1; 4402b73985eSStefano Ceccherini fDirectLockStack = NULL; 4412b73985eSStefano Ceccherini fDirectSem = create_sem(1, "direct sem"); 4422b73985eSStefano Ceccherini if (fDirectSem > 0) 4432b73985eSStefano Ceccherini fInitStatus |= DW_STATUS_SEM_CREATED; 444cafaa5aaSStefano Ceccherini #endif 445cafaa5aaSStefano Ceccherini 4462b73985eSStefano Ceccherini fSourceClippingArea = syncData.area; 4472b73985eSStefano Ceccherini fDisableSem = syncData.disable_sem; 4482b73985eSStefano Ceccherini fDisableSemAck = syncData.disable_sem_ack; 449cafaa5aaSStefano Ceccherini 4502b73985eSStefano Ceccherini fClonedClippingArea = clone_area("Clone direct area", (void**)&fBufferDesc, 4512b73985eSStefano Ceccherini B_ANY_ADDRESS, B_READ_AREA, fSourceClippingArea); 4525fdea13fSStefano Ceccherini 453*302f6260SStefano Ceccherini if (fClonedClippingArea > 0) { 4542b73985eSStefano Ceccherini fInitStatus |= DW_STATUS_AREA_CLONED; 455cafaa5aaSStefano Ceccherini 4562b73985eSStefano Ceccherini fDirectDaemonId = spawn_thread(_DaemonStarter, "direct daemon", 457cafaa5aaSStefano Ceccherini B_DISPLAY_PRIORITY, this); 458cafaa5aaSStefano Ceccherini 4592b73985eSStefano Ceccherini if (fDirectDaemonId > 0) { 4602b73985eSStefano Ceccherini fDaemonKiller = false; 4612b73985eSStefano Ceccherini if (resume_thread(fDirectDaemonId) == B_OK) 4622b73985eSStefano Ceccherini fInitStatus |= DW_STATUS_THREAD_STARTED; 463cafaa5aaSStefano Ceccherini else 4642b73985eSStefano Ceccherini kill_thread(fDirectDaemonId); 465cafaa5aaSStefano Ceccherini } 466cafaa5aaSStefano Ceccherini } 467cafaa5aaSStefano Ceccherini } 4680b4a36abSbeveloper 4690b4a36abSbeveloper 4700b4a36abSbeveloper void 471cafaa5aaSStefano Ceccherini BDirectWindow::DisposeData() 4720b4a36abSbeveloper { 473cafaa5aaSStefano Ceccherini // wait until the connection terminates: we can't destroy 474cafaa5aaSStefano Ceccherini // the object until the client receives the B_DIRECT_STOP 475cafaa5aaSStefano Ceccherini // notification, or bad things will happen 4762b73985eSStefano Ceccherini while (fConnectionEnable) 477cafaa5aaSStefano Ceccherini snooze(50000); 478cafaa5aaSStefano Ceccherini 479cafaa5aaSStefano Ceccherini LockDirect(); 480cafaa5aaSStefano Ceccherini 4812b73985eSStefano Ceccherini if (fInitStatus & DW_STATUS_THREAD_STARTED) { 4822b73985eSStefano Ceccherini fDaemonKiller = true; 483af294326SPhilippe Houdoin // Release this sem, otherwise the Direct daemon thread 484cafaa5aaSStefano Ceccherini // will wait forever on it 4852b73985eSStefano Ceccherini release_sem(fDisableSem); 486cafaa5aaSStefano Ceccherini status_t retVal; 4872b73985eSStefano Ceccherini wait_for_thread(fDirectDaemonId, &retVal); 488cafaa5aaSStefano Ceccherini } 489cafaa5aaSStefano Ceccherini 490cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING 4912b73985eSStefano Ceccherini if (fInitStatus & DW_STATUS_SEM_CREATED) 4922b73985eSStefano Ceccherini delete_sem(fDirectSem); 493cafaa5aaSStefano Ceccherini #endif 494cafaa5aaSStefano Ceccherini 4952b73985eSStefano Ceccherini if (fInitStatus & DW_STATUS_AREA_CLONED) 4962b73985eSStefano Ceccherini delete_area(fClonedClippingArea); 4970b4a36abSbeveloper } 4980b4a36abSbeveloper 4990b4a36abSbeveloper 500cafaa5aaSStefano Ceccherini status_t 501cafaa5aaSStefano Ceccherini BDirectWindow::DriverSetup() const 5020b4a36abSbeveloper { 50317495d0bSStefano Ceccherini // Unimplemented in R5. 50409ea3092SStefano Ceccherini // This function is probably here because they wanted, in a future time, 50509ea3092SStefano Ceccherini // to implement graphic acceleration within BDirectWindow 50609ea3092SStefano Ceccherini // (in fact, there is also a BDirectDriver member in BDirectWindow, 50717495d0bSStefano Ceccherini // though it's not used). 50809ea3092SStefano Ceccherini 509cafaa5aaSStefano Ceccherini return B_OK; 5100b4a36abSbeveloper } 5110b4a36abSbeveloper 5120b4a36abSbeveloper 513cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow1() {} 514cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow2() {} 515cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow3() {} 516cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow4() {} 517