now directly banging the hardware by using a cloned accelerant, soon to be ported to the app_server test environment. Unfortunately deadlocks most of the time when quitting...

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15462 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2005-12-10 12:43:19 +00:00
parent 7be34d3eb2
commit e76d86d5dd
17 changed files with 1814 additions and 597 deletions

View File

@ -8,12 +8,13 @@
#include <Window.h>
#include "DrawingEngine.h"
#include "DrawView.h"
#include "WindowLayer.h"
#include "Desktop.h"
// constructor
Desktop::Desktop(DrawView* drawView)
Desktop::Desktop(DrawView* drawView, DrawingEngine* engine)
: BLooper("desktop", B_URGENT_DISPLAY_PRIORITY),
fTracking(false),
fLastMousePos(-1.0, -1.0),
@ -25,8 +26,12 @@ Desktop::Desktop(DrawView* drawView)
fClippingLock("clipping lock"),
fBackgroundRegion(),
fMasterClipping(),
fXOffset(0),
fYOffset(0),
fDrawView(drawView),
fDrawingEngine(fDrawView->GetDrawingEngine()),
fDrawingEngine(engine),
fWindows(64),
@ -45,36 +50,6 @@ Desktop::~Desktop()
{
}
// Draw
void
Desktop::Draw(BRect updateRect)
{
#if !RUN_WITH_FRAME_BUFFER
// since parts of the view might have been exposed,
// we need a clipping rebuild
if (LockClipping()) {
BRegion background;
_RebuildClippingForAllWindows(&background);
_SetBackground(&background);
UnlockClipping();
}
#endif
if (fDrawingEngine->Lock()) {
fDrawingEngine->SetHighColor(51, 102, 152);
fDrawingEngine->FillRegion(&fBackgroundRegion);
fDrawingEngine->Unlock();
}
#if !RUN_WITH_FRAME_BUFFER
// trigger redrawing windows
BRegion update(updateRect);
update.Exclude(&fBackgroundRegion);
MarkDirty(&update);
#endif
}
// MouseDown
void
Desktop::MouseDown(BPoint where, uint32 buttons, int32 clicks)
@ -103,19 +78,7 @@ Desktop::MouseDown(BPoint where, uint32 buttons, int32 clicks)
fIs2ndButton = true;
} else if (buttons == B_TERTIARY_MOUSE_BUTTON) {
#if RUN_WITH_FRAME_BUFFER
if (fDrawingEngine->Lock()) {
BRegion region(fDrawingEngine->Bounds());
fDrawingEngine->Unlock();
MarkDirty(&region);
region = fBackgroundRegion;
fBackgroundRegion.MakeEmpty();
_SetBackground(&region);
}
#else
fDrawingEngine->MarkDirty();
#endif
fDrawView->Invalidate();
}
}
@ -163,23 +126,7 @@ Desktop::MouseMoved(BPoint where, uint32 code, const BMessage* dragMessage)
}
}
} else if (fIs2ndButton) {
if (fDrawingEngine->Lock()) {
fDrawingEngine->SetHighColor(0, 0, 0);
fDrawingEngine->StrokeLine(fLastMousePos, where);
BRect dirty(fLastMousePos, where);
if (dirty.left > dirty.right) {
dirty.left = where.x;
dirty.right = fLastMousePos.x;
}
if (dirty.top > dirty.bottom) {
dirty.top = where.y;
dirty.bottom = fLastMousePos.y;
}
fDrawingEngine->MarkDirty(dirty);
fDrawingEngine->Unlock();
}
fDrawingEngine->StrokeLine(fLastMousePos, where, (rgb_color){ 0, 0, 0, 255 });
fLastMousePos = where;
}
}
@ -197,6 +144,9 @@ Desktop::MessageReceived(BMessage* message)
message->FindInt32("buttons", (int32*)&buttons) >= B_OK &&
message->FindInt32("clicks", &clicks) >= B_OK) {
where.x += fXOffset;
where.y += fYOffset;
MouseDown(where, buttons, clicks);
}
break;
@ -205,6 +155,9 @@ Desktop::MessageReceived(BMessage* message)
BPoint where;
if (message->FindPoint("where", &where) >= B_OK) {
where.x += fXOffset;
where.y += fYOffset;
MouseUp(where);
}
break;
@ -215,18 +168,15 @@ Desktop::MessageReceived(BMessage* message)
uint32 transit;
if (message->FindPoint("where", &where) >= B_OK &&
message->FindInt32("be:transit", (int32*)&transit) >= B_OK) {
where.x += fXOffset;
where.y += fYOffset;
MouseMoved(where, transit, NULL);
}
}
break;
}
case MSG_DRAW: {
BRect area;
if (message->FindRect("area", &area) >= B_OK)
Draw(area);
}
case MSG_ADD_WINDOW: {
WindowLayer* window;
@ -251,6 +201,37 @@ Desktop::MessageReceived(BMessage* message)
// #pragma mark -
// SetMasterClipping
void
Desktop::SetMasterClipping(BRegion* clipping)
{
BRegion update = *clipping;
update.Exclude(&fMasterClipping);
fMasterClipping = *clipping;
// since parts of the view might have been exposed,
// we need a clipping rebuild
BRegion background;
_RebuildClippingForAllWindows(&background);
_SetBackground(&background);
fDrawingEngine->FillRegion(&fBackgroundRegion, (rgb_color){ 51, 102, 152, 255 });
// trigger redrawing windows
update.Exclude(&fBackgroundRegion);
MarkDirty(&update);
}
// SetOffset
void
Desktop::SetOffset(int32 x, int32 y)
{
fXOffset = x;
fYOffset = y;
}
// #pragma mark -
// AddWindow
bool
Desktop::AddWindow(WindowLayer* window)
@ -387,17 +368,10 @@ Desktop::MoveWindowBy(WindowLayer* window, int32 x, int32 y)
// moved into the dirty region (for now)
newDirtyRegion.Include(&window->VisibleRegion());
if (fDrawingEngine->Lock()) {
fDrawingEngine->CopyRegion(&copyRegion, x, y);
// in the dirty region, exclude the parts that we
// could move by blitting
copyRegion.OffsetBy(x, y);
newDirtyRegion.Exclude(&copyRegion);
fDrawingEngine->MarkDirty(&copyRegion);
fDrawingEngine->Unlock();
}
fDrawingEngine->CopyRegion(&copyRegion, x, y);
copyRegion.OffsetBy(x, y);
newDirtyRegion.Exclude(&copyRegion);
MarkDirty(&newDirtyRegion);
_SetBackground(&background);
@ -456,6 +430,8 @@ Desktop::HideWindow(WindowLayer* window)
void
Desktop::SetWindowHidden(WindowLayer* window, bool hidden)
{
// TODO: if in ffm mode, make sure to switch focus
// if appropriate
if (LockClipping()) {
if (window->IsHidden() != hidden) {
@ -627,14 +603,7 @@ Desktop::_RebuildClippingForAllWindows(BRegion* stillAvailableOnScreen)
// each window on the screen will take a portion from that area
// figure out what the entire screen area is
if (!fDrawView->Window())
stillAvailableOnScreen->Set(fDrawView->Bounds());
else {
if (fDrawView->Window()->Lock()) {
fDrawView->GetClippingRegion(stillAvailableOnScreen);
fDrawView->Window()->Unlock();
}
}
*stillAvailableOnScreen = fMasterClipping;
// set clipping of each window
int32 count = CountWindows();
@ -677,12 +646,6 @@ Desktop::_SetBackground(BRegion* background)
dirtyBackground.IntersectWith(background);
fBackgroundRegion = *background;
if (dirtyBackground.Frame().IsValid()) {
if (fDrawingEngine->Lock()) {
fDrawingEngine->SetHighColor(51, 102, 152);
fDrawingEngine->FillRegion(&dirtyBackground);
fDrawingEngine->MarkDirty(&dirtyBackground);
fDrawingEngine->Unlock();
}
fDrawingEngine->FillRegion(&dirtyBackground, (rgb_color){ 51, 102, 152, 255 });
}
}

View File

@ -7,8 +7,6 @@
#include <View.h>
#include <Window.h>
#include "DrawingEngine.h"
#define SHOW_GLOBAL_DIRTY_REGION 0
#define SHOW_WINDOW_CONTENT_DIRTY_REGION 0
@ -20,6 +18,8 @@
# include <Locker.h>
#endif
class DrawingEngine;
class DrawView;
class WindowLayer;
class ViewLayer;
@ -34,12 +34,11 @@ enum {
class Desktop : public BLooper {
public:
Desktop(DrawView* drawView);
Desktop(DrawView* drawView,
DrawingEngine* engine);
virtual ~Desktop();
// functions for the DrawView
void Draw(BRect updateRect);
void MouseDown(BPoint where, uint32 buttons,
int32 clicks);
void MouseUp(BPoint where);
@ -48,6 +47,9 @@ class Desktop : public BLooper {
virtual void MessageReceived(BMessage* message);
void SetMasterClipping(BRegion* clipping);
void SetOffset(int32 x, int32 y);
bool AddWindow(WindowLayer* window);
bool RemoveWindow(WindowLayer* window);
int32 IndexOf(WindowLayer* window) const;
@ -117,6 +119,10 @@ private:
#endif
BRegion fBackgroundRegion;
BRegion fMasterClipping;
int32 fXOffset;
int32 fYOffset;
DrawView* fDrawView;
DrawingEngine* fDrawingEngine;

View File

@ -1,315 +0,0 @@
#include <stdio.h>
#include <stack.h>
#include <Bitmap.h>
#include <Message.h>
#include <Region.h>
#include <Window.h>
#include "Desktop.h"
#include "DrawingEngine.h"
// constructor
DrawingEngine::DrawingEngine(BRect frame, DrawView* drawView)
: BView(frame, "drawing engine", B_FOLLOW_ALL, B_WILL_DRAW),
fDrawView(drawView)
{
}
// destructor
DrawingEngine::~DrawingEngine()
{
}
// Lock
bool
DrawingEngine::Lock()
{
return Window()->Lock();
}
// Unlock
void
DrawingEngine::Unlock()
{
#if RUN_WITH_FRAME_BUFFER
Sync();
#else
// Flush() takes some time, but we
// need to do that, since we draw
// at any time, outside actual updates
Flush();
#endif
Window()->Unlock();
}
// MarkDirty
void
DrawingEngine::MarkDirty(BRegion* region)
{
#if RUN_WITH_FRAME_BUFFER
BRect frame = region->Frame();
if (frame.IsValid()) {
BMessage message(MSG_INVALIDATE);
message.AddRect("area", frame);
fDrawView->Looper()->PostMessage(&message, fDrawView);
}
#endif
}
// MarkDirty
void
DrawingEngine::MarkDirty(BRect rect)
{
#if RUN_WITH_FRAME_BUFFER
if (rect.IsValid()) {
BMessage message(MSG_INVALIDATE);
message.AddRect("area", rect);
fDrawView->Looper()->PostMessage(&message, fDrawView);
}
#endif
}
// MarkDirty
void
DrawingEngine::MarkDirty()
{
if (Lock()) {
Invalidate();
Unlock();
}
}
struct node {
node()
{
pointers = NULL;
}
node(const BRect& r, int32 maxPointers)
{
init(r, maxPointers);
}
~node()
{
delete [] pointers;
}
void init(const BRect& r, int32 maxPointers)
{
rect = r;
pointers = new node*[maxPointers];
in_degree = 0;
next_pointer = 0;
}
void push(node* node)
{
pointers[next_pointer] = node;
next_pointer++;
}
node* top()
{
return pointers[next_pointer];
}
node* pop()
{
node* ret = top();
next_pointer--;
return ret;
}
BRect rect;
int32 in_degree;
node** pointers;
int32 next_pointer;
};
bool
is_left_of(const BRect& a, const BRect& b)
{
return (a.right < b.left);
}
bool
is_above(const BRect& a, const BRect& b)
{
return (a.bottom < b.top);
}
void
DrawingEngine::CopyRegion(BRegion* region, int32 xOffset, int32 yOffset)
{
int32 count = region->CountRects();
// TODO: make this step unnecessary
// (by using different stack impl inside node)
node nodes[count];
for (int32 i= 0; i < count; i++) {
nodes[i].init(region->RectAt(i), count);
}
for (int32 i = 0; i < count; i++) {
BRect a = region->RectAt(i);
for (int32 k = i + 1; k < count; k++) {
BRect b = region->RectAt(k);
int cmp = 0;
// compare horizontally
if (xOffset > 0) {
if (is_left_of(a, b)) {
cmp -= 1;
} else if (is_left_of(b, a)) {
cmp += 1;
}
} else if (xOffset < 0) {
if (is_left_of(a, b)) {
cmp += 1;
} else if (is_left_of(b, a)) {
cmp -= 1;
}
}
// compare vertically
if (yOffset > 0) {
if (is_above(a, b)) {
cmp -= 1;
} else if (is_above(b, a)) {
cmp += 1;
}
} else if (yOffset < 0) {
if (is_above(a, b)) {
cmp += 1;
} else if (is_above(b, a)) {
cmp -= 1;
}
}
// add appropriate node as successor
if (cmp > 0) {
nodes[i].push(&nodes[k]);
nodes[k].in_degree++;
} else if (cmp < 0) {
nodes[k].push(&nodes[i]);
nodes[i].in_degree++;
}
}
}
// put all nodes onto a stack that have an "indegree" count of zero
stack<node*> inDegreeZeroNodes;
for (int32 i = 0; i < count; i++) {
if (nodes[i].in_degree == 0) {
inDegreeZeroNodes.push(&nodes[i]);
}
}
// pop the rects from the stack, do the actual copy operation
// and decrease the "indegree" count of the other rects not
// currently on the stack and to which the current rect pointed
// to. If their "indegree" count reaches zero, put them onto the
// stack as well.
while (!inDegreeZeroNodes.empty()) {
node* n = inDegreeZeroNodes.top();
inDegreeZeroNodes.pop();
CopyBits(n->rect, BRect(n->rect).OffsetByCopy(xOffset, yOffset));
for (int32 k = 0; k < n->next_pointer; k++) {
n->pointers[k]->in_degree--;
if (n->pointers[k]->in_degree == 0)
inDegreeZeroNodes.push(n->pointers[k]);
}
}
}
// constructor
DrawView::DrawView(BRect frame)
#if RUN_WITH_FRAME_BUFFER
: BView(frame, "desktop", B_FOLLOW_ALL, B_WILL_DRAW),
#else
: DrawingEngine(frame, NULL),
#endif
fDesktop(NULL),
#if RUN_WITH_FRAME_BUFFER
fFrameBuffer(new BBitmap(Bounds(), B_RGB32, true)),
fDrawingEngine(new DrawingEngine(Bounds(), this))
#else
fDrawingEngine(this)
#endif
{
SetViewColor(B_TRANSPARENT_COLOR);
#if RUN_WITH_FRAME_BUFFER
if (fFrameBuffer->Lock()) {
fFrameBuffer->AddChild(fDrawingEngine);
fFrameBuffer->Unlock();
}
#endif
}
// destructor
DrawView::~DrawView()
{
#if RUN_WITH_FRAME_BUFFER
delete fFrameBuffer;
#endif
}
// MessageReceived
void
DrawView::MessageReceived(BMessage* message)
{
switch (message->what) {
case MSG_INVALIDATE: {
BRect area;
if (message->FindRect("area", &area) == B_OK) {
Invalidate(area);
}
break;
}
default:
BView::MessageReceived(message);
}
}
// Draw
void
DrawView::Draw(BRect updateRect)
{
#if RUN_WITH_FRAME_BUFFER
DrawBitmap(fFrameBuffer, updateRect, updateRect);
#else
BMessage message(MSG_DRAW);
message.AddRect("area", updateRect);
fDesktop->PostMessage(&message);
#endif
}
// MouseDown
void
DrawView::MouseDown(BPoint where)
{
SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
fDesktop->PostMessage(Window()->CurrentMessage());
}
// MouseUp
void
DrawView::MouseUp(BPoint where)
{
fDesktop->PostMessage(Window()->CurrentMessage());
}
// MouseMoved
void
DrawView::MouseMoved(BPoint where, uint32 code, const BMessage* dragMessage)
{
fDesktop->PostMessage(Window()->CurrentMessage());
}
// SetDesktop
void
DrawView::SetDesktop(Desktop* desktop)
{
fDesktop = desktop;
}

View File

@ -1,68 +0,0 @@
#ifndef DRAWING_ENGINE_H
#define DRAWING_ENGINE_H
#include <View.h>
class Desktop;
class DrawView;
enum {
MSG_INVALIDATE = 'invl',
};
class DrawingEngine : public BView {
public:
DrawingEngine(BRect frame, DrawView* drawView);
virtual ~DrawingEngine();
bool Lock();
void Unlock();
void CopyRegion(BRegion *region, int32 xOffset, int32 yOffset);
void MarkDirty(BRegion* region);
void MarkDirty(BRect rect);
void MarkDirty();
private:
DrawView* fDrawView;
};
#define RUN_WITH_FRAME_BUFFER 0
#if RUN_WITH_FRAME_BUFFER
class DrawView : public BView {
#else
class DrawView : public DrawingEngine {
#endif
public:
DrawView(BRect frame);
virtual ~DrawView();
virtual void MessageReceived(BMessage* message);
virtual void Draw(BRect updateRect);
virtual void MouseDown(BPoint where);
virtual void MouseUp(BPoint where);
virtual void MouseMoved(BPoint where, uint32 code,
const BMessage* dragMessage);
void SetDesktop(Desktop* desktop);
DrawingEngine* GetDrawingEngine() const
{ return fDrawingEngine; }
private:
Desktop* fDesktop;
#if RUN_WITH_FRAME_BUFFER
BBitmap* fFrameBuffer;
#endif
DrawingEngine* fDrawingEngine;
};
#endif // DRAWING_ENGINE_H

View File

@ -618,14 +618,8 @@ ViewLayer::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping,
// add the current clipping
redraw.IntersectWith(effectiveClipping);
if (drawingEngine->Lock()) {
// fill visible region with white
drawingEngine->SetHighColor(255, 255, 255);
drawingEngine->FillRegion(&redraw);
drawingEngine->MarkDirty(&redraw);
drawingEngine->Unlock();
}
// fill visible region with white
drawingEngine->FillRegion(&redraw, (rgb_color){ 255, 255, 255, 255 });
// let children draw
if (deep) {
@ -644,28 +638,22 @@ ViewLayer::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping,
void
ViewLayer::ClientDraw(DrawingEngine* drawingEngine, BRegion* effectiveClipping)
{
BRect b(Bounds());
b.OffsetTo(0.0, 0.0);
ConvertToTop(&b);
if (drawingEngine->Lock()) {
drawingEngine->ConstrainClipping(effectiveClipping);
// draw a frame with the view color
BRect b(Bounds());
b.OffsetTo(0.0, 0.0);
ConvertToTop(&b);
drawingEngine->PushState();
drawingEngine->ConstrainClippingRegion(effectiveClipping);
drawingEngine->SetHighColor(fViewColor);
// drawingEngine->SetDrawingMode(B_OP_BLEND);
drawingEngine->StrokeRect(b);
drawingEngine->StrokeRect(b, fViewColor);
b.InsetBy(1, 1);
drawingEngine->StrokeRect(b);
drawingEngine->StrokeRect(b, fViewColor);
b.InsetBy(1, 1);
drawingEngine->StrokeRect(b);
drawingEngine->StrokeRect(b, fViewColor);
b.InsetBy(1, 1);
drawingEngine->StrokeLine(b.LeftTop(), b.RightBottom());
drawingEngine->StrokeLine(b.LeftTop(), b.RightBottom(), fViewColor);
drawingEngine->PopState();
drawingEngine->MarkDirty(effectiveClipping);
drawingEngine->Unlock();
}
}

View File

@ -192,7 +192,7 @@ WindowLayer::GetFullRegion(BRegion* region) const
fFrame.right + 4, fFrame.bottom + 4));
// add the title tab
region->Include(BRect(fFrame.left - 4, fFrame.top - 20,
(fFrame.left + fFrame.right) / 2, fFrame.top - 5));
ceilf((fFrame.left + fFrame.right) / 2), fFrame.top - 5));
}
// GetBorderRegion
@ -201,7 +201,7 @@ WindowLayer::GetBorderRegion(BRegion* region)
{
if (!fBorderRegionValid) {
fBorderRegion.Set(BRect(fFrame.left - 4, fFrame.top - 20,
(fFrame.left + fFrame.right) / 2, fFrame.top - 5));
ceilf((fFrame.left + fFrame.right) / 2), fFrame.top - 5));
fBorderRegion.Include(BRect(fFrame.left - 4, fFrame.top - 4,
fFrame.right + 4, fFrame.top - 1));
fBorderRegion.Include(BRect(fFrame.left - 4, fFrame.top,
@ -212,21 +212,6 @@ WindowLayer::GetBorderRegion(BRegion* region)
fFrame.right - 11, fFrame.bottom + 4));
fBorderRegion.Include(BRect(fFrame.right - 10, fFrame.bottom - 10,
fFrame.right + 4, fFrame.bottom + 4));
/* // TODO: speed up by avoiding "Exclude()"
// start from the frame, extend to include decorator border
fBorderRegion.Set(BRect(fFrame.left - 4, fFrame.top - 4,
fFrame.right + 4, fFrame.bottom + 4));
fBorderRegion.Exclude(fFrame);
// add the title tab
fBorderRegion.Include(BRect(fFrame.left - 4, fFrame.top - 20,
(fFrame.left + fFrame.right) / 2, fFrame.top - 5));
// resize handle
// if (B_DOCUMENT_WINDOW_LOOK)
fBorderRegion.Include(BRect(fFrame.right - 10, fFrame.bottom - 10,
fFrame.right, fFrame.bottom));*/
fBorderRegionValid = true;
}
@ -680,25 +665,22 @@ WindowLayer::_DrawClientPolygon(int32 token, BPoint polygon[4])
&fContentRegion, false);
#endif
layer->ConvertToTop(&polygon[0]);
layer->ConvertToTop(&polygon[1]);
layer->ConvertToTop(&polygon[2]);
layer->ConvertToTop(&polygon[3]);
if (fDrawingEngine->Lock()) {
fDrawingEngine->PushState();
fDrawingEngine->ConstrainClippingRegion(&effectiveClipping);
fDrawingEngine->SetPenSize(3);
// fDrawingEngine->SetDrawingMode(B_OP_BLEND);
layer->ConvertToTop(&polygon[0]);
layer->ConvertToTop(&polygon[1]);
layer->ConvertToTop(&polygon[2]);
layer->ConvertToTop(&polygon[3]);
fDrawingEngine->BeginLineArray(4);
fDrawingEngine->AddLine(polygon[0], polygon[1], layer->ViewColor());
fDrawingEngine->AddLine(polygon[1], polygon[2], layer->ViewColor());
fDrawingEngine->AddLine(polygon[2], polygon[3], layer->ViewColor());
fDrawingEngine->AddLine(polygon[3], polygon[0], layer->ViewColor());
fDrawingEngine->EndLineArray();
fDrawingEngine->ConstrainClipping(&effectiveClipping);
// fDrawingEngine->SetPenSize(3);
// fDrawingEngine->SetDrawingMode(B_OP_BLEND);
fDrawingEngine->StrokeLine(polygon[0], polygon[1], layer->ViewColor());
fDrawingEngine->StrokeLine(polygon[1], polygon[2], layer->ViewColor());
fDrawingEngine->StrokeLine(polygon[2], polygon[3], layer->ViewColor());
fDrawingEngine->StrokeLine(polygon[3], polygon[0], layer->ViewColor());
fDrawingEngine->PopState();
fDrawingEngine->MarkDirty(&effectiveClipping);
fDrawingEngine->Unlock();
}
}
@ -728,57 +710,59 @@ WindowLayer::_DrawBorder()
dirtyBorderRegion.IntersectWith(&fDirtyRegion);
if (dirtyBorderRegion.CountRects() > 0) {
rgb_color lowColor;
rgb_color highColor;
if (fFocus) {
lowColor = (rgb_color){ 255, 203, 0, 255 };
highColor = (rgb_color){ 0, 0, 0, 255 };
} else {
lowColor = (rgb_color){ 216, 216, 216, 0 };
highColor = (rgb_color){ 30, 30, 30, 255 };
}
fDrawingEngine->FillRegion(&dirtyBorderRegion, lowColor);
rgb_color light = tint_color(lowColor, B_LIGHTEN_2_TINT);
rgb_color shadow = tint_color(lowColor, B_DARKEN_2_TINT);
if (fDrawingEngine->Lock()) {
fDrawingEngine->ConstrainClippingRegion(&dirtyBorderRegion);
fDrawingEngine->ConstrainClipping(&dirtyBorderRegion);
if (fFocus) {
fDrawingEngine->SetLowColor(255, 203, 0, 255);
fDrawingEngine->SetHighColor(0, 0, 0, 255);
} else {
fDrawingEngine->SetLowColor(216, 216, 216, 0);
fDrawingEngine->SetHighColor(30, 30, 30, 255);
}
rgb_color light = tint_color(fDrawingEngine->LowColor(), B_LIGHTEN_2_TINT);
rgb_color shadow = tint_color(fDrawingEngine->LowColor(), B_DARKEN_2_TINT);
fDrawingEngine->FillRect(dirtyBorderRegion.Frame(), B_SOLID_LOW);
fDrawingEngine->DrawString(Name(), BPoint(fFrame.left, fFrame.top - 5));
fDrawingEngine->DrawString(Name(), BPoint(fFrame.left, fFrame.top - 5), highColor);
BRect frame(fFrame);
fDrawingEngine->BeginLineArray(12);
frame.InsetBy(-1, -1);
fDrawingEngine->AddLine(BPoint(frame.left, frame.bottom),
BPoint(frame.left, frame.top), shadow);
fDrawingEngine->AddLine(BPoint(frame.left + 1, frame.top),
BPoint(frame.right, frame.top), shadow);
fDrawingEngine->AddLine(BPoint(frame.right, frame.top + 1),
BPoint(frame.right, frame.bottom - 11), light);
fDrawingEngine->AddLine(BPoint(frame.right - 1, frame.bottom - 11),
BPoint(frame.right - 11, frame.bottom - 11), light);
fDrawingEngine->AddLine(BPoint(frame.right - 11, frame.bottom - 10),
BPoint(frame.right - 11, frame.bottom), light);
fDrawingEngine->AddLine(BPoint(frame.right - 12, frame.bottom),
BPoint(frame.left + 1, frame.bottom), light);
fDrawingEngine->StrokeLine(BPoint(frame.left, frame.bottom),
BPoint(frame.left, frame.top), shadow);
fDrawingEngine->StrokeLine(BPoint(frame.left + 1, frame.top),
BPoint(frame.right, frame.top), shadow);
fDrawingEngine->StrokeLine(BPoint(frame.right, frame.top + 1),
BPoint(frame.right, frame.bottom - 11), light);
fDrawingEngine->StrokeLine(BPoint(frame.right - 1, frame.bottom - 11),
BPoint(frame.right - 11, frame.bottom - 11), light);
fDrawingEngine->StrokeLine(BPoint(frame.right - 11, frame.bottom - 10),
BPoint(frame.right - 11, frame.bottom), light);
fDrawingEngine->StrokeLine(BPoint(frame.right - 12, frame.bottom),
BPoint(frame.left + 1, frame.bottom), light);
frame.InsetBy(-3, -3);
fDrawingEngine->AddLine(BPoint(frame.left, frame.bottom),
BPoint(frame.left, frame.top - 16), light);
fDrawingEngine->AddLine(BPoint(frame.left + 1, frame.top - 16),
BPoint((frame.left + frame.right) / 2, frame.top - 16), light);
fDrawingEngine->AddLine(BPoint((frame.left + frame.right) / 2, frame.top - 15),
BPoint((frame.left + frame.right) / 2, frame.top), shadow);
fDrawingEngine->AddLine(BPoint((frame.left + frame.right) / 2 + 1, frame.top),
BPoint(frame.left + frame.right, frame.top), light);
fDrawingEngine->AddLine(BPoint(frame.right, frame.top + 1),
BPoint(frame.right, frame.bottom), shadow);
fDrawingEngine->AddLine(BPoint(frame.right, frame.bottom),
BPoint(frame.left + 1, frame.bottom), shadow);
fDrawingEngine->EndLineArray();
int32 tabRight = ceilf((fFrame.left + fFrame.right) / 2);
fDrawingEngine->StrokeLine(BPoint(frame.left, frame.bottom),
BPoint(frame.left, frame.top - 16), light);
fDrawingEngine->StrokeLine(BPoint(frame.left + 1, frame.top - 16),
BPoint(tabRight, frame.top - 16), light);
fDrawingEngine->StrokeLine(BPoint(tabRight, frame.top - 15),
BPoint(tabRight, frame.top), shadow);
fDrawingEngine->StrokeLine(BPoint(tabRight + 1, frame.top),
BPoint(frame.right, frame.top), light);
fDrawingEngine->StrokeLine(BPoint(frame.right, frame.top + 1),
BPoint(frame.right, frame.bottom), shadow);
fDrawingEngine->StrokeLine(BPoint(frame.right, frame.bottom),
BPoint(frame.left + 1, frame.bottom), shadow);
fDrawingEngine->ConstrainClippingRegion(NULL);
fDrawingEngine->MarkDirty(&dirtyBorderRegion);
fDrawingEngine->ConstrainClipping(NULL);
fDrawingEngine->Unlock();
}
}

