1/* 2 Touchpad sensitivity filter 3 Most windows/mac/etc laptops have a sensitivity filter/mechanism 4 which protects the user from accidently rubbing the 5 touchpad while typing and thus deleting text or moving 6 the cursor to a new insertion point. I've been grousing 7 about this to myself for months, and finally decided to 8 write something for BeOS which other people might benefit 9 from. 10 11 Just an input_server add_on. I wrote it in < hour. Works on 12 my inspiron 3500, but I imagine it would work fine on any BeOS 13 machine. Not that desktops would benefit. Compiled under 4.5.2 14 15 Do what you want with it. Enjoy. 16 17 --Shamyl Zakariya 18 --March 22 2000 19 --zakariya@earthlink.net 20 21 Note: 22 reads Touchpad_settings file in home/config/settings . 23 padblocker_threshold value represents the delay between the last 24 B_KEY_UP message and when the filter will allow 25 a B_MOUSE_DOWN message. Eg, if less than _threshold has 26 transpired between a B_KEY_DOWN and a B_MOUSE_DOWN, the mouse 27 down event will be skipped, cast into oblivion. 28 29 Kudos to the people at Be for making this kind of thing 30 so damnably easy to do. Bravo! 31 32 And a hearty thanks to Magnus Landahl for his superb 33 debug console, without which I wouldn't have ever known if 34 this damn thing worked at all. 35 36*/ 37 38 39#include <stdlib.h> 40#include <string.h> 41#include <ctype.h> 42#include <input/touchpad_settings.h> 43#include <Debug.h> 44#include <List.h> 45#include <Message.h> 46#include <OS.h> 47#include <StorageKit.h> 48 49#include <add-ons/input_server/InputServerFilter.h> 50 51#if DEBUG 52# define LOG(text...) PRINT((text)) 53#else 54# define LOG(text...) 55#endif 56 57//#define Z_DEBUG 1 58 59 60#if Z_DEBUG 61#include <BeDC.h> 62#endif 63 64extern "C" _EXPORT BInputServerFilter* instantiate_input_filter(); 65 66class PadBlocker : public BInputServerFilter 67{ 68 public: 69 PadBlocker(); 70 virtual ~PadBlocker(); 71 virtual filter_result Filter(BMessage *message, BList *outList); 72 73 private: 74 bigtime_t _lastKeyUp; //timestamp of last B_KEY_DOWN 75 bigtime_t _threshold; 76 status_t GetSettingsPath(BPath& path); 77 BPoint fWindowPosition; 78}; 79 80 81status_t 82PadBlocker::GetSettingsPath(BPath &path) 83{ 84 status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path); 85 if (status < B_OK) 86 return status; 87 88 return path.Append(TOUCHPAD_SETTINGS_FILE); 89} 90 91 92PadBlocker::PadBlocker() 93{ 94 _lastKeyUp = 0; 95 _threshold = 300; //~one third of a second? 96 97 touchpad_settings settings; 98 99 #if Z_DEBUG 100 BeDC dc("PadBlocker"); 101 #endif 102 BPath path; 103 status_t status = GetSettingsPath(path); 104 if (status == B_OK) 105 { 106 107 BFile settingsFile(path.Path(), B_READ_ONLY); 108 status = settingsFile.InitCheck(); 109 if (status == B_OK) 110 { 111 112 if (settingsFile.Read(&settings, sizeof(touchpad_settings)) 113 != sizeof(touchpad_settings)) { 114 LOG("failed to load settings\n"); 115 status = B_ERROR; 116 } 117 if (settingsFile.Read(&fWindowPosition, sizeof(BPoint)) 118 != sizeof(BPoint)) { 119 LOG("failed to load settings\n"); 120 status = B_ERROR; 121 } 122 } 123 } 124 125 //load settings file 126 127 if (status == B_OK) 128 { 129 #if Z_DEBUG 130 dc.SendMessage("Settings file Exists"); 131 #endif 132 _threshold = settings.padblocker_threshold; 133 } 134 135 136 137 _threshold *= 1000; //I'd rather keep the number in the file in thousandths 138 139 #ifdef Z_DEBUG 140 dc.SendInt(_threshold, "Touchpad threshold."); 141 #endif 142} 143 144 145PadBlocker::~PadBlocker() 146{ 147} 148 149 150filter_result PadBlocker::Filter(BMessage *message, BList *outList) 151{ 152 filter_result res = B_DISPATCH_MESSAGE; 153 154 switch (message->what) 155 { 156 case B_KEY_UP: case B_KEY_DOWN: 157 { 158 _lastKeyUp = system_time(); //update timestamp 159 break; 160 } 161 162 case B_MOUSE_DOWN: 163 { 164 // do nothing if disabled 165 if (_threshold == 0) 166 break; 167 168 bigtime_t now = system_time(); 169 // if less than the threshold has passed, tell input server 170 // to ignore this message 171 if ((now - _lastKeyUp) < _threshold) res = B_SKIP_MESSAGE; 172 break; 173 } 174 175 default: 176 { 177 //we don't want to mess with anybody else 178 break; 179 } 180 } 181 182 #if Z_DEBUG 183 if (res == B_SKIP_MESSAGE) 184 { 185 BeDC dc("PadBlocker"); 186 dc.SendMessage("Skipping mouse down event"); 187 } 188 #endif 189 190 return (res); 191} 192 193 194//************************************************************************* 195//Exported instantiator 196 197BInputServerFilter* instantiate_input_filter() 198{ 199 return new (std::nothrow) PadBlocker(); 200} 201