Added a *serious* speedup to window move code

Added a couple more empty message handlers to ServerWindow
Improved DefaultDecorator - works better now
DisplayDriver::CopyRegion added and implemented it for ViewDriver


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3637 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
DarkWyrm 2003-06-24 13:55:18 +00:00
parent 4f4f381f93
commit a8c44e89f8
17 changed files with 209 additions and 111 deletions

View File

@ -68,8 +68,8 @@ AppServer::AppServer(void) : BApplication (SERVER_SIGNATURE)
AppServer::AppServer(void)
#endif
{
_mouseport=create_port(100,SERVER_INPUT_PORT);
_messageport=create_port(100,SERVER_PORT_NAME);
_mouseport=create_port(200,SERVER_INPUT_PORT);
_messageport=create_port(200,SERVER_PORT_NAME);
_applist=new BList(0);
_quitting_server=false;

View File

@ -46,7 +46,7 @@ Decorator::Decorator(BRect rect, int32 wlook, int32 wfeel, int32 wflags)
_zoom_state=false;
_title_string=new BString;
_driver=NULL;
_closerect.Set(0,0,1,1);
_zoomrect.Set(0,0,1,1);
_minimizerect.Set(0,0,1,1);
@ -231,6 +231,7 @@ int32 Decorator::GetFlags(void)
void Decorator::SetTitle(const char *string)
{
_title_string->SetTo(string);
_DoLayout();
}
/*!

View File

@ -95,6 +95,11 @@ public:
protected:
int32 _ClipTitle(float width);
/*!
\brief Returns the number of characters in the title
\return The title character count
*/
int32 _TitleWidth(void) { return (_title_string)?_title_string->CountChars():0; }
virtual void _DrawClose(BRect r);

View File

@ -44,9 +44,9 @@ DefaultDecorator::DefaultDecorator(BRect rect, int32 wlook, int32 wfeel, int32 w
: Decorator(rect,wlook,wfeel,wflags)
{
taboffset=0;
titlepixelwidth=0;
// commented these out because they are taken care of by the SetFocus() call
SetFocus(false);
_SetFocus();
// These hard-coded assignments will go bye-bye when the system _colors
// API is implemented
@ -99,7 +99,7 @@ else
if(buttons & B_TERTIARY_MOUSE_BUTTON)
printf("\t\tTertiary\n");
}
printf("\tNodifiers:\n");
printf("\tModifiers:\n");
if(modifiers==0)
printf("\t\tNone\n");
else
@ -182,6 +182,8 @@ printf("DefaultDecorator: Do Layout\n");
_borderrect=_frame;
_closerect=_frame;
textoffset=(_look==B_FLOATING_WINDOW_LOOK)?5:7;
_closerect.left+=(_look==B_FLOATING_WINDOW_LOOK)?2:4;
_closerect.top+=(_look==B_FLOATING_WINDOW_LOOK)?6:4;
_closerect.right=_closerect.left+10;
@ -193,16 +195,14 @@ printf("DefaultDecorator: Do Layout\n");
_resizerect.left=_resizerect.right-18;
_tabrect.bottom=_tabrect.top+18;
/* if(GetTitle())
if(GetTitle() && _driver)
{
float titlewidth=_closerect.right
+_driver->StringWidth(layer->name->String(),
layer->name->Length())
+35;
_tabrect.right=(titlewidth<_frame.right -1)?titlewidth:_frame.right;
titlepixelwidth=_driver->StringWidth(GetTitle(),_TitleWidth(), &_layerdata);
if(_closerect.right+textoffset+titlepixelwidth+35< _frame.Width()-1)
_tabrect.right=_tabrect.left+titlepixelwidth;
}
else
*/ _tabrect.right=_tabrect.left+_tabrect.Width()/2;
_tabrect.right=_tabrect.left+_tabrect.Width()/2;
if(_look==B_FLOATING_WINDOW_LOOK)
_tabrect.top+=4;
@ -214,7 +214,6 @@ printf("DefaultDecorator: Do Layout\n");
_zoomrect.left=_zoomrect.right-10;
_zoomrect.bottom=_zoomrect.top+10;
textoffset=(_look==B_FLOATING_WINDOW_LOOK)?5:7;
}
void DefaultDecorator::MoveBy(float x, float y)
@ -254,14 +253,14 @@ void DefaultDecorator::_DrawTitle(BRect r)
{
// Designed simply to redraw the title when it has changed on
// the client side.
/* _driver->SetDrawingMode(B_OP_OVER);
rgb_color tmpcol=_driver->HighColor();
_driver->SetHighColor(textcol.red,textcol.green,textcol.blue);
_driver->DrawString((char *)string,strlen(string),
BPoint(_closerect.right+textoffset,_closerect.bottom-1));
_driver->SetHighColor(tmpcol.red,tmpcol.green,tmpcol.blue);
_driver->SetDrawingMode(B_OP_COPY);
*/
_layerdata.draw_mode=B_OP_OVER;
_layerdata.highcolor=_colors->window_tab_text;
// closerect.bottom+1 because the driver subtracts one from the y coordinate
// for compatibility with the BeOS font system
_driver->DrawString(GetTitle(),_ClipTitle((_zoomrect.left-5)-(_closerect.right+textoffset)),
BPoint(_closerect.right+textoffset,_closerect.bottom+1),&_layerdata);
_layerdata.draw_mode=B_OP_COPY;
}
void DefaultDecorator::_SetFocus(void)
@ -354,11 +353,12 @@ void DefaultDecorator::_DrawTab(BRect r)
_layerdata.highcolor=frame_lowcol;
_driver->StrokeRect(_tabrect,&_layerdata,(int8*)&solidhigh);
// UpdateTitle(layer->name->String());
_layerdata.highcolor=_colors->window_tab;
_driver->FillRect(_tabrect.InsetByCopy(1,1),&_layerdata,(int8*)&solidhigh);
// UpdateTitle(layer->name->String());
_DrawTitle(_tabrect);
// Draw the buttons if we're supposed to
if(!(_flags & B_NOT_CLOSABLE))
_DrawClose(_closerect);

View File

@ -63,6 +63,7 @@ protected:
bool slidetab;
int textoffset;
float titlepixelwidth;
};
#endif