View File

@ -0,0 +1,890 @@
/*
* Copyright 2001-2005, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Lotz <mmlr@mlotz.ch>
* DarkWyrm <bpmagic@columbus.rr.com>
* Stephan Aßmus <superstippi@gmx.de>
*/
/** Accelerant based HWInterface implementation */
#include <new>
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include <Cursor.h>
#include <graphic_driver.h>
#include <FindDirectory.h>
#include <image.h>
#include <dirent.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include "AccelerantHWInterface.h"
//#include "AccelerantBuffer.h"
//#include "MallocBuffer.h"
using std::nothrow;
#define DEBUG_DRIVER_MODULE
#ifdef DEBUG_DRIVER_MODULE
# include <stdio.h>
# define ATRACE(x) printf x
#else
# define ATRACE(x) ;
#endif
// constructor
AccelerantHWInterface::AccelerantHWInterface()
: //HWInterface(),
fCardFD(-1),
fAccelerantImage(-1),
fAccelerantHook(NULL),
fEngineToken(NULL),
fSyncToken(),
// required hooks
fAccAcquireEngine(NULL),
fAccReleaseEngine(NULL),
fAccSyncToToken(NULL),
fAccGetModeCount(NULL),
fAccGetModeList(NULL),
fAccGetFrameBufferConfig(NULL),
fAccSetDisplayMode(NULL),
fAccGetDisplayMode(NULL),
fAccGetPixelClockLimits(NULL),
// optional accelerant hooks
fAccGetTimingConstraints(NULL),
fAccProposeDisplayMode(NULL),
fAccFillRect(NULL),
fAccInvertRect(NULL),
fAccScreenBlit(NULL),
fAccSetCursorShape(NULL),
fAccMoveCursor(NULL),
fAccShowCursor(NULL)//,
// dpms hooks
/* fAccDPMSCapabilities(NULL),
fAccDPMSMode(NULL),
fAccSetDPMSMode(NULL),
fModeCount(0),
fModeList(NULL),*/
// fBackBuffer(NULL),
// fFrontBuffer(new(nothrow) AccelerantBuffer())
{
/* fDisplayMode.virtual_width = 640;
fDisplayMode.virtual_height = 480;
fDisplayMode.space = B_RGB32;*/
// NOTE: I have no clue what I'm doing here.
// fSyncToken.counter = 0;
// fSyncToken.engine_id = 0;
memset(&fSyncToken, 0, sizeof(sync_token));
}
// destructor
AccelerantHWInterface::~AccelerantHWInterface()
{
// delete fBackBuffer;
// delete fFrontBuffer;
// delete[] fModeList;
}
/*!
\brief Opens the first available graphics device and initializes it
\return B_OK on success or an appropriate error message on failure.
*/
status_t
AccelerantHWInterface::Initialize()
{
status_t ret = B_OK;//HWInterface::Initialize();
if (ret >= B_OK) {
for (int32 i = 1; fCardFD != B_ENTRY_NOT_FOUND; i++) {
fCardFD = _OpenGraphicsDevice(i);
if (fCardFD < 0) {
ATRACE(("Failed to open graphics device\n"));
continue;
}
if (_OpenAccelerant(fCardFD) == B_OK)
break;
close(fCardFD);
// _OpenAccelerant() failed, try to open next graphics card
}
return fCardFD >= 0 ? B_OK : fCardFD;
}
return ret;
}
/*!
\brief Opens a graphics device for read-write access
\param deviceNumber Number identifying which graphics card to open (1 for first card)
\return The file descriptor for the opened graphics device
The deviceNumber is relative to the number of graphics devices that can be successfully
opened. One represents the first card that can be successfully opened (not necessarily
the first one listed in the directory).
Graphics drivers must be able to be opened more than once, so we really get
the first working entry.
*/
int
AccelerantHWInterface::_OpenGraphicsDevice(int deviceNumber)
{
DIR *directory = opendir("/dev/graphics");
if (!directory)
return -1;
// ToDo: the former R5 "stub" driver is called "vesa" under Haiku; however,
// we do not need to avoid this driver this way when is has been ported
// to the new driver architecture - the special case here can then be
// removed.
int count = 0;
struct dirent *entry;
int current_card_fd = -1;
char path[PATH_MAX];
while (count < deviceNumber && (entry = readdir(directory)) != NULL) {
if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..") ||
!strcmp(entry->d_name, "stub") || !strcmp(entry->d_name, "vesa"))
continue;
if (current_card_fd >= 0) {
close(current_card_fd);
current_card_fd = -1;
}
sprintf(path, "/dev/graphics/%s", entry->d_name);
current_card_fd = open(path, B_READ_WRITE);
if (current_card_fd >= 0)
count++;
}
// Open VESA driver if we were not able to get a better one
if (count < deviceNumber) {
if (deviceNumber == 1) {
sprintf(path, "/dev/graphics/vesa");
current_card_fd = open(path, B_READ_WRITE);
} else {
close(current_card_fd);
current_card_fd = B_ENTRY_NOT_FOUND;
}
}
fCardNameInDevFS = entry->d_name;
return current_card_fd;
}
status_t
AccelerantHWInterface::_OpenAccelerant(int device)
{
char signature[1024];
if (ioctl(device, B_GET_ACCELERANT_SIGNATURE,
&signature, sizeof(signature)) != B_OK)
return B_ERROR;
ATRACE(("accelerant signature is: %s\n", signature));
struct stat accelerant_stat;
const static directory_which dirs[] = {
B_USER_ADDONS_DIRECTORY,
B_COMMON_ADDONS_DIRECTORY,
B_BEOS_ADDONS_DIRECTORY
};
fAccelerantImage = -1;
for (int32 i = 0; i < 3; i++) {
char path[PATH_MAX];
if (find_directory(dirs[i], -1, false, path, PATH_MAX) != B_OK)
continue;
strcat(path, "/accelerants/");
strcat(path, signature);
if (stat(path, &accelerant_stat) != 0)
continue;
fAccelerantImage = load_add_on(path);
if (fAccelerantImage >= 0) {
if (get_image_symbol(fAccelerantImage, B_ACCELERANT_ENTRY_POINT,
B_SYMBOL_TYPE_ANY, (void**)(&fAccelerantHook)) != B_OK ) {
ATRACE(("unable to get B_ACCELERANT_ENTRY_POINT\n"));
unload_add_on(fAccelerantImage);
fAccelerantImage = -1;
return B_ERROR;
}
accelerant_clone_info_size cloneInfoSize;
cloneInfoSize = (accelerant_clone_info_size)fAccelerantHook(B_ACCELERANT_CLONE_INFO_SIZE, NULL);
if (!cloneInfoSize) {
ATRACE(("unable to get B_ACCELERANT_CLONE_INFO_SIZE (%s)\n", path));
unload_add_on(fAccelerantImage);
fAccelerantImage = -1;
return B_ERROR;
}
ssize_t cloneSize = cloneInfoSize();
void* cloneInfoData = malloc(cloneSize);
// get_accelerant_clone_info getCloneInfo;
// getCloneInfo = (get_accelerant_clone_info)fAccelerantHook(B_GET_ACCELERANT_CLONE_INFO, NULL);
// if (!getCloneInfo) {
// ATRACE(("unable to get B_GET_ACCELERANT_CLONE_INFO (%s)\n", path));
// unload_add_on(fAccelerantImage);
// fAccelerantImage = -1;
// return B_ERROR;
// }
// printf("getCloneInfo: %p\n", getCloneInfo);
//
// getCloneInfo(cloneInfoData);
// TODO: this is what works for the ATI Radeon driver...
sprintf((char*)cloneInfoData, "graphics/%s", fCardNameInDevFS.String());
clone_accelerant cloneAccelerant;
cloneAccelerant = (clone_accelerant)fAccelerantHook(B_CLONE_ACCELERANT, NULL);
if (!cloneAccelerant) {
ATRACE(("unable to get B_CLONE_ACCELERANT\n"));
unload_add_on(fAccelerantImage);
fAccelerantImage = -1;
return B_ERROR;
}
status_t ret = cloneAccelerant(cloneInfoData);
if (ret != B_OK) {
ATRACE(("Cloning accelerant unsuccessful: %s\n", strerror(ret)));
unload_add_on(fAccelerantImage);
fAccelerantImage = -1;
return B_ERROR;
}
break;
}
}
if (fAccelerantImage < B_OK)
return B_ERROR;
if (_SetupDefaultHooks() != B_OK) {
ATRACE(("cannot setup default hooks\n"));
uninit_accelerant uninitAccelerant = (uninit_accelerant)
fAccelerantHook(B_UNINIT_ACCELERANT, NULL);
if (uninitAccelerant != NULL)
uninitAccelerant();
unload_add_on(fAccelerantImage);
return B_ERROR;
}
return B_OK;
}
status_t
AccelerantHWInterface::_SetupDefaultHooks()
{
// required
fAccAcquireEngine = (acquire_engine)fAccelerantHook(B_ACQUIRE_ENGINE, NULL);
fAccReleaseEngine = (release_engine)fAccelerantHook(B_RELEASE_ENGINE, NULL);
fAccSyncToToken = (sync_to_token)fAccelerantHook(B_SYNC_TO_TOKEN, NULL);
fAccGetModeCount = (accelerant_mode_count)fAccelerantHook(B_ACCELERANT_MODE_COUNT, NULL);
fAccGetModeList = (get_mode_list)fAccelerantHook(B_GET_MODE_LIST, NULL);
fAccGetFrameBufferConfig = (get_frame_buffer_config)fAccelerantHook(B_GET_FRAME_BUFFER_CONFIG, NULL);
fAccSetDisplayMode = (set_display_mode)fAccelerantHook(B_SET_DISPLAY_MODE, NULL);
fAccGetDisplayMode = (get_display_mode)fAccelerantHook(B_GET_DISPLAY_MODE, NULL);
fAccGetPixelClockLimits = (get_pixel_clock_limits)fAccelerantHook(B_GET_PIXEL_CLOCK_LIMITS, NULL);
if (!fAccAcquireEngine || !fAccReleaseEngine || !fAccGetFrameBufferConfig
|| !fAccGetModeCount || !fAccGetModeList || !fAccSetDisplayMode
|| !fAccGetDisplayMode || !fAccGetPixelClockLimits) {
return B_ERROR;
}
// optional
fAccGetTimingConstraints = (get_timing_constraints)fAccelerantHook(B_GET_TIMING_CONSTRAINTS, NULL);
fAccProposeDisplayMode = (propose_display_mode)fAccelerantHook(B_PROPOSE_DISPLAY_MODE, NULL);
// cursor
fAccSetCursorShape = (set_cursor_shape)fAccelerantHook(B_SET_CURSOR_SHAPE, NULL);
fAccMoveCursor = (move_cursor)fAccelerantHook(B_MOVE_CURSOR, NULL);
fAccShowCursor = (show_cursor)fAccelerantHook(B_SHOW_CURSOR, NULL);
// dpms
// fAccDPMSCapabilities = (dpms_capabilities)fAccelerantHook(B_DPMS_CAPABILITIES, NULL);
// fAccDPMSMode = (dpms_mode)fAccelerantHook(B_DPMS_MODE, NULL);
// fAccSetDPMSMode = (set_dpms_mode)fAccelerantHook(B_SET_DPMS_MODE, NULL);
// update acceleration hooks
// TODO: would actually have to pass a valid display_mode!
fAccFillRect = (fill_rectangle)fAccelerantHook(B_FILL_RECTANGLE, NULL);
fAccInvertRect = (invert_rectangle)fAccelerantHook(B_INVERT_RECTANGLE, NULL);
fAccScreenBlit = (screen_to_screen_blit)fAccelerantHook(B_SCREEN_TO_SCREEN_BLIT, NULL);
return B_OK;
}
// Shutdown
status_t
AccelerantHWInterface::Shutdown()
{
if (fAccelerantHook) {
uninit_accelerant UninitAccelerant = (uninit_accelerant)fAccelerantHook(B_UNINIT_ACCELERANT, NULL);
if (UninitAccelerant)
UninitAccelerant();
}
if (fAccelerantImage >= 0)
unload_add_on(fAccelerantImage);
if (fCardFD >= 0)
close(fCardFD);
return B_OK;
}
/*
// SetMode
status_t
AccelerantHWInterface::SetMode(const display_mode &mode)
{
AutoWriteLocker _(this);
// TODO: There are places this function can fail,
// maybe it needs to roll back changes in case of an
// error.
// prevent from doing the unnecessary
if (fModeCount > 0 && fBackBuffer && fFrontBuffer
&& fDisplayMode == mode) {
// TODO: better comparison of display modes
return B_OK;
}
// just try to set the mode - we let the graphics driver
// approve or deny the request, as it should know best
fDisplayMode = mode;
if (fAccSetDisplayMode(&fDisplayMode) != B_OK) {
ATRACE(("setting display mode failed\n"));
fAccGetDisplayMode(&fDisplayMode);
// We just keep the current mode and continue.
// Note, on startup, this may be different from
// what we think is the current display mode
}
// update frontbuffer
fFrontBuffer->SetDisplayMode(fDisplayMode);
if (_UpdateFrameBufferConfig() != B_OK)
return B_ERROR;
// Update the frame buffer used by the on-screen KDL
#ifdef __HAIKU__
uint32 depth = (fFrameBufferConfig.bytes_per_row / fDisplayMode.virtual_width) << 3;
if (fDisplayMode.space == B_RGB15)
depth = 15;
_kern_frame_buffer_update(fFrameBufferConfig.frame_buffer,
fDisplayMode.virtual_width, fDisplayMode.virtual_height,
depth, fFrameBufferConfig.bytes_per_row);
#endif
// update backbuffer if neccessary
if (!fBackBuffer || fBackBuffer->Width() != fDisplayMode.virtual_width
|| fBackBuffer->Height() != fDisplayMode.virtual_height) {
// NOTE: backbuffer is always B_RGBA32, this simplifies the
// drawing backend implementation tremendously for the time
// being. The color space conversion is handled in CopyBackToFront()
delete fBackBuffer;
fBackBuffer = NULL;
// TODO: Above not true anymore for single buffered mode!!!
// -> fall back to double buffer for fDisplayMode.space != B_RGB32
// as intermediate solution...
bool doubleBuffered = HWInterface::IsDoubleBuffered();
if ((color_space)fDisplayMode.space != B_RGB32 &&
(color_space)fDisplayMode.space != B_RGBA32)
doubleBuffered = true;
if (doubleBuffered) {
fBackBuffer = new(nothrow) MallocBuffer(fDisplayMode.virtual_width,
fDisplayMode.virtual_height);
status_t ret = fBackBuffer ? fBackBuffer->InitCheck() : B_NO_MEMORY;
if (ret < B_OK) {
delete fBackBuffer;
fBackBuffer = NULL;
return ret;
}
// clear out backbuffer, alpha is 255 this way
memset(fBackBuffer->Bits(), 255, fBackBuffer->BitsLength());
}
}
// update acceleration hooks
fAccFillRect = (fill_rectangle)fAccelerantHook(B_FILL_RECTANGLE, (void *)&fDisplayMode);
fAccInvertRect = (invert_rectangle)fAccelerantHook(B_INVERT_RECTANGLE,
(void *)&fDisplayMode);
fAccScreenBlit = (screen_to_screen_blit)fAccelerantHook(B_SCREEN_TO_SCREEN_BLIT,
(void *)&fDisplayMode);
return B_OK;
}
void
AccelerantHWInterface::GetMode(display_mode *mode)
{
if (mode && ReadLock()) {
*mode = fDisplayMode;
ReadUnlock();
}
}
status_t
AccelerantHWInterface::_UpdateModeList()
{
fModeCount = fAccGetModeCount();
if (fModeCount <= 0)
return B_ERROR;
delete[] fModeList;
fModeList = new(nothrow) display_mode[fModeCount];
if (!fModeList)
return B_NO_MEMORY;
if (fAccGetModeList(fModeList) != B_OK) {
ATRACE(("unable to get mode list\n"));
return B_ERROR;
}
return B_OK;
}
status_t
AccelerantHWInterface::_UpdateFrameBufferConfig()
{
if (fAccGetFrameBufferConfig(&fFrameBufferConfig) != B_OK) {
ATRACE(("unable to get frame buffer config\n"));
return B_ERROR;
}
fFrontBuffer->SetFrameBufferConfig(fFrameBufferConfig);
return B_OK;
}
status_t
AccelerantHWInterface::GetDeviceInfo(accelerant_device_info *info)
{
get_accelerant_device_info GetAccelerantDeviceInfo = (get_accelerant_device_info)fAccelerantHook(B_GET_ACCELERANT_DEVICE_INFO, NULL);
if (!GetAccelerantDeviceInfo) {
ATRACE(("No B_GET_ACCELERANT_DEVICE_INFO hook found\n"));
return B_UNSUPPORTED;
}
return GetAccelerantDeviceInfo(info);
}
status_t
AccelerantHWInterface::GetFrameBufferConfig(frame_buffer_config& config)
{
config = fFrameBufferConfig;
return B_OK;
}
status_t
AccelerantHWInterface::GetModeList(display_mode** modes, uint32 *count)
{
AutoReadLocker _(this);
if (!count || !modes)
return B_BAD_VALUE;
status_t ret = fModeList ? B_OK : _UpdateModeList();
if (ret >= B_OK) {
*modes = new(nothrow) display_mode[fModeCount];
if (*modes) {
*count = fModeCount;
memcpy(*modes, fModeList, sizeof(display_mode) * fModeCount);
} else {
*count = 0;
ret = B_NO_MEMORY;
}
}
return ret;
}
status_t
AccelerantHWInterface::GetPixelClockLimits(display_mode *mode, uint32 *low, uint32 *high)
{
AutoReadLocker _(this);
if (!mode || !low || !high)
return B_BAD_VALUE;
return fAccGetPixelClockLimits(mode, low, high);
}
status_t
AccelerantHWInterface::GetTimingConstraints(display_timing_constraints *dtc)
{
AutoReadLocker _(this);
if (!dtc)
return B_BAD_VALUE;
if (fAccGetTimingConstraints)
return fAccGetTimingConstraints(dtc);
return B_UNSUPPORTED;
}
status_t
AccelerantHWInterface::ProposeMode(display_mode *candidate, const display_mode *low, const display_mode *high)
{
AutoReadLocker _(this);
if (!candidate || !low || !high)
return B_BAD_VALUE;
if (!fAccProposeDisplayMode)
return B_UNSUPPORTED;
// avoid const issues
display_mode this_high, this_low;
this_high = *high;
this_low = *low;
return fAccProposeDisplayMode(candidate, &this_low, &this_high);
}
// RetraceSemaphore
sem_id
AccelerantHWInterface::RetraceSemaphore()
{
accelerant_retrace_semaphore AccelerantRetraceSemaphore = (accelerant_retrace_semaphore)fAccelerantHook(B_ACCELERANT_RETRACE_SEMAPHORE, NULL);
if (!AccelerantRetraceSemaphore)
return B_UNSUPPORTED;
return AccelerantRetraceSemaphore();
}
// WaitForRetrace
status_t
AccelerantHWInterface::WaitForRetrace(bigtime_t timeout)
{
AutoReadLocker _(this);
accelerant_retrace_semaphore AccelerantRetraceSemaphore = (accelerant_retrace_semaphore)fAccelerantHook(B_ACCELERANT_RETRACE_SEMAPHORE, NULL);
if (!AccelerantRetraceSemaphore)
return B_UNSUPPORTED;
sem_id sem = AccelerantRetraceSemaphore();
if (sem < 0)
return B_ERROR;
return acquire_sem_etc(sem, 1, B_RELATIVE_TIMEOUT, timeout);
}
// SetDPMSMode
status_t
AccelerantHWInterface::SetDPMSMode(const uint32 &state)
{
AutoWriteLocker _(this);
if (!fAccSetDPMSMode)
return B_UNSUPPORTED;
return fAccSetDPMSMode(state);
}
// DPMSMode
uint32
AccelerantHWInterface::DPMSMode()
{
AutoReadLocker _(this);
if (!fAccDPMSMode)
return B_UNSUPPORTED;
return fAccDPMSMode();
}
// DPMSCapabilities
uint32
AccelerantHWInterface::DPMSCapabilities()
{
AutoReadLocker _(this);
if (!fAccDPMSCapabilities)
return B_UNSUPPORTED;
return fAccDPMSCapabilities();
}
*/
// AvailableHardwareAcceleration
uint32
AccelerantHWInterface::AvailableHWAcceleration() const
{
uint32 flags = 0;
/* if (!IsDoubleBuffered()) {
if (fAccScreenBlit)
flags |= HW_ACC_COPY_REGION;
if (fAccFillRect)
flags |= HW_ACC_FILL_REGION;
if (fAccInvertRect)
flags |= HW_ACC_INVERT_REGION;
}*/
return flags;
}
// CopyRegion
void
AccelerantHWInterface::CopyRegion(const clipping_rect* sortedRectList,
uint32 count, int32 xOffset, int32 yOffset)
{
if (fAccScreenBlit && fAccAcquireEngine) {
if (fAccAcquireEngine(B_2D_ACCELERATION, 0xff, &fSyncToken, &fEngineToken) >= B_OK) {
// convert the rects
blit_params* params = new blit_params[count];
for (uint32 i = 0; i < count; i++) {
params[i].src_left = (uint16)sortedRectList[i].left;
params[i].src_top = (uint16)sortedRectList[i].top;
params[i].dest_left = (uint16)sortedRectList[i].left + xOffset;
params[i].dest_top = (uint16)sortedRectList[i].top + yOffset;
// NOTE: width and height are expressed as distance, not pixel count!
params[i].width = (uint16)(sortedRectList[i].right - sortedRectList[i].left);
params[i].height = (uint16)(sortedRectList[i].bottom - sortedRectList[i].top);
}
// go
fAccScreenBlit(fEngineToken, params, count);
// done
if (fAccReleaseEngine)
fAccReleaseEngine(fEngineToken, &fSyncToken);
// sync
if (fAccSyncToToken)
fAccSyncToToken(&fSyncToken);
delete[] params;
}
}
}
// FillRegion
void
AccelerantHWInterface::FillRegion(/*const*/ BRegion& region, const rgb_color& color)
{
if (fAccFillRect && fAccAcquireEngine) {
if (fAccAcquireEngine(B_2D_ACCELERATION, 0xff, &fSyncToken, &fEngineToken) >= B_OK) {
// convert the region
uint32 count;
fill_rect_params* fillParams;
_RegionToRectParams(&region, &fillParams, &count);
// go
fAccFillRect(fEngineToken, _NativeColor(color), fillParams, count);
// done
if (fAccReleaseEngine)
fAccReleaseEngine(fEngineToken, &fSyncToken);
// sync
if (fAccSyncToToken)
fAccSyncToToken(&fSyncToken);
delete[] fillParams;
}
}
}
// InvertRegion
void
AccelerantHWInterface::InvertRegion(/*const*/ BRegion& region)
{
if (fAccInvertRect && fAccAcquireEngine) {
if (fAccAcquireEngine(B_2D_ACCELERATION, 0xff, &fSyncToken, &fEngineToken) >= B_OK) {
// convert the region
uint32 count;
fill_rect_params* fillParams;
_RegionToRectParams(&region, &fillParams, &count);
// go
fAccInvertRect(fEngineToken, fillParams, count);
// done
if (fAccReleaseEngine)
fAccReleaseEngine(fEngineToken, &fSyncToken);
// sync
if (fAccSyncToToken)
fAccSyncToToken(&fSyncToken);
delete[] fillParams;
} else {
fprintf(stderr, "AcquireEngine failed!\n");
}
} else {
fprintf(stderr, "AccelerantHWInterface::InvertRegion() called, but hook not available!\n");
}
}
/*
// SetCursor
void
AccelerantHWInterface::SetCursor(ServerCursor* cursor)
{
HWInterface::SetCursor(cursor);
// if (WriteLock()) {
// TODO: implement setting the hard ware cursor
// NOTE: cursor should be always B_RGBA32
// NOTE: The HWInterface implementation should
// still be called, since it takes ownership of
// the cursor.
// WriteUnlock();
// }
}
// SetCursorVisible
void
AccelerantHWInterface::SetCursorVisible(bool visible)
{
HWInterface::SetCursorVisible(visible);
// if (WriteLock()) {
// TODO: update graphics hardware
// WriteUnlock();
// }
}
// MoveCursorTo
void
AccelerantHWInterface::MoveCursorTo(const float& x, const float& y)
{
HWInterface::MoveCursorTo(x, y);
// if (WriteLock()) {
// TODO: update graphics hardware
// WriteUnlock();
// }
}
// FrontBuffer
RenderingBuffer *
AccelerantHWInterface::FrontBuffer() const
{
if (!fModeList)
return NULL;
return fFrontBuffer;
}
// BackBuffer
RenderingBuffer *
AccelerantHWInterface::BackBuffer() const
{
if (!fModeList)
return NULL;
return fBackBuffer;
}
// IsDoubleBuffered
bool
AccelerantHWInterface::IsDoubleBuffered() const
{
if (fModeList)
return fBackBuffer != NULL;
return HWInterface::IsDoubleBuffered();
}
// _DrawCursor
void
AccelerantHWInterface::_DrawCursor(BRect area) const
{
// use the default implementation for now,
// until we have a hardware cursor
HWInterface::_DrawCursor(area);
// TODO: this would only be called, if we don't have
// a hardware cursor for some reason
}
*/
// _RegionToRectParams
void
AccelerantHWInterface::_RegionToRectParams(/*const*/ BRegion* region,
fill_rect_params** params,
uint32* count) const
{
*count = region->CountRects();
*params = new fill_rect_params[*count];
for (uint32 i = 0; i < *count; i++) {
clipping_rect r = region->RectAtInt(i);
(*params)[i].left = (uint16)r.left;
(*params)[i].top = (uint16)r.top;
(*params)[i].right = (uint16)r.right;
(*params)[i].bottom = (uint16)r.bottom;
}
}
// _NativeColor
uint32
AccelerantHWInterface::_NativeColor(const rgb_color& c) const
{
// NOTE: This functions looks somehow suspicios to me.
// It assumes that all graphics cards have the same native endianess, no?
/* switch (fDisplayMode.space) {
case B_CMAP8:
case B_GRAY8:
return color.GetColor8();
case B_RGB15_BIG:
case B_RGBA15_BIG:
case B_RGB15_LITTLE:
case B_RGBA15_LITTLE:
return color.GetColor15();
case B_RGB16_BIG:
case B_RGB16_LITTLE:
return color.GetColor16();
case B_RGB32_BIG:
case B_RGBA32_BIG:
case B_RGB32_LITTLE:
case B_RGBA32_LITTLE: {
rgb_color c = color.GetColor32();
uint32 native = (c.alpha << 24) |
(c.red << 16) |
(c.green << 8) |
(c.blue);
return native;
}
}
return 0;*/
uint32 native = (c.alpha << 24) | (c.red << 16) | (c.green << 8) | (c.blue);
return native;
}

