102 lines
3.1 KiB
Nim
102 lines
3.1 KiB
Nim
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
|
# SPDX-License-Identifier: Unlicense
|
|
|
|
include ./protocol
|
|
|
|
from std/strutils import normalize
|
|
import syndicate
|
|
|
|
{.passC: staticExec("pkg-config --cflags libnotify").}
|
|
{.passL: staticExec("pkg-config --libs libnotify").}
|
|
|
|
const notifyHeader = "<libnotify/notify.h>"
|
|
{.pragma: notify, header: notifyHeader, importc: "notify_$1".}
|
|
{.pragma: notification, header: notifyHeader, importc: "notify_notification_$1".}
|
|
|
|
type
|
|
Notification {.importc: "NotifyNotification".} = ptr object
|
|
discard
|
|
GError {.importc, header: "glib/gerror.h".} = object
|
|
message: cstring
|
|
|
|
proc g_free(mem: pointer) {.importc.}
|
|
proc g_error_free(err: ptr GError) {.importc, header: "glib/gerror.h".}
|
|
|
|
proc init(appName: cstring): bool {.notify.}
|
|
proc uninit() {.notify.}
|
|
|
|
proc get_server_info(name, vendor, version, specVersion: ptr cstring): bool {.notify.}
|
|
|
|
proc notification_new(summary, body, icon: cstring = nil): Notification {.notify.}
|
|
|
|
proc set_app_name(n: Notification; s: string) {.notification.}
|
|
proc set_category(n: Notification; s: string) {.notification.}
|
|
|
|
type NotifyUrgency {.importc.} = enum Low, Normal, Critical
|
|
proc set_urgency(n: Notification; u: NotifyUrgency) {.notification.}
|
|
|
|
proc show(n: Notification) =
|
|
if not show(n, nil):
|
|
stderr.writeLine "show failed"
|
|
|
|
const appName = "libnotify_actor"
|
|
|
|
if not init(appName):
|
|
quit "failed to initialize libnotify"
|
|
|
|
proc show(n: Notification; err: ptr (ptr GError)): bool {.notification.}
|
|
var err: ptr GError
|
|
if not show(n, addr err):
|
|
doAssert not err.isNil, "GLIB shit itself without setting an error"
|
|
doAssert not err.message.isNil, "GLIB shit itself without setting an error message"
|
|
stderr.writeLine "show failed: ", err.message
|
|
if not err.isNil:
|
|
g_error_free(err)
|
|
|
|
proc assertServerInfo(turn: var Turn; ds: Ref) =
|
|
var name, vendor, version, specVersion: cstring
|
|
if get_server_info(addr name, addr vendor, addr version, addr specVersion):
|
|
var a = ServerInfo(
|
|
name: $name,
|
|
vendor: $vendor,
|
|
version: $version,
|
|
specVersion: $specVersion,
|
|
)
|
|
discard publish(turn, ds, a)
|
|
|
|
type Args {.preservesDictionary.} = object
|
|
dataspace: Ref
|
|
|
|
runActor("main") do (root: Ref; turn: var Turn):
|
|
connectStdio(root, turn)
|
|
during(turn, root, ?Args) do (ds: Ref):
|
|
if not init(appName):
|
|
stderr.writeLine "failed to initialize libnotify"
|
|
else:
|
|
assertServerInfo(turn, ds)
|
|
onMessage(turn, ds, ?Notify) do (summary: string, attrs: Attrs):
|
|
let
|
|
body = getOrDefault(attrs, Symbol"body")
|
|
icon = getOrDefault(attrs, Symbol"icon")
|
|
n = notification_new(summary, body, icon)
|
|
|
|
case getOrDefault(attrs, Symbol"urgency").normalize
|
|
of "high", "critical":
|
|
set_urgency(n, Critical)
|
|
of "low":
|
|
set_urgency(n, Low)
|
|
else: discard
|
|
|
|
let app_name = getOrDefault(attrs, Symbol"app_name")
|
|
if app_name != "":
|
|
set_app_name(n, app_name)
|
|
|
|
let category = getOrDefault(attrs, Symbol"category")
|
|
if category != "":
|
|
set_category(n, category)
|
|
|
|
show(n)
|
|
|
|
do:
|
|
uninit()
|