#ifdef HAVE_INOTIFY
ECORE_FILE_MONITOR_TYPE_INOTIFY,
#endif
+#ifdef HAVE_NOTIFY_WIN32
+ ECORE_FILE_MONITOR_TYPE_NOTIFY_WIN32,
+#endif
#ifdef HAVE_POLL
ECORE_FILE_MONITOR_TYPE_POLL
#endif
if (ecore_file_monitor_inotify_init())
return 1;
#endif
+#ifdef HAVE_NOTIFY_WIN32
+ monitor_type = ECORE_FILE_MONITOR_TYPE_NOTIFY_WIN32;
+ if (ecore_file_monitor_win32_init())
+ return 1;
+#endif
#ifdef HAVE_POLL
monitor_type = ECORE_FILE_MONITOR_TYPE_POLL;
if (ecore_file_monitor_poll_init())
ecore_file_monitor_inotify_shutdown();
break;
#endif
+#ifdef HAVE_NOTIFY_WIN32
+ case ECORE_FILE_MONITOR_TYPE_NOTIFY_WIN32:
+ ecore_file_monitor_win32_shutdown();
+ break;
+#endif
#ifdef HAVE_POLL
case ECORE_FILE_MONITOR_TYPE_POLL:
ecore_file_monitor_poll_shutdown();
*/
EAPI Ecore_File_Monitor *
ecore_file_monitor_add(const char *path,
- void (*func) (void *data, Ecore_File_Monitor *em,
- Ecore_File_Event event,
- const char *path),
- void *data)
+ void (*func) (void *data,
+ Ecore_File_Monitor *em,
+ Ecore_File_Event event,
+ const char *path),
+ void *data)
{
switch (monitor_type)
{
case ECORE_FILE_MONITOR_TYPE_INOTIFY:
return ecore_file_monitor_inotify_add(path, func, data);
#endif
+#ifdef HAVE_NOTIFY_WIN32
+ case ECORE_FILE_MONITOR_TYPE_NOTIFY_WIN32:
+ return ecore_file_monitor_win32_add(path, func, data);
+#endif
#ifdef HAVE_POLL
case ECORE_FILE_MONITOR_TYPE_POLL:
return ecore_file_monitor_poll_add(path, func, data);
ecore_file_monitor_inotify_del(em);
break;
#endif
+#ifdef HAVE_NOTIFY_WIN32
+ case ECORE_FILE_MONITOR_TYPE_NOTIFY_WIN32:
+ ecore_file_monitor_win32_del(em);
+ break;
+#endif
#ifdef HAVE_POLL
case ECORE_FILE_MONITOR_TYPE_POLL:
ecore_file_monitor_poll_del(em);
--- /dev/null
+/*\r
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2\r
+ */\r
+\r
+#ifdef HAVE_CONFIG_H\r
+# include <config.h>\r
+#endif\r
+\r
+#ifdef HAVE_NOTIFY_WIN32\r
+\r
+# define WIN32_LEAN_AND_MEAN\r
+# include <windows.h>\r
+# undef WIN32_LEAN_AND_MEAN\r
+# include <process.h>\r
+\r
+# include "ecore_file_private.h"\r
+\r
+\r
+typedef struct _Ecore_File_Monitor_Win32 Ecore_File_Monitor_Win32;\r
+typedef struct _Ecore_File_Monitor_Win32_Data Ecore_File_Monitor_Win32_Data;\r
+\r
+/* 4096 = 256 * sizeof(FILE_NOTIFY_INFORMATION) */\r
+# define ECORE_FILE_MONITOR_WIN32_BUFFER_SIZE 4096\r
+# define ECORE_FILE_MONITOR_WIN32(x) ((Ecore_File_Monitor_Win32 *)(x))\r
+\r
+struct _Ecore_File_Monitor_Win32_Data\r
+{\r
+ char buffer[ECORE_FILE_MONITOR_WIN32_BUFFER_SIZE];\r
+ OVERLAPPED overlapped;\r
+ HANDLE handle;\r
+ HANDLE event;\r
+ Ecore_File_Monitor *monitor;\r
+ Ecore_Win32_Handler *h;\r
+ DWORD buf_length;\r
+ int is_dir;\r
+};\r
+\r
+struct _Ecore_File_Monitor_Win32\r
+{\r
+ Ecore_File_Monitor monitor;\r
+ Ecore_File_Monitor_Win32_Data *file;\r
+ Ecore_File_Monitor_Win32_Data *dir;\r
+};\r
+\r
+static Ecore_File_Monitor *_monitors = NULL;\r
+\r
+static int _ecore_file_monitor_win32_cb(void *data, Ecore_Win32_Handler *wh);\r
+\r
+\r
+static Ecore_File_Monitor_Win32_Data *\r
+_ecore_file_monitor_win32_data_new(Ecore_File_Monitor *monitor, int type)\r
+{\r
+ Ecore_File_Monitor_Win32_Data *md;\r
+ DWORD filter;\r
+\r
+ md = (Ecore_File_Monitor_Win32_Data *)calloc(1, sizeof(Ecore_File_Monitor_Win32_Data));\r
+ if (!md) return NULL;\r
+\r
+ md->handle = CreateFile(monitor->path,\r
+ FILE_LIST_DIRECTORY,\r
+ FILE_SHARE_READ |\r
+ FILE_SHARE_WRITE,\r
+ NULL,\r
+ OPEN_EXISTING,\r
+ FILE_FLAG_BACKUP_SEMANTICS |\r
+ FILE_FLAG_OVERLAPPED,\r
+ NULL);\r
+ if (md->handle == INVALID_HANDLE_VALUE)\r
+ goto free_md;\r
+\r
+ md->event = CreateEvent(NULL, FALSE, FALSE, NULL);\r
+ if (!md->event)\r
+ goto close_handle;\r
+\r
+ ZeroMemory (&md->overlapped, sizeof(md->overlapped));\r
+ md->overlapped.hEvent = md->event;\r
+\r
+ filter = (type == 0) ? FILE_NOTIFY_CHANGE_FILE_NAME : FILE_NOTIFY_CHANGE_DIR_NAME;\r
+ filter |=\r
+ FILE_NOTIFY_CHANGE_ATTRIBUTES |\r
+ FILE_NOTIFY_CHANGE_SIZE |\r
+ FILE_NOTIFY_CHANGE_LAST_WRITE |\r
+ FILE_NOTIFY_CHANGE_LAST_ACCESS |\r
+ FILE_NOTIFY_CHANGE_CREATION |\r
+ FILE_NOTIFY_CHANGE_SECURITY;\r
+\r
+ if (!ReadDirectoryChangesW(md->handle,\r
+ md->buffer,\r
+ ECORE_FILE_MONITOR_WIN32_BUFFER_SIZE,\r
+ FALSE,\r
+ filter,\r
+ &md->buf_length,\r
+ &md->overlapped,\r
+ NULL))\r
+ goto close_event;\r
+\r
+ md->h = ecore_main_win32_handler_add(md->event,\r
+ _ecore_file_monitor_win32_cb,\r
+ md);\r
+ if (!md->h)\r
+ goto close_event;\r
+\r
+ md->monitor = monitor;\r
+ md->is_dir = type;\r
+\r
+ return md;\r
+\r
+ close_event:\r
+ CloseHandle(md->event);\r
+ close_handle:\r
+ CloseHandle(md->handle);\r
+ free_md:\r
+ free(md);\r
+\r
+ return NULL;\r
+}\r
+\r
+static void\r
+_ecore_file_monitor_win32_data_free(Ecore_File_Monitor_Win32_Data *md)\r
+{\r
+ if (!md) return;\r
+\r
+ CloseHandle(md->event);\r
+ CloseHandle (md->handle);\r
+ free (md);\r
+}\r
+\r
+static int\r
+_ecore_file_monitor_win32_cb(void *data, Ecore_Win32_Handler *wh)\r
+{\r
+ char filename[PATH_MAX];\r
+ PFILE_NOTIFY_INFORMATION fni;\r
+ Ecore_File_Monitor_Win32_Data *md;\r
+ wchar_t *wname;\r
+ char *name;\r
+ DWORD filter;\r
+ DWORD offset;\r
+ DWORD buf_length;\r
+ Ecore_File_Event event = ECORE_FILE_EVENT_NONE;\r
+\r
+ md = (Ecore_File_Monitor_Win32_Data *)data;\r
+\r
+ if (!GetOverlappedResult (md->handle, &md->overlapped, &buf_length, TRUE))\r
+ return 1;\r
+\r
+ fni = (PFILE_NOTIFY_INFORMATION)md->buffer;\r
+ do {\r
+ if (!fni)\r
+ break;\r
+ offset = fni->NextEntryOffset;\r
+\r
+ wname = (wchar_t *)malloc(sizeof(wchar_t) * (fni->FileNameLength + 1));\r
+ if (!wname)\r
+ return 0;\r
+\r
+ memcpy(wname, fni->FileName, fni->FileNameLength);\r
+ wname[fni->FileNameLength]='\0';\r
+ name = evil_wchar_to_char(wname);\r
+ free(wname);\r
+ if (!name)\r
+ return 0;\r
+\r
+ _snprintf(filename, PATH_MAX, "%s\\%s", md->monitor->path, name);\r
+ free(name);\r
+\r
+ switch (fni->Action)\r
+ {\r
+ case FILE_ACTION_ADDED:\r
+ if (md->is_dir)\r
+ event = ECORE_FILE_EVENT_CREATED_DIRECTORY;\r
+ else\r
+ event = ECORE_FILE_EVENT_CREATED_FILE;\r
+ break;\r
+ case FILE_ACTION_REMOVED:\r
+ if (md->is_dir)\r
+ event = ECORE_FILE_EVENT_DELETED_DIRECTORY;\r
+ else\r
+ event = ECORE_FILE_EVENT_DELETED_FILE;\r
+ break;\r
+ case FILE_ACTION_MODIFIED:\r
+ if (!md->is_dir)\r
+ event = ECORE_FILE_EVENT_MODIFIED;\r
+ break;\r
+ case FILE_ACTION_RENAMED_OLD_NAME:\r
+ if (md->is_dir)\r
+ event = ECORE_FILE_EVENT_DELETED_DIRECTORY;\r
+ else\r
+ event = ECORE_FILE_EVENT_DELETED_FILE;\r
+ break;\r
+ case FILE_ACTION_RENAMED_NEW_NAME:\r
+ if (md->is_dir)\r
+ event = ECORE_FILE_EVENT_CREATED_DIRECTORY;\r
+ else\r
+ event = ECORE_FILE_EVENT_CREATED_FILE;\r
+ break;\r
+ default: \r
+ fprintf(stderr, "unknown event\n");\r
+ event = ECORE_FILE_EVENT_NONE;\r
+ break;\r
+ }\r
+ if (event != ECORE_FILE_EVENT_NONE)\r
+ md->monitor->func(md->monitor->data, md->monitor, event, filename);\r
+\r
+ fni = (PFILE_NOTIFY_INFORMATION)((LPBYTE)fni + offset);\r
+ } while (offset);\r
+\r
+ filter = (md->is_dir == 0) ? FILE_NOTIFY_CHANGE_FILE_NAME : FILE_NOTIFY_CHANGE_DIR_NAME;\r
+ filter |=\r
+ FILE_NOTIFY_CHANGE_ATTRIBUTES |\r
+ FILE_NOTIFY_CHANGE_SIZE |\r
+ FILE_NOTIFY_CHANGE_LAST_WRITE |\r
+ FILE_NOTIFY_CHANGE_LAST_ACCESS |\r
+ FILE_NOTIFY_CHANGE_CREATION |\r
+ FILE_NOTIFY_CHANGE_SECURITY;\r
+\r
+ ReadDirectoryChangesW(md->handle,\r
+ md->buffer,\r
+ ECORE_FILE_MONITOR_WIN32_BUFFER_SIZE,\r
+ FALSE,\r
+ filter,\r
+ &md->buf_length,\r
+ &md->overlapped,\r
+ NULL);\r
+ return 0;\r
+}\r
+\r
+int\r
+ecore_file_monitor_win32_init(void)\r
+{\r
+ return 1;\r
+}\r
+\r
+int\r
+ecore_file_monitor_win32_shutdown(void)\r
+{\r
+ return 1;\r
+}\r
+\r
+Ecore_File_Monitor *\r
+ecore_file_monitor_win32_add(const char *path,\r
+ void (*func) (void *data, Ecore_File_Monitor *em,\r
+ Ecore_File_Event event,\r
+ const char *path),\r
+ void *data)\r
+{\r
+ Ecore_File_Monitor_Win32 *m;\r
+ Ecore_File_Monitor *em;\r
+ size_t len;\r
+\r
+ if (!path || (*path == '\0')) return NULL;\r
+ if (!ecore_file_exists(path) || !ecore_file_is_dir(path))\r
+ return NULL;\r
+ if (!func) return NULL;\r
+\r
+ em = (Ecore_File_Monitor *)calloc(1, sizeof(Ecore_File_Monitor_Win32));\r
+ if (!em) return NULL;\r
+\r
+ em->func = func;\r
+ em->data = data;\r
+\r
+ em->path = strdup(path);\r
+ if (!em->path)\r
+ {\r
+ free(em);\r
+ return NULL;\r
+ }\r
+ len = strlen(em->path);\r
+ if (em->path[len - 1] == '/' || em->path[len - 1] == '\\')\r
+ em->path[len - 1] = '\0';\r
+\r
+ m = ECORE_FILE_MONITOR_WIN32(em);\r
+\r
+ m->file = _ecore_file_monitor_win32_data_new(em, 0);\r
+ if (!m->file)\r
+ {\r
+ free(em->path);\r
+ free(em);\r
+ return NULL;\r
+ }\r
+\r
+ m->dir = _ecore_file_monitor_win32_data_new(em, 1);\r
+ if (!m->dir)\r
+ {\r
+ _ecore_file_monitor_win32_data_free(m->file);\r
+ free(em->path);\r
+ free(em);\r
+ return NULL;\r
+ }\r
+\r
+ _monitors = ECORE_FILE_MONITOR(eina_inlist_append(EINA_INLIST_GET(_monitors), EINA_INLIST_GET(em)));\r
+\r
+ return em;\r
+}\r
+\r
+void\r
+ecore_file_monitor_win32_del(Ecore_File_Monitor *em)\r
+{\r
+ Ecore_File_Monitor_Win32 *m;\r
+\r
+ if (!em)\r
+ return;\r
+\r
+ m = ECORE_FILE_MONITOR_WIN32(em);\r
+ _ecore_file_monitor_win32_data_free(m->dir);\r
+ _ecore_file_monitor_win32_data_free(m->file);\r
+ free(em->path);\r
+ free(em);\r
+}\r
+\r
+#endif\r