summaryrefslogtreecommitdiff
path: root/src/lib/eeze/Eeze.h
blob: 12b225eab8da3ccea876175e9fa5f04356b87303 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
/**

   @brief Eeze Device Library

   @page eeze_main Eeze

   @date 2010 (created)

   @section eeze_toc Table of Contents

   @li @ref eeze_main_intro
   @li @ref eeze_main_compiling
   @li @ref eeze_main_next_steps

   @section eeze_main_intro Introduction

   Eeze is a library for manipulating devices through udev with a
   simple and fast api. It interfaces directly with libudev, avoiding
   such middleman daemons as udisks/upower or hal, to immediately
   gather device information the instant it becomes known to the
   system.  This can be used to determine such things as:

   @li If a cdrom has a disk inserted
   @li The temperature of a cpu core
   @li The remaining power left in a battery
   @li The current power consumption of various parts
   @li Monitor in realtime the status of peripheral devices

   Each of the above examples can be performed by using only a single eeze
   function, as one of the primary focuses of the library is to reduce the
   complexity of managing devices.

   @section eeze_main_compiling How to compile

   Eeze is a library your application links to. The procedure for this is very
   simple. You simply have to compile your application with the appropriate
   compiler flags that the @p pkg-config script outputs. For example:

   Compiling C or C++ files into object files:

   @verbatim
   gcc -c -o main.o main.c `pkg-config --cflags eeze`
   @endverbatim

   Linking object files into a binary executable:

   @verbatim
   gcc -o my_application main.o `pkg-config --libs eeze`
   @endverbatim

   See @ref pkgconfig

   @section eeze_main_next_steps Next Steps

   After you understood what Eeze is and installed it in your system
   you should proceed understanding the programming interface. We'd
   recommend you to take a while to learn @ref Eina and @ref Ecore as
   they convenient and Eeze provides integration with it.

   Recommended reading:

   @li @link Eeze.h Eeze functions @endlink
   @li @ref Eeze_Udev UDEV functions
   @li @ref Eeze_Watch Functions that watch for events
   @li @ref Eeze_Syspath Functions that accept a device /sys/ path
   @li @ref Eeze_Find Functions which find types of devices
   @li @ref Eeze_Disk Disk functions
   @li @ref Eeze_Net Net functions
   @li @ref Eeze_Sensor Sensor functions

 */
#ifndef EEZE_UDEV_H
#define EEZE_UDEV_H

#include <Eina.h>
#include <Efl_Config.h>

#include <eeze_api.h>

/**
 * @file Eeze.h
 * @brief Easy device manipulation.
 *
 * Eeze is a library for manipulating devices through udev with a simple and fast
 * api. It interfaces directly with libudev, avoiding such middleman daemons as
 * udisks/upower or hal, to immediately gather device information the instant it
 * becomes known to the system.  This can be used to determine such things as:
 * @li If a cdrom has a disk inserted
 * @li The temperature of a cpu core
 * @li The remaining power left in a battery
 * @li The current power consumption of various parts
 * @li Monitor in realtime the status of peripheral devices
 * Each of the above examples can be performed by using only a single eeze
 * function, as one of the primary focuses of the library is to reduce the
 * complexity of managing devices.
 *
 *
 * For udev functions, see @ref udev.
 */

/**
 * @defgroup Eeze_Main main
 * @ingroup Eeze
 *
 * These are general eeze functions which include init and shutdown.
 */

/**
 * @defgroup Eeze_Udev udev
 * @ingroup Eeze_Main
 *
 * These are functions which interact directly with udev.
 */