View File

@ -96,6 +96,18 @@ void DisplayDriver::CopyBits(BRect src, BRect dest)
{
}
/*!
\brief A screen-to-screen blit (of sorts) which copies a BRegion
\param src Source region
\param lefttop Offset to which the region will be copied
Bounds checking must be done in this call. This function needs to be literally as
fast as possible - all window moves will be done with it.
*/
void DisplayDriver::CopyRegion(BRegion *src, const BPoint &lefttop)
{
}
/*!
\brief Called for all BView::DrawBitmap calls
\param bmp Bitmap to be drawn. It will always be non-NULL and valid. The color

View File

@ -97,6 +97,7 @@ public:
virtual bool Initialize(void);
virtual void Shutdown(void);
virtual void CopyBits(BRect src, BRect dest);
virtual void CopyRegion(BRegion *src, const BPoint &lefttop);
virtual void DrawBitmap(ServerBitmap *bmp, BRect src, BRect dest, LayerData *d);
virtual void DrawString(const char *string, int32 length, BPoint pt, LayerData *d, escapement_delta *delta=NULL);

View File

@ -185,7 +185,7 @@ printf("Layer: %s: Add Child (%s, %s, %s) - Incomplete\n",_name->String(),layer?
_bottomchild=layer;
_topchild=layer;
layer->_level=_level+1;
if(rebuild)
RebuildRegions(true);
}
@ -233,7 +233,6 @@ printf("Layer: %s: Remove Child (%s,%s)\n",_name->String(),layer?layer->_name->S
layer->_lowersibling->_uppersibling=layer->_uppersibling;
layer->_uppersibling=NULL;
layer->_lowersibling=NULL;
if(rebuild)
RebuildRegions(true);
}
@ -754,15 +753,18 @@ printf("Layer: %s: Rebuild Regions (%s)\n",_name->String(),include_children?"inc
if(childlay->_visible && childlay->_hidecount==0)
{
// reg is what is _visible in the layer's _parent's coordinate system
reg=new BRegion(ConvertToParent(_visible));
// reg=new BRegion(ConvertToParent(_visible));
// reg2 is the layer's _visible region in the sibling's coordinate system
reg2=new BRegion(childlay->ConvertFromParent(reg));
delete reg;
// reg2=new BRegion(childlay->ConvertFromParent(reg));
// delete reg;
// lowersiblings occupy screen space _above_ a layer, so the layer itself
// must remove from its _visible region
_visible->Exclude(reg2);
delete reg2;
// _visible->Exclude(reg2);
// delete reg2;
reg=new BRegion(ConvertToParent(_visible));
_visible->Exclude(reg);
delete reg;
}
}

View File

@ -113,7 +113,7 @@ protected:
*_lowersibling,
*_topchild,
*_bottomchild;
BRegion *_visible,
*_invalid,
*_full;

View File

@ -31,10 +31,6 @@
#include "PatternHandler.h" // for pattern_union
#include "ServerConfig.h"
#ifdef DISPLAYDRIVER_TEST_HACK
#include <stdio.h>
#endif
/*!
\brief Sets up internal variables needed by the RootLayer
@ -100,7 +96,6 @@ void RootLayer::RequestDraw(void)
}
#ifdef DISPLAYDRIVER_TEST_HACK
/* Note to self, commented out tests appear to work correctly */
int8 pattern[8];
int8 pattern2[8];
memset(pattern,255,8);
@ -111,11 +106,9 @@ void RootLayer::RequestDraw(void)
pts[0].y = 200;
pts[1].x = 400;
pts[1].y = 1000;
//pts[2].x = 600;
pts[2].x = 100;
pts[2].y = 100;
//pts[3].x = 1200;
pts[3].x = 200;
pts[2].x = 600;
pts[2].y = 400;
pts[3].x = 1200;
pts[3].y = 800;
BPoint triangle[3];
BRect triangleRect(100,100,400,300);
@ -142,66 +135,26 @@ void RootLayer::RequestDraw(void)
_layerdata->highcolor.SetColor(255,0,0,255);
_layerdata->lowcolor.SetColor(255,255,255,255);
printf("FillRect big red\n");
_driver->FillRect(r1,_layerdata,pattern);
getchar();
/*
_layerdata->highcolor.SetColor(255,255,0,255);
printf("StrokeLine yellow\n");
_driver->StrokeLine(BPoint(100,100),BPoint(1500,1100),_layerdata,pattern);
getchar();
_layerdata->highcolor.SetColor(0,0,255,255);
printf("StrokeBezier blue\n");
_driver->StrokeBezier(pts,_layerdata,pattern);
getchar();
printf("StrokeArc blue\n");
_driver->StrokeArc(BRect(200,300,400,600),30,270,_layerdata,pattern);
getchar();
printf("StrokeEllipse blue\n");
_driver->StrokeEllipse(BRect(200,700,400,900),_layerdata,pattern);
getchar();
printf("StrokeRect blue\n");
_driver->StrokeRect(BRect(650,1000,750,1090),_layerdata,pattern);
getchar();
printf("StrokeRoundRect blue\n");
_driver->StrokeRoundRect(BRect(200,1000,600,1090),30,40,_layerdata,pattern);
getchar();
printf("StrokePolygon blue\n");
_driver->StrokePolygon(polygon,6,polygonRect,_layerdata,pattern);
getchar();
printf("StrokeTriangle blue\n");
_driver->StrokeTriangle(triangle,triangleRect,_layerdata,pattern);
getchar();
_layerdata->highcolor.SetColor(0,255,0,255);
printf("FillArc green\n");
_driver->FillArc(BRect(250,300,450,600),30,270,_layerdata,pattern);
getchar();
*/
// _driver->StrokePolygon(polygon,6,polygonRect,_layerdata,pattern);
// _driver->StrokeTriangle(triangle,triangleRect,_layerdata,pattern);
_layerdata->highcolor.SetColor(255,0,255,255);
printf("FillBezier magenta\n");
_driver->FillBezier(pts,_layerdata,pattern);
getchar();
_layerdata->highcolor.SetColor(0,0,255,255);
printf("StrokeBezier blue\n");
_driver->StrokeBezier(pts,_layerdata,pattern);
getchar();
/*
_layerdata->highcolor.SetColor(255,0,255,255);
printf("FillEllipse magenta\n");
_driver->FillArc(BRect(1250,300,1450,600),30,270,_layerdata,pattern);
// _driver->FillBezier(pts,_layerdata,pattern);
_driver->FillEllipse(BRect(800,300,1200,600),_layerdata,pattern);
getchar();
printf("FillRoundRect striped\n");
_driver->FillRoundRect(BRect(800,1000,1200,1090),30,40,_layerdata,pattern2);
getchar();
printf("FillPolygon magenta\n");
_driver->FillPolygon(polygon,6,polygonRect,_layerdata,pattern);
getchar();
_layerdata->highcolor.SetColor(255,255,0,255);
printf("FillTriangle yellow\n");
_driver->FillTriangle(triangle,triangleRect,_layerdata,pattern);
getchar();
*/
// _driver->FillTriangle(triangle,triangleRect,_layerdata,pattern);
#endif
}

