diff --git a/headers/os/game/DirectWindow.h b/headers/os/game/DirectWindow.h index 393a4c6f5b..d482b887ba 100644 --- a/headers/os/game/DirectWindow.h +++ b/headers/os/game/DirectWindow.h @@ -1,167 +1,168 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2001-2002, OpenBeOS -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// File Name: DirectWindow.h -// Author: Christopher ML Zumwalt May (zummy@users.sf.net) -// Description: BFileGameSound allow the developer to directly draw to the -// app_server's frame buffer. -//------------------------------------------------------------------------------ - -#ifndef _DIRECTWINDOW_H -#define _DIRECTWINDOW_H - -// Standard Includes ----------------------------------------------------------- - -// System Includes ------------------------------------------------------------- -#include -#include - -// Project Includes ------------------------------------------------------------ - -// Local Includes -------------------------------------------------------------- - -// Local Defines --------------------------------------------------------------- - -// Globals --------------------------------------------------------------------- -enum direct_buffer_state { - B_DIRECT_MODE_MASK = 15, - - B_DIRECT_START = 0, - B_DIRECT_STOP = 1, - B_DIRECT_MODIFY = 2, - - B_CLIPPING_MODIFIED = 16, - B_BUFFER_RESIZED = 32, - B_BUFFER_MOVED = 64, - B_BUFFER_RESET = 128 -}; - -enum direct_driver_state { - B_DRIVER_CHANGED = 0x0001, - B_MODE_CHANGED = 0x0002 -}; - -typedef struct { - direct_buffer_state buffer_state; - direct_driver_state driver_state; - void *bits; - void *pci_bits; - int32 bytes_per_row; - uint32 bits_per_pixel; - color_space pixel_format; - buffer_layout layout; - buffer_orientation orientation; - uint32 _reserved[9]; - uint32 _dd_type_; - uint32 _dd_token_; - uint32 clip_list_count; - clipping_rect window_bounds; - clipping_rect clip_bounds; - clipping_rect clip_list[1]; -} direct_buffer_info; - -// PushGameSound --------------------------------------------------------------- -class BDirectWindow : public BWindow -{ -public: - BDirectWindow(BRect frame, - const char *title, - window_type type, - uint32 flags, - uint32 workspace = B_CURRENT_WORKSPACE); - BDirectWindow(BRect frame, - const char *title, - window_look look, - window_feel feel, - uint32 flags, - uint32 workspace = B_CURRENT_WORKSPACE); - virtual ~BDirectWindow(); - - static BArchivable *Instantiate(BMessage *data); - virtual status_t Archive(BMessage *data, bool deep = true) const; - virtual void Quit(void); - virtual void DispatchMessage(BMessage *message, BHandler *handler); - virtual void MessageReceived(BMessage *message); - virtual void FrameMoved(BPoint new_position); - virtual void WorkspacesChanged(uint32 old_ws, uint32 new_ws); - virtual void WorkspaceActivated(int32 ws, bool state); - virtual void FrameResized(float new_width, float new_height); - virtual void Minimize(bool minimize); - virtual void Zoom(BPoint rec_position, - float rec_width, - float rec_height); - virtual void ScreenChanged(BRect screen_size, color_space depth); - virtual void MenusBeginning(); - virtual void MenusEnded(); - virtual void WindowActivated(bool state); - virtual void Show(); - virtual void Hide(); - virtual BHandler *ResolveSpecifier(BMessage *msg, - int32 index, - BMessage *specifier, - int32 form, - const char *property); - virtual status_t GetSupportedSuites(BMessage *data); - virtual status_t Perform(perform_code d, void *arg); - -private: - virtual void task_looper(); - virtual BMessage *ConvertToMessage(void *raw, int32 code); - -public: - // BDirectWindow API - virtual void DirectConnected(direct_buffer_info *info); - status_t GetClippingRegion(BRegion *region, BPoint *origin = NULL) const; - status_t SetFullScreen(bool enable); - bool IsFullScreen() const; - - static bool SupportsWindowMode(screen_id = B_MAIN_SCREEN_ID); - -private: - - typedef BWindow inherited; - - virtual void _ReservedDirectWindow1(); - virtual void _ReservedDirectWindow2(); - virtual void _ReservedDirectWindow3(); - virtual void _ReservedDirectWindow4(); - - BDirectWindow(); - BDirectWindow(BDirectWindow &); - BDirectWindow &operator=(BDirectWindow &); - - void InitData(BRect frame); - - void DoDirectConnected(); - void Connect(); - void Disconnect(); - - void CreateClippingList(); - void GetFrameBuffer(); - - bool fIsFullScreen; - bool fIsConnected; - direct_buffer_info *fBufferInfo; - uint32 _reserved_[31]; -}; - -#endif - +/******************************************************************************* +// +// File: DirectWindow.h +// +// Description: Client window class for direct screen access. +// +// Copyright 1998, Be Incorporated, All Rights Reserved. +// +*******************************************************************************/ + + +#ifndef _DIRECT_WINDOW_H +#define _DIRECT_WINDOW_H + +#include +#include + +class BDirectDriver; + +/* State of the direct access when called back through DirectConnected */ +enum direct_buffer_state { + B_DIRECT_MODE_MASK = 15, + + B_DIRECT_START = 0, + B_DIRECT_STOP = 1, + B_DIRECT_MODIFY = 2, + + B_CLIPPING_MODIFIED = 16, + B_BUFFER_RESIZED = 32, + B_BUFFER_MOVED = 64, + B_BUFFER_RESET = 128 +}; + +/* State of the direct driver and its hooks functions */ +enum direct_driver_state { + B_DRIVER_CHANGED = 0x0001, + B_MODE_CHANGED = 0x0002 +}; + +/* Integer rect used to define a cliping rectangle. All bounds are included */ +/* Moved to Region.h */ + +/* Frame buffer access descriptor */ +typedef struct { + direct_buffer_state buffer_state; + direct_driver_state driver_state; + void *bits; + void *pci_bits; + int32 bytes_per_row; + uint32 bits_per_pixel; + color_space pixel_format; + buffer_layout layout; + buffer_orientation orientation; + uint32 _reserved[9]; + uint32 _dd_type_; + uint32 _dd_token_; + uint32 clip_list_count; + clipping_rect window_bounds; + clipping_rect clip_bounds; + clipping_rect clip_list[1]; +} direct_buffer_info; + +/* BDirectWindow class */ +class BDirectWindow : public BWindow { +public: + BDirectWindow( BRect frame, + const char *title, + window_type type, + uint32 flags, + uint32 workspace = B_CURRENT_WORKSPACE); + BDirectWindow( BRect frame, + const char *title, + window_look look, + window_feel feel, + uint32 flags, + uint32 workspace = B_CURRENT_WORKSPACE); +virtual ~BDirectWindow(); +static BArchivable *Instantiate(BMessage *data); +virtual status_t Archive(BMessage *data, bool deep = true) const; + +/* defined for future extension (fragile base class). Identical to BWindow */ +virtual void Quit(void); +virtual void DispatchMessage(BMessage *message, BHandler *handler); +virtual void MessageReceived(BMessage *message); +virtual void FrameMoved(BPoint new_position); +virtual void WorkspacesChanged(uint32 old_ws, uint32 new_ws); +virtual void WorkspaceActivated(int32 ws, bool state); +virtual void FrameResized(float new_width, float new_height); +virtual void Minimize(bool minimize); +virtual void Zoom( BPoint rec_position, + float rec_width, + float rec_height); +virtual void ScreenChanged(BRect screen_size, color_space depth); +virtual void MenusBeginning(); +virtual void MenusEnded(); +virtual void WindowActivated(bool state); +virtual void Show(); +virtual void Hide(); +virtual BHandler *ResolveSpecifier(BMessage *msg, + int32 index, + BMessage *specifier, + int32 form, + const char *property); +virtual status_t GetSupportedSuites(BMessage *data); +virtual status_t Perform(perform_code d, void *arg); + +private: +virtual void task_looper(); +virtual BMessage *ConvertToMessage(void *raw, int32 code); + +/* new APIs */ + +public: +virtual void DirectConnected(direct_buffer_info *info); + status_t GetClippingRegion(BRegion *region, BPoint *origin = NULL) const; + status_t SetFullScreen(bool enable); + bool IsFullScreen() const; + +static bool SupportsWindowMode(screen_id = B_MAIN_SCREEN_ID); + +/* private */ +private: + + typedef BWindow inherited; + +virtual void _ReservedDirectWindow1(); +virtual void _ReservedDirectWindow2(); +virtual void _ReservedDirectWindow3(); +virtual void _ReservedDirectWindow4(); + + + BDirectWindow(); + BDirectWindow(BDirectWindow &); + BDirectWindow &operator=(BDirectWindow &); + + bool deamon_killer; + bool connection_enable; + bool full_screen_enable; + bool direct_driver_ready; + bool in_direct_connect; + int32 direct_lock; + sem_id direct_sem; + uint32 direct_lock_count; + thread_id direct_lock_owner; + char *direct_lock_stack; + sem_id disable_sem; + sem_id disable_sem_ack; + uint32 dw_init_status; + uint32 info_area_size; + uint32 direct_driver_type; + uint32 direct_driver_token; + area_id cloned_clipping_area; + area_id source_clipping_area; + thread_id direct_deamon_id; + direct_buffer_info *buffer_desc; + BDirectDriver *direct_driver; + struct priv_ext *extension; + uint32 _reserved_[15]; + +static int32 DirectDeamonFunc(void *arg); + bool LockDirect() const; + void UnlockDirect() const; + void InitData(); + void DisposeData(); + status_t DriverSetup() const; +}; + +#endif diff --git a/headers/private/interface/R5_AppServerLink.h b/headers/private/interface/R5_AppServerLink.h new file mode 100644 index 0000000000..6fd374fe91 --- /dev/null +++ b/headers/private/interface/R5_AppServerLink.h @@ -0,0 +1,21 @@ +// TODO: This file is here just to be able to use BDirectWindow +// with BeOS R5. Remove it when we don't need it anymore + +#ifndef _APP_SERVER_LINK_H +#define _APP_SERVER_LINK_H + +#include +#include +#include +#include "Session.h" + +class _BAppServerLink_ { + +public: + _BAppServerLink_(); +virtual ~_BAppServerLink_(); + + _BSession_ *fSession; +}; + +#endif diff --git a/headers/private/interface/R5_Session.h b/headers/private/interface/R5_Session.h new file mode 100644 index 0000000000..a360c52770 --- /dev/null +++ b/headers/private/interface/R5_Session.h @@ -0,0 +1,69 @@ +// TODO: This file is here just to be able to use BDirectWindow +// with BeOS R5. Remove it when we don't need it anymore + +#ifndef _SESSION_H +#define _SESSION_H + +#include +#include +#include +#include +#include + +class _BSession_ { + +public: + _BSession_(port_id receivePort, port_id sendPort); + _BSession_(int32, char *); +virtual ~_BSession_(); + + char *sread(); + void sread_coo(float *coo); + void sread_coo_a(float *coo); + void sread_point(BPoint *point); + void sread_point_a(BPoint *point); + void sread_rect(clipping_rect *rect); + void sread_rect(BRect *rect); + void sread_rect_a(BRect *rect); + void sread(int32 size, void *data); + void sread2(int32 size, void *data); + void sreadd(int32 size, void *data); + + void swrite_s(int16 s); + void swrite_l(int32 l); + void swrite(char *string); + void swrite_point(const BPoint *point); + void swrite_point_a(const BPoint *point); + void swrite_coo(float *coo); + void swrite_coo_a(float *coo); + void swrite_rect(const clipping_rect *rect); + void swrite_rect(const BRect *rect); + void swrite_rect_a(const BRect *rect); + void swrite(int32 size, void *data); + +// void get_other(message *); +// void add_to_buffer(message *); + + void recv_buffer(); + void send_buffer(); + + void sync(); + void sync_debug(); + void sclose(); + void xclose(); + +private: + port_id fSendPort; + port_id fReceivePort; + + char *fSendBuffer; + int32 fSendBufferSize; + int32 fSendSize; + char *fReceiveBuffer; + int32 fReceiveSize; + int32 fReceivePos; +}; + +extern _IMPEXP_BE _BSession_ *main_session; + +#endif diff --git a/src/kits/game/DirectWindow.cpp b/src/kits/game/DirectWindow.cpp index 5e71004af0..b17fc59f90 100644 --- a/src/kits/game/DirectWindow.cpp +++ b/src/kits/game/DirectWindow.cpp @@ -1,400 +1,483 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2001-2002, OpenBeOS -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// File Name: DirectWindow.cpp -// Author: Christopher ML Zumwalt May (zummy@users.sf.net) -// Description: BFileGameSound allow the developer to directly draw to the -// app_server's frame buffer. -//------------------------------------------------------------------------------ - -#include - -#include "DirectWindow.h" - -BDirectWindow::BDirectWindow(BRect frame, - const char *title, - window_type type, - uint32 flags, - uint32 workspace) - : BWindow(frame, title, type, flags, workspace), - fIsFullScreen(false), - fIsConnected(false) -{ - InitData(frame); -} - - -BDirectWindow::BDirectWindow(BRect frame, - const char *title, - window_look look, - window_feel feel, - uint32 flags, - uint32 workspace) - : BWindow(frame, title, look, feel, flags, workspace), - fIsFullScreen(false), - fIsConnected(false) -{ - InitData(frame); -} - - -BDirectWindow::~BDirectWindow() -{ - if (fIsConnected) - { - fBufferInfo->buffer_state = B_DIRECT_STOP; - DoDirectConnected(); - } - - delete fBufferInfo; -} - -BArchivable * -BDirectWindow::Instantiate(BMessage *data) -{ - return NULL; -} - - -status_t -BDirectWindow::Archive(BMessage *data, - bool deep) const -{ - return B_ERROR; -} - - -void -BDirectWindow::Quit(void) -{ - if (fIsConnected) Disconnect(); - - BWindow::Quit(); -} - - -void -BDirectWindow::DispatchMessage(BMessage *message, - BHandler *handler) -{ - BWindow::DispatchMessage(message, handler); -} - - -void -BDirectWindow::MessageReceived(BMessage *message) -{ - BWindow::MessageReceived(message); -} - - -void -BDirectWindow::FrameMoved(BPoint new_position) -{ - clipping_rect * bounds = &fBufferInfo->window_bounds; - - int32 dx = int32(new_position.x - bounds->left); - int32 dy = int32(new_position.y - bounds->top); - - bounds->top += dy; - bounds->left += dx; - bounds->right += dx; - bounds->bottom += dy; - - fBufferInfo->buffer_state = direct_buffer_state(B_DIRECT_MODIFY | B_BUFFER_MOVED); - DoDirectConnected(); -} - - -void -BDirectWindow::WorkspacesChanged(uint32 old_ws, - uint32 new_ws) -{ -} - - -void -BDirectWindow::WorkspaceActivated(int32 ws, - bool state) -{ - if (state) - Connect(); - else - Disconnect(); -} - - -void -BDirectWindow::FrameResized(float new_width, - float new_height) -{ - clipping_rect * bounds = &fBufferInfo->window_bounds; - - bounds->right = int32(bounds->left + new_width); - bounds->bottom = int32(bounds->top + new_height); - - fBufferInfo->buffer_state = direct_buffer_state(B_DIRECT_MODIFY | B_BUFFER_RESIZED); - DoDirectConnected(); -} - - -void -BDirectWindow::Minimize(bool minimize) -{ - if (minimize) - { - Disconnect(); - BWindow::Minimize(false); - } - else - { - BWindow::Minimize(true); - Connect(); - } -} - - -void -BDirectWindow::Zoom(BPoint rec_position, - float rec_width, - float rec_height) -{ - BWindow::Zoom(rec_position, rec_width, rec_height); -} - - -void -BDirectWindow::ScreenChanged(BRect screen_size, - color_space depth) -{ - direct_buffer_state state = B_DIRECT_MODIFY; - - if (fIsConnected && fIsFullScreen) - { - ResizeTo(screen_size.right, screen_size.bottom); - state = direct_buffer_state(state | B_BUFFER_RESIZED); - } - - GetFrameBuffer(); - - fBufferInfo->buffer_state = direct_buffer_state(state | B_BUFFER_RESET); - DoDirectConnected(); -} - - -void -BDirectWindow::MenusBeginning() -{ -} - - -void -BDirectWindow::MenusEnded() -{ -} - - -void -BDirectWindow::WindowActivated(bool state) -{ - CreateClippingList(); -} - - -void -BDirectWindow::Show() -{ - BWindow::Show(); - - Connect(); -} - - -void -BDirectWindow::Hide() -{ - Disconnect(); - - BWindow::Hide(); -} - - -BHandler * -BDirectWindow::ResolveSpecifier(BMessage *msg, - int32 index, - BMessage *specifier, - int32 form, - const char *property) -{ - return NULL; -} - - -status_t -BDirectWindow::GetSupportedSuites(BMessage *data) -{ - return B_ERROR; -} - - -status_t -BDirectWindow::Perform(perform_code d, - void *arg) -{ - return B_ERROR; -} - - -void -BDirectWindow::task_looper() -{ - BWindow::task_looper(); -} - -BMessage * -BDirectWindow::ConvertToMessage(void *raw, int32 code) -{ - return BWindow::ConvertToMessage(raw, code); -} - - -void -BDirectWindow::DirectConnected(direct_buffer_info *info) -{ -} - - -status_t -BDirectWindow::GetClippingRegion(BRegion *region, - BPoint *origin) const -{ - return B_ERROR; -} - - -status_t -BDirectWindow::SetFullScreen(bool enable) -{ - return B_ERROR; -} - - -bool -BDirectWindow::IsFullScreen() const -{ - return fIsFullScreen; -} - - -bool -BDirectWindow::SupportsWindowMode(screen_id) -{ - return true; -} - - -void -BDirectWindow::_ReservedDirectWindow1() -{ -} - - -void -BDirectWindow::_ReservedDirectWindow2() -{ -} - - -void -BDirectWindow::_ReservedDirectWindow3() -{ -} - - -void -BDirectWindow::_ReservedDirectWindow4() -{ -} - - -/* unimplemented for protection of the user: - * - * BDirectWindow::BDirectWindow() - * BDirectWindow::BDirectWindow(BDirectWindow &) - * BDirectWindow &BDirectWindow::operator=(BDirectWindow &) - */ - - -void -BDirectWindow::InitData(BRect frame) -{ - fBufferInfo = new direct_buffer_info; - memset(fBufferInfo, 0, sizeof(direct_buffer_info)); - - fBufferInfo->window_bounds.top = int32(frame.top); - fBufferInfo->window_bounds.left = int32(frame.left); - fBufferInfo->window_bounds.right = int32(frame.right); - fBufferInfo->window_bounds.bottom = int32(frame.bottom); - - GetFrameBuffer(); -} - - -void -BDirectWindow::DoDirectConnected() -{ - if (fIsConnected) - { - direct_buffer_info * info = new direct_buffer_info; - memcpy(info, fBufferInfo, sizeof(direct_buffer_info)); - - DirectConnected(info); - - delete info; - } -} - -void -BDirectWindow::Connect() -{ - fIsConnected = true; - fBufferInfo->buffer_state = B_DIRECT_START; - DoDirectConnected(); -} - -void -BDirectWindow::Disconnect() -{ - fBufferInfo->buffer_state = B_DIRECT_STOP; - DoDirectConnected(); - fIsConnected = false; -} - -void -BDirectWindow::CreateClippingList() -{ -} - -void -BDirectWindow::GetFrameBuffer() -{ -} - +// Copyright 2003 Stefano Ceccherini (burton666@libero.it) + +#include + +#include + +#include +#include + +// TODO: We'll want to move this to a private header, +// accessible by the app server. +struct dw_sync_data +{ + area_id area; + sem_id disableSem; + sem_id disableSemAck; +}; + + +// TODO: This commands are used by the BeOS R5 app_server. +// Change this when our app_server supports BDirectWindow +#define DW_GET_SYNC_DATA 0x880 +#define DW_SUPPORTS_WINDOW_MODE 0xF2C + + +// We don't need this kind of locking, since the directDeamonFunc +// doesn't access critical shared data. +#define DW_NEEDS_LOCKING 0 + +enum dw_status_bits { + DW_STATUS_AREA_CLONED = 0x01, + DW_STATUS_THREAD_STARTED = 0x02, + DW_STATUS_SEM_CREATED =0x04 +}; + + +BDirectWindow::BDirectWindow(BRect frame, const char *title, window_type type, uint32 flags, uint32 workspace) + :BWindow(frame, title, type, flags, workspace) +{ + InitData(); +} + + +BDirectWindow::BDirectWindow(BRect frame, const char *title, window_look look, window_feel feel, uint32 flags, uint32 workspace) + :BWindow(frame, title, look, feel, flags, workspace) +{ + InitData(); +} + + +BDirectWindow::~BDirectWindow() +{ + DisposeData(); +} + + +// start of regular BWindow API +BArchivable * +BDirectWindow::Instantiate(BMessage *data) +{ + return NULL; +} + + +status_t +BDirectWindow::Archive(BMessage *data, bool deep) const +{ + return inherited::Archive(data, deep); +} + + +void +BDirectWindow::Quit() +{ + inherited::Quit(); +} + + +void +BDirectWindow::DispatchMessage(BMessage *message, BHandler *handler) +{ + inherited::DispatchMessage(message, handler); +} + + +void +BDirectWindow::MessageReceived(BMessage *message) +{ + inherited::MessageReceived(message); +} + + +void +BDirectWindow::FrameMoved(BPoint new_position) +{ + inherited::FrameMoved(new_position); +} + + +void +BDirectWindow::WorkspacesChanged(uint32 old_ws, uint32 new_ws) +{ + inherited::WorkspacesChanged(old_ws, new_ws); +} + + +void +BDirectWindow::WorkspaceActivated(int32 ws, bool state) +{ + inherited::WorkspaceActivated(ws, state); +} + + +void +BDirectWindow::FrameResized(float new_width, float new_height) +{ + inherited::FrameResized(new_width, new_height); +} + + +void +BDirectWindow::Minimize(bool minimize) +{ + inherited::Minimize(minimize); +} + + +void +BDirectWindow::Zoom(BPoint rec_position, float rec_width, float rec_height) +{ + inherited::Zoom(rec_position, rec_width, rec_height); +} + + +void +BDirectWindow::ScreenChanged(BRect screen_size, color_space depth) +{ + inherited::ScreenChanged(screen_size, depth); +} + + +void +BDirectWindow::MenusBeginning() +{ + inherited::MenusBeginning(); +} + + +void +BDirectWindow::MenusEnded() +{ + inherited::MenusEnded(); +} + + +void +BDirectWindow::WindowActivated(bool state) +{ + inherited::WindowActivated(state); +} + + +void +BDirectWindow::Show() +{ + inherited::Show(); +} + + +void +BDirectWindow::Hide() +{ + inherited::Hide(); +} + + +BHandler * +BDirectWindow::ResolveSpecifier(BMessage *msg, int32 index, + BMessage *specifier, int32 form, const char *property) +{ + return inherited::ResolveSpecifier(msg, index, specifier, form, property); +} + + +status_t +BDirectWindow::GetSupportedSuites(BMessage *data) +{ + return inherited::GetSupportedSuites(data); +} + + +status_t +BDirectWindow::Perform(perform_code d, void *arg) +{ + return inherited::Perform(d, arg); +} + + +void +BDirectWindow::task_looper() +{ + inherited::task_looper(); +} + + +BMessage * +BDirectWindow::ConvertToMessage(void *raw, int32 code) +{ + return inherited::ConvertToMessage(raw, code); +} +// end of BWindow API + + +// BDirectWindow specific API +void +BDirectWindow::DirectConnected(direct_buffer_info *info) +{ + //implemented in subclasses +} + + +status_t +BDirectWindow::GetClippingRegion(BRegion *region, BPoint *origin) const +{ + if (region == NULL) + return B_BAD_VALUE; + + if (IsLocked()) + return B_ERROR; + + if (LockDirect()) { + if (in_direct_connect) { + UnlockDirect(); + return B_ERROR; + } + + // BPoint's coordinates are floats. We can only work + // with integers. + int32 originX, originY; + if (origin == NULL) { + originX = 0; + originY = 0; + } else { + originX = (int32)origin->x; + originY = (int32)origin->y; + } + + // Since we are friend of BRegion, we can access its private members. + // Otherwise, we would need to call BRegion::Include(clipping_rect) + // for every clipping_rect in our clip_list, and that would be much + // more overkill than this. + region->set_size(buffer_desc->clip_list_count); + region->count = buffer_desc->clip_list_count; + region->bound = buffer_desc->clip_bounds; + + // adjust bounds by the given origin point + offset_rect(region->bound, -originX, -originY); + + for (uint32 c = 0; c < buffer_desc->clip_list_count; c++) { + region->data[c] = buffer_desc->clip_list[c]; + offset_rect(region->data[c], -originX, -originY); + } + + UnlockDirect(); + + return B_OK; + } + + return B_ERROR; +} + + +status_t +BDirectWindow::SetFullScreen(bool enable) +{ + status_t status = B_ERROR; + //TODO: Implement + return status; +} + + +bool +BDirectWindow::IsFullScreen() const +{ + return full_screen_enable; +} + + +bool +BDirectWindow::SupportsWindowMode(screen_id id) +{ + _BAppServerLink_ link; + link.fSession->swrite_l(DW_SUPPORTS_WINDOW_MODE); + link.fSession->swrite_l(id.id); + link.fSession->sync(); + + int32 result; + link.fSession->sread(sizeof(result), &result); + + return result & true; +} + + +// Private methods +int32 +BDirectWindow::DirectDeamonFunc(void *arg) +{ + BDirectWindow *object = static_cast(arg); + + while (!object->deamon_killer) { + // This sem is released by the app_server when our + // clipping region changes, or when our window is moved, + // resized, etc. etc. + while (acquire_sem(object->disable_sem) == B_INTERRUPTED) + ; + + if (object->LockDirect()) { + if ((object->buffer_desc->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_START) + object->connection_enable = true; + + object->in_direct_connect = true; + object->DirectConnected(object->buffer_desc); + object->in_direct_connect = false; + + if ((object->buffer_desc->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_STOP) + object->connection_enable = false; + + object->UnlockDirect(); + } + + // The app_server then waits (with a timeout) on this sem. + // If we aren't quick enough to release this sem, our app + // will be terminated by the app_server + release_sem(object->disable_sem_ack); + } + + return 0; +} + + +bool +BDirectWindow::LockDirect() const +{ + status_t status = B_OK; + +#if DW_NEEDS_LOCKING + BDirectWindow *casted = const_cast(this); + + if (atomic_add(&casted->direct_lock, 1) > 0) + do { + status = acquire_sem(direct_sem); + } while (status == B_INTERRUPTED); + + if (status == B_OK) { + casted->direct_lock_owner = find_thread(NULL); + casted->direct_lock_count++; + } +#endif + + return status == B_OK; +} + + +void +BDirectWindow::UnlockDirect() const +{ +#if DW_NEEDS_LOCKING + BDirectWindow *casted = const_cast(this); + + if (atomic_add(&casted->direct_lock, -1) > 1) + release_sem(direct_sem); + + casted->direct_lock_count--; +#endif +} + + +void +BDirectWindow::InitData() +{ + connection_enable = false; + full_screen_enable = false; + in_direct_connect = false; + + dw_init_status = 0; + + direct_driver_ready = false; + direct_driver_type = 0; + direct_driver_token = 0; + direct_driver = NULL; + + if (Lock()) { + a_session->swrite_l(DW_GET_SYNC_DATA); + a_session->swrite_l(server_token); + Flush(); + + struct dw_sync_data sync_data; + a_session->sread(sizeof(sync_data), &sync_data); + + status_t status; + a_session->sread(4, &status); + + Unlock(); + + if (status == B_OK) { + +#if DW_NEEDS_LOCKING + direct_lock = 0; + direct_lock_count = 0; + direct_lock_owner = B_ERROR; + direct_lock_stack = NULL; + direct_sem = create_sem(1, "direct sem"); + if (direct_sem > 0) + dw_init_status |= DW_STATUS_SEM_CREATED; +#endif + + source_clipping_area = sync_data.area; + disable_sem = sync_data.disableSem; + disable_sem_ack = sync_data.disableSemAck; + + cloned_clipping_area = clone_area("Clone direct area", (void**)&buffer_desc, + B_ANY_ADDRESS, B_READ_AREA, source_clipping_area); + if (cloned_clipping_area > 0) { + dw_init_status |= DW_STATUS_AREA_CLONED; + + direct_deamon_id = spawn_thread(DirectDeamonFunc, "direct deamon", + B_DISPLAY_PRIORITY, this); + + if (direct_deamon_id > 0) { + deamon_killer = false; + if (resume_thread(direct_deamon_id) == B_OK) + dw_init_status |= DW_STATUS_THREAD_STARTED; + else + kill_thread(direct_deamon_id); + } + } + } + } +} + + +void +BDirectWindow::DisposeData() +{ + // wait until the connection terminates: we can't destroy + // the object until the client receives the B_DIRECT_STOP + // notification, or bad things will happen + while (connection_enable) + snooze(50000); + + LockDirect(); + + if (dw_init_status & DW_STATUS_THREAD_STARTED) { + deamon_killer = true; + // Release this sem, otherwise the Direct deamon thread + // will wait forever on it + release_sem(disable_sem); + status_t retVal; + wait_for_thread(direct_deamon_id, &retVal); + } + +#if DW_NEEDS_LOCKING + if (dw_init_status & DW_STATUS_SEM_CREATED) + delete_sem(direct_sem); +#endif + + if (dw_init_status & DW_STATUS_AREA_CLONED) + delete_area(cloned_clipping_area); +} + + +status_t +BDirectWindow::DriverSetup() const +{ + //Unimplemented + return B_OK; +} + + +void BDirectWindow::_ReservedDirectWindow1() {} +void BDirectWindow::_ReservedDirectWindow2() {} +void BDirectWindow::_ReservedDirectWindow3() {} +void BDirectWindow::_ReservedDirectWindow4() {}