View File

@ -0,0 +1,134 @@
/*
* Copyright 2005, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Lotz <mmlr@mlotz.ch>
* Stephan Aßmus <superstippi@gmx.de>
*/
#ifndef ACCELERANT_HW_INTERFACE_H
#define ACCELERANT_HW_INTERFACE_H
#include <image.h>
#include <Accelerant.h>
#include <Locker.h>
#include <Region.h>
#include <String.h>
//class MallocBuffer;
//class AccelerantBuffer;
class AccelerantHWInterface : public BLocker/* : public HWInterface*/ {
public:
AccelerantHWInterface();
virtual ~AccelerantHWInterface();
virtual status_t Initialize();
virtual status_t Shutdown();
/* virtual status_t SetMode(const display_mode &mode);
virtual void GetMode(display_mode *mode);
virtual status_t GetDeviceInfo(accelerant_device_info *info);
virtual status_t GetFrameBufferConfig(frame_buffer_config& config);
virtual status_t GetModeList(display_mode **mode_list,
uint32 *count);
virtual status_t GetPixelClockLimits(display_mode *mode,
uint32 *low, uint32 *high);
virtual status_t GetTimingConstraints(display_timing_constraints *dtc);
virtual status_t ProposeMode(display_mode *candidate,
const display_mode *low,
const display_mode *high);
virtual sem_id RetraceSemaphore();
virtual status_t WaitForRetrace(bigtime_t timeout = B_INFINITE_TIMEOUT);
virtual status_t SetDPMSMode(const uint32 &state);
virtual uint32 DPMSMode();
virtual uint32 DPMSCapabilities();*/
// query for available hardware accleration and perform it
virtual uint32 AvailableHWAcceleration() const;
virtual void CopyRegion(const clipping_rect* sortedRectList,
uint32 count,
int32 xOffset, int32 yOffset);
virtual void FillRegion(/*const*/ BRegion& region,
const rgb_color& color);
virtual void InvertRegion(/*const*/ BRegion& region);
// cursor handling
/*virtual void SetCursor(ServerCursor* cursor);
virtual void SetCursorVisible(bool visible);
virtual void MoveCursorTo(const float& x,
const float& y);*/
// frame buffer access
//virtual RenderingBuffer* FrontBuffer() const;
//virtual RenderingBuffer* BackBuffer() const;
//virtual bool IsDoubleBuffered() const;
protected:
//virtual void _DrawCursor(BRect area) const;
private:
int _OpenGraphicsDevice(int deviceNumber);
status_t _OpenAccelerant(int device);
status_t _SetupDefaultHooks();
status_t _UpdateModeList();
status_t _UpdateFrameBufferConfig();
void _RegionToRectParams(/*const*/ BRegion* region,
fill_rect_params** params,
uint32* count) const;
uint32 _NativeColor(const rgb_color& color) const;
int fCardFD;
image_id fAccelerantImage;
GetAccelerantHook fAccelerantHook;
engine_token *fEngineToken;
sync_token fSyncToken;
// required hooks - guaranteed to be valid
acquire_engine fAccAcquireEngine;
release_engine fAccReleaseEngine;
sync_to_token fAccSyncToToken;
accelerant_mode_count fAccGetModeCount;
get_mode_list fAccGetModeList;
get_frame_buffer_config fAccGetFrameBufferConfig;
set_display_mode fAccSetDisplayMode;
get_display_mode fAccGetDisplayMode;
get_pixel_clock_limits fAccGetPixelClockLimits;
// optional accelerant hooks
get_timing_constraints fAccGetTimingConstraints;
propose_display_mode fAccProposeDisplayMode;
fill_rectangle fAccFillRect;
invert_rectangle fAccInvertRect;
screen_to_screen_blit fAccScreenBlit;
set_cursor_shape fAccSetCursorShape;
move_cursor fAccMoveCursor;
show_cursor fAccShowCursor;
BString fCardNameInDevFS;
// dpms hooks
/* dpms_capabilities fAccDPMSCapabilities;
dpms_mode fAccDPMSMode;
set_dpms_mode fAccSetDPMSMode;
frame_buffer_config fFrameBufferConfig;
int fModeCount;
display_mode *fModeList;*/
// MallocBuffer *fBackBuffer;
// AccelerantBuffer *fFrontBuffer;
// display_mode fDisplayMode;
};
#endif // ACCELERANT_HW_INTERFACE_H

