   [player]
   (show-spinner player))
 
-(defn handle-update-state
-  "Applies given function (with args) to player."
-  [player [f & args]]
-  (apply f player args))
+(defn handle-frame
+  "Updates screen with given frame and resets cursor visibility."
+  [player [frame]]
+  (-> player
+      (update-screen frame)
+      reset-blink))
+
+(defn handle-blink
+  "Shows or hides the cursor."
+  [player [cursor-on?]]
+  (assoc-in player [:cursor :on] cursor-on?))
+
+(defn handle-time
+  "Updates player's current time (as displayed in control bar)."
+  [player [t]]
+  (assoc player :current-time t))
 
 (def event-handlers {:toggle-play handle-toggle-play
                      :seek handle-seek

                     :bad-response handle-bad-response
                     :stream-connected handle-stream-connected
                     :stream-disconnected handle-stream-disconnected
                     :update-state handle-update-state})

(defn process-event
  "Finds handler for the given event and applies it to the player."

  [player & _]
  (-> player :source :type))

(defn priority-chan
  "Given primary channel and a function f returning secondary channel, returns a
  new channel that emits values from both primary and secondary channel. Every
  time there is a take from primary channel the current secondary channel is
  discarded and the new one is obtained by calling f. The resulting channel is
  closed when either input channel closes."
  [[primary-label primary-ch] [secondary-label secondary-fn]]
  (let [output-ch (chan)]
    (go-loop [secondary-ch (secondary-fn)]
      (let [[v c] (alts! [primary-ch secondary-ch])]
        (if-not (nil? v)
          (condp = c
            primary-ch (do (>! output-ch [primary-label v]) (recur (secondary-fn)))
            secondary-ch (do (>! output-ch [secondary-label v]) (recur secondary-ch)))
          (close! output-ch))))
    output-ch))

(defn screen-events
  "Given frames channel returns a channel of player events (as used with
  `dispatch`). The resulting channel produces screen update events (:frame)
  intermixed with cursor blinking events (:blink)."
  [frames-ch]
  (priority-chan [:frame frames-ch] [:blink make-cursor-blink-chan]))

(defmulti start-playback
  "The heart of the player. Coordinates dispatching of state update events like
  terminal line updating, time reporting and cursor blinking. Returns player
