xref: /haiku/src/servers/app/ServerWindow.cpp (revision 94978fa6a71bdb289ed6a14fa0292adaeceb5380)
1 /*
2  * Copyright 2001-2005, Haiku.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		DarkWyrm <bpmagic@columbus.rr.com>
7  *		Adrian Oanca <adioanca@cotty.iren.ro>
8  *		Stephan Aßmus <superstippi@gmx.de>
9  *		Stefano Ceccherini (burton666@libero.it)
10  *		Axel Dörfler, axeld@pinc-software.de
11  */
12 
13 /*!
14 	\class ServerWindow
15 	\brief Shadow BWindow class
16 
17 	A ServerWindow handles all the intraserver tasks required of it by its BWindow. There are
18 	too many tasks to list as being done by them, but they include handling View transactions,
19 	coordinating and linking a window's WinBorder half with its messaging half, dispatching
20 	mouse and key events from the server to its window, and other such things.
21 */
22 
23 #include <new>
24 
25 #include <AppDefs.h>
26 #include <DirectWindow.h>
27 #include <GraphicsDefs.h>
28 #include <Message.h>
29 #include <PortLink.h>
30 #include <Rect.h>
31 #include <View.h>
32 #include <ViewAux.h>
33 #include <Autolock.h>
34 #include <TokenSpace.h>
35 #include <WindowInfo.h>
36 #include <WindowPrivate.h>
37 
38 #include "AppServer.h"
39 #include "BGet++.h"
40 #include "DebugInfoManager.h"
41 #include "Desktop.h"
42 #include "DisplayDriver.h"
43 #include "HWInterface.h"
44 #include "Layer.h"
45 #include "MessagePrivate.h"
46 #include "RAMLinkMsgReader.h"
47 #include "RenderingBuffer.h"
48 #include "RootLayer.h"
49 #include "ServerApp.h"
50 #include "ServerBitmap.h"
51 #include "ServerPicture.h"
52 #include "ServerProtocol.h"
53 #include "TokenHandler.h"
54 #include "Utils.h"
55 #include "WinBorder.h"
56 #include "Workspace.h"
57 #include "WorkspacesLayer.h"
58 
59 #include "ServerWindow.h"
60 
61 #include "clipping.h"
62 
63 //#define DEBUG_SERVERWINDOW
64 //#define DEBUG_SERVERWINDOW_GRAPHICS
65 
66 
67 #ifdef DEBUG_SERVERWINDOW
68 #	include <stdio.h>
69 #	define STRACE(x) printf x
70 #else
71 #	define STRACE(x) ;
72 #endif
73 
74 #ifdef DEBUG_SERVERWINDOW_GRAPHICS
75 #	include <stdio.h>
76 #	define DTRACE(x) printf x
77 #else
78 #	define DTRACE(x) ;
79 #endif
80 
81 struct dw_data {
82 	sem_id direct_sem;
83 	sem_id direct_sem_ack;
84 	area_id direct_area;
85 	direct_buffer_info *direct_info;
86 
87 	dw_data() :
88 		direct_sem(-1),
89 		direct_sem_ack(-1),
90 		direct_area(-1),
91 		direct_info(NULL)
92 	{
93 		direct_area = create_area("direct area", (void **)&direct_info,
94 							B_ANY_ADDRESS, B_PAGE_SIZE, B_NO_LOCK, B_READ_WRITE);
95 
96 		direct_sem = create_sem(1, "direct sem");
97 		direct_sem_ack = create_sem(1, "direct sem ack");
98 	}
99 
100 	~dw_data()
101 	{
102 		if (direct_area >= 0)
103 			delete_area(direct_area);
104 		if (direct_sem >= 0)
105 			delete_sem(direct_sem);
106 		if (direct_sem_ack >= 0)
107 			delete_sem(direct_sem_ack);
108 	}
109 
110 	bool IsValid() const
111 	{
112 		return (direct_area >= 0) && (direct_sem >= 0)
113 			&& (direct_sem_ack >= 0) && (direct_info != NULL);
114 	}
115 };
116 
117 
118 // TODO: Copied from DirectWindow.cpp: Move to a common header
119 struct dw_sync_data {
120 	area_id area;
121 	sem_id disableSem;
122 	sem_id disableSemAck;
123 };
124 
125 /*!
126 	\brief Constructor
127 
128 	Does a lot of stuff to set up for the window - new decorator, new winborder, spawn a
129 	monitor thread.
130 */
131 ServerWindow::ServerWindow(const char *title, ServerApp *app,
132 						   port_id clientPort, port_id looperPort, int32 handlerID)
133 	: MessageLooper(title && *title ? title : "Unnamed Window"),
134 	fTitle(title),
135 	fDesktop(app->GetDesktop()),
136 	fServerApp(app),
137 	fWinBorder(NULL),
138 	fClientTeam(app->ClientTeam()),
139 	fMessagePort(-1),
140 	fClientReplyPort(clientPort),
141 	fClientLooperPort(looperPort),
142 	fClientViewsWithInvalidCoords(B_VIEW_RESIZED),
143 	fHandlerToken(handlerID),
144 	fCurrentLayer(NULL),
145 	fDirectWindowData(NULL)
146 {
147 	STRACE(("ServerWindow(%s)::ServerWindow()\n", title));
148 
149 	fServerToken = BPrivate::gDefaultTokens.NewToken(B_SERVER_TOKEN, this);
150 }
151 
152 
153 //!Tears down all connections the main app_server objects, and deletes some internals.
154 ServerWindow::~ServerWindow()
155 {
156 	STRACE(("*ServerWindow(%s@%p):~ServerWindow()\n", fTitle, this));
157 
158 	if (!fWinBorder->IsOffscreenWindow())
159 		fDesktop->RemoveWinBorder(fWinBorder);
160 
161 	delete fWinBorder;
162 
163 	free(const_cast<char *>(fTitle));
164 	delete_port(fMessagePort);
165 
166 	BPrivate::gDefaultTokens.RemoveToken(fServerToken);
167 
168 	delete fDirectWindowData;
169 	STRACE(("#ServerWindow(%p) will exit NOW\n", this));
170 }
171 
172 
173 status_t
174 ServerWindow::Init(BRect frame, uint32 look, uint32 feel, uint32 flags, uint32 workspace)
175 {
176 	if (fTitle == NULL)
177 		fTitle = strdup("Unnamed Window");
178 	if (fTitle == NULL)
179 		return B_NO_MEMORY;
180 
181 	// fMessagePort is the port to which the app sends messages for the server
182 	fMessagePort = create_port(100, fTitle);
183 	if (fMessagePort < B_OK)
184 		return fMessagePort;
185 
186 	fLink.SetSenderPort(fClientReplyPort);
187 	fLink.SetReceiverPort(fMessagePort);
188 
189 	// We cannot call MakeWinBorder in the constructor, since it
190 	fWinBorder = MakeWinBorder(frame, fTitle, look, feel, flags, workspace);
191 	if (!fWinBorder)
192 		return B_NO_MEMORY;
193 
194 	if (!fWinBorder->IsOffscreenWindow())
195 		fDesktop->AddWinBorder(fWinBorder);
196 
197 	return B_OK;
198 }
199 
200 
201 bool
202 ServerWindow::Run()
203 {
204 	if (!MessageLooper::Run())
205 		return false;
206 
207 	// Send a reply to our window - it is expecting fMessagePort
208 	// port and some other info
209 
210 	fLink.StartMessage(SERVER_TRUE);
211 	fLink.Attach<port_id>(fMessagePort);
212 
213 	float minWidth, maxWidth, minHeight, maxHeight;
214 	fWinBorder->GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight);
215 
216 	fLink.Attach<BRect>(fWinBorder->Frame());
217 	fLink.Attach<float>(minWidth);
218 	fLink.Attach<float>(maxWidth);
219 	fLink.Attach<float>(minHeight);
220 	fLink.Attach<float>(maxHeight);
221 	fLink.Flush();
222 
223 	return true;
224 }
225 
226 
227 void
228 ServerWindow::_PrepareQuit()
229 {
230 	if (fThread == find_thread(NULL)) {
231 		// make sure we're hidden
232 		Hide();
233 
234 		App()->RemoveWindow(this);
235 	} else if (fThread >= B_OK)
236 		PostMessage(AS_HIDE_WINDOW);
237 }
238 
239 
240 void
241 ServerWindow::_GetLooperName(char* name, size_t length)
242 {
243 	snprintf(name, length, "w:%ld:%s", ClientTeam(), Title());
244 }
245 
246 
247 //! Forces the window border to update its decorator
248 void
249 ServerWindow::ReplaceDecorator()
250 {
251 	if (!IsLocked())
252 		debugger("you must lock a ServerWindow object before calling ::ReplaceDecorator()\n");
253 
254 	STRACE(("ServerWindow %s: Replace Decorator\n", fTitle));
255 	fWinBorder->UpdateDecorator();
256 }
257 
258 
259 //! Shows the window's WinBorder
260 void
261 ServerWindow::Show()
262 {
263 	// NOTE: if you do something else, other than sending a port message, PLEASE lock
264 	STRACE(("ServerWindow %s: Show\n", Title()));
265 
266 	if (fQuitting || !fWinBorder->IsHidden())
267 		return;
268 
269 	RootLayer* rootLayer = fWinBorder->GetRootLayer();
270 	if (rootLayer && rootLayer->Lock()) {
271 		rootLayer->ShowWinBorder(fWinBorder);
272 		rootLayer->Unlock();
273 	}
274 
275 	// TODO: This doesn't work: Here we aren't shown yet as RootLayer::ShowWinBorder()
276 	// does its work asynchronously. As we lock the rootlayer, I think it could be synchronous.
277 	// Otherwise, we need a "Shown()" hook or something like that.
278 	if (fDirectWindowData != NULL)
279 		_HandleDirectConnection(B_DIRECT_START);
280 }
281 
282 
283 //! Hides the window's WinBorder
284 void
285 ServerWindow::Hide()
286 {
287 	// NOTE: if you do something else, other than sending a port message, PLEASE lock
288 	STRACE(("ServerWindow %s: Hide\n", Title()));
289 
290 	if (fWinBorder->IsHidden())
291 		return;
292 
293 	if (fDirectWindowData != NULL)
294 		_HandleDirectConnection(B_DIRECT_STOP);
295 
296 	RootLayer* rootLayer = fWinBorder->GetRootLayer();
297 	if (rootLayer && rootLayer->Lock()) {
298 		rootLayer->HideWinBorder(fWinBorder);
299 		rootLayer->Unlock();
300 	}
301 }
302 
303 
304 void
305 ServerWindow::SetTitle(const char* newTitle)
306 {
307 	const char* oldTitle = fTitle;
308 
309 	if (newTitle == NULL || !newTitle[0])
310 		fTitle = strdup("Unnamed Window");
311 	else
312 		fTitle = strdup(newTitle);
313 
314 	if (fTitle == NULL) {
315 		fTitle = oldTitle;
316 		return;
317 	}
318 
319 	free(const_cast<char*>(oldTitle));
320 
321 	if (Thread() >= B_OK) {
322 		char name[B_OS_NAME_LENGTH];
323 		snprintf(name, sizeof(name), "w:%ld:%s", ClientTeam(), fTitle);
324 		rename_thread(Thread(), name);
325 	}
326 
327 	if (fWinBorder != NULL)
328 		fWinBorder->SetName(newTitle);
329 }
330 
331 
332 //! Requests that the ServerWindow's BWindow quit
333 void
334 ServerWindow::NotifyQuitRequested()
335 {
336 	// NOTE: if you do something else, other than sending a port message, PLEASE lock
337 	STRACE(("ServerWindow %s: Quit\n", fTitle));
338 
339 	BMessage msg(B_QUIT_REQUESTED);
340 	SendMessageToClient(&msg);
341 }
342 
343 
344 void
345 ServerWindow::NotifyMinimize(bool minimize)
346 {
347 	// NOTE: if you do something else, other than sending a port message, PLEASE lock
348 	// This function doesn't need much -- check to make sure that we should and
349 	// send the message to the client. According to the BeBook, the BWindow hook function
350 	// does all the heavy lifting for us. :)
351 	bool sendMessages = false;
352 
353 	if (minimize) {
354 		if (!fWinBorder->IsHidden()) {
355 			Hide();
356 			sendMessages = true;
357 		}
358 	} else {
359 		if (fWinBorder->IsHidden()) {
360 			Show();
361 			sendMessages = true;
362 		}
363 	}
364 
365 	if (sendMessages) {
366 		BMessage msg(B_MINIMIZE);
367 		msg.AddInt64("when", real_time_clock_usecs());
368 		msg.AddBool("minimize", minimize);
369 
370 		SendMessageToClient(&msg);
371 	}
372 }
373 
374 //! Sends a message to the client to perform a Zoom
375 void
376 ServerWindow::NotifyZoom()
377 {
378 	// NOTE: if you do something else, other than sending a port message, PLEASE lock
379 	BMessage msg(B_ZOOM);
380 	SendMessageToClient(&msg);
381 }
382 
383 /*!
384 	\brief Notifies window of a change in screen resolution
385 	\param frame Size of the new resolution
386 	\param color_space Color space of the new screen mode
387 */
388 void
389 ServerWindow::NotifyScreenModeChanged(const BRect frame, const color_space colorSpace)
390 {
391 	STRACE(("ServerWindow %s: ScreenModeChanged\n", fTitle));
392 
393 	BMessage msg(B_SCREEN_CHANGED);
394 	msg.AddRect("frame", frame);
395 	msg.AddInt32("mode", (int32)colorSpace);
396 
397 	SendMessageToClient(&msg);
398 }
399 
400 
401 void
402 ServerWindow::GetInfo(window_info& info)
403 {
404 	info.team = ClientTeam();
405 	info.server_token = ServerToken();
406 
407 	info.thread = Thread();
408 	info.client_token = ClientToken();
409 	info.client_port = fClientLooperPort;
410 	info.workspaces = fWinBorder->Workspaces();
411 
412 	info.layer = 0; // ToDo: what is this???
413 	info.feel = fWinBorder->Feel();
414 	info.flags = fWinBorder->WindowFlags();
415 	info.window_left = (int)floor(fWinBorder->Frame().left);
416 	info.window_top = (int)floor(fWinBorder->Frame().top);
417 	info.window_right = (int)floor(fWinBorder->Frame().right);
418 	info.window_bottom = (int)floor(fWinBorder->Frame().bottom);
419 
420 	info.show_hide_level = fWinBorder->IsHidden() ? 1 : -1; // ???
421 	info.is_mini = fWinBorder->IsHidden();
422 }
423 
424 
425 /*!
426 	\brief Sets the font state for a layer
427 	\param layer The layer to set the font
428 */
429 inline void
430 ServerWindow::SetLayerFontState(Layer *layer, BPrivate::LinkReceiver &link)
431 {
432 	STRACE(("ServerWindow %s: SetLayerFontStateMessage for layer %s\n",
433 			fTitle, layer->Name()));
434 	// NOTE: no need to check for a lock. This is a private method.
435 
436 	layer->fLayerData->ReadFontFromLink(link);
437 }
438 
439 
440 inline void
441 ServerWindow::SetLayerState(Layer *layer, BPrivate::LinkReceiver &link)
442 {
443 	STRACE(("ServerWindow %s: SetLayerState for layer %s\n", Title(),
444 			 layer->Name()));
445 	// NOTE: no need to check for a lock. This is a private method.
446 
447 	layer->fLayerData->ReadFromLink(link);
448 	// TODO: Rebuild clipping here?
449 }
450 
451 
452 inline Layer*
453 ServerWindow::CreateLayerTree(BPrivate::LinkReceiver &link, Layer **_parent)
454 {
455 	// NOTE: no need to check for a lock. This is a private method.
456 
457 	int32 token;
458 	BRect frame;
459 	uint32 resizeMask;
460 	uint32 eventMask;
461 	uint32 eventOptions;
462 	uint32 flags;
463 	bool hidden;
464 	int32 parentToken;
465 	char *name = NULL;
466 	rgb_color viewColor;
467 
468 	link.Read<int32>(&token);
469 	link.ReadString(&name);
470 	link.Read<BRect>(&frame);
471 	link.Read<uint32>(&resizeMask);
472 	link.Read<uint32>(&eventMask);
473 	link.Read<uint32>(&eventOptions);
474 	link.Read<uint32>(&flags);
475 	link.Read<bool>(&hidden);
476 	link.Read<rgb_color>(&viewColor);
477 	link.Read<int32>(&parentToken);
478 
479 	STRACE(("ServerWindow(%s)::CreateLayerTree()-> layer %s, token %ld\n",
480 		fTitle, name, token));
481 
482 	Layer *newLayer;
483 
484 	if (link.Code() == AS_LAYER_CREATE_ROOT
485 		&& (fWinBorder->WindowFlags() & kWorkspacesWindowFlag) != 0) {
486 		// this is a workspaces window!
487 		newLayer = new WorkspacesLayer(frame, name, token, resizeMask,
488 								flags, fWinBorder->GetDisplayDriver());
489 	} else {
490 		newLayer = new Layer(frame, name, token, resizeMask,
491 			flags, fDesktop->GetDisplayDriver());
492 	}
493 
494 	free(name);
495 
496 	// there is no way of setting this, other than manually :-)
497 	newLayer->fViewColor = viewColor;
498 	newLayer->fHidden = hidden;
499 	newLayer->fEventMask = eventMask;
500 	newLayer->fEventOptions = eventOptions;
501 	newLayer->fOwner = fWinBorder;
502 
503 // TODO: rework the clipping stuff to remove RootLayer dependency and then
504 // remove this hack:
505 if (fWinBorder->IsOffscreenWindow()) {
506 #ifndef NEW_CLIPPING
507 	newLayer->fVisible.Set(newLayer->fFrame);
508 #else
509 	newLayer->fVisible2.Set(newLayer->fFrame);
510 #endif
511 }
512 
513 	if (_parent) {
514 		Layer *parent = fWinBorder->FindLayer(parentToken);
515 		if (parent == NULL)
516 			CRITICAL("View token not found!\n");
517 
518 		*_parent = parent;
519 	}
520 
521 	return newLayer;
522 }
523 
524 
525 void
526 ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
527 {
528 	if (fCurrentLayer == NULL && code != AS_LAYER_CREATE_ROOT && code != AS_LAYER_CREATE) {
529 		printf("ServerWindow %s received unexpected code - message offset %ld before top_view attached.\n", Title(), code - SERVER_TRUE);
530 		return;
531 	}
532 
533 	RootLayer *myRootLayer = fWinBorder->GetRootLayer();
534 	// NOTE: is NULL when fWinBorder is offscreen!
535 	if (myRootLayer)
536 		myRootLayer->Lock();
537 
538 	switch (code) {
539 		//--------- BView Messages -----------------
540 		case AS_LAYER_SCROLL:
541 		{
542 			DTRACE(("ServerWindow %s: Message AS_LAYER_SCROLL: Layer name: %s\n", fTitle, fCurrentLayer->Name()));
543 			float dh;
544 			float dv;
545 
546 			link.Read<float>(&dh);
547 			link.Read<float>(&dv);
548 #ifndef NEW_CLIPPING
549 			// scroll visually by using the CopyBits() implementation
550 			// this will also take care of invalidating previously invisible
551 			// areas (areas scrolled into view)
552 			BRect src = fCurrentLayer->Bounds();
553 			BRect dst = src;
554 			// NOTE: if we scroll down, the contents are moved *up*
555 			dst.OffsetBy(-dh, -dv);
556 
557 			// TODO: Are origin and scale handled in this conversion?
558 			src = fCurrentLayer->ConvertToTop(src);
559 			dst = fCurrentLayer->ConvertToTop(dst);
560 
561 			int32 xOffset = (int32)(dst.left - src.left);
562 			int32 yOffset = (int32)(dst.top - src.top);
563 
564 			// this little detail is where it differs from CopyBits()
565 			// -> it will invalidate areas previously out of screen
566 			dst = dst | src;
567 
568 			fCurrentLayer->fLayerData->OffsetOrigin(BPoint(dh, dv));
569 
570 			fCurrentLayer->CopyBits(src, dst, xOffset, yOffset);
571 #else
572 			fCurrentLayer->ScrollBy(dh, dv);
573 #endif
574 
575 			break;
576 		}
577 		case AS_LAYER_COPY_BITS:
578 		{
579 			BRect src;
580 			BRect dst;
581 
582 			link.Read<BRect>(&src);
583 			link.Read<BRect>(&dst);
584 
585 			// TODO: Are origin and scale handled in this conversion?
586 			src = fCurrentLayer->ConvertToTop(src);
587 			dst = fCurrentLayer->ConvertToTop(dst);
588 
589 			int32 xOffset = (int32)(dst.left - src.left);
590 			int32 yOffset = (int32)(dst.top - src.top);
591 
592 			fCurrentLayer->CopyBits(src, dst, xOffset, yOffset);
593 
594 			break;
595 		}
596 		case AS_SET_CURRENT_LAYER:
597 		{
598 			int32 token;
599 
600 			link.Read<int32>(&token);
601 
602 			Layer *current = fWinBorder->FindLayer(token);
603 			if (current) {
604 				DTRACE(("ServerWindow %s: Message AS_SET_CURRENT_LAYER: %s, token %ld\n", fTitle, current->Name(), token));
605 			} else {
606 				DTRACE(("ServerWindow %s: Message AS_SET_CURRENT_LAYER: layer not found, token %ld\n", fTitle, token));
607 			}
608 
609 			if (current)
610 				fCurrentLayer = current;
611 			else // hope this NEVER happens! :-)
612 				CRITICAL("Server PANIC: window cannot find Layer with ID\n");
613 			// ToDo: if this happens, we probably want to kill the app and clean up
614 			break;
615 		}
616 
617 		case AS_LAYER_CREATE_ROOT:
618 		{
619 			STRACE(("ServerWindow %s: Message AS_LAYER_CREATE_ROOT\n", fTitle));
620 
621 			// Start receiving top_view data -- pass NULL as the parent view.
622 			// This should be the *only* place where this happens.
623 			if (fCurrentLayer != NULL)
624 				break;
625 
626 			fWinBorder->SetTopLayer(CreateLayerTree(link, NULL));
627 			fCurrentLayer = fWinBorder->TopLayer();
628 			break;
629 		}
630 
631 		case AS_LAYER_CREATE:
632 		{
633 			STRACE(("ServerWindow %s: Message AS_LAYER_CREATE: Layer name: %s\n", fTitle, fCurrentLayer->Name()));
634 
635 			Layer* parent = NULL;
636 			Layer* newLayer = CreateLayerTree(link, &parent);
637 			if (parent != NULL)
638 				parent->AddChild(newLayer, this);
639 
640 			if (myRootLayer && !newLayer->IsHidden() && parent)
641 #ifndef NEW_CLIPPING
642 				myRootLayer->GoInvalidate(newLayer, newLayer->fFull);
643 #else
644 			{
645 				BRegion invalidRegion;
646 				newLayer->GetWantedRegion(invalidRegion);
647 				myRootLayer->GoInvalidate(newLayer, invalidRegion);
648 			}
649 #endif
650 			break;
651 		}
652 		case AS_LAYER_DELETE:
653 		{
654 			// Received when a view is detached from a window. This is definitely
655 			// the less taxing operation - we call PruneTree() on the removed
656 			// layer, detach the layer itself, delete it, and invalidate the
657 			// area assuming that the view was visible when removed
658 
659 			STRACE(("ServerWindow %s: AS_LAYER_DELETE(self)...\n", fTitle));
660 
661 			Layer *parent = fCurrentLayer->fParent;
662 			BRegion *invalidRegion = NULL;
663 
664 			if (!fCurrentLayer->IsHidden() && parent) {
665 #ifndef NEW_CLIPPING
666 				if (fCurrentLayer->fFullVisible.CountRects() > 0)
667 					invalidRegion = new BRegion(fCurrentLayer->fFullVisible);
668 #else
669 				if (fCurrentLayer->FullVisible().Frame().IsValid())
670 					invalidRegion = new BRegion(fCurrentLayer->FullVisible());
671 #endif
672 			}
673 
674 			// here we remove current layer from list.
675 			fCurrentLayer->RemoveSelf();
676 			fCurrentLayer->PruneTree();
677 
678 			if (myRootLayer) {
679 
680 				myRootLayer->LayerRemoved(fCurrentLayer);
681 
682 				// trigger update
683 				if (invalidRegion) {
684 					myRootLayer->GoInvalidate(parent, *invalidRegion);
685 					delete invalidRegion;
686 				}
687 			}
688 
689 			#ifdef DEBUG_SERVERWINDOW
690 			parent->PrintTree();
691 			#endif
692 			STRACE(("DONE: ServerWindow %s: Message AS_DELETE_LAYER: Parent: %s Layer: %s\n", fTitle, parent->Name(), fCurrentLayer->Name()));
693 
694 			delete fCurrentLayer;
695 // TODO: It is necessary to do this, but I find it very obscure.
696 			fCurrentLayer = parent;
697 			break;
698 		}
699 		case AS_LAYER_SET_STATE:
700 		{
701 			DTRACE(("ServerWindow %s: Message AS_LAYER_SET_STATE: Layer name: %s\n", fTitle, fCurrentLayer->Name()));
702 //			SetLayerState(fCurrentLayer);
703 			SetLayerState(fCurrentLayer, link);
704 			// TODO: should this be moved into SetLayerState?
705 			// If it _always_ needs to be done afterwards, then yes!
706 #ifndef NEW_CLIPPING
707 			fCurrentLayer->RebuildFullRegion();
708 #endif
709 			break;
710 		}
711 		case AS_LAYER_SET_FONT_STATE:
712 		{
713 			DTRACE(("ServerWindow %s: Message AS_LAYER_SET_FONT_STATE: Layer name: %s\n", fTitle, fCurrentLayer->Name()));
714 //			SetLayerFontState(fCurrentLayer);
715 			SetLayerFontState(fCurrentLayer, link);
716 #ifndef NEW_CLIPPING
717 			fCurrentLayer->RebuildFullRegion();
718 #endif
719 			break;
720 		}
721 		case AS_LAYER_GET_STATE:
722 		{
723 			DTRACE(("ServerWindow %s: Message AS_LAYER_GET_STATE: Layer name: %s\n", fTitle, fCurrentLayer->Name()));
724 
725 			fLink.StartMessage(SERVER_TRUE);
726 
727 			// attach state data
728 			fCurrentLayer->fLayerData->WriteToLink(fLink.Sender());
729 			fLink.Flush();
730 			break;
731 		}
732 		case AS_LAYER_SET_EVENT_MASK:
733 		{
734 			STRACE(("ServerWindow %s: Message AS_LAYER_SET_MOUSE_EVENT_MASK: Layer name: %s\n", fTitle, fCurrentLayer->Name()));
735 
736 			uint32		mask;
737 			uint32		options;
738 
739 			link.Read<uint32>(&mask);
740 			link.Read<uint32>(&options);
741 
742 			fCurrentLayer->QuietlySetEventMask(mask);
743 			fCurrentLayer->QuietlySetEventOptions(options);
744 
745 			if (myRootLayer)
746 				myRootLayer->AddToInputNotificationLists(fCurrentLayer, mask, options);
747 		}
748 		case AS_LAYER_SET_MOUSE_EVENT_MASK:
749 		{
750 			STRACE(("ServerWindow %s: Message AS_LAYER_SET_MOUSE_EVENT_MASK: Layer name: %s\n", fTitle, fCurrentLayer->Name()));
751 
752 			uint32		mask;
753 			uint32		options;
754 
755 			link.Read<uint32>(&mask);
756 			link.Read<uint32>(&options);
757 
758 			if (myRootLayer)
759 				myRootLayer->SetNotifyLayer(fCurrentLayer, mask, options);
760 			break;
761 		}
762 		case AS_LAYER_MOVE_TO:
763 		{
764 			STRACE(("ServerWindow %s: Message AS_LAYER_MOVE_TO: Layer name: %s\n",
765 				fTitle, fCurrentLayer->Name()));
766 
767 			float x, y;
768 			link.Read<float>(&x);
769 			link.Read<float>(&y);
770 
771 			float offsetX = x - fCurrentLayer->fFrame.left;
772 			float offsetY = y - fCurrentLayer->fFrame.top;
773 
774 			fCurrentLayer->MoveBy(offsetX, offsetY);
775 			break;
776 		}
777 		case AS_LAYER_RESIZE_TO:
778 		{
779 			STRACE(("ServerWindow %s: Message AS_LAYER_RESIZE_TO: Layer name: %s\n",
780 				fTitle, fCurrentLayer->Name()));
781 
782 			float newWidth, newHeight;
783 			link.Read<float>(&newWidth);
784 			link.Read<float>(&newHeight);
785 
786 			// TODO: If fCurrentLayer is a window, check for minimum size allowed.
787 			// Need WinBorder::GetSizeLimits
788 			float deltaWidth = newWidth - fCurrentLayer->fFrame.Width();
789 			float deltaHeight = newHeight - fCurrentLayer->fFrame.Height();
790 
791 			fCurrentLayer->ResizeBy(deltaWidth, deltaHeight);
792 			break;
793 		}
794 		case AS_LAYER_GET_COORD:
795 		{
796 			STRACE(("ServerWindow %s: Message AS_LAYER_GET_COORD: Layer: %s\n", Title(), fCurrentLayer->Name()));
797 			fLink.StartMessage(SERVER_TRUE);
798 			// our offset in the parent -> will be originX and originY in BView
799 			fLink.Attach<float>(fCurrentLayer->fFrame.left);
800 			fLink.Attach<float>(fCurrentLayer->fFrame.top);
801 			// convert frame to bounds
802 			fLink.Attach<BRect>(fCurrentLayer->fFrame.OffsetToCopy(fCurrentLayer->BoundsOrigin()));
803 			fLink.Flush();
804 			break;
805 		}
806 		case AS_LAYER_SET_ORIGIN:
807 		{
808 			STRACE(("ServerWindow %s: Message AS_LAYER_SET_ORIGIN: Layer: %s\n", Title(), fCurrentLayer->Name()));
809 			float x, y;
810 
811 			link.Read<float>(&x);
812 			link.Read<float>(&y);
813 
814 			fCurrentLayer->fLayerData->SetOrigin(BPoint(x, y));
815 			break;
816 		}
817 		case AS_LAYER_GET_ORIGIN:
818 		{
819 			STRACE(("ServerWindow %s: Message AS_LAYER_GET_ORIGIN: Layer: %s\n", Title(), fCurrentLayer->Name()));
820 			fLink.StartMessage(SERVER_TRUE);
821 			fLink.Attach<BPoint>(fCurrentLayer->fLayerData->Origin());
822 			fLink.Flush();
823 			break;
824 		}
825 		case AS_LAYER_RESIZE_MODE:
826 		{
827 			STRACE(("ServerWindow %s: Message AS_LAYER_RESIZE_MODE: Layer: %s\n", Title(), fCurrentLayer->Name()));
828 			link.Read<uint32>(&(fCurrentLayer->fResizeMode));
829 			break;
830 		}
831 		case AS_LAYER_CURSOR:
832 		{
833 			DTRACE(("ServerWindow %s: Message AS_LAYER_CURSOR: Layer: %s - NOT IMPLEMENTED\n", Title(), fCurrentLayer->Name()));
834 			int32 token;
835 
836 			link.Read<int32>(&token);
837 
838 			// TODO: implement; I think each Layer should have a member pointing
839 			// to this requested cursor.
840 
841 			break;
842 		}
843 		case AS_LAYER_SET_FLAGS:
844 		{
845 			uint32 flags;
846 			link.Read<uint32>(&flags);
847 			fCurrentLayer->SetFlags(flags);
848 
849 			STRACE(("ServerWindow %s: Message AS_LAYER_SET_FLAGS: Layer: %s\n", Title(), fCurrentLayer->Name()));
850 			break;
851 		}
852 		case AS_LAYER_HIDE:
853 		{
854 			STRACE(("ServerWindow %s: Message AS_LAYER_HIDE: Layer: %s\n", Title(), fCurrentLayer->Name()));
855 			fCurrentLayer->Hide();
856 			break;
857 		}
858 		case AS_LAYER_SHOW:
859 		{
860 			STRACE(("ServerWindow %s: Message AS_LAYER_SHOW: Layer: %s\n", Title(), fCurrentLayer->Name()));
861 			fCurrentLayer->Show();
862 			break;
863 		}
864 		case AS_LAYER_SET_LINE_MODE:
865 		{
866 			DTRACE(("ServerWindow %s: Message AS_LAYER_SET_LINE_MODE: Layer: %s\n", Title(), fCurrentLayer->Name()));
867 			int8 lineCap, lineJoin;
868 			float miterLimit;
869 
870 			// TODO: Look into locking scheme relating to Layers and modifying redraw-related members
871 
872 			link.Read<int8>(&lineCap);
873 			link.Read<int8>(&lineJoin);
874 			link.Read<float>(&miterLimit);
875 
876 			fCurrentLayer->fLayerData->SetLineCapMode((cap_mode)lineCap);
877 			fCurrentLayer->fLayerData->SetLineJoinMode((join_mode)lineJoin);
878 			fCurrentLayer->fLayerData->SetMiterLimit(miterLimit);
879 
880 			break;
881 		}
882 		case AS_LAYER_GET_LINE_MODE:
883 		{
884 			DTRACE(("ServerWindow %s: Message AS_LAYER_GET_LINE_MODE: Layer: %s\n", Title(), fCurrentLayer->Name()));
885 			fLink.StartMessage(SERVER_TRUE);
886 			fLink.Attach<int8>((int8)(fCurrentLayer->fLayerData->LineCapMode()));
887 			fLink.Attach<int8>((int8)(fCurrentLayer->fLayerData->LineJoinMode()));
888 			fLink.Attach<float>(fCurrentLayer->fLayerData->MiterLimit());
889 			fLink.Flush();
890 
891 			break;
892 		}
893 		case AS_LAYER_PUSH_STATE:
894 		{
895 			DTRACE(("ServerWindow %s: Message AS_LAYER_PUSH_STATE: Layer: %s\n", Title(), fCurrentLayer->Name()));
896 
897 			fCurrentLayer->PushState();
898 #ifndef NEW_CLIPPING
899 			fCurrentLayer->RebuildFullRegion();
900 #endif
901 			break;
902 		}
903 		case AS_LAYER_POP_STATE:
904 		{
905 			DTRACE(("ServerWindow %s: Message AS_LAYER_POP_STATE: Layer: %s\n", Title(), fCurrentLayer->Name()));
906 
907 			fCurrentLayer->PopState();
908 #ifndef NEW_CLIPPING
909 			fCurrentLayer->RebuildFullRegion();
910 #endif
911 			break;
912 		}
913 		case AS_LAYER_SET_SCALE:
914 		{
915 			DTRACE(("ServerWindow %s: Message AS_LAYER_SET_SCALE: Layer: %s\n", Title(), fCurrentLayer->Name()));
916 			float scale;
917 			link.Read<float>(&scale);
918 			// TODO: The BeBook says, if you call SetScale() it will be
919 			// multiplied with the scale from all previous states on the stack
920 			fCurrentLayer->fLayerData->SetScale(scale);
921 			break;
922 		}
923 		case AS_LAYER_GET_SCALE:
924 		{
925 			DTRACE(("ServerWindow %s: Message AS_LAYER_GET_SCALE: Layer: %s\n", Title(), fCurrentLayer->Name()));
926 			LayerData		*ld = fCurrentLayer->fLayerData;
927 
928 			// TODO: And here, we're taking that into account, but not above
929 			// -> refactor put scale into Layer, or better yet, when the
930 			// state stack is within Layer, PushState() should multiply
931 			// by the previous last states scale. Would fix the problem above too.
932 			float			scale = ld->Scale();
933 
934 			while ((ld = ld->prevState))
935 				scale *= ld->Scale();
936 
937 			fLink.StartMessage(SERVER_TRUE);
938 			fLink.Attach<float>(scale);
939 			fLink.Flush();
940 
941 			break;
942 		}
943 		case AS_LAYER_SET_PEN_LOC:
944 		{
945 			DTRACE(("ServerWindow %s: Message AS_LAYER_SET_PEN_LOC: Layer: %s\n", Title(), fCurrentLayer->Name()));
946 			float		x, y;
947 
948 			link.Read<float>(&x);
949 			link.Read<float>(&y);
950 
951 			fCurrentLayer->fLayerData->SetPenLocation(BPoint(x, y));
952 
953 			break;
954 		}
955 		case AS_LAYER_GET_PEN_LOC:
956 		{
957 			DTRACE(("ServerWindow %s: Message AS_LAYER_GET_PEN_LOC: Layer: %s\n", Title(), fCurrentLayer->Name()));
958 			fLink.StartMessage(SERVER_TRUE);
959 			fLink.Attach<BPoint>(fCurrentLayer->fLayerData->PenLocation());
960 			fLink.Flush();
961 
962 			break;
963 		}
964 		case AS_LAYER_SET_PEN_SIZE:
965 		{
966 			DTRACE(("ServerWindow %s: Message AS_LAYER_SET_PEN_SIZE: Layer: %s\n", Title(), fCurrentLayer->Name()));
967 			float penSize;
968 			link.Read<float>(&penSize);
969 			fCurrentLayer->fLayerData->SetPenSize(penSize);
970 
971 			break;
972 		}
973 		case AS_LAYER_GET_PEN_SIZE:
974 		{
975 			DTRACE(("ServerWindow %s: Message AS_LAYER_GET_PEN_SIZE: Layer: %s\n", Title(), fCurrentLayer->Name()));
976 			fLink.StartMessage(SERVER_TRUE);
977 			fLink.Attach<float>(fCurrentLayer->fLayerData->PenSize());
978 			fLink.Flush();
979 
980 			break;
981 		}
982 		case AS_LAYER_SET_VIEW_COLOR:
983 		{
984 			DTRACE(("ServerWindow %s: Message AS_LAYER_SET_VIEW_COLOR: Layer: %s\n", Title(), fCurrentLayer->Name()));
985 			rgb_color c;
986 
987 			link.Read(&c, sizeof(rgb_color));
988 myRootLayer->Lock();
989 			fCurrentLayer->SetViewColor(RGBColor(c));
990 
991 #ifndef NEW_CLIPPING
992 			if (myRootLayer)
993 				myRootLayer->GoRedraw(fCurrentLayer, fCurrentLayer->fVisible);
994 #else
995 			myRootLayer->GoRedraw(fCurrentLayer, fCurrentLayer->VisibleRegion());
996 #endif
997 myRootLayer->Unlock();
998 			break;
999 		}
1000 
1001 		case AS_LAYER_GET_HIGH_COLOR:
1002 			DTRACE(("ServerWindow %s: Message AS_LAYER_GET_HIGH_COLOR: Layer: %s\n",
1003 				Title(), fCurrentLayer->Name()));
1004 
1005 			fLink.StartMessage(SERVER_TRUE);
1006 			fLink.Attach<rgb_color>(fCurrentLayer->fLayerData->HighColor().GetColor32());
1007 			fLink.Flush();
1008 			break;
1009 
1010 		case AS_LAYER_GET_LOW_COLOR:
1011 			DTRACE(("ServerWindow %s: Message AS_LAYER_GET_LOW_COLOR: Layer: %s\n",
1012 				Title(), fCurrentLayer->Name()));
1013 
1014 			fLink.StartMessage(SERVER_TRUE);
1015 			fLink.Attach<rgb_color>(fCurrentLayer->fLayerData->LowColor().GetColor32());
1016 			fLink.Flush();
1017 			break;
1018 
1019 		case AS_LAYER_GET_VIEW_COLOR:
1020 			DTRACE(("ServerWindow %s: Message AS_LAYER_GET_VIEW_COLOR: Layer: %s\n",
1021 				Title(), fCurrentLayer->Name()));
1022 
1023 			fLink.StartMessage(SERVER_TRUE);
1024 			fLink.Attach<rgb_color>(fCurrentLayer->ViewColor().GetColor32());
1025 			fLink.Flush();
1026 			break;
1027 
1028 		case AS_LAYER_SET_BLEND_MODE:
1029 		{
1030 			DTRACE(("ServerWindow %s: Message AS_LAYER_SET_BLEND_MODE: Layer: %s\n", Title(), fCurrentLayer->Name()));
1031 			int8 srcAlpha, alphaFunc;
1032 
1033 			link.Read<int8>(&srcAlpha);
1034 			link.Read<int8>(&alphaFunc);
1035 
1036 			fCurrentLayer->fLayerData->SetBlendingMode((source_alpha)srcAlpha,
1037 											(alpha_function)alphaFunc);
1038 
1039 			break;
1040 		}
1041 		case AS_LAYER_GET_BLEND_MODE:
1042 		{
1043 			DTRACE(("ServerWindow %s: Message AS_LAYER_GET_BLEND_MODE: Layer: %s\n", Title(), fCurrentLayer->Name()));
1044 			fLink.StartMessage(SERVER_TRUE);
1045 			fLink.Attach<int8>((int8)(fCurrentLayer->fLayerData->AlphaSrcMode()));
1046 			fLink.Attach<int8>((int8)(fCurrentLayer->fLayerData->AlphaFncMode()));
1047 			fLink.Flush();
1048 
1049 			break;
1050 		}
1051 		case AS_LAYER_SET_DRAW_MODE:
1052 		{
1053 			DTRACE(("ServerWindow %s: Message AS_LAYER_SET_DRAW_MODE: Layer: %s\n", Title(), fCurrentLayer->Name()));
1054 			int8 drawingMode;
1055 
1056 			link.Read<int8>(&drawingMode);
1057 
1058 			fCurrentLayer->fLayerData->SetDrawingMode((drawing_mode)drawingMode);
1059 
1060 			break;
1061 		}
1062 		case AS_LAYER_GET_DRAW_MODE:
1063 		{
1064 			DTRACE(("ServerWindow %s: Message AS_LAYER_GET_DRAW_MODE: Layer: %s\n", Title(), fCurrentLayer->Name()));
1065 			fLink.StartMessage(SERVER_TRUE);
1066 			fLink.Attach<int8>((int8)(fCurrentLayer->fLayerData->GetDrawingMode()));
1067 			fLink.Flush();
1068 
1069 			break;
1070 		}
1071 		case AS_LAYER_PRINT_ALIASING:
1072 		{
1073 			DTRACE(("ServerWindow %s: Message AS_LAYER_PRINT_ALIASING: Layer: %s\n", Title(), fCurrentLayer->Name()));
1074 			bool fontAliasing;
1075 			link.Read<bool>(&fontAliasing);
1076 			fCurrentLayer->fLayerData->SetForceFontAliasing(fontAliasing);
1077 
1078 			break;
1079 		}
1080 		case AS_LAYER_CLIP_TO_PICTURE:
1081 		{
1082 			DTRACE(("ServerWindow %s: Message AS_LAYER_CLIP_TO_PICTURE: Layer: %s\n", Title(), fCurrentLayer->Name()));
1083 		// TODO: you are not allowed to use Layer regions here!!!
1084 		// If there is no other way, then first lock RootLayer object first.
1085 
1086 			int32 pictureToken;
1087 			BPoint where;
1088 			bool inverse = false;
1089 
1090 			link.Read<int32>(&pictureToken);
1091 			link.Read<BPoint>(&where);
1092 			link.Read<bool>(&inverse);
1093 
1094 			// search for a picture with the specified token.
1095 			ServerPicture *picture = fServerApp->FindPicture(pictureToken);
1096 			// TODO: Increase that picture's reference count.(~ allocate a picture)
1097 			if (picture == NULL)
1098 				break;
1099 
1100 			BRegion region;
1101 			// TODO: I think we also need the BView's token
1102 			// I think PictureToRegion would fit better into the Layer class (?)
1103 			if (PictureToRegion(picture, region, inverse, where) < B_OK)
1104 				break;
1105 
1106 			fCurrentLayer->fLayerData->SetClippingRegion(region);
1107 
1108 #ifndef NEW_CLIPPING
1109 			fCurrentLayer->RebuildFullRegion();
1110 #endif
1111 			if (myRootLayer && !(fCurrentLayer->IsHidden()) && !fWinBorder->InUpdate())
1112 #ifndef NEW_CLIPPING
1113 				myRootLayer->GoInvalidate(fCurrentLayer, fCurrentLayer->fFull);
1114 #else
1115 			{
1116 				BRegion invalidRegion;
1117 				fCurrentLayer->GetWantedRegion(invalidRegion);
1118 				myRootLayer->GoInvalidate(fCurrentLayer, invalidRegion);
1119 			}
1120 #endif
1121 
1122 			break;
1123 		}
1124 
1125 		case AS_LAYER_GET_CLIP_REGION:
1126 		{
1127 			DTRACE(("ServerWindow %s: Message AS_LAYER_GET_CLIP_REGION: Layer: %s\n", Title(), fCurrentLayer->Name()));
1128 
1129 			// if this Layer is hidden, it is clear that its visible region is void.
1130 			if (fCurrentLayer->IsHidden()) {
1131 				fLink.StartMessage(SERVER_TRUE);
1132 				fLink.Attach<int32>(0L);
1133 				fLink.Flush();
1134 			} else {
1135 				// TODO: Watch out for the coordinate system in AS_LAYER_GET_CLIP_REGION
1136 #ifndef NEW_CLIPPING
1137 				int32 rectCount = fCurrentLayer->fVisible.CountRects();
1138 #else
1139 				int32 rectCount = fCurrentLayer->fVisible2.CountRects();
1140 #endif
1141 
1142 				fLink.StartMessage(SERVER_TRUE);
1143 				fLink.Attach<int32>(rectCount);
1144 
1145 				for (int32 i = 0; i < rectCount; i++)
1146 #ifndef NEW_CLIPPING
1147 					fLink.Attach<BRect>(fCurrentLayer->ConvertFromTop(fCurrentLayer->fVisible.RectAt(i)));
1148 #else
1149 					fLink.Attach<BRect>(fCurrentLayer->ConvertFromTop(fCurrentLayer->fVisible2.RectAt(i)));
1150 #endif
1151 
1152 				fLink.Flush();
1153 			}
1154 
1155 			break;
1156 		}
1157 		case AS_LAYER_SET_CLIP_REGION:
1158 		{
1159 			DTRACE(("ServerWindow %s: Message AS_LAYER_SET_CLIP_REGION: Layer: %s\n", Title(), fCurrentLayer->Name()));
1160 
1161 			// TODO: Watch out for the coordinate system in AS_LAYER_SET_CLIP_REGION
1162 			int32 noOfRects;
1163 			BRect r;
1164 
1165 			link.Read<int32>(&noOfRects);
1166 
1167 			BRegion region;
1168 			for (int i = 0; i < noOfRects; i++) {
1169 				link.Read<BRect>(&r);
1170 				region.Include(fCurrentLayer->ConvertToTop(r));
1171 			}
1172 // TODO: Turned off user clipping for now (will probably not harm anything but performance right now)
1173 // We need to integrate user clipping more, in Layer::PopState, the clipping needs to be
1174 // restored too. "AS_LAYER_SET_CLIP_REGION" is irritating, as I think it should be
1175 // "AS_LAYER_CONSTRAIN_CLIP_REGION", since it means to "add" to the current clipping, not "set" it.
1176 //			fCurrentLayer->fLayerData->SetClippingRegion(region);
1177 #ifndef NEW_CLIPPING
1178 // TODO: set the clipping
1179 //			fCurrentLayer->fVisible.IntersectWith(&region);
1180 #endif
1181 /*
1182 #ifndef NEW_CLIPPING
1183 			fCurrentLayer->RebuildFullRegion();
1184 			if (myRootLayer && !(fCurrentLayer->IsHidden()) && !fWinBorder->InUpdate())
1185 				myRootLayer->GoInvalidate(fCurrentLayer, fCurrentLayer->fFull);
1186 #else
1187 			if (myRootLayer && !(fCurrentLayer->IsHidden()) && !fWinBorder->InUpdate())
1188 				myRootLayer->GoInvalidate(fCurrentLayer, fCurrentLayer->Frame());
1189 #endif
1190 */
1191 			break;
1192 		}
1193 		case AS_LAYER_INVAL_RECT:
1194 		{
1195 			DTRACE(("ServerWindow %s: Message AS_LAYER_INVAL_RECT: Layer: %s\n", Title(), fCurrentLayer->Name()));
1196 
1197 			// TODO: handle transformation (origin and scale) prior to converting to top
1198 			BRect		invalRect;
1199 
1200 			link.Read<BRect>(&invalRect);
1201 
1202 			if (myRootLayer) {
1203 				BRect converted(fCurrentLayer->ConvertToTop(invalRect.LeftTop()),
1204 								fCurrentLayer->ConvertToTop(invalRect.RightBottom()));
1205 				BRegion invalidRegion(converted);
1206 #ifdef NEW_CLIPPING
1207 				invalidRegion.IntersectWith(&fCurrentLayer->fVisible2);
1208 #endif
1209 				myRootLayer->GoRedraw(fWinBorder, invalidRegion);
1210 //				myRootLayer->RequestDraw(invalidRegion, fWinBorder);
1211 			}
1212 			break;
1213 		}
1214 		case AS_LAYER_INVAL_REGION:
1215 		{
1216 			DTRACE(("ServerWindow %s: Message AS_LAYER_INVAL_RECT: Layer: %s\n", Title(), fCurrentLayer->Name()));
1217 
1218 			// TODO: handle transformation (origin and scale) prior to converting to top
1219 			// TODO: Handle conversion to top
1220 			BRegion invalReg;
1221 			int32 noOfRects;
1222 			BRect rect;
1223 
1224 			link.Read<int32>(&noOfRects);
1225 
1226 			for (int i = 0; i < noOfRects; i++) {
1227 				link.Read<BRect>(&rect);
1228 				invalReg.Include(rect);
1229 			}
1230 
1231 			if (myRootLayer)
1232 				myRootLayer->GoRedraw(fCurrentLayer, invalReg);
1233 
1234 			break;
1235 		}
1236 		case AS_BEGIN_UPDATE:
1237 		{
1238 			DTRACE(("ServerWindowo %s: AS_BEGIN_UPDATE\n", Title()));
1239 			fWinBorder->UpdateStart();
1240 			break;
1241 		}
1242 		case AS_END_UPDATE:
1243 		{
1244 			DTRACE(("ServerWindowo %s: AS_END_UPDATE\n", Title()));
1245 			fWinBorder->UpdateEnd();
1246 			break;
1247 		}
1248 
1249 		// ********** END: BView Messages ***********
1250 
1251 		// ********* BWindow Messages ***********
1252 		case AS_LAYER_DELETE_ROOT:
1253 		{
1254 			// Received when a window deletes its internal top view
1255 
1256 			// TODO: Implement AS_LAYER_DELETE_ROOT
1257 			STRACE(("ServerWindow %s: Message Delete_Layer_Root unimplemented\n", Title()));
1258 			break;
1259 		}
1260 		case AS_SHOW_WINDOW:
1261 		{
1262 			STRACE(("ServerWindow %s: Message AS_SHOW_WINDOW\n", Title()));
1263 			Show();
1264 			break;
1265 		}
1266 		case AS_HIDE_WINDOW:
1267 		{
1268 			STRACE(("ServerWindow %s: Message AS_HIDE_WINDOW\n", Title()));
1269 			Hide();
1270 			break;
1271 		}
1272 		case AS_SEND_BEHIND:
1273 		{
1274 			STRACE(("ServerWindow %s: Message  Send_Behind unimplemented\n", Title()));
1275 			int32 token;
1276 			team_id teamID;
1277 			status_t status = B_NAME_NOT_FOUND;
1278 
1279 			link.Read<int32>(&token);
1280 			link.Read<team_id>(&teamID);
1281 
1282 			WinBorder *behindOf;
1283 			if ((behindOf = fDesktop->FindWinBorderByClientToken(token, teamID)) != NULL) {
1284 				fWinBorder->GetRootLayer()->Lock();
1285 				// TODO: move to back ATM. Fix this later!
1286 				fWinBorder->GetRootLayer()->SetActive(fWinBorder, false);
1287 				fWinBorder->GetRootLayer()->Unlock();
1288 				status = B_OK;
1289 			}
1290 
1291 			fLink.StartMessage(status);
1292 			fLink.Flush();
1293 			break;
1294 		}
1295 		case AS_ENABLE_UPDATES:
1296 		{
1297 			STRACE(("ServerWindow %s: Message Enable_Updates unimplemented\n", Title()));
1298 			fWinBorder->EnableUpdateRequests();
1299 			if (fWinBorder->CulmulatedUpdateRegion().Frame().IsValid()) {
1300 				BRegion		reg(fWinBorder->CulmulatedUpdateRegion());
1301 				fWinBorder->RequestDraw(reg, NULL);
1302 			}
1303 			break;
1304 		}
1305 		case AS_DISABLE_UPDATES:
1306 		{
1307 			STRACE(("ServerWindow %s: Message Disable_Updates unimplemented\n", Title()));
1308 			fWinBorder->DisableUpdateRequests();
1309 			break;
1310 		}
1311 		case AS_NEEDS_UPDATE:
1312 		{
1313 			STRACE(("ServerWindow %s: Message Needs_Update unimplemented\n", Title()));
1314 			if (fWinBorder->CulmulatedUpdateRegion().Frame().IsValid())
1315 				fLink.StartMessage(B_OK);
1316 			else
1317 				fLink.StartMessage(B_ERROR);
1318 			fLink.Flush();
1319 			break;
1320 		}
1321 		case AS_SET_WINDOW_TITLE:
1322 		{
1323 			char* newTitle;
1324 			if (link.ReadString(&newTitle) == B_OK) {
1325 				SetTitle(newTitle);
1326 				free(newTitle);
1327 			}
1328 			break;
1329 		}
1330 
1331 		case AS_ADD_TO_SUBSET:
1332 		{
1333 			STRACE(("ServerWindow %s: Message AS_ADD_TO_SUBSET\n", Title()));
1334 			WinBorder *windowBorder;
1335 			int32 mainToken;
1336 			team_id	teamID;
1337 
1338 			link.Read<int32>(&mainToken);
1339 			link.Read(&teamID, sizeof(team_id));
1340 
1341 			windowBorder = fDesktop->FindWinBorderByClientToken(mainToken, teamID);
1342 			if (windowBorder) {
1343 				fLink.StartMessage(SERVER_TRUE);
1344 				fLink.Flush();
1345 
1346 				fWinBorder->GetRootLayer()->Lock();
1347 				fDesktop->AddWinBorderToSubset(fWinBorder, windowBorder);
1348 				fWinBorder->GetRootLayer()->Unlock();
1349 			} else {
1350 				fLink.StartMessage(SERVER_FALSE);
1351 				fLink.Flush();
1352 			}
1353 			break;
1354 		}
1355 		case AS_REM_FROM_SUBSET:
1356 		{
1357 			STRACE(("ServerWindow %s: Message AS_REM_FROM_SUBSET\n", Title()));
1358 			WinBorder *windowBorder;
1359 			int32 mainToken;
1360 			team_id teamID;
1361 
1362 			link.Read<int32>(&mainToken);
1363 			link.Read(&teamID, sizeof(team_id));
1364 
1365 			windowBorder = fDesktop->FindWinBorderByClientToken(mainToken, teamID);
1366 			if (windowBorder) {
1367 				fLink.StartMessage(SERVER_TRUE);
1368 				fLink.Flush();
1369 
1370 				fWinBorder->GetRootLayer()->Lock();
1371 				fDesktop->RemoveWinBorderFromSubset(fWinBorder, windowBorder);
1372 				fWinBorder->GetRootLayer()->Unlock();
1373 			} else {
1374 				fLink.StartMessage(SERVER_FALSE);
1375 				fLink.Flush();
1376 			}
1377 			break;
1378 		}
1379 #if 0
1380 		case AS_SET_LOOK:
1381 		{
1382 			// TODO: Implement AS_SET_LOOK
1383 			STRACE(("ServerWindow %s: Message Set_Look unimplemented\n", Title()));
1384 			break;
1385 		}
1386 		case AS_SET_FLAGS:
1387 		{
1388 			// TODO: Implement AS_SET_FLAGS
1389 			STRACE(("ServerWindow %s: Message Set_Flags unimplemented\n", Title()));
1390 			break;
1391 		}
1392 		case AS_SET_FEEL:
1393 		{
1394 			STRACE(("ServerWindow %s: Message AS_SET_FEEL\n", Title()));
1395 			int32 newFeel;
1396 			link.Read<int32>(&newFeel);
1397 
1398 			fWinBorder->GetRootLayer()->GoChangeWinBorderFeel(winBorder, newFeel);
1399 			break;
1400 		}
1401 		case AS_SET_ALIGNMENT:
1402 		{
1403 			// TODO: Implement AS_SET_ALIGNMENT
1404 			STRACE(("ServerWindow %s: Message Set_Alignment unimplemented\n", Title()));
1405 			break;
1406 		}
1407 		case AS_GET_ALIGNMENT:
1408 		{
1409 			// TODO: Implement AS_GET_ALIGNMENT
1410 			STRACE(("ServerWindow %s: Message Get_Alignment unimplemented\n", Title()));
1411 			break;
1412 		}
1413 #endif
1414 		case AS_GET_WORKSPACES:
1415 		{
1416 			STRACE(("ServerWindow %s: Message Get_Workspaces unimplemented\n", Title()));
1417 			fLink.StartMessage(SERVER_TRUE);
1418 			fLink.Attach<uint32>(fWinBorder->Workspaces());
1419 			fLink.Flush();
1420 			break;
1421 		}
1422 		case AS_SET_WORKSPACES:
1423 		{
1424 			STRACE(("ServerWindow %s: Message Set_Workspaces unimplemented\n", Title()));
1425 			uint32 newWorkspaces;
1426 			link.Read<uint32>(&newWorkspaces);
1427 
1428 			fWinBorder->GetRootLayer()->Lock();
1429 			fWinBorder->GetRootLayer()->SetWinBorderWorskpaces( fWinBorder,
1430 																fWinBorder->Workspaces(),
1431 																newWorkspaces);
1432 			fWinBorder->GetRootLayer()->Unlock();
1433 			break;
1434 		}
1435 		case AS_WINDOW_RESIZE:
1436 		{
1437 			float xResizeBy;
1438 			float yResizeBy;
1439 
1440 			link.Read<float>(&xResizeBy);
1441 			link.Read<float>(&yResizeBy);
1442 
1443 			STRACE(("ServerWindow %s: Message AS_WINDOW_RESIZE %.1f, %.1f\n", Title(), xResizeBy, yResizeBy));
1444 
1445 			fWinBorder->ResizeBy(xResizeBy, yResizeBy);
1446 			break;
1447 		}
1448 		case AS_WINDOW_MOVE:
1449 		{
1450 			float xMoveBy;
1451 			float yMoveBy;
1452 
1453 			link.Read<float>(&xMoveBy);
1454 			link.Read<float>(&yMoveBy);
1455 
1456 			STRACE(("ServerWindow %s: Message AS_WINDOW_MOVE: %.1f, %.1f\n", Title(), xMoveBy, yMoveBy));
1457 
1458 			fWinBorder->MoveBy(xMoveBy, yMoveBy);
1459 			break;
1460 		}
1461 		case AS_SET_SIZE_LIMITS:
1462 		{
1463 			// Attached Data:
1464 			// 1) float minimum width
1465 			// 2) float maximum width
1466 			// 3) float minimum height
1467 			// 4) float maximum height
1468 
1469 			float minWidth;
1470 			float maxWidth;
1471 			float minHeight;
1472 			float maxHeight;
1473 
1474 			link.Read<float>(&minWidth);
1475 			link.Read<float>(&maxWidth);
1476 			link.Read<float>(&minHeight);
1477 			link.Read<float>(&maxHeight);
1478 
1479 			fWinBorder->SetSizeLimits(minWidth, maxWidth, minHeight, maxHeight);
1480 
1481 			// and now, sync the client to the limits that we were able to enforce
1482 			fWinBorder->GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight);
1483 
1484 			fLink.StartMessage(SERVER_TRUE);
1485 			fLink.Attach<BRect>(fWinBorder->Frame());
1486 			fLink.Attach<float>(minWidth);
1487 			fLink.Attach<float>(maxWidth);
1488 			fLink.Attach<float>(minHeight);
1489 			fLink.Attach<float>(maxHeight);
1490 
1491 			fLink.Flush();
1492 			break;
1493 		}
1494 		case AS_ACTIVATE_WINDOW:
1495 		{
1496 			DTRACE(("ServerWindow %s: Message AS_ACTIVATE_WINDOW: Layer: %s\n", Title(), fCurrentLayer->Name()));
1497 			bool activate = true;
1498 
1499 			link.Read<bool>(&activate);
1500 
1501 			if (myRootLayer && myRootLayer->Lock()) {
1502 				myRootLayer->SetActive(fWinBorder, activate);
1503 				myRootLayer->Unlock();
1504 			}
1505 			break;
1506 		}
1507 		// Some BView drawing messages, but which don't need clipping
1508 		case AS_LAYER_SET_HIGH_COLOR:
1509 		{
1510 			DTRACE(("ServerWindow %s: Message AS_LAYER_SET_HIGH_COLOR: Layer: %s\n", Title(), fCurrentLayer->Name()));
1511 			rgb_color c;
1512 
1513 			link.Read(&c, sizeof(rgb_color));
1514 
1515 			fCurrentLayer->fLayerData->SetHighColor(RGBColor(c));
1516 
1517 			break;
1518 		}
1519 		case AS_LAYER_SET_LOW_COLOR:
1520 		{
1521 			DTRACE(("ServerWindow %s: Message AS_LAYER_SET_LOW_COLOR: Layer: %s\n", Title(), fCurrentLayer->Name()));
1522 			rgb_color c;
1523 
1524 			link.Read(&c, sizeof(rgb_color));
1525 
1526 			fCurrentLayer->fLayerData->SetLowColor(RGBColor(c));
1527 
1528 			break;
1529 		}
1530 		case AS_LAYER_SET_PATTERN:
1531 		{
1532 			DTRACE(("ServerWindow %s: Message AS_LAYER_SET_PATTERN: Layer: %s\n", fTitle, fCurrentLayer->Name()));
1533 			pattern pat;
1534 
1535 			link.Read(&pat, sizeof(pattern));
1536 
1537 			fCurrentLayer->fLayerData->SetPattern(Pattern(pat));
1538 
1539 			break;
1540 		}
1541 		case AS_MOVEPENTO:
1542 		{
1543 			DTRACE(("ServerWindow %s: Message AS_MOVEPENTO\n", Title()));
1544 
1545 			float x,y;
1546 
1547 			link.Read<float>(&x);
1548 			link.Read<float>(&y);
1549 			if (fCurrentLayer && fCurrentLayer->fLayerData)
1550 				fCurrentLayer->fLayerData->SetPenLocation(BPoint(x, y));
1551 
1552 			break;
1553 		}
1554 		case AS_SETPENSIZE:
1555 		{
1556 			DTRACE(("ServerWindow %s: Message AS_SETPENSIZE\n", Title()));
1557 			float size;
1558 
1559 			link.Read<float>(&size);
1560 			if (fCurrentLayer && fCurrentLayer->fLayerData)
1561 				fCurrentLayer->fLayerData->SetPenSize(size);
1562 
1563 			break;
1564 		}
1565 		case AS_SET_FONT:
1566 		{
1567 			DTRACE(("ServerWindow %s: Message AS_SET_FONT\n", Title()));
1568 			// TODO: Implement AS_SET_FONT?
1569 			// Confusing!! But it works already!
1570 			break;
1571 		}
1572 		case AS_SET_FONT_SIZE:
1573 		{
1574 			DTRACE(("ServerWindow %s: Message AS_SET_FONT_SIZE\n", Title()));
1575 			// TODO: Implement AS_SET_FONT_SIZE?
1576 			break;
1577 		}
1578 		case AS_AREA_MESSAGE:
1579 		{
1580 			STRACE(("ServerWindow %s: Message AS_AREA_MESSAGE\n", Title()));
1581 			// This occurs in only one kind of case: a message is too big to send over a port. This
1582 			// is really an edge case, so this shouldn't happen *too* often
1583 
1584 			// Attached Data:
1585 			// 1) area_id id of an area already owned by the server containing the message
1586 			// 2) size_t offset of the pointer in the area
1587 			// 3) size_t size of the message
1588 
1589 			area_id area;
1590 			size_t offset;
1591 			size_t msgsize;
1592 			area_info ai;
1593 			int8 *msgpointer;
1594 
1595 			link.Read<area_id>(&area);
1596 			link.Read<size_t>(&offset);
1597 			link.Read<size_t>(&msgsize);
1598 
1599 			// Part sanity check, part get base pointer :)
1600 			if(get_area_info(area,&ai)!=B_OK)
1601 				break;
1602 
1603 			msgpointer = (int8*)ai.address + offset;
1604 
1605 			RAMLinkMsgReader mlink(msgpointer);
1606 			_DispatchMessage(mlink.Code(), mlink);
1607 
1608 			// This is a very special case in the sense that when ServerMemIO is used for this
1609 			// purpose, it will be set to NOT automatically free the memory which it had
1610 			// requested. This is the server's job once the message has been dispatched.
1611 			fServerApp->AppAreaPool()->ReleaseBuffer(msgpointer);
1612 			break;
1613 		}
1614 		case AS_SYNC:
1615 		{
1616 			// TODO: AS_SYNC is a no-op for now, just to get things working
1617 			fLink.StartMessage(SERVER_TRUE);
1618 			fLink.Flush();
1619 			break;
1620 		}
1621 		case AS_LAYER_DRAG_IMAGE:
1622 		{
1623 			// TODO: Implement AS_LAYER_DRAG_IMAGE
1624 			STRACE(("ServerWindow %s: Message AS_DRAG_IMAGE unimplemented\n", Title()));
1625 			DTRACE(("ServerWindow %s: Message AS_DRAG_IMAGE unimplemented\n", Title()));
1626 			break;
1627 		}
1628 		case AS_LAYER_DRAG_RECT:
1629 		{
1630 			// TODO: Implement AS_LAYER_DRAG_RECT
1631 			STRACE(("ServerWindow %s: Message AS_DRAG_RECT unimplemented\n", Title()));
1632 			DTRACE(("ServerWindow %s: Message AS_DRAG_RECT unimplemented\n", Title()));
1633 			break;
1634 		}
1635 		case AS_LAYER_GET_MOUSE_COORDS:
1636 		{
1637 			DTRACE(("ServerWindow %s: Message AS_GET_MOUSE_COORDS\n", fTitle));
1638 
1639 			fLink.StartMessage(SERVER_TRUE);
1640 
1641 			// Returns
1642 			// 1) BPoint mouse location
1643 			// 2) int32 button state
1644 
1645 			fLink.Attach<BPoint>(fDesktop->GetHWInterface()->GetCursorPosition());
1646 			fLink.Attach<int32>(fDesktop->ActiveRootLayer()->Buttons());
1647 
1648 			fLink.Flush();
1649 			break;
1650 		}
1651 
1652 		case AS_DW_GET_SYNC_DATA:
1653 		{
1654 			// TODO: Use token or get rid of it.
1655 			int32 serverToken;
1656 			link.Read<int32>(&serverToken);
1657 
1658 			if (_EnableDirectWindowMode() == B_OK) {
1659 				fLink.StartMessage(SERVER_TRUE);
1660 				struct dw_sync_data syncData = {
1661 					fDirectWindowData->direct_area,
1662 					fDirectWindowData->direct_sem,
1663 					fDirectWindowData->direct_sem_ack
1664 				};
1665 
1666 				fLink.Attach(&syncData, sizeof(syncData));
1667 
1668 			} else
1669 				fLink.StartMessage(SERVER_FALSE);
1670 
1671 			fLink.Flush();
1672 
1673 			break;
1674 		}
1675 
1676 		default:
1677 			_DispatchGraphicsMessage(code, link);
1678 			break;
1679 	}
1680 
1681 	if (myRootLayer)
1682 		myRootLayer->Unlock();
1683 }
1684 
1685 // -------------------- Graphics messages ----------------------------------
1686 
1687 void
1688 ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
1689 {
1690 #ifndef NEW_CLIPPING
1691 	BRegion rreg(fCurrentLayer->fVisible);
1692 #else
1693 	BRegion rreg(fCurrentLayer->fVisible2);
1694 #endif
1695 
1696 	if (fWinBorder->InUpdate())
1697 		rreg.IntersectWith(&fWinBorder->RegionToBeUpdated());
1698 
1699 	DisplayDriver* driver = fWinBorder->GetDisplayDriver();
1700 
1701 	driver->ConstrainClippingRegion(&rreg);
1702 //	rgb_color  rrr = fCurrentLayer->fLayerData->viewcolor.GetColor32();
1703 //	RGBColor c(rand()%255,rand()%255,rand()%255);
1704 //	driver->FillRect(BRect(0,0,639,479), c);
1705 
1706 	switch (code) {
1707 		case AS_STROKE_LINE:
1708 		{
1709 			DTRACE(("ServerWindow %s: Message AS_STROKE_LINE\n", Title()));
1710 
1711 			float x1, y1, x2, y2;
1712 
1713 			link.Read<float>(&x1);
1714 			link.Read<float>(&y1);
1715 			link.Read<float>(&x2);
1716 			link.Read<float>(&y2);
1717 
1718 			if (fCurrentLayer && fCurrentLayer->fLayerData) {
1719 
1720 				BPoint p1(x1,y1);
1721 				BPoint p2(x2,y2);
1722 				driver->StrokeLine(fCurrentLayer->ConvertToTop(p1),
1723 								   fCurrentLayer->ConvertToTop(p2),
1724 								   fCurrentLayer->fLayerData);
1725 
1726 				// We update the pen here because many DisplayDriver calls which do not update the
1727 				// pen position actually call StrokeLine
1728 
1729 				// TODO: Decide where to put this, for example, it cannot be done
1730 				// for DrawString(), also there needs to be a decision, if penlocation
1731 				// is in View coordinates (I think it should be) or in screen coordinates.
1732 				fCurrentLayer->fLayerData->SetPenLocation(p2);
1733 			}
1734 			break;
1735 		}
1736 		case AS_LAYER_INVERT_RECT:
1737 		{
1738 			DTRACE(("ServerWindow %s: Message AS_INVERT_RECT\n", Title()));
1739 
1740 			BRect rect;
1741 			link.Read<BRect>(&rect);
1742 
1743 			if (fCurrentLayer && fCurrentLayer->fLayerData)
1744 				driver->InvertRect(fCurrentLayer->ConvertToTop(rect));
1745 			break;
1746 		}
1747 		case AS_STROKE_RECT:
1748 		{
1749 			DTRACE(("ServerWindow %s: Message AS_STROKE_RECT\n", Title()));
1750 
1751 			float left, top, right, bottom;
1752 			link.Read<float>(&left);
1753 			link.Read<float>(&top);
1754 			link.Read<float>(&right);
1755 			link.Read<float>(&bottom);
1756 			BRect rect(left,top,right,bottom);
1757 
1758 			if (fCurrentLayer && fCurrentLayer->fLayerData)
1759 				driver->StrokeRect(fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData);
1760 			break;
1761 		}
1762 		case AS_FILL_RECT:
1763 		{
1764 			DTRACE(("ServerWindow %s: Message AS_FILL_RECT\n", Title()));
1765 
1766 			BRect rect;
1767 			link.Read<BRect>(&rect);
1768 			if (fCurrentLayer && fCurrentLayer->fLayerData)
1769 				driver->FillRect(fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData);
1770 			break;
1771 		}
1772 		case AS_LAYER_DRAW_BITMAP_SYNC_AT_POINT:
1773 		{
1774 			DTRACE(("ServerWindow %s: Message AS_LAYER_DRAW_BITMAP_SYNC_AT_POINT: Layer name: %s\n", fTitle, fCurrentLayer->Name()));
1775 			int32		bitmapToken;
1776 			BPoint 		point;
1777 
1778 			link.Read<int32>(&bitmapToken);
1779 			link.Read<BPoint>(&point);
1780 
1781 			ServerBitmap* sbmp = fServerApp->FindBitmap(bitmapToken);
1782 			if (sbmp) {
1783 				BRect src = sbmp->Bounds();
1784 				BRect dst = src.OffsetToCopy(point);
1785 				dst = fCurrentLayer->ConvertToTop(dst);
1786 
1787 				driver->DrawBitmap(sbmp, src, dst, fCurrentLayer->fLayerData);
1788 			}
1789 
1790 			// TODO: Adi -- shouldn't AS_LAYER_DRAW_BITMAP_SYNC_AT_POINT sync with the client?
1791 			break;
1792 		}
1793 		case AS_LAYER_DRAW_BITMAP_ASYNC_AT_POINT:
1794 		{
1795 			DTRACE(("ServerWindow %s: Message AS_LAYER_DRAW_BITMAP_ASYNC_AT_POINT: Layer name: %s\n", fTitle, fCurrentLayer->Name()));
1796 			int32		bitmapToken;
1797 			BPoint 		point;
1798 
1799 			link.Read<int32>(&bitmapToken);
1800 			link.Read<BPoint>(&point);
1801 
1802 			ServerBitmap* sbmp = fServerApp->FindBitmap(bitmapToken);
1803 			if (sbmp) {
1804 				BRect src = sbmp->Bounds();
1805 				BRect dst = src.OffsetToCopy(point);
1806 				dst = fCurrentLayer->ConvertToTop(dst);
1807 
1808 				driver->DrawBitmap(sbmp, src, dst, fCurrentLayer->fLayerData);
1809 			}
1810 			break;
1811 		}
1812 		case AS_LAYER_DRAW_BITMAP_SYNC_IN_RECT:
1813 		{
1814 			DTRACE(("ServerWindow %s: Message AS_LAYER_DRAW_BITMAP_SYNC_IN_RECT: Layer name: %s\n", fTitle, fCurrentLayer->Name()));
1815 			int32 bitmapToken;
1816 			BRect srcRect, dstRect;
1817 
1818 			link.Read<int32>(&bitmapToken);
1819 			link.Read<BRect>(&dstRect);
1820 			link.Read<BRect>(&srcRect);
1821 
1822 			ServerBitmap* sbmp = fServerApp->FindBitmap(bitmapToken);
1823 			if (sbmp) {
1824 				dstRect = fCurrentLayer->ConvertToTop(dstRect);
1825 
1826 				driver->DrawBitmap(sbmp, srcRect, dstRect, fCurrentLayer->fLayerData);
1827 			}
1828 
1829 			// TODO: Adi -- shouldn't AS_LAYER_DRAW_BITMAP_SYNC_IN_RECT sync with the client?
1830 			break;
1831 		}
1832 		case AS_LAYER_DRAW_BITMAP_ASYNC_IN_RECT:
1833 		{
1834 			DTRACE(("ServerWindow %s: Message AS_LAYER_DRAW_BITMAP_ASYNC_IN_RECT: Layer name: %s\n", fTitle, fCurrentLayer->Name()));
1835 			int32 bitmapToken;
1836 			BRect srcRect, dstRect;
1837 
1838 			link.Read<int32>(&bitmapToken);
1839 			link.Read<BRect>(&dstRect);
1840 			link.Read<BRect>(&srcRect);
1841 
1842 			ServerBitmap* sbmp = fServerApp->FindBitmap(bitmapToken);
1843 			if (sbmp) {
1844 				dstRect = fCurrentLayer->ConvertToTop(dstRect);
1845 
1846 				driver->DrawBitmap(sbmp, srcRect, dstRect, fCurrentLayer->fLayerData);
1847 			}
1848 			break;
1849 		}
1850 		case AS_STROKE_ARC:
1851 		{
1852 			DTRACE(("ServerWindow %s: Message AS_STROKE_ARC\n", Title()));
1853 
1854 			float angle, span;
1855 			BRect r;
1856 
1857 			link.Read<BRect>(&r);
1858 			link.Read<float>(&angle);
1859 			link.Read<float>(&span);
1860 			if (fCurrentLayer && fCurrentLayer->fLayerData)
1861 				driver->StrokeArc(fCurrentLayer->ConvertToTop(r),angle,span, fCurrentLayer->fLayerData);
1862 			break;
1863 		}
1864 		case AS_FILL_ARC:
1865 		{
1866 			DTRACE(("ServerWindow %s: Message AS_FILL_ARC\n", Title()));
1867 
1868 			float angle, span;
1869 			BRect r;
1870 
1871 			link.Read<BRect>(&r);
1872 			link.Read<float>(&angle);
1873 			link.Read<float>(&span);
1874 			if (fCurrentLayer && fCurrentLayer->fLayerData)
1875 				driver->FillArc(fCurrentLayer->ConvertToTop(r),angle,span, fCurrentLayer->fLayerData);
1876 			break;
1877 		}
1878 		case AS_STROKE_BEZIER:
1879 		{
1880 			DTRACE(("ServerWindow %s: Message AS_STROKE_BEZIER\n", Title()));
1881 
1882 			BPoint *pts;
1883 			int i;
1884 			pts = new BPoint[4];
1885 
1886 			for (i=0; i<4; i++)
1887 				link.Read<BPoint>(&(pts[i]));
1888 
1889 			if (fCurrentLayer && fCurrentLayer->fLayerData)
1890 			{
1891 				for (i=0; i<4; i++)
1892 					pts[i]=fCurrentLayer->ConvertToTop(pts[i]);
1893 
1894 				driver->StrokeBezier(pts, fCurrentLayer->fLayerData);
1895 			}
1896 			delete [] pts;
1897 			break;
1898 		}
1899 		case AS_FILL_BEZIER:
1900 		{
1901 			DTRACE(("ServerWindow %s: Message AS_FILL_BEZIER\n", Title()));
1902 
1903 			BPoint *pts;
1904 			int i;
1905 			pts = new BPoint[4];
1906 
1907 			for (i=0; i<4; i++)
1908 				link.Read<BPoint>(&(pts[i]));
1909 
1910 			if (fCurrentLayer && fCurrentLayer->fLayerData)
1911 			{
1912 				for (i=0; i<4; i++)
1913 					pts[i]=fCurrentLayer->ConvertToTop(pts[i]);
1914 
1915 				driver->FillBezier(pts, fCurrentLayer->fLayerData);
1916 			}
1917 			delete [] pts;
1918 			break;
1919 		}
1920 		case AS_STROKE_ELLIPSE:
1921 		{
1922 			DTRACE(("ServerWindow %s: Message AS_STROKE_ELLIPSE\n", Title()));
1923 
1924 			BRect rect;
1925 			link.Read<BRect>(&rect);
1926 			if (fCurrentLayer && fCurrentLayer->fLayerData)
1927 				driver->StrokeEllipse(fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData);
1928 			break;
1929 		}
1930 		case AS_FILL_ELLIPSE:
1931 		{
1932 			DTRACE(("ServerWindow %s: Message AS_FILL_ELLIPSE\n", Title()));
1933 
1934 			BRect rect;
1935 			link.Read<BRect>(&rect);
1936 			if (fCurrentLayer && fCurrentLayer->fLayerData)
1937 				driver->FillEllipse(fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData);
1938 			break;
1939 		}
1940 		case AS_STROKE_ROUNDRECT:
1941 		{
1942 			DTRACE(("ServerWindow %s: Message AS_STROKE_ROUNDRECT\n", Title()));
1943 
1944 			BRect rect;
1945 			float xrad,yrad;
1946 			link.Read<BRect>(&rect);
1947 			link.Read<float>(&xrad);
1948 			link.Read<float>(&yrad);
1949 
1950 			if (fCurrentLayer && fCurrentLayer->fLayerData)
1951 				driver->StrokeRoundRect(fCurrentLayer->ConvertToTop(rect),xrad,yrad, fCurrentLayer->fLayerData);
1952 			break;
1953 		}
1954 		case AS_FILL_ROUNDRECT:
1955 		{
1956 			DTRACE(("ServerWindow %s: Message AS_FILL_ROUNDRECT\n", Title()));
1957 
1958 			BRect rect;
1959 			float xrad,yrad;
1960 			link.Read<BRect>(&rect);
1961 			link.Read<float>(&xrad);
1962 			link.Read<float>(&yrad);
1963 
1964 			if (fCurrentLayer && fCurrentLayer->fLayerData)
1965 				driver->FillRoundRect(fCurrentLayer->ConvertToTop(rect),xrad,yrad, fCurrentLayer->fLayerData);
1966 			break;
1967 		}
1968 		case AS_STROKE_TRIANGLE:
1969 		{
1970 			DTRACE(("ServerWindow %s: Message AS_STROKE_TRIANGLE\n", Title()));
1971 
1972 			BPoint pts[3];
1973 			BRect rect;
1974 
1975 			for (int i = 0; i < 3; i++)
1976 				link.Read<BPoint>(&(pts[i]));
1977 
1978 			link.Read<BRect>(&rect);
1979 
1980 			if (fCurrentLayer && fCurrentLayer->fLayerData) {
1981 				for (int i = 0;i < 3; i++)
1982 					pts[i] = fCurrentLayer->ConvertToTop(pts[i]);
1983 
1984 				driver->StrokeTriangle(pts, fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData);
1985 			}
1986 			break;
1987 		}
1988 		case AS_FILL_TRIANGLE:
1989 		{
1990 			DTRACE(("ServerWindow %s: Message AS_FILL_TRIANGLE\n", Title()));
1991 
1992 			BPoint pts[3];
1993 			BRect rect;
1994 
1995 			for (int i = 0; i < 3; i++)
1996 				link.Read<BPoint>(&(pts[i]));
1997 
1998 			link.Read<BRect>(&rect);
1999 
2000 			if (fCurrentLayer && fCurrentLayer->fLayerData) {
2001 				for (int i = 0; i < 3; i++)
2002 					pts[i] = fCurrentLayer->ConvertToTop(pts[i]);
2003 
2004 				driver->FillTriangle(pts, fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData);
2005 			}
2006 			break;
2007 		}
2008 // TODO: get rid of all this code duplication!!
2009 		case AS_STROKE_POLYGON:
2010 		{
2011 			DTRACE(("ServerWindow %s: Message AS_STROKE_POLYGON\n", Title()));
2012 
2013 			BRect polyframe;
2014 			bool isclosed;
2015 			int32 pointcount;
2016 			BPoint *pointlist;
2017 
2018 			link.Read<BRect>(&polyframe);
2019 			link.Read<bool>(&isclosed);
2020 			link.Read<int32>(&pointcount);
2021 
2022 			pointlist = new BPoint[pointcount];
2023 
2024 			link.Read(pointlist, sizeof(BPoint)*pointcount);
2025 
2026 			for (int32 i = 0; i < pointcount; i++)
2027 				pointlist[i] = fCurrentLayer->ConvertToTop(pointlist[i]);
2028 
2029 			driver->StrokePolygon(pointlist,pointcount,polyframe,
2030 					fCurrentLayer->fLayerData,isclosed);
2031 
2032 			delete [] pointlist;
2033 			break;
2034 		}
2035 		case AS_FILL_POLYGON:
2036 		{
2037 			DTRACE(("ServerWindow %s: Message AS_FILL_POLYGON\n", Title()));
2038 
2039 			BRect polyframe;
2040 			int32 pointcount;
2041 			BPoint *pointlist;
2042 
2043 			link.Read<BRect>(&polyframe);
2044 			link.Read<int32>(&pointcount);
2045 
2046 			pointlist = new BPoint[pointcount];
2047 
2048 			link.Read(pointlist, sizeof(BPoint) * pointcount);
2049 
2050 			for (int32 i = 0; i < pointcount; i++)
2051 				pointlist[i] = fCurrentLayer->ConvertToTop(pointlist[i]);
2052 
2053 			driver->FillPolygon(pointlist,pointcount,polyframe, fCurrentLayer->fLayerData);
2054 
2055 			delete [] pointlist;
2056 			break;
2057 		}
2058 		case AS_STROKE_SHAPE:
2059 		{
2060 			DTRACE(("ServerWindow %s: Message AS_STROKE_SHAPE\n", Title()));
2061 
2062 			BRect shaperect;
2063 			int32 opcount;
2064 			int32 ptcount;
2065 			int32 *oplist;
2066 			BPoint *ptlist;
2067 
2068 			link.Read<BRect>(&shaperect);
2069 			link.Read<int32>(&opcount);
2070 			link.Read<int32>(&ptcount);
2071 
2072 			oplist = new int32[opcount];
2073 			ptlist = new BPoint[ptcount];
2074 
2075 			link.Read(oplist, sizeof(int32) * opcount);
2076 			link.Read(ptlist, sizeof(BPoint) * ptcount);
2077 
2078 			for (int32 i = 0; i < ptcount; i++)
2079 				ptlist[i] = fCurrentLayer->ConvertToTop(ptlist[i]);
2080 
2081 			driver->StrokeShape(shaperect, opcount, oplist, ptcount, ptlist, fCurrentLayer->fLayerData);
2082 			delete[] oplist;
2083 			delete[] ptlist;
2084 			break;
2085 		}
2086 		case AS_FILL_SHAPE:
2087 		{
2088 			DTRACE(("ServerWindow %s: Message AS_FILL_SHAPE\n", Title()));
2089 
2090 			BRect shaperect;
2091 			int32 opcount;
2092 			int32 ptcount;
2093 			int32 *oplist;
2094 			BPoint *ptlist;
2095 
2096 			link.Read<BRect>(&shaperect);
2097 			link.Read<int32>(&opcount);
2098 			link.Read<int32>(&ptcount);
2099 
2100 			oplist = new int32[opcount];
2101 			ptlist = new BPoint[ptcount];
2102 
2103 			link.Read(oplist, sizeof(int32) * opcount);
2104 			link.Read(ptlist, sizeof(BPoint) * ptcount);
2105 
2106 			for (int32 i = 0; i < ptcount; i++)
2107 				ptlist[i] = fCurrentLayer->ConvertToTop(ptlist[i]);
2108 
2109 			driver->FillShape(shaperect, opcount, oplist, ptcount, ptlist, fCurrentLayer->fLayerData);
2110 
2111 			delete[] oplist;
2112 			delete[] ptlist;
2113 			break;
2114 		}
2115 		case AS_FILL_REGION:
2116 		{
2117 			DTRACE(("ServerWindow %s: Message AS_FILL_REGION\n", Title()));
2118 
2119 			int32 count;
2120 			link.Read<int32>(&count);
2121 
2122 			BRect *rects = new BRect[count];
2123 			if (link.Read(rects, sizeof(BRect) * count) != B_OK) {
2124 				delete[] rects;
2125 				break;
2126 			}
2127 
2128 			// Between the client-side conversion to BRects from clipping_rects to the overhead
2129 			// in repeatedly calling FillRect(), this is definitely in need of optimization. At
2130 			// least it works for now. :)
2131 			BRegion region;
2132 			for (int32 i = 0; i < count; i++) {
2133 				region.Include(fCurrentLayer->ConvertToTop(rects[i]));
2134 			}
2135 			driver->FillRegion(region, fCurrentLayer->fLayerData);
2136 
2137 			delete[] rects;
2138 
2139 			// TODO: create support for clipping_rect usage for faster BRegion display.
2140 			// Tweaks to DisplayDriver are necessary along with conversion routines in Layer
2141 			break;
2142 		}
2143 		case AS_STROKE_LINEARRAY:
2144 		{
2145 			DTRACE(("ServerWindow %s: Message AS_STROKE_LINEARRAY\n", Title()));
2146 
2147 			// Attached Data:
2148 			// 1) int32 Number of lines in the array
2149 			// 2) array of struct _array_data_ objects, as defined in ViewAux.h
2150 
2151 			int32 linecount;
2152 
2153 			link.Read<int32>(&linecount);
2154 			if (linecount > 0) {
2155 				LineArrayData linedata[linecount], *index;
2156 
2157 				for (int32 i = 0; i < linecount; i++) {
2158 					index = &linedata[i];
2159 
2160 					link.Read<float>(&(index->pt1.x));
2161 					link.Read<float>(&(index->pt1.y));
2162 					link.Read<float>(&(index->pt2.x));
2163 					link.Read<float>(&(index->pt2.y));
2164 					link.Read<rgb_color>(&(index->color));
2165 
2166 					index->pt1 = fCurrentLayer->ConvertToTop(index->pt1);
2167 					index->pt2 = fCurrentLayer->ConvertToTop(index->pt2);
2168 				}
2169 				driver->StrokeLineArray(linecount,linedata,fCurrentLayer->fLayerData);
2170 			}
2171 			break;
2172 		}
2173 		case AS_DRAW_STRING:
2174 		{
2175 			DTRACE(("ServerWindow %s: Message AS_DRAW_STRING\n", Title()));
2176 			char *string;
2177 			int32 length;
2178 			BPoint location;
2179 			escapement_delta delta;
2180 
2181 			link.Read<int32>(&length);
2182 			link.Read<BPoint>(&location);
2183 			link.Read<escapement_delta>(&delta);
2184 			link.ReadString(&string);
2185 
2186 			if (fCurrentLayer && fCurrentLayer->fLayerData)
2187 				driver->DrawString(string, length,
2188 								   fCurrentLayer->ConvertToTop(location),
2189 								   fCurrentLayer->fLayerData, &delta);
2190 
2191 			free(string);
2192 			break;
2193 		}
2194 		case AS_LAYER_BEGIN_PICTURE:
2195 			CRITICAL("AS_LAYER_BEGIN_PICTURE not implemented\n");
2196 			break;
2197 		case AS_LAYER_APPEND_TO_PICTURE:
2198 			CRITICAL("AS_LAYER_APPEND_TO_PICTURE not implemented\n");
2199 			break;
2200 		case AS_LAYER_END_PICTURE:
2201 			CRITICAL("AS_LAYER_END_PICTURE not implemented\n");
2202 			break;
2203 
2204 		default:
2205 			printf("ServerWindow %s received unexpected code - message offset %ld\n",
2206 				Title(), code - SERVER_TRUE);
2207 
2208 			if (link.NeedsReply()) {
2209 				// the client is now blocking and waiting for a reply!
2210 				fLink.StartMessage(SERVER_FALSE);
2211 				fLink.Flush();
2212 			}
2213 			break;
2214 	}
2215 
2216 	driver->ConstrainClippingRegion(NULL);
2217 }
2218 
2219 
2220 /*!
2221 	\brief Message-dispatching loop for the ServerWindow
2222 
2223 	Watches the ServerWindow's message port and dispatches as necessary
2224 */
2225 void
2226 ServerWindow::_MessageLooper()
2227 {
2228 	BPrivate::LinkReceiver& receiver = fLink.Receiver();
2229 	bool quitLoop = false;
2230 
2231 	while (!quitLoop) {
2232 		//STRACE(("info: ServerWindow::MonitorWin listening on port %ld.\n",
2233 		//	fMessagePort));
2234 
2235 		int32 code;
2236 		status_t status = receiver.GetNextMessage(code);
2237 		if (status < B_OK) {
2238 			// that shouldn't happen, it's our port
2239 			printf("Someone deleted our message port!\n");
2240 
2241 			// try to let our client die happily
2242 			NotifyQuitRequested();
2243 			break;
2244 		}
2245 
2246 		Lock();
2247 
2248 		switch (code) {
2249 			case AS_DELETE_WINDOW:
2250 			case kMsgQuitLooper:
2251 				// this means the client has been killed
2252 				STRACE(("ServerWindow %s received 'AS_DELETE_WINDOW' message code\n",
2253 					Title()));
2254 
2255 				quitLoop = true;
2256 
2257 				// ToDo: what's this?
2258 				//RootLayer *rootLayer = fWinBorder->GetRootLayer();
2259 
2260 				// we are preparing to delete a ServerWindow, RootLayer should be aware
2261 				// of that and stop for a moment.
2262 				// also we must wait a bit for the associated WinBorder to become hidden
2263 				//while(1) {
2264 				//	myRootLayer->Lock();
2265 				//	if (IsHidden())
2266 				//		break;
2267 				//	else
2268 				//		rootLayer->Unlock();
2269 				//}
2270 
2271 				// ServerWindow's destructor takes care of pulling this object off the desktop.
2272 				if (!fWinBorder->IsHidden())
2273 					CRITICAL("ServerWindow: a window must be hidden before it's deleted\n");
2274 				break;
2275 
2276 			case B_QUIT_REQUESTED:
2277 				STRACE(("ServerWindow %s received quit request\n", Title()));
2278 				NotifyQuitRequested();
2279 				break;
2280 
2281 			default:
2282 				_DispatchMessage(code, receiver);
2283 				break;
2284 		}
2285 
2286 		Unlock();
2287 	}
2288 
2289 	// we were asked to quit the message loop - either on request or because of an error
2290 	Quit();
2291 		// does not return
2292 }
2293 
2294 /*
2295 void
2296 ServerWindow::_CopyBits(RootLayer* rootLayer, Layer* layer,
2297 						BRect& src, BRect& dst,
2298 						int32 xOffset, int32 yOffset) const
2299 {
2300 	// NOTE: The correct behaviour is this:
2301 	// * The region that is copied is the
2302 	//   src rectangle, no matter if it fits
2303 	//   into the dst rectangle. It is copied
2304 	//   by the offset dst.LeftTop() - src.LeftTop()
2305 	// * The dst rectangle is used for invalidation:
2306 	//   Any area in the dst rectangle that could
2307 	//   not be copied from src (because either the
2308 	//   src rectangle was not big enough, or because there
2309 	//   were parts cut off by the current layer clipping),
2310 	//   are triggering BView::Draw() to be called
2311 	//   and for these parts only.
2312 
2313 #ifndef NEW_CLIPPING
2314 
2315 	// the region that is going to be copied
2316 	BRegion copyRegion(src);
2317 	// apply the current clipping of the layer
2318 
2319 	copyRegion.IntersectWith(&layer->fVisible);
2320 
2321 	// offset the region to the destination
2322 	// and apply the current clipping there as well
2323 	copyRegion.OffsetBy(xOffset, yOffset);
2324 	copyRegion.IntersectWith(&layer->fVisible);
2325 
2326 	// the region at the destination that needs invalidation
2327 	BRegion invalidRegion(dst);
2328 	// exclude the region drawn by the copy operation
2329 	invalidRegion.Exclude(&copyRegion);
2330 	// apply the current clipping as well
2331 	invalidRegion.IntersectWith(&layer->fVisible);
2332 
2333 	// move the region back for the actual operation
2334 	copyRegion.OffsetBy(-xOffset, -yOffset);
2335 
2336 	layer->GetDisplayDriver()->CopyRegion(&copyRegion, xOffset, yOffset);
2337 
2338 	// trigger the redraw
2339 	if (rootLayer) {
2340 		// the following code solves a "concurrency" problem:
2341 		// since the scrolling might happen more often
2342 		// than redrawing, we need to keep track of the region
2343 		// pending for redraw that might fall into the area
2344 		// that is scrolled.
2345 		BRegion scrolledInvalid(fWinBorder->CulmulatedUpdateRegion());
2346 		scrolledInvalid.IntersectWith(&layer->fVisible);
2347 		if (scrolledInvalid.Frame().IsValid()) {
2348 //printf("the layer has pending updates that will be scrolled\n");
2349 			scrolledInvalid.OffsetBy(xOffset, yOffset);
2350 			invalidRegion.Include(&scrolledInvalid);
2351 		}
2352 
2353 		rootLayer->GoRedraw(fWinBorder, invalidRegion);
2354 	}
2355 
2356 #endif
2357 }*/
2358 
2359 
2360 status_t
2361 ServerWindow::SendMessageToClient(const BMessage* msg, int32 target, bool usePreferred) const
2362 {
2363 	ssize_t size = msg->FlattenedSize();
2364 	char* buffer = new char[size];
2365 	status_t ret;
2366 
2367 	if ((ret = msg->Flatten(buffer, size)) == B_OK) {
2368 		ret = BMessage::Private::SendFlattenedMessage(buffer, size,
2369 					fClientLooperPort, target, usePreferred, 100000);
2370 		if (ret < B_OK)
2371 			fprintf(stderr, "ServerWindow::SendMessageToClient(): %s\n", strerror(ret));
2372 	} else
2373 		printf("PANIC: ServerWindow %s: can't flatten message in 'SendMessageToClient()'\n", fTitle);
2374 
2375 	delete[] buffer;
2376 
2377 	return ret;
2378 }
2379 
2380 // MakeWinBorder
2381 WinBorder*
2382 ServerWindow::MakeWinBorder(BRect frame, const char* name,
2383 							uint32 look, uint32 feel, uint32 flags,
2384 							uint32 workspace)
2385 {
2386 	// The non-offscreen ServerWindow uses the DisplayDriver instance from the desktop.
2387 	return new(nothrow) WinBorder(frame, name, look, feel, flags,
2388 								  workspace, this, fDesktop->GetDisplayDriver());
2389 }
2390 
2391 
2392 status_t
2393 ServerWindow::_EnableDirectWindowMode()
2394 {
2395 	if (fDirectWindowData != NULL)
2396 		return B_ERROR; // already in direct window mode
2397 
2398 	fDirectWindowData = new (nothrow) dw_data;
2399 	if (fDirectWindowData == NULL)
2400 		return B_NO_MEMORY;
2401 
2402 	if (!fDirectWindowData->IsValid()) {
2403 		delete fDirectWindowData;
2404 		fDirectWindowData = NULL;
2405 		return B_ERROR;
2406 	}
2407 
2408 	return B_OK;
2409 }
2410 
2411 
2412 void
2413 ServerWindow::_HandleDirectConnection(direct_buffer_state state)
2414 {
2415 	if (fDirectWindowData == NULL)
2416 		return;
2417 
2418 	fDirectWindowData->direct_info->buffer_state = state;
2419 
2420 	if ((state & B_DIRECT_MODE_MASK) != B_DIRECT_STOP) {
2421 		// TODO: Locking ?
2422 		RenderingBuffer *buffer = fDesktop->GetHWInterface()->FrontBuffer();
2423 		fDirectWindowData->direct_info->bits = buffer->Bits();
2424 		fDirectWindowData->direct_info->pci_bits = NULL; // TODO
2425 		fDirectWindowData->direct_info->bytes_per_row = buffer->BytesPerRow();
2426 		fDirectWindowData->direct_info->bits_per_pixel = buffer->BytesPerRow() / buffer->Width() * 8;
2427 		fDirectWindowData->direct_info->pixel_format = buffer->ColorSpace();
2428 		fDirectWindowData->direct_info->layout = B_BUFFER_NONINTERLEAVED;
2429 		fDirectWindowData->direct_info->orientation = B_BUFFER_TOP_TO_BOTTOM; // TODO
2430 
2431 		WinBorder *border = const_cast<WinBorder *>(GetWinBorder());
2432 		fDirectWindowData->direct_info->window_bounds = to_clipping_rect(border->Frame());
2433 
2434 		// TODO: Review this
2435 		const int32 kMaxClipRectsCount = (B_PAGE_SIZE - sizeof(direct_buffer_info)) / sizeof(clipping_rect);
2436 
2437 		// TODO: Is this the correct region to take into account ?
2438 		BRegion clipRegion = const_cast<BRegion &>(border->VisibleRegion());
2439 		border->ConvertToTop(&clipRegion);
2440 		fDirectWindowData->direct_info->clip_list_count = min_c(clipRegion.CountRects(), kMaxClipRectsCount);
2441 		fDirectWindowData->direct_info->clip_bounds = clipRegion.FrameInt();
2442 
2443 		for (uint32 i = 0; i < fDirectWindowData->direct_info->clip_list_count; i++)
2444 			fDirectWindowData->direct_info->clip_list[i] = clipRegion.RectAtInt(i);
2445 	}
2446 
2447 	// Releasing this sem causes the client to call BDirectWindow::DirectConnected()
2448 	release_sem(fDirectWindowData->direct_sem);
2449 
2450 	// TODO: Waiting 3 seconds in this thread could cause weird things: test
2451 	status_t status = acquire_sem_etc(fDirectWindowData->direct_sem_ack, 1, B_TIMEOUT, 3000000);
2452 	if (status == B_TIMED_OUT) {
2453 		// The client application didn't release the semaphore
2454 		// within the given timeout. Deleting this member should make it crash.
2455 		// TODO: Actually, it will not. At least, not always. Find a better way to
2456 		// crash the client application.
2457 		delete fDirectWindowData;
2458 		fDirectWindowData = NULL;
2459 	}
2460 }
2461 
2462 
2463 status_t
2464 ServerWindow::PictureToRegion(ServerPicture *picture, BRegion &region,
2465 							bool inverse, BPoint where)
2466 {
2467 	fprintf(stderr, "ServerWindow::PictureToRegion() not implemented\n");
2468 	region.MakeEmpty();
2469 	return B_ERROR;
2470 }
2471