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 10*366fdcdfSMarcus Overhagen #ifdef COMPILE_FOR_R5 11*366fdcdfSMarcus Overhagen #include "/boot/develop/headers/be/interface/Window.h" 12*366fdcdfSMarcus Overhagen #endif 13*366fdcdfSMarcus Overhagen 14cafaa5aaSStefano Ceccherini #include <DirectWindow.h> 15cafaa5aaSStefano Ceccherini #include <clipping.h> 160b4a36abSbeveloper 178575beb8SJérôme Duval #ifdef COMPILE_FOR_R5 18cafaa5aaSStefano Ceccherini #include <R5_AppServerLink.h> 19cafaa5aaSStefano Ceccherini #include <R5_Session.h> 208575beb8SJérôme Duval #endif 2109ea3092SStefano Ceccherini 22*366fdcdfSMarcus Overhagen // Compiling for DANO/Zeta is broken as it doesn't have BRegion::set_size() 23*366fdcdfSMarcus Overhagen #ifdef COMPILE_FOR_DANO 24*366fdcdfSMarcus Overhagen #warning "##### Bilding BDirectWindow for TARGET_PLATFORM=dano (DANO/Zeta) is broken #####" 25*366fdcdfSMarcus Overhagen #endif 26*366fdcdfSMarcus Overhagen 27*366fdcdfSMarcus Overhagen 28cafaa5aaSStefano Ceccherini // TODO: We'll want to move this to a private header, 29cafaa5aaSStefano Ceccherini // accessible by the app server. 30cafaa5aaSStefano Ceccherini struct dw_sync_data 310b4a36abSbeveloper { 32cafaa5aaSStefano Ceccherini area_id area; 33cafaa5aaSStefano Ceccherini sem_id disableSem; 34cafaa5aaSStefano Ceccherini sem_id disableSemAck; 35cafaa5aaSStefano Ceccherini }; 36cafaa5aaSStefano Ceccherini 37cafaa5aaSStefano Ceccherini 3817495d0bSStefano Ceccherini // TODO: These commands are used by the BeOS R5 app_server. 39cafaa5aaSStefano Ceccherini // Change this when our app_server supports BDirectWindow 40cafaa5aaSStefano Ceccherini #define DW_GET_SYNC_DATA 0x880 4109ea3092SStefano Ceccherini #define DW_SET_FULLSCREEN 0x881 42cafaa5aaSStefano Ceccherini #define DW_SUPPORTS_WINDOW_MODE 0xF2C 43cafaa5aaSStefano Ceccherini 44cafaa5aaSStefano Ceccherini 45cafaa5aaSStefano Ceccherini // We don't need this kind of locking, since the directDeamonFunc 46cafaa5aaSStefano Ceccherini // doesn't access critical shared data. 47cafaa5aaSStefano Ceccherini #define DW_NEEDS_LOCKING 0 48cafaa5aaSStefano Ceccherini 49cafaa5aaSStefano Ceccherini enum dw_status_bits { 5017495d0bSStefano Ceccherini DW_STATUS_AREA_CLONED = 0x1, 5117495d0bSStefano Ceccherini DW_STATUS_THREAD_STARTED = 0x2, 5217495d0bSStefano Ceccherini DW_STATUS_SEM_CREATED = 0x4 53cafaa5aaSStefano Ceccherini }; 54cafaa5aaSStefano Ceccherini 55cafaa5aaSStefano Ceccherini 56cafaa5aaSStefano Ceccherini BDirectWindow::BDirectWindow(BRect frame, const char *title, window_type type, uint32 flags, uint32 workspace) 57cafaa5aaSStefano Ceccherini :BWindow(frame, title, type, flags, workspace) 58cafaa5aaSStefano Ceccherini { 59cafaa5aaSStefano Ceccherini InitData(); 600b4a36abSbeveloper } 610b4a36abSbeveloper 620b4a36abSbeveloper 63cafaa5aaSStefano Ceccherini BDirectWindow::BDirectWindow(BRect frame, const char *title, window_look look, window_feel feel, uint32 flags, uint32 workspace) 64cafaa5aaSStefano Ceccherini :BWindow(frame, title, look, feel, flags, workspace) 650b4a36abSbeveloper { 66cafaa5aaSStefano Ceccherini InitData(); 670b4a36abSbeveloper } 680b4a36abSbeveloper 690b4a36abSbeveloper 700b4a36abSbeveloper BDirectWindow::~BDirectWindow() 710b4a36abSbeveloper { 72cafaa5aaSStefano Ceccherini DisposeData(); 730b4a36abSbeveloper } 740b4a36abSbeveloper 750b4a36abSbeveloper 76cafaa5aaSStefano Ceccherini // start of regular BWindow API 770b4a36abSbeveloper BArchivable * 780b4a36abSbeveloper BDirectWindow::Instantiate(BMessage *data) 790b4a36abSbeveloper { 800b4a36abSbeveloper return NULL; 810b4a36abSbeveloper } 820b4a36abSbeveloper 830b4a36abSbeveloper 840b4a36abSbeveloper status_t 85cafaa5aaSStefano Ceccherini BDirectWindow::Archive(BMessage *data, bool deep) const 860b4a36abSbeveloper { 87cafaa5aaSStefano Ceccherini return inherited::Archive(data, deep); 880b4a36abSbeveloper } 890b4a36abSbeveloper 900b4a36abSbeveloper 910b4a36abSbeveloper void 92cafaa5aaSStefano Ceccherini BDirectWindow::Quit() 930b4a36abSbeveloper { 94cafaa5aaSStefano Ceccherini inherited::Quit(); 950b4a36abSbeveloper } 960b4a36abSbeveloper 970b4a36abSbeveloper 980b4a36abSbeveloper void 99cafaa5aaSStefano Ceccherini BDirectWindow::DispatchMessage(BMessage *message, BHandler *handler) 1000b4a36abSbeveloper { 101cafaa5aaSStefano Ceccherini inherited::DispatchMessage(message, handler); 1020b4a36abSbeveloper } 1030b4a36abSbeveloper 1040b4a36abSbeveloper 1050b4a36abSbeveloper void 1060b4a36abSbeveloper BDirectWindow::MessageReceived(BMessage *message) 1070b4a36abSbeveloper { 108cafaa5aaSStefano Ceccherini inherited::MessageReceived(message); 1090b4a36abSbeveloper } 1100b4a36abSbeveloper 1110b4a36abSbeveloper 1120b4a36abSbeveloper void 1130b4a36abSbeveloper BDirectWindow::FrameMoved(BPoint new_position) 1140b4a36abSbeveloper { 115cafaa5aaSStefano Ceccherini inherited::FrameMoved(new_position); 1160b4a36abSbeveloper } 1170b4a36abSbeveloper 1180b4a36abSbeveloper 1190b4a36abSbeveloper void 120cafaa5aaSStefano Ceccherini BDirectWindow::WorkspacesChanged(uint32 old_ws, uint32 new_ws) 1210b4a36abSbeveloper { 122cafaa5aaSStefano Ceccherini inherited::WorkspacesChanged(old_ws, new_ws); 1230b4a36abSbeveloper } 1240b4a36abSbeveloper 1250b4a36abSbeveloper 1260b4a36abSbeveloper void 127cafaa5aaSStefano Ceccherini BDirectWindow::WorkspaceActivated(int32 ws, bool state) 1280b4a36abSbeveloper { 129cafaa5aaSStefano Ceccherini inherited::WorkspaceActivated(ws, state); 1300b4a36abSbeveloper } 1310b4a36abSbeveloper 1320b4a36abSbeveloper 1330b4a36abSbeveloper void 134cafaa5aaSStefano Ceccherini BDirectWindow::FrameResized(float new_width, float new_height) 1350b4a36abSbeveloper { 136cafaa5aaSStefano Ceccherini inherited::FrameResized(new_width, new_height); 1370b4a36abSbeveloper } 1380b4a36abSbeveloper 1390b4a36abSbeveloper 1400b4a36abSbeveloper void 1410b4a36abSbeveloper BDirectWindow::Minimize(bool minimize) 1420b4a36abSbeveloper { 143cafaa5aaSStefano Ceccherini inherited::Minimize(minimize); 1440b4a36abSbeveloper } 1450b4a36abSbeveloper 1460b4a36abSbeveloper 1470b4a36abSbeveloper void 148cafaa5aaSStefano Ceccherini BDirectWindow::Zoom(BPoint rec_position, float rec_width, float rec_height) 1490b4a36abSbeveloper { 150cafaa5aaSStefano Ceccherini inherited::Zoom(rec_position, rec_width, rec_height); 1510b4a36abSbeveloper } 1520b4a36abSbeveloper 1530b4a36abSbeveloper 1540b4a36abSbeveloper void 155cafaa5aaSStefano Ceccherini BDirectWindow::ScreenChanged(BRect screen_size, color_space depth) 1560b4a36abSbeveloper { 157cafaa5aaSStefano Ceccherini inherited::ScreenChanged(screen_size, depth); 1580b4a36abSbeveloper } 1590b4a36abSbeveloper 1600b4a36abSbeveloper 1610b4a36abSbeveloper void 1620b4a36abSbeveloper BDirectWindow::MenusBeginning() 1630b4a36abSbeveloper { 164cafaa5aaSStefano Ceccherini inherited::MenusBeginning(); 1650b4a36abSbeveloper } 1660b4a36abSbeveloper 1670b4a36abSbeveloper 1680b4a36abSbeveloper void 1690b4a36abSbeveloper BDirectWindow::MenusEnded() 1700b4a36abSbeveloper { 171cafaa5aaSStefano Ceccherini inherited::MenusEnded(); 1720b4a36abSbeveloper } 1730b4a36abSbeveloper 1740b4a36abSbeveloper 1750b4a36abSbeveloper void 1760b4a36abSbeveloper BDirectWindow::WindowActivated(bool state) 1770b4a36abSbeveloper { 178cafaa5aaSStefano Ceccherini inherited::WindowActivated(state); 1790b4a36abSbeveloper } 1800b4a36abSbeveloper 1810b4a36abSbeveloper 1820b4a36abSbeveloper void 1830b4a36abSbeveloper BDirectWindow::Show() 1840b4a36abSbeveloper { 185cafaa5aaSStefano Ceccherini inherited::Show(); 1860b4a36abSbeveloper } 1870b4a36abSbeveloper 1880b4a36abSbeveloper 1890b4a36abSbeveloper void 1900b4a36abSbeveloper BDirectWindow::Hide() 1910b4a36abSbeveloper { 192cafaa5aaSStefano Ceccherini inherited::Hide(); 1930b4a36abSbeveloper } 1940b4a36abSbeveloper 1950b4a36abSbeveloper 1960b4a36abSbeveloper BHandler * 197cafaa5aaSStefano Ceccherini BDirectWindow::ResolveSpecifier(BMessage *msg, int32 index, 198cafaa5aaSStefano Ceccherini BMessage *specifier, int32 form, const char *property) 1990b4a36abSbeveloper { 200cafaa5aaSStefano Ceccherini return inherited::ResolveSpecifier(msg, index, specifier, form, property); 2010b4a36abSbeveloper } 2020b4a36abSbeveloper 2030b4a36abSbeveloper 2040b4a36abSbeveloper status_t 2050b4a36abSbeveloper BDirectWindow::GetSupportedSuites(BMessage *data) 2060b4a36abSbeveloper { 207cafaa5aaSStefano Ceccherini return inherited::GetSupportedSuites(data); 2080b4a36abSbeveloper } 2090b4a36abSbeveloper 2100b4a36abSbeveloper 2110b4a36abSbeveloper status_t 212cafaa5aaSStefano Ceccherini BDirectWindow::Perform(perform_code d, void *arg) 2130b4a36abSbeveloper { 214cafaa5aaSStefano Ceccherini return inherited::Perform(d, arg); 2150b4a36abSbeveloper } 2160b4a36abSbeveloper 2170b4a36abSbeveloper 218b816dc1eSIngo Weinhold void 219b816dc1eSIngo Weinhold BDirectWindow::task_looper() 220b816dc1eSIngo Weinhold { 221cafaa5aaSStefano Ceccherini inherited::task_looper(); 222b816dc1eSIngo Weinhold } 223b816dc1eSIngo Weinhold 224cafaa5aaSStefano Ceccherini 225b816dc1eSIngo Weinhold BMessage * 226b816dc1eSIngo Weinhold BDirectWindow::ConvertToMessage(void *raw, int32 code) 227b816dc1eSIngo Weinhold { 228cafaa5aaSStefano Ceccherini return inherited::ConvertToMessage(raw, code); 229b816dc1eSIngo Weinhold } 230cafaa5aaSStefano Ceccherini // end of BWindow API 2310b4a36abSbeveloper 2320b4a36abSbeveloper 233cafaa5aaSStefano Ceccherini // BDirectWindow specific API 2340b4a36abSbeveloper void 2350b4a36abSbeveloper BDirectWindow::DirectConnected(direct_buffer_info *info) 2360b4a36abSbeveloper { 237cafaa5aaSStefano Ceccherini //implemented in subclasses 2380b4a36abSbeveloper } 2390b4a36abSbeveloper 2400b4a36abSbeveloper 2410b4a36abSbeveloper status_t 242cafaa5aaSStefano Ceccherini BDirectWindow::GetClippingRegion(BRegion *region, BPoint *origin) const 2430b4a36abSbeveloper { 244cafaa5aaSStefano Ceccherini if (region == NULL) 245cafaa5aaSStefano Ceccherini return B_BAD_VALUE; 246cafaa5aaSStefano Ceccherini 247cafaa5aaSStefano Ceccherini if (IsLocked()) 248cafaa5aaSStefano Ceccherini return B_ERROR; 249cafaa5aaSStefano Ceccherini 250cafaa5aaSStefano Ceccherini if (LockDirect()) { 251cafaa5aaSStefano Ceccherini if (in_direct_connect) { 252cafaa5aaSStefano Ceccherini UnlockDirect(); 253cafaa5aaSStefano Ceccherini return B_ERROR; 254cafaa5aaSStefano Ceccherini } 255cafaa5aaSStefano Ceccherini 256cafaa5aaSStefano Ceccherini // BPoint's coordinates are floats. We can only work 257cafaa5aaSStefano Ceccherini // with integers. 258cafaa5aaSStefano Ceccherini int32 originX, originY; 259cafaa5aaSStefano Ceccherini if (origin == NULL) { 260cafaa5aaSStefano Ceccherini originX = 0; 261cafaa5aaSStefano Ceccherini originY = 0; 262cafaa5aaSStefano Ceccherini } else { 263cafaa5aaSStefano Ceccherini originX = (int32)origin->x; 264cafaa5aaSStefano Ceccherini originY = (int32)origin->y; 265cafaa5aaSStefano Ceccherini } 266cafaa5aaSStefano Ceccherini 267*366fdcdfSMarcus Overhagen #ifndef COMPILE_FOR_DANO 268cafaa5aaSStefano Ceccherini // Since we are friend of BRegion, we can access its private members. 269cafaa5aaSStefano Ceccherini // Otherwise, we would need to call BRegion::Include(clipping_rect) 270cafaa5aaSStefano Ceccherini // for every clipping_rect in our clip_list, and that would be much 271cafaa5aaSStefano Ceccherini // more overkill than this. 272cafaa5aaSStefano Ceccherini region->set_size(buffer_desc->clip_list_count); 273cafaa5aaSStefano Ceccherini region->count = buffer_desc->clip_list_count; 274cafaa5aaSStefano Ceccherini region->bound = buffer_desc->clip_bounds; 275cafaa5aaSStefano Ceccherini 276cafaa5aaSStefano Ceccherini // adjust bounds by the given origin point 277cafaa5aaSStefano Ceccherini offset_rect(region->bound, -originX, -originY); 278cafaa5aaSStefano Ceccherini 279cafaa5aaSStefano Ceccherini for (uint32 c = 0; c < buffer_desc->clip_list_count; c++) { 280cafaa5aaSStefano Ceccherini region->data[c] = buffer_desc->clip_list[c]; 281cafaa5aaSStefano Ceccherini offset_rect(region->data[c], -originX, -originY); 282cafaa5aaSStefano Ceccherini } 283cafaa5aaSStefano Ceccherini 284*366fdcdfSMarcus Overhagen #endif 285*366fdcdfSMarcus Overhagen 286cafaa5aaSStefano Ceccherini UnlockDirect(); 287cafaa5aaSStefano Ceccherini 288cafaa5aaSStefano Ceccherini return B_OK; 289cafaa5aaSStefano Ceccherini } 290cafaa5aaSStefano Ceccherini 2910b4a36abSbeveloper return B_ERROR; 2920b4a36abSbeveloper } 2930b4a36abSbeveloper 2940b4a36abSbeveloper 2950b4a36abSbeveloper status_t 2960b4a36abSbeveloper BDirectWindow::SetFullScreen(bool enable) 2970b4a36abSbeveloper { 298cafaa5aaSStefano Ceccherini status_t status = B_ERROR; 29909ea3092SStefano Ceccherini if (Lock()) { 3008575beb8SJérôme Duval 3018575beb8SJérôme Duval #ifdef COMPILE_FOR_R5 30209ea3092SStefano Ceccherini a_session->swrite_l(DW_SET_FULLSCREEN); 30309ea3092SStefano Ceccherini a_session->swrite_l(server_token); 30417495d0bSStefano Ceccherini a_session->swrite_l((int32)enable); 30509ea3092SStefano Ceccherini Flush(); 30609ea3092SStefano Ceccherini 307bfc3bb18SStefano Ceccherini status_t fullScreen; 308bfc3bb18SStefano Ceccherini a_session->sread(sizeof(status_t), &fullScreen); 309bfc3bb18SStefano Ceccherini a_session->sread(sizeof(status_t), &status); 3108575beb8SJérôme Duval #endif 31109ea3092SStefano Ceccherini Unlock(); 312bfc3bb18SStefano Ceccherini 3133f9ae8a3SStefano Ceccherini // TODO: Revisit this when we move to our app_server 3143f9ae8a3SStefano Ceccherini // Currently the full screen/window status is set 3153f9ae8a3SStefano Ceccherini // even if something goes wrong 3163f9ae8a3SStefano Ceccherini full_screen_enable = enable; 31709ea3092SStefano Ceccherini } 318cafaa5aaSStefano Ceccherini return status; 3190b4a36abSbeveloper } 3200b4a36abSbeveloper 3210b4a36abSbeveloper 3220b4a36abSbeveloper bool 3230b4a36abSbeveloper BDirectWindow::IsFullScreen() const 3240b4a36abSbeveloper { 325cafaa5aaSStefano Ceccherini return full_screen_enable; 3260b4a36abSbeveloper } 3270b4a36abSbeveloper 3280b4a36abSbeveloper 3290b4a36abSbeveloper bool 330cafaa5aaSStefano Ceccherini BDirectWindow::SupportsWindowMode(screen_id id) 3310b4a36abSbeveloper { 3328575beb8SJérôme Duval int32 result = 0; 3338575beb8SJérôme Duval 3348575beb8SJérôme Duval #ifdef COMPILE_FOR_R5 335cafaa5aaSStefano Ceccherini _BAppServerLink_ link; 336cafaa5aaSStefano Ceccherini link.fSession->swrite_l(DW_SUPPORTS_WINDOW_MODE); 337cafaa5aaSStefano Ceccherini link.fSession->swrite_l(id.id); 338cafaa5aaSStefano Ceccherini link.fSession->sync(); 339cafaa5aaSStefano Ceccherini link.fSession->sread(sizeof(result), &result); 3408575beb8SJérôme Duval #endif 341cafaa5aaSStefano Ceccherini 342cafaa5aaSStefano Ceccherini return result & true; 343cafaa5aaSStefano Ceccherini } 344cafaa5aaSStefano Ceccherini 345cafaa5aaSStefano Ceccherini 346cafaa5aaSStefano Ceccherini // Private methods 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. 356cafaa5aaSStefano Ceccherini while (acquire_sem(object->disable_sem) == B_INTERRUPTED) 357cafaa5aaSStefano Ceccherini ; 358cafaa5aaSStefano Ceccherini 359cafaa5aaSStefano Ceccherini if (object->LockDirect()) { 360cafaa5aaSStefano Ceccherini if ((object->buffer_desc->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_START) 361cafaa5aaSStefano Ceccherini object->connection_enable = true; 362cafaa5aaSStefano Ceccherini 363cafaa5aaSStefano Ceccherini object->in_direct_connect = true; 364cafaa5aaSStefano Ceccherini object->DirectConnected(object->buffer_desc); 365cafaa5aaSStefano Ceccherini object->in_direct_connect = false; 366cafaa5aaSStefano Ceccherini 367cafaa5aaSStefano Ceccherini if ((object->buffer_desc->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_STOP) 368cafaa5aaSStefano Ceccherini object->connection_enable = false; 369cafaa5aaSStefano Ceccherini 370cafaa5aaSStefano Ceccherini object->UnlockDirect(); 371cafaa5aaSStefano Ceccherini } 372cafaa5aaSStefano Ceccherini 373cafaa5aaSStefano Ceccherini // The app_server then waits (with a timeout) on this sem. 374cafaa5aaSStefano Ceccherini // If we aren't quick enough to release this sem, our app 375cafaa5aaSStefano Ceccherini // will be terminated by the app_server 376cafaa5aaSStefano Ceccherini release_sem(object->disable_sem_ack); 377cafaa5aaSStefano Ceccherini } 378cafaa5aaSStefano Ceccherini 379cafaa5aaSStefano Ceccherini return 0; 380cafaa5aaSStefano Ceccherini } 381cafaa5aaSStefano Ceccherini 382cafaa5aaSStefano Ceccherini 38317495d0bSStefano Ceccherini // LockDirect() and UnlockDirect() are no-op on R5. I tried to call (R5's) LockDirect() 38417495d0bSStefano Ceccherini // repeatedly, from the same thread and from different threads, nothing happened. 38517495d0bSStefano Ceccherini // I implemented them anyway, as they were the first methods I wrote 38617495d0bSStefano Ceccherini // in this class (As you can see, I even needed to cast away their constness 38717495d0bSStefano Ceccherini // to make them do something useful). 38817495d0bSStefano Ceccherini // They're not needed though, as the direct_deamon_thread doesn't change 38917495d0bSStefano Ceccherini // any shared data. They are probably here for future enhancements (see also the 39017495d0bSStefano Ceccherini // comment in DriverSetup() 391cafaa5aaSStefano Ceccherini bool 392cafaa5aaSStefano Ceccherini BDirectWindow::LockDirect() const 393cafaa5aaSStefano Ceccherini { 394cafaa5aaSStefano Ceccherini status_t status = B_OK; 395cafaa5aaSStefano Ceccherini 396cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING 397cafaa5aaSStefano Ceccherini BDirectWindow *casted = const_cast<BDirectWindow *>(this); 398cafaa5aaSStefano Ceccherini 399cafaa5aaSStefano Ceccherini if (atomic_add(&casted->direct_lock, 1) > 0) 400cafaa5aaSStefano Ceccherini do { 401cafaa5aaSStefano Ceccherini status = acquire_sem(direct_sem); 402cafaa5aaSStefano Ceccherini } while (status == B_INTERRUPTED); 403cafaa5aaSStefano Ceccherini 404cafaa5aaSStefano Ceccherini if (status == B_OK) { 405cafaa5aaSStefano Ceccherini casted->direct_lock_owner = find_thread(NULL); 406cafaa5aaSStefano Ceccherini casted->direct_lock_count++; 407cafaa5aaSStefano Ceccherini } 408cafaa5aaSStefano Ceccherini #endif 409cafaa5aaSStefano Ceccherini 410cafaa5aaSStefano Ceccherini return status == B_OK; 4110b4a36abSbeveloper } 4120b4a36abSbeveloper 4130b4a36abSbeveloper 4140b4a36abSbeveloper void 415cafaa5aaSStefano Ceccherini BDirectWindow::UnlockDirect() const 4160b4a36abSbeveloper { 417cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING 418cafaa5aaSStefano Ceccherini BDirectWindow *casted = const_cast<BDirectWindow *>(this); 419cafaa5aaSStefano Ceccherini 420cafaa5aaSStefano Ceccherini if (atomic_add(&casted->direct_lock, -1) > 1) 421cafaa5aaSStefano Ceccherini release_sem(direct_sem); 422cafaa5aaSStefano Ceccherini 423cafaa5aaSStefano Ceccherini casted->direct_lock_count--; 424cafaa5aaSStefano Ceccherini #endif 4250b4a36abSbeveloper } 4260b4a36abSbeveloper 4270b4a36abSbeveloper 4280b4a36abSbeveloper void 429cafaa5aaSStefano Ceccherini BDirectWindow::InitData() 4300b4a36abSbeveloper { 431cafaa5aaSStefano Ceccherini connection_enable = false; 432cafaa5aaSStefano Ceccherini full_screen_enable = false; 433cafaa5aaSStefano Ceccherini in_direct_connect = false; 434cafaa5aaSStefano Ceccherini 435cafaa5aaSStefano Ceccherini dw_init_status = 0; 436cafaa5aaSStefano Ceccherini 437cafaa5aaSStefano Ceccherini direct_driver_ready = false; 438cafaa5aaSStefano Ceccherini direct_driver_type = 0; 439cafaa5aaSStefano Ceccherini direct_driver_token = 0; 440cafaa5aaSStefano Ceccherini direct_driver = NULL; 441cafaa5aaSStefano Ceccherini 442cafaa5aaSStefano Ceccherini if (Lock()) { 4438575beb8SJérôme Duval struct dw_sync_data sync_data; 4448575beb8SJérôme Duval status_t status = B_ERROR; 4458575beb8SJérôme Duval 4468575beb8SJérôme Duval #ifdef COMPILE_FOR_R5 447cafaa5aaSStefano Ceccherini a_session->swrite_l(DW_GET_SYNC_DATA); 448cafaa5aaSStefano Ceccherini a_session->swrite_l(server_token); 4498575beb8SJérôme Duval 450cafaa5aaSStefano Ceccherini Flush(); 451cafaa5aaSStefano Ceccherini 452cafaa5aaSStefano Ceccherini a_session->sread(sizeof(sync_data), &sync_data); 453cafaa5aaSStefano Ceccherini 454cafaa5aaSStefano Ceccherini 4558575beb8SJérôme Duval a_session->sread(sizeof(status), &status); 4568575beb8SJérôme Duval #endif 457cafaa5aaSStefano Ceccherini Unlock(); 458cafaa5aaSStefano Ceccherini 459cafaa5aaSStefano Ceccherini if (status == B_OK) { 460cafaa5aaSStefano Ceccherini 461cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING 462cafaa5aaSStefano Ceccherini direct_lock = 0; 463cafaa5aaSStefano Ceccherini direct_lock_count = 0; 464cafaa5aaSStefano Ceccherini direct_lock_owner = B_ERROR; 465cafaa5aaSStefano Ceccherini direct_lock_stack = NULL; 466cafaa5aaSStefano Ceccherini direct_sem = create_sem(1, "direct sem"); 467cafaa5aaSStefano Ceccherini if (direct_sem > 0) 468cafaa5aaSStefano Ceccherini dw_init_status |= DW_STATUS_SEM_CREATED; 469cafaa5aaSStefano Ceccherini #endif 470cafaa5aaSStefano Ceccherini 471cafaa5aaSStefano Ceccherini source_clipping_area = sync_data.area; 472cafaa5aaSStefano Ceccherini disable_sem = sync_data.disableSem; 473cafaa5aaSStefano Ceccherini disable_sem_ack = sync_data.disableSemAck; 474cafaa5aaSStefano Ceccherini 475cafaa5aaSStefano Ceccherini cloned_clipping_area = clone_area("Clone direct area", (void**)&buffer_desc, 476cafaa5aaSStefano Ceccherini B_ANY_ADDRESS, B_READ_AREA, source_clipping_area); 477cafaa5aaSStefano Ceccherini if (cloned_clipping_area > 0) { 478cafaa5aaSStefano Ceccherini dw_init_status |= DW_STATUS_AREA_CLONED; 479cafaa5aaSStefano Ceccherini 480cafaa5aaSStefano Ceccherini direct_deamon_id = spawn_thread(DirectDeamonFunc, "direct deamon", 481cafaa5aaSStefano Ceccherini B_DISPLAY_PRIORITY, this); 482cafaa5aaSStefano Ceccherini 483cafaa5aaSStefano Ceccherini if (direct_deamon_id > 0) { 484cafaa5aaSStefano Ceccherini deamon_killer = false; 485cafaa5aaSStefano Ceccherini if (resume_thread(direct_deamon_id) == B_OK) 486cafaa5aaSStefano Ceccherini dw_init_status |= DW_STATUS_THREAD_STARTED; 487cafaa5aaSStefano Ceccherini else 488cafaa5aaSStefano Ceccherini kill_thread(direct_deamon_id); 489cafaa5aaSStefano Ceccherini } 490cafaa5aaSStefano Ceccherini } 491cafaa5aaSStefano Ceccherini } 492cafaa5aaSStefano Ceccherini } 4930b4a36abSbeveloper } 4940b4a36abSbeveloper 4950b4a36abSbeveloper 4960b4a36abSbeveloper void 497cafaa5aaSStefano Ceccherini BDirectWindow::DisposeData() 4980b4a36abSbeveloper { 499cafaa5aaSStefano Ceccherini // wait until the connection terminates: we can't destroy 500cafaa5aaSStefano Ceccherini // the object until the client receives the B_DIRECT_STOP 501cafaa5aaSStefano Ceccherini // notification, or bad things will happen 502cafaa5aaSStefano Ceccherini while (connection_enable) 503cafaa5aaSStefano Ceccherini snooze(50000); 504cafaa5aaSStefano Ceccherini 505cafaa5aaSStefano Ceccherini LockDirect(); 506cafaa5aaSStefano Ceccherini 507cafaa5aaSStefano Ceccherini if (dw_init_status & DW_STATUS_THREAD_STARTED) { 508cafaa5aaSStefano Ceccherini deamon_killer = true; 509cafaa5aaSStefano Ceccherini // Release this sem, otherwise the Direct deamon thread 510cafaa5aaSStefano Ceccherini // will wait forever on it 511cafaa5aaSStefano Ceccherini release_sem(disable_sem); 512cafaa5aaSStefano Ceccherini status_t retVal; 513cafaa5aaSStefano Ceccherini wait_for_thread(direct_deamon_id, &retVal); 514cafaa5aaSStefano Ceccherini } 515cafaa5aaSStefano Ceccherini 516cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING 517cafaa5aaSStefano Ceccherini if (dw_init_status & DW_STATUS_SEM_CREATED) 518cafaa5aaSStefano Ceccherini delete_sem(direct_sem); 519cafaa5aaSStefano Ceccherini #endif 520cafaa5aaSStefano Ceccherini 521cafaa5aaSStefano Ceccherini if (dw_init_status & DW_STATUS_AREA_CLONED) 522cafaa5aaSStefano Ceccherini delete_area(cloned_clipping_area); 5230b4a36abSbeveloper } 5240b4a36abSbeveloper 5250b4a36abSbeveloper 526cafaa5aaSStefano Ceccherini status_t 527cafaa5aaSStefano Ceccherini BDirectWindow::DriverSetup() const 5280b4a36abSbeveloper { 52917495d0bSStefano Ceccherini // Unimplemented in R5. 53009ea3092SStefano Ceccherini // This function is probably here because they wanted, in a future time, 53109ea3092SStefano Ceccherini // to implement graphic acceleration within BDirectWindow 53209ea3092SStefano Ceccherini // (in fact, there is also a BDirectDriver member in BDirectWindow, 53317495d0bSStefano Ceccherini // though it's not used). 53409ea3092SStefano Ceccherini 535cafaa5aaSStefano Ceccherini return B_OK; 5360b4a36abSbeveloper } 5370b4a36abSbeveloper 5380b4a36abSbeveloper 539cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow1() {} 540cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow2() {} 541cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow3() {} 542cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow4() {} 543