* the new input event dispatcher is now actually used, although it doesn't
distribute any messages to the clients yet. * removed the working thread from RootLayer - for now, its event handlers are still called using input filters in the new event dispatcher, though (to get things started). * ServerApp is now using a BMessenger to identify its client, and no longer stores the port/token separately. * the input_server handshake is a bit simpler now, as it can now just reply to the app_server message, removed unused code from ServerProtocol.h * calmed down the MultiLocker (it always printed thread statistics on startup, because it's compiled in debug mode). * removed the cursor thread stuff from AppServer.cpp * the new event dispatcher now uses a cursor thread when supported (only in native mode, not in the test environment), although it improves cursor movement under Qemu, the effect is not as good as expected - this might need some more investigations (might just be a thread priority problem). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15012 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -18,7 +18,9 @@
|
||||
// input messages from the Input Server. The other is the "main" port for
|
||||
// the server and is utilized mostly by BApplication objects.
|
||||
#define SERVER_PORT_NAME "OBappserver"
|
||||
#define SERVER_INPUT_PORT "OBinputport"
|
||||
#if TEST_MODE
|
||||
# define SERVER_INPUT_PORT "OBinputport"
|
||||
#endif
|
||||
|
||||
enum {
|
||||
// Used for quick replies from the app_server
|
||||
@@ -26,7 +28,6 @@ enum {
|
||||
SERVER_FALSE = B_ERROR,
|
||||
|
||||
AS_REGISTER_INPUT_SERVER = 1,
|
||||
AS_ACQUIRED_INPUT_STREAM,
|
||||
AS_GET_DESKTOP,
|
||||
|
||||
// Desktop definitions
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "Desktop.h"
|
||||
#include "FontManager.h"
|
||||
#include "HWInterface.h"
|
||||
#include "InputManager.h"
|
||||
#include "Layer.h"
|
||||
#include "RGBColor.h"
|
||||
#include "RegistrarDefs.h"
|
||||
@@ -47,16 +48,8 @@
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
//#define DEBUG_KEYHANDLING
|
||||
|
||||
//#define DEBUG_SERVER
|
||||
|
||||
#ifdef DEBUG_KEYHANDLING
|
||||
# include <stdio.h>
|
||||
# define KBTRACE(x) printf x
|
||||
#else
|
||||
# define KBTRACE(x) ;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_SERVER
|
||||
# include <stdio.h>
|
||||
# define STRACE(x) printf x
|
||||
@@ -94,6 +87,8 @@ AppServer::AppServer()
|
||||
|
||||
sAppServer = this;
|
||||
|
||||
gInputManager = new InputManager();
|
||||
|
||||
// Create the font server and scan the proper directories.
|
||||
gFontManager = new FontManager;
|
||||
if (gFontManager->InitCheck() != B_OK)
|
||||
@@ -206,48 +201,6 @@ AppServer::_LaunchInputServer()
|
||||
// if at any time, one of these ports is error prone, it might mean input_server is gone
|
||||
// then relaunch input_server
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Starts the Cursor Thread
|
||||
*/
|
||||
void
|
||||
AppServer::_LaunchCursorThread()
|
||||
{
|
||||
// Spawn our cursor thread
|
||||
fCursorThreadID = spawn_thread(_CursorThread, "CursorThreadOfTheDeath",
|
||||
B_REAL_TIME_DISPLAY_PRIORITY - 1, this);
|
||||
if (fCursorThreadID >= 0)
|
||||
resume_thread(fCursorThreadID);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief The Cursor Thread task
|
||||
*/
|
||||
int32
|
||||
AppServer::_CursorThread(void* data)
|
||||
{
|
||||
AppServer *server = (AppServer *)data;
|
||||
|
||||
server->_LaunchInputServer();
|
||||
|
||||
do {
|
||||
while (acquire_sem(server->fCursorSem) == B_OK) {
|
||||
BPoint p;
|
||||
p.y = *server->fCursorAddr & 0x7fff;
|
||||
p.x = *server->fCursorAddr >> 15 & 0x7fff;
|
||||
|
||||
//sDesktop->GetHWInterface()->MoveCursorTo(p.x, p.y);
|
||||
STRACE(("CursorThread : %f, %f\n", p.x, p.y));
|
||||
}
|
||||
|
||||
snooze(100000);
|
||||
} while (!server->IsQuitting());
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
+69
-40
@@ -11,47 +11,40 @@
|
||||
/** Class used to encapsulate desktop management */
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "Desktop.h"
|
||||
|
||||
#include <Message.h>
|
||||
#include <Region.h>
|
||||
#include "AppServer.h"
|
||||
#include "DesktopSettingsPrivate.h"
|
||||
#include "DrawingEngine.h"
|
||||
#include "HWInterface.h"
|
||||
#include "InputManager.h"
|
||||
#include "Layer.h"
|
||||
#include "RootLayer.h"
|
||||
#include "ServerApp.h"
|
||||
#include "ServerConfig.h"
|
||||
#include "ServerScreen.h"
|
||||
#include "ServerWindow.h"
|
||||
#include "WinBorder.h"
|
||||
#include "Workspace.h"
|
||||
|
||||
#include <WindowInfo.h>
|
||||
#include <ServerProtocol.h>
|
||||
|
||||
#include "AppServer.h"
|
||||
#include "DrawingEngine.h"
|
||||
#include "Layer.h"
|
||||
#include "RootLayer.h"
|
||||
#include "ServerConfig.h"
|
||||
#include "ServerScreen.h"
|
||||
#include "ServerApp.h"
|
||||
#include "ServerWindow.h"
|
||||
#include "WinBorder.h"
|
||||
#include "Workspace.h"
|
||||
#include "DesktopSettingsPrivate.h"
|
||||
#include <Message.h>
|
||||
#include <MessageFilter.h>
|
||||
#include <Region.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __HAIKU__
|
||||
# define USE_ACCELERANT 1
|
||||
#else
|
||||
# define USE_ACCELERANT 0
|
||||
#if TEST_MODE
|
||||
# include "EventStream.h"
|
||||
#endif
|
||||
|
||||
#if USE_ACCELERANT
|
||||
# include "AccelerantHWInterface.h"
|
||||
#else
|
||||
# include "ViewHWInterface.h"
|
||||
#endif
|
||||
|
||||
#include "Desktop.h"
|
||||
|
||||
//#define DEBUG_DESKTOP
|
||||
|
||||
#ifdef DEBUG_DESKTOP
|
||||
# define STRACE(a) printf(a)
|
||||
#else
|
||||
# define STRACE(a) /* nothing */
|
||||
# define STRACE(a) ;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -104,14 +97,60 @@ Desktop::Init()
|
||||
fRootLayer = new RootLayer(name, 4, this, GetDrawingEngine());
|
||||
|
||||
#if TEST_MODE
|
||||
RegisterInputServer(find_port(SERVER_INPUT_PORT));
|
||||
// this is where the ViewHWInterface will send its input events to
|
||||
gInputManager->AddStream(new InputServerStream);
|
||||
#endif
|
||||
fEventDispatcher.SetTo(gInputManager->GetStream());
|
||||
fEventDispatcher.SetHWInterface(fVirtualScreen.HWInterface());
|
||||
|
||||
// temporary hack to get things started
|
||||
class MouseFilter : public BMessageFilter {
|
||||
public:
|
||||
MouseFilter(RootLayer* layer)
|
||||
: BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE),
|
||||
fRootLayer(layer)
|
||||
{
|
||||
}
|
||||
|
||||
virtual filter_result
|
||||
Filter(BMessage* message, BHandler** /*_target*/)
|
||||
{
|
||||
fRootLayer->Lock();
|
||||
fRootLayer->MouseEventHandler(message);
|
||||
fRootLayer->Unlock();
|
||||
return B_SKIP_MESSAGE;
|
||||
}
|
||||
|
||||
private:
|
||||
RootLayer* fRootLayer;
|
||||
};
|
||||
class KeyFilter : public BMessageFilter {
|
||||
public:
|
||||
KeyFilter(RootLayer* layer)
|
||||
: BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE),
|
||||
fRootLayer(layer)
|
||||
{
|
||||
}
|
||||
|
||||
virtual filter_result
|
||||
Filter(BMessage* message, BHandler** /*_target*/)
|
||||
{
|
||||
fRootLayer->Lock();
|
||||
fRootLayer->KeyboardEventHandler(message);
|
||||
fRootLayer->Unlock();
|
||||
return B_SKIP_MESSAGE;
|
||||
}
|
||||
|
||||
private:
|
||||
RootLayer* fRootLayer;
|
||||
};
|
||||
fEventDispatcher.SetMouseFilter(new MouseFilter(fRootLayer));
|
||||
fEventDispatcher.SetKeyFilter(new KeyFilter(fRootLayer));
|
||||
|
||||
// take care of setting the default cursor
|
||||
ServerCursor *cursor = fCursorManager.GetCursor(B_CURSOR_DEFAULT);
|
||||
if (cursor)
|
||||
fVirtualScreen.HWInterface()->SetCursor(cursor);
|
||||
fVirtualScreen.HWInterface()->SetCursorVisible(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -341,16 +380,6 @@ Desktop::_ActivateApp(team_id team)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Desktop::RegisterInputServer(port_id port)
|
||||
{
|
||||
fInputPort = port;
|
||||
fRootLayer->RunThread();
|
||||
|
||||
fVirtualScreen.HWInterface()->SetCursorVisible(true);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Send a quick (no attachments) message to all applications
|
||||
|
||||
|
||||
@@ -51,8 +51,7 @@ class Desktop : public MessageLooper, public ScreenOwner {
|
||||
uid_t UserID() const { return fUserID; }
|
||||
virtual port_id MessagePort() const { return fMessagePort; }
|
||||
|
||||
void RegisterInputServer(port_id port);
|
||||
port_id InputServerPort() { return fInputPort; }
|
||||
::EventDispatcher& EventDispatcher() { return fEventDispatcher; }
|
||||
|
||||
void BroadcastToAllApps(int32 code);
|
||||
|
||||
@@ -106,7 +105,7 @@ class Desktop : public MessageLooper, public ScreenOwner {
|
||||
::VirtualScreen fVirtualScreen;
|
||||
DesktopSettings::Private* fSettings;
|
||||
port_id fMessagePort;
|
||||
EventDispatcher fEventDispatcher;
|
||||
::EventDispatcher fEventDispatcher;
|
||||
port_id fInputPort;
|
||||
|
||||
BLocker fAppListLock;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "EventDispatcher.h"
|
||||
#include "EventStream.h"
|
||||
#include "HWInterface.h"
|
||||
#include "InputManager.h"
|
||||
|
||||
#include <Autolock.h>
|
||||
#include <MessageFilter.h>
|
||||
@@ -19,6 +20,14 @@
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
//#define TRACE_EVENTS
|
||||
#ifdef TRACE_EVENTS
|
||||
# define ETRACE(x) printf x
|
||||
#else
|
||||
# define ETRACE(x) ;
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
The differentiation between messenger and token looks odd, but it
|
||||
really has a reason as well:
|
||||
@@ -68,11 +77,16 @@ EventDispatcher::~EventDispatcher()
|
||||
|
||||
|
||||
status_t
|
||||
EventDispatcher::SetTo(EventStream& stream)
|
||||
EventDispatcher::SetTo(EventStream* stream)
|
||||
{
|
||||
ETRACE(("event dispatcher: stream = %p\n", stream));
|
||||
|
||||
_Unset();
|
||||
|
||||
fStream = &stream;
|
||||
if (stream == NULL)
|
||||
return B_OK;
|
||||
|
||||
fStream = stream;
|
||||
return _Run();
|
||||
}
|
||||
|
||||
@@ -93,12 +107,18 @@ EventDispatcher::InitCheck()
|
||||
void
|
||||
EventDispatcher::_Unset()
|
||||
{
|
||||
if (fStream == NULL)
|
||||
return;
|
||||
|
||||
fStream->SendQuit();
|
||||
|
||||
wait_for_thread(fThread, NULL);
|
||||
wait_for_thread(fCursorThread, NULL);
|
||||
|
||||
fThread = fCursorThread = -1;
|
||||
|
||||
gInputManager->PutStream(fStream);
|
||||
fStream = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -111,6 +131,8 @@ EventDispatcher::_Run()
|
||||
return fThread;
|
||||
|
||||
if (fStream->SupportsCursorThread()) {
|
||||
ETRACE(("event stream supports cursor thread!\n"));
|
||||
|
||||
fCursorThread = spawn_thread(_cursor_looper, "cursor loop",
|
||||
B_REAL_TIME_DISPLAY_PRIORITY - 5, this);
|
||||
if (resume_thread(fCursorThread) != B_OK) {
|
||||
@@ -556,6 +578,7 @@ EventDispatcher::_event_looper(void* _dispatcher)
|
||||
{
|
||||
EventDispatcher* dispatcher = (EventDispatcher*)_dispatcher;
|
||||
|
||||
ETRACE(("Start event loop\n"));
|
||||
dispatcher->_EventLoop();
|
||||
return B_OK;
|
||||
}
|
||||
@@ -567,6 +590,7 @@ EventDispatcher::_cursor_looper(void* _dispatcher)
|
||||
{
|
||||
EventDispatcher* dispatcher = (EventDispatcher*)_dispatcher;
|
||||
|
||||
ETRACE(("Start cursor loop\n"));
|
||||
dispatcher->_CursorLoop();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ class EventDispatcher : public BLocker {
|
||||
EventDispatcher();
|
||||
~EventDispatcher();
|
||||
|
||||
status_t SetTo(EventStream& stream);
|
||||
status_t SetTo(EventStream* stream);
|
||||
status_t InitCheck();
|
||||
|
||||
void SetFocus(BMessenger* messenger);
|
||||
@@ -41,8 +41,6 @@ class EventDispatcher : public BLocker {
|
||||
bool HasCursorThread();
|
||||
void SetHWInterface(HWInterface* interface);
|
||||
|
||||
EventStream* Stream();
|
||||
|
||||
private:
|
||||
struct event_target;
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
#include "EventStream.h"
|
||||
|
||||
#include <InputServerTypes.h>
|
||||
#include <ServerProtocol.h>
|
||||
#include <shared_cursor_area.h>
|
||||
|
||||
#include <new>
|
||||
@@ -32,19 +34,53 @@ EventStream::SupportsCursorThread() const
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
EventStream::GetNextCursorPosition(BPoint& where)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
InputServerStream::InputServerStream(port_id port, port_id inputServerPort)
|
||||
InputServerStream::InputServerStream(BMessenger& messenger)
|
||||
:
|
||||
fPort(port),
|
||||
fInputServer(messenger),
|
||||
fPort(-1),
|
||||
fQuitting(false)
|
||||
{
|
||||
BMessage message(IS_ACQUIRE_INPUT);
|
||||
fCursorArea = create_area("shared cursor", (void **)&fCursorBuffer, B_ANY_ADDRESS,
|
||||
B_PAGE_SIZE, B_LAZY_LOCK, B_READ_AREA | B_WRITE_AREA);
|
||||
if (fCursorArea >= B_OK)
|
||||
message.AddInt32("cursor area", fCursorArea);
|
||||
|
||||
BMessage reply;
|
||||
if (messenger.SendMessage(&message, &reply) != B_OK)
|
||||
return;
|
||||
|
||||
if (reply.FindInt32("event port", &fPort) != B_OK)
|
||||
fPort = -1;
|
||||
if (reply.FindInt32("cursor semaphore", &fCursorSemaphore) != B_OK)
|
||||
fCursorSemaphore = -1;
|
||||
}
|
||||
|
||||
|
||||
#if TEST_MODE
|
||||
InputServerStream::InputServerStream()
|
||||
:
|
||||
fQuitting(false),
|
||||
fCursorSemaphore(-1)
|
||||
{
|
||||
fPort = find_port(SERVER_INPUT_PORT);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
InputServerStream::~InputServerStream()
|
||||
{
|
||||
delete_area(fCursorArea);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#define EVENT_STREAM_H
|
||||
|
||||
|
||||
#include <LinkReceiver.h>
|
||||
#include <MessageQueue.h>
|
||||
|
||||
struct shared_cursor;
|
||||
@@ -25,13 +26,17 @@ class EventStream {
|
||||
virtual bool SupportsCursorThread() const;
|
||||
|
||||
virtual bool GetNextEvent(BMessage** _event) = 0;
|
||||
virtual bool GetNextCursorPosition(BPoint& where) = 0;
|
||||
virtual bool GetNextCursorPosition(BPoint& where);
|
||||
};
|
||||
|
||||
|
||||
class InputServerStream {
|
||||
class InputServerStream : public EventStream {
|
||||
public:
|
||||
InputServerStream(port_id port, port_id inputServerPort);
|
||||
InputServerStream(BMessenger& inputServerMessenger);
|
||||
#if TEST_MODE
|
||||
InputServerStream();
|
||||
#endif
|
||||
|
||||
virtual ~InputServerStream();
|
||||
|
||||
virtual bool IsValid();
|
||||
@@ -46,6 +51,7 @@ class InputServerStream {
|
||||
status_t _MessageFromPort(BMessage** _message,
|
||||
bigtime_t timeout = B_INFINITE_TIMEOUT);
|
||||
|
||||
BMessenger fInputServer;
|
||||
BMessageQueue fEvents;
|
||||
port_id fPort;
|
||||
bool fQuitting;
|
||||
|
||||
@@ -37,7 +37,6 @@ bool
|
||||
InputManager::AddStream(EventStream* stream)
|
||||
{
|
||||
BAutolock _(this);
|
||||
printf("got stream: %p\n", stream);
|
||||
return fFreeStreams.AddItem(stream);
|
||||
}
|
||||
|
||||
@@ -57,7 +56,6 @@ InputManager::GetStream()
|
||||
|
||||
EventStream* stream = NULL;
|
||||
do {
|
||||
printf("remove invalid stream: %p\n", stream);
|
||||
delete stream;
|
||||
// this deletes the previous invalid stream
|
||||
|
||||
@@ -68,7 +66,6 @@ printf("remove invalid stream: %p\n", stream);
|
||||
return NULL;
|
||||
|
||||
fUsedStreams.AddItem(stream);
|
||||
printf("return stream: %p\n", stream);
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ Server app_server :
|
||||
FontFamily.cpp
|
||||
FontManager.cpp
|
||||
HashTable.cpp
|
||||
InputManager.cpp
|
||||
Layer.cpp
|
||||
MessageLooper.cpp
|
||||
MultiLocker.cpp
|
||||
|
||||
@@ -53,7 +53,6 @@ MultiLocker::MultiLocker(const char* semaphoreBaseName)
|
||||
system_info sys;
|
||||
get_system_info(&sys);
|
||||
fMaxThreads = sys.max_threads;
|
||||
printf("max_threads: %ld used_threads: %ld\n", sys.max_threads, sys.used_threads);
|
||||
fDebugArray = (int32 *) malloc(fMaxThreads * sizeof(int32));
|
||||
for (int32 i = 0; i < fMaxThreads; i++) {
|
||||
fDebugArray[i] = 0;
|
||||
|
||||
@@ -69,9 +69,6 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount,
|
||||
|
||||
fDirtyForRedraw(),
|
||||
|
||||
fThreadID(B_ERROR),
|
||||
fListenPort(-1),
|
||||
|
||||
fButtons(0),
|
||||
fLastMousePosition(0.0, 0.0),
|
||||
|
||||
@@ -82,8 +79,7 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount,
|
||||
fWMState(),
|
||||
fWinBorderIndex(0),
|
||||
|
||||
fScreenShotIndex(1),
|
||||
fQuiting(false)
|
||||
fScreenShotIndex(1)
|
||||
{
|
||||
//NOTE: be careful about this one.
|
||||
fRootLayer = this;
|
||||
@@ -127,9 +123,6 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount,
|
||||
fDrawState->SetHighColor(RGBColor(255, 255, 255));
|
||||
fDrawState->SetLowColor(fWorkspace[fActiveWksIndex]->BGColor());
|
||||
|
||||
// Spawn our working thread
|
||||
fThreadID = spawn_thread(WorkingThread, name, B_DISPLAY_PRIORITY, this);
|
||||
|
||||
#if ON_SCREEN_DEBUGGING_INFO
|
||||
DebugInfoManager::Default()->SetRootLayer(this);
|
||||
#endif
|
||||
@@ -139,28 +132,18 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount,
|
||||
// RootLayer starts with valid visible regions
|
||||
fFullVisible.Set(Bounds());
|
||||
fVisible.Set(Bounds());
|
||||
|
||||
// first make sure we are actualy visible
|
||||
MarkForRebuild(Bounds());
|
||||
MarkForRedraw(Bounds());
|
||||
|
||||
TriggerRebuild();
|
||||
TriggerRedraw();
|
||||
}
|
||||
|
||||
|
||||
RootLayer::~RootLayer()
|
||||
{
|
||||
fQuiting = true;
|
||||
|
||||
BMessage quitMsg(B_QUIT_REQUESTED);
|
||||
ssize_t length = quitMsg.FlattenedSize();
|
||||
char buffer[length];
|
||||
if (quitMsg.Flatten(buffer,length) < B_OK) {
|
||||
// failed to flatten?
|
||||
kill_thread(fThreadID);
|
||||
}
|
||||
else{
|
||||
write_port(fListenPort, 0, buffer, length);
|
||||
|
||||
status_t dummy;
|
||||
wait_for_thread(fThreadID, &dummy);
|
||||
}
|
||||
|
||||
|
||||
delete fDragMessage;
|
||||
|
||||
for (int32 i = 0; i < fWsCount; i++)
|
||||
@@ -175,103 +158,6 @@ RootLayer::~RootLayer()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RootLayer::RunThread()
|
||||
{
|
||||
if (fThreadID > 0)
|
||||
resume_thread(fThreadID);
|
||||
else
|
||||
CRITICAL("Can not create any more threads.\n");
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Thread function for handling input messages and calculating visible regions.
|
||||
\param data Pointer to the app_server to which the thread belongs
|
||||
\return Throwaway value - always 0
|
||||
*/
|
||||
int32
|
||||
RootLayer::WorkingThread(void *data)
|
||||
{
|
||||
RootLayer *oneRootLayer = (RootLayer*)data;
|
||||
|
||||
oneRootLayer->Lock();
|
||||
oneRootLayer->fListenPort = oneRootLayer->fDesktop->InputServerPort();
|
||||
|
||||
// first make sure we are actualy visible
|
||||
|
||||
oneRootLayer->MarkForRebuild(oneRootLayer->Bounds());
|
||||
oneRootLayer->MarkForRedraw(oneRootLayer->Bounds());
|
||||
|
||||
oneRootLayer->TriggerRebuild();
|
||||
oneRootLayer->TriggerRedraw();
|
||||
|
||||
oneRootLayer->Unlock();
|
||||
|
||||
STRACE(("info: RootLayer(%s)::WorkingThread listening on port %ld.\n", oneRootLayer->Name(), oneRootLayer->fListenPort));
|
||||
while (!oneRootLayer->fQuiting) {
|
||||
BMessage *msg = oneRootLayer->ReadMessageFromPort(B_INFINITE_TIMEOUT);
|
||||
if (msg)
|
||||
oneRootLayer->fQueue.AddMessage(msg);
|
||||
|
||||
int32 msgCount = port_count(oneRootLayer->fListenPort);
|
||||
for (int32 i = 0; i < msgCount; ++i) {
|
||||
msg = oneRootLayer->ReadMessageFromPort(0);
|
||||
if (msg)
|
||||
oneRootLayer->fQueue.AddMessage(msg);
|
||||
}
|
||||
|
||||
// loop as long as there are messages in the queue and the port is empty.
|
||||
bool dispatchNextMessage = true;
|
||||
while(dispatchNextMessage && !oneRootLayer->fQuiting) {
|
||||
BMessage *currentMessage = oneRootLayer->fQueue.NextMessage();
|
||||
|
||||
if (!currentMessage)
|
||||
// no more messages
|
||||
dispatchNextMessage = false;
|
||||
else {
|
||||
oneRootLayer->Lock();
|
||||
|
||||
switch (currentMessage->what) {
|
||||
// We don't need to do anything with these two, so just pass them
|
||||
// onto the active application. Eventually, we will end up passing
|
||||
// them onto the window which is currently under the cursor.
|
||||
case B_MOUSE_DOWN:
|
||||
case B_MOUSE_UP:
|
||||
case B_MOUSE_MOVED:
|
||||
case B_MOUSE_WHEEL_CHANGED:
|
||||
oneRootLayer->MouseEventHandler(currentMessage);
|
||||
break;
|
||||
|
||||
case B_KEY_DOWN:
|
||||
case B_KEY_UP:
|
||||
case B_UNMAPPED_KEY_DOWN:
|
||||
case B_UNMAPPED_KEY_UP:
|
||||
case B_MODIFIERS_CHANGED:
|
||||
oneRootLayer->KeyboardEventHandler(currentMessage);
|
||||
break;
|
||||
|
||||
case B_QUIT_REQUESTED:
|
||||
exit_thread(0);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("RootLayer(%s)::WorkingThread received unexpected code %lx\n", oneRootLayer->Name(), msg->what);
|
||||
break;
|
||||
}
|
||||
|
||||
oneRootLayer->Unlock();
|
||||
|
||||
delete currentMessage;
|
||||
|
||||
// Are any messages on the port?
|
||||
if (port_count(oneRootLayer->fListenPort) > 0)
|
||||
dispatchNextMessage = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
RootLayer::GoChangeWinBorderFeel(WinBorder *winBorder, int32 newFeel)
|
||||
{
|
||||
@@ -1599,72 +1485,6 @@ RootLayer::AddDebugInfo(const char* string)
|
||||
#endif // ON_SCREEN_DEBUGGING_INFO
|
||||
|
||||
|
||||
// taken from BLooper
|
||||
void *
|
||||
RootLayer::ReadRawFromPort(int32 *msgCode, bigtime_t timeout)
|
||||
{
|
||||
int8 *msgBuffer = NULL;
|
||||
ssize_t bufferSize;
|
||||
|
||||
do {
|
||||
bufferSize = port_buffer_size_etc(fListenPort, B_RELATIVE_TIMEOUT, timeout);
|
||||
} while (bufferSize == B_INTERRUPTED);
|
||||
|
||||
if (bufferSize < B_OK)
|
||||
return NULL;
|
||||
|
||||
if (bufferSize > 0)
|
||||
msgBuffer = new int8[bufferSize];
|
||||
|
||||
// we don't want to wait again here, since that can only mean
|
||||
// that someone else has read our message and our bufferSize
|
||||
// is now probably wrong
|
||||
bufferSize = read_port_etc(fListenPort, msgCode, msgBuffer, bufferSize,
|
||||
B_RELATIVE_TIMEOUT, 0);
|
||||
if (bufferSize < B_OK) {
|
||||
delete[] msgBuffer;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return msgBuffer;
|
||||
}
|
||||
|
||||
|
||||
BMessage *
|
||||
RootLayer::ReadMessageFromPort(bigtime_t tout)
|
||||
{
|
||||
int32 msgcode;
|
||||
BMessage* bmsg;
|
||||
|
||||
void* msgbuffer = ReadRawFromPort(&msgcode, tout);
|
||||
if (!msgbuffer)
|
||||
return NULL;
|
||||
|
||||
bmsg = ConvertToMessage(msgbuffer, msgcode);
|
||||
|
||||
delete[] (int8*)msgbuffer;
|
||||
|
||||
return bmsg;
|
||||
}
|
||||
|
||||
|
||||
BMessage*
|
||||
RootLayer::ConvertToMessage(void* raw, int32 code)
|
||||
{
|
||||
BMessage* message = new BMessage(code);
|
||||
|
||||
if (raw != NULL) {
|
||||
if (message->Unflatten((const char*)raw) != B_OK) {
|
||||
printf("Convert To BMessage FAILED. port message code was: %ld - %c%c%c%c\n",
|
||||
code, (int8)(code >> 24), (int8)(code >> 16), (int8)(code >> 8), (int8)code);
|
||||
delete message;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
void
|
||||
RootLayer::MarkForRedraw(const BRegion &dirty)
|
||||
{
|
||||
|
||||
@@ -109,13 +109,10 @@ public:
|
||||
|
||||
void LayerRemoved(Layer* layer);
|
||||
|
||||
static int32 WorkingThread(void *data);
|
||||
|
||||
// Other methods
|
||||
bool Lock() { return fAllRegionsLock.Lock(); }
|
||||
void Unlock() { fAllRegionsLock.Unlock(); }
|
||||
bool IsLocked() { return fAllRegionsLock.IsLocked(); }
|
||||
void RunThread();
|
||||
|
||||
void GoChangeWinBorderFeel(WinBorder *winBorder, int32 newFeel);
|
||||
|
||||
@@ -153,10 +150,6 @@ friend class Desktop;
|
||||
inline HWInterface* GetHWInterface() const
|
||||
{ return fDesktop->GetHWInterface(); }
|
||||
|
||||
void* ReadRawFromPort(int32 *msgCode, bigtime_t timeout);
|
||||
BMessage* ReadMessageFromPort(bigtime_t tout);
|
||||
BMessage* ConvertToMessage(void* raw, int32 code);
|
||||
|
||||
Desktop* fDesktop;
|
||||
BMessage* fDragMessage;
|
||||
Layer* fLastLayerUnderMouse;
|
||||
@@ -171,10 +164,6 @@ friend class Desktop;
|
||||
|
||||
BRegion fDirtyForRedraw;
|
||||
|
||||
thread_id fThreadID;
|
||||
port_id fListenPort;
|
||||
BMessageQueue fQueue;
|
||||
|
||||
int32 fButtons;
|
||||
BPoint fLastMousePosition;
|
||||
|
||||
@@ -190,7 +179,6 @@ friend class Desktop;
|
||||
mutable int32 fWinBorderIndex;
|
||||
|
||||
int32 fScreenShotIndex;
|
||||
bool fQuiting;
|
||||
|
||||
#if ON_SCREEN_DEBUGGING_INFO
|
||||
friend class DebugInfoManager;
|
||||
|
||||
@@ -28,10 +28,9 @@
|
||||
#include <String.h>
|
||||
|
||||
#include <ColorSet.h>
|
||||
#include <ServerProtocol.h>
|
||||
#include <FontPrivate.h>
|
||||
|
||||
#include <InputServerTypes.h>
|
||||
#include <MessengerPrivate.h>
|
||||
#include <ServerProtocol.h>
|
||||
|
||||
#include "AppServer.h"
|
||||
#include "BGet++.h"
|
||||
@@ -41,8 +40,10 @@
|
||||
#include "Desktop.h"
|
||||
#include "DecorManager.h"
|
||||
#include "DrawingEngine.h"
|
||||
#include "EventStream.h"
|
||||
#include "FontManager.h"
|
||||
#include "HWInterface.h"
|
||||
#include "InputManager.h"
|
||||
#include "OffscreenServerWindow.h"
|
||||
#include "RAMLinkMsgReader.h"
|
||||
#include "RootLayer.h"
|
||||
@@ -86,13 +87,11 @@ static const uint32 kMsgAppQuit = 'appQ';
|
||||
MIME fSignature.
|
||||
*/
|
||||
ServerApp::ServerApp(Desktop* desktop, port_id clientReplyPort,
|
||||
port_id clientLooperPort, team_id clientTeam, int32 handlerID,
|
||||
port_id clientLooperPort, team_id clientTeam, int32 clientToken,
|
||||
const char* signature)
|
||||
: MessageLooper("application"),
|
||||
fMessagePort(-1),
|
||||
fClientReplyPort(clientReplyPort),
|
||||
fClientLooperPort(clientLooperPort),
|
||||
fClientToken(handlerID),
|
||||
fDesktop(desktop),
|
||||
fSignature(signature),
|
||||
fClientTeam(clientTeam),
|
||||
@@ -122,6 +121,9 @@ ServerApp::ServerApp(Desktop* desktop, port_id clientReplyPort,
|
||||
return;
|
||||
}
|
||||
|
||||
BMessenger::Private(fClientMessenger).SetTo(fClientTeam,
|
||||
clientLooperPort, clientToken, false);
|
||||
|
||||
ServerCursor *defaultCursor =
|
||||
fDesktop->GetCursorManager().GetCursor(B_CURSOR_DEFAULT);
|
||||
|
||||
@@ -273,17 +275,9 @@ ServerApp::Quit(sem_id shutdownSemaphore)
|
||||
\param msg The message to send
|
||||
*/
|
||||
void
|
||||
ServerApp::SendMessageToClient(const BMessage *msg) const
|
||||
ServerApp::SendMessageToClient(BMessage *msg) const
|
||||
{
|
||||
ssize_t size = msg->FlattenedSize();
|
||||
char *buffer = new char[size];
|
||||
|
||||
if (msg->Flatten(buffer, size) == B_OK)
|
||||
write_port(fClientLooperPort, msg->what, buffer, size);
|
||||
else
|
||||
printf("PANIC: ServerApp: '%s': can't flatten message in 'SendMessageToClient()'\n", Signature());
|
||||
|
||||
delete [] buffer;
|
||||
fClientMessenger.SendMessage(msg);
|
||||
}
|
||||
|
||||
|
||||
@@ -398,32 +392,31 @@ ServerApp::_MessageLooper()
|
||||
\brief Handler function for BApplication API messages
|
||||
\param code Identifier code for the message. Equivalent to BMessage::what
|
||||
\param buffer Any attachments
|
||||
|
||||
|
||||
Note that the buffer's exact format is determined by the particular message.
|
||||
All attachments are placed in the buffer via a PortLink, so it will be a
|
||||
matter of casting and incrementing an index variable to access them.
|
||||
*/
|
||||
void
|
||||
ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
{
|
||||
switch (code) {
|
||||
case AS_REGISTER_INPUT_SERVER:
|
||||
{
|
||||
BMessage message(IS_ACQUIRE_INPUT);
|
||||
SendMessageToClient(&message);
|
||||
break;
|
||||
}
|
||||
case AS_ACQUIRED_INPUT_STREAM:
|
||||
{
|
||||
bool hasKeyboard, hasMouse;
|
||||
link.Read<bool>(&hasKeyboard);
|
||||
link.Read<bool>(&hasMouse);
|
||||
EventStream* stream = new (nothrow) InputServerStream(fClientMessenger);
|
||||
if (stream != NULL
|
||||
&& (!stream->IsValid() || !gInputManager->AddStream(stream))) {
|
||||
delete stream;
|
||||
break;
|
||||
}
|
||||
|
||||
port_id port;
|
||||
link.Read<int32>(&port);
|
||||
sem_id sem;
|
||||
if (link.Read<int32>(&sem) == B_OK)
|
||||
fDesktop->RegisterInputServer(port);
|
||||
// TODO: this should be done using notifications (so that an abandoned
|
||||
// stream will get noticed directly)
|
||||
if (fDesktop->EventDispatcher().InitCheck() != B_OK) {
|
||||
fDesktop->EventDispatcher().SetTo(gInputManager->GetStream());
|
||||
fDesktop->EventDispatcher().SetHWInterface(fDesktop->GetHWInterface());
|
||||
fDesktop->GetHWInterface()->SetCursorVisible(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AS_CREATE_WINDOW:
|
||||
|
||||
@@ -55,7 +55,7 @@ class ServerApp : public MessageLooper {
|
||||
bool IsActive(void) const { return fIsActive; }
|
||||
void Activate(bool value);
|
||||
|
||||
void SendMessageToClient(const BMessage* msg) const;
|
||||
void SendMessageToClient(BMessage* msg) const;
|
||||
|
||||
void SetAppCursor(void);
|
||||
|
||||
@@ -86,6 +86,7 @@ class ServerApp : public MessageLooper {
|
||||
port_id fClientReplyPort;
|
||||
// our BApplication's event port
|
||||
|
||||
BMessenger fClientMessenger;
|
||||
port_id fClientLooperPort;
|
||||
int32 fClientToken;
|
||||
// To send a BMessage to the client (port + token)
|
||||
|
||||
@@ -406,7 +406,7 @@ InputServer::_AcquireInput(BMessage& message, BMessage& reply)
|
||||
{
|
||||
// TODO: it currently just gets everything we have
|
||||
area_id area;
|
||||
if (message.FindInt32("cursor_area", &area) == B_OK) {
|
||||
if (message.FindInt32("cursor area", &area) == B_OK) {
|
||||
// try to clone the area
|
||||
fCursorBuffer = NULL;
|
||||
|
||||
@@ -423,25 +423,15 @@ InputServer::_AcquireInput(BMessage& message, BMessage& reply)
|
||||
return fAppServerPort;
|
||||
}
|
||||
|
||||
// TODO: would be nice if we could just reply to this message...
|
||||
#if 0
|
||||
reply.AddBool("has_keyboard", true);
|
||||
reply.AddBool("has_mouse", true);
|
||||
reply.AddBool("has keyboard", true);
|
||||
reply.AddBool("has mouse", true);
|
||||
reply.AddInt32("event port", fAppServerPort);
|
||||
|
||||
if (fCursorBuffer != NULL) {
|
||||
// cursor shared buffer is supported
|
||||
reply.AddInt32("cursor semaphore", fCursorSem);
|
||||
}
|
||||
#else
|
||||
BPrivate::AppServerLink link;
|
||||
link.StartMessage(AS_ACQUIRED_INPUT_STREAM);
|
||||
link.Attach<bool>(true);
|
||||
link.Attach<bool>(true);
|
||||
link.Attach<int32>(fAppServerPort);
|
||||
link.Attach<int32>(fCursorSem);
|
||||
link.Flush();
|
||||
#endif
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -554,8 +544,8 @@ InputServer::MessageReceived(BMessage* message)
|
||||
|
||||
// app_server communication
|
||||
case IS_ACQUIRE_INPUT:
|
||||
_AcquireInput(*message, reply);
|
||||
return;
|
||||
status = _AcquireInput(*message, reply);
|
||||
break;
|
||||
case IS_RELEASE_INPUT:
|
||||
_ReleaseInput(message);
|
||||
return;
|
||||
|
||||
@@ -89,6 +89,7 @@ Server haiku_app_server :
|
||||
BitmapManager.cpp
|
||||
CursorManager.cpp
|
||||
DecorManager.cpp
|
||||
InputManager.cpp
|
||||
ScreenManager.cpp
|
||||
|
||||
AppServer.cpp
|
||||
|
||||
Reference in New Issue
Block a user