Skip to content

Commit a2d354d

Browse files
committed
simplify enums, incl. dropping weird and unnecessary Enum instances that we previously got free from c2hs
1 parent 93f095b commit a2d354d

3 files changed

Lines changed: 35 additions & 85 deletions

File tree

evdev/src/Evdev.hs

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{-# LANGUAGE OverloadedRecordDot #-}
12
{-# OPTIONS_GHC -fno-state-hack #-}
23

34
-- | The main module for working with devices and events.
@@ -36,7 +37,7 @@ module Evdev (
3637
-- * Lower-level
3738
newDeviceFromFd,
3839
nextEventMay,
39-
LL.LEDValue(..),
40+
LEDValue(..),
4041
setDeviceLED,
4142
-- ** C-style types
4243
-- | These correspond more directly to C's /input_event/ and /timeval/.
@@ -66,13 +67,14 @@ import Data.Time.Clock (DiffTime)
6667
import Data.Tuple.Extra (uncurry3)
6768
import Data.Word (Word16)
6869
import Foreign ((.|.))
69-
import Foreign.C (CUInt)
70+
import Foreign.C (CUInt, Errno (Errno))
7071
import System.Posix.Process (getProcessID)
7172
import System.Posix.Files (readSymbolicLink)
7273
import System.Posix.ByteString (Fd, RawFilePath)
7374
import System.Posix.IO.ByteString (OpenMode (..), defaultFileFlags, openFd)
7475

7576
import qualified Evdev.LowLevel as LL
77+
import qualified Evdev.Raw as Raw
7678
import Evdev.Codes
7779
import Util
7880

@@ -126,21 +128,30 @@ data KeyEvent
126128
| Repeated
127129
deriving (Bounded, Enum, Eq, Ord, Read, Show)
128130

129-
convertFlags :: Set LL.ReadFlag -> CUInt
130-
convertFlags = fromIntegral . foldr ((.|.) . fromEnum) 0
131+
data ReadFlag = Sync | Normal | ForceSync | Blocking
132+
deriving (Eq, Ord, Show)
131133

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]
134145

135-
nonBlockingReadFlags :: Set LL.ReadFlag
136-
nonBlockingReadFlags = Set.fromList [LL.Normal]
146+
nonBlockingReadFlags :: Set ReadFlag
147+
nonBlockingReadFlags = Set.fromList [Normal]
137148

138149
-- | Prevent other clients (including kernel-internal ones) from receiving events. Often a bad idea.
139150
grabDevice :: Device -> IO ()
140-
grabDevice = grabDevice' LL.LibevdevGrab
151+
grabDevice = grabDevice' Raw.LIBEVDEV_GRAB
141152
-- | Release a grabbed device.
142153
ungrabDevice :: Device -> IO ()
143-
ungrabDevice = grabDevice' LL.LibevdevUngrab
154+
ungrabDevice = grabDevice' Raw.LIBEVDEV_UNGRAB
144155

145156
-- | Get the next event from the device.
146157
nextEvent :: Device -> IO Event
@@ -258,15 +269,21 @@ deviceHasEvent dev e = LL.hasEventCode (cDevice dev) typ code
258269
deviceAbsAxis :: Device -> AbsoluteAxis -> IO (Maybe LL.AbsInfo)
259270
deviceAbsAxis dev = LL.getAbsInfo (cDevice dev) . fromEnum'
260271

272+
data LEDValue = LedOn | LedOff
273+
deriving (Bounded, Eq, Ord, Read, Show)
274+
261275
-- | 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
264281

265282
{- Util -}
266283

267-
grabDevice' :: LL.GrabMode -> Device -> IO ()
284+
grabDevice' :: Raw.Libevdev_grab_mode -> Device -> IO ()
268285
grabDevice' mode dev = cErrCall "grabDevice" dev $
269-
LL.grabDevice (cDevice dev) mode
286+
LL.withDevice (cDevice dev) $ fmap Errno . flip Raw.libevdev_grab mode
270287

271288
{-
272289
TODO this is a workaround until c2hs has a better story for enum conversions

evdev/src/Evdev/LowLevel.hs

Lines changed: 0 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -13,64 +13,6 @@ import System.Posix.Types (Fd (Fd))
1313
import Evdev.Codes
1414
import Evdev.Raw qualified as Raw
1515

16-
-- * Enums
17-
18-
-- | Extract an Int from an hs-bindgen enum newtype
19-
rawEnum :: (Integral a) => a -> Int
20-
rawEnum = fromIntegral
21-
22-
data ReadFlag = Sync | Normal | ForceSync | Blocking
23-
deriving (Eq, Ord, Show)
24-
instance Enum ReadFlag where
25-
fromEnum Sync = let Raw.Libevdev_read_flag n = Raw.LIBEVDEV_READ_FLAG_SYNC in rawEnum n
26-
fromEnum Normal = let Raw.Libevdev_read_flag n = Raw.LIBEVDEV_READ_FLAG_NORMAL in rawEnum n
27-
fromEnum ForceSync = let Raw.Libevdev_read_flag n = Raw.LIBEVDEV_READ_FLAG_FORCE_SYNC in rawEnum n
28-
fromEnum Blocking = let Raw.Libevdev_read_flag n = Raw.LIBEVDEV_READ_FLAG_BLOCKING in rawEnum n
29-
toEnum n
30-
| n == fromEnum Sync = Sync
31-
| n == fromEnum Normal = Normal
32-
| n == fromEnum ForceSync = ForceSync
33-
| n == fromEnum Blocking = Blocking
34-
| otherwise = error $ "ReadFlag.toEnum: Cannot match " ++ show n
35-
36-
data GrabMode = LibevdevGrab | LibevdevUngrab
37-
deriving (Show)
38-
instance Enum GrabMode where
39-
fromEnum LibevdevGrab = let Raw.Libevdev_grab_mode n = Raw.LIBEVDEV_GRAB in rawEnum n
40-
fromEnum LibevdevUngrab = let Raw.Libevdev_grab_mode n = Raw.LIBEVDEV_UNGRAB in rawEnum n
41-
toEnum n
42-
| n == fromEnum LibevdevGrab = LibevdevGrab
43-
| n == fromEnum LibevdevUngrab = LibevdevUngrab
44-
| otherwise = error $ "GrabMode.toEnum: Cannot match " ++ show n
45-
46-
data LEDValue = LedOn | LedOff
47-
deriving (Bounded, Eq, Ord, Read, Show)
48-
instance Enum LEDValue where
49-
fromEnum LedOn = let Raw.Libevdev_led_value n = Raw.LIBEVDEV_LED_ON in rawEnum n
50-
fromEnum LedOff = let Raw.Libevdev_led_value n = Raw.LIBEVDEV_LED_OFF in rawEnum n
51-
toEnum n
52-
| n == fromEnum LedOn = LedOn
53-
| n == fromEnum LedOff = LedOff
54-
| otherwise = error $ "LEDValue.toEnum: Cannot match " ++ show n
55-
56-
data UInputOpenMode = UOMManaged
57-
deriving (Show)
58-
instance Enum UInputOpenMode where
59-
fromEnum UOMManaged = let Raw.Libevdev_uinput_open_mode n = Raw.LIBEVDEV_UINPUT_OPEN_MANAGED in rawEnum n
60-
toEnum n
61-
| n == fromEnum UOMManaged = UOMManaged
62-
| otherwise = error $ "UInputOpenMode.toEnum: Cannot match " ++ show n
63-
64-
grabModeToRaw :: GrabMode -> Raw.Libevdev_grab_mode
65-
grabModeToRaw = \case
66-
LibevdevGrab -> Raw.LIBEVDEV_GRAB
67-
LibevdevUngrab -> Raw.LIBEVDEV_UNGRAB
68-
69-
ledValueToRaw :: LEDValue -> Raw.Libevdev_led_value
70-
ledValueToRaw = \case
71-
LedOn -> Raw.LIBEVDEV_LED_ON
72-
LedOff -> Raw.LIBEVDEV_LED_OFF
73-
7416
-- * Opaque device types
7517

7618
newtype Device = Device (ForeignPtr Raw.Libevdev)
@@ -180,12 +122,6 @@ getEvent evPtr = do
180122
, cEventTime = CTimeVal (fromIntegral sec) (fromIntegral usec)
181123
}
182124

183-
-- * Grabbing
184-
185-
grabDevice :: Device -> GrabMode -> IO Errno
186-
grabDevice dev mode = withDevice dev $ \devPtr ->
187-
Errno <$> Raw.libevdev_grab devPtr (grabModeToRaw mode)
188-
189125
-- * Device properties (getters)
190126

191127
deviceFd :: Device -> IO Fd
@@ -344,12 +280,6 @@ writeEvent :: UDevice -> Word16 -> Word16 -> Int32 -> IO Errno
344280
writeEvent dev t c v = withUDevice dev $ \devPtr ->
345281
Errno <$> Raw.libevdev_uinput_write_event (constPtr devPtr) (fromIntegral t) (fromIntegral c) (fromIntegral v)
346282

347-
-- * LEDs
348-
349-
libevdev_kernel_set_led_value :: Device -> LEDEvent -> LEDValue -> IO Errno
350-
libevdev_kernel_set_led_value dev led val = withDevice dev $ \devPtr ->
351-
Errno <$> Raw.libevdev_kernel_set_led_value devPtr (convertEnum led) (ledValueToRaw val)
352-
353283
-- * Util
354284

355285
convertEnum :: (Enum a, Integral b) => a -> b

evdev/src/Evdev/Uinput.hs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
{-# LANGUAGE OverloadedRecordDot #-}
2+
13
-- | Create virtual input devices.
24
module Evdev.Uinput (
35
Device,
@@ -30,6 +32,7 @@ import Data.ByteString.Char8 (ByteString)
3032
import Evdev hiding (Device, newDevice)
3133
import Evdev.Codes
3234
import qualified Evdev.LowLevel as LL
35+
import qualified Evdev.Raw as Raw
3336
import Util
3437

3538
-- | A `uinput` device.
@@ -84,7 +87,7 @@ newDevice name DeviceOpts{..} = do
8487
LL.withAbsInfo absInfo $ \ptr ->
8588
enable ptr EvAbs [fromEnum' axis]
8689

87-
fmap Device $ cec $ LL.createFromDevice dev $ fromEnum' LL.UOMManaged
90+
fmap Device $ cec $ LL.createFromDevice dev $ fromIntegral (Raw.LIBEVDEV_UINPUT_OPEN_MANAGED).unwrap
8891
where
8992
cec :: CErrCall a => IO a -> IO (CErrCallRes a)
9093
cec = cErrCall "newDevice" ()

0 commit comments

Comments
 (0)