diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -7,21 +7,22 @@
 Recyle your clipboard selections with greenclip and don't waste your time anymore
 to reselect things other and other.
 
-**Purpose :**
+**Purpose:**
 Keeps track of your history of selections to quickly switch between them
 
-**Demo :** 
-<video controls>
-  <source src="https://github.com/erebe/greenclip/releases/download/1.1/demo.webm" type="video/webm">
- <a href="https://www.youtube.com/watch?v=Utk-9Gy8H3w">Video Link</a>
-</video>
+**Demo:**  <a href="https://www.youtube.com/watch?v=Utk-9Gy8H3w">Video Link</a>
 
-**Installation :**
+**Features:**
+  + Integrated with [rofi](https://github.com/DaveDavenport/rofi)
+  + Permanently set some selections to added at the end (set `staticHistoryPath = your/file/with/static/entries` in the config file)
+  + Merge X Primary selection with clipboard selection (set `usePrimarySelectionAsInput = True` in the config file)
 
-1. It's a static binary so drop it anywhere in your $PATH env 
+**Installation:**
 
-```wget https://github.com/erebe/greenclip/releases/download/1.3/greenclip```
+1. It's a static binary so drop it anywhere in your $PATH env
 
+```wget https://github.com/erebe/greenclip/releases/download/2.0/greenclip```
+
 Alternatively if you are using Archlinux you can install the package from AUR
 
 ``pacman -S greenclip``
@@ -29,7 +30,7 @@
 PS: If you want, you can add a permanent list of selections to be added to your current history. Go see the config file
 
 
-**Usage :**
+**Usage:**
 
 Greenclip is intended to be used with [rofi](https://github.com/DaveDavenport/rofi)
 
@@ -38,7 +39,7 @@
 3. The entry that you have selected will be in your clipboard now
 4. Configuration file can be found in ```.config/greenclip.cfg```
 
-**Compilation :**
+**Compilation:**
 
 1. Get [stack](https://docs.haskellstack.org/en/stable/README/) for Haskell
 2. stack init && stack install
diff --git a/greenclip.cabal b/greenclip.cabal
--- a/greenclip.cabal
+++ b/greenclip.cabal
@@ -3,7 +3,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           greenclip
-version:        2.0.0
+version:        2.0.1
 synopsis:       Simple clipboard manager to be integrated with rofi
 description:    Please see README.md
 category:       Linux Desktop
@@ -27,11 +27,16 @@
   build-depends:
       base >= 4.7 && < 5
     , classy-prelude
-    , Clipboard
     , text
     , vector
     , binary
     , microlens
     , microlens-mtl
     , directory
+    , X11 >= 1.6
+    , utf8-string
+    , unix
+    , directory
+  other-modules:
+      Clipboard
   default-language: Haskell2010
diff --git a/src/Clipboard.hs b/src/Clipboard.hs
new file mode 100644
--- /dev/null
+++ b/src/Clipboard.hs
@@ -0,0 +1,119 @@
+{-# LANGUAGE RecordWildCards #-}
+
+module Clipboard
+  ( getClipboardString
+  , setClipboardString
+  , getPrimaryClipboard
+  ) where
+
+import Graphics.X11.Xlib
+import Graphics.X11.Xlib.Extras
+import System.Posix.Process     (forkProcess)
+
+import Codec.Binary.UTF8.String (decode, encode)
+import Control.Monad
+import Data.Maybe
+import Foreign                  (peekByteOff)
+import Foreign.C.Types          (CChar, CUChar)
+import Foreign.Marshal.Array    (withArrayLen)
+import System.Directory         (setCurrentDirectory)
+import System.IO                (hClose, stderr, stdin, stdout)
+import System.IO.Unsafe (unsafePerformIO)
+import Data.IORef
+import Control.Concurrent (threadDelay)
+
+getClipboardString :: IO (Maybe String)
+getClipboardString = do
+    (display, window, clipboards) <- readIORef initialSetup
+    inp <- internAtom display "clipboard_get" False
+    target <- internAtom display "UTF8_STRING" True
+    xConvertSelection display (head clipboards) target inp window currentTime
+    Just <$> clipboardInputWait display window inp
+
+getPrimaryClipboard :: IO (Maybe String)
+getPrimaryClipboard = do
+    (display, window, clipboards) <- readIORef initialSetup
+    inp <- internAtom display "clipboard_get" False
+    target <- internAtom display "UTF8_STRING" True
+    xConvertSelection display (clipboards !! 1) target inp window currentTime
+    Just <$> clipboardInputWait display window inp
+
+clipboardInputWait :: Display -> Window -> Atom -> IO String
+clipboardInputWait display' window' inp' = allocaXEvent (go display' window' inp')
+  where
+  go display window inp evPtr = do
+    waitForEvent display
+    nextEvent display evPtr
+    ev <- getEvent evPtr
+    if ev_event_type ev == selectionNotify
+       then charsToString . fromMaybe mempty <$> getWindowProperty8 display inp window
+       else go display window inp evPtr
+  waitForEvent display = do
+    nbEvs <- pending display
+    when (nbEvs == 0) $ threadDelay 100000 >> waitForEvent display
+
+charsToString :: [CChar] -> String
+charsToString = decode . map fromIntegral
+
+setClipboardString :: String -> IO ()
+setClipboardString str = void $ forkProcess $ do
+        mapM_ hClose [stdin, stdout, stderr]
+        setCurrentDirectory "/"
+        (display, window, clipboards) <- readIORef initialSetup
+        mapM_ (\atom -> xSetSelectionOwner display atom window currentTime) clipboards
+        advertiseSelection display clipboards (stringToChars str)
+        cleanup display window
+
+advertiseSelection :: Display -> [Atom] -> [CUChar] -> IO ()
+advertiseSelection display clipboards' str = allocaXEvent (go clipboards')
+  where
+    go [] _ = return ()
+    go clipboards evPtr = do
+      nextEvent display evPtr
+      ev <- getEvent evPtr
+      case ev of
+          SelectionRequest {..} -> do
+              target' <- getAtomName display ev_target
+              res <- handleOutput display ev_requestor ev_property target' str
+              sendSelectionNotify display ev_requestor ev_selection ev_target res ev_time
+              go clipboards evPtr
+
+          _ | ev_event_type ev == selectionClear -> do
+              target <- peekByteOff evPtr 40 :: IO Atom
+              go (filter (/= target) clipboards) evPtr
+
+          _ -> go clipboards evPtr
+
+handleOutput :: Display -> Window -> Atom -> Maybe String -> [CUChar] -> IO Atom
+handleOutput display req prop (Just "UTF8_STRING") str = do
+    prop' <- getAtomName display prop
+    if isNothing prop' then handleOutput display req prop Nothing str else do
+        target <- internAtom display "UTF8_STRING" True
+        void $ withArrayLen str $ \len str' ->
+            xChangeProperty display req prop target 8 propModeReplace str'
+                            (fromIntegral len)
+        return prop
+handleOutput _ _ _ _ _ = return none
+
+sendSelectionNotify :: Display -> Window -> Atom -> Atom -> Atom -> Time -> IO ()
+sendSelectionNotify display req sel target prop time = allocaXEvent $ \ev -> do
+    setEventType ev selectionNotify
+    setSelectionNotify ev req sel target prop time
+    sendEvent display req False 0 ev
+
+stringToChars :: String -> [CUChar]
+stringToChars = map fromIntegral . encode
+
+initialSetup :: IORef (Display, Window, [Atom])
+initialSetup = unsafePerformIO $ do
+    display <- openDisplay ""
+    window <- createSimpleWindow display (defaultRootWindow display)
+                                 0 0 1 1 0 0 0
+    clipboards <- internAtom display "CLIPBOARD" False
+    newIORef (display, window, [clipboards, pRIMARY])
+{-# NOINLINE initialSetup #-}
+
+cleanup :: Display -> Window -> IO ()
+cleanup display window = do
+    destroyWindow display window
+    closeDisplay display
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -14,7 +14,7 @@
 import qualified Data.Vector        as V
 import           Lens.Micro
 import           Lens.Micro.Mtl
-import qualified System.Clipboard   as Clip
+import qualified Clipboard   as Clip
 import qualified System.Directory   as Dir
 import           System.Environment (lookupEnv)
 import           System.IO          (IOMode (..), openFile)
@@ -153,7 +153,7 @@
     -- Should rename COPY into ADVERTISE but as greenclip is already used I don't want to break configs
     -- of other people
     COPY sel -> advertiseSelection sel
-    HELP     -> putStrLn $ "greenclip v1.3 -- Recyle your clipboard selections\n\n" <>
+    HELP     -> putStrLn $ "greenclip v2.0 -- Recyle your clipboard selections\n\n" <>
                            "Available commands\n" <>
                            "daemon: Spawn the daemon that will listen to selections\n" <>
                            "print:  Display all selections history\n" <>
