Added a BDirectWindow implementation which works with BeOS R5 (at least, with the Chart demo app)

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4755 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stefano Ceccherini
2003-09-18 13:39:39 +00:00
parent 92d054b3ea
commit cafaa5aa29
4 changed files with 741 additions and 567 deletions
+168 -167
View File
@@ -1,167 +1,168 @@
//------------------------------------------------------------------------------ /*******************************************************************************
// Copyright (c) 2001-2002, OpenBeOS //
// // File: DirectWindow.h
// Permission is hereby granted, free of charge, to any person obtaining a //
// copy of this software and associated documentation files (the "Software"), // Description: Client window class for direct screen access.
// to deal in the Software without restriction, including without limitation //
// the rights to use, copy, modify, merge, publish, distribute, sublicense, // Copyright 1998, Be Incorporated, All Rights Reserved.
// 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. #ifndef _DIRECT_WINDOW_H
// #define _DIRECT_WINDOW_H
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #include <Region.h>
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #include <Window.h>
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING class BDirectDriver;
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. /* State of the direct access when called back through DirectConnected */
// enum direct_buffer_state {
// File Name: DirectWindow.h B_DIRECT_MODE_MASK = 15,
// Author: Christopher ML Zumwalt May ([email protected])
// Description: BFileGameSound allow the developer to directly draw to the B_DIRECT_START = 0,
// app_server's frame buffer. B_DIRECT_STOP = 1,
//------------------------------------------------------------------------------ B_DIRECT_MODIFY = 2,
#ifndef _DIRECTWINDOW_H B_CLIPPING_MODIFIED = 16,
#define _DIRECTWINDOW_H B_BUFFER_RESIZED = 32,
B_BUFFER_MOVED = 64,
// Standard Includes ----------------------------------------------------------- B_BUFFER_RESET = 128
};
// System Includes -------------------------------------------------------------
#include <Region.h> /* State of the direct driver and its hooks functions */
#include <Window.h> enum direct_driver_state {
B_DRIVER_CHANGED = 0x0001,
// Project Includes ------------------------------------------------------------ B_MODE_CHANGED = 0x0002
};
// Local Includes --------------------------------------------------------------
/* Integer rect used to define a cliping rectangle. All bounds are included */
// Local Defines --------------------------------------------------------------- /* Moved to Region.h */
// Globals --------------------------------------------------------------------- /* Frame buffer access descriptor */
enum direct_buffer_state { typedef struct {
B_DIRECT_MODE_MASK = 15, direct_buffer_state buffer_state;
direct_driver_state driver_state;
B_DIRECT_START = 0, void *bits;
B_DIRECT_STOP = 1, void *pci_bits;
B_DIRECT_MODIFY = 2, int32 bytes_per_row;
uint32 bits_per_pixel;
B_CLIPPING_MODIFIED = 16, color_space pixel_format;
B_BUFFER_RESIZED = 32, buffer_layout layout;
B_BUFFER_MOVED = 64, buffer_orientation orientation;
B_BUFFER_RESET = 128 uint32 _reserved[9];
}; uint32 _dd_type_;
uint32 _dd_token_;
enum direct_driver_state { uint32 clip_list_count;
B_DRIVER_CHANGED = 0x0001, clipping_rect window_bounds;
B_MODE_CHANGED = 0x0002 clipping_rect clip_bounds;
}; clipping_rect clip_list[1];
} direct_buffer_info;
typedef struct {
direct_buffer_state buffer_state; /* BDirectWindow class */
direct_driver_state driver_state; class BDirectWindow : public BWindow {
void *bits; public:
void *pci_bits; BDirectWindow( BRect frame,
int32 bytes_per_row; const char *title,
uint32 bits_per_pixel; window_type type,
color_space pixel_format; uint32 flags,
buffer_layout layout; uint32 workspace = B_CURRENT_WORKSPACE);
buffer_orientation orientation; BDirectWindow( BRect frame,
uint32 _reserved[9]; const char *title,
uint32 _dd_type_; window_look look,
uint32 _dd_token_; window_feel feel,
uint32 clip_list_count; uint32 flags,
clipping_rect window_bounds; uint32 workspace = B_CURRENT_WORKSPACE);
clipping_rect clip_bounds; virtual ~BDirectWindow();
clipping_rect clip_list[1]; static BArchivable *Instantiate(BMessage *data);
} direct_buffer_info; virtual status_t Archive(BMessage *data, bool deep = true) const;
// PushGameSound --------------------------------------------------------------- /* defined for future extension (fragile base class). Identical to BWindow */
class BDirectWindow : public BWindow virtual void Quit(void);
{ virtual void DispatchMessage(BMessage *message, BHandler *handler);
public: virtual void MessageReceived(BMessage *message);
BDirectWindow(BRect frame, virtual void FrameMoved(BPoint new_position);
const char *title, virtual void WorkspacesChanged(uint32 old_ws, uint32 new_ws);
window_type type, virtual void WorkspaceActivated(int32 ws, bool state);
uint32 flags, virtual void FrameResized(float new_width, float new_height);
uint32 workspace = B_CURRENT_WORKSPACE); virtual void Minimize(bool minimize);
BDirectWindow(BRect frame, virtual void Zoom( BPoint rec_position,
const char *title, float rec_width,
window_look look, float rec_height);
window_feel feel, virtual void ScreenChanged(BRect screen_size, color_space depth);
uint32 flags, virtual void MenusBeginning();
uint32 workspace = B_CURRENT_WORKSPACE); virtual void MenusEnded();
virtual ~BDirectWindow(); virtual void WindowActivated(bool state);
virtual void Show();
static BArchivable *Instantiate(BMessage *data); virtual void Hide();
virtual status_t Archive(BMessage *data, bool deep = true) const; virtual BHandler *ResolveSpecifier(BMessage *msg,
virtual void Quit(void); int32 index,
virtual void DispatchMessage(BMessage *message, BHandler *handler); BMessage *specifier,
virtual void MessageReceived(BMessage *message); int32 form,
virtual void FrameMoved(BPoint new_position); const char *property);
virtual void WorkspacesChanged(uint32 old_ws, uint32 new_ws); virtual status_t GetSupportedSuites(BMessage *data);
virtual void WorkspaceActivated(int32 ws, bool state); virtual status_t Perform(perform_code d, void *arg);
virtual void FrameResized(float new_width, float new_height);
virtual void Minimize(bool minimize); private:
virtual void Zoom(BPoint rec_position, virtual void task_looper();
float rec_width, virtual BMessage *ConvertToMessage(void *raw, int32 code);
float rec_height);
virtual void ScreenChanged(BRect screen_size, color_space depth); /* new APIs */
virtual void MenusBeginning();
virtual void MenusEnded(); public:
virtual void WindowActivated(bool state); virtual void DirectConnected(direct_buffer_info *info);
virtual void Show(); status_t GetClippingRegion(BRegion *region, BPoint *origin = NULL) const;
virtual void Hide(); status_t SetFullScreen(bool enable);
virtual BHandler *ResolveSpecifier(BMessage *msg, bool IsFullScreen() const;
int32 index,
BMessage *specifier, static bool SupportsWindowMode(screen_id = B_MAIN_SCREEN_ID);
int32 form,
const char *property); /* private */
virtual status_t GetSupportedSuites(BMessage *data); private:
virtual status_t Perform(perform_code d, void *arg);
typedef BWindow inherited;
private:
virtual void task_looper(); virtual void _ReservedDirectWindow1();
virtual BMessage *ConvertToMessage(void *raw, int32 code); virtual void _ReservedDirectWindow2();
virtual void _ReservedDirectWindow3();
public: virtual void _ReservedDirectWindow4();
// BDirectWindow API
virtual void DirectConnected(direct_buffer_info *info);
status_t GetClippingRegion(BRegion *region, BPoint *origin = NULL) const; BDirectWindow();
status_t SetFullScreen(bool enable); BDirectWindow(BDirectWindow &);
bool IsFullScreen() const; BDirectWindow &operator=(BDirectWindow &);
static bool SupportsWindowMode(screen_id = B_MAIN_SCREEN_ID); bool deamon_killer;
bool connection_enable;
private: bool full_screen_enable;
bool direct_driver_ready;
typedef BWindow inherited; bool in_direct_connect;
int32 direct_lock;
virtual void _ReservedDirectWindow1(); sem_id direct_sem;
virtual void _ReservedDirectWindow2(); uint32 direct_lock_count;
virtual void _ReservedDirectWindow3(); thread_id direct_lock_owner;
virtual void _ReservedDirectWindow4(); char *direct_lock_stack;
sem_id disable_sem;
BDirectWindow(); sem_id disable_sem_ack;
BDirectWindow(BDirectWindow &); uint32 dw_init_status;
BDirectWindow &operator=(BDirectWindow &); uint32 info_area_size;
uint32 direct_driver_type;
void InitData(BRect frame); uint32 direct_driver_token;
area_id cloned_clipping_area;
void DoDirectConnected(); area_id source_clipping_area;
void Connect(); thread_id direct_deamon_id;
void Disconnect(); direct_buffer_info *buffer_desc;
BDirectDriver *direct_driver;
void CreateClippingList(); struct priv_ext *extension;
void GetFrameBuffer(); uint32 _reserved_[15];
bool fIsFullScreen; static int32 DirectDeamonFunc(void *arg);
bool fIsConnected; bool LockDirect() const;
direct_buffer_info *fBufferInfo; void UnlockDirect() const;
uint32 _reserved_[31]; void InitData();
}; void DisposeData();
status_t DriverSetup() const;
#endif };
#endif
@@ -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 <BeBuild.h>
#include <SupportDefs.h>
#include <OS.h>
#include "Session.h"
class _BAppServerLink_ {
public:
_BAppServerLink_();
virtual ~_BAppServerLink_();
_BSession_ *fSession;
};
#endif
+69
View File
@@ -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 <BeBuild.h>
#include <SupportDefs.h>
#include <Region.h>
#include <Rect.h>
#include <OS.h>
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
+483 -400
View File
@@ -1,400 +1,483 @@
//------------------------------------------------------------------------------ // Copyright 2003 Stefano Ceccherini ([email protected])
// Copyright (c) 2001-2002, OpenBeOS
// #include <DirectWindow.h>
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"), #include <clipping.h>
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, #include <R5_AppServerLink.h>
// and/or sell copies of the Software, and to permit persons to whom the #include <R5_Session.h>
// Software is furnished to do so, subject to the following conditions:
// // TODO: We'll want to move this to a private header,
// The above copyright notice and this permission notice shall be included in // accessible by the app server.
// all copies or substantial portions of the Software. struct dw_sync_data
// {
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR area_id area;
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, sem_id disableSem;
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE sem_id disableSemAck;
// 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. // TODO: This commands are used by the BeOS R5 app_server.
// // Change this when our app_server supports BDirectWindow
// File Name: DirectWindow.cpp #define DW_GET_SYNC_DATA 0x880
// Author: Christopher ML Zumwalt May ([email protected]) #define DW_SUPPORTS_WINDOW_MODE 0xF2C
// Description: BFileGameSound allow the developer to directly draw to the
// app_server's frame buffer.
//------------------------------------------------------------------------------ // We don't need this kind of locking, since the directDeamonFunc
// doesn't access critical shared data.
#include <memory.h> #define DW_NEEDS_LOCKING 0
#include "DirectWindow.h" enum dw_status_bits {
DW_STATUS_AREA_CLONED = 0x01,
BDirectWindow::BDirectWindow(BRect frame, DW_STATUS_THREAD_STARTED = 0x02,
const char *title, DW_STATUS_SEM_CREATED =0x04
window_type type, };
uint32 flags,
uint32 workspace)
: BWindow(frame, title, type, flags, workspace), BDirectWindow::BDirectWindow(BRect frame, const char *title, window_type type, uint32 flags, uint32 workspace)
fIsFullScreen(false), :BWindow(frame, title, type, flags, workspace)
fIsConnected(false) {
{ InitData();
InitData(frame); }
}
BDirectWindow::BDirectWindow(BRect frame, const char *title, window_look look, window_feel feel, uint32 flags, uint32 workspace)
BDirectWindow::BDirectWindow(BRect frame, :BWindow(frame, title, look, feel, flags, workspace)
const char *title, {
window_look look, InitData();
window_feel feel, }
uint32 flags,
uint32 workspace)
: BWindow(frame, title, look, feel, flags, workspace), BDirectWindow::~BDirectWindow()
fIsFullScreen(false), {
fIsConnected(false) DisposeData();
{ }
InitData(frame);
}
// start of regular BWindow API
BArchivable *
BDirectWindow::~BDirectWindow() BDirectWindow::Instantiate(BMessage *data)
{ {
if (fIsConnected) return NULL;
{ }
fBufferInfo->buffer_state = B_DIRECT_STOP;
DoDirectConnected();
} status_t
BDirectWindow::Archive(BMessage *data, bool deep) const
delete fBufferInfo; {
} return inherited::Archive(data, deep);
}
BArchivable *
BDirectWindow::Instantiate(BMessage *data)
{ void
return NULL; BDirectWindow::Quit()
} {
inherited::Quit();
}
status_t
BDirectWindow::Archive(BMessage *data,
bool deep) const void
{ BDirectWindow::DispatchMessage(BMessage *message, BHandler *handler)
return B_ERROR; {
} inherited::DispatchMessage(message, handler);
}
void
BDirectWindow::Quit(void) void
{ BDirectWindow::MessageReceived(BMessage *message)
if (fIsConnected) Disconnect(); {
inherited::MessageReceived(message);
BWindow::Quit(); }
}
void
void BDirectWindow::FrameMoved(BPoint new_position)
BDirectWindow::DispatchMessage(BMessage *message, {
BHandler *handler) inherited::FrameMoved(new_position);
{ }
BWindow::DispatchMessage(message, handler);
}
void
BDirectWindow::WorkspacesChanged(uint32 old_ws, uint32 new_ws)
void {
BDirectWindow::MessageReceived(BMessage *message) inherited::WorkspacesChanged(old_ws, new_ws);
{ }
BWindow::MessageReceived(message);
}
void
BDirectWindow::WorkspaceActivated(int32 ws, bool state)
void {
BDirectWindow::FrameMoved(BPoint new_position) inherited::WorkspaceActivated(ws, state);
{ }
clipping_rect * bounds = &fBufferInfo->window_bounds;
int32 dx = int32(new_position.x - bounds->left); void
int32 dy = int32(new_position.y - bounds->top); BDirectWindow::FrameResized(float new_width, float new_height)
{
bounds->top += dy; inherited::FrameResized(new_width, new_height);
bounds->left += dx; }
bounds->right += dx;
bounds->bottom += dy;
void
fBufferInfo->buffer_state = direct_buffer_state(B_DIRECT_MODIFY | B_BUFFER_MOVED); BDirectWindow::Minimize(bool minimize)
DoDirectConnected(); {
} inherited::Minimize(minimize);
}
void
BDirectWindow::WorkspacesChanged(uint32 old_ws, void
uint32 new_ws) BDirectWindow::Zoom(BPoint rec_position, float rec_width, float rec_height)
{ {
} inherited::Zoom(rec_position, rec_width, rec_height);
}
void
BDirectWindow::WorkspaceActivated(int32 ws, void
bool state) BDirectWindow::ScreenChanged(BRect screen_size, color_space depth)
{ {
if (state) inherited::ScreenChanged(screen_size, depth);
Connect(); }
else
Disconnect();
} void
BDirectWindow::MenusBeginning()
{
void inherited::MenusBeginning();
BDirectWindow::FrameResized(float new_width, }
float new_height)
{
clipping_rect * bounds = &fBufferInfo->window_bounds; void
BDirectWindow::MenusEnded()
bounds->right = int32(bounds->left + new_width); {
bounds->bottom = int32(bounds->top + new_height); inherited::MenusEnded();
}
fBufferInfo->buffer_state = direct_buffer_state(B_DIRECT_MODIFY | B_BUFFER_RESIZED);
DoDirectConnected();
} void
BDirectWindow::WindowActivated(bool state)
{
void inherited::WindowActivated(state);
BDirectWindow::Minimize(bool minimize) }
{
if (minimize)
{ void
Disconnect(); BDirectWindow::Show()
BWindow::Minimize(false); {
} inherited::Show();
else }
{
BWindow::Minimize(true);
Connect(); void
} BDirectWindow::Hide()
} {
inherited::Hide();
}
void
BDirectWindow::Zoom(BPoint rec_position,
float rec_width, BHandler *
float rec_height) BDirectWindow::ResolveSpecifier(BMessage *msg, int32 index,
{ BMessage *specifier, int32 form, const char *property)
BWindow::Zoom(rec_position, rec_width, rec_height); {
} return inherited::ResolveSpecifier(msg, index, specifier, form, property);
}
void
BDirectWindow::ScreenChanged(BRect screen_size, status_t
color_space depth) BDirectWindow::GetSupportedSuites(BMessage *data)
{ {
direct_buffer_state state = B_DIRECT_MODIFY; return inherited::GetSupportedSuites(data);
}
if (fIsConnected && fIsFullScreen)
{
ResizeTo(screen_size.right, screen_size.bottom); status_t
state = direct_buffer_state(state | B_BUFFER_RESIZED); BDirectWindow::Perform(perform_code d, void *arg)
} {
return inherited::Perform(d, arg);
GetFrameBuffer(); }
fBufferInfo->buffer_state = direct_buffer_state(state | B_BUFFER_RESET);
DoDirectConnected(); void
} BDirectWindow::task_looper()
{
inherited::task_looper();
void }
BDirectWindow::MenusBeginning()
{
} BMessage *
BDirectWindow::ConvertToMessage(void *raw, int32 code)
{
void return inherited::ConvertToMessage(raw, code);
BDirectWindow::MenusEnded() }
{ // end of BWindow API
}
// BDirectWindow specific API
void void
BDirectWindow::WindowActivated(bool state) BDirectWindow::DirectConnected(direct_buffer_info *info)
{ {
CreateClippingList(); //implemented in subclasses
} }
void status_t
BDirectWindow::Show() BDirectWindow::GetClippingRegion(BRegion *region, BPoint *origin) const
{ {
BWindow::Show(); if (region == NULL)
return B_BAD_VALUE;
Connect();
} if (IsLocked())
return B_ERROR;
void if (LockDirect()) {
BDirectWindow::Hide() if (in_direct_connect) {
{ UnlockDirect();
Disconnect(); return B_ERROR;
}
BWindow::Hide();
} // BPoint's coordinates are floats. We can only work
// with integers.
int32 originX, originY;
BHandler * if (origin == NULL) {
BDirectWindow::ResolveSpecifier(BMessage *msg, originX = 0;
int32 index, originY = 0;
BMessage *specifier, } else {
int32 form, originX = (int32)origin->x;
const char *property) originY = (int32)origin->y;
{ }
return NULL;
} // 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
status_t // more overkill than this.
BDirectWindow::GetSupportedSuites(BMessage *data) region->set_size(buffer_desc->clip_list_count);
{ region->count = buffer_desc->clip_list_count;
return B_ERROR; region->bound = buffer_desc->clip_bounds;
}
// adjust bounds by the given origin point
offset_rect(region->bound, -originX, -originY);
status_t
BDirectWindow::Perform(perform_code d, for (uint32 c = 0; c < buffer_desc->clip_list_count; c++) {
void *arg) region->data[c] = buffer_desc->clip_list[c];
{ offset_rect(region->data[c], -originX, -originY);
return B_ERROR; }
}
UnlockDirect();
void return B_OK;
BDirectWindow::task_looper() }
{
BWindow::task_looper(); return B_ERROR;
} }
BMessage *
BDirectWindow::ConvertToMessage(void *raw, int32 code) status_t
{ BDirectWindow::SetFullScreen(bool enable)
return BWindow::ConvertToMessage(raw, code); {
} status_t status = B_ERROR;
//TODO: Implement
return status;
void }
BDirectWindow::DirectConnected(direct_buffer_info *info)
{
} bool
BDirectWindow::IsFullScreen() const
{
status_t return full_screen_enable;
BDirectWindow::GetClippingRegion(BRegion *region, }
BPoint *origin) const
{
return B_ERROR; bool
} BDirectWindow::SupportsWindowMode(screen_id id)
{
_BAppServerLink_ link;
status_t link.fSession->swrite_l(DW_SUPPORTS_WINDOW_MODE);
BDirectWindow::SetFullScreen(bool enable) link.fSession->swrite_l(id.id);
{ link.fSession->sync();
return B_ERROR;
} int32 result;
link.fSession->sread(sizeof(result), &result);
bool return result & true;
BDirectWindow::IsFullScreen() const }
{
return fIsFullScreen;
} // Private methods
int32
BDirectWindow::DirectDeamonFunc(void *arg)
bool {
BDirectWindow::SupportsWindowMode(screen_id) BDirectWindow *object = static_cast<BDirectWindow *>(arg);
{
return true; 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.
void while (acquire_sem(object->disable_sem) == B_INTERRUPTED)
BDirectWindow::_ReservedDirectWindow1() ;
{
} if (object->LockDirect()) {
if ((object->buffer_desc->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_START)
object->connection_enable = true;
void
BDirectWindow::_ReservedDirectWindow2() 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)
void object->connection_enable = false;
BDirectWindow::_ReservedDirectWindow3()
{ object->UnlockDirect();
} }
// The app_server then waits (with a timeout) on this sem.
void // If we aren't quick enough to release this sem, our app
BDirectWindow::_ReservedDirectWindow4() // will be terminated by the app_server
{ release_sem(object->disable_sem_ack);
} }
return 0;
/* unimplemented for protection of the user: }
*
* BDirectWindow::BDirectWindow()
* BDirectWindow::BDirectWindow(BDirectWindow &) bool
* BDirectWindow &BDirectWindow::operator=(BDirectWindow &) BDirectWindow::LockDirect() const
*/ {
status_t status = B_OK;
void #if DW_NEEDS_LOCKING
BDirectWindow::InitData(BRect frame) BDirectWindow *casted = const_cast<BDirectWindow *>(this);
{
fBufferInfo = new direct_buffer_info; if (atomic_add(&casted->direct_lock, 1) > 0)
memset(fBufferInfo, 0, sizeof(direct_buffer_info)); do {
status = acquire_sem(direct_sem);
fBufferInfo->window_bounds.top = int32(frame.top); } while (status == B_INTERRUPTED);
fBufferInfo->window_bounds.left = int32(frame.left);
fBufferInfo->window_bounds.right = int32(frame.right); if (status == B_OK) {
fBufferInfo->window_bounds.bottom = int32(frame.bottom); casted->direct_lock_owner = find_thread(NULL);
casted->direct_lock_count++;
GetFrameBuffer(); }
} #endif
return status == B_OK;
void }
BDirectWindow::DoDirectConnected()
{
if (fIsConnected) void
{ BDirectWindow::UnlockDirect() const
direct_buffer_info * info = new direct_buffer_info; {
memcpy(info, fBufferInfo, sizeof(direct_buffer_info)); #if DW_NEEDS_LOCKING
BDirectWindow *casted = const_cast<BDirectWindow *>(this);
DirectConnected(info);
if (atomic_add(&casted->direct_lock, -1) > 1)
delete info; release_sem(direct_sem);
}
} casted->direct_lock_count--;
#endif
void }
BDirectWindow::Connect()
{
fIsConnected = true; void
fBufferInfo->buffer_state = B_DIRECT_START; BDirectWindow::InitData()
DoDirectConnected(); {
} connection_enable = false;
full_screen_enable = false;
void in_direct_connect = false;
BDirectWindow::Disconnect()
{ dw_init_status = 0;
fBufferInfo->buffer_state = B_DIRECT_STOP;
DoDirectConnected(); direct_driver_ready = false;
fIsConnected = false; direct_driver_type = 0;
} direct_driver_token = 0;
direct_driver = NULL;
void
BDirectWindow::CreateClippingList() if (Lock()) {
{ a_session->swrite_l(DW_GET_SYNC_DATA);
} a_session->swrite_l(server_token);
Flush();
void
BDirectWindow::GetFrameBuffer() 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() {}