View File

@ -0,0 +1,94 @@
#include <DirectWindow.h>
#include "DirectWindowBuffer.h"
// constructor
DirectWindowBuffer::DirectWindowBuffer()
: fBits(NULL),
fWidth(0),
fHeight(0),
fBytesPerRow(0),
fFormat(B_NO_COLOR_SPACE),
fWindowClipping()
{
}
// destructor
DirectWindowBuffer::~DirectWindowBuffer()
{
}
// InitCheck
status_t
DirectWindowBuffer::InitCheck() const
{
if (fBits)
return B_OK;
return B_NO_INIT;
}
// ColorSpace
color_space
DirectWindowBuffer::ColorSpace() const
{
return fFormat;
}
// Bits
void*
DirectWindowBuffer::Bits() const
{
return fBits;
}
// BytesPerRow
uint32
DirectWindowBuffer::BytesPerRow() const
{
return fBytesPerRow;
}
// Width
uint32
DirectWindowBuffer::Width() const
{
return fWidth;
}
// Height
uint32
DirectWindowBuffer::Height() const
{
return fHeight;
}
// Set
void
DirectWindowBuffer::SetTo(direct_buffer_info* info)
{
fWindowClipping.MakeEmpty();
if (info) {
int32 xOffset = info->window_bounds.left;
int32 yOffset = info->window_bounds.top;
// Get clipping information
for (int32 i = 0; i < info->clip_list_count; i++) {
fWindowClipping.Include(info->clip_list[i]);
}
fBytesPerRow = info->bytes_per_row;
fBits = (void*)info->bits;
fFormat = info->pixel_format;
// fBounds = info->window_bounds;
// fDirty = true;
fWidth = info->window_bounds.right - info->window_bounds.left + 1;
fHeight = info->window_bounds.bottom - info->window_bounds.top + 1;
} else {
fBits = NULL;
fWidth = 0;
fHeight = 0;
fBytesPerRow = 0;
fFormat = B_NO_COLOR_SPACE;
}
}

