2005-06-23 21:40:35 +04:00
|
|
|
/*
|
2007-01-06 20:08:19 +03:00
|
|
|
* Copyright 2001-2007, Haiku.
|
2005-06-23 21:40:35 +04:00
|
|
|
* Distributed under the terms of the MIT License.
|
|
|
|
*
|
|
|
|
* Authors:
|
|
|
|
* DarkWyrm <bpmagic@columbus.rr.com>
|
2005-11-07 22:01:12 +03:00
|
|
|
* Adrian Oanca <adioanca@gmail.com>
|
2005-06-23 21:40:35 +04:00
|
|
|
* Stephan Aßmus <superstippi@gmx.de>
|
|
|
|
* Stefano Ceccherini (burton666@libero.it)
|
|
|
|
* Axel Dörfler, axeld@pinc-software.de
|
|
|
|
*/
|
|
|
|
|
2005-07-24 21:13:02 +04:00
|
|
|
/*!
|
|
|
|
\class ServerWindow
|
|
|
|
\brief Shadow BWindow class
|
|
|
|
|
|
|
|
A ServerWindow handles all the intraserver tasks required of it by its BWindow. There are
|
|
|
|
too many tasks to list as being done by them, but they include handling View transactions,
|
2005-11-24 20:45:26 +03:00
|
|
|
coordinating and linking a window's WindowLayer half with its messaging half, dispatching
|
2005-07-24 21:13:02 +04:00
|
|
|
mouse and key events from the server to its window, and other such things.
|
|
|
|
*/
|
|
|
|
|
2005-07-01 10:44:39 +04:00
|
|
|
|
2006-04-23 19:45:35 +04:00
|
|
|
#include "ServerWindow.h"
|
2005-11-20 19:24:23 +03:00
|
|
|
|
2003-02-07 15:53:57 +03:00
|
|
|
#include "AppServer.h"
|
2005-05-26 03:59:23 +04:00
|
|
|
#include "DebugInfoManager.h"
|
2004-10-16 06:02:27 +04:00
|
|
|
#include "Desktop.h"
|
2005-11-04 18:54:16 +03:00
|
|
|
#include "DrawingEngine.h"
|
2005-06-24 03:46:17 +04:00
|
|
|
#include "HWInterface.h"
|
2006-04-23 19:45:35 +04:00
|
|
|
#include "Overlay.h"
|
2007-07-18 16:59:05 +04:00
|
|
|
#include "ProfileMessageSupport.h"
|
2004-10-16 06:02:27 +04:00
|
|
|
#include "RAMLinkMsgReader.h"
|
2005-10-12 01:37:47 +04:00
|
|
|
#include "RenderingBuffer.h"
|
2003-02-07 15:53:57 +03:00
|
|
|
#include "ServerApp.h"
|
2005-06-24 03:46:17 +04:00
|
|
|
#include "ServerBitmap.h"
|
2005-06-03 18:20:10 +04:00
|
|
|
#include "ServerPicture.h"
|
2005-06-24 03:46:17 +04:00
|
|
|
#include "ServerProtocol.h"
|
2005-11-24 20:45:26 +03:00
|
|
|
#include "WindowLayer.h"
|
2005-07-01 10:53:07 +04:00
|
|
|
#include "WorkspacesLayer.h"
|
2005-06-24 03:46:17 +04:00
|
|
|
|
2005-10-12 01:37:47 +04:00
|
|
|
#include "clipping.h"
|
|
|
|
|
2006-04-23 19:45:35 +04:00
|
|
|
#include <DirectWindowPrivate.h>
|
|
|
|
#include <MessagePrivate.h>
|
|
|
|
#include <PortLink.h>
|
|
|
|
#include <WindowInfo.h>
|
|
|
|
#include <WindowPrivate.h>
|
|
|
|
|
|
|
|
#include <AppDefs.h>
|
|
|
|
#include <Autolock.h>
|
|
|
|
#include <DirectWindow.h>
|
|
|
|
#include <TokenSpace.h>
|
|
|
|
#include <View.h>
|
|
|
|
|
|
|
|
#include <new>
|
|
|
|
|
2005-11-13 02:27:14 +03:00
|
|
|
using std::nothrow;
|
|
|
|
|
2005-11-30 18:47:01 +03:00
|
|
|
//#define TRACE_SERVER_WINDOW
|
|
|
|
//#define TRACE_SERVER_WINDOW_MESSAGES
|
2007-07-18 17:22:26 +04:00
|
|
|
//#define PROFILE_MESSAGE_LOOP
|
2003-03-23 23:52:37 +03:00
|
|
|
|
2003-09-09 01:18:39 +04:00
|
|
|
|
2005-11-30 18:47:01 +03:00
|
|
|
#ifdef TRACE_SERVER_WINDOW
|
2003-09-09 01:18:39 +04:00
|
|
|
# include <stdio.h>
|
|
|
|
# define STRACE(x) printf x
|
|
|
|
#else
|
|
|
|
# define STRACE(x) ;
|
|
|
|
#endif
|
|
|
|
|
2005-11-30 18:47:01 +03:00
|
|
|
#ifdef TRACE_SERVER_WINDOW_MESSAGES
|
2005-01-19 18:12:35 +03:00
|
|
|
# include <stdio.h>
|
|
|
|
# define DTRACE(x) printf x
|
|
|
|
#else
|
|
|
|
# define DTRACE(x) ;
|
|
|
|
#endif
|
|
|
|
|
2005-11-25 18:35:47 +03:00
|
|
|
#ifdef PROFILE_MESSAGE_LOOP
|
2007-07-18 16:59:05 +04:00
|
|
|
struct profile { int32 code; int32 count; bigtime_t time; };
|
|
|
|
static profile sMessageProfile[AS_LAST_CODE];
|
|
|
|
static profile sRedrawProcessingTime;
|
|
|
|
//static profile sNextMessageTime;
|
2005-11-25 18:35:47 +03:00
|
|
|
#endif
|
|
|
|
|
2005-12-12 00:46:35 +03:00
|
|
|
|
|
|
|
struct direct_window_data {
|
|
|
|
direct_window_data();
|
|
|
|
~direct_window_data();
|
|
|
|
|
|
|
|
status_t InitCheck() const;
|
2007-05-08 01:26:33 +04:00
|
|
|
|
2005-12-12 00:46:35 +03:00
|
|
|
sem_id sem;
|
|
|
|
sem_id sem_ack;
|
|
|
|
area_id area;
|
|
|
|
bool started;
|
2007-05-08 01:26:33 +04:00
|
|
|
int next_buffer_state;
|
2005-12-12 00:46:35 +03:00
|
|
|
direct_buffer_info *buffer_info;
|
2005-10-11 09:25:52 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2005-12-12 00:46:35 +03:00
|
|
|
direct_window_data::direct_window_data()
|
|
|
|
:
|
|
|
|
sem(-1),
|
|
|
|
sem_ack(-1),
|
|
|
|
area(-1),
|
|
|
|
started(false),
|
2007-05-08 01:26:33 +04:00
|
|
|
next_buffer_state(0),
|
2005-12-12 00:46:35 +03:00
|
|
|
buffer_info(NULL)
|
|
|
|
{
|
|
|
|
area = create_area("direct area", (void **)&buffer_info,
|
|
|
|
B_ANY_ADDRESS, B_PAGE_SIZE, B_NO_LOCK, B_READ_WRITE);
|
|
|
|
|
|
|
|
sem = create_sem(0, "direct sem");
|
|
|
|
sem_ack = create_sem(0, "direct sem ack");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
direct_window_data::~direct_window_data()
|
|
|
|
{
|
|
|
|
// this should make the client die in case it's still running
|
|
|
|
buffer_info->bits = NULL;
|
|
|
|
buffer_info->bytes_per_row = 0;
|
|
|
|
|
|
|
|
delete_area(area);
|
|
|
|
delete_sem(sem);
|
|
|
|
delete_sem(sem_ack);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
direct_window_data::InitCheck() const
|
|
|
|
{
|
|
|
|
if (area < B_OK)
|
|
|
|
return area;
|
|
|
|
if (sem < B_OK)
|
|
|
|
return sem;
|
|
|
|
if (sem_ack < B_OK)
|
|
|
|
return sem_ack;
|
|
|
|
|
|
|
|
return B_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// #pragma mark -
|
|
|
|
|
|
|
|
|
2003-02-12 04:11:55 +03:00
|
|
|
/*!
|
2005-11-24 20:45:26 +03:00
|
|
|
Sets up the basic BWindow counterpart - you have to call Init() before
|
|
|
|
you can actually use it, though.
|
2003-02-12 04:11:55 +03:00
|
|
|
*/
|
2005-06-23 22:48:10 +04:00
|
|
|
ServerWindow::ServerWindow(const char *title, ServerApp *app,
|
2005-11-14 15:08:21 +03:00
|
|
|
port_id clientPort, port_id looperPort, int32 clientToken)
|
2005-07-23 22:30:48 +04:00
|
|
|
: MessageLooper(title && *title ? title : "Unnamed Window"),
|
2005-11-11 16:06:22 +03:00
|
|
|
fTitle(NULL),
|
2005-10-31 14:05:52 +03:00
|
|
|
fDesktop(app->GetDesktop()),
|
2005-06-23 21:40:35 +04:00
|
|
|
fServerApp(app),
|
2005-11-24 20:45:26 +03:00
|
|
|
fWindowLayer(NULL),
|
2006-06-20 03:42:22 +04:00
|
|
|
fWindowAddedToDesktop(false),
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2005-06-24 02:43:11 +04:00
|
|
|
fClientTeam(app->ClientTeam()),
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2005-06-24 02:43:11 +04:00
|
|
|
fMessagePort(-1),
|
2005-06-23 21:40:35 +04:00
|
|
|
fClientReplyPort(clientPort),
|
2005-04-16 17:30:49 +04:00
|
|
|
fClientLooperPort(looperPort),
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2005-11-14 15:08:21 +03:00
|
|
|
fClientToken(clientToken),
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2005-10-11 09:25:52 +04:00
|
|
|
fCurrentLayer(NULL),
|
2005-12-08 15:41:19 +03:00
|
|
|
fCurrentDrawingRegion(),
|
|
|
|
fCurrentDrawingRegionValid(false),
|
|
|
|
|
2005-10-11 09:25:52 +04:00
|
|
|
fDirectWindowData(NULL)
|
2003-02-07 15:53:57 +03:00
|
|
|
{
|
2005-06-23 22:48:10 +04:00
|
|
|
STRACE(("ServerWindow(%s)::ServerWindow()\n", title));
|
2005-07-05 22:14:24 +04:00
|
|
|
|
2005-11-11 16:06:22 +03:00
|
|
|
SetTitle(title);
|
2005-07-05 22:14:24 +04:00
|
|
|
fServerToken = BPrivate::gDefaultTokens.NewToken(B_SERVER_TOKEN, this);
|
2005-11-18 16:21:07 +03:00
|
|
|
|
2005-11-20 19:24:23 +03:00
|
|
|
BMessenger::Private(fFocusMessenger).SetTo(fClientTeam,
|
|
|
|
looperPort, B_PREFERRED_TOKEN);
|
|
|
|
BMessenger::Private(fHandlerMessenger).SetTo(fClientTeam,
|
|
|
|
looperPort, clientToken);
|
2005-11-25 16:49:29 +03:00
|
|
|
|
Have I said input event handling is done?
* didn't realize that mouse events always go to the view under the mouse, not
only if its the focus window (FFM can really do harm, after all :-)).
* removed a TODO from the list: EventDispatcher::Target is now a public
class EventTarget, and every ServerWindow has one.
* as a result, EventDispatcher no longer manages targets itself, it
just maintains a list of them. You no longer set messengers, you
only set targets.
* customization of the message filters, they no longer inherit from
BMessageFilter (but EventFilter).
* a message target is no longer set explicetly anywhere, it's only
changed in the message filters if needed.
* therefore, no more locking mess in the EventDispatcher needed.
* this also made the EventDispatcher::fLastFocus stuff superfluous.
* moved the RootLayer::MouseEventHandler() into the message filter.
* Replaced RootLayer::_ChildAt() with WindowAt().
* WindowLayer now has an idea if it has focus or not, it no longer needs
to query the RootLayer for this - maybe we should rename "focus" to
"active", though (as far as layers are concerned).
* the "_view_token" data is now added from the EventDispatcher, not
the (Window)Layer class anymore.
* removed Layer::MouseWheelChanged() as we currently don't need it
(if the need arises, we can add it back later again)
* there is still no mouse moved message sent when opening a window
under the cursor, though...
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15228 a95241bf-73f2-0310-859d-f6bbb57e9c96
2005-11-29 19:01:41 +03:00
|
|
|
fEventTarget.SetTo(fFocusMessenger);
|
|
|
|
|
2005-11-25 16:49:29 +03:00
|
|
|
fDeathSemaphore = create_sem(0, "window death");
|
2003-02-07 15:53:57 +03:00
|
|
|
}
|
2005-05-26 19:04:45 +04:00
|
|
|
|
2007-07-18 16:59:05 +04:00
|
|
|
#ifdef PROFILE_MESSAGE_LOOP
|
|
|
|
static int
|
|
|
|
compare_message_profiles(const void* _a, const void* _b)
|
|
|
|
{
|
|
|
|
profile* a = (profile*)*(void**)_a;
|
|
|
|
profile* b = (profile*)*(void**)_b;
|
|
|
|
if (a->time < b->time)
|
|
|
|
return 1;
|
|
|
|
if (a->time > b->time)
|
|
|
|
return -1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2005-05-26 19:04:45 +04:00
|
|
|
|
2005-11-24 16:14:49 +03:00
|
|
|
//! Tears down all connections the main app_server objects, and deletes some internals.
|
2005-06-24 02:43:11 +04:00
|
|
|
ServerWindow::~ServerWindow()
|
2003-02-07 15:53:57 +03:00
|
|
|
{
|
2005-11-30 18:47:01 +03:00
|
|
|
STRACE(("ServerWindow(%s@%p):~ServerWindow()\n", fTitle, this));
|
2005-02-28 23:23:51 +03:00
|
|
|
|
2006-06-20 03:42:22 +04:00
|
|
|
if (!fWindowLayer->IsOffscreenWindow()) {
|
|
|
|
fWindowAddedToDesktop = false;
|
2005-11-30 18:47:01 +03:00
|
|
|
fDesktop->RemoveWindow(fWindowLayer);
|
2006-06-20 03:42:22 +04:00
|
|
|
}
|
2005-07-07 02:39:15 +04:00
|
|
|
|
2006-04-22 02:43:23 +04:00
|
|
|
if (App() != NULL)
|
|
|
|
App()->RemoveWindow(this);
|
|
|
|
|
2006-06-20 03:42:22 +04:00
|
|
|
delete fWindowLayer;
|
|
|
|
|
2005-11-11 16:06:22 +03:00
|
|
|
free(fTitle);
|
2005-07-07 02:39:15 +04:00
|
|
|
delete_port(fMessagePort);
|
2005-02-28 23:23:51 +03:00
|
|
|
|
2005-07-05 22:14:24 +04:00
|
|
|
BPrivate::gDefaultTokens.RemoveToken(fServerToken);
|
|
|
|
|
2005-10-11 09:25:52 +04:00
|
|
|
delete fDirectWindowData;
|
2005-11-30 18:47:01 +03:00
|
|
|
STRACE(("ServerWindow(%p) will exit NOW\n", this));
|
2005-11-25 16:49:29 +03:00
|
|
|
|
|
|
|
delete_sem(fDeathSemaphore);
|
2005-11-25 18:35:47 +03:00
|
|
|
|
|
|
|
#ifdef PROFILE_MESSAGE_LOOP
|
2007-07-18 16:59:05 +04:00
|
|
|
BList profiles;
|
2005-11-25 18:35:47 +03:00
|
|
|
for (int32 i = 0; i < AS_LAST_CODE; i++) {
|
|
|
|
if (sMessageProfile[i].count == 0)
|
|
|
|
continue;
|
2007-07-18 16:59:05 +04:00
|
|
|
sMessageProfile[i].code = i;
|
|
|
|
profiles.AddItem(&sMessageProfile[i]);
|
2005-11-25 18:35:47 +03:00
|
|
|
}
|
2007-07-18 16:59:05 +04:00
|
|
|
|
|
|
|
profiles.SortItems(compare_message_profiles);
|
|
|
|
|
|
|
|
BString codeName;
|
|
|
|
int32 count = profiles.CountItems();
|
|
|
|
for (int32 i = 0; i < count; i++) {
|
|
|
|
profile* p = (profile*)profiles.ItemAtFast(i);
|
|
|
|
string_for_message_code(p->code, codeName);
|
|
|
|
printf("[%s] called %ld times, %g secs (%Ld usecs per call)\n",
|
|
|
|
codeName.String(), p->count, p->time / 1000000.0,
|
|
|
|
p->time / p->count);
|
|
|
|
}
|
|
|
|
if (sRedrawProcessingTime.count > 0) {
|
|
|
|
printf("average redraw processing time: %g secs, count: %ld (%lld usecs per call)\n",
|
|
|
|
sRedrawProcessingTime.time / 1000000.0, sRedrawProcessingTime.count,
|
|
|
|
sRedrawProcessingTime.time / sRedrawProcessingTime.count);
|
|
|
|
}
|
|
|
|
// if (sNextMessageTime.count > 0) {
|
|
|
|
// printf("average NextMessage() time: %g secs, count: %ld (%lld usecs per call)\n",
|
|
|
|
// sNextMessageTime.time / 1000000.0, sNextMessageTime.count,
|
|
|
|
// sNextMessageTime.time / sNextMessageTime.count);
|
|
|
|
// }
|
2005-11-25 18:35:47 +03:00
|
|
|
#endif
|
2003-02-07 15:53:57 +03:00
|
|
|
}
|
2004-06-26 06:15:48 +04:00
|
|
|
|
2005-06-24 02:43:11 +04:00
|
|
|
|
|
|
|
status_t
|
2005-12-01 15:07:28 +03:00
|
|
|
ServerWindow::Init(BRect frame, window_look look, window_feel feel,
|
|
|
|
uint32 flags, uint32 workspace)
|
2005-06-24 02:43:11 +04:00
|
|
|
{
|
2006-04-22 02:43:23 +04:00
|
|
|
if (!App()->AddWindow(this)) {
|
|
|
|
fServerApp = NULL;
|
|
|
|
return B_NO_MEMORY;
|
|
|
|
}
|
|
|
|
|
2005-11-01 04:32:49 +03:00
|
|
|
if (fTitle == NULL)
|
|
|
|
return B_NO_MEMORY;
|
|
|
|
|
offscreen bitmaps work, tested on Haiku as well, supports all colorspaces that BBitmap::ImportBits() supports. It uses a fallback for non-B_RGB(A)32 bitmaps. Added support for B_SUB_PIXEL_PRECISION view flags, though it is a bit hacky, since I had to add it to LayerData, even though it is not a true part of stack data. Added Layer::SetFlags() to enforce code path and update fLayerData. Cleaned up DisplayDriverPainter and DisplayDriver API (changed some const BRect& rect to simply BRect rect in order to be able to reuse it in the code), moved Painter.h, the test environment only draws the changed part of the frame buffer again - this causes a lot less CPU overhead, Painter special cases stroke width of 1.0 to use square caps, which is similar to R5 implementation and removes a lot of problems with non-straight line drawing, ServerWindow uses the DisplayDriver from it's WinBorder instead of the one from the Desktop (needed for offscreen windows, which have their own DisplayDriverPainter), it also checks for GetRootLayer() == NULL, because offscreen layers are not attached to a RootLayer, there was a fix for scrolling which worked at least in the test environment, it is now defunced, because Adi moved _CopyBits to Layer... I need to reenable it later, LayerData has no more fEscapementDelta, also fixed fFontAliasing (which was thought to overriding the font flags, and now works as such again), Desktop initialises the menu_info and scroll_bar_info stuff, which makes ScrollBars work actually... hope I didn't forget something.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13448 a95241bf-73f2-0310-859d-f6bbb57e9c96
2005-07-05 20:17:16 +04:00
|
|
|
// fMessagePort is the port to which the app sends messages for the server
|
|
|
|
fMessagePort = create_port(100, fTitle);
|
2005-06-24 02:43:11 +04:00
|
|
|
if (fMessagePort < B_OK)
|
|
|
|
return fMessagePort;
|
|
|
|
|
offscreen bitmaps work, tested on Haiku as well, supports all colorspaces that BBitmap::ImportBits() supports. It uses a fallback for non-B_RGB(A)32 bitmaps. Added support for B_SUB_PIXEL_PRECISION view flags, though it is a bit hacky, since I had to add it to LayerData, even though it is not a true part of stack data. Added Layer::SetFlags() to enforce code path and update fLayerData. Cleaned up DisplayDriverPainter and DisplayDriver API (changed some const BRect& rect to simply BRect rect in order to be able to reuse it in the code), moved Painter.h, the test environment only draws the changed part of the frame buffer again - this causes a lot less CPU overhead, Painter special cases stroke width of 1.0 to use square caps, which is similar to R5 implementation and removes a lot of problems with non-straight line drawing, ServerWindow uses the DisplayDriver from it's WinBorder instead of the one from the Desktop (needed for offscreen windows, which have their own DisplayDriverPainter), it also checks for GetRootLayer() == NULL, because offscreen layers are not attached to a RootLayer, there was a fix for scrolling which worked at least in the test environment, it is now defunced, because Adi moved _CopyBits to Layer... I need to reenable it later, LayerData has no more fEscapementDelta, also fixed fFontAliasing (which was thought to overriding the font flags, and now works as such again), Desktop initialises the menu_info and scroll_bar_info stuff, which makes ScrollBars work actually... hope I didn't forget something.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13448 a95241bf-73f2-0310-859d-f6bbb57e9c96
2005-07-05 20:17:16 +04:00
|
|
|
fLink.SetSenderPort(fClientReplyPort);
|
|
|
|
fLink.SetReceiverPort(fMessagePort);
|
|
|
|
|
2005-12-23 18:54:41 +03:00
|
|
|
// We cannot call MakeWindowLayer in the constructor, since it
|
|
|
|
// is a virtual function!
|
2005-11-24 20:45:26 +03:00
|
|
|
fWindowLayer = MakeWindowLayer(frame, fTitle, look, feel, flags, workspace);
|
|
|
|
if (!fWindowLayer)
|
offscreen bitmaps work, tested on Haiku as well, supports all colorspaces that BBitmap::ImportBits() supports. It uses a fallback for non-B_RGB(A)32 bitmaps. Added support for B_SUB_PIXEL_PRECISION view flags, though it is a bit hacky, since I had to add it to LayerData, even though it is not a true part of stack data. Added Layer::SetFlags() to enforce code path and update fLayerData. Cleaned up DisplayDriverPainter and DisplayDriver API (changed some const BRect& rect to simply BRect rect in order to be able to reuse it in the code), moved Painter.h, the test environment only draws the changed part of the frame buffer again - this causes a lot less CPU overhead, Painter special cases stroke width of 1.0 to use square caps, which is similar to R5 implementation and removes a lot of problems with non-straight line drawing, ServerWindow uses the DisplayDriver from it's WinBorder instead of the one from the Desktop (needed for offscreen windows, which have their own DisplayDriverPainter), it also checks for GetRootLayer() == NULL, because offscreen layers are not attached to a RootLayer, there was a fix for scrolling which worked at least in the test environment, it is now defunced, because Adi moved _CopyBits to Layer... I need to reenable it later, LayerData has no more fEscapementDelta, also fixed fFontAliasing (which was thought to overriding the font flags, and now works as such again), Desktop initialises the menu_info and scroll_bar_info stuff, which makes ScrollBars work actually... hope I didn't forget something.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13448 a95241bf-73f2-0310-859d-f6bbb57e9c96
2005-07-05 20:17:16 +04:00
|
|
|
return B_NO_MEMORY;
|
|
|
|
|
2006-06-20 03:42:22 +04:00
|
|
|
if (!fWindowLayer->IsOffscreenWindow()) {
|
2005-11-30 18:47:01 +03:00
|
|
|
fDesktop->AddWindow(fWindowLayer);
|
2006-06-20 03:42:22 +04:00
|
|
|
fWindowAddedToDesktop = true;
|
|
|
|
}
|
offscreen bitmaps work, tested on Haiku as well, supports all colorspaces that BBitmap::ImportBits() supports. It uses a fallback for non-B_RGB(A)32 bitmaps. Added support for B_SUB_PIXEL_PRECISION view flags, though it is a bit hacky, since I had to add it to LayerData, even though it is not a true part of stack data. Added Layer::SetFlags() to enforce code path and update fLayerData. Cleaned up DisplayDriverPainter and DisplayDriver API (changed some const BRect& rect to simply BRect rect in order to be able to reuse it in the code), moved Painter.h, the test environment only draws the changed part of the frame buffer again - this causes a lot less CPU overhead, Painter special cases stroke width of 1.0 to use square caps, which is similar to R5 implementation and removes a lot of problems with non-straight line drawing, ServerWindow uses the DisplayDriver from it's WinBorder instead of the one from the Desktop (needed for offscreen windows, which have their own DisplayDriverPainter), it also checks for GetRootLayer() == NULL, because offscreen layers are not attached to a RootLayer, there was a fix for scrolling which worked at least in the test environment, it is now defunced, because Adi moved _CopyBits to Layer... I need to reenable it later, LayerData has no more fEscapementDelta, also fixed fFontAliasing (which was thought to overriding the font flags, and now works as such again), Desktop initialises the menu_info and scroll_bar_info stuff, which makes ScrollBars work actually... hope I didn't forget something.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13448 a95241bf-73f2-0310-859d-f6bbb57e9c96
2005-07-05 20:17:16 +04:00
|
|
|
|
2005-06-24 02:43:11 +04:00
|
|
|
return B_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
ServerWindow::Run()
|
|
|
|
{
|
2005-07-23 22:30:48 +04:00
|
|
|
if (!MessageLooper::Run())
|
2005-06-24 02:43:11 +04:00
|
|
|
return false;
|
|
|
|
|
2005-06-28 05:14:39 +04:00
|
|
|
// Send a reply to our window - it is expecting fMessagePort
|
|
|
|
// port and some other info
|
|
|
|
|
2005-11-14 15:08:21 +03:00
|
|
|
fLink.StartMessage(B_OK);
|
2005-06-24 02:43:11 +04:00
|
|
|
fLink.Attach<port_id>(fMessagePort);
|
2005-06-28 05:14:39 +04:00
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
int32 minWidth, maxWidth, minHeight, maxHeight;
|
2005-11-24 20:45:26 +03:00
|
|
|
fWindowLayer->GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight);
|
2005-06-28 05:14:39 +04:00
|
|
|
|
2005-11-24 20:45:26 +03:00
|
|
|
fLink.Attach<BRect>(fWindowLayer->Frame());
|
2005-12-08 15:41:19 +03:00
|
|
|
fLink.Attach<float>((float)minWidth);
|
|
|
|
fLink.Attach<float>((float)maxWidth);
|
|
|
|
fLink.Attach<float>((float)minHeight);
|
|
|
|
fLink.Attach<float>((float)maxHeight);
|
2005-06-24 02:43:11 +04:00
|
|
|
fLink.Flush();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-05-26 19:04:45 +04:00
|
|
|
void
|
2005-07-24 21:13:02 +04:00
|
|
|
ServerWindow::_PrepareQuit()
|
2003-02-12 04:11:55 +03:00
|
|
|
{
|
2005-06-24 02:43:11 +04:00
|
|
|
if (fThread == find_thread(NULL)) {
|
2005-07-07 02:39:15 +04:00
|
|
|
// make sure we're hidden
|
2006-02-27 19:14:08 +03:00
|
|
|
fDesktop->LockSingleWindow();
|
|
|
|
_Hide();
|
|
|
|
fDesktop->UnlockSingleWindow();
|
2005-07-24 21:13:02 +04:00
|
|
|
} else if (fThread >= B_OK)
|
2005-06-24 03:21:10 +04:00
|
|
|
PostMessage(AS_HIDE_WINDOW);
|
2003-02-07 15:53:57 +03:00
|
|
|
}
|
2005-05-26 19:04:45 +04:00
|
|
|
|
2005-06-24 02:43:11 +04:00
|
|
|
|
2005-05-26 19:04:45 +04:00
|
|
|
void
|
2005-07-23 22:30:48 +04:00
|
|
|
ServerWindow::_GetLooperName(char* name, size_t length)
|
2003-02-07 15:53:57 +03:00
|
|
|
{
|
2005-11-11 16:06:22 +03:00
|
|
|
const char *title = Title();
|
|
|
|
if (title == NULL || !title[0])
|
|
|
|
title = "Unnamed Window";
|
|
|
|
|
|
|
|
snprintf(name, length, "w:%ld:%s", ClientTeam(), title);
|
2005-06-24 02:43:11 +04:00
|
|
|
}
|
2005-05-26 19:04:45 +04:00
|
|
|
|
2005-06-24 02:43:11 +04:00
|
|
|
|
2005-11-24 20:45:26 +03:00
|
|
|
//! Forces the window layer to update its decorator
|
2005-06-24 02:43:11 +04:00
|
|
|
void
|
|
|
|
ServerWindow::ReplaceDecorator()
|
|
|
|
{
|
|
|
|
if (!IsLocked())
|
|
|
|
debugger("you must lock a ServerWindow object before calling ::ReplaceDecorator()\n");
|
|
|
|
|
|
|
|
STRACE(("ServerWindow %s: Replace Decorator\n", fTitle));
|
2005-12-08 15:41:19 +03:00
|
|
|
//fWindowLayer->UpdateDecorator();
|
2003-02-07 15:53:57 +03:00
|
|
|
}
|
2005-05-26 19:04:45 +04:00
|
|
|
|
2005-10-12 18:41:02 +04:00
|
|
|
|
2005-11-24 20:45:26 +03:00
|
|
|
//! Shows the window's WindowLayer
|
2005-05-26 19:04:45 +04:00
|
|
|
void
|
2006-02-27 19:14:08 +03:00
|
|
|
ServerWindow::_Show()
|
2003-02-07 15:53:57 +03:00
|
|
|
{
|
2005-03-17 20:41:00 +03:00
|
|
|
// NOTE: if you do something else, other than sending a port message, PLEASE lock
|
2006-02-27 19:14:08 +03:00
|
|
|
STRACE(("ServerWindow %s: _Show\n", Title()));
|
2004-06-19 14:23:14 +04:00
|
|
|
|
2005-12-01 18:58:04 +03:00
|
|
|
if (fQuitting || !fWindowLayer->IsHidden() || fWindowLayer->IsOffscreenWindow())
|
2004-01-14 18:55:10 +03:00
|
|
|
return;
|
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
// TODO: race condition? maybe we need to dispatch a message to the desktop to show/hide us
|
|
|
|
// instead of doing it from this thread.
|
2005-12-12 13:41:31 +03:00
|
|
|
fDesktop->UnlockSingleWindow();
|
2005-12-01 18:58:04 +03:00
|
|
|
fDesktop->ShowWindow(fWindowLayer);
|
2005-12-12 13:41:31 +03:00
|
|
|
fDesktop->LockSingleWindow();
|
2005-11-29 02:36:59 +03:00
|
|
|
|
2005-10-11 09:25:52 +04:00
|
|
|
if (fDirectWindowData != NULL)
|
2005-11-29 02:36:59 +03:00
|
|
|
HandleDirectConnection(B_DIRECT_START | B_BUFFER_RESET);
|
2003-02-07 15:53:57 +03:00
|
|
|
}
|
2005-05-26 19:04:45 +04:00
|
|
|
|
2005-10-12 18:41:02 +04:00
|
|
|
|
2005-11-24 20:45:26 +03:00
|
|
|
//! Hides the window's WindowLayer
|
2005-05-26 19:04:45 +04:00
|
|
|
void
|
2006-02-27 19:14:08 +03:00
|
|
|
ServerWindow::_Hide()
|
2003-02-07 15:53:57 +03:00
|
|
|
{
|
2005-03-17 20:41:00 +03:00
|
|
|
// NOTE: if you do something else, other than sending a port message, PLEASE lock
|
2006-02-27 19:14:08 +03:00
|
|
|
STRACE(("ServerWindow %s: _Hide\n", Title()));
|
2004-06-19 14:23:14 +04:00
|
|
|
|
2005-12-01 18:58:04 +03:00
|
|
|
if (fWindowLayer->IsHidden() || fWindowLayer->IsOffscreenWindow())
|
2004-01-14 18:55:10 +03:00
|
|
|
return;
|
|
|
|
|
2005-10-12 01:37:47 +04:00
|
|
|
if (fDirectWindowData != NULL)
|
2005-11-08 11:32:32 +03:00
|
|
|
HandleDirectConnection(B_DIRECT_STOP);
|
2005-11-29 02:36:59 +03:00
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
// TODO: race condition? maybe we need to dispatch a message to the desktop to show/hide us
|
|
|
|
// instead of doing it from this thread.
|
2005-12-12 13:41:31 +03:00
|
|
|
fDesktop->UnlockSingleWindow();
|
2005-12-01 18:58:04 +03:00
|
|
|
fDesktop->HideWindow(fWindowLayer);
|
2005-12-12 13:41:31 +03:00
|
|
|
fDesktop->LockSingleWindow();
|
2003-02-12 04:11:55 +03:00
|
|
|
}
|
2005-05-26 19:04:45 +04:00
|
|
|
|
|
|
|
|
2005-12-12 16:14:21 +03:00
|
|
|
void
|
|
|
|
ServerWindow::RequestRedraw()
|
|
|
|
{
|
|
|
|
PostMessage(AS_REDRAW, 0);
|
|
|
|
// we don't care if this fails - it's only a notification, and if
|
|
|
|
// it fails, there are obviously enough messages in the queue
|
|
|
|
// already
|
|
|
|
|
|
|
|
atomic_add(&fRedrawRequested, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-07-05 23:20:19 +04:00
|
|
|
void
|
|
|
|
ServerWindow::SetTitle(const char* newTitle)
|
|
|
|
{
|
2005-11-11 16:06:22 +03:00
|
|
|
char* oldTitle = fTitle;
|
2005-11-01 04:32:49 +03:00
|
|
|
|
2005-11-11 16:06:22 +03:00
|
|
|
if (newTitle == NULL)
|
|
|
|
newTitle = "";
|
2005-11-01 04:32:49 +03:00
|
|
|
|
2005-11-11 16:06:22 +03:00
|
|
|
fTitle = strdup(newTitle);
|
2005-11-01 04:32:49 +03:00
|
|
|
if (fTitle == NULL) {
|
2005-11-11 16:06:22 +03:00
|
|
|
// out of memory condition
|
2005-11-01 04:32:49 +03:00
|
|
|
fTitle = oldTitle;
|
2005-07-05 23:20:19 +04:00
|
|
|
return;
|
2005-11-01 04:32:49 +03:00
|
|
|
}
|
|
|
|
|
2005-11-11 16:06:22 +03:00
|
|
|
free(oldTitle);
|
2005-07-05 23:20:19 +04:00
|
|
|
|
|
|
|
if (Thread() >= B_OK) {
|
|
|
|
char name[B_OS_NAME_LENGTH];
|
2005-11-11 16:06:22 +03:00
|
|
|
_GetLooperName(name, sizeof(name));
|
2005-07-05 23:20:19 +04:00
|
|
|
rename_thread(Thread(), name);
|
|
|
|
}
|
|
|
|
|
2006-04-07 23:14:25 +04:00
|
|
|
if (fWindowLayer != NULL) {
|
|
|
|
fDesktop->UnlockSingleWindow();
|
2005-12-09 01:15:12 +03:00
|
|
|
fDesktop->SetWindowTitle(fWindowLayer, newTitle);
|
2006-04-07 23:14:25 +04:00
|
|
|
fDesktop->LockSingleWindow();
|
|
|
|
}
|
2005-07-05 23:20:19 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-06-24 02:43:11 +04:00
|
|
|
//! Requests that the ServerWindow's BWindow quit
|
2005-05-26 19:04:45 +04:00
|
|
|
void
|
2005-06-24 02:43:11 +04:00
|
|
|
ServerWindow::NotifyQuitRequested()
|
|
|
|
{
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
// NOTE: if you do something else, other than sending a port message,
|
|
|
|
// PLEASE lock
|
2005-06-24 02:43:11 +04:00
|
|
|
STRACE(("ServerWindow %s: Quit\n", fTitle));
|
|
|
|
|
|
|
|
BMessage msg(B_QUIT_REQUESTED);
|
|
|
|
SendMessageToClient(&msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
ServerWindow::NotifyMinimize(bool minimize)
|
2004-06-11 18:47:36 +04:00
|
|
|
{
|
2006-02-28 21:31:16 +03:00
|
|
|
if (fWindowLayer->Feel() != B_NORMAL_WINDOW_FEEL)
|
|
|
|
return;
|
|
|
|
|
2006-02-09 21:28:29 +03:00
|
|
|
// The client is responsible for the actual minimization
|
2005-05-26 19:04:45 +04:00
|
|
|
|
2006-02-09 21:28:29 +03:00
|
|
|
BMessage msg(B_MINIMIZE);
|
|
|
|
msg.AddInt64("when", real_time_clock_usecs());
|
|
|
|
msg.AddBool("minimize", minimize);
|
2005-05-26 19:04:45 +04:00
|
|
|
|
2006-02-09 21:28:29 +03:00
|
|
|
SendMessageToClient(&msg);
|
2003-11-15 03:28:40 +03:00
|
|
|
}
|
2005-05-26 19:04:45 +04:00
|
|
|
|
2006-02-09 21:28:29 +03:00
|
|
|
|
2005-05-26 19:04:45 +04:00
|
|
|
//! Sends a message to the client to perform a Zoom
|
|
|
|
void
|
2005-06-24 02:43:11 +04:00
|
|
|
ServerWindow::NotifyZoom()
|
2004-06-11 18:47:36 +04:00
|
|
|
{
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
// NOTE: if you do something else, other than sending a port message,
|
|
|
|
// PLEASE lock
|
2005-05-26 19:04:45 +04:00
|
|
|
BMessage msg(B_ZOOM);
|
2004-06-11 06:46:48 +04:00
|
|
|
SendMessageToClient(&msg);
|
2003-11-15 03:28:40 +03:00
|
|
|
}
|
2005-05-26 19:04:45 +04:00
|
|
|
|
2005-07-05 22:14:24 +04:00
|
|
|
|
|
|
|
void
|
|
|
|
ServerWindow::GetInfo(window_info& info)
|
|
|
|
{
|
|
|
|
info.team = ClientTeam();
|
|
|
|
info.server_token = ServerToken();
|
|
|
|
|
|
|
|
info.thread = Thread();
|
|
|
|
info.client_token = ClientToken();
|
|
|
|
info.client_port = fClientLooperPort;
|
2005-11-24 20:45:26 +03:00
|
|
|
info.workspaces = fWindowLayer->Workspaces();
|
2005-07-05 22:14:24 +04:00
|
|
|
|
|
|
|
info.layer = 0; // ToDo: what is this???
|
2005-11-24 20:45:26 +03:00
|
|
|
info.feel = fWindowLayer->Feel();
|
2005-12-08 15:41:19 +03:00
|
|
|
info.flags = fWindowLayer->Flags();
|
2005-11-24 20:45:26 +03:00
|
|
|
info.window_left = (int)floor(fWindowLayer->Frame().left);
|
|
|
|
info.window_top = (int)floor(fWindowLayer->Frame().top);
|
|
|
|
info.window_right = (int)floor(fWindowLayer->Frame().right);
|
|
|
|
info.window_bottom = (int)floor(fWindowLayer->Frame().bottom);
|
|
|
|
|
2006-02-09 21:28:29 +03:00
|
|
|
info.show_hide_level = fWindowLayer->IsHidden() ? 1 : 0; // ???
|
|
|
|
info.is_mini = fWindowLayer->IsMinimized();
|
2005-07-05 22:14:24 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
void
|
|
|
|
ServerWindow::ResyncDrawState()
|
|
|
|
{
|
|
|
|
_UpdateDrawState(fCurrentLayer);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-06-20 03:42:22 +04:00
|
|
|
/*!
|
|
|
|
Returns the ServerWindow's WindowLayer, if it exists and has been
|
|
|
|
added to the Desktop already.
|
|
|
|
In other words, you cannot assume this method will always give you
|
|
|
|
a valid pointer.
|
|
|
|
*/
|
2006-02-28 21:31:16 +03:00
|
|
|
WindowLayer*
|
|
|
|
ServerWindow::Window() const
|
|
|
|
{
|
|
|
|
// TODO: ensure desktop is locked!
|
2006-06-20 03:42:22 +04:00
|
|
|
if (!fWindowAddedToDesktop)
|
|
|
|
return NULL;
|
|
|
|
|
2006-02-28 21:31:16 +03:00
|
|
|
return fWindowLayer;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
ViewLayer*
|
2006-02-27 19:14:08 +03:00
|
|
|
ServerWindow::_CreateLayerTree(BPrivate::LinkReceiver &link, ViewLayer **_parent)
|
2004-06-11 18:47:36 +04:00
|
|
|
{
|
2004-06-19 14:23:14 +04:00
|
|
|
// NOTE: no need to check for a lock. This is a private method.
|
2004-06-11 18:47:36 +04:00
|
|
|
|
|
|
|
int32 token;
|
|
|
|
BRect frame;
|
|
|
|
uint32 resizeMask;
|
2005-03-21 23:29:24 +03:00
|
|
|
uint32 eventMask;
|
|
|
|
uint32 eventOptions;
|
2004-06-11 18:47:36 +04:00
|
|
|
uint32 flags;
|
|
|
|
bool hidden;
|
2005-06-16 04:46:02 +04:00
|
|
|
int32 parentToken;
|
2005-12-08 15:41:19 +03:00
|
|
|
char* name = NULL;
|
2005-06-10 20:20:38 +04:00
|
|
|
rgb_color viewColor;
|
2006-04-04 05:51:16 +04:00
|
|
|
BPoint scrollingOffset;
|
2005-05-26 19:04:45 +04:00
|
|
|
|
2004-10-16 06:02:27 +04:00
|
|
|
link.Read<int32>(&token);
|
|
|
|
link.ReadString(&name);
|
|
|
|
link.Read<BRect>(&frame);
|
2006-04-04 05:51:16 +04:00
|
|
|
link.Read<BPoint>(&scrollingOffset);
|
2004-10-16 06:02:27 +04:00
|
|
|
link.Read<uint32>(&resizeMask);
|
2005-03-21 23:29:24 +03:00
|
|
|
link.Read<uint32>(&eventMask);
|
|
|
|
link.Read<uint32>(&eventOptions);
|
2004-10-16 06:02:27 +04:00
|
|
|
link.Read<uint32>(&flags);
|
|
|
|
link.Read<bool>(&hidden);
|
2005-06-16 04:46:02 +04:00
|
|
|
link.Read<rgb_color>(&viewColor);
|
|
|
|
link.Read<int32>(&parentToken);
|
2005-05-26 19:04:45 +04:00
|
|
|
|
2006-02-27 19:14:08 +03:00
|
|
|
STRACE(("ServerWindow(%s)::_CreateLayerTree()-> layer %s, token %ld\n",
|
2005-06-23 22:48:10 +04:00
|
|
|
fTitle, name, token));
|
2005-02-28 23:23:51 +03:00
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
ViewLayer* newLayer;
|
2005-07-01 10:53:07 +04:00
|
|
|
|
|
|
|
if (link.Code() == AS_LAYER_CREATE_ROOT
|
2005-12-08 15:41:19 +03:00
|
|
|
&& (fWindowLayer->Flags() & kWorkspacesWindowFlag) != 0) {
|
2005-07-01 10:53:07 +04:00
|
|
|
// this is a workspaces window!
|
2006-04-04 05:51:16 +04:00
|
|
|
newLayer = new (nothrow) WorkspacesLayer(frame, scrollingOffset, name,
|
|
|
|
token, resizeMask, flags);
|
2005-07-01 10:53:07 +04:00
|
|
|
} else {
|
2006-04-04 05:51:16 +04:00
|
|
|
newLayer = new (nothrow) ViewLayer(frame, scrollingOffset, name, token,
|
|
|
|
resizeMask, flags);
|
2005-07-01 10:53:07 +04:00
|
|
|
}
|
2005-05-26 19:04:45 +04:00
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
free(name);
|
|
|
|
|
2005-11-04 12:52:56 +03:00
|
|
|
if (newLayer == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
2004-06-11 18:47:36 +04:00
|
|
|
// there is no way of setting this, other than manually :-)
|
2005-11-04 15:15:36 +03:00
|
|
|
newLayer->SetViewColor(viewColor);
|
2005-12-08 15:41:19 +03:00
|
|
|
newLayer->SetHidden(hidden);
|
|
|
|
newLayer->SetEventMask(eventMask, eventOptions);
|
2004-03-28 19:00:31 +04:00
|
|
|
|
2006-06-13 01:54:24 +04:00
|
|
|
if (eventMask != 0 || eventOptions != 0) {
|
|
|
|
fDesktop->UnlockSingleWindow();
|
|
|
|
fDesktop->EventDispatcher().AddListener(EventTarget(),
|
|
|
|
newLayer->Token(), eventMask, eventOptions);
|
|
|
|
fDesktop->LockSingleWindow();
|
|
|
|
}
|
|
|
|
|
2005-11-04 12:52:56 +03:00
|
|
|
DesktopSettings settings(fDesktop);
|
|
|
|
ServerFont font;
|
|
|
|
settings.GetDefaultPlainFont(font);
|
2005-11-04 15:15:36 +03:00
|
|
|
newLayer->CurrentState()->SetFont(font);
|
2005-11-04 12:52:56 +03:00
|
|
|
|
2005-06-16 04:46:02 +04:00
|
|
|
if (_parent) {
|
2005-12-08 15:41:19 +03:00
|
|
|
ViewLayer *parent;
|
2005-11-24 16:14:49 +03:00
|
|
|
if (App()->ViewTokens().GetToken(parentToken, B_HANDLER_TOKEN,
|
|
|
|
(void**)&parent) != B_OK
|
2005-12-08 15:41:19 +03:00
|
|
|
|| parent->Window()->ServerWindow() != this) {
|
2005-06-16 04:46:02 +04:00
|
|
|
CRITICAL("View token not found!\n");
|
2005-11-24 16:14:49 +03:00
|
|
|
parent = NULL;
|
|
|
|
}
|
2005-06-16 04:46:02 +04:00
|
|
|
|
|
|
|
*_parent = parent;
|
|
|
|
}
|
2004-07-30 19:16:59 +04:00
|
|
|
|
2004-04-03 19:05:49 +04:00
|
|
|
return newLayer;
|
2004-03-28 19:00:31 +04:00
|
|
|
}
|
2005-05-26 19:04:45 +04:00
|
|
|
|
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
/*!
|
|
|
|
Dispatches all window messages, and those view messages that
|
|
|
|
don't need a valid fCurrentLayer (ie. layer creation).
|
|
|
|
*/
|
2005-05-26 19:04:45 +04:00
|
|
|
void
|
2005-06-24 02:43:11 +04:00
|
|
|
ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
|
2003-02-24 18:47:06 +03:00
|
|
|
{
|
2005-05-26 19:04:45 +04:00
|
|
|
switch (code) {
|
2005-12-08 15:41:19 +03:00
|
|
|
case AS_SHOW_WINDOW:
|
|
|
|
STRACE(("ServerWindow %s: Message AS_SHOW_WINDOW\n", Title()));
|
2006-02-27 19:14:08 +03:00
|
|
|
_Show();
|
2005-12-08 15:41:19 +03:00
|
|
|
break;
|
2005-04-26 17:50:34 +04:00
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
case AS_HIDE_WINDOW:
|
|
|
|
STRACE(("ServerWindow %s: Message AS_HIDE_WINDOW\n", Title()));
|
2006-02-27 19:14:08 +03:00
|
|
|
_Hide();
|
2005-04-27 21:26:57 +04:00
|
|
|
break;
|
2005-04-26 17:50:34 +04:00
|
|
|
|
2006-02-09 21:28:29 +03:00
|
|
|
case AS_MINIMIZE_WINDOW:
|
|
|
|
{
|
|
|
|
DTRACE(("ServerWindow %s: Message AS_MINIMIZE_WINDOW\n", Title()));
|
2006-02-27 19:45:58 +03:00
|
|
|
int32 showLevel;
|
2006-02-09 21:28:29 +03:00
|
|
|
bool minimize;
|
2006-02-27 19:45:58 +03:00
|
|
|
|
|
|
|
link.Read<bool>(&minimize);
|
|
|
|
if (link.Read<int32>(&showLevel) == B_OK) {
|
|
|
|
if (showLevel <= 0) {
|
|
|
|
// window is currently hidden - ignore the minimize request
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2006-02-09 21:28:29 +03:00
|
|
|
if (minimize && !fWindowLayer->IsHidden())
|
2006-02-27 19:14:08 +03:00
|
|
|
_Hide();
|
2006-02-09 21:28:29 +03:00
|
|
|
else if (!minimize && fWindowLayer->IsHidden())
|
2006-02-27 19:14:08 +03:00
|
|
|
_Show();
|
2006-02-09 21:28:29 +03:00
|
|
|
|
|
|
|
fWindowLayer->SetMinimized(minimize);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
case AS_ACTIVATE_WINDOW:
|
|
|
|
{
|
|
|
|
DTRACE(("ServerWindow %s: Message AS_ACTIVATE_WINDOW: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
|
|
|
bool activate = true;
|
2005-04-26 17:50:34 +04:00
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
link.Read<bool>(&activate);
|
2005-04-27 21:26:57 +04:00
|
|
|
|
2006-04-07 23:14:25 +04:00
|
|
|
fDesktop->UnlockSingleWindow();
|
2005-12-08 15:41:19 +03:00
|
|
|
if (activate)
|
|
|
|
fDesktop->ActivateWindow(fWindowLayer);
|
|
|
|
else
|
|
|
|
fDesktop->SendWindowBehind(fWindowLayer, NULL);
|
2006-04-07 23:14:25 +04:00
|
|
|
fDesktop->LockSingleWindow();
|
2005-03-27 09:25:59 +04:00
|
|
|
break;
|
|
|
|
}
|
2005-12-08 15:41:19 +03:00
|
|
|
case AS_SEND_BEHIND:
|
2003-09-09 01:18:39 +04:00
|
|
|
{
|
2006-03-09 21:37:28 +03:00
|
|
|
STRACE(("ServerWindow %s: Message AS_SEND_BEHIND\n", Title()));
|
2003-12-07 08:40:51 +03:00
|
|
|
int32 token;
|
2005-12-08 15:41:19 +03:00
|
|
|
team_id teamID;
|
|
|
|
status_t status;
|
|
|
|
|
2004-10-16 06:02:27 +04:00
|
|
|
link.Read<int32>(&token);
|
2005-12-08 15:41:19 +03:00
|
|
|
link.Read<team_id>(&teamID);
|
2005-06-16 04:46:02 +04:00
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
WindowLayer *behindOf;
|
|
|
|
if ((behindOf = fDesktop->FindWindowLayerByClientToken(token, teamID)) != NULL) {
|
2006-04-07 23:14:25 +04:00
|
|
|
fDesktop->UnlockSingleWindow();
|
2006-04-16 17:18:35 +04:00
|
|
|
// TODO: there is a big race condition when we unlock here (window could be gone by now)!
|
2005-12-08 15:41:19 +03:00
|
|
|
fDesktop->SendWindowBehind(fWindowLayer, behindOf);
|
2006-04-07 23:14:25 +04:00
|
|
|
fDesktop->LockSingleWindow();
|
2005-12-08 15:41:19 +03:00
|
|
|
status = B_OK;
|
|
|
|
} else
|
|
|
|
status = B_NAME_NOT_FOUND;
|
|
|
|
|
|
|
|
fLink.StartMessage(status);
|
|
|
|
fLink.Flush();
|
2003-09-09 01:18:39 +04:00
|
|
|
break;
|
|
|
|
}
|
2004-07-30 19:16:59 +04:00
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
case B_QUIT_REQUESTED:
|
|
|
|
STRACE(("ServerWindow %s received quit request\n", Title()));
|
|
|
|
NotifyQuitRequested();
|
2004-07-30 19:16:59 +04:00
|
|
|
break;
|
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
case AS_ENABLE_UPDATES:
|
2003-09-09 01:18:39 +04:00
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
STRACE(("ServerWindow %s: Message AS_ENABLE_UPDATES unimplemented\n",
|
|
|
|
Title()));
|
|
|
|
// TODO: AS_ENABLE_UPDATES
|
|
|
|
//fWindowLayer->EnableUpdateRequests();
|
2003-09-15 23:14:45 +04:00
|
|
|
break;
|
|
|
|
}
|
2005-12-08 15:41:19 +03:00
|
|
|
case AS_DISABLE_UPDATES:
|
2003-09-15 23:14:45 +04:00
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
STRACE(("ServerWindow %s: Message AS_DISABLE_UPDATES unimplemented\n",
|
|
|
|
Title()));
|
|
|
|
// TODO: AS_DISABLE_UPDATES
|
|
|
|
//fWindowLayer->DisableUpdateRequests();
|
2003-09-15 23:14:45 +04:00
|
|
|
break;
|
|
|
|
}
|
2005-12-08 15:41:19 +03:00
|
|
|
case AS_NEEDS_UPDATE:
|
2003-09-15 23:14:45 +04:00
|
|
|
{
|
2006-03-09 21:37:28 +03:00
|
|
|
STRACE(("ServerWindow %s: Message AS_NEEDS_UPDATE\n", Title()));
|
2005-12-08 15:41:19 +03:00
|
|
|
if (fWindowLayer->NeedsUpdate())
|
|
|
|
fLink.StartMessage(B_OK);
|
|
|
|
else
|
|
|
|
fLink.StartMessage(B_ERROR);
|
2005-06-24 02:43:11 +04:00
|
|
|
fLink.Flush();
|
2003-09-09 01:18:39 +04:00
|
|
|
break;
|
|
|
|
}
|
2005-12-08 15:41:19 +03:00
|
|
|
case AS_SET_WINDOW_TITLE:
|
2005-05-23 21:23:20 +04:00
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
char* newTitle;
|
|
|
|
if (link.ReadString(&newTitle) == B_OK) {
|
|
|
|
SetTitle(newTitle);
|
|
|
|
free(newTitle);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2005-05-23 21:23:20 +04:00
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
case AS_ADD_TO_SUBSET:
|
|
|
|
{
|
|
|
|
STRACE(("ServerWindow %s: Message AS_ADD_TO_SUBSET\n", Title()));
|
|
|
|
status_t status = B_ERROR;
|
2005-09-08 20:53:42 +04:00
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
int32 token;
|
|
|
|
if (link.Read<int32>(&token) == B_OK) {
|
|
|
|
WindowLayer* windowLayer = fDesktop->FindWindowLayerByClientToken(
|
|
|
|
token, App()->ClientTeam());
|
|
|
|
if (windowLayer == NULL
|
|
|
|
|| windowLayer->Feel() != B_NORMAL_WINDOW_FEEL) {
|
|
|
|
status = B_BAD_VALUE;
|
2005-11-18 18:50:30 +03:00
|
|
|
} else {
|
2006-04-07 23:14:25 +04:00
|
|
|
fDesktop->UnlockSingleWindow();
|
2006-04-16 17:18:35 +04:00
|
|
|
// TODO: there is a big race condition when we unlock here (window could be gone by now)!
|
2005-12-09 16:17:43 +03:00
|
|
|
status = fDesktop->AddWindowToSubset(fWindowLayer, windowLayer)
|
2005-12-08 15:41:19 +03:00
|
|
|
? B_OK : B_NO_MEMORY;
|
2006-04-07 23:14:25 +04:00
|
|
|
fDesktop->LockSingleWindow();
|
2005-11-18 18:50:30 +03:00
|
|
|
}
|
|
|
|
}
|
Have I said input event handling is done?
* didn't realize that mouse events always go to the view under the mouse, not
only if its the focus window (FFM can really do harm, after all :-)).
* removed a TODO from the list: EventDispatcher::Target is now a public
class EventTarget, and every ServerWindow has one.
* as a result, EventDispatcher no longer manages targets itself, it
just maintains a list of them. You no longer set messengers, you
only set targets.
* customization of the message filters, they no longer inherit from
BMessageFilter (but EventFilter).
* a message target is no longer set explicetly anywhere, it's only
changed in the message filters if needed.
* therefore, no more locking mess in the EventDispatcher needed.
* this also made the EventDispatcher::fLastFocus stuff superfluous.
* moved the RootLayer::MouseEventHandler() into the message filter.
* Replaced RootLayer::_ChildAt() with WindowAt().
* WindowLayer now has an idea if it has focus or not, it no longer needs
to query the RootLayer for this - maybe we should rename "focus" to
"active", though (as far as layers are concerned).
* the "_view_token" data is now added from the EventDispatcher, not
the (Window)Layer class anymore.
* removed Layer::MouseWheelChanged() as we currently don't need it
(if the need arises, we can add it back later again)
* there is still no mouse moved message sent when opening a window
under the cursor, though...
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15228 a95241bf-73f2-0310-859d-f6bbb57e9c96
2005-11-29 19:01:41 +03:00
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
fLink.StartMessage(status);
|
|
|
|
fLink.Flush();
|
2005-11-18 18:50:30 +03:00
|
|
|
break;
|
2005-09-03 21:55:16 +04:00
|
|
|
}
|
2005-12-08 15:41:19 +03:00
|
|
|
case AS_REMOVE_FROM_SUBSET:
|
2005-09-03 21:55:16 +04:00
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
STRACE(("ServerWindow %s: Message AS_REM_FROM_SUBSET\n", Title()));
|
|
|
|
status_t status = B_ERROR;
|
2005-09-03 21:55:16 +04:00
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
int32 token;
|
|
|
|
if (link.Read<int32>(&token) == B_OK) {
|
|
|
|
WindowLayer* windowLayer = fDesktop->FindWindowLayerByClientToken(
|
|
|
|
token, App()->ClientTeam());
|
|
|
|
if (windowLayer != NULL) {
|
2006-04-07 23:14:25 +04:00
|
|
|
fDesktop->UnlockSingleWindow();
|
2006-04-16 17:18:35 +04:00
|
|
|
// TODO: there is a big race condition when we unlock here (window could be gone by now)!
|
2005-12-09 16:17:43 +03:00
|
|
|
fDesktop->RemoveWindowFromSubset(fWindowLayer, windowLayer);
|
2006-04-07 23:14:25 +04:00
|
|
|
fDesktop->LockSingleWindow();
|
2005-12-08 15:41:19 +03:00
|
|
|
status = B_OK;
|
|
|
|
} else
|
|
|
|
status = B_BAD_VALUE;
|
2005-11-18 18:50:30 +03:00
|
|
|
}
|
2005-09-03 21:55:16 +04:00
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
fLink.StartMessage(status);
|
|
|
|
fLink.Flush();
|
2005-05-23 21:23:20 +04:00
|
|
|
break;
|
|
|
|
}
|
2005-12-08 15:41:19 +03:00
|
|
|
|
|
|
|
case AS_SET_LOOK:
|
2003-09-25 16:31:11 +04:00
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
STRACE(("ServerWindow %s: Message AS_SET_LOOK\n", Title()));
|
2005-06-28 22:56:55 +04:00
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
status_t status = B_ERROR;
|
|
|
|
int32 look;
|
|
|
|
if (link.Read<int32>(&look) == B_OK) {
|
|
|
|
// test if look is valid
|
|
|
|
status = WindowLayer::IsValidLook((window_look)look)
|
|
|
|
? B_OK : B_BAD_VALUE;
|
|
|
|
}
|
2005-04-28 13:44:29 +04:00
|
|
|
|
2006-04-07 23:14:25 +04:00
|
|
|
if (status == B_OK && !fWindowLayer->IsOffscreenWindow()) {
|
|
|
|
fDesktop->UnlockSingleWindow();
|
2005-12-08 15:41:19 +03:00
|
|
|
fDesktop->SetWindowLook(fWindowLayer, (window_look)look);
|
2006-04-07 23:14:25 +04:00
|
|
|
fDesktop->LockSingleWindow();
|
|
|
|
}
|
2005-04-28 13:44:29 +04:00
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
fLink.StartMessage(status);
|
|
|
|
fLink.Flush();
|
2003-09-25 16:31:11 +04:00
|
|
|
break;
|
|
|
|
}
|
2005-12-08 15:41:19 +03:00
|
|
|
case AS_SET_FEEL:
|
2003-09-25 16:31:11 +04:00
|
|
|
{
|
2005-12-09 17:03:00 +03:00
|
|
|
STRACE(("ServerWindow %s: Message AS_SET_FEEL\n", Title()));
|
2005-06-28 22:56:55 +04:00
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
status_t status = B_ERROR;
|
|
|
|
int32 feel;
|
|
|
|
if (link.Read<int32>(&feel) == B_OK) {
|
|
|
|
// test if feel is valid
|
|
|
|
status = WindowLayer::IsValidFeel((window_feel)feel)
|
|
|
|
? B_OK : B_BAD_VALUE;
|
|
|
|
}
|
|
|
|
|
2006-04-07 23:14:25 +04:00
|
|
|
if (status == B_OK && !fWindowLayer->IsOffscreenWindow()) {
|
|
|
|
fDesktop->UnlockSingleWindow();
|
2005-12-08 15:41:19 +03:00
|
|
|
fDesktop->SetWindowFeel(fWindowLayer, (window_feel)feel);
|
2006-04-07 23:14:25 +04:00
|
|
|
fDesktop->LockSingleWindow();
|
|
|
|
}
|
2005-04-28 13:44:29 +04:00
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
fLink.StartMessage(status);
|
|
|
|
fLink.Flush();
|
2003-09-25 16:31:11 +04:00
|
|
|
break;
|
|
|
|
}
|
2005-12-08 15:41:19 +03:00
|
|
|
case AS_SET_FLAGS:
|
2003-09-25 16:31:11 +04:00
|
|
|
{
|
2005-12-09 17:03:00 +03:00
|
|
|
STRACE(("ServerWindow %s: Message AS_SET_FLAGS\n", Title()));
|
2005-12-08 15:41:19 +03:00
|
|
|
|
|
|
|
status_t status = B_ERROR;
|
|
|
|
uint32 flags;
|
|
|
|
if (link.Read<uint32>(&flags) == B_OK) {
|
|
|
|
// test if flags are valid
|
|
|
|
status = (flags & ~WindowLayer::ValidWindowFlags()) == 0
|
|
|
|
? B_OK : B_BAD_VALUE;
|
|
|
|
}
|
|
|
|
|
2006-04-07 23:14:25 +04:00
|
|
|
if (status == B_OK && !fWindowLayer->IsOffscreenWindow()) {
|
|
|
|
fDesktop->UnlockSingleWindow();
|
2005-12-08 15:41:19 +03:00
|
|
|
fDesktop->SetWindowFlags(fWindowLayer, flags);
|
2006-04-07 23:14:25 +04:00
|
|
|
fDesktop->LockSingleWindow();
|
|
|
|
}
|
2005-12-08 15:41:19 +03:00
|
|
|
|
|
|
|
fLink.StartMessage(status);
|
2005-06-24 02:43:11 +04:00
|
|
|
fLink.Flush();
|
2003-09-25 16:31:11 +04:00
|
|
|
break;
|
|
|
|
}
|
2005-12-08 15:41:19 +03:00
|
|
|
#if 0
|
|
|
|
case AS_SET_ALIGNMENT:
|
2003-09-25 21:25:38 +04:00
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
// TODO: Implement AS_SET_ALIGNMENT
|
|
|
|
STRACE(("ServerWindow %s: Message Set_Alignment unimplemented\n", Title()));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_GET_ALIGNMENT:
|
|
|
|
{
|
|
|
|
// TODO: Implement AS_GET_ALIGNMENT
|
|
|
|
STRACE(("ServerWindow %s: Message Get_Alignment unimplemented\n", Title()));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
#endif
|
2007-01-06 20:08:19 +03:00
|
|
|
case AS_IS_FRONT_WINDOW:
|
|
|
|
fLink.StartMessage(fDesktop->FrontWindow() == fWindowLayer ? B_OK : B_ERROR);
|
|
|
|
fLink.Flush();
|
|
|
|
break;
|
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
case AS_GET_WORKSPACES:
|
|
|
|
{
|
2006-02-27 19:14:08 +03:00
|
|
|
STRACE(("ServerWindow %s: Message AS_GET_WORKSPACES\n", Title()));
|
2005-12-08 15:41:19 +03:00
|
|
|
fLink.StartMessage(B_OK);
|
|
|
|
fLink.Attach<uint32>(fWindowLayer->Workspaces());
|
|
|
|
fLink.Flush();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_SET_WORKSPACES:
|
|
|
|
{
|
|
|
|
uint32 newWorkspaces;
|
2006-02-27 19:14:08 +03:00
|
|
|
if (link.Read<uint32>(&newWorkspaces) != B_OK)
|
|
|
|
break;
|
|
|
|
|
|
|
|
STRACE(("ServerWindow %s: Message AS_SET_WORKSPACES %lx\n",
|
|
|
|
Title(), newWorkspaces));
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2006-04-07 23:14:25 +04:00
|
|
|
fDesktop->UnlockSingleWindow();
|
2005-12-08 15:41:19 +03:00
|
|
|
fDesktop->SetWindowWorkspaces(fWindowLayer, newWorkspaces);
|
2006-04-07 23:14:25 +04:00
|
|
|
fDesktop->LockSingleWindow();
|
2005-12-08 15:41:19 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_WINDOW_RESIZE:
|
|
|
|
{
|
|
|
|
float xResizeBy;
|
|
|
|
float yResizeBy;
|
|
|
|
link.Read<float>(&xResizeBy);
|
2006-02-27 19:14:08 +03:00
|
|
|
if (link.Read<float>(&yResizeBy) != B_OK)
|
|
|
|
break;
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2006-02-27 19:14:08 +03:00
|
|
|
STRACE(("ServerWindow %s: Message AS_WINDOW_RESIZE %.1f, %.1f\n",
|
|
|
|
Title(), xResizeBy, yResizeBy));
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2006-06-20 03:42:22 +04:00
|
|
|
if (fWindowLayer->IsResizing()) {
|
2006-03-12 19:59:15 +03:00
|
|
|
// While the user resizes the window, we ignore
|
|
|
|
// pragmatically set window bounds
|
|
|
|
fLink.StartMessage(B_BUSY);
|
|
|
|
} else {
|
2006-04-07 23:14:25 +04:00
|
|
|
fDesktop->UnlockSingleWindow();
|
2006-03-12 19:59:15 +03:00
|
|
|
fDesktop->ResizeWindowBy(fWindowLayer, xResizeBy, yResizeBy);
|
2006-04-07 23:14:25 +04:00
|
|
|
fDesktop->LockSingleWindow();
|
2006-03-12 19:59:15 +03:00
|
|
|
fLink.StartMessage(B_OK);
|
|
|
|
}
|
|
|
|
fLink.Flush();
|
2005-12-08 15:41:19 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_WINDOW_MOVE:
|
|
|
|
{
|
|
|
|
float xMoveBy;
|
|
|
|
float yMoveBy;
|
|
|
|
link.Read<float>(&xMoveBy);
|
2006-02-27 19:14:08 +03:00
|
|
|
if (link.Read<float>(&yMoveBy) != B_OK)
|
|
|
|
break;
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2006-02-27 19:14:08 +03:00
|
|
|
STRACE(("ServerWindow %s: Message AS_WINDOW_MOVE: %.1f, %.1f\n",
|
|
|
|
Title(), xMoveBy, yMoveBy));
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2006-06-20 03:42:22 +04:00
|
|
|
if (fWindowLayer->IsDragging()) {
|
2006-03-12 19:59:15 +03:00
|
|
|
// While the user moves the window, we ignore
|
|
|
|
// pragmatically set window positions
|
|
|
|
fLink.StartMessage(B_BUSY);
|
|
|
|
} else {
|
2006-04-07 23:14:25 +04:00
|
|
|
fDesktop->UnlockSingleWindow();
|
2006-03-12 19:59:15 +03:00
|
|
|
fDesktop->MoveWindowBy(fWindowLayer, xMoveBy, yMoveBy);
|
2006-04-07 23:14:25 +04:00
|
|
|
fDesktop->LockSingleWindow();
|
2006-03-12 19:59:15 +03:00
|
|
|
fLink.StartMessage(B_OK);
|
|
|
|
}
|
|
|
|
fLink.Flush();
|
2005-12-08 15:41:19 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_SET_SIZE_LIMITS:
|
|
|
|
{
|
|
|
|
// Attached Data:
|
|
|
|
// 1) float minimum width
|
|
|
|
// 2) float maximum width
|
|
|
|
// 3) float minimum height
|
|
|
|
// 4) float maximum height
|
|
|
|
|
|
|
|
// TODO: for now, move the client to int32 as well!
|
|
|
|
int32 minWidth, maxWidth, minHeight, maxHeight;
|
|
|
|
float value;
|
|
|
|
link.Read<float>(&value); minWidth = (int32)value;
|
|
|
|
link.Read<float>(&value); maxWidth = (int32)value;
|
|
|
|
link.Read<float>(&value); minHeight = (int32)value;
|
|
|
|
link.Read<float>(&value); maxHeight = (int32)value;
|
|
|
|
/*
|
|
|
|
link.Read<int32>(&minWidth);
|
|
|
|
link.Read<int32>(&maxWidth);
|
|
|
|
link.Read<int32>(&minHeight);
|
|
|
|
link.Read<int32>(&maxHeight);
|
|
|
|
*/
|
2006-03-10 14:42:58 +03:00
|
|
|
fDesktop->UnlockSingleWindow();
|
|
|
|
|
2005-12-29 17:15:59 +03:00
|
|
|
if (fDesktop->LockAllWindows()) {
|
|
|
|
fWindowLayer->SetSizeLimits(minWidth, maxWidth,
|
|
|
|
minHeight, maxHeight);
|
|
|
|
fDesktop->UnlockAllWindows();
|
|
|
|
}
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2006-03-10 14:42:58 +03:00
|
|
|
fDesktop->LockSingleWindow();
|
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
// and now, sync the client to the limits that we were able to enforce
|
|
|
|
fWindowLayer->GetSizeLimits(&minWidth, &maxWidth,
|
|
|
|
&minHeight, &maxHeight);
|
|
|
|
|
|
|
|
fLink.StartMessage(B_OK);
|
|
|
|
fLink.Attach<BRect>(fWindowLayer->Frame());
|
|
|
|
fLink.Attach<float>((float)minWidth);
|
|
|
|
fLink.Attach<float>((float)maxWidth);
|
|
|
|
fLink.Attach<float>((float)minHeight);
|
|
|
|
fLink.Attach<float>((float)maxHeight);
|
|
|
|
|
|
|
|
fLink.Flush();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2006-05-25 16:01:28 +04:00
|
|
|
case AS_SET_DECORATOR_SETTINGS:
|
|
|
|
{
|
|
|
|
STRACE(("ServerWindow %s: Message AS_SET_DECORATOR_SETTINGS\n"));
|
|
|
|
|
|
|
|
int32 size;
|
|
|
|
if (fWindowLayer && link.Read<int32>(&size) == B_OK) {
|
|
|
|
char buffer[size];
|
|
|
|
if (link.Read(buffer, size) == B_OK) {
|
|
|
|
BMessage settings;
|
|
|
|
if (settings.Unflatten(buffer) == B_OK) {
|
|
|
|
fDesktop->UnlockSingleWindow();
|
|
|
|
fDesktop->SetWindowDecoratorSettings(fWindowLayer, settings);
|
|
|
|
fDesktop->LockSingleWindow();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case AS_GET_DECORATOR_SETTINGS:
|
|
|
|
{
|
|
|
|
STRACE(("ServerWindow %s: Message AS_GET_DECORATOR_SETTINGS\n"));
|
|
|
|
|
|
|
|
bool success = false;
|
|
|
|
|
|
|
|
BMessage settings;
|
|
|
|
if (fWindowLayer->GetDecoratorSettings(&settings)) {
|
|
|
|
int32 size = settings.FlattenedSize();
|
|
|
|
char buffer[size];
|
|
|
|
if (settings.Flatten(buffer, size) == B_OK) {
|
|
|
|
success = true;
|
|
|
|
fLink.StartMessage(B_OK);
|
|
|
|
fLink.Attach<int32>(size);
|
|
|
|
fLink.Attach(buffer, size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!success)
|
|
|
|
fLink.StartMessage(B_ERROR);
|
|
|
|
|
|
|
|
fLink.Flush();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
case AS_REDRAW:
|
2005-12-12 16:14:21 +03:00
|
|
|
// Nothing to do here - the redraws are actually handled by looking
|
|
|
|
// at the fRedrawRequested member variable in _MessageLooper().
|
2005-12-08 15:41:19 +03:00
|
|
|
break;
|
|
|
|
|
|
|
|
case AS_BEGIN_UPDATE:
|
|
|
|
DTRACE(("ServerWindowo %s: AS_BEGIN_UPDATE\n", Title()));
|
2006-02-06 13:28:30 +03:00
|
|
|
fWindowLayer->BeginUpdate(fLink);
|
2005-12-08 15:41:19 +03:00
|
|
|
break;
|
|
|
|
|
|
|
|
case AS_END_UPDATE:
|
|
|
|
DTRACE(("ServerWindowo %s: AS_END_UPDATE\n", Title()));
|
|
|
|
fWindowLayer->EndUpdate();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case AS_GET_MOUSE:
|
|
|
|
{
|
|
|
|
DTRACE(("ServerWindow %s: Message AS_GET_MOUSE\n", fTitle));
|
|
|
|
|
2006-03-10 14:42:58 +03:00
|
|
|
fDesktop->UnlockSingleWindow();
|
2005-12-08 15:41:19 +03:00
|
|
|
// Returns
|
|
|
|
// 1) BPoint mouse location
|
|
|
|
// 2) int32 button state
|
|
|
|
|
|
|
|
BPoint where;
|
|
|
|
int32 buttons;
|
|
|
|
fDesktop->EventDispatcher().GetMouse(where, buttons);
|
2006-05-25 16:01:28 +04:00
|
|
|
fDesktop->LockSingleWindow();
|
2005-12-08 15:41:19 +03:00
|
|
|
|
|
|
|
fLink.StartMessage(B_OK);
|
|
|
|
fLink.Attach<BPoint>(where);
|
|
|
|
fLink.Attach<int32>(buttons);
|
|
|
|
fLink.Flush();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2005-12-12 00:46:35 +03:00
|
|
|
// BDirectWindow communication
|
|
|
|
|
|
|
|
case AS_DIRECT_WINDOW_GET_SYNC_DATA:
|
|
|
|
{
|
|
|
|
status_t status = _EnableDirectWindowMode();
|
2006-04-29 20:40:29 +04:00
|
|
|
|
|
|
|
fLink.StartMessage(status);
|
2005-12-12 00:46:35 +03:00
|
|
|
if (status == B_OK) {
|
|
|
|
struct direct_window_sync_data syncData = {
|
|
|
|
fDirectWindowData->area,
|
|
|
|
fDirectWindowData->sem,
|
|
|
|
fDirectWindowData->sem_ack
|
|
|
|
};
|
|
|
|
|
|
|
|
fLink.Attach(&syncData, sizeof(syncData));
|
2006-04-29 20:40:29 +04:00
|
|
|
}
|
2005-12-12 00:46:35 +03:00
|
|
|
|
|
|
|
fLink.Flush();
|
|
|
|
break;
|
|
|
|
}
|
2006-04-29 20:40:29 +04:00
|
|
|
case AS_DIRECT_WINDOW_SET_FULLSCREEN:
|
|
|
|
{
|
2006-06-10 01:46:40 +04:00
|
|
|
// TODO: maybe there is more to do than this?
|
2006-04-29 20:40:29 +04:00
|
|
|
bool enable;
|
|
|
|
link.Read<bool>(&enable);
|
|
|
|
|
2006-06-10 01:46:40 +04:00
|
|
|
status_t status = B_OK;
|
|
|
|
if (!fWindowLayer->IsOffscreenWindow()) {
|
|
|
|
fDesktop->UnlockSingleWindow();
|
|
|
|
fDesktop->SetWindowFeel(fWindowLayer,
|
|
|
|
enable ? kWindowScreenFeel : B_NORMAL_WINDOW_FEEL);
|
|
|
|
fDesktop->LockSingleWindow();
|
|
|
|
} else
|
|
|
|
status = B_BAD_TYPE;
|
2006-04-29 20:40:29 +04:00
|
|
|
|
2006-06-10 01:46:40 +04:00
|
|
|
fLink.StartMessage(status);
|
|
|
|
fLink.Flush();
|
2006-04-29 20:40:29 +04:00
|
|
|
break;
|
|
|
|
}
|
2005-12-12 00:46:35 +03:00
|
|
|
|
|
|
|
// View creation and destruction (don't need a valid fCurrentLayer)
|
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
case AS_SET_CURRENT_LAYER:
|
|
|
|
{
|
|
|
|
int32 token;
|
2006-02-16 17:43:33 +03:00
|
|
|
if (link.Read<int32>(&token) != B_OK)
|
|
|
|
break;
|
2005-12-08 15:41:19 +03:00
|
|
|
|
|
|
|
ViewLayer *current;
|
|
|
|
if (App()->ViewTokens().GetToken(token, B_HANDLER_TOKEN,
|
|
|
|
(void**)¤t) != B_OK
|
|
|
|
|| current->Window()->ServerWindow() != this) {
|
|
|
|
// ToDo: if this happens, we probably want to kill the app and clean up
|
|
|
|
fprintf(stderr, "ServerWindow %s: Message AS_SET_CURRENT_LAYER: layer not found, token %ld\n", fTitle, token);
|
|
|
|
current = NULL;
|
|
|
|
} else {
|
|
|
|
DTRACE(("ServerWindow %s: Message AS_SET_CURRENT_LAYER: %s, token %ld\n", fTitle, current->Name(), token));
|
|
|
|
_SetCurrentLayer(current);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case AS_LAYER_CREATE_ROOT:
|
|
|
|
{
|
|
|
|
STRACE(("ServerWindow %s: Message AS_LAYER_CREATE_ROOT\n", fTitle));
|
|
|
|
|
|
|
|
// Start receiving top_view data -- pass NULL as the parent view.
|
|
|
|
// This should be the *only* place where this happens.
|
|
|
|
if (fCurrentLayer != NULL) {
|
|
|
|
fprintf(stderr, "ServerWindow %s: Message AS_LAYER_CREATE_ROOT: fCurrentLayer already set!!\n", fTitle);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2006-02-27 19:14:08 +03:00
|
|
|
_SetCurrentLayer(_CreateLayerTree(link, NULL));
|
2005-12-08 15:41:19 +03:00
|
|
|
fWindowLayer->SetTopLayer(fCurrentLayer);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case AS_LAYER_CREATE:
|
|
|
|
{
|
|
|
|
STRACE(("ServerWindow %s: Message AS_LAYER_CREATE: ViewLayer name: %s\n", fTitle, fCurrentLayer->Name()));
|
|
|
|
|
|
|
|
ViewLayer* parent = NULL;
|
2006-02-27 19:14:08 +03:00
|
|
|
ViewLayer* newLayer = _CreateLayerTree(link, &parent);
|
2005-12-08 15:41:19 +03:00
|
|
|
if (parent != NULL && newLayer != NULL)
|
|
|
|
parent->AddChild(newLayer);
|
|
|
|
else
|
|
|
|
fprintf(stderr, "ServerWindow %s: Message AS_LAYER_CREATE: parent or newLayer NULL!!\n", fTitle);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
// TODO: when creating a ViewLayer, check for yet non-existing ViewLayer::InitCheck()
|
2005-12-20 00:18:01 +03:00
|
|
|
// and take appropriate actions, then checking for fCurrentLayer->CurrentState()
|
2005-12-08 15:41:19 +03:00
|
|
|
// is unnecessary
|
|
|
|
if (fCurrentLayer == NULL || fCurrentLayer->CurrentState() == NULL) {
|
|
|
|
printf("ServerWindow %s received unexpected code - message offset %ld before top_view attached.\n", Title(), code - B_OK);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
_DispatchViewMessage(code, link);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Dispatches all view messages that need a valid fCurrentLayer.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
ServerWindow::_DispatchViewMessage(int32 code,
|
|
|
|
BPrivate::LinkReceiver &link)
|
|
|
|
{
|
2006-01-04 10:30:38 +03:00
|
|
|
if (_DispatchPictureMessage(code, link))
|
|
|
|
return;
|
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
switch (code) {
|
|
|
|
case AS_LAYER_SCROLL:
|
|
|
|
{
|
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_SCROLL: ViewLayer name: %s\n", fTitle, fCurrentLayer->Name()));
|
|
|
|
float dh;
|
|
|
|
float dv;
|
|
|
|
|
|
|
|
link.Read<float>(&dh);
|
|
|
|
link.Read<float>(&dv);
|
|
|
|
fWindowLayer->ScrollViewBy(fCurrentLayer, dh, dv);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_LAYER_COPY_BITS:
|
|
|
|
{
|
|
|
|
BRect src;
|
|
|
|
BRect dst;
|
|
|
|
|
|
|
|
link.Read<BRect>(&src);
|
|
|
|
link.Read<BRect>(&dst);
|
|
|
|
|
|
|
|
BRegion contentRegion;
|
|
|
|
// TODO: avoid copy operation maybe?
|
|
|
|
fWindowLayer->GetContentRegion(&contentRegion);
|
|
|
|
fCurrentLayer->CopyBits(src, dst, contentRegion);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_LAYER_DELETE:
|
|
|
|
{
|
2006-02-16 17:43:33 +03:00
|
|
|
// Received when a view is detached from a window
|
|
|
|
|
|
|
|
int32 token;
|
|
|
|
if (link.Read<int32>(&token) != B_OK)
|
|
|
|
break;
|
|
|
|
|
|
|
|
ViewLayer *view;
|
|
|
|
if (App()->ViewTokens().GetToken(token, B_HANDLER_TOKEN,
|
|
|
|
(void**)&view) == B_OK
|
2006-02-16 23:58:58 +03:00
|
|
|
&& view->Window()->ServerWindow() == this) {
|
2006-02-16 17:43:33 +03:00
|
|
|
ViewLayer* parent = view->Parent();
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2006-02-16 17:43:33 +03:00
|
|
|
STRACE(("ServerWindow %s: AS_LAYER_DELETE view: %p, parent: %p\n",
|
|
|
|
fTitle, view, parent));
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2006-02-16 17:43:33 +03:00
|
|
|
if (parent != NULL) {
|
|
|
|
parent->RemoveChild(view);
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2006-02-16 17:43:33 +03:00
|
|
|
if (view->EventMask() != 0) {
|
|
|
|
fDesktop->EventDispatcher().RemoveListener(EventTarget(),
|
|
|
|
token);
|
|
|
|
}
|
|
|
|
delete view;
|
ServerFont:
* fixed weird pointer conversion in SetStyle()
* fixed a potential mix up in operator=() in case the
other ServerFont has fStyle == NULL
ServerWindow:
* the WindowLayer fTopLayer cannot be deleted by
client request, just for safety reasons
* the link is flushed if there is no drawing engine,
but this case is theoretical only
* deleting the ServerWindow object syncs with the
client, so that when BBitmaps are deleted, they
can be sure there are no pending messages (which
would be executed in a nother thread)
* there is no timeout anymore when sending messages
to the client, which made absolutely no sense
AGGTextRenderer:
* renamed fFontManager to fFontCache, because that's
what it really is
* fLastFamilyAndStyle defaulted to the system plain
font and therefor that font was never loaded when
the font never changed meanwhile
DrawingMode:
* I'm not quite sure but I think there was the
potential of a division by zero, at least I
had crashes with "divide error"
HWInterface:
* fix update when the cursor shape changed in
double buffered mode
ViewLayer:
* since the top layer is never really deleted
before its time has come, it is not necessary
to set it to NULL in the ViewLayer destructor
ViewLayer/WindowLayer:
* added a function to collect the view tokens
that are affected by an update session
EventDispatcher:
* use the importance of the message for the timeout
in _SendMessage()
* drop mouse moved events in the server if we're
lagging behind more than 5 ms (Axel, maybe review)
View:
* there were some problems with the locking
of the BWindow looper in RemoveSelf(), since
this is called from the window destructor,
also of BWindows from BBitmaps, which have
never been run (this might need review), at
least I seem to have solved the crashing
problems introduced by actually deleting the
view hirarchy in the BWindow destructor
* fixed _Draw() for being used non-recursively,
temporarily disabled DrawAfterChildren, which
didn't work yet anyways (because views cannot
draw over children in the server yet)
Window:
* small cleanup when deleting shortcuts
* sync with the server when having send
AS_DELETE_WINDOW (see ServerWindow above)
* fixed locking in Begin/EndViewTransaction()
* removed folding of _UPDATE_ messages, since
there is only one ever in the queue
* set the fInTransaction flag during an update,
I plan to use this in BView later to
flush the link when drawing outside of an
update
* BView::_Draw() is now called by view token,
this gives the next leap forward in speed,
the overhead because of drawing clean views
was considerable
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15878 a95241bf-73f2-0310-859d-f6bbb57e9c96
2006-01-09 01:04:52 +03:00
|
|
|
}
|
2005-12-08 15:41:19 +03:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_LAYER_SET_STATE:
|
|
|
|
{
|
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_SET_STATE: ViewLayer name: %s\n", fTitle, fCurrentLayer->Name()));
|
2006-02-27 19:14:08 +03:00
|
|
|
|
|
|
|
fCurrentLayer->CurrentState()->ReadFromLink(link);
|
|
|
|
// TODO: When is this used?!?
|
|
|
|
fCurrentLayer->RebuildClipping(true);
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
_UpdateDrawState(fCurrentLayer);
|
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_LAYER_SET_FONT_STATE:
|
|
|
|
{
|
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_SET_FONT_STATE: ViewLayer name: %s\n", fTitle, fCurrentLayer->Name()));
|
2006-02-27 19:14:08 +03:00
|
|
|
fCurrentLayer->CurrentState()->ReadFontFromLink(link);
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
_UpdateDrawState(fCurrentLayer);
|
2005-12-08 15:41:19 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_LAYER_GET_STATE:
|
|
|
|
{
|
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_GET_STATE: ViewLayer name: %s\n", fTitle, fCurrentLayer->Name()));
|
|
|
|
|
|
|
|
fLink.StartMessage(B_OK);
|
|
|
|
|
|
|
|
// attach state data
|
|
|
|
fCurrentLayer->CurrentState()->WriteToLink(fLink.Sender());
|
|
|
|
fLink.Flush();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_LAYER_SET_EVENT_MASK:
|
|
|
|
{
|
|
|
|
STRACE(("ServerWindow %s: Message AS_LAYER_SET_MOUSE_EVENT_MASK: ViewLayer name: %s\n", fTitle, fCurrentLayer->Name()));
|
|
|
|
uint32 eventMask, options;
|
|
|
|
|
|
|
|
link.Read<uint32>(&eventMask);
|
|
|
|
if (link.Read<uint32>(&options) == B_OK) {
|
2005-12-12 13:41:31 +03:00
|
|
|
fDesktop->UnlockSingleWindow();
|
2005-12-08 15:41:19 +03:00
|
|
|
fCurrentLayer->SetEventMask(eventMask, options);
|
|
|
|
|
|
|
|
if (eventMask != 0 || options != 0) {
|
|
|
|
fDesktop->EventDispatcher().AddListener(EventTarget(),
|
|
|
|
fCurrentLayer->Token(), eventMask, options);
|
|
|
|
} else {
|
|
|
|
fDesktop->EventDispatcher().RemoveListener(EventTarget(),
|
|
|
|
fCurrentLayer->Token());
|
|
|
|
}
|
2005-12-12 13:41:31 +03:00
|
|
|
fDesktop->LockSingleWindow();
|
2005-12-08 15:41:19 +03:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_LAYER_SET_MOUSE_EVENT_MASK:
|
|
|
|
{
|
|
|
|
STRACE(("ServerWindow %s: Message AS_LAYER_SET_MOUSE_EVENT_MASK: ViewLayer name: %s\n", fTitle, fCurrentLayer->Name()));
|
|
|
|
uint32 eventMask, options;
|
|
|
|
|
|
|
|
link.Read<uint32>(&eventMask);
|
|
|
|
if (link.Read<uint32>(&options) == B_OK) {
|
2005-12-12 13:41:31 +03:00
|
|
|
fDesktop->UnlockSingleWindow();
|
2005-12-08 15:41:19 +03:00
|
|
|
if (eventMask != 0 || options != 0) {
|
|
|
|
fDesktop->EventDispatcher().AddTemporaryListener(EventTarget(),
|
|
|
|
fCurrentLayer->Token(), eventMask, options);
|
|
|
|
} else {
|
|
|
|
fDesktop->EventDispatcher().RemoveTemporaryListener(EventTarget(),
|
|
|
|
fCurrentLayer->Token());
|
|
|
|
}
|
2005-12-12 13:41:31 +03:00
|
|
|
fDesktop->LockSingleWindow();
|
2005-12-08 15:41:19 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: support B_LOCK_WINDOW_FOCUS option in Desktop
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_LAYER_MOVE_TO:
|
|
|
|
{
|
|
|
|
STRACE(("ServerWindow %s: Message AS_LAYER_MOVE_TO: ViewLayer name: %s\n",
|
|
|
|
fTitle, fCurrentLayer->Name()));
|
|
|
|
|
|
|
|
float x, y;
|
|
|
|
link.Read<float>(&x);
|
|
|
|
link.Read<float>(&y);
|
|
|
|
|
|
|
|
float offsetX = x - fCurrentLayer->Frame().left;
|
|
|
|
float offsetY = y - fCurrentLayer->Frame().top;
|
|
|
|
|
2006-03-10 14:42:58 +03:00
|
|
|
BRegion dirty;
|
|
|
|
fCurrentLayer->MoveBy(offsetX, offsetY, &dirty);
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2006-03-10 14:42:58 +03:00
|
|
|
// TODO: think about how to avoid this hack:
|
|
|
|
// the parent clipping needs to be updated, it is not
|
2007-07-18 21:02:03 +04:00
|
|
|
// done in MoveBy() since it would need to avoid
|
2006-03-10 14:42:58 +03:00
|
|
|
// too much computations when children are resized because
|
|
|
|
// follow modes
|
|
|
|
if (ViewLayer* parent = fCurrentLayer->Parent())
|
|
|
|
parent->RebuildClipping(false);
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2006-03-10 14:42:58 +03:00
|
|
|
fWindowLayer->MarkContentDirty(dirty);
|
2005-12-08 15:41:19 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_LAYER_RESIZE_TO:
|
|
|
|
{
|
|
|
|
STRACE(("ServerWindow %s: Message AS_LAYER_RESIZE_TO: ViewLayer name: %s\n",
|
|
|
|
fTitle, fCurrentLayer->Name()));
|
|
|
|
|
|
|
|
float newWidth, newHeight;
|
|
|
|
link.Read<float>(&newWidth);
|
|
|
|
link.Read<float>(&newHeight);
|
|
|
|
|
|
|
|
float deltaWidth = newWidth - fCurrentLayer->Frame().Width();
|
|
|
|
float deltaHeight = newHeight - fCurrentLayer->Frame().Height();
|
|
|
|
|
2006-03-10 14:42:58 +03:00
|
|
|
BRegion dirty;
|
|
|
|
fCurrentLayer->ResizeBy(deltaWidth, deltaHeight, &dirty);
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2006-03-10 14:42:58 +03:00
|
|
|
// TODO: see above
|
|
|
|
if (ViewLayer* parent = fCurrentLayer->Parent())
|
|
|
|
parent->RebuildClipping(false);
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2006-03-10 14:42:58 +03:00
|
|
|
fWindowLayer->MarkContentDirty(dirty);
|
2005-12-08 15:41:19 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_LAYER_GET_COORD:
|
|
|
|
{
|
|
|
|
STRACE(("ServerWindow %s: Message AS_LAYER_GET_COORD: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
|
|
|
fLink.StartMessage(B_OK);
|
|
|
|
// our offset in the parent -> will be originX and originY in BView
|
|
|
|
fLink.Attach<float>(fCurrentLayer->Frame().left);
|
|
|
|
fLink.Attach<float>(fCurrentLayer->Frame().top);
|
|
|
|
fLink.Attach<BRect>(fCurrentLayer->Bounds());
|
|
|
|
fLink.Flush();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_LAYER_SET_ORIGIN:
|
|
|
|
{
|
|
|
|
STRACE(("ServerWindow %s: Message AS_LAYER_SET_ORIGIN: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
|
|
|
|
|
|
|
float x, y;
|
|
|
|
link.Read<float>(&x);
|
|
|
|
link.Read<float>(&y);
|
|
|
|
|
|
|
|
fCurrentLayer->SetDrawingOrigin(BPoint(x, y));
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
_UpdateDrawState(fCurrentLayer);
|
2005-12-08 15:41:19 +03:00
|
|
|
break;
|
2003-09-25 21:25:38 +04:00
|
|
|
}
|
|
|
|
case AS_LAYER_GET_ORIGIN:
|
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
STRACE(("ServerWindow %s: Message AS_LAYER_GET_ORIGIN: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
2005-11-30 18:47:01 +03:00
|
|
|
fLink.StartMessage(B_OK);
|
2005-11-20 18:10:18 +03:00
|
|
|
// TODO: rename this where it is used in the BView code!
|
|
|
|
// (it wants to know scrolling offset, not drawing origin)
|
|
|
|
fLink.Attach<BPoint>(fCurrentLayer->ScrollingOffset());
|
2005-06-24 02:43:11 +04:00
|
|
|
fLink.Flush();
|
2003-09-25 21:25:38 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_LAYER_RESIZE_MODE:
|
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
STRACE(("ServerWindow %s: Message AS_LAYER_RESIZE_MODE: ViewLayer: %s\n",
|
|
|
|
Title(), fCurrentLayer->Name()));
|
|
|
|
|
|
|
|
uint32 resizeMode;
|
|
|
|
if (link.Read<uint32>(&resizeMode) == B_OK)
|
|
|
|
fCurrentLayer->SetResizeMode(resizeMode);
|
2003-09-25 21:25:38 +04:00
|
|
|
break;
|
|
|
|
}
|
2006-02-05 21:14:14 +03:00
|
|
|
case AS_LAYER_SET_CURSOR:
|
2003-09-25 21:25:38 +04:00
|
|
|
{
|
2006-03-09 21:37:28 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_CURSOR: ViewLayer: %s\n", Title(),
|
|
|
|
fCurrentLayer->Name()));
|
|
|
|
|
2006-02-05 21:14:14 +03:00
|
|
|
int32 token;
|
2006-03-15 17:04:44 +03:00
|
|
|
bool sync;
|
|
|
|
link.Read<int32>(&token);
|
|
|
|
if (link.Read<bool>(&sync) != B_OK)
|
2006-02-26 21:15:31 +03:00
|
|
|
break;
|
|
|
|
|
2006-04-01 20:56:10 +04:00
|
|
|
if (!fDesktop->GetCursorManager().Lock())
|
|
|
|
break;
|
|
|
|
|
2006-02-26 21:15:31 +03:00
|
|
|
ServerCursor* cursor = fDesktop->GetCursorManager().FindCursor(token);
|
|
|
|
fCurrentLayer->SetCursor(cursor);
|
2004-06-16 10:40:26 +04:00
|
|
|
|
2006-04-01 20:56:10 +04:00
|
|
|
fDesktop->GetCursorManager().Unlock();
|
|
|
|
|
2006-02-26 21:15:31 +03:00
|
|
|
if (fWindowLayer->IsFocus()) {
|
|
|
|
// The cursor might need to be updated now
|
2006-03-10 16:03:41 +03:00
|
|
|
if (fDesktop->ViewUnderMouse(fWindowLayer) == fCurrentLayer->Token())
|
2006-03-09 21:37:28 +03:00
|
|
|
fServerApp->SetCurrentCursor(cursor);
|
2006-02-26 21:15:31 +03:00
|
|
|
}
|
2006-03-15 17:04:44 +03:00
|
|
|
if (sync) {
|
|
|
|
// sync the client (it can now delete the cursor)
|
|
|
|
fLink.StartMessage(B_OK);
|
|
|
|
fLink.Flush();
|
|
|
|
}
|
|
|
|
|
2003-09-25 21:25:38 +04:00
|
|
|
break;
|
|
|
|
}
|
2003-09-25 16:31:11 +04:00
|
|
|
case AS_LAYER_SET_FLAGS:
|
|
|
|
{
|
offscreen bitmaps work, tested on Haiku as well, supports all colorspaces that BBitmap::ImportBits() supports. It uses a fallback for non-B_RGB(A)32 bitmaps. Added support for B_SUB_PIXEL_PRECISION view flags, though it is a bit hacky, since I had to add it to LayerData, even though it is not a true part of stack data. Added Layer::SetFlags() to enforce code path and update fLayerData. Cleaned up DisplayDriverPainter and DisplayDriver API (changed some const BRect& rect to simply BRect rect in order to be able to reuse it in the code), moved Painter.h, the test environment only draws the changed part of the frame buffer again - this causes a lot less CPU overhead, Painter special cases stroke width of 1.0 to use square caps, which is similar to R5 implementation and removes a lot of problems with non-straight line drawing, ServerWindow uses the DisplayDriver from it's WinBorder instead of the one from the Desktop (needed for offscreen windows, which have their own DisplayDriverPainter), it also checks for GetRootLayer() == NULL, because offscreen layers are not attached to a RootLayer, there was a fix for scrolling which worked at least in the test environment, it is now defunced, because Adi moved _CopyBits to Layer... I need to reenable it later, LayerData has no more fEscapementDelta, also fixed fFontAliasing (which was thought to overriding the font flags, and now works as such again), Desktop initialises the menu_info and scroll_bar_info stuff, which makes ScrollBars work actually... hope I didn't forget something.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13448 a95241bf-73f2-0310-859d-f6bbb57e9c96
2005-07-05 20:17:16 +04:00
|
|
|
uint32 flags;
|
|
|
|
link.Read<uint32>(&flags);
|
|
|
|
fCurrentLayer->SetFlags(flags);
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
_UpdateDrawState(fCurrentLayer);
|
2006-02-02 23:19:29 +03:00
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
STRACE(("ServerWindow %s: Message AS_LAYER_SET_FLAGS: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
2003-09-25 16:31:11 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_LAYER_HIDE:
|
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
STRACE(("ServerWindow %s: Message AS_LAYER_HIDE: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
|
|
|
fCurrentLayer->SetHidden(true);
|
2003-09-25 16:31:11 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_LAYER_SHOW:
|
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
STRACE(("ServerWindow %s: Message AS_LAYER_SHOW: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
|
|
|
fCurrentLayer->SetHidden(false);
|
2003-09-25 16:31:11 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_LAYER_SET_LINE_MODE:
|
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_SET_LINE_MODE: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
2004-06-11 18:47:36 +04:00
|
|
|
int8 lineCap, lineJoin;
|
2005-04-19 04:42:42 +04:00
|
|
|
float miterLimit;
|
2004-01-20 01:18:37 +03:00
|
|
|
|
2004-10-16 06:02:27 +04:00
|
|
|
link.Read<int8>(&lineCap);
|
|
|
|
link.Read<int8>(&lineJoin);
|
2005-04-19 04:42:42 +04:00
|
|
|
link.Read<float>(&miterLimit);
|
2003-09-25 16:31:11 +04:00
|
|
|
|
2005-11-04 15:15:36 +03:00
|
|
|
fCurrentLayer->CurrentState()->SetLineCapMode((cap_mode)lineCap);
|
|
|
|
fCurrentLayer->CurrentState()->SetLineJoinMode((join_mode)lineJoin);
|
|
|
|
fCurrentLayer->CurrentState()->SetMiterLimit(miterLimit);
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
|
|
|
|
_UpdateDrawState(fCurrentLayer);
|
|
|
|
|
2003-09-25 16:31:11 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_LAYER_GET_LINE_MODE:
|
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_GET_LINE_MODE: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
2005-11-30 18:47:01 +03:00
|
|
|
fLink.StartMessage(B_OK);
|
2005-11-04 15:15:36 +03:00
|
|
|
fLink.Attach<int8>((int8)(fCurrentLayer->CurrentState()->LineCapMode()));
|
|
|
|
fLink.Attach<int8>((int8)(fCurrentLayer->CurrentState()->LineJoinMode()));
|
|
|
|
fLink.Attach<float>(fCurrentLayer->CurrentState()->MiterLimit());
|
2005-06-24 02:43:11 +04:00
|
|
|
fLink.Flush();
|
2003-09-25 16:31:11 +04:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_LAYER_PUSH_STATE:
|
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_PUSH_STATE: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
2004-06-11 18:47:36 +04:00
|
|
|
|
2005-06-10 19:28:34 +04:00
|
|
|
fCurrentLayer->PushState();
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
// TODO: is this necessary?
|
|
|
|
_UpdateDrawState(fCurrentLayer);
|
2003-09-25 16:31:11 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_LAYER_POP_STATE:
|
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_POP_STATE: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
2004-06-11 18:47:36 +04:00
|
|
|
|
2005-06-10 19:28:34 +04:00
|
|
|
fCurrentLayer->PopState();
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
_UpdateDrawState(fCurrentLayer);
|
2003-09-25 16:31:11 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_LAYER_SET_SCALE:
|
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_SET_SCALE: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
2005-04-19 04:42:42 +04:00
|
|
|
float scale;
|
|
|
|
link.Read<float>(&scale);
|
2005-11-04 15:01:44 +03:00
|
|
|
|
2005-11-20 18:10:18 +03:00
|
|
|
fCurrentLayer->SetScale(scale);
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
_UpdateDrawState(fCurrentLayer);
|
2003-09-25 16:31:11 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_LAYER_GET_SCALE:
|
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_GET_SCALE: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
2005-11-04 12:52:56 +03:00
|
|
|
|
2005-11-30 18:47:01 +03:00
|
|
|
fLink.StartMessage(B_OK);
|
2005-11-04 15:15:36 +03:00
|
|
|
fLink.Attach<float>(fCurrentLayer->CurrentState()->Scale());
|
2005-06-24 02:43:11 +04:00
|
|
|
fLink.Flush();
|
2003-09-25 16:31:11 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_LAYER_SET_PEN_LOC:
|
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_SET_PEN_LOC: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
2005-11-04 12:52:56 +03:00
|
|
|
float x, y;
|
|
|
|
|
2004-10-16 06:02:27 +04:00
|
|
|
link.Read<float>(&x);
|
|
|
|
link.Read<float>(&y);
|
2004-07-30 19:16:59 +04:00
|
|
|
|
2005-11-04 15:15:36 +03:00
|
|
|
fCurrentLayer->CurrentState()->SetPenLocation(BPoint(x, y));
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
// TODO: is this necessary?
|
|
|
|
_UpdateDrawState(fCurrentLayer);
|
2003-09-25 16:31:11 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_LAYER_GET_PEN_LOC:
|
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_GET_PEN_LOC: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
2005-11-30 18:47:01 +03:00
|
|
|
fLink.StartMessage(B_OK);
|
2005-11-04 15:15:36 +03:00
|
|
|
fLink.Attach<BPoint>(fCurrentLayer->CurrentState()->PenLocation());
|
2005-06-24 02:43:11 +04:00
|
|
|
fLink.Flush();
|
2004-07-30 19:16:59 +04:00
|
|
|
|
2003-09-25 16:31:11 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_LAYER_SET_PEN_SIZE:
|
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_SET_PEN_SIZE: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
2005-04-19 04:42:42 +04:00
|
|
|
float penSize;
|
|
|
|
link.Read<float>(&penSize);
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
|
2005-11-04 15:15:36 +03:00
|
|
|
fCurrentLayer->CurrentState()->SetPenSize(penSize);
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
//_UpdateDrawState(fCurrentLayer);
|
|
|
|
fWindowLayer->GetDrawingEngine()->SetPenSize(penSize);
|
2003-09-25 16:31:11 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_LAYER_GET_PEN_SIZE:
|
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_GET_PEN_SIZE: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
2005-11-30 18:47:01 +03:00
|
|
|
fLink.StartMessage(B_OK);
|
2005-11-04 15:15:36 +03:00
|
|
|
fLink.Attach<float>(fCurrentLayer->CurrentState()->PenSize());
|
2005-06-24 02:43:11 +04:00
|
|
|
fLink.Flush();
|
2004-07-30 19:16:59 +04:00
|
|
|
|
2003-09-25 16:31:11 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_LAYER_SET_VIEW_COLOR:
|
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_SET_VIEW_COLOR: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
2004-06-11 18:47:36 +04:00
|
|
|
rgb_color c;
|
2003-09-25 16:31:11 +04:00
|
|
|
|
2004-10-16 06:02:27 +04:00
|
|
|
link.Read(&c, sizeof(rgb_color));
|
2005-11-30 22:51:43 +03:00
|
|
|
|
2005-06-10 20:20:38 +04:00
|
|
|
fCurrentLayer->SetViewColor(RGBColor(c));
|
2003-09-25 16:31:11 +04:00
|
|
|
break;
|
|
|
|
}
|
2005-06-28 22:56:55 +04:00
|
|
|
|
|
|
|
case AS_LAYER_GET_HIGH_COLOR:
|
2005-12-08 15:41:19 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_GET_HIGH_COLOR: ViewLayer: %s\n",
|
2005-06-28 22:56:55 +04:00
|
|
|
Title(), fCurrentLayer->Name()));
|
|
|
|
|
2005-11-30 18:47:01 +03:00
|
|
|
fLink.StartMessage(B_OK);
|
2005-11-04 15:15:36 +03:00
|
|
|
fLink.Attach<rgb_color>(fCurrentLayer->CurrentState()->HighColor().GetColor32());
|
2005-06-28 22:56:55 +04:00
|
|
|
fLink.Flush();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case AS_LAYER_GET_LOW_COLOR:
|
2005-12-08 15:41:19 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_GET_LOW_COLOR: ViewLayer: %s\n",
|
2005-06-28 22:56:55 +04:00
|
|
|
Title(), fCurrentLayer->Name()));
|
|
|
|
|
2005-11-30 18:47:01 +03:00
|
|
|
fLink.StartMessage(B_OK);
|
2005-11-04 15:15:36 +03:00
|
|
|
fLink.Attach<rgb_color>(fCurrentLayer->CurrentState()->LowColor().GetColor32());
|
2005-06-24 02:43:11 +04:00
|
|
|
fLink.Flush();
|
2005-06-28 22:56:55 +04:00
|
|
|
break;
|
2004-06-16 10:40:26 +04:00
|
|
|
|
2005-06-28 22:56:55 +04:00
|
|
|
case AS_LAYER_GET_VIEW_COLOR:
|
2005-12-08 15:41:19 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_GET_VIEW_COLOR: ViewLayer: %s\n",
|
2005-06-28 22:56:55 +04:00
|
|
|
Title(), fCurrentLayer->Name()));
|
|
|
|
|
2005-11-30 18:47:01 +03:00
|
|
|
fLink.StartMessage(B_OK);
|
2005-06-28 22:56:55 +04:00
|
|
|
fLink.Attach<rgb_color>(fCurrentLayer->ViewColor().GetColor32());
|
|
|
|
fLink.Flush();
|
2003-09-25 16:31:11 +04:00
|
|
|
break;
|
2005-06-28 22:56:55 +04:00
|
|
|
|
2005-12-29 18:06:24 +03:00
|
|
|
case AS_LAYER_SET_BLENDING_MODE:
|
2003-09-25 16:31:11 +04:00
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_SET_BLEND_MODE: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
2004-06-11 18:47:36 +04:00
|
|
|
int8 srcAlpha, alphaFunc;
|
2003-09-25 16:31:11 +04:00
|
|
|
|
2004-10-16 06:02:27 +04:00
|
|
|
link.Read<int8>(&srcAlpha);
|
|
|
|
link.Read<int8>(&alphaFunc);
|
2003-09-25 16:31:11 +04:00
|
|
|
|
2005-11-04 15:15:36 +03:00
|
|
|
fCurrentLayer->CurrentState()->SetBlendingMode((source_alpha)srcAlpha,
|
2005-04-19 04:42:42 +04:00
|
|
|
(alpha_function)alphaFunc);
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
_UpdateDrawState(fCurrentLayer);
|
2003-09-25 16:31:11 +04:00
|
|
|
break;
|
|
|
|
}
|
2005-12-29 18:06:24 +03:00
|
|
|
case AS_LAYER_GET_BLENDING_MODE:
|
2003-09-25 16:31:11 +04:00
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_GET_BLEND_MODE: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
2005-11-30 18:47:01 +03:00
|
|
|
fLink.StartMessage(B_OK);
|
2005-11-04 15:15:36 +03:00
|
|
|
fLink.Attach<int8>((int8)(fCurrentLayer->CurrentState()->AlphaSrcMode()));
|
|
|
|
fLink.Attach<int8>((int8)(fCurrentLayer->CurrentState()->AlphaFncMode()));
|
2005-06-24 02:43:11 +04:00
|
|
|
fLink.Flush();
|
2004-06-16 10:40:26 +04:00
|
|
|
|
2003-09-25 16:31:11 +04:00
|
|
|
break;
|
|
|
|
}
|
2005-12-29 18:06:24 +03:00
|
|
|
case AS_LAYER_SET_DRAWING_MODE:
|
2003-09-25 16:31:11 +04:00
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_SET_DRAW_MODE: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
2004-06-11 18:47:36 +04:00
|
|
|
int8 drawingMode;
|
2003-09-25 16:31:11 +04:00
|
|
|
|
2004-10-16 06:02:27 +04:00
|
|
|
link.Read<int8>(&drawingMode);
|
2003-09-25 16:31:11 +04:00
|
|
|
|
2005-11-04 15:15:36 +03:00
|
|
|
fCurrentLayer->CurrentState()->SetDrawingMode((drawing_mode)drawingMode);
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
//_UpdateDrawState(fCurrentLayer);
|
|
|
|
fWindowLayer->GetDrawingEngine()->SetDrawingMode((drawing_mode)drawingMode);
|
2003-09-25 16:31:11 +04:00
|
|
|
break;
|
|
|
|
}
|
2005-12-29 18:06:24 +03:00
|
|
|
case AS_LAYER_GET_DRAWING_MODE:
|
2003-09-25 16:31:11 +04:00
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_GET_DRAW_MODE: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
2005-11-30 18:47:01 +03:00
|
|
|
fLink.StartMessage(B_OK);
|
2005-11-04 15:15:36 +03:00
|
|
|
fLink.Attach<int8>((int8)(fCurrentLayer->CurrentState()->GetDrawingMode()));
|
2005-06-24 02:43:11 +04:00
|
|
|
fLink.Flush();
|
2004-07-30 19:16:59 +04:00
|
|
|
|
2003-09-25 16:31:11 +04:00
|
|
|
break;
|
|
|
|
}
|
2005-12-29 19:46:02 +03:00
|
|
|
case AS_LAYER_SET_VIEW_BITMAP:
|
|
|
|
{
|
|
|
|
int32 bitmapToken, resizingMode, options;
|
|
|
|
BRect srcRect, dstRect;
|
|
|
|
|
|
|
|
link.Read<int32>(&bitmapToken);
|
|
|
|
link.Read<BRect>(&srcRect);
|
|
|
|
link.Read<BRect>(&dstRect);
|
|
|
|
link.Read<int32>(&resizingMode);
|
|
|
|
status_t status = link.Read<int32>(&options);
|
|
|
|
|
2006-04-23 18:28:48 +04:00
|
|
|
rgb_color colorKey = {0};
|
|
|
|
|
2005-12-29 19:46:02 +03:00
|
|
|
if (status == B_OK) {
|
|
|
|
ServerBitmap* bitmap = fServerApp->FindBitmap(bitmapToken);
|
|
|
|
if (bitmapToken == -1 || bitmap != NULL) {
|
2006-05-04 15:21:36 +04:00
|
|
|
bool wasOverlay = fCurrentLayer->ViewBitmap() != NULL
|
|
|
|
&& fCurrentLayer->ViewBitmap()->Overlay() != NULL;
|
|
|
|
|
2006-04-23 18:28:48 +04:00
|
|
|
// TODO: this is a race condition: the bitmap could have been
|
|
|
|
// deleted in the mean time!!
|
2005-12-29 19:46:02 +03:00
|
|
|
fCurrentLayer->SetViewBitmap(bitmap, srcRect, dstRect,
|
|
|
|
resizingMode, options);
|
|
|
|
|
2006-05-04 15:21:36 +04:00
|
|
|
// TODO: if we revert the view color overlay handling
|
|
|
|
// in ViewLayer::Draw() to the R5 version, we never
|
|
|
|
// need to invalidate the view for overlays.
|
|
|
|
|
|
|
|
// invalidate view - but only if this is a non-overlay switch
|
|
|
|
if (bitmap == NULL || bitmap->Overlay() == NULL || !wasOverlay) {
|
2007-07-19 21:06:28 +04:00
|
|
|
BRegion dirty((BRect)fCurrentLayer->Bounds());
|
2006-05-04 15:21:36 +04:00
|
|
|
fWindowLayer->InvalidateView(fCurrentLayer, dirty);
|
|
|
|
}
|
2006-04-23 18:28:48 +04:00
|
|
|
|
2006-05-05 00:25:19 +04:00
|
|
|
if (bitmap != NULL && bitmap->Overlay() != NULL) {
|
|
|
|
bitmap->Overlay()->SetFlags(options);
|
2006-04-23 19:45:35 +04:00
|
|
|
colorKey = bitmap->Overlay()->Color().GetColor32();
|
2006-05-05 00:25:19 +04:00
|
|
|
}
|
2005-12-29 19:46:02 +03:00
|
|
|
} else
|
|
|
|
status = B_BAD_VALUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
fLink.StartMessage(status);
|
2006-03-02 00:20:57 +03:00
|
|
|
if (status == B_OK && (options & AS_REQUEST_COLOR_KEY) != 0) {
|
|
|
|
// Attach color key for the overlay bitmap
|
|
|
|
fLink.Attach<rgb_color>(colorKey);
|
|
|
|
}
|
|
|
|
|
2005-12-29 19:46:02 +03:00
|
|
|
fLink.Flush();
|
|
|
|
break;
|
|
|
|
}
|
2003-09-25 16:31:11 +04:00
|
|
|
case AS_LAYER_PRINT_ALIASING:
|
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_PRINT_ALIASING: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
2005-04-19 04:42:42 +04:00
|
|
|
bool fontAliasing;
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
if (link.Read<bool>(&fontAliasing) == B_OK) {
|
2005-12-29 19:46:02 +03:00
|
|
|
fCurrentLayer->CurrentState()->SetForceFontAliasing(fontAliasing);
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
_UpdateDrawState(fCurrentLayer);
|
|
|
|
}
|
2003-09-25 16:31:11 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_LAYER_CLIP_TO_PICTURE:
|
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_CLIP_TO_PICTURE: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
2005-12-29 19:46:02 +03:00
|
|
|
// TODO: you are not allowed to use ViewLayer regions here!!!
|
|
|
|
|
2004-06-11 18:47:36 +04:00
|
|
|
int32 pictureToken;
|
|
|
|
BPoint where;
|
2005-06-03 18:20:10 +04:00
|
|
|
bool inverse = false;
|
2005-12-29 19:46:02 +03:00
|
|
|
|
2004-10-16 06:02:27 +04:00
|
|
|
link.Read<int32>(&pictureToken);
|
|
|
|
link.Read<BPoint>(&where);
|
2005-06-03 18:20:10 +04:00
|
|
|
link.Read<bool>(&inverse);
|
2005-12-29 19:46:02 +03:00
|
|
|
|
2004-06-11 18:47:36 +04:00
|
|
|
// search for a picture with the specified token.
|
2005-06-03 18:20:10 +04:00
|
|
|
ServerPicture *picture = fServerApp->FindPicture(pictureToken);
|
2005-05-14 17:22:26 +04:00
|
|
|
// TODO: Increase that picture's reference count.(~ allocate a picture)
|
2005-06-03 18:20:10 +04:00
|
|
|
if (picture == NULL)
|
2005-05-14 17:22:26 +04:00
|
|
|
break;
|
2005-12-29 19:46:02 +03:00
|
|
|
|
2005-06-03 18:20:10 +04:00
|
|
|
BRegion region;
|
|
|
|
// TODO: I think we also need the BView's token
|
2005-12-08 15:41:19 +03:00
|
|
|
// I think PictureToRegion would fit better into the ViewLayer class (?)
|
2005-06-03 18:20:10 +04:00
|
|
|
if (PictureToRegion(picture, region, inverse, where) < B_OK)
|
2005-05-14 17:22:26 +04:00
|
|
|
break;
|
2005-06-25 19:45:58 +04:00
|
|
|
|
2006-03-08 21:57:44 +03:00
|
|
|
fCurrentLayer->SetUserClipping(®ion);
|
2005-06-03 18:20:10 +04:00
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
// TODO: reenable AS_LAYER_CLIP_TO_PICTURE
|
|
|
|
#if 0
|
2005-11-24 20:45:26 +03:00
|
|
|
if (rootLayer && !(fCurrentLayer->IsHidden()) && !fWindowLayer->InUpdate()) {
|
2005-06-28 18:57:16 +04:00
|
|
|
BRegion invalidRegion;
|
2005-11-14 20:50:39 +03:00
|
|
|
fCurrentLayer->GetOnScreenRegion(invalidRegion);
|
2005-11-06 20:47:06 +03:00
|
|
|
|
|
|
|
// TODO: this is broken! a smaller area may be invalidated!
|
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
fCurrentLayer->fParent->MarkForRebuild(invalidRegion);
|
|
|
|
fCurrentLayer->fParent->TriggerRebuild();
|
|
|
|
rootLayer->MarkForRedraw(invalidRegion);
|
|
|
|
rootLayer->TriggerRedraw();
|
|
|
|
}
|
2005-07-01 12:50:45 +04:00
|
|
|
#endif
|
2003-03-23 23:52:37 +03:00
|
|
|
break;
|
|
|
|
}
|
2005-04-10 23:04:06 +04:00
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
case AS_LAYER_GET_CLIP_REGION:
|
2003-03-23 23:52:37 +03:00
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_GET_CLIP_REGION: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
|
|
|
|
|
|
|
// if this ViewLayer is hidden, it is clear that its visible region is void.
|
2007-07-18 16:59:05 +04:00
|
|
|
fLink.StartMessage(B_OK);
|
2005-12-08 15:41:19 +03:00
|
|
|
if (fCurrentLayer->IsHidden()) {
|
2007-07-18 16:59:05 +04:00
|
|
|
BRegion empty;
|
|
|
|
fLink.AttachRegion(empty);
|
2005-12-08 15:41:19 +03:00
|
|
|
} else {
|
|
|
|
BRegion drawingRegion = fCurrentLayer->LocalClipping();
|
2007-07-18 16:59:05 +04:00
|
|
|
fLink.AttachRegion(drawingRegion);
|
2005-12-08 15:41:19 +03:00
|
|
|
}
|
2007-07-18 16:59:05 +04:00
|
|
|
fLink.Flush();
|
2005-12-01 13:31:30 +03:00
|
|
|
|
2003-03-23 23:52:37 +03:00
|
|
|
break;
|
|
|
|
}
|
2005-12-08 15:41:19 +03:00
|
|
|
case AS_LAYER_SET_CLIP_REGION:
|
2004-06-18 23:13:06 +04:00
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_SET_CLIP_REGION: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
|
|
|
|
|
|
|
int32 rectCount;
|
2006-03-08 21:57:44 +03:00
|
|
|
status_t status = link.Read<int32>(&rectCount);
|
|
|
|
// a negative count means no
|
|
|
|
// region for the current draw state,
|
|
|
|
// but an *empty* region is actually valid!
|
|
|
|
// even if it means no drawing is allowed
|
|
|
|
|
2007-07-18 16:59:05 +04:00
|
|
|
if (status < B_OK)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (rectCount >= 0) {
|
|
|
|
// we are supposed to set the clipping region
|
|
|
|
BRegion region;
|
|
|
|
if (link.ReadRegion(®ion) < B_OK)
|
|
|
|
break;
|
2006-03-08 21:57:44 +03:00
|
|
|
fCurrentLayer->SetUserClipping(®ion);
|
|
|
|
} else {
|
2007-07-18 16:59:05 +04:00
|
|
|
// we are supposed to unset the clipping region
|
|
|
|
// passing NULL sets this states region to that
|
|
|
|
// of the previous state
|
2006-03-08 21:57:44 +03:00
|
|
|
fCurrentLayer->SetUserClipping(NULL);
|
2005-12-08 15:41:19 +03:00
|
|
|
}
|
2006-03-08 21:57:44 +03:00
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
break;
|
|
|
|
}
|
2005-04-28 16:31:25 +04:00
|
|
|
|
2005-12-10 18:12:28 +03:00
|
|
|
case AS_LAYER_INVALIDATE_RECT:
|
2005-12-08 15:41:19 +03:00
|
|
|
{
|
2005-12-10 18:12:28 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_INVALIDATE_RECT: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
// NOTE: looks like this call is NOT affected by origin and scale on R5
|
|
|
|
// so this implementation is "correct"
|
|
|
|
BRect invalidRect;
|
|
|
|
if (link.Read<BRect>(&invalidRect) == B_OK) {
|
|
|
|
BRegion dirty(invalidRect);
|
|
|
|
fWindowLayer->InvalidateView(fCurrentLayer, dirty);
|
|
|
|
}
|
2004-06-18 23:13:06 +04:00
|
|
|
break;
|
|
|
|
}
|
2005-12-10 18:12:28 +03:00
|
|
|
case AS_LAYER_INVALIDATE_REGION:
|
2004-08-08 00:30:58 +04:00
|
|
|
{
|
2005-12-10 18:12:28 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_INVALIDATE_RECT: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
// NOTE: looks like this call is NOT affected by origin and scale on R5
|
|
|
|
// so this implementation is "correct"
|
2007-07-18 16:59:05 +04:00
|
|
|
BRegion region;
|
|
|
|
if (link.ReadRegion(®ion) < B_OK)
|
|
|
|
break;
|
2005-06-03 23:50:30 +04:00
|
|
|
|
2007-07-18 16:59:05 +04:00
|
|
|
fWindowLayer->InvalidateView(fCurrentLayer, region);
|
2004-08-08 00:30:58 +04:00
|
|
|
break;
|
|
|
|
}
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2004-09-15 02:21:26 +04:00
|
|
|
case AS_LAYER_SET_HIGH_COLOR:
|
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_SET_HIGH_COLOR: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
|
|
|
|
2004-09-15 02:21:26 +04:00
|
|
|
rgb_color c;
|
2004-10-16 06:02:27 +04:00
|
|
|
link.Read(&c, sizeof(rgb_color));
|
2004-09-15 02:21:26 +04:00
|
|
|
|
2005-11-04 15:15:36 +03:00
|
|
|
fCurrentLayer->CurrentState()->SetHighColor(RGBColor(c));
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
// _UpdateDrawState(fCurrentLayer);
|
|
|
|
fWindowLayer->GetDrawingEngine()->SetHighColor(c);
|
2004-09-15 02:21:26 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_LAYER_SET_LOW_COLOR:
|
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_SET_LOW_COLOR: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
|
|
|
|
2004-09-15 02:21:26 +04:00
|
|
|
rgb_color c;
|
2004-10-16 06:02:27 +04:00
|
|
|
link.Read(&c, sizeof(rgb_color));
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2005-11-04 15:15:36 +03:00
|
|
|
fCurrentLayer->CurrentState()->SetLowColor(RGBColor(c));
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
// _UpdateDrawState(fCurrentLayer);
|
|
|
|
fWindowLayer->GetDrawingEngine()->SetLowColor(c);
|
2004-09-15 02:21:26 +04:00
|
|
|
break;
|
|
|
|
}
|
2005-03-27 08:08:33 +04:00
|
|
|
case AS_LAYER_SET_PATTERN:
|
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_SET_PATTERN: ViewLayer: %s\n", fTitle, fCurrentLayer->Name()));
|
|
|
|
|
2005-03-27 08:08:33 +04:00
|
|
|
pattern pat;
|
|
|
|
link.Read(&pat, sizeof(pattern));
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2005-11-04 15:15:36 +03:00
|
|
|
fCurrentLayer->CurrentState()->SetPattern(Pattern(pat));
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
// _UpdateDrawState(fCurrentLayer);
|
|
|
|
fWindowLayer->GetDrawingEngine()->SetPattern(pat);
|
2005-03-27 08:08:33 +04:00
|
|
|
break;
|
2005-05-20 04:09:59 +04:00
|
|
|
}
|
|
|
|
case AS_SET_FONT:
|
|
|
|
{
|
2005-06-23 22:48:10 +04:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_SET_FONT\n", Title()));
|
2005-05-20 04:09:59 +04:00
|
|
|
// TODO: Implement AS_SET_FONT?
|
|
|
|
// Confusing!! But it works already!
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_SET_FONT_SIZE:
|
|
|
|
{
|
2005-06-23 22:48:10 +04:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_SET_FONT_SIZE\n", Title()));
|
2005-05-20 04:09:59 +04:00
|
|
|
// TODO: Implement AS_SET_FONT_SIZE?
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_SYNC:
|
|
|
|
{
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
// the synchronisation works by the fact that the client
|
|
|
|
// window is waiting for this reply, after having received it,
|
|
|
|
// client and server queues are in sync (earlier, the client
|
|
|
|
// may have pushed drawing commands at the server and now it
|
|
|
|
// knows they have all been carried out)
|
2005-11-30 18:47:01 +03:00
|
|
|
fLink.StartMessage(B_OK);
|
2005-06-24 02:43:11 +04:00
|
|
|
fLink.Flush();
|
2005-05-20 04:09:59 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_LAYER_DRAG_IMAGE:
|
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
// TODO: flesh out AS_LAYER_DRAG_IMAGE
|
|
|
|
STRACE(("ServerWindow %s: Message AS_DRAG_IMAGE\n", Title()));
|
|
|
|
|
|
|
|
int32 bitmapToken;
|
|
|
|
drawing_mode dragMode;
|
|
|
|
BPoint offset;
|
|
|
|
int32 bufferSize;
|
|
|
|
|
|
|
|
link.Read<int32>(&bitmapToken);
|
|
|
|
link.Read<int32>((int32*)&dragMode);
|
|
|
|
link.Read<BPoint>(&offset);
|
|
|
|
link.Read<int32>(&bufferSize);
|
|
|
|
|
|
|
|
if (bufferSize > 0) {
|
|
|
|
char* buffer = new (nothrow) char[bufferSize];
|
|
|
|
BMessage dragMessage;
|
|
|
|
if (link.Read(buffer, bufferSize) == B_OK
|
|
|
|
&& dragMessage.Unflatten(buffer) == B_OK) {
|
2006-03-08 21:57:44 +03:00
|
|
|
ServerBitmap* bitmap = fServerApp->FindBitmap(bitmapToken);
|
|
|
|
fDesktop->EventDispatcher().SetDragMessage(dragMessage,
|
|
|
|
bitmap, offset);
|
2005-12-08 15:41:19 +03:00
|
|
|
}
|
|
|
|
delete[] buffer;
|
|
|
|
}
|
2005-12-26 01:17:17 +03:00
|
|
|
// sync the client (it can now delete the bitmap)
|
|
|
|
fLink.StartMessage(B_OK);
|
|
|
|
fLink.Flush();
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2005-05-20 04:09:59 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_LAYER_DRAG_RECT:
|
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
// TODO: flesh out AS_LAYER_DRAG_RECT
|
|
|
|
STRACE(("ServerWindow %s: Message AS_DRAG_RECT\n", Title()));
|
2005-05-20 06:42:52 +04:00
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
BRect dragRect;
|
|
|
|
BPoint offset;
|
|
|
|
int32 bufferSize;
|
|
|
|
|
|
|
|
link.Read<BRect>(&dragRect);
|
|
|
|
link.Read<BPoint>(&offset);
|
|
|
|
link.Read<int32>(&bufferSize);
|
2005-05-20 06:42:52 +04:00
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
if (bufferSize > 0) {
|
|
|
|
char* buffer = new (nothrow) char[bufferSize];
|
|
|
|
BMessage dragMessage;
|
|
|
|
if (link.Read(buffer, bufferSize) == B_OK
|
|
|
|
&& dragMessage.Unflatten(buffer) == B_OK) {
|
2006-03-08 21:57:44 +03:00
|
|
|
fDesktop->EventDispatcher().SetDragMessage(dragMessage,
|
2006-04-11 01:22:05 +04:00
|
|
|
NULL /* should be dragRect */, offset);
|
2005-12-08 15:41:19 +03:00
|
|
|
}
|
|
|
|
delete[] buffer;
|
|
|
|
}
|
2005-11-30 22:51:43 +03:00
|
|
|
|
2005-05-20 04:09:59 +04:00
|
|
|
break;
|
|
|
|
}
|
2005-11-23 18:17:58 +03:00
|
|
|
|
2006-01-03 16:49:20 +03:00
|
|
|
case AS_LAYER_BEGIN_PICTURE:
|
|
|
|
{
|
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_BEGIN_PICTURE\n", Title()));
|
|
|
|
ServerPicture *picture = App()->CreatePicture();
|
2006-05-24 23:10:15 +04:00
|
|
|
picture->SyncState(fCurrentLayer);
|
2006-01-03 16:49:20 +03:00
|
|
|
fCurrentLayer->SetPicture(picture);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case AS_LAYER_APPEND_TO_PICTURE:
|
|
|
|
{
|
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_APPEND_TO_PICTURE\n", Title()));
|
|
|
|
|
|
|
|
int32 pictureToken;
|
|
|
|
link.Read<int32>(&pictureToken);
|
2006-05-24 23:10:15 +04:00
|
|
|
ServerPicture *picture = App()->FindPicture(pictureToken);
|
|
|
|
if (picture)
|
|
|
|
picture->SyncState(fCurrentLayer);
|
|
|
|
fCurrentLayer->SetPicture(picture);
|
2006-01-03 16:49:20 +03:00
|
|
|
// we don't care if it's NULL
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case AS_LAYER_END_PICTURE:
|
|
|
|
{
|
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_END_PICTURE\n", Title()));
|
|
|
|
|
|
|
|
ServerPicture *picture = fCurrentLayer->Picture();
|
|
|
|
if (picture != NULL) {
|
|
|
|
fCurrentLayer->SetPicture(NULL);
|
|
|
|
fLink.StartMessage(B_OK);
|
|
|
|
fLink.Attach<int32>(picture->Token());
|
|
|
|
} else
|
|
|
|
fLink.StartMessage(B_ERROR);
|
|
|
|
|
|
|
|
fLink.Flush();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2005-05-20 04:09:59 +04:00
|
|
|
default:
|
2006-03-10 14:42:58 +03:00
|
|
|
_DispatchViewDrawingMessage(code, link);
|
2005-05-20 06:42:52 +04:00
|
|
|
break;
|
2005-05-20 04:09:59 +04:00
|
|
|
}
|
|
|
|
}
|
2005-06-15 01:28:56 +04:00
|
|
|
|
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
/*!
|
|
|
|
Dispatches all view drawing messages.
|
|
|
|
The desktop clipping must be read locked when entering this method.
|
|
|
|
Requires a valid fCurrentLayer.
|
|
|
|
*/
|
2005-05-26 17:56:42 +04:00
|
|
|
void
|
2005-12-08 15:41:19 +03:00
|
|
|
ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &link)
|
2005-05-20 04:09:59 +04:00
|
|
|
{
|
2005-12-08 15:41:19 +03:00
|
|
|
if (!fCurrentLayer->IsVisible() || !fWindowLayer->IsVisible()) {
|
|
|
|
if (link.NeedsReply()) {
|
|
|
|
printf("ServerWindow::DispatchViewDrawingMessage() got message %ld that needs a reply!\n", code);
|
|
|
|
// the client is now blocking and waiting for a reply!
|
|
|
|
fLink.StartMessage(B_ERROR);
|
|
|
|
fLink.Flush();
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2005-05-20 04:09:59 +04:00
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
DrawingEngine* drawingEngine = fWindowLayer->GetDrawingEngine();
|
|
|
|
if (!drawingEngine) {
|
2005-11-04 16:45:16 +03:00
|
|
|
// ?!?
|
2005-12-08 15:41:19 +03:00
|
|
|
DTRACE(("ServerWindow %s: no drawing engine!!\n", Title()));
|
ServerFont:
* fixed weird pointer conversion in SetStyle()
* fixed a potential mix up in operator=() in case the
other ServerFont has fStyle == NULL
ServerWindow:
* the WindowLayer fTopLayer cannot be deleted by
client request, just for safety reasons
* the link is flushed if there is no drawing engine,
but this case is theoretical only
* deleting the ServerWindow object syncs with the
client, so that when BBitmaps are deleted, they
can be sure there are no pending messages (which
would be executed in a nother thread)
* there is no timeout anymore when sending messages
to the client, which made absolutely no sense
AGGTextRenderer:
* renamed fFontManager to fFontCache, because that's
what it really is
* fLastFamilyAndStyle defaulted to the system plain
font and therefor that font was never loaded when
the font never changed meanwhile
DrawingMode:
* I'm not quite sure but I think there was the
potential of a division by zero, at least I
had crashes with "divide error"
HWInterface:
* fix update when the cursor shape changed in
double buffered mode
ViewLayer:
* since the top layer is never really deleted
before its time has come, it is not necessary
to set it to NULL in the ViewLayer destructor
ViewLayer/WindowLayer:
* added a function to collect the view tokens
that are affected by an update session
EventDispatcher:
* use the importance of the message for the timeout
in _SendMessage()
* drop mouse moved events in the server if we're
lagging behind more than 5 ms (Axel, maybe review)
View:
* there were some problems with the locking
of the BWindow looper in RemoveSelf(), since
this is called from the window destructor,
also of BWindows from BBitmaps, which have
never been run (this might need review), at
least I seem to have solved the crashing
problems introduced by actually deleting the
view hirarchy in the BWindow destructor
* fixed _Draw() for being used non-recursively,
temporarily disabled DrawAfterChildren, which
didn't work yet anyways (because views cannot
draw over children in the server yet)
Window:
* small cleanup when deleting shortcuts
* sync with the server when having send
AS_DELETE_WINDOW (see ServerWindow above)
* fixed locking in Begin/EndViewTransaction()
* removed folding of _UPDATE_ messages, since
there is only one ever in the queue
* set the fInTransaction flag during an update,
I plan to use this in BView later to
flush the link when drawing outside of an
update
* BView::_Draw() is now called by view token,
this gives the next leap forward in speed,
the overhead because of drawing clean views
was considerable
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15878 a95241bf-73f2-0310-859d-f6bbb57e9c96
2006-01-09 01:04:52 +03:00
|
|
|
if (link.NeedsReply()) {
|
|
|
|
// the client is now blocking and waiting for a reply!
|
|
|
|
fLink.StartMessage(B_ERROR);
|
|
|
|
fLink.Flush();
|
|
|
|
}
|
2005-11-04 16:45:16 +03:00
|
|
|
return;
|
|
|
|
}
|
offscreen bitmaps work, tested on Haiku as well, supports all colorspaces that BBitmap::ImportBits() supports. It uses a fallback for non-B_RGB(A)32 bitmaps. Added support for B_SUB_PIXEL_PRECISION view flags, though it is a bit hacky, since I had to add it to LayerData, even though it is not a true part of stack data. Added Layer::SetFlags() to enforce code path and update fLayerData. Cleaned up DisplayDriverPainter and DisplayDriver API (changed some const BRect& rect to simply BRect rect in order to be able to reuse it in the code), moved Painter.h, the test environment only draws the changed part of the frame buffer again - this causes a lot less CPU overhead, Painter special cases stroke width of 1.0 to use square caps, which is similar to R5 implementation and removes a lot of problems with non-straight line drawing, ServerWindow uses the DisplayDriver from it's WinBorder instead of the one from the Desktop (needed for offscreen windows, which have their own DisplayDriverPainter), it also checks for GetRootLayer() == NULL, because offscreen layers are not attached to a RootLayer, there was a fix for scrolling which worked at least in the test environment, it is now defunced, because Adi moved _CopyBits to Layer... I need to reenable it later, LayerData has no more fEscapementDelta, also fixed fFontAliasing (which was thought to overriding the font flags, and now works as such again), Desktop initialises the menu_info and scroll_bar_info stuff, which makes ScrollBars work actually... hope I didn't forget something.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13448 a95241bf-73f2-0310-859d-f6bbb57e9c96
2005-07-05 20:17:16 +04:00
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
if (!fCurrentDrawingRegionValid || fWindowLayer->DrawingRegionChanged(fCurrentLayer)) {
|
|
|
|
fWindowLayer->GetEffectiveDrawingRegion(fCurrentLayer, fCurrentDrawingRegion);
|
|
|
|
fCurrentDrawingRegionValid = true;
|
|
|
|
}
|
|
|
|
|
2005-12-21 01:30:02 +03:00
|
|
|
if (fCurrentDrawingRegion.CountRects() <= 0) {
|
|
|
|
if (link.NeedsReply()) {
|
|
|
|
// the client is now blocking and waiting for a reply!
|
|
|
|
fLink.StartMessage(B_ERROR);
|
|
|
|
fLink.Flush();
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2006-12-05 01:25:17 +03:00
|
|
|
drawingEngine->LockParallelAccess();
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
// NOTE: the region is not copied, Painter keeps a pointer,
|
|
|
|
// that's why you need to use the clipping only for as long
|
|
|
|
// as you have it locked
|
2005-12-08 15:41:19 +03:00
|
|
|
drawingEngine->ConstrainClippingRegion(&fCurrentDrawingRegion);
|
2005-05-20 04:09:59 +04:00
|
|
|
|
2005-05-26 17:56:42 +04:00
|
|
|
switch (code) {
|
2004-09-14 04:51:51 +04:00
|
|
|
case AS_STROKE_LINE:
|
|
|
|
{
|
2005-06-23 22:48:10 +04:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_STROKE_LINE\n", Title()));
|
2005-05-26 17:56:42 +04:00
|
|
|
|
2004-09-14 04:51:51 +04:00
|
|
|
float x1, y1, x2, y2;
|
2005-05-26 17:56:42 +04:00
|
|
|
|
2004-10-16 06:02:27 +04:00
|
|
|
link.Read<float>(&x1);
|
|
|
|
link.Read<float>(&y1);
|
|
|
|
link.Read<float>(&x2);
|
|
|
|
link.Read<float>(&y2);
|
2005-05-26 17:56:42 +04:00
|
|
|
|
2005-11-09 16:28:15 +03:00
|
|
|
BPoint p1(x1, y1);
|
|
|
|
BPoint p2(x2, y2);
|
|
|
|
BPoint penPos = p2;
|
2005-11-20 18:10:18 +03:00
|
|
|
fCurrentLayer->ConvertToScreenForDrawing(&p1);
|
|
|
|
fCurrentLayer->ConvertToScreenForDrawing(&p2);
|
2005-12-08 15:41:19 +03:00
|
|
|
drawingEngine->StrokeLine(p1, p2, fCurrentLayer->CurrentState());
|
2005-11-04 16:45:16 +03:00
|
|
|
|
2005-11-04 18:23:54 +03:00
|
|
|
// We update the pen here because many DrawingEngine calls which do not update the
|
2005-11-04 16:45:16 +03:00
|
|
|
// pen position actually call StrokeLine
|
2005-04-19 04:42:42 +04:00
|
|
|
|
2005-11-04 16:45:16 +03:00
|
|
|
// TODO: Decide where to put this, for example, it cannot be done
|
|
|
|
// for DrawString(), also there needs to be a decision, if penlocation
|
|
|
|
// is in View coordinates (I think it should be) or in screen coordinates.
|
2005-11-09 16:28:15 +03:00
|
|
|
fCurrentLayer->CurrentState()->SetPenLocation(penPos);
|
2004-09-14 04:51:51 +04:00
|
|
|
break;
|
|
|
|
}
|
2005-01-21 05:01:28 +03:00
|
|
|
case AS_LAYER_INVERT_RECT:
|
|
|
|
{
|
2005-06-23 22:48:10 +04:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_INVERT_RECT\n", Title()));
|
2005-01-21 05:01:28 +03:00
|
|
|
|
|
|
|
BRect rect;
|
|
|
|
link.Read<BRect>(&rect);
|
|
|
|
|
2005-11-20 18:10:18 +03:00
|
|
|
fCurrentLayer->ConvertToScreenForDrawing(&rect);
|
2005-12-08 15:41:19 +03:00
|
|
|
drawingEngine->InvertRect(rect);
|
2005-01-21 05:01:28 +03:00
|
|
|
break;
|
|
|
|
}
|
2004-09-15 02:21:26 +04:00
|
|
|
case AS_STROKE_RECT:
|
|
|
|
{
|
2005-06-23 22:48:10 +04:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_STROKE_RECT\n", Title()));
|
2004-10-17 02:42:08 +04:00
|
|
|
|
2004-09-15 02:21:26 +04:00
|
|
|
float left, top, right, bottom;
|
2004-10-16 06:02:27 +04:00
|
|
|
link.Read<float>(&left);
|
|
|
|
link.Read<float>(&top);
|
|
|
|
link.Read<float>(&right);
|
|
|
|
link.Read<float>(&bottom);
|
2004-09-15 02:21:26 +04:00
|
|
|
BRect rect(left,top,right,bottom);
|
2005-11-04 16:45:16 +03:00
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
fCurrentLayer->ConvertToScreenForDrawing(&rect);
|
|
|
|
drawingEngine->StrokeRect(rect, fCurrentLayer->CurrentState());
|
2004-10-17 02:42:08 +04:00
|
|
|
break;
|
2004-09-15 02:21:26 +04:00
|
|
|
}
|
|
|
|
case AS_FILL_RECT:
|
|
|
|
{
|
2005-06-23 22:48:10 +04:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_FILL_RECT\n", Title()));
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2004-09-15 02:21:26 +04:00
|
|
|
BRect rect;
|
2004-10-16 06:02:27 +04:00
|
|
|
link.Read<BRect>(&rect);
|
2005-11-08 20:38:07 +03:00
|
|
|
|
2005-11-20 18:10:18 +03:00
|
|
|
fCurrentLayer->ConvertToScreenForDrawing(&rect);
|
2005-12-08 15:41:19 +03:00
|
|
|
drawingEngine->FillRect(rect, fCurrentLayer->CurrentState());
|
2004-10-17 02:42:08 +04:00
|
|
|
break;
|
2004-09-15 02:21:26 +04:00
|
|
|
}
|
2006-01-04 15:15:58 +03:00
|
|
|
case AS_LAYER_DRAW_BITMAP:
|
2005-05-20 04:09:59 +04:00
|
|
|
{
|
2006-01-04 15:15:58 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_LAYER_DRAW_BITMAP: ViewLayer name: %s\n", fTitle, fCurrentLayer->Name()));
|
2005-05-20 04:09:59 +04:00
|
|
|
int32 bitmapToken;
|
|
|
|
BRect srcRect, dstRect;
|
2005-11-25 18:35:47 +03:00
|
|
|
|
2005-05-20 04:09:59 +04:00
|
|
|
link.Read<int32>(&bitmapToken);
|
|
|
|
link.Read<BRect>(&dstRect);
|
|
|
|
link.Read<BRect>(&srcRect);
|
2005-11-25 18:35:47 +03:00
|
|
|
|
|
|
|
ServerBitmap* bitmap = fServerApp->FindBitmap(bitmapToken);
|
|
|
|
if (bitmap) {
|
2005-11-20 18:10:18 +03:00
|
|
|
fCurrentLayer->ConvertToScreenForDrawing(&dstRect);
|
2005-05-20 04:09:59 +04:00
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
drawingEngine->DrawBitmap(bitmap, srcRect, dstRect, fCurrentLayer->CurrentState());
|
2005-05-20 04:09:59 +04:00
|
|
|
}
|
2005-11-25 18:35:47 +03:00
|
|
|
|
2004-09-15 02:21:26 +04:00
|
|
|
break;
|
|
|
|
}
|
2005-11-04 16:45:16 +03:00
|
|
|
case AS_STROKE_ARC:
|
2004-09-15 02:21:26 +04:00
|
|
|
case AS_FILL_ARC:
|
|
|
|
{
|
2005-11-04 16:45:16 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_STROKE/FILL_ARC\n", Title()));
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2004-09-15 02:21:26 +04:00
|
|
|
float angle, span;
|
|
|
|
BRect r;
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2004-10-16 06:02:27 +04:00
|
|
|
link.Read<BRect>(&r);
|
|
|
|
link.Read<float>(&angle);
|
|
|
|
link.Read<float>(&span);
|
2005-11-04 16:45:16 +03:00
|
|
|
|
2005-11-20 18:10:18 +03:00
|
|
|
fCurrentLayer->ConvertToScreenForDrawing(&r);
|
2006-05-04 00:33:18 +04:00
|
|
|
drawingEngine->DrawArc(r, angle, span, fCurrentLayer->CurrentState(),
|
|
|
|
code == AS_FILL_ARC);
|
2004-09-15 02:21:26 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_STROKE_BEZIER:
|
|
|
|
case AS_FILL_BEZIER:
|
|
|
|
{
|
2005-11-04 16:45:16 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_STROKE/FILL_BEZIER\n", Title()));
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2005-11-04 16:45:16 +03:00
|
|
|
BPoint pts[4];
|
|
|
|
for (int32 i = 0; i < 4; i++) {
|
2004-10-16 06:02:27 +04:00
|
|
|
link.Read<BPoint>(&(pts[i]));
|
2005-11-20 18:10:18 +03:00
|
|
|
fCurrentLayer->ConvertToScreenForDrawing(&pts[i]);
|
2005-11-04 16:45:16 +03:00
|
|
|
}
|
|
|
|
|
2006-05-04 00:33:18 +04:00
|
|
|
drawingEngine->DrawBezier(pts, fCurrentLayer->CurrentState(),
|
|
|
|
code == AS_FILL_BEZIER);
|
2004-09-15 02:21:26 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_STROKE_ELLIPSE:
|
|
|
|
case AS_FILL_ELLIPSE:
|
|
|
|
{
|
2005-11-04 16:45:16 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_STROKE/FILL_ELLIPSE\n", Title()));
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2004-09-15 02:21:26 +04:00
|
|
|
BRect rect;
|
2004-10-16 06:02:27 +04:00
|
|
|
link.Read<BRect>(&rect);
|
2005-11-04 16:45:16 +03:00
|
|
|
|
2005-11-20 18:10:18 +03:00
|
|
|
fCurrentLayer->ConvertToScreenForDrawing(&rect);
|
2005-12-08 15:41:19 +03:00
|
|
|
drawingEngine->DrawEllipse(rect, fCurrentLayer->CurrentState(), code == AS_FILL_ELLIPSE);
|
2004-09-15 02:21:26 +04:00
|
|
|
break;
|
|
|
|
}
|
2005-11-04 16:45:16 +03:00
|
|
|
case AS_STROKE_ROUNDRECT:
|
2004-09-15 02:21:26 +04:00
|
|
|
case AS_FILL_ROUNDRECT:
|
|
|
|
{
|
2005-11-04 16:45:16 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_STROKE/FILL_ROUNDRECT\n", Title()));
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2004-09-15 02:21:26 +04:00
|
|
|
BRect rect;
|
|
|
|
float xrad,yrad;
|
2004-10-16 06:02:27 +04:00
|
|
|
link.Read<BRect>(&rect);
|
|
|
|
link.Read<float>(&xrad);
|
|
|
|
link.Read<float>(&yrad);
|
2005-07-01 12:50:45 +04:00
|
|
|
|
2005-11-20 18:10:18 +03:00
|
|
|
fCurrentLayer->ConvertToScreenForDrawing(&rect);
|
2005-12-08 15:41:19 +03:00
|
|
|
drawingEngine->DrawRoundRect(rect, xrad, yrad, fCurrentLayer->CurrentState(), code == AS_FILL_ROUNDRECT);
|
2004-09-15 02:21:26 +04:00
|
|
|
break;
|
|
|
|
}
|
2005-11-04 16:45:16 +03:00
|
|
|
case AS_STROKE_TRIANGLE:
|
2004-09-15 02:21:26 +04:00
|
|
|
case AS_FILL_TRIANGLE:
|
|
|
|
{
|
2005-11-04 16:45:16 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_STROKE/FILL_TRIANGLE\n", Title()));
|
2005-07-01 12:50:45 +04:00
|
|
|
|
2004-09-15 02:21:26 +04:00
|
|
|
BPoint pts[3];
|
|
|
|
BRect rect;
|
2005-07-01 12:50:45 +04:00
|
|
|
|
2005-11-04 16:45:16 +03:00
|
|
|
for (int32 i = 0; i < 3; i++) {
|
2004-10-16 06:02:27 +04:00
|
|
|
link.Read<BPoint>(&(pts[i]));
|
2005-11-20 18:10:18 +03:00
|
|
|
fCurrentLayer->ConvertToScreenForDrawing(&pts[i]);
|
2005-11-04 16:45:16 +03:00
|
|
|
}
|
2005-07-01 12:50:45 +04:00
|
|
|
|
2004-10-16 06:02:27 +04:00
|
|
|
link.Read<BRect>(&rect);
|
2005-07-01 12:50:45 +04:00
|
|
|
|
2005-11-20 18:10:18 +03:00
|
|
|
fCurrentLayer->ConvertToScreenForDrawing(&rect);
|
2005-12-08 15:41:19 +03:00
|
|
|
drawingEngine->DrawTriangle(pts, rect, fCurrentLayer->CurrentState(), code == AS_FILL_TRIANGLE);
|
2004-09-15 02:21:26 +04:00
|
|
|
break;
|
|
|
|
}
|
2004-09-17 14:27:58 +04:00
|
|
|
case AS_STROKE_POLYGON:
|
2005-11-04 16:45:16 +03:00
|
|
|
case AS_FILL_POLYGON:
|
2003-02-24 18:47:06 +03:00
|
|
|
{
|
2005-11-04 16:45:16 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_STROKE/FILL_POLYGON\n", Title()));
|
2005-07-01 12:50:45 +04:00
|
|
|
|
2005-11-10 16:37:08 +03:00
|
|
|
BRect polyFrame;
|
|
|
|
bool isClosed = true;
|
|
|
|
int32 pointCount;
|
2005-07-01 12:50:45 +04:00
|
|
|
|
2005-11-10 16:37:08 +03:00
|
|
|
link.Read<BRect>(&polyFrame);
|
2005-11-04 16:45:16 +03:00
|
|
|
if (code == AS_STROKE_POLYGON)
|
2005-11-10 16:37:08 +03:00
|
|
|
link.Read<bool>(&isClosed);
|
|
|
|
link.Read<int32>(&pointCount);
|
2005-07-01 12:50:45 +04:00
|
|
|
|
2005-11-10 16:37:08 +03:00
|
|
|
BPoint* pointList = new(nothrow) BPoint[pointCount];
|
|
|
|
if (link.Read(pointList, pointCount * sizeof(BPoint)) >= B_OK) {
|
|
|
|
for (int32 i = 0; i < pointCount; i++)
|
2005-11-20 18:10:18 +03:00
|
|
|
fCurrentLayer->ConvertToScreenForDrawing(&pointList[i]);
|
2006-05-04 00:33:18 +04:00
|
|
|
fCurrentLayer->ConvertToScreenForDrawing(&polyFrame);
|
2005-12-08 15:41:19 +03:00
|
|
|
|
|
|
|
drawingEngine->DrawPolygon(pointList, pointCount, polyFrame,
|
|
|
|
fCurrentLayer->CurrentState(), code == AS_FILL_POLYGON,
|
|
|
|
isClosed && pointCount > 2);
|
2005-11-10 16:37:08 +03:00
|
|
|
}
|
2005-11-20 18:10:18 +03:00
|
|
|
delete[] pointList;
|
2004-09-17 14:27:58 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_STROKE_SHAPE:
|
2005-11-04 16:45:16 +03:00
|
|
|
case AS_FILL_SHAPE:
|
2004-09-17 14:27:58 +04:00
|
|
|
{
|
2005-11-04 16:45:16 +03:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_STROKE/FILL_SHAPE\n", Title()));
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2005-11-10 16:37:08 +03:00
|
|
|
BRect shapeFrame;
|
|
|
|
int32 opCount;
|
|
|
|
int32 ptCount;
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2005-11-10 16:37:08 +03:00
|
|
|
link.Read<BRect>(&shapeFrame);
|
|
|
|
link.Read<int32>(&opCount);
|
|
|
|
link.Read<int32>(&ptCount);
|
2005-07-01 12:50:45 +04:00
|
|
|
|
2005-11-10 16:37:08 +03:00
|
|
|
uint32* opList = new(nothrow) uint32[opCount];
|
|
|
|
BPoint* ptList = new(nothrow) BPoint[ptCount];
|
|
|
|
if (link.Read(opList, opCount * sizeof(uint32)) >= B_OK &&
|
|
|
|
link.Read(ptList, ptCount * sizeof(BPoint)) >= B_OK) {
|
2005-07-01 12:50:45 +04:00
|
|
|
|
2005-11-10 16:37:08 +03:00
|
|
|
for (int32 i = 0; i < ptCount; i++)
|
2005-11-20 18:10:18 +03:00
|
|
|
fCurrentLayer->ConvertToScreenForDrawing(&ptList[i]);
|
2005-12-08 15:41:19 +03:00
|
|
|
|
|
|
|
drawingEngine->DrawShape(shapeFrame, opCount, opList, ptCount, ptList,
|
|
|
|
fCurrentLayer->CurrentState(), code == AS_FILL_SHAPE);
|
2005-11-10 16:37:08 +03:00
|
|
|
}
|
2005-07-01 12:50:45 +04:00
|
|
|
|
2005-11-10 16:37:08 +03:00
|
|
|
delete[] opList;
|
|
|
|
delete[] ptList;
|
2004-09-17 14:27:58 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_FILL_REGION:
|
2003-07-09 06:28:33 +04:00
|
|
|
{
|
2005-06-23 22:48:10 +04:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_FILL_REGION\n", Title()));
|
2005-12-08 15:41:19 +03:00
|
|
|
|
offscreen bitmaps work, tested on Haiku as well, supports all colorspaces that BBitmap::ImportBits() supports. It uses a fallback for non-B_RGB(A)32 bitmaps. Added support for B_SUB_PIXEL_PRECISION view flags, though it is a bit hacky, since I had to add it to LayerData, even though it is not a true part of stack data. Added Layer::SetFlags() to enforce code path and update fLayerData. Cleaned up DisplayDriverPainter and DisplayDriver API (changed some const BRect& rect to simply BRect rect in order to be able to reuse it in the code), moved Painter.h, the test environment only draws the changed part of the frame buffer again - this causes a lot less CPU overhead, Painter special cases stroke width of 1.0 to use square caps, which is similar to R5 implementation and removes a lot of problems with non-straight line drawing, ServerWindow uses the DisplayDriver from it's WinBorder instead of the one from the Desktop (needed for offscreen windows, which have their own DisplayDriverPainter), it also checks for GetRootLayer() == NULL, because offscreen layers are not attached to a RootLayer, there was a fix for scrolling which worked at least in the test environment, it is now defunced, because Adi moved _CopyBits to Layer... I need to reenable it later, LayerData has no more fEscapementDelta, also fixed fFontAliasing (which was thought to overriding the font flags, and now works as such again), Desktop initialises the menu_info and scroll_bar_info stuff, which makes ScrollBars work actually... hope I didn't forget something.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13448 a95241bf-73f2-0310-859d-f6bbb57e9c96
2005-07-05 20:17:16 +04:00
|
|
|
BRegion region;
|
2006-04-01 20:56:10 +04:00
|
|
|
if (link.ReadRegion(®ion) < B_OK)
|
|
|
|
break;
|
2005-11-08 20:38:07 +03:00
|
|
|
|
2005-11-20 18:10:18 +03:00
|
|
|
fCurrentLayer->ConvertToScreenForDrawing(®ion);
|
2005-12-08 15:41:19 +03:00
|
|
|
drawingEngine->FillRegion(region, fCurrentLayer->CurrentState());
|
2005-06-23 22:48:10 +04:00
|
|
|
|
2004-09-17 14:27:58 +04:00
|
|
|
break;
|
2003-07-09 06:28:33 +04:00
|
|
|
}
|
2004-09-17 14:27:58 +04:00
|
|
|
case AS_STROKE_LINEARRAY:
|
|
|
|
{
|
2005-06-23 22:48:10 +04:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_STROKE_LINEARRAY\n", Title()));
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2004-10-16 06:02:27 +04:00
|
|
|
// Attached Data:
|
|
|
|
// 1) int32 Number of lines in the array
|
2006-04-23 19:55:15 +04:00
|
|
|
// 2) LineArrayData
|
2005-07-01 12:50:45 +04:00
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
int32 lineCount;
|
|
|
|
|
|
|
|
link.Read<int32>(&lineCount);
|
|
|
|
if (lineCount > 0) {
|
|
|
|
LineArrayData lineData[lineCount];
|
|
|
|
|
|
|
|
for (int32 i = 0; i < lineCount; i++) {
|
|
|
|
LineArrayData* index = &lineData[i];
|
2005-07-01 12:50:45 +04:00
|
|
|
|
2004-10-16 06:02:27 +04:00
|
|
|
link.Read<float>(&(index->pt1.x));
|
|
|
|
link.Read<float>(&(index->pt1.y));
|
|
|
|
link.Read<float>(&(index->pt2.x));
|
|
|
|
link.Read<float>(&(index->pt2.y));
|
|
|
|
link.Read<rgb_color>(&(index->color));
|
2005-07-01 12:50:45 +04:00
|
|
|
|
2005-11-20 18:10:18 +03:00
|
|
|
fCurrentLayer->ConvertToScreenForDrawing(&index->pt1);
|
|
|
|
fCurrentLayer->ConvertToScreenForDrawing(&index->pt2);
|
2005-07-01 12:50:45 +04:00
|
|
|
}
|
2005-12-08 15:41:19 +03:00
|
|
|
drawingEngine->StrokeLineArray(lineCount, lineData,
|
|
|
|
fCurrentLayer->CurrentState());
|
2004-10-16 06:02:27 +04:00
|
|
|
}
|
2004-09-17 14:27:58 +04:00
|
|
|
break;
|
|
|
|
}
|
2004-09-21 02:50:02 +04:00
|
|
|
case AS_DRAW_STRING:
|
2003-07-05 01:13:48 +04:00
|
|
|
{
|
2005-06-23 22:48:10 +04:00
|
|
|
DTRACE(("ServerWindow %s: Message AS_DRAW_STRING\n", Title()));
|
2005-12-20 00:18:01 +03:00
|
|
|
char* string;
|
2004-09-21 02:50:02 +04:00
|
|
|
int32 length;
|
|
|
|
BPoint location;
|
|
|
|
escapement_delta delta;
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2004-10-17 02:42:08 +04:00
|
|
|
link.Read<int32>(&length);
|
2004-10-16 06:02:27 +04:00
|
|
|
link.Read<BPoint>(&location);
|
|
|
|
link.Read<escapement_delta>(&delta);
|
|
|
|
link.ReadString(&string);
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2005-11-20 18:10:18 +03:00
|
|
|
fCurrentLayer->ConvertToScreenForDrawing(&location);
|
2005-12-08 15:41:19 +03:00
|
|
|
BPoint penLocation = drawingEngine->DrawString(string, length, location,
|
|
|
|
fCurrentLayer->CurrentState(), &delta);
|
|
|
|
|
2005-11-20 18:10:18 +03:00
|
|
|
fCurrentLayer->ConvertFromScreenForDrawing(&penLocation);
|
2005-11-09 19:55:08 +03:00
|
|
|
fCurrentLayer->CurrentState()->SetPenLocation(penLocation);
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
// TODO: optimize with flags
|
|
|
|
_UpdateDrawState(fCurrentLayer);
|
2005-12-08 15:41:19 +03:00
|
|
|
|
2004-09-21 02:50:02 +04:00
|
|
|
free(string);
|
2004-09-17 14:27:58 +04:00
|
|
|
break;
|
2003-07-05 01:13:48 +04:00
|
|
|
}
|
2006-01-03 15:44:29 +03:00
|
|
|
|
|
|
|
case AS_LAYER_DRAW_PICTURE:
|
|
|
|
{
|
|
|
|
int32 token;
|
|
|
|
if (link.Read<int32>(&token) == B_OK) {
|
|
|
|
BPoint where;
|
|
|
|
link.Read<BPoint>(&where);
|
|
|
|
|
|
|
|
ServerPicture *picture = App()->FindPicture(token);
|
|
|
|
if (picture != NULL) {
|
|
|
|
fCurrentLayer->ConvertToScreenForDrawing(&where);
|
|
|
|
fCurrentLayer->CurrentState()->SetPenLocation(where);
|
2006-01-18 23:49:29 +03:00
|
|
|
// TODO: pass the location to the play method and handle it there
|
2006-01-03 15:44:29 +03:00
|
|
|
picture->Play(fCurrentLayer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2004-09-17 14:27:58 +04:00
|
|
|
default:
|
2005-07-01 12:50:45 +04:00
|
|
|
printf("ServerWindow %s received unexpected code - message offset %ld\n",
|
2005-11-30 18:47:01 +03:00
|
|
|
Title(), code - B_OK);
|
2005-07-01 12:50:45 +04:00
|
|
|
|
|
|
|
if (link.NeedsReply()) {
|
|
|
|
// the client is now blocking and waiting for a reply!
|
2005-11-30 18:47:01 +03:00
|
|
|
fLink.StartMessage(B_ERROR);
|
2005-07-01 12:50:45 +04:00
|
|
|
fLink.Flush();
|
|
|
|
}
|
2004-09-17 14:27:58 +04:00
|
|
|
break;
|
2003-06-23 06:53:55 +04:00
|
|
|
}
|
2005-03-31 00:06:50 +04:00
|
|
|
|
2006-12-05 01:25:17 +03:00
|
|
|
drawingEngine->UnlockParallelAccess();
|
2003-03-19 04:12:53 +03:00
|
|
|
}
|
2005-05-26 19:04:45 +04:00
|
|
|
|
2005-06-24 02:43:11 +04:00
|
|
|
|
2006-01-04 10:30:38 +03:00
|
|
|
bool
|
|
|
|
ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link)
|
|
|
|
{
|
|
|
|
ServerPicture *picture = fCurrentLayer->Picture();
|
|
|
|
if (picture == NULL)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
switch (code) {
|
2006-02-11 01:20:32 +03:00
|
|
|
case AS_LAYER_SET_ORIGIN:
|
|
|
|
{
|
|
|
|
float x, y;
|
|
|
|
link.Read<float>(&x);
|
|
|
|
link.Read<float>(&y);
|
|
|
|
|
2006-11-12 23:00:36 +03:00
|
|
|
picture->WriteSetOrigin(BPoint(x, y));
|
2006-02-11 01:20:32 +03:00
|
|
|
break;
|
|
|
|
}
|
2006-02-11 20:48:19 +03:00
|
|
|
|
|
|
|
case AS_LAYER_INVERT_RECT:
|
|
|
|
{
|
|
|
|
BRect rect;
|
|
|
|
link.Read<BRect>(&rect);
|
2006-11-12 23:00:36 +03:00
|
|
|
picture->WriteInvertRect(rect);
|
2006-02-11 20:48:19 +03:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2006-11-10 00:53:45 +03:00
|
|
|
|
2006-02-11 20:48:19 +03:00
|
|
|
case AS_LAYER_PUSH_STATE:
|
|
|
|
{
|
2006-11-12 23:00:36 +03:00
|
|
|
picture->WritePushState();
|
2006-02-11 20:48:19 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case AS_LAYER_POP_STATE:
|
|
|
|
{
|
2006-11-12 23:00:36 +03:00
|
|
|
picture->WritePopState();
|
2006-02-11 20:48:19 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case AS_LAYER_SET_DRAWING_MODE:
|
|
|
|
{
|
|
|
|
int8 drawingMode;
|
|
|
|
link.Read<int8>(&drawingMode);
|
|
|
|
|
2006-11-12 23:00:36 +03:00
|
|
|
picture->WriteSetDrawingMode((drawing_mode)drawingMode);
|
2006-02-11 20:48:19 +03:00
|
|
|
break;
|
|
|
|
}
|
2006-11-12 23:00:36 +03:00
|
|
|
|
2006-02-11 20:48:19 +03:00
|
|
|
case AS_LAYER_SET_PEN_SIZE:
|
|
|
|
{
|
|
|
|
float penSize;
|
|
|
|
link.Read<float>(&penSize);
|
2006-11-12 23:00:36 +03:00
|
|
|
picture->WriteSetPenSize(penSize);
|
2006-02-11 20:48:19 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2006-11-12 23:00:36 +03:00
|
|
|
case AS_LAYER_SET_LINE_MODE:
|
|
|
|
{
|
|
|
|
int8 lineCap, lineJoin;
|
|
|
|
float miterLimit;
|
|
|
|
|
|
|
|
link.Read<int8>(&lineCap);
|
|
|
|
link.Read<int8>(&lineJoin);
|
|
|
|
link.Read<float>(&miterLimit);
|
|
|
|
|
|
|
|
picture->WriteSetLineMode((cap_mode)lineCap, (join_mode)lineJoin, miterLimit);
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2006-10-26 23:49:02 +04:00
|
|
|
case AS_LAYER_SET_SCALE:
|
|
|
|
{
|
|
|
|
float scale;
|
|
|
|
link.Read<float>(&scale);
|
2006-11-12 23:00:36 +03:00
|
|
|
picture->WriteSetScale(scale);
|
2006-10-26 23:49:02 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2006-01-04 10:30:38 +03:00
|
|
|
case AS_FILL_RECT:
|
2006-01-18 23:49:29 +03:00
|
|
|
case AS_STROKE_RECT:
|
2006-01-04 10:30:38 +03:00
|
|
|
{
|
|
|
|
BRect rect;
|
|
|
|
link.Read<BRect>(&rect);
|
|
|
|
|
2006-11-12 23:00:36 +03:00
|
|
|
picture->WriteDrawRect(rect, code == AS_FILL_RECT);
|
2006-01-04 10:30:38 +03:00
|
|
|
break;
|
|
|
|
}
|
2006-01-18 23:49:29 +03:00
|
|
|
|
2006-02-11 20:48:19 +03:00
|
|
|
case AS_STROKE_ROUNDRECT:
|
|
|
|
case AS_FILL_ROUNDRECT:
|
|
|
|
{
|
|
|
|
BRect rect;
|
|
|
|
link.Read<BRect>(&rect);
|
|
|
|
|
|
|
|
BPoint radii;
|
|
|
|
link.Read<float>(&radii.x);
|
|
|
|
link.Read<float>(&radii.y);
|
|
|
|
|
2006-11-12 23:00:36 +03:00
|
|
|
picture->WriteDrawRoundRect(rect, radii, code == AS_FILL_ROUNDRECT);
|
2006-02-11 20:48:19 +03:00
|
|
|
break;
|
|
|
|
}
|
2006-11-10 00:53:45 +03:00
|
|
|
|
2006-10-23 13:50:22 +04:00
|
|
|
case AS_STROKE_ELLIPSE:
|
|
|
|
case AS_FILL_ELLIPSE:
|
|
|
|
{
|
|
|
|
BRect rect;
|
|
|
|
link.Read<BRect>(&rect);
|
2006-11-12 23:00:36 +03:00
|
|
|
picture->WriteDrawEllipse(rect, code == AS_FILL_ELLIPSE);
|
2006-10-23 13:50:22 +04:00
|
|
|
break;
|
|
|
|
}
|
2006-11-10 00:53:45 +03:00
|
|
|
|
2006-10-23 15:54:44 +04:00
|
|
|
case AS_STROKE_ARC:
|
|
|
|
case AS_FILL_ARC:
|
|
|
|
{
|
|
|
|
BRect rect;
|
|
|
|
link.Read<BRect>(&rect);
|
|
|
|
float startTheta, arcTheta;
|
|
|
|
link.Read<float>(&startTheta);
|
|
|
|
link.Read<float>(&arcTheta);
|
|
|
|
|
|
|
|
BPoint radii((rect.Width() + 1) / 2, (rect.Height() + 1) / 2);
|
|
|
|
BPoint center = rect.LeftTop() + radii;
|
|
|
|
|
2006-11-12 23:00:36 +03:00
|
|
|
picture->WriteDrawArc(center, radii, startTheta, arcTheta, code == AS_FILL_ARC);
|
2006-10-23 15:54:44 +04:00
|
|
|
break;
|
|
|
|
}
|
2006-11-10 00:53:45 +03:00
|
|
|
|
2006-01-18 23:49:29 +03:00
|
|
|
case AS_STROKE_LINE:
|
|
|
|
{
|
|
|
|
float x1, y1, x2, y2;
|
|
|
|
|
|
|
|
link.Read<float>(&x1);
|
|
|
|
link.Read<float>(&y1);
|
|
|
|
link.Read<float>(&x2);
|
|
|
|
link.Read<float>(&y2);
|
|
|
|
|
2006-11-12 23:00:36 +03:00
|
|
|
picture->WriteStrokeLine(BPoint(x1, y1), BPoint(x2, y2));
|
2006-01-18 23:49:29 +03:00
|
|
|
break;
|
|
|
|
}
|
2006-02-11 01:20:32 +03:00
|
|
|
|
|
|
|
case AS_STROKE_LINEARRAY:
|
|
|
|
{
|
|
|
|
int32 lineCount;
|
|
|
|
link.Read<int32>(&lineCount);
|
2006-02-11 20:48:19 +03:00
|
|
|
if (lineCount <= 0)
|
|
|
|
break;
|
|
|
|
|
2006-11-12 23:00:36 +03:00
|
|
|
picture->WritePushState();
|
2006-05-24 23:10:15 +04:00
|
|
|
|
2006-02-11 01:20:32 +03:00
|
|
|
for (int32 i = 0; i < lineCount; i++) {
|
|
|
|
float x1, y1, x2, y2;
|
|
|
|
link.Read<float>(&x1);
|
|
|
|
link.Read<float>(&y1);
|
|
|
|
link.Read<float>(&x2);
|
|
|
|
link.Read<float>(&y2);
|
|
|
|
|
|
|
|
rgb_color color;
|
|
|
|
link.Read<rgb_color>(&color);
|
|
|
|
|
2006-11-12 23:00:36 +03:00
|
|
|
picture->WriteSetHighColor(color);
|
|
|
|
picture->WriteStrokeLine(BPoint(x1, y1), BPoint(x2, y2));
|
2006-02-11 01:20:32 +03:00
|
|
|
}
|
2006-02-11 20:48:19 +03:00
|
|
|
|
2006-11-12 23:00:36 +03:00
|
|
|
picture->WritePopState();
|
2006-02-11 01:20:32 +03:00
|
|
|
break;
|
|
|
|
}
|
2006-01-18 23:49:29 +03:00
|
|
|
|
|
|
|
case AS_LAYER_SET_LOW_COLOR:
|
|
|
|
case AS_LAYER_SET_HIGH_COLOR:
|
|
|
|
{
|
|
|
|
rgb_color color;
|
|
|
|
link.Read(&color, sizeof(rgb_color));
|
|
|
|
|
2006-11-12 23:00:36 +03:00
|
|
|
if (code == AS_LAYER_SET_HIGH_COLOR)
|
|
|
|
picture->WriteSetHighColor(color);
|
|
|
|
else
|
|
|
|
picture->WriteSetLowColor(color);
|
2006-01-18 23:49:29 +03:00
|
|
|
break;
|
|
|
|
}
|
2006-01-19 00:29:29 +03:00
|
|
|
|
|
|
|
case AS_DRAW_STRING:
|
|
|
|
{
|
2006-10-31 14:24:58 +03:00
|
|
|
char* string = NULL;
|
2006-01-19 00:29:29 +03:00
|
|
|
int32 length;
|
|
|
|
BPoint location;
|
|
|
|
escapement_delta delta;
|
|
|
|
|
|
|
|
link.Read<int32>(&length);
|
|
|
|
link.Read<BPoint>(&location);
|
|
|
|
link.Read<escapement_delta>(&delta);
|
|
|
|
link.ReadString(&string);
|
2006-01-04 10:30:38 +03:00
|
|
|
|
2006-11-12 23:00:36 +03:00
|
|
|
picture->WriteDrawString(location, string, length, delta);
|
2006-10-31 14:24:58 +03:00
|
|
|
|
|
|
|
free(string);
|
2006-01-19 00:29:29 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2006-10-30 23:42:54 +03:00
|
|
|
case AS_STROKE_SHAPE:
|
|
|
|
case AS_FILL_SHAPE:
|
|
|
|
{
|
|
|
|
BRect shapeFrame;
|
|
|
|
int32 opCount;
|
|
|
|
int32 ptCount;
|
|
|
|
|
|
|
|
link.Read<BRect>(&shapeFrame);
|
|
|
|
link.Read<int32>(&opCount);
|
|
|
|
link.Read<int32>(&ptCount);
|
|
|
|
|
|
|
|
uint32 *opList = new(nothrow) uint32[opCount];
|
|
|
|
BPoint *ptList = new(nothrow) BPoint[ptCount];
|
2006-11-10 00:53:45 +03:00
|
|
|
if (opList != NULL && ptList != NULL
|
|
|
|
&& link.Read(opList, opCount * sizeof(uint32)) >= B_OK
|
|
|
|
&& link.Read(ptList, ptCount * sizeof(BPoint)) >= B_OK) {
|
2006-10-30 23:42:54 +03:00
|
|
|
|
2006-11-12 23:00:36 +03:00
|
|
|
const bool fill = (code == AS_FILL_SHAPE);
|
|
|
|
picture->WriteDrawShape(opCount, opList, ptCount, ptList, fill);
|
2006-10-30 23:42:54 +03:00
|
|
|
}
|
2006-10-31 14:24:58 +03:00
|
|
|
delete[] opList;
|
|
|
|
delete[] ptList;
|
|
|
|
|
2006-10-30 23:42:54 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2006-01-04 15:15:58 +03:00
|
|
|
case AS_LAYER_DRAW_BITMAP:
|
2006-01-04 10:30:38 +03:00
|
|
|
{
|
|
|
|
int32 token;
|
|
|
|
link.Read<int32>(&token);
|
|
|
|
|
|
|
|
BRect destRect;
|
|
|
|
link.Read<BRect>(&destRect);
|
|
|
|
|
|
|
|
BRect sourceRect;
|
|
|
|
link.Read<BRect>(&sourceRect);
|
|
|
|
|
|
|
|
ServerBitmap *bitmap = App()->FindBitmap(token);
|
|
|
|
if (bitmap == NULL)
|
|
|
|
break;
|
2006-05-24 23:10:15 +04:00
|
|
|
|
2006-11-12 23:00:36 +03:00
|
|
|
picture->WriteDrawBitmap(sourceRect, destRect, bitmap->Width(), bitmap->Height(),
|
|
|
|
bitmap->BytesPerRow(), bitmap->ColorSpace(), /*bitmap->Flags()*/0,
|
|
|
|
bitmap->Bits(), bitmap->BitsLength());
|
2006-05-24 23:10:15 +04:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2006-11-12 23:00:36 +03:00
|
|
|
/*
|
2006-05-24 23:10:15 +04:00
|
|
|
case AS_LAYER_SET_BLENDING_MODE:
|
|
|
|
{
|
|
|
|
int8 srcAlpha, alphaFunc;
|
|
|
|
|
|
|
|
link.Read<int8>(&srcAlpha);
|
|
|
|
link.Read<int8>(&alphaFunc);
|
|
|
|
|
|
|
|
picture->BeginOp(B_PIC_SET_BLENDING_MODE);
|
|
|
|
picture->AddInt16((int16)srcAlpha);
|
|
|
|
picture->AddInt16((int16)alphaFunc);
|
|
|
|
picture->EndOp();
|
|
|
|
|
2006-01-04 10:30:38 +03:00
|
|
|
break;
|
2006-11-12 23:00:36 +03:00
|
|
|
}*/
|
2006-01-04 10:30:38 +03:00
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (link.NeedsReply()) {
|
|
|
|
fLink.StartMessage(B_ERROR);
|
|
|
|
fLink.Flush();
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-06-24 02:43:11 +04:00
|
|
|
/*!
|
|
|
|
\brief Message-dispatching loop for the ServerWindow
|
|
|
|
|
|
|
|
Watches the ServerWindow's message port and dispatches as necessary
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
ServerWindow::_MessageLooper()
|
2003-02-07 15:53:57 +03:00
|
|
|
{
|
2005-06-24 02:43:11 +04:00
|
|
|
BPrivate::LinkReceiver& receiver = fLink.Receiver();
|
2005-07-07 02:39:15 +04:00
|
|
|
bool quitLoop = false;
|
2005-05-26 19:04:45 +04:00
|
|
|
|
2005-07-07 02:39:15 +04:00
|
|
|
while (!quitLoop) {
|
2005-07-18 13:24:08 +04:00
|
|
|
//STRACE(("info: ServerWindow::MonitorWin listening on port %ld.\n",
|
|
|
|
// fMessagePort));
|
2005-06-23 22:48:10 +04:00
|
|
|
|
2005-07-07 02:39:15 +04:00
|
|
|
int32 code;
|
|
|
|
status_t status = receiver.GetNextMessage(code);
|
|
|
|
if (status < B_OK) {
|
2005-06-24 02:43:11 +04:00
|
|
|
// that shouldn't happen, it's our port
|
2005-07-07 02:39:15 +04:00
|
|
|
printf("Someone deleted our message port!\n");
|
|
|
|
|
|
|
|
// try to let our client die happily
|
|
|
|
NotifyQuitRequested();
|
|
|
|
break;
|
2005-06-24 02:43:11 +04:00
|
|
|
}
|
2004-01-20 05:02:01 +03:00
|
|
|
|
2005-11-25 18:35:47 +03:00
|
|
|
#ifdef PROFILE_MESSAGE_LOOP
|
|
|
|
bigtime_t start = system_time();
|
|
|
|
#endif
|
|
|
|
|
2005-06-24 02:43:11 +04:00
|
|
|
Lock();
|
2004-06-19 14:23:14 +04:00
|
|
|
|
2005-11-25 18:35:47 +03:00
|
|
|
#ifdef PROFILE_MESSAGE_LOOP
|
|
|
|
bigtime_t diff = system_time() - start;
|
|
|
|
if (diff > 10000)
|
|
|
|
printf("ServerWindow %s: lock acquisition took %Ld usecs\n", Title(), diff);
|
|
|
|
#endif
|
|
|
|
|
2005-12-12 16:53:35 +03:00
|
|
|
int32 messagesProcessed = 0;
|
|
|
|
bool lockedDesktop = false;
|
2005-11-29 02:36:59 +03:00
|
|
|
|
2005-12-12 16:53:35 +03:00
|
|
|
while (true) {
|
|
|
|
if (code == AS_DELETE_WINDOW || code == kMsgQuitLooper) {
|
|
|
|
// this means the client has been killed
|
|
|
|
STRACE(("ServerWindow %s received 'AS_DELETE_WINDOW' message code\n",
|
|
|
|
Title()));
|
2005-06-24 02:43:11 +04:00
|
|
|
|
ServerFont:
* fixed weird pointer conversion in SetStyle()
* fixed a potential mix up in operator=() in case the
other ServerFont has fStyle == NULL
ServerWindow:
* the WindowLayer fTopLayer cannot be deleted by
client request, just for safety reasons
* the link is flushed if there is no drawing engine,
but this case is theoretical only
* deleting the ServerWindow object syncs with the
client, so that when BBitmaps are deleted, they
can be sure there are no pending messages (which
would be executed in a nother thread)
* there is no timeout anymore when sending messages
to the client, which made absolutely no sense
AGGTextRenderer:
* renamed fFontManager to fFontCache, because that's
what it really is
* fLastFamilyAndStyle defaulted to the system plain
font and therefor that font was never loaded when
the font never changed meanwhile
DrawingMode:
* I'm not quite sure but I think there was the
potential of a division by zero, at least I
had crashes with "divide error"
HWInterface:
* fix update when the cursor shape changed in
double buffered mode
ViewLayer:
* since the top layer is never really deleted
before its time has come, it is not necessary
to set it to NULL in the ViewLayer destructor
ViewLayer/WindowLayer:
* added a function to collect the view tokens
that are affected by an update session
EventDispatcher:
* use the importance of the message for the timeout
in _SendMessage()
* drop mouse moved events in the server if we're
lagging behind more than 5 ms (Axel, maybe review)
View:
* there were some problems with the locking
of the BWindow looper in RemoveSelf(), since
this is called from the window destructor,
also of BWindows from BBitmaps, which have
never been run (this might need review), at
least I seem to have solved the crashing
problems introduced by actually deleting the
view hirarchy in the BWindow destructor
* fixed _Draw() for being used non-recursively,
temporarily disabled DrawAfterChildren, which
didn't work yet anyways (because views cannot
draw over children in the server yet)
Window:
* small cleanup when deleting shortcuts
* sync with the server when having send
AS_DELETE_WINDOW (see ServerWindow above)
* fixed locking in Begin/EndViewTransaction()
* removed folding of _UPDATE_ messages, since
there is only one ever in the queue
* set the fInTransaction flag during an update,
I plan to use this in BView later to
flush the link when drawing outside of an
update
* BView::_Draw() is now called by view token,
this gives the next leap forward in speed,
the overhead because of drawing clean views
was considerable
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15878 a95241bf-73f2-0310-859d-f6bbb57e9c96
2006-01-09 01:04:52 +03:00
|
|
|
if (code == AS_DELETE_WINDOW) {
|
|
|
|
fLink.StartMessage(B_OK);
|
|
|
|
fLink.Flush();
|
|
|
|
}
|
|
|
|
|
2005-12-12 16:53:35 +03:00
|
|
|
if (lockedDesktop)
|
|
|
|
fDesktop->UnlockSingleWindow();
|
|
|
|
|
|
|
|
quitLoop = true;
|
|
|
|
|
|
|
|
// ServerWindow's destructor takes care of pulling this object off the desktop.
|
|
|
|
if (!fWindowLayer->IsHidden())
|
|
|
|
CRITICAL("ServerWindow: a window must be hidden before it's deleted\n");
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!lockedDesktop) {
|
|
|
|
// only lock it once
|
|
|
|
fDesktop->LockSingleWindow();
|
|
|
|
lockedDesktop = true;
|
|
|
|
}
|
2005-12-12 16:14:21 +03:00
|
|
|
|
2007-07-18 16:59:05 +04:00
|
|
|
if (atomic_and(&fRedrawRequested, 0) != 0) {
|
|
|
|
#ifdef PROFILE_MESSAGE_LOOP
|
|
|
|
bigtime_t redrawStart = system_time();
|
|
|
|
#endif
|
2005-12-12 16:14:21 +03:00
|
|
|
fWindowLayer->RedrawDirtyRegion();
|
2007-07-18 16:59:05 +04:00
|
|
|
#ifdef PROFILE_MESSAGE_LOOP
|
|
|
|
diff = system_time() - redrawStart;
|
|
|
|
atomic_add(&sRedrawProcessingTime.count, 1);
|
|
|
|
# ifndef HAIKU_TARGET_PLATFORM_LIBBE_TEST
|
|
|
|
atomic_add64(&sRedrawProcessingTime.time, diff);
|
|
|
|
# else
|
|
|
|
sRedrawProcessingTime.time += diff;
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-12-12 16:14:21 +03:00
|
|
|
|
2007-07-18 16:59:05 +04:00
|
|
|
#ifdef PROFILE_MESSAGE_LOOP
|
|
|
|
bigtime_t dispatchStart = system_time();
|
|
|
|
#endif
|
2005-12-08 15:41:19 +03:00
|
|
|
_DispatchMessage(code, receiver);
|
2004-06-19 14:23:14 +04:00
|
|
|
|
2005-11-25 18:35:47 +03:00
|
|
|
#ifdef PROFILE_MESSAGE_LOOP
|
2005-12-12 16:53:35 +03:00
|
|
|
if (code >= 0 && code < AS_LAST_CODE) {
|
2007-07-18 16:59:05 +04:00
|
|
|
diff = system_time() - dispatchStart;
|
2005-12-12 16:53:35 +03:00
|
|
|
atomic_add(&sMessageProfile[code].count, 1);
|
2006-02-02 23:19:29 +03:00
|
|
|
#ifndef HAIKU_TARGET_PLATFORM_LIBBE_TEST
|
2005-12-12 16:53:35 +03:00
|
|
|
atomic_add64(&sMessageProfile[code].time, diff);
|
2005-11-25 18:35:47 +03:00
|
|
|
#else
|
2005-12-12 16:53:35 +03:00
|
|
|
sMessageProfile[code].time += diff;
|
2005-11-25 18:35:47 +03:00
|
|
|
#endif
|
2005-12-12 16:53:35 +03:00
|
|
|
if (diff > 10000)
|
|
|
|
printf("ServerWindow %s: message %ld took %Ld usecs\n", Title(), code, diff);
|
|
|
|
}
|
2005-11-25 18:35:47 +03:00
|
|
|
#endif
|
|
|
|
|
2005-12-12 16:53:35 +03:00
|
|
|
// only process up to 70 waiting messages at once (we have the Desktop locked)
|
|
|
|
if (!receiver.HasMessages() || ++messagesProcessed > 70) {
|
|
|
|
fDesktop->UnlockSingleWindow();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2007-07-18 16:59:05 +04:00
|
|
|
// next message
|
2005-12-12 16:53:35 +03:00
|
|
|
status_t status = receiver.GetNextMessage(code);
|
|
|
|
if (status < B_OK) {
|
|
|
|
// that shouldn't happen, it's our port
|
|
|
|
printf("Someone deleted our message port!\n");
|
|
|
|
fDesktop->UnlockSingleWindow();
|
|
|
|
|
|
|
|
// try to let our client die happily
|
|
|
|
NotifyQuitRequested();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-06-24 02:43:11 +04:00
|
|
|
Unlock();
|
2003-02-07 15:53:57 +03:00
|
|
|
}
|
2005-07-07 02:39:15 +04:00
|
|
|
|
|
|
|
// we were asked to quit the message loop - either on request or because of an error
|
|
|
|
Quit();
|
|
|
|
// does not return
|
2003-02-07 15:53:57 +03:00
|
|
|
}
|
2005-04-27 21:26:57 +04:00
|
|
|
|
2005-11-16 17:34:56 +03:00
|
|
|
|
2005-10-24 20:21:49 +04:00
|
|
|
status_t
|
2005-11-20 19:24:23 +03:00
|
|
|
ServerWindow::SendMessageToClient(const BMessage* msg, int32 target) const
|
2004-01-20 01:18:37 +03:00
|
|
|
{
|
2005-11-23 18:17:58 +03:00
|
|
|
if (target == B_NULL_TOKEN)
|
|
|
|
target = fClientToken;
|
|
|
|
|
2005-11-13 14:31:07 +03:00
|
|
|
BMessenger reply;
|
|
|
|
BMessage::Private messagePrivate((BMessage *)msg);
|
2007-01-26 19:48:02 +03:00
|
|
|
return messagePrivate.SendMessage(fClientLooperPort, fClientTeam, target,
|
|
|
|
0, false, reply);
|
2003-09-25 16:31:11 +04:00
|
|
|
}
|
2003-09-09 01:18:39 +04:00
|
|
|
|
2005-11-16 17:34:56 +03:00
|
|
|
|
2005-11-24 20:45:26 +03:00
|
|
|
WindowLayer*
|
|
|
|
ServerWindow::MakeWindowLayer(BRect frame, const char* name,
|
2005-12-01 15:07:28 +03:00
|
|
|
window_look look, window_feel feel, uint32 flags, uint32 workspace)
|
offscreen bitmaps work, tested on Haiku as well, supports all colorspaces that BBitmap::ImportBits() supports. It uses a fallback for non-B_RGB(A)32 bitmaps. Added support for B_SUB_PIXEL_PRECISION view flags, though it is a bit hacky, since I had to add it to LayerData, even though it is not a true part of stack data. Added Layer::SetFlags() to enforce code path and update fLayerData. Cleaned up DisplayDriverPainter and DisplayDriver API (changed some const BRect& rect to simply BRect rect in order to be able to reuse it in the code), moved Painter.h, the test environment only draws the changed part of the frame buffer again - this causes a lot less CPU overhead, Painter special cases stroke width of 1.0 to use square caps, which is similar to R5 implementation and removes a lot of problems with non-straight line drawing, ServerWindow uses the DisplayDriver from it's WinBorder instead of the one from the Desktop (needed for offscreen windows, which have their own DisplayDriverPainter), it also checks for GetRootLayer() == NULL, because offscreen layers are not attached to a RootLayer, there was a fix for scrolling which worked at least in the test environment, it is now defunced, because Adi moved _CopyBits to Layer... I need to reenable it later, LayerData has no more fEscapementDelta, also fixed fFontAliasing (which was thought to overriding the font flags, and now works as such again), Desktop initialises the menu_info and scroll_bar_info stuff, which makes ScrollBars work actually... hope I didn't forget something.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13448 a95241bf-73f2-0310-859d-f6bbb57e9c96
2005-07-05 20:17:16 +04:00
|
|
|
{
|
2005-11-04 18:23:54 +03:00
|
|
|
// The non-offscreen ServerWindow uses the DrawingEngine instance from the desktop.
|
2005-12-01 15:07:28 +03:00
|
|
|
return new (nothrow) WindowLayer(frame, name, look, feel, flags,
|
2006-12-05 01:25:17 +03:00
|
|
|
// workspace, this, fDesktop->GetDrawingEngine());
|
|
|
|
workspace, this, new DrawingEngine(fDesktop->HWInterface()));
|
offscreen bitmaps work, tested on Haiku as well, supports all colorspaces that BBitmap::ImportBits() supports. It uses a fallback for non-B_RGB(A)32 bitmaps. Added support for B_SUB_PIXEL_PRECISION view flags, though it is a bit hacky, since I had to add it to LayerData, even though it is not a true part of stack data. Added Layer::SetFlags() to enforce code path and update fLayerData. Cleaned up DisplayDriverPainter and DisplayDriver API (changed some const BRect& rect to simply BRect rect in order to be able to reuse it in the code), moved Painter.h, the test environment only draws the changed part of the frame buffer again - this causes a lot less CPU overhead, Painter special cases stroke width of 1.0 to use square caps, which is similar to R5 implementation and removes a lot of problems with non-straight line drawing, ServerWindow uses the DisplayDriver from it's WinBorder instead of the one from the Desktop (needed for offscreen windows, which have their own DisplayDriverPainter), it also checks for GetRootLayer() == NULL, because offscreen layers are not attached to a RootLayer, there was a fix for scrolling which worked at least in the test environment, it is now defunced, because Adi moved _CopyBits to Layer... I need to reenable it later, LayerData has no more fEscapementDelta, also fixed fFontAliasing (which was thought to overriding the font flags, and now works as such again), Desktop initialises the menu_info and scroll_bar_info stuff, which makes ScrollBars work actually... hope I didn't forget something.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13448 a95241bf-73f2-0310-859d-f6bbb57e9c96
2005-07-05 20:17:16 +04:00
|
|
|
}
|
2005-06-03 18:20:10 +04:00
|
|
|
|
2005-10-11 09:25:52 +04:00
|
|
|
|
|
|
|
status_t
|
|
|
|
ServerWindow::_EnableDirectWindowMode()
|
|
|
|
{
|
2005-12-10 18:23:02 +03:00
|
|
|
if (fDirectWindowData != NULL) {
|
|
|
|
// already in direct window mode
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
2005-12-12 00:46:35 +03:00
|
|
|
fDirectWindowData = new (nothrow) direct_window_data;
|
2005-10-11 09:25:52 +04:00
|
|
|
if (fDirectWindowData == NULL)
|
|
|
|
return B_NO_MEMORY;
|
2005-12-10 18:23:02 +03:00
|
|
|
|
2005-12-12 00:46:35 +03:00
|
|
|
status_t status = fDirectWindowData->InitCheck();
|
|
|
|
if (status < B_OK) {
|
2005-10-11 09:25:52 +04:00
|
|
|
delete fDirectWindowData;
|
|
|
|
fDirectWindowData = NULL;
|
2005-12-12 00:46:35 +03:00
|
|
|
|
|
|
|
return status;
|
2005-10-11 09:25:52 +04:00
|
|
|
}
|
2005-12-10 18:23:02 +03:00
|
|
|
|
2005-10-11 09:25:52 +04:00
|
|
|
return B_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2005-12-12 00:46:35 +03:00
|
|
|
ServerWindow::HandleDirectConnection(int32 bufferState, int32 driverState)
|
2005-10-11 09:25:52 +04:00
|
|
|
{
|
2005-12-12 00:46:35 +03:00
|
|
|
STRACE(("HandleDirectConnection(bufferState = %ld, driverState = %ld)\n",
|
|
|
|
bufferState, driverState));
|
|
|
|
|
|
|
|
if (fDirectWindowData == NULL
|
|
|
|
|| (!fDirectWindowData->started
|
|
|
|
&& (bufferState & B_DIRECT_MODE_MASK) != B_DIRECT_START))
|
2005-10-11 09:25:52 +04:00
|
|
|
return;
|
2007-05-08 01:26:33 +04:00
|
|
|
|
|
|
|
// If the direct connection is stopped, only continue if a start notification is received.
|
|
|
|
// But save the "reason" of the call (B_BUFFER_RESIZED, B_CLIPPING_MODIFIED, etc)
|
|
|
|
if ((fDirectWindowData->buffer_info->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_STOP
|
|
|
|
&& (bufferState & B_DIRECT_MODE_MASK) != B_DIRECT_START) {
|
|
|
|
fDirectWindowData->next_buffer_state |= bufferState & ~B_DIRECT_MODE_MASK;
|
|
|
|
return;
|
|
|
|
}
|
2005-12-12 13:41:31 +03:00
|
|
|
|
2005-12-12 00:46:35 +03:00
|
|
|
fDirectWindowData->started = true;
|
|
|
|
|
2007-05-08 01:26:33 +04:00
|
|
|
fDirectWindowData->buffer_info->buffer_state =
|
|
|
|
(direct_buffer_state)(bufferState | fDirectWindowData->next_buffer_state);
|
|
|
|
fDirectWindowData->next_buffer_state = 0;
|
|
|
|
|
2005-11-01 12:53:47 +03:00
|
|
|
if (driverState != -1)
|
2005-12-12 00:46:35 +03:00
|
|
|
fDirectWindowData->buffer_info->driver_state = (direct_driver_state)driverState;
|
|
|
|
|
2005-11-01 12:53:47 +03:00
|
|
|
if ((bufferState & B_DIRECT_MODE_MASK) != B_DIRECT_STOP) {
|
2005-10-12 01:37:47 +04:00
|
|
|
// TODO: Locking ?
|
2005-11-18 15:26:20 +03:00
|
|
|
RenderingBuffer *buffer = fDesktop->HWInterface()->FrontBuffer();
|
2005-12-12 00:46:35 +03:00
|
|
|
fDirectWindowData->buffer_info->bits = buffer->Bits();
|
|
|
|
fDirectWindowData->buffer_info->pci_bits = NULL; // TODO
|
|
|
|
fDirectWindowData->buffer_info->bytes_per_row = buffer->BytesPerRow();
|
2005-12-21 01:30:02 +03:00
|
|
|
switch (buffer->ColorSpace()) {
|
|
|
|
case B_RGB32:
|
|
|
|
case B_RGBA32:
|
|
|
|
case B_RGB32_BIG:
|
|
|
|
case B_RGBA32_BIG:
|
|
|
|
fDirectWindowData->buffer_info->bits_per_pixel = 32;
|
|
|
|
break;
|
|
|
|
case B_RGB24:
|
|
|
|
case B_RGB24_BIG:
|
|
|
|
fDirectWindowData->buffer_info->bits_per_pixel = 24;
|
|
|
|
break;
|
|
|
|
case B_RGB16:
|
|
|
|
case B_RGB16_BIG:
|
|
|
|
case B_RGB15:
|
|
|
|
case B_RGB15_BIG:
|
|
|
|
fDirectWindowData->buffer_info->bits_per_pixel = 16;
|
|
|
|
break;
|
|
|
|
case B_CMAP8:
|
|
|
|
fDirectWindowData->buffer_info->bits_per_pixel = 8;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
fprintf(stderr, "unkown colorspace in HandleDirectConnection()!\n");
|
|
|
|
fDirectWindowData->buffer_info->bits_per_pixel = 0;
|
|
|
|
break;
|
|
|
|
}
|
2005-12-12 00:46:35 +03:00
|
|
|
fDirectWindowData->buffer_info->pixel_format = buffer->ColorSpace();
|
|
|
|
fDirectWindowData->buffer_info->layout = B_BUFFER_NONINTERLEAVED;
|
|
|
|
fDirectWindowData->buffer_info->orientation = B_BUFFER_TOP_TO_BOTTOM; // TODO
|
2006-02-09 18:05:33 +03:00
|
|
|
fDirectWindowData->buffer_info->window_bounds = to_clipping_rect(fWindowLayer->Frame());
|
2005-11-24 20:45:26 +03:00
|
|
|
|
2005-10-12 01:37:47 +04:00
|
|
|
// TODO: Review this
|
2005-11-24 20:45:26 +03:00
|
|
|
const int32 kMaxClipRectsCount = (B_PAGE_SIZE - sizeof(direct_buffer_info))
|
|
|
|
/ sizeof(clipping_rect);
|
|
|
|
|
2005-12-12 00:46:35 +03:00
|
|
|
// We just want the region inside the window, border excluded.
|
|
|
|
BRegion clipRegion = fWindowLayer->VisibleContentRegion();
|
|
|
|
|
|
|
|
fDirectWindowData->buffer_info->clip_list_count = min_c(clipRegion.CountRects(),
|
2005-11-24 20:45:26 +03:00
|
|
|
kMaxClipRectsCount);
|
2005-12-12 00:46:35 +03:00
|
|
|
fDirectWindowData->buffer_info->clip_bounds = clipRegion.FrameInt();
|
2005-11-24 20:45:26 +03:00
|
|
|
|
2005-12-12 00:46:35 +03:00
|
|
|
for (uint32 i = 0; i < fDirectWindowData->buffer_info->clip_list_count; i++)
|
|
|
|
fDirectWindowData->buffer_info->clip_list[i] = clipRegion.RectAtInt(i);
|
2005-10-11 09:25:52 +04:00
|
|
|
}
|
2005-11-24 20:45:26 +03:00
|
|
|
|
2005-10-11 09:25:52 +04:00
|
|
|
// Releasing this sem causes the client to call BDirectWindow::DirectConnected()
|
2005-12-12 00:46:35 +03:00
|
|
|
release_sem(fDirectWindowData->sem);
|
2005-11-24 20:45:26 +03:00
|
|
|
|
2005-12-12 00:46:35 +03:00
|
|
|
// TODO: Waiting half a second in the ServerWindow thread is not a problem,
|
|
|
|
// but since we are called from the Desktop's thread too, very bad things could happen.
|
2005-11-09 02:26:47 +03:00
|
|
|
// Find some way to call this method only within ServerWindow's thread (messaging ?)
|
2005-11-12 14:00:57 +03:00
|
|
|
status_t status;
|
|
|
|
do {
|
|
|
|
// TODO: The timeout is 3000000 usecs (3 seconds) on beos.
|
|
|
|
// Test, but I think half a second is enough.
|
2005-12-12 00:46:35 +03:00
|
|
|
status = acquire_sem_etc(fDirectWindowData->sem_ack, 1, B_TIMEOUT, 500000);
|
2005-11-12 14:00:57 +03:00
|
|
|
} while (status == B_INTERRUPTED);
|
2005-11-24 20:45:26 +03:00
|
|
|
|
2005-11-12 14:00:57 +03:00
|
|
|
if (status < B_OK) {
|
2005-10-11 09:25:52 +04:00
|
|
|
// The client application didn't release the semaphore
|
2005-11-12 14:00:57 +03:00
|
|
|
// within the given timeout. Or something else went wrong.
|
|
|
|
// Deleting this member should make it crash.
|
2005-10-11 09:25:52 +04:00
|
|
|
delete fDirectWindowData;
|
|
|
|
fDirectWindowData = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-12-08 15:41:19 +03:00
|
|
|
void
|
|
|
|
ServerWindow::_SetCurrentLayer(ViewLayer* layer)
|
|
|
|
{
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
if (fCurrentLayer == layer)
|
|
|
|
return;
|
|
|
|
|
|
|
|
fCurrentLayer = layer;
|
|
|
|
fCurrentDrawingRegionValid = false;
|
|
|
|
_UpdateDrawState(fCurrentLayer);
|
|
|
|
|
2005-12-21 01:30:02 +03:00
|
|
|
#if 0
|
|
|
|
#if DELAYED_BACKGROUND_CLEARING
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
if (fCurrentLayer && fCurrentLayer->IsBackgroundDirty()
|
|
|
|
&& fWindowLayer->InUpdate()) {
|
|
|
|
DrawingEngine* drawingEngine = fWindowLayer->GetDrawingEngine();
|
|
|
|
if (drawingEngine->LockParallelAccess()) {
|
|
|
|
|
|
|
|
fWindowLayer->GetEffectiveDrawingRegion(fCurrentLayer, fCurrentDrawingRegion);
|
|
|
|
fCurrentDrawingRegionValid = true;
|
|
|
|
BRegion dirty(fCurrentDrawingRegion);
|
2005-12-21 01:30:02 +03:00
|
|
|
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
BRegion content;
|
|
|
|
fWindowLayer->GetContentRegion(&content);
|
2005-12-21 01:30:02 +03:00
|
|
|
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
fCurrentLayer->Draw(drawingEngine, &dirty, &content, false);
|
|
|
|
|
|
|
|
drawingEngine->UnlockParallelAccess();
|
2005-12-21 01:30:02 +03:00
|
|
|
}
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
}
|
2005-12-21 01:30:02 +03:00
|
|
|
#endif
|
|
|
|
#endif // 0
|
* since every window has it's own Painter instance, the drawing state does
not need to be "set" (transfered from the "current" view to the painter)
for each singly drawing command. Now, painter is synchronized whenever
the client changes the drawing state of the current view, or when the
current view changes.
* the screen offset of the current view has become part of the Painter state,
in the PatternHandler. This fixes a bug in which moving or scrolling a view
which used patterns for drawing, resulted in visual glitches (seams in the
pattern).
NOTE: this patch is a bit work in progress, most importantly, it is not
complete with regards to text rendering. More specifically, the server
applications and other parts of the appserver might set a font on the Painter
and this might mess up the synchronization. But this happens on the Desktop's
Painter instance (only?), and so it is not a problem. I did observe some
drawing bugs with this patch though, so bug reports are welcome, particularily
how to reproduce these bugs reliably.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21643 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-18 13:35:40 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
ServerWindow::_UpdateDrawState(ViewLayer* layer)
|
|
|
|
{
|
|
|
|
// switch the drawing state
|
|
|
|
// TODO: is it possible to scroll a view while it
|
|
|
|
// is being drawn? probably not... otherwise the
|
|
|
|
// "offsets" passed below would need to be updated again
|
|
|
|
DrawingEngine* drawingEngine = fWindowLayer->GetDrawingEngine();
|
|
|
|
if (layer && drawingEngine) {
|
|
|
|
IntPoint p = layer->ScrollingOffset();
|
|
|
|
p += IntPoint(layer->CurrentState()->Origin());
|
|
|
|
drawingEngine->SetDrawState(layer->CurrentState(), p.x, p.y);
|
2005-12-08 15:41:19 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-06-03 18:20:10 +04:00
|
|
|
status_t
|
|
|
|
ServerWindow::PictureToRegion(ServerPicture *picture, BRegion ®ion,
|
2005-11-24 20:45:26 +03:00
|
|
|
bool inverse, BPoint where)
|
2005-06-03 18:20:10 +04:00
|
|
|
{
|
|
|
|
fprintf(stderr, "ServerWindow::PictureToRegion() not implemented\n");
|
|
|
|
region.MakeEmpty();
|
|
|
|
return B_ERROR;
|
|
|
|
}
|