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:
parent
7be34d3eb2
commit
e76d86d5dd
@ -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(®ion);
|
||||
region = fBackgroundRegion;
|
||||
fBackgroundRegion.MakeEmpty();
|
||||
_SetBackground(®ion);
|
||||
}
|
||||
#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(©Region, x, y);
|
||||
|
||||
// in the dirty region, exclude the parts that we
|
||||
// could move by blitting
|
||||
copyRegion.OffsetBy(x, y);
|
||||
newDirtyRegion.Exclude(©Region);
|
||||
fDrawingEngine->MarkDirty(©Region);
|
||||
|
||||
fDrawingEngine->Unlock();
|
||||
}
|
||||
fDrawingEngine->CopyRegion(©Region, x, y);
|
||||
|
||||
copyRegion.OffsetBy(x, y);
|
||||
newDirtyRegion.Exclude(©Region);
|
||||
|
||||
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 });
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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(®ion, &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(®ion, &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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
53
src/tests/servers/app/newerClipping/drawing/DrawView.cpp
Normal file
53
src/tests/servers/app/newerClipping/drawing/DrawView.cpp
Normal 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;
|
||||
}
|
||||
|
||||
|
26
src/tests/servers/app/newerClipping/drawing/DrawView.h
Normal file
26
src/tests/servers/app/newerClipping/drawing/DrawView.h
Normal 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
|
||||
|
308
src/tests/servers/app/newerClipping/drawing/DrawingEngine.cpp
Normal file
308
src/tests/servers/app/newerClipping/drawing/DrawingEngine.cpp
Normal 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();
|
||||
}
|
||||
}
|
41
src/tests/servers/app/newerClipping/drawing/DrawingEngine.h
Normal file
41
src/tests/servers/app/newerClipping/drawing/DrawingEngine.h
Normal 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
|
||||
|
@ -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
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user