View File

@ -0,0 +1,35 @@
#ifndef DIRECT_WINDOW_BUFFER_H
#define DIRECT_WINDOW_BUFFER_H
#include "RenderingBuffer.h"
struct direct_buffer_info;
class DirectWindowBuffer : public RenderingBuffer {
public:
DirectWindowBuffer();
virtual ~DirectWindowBuffer();
virtual status_t InitCheck() const;
virtual color_space ColorSpace() const;
virtual void* Bits() const;
virtual uint32 BytesPerRow() const;
virtual uint32 Width() const;
virtual uint32 Height() const;
void SetTo(direct_buffer_info* info);
BRegion& WindowClipping()
{ return fWindowClipping; }
private:
void* fBits;
uint32 fWidth;
uint32 fHeight;
uint32 fBytesPerRow;
color_space fFormat;
BRegion fWindowClipping;
};
#endif // DIRECT_WINDOW_BUFFER_H

View File

@ -0,0 +1,53 @@
#include <stdio.h>
#include <Message.h>
#include "Desktop.h"
#include "DrawView.h"
// constructor
DrawView::DrawView(BRect frame)
: BView(frame, "desktop", B_FOLLOW_ALL, 0),
fDesktop(NULL)
{
SetViewColor(B_TRANSPARENT_COLOR);
}
// destructor
DrawView::~DrawView()
{
}
// MouseDown
void
DrawView::MouseDown(BPoint where)
{
SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
fDesktop->PostMessage(Window()->CurrentMessage());
}
// MouseUp
void
DrawView::MouseUp(BPoint where)
{
fDesktop->PostMessage(Window()->CurrentMessage());
}
// MouseMoved
void
DrawView::MouseMoved(BPoint where, uint32 code, const BMessage* dragMessage)
{
fDesktop->PostMessage(Window()->CurrentMessage());
}
// SetDesktop
void
DrawView::SetDesktop(Desktop* desktop)
{
fDesktop = desktop;
}