View File

@ -39,8 +39,9 @@
#include "Desktop.h"
#include "DesktopClasses.h"
#include "TokenHandler.h"
#include "Utils.h"
//#define DEBUG_SERVERWINDOW
#define DEBUG_SERVERWINDOW
//#define DEBUG_SERVERWINDOW_MOUSE
//#define DEBUG_SERVERWINDOW_KEYBOARD
@ -382,6 +383,28 @@ printf("ServerWindow %s: Message Create_Layer unimplemented\n",_title->String())
// TODO: Implement
#ifdef DEBUG_SERVERWINDOW
printf("ServerWindow %s: Message Delete_Layer unimplemented\n",_title->String());
#endif
break;
}
case AS_LAYER_CREATE_ROOT:
{
// Received when a window creates its internal top view
// TODO: Implement
#ifdef DEBUG_SERVERWINDOW
printf("ServerWindow %s: Message Create_Layer_Root unimplemented\n",_title->String());
#endif
break;
}
case AS_LAYER_DELETE_ROOT:
{
// Received when a window deletes its internal top view
// TODO: Implement
#ifdef DEBUG_SERVERWINDOW
printf("ServerWindow %s: Message Delete_Layer_Root unimplemented\n",_title->String());
#endif
break;
@ -558,7 +581,7 @@ printf("ServerWindow %s: Message Move_By unimplemented\n",_title->String());
}
default:
{
printf("ServerWindow %s received unexpected code %lx",_title->String(),code);
printf("ServerWindow %s received unexpected code %s\n",_title->String(),MsgCodeToString(code));
break;
}
}