/**
 * @addtogroup Eeze_Udev
 *
 * These are the device subsystems of udev:
 * @li ac97
 * @li acpi
 * @li backlight
 * @li bdi
 * @li block
 * @li bsg
 * @li dmi
 * @li drm
 * @li graphics
 * @li hid
 * @li hwmon
 * @li i2c
 * @li input
 * @li leds
 * @li mem
 * @li misc
 * @li net
 * @li pci
 * @li pci_bus
 * @li pci_express
 * @li platform
 * @li pnp
 * @li rtc
 * @li scsi
 * @li scsi_device
 * @li scsi_disk
 * @li scsi_generic
 * @li scsi_host
 * @li serio
 * @li sound
 * @li thermal
 * @li tty
 * @li usb
 * @li usb_device
 * @li vc
 * @li vtconsole
 *
 * These are the devtypes of udev.
 * @li atapi
 * @li audio
 * @li block
 * @li cd
 * @li char
 * @li disk
 * @li drm_minor
 * @li floppy
 * @li generic
 * @li hid
 * @li hub
 * @li media
 * @li optical
 * @li printer
 * @li rbc
 * @li scsi
 * @li storage
 * @li tape
 * @li video
 */
#ifdef __cplusplus
extern "C" {
#endif

/**
 * @addtogroup Eeze_Udev
 * @typedef Eeze_Udev_Event
 * @enum Eeze_Udev_Event
 * @brief Flags for watch events
 *
 * These events are used to specify the events to watch in a
 * #Eeze_Udev_Watch.  They can be ORed together.
 *@{
 */
typedef enum
{
    /** - No event specified */
    EEZE_UDEV_EVENT_NONE = 0xf0,
    /** - Device added */
    EEZE_UDEV_EVENT_ADD = (1 << 1),
    /** - Device removed */
    EEZE_UDEV_EVENT_REMOVE = (1 << 2),
    /** - Device changed */
    EEZE_UDEV_EVENT_CHANGE = (1 << 3),
    /** - Device has come online */
    EEZE_UDEV_EVENT_ONLINE = (1 << 4),
    /** - Device has gone offline */
    EEZE_UDEV_EVENT_OFFLINE = (1 << 5)
} Eeze_Udev_Event;
/** @} */

/**
 * @addtogroup Eeze_Udev udev
 * @typedef Eeze_Udev_Type Eeze_Udev_Type
 * @enum Eeze_Udev_Type
 * @brief Convenience types to simplify udev access.
 *
 * These types allow easy access to certain udev device types.  They
 * may only be used in specified functions.
 *
 * @{
 */
/*FIXME: these probably need to be bitmasks with categories*/
typedef enum
{
   /** - No type */
   EEZE_UDEV_TYPE_NONE,
   /** - Keyboard device */
   EEZE_UDEV_TYPE_KEYBOARD,
   /** - Mouse device */
   EEZE_UDEV_TYPE_MOUSE,
   /** - Touchpad device */
   EEZE_UDEV_TYPE_TOUCHPAD,
   /** - Mountable drive */
   EEZE_UDEV_TYPE_DRIVE_MOUNTABLE,
   /** - Internal drive */
   EEZE_UDEV_TYPE_DRIVE_INTERNAL,
   /** - Removable drive */
   EEZE_UDEV_TYPE_DRIVE_REMOVABLE,
   /** - cd drive */
   EEZE_UDEV_TYPE_DRIVE_CDROM,
   /** - AC adapter */
   EEZE_UDEV_TYPE_POWER_AC,
   /** - Battery */
   EEZE_UDEV_TYPE_POWER_BAT,
   /** - Temperature sensor */
   EEZE_UDEV_TYPE_IS_IT_HOT_OR_IS_IT_COLD_SENSOR,
   /** - Network devices */
   EEZE_UDEV_TYPE_NET,
   /** - WebCam */
   EEZE_UDEV_TYPE_V4L,
   /** - Bluetooth */
   EEZE_UDEV_TYPE_BLUETOOTH,
   /** - Joystick
    * @since 1.7
    */
   EEZE_UDEV_TYPE_JOYSTICK,
   /** - Drm
    * @since 1.12
    */
   EEZE_UDEV_TYPE_DRM,
   /** - Backlight
    * @since 1.12
    */
   EEZE_UDEV_TYPE_BACKLIGHT,
   /** - Leds
    * @since 1.12
    */
   EEZE_UDEV_TYPE_LEDS,
   /** - Graphics
    * @since 1.18
    */
   EEZE_UDEV_TYPE_GRAPHICS,
   /** - GPIOS (includes gpioN and gpiochipN)
    * @since 1.19
    */
   EEZE_UDEV_TYPE_GPIO
} Eeze_Udev_Type;
/**@}*/

struct Eeze_Udev_Watch;

/**
 * @addtogroup Eeze_Watch
 * @typedef Eeze_Udev_Watch Eeze_Udev_Watch
 * @brief Opaque structure to hold data for a udev watch
 */
typedef struct Eeze_Udev_Watch Eeze_Udev_Watch;

#define EEZE_VERSION_MAJOR EFL_VERSION_MAJOR
#define EEZE_VERSION_MINOR EFL_VERSION_MINOR
  /**
   * @typedef Eeeze_Version
   * Represents the current version of Eeze
   */
   typedef struct _Eeze_Version
     {
        int major; /** < major (binary or source incompatible changes) */
        int minor; /** < minor (new features, bugfixes, major improvements version) */
        int micro; /** < micro (bugfix, internal improvements, no new features version) */
        int revision; /** < git revision (0 if a proper release or the git revision number Eeze is built from) */
     } Eeze_Version;

   EEZE_API extern Eeze_Version *eeze_version;

/**
 * @addtogroup Eeze_Watch
 * @typedef Eeze_Udev_Watch_Cb Eeze_Udev_Watch_Cb
 * @brief Callback type for use with #Eeze_Udev_Watch
 */
typedef void(*Eeze_Udev_Watch_Cb)(const char *, Eeze_Udev_Event, void *, Eeze_Udev_Watch *);


/**
 * Initialize the eeze library.
 * @return The number of times the function has been called, or -1 on failure.
 *
 * This function should be called prior to using any eeze functions, and MUST
 * be called prior to using any udev functions to avoid a segv.
 *
 * @ingroup Eeze_Main
 */
EEZE_API int             eeze_init(void);

/**
 * Shut down the eeze library.
 * @return The number of times the eeze_init has been called, or -1 when
 * all occurrences of eeze have been shut down.
 *
 * This function should be called when no further eeze functions will be called.
 *
 * @ingroup Eeze_Main
 */
EEZE_API int             eeze_shutdown(void);

/**
 * @return the main udev context used by the library
 * This allows for external reuse of the udev context, reducing direct dependency
 * on libudev.
 * @warning DO NOT CLOSE THIS CONTEXT.
 * @since 1.10
 */
EEZE_API void           *eeze_udev_get(void);


   /**
    * @addtogroup Eeze_Find Find
    *
    * These are functions which find/supplement lists of devices.
    *
    * @ingroup Eeze_Udev
    *
    * @{
    */

/**
 * Returns a stringshared list of all syspaths that are (or should be) the same
 * device as the device pointed at by @p syspath.
 *
 * @param syspath The syspath of the device to find matches for
 * @return All devices which are the same as the one passed
 */
EEZE_API Eina_List       *eeze_udev_find_similar_from_syspath(const char *syspath);

/**
 * Updates a list of all syspaths that are (or should be) the same
 * device.
 *
 * @param list The list of devices to update
 * @return The updated list
 *
 * This function will update @p list to include all devices matching
 * devices with syspaths currently stored in @p list.  All strings are
 * stringshared.
 *
 * @note This is an expensive call, do not use it unless you must.
 */
EEZE_API Eina_List       *eeze_udev_find_unlisted_similar(Eina_List *list);

/**
 * Find a list of devices by a sysattr (and, optionally, a value of that sysattr).
 *
 * @param sysattr The attribute to find
 * @param value Optional: the value that the attribute should have
 *
 * @return A stringshared list of the devices found with the attribute
 *
 * @ingroup Eeze_Find
 */
EEZE_API Eina_List       *eeze_udev_find_by_sysattr(const char *sysattr, const char *value);

/**
 * Find devices using an #Eeze_Udev_Type and/or a name.
 *
 * @param type An #Eeze_Udev_Type or 0
 * @param name A filter for the device name or @c NULL
 * @return A stringshared Eina_List of matched devices or @c NULL on failure
 *
 * Return a list of syspaths (/sys/$syspath) for matching udev devices.
 */
EEZE_API Eina_List       *eeze_udev_find_by_type(Eeze_Udev_Type type, const char *name);

/**
 * A more advanced find, allows finds using udev properties.
 *
 * @param subsystem The udev subsystem to filter by, or @c NULL
 * @param type "ID_INPUT_KEY", "ID_INPUT_MOUSE", "ID_INPUT_TOUCHPAD", @c NULL, etc
 * @param name A filter for the device name, or @c NULL
 * @return A stringshared Eina_List* of matched devices or @c NULL on failure
 *
 * Return a list of syspaths (/sys/$syspath) for matching udev devices.
 * Requires at least one filter.
 */
EEZE_API Eina_List       *eeze_udev_find_by_filter(const char *subsystem, const char *type, const char *name);

/**
 * A more advanced find, allows finds using udev subsystem and sysname
 *
 * @param subsystem The udev subsystem to filter by, or @c NULL
 * @param sysname A filter for the device name, or @c NULL
 * @return A stringshared Eina_List* of matched devices or @c NULL on failure
 *
 * @return A stringshared list of the devices found
 *
 * @since 1.13

 EEZE_API */
EEZE_API Eina_List       *eeze_udev_find_by_subsystem_sysname(const char *subsystem, const char *sysname);

   /**
    * @}
    */

   /**
    * @addtogroup Eeze_Syspath Syspath
    *
    * These are functions which interact with the syspath (/sys/$PATH) of
    * a device.
    *
    * @ingroup Eeze_Udev
    *
    * @{
    */

/**
 * Get the syspath of a device from the /dev/ path.
 *
 * @param devpath The /dev/ path of the device
 * @return A stringshared char* which corresponds to the /sys/ path of the device or @c NULL on failure
 *
 * Takes "/dev/path" and returns the corresponding /sys/ path (without the "/sys/")
 */
EEZE_API const char      *eeze_udev_devpath_get_syspath(const char *devpath);

/**
 * Find the root device of a device from its syspath.
 *
 * @param syspath The syspath of a device, with or without "/sys/"
 * @return The syspath of the parent device
 *
 * Return a stringshared syspath (/sys/$syspath) for the parent device.
 */
EEZE_API const char      *eeze_udev_syspath_get_parent(const char *syspath);

/**
 * Find the parent device of a device from its syspath with a filter applied.
 *
 * @param syspath The syspath of a device, with or without "/sys/"
 * @param subsystem The desired subsystem of the parent device
 * @param devtype The desired device type of the parent device
 * @return The syspath of the parent device
 *
 * Return a stringshared syspath (/sys/$syspath) for the parent device if one exists which matches the filter.
 * @since 1.10
 */
EEZE_API Eina_Stringshare *eeze_udev_syspath_get_parent_filtered(const char *syspath, const char *subsystem, const char *devtype);

/**
 * Returns a list of all parent device syspaths for @p syspath.
 *
 * @param syspath The device to find parents of
 * @return A stringshared list of the parent devices of @p syspath
 */
EEZE_API Eina_List       *eeze_udev_syspath_get_parents(const char *syspath);

/**
 * Get the /dev/ path from the /sys/ path.
 *
 * @param syspath The /sys/ path with or without the /sys/
 * @return A stringshared char* with the /dev/ path or @c NULL on failure
 *
 * Takes /sys/$PATH and turns it into the corresponding "/dev/x/y".
 */
EEZE_API const char      *eeze_udev_syspath_get_devpath(const char *syspath);

/**
 * Get the /dev/ name from the /sys/ path.
 *
 * @param syspath The /sys/ path with or without the /sys/
 * @return A stringshared char* of the device name without the /dev/ path, or @c NULL on failure
 *
 * Takes /sys/$PATH and turns it into the corresponding /dev/x/"y".
 */
EEZE_API const char      *eeze_udev_syspath_get_devname(const char *syspath);

/**
 * Get the subsystem of a device from the /sys/ path.
 *
 * @param syspath The /sys/ path with or without the /sys/
 * @return A stringshared char* with the subsystem of the device or @c NULL on failure
 *
 * Takes /sys/$PATH and returns the corresponding device subsystem,
 * such as "input" for keyboards/mice.
 */
EEZE_API const char      *eeze_udev_syspath_get_subsystem(const char *syspath);

/**
 * Check the property value of a device from the /sys/ path against a provided value.
 *
 * @param syspath The /sys/ path with or without the /sys/
 * @param property The property to check; full list of these is a FIXME
 * @param value The value to check the property against
 * @return @c EINA_TRUE if the property matches the supplied value
 * @since 1.10
 */
EEZE_API Eina_Bool eeze_udev_syspath_check_property(const char *syspath, const char *property, const char *value);

/**
 * Get the property value of a device from the /sys/ path.
 *
 * @param syspath The /sys/ path with or without the /sys/
 * @param property The property to get; full list of these is a FIXME
 * @return A stringshared char* with the property or @c NULL on failure
 */
EEZE_API const char      *eeze_udev_syspath_get_property(const char *syspath, const char *property);

/**
 * Get the sysattr value of a device from the /sys/ path.
 *
 * @param syspath The /sys/ path with or without the /sys/
 * @param sysattr The sysattr to get; full list of these is a FIXME
 * @return A stringshared char* with the sysattr or @c NULL on failure
 */
EEZE_API const char      *eeze_udev_syspath_get_sysattr(const char *syspath, const char *sysattr);

/**
 * Check the sysattr value of a device from the /sys/ path against a provided value.
 *
 * @param syspath The /sys/ path with or without the /sys/
 * @param sysattr The sysattr to check; full list of these is a FIXME
 * @param value The value to check the property against
 * @return @c EINA_TRUE if the sysattr matches the supplied value
 * @since 1.10
 */
EEZE_API Eina_Bool eeze_udev_syspath_check_sysattr(const char *syspath, const char *sysattr, const char *value);

/**
 * Set the sysattr value of a device from the /sys/ path.
 *
 * @param syspath The /sys/ path with or without the /sys/
 * @param sysattr The sysattr to set;
 * @param value The value of sysattr to be set
 * @return @c EINA_TRUE if the sysattr value is set
 * @since 1.12
 */
EEZE_API Eina_Bool eeze_udev_syspath_set_sysattr(const char *syspath, const char *sysattr, double value);

/**
 * Get the sysattr list of a device from the /sys/ path.
 *
 * @param syspath The /sys/ path with or without the /sys/
 * @return Eina_list containing list of sysattr for a device or @c NULL on failure
 * @since 1.12
 */
EEZE_API Eina_List *eeze_udev_syspath_get_sysattr_list(const char *syspath);

/**
 * Checks whether the device is a mouse.
 *
 * @param syspath The /sys/ path with or without the /sys/
 * @return If true, the device is a mouse
 */
EEZE_API Eina_Bool        eeze_udev_syspath_is_mouse(const char *syspath);

/**
 * Checks whether the device is a keyboard.
 *
 * @param syspath The /sys/ path with or without the /sys/
 * @return If true, the device is a keyboard
 */
EEZE_API Eina_Bool        eeze_udev_syspath_is_kbd(const char *syspath);

/**
 * Checks whether the device is a touchpad.
 *
 * @param syspath The /sys/ path with or without the /sys/
 * @return If true, the device is a touchpad
 */
EEZE_API Eina_Bool        eeze_udev_syspath_is_touchpad(const char *syspath);

/**
 * Checks whether the device is a joystick.
 *
 * @param syspath The /sys/ path with or without the /sys/
 * @return If true, the device is a joystick
 * @since 1.7
 */
EEZE_API Eina_Bool        eeze_udev_syspath_is_joystick(const char *syspath);

/**
 * Get the sysnum value of a device from the /sys/ path.
 *
 * @param syspath The /sys/ path with or without the /sys/
 * @return A integer with the sysnum or -1 on failure
 *
 * @since 1.12
 */
EEZE_API int              eeze_udev_syspath_get_sysnum(const char *syspath);

   /**
    * @}
    */

   /**
    * @addtogroup Eeze_Walks Walks
    *
    * These are functions which walk up the device chain.
    *
    * @ingroup Eeze_Udev
    *
    * @{
    */

/**
 * Walks up the device chain starting at @p syspath,
 * checking each device for @p sysattr with (optional) @p value.
 *
 * @param syspath The /sys/ path of the device to start at, with or without the /sys/
 * @param sysattr The attribute to find
 * @param value OPTIONAL: The value that @p sysattr should have, or @c NULL
 *
 * @return If the sysattr (with value) is found, returns TRUE.  Else, false.
 */
EEZE_API Eina_Bool        eeze_udev_walk_check_sysattr(const char *syspath, const char *sysattr, const char *value);

/**
 * Walks up the device chain starting at @p syspath,
 * checking each device for @p sysattr, and returns the value if found.
 *
 * @param syspath The /sys/ path of the device to start at, with or without the /sys/
 * @param sysattr The attribute to find
 *
 * @return The stringshared value of @p sysattr if found, or @c NULL
 */
EEZE_API const char      *eeze_udev_walk_get_sysattr(const char *syspath, const char *sysattr);
   /**
    * @}
    */

   /**
    * @addtogroup Eeze_Watch Watch
    *
    * @brief These are functions which monitor udev for events.
    *
    * Eeze watches are simple: you specify a type of device to watch (or all devices), some events (or all) to watch for, a callback,
    * and some data, and then udev watches those device types for events of the type you specified.  Your callback is called with a
    * syspath of the triggering device and the event that happened to the device, along with the data you associated with the watch and
    * the watch object itself in case you want to stop the watch easily in a callback.
    *
    * @ingroup Eeze_Udev
    *
    * @{
    */

/**
 * Add a watch for a device type
 *
 * @param type The #Eeze_Udev_Type to watch
 * @param event The events to watch; an OR list of #Eeze_Udev_Event (ie (#EEZE_UDEV_EVENT_ADD | #EEZE_UDEV_EVENT_REMOVE)), or 0 for all events
 * @param cb The function to call when the watch receives data of type #Eeze_Udev_Watch_Cb
 * @param user_data Data to pass to the callback function
 *
 * @return A watch struct for the watch type specified, or @c NULL on failure
 *
 * Eeze watches will monitor udev for changes of type(s) @p event to devices of type @p type.  When these changes occur, the stringshared
 * syspath of the device will be sent to function @p func, along with the bitmask of the event type which can be detected through
 * binary &.
 */
EEZE_API Eeze_Udev_Watch *eeze_udev_watch_add(Eeze_Udev_Type type, int event, Eeze_Udev_Watch_Cb cb, void *user_data);

/**
 * Deletes a watch.
 *
 * @param watch An Eeze_Udev_Watch object
 * @return The data originally associated with the watch, or @c NULL
 *
 * Deletes a watch, closing file descriptors and freeing related udev memory.
 */
EEZE_API void            *eeze_udev_watch_del(Eeze_Udev_Watch *watch);
   /**
    * @}
    */

#ifdef __cplusplus
}
#endif

#endif