View File

@ -0,0 +1,26 @@
#ifndef DRAW_VIEW_H
#define DRAW_VIEW_H
#include <View.h>
class Desktop;
class DrawView : public BView {
public:
DrawView(BRect frame);
virtual ~DrawView();
virtual void MouseDown(BPoint where);
virtual void MouseUp(BPoint where);
virtual void MouseMoved(BPoint where, uint32 code,
const BMessage* dragMessage);
void SetDesktop(Desktop* desktop);
private:
Desktop* fDesktop;
};
#endif // DRAW_VIEW_H

View File

@ -0,0 +1,308 @@
#include <stdio.h>
#include <stack.h>
#include <Region.h>
#include "AccelerantHWInterface.h"
#include "DirectWindowBuffer.h"
#include "DrawingEngine.h"
// constructor
DrawingEngine::DrawingEngine(AccelerantHWInterface* interface,
DirectWindowBuffer* buffer)
: fHWInterface(interface),
fBuffer(buffer),
fCurrentClipping()
{
}
// destructor
DrawingEngine::~DrawingEngine()
{
}
// Lock
bool
DrawingEngine::Lock()
{
return fHWInterface->Lock();
}
// Unlock
void
DrawingEngine::Unlock()
{
fHWInterface->Unlock();
}
// ConstrainClipping
void
DrawingEngine::ConstrainClipping(BRegion* region)
{
if (region)
fCurrentClipping = *region;
else
fCurrentClipping.MakeEmpty();
}
// StraightLine
bool
DrawingEngine::StraightLine(BPoint a, BPoint b, const rgb_color& c)
{
uint8* dst = (uint8*)fBuffer->Bits();
uint32 bpr = fBuffer->BytesPerRow();
if (dst && fCurrentClipping.Frame().IsValid()) {
int32 clipBoxCount = fCurrentClipping.CountRects();
uint32 color;
color = (255 << 24) | (c.red << 16) | (c.green << 8) | (c.blue);
if (a.x == b.x) {
// vertical
int32 x = (int32)a.x;
dst += x * 4;
int32 y1 = (int32)min_c(a.y, b.y);
int32 y2 = (int32)max_c(a.y, b.y);
// draw a line, iterate over clipping boxes
for (int32 i = 0; i < clipBoxCount; i++) {
clipping_rect rect = fCurrentClipping.RectAtInt(i);
if (rect.left <= x &&
rect.right >= x) {
int32 i = max_c(rect.top, y1);
int32 end = min_c(rect.bottom, y2);
uint8* handle = dst + i * bpr;
for (; i <= end; i++) {
*(uint32*)handle = color;
handle += bpr;
}
}
}
return true;
} else if (a.y == b.y) {
// horizontal
int32 y = (int32)a.y;
dst += y * bpr;
int32 x1 = (int32)min_c(a.x, b.x);
int32 x2 = (int32)max_c(a.x, b.x);
// draw a line, iterate over clipping boxes
for (int32 i = 0; i < clipBoxCount; i++) {
clipping_rect rect = fCurrentClipping.RectAtInt(i);
if (rect.top <= y &&
rect.bottom >= y) {
int32 i = max_c(rect.left, x1);
int32 end = min_c(rect.right, x2);
uint32* handle = (uint32*)(dst + i * 4);
for (; i <= end; i++) {
*handle++ = color;
}
}
}
return true;
}
}
return false;
}
// StrokeLine
void
DrawingEngine::StrokeLine(BPoint a, BPoint b, const rgb_color& color)
{
if (!StraightLine(a, b, color)) {
// ...
}
}
// StrokeRect
void
DrawingEngine::StrokeRect(BRect r, const rgb_color& color)
{
StrokeLine(r.LeftTop(), r.RightTop(), color);
StrokeLine(r.RightTop(), r.RightBottom(), color);
StrokeLine(r.RightBottom(), r.LeftBottom(), color);
StrokeLine(r.LeftBottom(), r.LeftTop(), color);
}
// FillRegion
void
DrawingEngine::FillRegion(BRegion *region, const rgb_color& color)
{
if (Lock()) {
// for speed reasons, expected to be already clipped
fHWInterface->FillRegion(*region, color);
Unlock();
}
}
// DrawString
void
DrawingEngine::DrawString(const char* string, BPoint baseLine,
const rgb_color& color)
{
}
struct node {
node()
{
pointers = NULL;
}
node(const BRect& r, int32 maxPointers)
{
init(r, maxPointers);
}
~node()
{
delete [] pointers;
}
void init(const BRect& r, int32 maxPointers)
{
rect = r;
pointers = new node*[maxPointers];
in_degree = 0;
next_pointer = 0;
}
void push(node* node)
{
pointers[next_pointer] = node;
next_pointer++;
}
node* top()
{
return pointers[next_pointer];
}
node* pop()
{
node* ret = top();
next_pointer--;
return ret;
}
BRect rect;
int32 in_degree;
node** pointers;
int32 next_pointer;
};
bool
is_left_of(const BRect& a, const BRect& b)
{
return (a.right < b.left);
}
bool
is_above(const BRect& a, const BRect& b)
{
return (a.bottom < b.top);
}
void
DrawingEngine::CopyRegion(BRegion* region, int32 xOffset, int32 yOffset)
{
if (Lock()) {
int32 count = region->CountRects();
// TODO: make this step unnecessary
// (by using different stack impl inside node)
node nodes[count];
for (int32 i= 0; i < count; i++) {
nodes[i].init(region->RectAt(i), count);
}
for (int32 i = 0; i < count; i++) {
BRect a = region->RectAt(i);
for (int32 k = i + 1; k < count; k++) {
BRect b = region->RectAt(k);
int cmp = 0;
// compare horizontally
if (xOffset > 0) {
if (is_left_of(a, b)) {
cmp -= 1;
} else if (is_left_of(b, a)) {
cmp += 1;
}
} else if (xOffset < 0) {
if (is_left_of(a, b)) {
cmp += 1;
} else if (is_left_of(b, a)) {
cmp -= 1;
}
}
// compare vertically
if (yOffset > 0) {
if (is_above(a, b)) {
cmp -= 1;
} else if (is_above(b, a)) {
cmp += 1;
}
} else if (yOffset < 0) {
if (is_above(a, b)) {
cmp += 1;
} else if (is_above(b, a)) {
cmp -= 1;
}
}
// add appropriate node as successor
if (cmp > 0) {
nodes[i].push(&nodes[k]);
nodes[k].in_degree++;
} else if (cmp < 0) {
nodes[k].push(&nodes[i]);
nodes[i].in_degree++;
}
}
}
// put all nodes onto a stack that have an "indegree" count of zero
stack<node*> inDegreeZeroNodes;
for (int32 i = 0; i < count; i++) {
if (nodes[i].in_degree == 0) {
inDegreeZeroNodes.push(&nodes[i]);
}
}
// pop the rects from the stack, do the actual copy operation
// and decrease the "indegree" count of the other rects not
// currently on the stack and to which the current rect pointed
// to. If their "indegree" count reaches zero, put them onto the
// stack as well.
clipping_rect* sortedRectList = new clipping_rect[count];
int32 nextSortedIndex = 0;
while (!inDegreeZeroNodes.empty()) {
node* n = inDegreeZeroNodes.top();
inDegreeZeroNodes.pop();
sortedRectList[nextSortedIndex].left = (int32)n->rect.left;
sortedRectList[nextSortedIndex].top = (int32)n->rect.top;
sortedRectList[nextSortedIndex].right = (int32)n->rect.right;
sortedRectList[nextSortedIndex].bottom = (int32)n->rect.bottom;
nextSortedIndex++;
for (int32 k = 0; k < n->next_pointer; k++) {
n->pointers[k]->in_degree--;
if (n->pointers[k]->in_degree == 0)
inDegreeZeroNodes.push(n->pointers[k]);
}
}
// trigger the HW accelerated blit
fHWInterface->CopyRegion(sortedRectList, count, xOffset, yOffset);
delete[] sortedRectList;
Unlock();
}
}

