#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <input/touchpad_settings.h>
#include <Debug.h>
#include <List.h>
#include <Message.h>
#include <OS.h>
#include <StorageKit.h>
#include <add-ons/input_server/InputServerDevice.h>
#include <add-ons/input_server/InputServerFilter.h>
#if DEBUG
# define LOG(text...) PRINT((text))
#else
# define LOG(text...)
#endif
#if Z_DEBUG
#include <BeDC.h>
#endif
extern "C" _EXPORT BInputServerFilter* instantiate_input_filter();
class PadBlocker : public BInputServerFilter
{
public:
PadBlocker();
virtual ~PadBlocker();
virtual filter_result Filter(BMessage *message, BList *outList);
private:
bigtime_t _lastKeyUp;
bigtime_t _threshold;
status_t GetSettingsPath(BPath& path);
};
status_t
PadBlocker::GetSettingsPath(BPath &path)
{
status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path);
if (status < B_OK)
return status;
return path.Append(TOUCHPAD_SETTINGS_FILE);
}
PadBlocker::PadBlocker()
{
_lastKeyUp = 0;
_threshold = 300;
touchpad_settings settings;
#if Z_DEBUG
BeDC dc("PadBlocker");
#endif
BPath path;
status_t status = GetSettingsPath(path);
if (status == B_OK) {
BFile settingsFile(path.Path(), B_READ_ONLY);
status = settingsFile.InitCheck();
if (status == B_OK) {
BMessage settingsMsg;
status = settingsMsg.Unflatten(&settingsFile);
if (status != B_OK) {
off_t size;
settingsFile.Seek(0, SEEK_SET);
if (settingsFile.GetSize(&size) == B_OK && size == 28) {
if (settingsFile.Read(&settings, 20) != 20) {
LOG("failed to load old settings\n");
status = B_ERROR;
} else
status = B_OK;
} else {
LOG("failed to load settings\n");
status = B_ERROR;
}
} else
settingsMsg.FindInt16("padblocker_threshold",
(int16*)&settings.padblocker_threshold);
}
}
if (status == B_OK)
{
#if Z_DEBUG
dc.SendMessage("Settings file Exists");
#endif
_threshold = settings.padblocker_threshold;
}
_threshold *= 1000;
#ifdef Z_DEBUG
dc.SendInt(_threshold, "Touchpad threshold.");
#endif
}
PadBlocker::~PadBlocker()
{
}
filter_result PadBlocker::Filter(BMessage *message, BList *outList)
{
filter_result res = B_DISPATCH_MESSAGE;
switch (message->what)
{
case B_KEY_UP: case B_KEY_DOWN:
{
if (!message->HasInt32("be:key_repeat"))
_lastKeyUp = system_time();
break;
}
case B_MOUSE_DOWN:
{
int32 device;
if (_threshold == 0)
break;
if (message->FindInt32("be:device_subtype", &device) != B_OK
|| device != B_TOUCHPAD_POINTING_DEVICE)
break;
bigtime_t now = system_time();
if ((now - _lastKeyUp) < _threshold) res = B_SKIP_MESSAGE;
break;
}
default:
{
break;
}
}
#if Z_DEBUG
if (res == B_SKIP_MESSAGE)
{
BeDC dc("PadBlocker");
dc.SendMessage("Skipping mouse down event");
}
#endif
return (res);
}
BInputServerFilter* instantiate_input_filter()
{
return new (std::nothrow) PadBlocker();
}