View File

@ -60,3 +60,15 @@ bool _use_preferred_target_(BMessage *msg)
{
return msg->fPreferred;
}
const char *MsgCodeToString(int32 code)
{
// Used to translate BMessage message codes back to a character
// format
char string [10];
sprintf(string,"'%c%c%c%c'",(char)((code & 0xFF000000) >> 24),
(char)((code & 0x00FF0000) >> 16),
(char)((code & 0x0000FF00) >> 8),
(char)((code & 0x000000FF)) );
return string;
}

View File

@ -5,5 +5,6 @@
#include <OS.h>
void SendMessage(port_id port, BMessage *message, int32 target=-1);
const char *MsgCodeToString(int32 code);
#endif

View File

@ -40,6 +40,7 @@
#include "Angle.h"
#include "PortLink.h"
#include "RectUtils.h"
#include "ServerProtocol.h"
#include "ServerBitmap.h"
#include "ViewDriver.h"
@ -651,6 +652,83 @@ void ViewDriver::CopyBits(BRect src, BRect dest)
screenwin->Unlock();
}
void ViewDriver::CopyRegion(BRegion *src, const BPoint &lefttop)
{
#ifdef DEBUG_DRIVER_MODULE
printf("ViewDriver:: CopyRegion unimplemented()\n");
#endif
screenwin->Lock();
framebuffer->Lock();
// Check for overlap
bool overlap=false;
BRect regframe=src->Frame();
regframe.OffsetTo(lefttop);
BRegion inverse;
int8 *savebuffer=NULL,*srcindex=NULL,*destindex=NULL,
*framebufferstart=NULL;
int32 buffer_row_size=0,i;
if(TestRectIntersection(regframe,src->Frame()) && src->CountRects()>1)
overlap=true;
if(overlap)
{
// If overlap, get the inverse of the region passed to us and save the
// inverse region's frame
inverse=src->Frame();
inverse.Exclude(src);
buffer_row_size=inverse.Frame().IntegerWidth() * 4;
destindex=savebuffer=new int8[ buffer_row_size * inverse.Frame().IntegerHeight()];
framebufferstart=srcindex=(int8*)framebuffer->Bits()+
(framebuffer->BytesPerRow()* int32(inverse.Frame().top));
srcindex+=int32(inverse.Frame().left)*4;
for(i=int32(inverse.Frame().top);i<int32(inverse.Frame().bottom); i++)
{
memcpy(destindex,srcindex,buffer_row_size);
srcindex+=framebuffer->BytesPerRow();
destindex+=buffer_row_size;
}
}
// Copy all rectangles in the region to the new offset
BRect srcrect,destrect;
for(i=0; i<src->CountRects(); i++)
{
srcrect=destrect=src->RectAt(i);
destrect.OffsetTo(lefttop);
drawview->CopyBits(srcrect,destrect);
}
drawview->Sync();
if(overlap)
{
// Copy all saved rectangles back to the screen and clean up
srcindex=savebuffer;
destindex=framebufferstart;
for(i=int32(inverse.Frame().top);i<int32(inverse.Frame().bottom); i++)
{
memcpy(destindex,srcindex,buffer_row_size);
srcindex+=framebuffer->BytesPerRow();
destindex+=buffer_row_size;
}
delete savebuffer;
}
screenwin->view->Invalidate(src->Frame());
screenwin->view->Invalidate(regframe);
framebuffer->Unlock();
screenwin->Unlock();
}
void ViewDriver::DrawBitmap(ServerBitmap *bitmap, BRect src, BRect dest)
{
#ifdef DEBUG_DRIVER_MODULE

View File

@ -108,6 +108,7 @@ public:
// Drawing functions
void CopyBits(BRect src, BRect dest);
void CopyRegion(BRegion *src, const BPoint &lefttop);
void DrawBitmap(ServerBitmap *bmp, BRect src, BRect dest);
void DrawChar(char c, BPoint pt, LayerData *d);
// virtual void DrawPicture(SPicture *pic, BPoint pt);

View File

@ -76,6 +76,7 @@ WinBorder::WinBorder(BRect r, const char *name, int32 look, int32 feel, int32 fl
: Layer(r,name,B_FOLLOW_NONE,flags,win)
{
_mbuttons=0;
_kmodifiers=0;
_win=win;
if(_win)
_frame=_win->_frame;
@ -86,9 +87,10 @@ WinBorder::WinBorder(BRect r, const char *name, int32 look, int32 feel, int32 fl
_title=new BString(name);
_hresizewin=false;
_vresizewin=false;
_driver=GetGfxDriver(ActiveScreen());
_decorator=new_decorator(r,name,look,feel,flags,GetGfxDriver(ActiveScreen()));
_decorator->SetDriver(GetGfxDriver(ActiveScreen()));
_decorator->SetDriver(_driver);
_decorator->SetTitle(name);
#ifdef DEBUG_WINBORDER
printf("WinBorder %s:\n",_title->String());
@ -107,9 +109,6 @@ printf("WinBorder %s:~WinBorder()\n",_title->String());
void WinBorder::MouseDown(int8 *buffer)
{
#ifdef DEBUG_WINBORDER_MOUSE
printf("WinBorder %s: MouseDown unimplemented\n",_title->String());
#endif
// Buffer data:
// 1) int64 - time of mouse click
// 2) float - x coordinate of mouse click
@ -223,9 +222,6 @@ printf("Click: Resize\n");
break;
}
}
// TODO: fix this
// if(click!=CLICK_NONE)
// ActivateWindow(_win);
}
void WinBorder::MouseMoved(int8 *buffer)
@ -243,10 +239,6 @@ void WinBorder::MouseMoved(int8 *buffer)
BPoint pt(x,y);
click_type click=_decorator->Clicked(pt, _mbuttons, _kmodifiers);
#ifdef DEBUG_WINBORDER_MOUSE
printf("WinBorder %s: MouseMoved unimplemented\n",_title->String());
#endif
if(click!=CLICK_CLOSE && _decorator->GetClose())
{
_decorator->SetClose(false);
@ -291,6 +283,7 @@ printf("ClickMove: Slide Tab\n");
#ifdef DEBUG_WINBORDER_CLICK
printf("ClickMove: Drag\n");
#endif
//debugger("");
float dx=pt.x-_mousepos.x,
dy=pt.y-_mousepos.y;
if(buttons!=0 && (dx!=0 || dy!=0))
@ -303,11 +296,23 @@ printf("ClickMove: Drag\n");
_win->Unlock();
lock_layers();
_parent->Invalidate(oldmoveframe);
// _parent->Invalidate(oldmoveframe);
// MoveBy(dx,dy);
// _decorator->MoveBy(BPoint(dx, dy));
// _parent->RequestDraw();
// _decorator->Draw();
BRegion *reg=_decorator->GetFootprint();
_driver->CopyRegion(reg,_win->_frame.LeftTop());
BRegion reg2(oldmoveframe);
MoveBy(dx,dy);
_parent->RequestDraw();
_decorator->MoveBy(BPoint(dx, dy));
_decorator->Draw();
reg->OffsetBy(dx, dy);
reg2.Exclude(reg);
_parent->RebuildRegions();
_parent->RequestDraw();
delete reg;
unlock_layers();
}
}
@ -419,7 +424,7 @@ printf("WinBorder %s::RequestDraw\n",_title->String());
#endif
_decorator->Draw();
}
/*
void WinBorder::MoveBy(BPoint pt)
{
}
@ -435,7 +440,7 @@ void WinBorder::ResizeBy(BPoint pt)
void WinBorder::ResizeBy(float x, float y)
{
}
*/
void WinBorder::UpdateColors(void)
{
#ifdef DEBUG_WINBORDER

View File

@ -42,10 +42,10 @@ public:
~WinBorder(void);
void RequestDraw(void);
void RequestDraw(const BRect &r);
void MoveBy(BPoint pt);
void MoveBy(float x, float y);
void ResizeBy(BPoint pt);
void ResizeBy(float x, float y);
// void MoveBy(BPoint pt);
// void MoveBy(float x, float y);
// void ResizeBy(BPoint pt);
// void ResizeBy(float x, float y);
void MouseDown(int8 *buffer);
void MouseMoved(int8 *buffer);
void MouseUp(int8 *buffer);
@ -67,6 +67,7 @@ protected:
BPoint _mousepos;
bool _update;
bool _hresizewin,_vresizewin;
DisplayDriver *_driver;
};
bool is_moving_window(void);
@ -75,5 +76,7 @@ bool is_resizing_window(void);
void set_is_resizing_window(bool state);
void set_active_winborder(WinBorder *win);
WinBorder * get_active_winborder(void);
void set_is_resizing_window(bool state);
bool is_sliding_tab(void);
#endif