View File

@ -0,0 +1,41 @@
#ifndef DRAWING_ENGINE_H
#define DRAWING_ENGINE_H
#include <GraphicsDefs.h>
#include <Region.h>
class AccelerantHWInterface;
class DirectWindowBuffer;
class DrawingEngine {
public:
DrawingEngine(AccelerantHWInterface* interface,
DirectWindowBuffer* buffer);
virtual ~DrawingEngine();
bool Lock();
void Unlock();
void ConstrainClipping(BRegion* region);
bool StraightLine(BPoint a, BPoint b, const rgb_color& c);
void StrokeLine(BPoint a, BPoint b, const rgb_color& color);
void StrokeRect(BRect r, const rgb_color& color);
void FillRegion(BRegion *region, const rgb_color& color);
void DrawString(const char* string, BPoint baseLine,
const rgb_color& color);
void CopyRegion(BRegion *region, int32 xOffset, int32 yOffset);
private:
AccelerantHWInterface* fHWInterface;
DirectWindowBuffer* fBuffer;
BRegion fCurrentClipping;
};
#endif // DRAWING_ENGINE_H

View File

@ -0,0 +1,33 @@
// RenderingBuffer.h
#ifndef RENDERING_BUFFER_H
#define RENDERING_BUFFER_H
#include <GraphicsDefs.h>
#include <Rect.h>
class RenderingBuffer {
public:
RenderingBuffer() {}
virtual ~RenderingBuffer() {}
virtual status_t InitCheck() const = 0;
virtual color_space ColorSpace() const = 0;
virtual void* Bits() const = 0;
virtual uint32 BytesPerRow() const = 0;
// the *count* of the pixels per line
virtual uint32 Width() const = 0;
// the *count* of lines
virtual uint32 Height() const = 0;
inline uint32 BitsLength() const
{ return Height() * BytesPerRow(); }
inline BRect Bounds() const
{ return BRect(0.0, 0.0,
Width() - 1,
Height() - 1); }
};
#endif // RENDERING_BUFFER_H

