The code for an handwriting input method front-end, currently doesn't do much more than draw the strokes over the screen. The idea is to have a base backend class that will be used to call several backends like Lipi Toolkit or others. WIP.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25997 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,256 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <BeBuild.h>
|
||||||
|
#include <Font.h>
|
||||||
|
#include <Message.h>
|
||||||
|
#include <String.h>
|
||||||
|
#include "DumpMessage.h"
|
||||||
|
|
||||||
|
//#define WHAT_ALWAYS_HEX 1
|
||||||
|
|
||||||
|
const char *msg_header_comment = "// new BMessage\n"; // avoids mime to think it's a .bmp ("BM")
|
||||||
|
|
||||||
|
// '_' also widely used in what codes
|
||||||
|
inline int myisprint(int c)
|
||||||
|
{
|
||||||
|
if (isalnum(c))
|
||||||
|
return 1;
|
||||||
|
return (c == '_')?1:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t HexDumpToStream(const void *data, size_t len, BDataIO &stream, const char *prefix = NULL)
|
||||||
|
{
|
||||||
|
const unsigned char *p = (unsigned char *)data;
|
||||||
|
char buffer[100];
|
||||||
|
size_t i, j;
|
||||||
|
for (i=0; i<len; i+=16) {
|
||||||
|
if (prefix) stream.Write(prefix, strlen(prefix));
|
||||||
|
sprintf(buffer, "0x%06lx: ", i);
|
||||||
|
stream.Write(buffer, strlen(buffer));
|
||||||
|
for (j=0; j<16; j++) {
|
||||||
|
if (i+j < len)
|
||||||
|
sprintf(buffer, "%02x", p[i+j]);
|
||||||
|
else
|
||||||
|
sprintf(buffer, " ");
|
||||||
|
if (j % 4 == 3)
|
||||||
|
sprintf(buffer+strlen(buffer), " ");
|
||||||
|
stream.Write(buffer, strlen(buffer));
|
||||||
|
}
|
||||||
|
sprintf(buffer, " '");
|
||||||
|
stream.Write(buffer, strlen(buffer));
|
||||||
|
for (j=0; j<16; j++) {
|
||||||
|
if (i+j >= len)
|
||||||
|
sprintf(buffer, " ");
|
||||||
|
//else if (p[i+j] < 255 && p[i+j] >= 0x20)
|
||||||
|
else if (isalpha(p[i+j]))
|
||||||
|
sprintf(buffer, "%c", p[i+j]);
|
||||||
|
else
|
||||||
|
sprintf(buffer, ".");
|
||||||
|
stream.Write(buffer, 1);
|
||||||
|
}
|
||||||
|
sprintf(buffer, "'\n");
|
||||||
|
stream.Write(buffer, strlen(buffer));
|
||||||
|
}
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* look up human readable names from an other BMessage */
|
||||||
|
bool LookUpFieldName(const char **name, const char *field_name, BMessage *names)
|
||||||
|
{
|
||||||
|
if (names == NULL)
|
||||||
|
return false;
|
||||||
|
if (names->FindString(field_name, name) == B_OK)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t DumpMessageToStream(BMessage *message, BDataIO &stream, int tabCount, BMessage *names)
|
||||||
|
{
|
||||||
|
int32 index;
|
||||||
|
void *cookie = NULL;
|
||||||
|
const char *field_name;
|
||||||
|
type_code field_code;
|
||||||
|
int32 field_count;
|
||||||
|
char buffer[80];
|
||||||
|
char tabs[20];
|
||||||
|
const char *easy_name;
|
||||||
|
|
||||||
|
if (message == NULL)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
if (tabCount < 1)
|
||||||
|
stream.Write(msg_header_comment, strlen(msg_header_comment));
|
||||||
|
|
||||||
|
memset(tabs, '\t', (++tabCount) + 1);
|
||||||
|
tabs[tabCount+1] = '\0';
|
||||||
|
//tabCount;
|
||||||
|
|
||||||
|
#ifndef WHAT_ALWAYS_HEX
|
||||||
|
if ( myisprint(message->what & 0x0ff) &&
|
||||||
|
myisprint((message->what >> 8) & 0x0ff) &&
|
||||||
|
myisprint((message->what >> 16) & 0x0ff) &&
|
||||||
|
myisprint((message->what >> 24) & 0x0ff))
|
||||||
|
sprintf(buffer, "BMessage('%c%c%c%c') {\n",
|
||||||
|
(char)(message->what >> 24) & 0x0ff,
|
||||||
|
(char)(message->what >> 16) & 0x0ff,
|
||||||
|
(char)(message->what >> 8) & 0x0ff,
|
||||||
|
(char)message->what & 0x0ff);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
sprintf(buffer, "BMessage(0x%08lx) {\n", message->what);
|
||||||
|
// stream.Write(tabs+2, tabCount-2);
|
||||||
|
stream.Write(buffer, strlen(buffer));
|
||||||
|
|
||||||
|
#ifdef B_BEOS_VERSION_DANO
|
||||||
|
while (message->GetNextName(&cookie,
|
||||||
|
&field_name,
|
||||||
|
&field_code,
|
||||||
|
&field_count) == B_OK) {
|
||||||
|
#else
|
||||||
|
#warning mem leak likely! (name=char *)
|
||||||
|
for (int which=0; message->GetInfo(B_ANY_TYPE, which,
|
||||||
|
(char **)&field_name, &field_code, &field_count) == B_OK; which++) {
|
||||||
|
#endif
|
||||||
|
if (LookUpFieldName(&easy_name, field_name, names)) {
|
||||||
|
stream.Write(tabs+1, tabCount);
|
||||||
|
stream.Write("// ", 3);
|
||||||
|
stream.Write(easy_name, strlen(easy_name));
|
||||||
|
stream.Write("\n", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (index=0; index < field_count; index++) {
|
||||||
|
stream.Write(tabs+1, tabCount);
|
||||||
|
stream.Write(field_name, strlen(field_name));
|
||||||
|
if (field_count > 1) {
|
||||||
|
sprintf(buffer, "[%ld]", index);
|
||||||
|
stream.Write(buffer, strlen(buffer));
|
||||||
|
}
|
||||||
|
stream.Write(" = ", 3);
|
||||||
|
|
||||||
|
switch (field_code) {
|
||||||
|
case 'MSGG':
|
||||||
|
{
|
||||||
|
BMessage m;
|
||||||
|
if (message->FindMessage(field_name, index, &m) >= B_OK)
|
||||||
|
DumpMessageToStream(&m, stream, tabCount, names);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#ifdef B_BEOS_VERSION_DANO
|
||||||
|
case 'FONt':
|
||||||
|
{
|
||||||
|
BFont f;
|
||||||
|
if (message->FindFlat(field_name, index, &f) >= B_OK)
|
||||||
|
stream << f;
|
||||||
|
stream.Write("\n", 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case B_RGB_COLOR_TYPE:
|
||||||
|
{
|
||||||
|
rgb_color c;
|
||||||
|
if (message->FindRGBColor(field_name, index, &c) >= B_OK) {
|
||||||
|
sprintf(buffer, "rgb_color(%d,%d,%d,%d)",
|
||||||
|
c.red, c.green, c.blue, c.alpha);
|
||||||
|
stream.Write(buffer, strlen(buffer));
|
||||||
|
}
|
||||||
|
stream.Write("\n", 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#else
|
||||||
|
#warning IMPLEMENT ME
|
||||||
|
#endif
|
||||||
|
case B_BOOL_TYPE:
|
||||||
|
{
|
||||||
|
bool value;
|
||||||
|
if (message->FindBool(field_name, index, &value) >= B_OK) {
|
||||||
|
sprintf(buffer, "bool(%s)", value?"true":"false");
|
||||||
|
stream.Write(buffer, strlen(buffer));
|
||||||
|
}
|
||||||
|
stream.Write("\n", 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case B_INT32_TYPE:
|
||||||
|
{
|
||||||
|
int32 value;
|
||||||
|
if (message->FindInt32(field_name, index, &value) >= B_OK) {
|
||||||
|
#if 1
|
||||||
|
if (value == 0)
|
||||||
|
sprintf(buffer, "int32(0 or (nil))");
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
// sprintf(buffer, "int32(%d)", value);
|
||||||
|
sprintf(buffer, "int32(%ld or 0x%lx)", value, value);
|
||||||
|
stream.Write(buffer, strlen(buffer));
|
||||||
|
}
|
||||||
|
stream.Write("\n", 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case B_FLOAT_TYPE:
|
||||||
|
{
|
||||||
|
float value;
|
||||||
|
if (message->FindFloat(field_name, index, &value) >= B_OK) {
|
||||||
|
sprintf(buffer, "float(%f)", value);
|
||||||
|
stream.Write(buffer, strlen(buffer));
|
||||||
|
}
|
||||||
|
stream.Write("\n", 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case B_STRING_TYPE:
|
||||||
|
{
|
||||||
|
const char *value;
|
||||||
|
if (message->FindString(field_name, index, &value) >= B_OK) {
|
||||||
|
BString str(value);
|
||||||
|
str.CharacterEscape("\\\"\n", '\\');
|
||||||
|
//sprintf(buffer, "string(\"%s\", %ld bytes)", str.String(), strlen(value));
|
||||||
|
// DO NOT use buffer!
|
||||||
|
str.Prepend("string(\"");
|
||||||
|
str << "\", " << strlen(value) << " bytes)";
|
||||||
|
stream.Write(str.String(), strlen(str.String()));
|
||||||
|
}
|
||||||
|
stream.Write("\n", 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case B_POINT_TYPE:
|
||||||
|
{
|
||||||
|
BPoint value;
|
||||||
|
if (message->FindPoint(field_name, index, &value) >= B_OK) {
|
||||||
|
sprintf(buffer, "BPoint(%1.1f, %1.1f)", value.x, value.y);
|
||||||
|
stream.Write(buffer, strlen(buffer));
|
||||||
|
}
|
||||||
|
stream.Write("\n", 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
const void *data;
|
||||||
|
ssize_t numBytes = 0;
|
||||||
|
if (message->FindData(field_name, field_code, index, &data, &numBytes) != B_OK) {
|
||||||
|
//stream.Write("\n", 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isalnum(field_code & 0x0ff) &&
|
||||||
|
isalnum((field_code >> 8) & 0x0ff) &&
|
||||||
|
isalnum((field_code >> 16) & 0x0ff) &&
|
||||||
|
isalnum((field_code >> 24) & 0x0ff))
|
||||||
|
sprintf(buffer, "'%c%c%c%c' %ld bytes:\n",
|
||||||
|
(char)(field_code >> 24) & 0x0ff,
|
||||||
|
(char)(field_code >> 16) & 0x0ff,
|
||||||
|
(char)(field_code >> 8) & 0x0ff,
|
||||||
|
(char)field_code & 0x0ff,
|
||||||
|
numBytes);
|
||||||
|
else
|
||||||
|
sprintf(buffer, "0x%08lx %ld bytes:\n", field_code, numBytes);
|
||||||
|
stream.Write(buffer, strlen(buffer));
|
||||||
|
stream.Write("\n", 1);
|
||||||
|
HexDumpToStream(data, numBytes, stream, tabs);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stream.Write(tabs+2, tabCount-1);
|
||||||
|
stream.Write("}\n", 2);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef _DUMP_MESSAGE_H
|
||||||
|
#define _DUMP_MESSAGE_H
|
||||||
|
|
||||||
|
class BMessage;
|
||||||
|
class BDataIO;
|
||||||
|
|
||||||
|
status_t DumpMessageToStream(BMessage *message, BDataIO &stream, int tabCount = 0, BMessage *names = NULL);
|
||||||
|
|
||||||
|
#endif /* _DUMP_MESSAGE_H */
|
||||||
|
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// will need better, stippi ?
|
||||||
|
// should have icons showing modes (word/char/num + caps)
|
||||||
|
const uchar PenIconData[] = {
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0x4b, 0x4b, 0x4b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0x4b, 0x4b, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x4b, 0x4b, 0x00, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0x4b, 0xff, 0xff, 0xff, 0xff, 0x00, 0x4b, 0x4b, 0x4b, 0x00, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0x4b, 0xff, 0xff, 0xff, 0x00, 0x4b, 0x4b, 0x4b, 0x00, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0x4b, 0x4b, 0xff, 0xff, 0x00, 0x4b, 0x4b, 0x4b, 0x00, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0x4b, 0x4b, 0x4b, 0xff, 0xff, 0x00, 0x4b, 0x4b, 0x4b, 0x00, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0x4b, 0xff, 0xff, 0xff, 0x00, 0x4b, 0x4b, 0x4b, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0x4b, 0x4b, 0xff, 0xff, 0x00, 0x4b, 0x4b, 0x4b, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x4b, 0x4b, 0xff, 0xff, 0x00, 0x4b, 0x4b, 0x4b, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x4b, 0xff, 0xff, 0x00, 0x4b, 0x4b, 0x4b, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x4b, 0xff, 0xff, 0x00, 0x4b, 0x4b, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x4b, 0x4b, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0x4b, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
||||||
|
};
|
||||||
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#include <OS.h>
|
||||||
|
#include "PenInputBackend.h"
|
||||||
|
|
||||||
|
|
||||||
|
PenInputBackend::PenInputBackend(const char *name)
|
||||||
|
: BHandler(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
PenInputBackend::~PenInputBackend()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#ifndef _PEN_INPUT_BACKEND_H
|
||||||
|
#define _PEN_INPUT_BACKEND_H
|
||||||
|
|
||||||
|
#include <Handler.h>
|
||||||
|
|
||||||
|
|
||||||
|
class PenInputBackend : public BHandler {
|
||||||
|
protected:
|
||||||
|
PenInputBackend(const char *name);
|
||||||
|
virtual ~PenInputBackend();
|
||||||
|
|
||||||
|
public:
|
||||||
|
status_t InitCheck() const { return fInitStatus; };
|
||||||
|
|
||||||
|
private:
|
||||||
|
status_t fInitStatus;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _PEN_INPUT_BACKEND_H */
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2007, Francois Revol. All Rights Reserved.
|
||||||
|
This file may be used under the terms of the Be Sample Code License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <OS.h>
|
||||||
|
#include <Debug.h>
|
||||||
|
#include <View.h>
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
//#include <File.h>
|
||||||
|
#include <Alert.h>
|
||||||
|
#include <Button.h>
|
||||||
|
#include <TextView.h>
|
||||||
|
#include <StringIO.h>
|
||||||
|
#include "DumpMessage.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "PenInputInkWindow.h"
|
||||||
|
#include "PenInputLooper.h"
|
||||||
|
#include "PenInputStrings.h"
|
||||||
|
|
||||||
|
const rgb_color kInkColor = { 100, 100, 255, 0 };
|
||||||
|
|
||||||
|
class PenInputInkView : public BView {
|
||||||
|
public:
|
||||||
|
PenInputInkView(BRect frame, PenInputInkWindow *window);
|
||||||
|
virtual ~PenInputInkView();
|
||||||
|
virtual void Draw(BRect udpateRect);
|
||||||
|
private:
|
||||||
|
PenInputInkWindow *fWindow;
|
||||||
|
};
|
||||||
|
|
||||||
|
PenInputInkView::PenInputInkView(BRect frame, PenInputInkWindow *window)
|
||||||
|
: BView(frame, "PenInkView", B_FOLLOW_ALL, B_WILL_DRAW),
|
||||||
|
fWindow(window)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
PenInputInkView::~PenInputInkView()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void PenInputInkView::Draw(BRect udpateRect)
|
||||||
|
{
|
||||||
|
/* ugh ? */
|
||||||
|
if (!fWindow)
|
||||||
|
return;
|
||||||
|
|
||||||
|
StrokeShape(&fWindow->fStrokes);
|
||||||
|
//DEBUG:StrokeRect(fWindow->fStrokes.Bounds());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PenInputInkWindow::PenInputInkWindow(BRect frame)
|
||||||
|
: BWindow(frame, "PenInputInkWindow",
|
||||||
|
B_NO_BORDER_WINDOW_LOOK,
|
||||||
|
B_FLOATING_ALL_WINDOW_FEEL,
|
||||||
|
B_NOT_MOVABLE | B_NOT_CLOSABLE | B_NOT_ZOOMABLE |
|
||||||
|
B_NOT_MINIMIZABLE | B_NOT_RESIZABLE | B_AVOID_FOCUS,
|
||||||
|
B_ALL_WORKSPACES),
|
||||||
|
fStrokeCount(0)
|
||||||
|
{
|
||||||
|
PRINT(("%s\n", __FUNCTION__));
|
||||||
|
fInkView = new PenInputInkView(Bounds(), this);
|
||||||
|
fInkView->SetViewColor(B_TRANSPARENT_32_BIT);
|
||||||
|
fInkView->SetLowColor(B_TRANSPARENT_32_BIT);
|
||||||
|
//fInkView->SetHighColor(0,255,0);
|
||||||
|
fInkView->SetHighColor(kInkColor);
|
||||||
|
fInkView->SetPenSize(2.0);
|
||||||
|
AddChild(fInkView);
|
||||||
|
}
|
||||||
|
|
||||||
|
PenInputInkWindow::~PenInputInkWindow()
|
||||||
|
{
|
||||||
|
PRINT(("%s\n", __FUNCTION__));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PenInputInkWindow::MessageReceived(BMessage *message)
|
||||||
|
{
|
||||||
|
BPoint where;
|
||||||
|
switch (message->what) {
|
||||||
|
case MSG_BEGIN_INK:
|
||||||
|
fStrokeCount = 0;
|
||||||
|
fStrokes.Clear();
|
||||||
|
// fall through
|
||||||
|
case MSG_SHOW_WIN:
|
||||||
|
if (IsHidden())
|
||||||
|
Show();
|
||||||
|
break;
|
||||||
|
case MSG_END_INK:
|
||||||
|
case MSG_HIDE_WIN:
|
||||||
|
if (!IsHidden())
|
||||||
|
Hide();
|
||||||
|
break;
|
||||||
|
case B_MOUSE_MOVED:
|
||||||
|
if (message->FindPoint("where", &where) == B_OK) {
|
||||||
|
fStrokes.LineTo(where);
|
||||||
|
fStrokeCount++;
|
||||||
|
//fInkView->Invalidate(fStrokes.Bounds()); // XXX
|
||||||
|
fInkView->Invalidate(Bounds()); // XXX
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case B_MOUSE_UP:
|
||||||
|
if (message->FindPoint("where", &where) == B_OK) {
|
||||||
|
fStrokes.LineTo(where);
|
||||||
|
fStrokeCount++;
|
||||||
|
//fInkView->Invalidate(fStrokes.Bounds()); // XXX
|
||||||
|
fInkView->Invalidate(Bounds()); // XXX
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case B_MOUSE_DOWN:
|
||||||
|
if (message->FindPoint("where", &where) == B_OK) {
|
||||||
|
fStrokes.MoveTo(where);
|
||||||
|
//fStrokeCount++;
|
||||||
|
//fInkView->Invalidate(fStrokes.Bounds()); // XXX
|
||||||
|
fInkView->Invalidate(Bounds()); // XXX
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BWindow::MessageReceived(message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2005, Francois Revol. All Rights Reserved.
|
||||||
|
This file may be used under the terms of the Be Sample Code License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Window.h>
|
||||||
|
#include <Shape.h>
|
||||||
|
|
||||||
|
class PenInputInkView;
|
||||||
|
|
||||||
|
class PenInputInkWindow : public BWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PenInputInkWindow(BRect frame);
|
||||||
|
virtual ~PenInputInkWindow();
|
||||||
|
void MessageReceived(BMessage *message);
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class PenInputInkView;
|
||||||
|
friend class PenInputLooper;//DEBUG
|
||||||
|
void ClearStrokes();
|
||||||
|
PenInputInkView *fInkView;
|
||||||
|
BShape fStrokes;
|
||||||
|
int32 fStrokeCount;
|
||||||
|
};
|
||||||
|
|
||||||
@@ -0,0 +1,255 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2007, Francois Revol. All Rights Reserved.
|
||||||
|
This file may be used under the terms of the Be Sample Code License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DEBUG 1
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include <Debug.h>
|
||||||
|
#include <List.h>
|
||||||
|
#include <Message.h>
|
||||||
|
#include <OS.h>
|
||||||
|
|
||||||
|
#include <Application.h>
|
||||||
|
#include <Menu.h>
|
||||||
|
#include <MenuItem.h>
|
||||||
|
#include <MessageRunner.h>
|
||||||
|
#include <Region.h>
|
||||||
|
#include <Screen.h>
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
//#include <File.h>
|
||||||
|
#include <Alert.h>
|
||||||
|
#include <Button.h>
|
||||||
|
#include <TextView.h>
|
||||||
|
#include <StringIO.h>
|
||||||
|
#include "DumpMessage.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "PenInputLooper.h"
|
||||||
|
#include "PenInputBackend.h"
|
||||||
|
#include "PenInputInkWindow.h"
|
||||||
|
#include "PenInputServerMethod.h"
|
||||||
|
#include "PenInputStrings.h"
|
||||||
|
|
||||||
|
PenInputLooper::PenInputLooper(PenInputServerMethod *method)
|
||||||
|
: BLooper("PenInputLooper", B_NORMAL_PRIORITY),
|
||||||
|
fOwner(method),
|
||||||
|
fInkWindow(NULL),
|
||||||
|
fBackend(NULL),
|
||||||
|
fDeskbarMenu(NULL),
|
||||||
|
fMouseDown(false),
|
||||||
|
fStroking(false),
|
||||||
|
fThresholdRunner(NULL),
|
||||||
|
fCachedMouseDown(NULL),
|
||||||
|
fShowInk(true),
|
||||||
|
fMouseDownThreshold(100000)
|
||||||
|
{
|
||||||
|
PRINT(("%s\n", __FUNCTION__));
|
||||||
|
|
||||||
|
//
|
||||||
|
fDeskbarMenu = new BMenu(_T("Options"));
|
||||||
|
BMenu *subMenu;
|
||||||
|
|
||||||
|
|
||||||
|
subMenu = new BMenu(_T("Backend"));
|
||||||
|
|
||||||
|
BMessage *msg;
|
||||||
|
msg = new BMessage(MSG_SET_BACKEND);
|
||||||
|
BMenuItem *item;
|
||||||
|
// for (i = 0; i < fBackends.CountItems(); i++) ...
|
||||||
|
item = new BMenuItem(_T("Default"), msg);
|
||||||
|
item->SetMarked(true);
|
||||||
|
subMenu->AddItem(item);
|
||||||
|
|
||||||
|
item = new BMenuItem(subMenu);
|
||||||
|
fDeskbarMenu->AddItem(item);
|
||||||
|
|
||||||
|
msg = new BMessage(MSG_SHOW_INK);
|
||||||
|
item = new BMenuItem(_T("Show Ink"), msg);
|
||||||
|
item->SetMarked(true);
|
||||||
|
fDeskbarMenu->AddItem(item);
|
||||||
|
|
||||||
|
fDeskbarMenu->SetFont(be_plain_font);
|
||||||
|
fOwner->SetMenu(fDeskbarMenu, BMessenger(NULL, this));
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
BRegion region;
|
||||||
|
fOwner->GetScreenRegion(®ion);
|
||||||
|
fInkWindow = new PenInputInkWindow(region.Frame());
|
||||||
|
#endif
|
||||||
|
BScreen screen;
|
||||||
|
fInkWindow = new PenInputInkWindow(screen.Frame());
|
||||||
|
fInkWindow->Show();
|
||||||
|
fInkWindow->Lock();
|
||||||
|
fInkWindow->Hide();
|
||||||
|
fInkWindow->Unlock();
|
||||||
|
fInkWindowMsgr = BMessenger(NULL, fInkWindow);
|
||||||
|
|
||||||
|
BMessage m(MSG_CHECK_PEN_DOWN);
|
||||||
|
fThresholdRunner = new BMessageRunner(BMessenger(NULL, this), &m, fMouseDownThreshold, 0);
|
||||||
|
|
||||||
|
Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PenInputLooper::Quit()
|
||||||
|
{
|
||||||
|
PRINT(("%s\n", __FUNCTION__));
|
||||||
|
delete fThresholdRunner;
|
||||||
|
fInkWindow->Lock();
|
||||||
|
fInkWindow->Quit();
|
||||||
|
fOwner->SetMenu(NULL, BMessenger());
|
||||||
|
delete fDeskbarMenu;
|
||||||
|
BLooper::Quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PenInputLooper::DispatchMessage(BMessage *message, BHandler *handler)
|
||||||
|
{
|
||||||
|
switch (message->what) {
|
||||||
|
#if 0
|
||||||
|
case B_MOUSE_MOVED:
|
||||||
|
case B_MOUSE_DOWN:
|
||||||
|
case B_MOUSE_UP:
|
||||||
|
|
||||||
|
case B_INPUT_METHOD_EVENT:
|
||||||
|
//case B_REPLY:
|
||||||
|
if (fBackend) {
|
||||||
|
fBackend->MessageReceived(message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
return BLooper::DispatchMessage(message, handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PenInputLooper::MessageReceived(BMessage *message)
|
||||||
|
{
|
||||||
|
int32 v;
|
||||||
|
int32 buttons;
|
||||||
|
bool b;
|
||||||
|
#if 1
|
||||||
|
{
|
||||||
|
//message->Flatten(&fDebugFile);
|
||||||
|
BStringIO sio;
|
||||||
|
DumpMessageToStream(message, sio);
|
||||||
|
fInkWindow->Lock();
|
||||||
|
sio << BString("StrokesCount: ");
|
||||||
|
BString tmp;
|
||||||
|
tmp << fInkWindow->fStrokeCount;
|
||||||
|
sio << tmp;
|
||||||
|
sio << BString("\nStrokes.Bounds: ");
|
||||||
|
sio << (fInkWindow->fStrokes.Bounds());
|
||||||
|
sio << BString("\n");
|
||||||
|
fInkWindow->Unlock();
|
||||||
|
fOwner->fDebugAlert->Lock();
|
||||||
|
fOwner->fDebugAlert->TextView()->Insert("Looper:\n");
|
||||||
|
fOwner->fDebugAlert->TextView()->Insert(sio.String());
|
||||||
|
fOwner->fDebugAlert->Unlock();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
switch (message->what) {
|
||||||
|
case MSG_CHECK_PEN_DOWN:
|
||||||
|
if (fCachedMouseDown) {
|
||||||
|
/* nothing happened, we want to move the mouse */
|
||||||
|
EnqueueMessage(fCachedMouseDown);
|
||||||
|
fCachedMouseDown = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case B_MOUSE_MOVED:
|
||||||
|
if (!fMouseDown) { /* definitely not writing */
|
||||||
|
/* pass it along */
|
||||||
|
EnqueueMessage(DetachCurrentMessage());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (fShowInk) {
|
||||||
|
BMessage *msg = new BMessage(*message);
|
||||||
|
fInkWindowMsgr.SendMessage(msg);
|
||||||
|
}
|
||||||
|
if (fBackend)
|
||||||
|
fBackend->MessageReceived(message);
|
||||||
|
else
|
||||||
|
EnqueueMessage(DetachCurrentMessage());
|
||||||
|
break;
|
||||||
|
case B_MOUSE_DOWN:
|
||||||
|
if (message->FindInt32("buttons", &buttons) == B_OK) {
|
||||||
|
if (!(buttons & B_PRIMARY_MOUSE_BUTTON)) {
|
||||||
|
/* pass it along */
|
||||||
|
EnqueueMessage(DetachCurrentMessage());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fMouseDown = true;
|
||||||
|
if (fShowInk) {
|
||||||
|
{
|
||||||
|
BMessage *msg = new BMessage(MSG_BEGIN_INK);
|
||||||
|
fInkWindowMsgr.SendMessage(msg);
|
||||||
|
}
|
||||||
|
BMessage *msg = new BMessage(*message);
|
||||||
|
fInkWindowMsgr.SendMessage(msg);
|
||||||
|
}
|
||||||
|
if (fBackend)
|
||||||
|
fBackend->MessageReceived(message);
|
||||||
|
break;
|
||||||
|
case B_MOUSE_UP:
|
||||||
|
if (message->FindInt32("buttons", &buttons) == B_OK) {
|
||||||
|
if (!fMouseDown || (buttons & B_PRIMARY_MOUSE_BUTTON)) {
|
||||||
|
/* pass it along */
|
||||||
|
EnqueueMessage(DetachCurrentMessage());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fMouseDown = false;
|
||||||
|
if (fShowInk) {
|
||||||
|
BMessage *msg = new BMessage(*message);
|
||||||
|
fInkWindowMsgr.SendMessage(msg);
|
||||||
|
{
|
||||||
|
BMessage *msg = new BMessage(MSG_END_INK);
|
||||||
|
fInkWindowMsgr.SendMessage(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fBackend)
|
||||||
|
fBackend->MessageReceived(message);
|
||||||
|
break;
|
||||||
|
case B_INPUT_METHOD_EVENT:
|
||||||
|
if (fBackend)
|
||||||
|
fBackend->MessageReceived(message);
|
||||||
|
break;
|
||||||
|
case MSG_METHOD_ACTIVATED:
|
||||||
|
if (message->FindBool(MSGF_ACTIVE, &b) < B_OK)
|
||||||
|
b = false;
|
||||||
|
HandleMethodActivated(b);
|
||||||
|
break;
|
||||||
|
case B_REPLY:
|
||||||
|
|
||||||
|
default:
|
||||||
|
BLooper::MessageReceived(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PenInputLooper::EnqueueMessage(BMessage *message)
|
||||||
|
{
|
||||||
|
fOwner->EnqueueMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t PenInputLooper::InitCheck()
|
||||||
|
{
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PenInputLooper::HandleMethodActivated(bool active)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
if (fShowInk && active)
|
||||||
|
fInkWindowMsgr.SendMessage(MSG_SHOW_WIN);
|
||||||
|
if (fShowInk && !active)
|
||||||
|
fInkWindowMsgr.SendMessage(MSG_END_INK);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2007, Francois Revol. All Rights Reserved.
|
||||||
|
This file may be used under the terms of the Be Sample Code License.
|
||||||
|
*/
|
||||||
|
#ifndef _PEN_INPUT_LOOPER_H
|
||||||
|
#define _PEN_INPUT_LOOPER_H
|
||||||
|
|
||||||
|
#include <MessageRunner.h>
|
||||||
|
#include <Messenger.h>
|
||||||
|
#include <Looper.h>
|
||||||
|
|
||||||
|
/* internal messages */
|
||||||
|
|
||||||
|
#define MSG_METHOD_ACTIVATED 'IMAc'
|
||||||
|
#define MSGF_ACTIVE "active" /* bool */
|
||||||
|
|
||||||
|
#define MSG_BEGIN_INK 'InkB'
|
||||||
|
#define MSG_END_INK 'InkE'
|
||||||
|
|
||||||
|
#define MSG_SHOW_WIN 'ShoW'
|
||||||
|
#define MSG_HIDE_WIN 'HidW'
|
||||||
|
|
||||||
|
#define MSG_CHECK_PEN_DOWN 'ChkP'
|
||||||
|
|
||||||
|
/* menu messages */
|
||||||
|
|
||||||
|
#define MSG_SET_BACKEND 'SetB'
|
||||||
|
#define MSGF_BACKEND "backend" /* string */
|
||||||
|
|
||||||
|
#define MSG_SHOW_INK 'InkS' /* toggle */
|
||||||
|
|
||||||
|
|
||||||
|
class BMenu;
|
||||||
|
class BWindow;
|
||||||
|
class PenInputServerMethod;
|
||||||
|
class PenInputInkWindow;
|
||||||
|
class PenInputBackend;
|
||||||
|
|
||||||
|
class PenInputLooper : public BLooper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PenInputLooper(PenInputServerMethod *method);
|
||||||
|
virtual void Quit();
|
||||||
|
void DispatchMessage(BMessage *message, BHandler *handler);
|
||||||
|
void MessageReceived(BMessage *message);
|
||||||
|
void EnqueueMessage(BMessage *message);
|
||||||
|
status_t InitCheck();
|
||||||
|
|
||||||
|
// virtual ~PenInputLooper();
|
||||||
|
void MethodActivated(bool active);
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class PenInputInkWindow;
|
||||||
|
void HandleMethodActivated(bool active);
|
||||||
|
PenInputServerMethod *fOwner;
|
||||||
|
PenInputInkWindow *fInkWindow;
|
||||||
|
PenInputBackend *fBackend;
|
||||||
|
BMenu *fDeskbarMenu;
|
||||||
|
BMessenger fInkWindowMsgr;
|
||||||
|
bool fMouseDown;
|
||||||
|
bool fStroking;
|
||||||
|
BMessageRunner *fThresholdRunner;
|
||||||
|
BMessage *fCachedMouseDown;
|
||||||
|
/* config */
|
||||||
|
bool fShowInk;
|
||||||
|
bigtime_t fMouseDownThreshold;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _PEN_INPUT_LOOPER_H */
|
||||||
@@ -0,0 +1,217 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2007, Francois Revol. All Rights Reserved.
|
||||||
|
This file may be used under the terms of the Be Sample Code License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//#define DEBUG 1
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include <Debug.h>
|
||||||
|
#include <List.h>
|
||||||
|
#include <Message.h>
|
||||||
|
#include <OS.h>
|
||||||
|
|
||||||
|
#include <Application.h>
|
||||||
|
#include <Menu.h>
|
||||||
|
#include <MenuItem.h>
|
||||||
|
#include <Region.h>
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
//#include <File.h>
|
||||||
|
#include <Alert.h>
|
||||||
|
#include <Button.h>
|
||||||
|
#include <TextView.h>
|
||||||
|
#include <StringIO.h>
|
||||||
|
#include "DumpMessage.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <add-ons/input_server/InputServerDevice.h>
|
||||||
|
#include <add-ons/input_server/InputServerMethod.h>
|
||||||
|
|
||||||
|
#include "PenIcon.h"
|
||||||
|
|
||||||
|
#include "PenInputServerMethod.h"
|
||||||
|
#include "PenInputLooper.h"
|
||||||
|
#include "PenInputStrings.h"
|
||||||
|
|
||||||
|
BInputServerMethod* instantiate_input_method()
|
||||||
|
{
|
||||||
|
PRINT(("%s\n", __FUNCTION__));
|
||||||
|
return (new PenInputServerMethod());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PenInputServerMethod::PenInputServerMethod()
|
||||||
|
: BInputServerMethod("Pen", PenIconData),
|
||||||
|
fEnabled(false)
|
||||||
|
{
|
||||||
|
PRINT(("%s\n", __FUNCTION__));
|
||||||
|
#if DEBUG
|
||||||
|
//fDebugFile.SetTo("/tmp/PenInputMethodMessages.txt", B_READ_WRITE|B_CREATE_FILE);
|
||||||
|
fDebugAlert = new BAlert("PenInput Debug", "Plip \n\n\n\n\n\n\n\n\n\n\n\n\n", "Ok");
|
||||||
|
fDebugAlert->SetLook(B_TITLED_WINDOW_LOOK);
|
||||||
|
fDebugAlert->TextView()->MakeSelectable();
|
||||||
|
fDebugAlert->TextView()->SelectAll();
|
||||||
|
fDebugAlert->TextView()->Delete();
|
||||||
|
fDebugAlert->ButtonAt(0)->SetEnabled(false);
|
||||||
|
BRegion r;
|
||||||
|
GetScreenRegion(&r);
|
||||||
|
BString s;
|
||||||
|
s << r.CountRects() << " rects\n";
|
||||||
|
fDebugAlert->TextView()->Insert(s.String());
|
||||||
|
fDebugAlert->Go(NULL);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
PenInputServerMethod::~PenInputServerMethod()
|
||||||
|
{
|
||||||
|
PRINT(("%s\n", __FUNCTION__));
|
||||||
|
SetMenu(NULL, BMessenger());
|
||||||
|
#if DEBUG
|
||||||
|
fDebugAlert->Lock();
|
||||||
|
fDebugAlert->Quit();
|
||||||
|
#endif
|
||||||
|
BLooper *looper = NULL;
|
||||||
|
fLooper.Target(&looper);
|
||||||
|
if (looper != NULL)
|
||||||
|
{
|
||||||
|
if (looper->Lock())
|
||||||
|
looper->Quit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t PenInputServerMethod::InitCheck()
|
||||||
|
{
|
||||||
|
PenInputLooper *looper;
|
||||||
|
status_t err;
|
||||||
|
PRINT(("%s\n", __FUNCTION__));
|
||||||
|
looper = new PenInputLooper(this);
|
||||||
|
looper->Lock();
|
||||||
|
err = looper->InitCheck();
|
||||||
|
looper->Unlock();
|
||||||
|
fLooper = BMessenger(NULL, looper);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
filter_result PenInputServerMethod::Filter(BMessage *message, BList *outList)
|
||||||
|
{
|
||||||
|
status_t err;
|
||||||
|
filter_result res = B_DISPATCH_MESSAGE;
|
||||||
|
|
||||||
|
if (!IsEnabled())
|
||||||
|
return B_DISPATCH_MESSAGE;
|
||||||
|
|
||||||
|
|
||||||
|
#if 0//DEBUG
|
||||||
|
//message->Flatten(&fDebugFile);
|
||||||
|
BStringIO sio;
|
||||||
|
DumpMessageToStream(message, sio);
|
||||||
|
fDebugAlert->Lock();
|
||||||
|
fDebugAlert->TextView()->Insert(sio.String());
|
||||||
|
fDebugAlert->Unlock();
|
||||||
|
#endif
|
||||||
|
switch (message->what) {
|
||||||
|
case B_KEY_UP:
|
||||||
|
case B_KEY_DOWN:
|
||||||
|
case B_UNMAPPED_KEY_UP:
|
||||||
|
case B_UNMAPPED_KEY_DOWN:
|
||||||
|
case B_MODIFIERS_CHANGED:
|
||||||
|
case B_MOUSE_WHEEL_CHANGED:
|
||||||
|
return B_DISPATCH_MESSAGE;
|
||||||
|
default:
|
||||||
|
//case B_MOUSE_MOVED:
|
||||||
|
fLooper.SendMessage(message);
|
||||||
|
return B_SKIP_MESSAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (message->what == B_MOUSE_MOVED) {
|
||||||
|
BMessage *mDown = new BMessage(B_KEY_DOWN);
|
||||||
|
BMessage *mUp;
|
||||||
|
char states[16];
|
||||||
|
mDown->AddInt32("modifiers", 0x0);
|
||||||
|
mDown->AddInt32("key", 94);
|
||||||
|
mDown->AddInt32("raw_char", 32);
|
||||||
|
mDown->AddData("states", 'UBYT', states, sizeof(states));
|
||||||
|
mDown->AddString("bytes", " ");
|
||||||
|
mDown->AddData("byte", 'BYTE', " ", 1);
|
||||||
|
mUp = new BMessage(*mDown);
|
||||||
|
mUp->what = B_KEY_UP;
|
||||||
|
outList->AddItem(mDown);
|
||||||
|
outList->AddItem(mUp);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (message->what == B_MOUSE_DOWN) {
|
||||||
|
int32 buttons;
|
||||||
|
int32 modifiers;
|
||||||
|
BPoint where;
|
||||||
|
if (message->FindInt32("buttons", &buttons) == B_OK) {
|
||||||
|
/* replace first with a button that likely won't exist,
|
||||||
|
* and so shouldn't cause any side effect (hmm err...) */
|
||||||
|
/* XXX: use get_mouse_map() ? */
|
||||||
|
if (buttons == B_PRIMARY_MOUSE_BUTTON)
|
||||||
|
//message->ReplaceInt32("buttons", 0x0000);
|
||||||
|
message->what = B_MOUSE_UP;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
outList->AddItem(new BMessage(*message));
|
||||||
|
BMessage *m = new BMessage(B_MOUSE_MOVED);
|
||||||
|
if (message->FindInt32("buttons", &buttons) == B_OK)
|
||||||
|
m->AddInt32("buttons", buttons);
|
||||||
|
if (message->FindInt32("modifiers", &modifiers) == B_OK)
|
||||||
|
m->AddInt32("modifiers", modifiers);
|
||||||
|
if (message->FindPoint("where", &where) == B_OK)
|
||||||
|
m->AddPoint("where", where);
|
||||||
|
outList->AddItem(m);
|
||||||
|
#endif
|
||||||
|
#if DEBUG
|
||||||
|
fDebugAlert->Lock();
|
||||||
|
fDebugAlert->TextView()->Insert(">>>\n");
|
||||||
|
fDebugAlert->Unlock();
|
||||||
|
#endif
|
||||||
|
#if 0
|
||||||
|
m = new BMessage(B_INPUT_METHOD_EVENT);
|
||||||
|
m->AddInt32("be:opcode", B_INPUT_METHOD_STARTED);
|
||||||
|
m->AddMessenger("be:reply_to", this);
|
||||||
|
EnqueueMessage(m);
|
||||||
|
m = new BMessage(B_INPUT_METHOD_EVENT);
|
||||||
|
m->AddInt32("be:opcode", B_INPUT_METHOD_LOCATION_REQUEST);
|
||||||
|
m->AddString("be:string", " ");
|
||||||
|
EnqueueMessage(m);
|
||||||
|
m = new BMessage(B_INPUT_METHOD_EVENT);
|
||||||
|
m->AddInt32("be:opcode", B_INPUT_METHOD_STOPPED);
|
||||||
|
EnqueueMessage(m);
|
||||||
|
sleep(3);
|
||||||
|
#endif
|
||||||
|
#if DEBUG
|
||||||
|
fDebugAlert->Lock();
|
||||||
|
fDebugAlert->TextView()->Insert("<<<\n");
|
||||||
|
fDebugAlert->Unlock();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return (res);
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t PenInputServerMethod::MethodActivated(bool active)
|
||||||
|
{
|
||||||
|
fEnabled = active;
|
||||||
|
|
||||||
|
BMessage msg(MSG_METHOD_ACTIVATED);
|
||||||
|
if (active)
|
||||||
|
msg.AddBool(MSGF_ACTIVE, true);
|
||||||
|
fLooper.SendMessage( &msg );
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2005, Francois Revol. All Rights Reserved.
|
||||||
|
This file may be used under the terms of the Be Sample Code License.
|
||||||
|
*/
|
||||||
|
#ifndef _PEN_INPUT_SERVER_METHOD_H
|
||||||
|
#define _PEN_INPUT_SERVER_METHOD_H
|
||||||
|
|
||||||
|
#include <OS.h>
|
||||||
|
#include <Messenger.h>
|
||||||
|
#include <add-ons/input_server/InputServerMethod.h>
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
//#include <File.h>
|
||||||
|
class BAlert;
|
||||||
|
#endif
|
||||||
|
class BList;
|
||||||
|
class BMessage;
|
||||||
|
class PenInputLooper;
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" _EXPORT BInputServerMethod* instantiate_input_method();
|
||||||
|
|
||||||
|
class PenInputServerMethod : public BInputServerMethod
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PenInputServerMethod();
|
||||||
|
virtual ~PenInputServerMethod();
|
||||||
|
virtual status_t InitCheck();
|
||||||
|
virtual filter_result Filter(BMessage *message, BList *outList);
|
||||||
|
virtual status_t MethodActivated(bool active);
|
||||||
|
|
||||||
|
bool IsEnabled() const { return fEnabled; };
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend PenInputLooper;//DEBUG
|
||||||
|
bool fEnabled;
|
||||||
|
//BLocker fLocker;
|
||||||
|
BMessenger fLooper;
|
||||||
|
#if DEBUG
|
||||||
|
//BFile fDebugFile;
|
||||||
|
BAlert *fDebugAlert;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _PEN_INPUT_SERVER_METHOD_H */
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
#ifndef _PEN_INPUT_STRINGS_H
|
||||||
|
#define _PEN_INPUT_STRINGS_H
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _T
|
||||||
|
#define _T(s) s
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* more to come */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _PEN_INPUT_STRINGS_H */
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
quit application/x-vnd.Be-input_server
|
||||||
|
|
||||||
|
tagfile=/tmp/dokillinputserver
|
||||||
|
tmout=$((30))
|
||||||
|
|
||||||
|
touch $tagfile
|
||||||
|
(alert "All is fine" "Ok"; rm $tagfile) &
|
||||||
|
|
||||||
|
sleep $tmout
|
||||||
|
|
||||||
|
if [ -e $tagfile ]; then
|
||||||
|
rm ~/config/add-ons/input_server/methods/Pen
|
||||||
|
quit application/x-vnd.Be-input_server
|
||||||
|
kill -9 input_server
|
||||||
|
rm $tagfile
|
||||||
|
fi
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
/system/servers/input_server
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* minimalistic Dano-like BStringIO
|
||||||
|
* (c) 2007, François Revol.
|
||||||
|
*/
|
||||||
|
#include <BeBuild.h>
|
||||||
|
#ifndef B_BEOS_VERSION_DANO
|
||||||
|
|
||||||
|
#include <StringIO.h>
|
||||||
|
#include <Rect.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
//#include <stdint.h>
|
||||||
|
|
||||||
|
// stripped down BStringIO
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BStringIO::BStringIO()
|
||||||
|
{
|
||||||
|
fString = new BString;
|
||||||
|
}
|
||||||
|
|
||||||
|
BStringIO::~BStringIO()
|
||||||
|
{
|
||||||
|
delete fString;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
BStringIO::ReadAt(off_t pos, void *buffer, size_t size)
|
||||||
|
{
|
||||||
|
return EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
BStringIO::WriteAt(off_t pos, const void *buffer, size_t size)
|
||||||
|
{
|
||||||
|
if (pos > (2147483647L)/*INT32_MAX*/)
|
||||||
|
return EINVAL;
|
||||||
|
if (fString->Length() < pos)
|
||||||
|
fString->Insert(' ', (int32)(pos - fString->Length()), fString->Length());
|
||||||
|
fString->Remove((int32)pos, size);
|
||||||
|
fString->Insert((const char *)buffer, size, (int32)pos);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
off_t
|
||||||
|
BStringIO::Seek(off_t pos, uint32 seek_mode)
|
||||||
|
{
|
||||||
|
switch (seek_mode) {
|
||||||
|
case SEEK_CUR:
|
||||||
|
fPosition += pos;
|
||||||
|
return fPosition;
|
||||||
|
case SEEK_SET:
|
||||||
|
fPosition = pos;
|
||||||
|
return fPosition;
|
||||||
|
case SEEK_END:
|
||||||
|
fPosition = fString->Length() - pos;
|
||||||
|
if (fPosition < 0)
|
||||||
|
fPosition = 0;
|
||||||
|
return fPosition;
|
||||||
|
default:
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
off_t
|
||||||
|
BStringIO::Position() const
|
||||||
|
{
|
||||||
|
return fPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BStringIO::SetSize(off_t size)
|
||||||
|
{
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
BStringIO::String() const
|
||||||
|
{
|
||||||
|
return fString->String();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ops
|
||||||
|
BStringIO & BStringIO::operator<<(const BString & s) {this->BPositionIO::Write(s.String(), s.Length()); return *this;};
|
||||||
|
BStringIO & BStringIO::operator<<(const BRect & r) {BString s; s << "Rect{" << r.left << r.top << r.right << r.bottom << "}"; this->BPositionIO::Write(s.String(), s.Length()); return *this;};
|
||||||
|
|
||||||
|
#endif /* B_BEOS_VERSION_DANO */
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* minimalistic Dano-ilke BStringIO
|
||||||
|
* (c) 2007, François Revol.
|
||||||
|
*/
|
||||||
|
#include <BeBuild.h>
|
||||||
|
#ifdef B_BEOS_VERSION_DANO
|
||||||
|
#include_next <StringIO.h>
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifndef _STRING_IO_H
|
||||||
|
#define _STRING_IO_H
|
||||||
|
|
||||||
|
#include <String.h>
|
||||||
|
#include <DataIO.h>
|
||||||
|
//#include <stdint.h>
|
||||||
|
|
||||||
|
// stripped down BStringIO
|
||||||
|
|
||||||
|
class BStringIO : public BPositionIO {
|
||||||
|
public:
|
||||||
|
BStringIO();
|
||||||
|
virtual ~BStringIO();
|
||||||
|
|
||||||
|
virtual ssize_t ReadAt(off_t pos, void *buffer, size_t size);
|
||||||
|
virtual ssize_t WriteAt(off_t pos, const void *buffer, size_t size);
|
||||||
|
|
||||||
|
virtual off_t Seek(off_t pos, uint32 seek_mode);
|
||||||
|
virtual off_t Position() const;
|
||||||
|
virtual status_t SetSize(off_t size);
|
||||||
|
|
||||||
|
// void SetBlockSize(size_t blocksize);
|
||||||
|
|
||||||
|
const char* String() const;
|
||||||
|
// size_t StringLength() const;
|
||||||
|
|
||||||
|
BStringIO & operator<<(const BString & s);
|
||||||
|
BStringIO & operator<<(const BRect & r);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
off_t fPosition;
|
||||||
|
BString *fString;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _STRING_IO_H */
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,192 @@
|
|||||||
|
## ********************************* ##
|
||||||
|
## Zeta Generic Makefile v3.0 ##
|
||||||
|
|
||||||
|
## Fill in this file to specify the project being created, and the referenced
|
||||||
|
## makefile-engine will do all of the hard work for you.
|
||||||
|
|
||||||
|
## Application Specific Settings ---------------------------------------------
|
||||||
|
|
||||||
|
# specify the name of the binary
|
||||||
|
NAME := Pen
|
||||||
|
|
||||||
|
# specify the type of binary
|
||||||
|
# APP: Application
|
||||||
|
# SHARED: Shared library or add-on
|
||||||
|
# STATIC: Static library archive
|
||||||
|
# DRIVER: Kernel Driver
|
||||||
|
# MODULE: Kernel Module
|
||||||
|
# DECOR: A window decorator project
|
||||||
|
TYPE := SHARED
|
||||||
|
|
||||||
|
# add support for new Pe and Eddie features
|
||||||
|
# to fill in generic makefile
|
||||||
|
|
||||||
|
#%{
|
||||||
|
# @src->@
|
||||||
|
|
||||||
|
# specify the source files to use
|
||||||
|
# full paths or paths relative to the makefile can be included
|
||||||
|
# all files, regardless of directory, will have their object
|
||||||
|
# files created in the common object directory.
|
||||||
|
# Note that this means this makefile will not work correctly
|
||||||
|
# if two source files with the same name (source.c or source.cpp)
|
||||||
|
# are included from different directories. Also note that spaces
|
||||||
|
# in folder names do not work well with this makefile.
|
||||||
|
SRCS := PenInputServerMethod.cpp \
|
||||||
|
PenInputLooper.cpp \
|
||||||
|
PenInputInkWindow.cpp \
|
||||||
|
PenInputBackend.cpp \
|
||||||
|
DumpMessage.cpp \
|
||||||
|
compat/StringIO.cpp
|
||||||
|
|
||||||
|
# specify the resource files to use
|
||||||
|
# full path or a relative path to the resource file can be used.
|
||||||
|
RSRCS :=
|
||||||
|
|
||||||
|
# Specify your RDEF files, if any.
|
||||||
|
RDEFS :=
|
||||||
|
|
||||||
|
# @<-src@
|
||||||
|
#%}
|
||||||
|
|
||||||
|
# end support for Pe and Eddie
|
||||||
|
|
||||||
|
# specify additional libraries to link against
|
||||||
|
# there are two acceptable forms of library specifications
|
||||||
|
# - if your library follows the naming pattern of:
|
||||||
|
# libXXX.so or libXXX.a you can simply specify XXX
|
||||||
|
# library: libbe.so entry: be
|
||||||
|
#
|
||||||
|
# - if your library does not follow the standard library
|
||||||
|
# naming scheme you need to specify the path to the library
|
||||||
|
# and it's name
|
||||||
|
# library: my_lib.a entry: my_lib.a or path/my_lib.a
|
||||||
|
LIBS := _APP_ be
|
||||||
|
|
||||||
|
# specify additional paths to directories following the standard
|
||||||
|
# libXXX.so or libXXX.a naming scheme. You can specify full paths
|
||||||
|
# or paths relative to the makefile. The paths included may not
|
||||||
|
# be recursive, so include all of the paths where libraries can
|
||||||
|
# be found. Directories where source files are found are
|
||||||
|
# automatically included.
|
||||||
|
LIBPATHS :=
|
||||||
|
|
||||||
|
# additional paths to look for system headers
|
||||||
|
# thes use the form: #include <header>
|
||||||
|
# source file directories are NOT auto-included here
|
||||||
|
SYSTEM_INCLUDE_PATHS := compat
|
||||||
|
|
||||||
|
# additional paths to look for local headers
|
||||||
|
# thes use the form: #include "header"
|
||||||
|
# source file directories are automatically included
|
||||||
|
LOCAL_INCLUDE_PATHS :=
|
||||||
|
|
||||||
|
# specify the level of optimization that you desire
|
||||||
|
# NONE, SOME, FULL
|
||||||
|
OPTIMIZE :=
|
||||||
|
|
||||||
|
# specify any preprocessor symbols to be defined. The symbols will not
|
||||||
|
# have their values set automatically; you must supply the value (if any)
|
||||||
|
# to use. For example, setting DEFINES to "DEBUG=1" will cause the
|
||||||
|
# compiler option "-DDEBUG=1" to be used. Setting DEFINES to "DEBUG"
|
||||||
|
# would pass "-DDEBUG" on the compiler's command line.
|
||||||
|
DEFINES := DEBUG=1
|
||||||
|
|
||||||
|
# specify special warning levels
|
||||||
|
# if unspecified default warnings will be used
|
||||||
|
# NONE = supress all warnings
|
||||||
|
# ALL = enable all warnings
|
||||||
|
WARNINGS :=
|
||||||
|
|
||||||
|
# specify whether image symbols will be created
|
||||||
|
# so that stack crawls in the debugger are meaningful
|
||||||
|
# if TRUE symbols will be created
|
||||||
|
SYMBOLS :=
|
||||||
|
|
||||||
|
# specify debug settings
|
||||||
|
# if TRUE will allow application to be run from a source-level
|
||||||
|
# debugger. Note that this will disable all optimzation.
|
||||||
|
DEBUGGER :=
|
||||||
|
|
||||||
|
# specify additional compiler flags for all files
|
||||||
|
COMPILER_FLAGS :=
|
||||||
|
|
||||||
|
# specify additional linker flags
|
||||||
|
LINKER_FLAGS :=
|
||||||
|
|
||||||
|
# specify the version of this particular item
|
||||||
|
# (for example, -app 3 4 0 d 0 -short 340 -long "340 "`echo -n -e '\302\251'`"1999 GNU GPL")
|
||||||
|
#E This may also be specified in a resource.
|
||||||
|
APP_VERSION :=
|
||||||
|
|
||||||
|
# (for TYPE == DRIVER only) Specify desired location of driver in the /dev
|
||||||
|
# hierarchy. Used by the driverinstall rule. E.g., DRIVER_PATH = video/usb will
|
||||||
|
# instruct the driverinstall rule to place a symlink to your driver's binary in
|
||||||
|
# ~/add-ons/kernel/drivers/dev/video/usb, so that your driver will appear at
|
||||||
|
# /dev/video/usb when loaded. Default is "misc".
|
||||||
|
DRIVER_PATH :=
|
||||||
|
|
||||||
|
# Specify if you want the object files to be somewhere besides the default location.
|
||||||
|
OBJ_DIR :=
|
||||||
|
|
||||||
|
# Specify a non default placement for the target
|
||||||
|
TARGET_DIR :=
|
||||||
|
|
||||||
|
# Specify a directory for the 'install' target.
|
||||||
|
INSTALL_DIR :=
|
||||||
|
|
||||||
|
# Specify the name of this makefile.
|
||||||
|
# If you leave this blank, the makefile will not be considered as part of the
|
||||||
|
# dependenies for the project, and the project will not be rebuilt when the makefile
|
||||||
|
# is changed
|
||||||
|
MAKEFILE :=
|
||||||
|
|
||||||
|
# Specify TRUE if you want the install target to create links in the BeMenu
|
||||||
|
MENU_LINKS :=
|
||||||
|
|
||||||
|
# Related to MENU_LINKS, specify the name of the direcotry in the BeMenu
|
||||||
|
# you wish the link to go in. If the directory does not exist, it will be
|
||||||
|
# created.
|
||||||
|
APP_MENU :=
|
||||||
|
|
||||||
|
# If, for some reason, you don't want to use the dependencies (flex and yacc seem to choke
|
||||||
|
# on them), set this to false
|
||||||
|
DODEPS :=
|
||||||
|
|
||||||
|
# Set this variable if you have an svg text file you wish to use as your targets
|
||||||
|
# icon.
|
||||||
|
SVG_ICON :=
|
||||||
|
|
||||||
|
# If you have some fancy custom build steps to do, specify them here
|
||||||
|
EXTRA_BUILD_STEPS =
|
||||||
|
|
||||||
|
# If you have some other files that should trigger a re-link, such as libs in the same
|
||||||
|
# project that may get rebuilt, specify the full path to them here.
|
||||||
|
EXTRA_DEPS :=
|
||||||
|
|
||||||
|
###########################################################################################
|
||||||
|
# The following variables are commented out here because the can be very useful to just
|
||||||
|
# set at the command line or in the env at time of compiling, allowing you to leave your
|
||||||
|
# makefile the same, but change the build types easily.
|
||||||
|
|
||||||
|
|
||||||
|
# If you wish to have the program output a profiling session file which can be read by bprof,
|
||||||
|
# set this to 'true'
|
||||||
|
#BUILD_PROFILE :=
|
||||||
|
|
||||||
|
# If you wish to have a debug build,
|
||||||
|
# set this to 'true'
|
||||||
|
#BUILD_DEBUG :=
|
||||||
|
|
||||||
|
# If you wish to have a build which can do memory checking when MALLOC_DEBUG=15 is set,
|
||||||
|
# set this to 'true'
|
||||||
|
#CHECK_MEM :=
|
||||||
|
|
||||||
|
# If you want to see the complete build line for every file, then set this to 'true',
|
||||||
|
# otherwise it will tell you at the end what the build flags were.
|
||||||
|
#CHATTY :=
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## include the makefile-engine
|
||||||
|
include $(BUILDHOME)/etc/makefile-engine
|
||||||
Reference in New Issue
Block a user