Improved method support : method replicant is working

Readding of replicant or reset of method replicant menu still to be done


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9558 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval 2004-10-28 13:47:51 +00:00
parent 9902467dac
commit 215b876d6e
6 changed files with 255 additions and 81 deletions

View File

@ -83,20 +83,20 @@ AddOnManager::RegisterAddOn(BEntry &entry)
if (get_image_symbol(addon_image, "instantiate_input_device",
B_SYMBOL_TYPE_TEXT, (void **)&instantiate_func) < B_OK) {
PRINT(("AddOnManager::RegisterAddOn(): can't find instantiate_input_device in \"%s\"\n",
PRINTERR(("AddOnManager::RegisterAddOn(): can't find instantiate_input_device in \"%s\"\n",
path.Path()));
goto exit_error;
}
BInputServerDevice *isd = (*instantiate_func)();
if (isd == NULL) {
PRINT(("AddOnManager::RegisterAddOn(): instantiate_input_device in \"%s\" returned NULL\n",
PRINTERR(("AddOnManager::RegisterAddOn(): instantiate_input_device in \"%s\" returned NULL\n",
path.Path()));
goto exit_error;
}
status_t status = isd->InitCheck();
if (status != B_OK) {
PRINT(("AddOnManager::RegisterAddOn(): BInputServerDevice.InitCheck in \"%s\" returned %s\n",
PRINTERR(("AddOnManager::RegisterAddOn(): BInputServerDevice.InitCheck in \"%s\" returned %s\n",
path.Path(), strerror(status)));
delete isd;
goto exit_error;
@ -110,20 +110,20 @@ AddOnManager::RegisterAddOn(BEntry &entry)
if (get_image_symbol(addon_image, "instantiate_input_filter",
B_SYMBOL_TYPE_TEXT, (void **)&instantiate_func) < B_OK) {
PRINT(("AddOnManager::RegisterAddOn(): can't find instantiate_input_filter in \"%s\"\n",
PRINTERR(("AddOnManager::RegisterAddOn(): can't find instantiate_input_filter in \"%s\"\n",
path.Path()));
goto exit_error;
}
BInputServerFilter *isf = (*instantiate_func)();
if (isf == NULL) {
PRINT(("AddOnManager::RegisterAddOn(): instantiate_input_filter in \"%s\" returned NULL\n",
PRINTERR(("AddOnManager::RegisterAddOn(): instantiate_input_filter in \"%s\" returned NULL\n",
path.Path()));
goto exit_error;
}
status_t status = isf->InitCheck();
if (status != B_OK) {
PRINT(("AddOnManager::RegisterAddOn(): BInputServerFilter.InitCheck in \"%s\" returned %s\n",
PRINTERR(("AddOnManager::RegisterAddOn(): BInputServerFilter.InitCheck in \"%s\" returned %s\n",
path.Path(), strerror(status)));
delete isf;
goto exit_error;
@ -136,21 +136,21 @@ AddOnManager::RegisterAddOn(BEntry &entry)
if (get_image_symbol(addon_image, "instantiate_input_method",
B_SYMBOL_TYPE_TEXT, (void **)&instantiate_func) < B_OK) {
PRINT(("AddOnManager::RegisterAddOn(): can't find instantiate_input_method in \"%s\"\n",
PRINTERR(("AddOnManager::RegisterAddOn(): can't find instantiate_input_method in \"%s\"\n",
path.Path()));
goto exit_error;
}
BInputServerMethod *ism = (*instantiate_func)();
if (ism == NULL) {
PRINT(("AddOnManager::RegisterAddOn(): instantiate_input_method in \"%s\" returned NULL\n",
PRINTERR(("AddOnManager::RegisterAddOn(): instantiate_input_method in \"%s\" returned NULL\n",
path.Path()));
goto exit_error;
}
status_t status = ism->InitCheck();
if (status != B_OK) {
printf("AddOnManager::RegisterAddOn(): BInputServerMethod.InitCheck in \"%s\" returned %s\n",
path.Path(), strerror(status));
PRINTERR(("AddOnManager::RegisterAddOn(): BInputServerMethod.InitCheck in \"%s\" returned %s\n",
path.Path(), strerror(status)));
delete ism;
goto exit_error;
}
@ -225,6 +225,11 @@ AddOnManager::UnregisterAddOn(BEntry &entry)
// we remove the method replicant
BDeskbar().RemoveItem(REPLICANT_CTL_NAME);
((InputServer*)be_app)->SetMethodReplicant(NULL);
} else {
BMessage msg(IS_REMOVE_METHOD);
msg.AddInt32("cookie", (uint32)pinfo->ism);
if (((InputServer*)be_app)->MethodReplicant())
((InputServer*)be_app)->MethodReplicant()->SendMessage(&msg);
}
}
@ -463,6 +468,16 @@ AddOnManager::RegisterMethod(BInputServerMethod *method, const entry_ref &ref, i
}
}
}
if (((InputServer*)be_app)->MethodReplicant()) {
_BMethodAddOn_ *addon = InputServer::gKeymapMethod.fOwner;
addon->AddMethod();
}
}
if (((InputServer*)be_app)->MethodReplicant()) {
_BMethodAddOn_ *addon = method->fOwner;
addon->AddMethod();
}
}

View File

@ -76,6 +76,8 @@ BLocker InputServer::gInputMethodListLocker("is_method_queue_sem");
DeviceManager InputServer::gDeviceManager;
KeymapMethod InputServer::gKeymapMethod;
#if DEBUG == 2
FILE *InputServer::sLogFile = NULL;
#endif
@ -168,8 +170,6 @@ InputServer::InputServer(void) : BApplication(INPUTSERVER_SIGNATURE),
fAddOnManager = new AddOnManager(SafeMode());
fAddOnManager->LoadState();
//BDeskbar().AddItem(new ::MethodReplicant);
BMessenger messenger(this);
BRoster().StartWatching(messenger, B_REQUEST_LAUNCHED);
}
@ -237,6 +237,8 @@ InputServer::InitKeyboardMouseStates(void)
BMessage *msg = new BMessage(B_MOUSE_MOVED);
HandleSetMousePosition(msg, msg);
fActiveMethod = &gKeymapMethod;
}
@ -506,10 +508,12 @@ InputServer::MessageReceived(BMessage *message)
void
InputServer::HandleSetMethod(BMessage *message)
{
int32 cookie;
if (message->FindInt32("cookie", &cookie) == B_OK) {
_BMethodAddOn_ *addon = (_BMethodAddOn_*)cookie;
SetActiveMethod(addon);
CALLED();
uint32 cookie;
if (message->FindInt32("cookie", (int32*)&cookie) == B_OK) {
BInputServerMethod *method = (BInputServerMethod*)cookie;
PRINT(("%s cookie %p\n", __PRETTY_FUNCTION__, method));
SetActiveMethod(method);
}
}
@ -928,13 +932,13 @@ InputServer::EnqueueMethodMessage(BMessage *message)
{
CALLED();
status_t err;
ssize_t length = message->FlattenedSize();
char buffer[length];
if ((err = message->Flatten(buffer,length)) < B_OK)
return err;
return write_port(fEventLooperPort, 0, buffer, length);
LockMethodQueue();
fMethodQueue.AddItem(message);
UnlockMethodQueue();
return B_OK;
}
@ -981,14 +985,16 @@ InputServer::SetNextMethod(bool)
* Descr:
*/
void
InputServer::SetActiveMethod(_BMethodAddOn_ *addon)
InputServer::SetActiveMethod(BInputServerMethod *method)
{
CALLED();
if (fActiveMethod)
fActiveMethod->MethodActivated(false);
fActiveMethod = addon;
fActiveMethod->fOwner->MethodActivated(false);
fActiveMethod = method;
if (fActiveMethod)
fActiveMethod->MethodActivated(true);
if (fActiveMethod) {
fActiveMethod->fOwner->MethodActivated(true);
}
}
@ -1292,6 +1298,8 @@ bool
InputServer::CacheEvents(BList *eventsToCache)
{
CALLED();
MethodizeEvents(eventsToCache, true);
FilterEvents(eventsToCache);
@ -1403,11 +1411,37 @@ InputServer::SanitizeEvents(BList *)
* Descr:
*/
bool
InputServer::MethodizeEvents(BList *,
InputServer::MethodizeEvents(BList *events,
bool)
{
CALLED();
if (fActiveMethod) {
BList newList;
for (int32 i=0; i<events->CountItems(); i++) {
BMessage *item = (BMessage *)events->ItemAt(i);
BList filterList;
filter_result res = fActiveMethod->Filter(item, &filterList);
switch (res) {
case B_SKIP_MESSAGE:
delete item;
case B_DISPATCH_MESSAGE:
if (filterList.CountItems()>0) {
newList.AddList(&filterList);
delete item;
} else
newList.AddItem(item);
}
newList.AddList(&fMethodQueue);
fMethodQueue.MakeEmpty();
}
events->MakeEmpty();
events->AddList(&newList);
}
return true;
}

View File

@ -87,6 +87,7 @@ class _BMethodAddOn_
status_t SetIcon(const uchar *icon);
status_t SetMenu(const BMenu *menu, const BMessenger &messenger);
status_t MethodActivated(bool activate);
status_t AddMethod();
private:
BInputServerMethod *fMethod;
char *fName;
@ -95,6 +96,15 @@ class _BMethodAddOn_
BMessenger fMessenger;
};
class KeymapMethod : public BInputServerMethod
{
public:
KeymapMethod();
~KeymapMethod();
};
/*****************************************************************************/
// InputServer
//
@ -114,7 +124,6 @@ public:
virtual bool QuitRequested(void);
virtual void ReadyToRun(void);
//thread_id Run(void);
virtual void MessageReceived(BMessage*);
void HandleSetMethod(BMessage*);
@ -139,7 +148,7 @@ public:
status_t UnlockMethodQueue(void);
status_t LockMethodQueue(void);
status_t SetNextMethod(bool);
void SetActiveMethod(_BMethodAddOn_*);
void SetActiveMethod(BInputServerMethod*);
const BMessenger* MethodReplicant(void);
void SetMethodReplicant(const BMessenger *);
status_t EventLoop();
@ -175,6 +184,8 @@ public:
static DeviceManager gDeviceManager;
static KeymapMethod gKeymapMethod;
BRect& ScreenFrame() { return fFrame;};
private:
status_t LoadKeymap();
@ -210,7 +221,8 @@ private:
BScreen fScreen;
BRect fFrame;
_BMethodAddOn_ *fActiveMethod;
BInputServerMethod *fActiveMethod;
BList fMethodQueue;
const BMessenger *fReplicantMessenger;
#ifndef COMPILE_FOR_R5

View File

@ -33,7 +33,7 @@
#include <Messenger.h>
#include "InputServer.h"
#include "InputServerTypes.h"
#include "remote_icon.h"
/**
* Method: BInputServerMethod::BInputServerMethod()
* Descr:
@ -173,52 +173,100 @@ _BMethodAddOn_::~_BMethodAddOn_()
status_t
_BMethodAddOn_::SetName(const char* name)
{
CALLED();
if (fName)
free(fName);
if (name)
fName = strdup(name);
BMessage msg(IS_UPDATE_NAME);
msg.AddInt32("cookie", (uint32)this);
msg.AddInt32("cookie", (uint32)fMethod);
msg.AddString("name", name);
return ((InputServer*)be_app)->MethodReplicant()->SendMessage(&msg);
if (((InputServer*)be_app)->MethodReplicant())
return ((InputServer*)be_app)->MethodReplicant()->SendMessage(&msg);
else
return B_ERROR;
}
status_t
_BMethodAddOn_::SetIcon(const uchar* icon)
{
{
CALLED();
memcpy(fIcon, icon, 16*16*1);
BMessage msg(IS_UPDATE_ICON);
msg.AddInt32("cookie", (uint32)this);
msg.AddInt32("cookie", (uint32)fMethod);
msg.AddData("icon", B_RAW_TYPE, icon, 16*16*1);
return ((InputServer*)be_app)->MethodReplicant()->SendMessage(&msg);
if (((InputServer*)be_app)->MethodReplicant())
return ((InputServer*)be_app)->MethodReplicant()->SendMessage(&msg);
else
return B_ERROR;
}
status_t
_BMethodAddOn_::SetMenu(const BMenu *menu, const BMessenger &messenger)
{
if (fMenu)
delete fMenu;
CALLED();
fMenu = menu;
fMessenger = messenger;
BMessage msg(IS_UPDATE_MENU);
msg.AddInt32("cookie", (uint32)this);
msg.AddInt32("cookie", (uint32)fMethod);
BMessage menuMsg;
menu->Archive(&menuMsg);
if (menu)
menu->Archive(&menuMsg);
msg.AddMessage("menu", &menuMsg);
msg.AddMessenger("target", messenger);
return ((InputServer*)be_app)->MethodReplicant()->SendMessage(&msg);
if (((InputServer*)be_app)->MethodReplicant())
return ((InputServer*)be_app)->MethodReplicant()->SendMessage(&msg);
else
return B_ERROR;
}
status_t
_BMethodAddOn_::MethodActivated(bool activate)
{
if (fMethod)
CALLED();
if (fMethod) {
PRINT(("%s cookie %p\n", __PRETTY_FUNCTION__, fMethod));
if (activate && ((InputServer*)be_app)->MethodReplicant()) {
BMessage msg(IS_UPDATE_METHOD);
msg.AddInt32("cookie", (uint32)fMethod);
((InputServer*)be_app)->MethodReplicant()->SendMessage(&msg);
}
return fMethod->MethodActivated(activate);
}
return B_ERROR;
}
status_t
_BMethodAddOn_::AddMethod()
{
PRINT(("%s cookie %p\n", __PRETTY_FUNCTION__, fMethod));
BMessage msg(IS_ADD_METHOD);
msg.AddInt32("cookie", (uint32)fMethod);
msg.AddString("name", fName);
msg.AddData("icon", B_RAW_TYPE, fIcon, 16*16*1);
if (((InputServer*)be_app)->MethodReplicant())
return ((InputServer*)be_app)->MethodReplicant()->SendMessage(&msg);
else
return B_ERROR;
}
KeymapMethod::KeymapMethod()
: BInputServerMethod("Roman", kRemoteBits)
{
}
KeymapMethod::~KeymapMethod()
{
}

View File

@ -148,6 +148,12 @@ MethodReplicant::MessageReceived(BMessage *message)
case IS_UPDATE_METHOD:
UpdateMethod(message);
break;
case IS_ADD_METHOD:
AddMethod(message);
break;
case IS_REMOVE_METHOD:
RemoveMethod(message);
break;
default:
BView::MessageReceived(message);
@ -176,14 +182,6 @@ MethodReplicant::MouseDown(BPoint point)
where = ConvertToScreen(point);
BMenuItem *tmpItem;
fMenu.AddItem(tmpItem = new MethodMenuItem(0, "Roman", kRemoteBits));
BMenu *otherMenu = new BMenu("Help");
otherMenu->AddItem(new BMenuItem("Help", NULL));
BMessenger messenger;
fMenu.AddItem(new MethodMenuItem(0x80029138, "Roman Roman", kRemoteBits, otherMenu, messenger));
tmpItem->SetMarked(true);
fMenu.SetTargetForItems(this);
MethodMenuItem *item = (MethodMenuItem*)fMenu.Go(where, true, true, BRect(where - BPoint(4, 4),
where + BPoint(4, 4)));
@ -219,6 +217,9 @@ MethodReplicant::UpdateMethod(BMessage *message)
return;
}
item->SetMarked(true);
fSegments->SetBits(item->Icon(), kRemoteWidth*kRemoteHeight, 0, kRemoteColorSpace);
Invalidate();
}
@ -227,23 +228,23 @@ MethodReplicant::UpdateMethodIcon(BMessage *message)
{
CALLED();
int32 cookie;
if (message->FindInt32("cookie", &cookie)!=B_OK) {
fprintf(stderr, "can't find cookie in message\n");
return;
}
if (message->FindInt32("cookie", &cookie)!=B_OK) {
fprintf(stderr, "can't find cookie in message\n");
return;
}
const uchar *data;
ssize_t numBytes;
if (message->FindData("icon", B_ANY_TYPE, (const void**)&data, &numBytes)!=B_OK) {
fprintf(stderr, "can't find icon in message\n");
return;
}
return;
}
MethodMenuItem *item = FindItemByCookie(cookie);
if (item == NULL) {
fprintf(stderr, "can't find item with cookie 0x%lx\n", cookie);
return;
}
if (item == NULL) {
fprintf(stderr, "can't find item with cookie 0x%lx\n", cookie);
return;
}
item->SetIcon(data);
}
@ -274,10 +275,9 @@ MethodReplicant::UpdateMethodMenu(BMessage *message)
BMenu *menu = (BMenu *)BMenu::Instantiate(&msg);
if (menu == NULL) {
fprintf(stderr, "can't instantiate menu\n");
return;
}
menu->SetTargetForItems(messenger);
PRINT(("can't instantiate menu\n"));
} else
menu->SetTargetForItems(messenger);
MethodMenuItem *item = FindItemByCookie(cookie);
if (item == NULL) {
@ -286,10 +286,16 @@ MethodReplicant::UpdateMethodMenu(BMessage *message)
}
int32 index = fMenu.IndexOf(item);
MethodMenuItem *item2 = new MethodMenuItem(cookie, item->Label(), item->Icon(),
menu, messenger);
fMenu.RemoveItem(index);
MethodMenuItem *item2 = NULL;
if (menu)
item2 = new MethodMenuItem(cookie, item->Label(), item->Icon(),
menu, messenger);
else
item2 = new MethodMenuItem(cookie, item->Label(), item->Icon());
item = (MethodMenuItem*)fMenu.RemoveItem(index);
fMenu.AddItem(item2, index);
item2->SetMarked(item->IsMarked());
delete item;
}
@ -298,22 +304,22 @@ MethodReplicant::UpdateMethodName(BMessage *message)
{
CALLED();
int32 cookie;
if (message->FindInt32("cookie", &cookie)!=B_OK) {
fprintf(stderr, "can't find cookie in message\n");
return;
}
if (message->FindInt32("cookie", &cookie)!=B_OK) {
fprintf(stderr, "can't find cookie in message\n");
return;
}
const char *name;
if (message->FindString("name", &name)!=B_OK) {
fprintf(stderr, "can't find name in message\n");
return;
}
fprintf(stderr, "can't find name in message\n");
return;
}
MethodMenuItem *item = FindItemByCookie(cookie);
if (item == NULL) {
fprintf(stderr, "can't find item with cookie 0x%lx\n", cookie);
return;
}
if (item == NULL) {
fprintf(stderr, "can't find item with cookie 0x%lx\n", cookie);
return;
}
item->SetName(name);
}
@ -332,3 +338,60 @@ MethodReplicant::FindItemByCookie(int32 cookie)
return NULL;
}
void
MethodReplicant::AddMethod(BMessage *message)
{
CALLED();
int32 cookie;
if (message->FindInt32("cookie", &cookie)!=B_OK) {
fprintf(stderr, "can't find cookie in message\n");
return;
}
const char *name;
if (message->FindString("name", &name)!=B_OK) {
fprintf(stderr, "can't find name in message\n");
return;
}
const uchar *icon;
ssize_t numBytes;
if (message->FindData("icon", B_ANY_TYPE, (const void**)&icon, &numBytes)!=B_OK) {
fprintf(stderr, "can't find icon in message\n");
return;
}
MethodMenuItem *item = FindItemByCookie(cookie);
if (item != NULL) {
fprintf(stderr, "item with cookie %lx already exists\n", cookie);
return;
}
item = new MethodMenuItem(cookie, name, icon);
fMenu.AddItem(item);
item->SetTarget(this);
if (fMenu.CountItems() == 1)
item->SetMarked(true);
}
void
MethodReplicant::RemoveMethod(BMessage *message)
{
CALLED();
int32 cookie;
if (message->FindInt32("cookie", &cookie)!=B_OK) {
fprintf(stderr, "can't find cookie in message\n");
return;
}
MethodMenuItem *item = FindItemByCookie(cookie);
if (item == NULL) {
fprintf(stderr, "can't find item with cookie %lx\n", cookie);
return;
}
fMenu.RemoveItem(item);
delete item;
}

View File

@ -55,6 +55,8 @@ private:
void UpdateMethodIcon(BMessage *);
void UpdateMethodMenu(BMessage *);
void UpdateMethodName(BMessage *);
void AddMethod(BMessage *message);
void RemoveMethod(BMessage *message);
MethodMenuItem *FindItemByCookie(int32 cookie);
};