|
| 1 | +{-# LANGUAGE OverloadedRecordDot #-} |
1 | 2 | {-# OPTIONS_GHC -fno-state-hack #-} |
2 | 3 |
|
3 | 4 | -- | The main module for working with devices and events. |
@@ -36,7 +37,7 @@ module Evdev ( |
36 | 37 | -- * Lower-level |
37 | 38 | newDeviceFromFd, |
38 | 39 | nextEventMay, |
39 | | - LL.LEDValue(..), |
| 40 | + LEDValue(..), |
40 | 41 | setDeviceLED, |
41 | 42 | -- ** C-style types |
42 | 43 | -- | These correspond more directly to C's /input_event/ and /timeval/. |
@@ -66,13 +67,14 @@ import Data.Time.Clock (DiffTime) |
66 | 67 | import Data.Tuple.Extra (uncurry3) |
67 | 68 | import Data.Word (Word16) |
68 | 69 | import Foreign ((.|.)) |
69 | | -import Foreign.C (CUInt) |
| 70 | +import Foreign.C (CUInt, Errno (Errno)) |
70 | 71 | import System.Posix.Process (getProcessID) |
71 | 72 | import System.Posix.Files (readSymbolicLink) |
72 | 73 | import System.Posix.ByteString (Fd, RawFilePath) |
73 | 74 | import System.Posix.IO.ByteString (OpenMode (..), defaultFileFlags, openFd) |
74 | 75 |
|
75 | 76 | import qualified Evdev.LowLevel as LL |
| 77 | +import qualified Evdev.Raw as Raw |
76 | 78 | import Evdev.Codes |
77 | 79 | import Util |
78 | 80 |
|
@@ -126,21 +128,30 @@ data KeyEvent |
126 | 128 | | Repeated |
127 | 129 | deriving (Bounded, Enum, Eq, Ord, Read, Show) |
128 | 130 |
|
129 | | -convertFlags :: Set LL.ReadFlag -> CUInt |
130 | | -convertFlags = fromIntegral . foldr ((.|.) . fromEnum) 0 |
| 131 | +data ReadFlag = Sync | Normal | ForceSync | Blocking |
| 132 | + deriving (Eq, Ord, Show) |
131 | 133 |
|
132 | | -defaultReadFlags :: Set LL.ReadFlag |
133 | | -defaultReadFlags = Set.fromList [LL.Normal, LL.Blocking] |
| 134 | +convertFlags :: Set ReadFlag -> CUInt |
| 135 | +convertFlags = foldr ((.|.) . (.unwrap) . convert) 0 |
| 136 | + where |
| 137 | + convert = \case |
| 138 | + Sync -> Raw.LIBEVDEV_READ_FLAG_SYNC |
| 139 | + Normal -> Raw.LIBEVDEV_READ_FLAG_NORMAL |
| 140 | + ForceSync -> Raw.LIBEVDEV_READ_FLAG_FORCE_SYNC |
| 141 | + Blocking -> Raw.LIBEVDEV_READ_FLAG_BLOCKING |
| 142 | + |
| 143 | +defaultReadFlags :: Set ReadFlag |
| 144 | +defaultReadFlags = Set.fromList [Normal, Blocking] |
134 | 145 |
|
135 | | -nonBlockingReadFlags :: Set LL.ReadFlag |
136 | | -nonBlockingReadFlags = Set.fromList [LL.Normal] |
| 146 | +nonBlockingReadFlags :: Set ReadFlag |
| 147 | +nonBlockingReadFlags = Set.fromList [Normal] |
137 | 148 |
|
138 | 149 | -- | Prevent other clients (including kernel-internal ones) from receiving events. Often a bad idea. |
139 | 150 | grabDevice :: Device -> IO () |
140 | | -grabDevice = grabDevice' LL.LibevdevGrab |
| 151 | +grabDevice = grabDevice' Raw.LIBEVDEV_GRAB |
141 | 152 | -- | Release a grabbed device. |
142 | 153 | ungrabDevice :: Device -> IO () |
143 | | -ungrabDevice = grabDevice' LL.LibevdevUngrab |
| 154 | +ungrabDevice = grabDevice' Raw.LIBEVDEV_UNGRAB |
144 | 155 |
|
145 | 156 | -- | Get the next event from the device. |
146 | 157 | nextEvent :: Device -> IO Event |
@@ -258,15 +269,21 @@ deviceHasEvent dev e = LL.hasEventCode (cDevice dev) typ code |
258 | 269 | deviceAbsAxis :: Device -> AbsoluteAxis -> IO (Maybe LL.AbsInfo) |
259 | 270 | deviceAbsAxis dev = LL.getAbsInfo (cDevice dev) . fromEnum' |
260 | 271 |
|
| 272 | +data LEDValue = LedOn | LedOff |
| 273 | + deriving (Bounded, Eq, Ord, Read, Show) |
| 274 | + |
261 | 275 | -- | Set the state of a LED on a device. |
262 | | -setDeviceLED :: Device -> LEDEvent -> LL.LEDValue -> IO () |
263 | | -setDeviceLED dev led val = cErrCall "setDeviceLED" dev (LL.libevdev_kernel_set_led_value (cDevice dev) led val) |
| 276 | +setDeviceLED :: Device -> LEDEvent -> LEDValue -> IO () |
| 277 | +setDeviceLED dev led val = cErrCall "setDeviceLED" dev $ LL.withDevice (cDevice dev) \devPtr -> |
| 278 | + Errno <$> Raw.libevdev_kernel_set_led_value devPtr (LL.convertEnum led) case val of |
| 279 | + LedOn -> Raw.LIBEVDEV_LED_ON |
| 280 | + LedOff -> Raw.LIBEVDEV_LED_OFF |
264 | 281 |
|
265 | 282 | {- Util -} |
266 | 283 |
|
267 | | -grabDevice' :: LL.GrabMode -> Device -> IO () |
| 284 | +grabDevice' :: Raw.Libevdev_grab_mode -> Device -> IO () |
268 | 285 | grabDevice' mode dev = cErrCall "grabDevice" dev $ |
269 | | - LL.grabDevice (cDevice dev) mode |
| 286 | + LL.withDevice (cDevice dev) $ fmap Errno . flip Raw.libevdev_grab mode |
270 | 287 |
|
271 | 288 | {- |
272 | 289 | TODO this is a workaround until c2hs has a better story for enum conversions |
|
0 commit comments