View File

@ -1,13 +1,16 @@
#include <Application.h>
#include <Window.h>
#include <DirectWindow.h>
#include <View.h>
#include <stdio.h>
#include <stdlib.h>
#include "AccelerantHWInterface.h"
#include "Desktop.h"
#include "DirectWindowBuffer.h"
#include "DrawingEngine.h"
#include "DrawView.h"
#include "ViewLayer.h"
#include "WindowLayer.h"
@ -18,19 +21,25 @@ class App : public BApplication {
virtual void ReadyToRun();
};
class Window : public BWindow {
class Window : public BDirectWindow {
public:
Window(const char* title);
virtual ~Window();
Window(const char* title);
virtual ~Window();
virtual bool QuitRequested();
virtual bool QuitRequested();
void AddWindow(BRect frame, const char* name);
void Test();
virtual void DirectConnected(direct_buffer_info* info);
void AddWindow(BRect frame, const char* name);
void Test();
private:
DrawView* fView;
Desktop* fDesktop;
bool fQuit;
DrawView* fView;
Desktop* fDesktop;
bool fQuit;
DirectWindowBuffer fBuffer;
AccelerantHWInterface fInterface;
DrawingEngine fEngine;
};
// constructor
@ -52,15 +61,20 @@ App::ReadyToRun()
// constructor
Window::Window(const char* title)
: BWindow(BRect(50, 50, 800, 650), title,
B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, B_ASYNCHRONOUS_CONTROLS)
: BDirectWindow(BRect(50, 50, 800, 650), title,
B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, B_ASYNCHRONOUS_CONTROLS),
fQuit(false),
fBuffer(),
fInterface(),
fEngine(&fInterface, &fBuffer)
{
fInterface.Initialize();
fView = new DrawView(Bounds());
fDesktop = new Desktop(fView);
fDesktop->Run();
AddChild(fView);
fView->MakeFocus(true);
fQuit = false;
fDesktop = new Desktop(fView, &fEngine);
fDesktop->Run();
}
// destructor
@ -82,6 +96,34 @@ Window::QuitRequested()
return true;
}
// DirectConnected
void
Window::DirectConnected(direct_buffer_info* info)
{
// TODO: for some reason, this deadlocks
// on B_DIRECT_STOP... be aware
fDesktop->LockClipping();
fEngine.Lock();
switch(info->buffer_state & B_DIRECT_MODE_MASK) {
case B_DIRECT_START:
case B_DIRECT_MODIFY:
fBuffer.SetTo(info);
fDesktop->SetOffset(info->window_bounds.left, info->window_bounds.top);
break;
case B_DIRECT_STOP:
fBuffer.SetTo(NULL);
break;
}
fDesktop->SetMasterClipping(&fBuffer.WindowClipping());
fEngine.Unlock();
fDesktop->UnlockClipping();
}
// AddWindow
void
Window::AddWindow(BRect frame, const char* name)

View File

@ -32,11 +32,14 @@ TYPE= APP
# in folder names do not work well with this makefile.
SRCS= ClientLooper.cpp \
Desktop.cpp \
DrawingEngine.cpp \
main.cpp \
MultiLocker.cpp \
ViewLayer.cpp \
WindowLayer.cpp \
drawing/AccelerantHWInterface.cpp \
drawing/DirectWindowBuffer.cpp \
drawing/DrawingEngine.cpp \
drawing/DrawView.cpp \
# trace.c
# specify the resource files to use
@ -58,7 +61,7 @@ RSRCS=
# naming scheme you need to specify the path to the library
# and it's name
# library: my_lib.a entry: my_lib.a or path/my_lib.a
LIBS= be
LIBS= be game
# specify additional paths to directories following the standard
# libXXX.so or libXXX.a naming scheme. You can specify full paths