* moved input handling code from Desktop class to RootLayer
* PollerThread was replaced by WorkingThread(RootLayerX) thread which is created every time a RootLayer object is created and destroyed when deleted. * ViewDriver now initializes the "inputServer" port because it is one of the first objects instantiated by the server. * changed the way a RootLayer(ex Poller) quits. The thread is not killed anymore, it is been asked to quit nicely. This prevents (future) deadlocks. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@10780 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -90,12 +90,10 @@ AppServer::AppServer(void) : BApplication (SERVER_SIGNATURE)
|
|||||||
AppServer::AppServer(void)
|
AppServer::AppServer(void)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
fMousePort= create_port(200,SERVER_INPUT_PORT);
|
|
||||||
fMessagePort= create_port(200,SERVER_PORT_NAME);
|
fMessagePort= create_port(200,SERVER_PORT_NAME);
|
||||||
|
|
||||||
fAppList= new BList(0);
|
fAppList= new BList(0);
|
||||||
fQuittingServer= false;
|
fQuittingServer= false;
|
||||||
fExitPoller= false;
|
|
||||||
make_decorator= NULL;
|
make_decorator= NULL;
|
||||||
|
|
||||||
// We need this in order for new_decorator to be able to instantiate new decorators
|
// We need this in order for new_decorator to be able to instantiate new decorators
|
||||||
@@ -153,11 +151,6 @@ AppServer::AppServer(void)
|
|||||||
// This locker is to mediate access to the make_decorator pointer
|
// This locker is to mediate access to the make_decorator pointer
|
||||||
fDecoratorLock= create_sem(1,"app_server_decor_sem");
|
fDecoratorLock= create_sem(1,"app_server_decor_sem");
|
||||||
|
|
||||||
// Spawn our input-polling thread
|
|
||||||
fPollerThreadID= spawn_thread(PollerThread, "Poller", B_NORMAL_PRIORITY, this);
|
|
||||||
if (fPollerThreadID >= 0)
|
|
||||||
resume_thread(fPollerThreadID);
|
|
||||||
|
|
||||||
// Spawn our thread-monitoring thread
|
// Spawn our thread-monitoring thread
|
||||||
fPicassoThreadID= spawn_thread(PicassoThread,"Picasso", B_NORMAL_PRIORITY, this);
|
fPicassoThreadID= spawn_thread(PicassoThread,"Picasso", B_NORMAL_PRIORITY, this);
|
||||||
if (fPicassoThreadID >= 0)
|
if (fPicassoThreadID >= 0)
|
||||||
@@ -195,7 +188,6 @@ AppServer::~AppServer(void)
|
|||||||
// If these threads are still running, kill them - after this, if exit_poller
|
// If these threads are still running, kill them - after this, if exit_poller
|
||||||
// is deleted, who knows what will happen... These things will just return an
|
// is deleted, who knows what will happen... These things will just return an
|
||||||
// error and fail if the threads have already exited.
|
// error and fail if the threads have already exited.
|
||||||
kill_thread(fPollerThreadID);
|
|
||||||
kill_thread(fPicassoThreadID);
|
kill_thread(fPicassoThreadID);
|
||||||
|
|
||||||
delete fontserver;
|
delete fontserver;
|
||||||
@@ -203,61 +195,6 @@ AppServer::~AppServer(void)
|
|||||||
make_decorator=NULL;
|
make_decorator=NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief Thread function for polling and handling input messages
|
|
||||||
\param data Pointer to the app_server to which the thread belongs
|
|
||||||
\return Throwaway value - always 0
|
|
||||||
*/
|
|
||||||
int32 AppServer::PollerThread(void *data)
|
|
||||||
{
|
|
||||||
// This thread handles nothing but input messages for mouse and keyboard
|
|
||||||
AppServer *appserver=(AppServer*)data;
|
|
||||||
BPortLink mousequeue(-1,appserver->fMousePort);
|
|
||||||
int32 code=0;
|
|
||||||
status_t err=B_OK;
|
|
||||||
|
|
||||||
for(;;)
|
|
||||||
{
|
|
||||||
STRACE(("info: AppServer::PollerThread listening on port %ld.\n", appserver->fMousePort));
|
|
||||||
err=mousequeue.GetNextReply(&code);
|
|
||||||
|
|
||||||
if(err<B_OK)
|
|
||||||
{
|
|
||||||
STRACE(("PollerThread:mousequeue.GetNextReply failed\n"));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(code)
|
|
||||||
{
|
|
||||||
// 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_WHEEL_CHANGED:
|
|
||||||
case B_MOUSE_MOVED:
|
|
||||||
desktop->MouseEventHandler(code,mousequeue);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_KEY_DOWN:
|
|
||||||
case B_KEY_UP:
|
|
||||||
case B_UNMAPPED_KEY_DOWN:
|
|
||||||
case B_UNMAPPED_KEY_UP:
|
|
||||||
case B_MODIFIERS_CHANGED:
|
|
||||||
desktop->KeyboardEventHandler(code,mousequeue);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
STRACE(("AppServer::Poller received unexpected code %lx\n",code));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(appserver->fExitPoller)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Thread function for watching for dead apps
|
\brief Thread function for watching for dead apps
|
||||||
\param data Pointer to the app_server to which the thread belongs
|
\param data Pointer to the app_server to which the thread belongs
|
||||||
@@ -270,24 +207,17 @@ int32 AppServer::PicassoThread(void *data)
|
|||||||
ServerApp *app;
|
ServerApp *app;
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
|
i = 0;
|
||||||
acquire_sem(appserver->fAppListLock);
|
acquire_sem(appserver->fAppListLock);
|
||||||
for(i= 0; i < appserver->fAppList->CountItems(); i++)
|
for(;;)
|
||||||
{
|
{
|
||||||
app=(ServerApp*)appserver->fAppList->ItemAt(i);
|
app=(ServerApp*)appserver->fAppList->ItemAt(i++);
|
||||||
if(!app)
|
if(!app)
|
||||||
{
|
break;
|
||||||
printf("PANIC: NULL app in app list\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
app->PingTarget();
|
app->PingTarget();
|
||||||
}
|
}
|
||||||
release_sem(appserver->fAppListLock);
|
release_sem(appserver->fAppListLock);
|
||||||
|
|
||||||
// if poller thread has to exit, so do we - I just was too lazy
|
|
||||||
// to rename the variable name. ;)
|
|
||||||
if(appserver->fExitPoller)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// we do this every other second so as not to suck *too* many CPU cycles
|
// we do this every other second so as not to suck *too* many CPU cycles
|
||||||
snooze(2000000);
|
snooze(2000000);
|
||||||
}
|
}
|
||||||
@@ -746,14 +676,6 @@ void AppServer::DispatchMessage(int32 code, BPortLink &msg)
|
|||||||
|
|
||||||
// When we delete the last ServerApp, we can exit the server
|
// When we delete the last ServerApp, we can exit the server
|
||||||
fQuittingServer=true;
|
fQuittingServer=true;
|
||||||
fExitPoller=true;
|
|
||||||
|
|
||||||
// also wait for picasso thread
|
|
||||||
kill_thread(fPicassoThreadID);
|
|
||||||
|
|
||||||
// poller thread is stuck reading messages from its input port
|
|
||||||
// so, there is no cleaner way to make it quit, other than killing it!
|
|
||||||
kill_thread(fPollerThreadID);
|
|
||||||
|
|
||||||
// we are now clear to exit
|
// we are now clear to exit
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -56,19 +56,16 @@ private:
|
|||||||
// global function pointer
|
// global function pointer
|
||||||
create_decorator *make_decorator;
|
create_decorator *make_decorator;
|
||||||
|
|
||||||
port_id fMessagePort,
|
port_id fMessagePort;
|
||||||
fMousePort;
|
|
||||||
|
|
||||||
image_id fDecoratorID;
|
image_id fDecoratorID;
|
||||||
|
|
||||||
BString fDecoratorName;
|
BString fDecoratorName;
|
||||||
|
|
||||||
bool fQuittingServer,
|
bool fQuittingServer;
|
||||||
fExitPoller;
|
|
||||||
|
|
||||||
BList *fAppList;
|
BList *fAppList;
|
||||||
thread_id fPollerThreadID,
|
thread_id fPicassoThreadID;
|
||||||
fPicassoThreadID;
|
|
||||||
|
|
||||||
sem_id fActiveAppLock,
|
sem_id fActiveAppLock,
|
||||||
fAppListLock,
|
fAppListLock,
|
||||||
|
|||||||
@@ -20,12 +20,11 @@
|
|||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
//
|
//
|
||||||
// File Name: Desktop.cpp
|
// File Name: Desktop.cpp
|
||||||
// Author: Adi Oanca <adioanca@mymail.ro>
|
// Author: Adi Oanca <adioanca@cotty.iren.ro>
|
||||||
// Description: Class used to encapsulate desktop management
|
// Description: Class used to encapsulate desktop management
|
||||||
//
|
//
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <Entry.h>
|
|
||||||
#include <Region.h>
|
#include <Region.h>
|
||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
|
|
||||||
@@ -45,7 +44,6 @@
|
|||||||
#include "Workspace.h"
|
#include "Workspace.h"
|
||||||
|
|
||||||
//#define DEBUG_DESKTOP
|
//#define DEBUG_DESKTOP
|
||||||
#define DEBUG_KEYHANDLING
|
|
||||||
|
|
||||||
#ifdef DEBUG_DESKTOP
|
#ifdef DEBUG_DESKTOP
|
||||||
#define STRACE(a) printf(a)
|
#define STRACE(a) printf(a)
|
||||||
@@ -55,27 +53,23 @@
|
|||||||
|
|
||||||
Desktop::Desktop(void)
|
Desktop::Desktop(void)
|
||||||
{
|
{
|
||||||
fDragMessage = NULL;
|
|
||||||
fActiveRootLayer = NULL;
|
fActiveRootLayer = NULL;
|
||||||
fMouseTarget = NULL;
|
|
||||||
fActiveScreen = NULL;
|
fActiveScreen = NULL;
|
||||||
fScreenShotIndex = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Desktop::~Desktop(void)
|
Desktop::~Desktop(void)
|
||||||
{
|
{
|
||||||
if (fDragMessage)
|
|
||||||
delete fDragMessage;
|
|
||||||
|
|
||||||
void *ptr;
|
void *ptr;
|
||||||
|
|
||||||
|
for(int32 i=0; (ptr=fWinBorderList.ItemAt(i)); i++)
|
||||||
|
delete (WinBorder*)ptr;
|
||||||
|
|
||||||
for(int32 i=0; (ptr=fRootLayerList.ItemAt(i)); i++)
|
for(int32 i=0; (ptr=fRootLayerList.ItemAt(i)); i++)
|
||||||
delete (RootLayer*)ptr;
|
delete (RootLayer*)ptr;
|
||||||
|
|
||||||
for(int32 i=0; (ptr=fScreenList.ItemAt(i)); i++)
|
for(int32 i=0; (ptr=fScreenList.ItemAt(i)); i++)
|
||||||
delete (Screen*)ptr;
|
delete (Screen*)ptr;
|
||||||
|
|
||||||
for(int32 i=0; (ptr=fWinBorderList.ItemAt(i)); i++)
|
|
||||||
delete (WinBorder*)ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Desktop::Init(void)
|
void Desktop::Init(void)
|
||||||
@@ -245,7 +239,7 @@ void Desktop::AddWinBorder(WinBorder* winBorder)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// special case for Tracker background window.
|
// special case for Tracker background window.
|
||||||
if (winBorder->fLevel == B_SYSTEM_LAST)
|
if (winBorder->Level() == B_SYSTEM_LAST)
|
||||||
{
|
{
|
||||||
// it's added in all RottLayers
|
// it's added in all RottLayers
|
||||||
for(int32 i=0; i<fRootLayerList.CountItems(); i++)
|
for(int32 i=0; i<fRootLayerList.CountItems(); i++)
|
||||||
@@ -267,7 +261,7 @@ void Desktop::RemoveWinBorder(WinBorder* winBorder)
|
|||||||
{
|
{
|
||||||
desktop->fGeneralLock.Lock();
|
desktop->fGeneralLock.Lock();
|
||||||
|
|
||||||
if(winBorder->fLevel == B_SYSTEM_LAST)
|
if(winBorder->Level() == B_SYSTEM_LAST)
|
||||||
{
|
{
|
||||||
for(int32 i=0; i<fRootLayerList.CountItems(); i++)
|
for(int32 i=0; i<fRootLayerList.CountItems(); i++)
|
||||||
((RootLayer*)fRootLayerList.ItemAt(i))->RemoveWinBorder(winBorder);
|
((RootLayer*)fRootLayerList.ItemAt(i))->RemoveWinBorder(winBorder);
|
||||||
@@ -287,603 +281,6 @@ bool Desktop::HasWinBorder(WinBorder* winBorder)
|
|||||||
return fWinBorderList.HasItem(winBorder);
|
return fWinBorderList.HasItem(winBorder);
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// Input related methods
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
void Desktop::MouseEventHandler(int32 code, BPortLink& msg)
|
|
||||||
{
|
|
||||||
// TODO: locking mechanism needs SERIOUS rethought
|
|
||||||
switch(code)
|
|
||||||
{
|
|
||||||
case B_MOUSE_DOWN:
|
|
||||||
{
|
|
||||||
// Attached data:
|
|
||||||
// 1) int64 - time of mouse click
|
|
||||||
// 2) float - x coordinate of mouse click
|
|
||||||
// 3) float - y coordinate of mouse click
|
|
||||||
// 4) int32 - modifier keys down
|
|
||||||
// 5) int32 - buttons down
|
|
||||||
// 6) int32 - clicks
|
|
||||||
|
|
||||||
PointerEvent evt;
|
|
||||||
evt.code = B_MOUSE_DOWN;
|
|
||||||
msg.Read<int64>(&evt.when);
|
|
||||||
msg.Read<float>(&evt.where.x);
|
|
||||||
msg.Read<float>(&evt.where.y);
|
|
||||||
msg.Read<int32>(&evt.modifiers);
|
|
||||||
msg.Read<int32>(&evt.buttons);
|
|
||||||
msg.Read<int32>(&evt.clicks);
|
|
||||||
|
|
||||||
// printf("MOUSE DOWN: at (%f, %f)\n", evt.where.x, evt.where.y);
|
|
||||||
|
|
||||||
WinBorder *target=NULL;
|
|
||||||
RootLayer *rl=NULL;
|
|
||||||
Workspace *ws=NULL;
|
|
||||||
rl = ActiveRootLayer();
|
|
||||||
ws = rl->ActiveWorkspace();
|
|
||||||
target = rl->WinBorderAt(evt.where);
|
|
||||||
if (target)
|
|
||||||
{
|
|
||||||
fGeneralLock.Lock();
|
|
||||||
rl->fMainLock.Lock();
|
|
||||||
|
|
||||||
STRACE(("Target: %s\n", target->GetName()));
|
|
||||||
STRACE(("Front: %s\n", ws->FrontLayer()->GetName()));
|
|
||||||
STRACE(("Focus: %s\n", ws->FocusLayer()->GetName()));
|
|
||||||
|
|
||||||
WinBorder *previousFocus=NULL;
|
|
||||||
WinBorder *activeFocus=NULL;
|
|
||||||
BRegion invalidRegion;
|
|
||||||
|
|
||||||
BMessage downmsg(B_MOUSE_DOWN);
|
|
||||||
downmsg.AddInt64("when",evt.when);
|
|
||||||
downmsg.AddPoint("where",evt.where);
|
|
||||||
downmsg.AddInt32("modifiers",evt.modifiers);
|
|
||||||
downmsg.AddInt32("buttons",evt.buttons);
|
|
||||||
downmsg.AddInt32("clicks",evt.clicks);
|
|
||||||
|
|
||||||
if (target!=ws->FrontLayer())
|
|
||||||
{
|
|
||||||
ws->BringToFrontANormalWindow(target);
|
|
||||||
ws->SearchAndSetNewFront(target);
|
|
||||||
previousFocus = ws->FocusLayer();
|
|
||||||
ws->SearchAndSetNewFocus(target);
|
|
||||||
activeFocus = ws->FocusLayer();
|
|
||||||
|
|
||||||
activeFocus->Window()->Lock();
|
|
||||||
|
|
||||||
if (target == activeFocus && target->Window()->Flags() & B_WILL_ACCEPT_FIRST_CLICK)
|
|
||||||
target->MouseDown(evt, true);
|
|
||||||
else
|
|
||||||
target->MouseDown(evt, false);
|
|
||||||
|
|
||||||
// may or may not be empty.
|
|
||||||
|
|
||||||
// TODO: B_MOUSE_DOWN: what if modal of floating windows are in front of us?
|
|
||||||
invalidRegion.Include(&(activeFocus->fFull));
|
|
||||||
invalidRegion.Include(&(activeFocus->fTopLayer->fFull));
|
|
||||||
activeFocus->fParent->RebuildAndForceRedraw(invalidRegion, activeFocus);
|
|
||||||
|
|
||||||
if (previousFocus != activeFocus && previousFocus)
|
|
||||||
{
|
|
||||||
if (previousFocus->fVisible.CountRects() > 0)
|
|
||||||
{
|
|
||||||
invalidRegion.MakeEmpty();
|
|
||||||
invalidRegion.Include(&(previousFocus->fVisible));
|
|
||||||
activeFocus->fParent->Invalidate(invalidRegion);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fMouseTarget = target;
|
|
||||||
|
|
||||||
STRACE(("2Target: %s\n", target->GetName()));
|
|
||||||
STRACE(("2Front: %s\n", ws->FrontLayer()->GetName()));
|
|
||||||
STRACE(("2Focus: %s\n", ws->FocusLayer()->GetName()));
|
|
||||||
|
|
||||||
fMouseTarget->Window()->SendMessageToClient(&downmsg);
|
|
||||||
activeFocus->Window()->Unlock();
|
|
||||||
}
|
|
||||||
else // target == ws->FrontLayer()
|
|
||||||
{
|
|
||||||
// only if target has the focus!
|
|
||||||
if (target == ws->FocusLayer())
|
|
||||||
{
|
|
||||||
target->Window()->Lock();
|
|
||||||
target->MouseDown(evt, true);
|
|
||||||
target->Window()->SendMessageToClient(&downmsg);
|
|
||||||
target->Window()->Unlock();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
previousFocus = ws->FocusLayer();
|
|
||||||
ws->SearchAndSetNewFocus(target);
|
|
||||||
activeFocus = ws->FocusLayer();
|
|
||||||
|
|
||||||
activeFocus->Window()->Lock();
|
|
||||||
|
|
||||||
if (target == activeFocus && target->Window()->Flags() & B_WILL_ACCEPT_FIRST_CLICK)
|
|
||||||
target->MouseDown(evt, true);
|
|
||||||
else
|
|
||||||
target->MouseDown(evt, false);
|
|
||||||
|
|
||||||
// may or may not be empty.
|
|
||||||
|
|
||||||
// TODO: B_MOUSE_DOWN: what if modal of floating windows are in front of us?
|
|
||||||
invalidRegion.Include(&(activeFocus->fFull));
|
|
||||||
invalidRegion.Include(&(activeFocus->fTopLayer->fFull));
|
|
||||||
activeFocus->fParent->RebuildAndForceRedraw(invalidRegion, activeFocus);
|
|
||||||
|
|
||||||
if (previousFocus != activeFocus && previousFocus)
|
|
||||||
{
|
|
||||||
if (previousFocus->fVisible.CountRects() > 0)
|
|
||||||
{
|
|
||||||
invalidRegion.MakeEmpty();
|
|
||||||
invalidRegion.Include(&(previousFocus->fVisible));
|
|
||||||
activeFocus->fParent->Invalidate(invalidRegion);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fMouseTarget = target;
|
|
||||||
fMouseTarget->Window()->SendMessageToClient(&downmsg);
|
|
||||||
|
|
||||||
activeFocus->Window()->Unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rl->fMainLock.Unlock();
|
|
||||||
fGeneralLock.Unlock();
|
|
||||||
}
|
|
||||||
else // target == NULL
|
|
||||||
{
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case B_MOUSE_UP:
|
|
||||||
{
|
|
||||||
// Attached data:
|
|
||||||
// 1) int64 - time of mouse click
|
|
||||||
// 2) float - x coordinate of mouse click
|
|
||||||
// 3) float - y coordinate of mouse click
|
|
||||||
// 4) int32 - modifier keys down
|
|
||||||
|
|
||||||
PointerEvent evt;
|
|
||||||
evt.code = B_MOUSE_UP;
|
|
||||||
msg.Read<int64>(&evt.when);
|
|
||||||
msg.Read<float>(&evt.where.x);
|
|
||||||
msg.Read<float>(&evt.where.y);
|
|
||||||
msg.Read<int32>(&evt.modifiers);
|
|
||||||
|
|
||||||
if (!fMouseTarget)
|
|
||||||
{
|
|
||||||
WinBorder *target = ActiveRootLayer()->WinBorderAt(BPoint(evt.where.x, evt.where.y));
|
|
||||||
if(!target)
|
|
||||||
break;
|
|
||||||
fMouseTarget=target;
|
|
||||||
}
|
|
||||||
|
|
||||||
fMouseTarget->Window()->Lock();
|
|
||||||
fMouseTarget->MouseUp(evt);
|
|
||||||
|
|
||||||
BMessage upmsg(B_MOUSE_UP);
|
|
||||||
upmsg.AddInt64("when",evt.when);
|
|
||||||
upmsg.AddPoint("where",evt.where);
|
|
||||||
upmsg.AddInt32("modifiers",evt.modifiers);
|
|
||||||
|
|
||||||
fMouseTarget->Window()->SendMessageToClient(&upmsg);
|
|
||||||
fMouseTarget->Window()->Unlock();
|
|
||||||
|
|
||||||
STRACE(("MOUSE UP: at (%f, %f)\n", evt.where.x, evt.where.y));
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case B_MOUSE_MOVED:
|
|
||||||
{
|
|
||||||
// Attached data:
|
|
||||||
// 1) int64 - time of mouse click
|
|
||||||
// 2) float - x coordinate of mouse click
|
|
||||||
// 3) float - y coordinate of mouse click
|
|
||||||
// 4) int32 - buttons down
|
|
||||||
|
|
||||||
PointerEvent evt;
|
|
||||||
evt.code = B_MOUSE_MOVED;
|
|
||||||
msg.Read<int64>(&evt.when);
|
|
||||||
msg.Read<float>(&evt.where.x);
|
|
||||||
msg.Read<float>(&evt.where.y);
|
|
||||||
msg.Read<int32>(&evt.buttons);
|
|
||||||
|
|
||||||
fActiveScreen->DDriver()->MoveCursorTo(evt.where.x, evt.where.y);
|
|
||||||
|
|
||||||
if (!fMouseTarget)
|
|
||||||
{
|
|
||||||
WinBorder *target = ActiveRootLayer()->WinBorderAt(BPoint(evt.where.x, evt.where.y));
|
|
||||||
if(!target)
|
|
||||||
break;
|
|
||||||
fMouseTarget=target;
|
|
||||||
}
|
|
||||||
|
|
||||||
fMouseTarget->Window()->Lock();
|
|
||||||
fMouseTarget->MouseMoved(evt);
|
|
||||||
|
|
||||||
BMessage movemsg(B_MOUSE_MOVED);
|
|
||||||
movemsg.AddInt64("when",evt.when);
|
|
||||||
movemsg.AddPoint("where",evt.where);
|
|
||||||
movemsg.AddInt32("buttons",evt.buttons);
|
|
||||||
|
|
||||||
fMouseTarget->Window()->SendMessageToClient(&movemsg);
|
|
||||||
fMouseTarget->Window()->Unlock();
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case B_MOUSE_WHEEL_CHANGED:
|
|
||||||
{
|
|
||||||
// FEATURE: This is a tentative change: mouse wheel messages are always sent to the window
|
|
||||||
// under the cursor. It's pretty stupid to send it to the active window unless a particular
|
|
||||||
// view has locked focus via SetMouseEventMask
|
|
||||||
|
|
||||||
PointerEvent evt;
|
|
||||||
evt.code = B_MOUSE_WHEEL_CHANGED;
|
|
||||||
msg.Read<int64>(&evt.when);
|
|
||||||
msg.Read<float>(&evt.wheel_delta_x);
|
|
||||||
msg.Read<float>(&evt.wheel_delta_y);
|
|
||||||
|
|
||||||
BMessage wheelmsg(B_MOUSE_WHEEL_CHANGED);
|
|
||||||
wheelmsg.AddInt64("when",evt.when);
|
|
||||||
wheelmsg.AddFloat("be:wheel_delta_x",evt.wheel_delta_x);
|
|
||||||
wheelmsg.AddFloat("be:wheel_delta_y",evt.wheel_delta_y);
|
|
||||||
|
|
||||||
if(!fMouseTarget)
|
|
||||||
{
|
|
||||||
fMouseTarget = ActiveRootLayer()->WinBorderAt(GetDisplayDriver()->GetCursorPosition());
|
|
||||||
|
|
||||||
// We do nothing because there ain't a window to receive the message
|
|
||||||
if(!fMouseTarget)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
fMouseTarget->Window()->Lock();
|
|
||||||
fMouseTarget->Window()->SendMessageToClient(&wheelmsg);
|
|
||||||
fMouseTarget->Window()->Unlock();
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
printf("\nDesktop::MouseEventHandler(): WARNING: unknown message\n\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Desktop::KeyboardEventHandler(int32 code, BPortLink& msg)
|
|
||||||
{
|
|
||||||
|
|
||||||
switch(code)
|
|
||||||
{
|
|
||||||
case B_KEY_DOWN:
|
|
||||||
{
|
|
||||||
// Attached Data:
|
|
||||||
// 1) int64 bigtime_t object of when the message was sent
|
|
||||||
// 2) int32 raw key code (scancode)
|
|
||||||
// 3) int32 modifier-independent ASCII code for the character
|
|
||||||
// 4) int32 repeat count
|
|
||||||
// 5) int32 modifiers
|
|
||||||
// 6) int8[3] UTF-8 data generated
|
|
||||||
// 7) int8 number of bytes to follow containing the
|
|
||||||
// generated string
|
|
||||||
// 8) Character string generated by the keystroke
|
|
||||||
// 9) int8[16] state of all keys
|
|
||||||
|
|
||||||
bigtime_t time;
|
|
||||||
int32 scancode, modifiers;
|
|
||||||
int8 utf[3];
|
|
||||||
char *string = NULL;
|
|
||||||
int32 keystate;
|
|
||||||
|
|
||||||
msg.Read<bigtime_t>(&time);
|
|
||||||
msg.Read<int32>(&scancode);
|
|
||||||
msg.Read<int32>(&modifiers);
|
|
||||||
msg.Read(utf, sizeof(utf));
|
|
||||||
msg.ReadString(&string);
|
|
||||||
msg.Read<int32>(&keystate);
|
|
||||||
if (string)
|
|
||||||
free(string);
|
|
||||||
|
|
||||||
if(DISPLAYDRIVER==HWDRIVER)
|
|
||||||
{
|
|
||||||
// Check for workspace change or safe video mode
|
|
||||||
if(scancode>0x01 && scancode<0x0e)
|
|
||||||
{
|
|
||||||
if(scancode==0x0d)
|
|
||||||
{
|
|
||||||
if(modifiers & (B_LEFT_COMMAND_KEY |
|
|
||||||
B_LEFT_CONTROL_KEY | B_LEFT_SHIFT_KEY))
|
|
||||||
{
|
|
||||||
// TODO: Set to Safe Mode in KeyboardEventHandler:B_KEY_DOWN. (DisplayDriver API change)
|
|
||||||
STRACE(("Safe Video Mode invoked - code unimplemented\n"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(modifiers & B_CONTROL_KEY)
|
|
||||||
{
|
|
||||||
STRACE(("Set Workspace %ld\n",scancode-1));
|
|
||||||
|
|
||||||
//TODO: SetWorkspace in KeyboardEventHandler
|
|
||||||
//SetWorkspace(scancode-2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tab key
|
|
||||||
if(scancode==0x26 && (modifiers & B_CONTROL_KEY))
|
|
||||||
{
|
|
||||||
ServerApp *deskbar=app_server->FindApp("application/x-vnd.Be-TSKB");
|
|
||||||
if(deskbar)
|
|
||||||
{
|
|
||||||
printf("Send Twitcher message key to Deskbar - unimplmemented\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// PrintScreen
|
|
||||||
if(scancode==0xe)
|
|
||||||
{
|
|
||||||
if(GetDisplayDriver())
|
|
||||||
{
|
|
||||||
char filename[128];
|
|
||||||
BEntry entry;
|
|
||||||
|
|
||||||
sprintf(filename,"/boot/home/screen%ld.png",fScreenShotIndex);
|
|
||||||
entry.SetTo(filename);
|
|
||||||
|
|
||||||
while(entry.Exists())
|
|
||||||
{
|
|
||||||
fScreenShotIndex++;
|
|
||||||
sprintf(filename,"/boot/home/screen%ld.png",fScreenShotIndex);
|
|
||||||
}
|
|
||||||
fScreenShotIndex++;
|
|
||||||
GetDisplayDriver()->DumpToFile(filename);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// F12
|
|
||||||
if(scancode>0x1 && scancode<0xe)
|
|
||||||
{
|
|
||||||
if(scancode==0xd)
|
|
||||||
{
|
|
||||||
if(modifiers & (B_LEFT_CONTROL_KEY | B_LEFT_SHIFT_KEY | B_LEFT_OPTION_KEY))
|
|
||||||
{
|
|
||||||
// TODO: Set to Safe Mode in KeyboardEventHandler:B_KEY_DOWN. (DisplayDriver API change)
|
|
||||||
STRACE(("Safe Video Mode invoked - code unimplemented\n"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(modifiers & (B_LEFT_SHIFT_KEY | B_LEFT_CONTROL_KEY))
|
|
||||||
{
|
|
||||||
STRACE(("Set Workspace %ld\n",scancode-1));
|
|
||||||
//TODO: SetWorkspace in KeyboardEventHandler
|
|
||||||
//SetWorkspace(scancode-2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Tab
|
|
||||||
if(scancode==0x26 && (modifiers & B_SHIFT_KEY))
|
|
||||||
{
|
|
||||||
STRACE(("Twitcher\n"));
|
|
||||||
ServerApp *deskbar=app_server->FindApp("application/x-vnd.Be-TSKB");
|
|
||||||
if(deskbar)
|
|
||||||
{
|
|
||||||
printf("Send Twitcher message key to Deskbar - unimplmemented\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pause/Break
|
|
||||||
if(scancode==0x7f)
|
|
||||||
{
|
|
||||||
if(GetDisplayDriver())
|
|
||||||
{
|
|
||||||
char filename[128];
|
|
||||||
BEntry entry;
|
|
||||||
|
|
||||||
sprintf(filename,"/boot/home/screen%ld.png",fScreenShotIndex);
|
|
||||||
entry.SetTo(filename);
|
|
||||||
|
|
||||||
while(entry.Exists())
|
|
||||||
{
|
|
||||||
fScreenShotIndex++;
|
|
||||||
sprintf(filename,"/boot/home/screen%ld.png",fScreenShotIndex);
|
|
||||||
}
|
|
||||||
fScreenShotIndex++;
|
|
||||||
|
|
||||||
GetDisplayDriver()->DumpToFile(filename);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We got this far, so apparently it's safe to pass to the active
|
|
||||||
// window.
|
|
||||||
|
|
||||||
// TODO: Pass on key down message to client window with the focus
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case B_KEY_UP:
|
|
||||||
{
|
|
||||||
// Attached Data:
|
|
||||||
// 1) int64 bigtime_t object of when the message was sent
|
|
||||||
// 2) int32 raw key code (scancode)
|
|
||||||
// 3) int32 modifier-independent ASCII code for the character
|
|
||||||
// 4) int32 modifiers
|
|
||||||
// 5) int8[3] UTF-8 data generated
|
|
||||||
// 6) int8 number of bytes to follow containing the
|
|
||||||
// generated string
|
|
||||||
// 7) Character string generated by the keystroke
|
|
||||||
// 8) int8[16] state of all keys
|
|
||||||
|
|
||||||
bigtime_t time;
|
|
||||||
int32 scancode;
|
|
||||||
int32 ascii;
|
|
||||||
int32 modifiers;
|
|
||||||
int8 utf[3];
|
|
||||||
int8 bytes;
|
|
||||||
char *string;
|
|
||||||
int8 keystate[16];
|
|
||||||
|
|
||||||
msg.Read<bigtime_t>(&time);
|
|
||||||
msg.Read<int32>(&scancode);
|
|
||||||
msg.Read<int32>(&ascii);
|
|
||||||
msg.Read<int32>(&modifiers);
|
|
||||||
msg.Read(utf, sizeof(utf));
|
|
||||||
msg.Read<int8>(&bytes);
|
|
||||||
msg.ReadString(&string);
|
|
||||||
msg.Read(keystate, sizeof(keystate));
|
|
||||||
if (string)
|
|
||||||
free(string);
|
|
||||||
|
|
||||||
STRACE(("Key Up: 0x%lx\n",scancode));
|
|
||||||
|
|
||||||
if(DISPLAYDRIVER==HWDRIVER)
|
|
||||||
{
|
|
||||||
// Tab key
|
|
||||||
if(scancode==0x26 && (modifiers & B_CONTROL_KEY))
|
|
||||||
{
|
|
||||||
ServerApp *deskbar=app_server->FindApp("application/x-vnd.Be-TSKB");
|
|
||||||
if(deskbar)
|
|
||||||
{
|
|
||||||
printf("Send Twitcher message key to Deskbar - unimplmemented\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(scancode==0x26 && (modifiers & B_LEFT_SHIFT_KEY))
|
|
||||||
{
|
|
||||||
ServerApp *deskbar=app_server->FindApp("application/x-vnd.Be-TSKB");
|
|
||||||
if(deskbar)
|
|
||||||
{
|
|
||||||
printf("Send Twitcher message key to Deskbar - unimplmemented\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We got this far, so apparently it's safe to pass to the active
|
|
||||||
// window.
|
|
||||||
|
|
||||||
// TODO: Pass on key up message to client window with the focus
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case B_UNMAPPED_KEY_DOWN:
|
|
||||||
{
|
|
||||||
// Attached Data:
|
|
||||||
// 1) int64 bigtime_t object of when the message was sent
|
|
||||||
// 2) int32 raw key code (scancode)
|
|
||||||
// 3) int32 modifiers
|
|
||||||
// 4) int32 number of elements in the key state array to follow
|
|
||||||
// 5) int8 state of all keys
|
|
||||||
|
|
||||||
bigtime_t time;
|
|
||||||
int32 scancode;
|
|
||||||
int32 modifiers;
|
|
||||||
int32 elements;
|
|
||||||
//int8 keystate[16];
|
|
||||||
|
|
||||||
msg.Read<bigtime_t>(&time);
|
|
||||||
msg.Read<int32>(&scancode);
|
|
||||||
msg.Read<int32>(&modifiers);
|
|
||||||
msg.Read<int32>(&elements);
|
|
||||||
//msg.Read(keystate, elements);
|
|
||||||
|
|
||||||
#ifdef DEBUG_KEYHANDLING
|
|
||||||
printf("Unmapped Key Down: 0x%lx\n", scancode);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// TODO: Pass on unmapped key down message to client window with the focus
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case B_UNMAPPED_KEY_UP:
|
|
||||||
{
|
|
||||||
// Attached Data:
|
|
||||||
// 1) int64 bigtime_t object of when the message was sent
|
|
||||||
// 2) int32 raw key code (scancode)
|
|
||||||
// 3) int32 modifiers
|
|
||||||
// 4) int32 number of elements in the key state array to follow
|
|
||||||
// 5) int8 state of all keys
|
|
||||||
|
|
||||||
bigtime_t time;
|
|
||||||
int32 scancode;
|
|
||||||
int32 modifiers;
|
|
||||||
int32 elements;
|
|
||||||
//int8 keystate[16];
|
|
||||||
|
|
||||||
msg.Read<bigtime_t>(&time);
|
|
||||||
msg.Read<int32>(&scancode);
|
|
||||||
msg.Read<int32>(&modifiers);
|
|
||||||
msg.Read<int32>(&elements);
|
|
||||||
//msg.Read(keystate, elements);
|
|
||||||
|
|
||||||
#ifdef DEBUG_KEYHANDLING
|
|
||||||
printf("Unmapped Key Up: 0x%lx\n", scancode);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// TODO: Pass on unmapped key up message to client window with the focus
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case B_MODIFIERS_CHANGED:
|
|
||||||
{
|
|
||||||
// Attached Data:
|
|
||||||
// 1) int64 bigtime_t object of when the message was sent
|
|
||||||
// 2) int32 modifiers
|
|
||||||
// 3) int32 old modifiers
|
|
||||||
// 4) int32 number of elements in the key state array to follow
|
|
||||||
// 5) int8 state of all keys
|
|
||||||
|
|
||||||
bigtime_t time;
|
|
||||||
int32 scancode;
|
|
||||||
int32 modifiers;
|
|
||||||
int32 elements;
|
|
||||||
//int8 keystate[16];
|
|
||||||
|
|
||||||
msg.Read<bigtime_t>(&time);
|
|
||||||
msg.Read<int32>(&scancode);
|
|
||||||
msg.Read<int32>(&modifiers);
|
|
||||||
msg.Read<int32>(&elements);
|
|
||||||
//msg.Read(keystate, elements);
|
|
||||||
|
|
||||||
#ifdef DEBUG_KEYHANDLING
|
|
||||||
printf("Modifiers Changed\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// TODO: Pass on modifier change message to client window with the focus
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Desktop::SetDragMessage(BMessage* msg)
|
|
||||||
{
|
|
||||||
if (fDragMessage)
|
|
||||||
{
|
|
||||||
delete fDragMessage;
|
|
||||||
fDragMessage = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (msg)
|
|
||||||
fDragMessage = new BMessage(*msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
BMessage* Desktop::DragMessage(void) const
|
|
||||||
{
|
|
||||||
return fDragMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
// Methods for various desktop stuff handled by the server
|
// Methods for various desktop stuff handled by the server
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -936,7 +333,7 @@ void Desktop::RemoveSubsetWindow(WinBorder* wb)
|
|||||||
for(int32 i=0; i < count; i++)
|
for(int32 i=0; i < count; i++)
|
||||||
{
|
{
|
||||||
winBorder = static_cast<WinBorder*>(fWinBorderList.ItemAt(i));
|
winBorder = static_cast<WinBorder*>(fWinBorderList.ItemAt(i));
|
||||||
if (winBorder->fLevel == B_NORMAL_FEEL)
|
if (winBorder->Level() == B_NORMAL_FEEL)
|
||||||
winBorder->Window()->fWinFMWList.RemoveItem(wb);
|
winBorder->Window()->fWinFMWList.RemoveItem(wb);
|
||||||
}
|
}
|
||||||
fLayerLock.Unlock();
|
fLayerLock.Unlock();
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
//
|
//
|
||||||
// File Name: Desktop.cpp
|
// File Name: Desktop.cpp
|
||||||
// Author: Adi Oanca <adioanca@mymail.ro>
|
// Author: Adi Oanca <adioanca@cotty.iren.ro>
|
||||||
// Description: Class used to encapsulate desktop management
|
// Description: Class used to encapsulate desktop management
|
||||||
//
|
//
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -69,13 +69,6 @@ public:
|
|||||||
void RemoveWinBorder(WinBorder *winBorder);
|
void RemoveWinBorder(WinBorder *winBorder);
|
||||||
bool HasWinBorder(WinBorder *winBorder);
|
bool HasWinBorder(WinBorder *winBorder);
|
||||||
|
|
||||||
// Input related methods
|
|
||||||
void MouseEventHandler(int32 code, BPortLink& link);
|
|
||||||
void KeyboardEventHandler(int32 code, BPortLink& link);
|
|
||||||
|
|
||||||
void SetDragMessage(BMessage *msg);
|
|
||||||
BMessage *DragMessage(void) const;
|
|
||||||
|
|
||||||
// Methods for various desktop stuff handled by the server
|
// Methods for various desktop stuff handled by the server
|
||||||
void SetScrollBarInfo(const scroll_bar_info &info);
|
void SetScrollBarInfo(const scroll_bar_info &info);
|
||||||
scroll_bar_info ScrollBarInfo(void) const;
|
scroll_bar_info ScrollBarInfo(void) const;
|
||||||
@@ -83,7 +76,6 @@ public:
|
|||||||
void SetMenuInfo(const menu_info &info);
|
void SetMenuInfo(const menu_info &info);
|
||||||
menu_info MenuInfo(void) const;
|
menu_info MenuInfo(void) const;
|
||||||
|
|
||||||
|
|
||||||
void UseFFMouse(const bool &useffm);
|
void UseFFMouse(const bool &useffm);
|
||||||
bool FFMouseInUse(void) const;
|
bool FFMouseInUse(void) const;
|
||||||
void SetFFMouseMode(const mode_mouse &value);
|
void SetFFMouseMode(const mode_mouse &value);
|
||||||
@@ -102,13 +94,9 @@ public:
|
|||||||
BList fWinBorderList;
|
BList fWinBorderList;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BMessage *fDragMessage;
|
|
||||||
|
|
||||||
BList fRootLayerList;
|
BList fRootLayerList;
|
||||||
RootLayer *fActiveRootLayer;
|
RootLayer *fActiveRootLayer;
|
||||||
|
|
||||||
WinBorder *fMouseTarget;
|
|
||||||
|
|
||||||
BList fScreenList;
|
BList fScreenList;
|
||||||
Screen *fActiveScreen;
|
Screen *fActiveScreen;
|
||||||
|
|
||||||
@@ -116,7 +104,6 @@ private:
|
|||||||
menu_info fMenuInfo;
|
menu_info fMenuInfo;
|
||||||
mode_mouse fMouseMode;
|
mode_mouse fMouseMode;
|
||||||
bool fFFMouseMode;
|
bool fFFMouseMode;
|
||||||
int32 fScreenShotIndex;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Desktop *desktop;
|
extern Desktop *desktop;
|
||||||
|
|||||||
@@ -794,7 +794,13 @@ DDView::DDView(BRect bounds)
|
|||||||
SetViewColor(B_TRANSPARENT_32_BIT);
|
SetViewColor(B_TRANSPARENT_32_BIT);
|
||||||
|
|
||||||
#ifdef ENABLE_INPUT_SERVER_EMULATION
|
#ifdef ENABLE_INPUT_SERVER_EMULATION
|
||||||
serverlink.SetSendPort(find_port(SERVER_INPUT_PORT));
|
port_id serverInputPort = create_port(200, SERVER_INPUT_PORT);
|
||||||
|
if (serverInputPort == B_NO_MORE_PORTS)
|
||||||
|
{
|
||||||
|
debugger("ViewDriver: out of ports\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
serverlink.SetSendPort(serverInputPort);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
//
|
//
|
||||||
// File Name: Layer.h
|
// File Name: Layer.h
|
||||||
// Author: DarkWyrm <[email protected]>
|
// Author: DarkWyrm <[email protected]>
|
||||||
// Adi Oanca <adioanca@myrealbox.com>
|
// Adi Oanca <adioanca@cotty.iren.com>
|
||||||
// Description: Class used for rendering to the frame buffer. One layer per
|
// Description: Class used for rendering to the frame buffer. One layer per
|
||||||
// view on screen and also for window decorators
|
// view on screen and also for window decorators
|
||||||
//
|
//
|
||||||
@@ -133,6 +133,7 @@ public:
|
|||||||
ServerWindow *Window(void) const { return fServerWin; }
|
ServerWindow *Window(void) const { return fServerWin; }
|
||||||
virtual bool HasClient(void) { return true; }
|
virtual bool HasClient(void) { return true; }
|
||||||
bool IsServerLayer() const;
|
bool IsServerLayer() const;
|
||||||
|
int32 Level() const { return fLevel; }
|
||||||
|
|
||||||
void PruneTree(void);
|
void PruneTree(void);
|
||||||
|
|
||||||
@@ -155,7 +156,6 @@ protected:
|
|||||||
friend class WinBorder;
|
friend class WinBorder;
|
||||||
friend class Screen;
|
friend class Screen;
|
||||||
friend class ServerWindow;
|
friend class ServerWindow;
|
||||||
friend class Desktop;
|
|
||||||
friend class Workspace;
|
friend class Workspace;
|
||||||
|
|
||||||
BRect fFrame;
|
BRect fFrame;
|
||||||
|
|||||||
@@ -31,7 +31,9 @@
|
|||||||
#include <Window.h>
|
#include <Window.h>
|
||||||
#include <List.h>
|
#include <List.h>
|
||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
|
#include <Entry.h>
|
||||||
#include <File.h>
|
#include <File.h>
|
||||||
|
#include <PortLink.h>
|
||||||
|
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "RootLayer.h"
|
#include "RootLayer.h"
|
||||||
@@ -45,6 +47,7 @@
|
|||||||
#include "ServerConfig.h"
|
#include "ServerConfig.h"
|
||||||
#include "FMWList.h"
|
#include "FMWList.h"
|
||||||
#include "DisplayDriver.h"
|
#include "DisplayDriver.h"
|
||||||
|
#include "ServerProtocol.h"
|
||||||
|
|
||||||
//#define DEBUG_ROOTLAYER
|
//#define DEBUG_ROOTLAYER
|
||||||
|
|
||||||
@@ -62,7 +65,13 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount,
|
|||||||
: Layer(BRect(0,0,0,0), name, 0, B_FOLLOW_ALL, B_WILL_DRAW, driver)
|
: Layer(BRect(0,0,0,0), name, 0, B_FOLLOW_ALL, B_WILL_DRAW, driver)
|
||||||
{
|
{
|
||||||
fDesktop = desktop;
|
fDesktop = desktop;
|
||||||
|
|
||||||
|
fMouseTarget = NULL;
|
||||||
|
fDragMessage = NULL;
|
||||||
|
fScreenShotIndex = 1;
|
||||||
|
|
||||||
|
fQuiting = false;
|
||||||
|
|
||||||
//NOTE: be careful about this one.
|
//NOTE: be careful about this one.
|
||||||
fRootLayer = this;
|
fRootLayer = this;
|
||||||
fActiveWorkspace = NULL;
|
fActiveWorkspace = NULL;
|
||||||
@@ -81,14 +90,94 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount,
|
|||||||
// easy way to identify this class.
|
// easy way to identify this class.
|
||||||
fClassID = AS_ROOTLAYER_CLASS;
|
fClassID = AS_ROOTLAYER_CLASS;
|
||||||
fHidden = false;
|
fHidden = false;
|
||||||
|
|
||||||
|
fListenPort = find_port(SERVER_INPUT_PORT);
|
||||||
|
if (fListenPort == B_NAME_NOT_FOUND)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Spawn our working thread
|
||||||
|
fThreadID= spawn_thread(WorkingThread, name, B_REAL_TIME_DISPLAY_PRIORITY, this);
|
||||||
|
if (fThreadID >= 0)
|
||||||
|
resume_thread(fThreadID);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RootLayer::~RootLayer()
|
RootLayer::~RootLayer()
|
||||||
{
|
{
|
||||||
|
int32 exitValue;
|
||||||
|
fQuiting = true;
|
||||||
|
BPortLink msg(fListenPort, -1);
|
||||||
|
msg.StartMessage(B_QUIT_REQUESTED);
|
||||||
|
msg.EndMessage();
|
||||||
|
msg.Flush();
|
||||||
|
|
||||||
|
wait_for_thread(fThreadID, &exitValue);
|
||||||
|
|
||||||
|
if (fDragMessage)
|
||||||
|
delete fDragMessage;
|
||||||
|
|
||||||
// RootLayer object just uses Screen objects, it is not allowed to delete them.
|
// RootLayer object just uses Screen objects, it is not allowed to delete them.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\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)
|
||||||
|
{
|
||||||
|
int32 code = 0;
|
||||||
|
status_t err = B_OK;
|
||||||
|
RootLayer *oneRootLayer = (RootLayer*)data;
|
||||||
|
BPortLink messageQueue(-1, oneRootLayer->fListenPort);
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
STRACE(("info: RootLayer(%s)::WorkingThread listening on port %ld.\n", oneRootLayer->GetName(), oneRootLayer->fListenPort));
|
||||||
|
err = messageQueue.GetNextReply(&code);
|
||||||
|
|
||||||
|
if(err < B_OK)
|
||||||
|
{
|
||||||
|
STRACE(("WorkingThread: messageQueue.GetNextReply failed\n"));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(code)
|
||||||
|
{
|
||||||
|
// 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_WHEEL_CHANGED:
|
||||||
|
case B_MOUSE_MOVED:
|
||||||
|
oneRootLayer->MouseEventHandler(code, messageQueue);
|
||||||
|
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(code, messageQueue);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_QUIT_REQUESTED:
|
||||||
|
exit_thread(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
STRACE(("RootLayer(%s)::WorkingThread received unexpected code %lx\n",oneRootLayer->GetName(), oneRootLayer->code));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we still have other messages in our queue, but we really want to quit
|
||||||
|
if (oneRootLayer->fQuiting)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void RootLayer::MoveBy(float x, float y)
|
void RootLayer::MoveBy(float x, float y)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -680,6 +769,603 @@ void RootLayer::RemoveAppWindow(WinBorder *wb)
|
|||||||
WorkspaceAt(i+1)->RemoveWinBorder(wb);
|
WorkspaceAt(i+1)->RemoveWinBorder(wb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// Input related methods
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
void RootLayer::MouseEventHandler(int32 code, BPortLink& msg)
|
||||||
|
{
|
||||||
|
// TODO: locking mechanism needs SERIOUS rethought
|
||||||
|
switch(code)
|
||||||
|
{
|
||||||
|
case B_MOUSE_DOWN:
|
||||||
|
{
|
||||||
|
// Attached data:
|
||||||
|
// 1) int64 - time of mouse click
|
||||||
|
// 2) float - x coordinate of mouse click
|
||||||
|
// 3) float - y coordinate of mouse click
|
||||||
|
// 4) int32 - modifier keys down
|
||||||
|
// 5) int32 - buttons down
|
||||||
|
// 6) int32 - clicks
|
||||||
|
|
||||||
|
PointerEvent evt;
|
||||||
|
evt.code = B_MOUSE_DOWN;
|
||||||
|
msg.Read<int64>(&evt.when);
|
||||||
|
msg.Read<float>(&evt.where.x);
|
||||||
|
msg.Read<float>(&evt.where.y);
|
||||||
|
msg.Read<int32>(&evt.modifiers);
|
||||||
|
msg.Read<int32>(&evt.buttons);
|
||||||
|
msg.Read<int32>(&evt.clicks);
|
||||||
|
|
||||||
|
// printf("MOUSE DOWN: at (%f, %f)\n", evt.where.x, evt.where.y);
|
||||||
|
|
||||||
|
WinBorder *target=NULL;
|
||||||
|
Workspace *ws=NULL;
|
||||||
|
ws = ActiveWorkspace();
|
||||||
|
target = WinBorderAt(evt.where);
|
||||||
|
if (target)
|
||||||
|
{
|
||||||
|
desktop->fGeneralLock.Lock();
|
||||||
|
fMainLock.Lock();
|
||||||
|
|
||||||
|
STRACE(("Target: %s\n", target->GetName()));
|
||||||
|
STRACE(("Front: %s\n", ws->FrontLayer()->GetName()));
|
||||||
|
STRACE(("Focus: %s\n", ws->FocusLayer()->GetName()));
|
||||||
|
|
||||||
|
WinBorder *previousFocus=NULL;
|
||||||
|
WinBorder *activeFocus=NULL;
|
||||||
|
BRegion invalidRegion;
|
||||||
|
|
||||||
|
BMessage downmsg(B_MOUSE_DOWN);
|
||||||
|
downmsg.AddInt64("when",evt.when);
|
||||||
|
downmsg.AddPoint("where",evt.where);
|
||||||
|
downmsg.AddInt32("modifiers",evt.modifiers);
|
||||||
|
downmsg.AddInt32("buttons",evt.buttons);
|
||||||
|
downmsg.AddInt32("clicks",evt.clicks);
|
||||||
|
|
||||||
|
if (target!=ws->FrontLayer())
|
||||||
|
{
|
||||||
|
ws->BringToFrontANormalWindow(target);
|
||||||
|
ws->SearchAndSetNewFront(target);
|
||||||
|
previousFocus = ws->FocusLayer();
|
||||||
|
ws->SearchAndSetNewFocus(target);
|
||||||
|
activeFocus = ws->FocusLayer();
|
||||||
|
|
||||||
|
activeFocus->Window()->Lock();
|
||||||
|
|
||||||
|
if (target == activeFocus && target->Window()->Flags() & B_WILL_ACCEPT_FIRST_CLICK)
|
||||||
|
target->MouseDown(evt, true);
|
||||||
|
else
|
||||||
|
target->MouseDown(evt, false);
|
||||||
|
|
||||||
|
// may or may not be empty.
|
||||||
|
|
||||||
|
// TODO: B_MOUSE_DOWN: what if modal of floating windows are in front of us?
|
||||||
|
invalidRegion.Include(&(activeFocus->fFull));
|
||||||
|
invalidRegion.Include(&(activeFocus->fTopLayer->fFull));
|
||||||
|
activeFocus->fParent->RebuildAndForceRedraw(invalidRegion, activeFocus);
|
||||||
|
|
||||||
|
if (previousFocus != activeFocus && previousFocus)
|
||||||
|
{
|
||||||
|
if (previousFocus->fVisible.CountRects() > 0)
|
||||||
|
{
|
||||||
|
invalidRegion.MakeEmpty();
|
||||||
|
invalidRegion.Include(&(previousFocus->fVisible));
|
||||||
|
activeFocus->fParent->Invalidate(invalidRegion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fMouseTarget = target;
|
||||||
|
|
||||||
|
STRACE(("2Target: %s\n", target->GetName()));
|
||||||
|
STRACE(("2Front: %s\n", ws->FrontLayer()->GetName()));
|
||||||
|
STRACE(("2Focus: %s\n", ws->FocusLayer()->GetName()));
|
||||||
|
|
||||||
|
fMouseTarget->Window()->SendMessageToClient(&downmsg);
|
||||||
|
activeFocus->Window()->Unlock();
|
||||||
|
}
|
||||||
|
else // target == ws->FrontLayer()
|
||||||
|
{
|
||||||
|
// only if target has the focus!
|
||||||
|
if (target == ws->FocusLayer())
|
||||||
|
{
|
||||||
|
target->Window()->Lock();
|
||||||
|
target->MouseDown(evt, true);
|
||||||
|
target->Window()->SendMessageToClient(&downmsg);
|
||||||
|
target->Window()->Unlock();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
previousFocus = ws->FocusLayer();
|
||||||
|
ws->SearchAndSetNewFocus(target);
|
||||||
|
activeFocus = ws->FocusLayer();
|
||||||
|
|
||||||
|
activeFocus->Window()->Lock();
|
||||||
|
|
||||||
|
if (target == activeFocus && target->Window()->Flags() & B_WILL_ACCEPT_FIRST_CLICK)
|
||||||
|
target->MouseDown(evt, true);
|
||||||
|
else
|
||||||
|
target->MouseDown(evt, false);
|
||||||
|
|
||||||
|
// may or may not be empty.
|
||||||
|
|
||||||
|
// TODO: B_MOUSE_DOWN: what if modal of floating windows are in front of us?
|
||||||
|
invalidRegion.Include(&(activeFocus->fFull));
|
||||||
|
invalidRegion.Include(&(activeFocus->fTopLayer->fFull));
|
||||||
|
activeFocus->fParent->RebuildAndForceRedraw(invalidRegion, activeFocus);
|
||||||
|
|
||||||
|
if (previousFocus != activeFocus && previousFocus)
|
||||||
|
{
|
||||||
|
if (previousFocus->fVisible.CountRects() > 0)
|
||||||
|
{
|
||||||
|
invalidRegion.MakeEmpty();
|
||||||
|
invalidRegion.Include(&(previousFocus->fVisible));
|
||||||
|
activeFocus->fParent->Invalidate(invalidRegion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fMouseTarget = target;
|
||||||
|
fMouseTarget->Window()->SendMessageToClient(&downmsg);
|
||||||
|
|
||||||
|
activeFocus->Window()->Unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fMainLock.Unlock();
|
||||||
|
desktop->fGeneralLock.Unlock();
|
||||||
|
}
|
||||||
|
else // target == NULL
|
||||||
|
{
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_MOUSE_UP:
|
||||||
|
{
|
||||||
|
// Attached data:
|
||||||
|
// 1) int64 - time of mouse click
|
||||||
|
// 2) float - x coordinate of mouse click
|
||||||
|
// 3) float - y coordinate of mouse click
|
||||||
|
// 4) int32 - modifier keys down
|
||||||
|
|
||||||
|
PointerEvent evt;
|
||||||
|
evt.code = B_MOUSE_UP;
|
||||||
|
msg.Read<int64>(&evt.when);
|
||||||
|
msg.Read<float>(&evt.where.x);
|
||||||
|
msg.Read<float>(&evt.where.y);
|
||||||
|
msg.Read<int32>(&evt.modifiers);
|
||||||
|
|
||||||
|
if (!fMouseTarget)
|
||||||
|
{
|
||||||
|
WinBorder *target = WinBorderAt(BPoint(evt.where.x, evt.where.y));
|
||||||
|
if(!target)
|
||||||
|
break;
|
||||||
|
fMouseTarget=target;
|
||||||
|
}
|
||||||
|
|
||||||
|
fMouseTarget->Window()->Lock();
|
||||||
|
fMouseTarget->MouseUp(evt);
|
||||||
|
|
||||||
|
BMessage upmsg(B_MOUSE_UP);
|
||||||
|
upmsg.AddInt64("when",evt.when);
|
||||||
|
upmsg.AddPoint("where",evt.where);
|
||||||
|
upmsg.AddInt32("modifiers",evt.modifiers);
|
||||||
|
|
||||||
|
fMouseTarget->Window()->SendMessageToClient(&upmsg);
|
||||||
|
fMouseTarget->Window()->Unlock();
|
||||||
|
|
||||||
|
STRACE(("MOUSE UP: at (%f, %f)\n", evt.where.x, evt.where.y));
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_MOUSE_MOVED:
|
||||||
|
{
|
||||||
|
// Attached data:
|
||||||
|
// 1) int64 - time of mouse click
|
||||||
|
// 2) float - x coordinate of mouse click
|
||||||
|
// 3) float - y coordinate of mouse click
|
||||||
|
// 4) int32 - buttons down
|
||||||
|
|
||||||
|
PointerEvent evt;
|
||||||
|
evt.code = B_MOUSE_MOVED;
|
||||||
|
msg.Read<int64>(&evt.when);
|
||||||
|
msg.Read<float>(&evt.where.x);
|
||||||
|
msg.Read<float>(&evt.where.y);
|
||||||
|
msg.Read<int32>(&evt.buttons);
|
||||||
|
|
||||||
|
GetDisplayDriver()->MoveCursorTo(evt.where.x, evt.where.y);
|
||||||
|
|
||||||
|
if (!fMouseTarget)
|
||||||
|
{
|
||||||
|
WinBorder *target = WinBorderAt(BPoint(evt.where.x, evt.where.y));
|
||||||
|
if(!target)
|
||||||
|
break;
|
||||||
|
fMouseTarget=target;
|
||||||
|
}
|
||||||
|
|
||||||
|
fMouseTarget->Window()->Lock();
|
||||||
|
fMouseTarget->MouseMoved(evt);
|
||||||
|
|
||||||
|
BMessage movemsg(B_MOUSE_MOVED);
|
||||||
|
movemsg.AddInt64("when",evt.when);
|
||||||
|
movemsg.AddPoint("where",evt.where);
|
||||||
|
movemsg.AddInt32("buttons",evt.buttons);
|
||||||
|
|
||||||
|
fMouseTarget->Window()->SendMessageToClient(&movemsg);
|
||||||
|
fMouseTarget->Window()->Unlock();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_MOUSE_WHEEL_CHANGED:
|
||||||
|
{
|
||||||
|
// FEATURE: This is a tentative change: mouse wheel messages are always sent to the window
|
||||||
|
// under the cursor. It's pretty stupid to send it to the active window unless a particular
|
||||||
|
// view has locked focus via SetMouseEventMask
|
||||||
|
|
||||||
|
PointerEvent evt;
|
||||||
|
evt.code = B_MOUSE_WHEEL_CHANGED;
|
||||||
|
msg.Read<int64>(&evt.when);
|
||||||
|
msg.Read<float>(&evt.wheel_delta_x);
|
||||||
|
msg.Read<float>(&evt.wheel_delta_y);
|
||||||
|
|
||||||
|
BMessage wheelmsg(B_MOUSE_WHEEL_CHANGED);
|
||||||
|
wheelmsg.AddInt64("when",evt.when);
|
||||||
|
wheelmsg.AddFloat("be:wheel_delta_x",evt.wheel_delta_x);
|
||||||
|
wheelmsg.AddFloat("be:wheel_delta_y",evt.wheel_delta_y);
|
||||||
|
|
||||||
|
if(!fMouseTarget)
|
||||||
|
{
|
||||||
|
fMouseTarget = WinBorderAt(GetDisplayDriver()->GetCursorPosition());
|
||||||
|
|
||||||
|
// We do nothing because there ain't a window to receive the message
|
||||||
|
if(!fMouseTarget)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fMouseTarget->Window()->Lock();
|
||||||
|
fMouseTarget->Window()->SendMessageToClient(&wheelmsg);
|
||||||
|
fMouseTarget->Window()->Unlock();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
printf("\nDesktop::MouseEventHandler(): WARNING: unknown message\n\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RootLayer::KeyboardEventHandler(int32 code, BPortLink& msg)
|
||||||
|
{
|
||||||
|
|
||||||
|
switch(code)
|
||||||
|
{
|
||||||
|
case B_KEY_DOWN:
|
||||||
|
{
|
||||||
|
// Attached Data:
|
||||||
|
// 1) int64 bigtime_t object of when the message was sent
|
||||||
|
// 2) int32 raw key code (scancode)
|
||||||
|
// 3) int32 modifier-independent ASCII code for the character
|
||||||
|
// 4) int32 repeat count
|
||||||
|
// 5) int32 modifiers
|
||||||
|
// 6) int8[3] UTF-8 data generated
|
||||||
|
// 7) int8 number of bytes to follow containing the
|
||||||
|
// generated string
|
||||||
|
// 8) Character string generated by the keystroke
|
||||||
|
// 9) int8[16] state of all keys
|
||||||
|
|
||||||
|
bigtime_t time;
|
||||||
|
int32 scancode, modifiers;
|
||||||
|
int8 utf[3];
|
||||||
|
char *string = NULL;
|
||||||
|
int32 keystate;
|
||||||
|
|
||||||
|
msg.Read<bigtime_t>(&time);
|
||||||
|
msg.Read<int32>(&scancode);
|
||||||
|
msg.Read<int32>(&modifiers);
|
||||||
|
msg.Read(utf, sizeof(utf));
|
||||||
|
msg.ReadString(&string);
|
||||||
|
msg.Read<int32>(&keystate);
|
||||||
|
if (string)
|
||||||
|
free(string);
|
||||||
|
|
||||||
|
if(DISPLAYDRIVER==HWDRIVER)
|
||||||
|
{
|
||||||
|
// Check for workspace change or safe video mode
|
||||||
|
if(scancode>0x01 && scancode<0x0e)
|
||||||
|
{
|
||||||
|
if(scancode==0x0d)
|
||||||
|
{
|
||||||
|
if(modifiers & (B_LEFT_COMMAND_KEY |
|
||||||
|
B_LEFT_CONTROL_KEY | B_LEFT_SHIFT_KEY))
|
||||||
|
{
|
||||||
|
// TODO: Set to Safe Mode in KeyboardEventHandler:B_KEY_DOWN. (DisplayDriver API change)
|
||||||
|
STRACE(("Safe Video Mode invoked - code unimplemented\n"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(modifiers & B_CONTROL_KEY)
|
||||||
|
{
|
||||||
|
STRACE(("Set Workspace %ld\n",scancode-1));
|
||||||
|
|
||||||
|
//TODO: SetWorkspace in KeyboardEventHandler
|
||||||
|
//SetWorkspace(scancode-2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tab key
|
||||||
|
if(scancode==0x26 && (modifiers & B_CONTROL_KEY))
|
||||||
|
{
|
||||||
|
//ServerApp *deskbar=app_server->FindApp("application/x-vnd.Be-TSKB");
|
||||||
|
//if(deskbar)
|
||||||
|
//{
|
||||||
|
printf("Send Twitcher message key to Deskbar - unimplmemented\n");
|
||||||
|
break;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrintScreen
|
||||||
|
if(scancode==0xe)
|
||||||
|
{
|
||||||
|
if(GetDisplayDriver())
|
||||||
|
{
|
||||||
|
char filename[128];
|
||||||
|
BEntry entry;
|
||||||
|
|
||||||
|
sprintf(filename,"/boot/home/screen%ld.png",fScreenShotIndex);
|
||||||
|
entry.SetTo(filename);
|
||||||
|
|
||||||
|
while(entry.Exists())
|
||||||
|
{
|
||||||
|
fScreenShotIndex++;
|
||||||
|
sprintf(filename,"/boot/home/screen%ld.png",fScreenShotIndex);
|
||||||
|
}
|
||||||
|
fScreenShotIndex++;
|
||||||
|
GetDisplayDriver()->DumpToFile(filename);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// F12
|
||||||
|
if(scancode>0x1 && scancode<0xe)
|
||||||
|
{
|
||||||
|
if(scancode==0xd)
|
||||||
|
{
|
||||||
|
if(modifiers & (B_LEFT_CONTROL_KEY | B_LEFT_SHIFT_KEY | B_LEFT_OPTION_KEY))
|
||||||
|
{
|
||||||
|
// TODO: Set to Safe Mode in KeyboardEventHandler:B_KEY_DOWN. (DisplayDriver API change)
|
||||||
|
STRACE(("Safe Video Mode invoked - code unimplemented\n"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(modifiers & (B_LEFT_SHIFT_KEY | B_LEFT_CONTROL_KEY))
|
||||||
|
{
|
||||||
|
STRACE(("Set Workspace %ld\n",scancode-1));
|
||||||
|
//TODO: SetWorkspace in KeyboardEventHandler
|
||||||
|
//SetWorkspace(scancode-2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Tab
|
||||||
|
if(scancode==0x26 && (modifiers & B_SHIFT_KEY))
|
||||||
|
{
|
||||||
|
STRACE(("Twitcher\n"));
|
||||||
|
//ServerApp *deskbar=app_server->FindApp("application/x-vnd.Be-TSKB");
|
||||||
|
//if(deskbar)
|
||||||
|
//{
|
||||||
|
printf("Send Twitcher message key to Deskbar - unimplmemented\n");
|
||||||
|
break;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pause/Break
|
||||||
|
if(scancode==0x7f)
|
||||||
|
{
|
||||||
|
if(GetDisplayDriver())
|
||||||
|
{
|
||||||
|
char filename[128];
|
||||||
|
BEntry entry;
|
||||||
|
|
||||||
|
sprintf(filename,"/boot/home/screen%ld.png",fScreenShotIndex);
|
||||||
|
entry.SetTo(filename);
|
||||||
|
|
||||||
|
while(entry.Exists())
|
||||||
|
{
|
||||||
|
fScreenShotIndex++;
|
||||||
|
sprintf(filename,"/boot/home/screen%ld.png",fScreenShotIndex);
|
||||||
|
}
|
||||||
|
fScreenShotIndex++;
|
||||||
|
|
||||||
|
GetDisplayDriver()->DumpToFile(filename);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We got this far, so apparently it's safe to pass to the active
|
||||||
|
// window.
|
||||||
|
|
||||||
|
// TODO: Pass on key down message to client window with the focus
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_KEY_UP:
|
||||||
|
{
|
||||||
|
// Attached Data:
|
||||||
|
// 1) int64 bigtime_t object of when the message was sent
|
||||||
|
// 2) int32 raw key code (scancode)
|
||||||
|
// 3) int32 modifier-independent ASCII code for the character
|
||||||
|
// 4) int32 modifiers
|
||||||
|
// 5) int8[3] UTF-8 data generated
|
||||||
|
// 6) int8 number of bytes to follow containing the
|
||||||
|
// generated string
|
||||||
|
// 7) Character string generated by the keystroke
|
||||||
|
// 8) int8[16] state of all keys
|
||||||
|
|
||||||
|
bigtime_t time;
|
||||||
|
int32 scancode;
|
||||||
|
int32 ascii;
|
||||||
|
int32 modifiers;
|
||||||
|
int8 utf[3];
|
||||||
|
int8 bytes;
|
||||||
|
char *string;
|
||||||
|
int8 keystate[16];
|
||||||
|
|
||||||
|
msg.Read<bigtime_t>(&time);
|
||||||
|
msg.Read<int32>(&scancode);
|
||||||
|
msg.Read<int32>(&ascii);
|
||||||
|
msg.Read<int32>(&modifiers);
|
||||||
|
msg.Read(utf, sizeof(utf));
|
||||||
|
msg.Read<int8>(&bytes);
|
||||||
|
msg.ReadString(&string);
|
||||||
|
msg.Read(keystate, sizeof(keystate));
|
||||||
|
if (string)
|
||||||
|
free(string);
|
||||||
|
|
||||||
|
STRACE(("Key Up: 0x%lx\n",scancode));
|
||||||
|
|
||||||
|
if(DISPLAYDRIVER==HWDRIVER)
|
||||||
|
{
|
||||||
|
// Tab key
|
||||||
|
if(scancode==0x26 && (modifiers & B_CONTROL_KEY))
|
||||||
|
{
|
||||||
|
//ServerApp *deskbar=app_server->FindApp("application/x-vnd.Be-TSKB");
|
||||||
|
//if(deskbar)
|
||||||
|
//{
|
||||||
|
printf("Send Twitcher message key to Deskbar - unimplmemented\n");
|
||||||
|
break;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(scancode==0x26 && (modifiers & B_LEFT_SHIFT_KEY))
|
||||||
|
{
|
||||||
|
//ServerApp *deskbar=app_server->FindApp("application/x-vnd.Be-TSKB");
|
||||||
|
//if(deskbar)
|
||||||
|
//{
|
||||||
|
printf("Send Twitcher message key to Deskbar - unimplmemented\n");
|
||||||
|
break;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We got this far, so apparently it's safe to pass to the active
|
||||||
|
// window.
|
||||||
|
|
||||||
|
// TODO: Pass on key up message to client window with the focus
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_UNMAPPED_KEY_DOWN:
|
||||||
|
{
|
||||||
|
// Attached Data:
|
||||||
|
// 1) int64 bigtime_t object of when the message was sent
|
||||||
|
// 2) int32 raw key code (scancode)
|
||||||
|
// 3) int32 modifiers
|
||||||
|
// 4) int32 number of elements in the key state array to follow
|
||||||
|
// 5) int8 state of all keys
|
||||||
|
|
||||||
|
bigtime_t time;
|
||||||
|
int32 scancode;
|
||||||
|
int32 modifiers;
|
||||||
|
int32 elements;
|
||||||
|
//int8 keystate[16];
|
||||||
|
|
||||||
|
msg.Read<bigtime_t>(&time);
|
||||||
|
msg.Read<int32>(&scancode);
|
||||||
|
msg.Read<int32>(&modifiers);
|
||||||
|
msg.Read<int32>(&elements);
|
||||||
|
//msg.Read(keystate, elements);
|
||||||
|
|
||||||
|
#ifdef DEBUG_KEYHANDLING
|
||||||
|
printf("Unmapped Key Down: 0x%lx\n", scancode);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// TODO: Pass on unmapped key down message to client window with the focus
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_UNMAPPED_KEY_UP:
|
||||||
|
{
|
||||||
|
// Attached Data:
|
||||||
|
// 1) int64 bigtime_t object of when the message was sent
|
||||||
|
// 2) int32 raw key code (scancode)
|
||||||
|
// 3) int32 modifiers
|
||||||
|
// 4) int32 number of elements in the key state array to follow
|
||||||
|
// 5) int8 state of all keys
|
||||||
|
|
||||||
|
bigtime_t time;
|
||||||
|
int32 scancode;
|
||||||
|
int32 modifiers;
|
||||||
|
int32 elements;
|
||||||
|
//int8 keystate[16];
|
||||||
|
|
||||||
|
msg.Read<bigtime_t>(&time);
|
||||||
|
msg.Read<int32>(&scancode);
|
||||||
|
msg.Read<int32>(&modifiers);
|
||||||
|
msg.Read<int32>(&elements);
|
||||||
|
//msg.Read(keystate, elements);
|
||||||
|
|
||||||
|
#ifdef DEBUG_KEYHANDLING
|
||||||
|
printf("Unmapped Key Up: 0x%lx\n", scancode);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// TODO: Pass on unmapped key up message to client window with the focus
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_MODIFIERS_CHANGED:
|
||||||
|
{
|
||||||
|
// Attached Data:
|
||||||
|
// 1) int64 bigtime_t object of when the message was sent
|
||||||
|
// 2) int32 modifiers
|
||||||
|
// 3) int32 old modifiers
|
||||||
|
// 4) int32 number of elements in the key state array to follow
|
||||||
|
// 5) int8 state of all keys
|
||||||
|
|
||||||
|
bigtime_t time;
|
||||||
|
int32 scancode;
|
||||||
|
int32 modifiers;
|
||||||
|
int32 elements;
|
||||||
|
//int8 keystate[16];
|
||||||
|
|
||||||
|
msg.Read<bigtime_t>(&time);
|
||||||
|
msg.Read<int32>(&scancode);
|
||||||
|
msg.Read<int32>(&modifiers);
|
||||||
|
msg.Read<int32>(&elements);
|
||||||
|
//msg.Read(keystate, elements);
|
||||||
|
|
||||||
|
#ifdef DEBUG_KEYHANDLING
|
||||||
|
printf("Modifiers Changed\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// TODO: Pass on modifier change message to client window with the focus
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RootLayer::SetDragMessage(BMessage* msg)
|
||||||
|
{
|
||||||
|
if (fDragMessage)
|
||||||
|
{
|
||||||
|
delete fDragMessage;
|
||||||
|
fDragMessage = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg)
|
||||||
|
fDragMessage = new BMessage(*msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
BMessage* RootLayer::DragMessage(void) const
|
||||||
|
{
|
||||||
|
return fDragMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DEBUG methods
|
||||||
|
|
||||||
void RootLayer::PrintToStream()
|
void RootLayer::PrintToStream()
|
||||||
{
|
{
|
||||||
printf("\nRootLayer '%s' internals:\n", GetName());
|
printf("\nRootLayer '%s' internals:\n", GetName());
|
||||||
|
|||||||
@@ -94,7 +94,17 @@ public:
|
|||||||
virtual bool HasClient(void) { return false; }
|
virtual bool HasClient(void) { return false; }
|
||||||
|
|
||||||
void AddWinBorderToWorkspaces(WinBorder *winBorder, uint32 wks);
|
void AddWinBorderToWorkspaces(WinBorder *winBorder, uint32 wks);
|
||||||
|
|
||||||
|
// Input related methods
|
||||||
|
void MouseEventHandler(int32 code, BPortLink& link);
|
||||||
|
void KeyboardEventHandler(int32 code, BPortLink& link);
|
||||||
|
|
||||||
|
void SetDragMessage(BMessage *msg);
|
||||||
|
BMessage *DragMessage(void) const;
|
||||||
|
|
||||||
|
static int32 WorkingThread(void *data);
|
||||||
|
|
||||||
|
// Debug methods
|
||||||
void PrintToStream(void);
|
void PrintToStream(void);
|
||||||
|
|
||||||
// "Private" to app_server :-) - they should not be used
|
// "Private" to app_server :-) - they should not be used
|
||||||
@@ -105,6 +115,11 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Desktop *fDesktop;
|
Desktop *fDesktop;
|
||||||
|
BMessage *fDragMessage;
|
||||||
|
WinBorder *fMouseTarget;
|
||||||
|
|
||||||
|
thread_id fThreadID;
|
||||||
|
port_id fListenPort;
|
||||||
|
|
||||||
BList fScreenPtrList;
|
BList fScreenPtrList;
|
||||||
int32 fRows;
|
int32 fRows;
|
||||||
@@ -115,6 +130,9 @@ private:
|
|||||||
|
|
||||||
BList fWorkspaceList;
|
BList fWorkspaceList;
|
||||||
Workspace *fActiveWorkspace;
|
Workspace *fActiveWorkspace;
|
||||||
|
|
||||||
|
int32 fScreenShotIndex;
|
||||||
|
bool fQuiting;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -2215,7 +2215,7 @@ int32 ServerWindow::MonitorWin(void *data)
|
|||||||
|
|
||||||
while(!quitting)
|
while(!quitting)
|
||||||
{
|
{
|
||||||
printf("info: ServerWindow::MonitorWin listening on port %ld.\n", win->fMessagePort);
|
// printf("info: ServerWindow::MonitorWin listening on port %ld.\n", win->fMessagePort);
|
||||||
code = AS_CLIENT_DEAD;
|
code = AS_CLIENT_DEAD;
|
||||||
err = ses->GetNextMessage(&code);
|
err = ses->GetNextMessage(&code);
|
||||||
if (err < B_OK)
|
if (err < B_OK)
|
||||||
|
|||||||
@@ -83,7 +83,13 @@ VDView::VDView(BRect bounds)
|
|||||||
|
|
||||||
// This link for sending mouse messages to the OBAppServer.
|
// This link for sending mouse messages to the OBAppServer.
|
||||||
// This is only to take the place of the Input Server.
|
// This is only to take the place of the Input Server.
|
||||||
serverlink = new BPortLink(find_port(SERVER_INPUT_PORT));
|
port_id serverInputPort = create_port(200, SERVER_INPUT_PORT);
|
||||||
|
if (serverInputPort == B_NO_MORE_PORTS)
|
||||||
|
{
|
||||||
|
debugger("ViewDriver: out of ports\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
serverlink = new BPortLink(serverInputPort);
|
||||||
|
|
||||||
// Create a cursor which isn't just a box
|
// Create a cursor which isn't just a box
|
||||||
cursor=new BBitmap(BRect(0,0,20,20),B_RGBA32,true);
|
cursor=new BBitmap(BRect(0,0,20,20),B_RGBA32,true);
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
friend class Layer;
|
friend class Layer;
|
||||||
friend class ServerWindow;
|
friend class ServerWindow;
|
||||||
friend class Desktop;
|
friend class RootLayer;
|
||||||
|
|
||||||
Decorator *fDecorator;
|
Decorator *fDecorator;
|
||||||
Layer *fTopLayer;
|
Layer *fTopLayer;
|
||||||
|
|||||||
Reference in New Issue
Block a user