nm.cpp (1640B)
1 #include <Directory.h> 2 #include <Looper.h> 3 #include <NodeMonitor.h> 4 #include <MessageFilter.h> 5 6 #include "haiku_interop.h" 7 8 filter_result dir_mon_flt(BMessage *message, BHandler **hnd, BMessageFilter *fltr) { 9 (void) hnd; 10 (void) fltr; 11 12 if (message->what == B_NODE_MONITOR) { 13 int32 val; 14 message->FindInt32("opcode", &val); 15 16 switch (val) { 17 case B_ENTRY_CREATED: 18 case B_ENTRY_MOVED: 19 case B_ENTRY_REMOVED: 20 return B_DISPATCH_MESSAGE; 21 } 22 } 23 24 return B_SKIP_MESSAGE; 25 } 26 27 class DirectoryListener : public BLooper { 28 public: 29 bool recv_reset() { 30 Lock(); 31 bool val = _ev_on; 32 _ev_on = false; 33 Unlock(); 34 35 return val; 36 } 37 private: 38 void MessageReceived(BMessage * message) override { 39 Lock(); 40 _ev_on = true; 41 Unlock(); 42 BLooper::MessageReceived(message); 43 } 44 45 bool _ev_on = false; 46 }; 47 48 struct haiku_nm_t { 49 haiku_nm_t() { 50 dl = new DirectoryListener(); 51 flt = new BMessageFilter(B_PROGRAMMED_DELIVERY, B_LOCAL_SOURCE, dir_mon_flt); 52 dl->AddCommonFilter(flt); 53 dl->Run(); 54 } 55 56 DirectoryListener *dl; 57 BMessageFilter *flt; 58 node_ref nr; 59 }; 60 61 haiku_nm_h haiku_init_nm() { 62 return new haiku_nm_t(); 63 } 64 65 void haiku_close_nm(haiku_nm_h hnd) { 66 delete hnd->flt; 67 // This is the way of deleting a BLooper 68 hnd->dl->PostMessage(B_QUIT_REQUESTED); 69 delete hnd; 70 } 71 int haiku_watch_dir(haiku_nm_h hnd, const char *path) { 72 BDirectory dir(path); 73 dir.GetNodeRef(&(hnd->nr)); 74 75 return watch_node(&(hnd->nr), B_WATCH_DIRECTORY, nullptr, hnd->dl); 76 } 77 int haiku_stop_watch(haiku_nm_h hnd) { 78 return watch_node(&(hnd->nr), B_STOP_WATCHING, nullptr, hnd->dl); 79 } 80 81 int haiku_is_update_needed(haiku_nm_h hnd) { 82 return hnd->dl->recv_reset(); 83 }