2021-12-05 02:34:14 +00:00
|
|
|
## This example show how to have real time pixie using the X11 API.
|
|
|
|
|
2021-12-05 02:46:32 +00:00
|
|
|
import math, pixie, std/os
|
|
|
|
import
|
|
|
|
x11/xlib,
|
|
|
|
x11/xutil,
|
|
|
|
x11/x
|
2021-12-05 02:34:14 +00:00
|
|
|
|
|
|
|
let
|
|
|
|
w: int32 = 256
|
|
|
|
h: int32 = 256
|
|
|
|
|
|
|
|
var
|
|
|
|
screen = newImage(w, h)
|
|
|
|
ctx = newContext(screen)
|
|
|
|
|
|
|
|
var
|
|
|
|
display: PDisplay
|
|
|
|
window: Window
|
|
|
|
deleteMessage: Atom
|
|
|
|
graphicsContext: GC
|
|
|
|
frameCount = 0
|
|
|
|
|
|
|
|
proc render() =
|
|
|
|
## Called every frame by main while loop
|
|
|
|
|
|
|
|
# draw shiny sphere on gradient background
|
|
|
|
let linerGradient = newPaint(pkGradientLinear)
|
|
|
|
linerGradient.gradientHandlePositions.add(vec2(0, 0))
|
|
|
|
linerGradient.gradientHandlePositions.add(vec2(0, 256))
|
|
|
|
linerGradient.gradientStops.add(
|
|
|
|
ColorStop(color: pixie.color(0, 0, 0, 1), position: 0))
|
|
|
|
linerGradient.gradientStops.add(
|
|
|
|
ColorStop(color: pixie.color(1, 1, 1, 1), position: 1))
|
|
|
|
ctx.fillStyle = linerGradient
|
|
|
|
ctx.fillRect(0, 0, 256, 256)
|
|
|
|
let radialGradient = newPaint(pkGradientRadial)
|
|
|
|
radialGradient.gradientHandlePositions.add(vec2(128, 128))
|
|
|
|
radialGradient.gradientHandlePositions.add(vec2(256, 128))
|
|
|
|
radialGradient.gradientHandlePositions.add(vec2(128, 256))
|
|
|
|
radialGradient.gradientStops.add(
|
|
|
|
ColorStop(color: pixie.color(1, 1, 1, 1), position: 0))
|
|
|
|
radialGradient.gradientStops.add(
|
|
|
|
ColorStop(color: pixie.color(0, 0, 0, 1), position: 1))
|
|
|
|
ctx.fillStyle = radialGradient
|
|
|
|
ctx.fillCircle(circle(
|
|
|
|
vec2(128.0, 128.0 + sin(float32(frameCount)/10.0) * 20),
|
|
|
|
76.8
|
|
|
|
))
|
|
|
|
inc frameCount
|
|
|
|
var frameBuffer = addr ctx.image.data[0]
|
|
|
|
let image = XCreateImage(display, DefaultVisualOfScreen(
|
|
|
|
DefaultScreenOfDisplay(display)), 24, ZPixmap, 0, cast[cstring](
|
|
|
|
frameBuffer), w.cuint, h.cuint, 8, w*4)
|
|
|
|
discard XPutImage(display, window, graphicsContext, image, 0, 0, 0, 0, w.cuint, h.cuint)
|
|
|
|
|
|
|
|
const
|
|
|
|
borderWidth = 0
|
|
|
|
eventMask = ButtonPressMask or KeyPressMask or ExposureMask
|
|
|
|
|
|
|
|
proc init() =
|
|
|
|
display = XOpenDisplay(nil)
|
|
|
|
if display == nil:
|
|
|
|
quit "Failed to open display"
|
|
|
|
|
|
|
|
let
|
|
|
|
screen = XDefaultScreen(display)
|
|
|
|
rootWindow = XRootWindow(display, screen)
|
|
|
|
foregroundColor = XBlackPixel(display, screen)
|
|
|
|
backgroundColor = XWhitePixel(display, screen)
|
|
|
|
|
|
|
|
window = XCreateSimpleWindow(display, rootWindow, -1, -1, w.cuint, h.cuint,
|
|
|
|
borderWidth, foregroundColor, backgroundColor)
|
|
|
|
|
|
|
|
|
|
|
|
discard XSetStandardProperties(display, window, "X11 Example", "window", 0,
|
|
|
|
nil, 0, nil)
|
|
|
|
|
|
|
|
discard XSelectInput(display, window, eventMask)
|
|
|
|
discard XMapWindow(display, window)
|
|
|
|
|
|
|
|
deleteMessage = XInternAtom(display, "WM_DELETE_WINDOW", false.XBool)
|
|
|
|
discard XSetWMProtocols(display, window, deleteMessage.addr, 1)
|
|
|
|
|
|
|
|
graphicsContext = XDefaultGC(display, screen)
|
|
|
|
|
|
|
|
|
|
|
|
proc mainLoop() =
|
|
|
|
## Process events until the quit event is received
|
|
|
|
var event: XEvent
|
|
|
|
var exposed: bool = false
|
|
|
|
while true:
|
|
|
|
if exposed: render()
|
|
|
|
if XPending(display) > 0:
|
|
|
|
discard XNextEvent(display, event.addr)
|
|
|
|
case event.theType
|
|
|
|
of Expose:
|
|
|
|
render()
|
|
|
|
exposed = true
|
|
|
|
of ClientMessage:
|
|
|
|
if cast[Atom](event.xclient.data.l[0]) == deleteMessage:
|
|
|
|
break
|
|
|
|
of KeyPress:
|
|
|
|
let key = XLookupKeysym(cast[PXKeyEvent](event.addr), 0)
|
|
|
|
if key != 0:
|
|
|
|
echo "Key ", key, " pressed"
|
|
|
|
of ButtonPressMask:
|
|
|
|
echo "Mouse button ", event.xbutton.button, " pressed at ",
|
|
|
|
event.xbutton.x, ",", event.xbutton.y
|
|
|
|
else:
|
|
|
|
discard
|
|
|
|
sleep 14
|
|
|
|
|
|
|
|
proc main() =
|
|
|
|
init()
|
|
|
|
mainLoop()
|
|
|
|
discard XDestroyWindow(display, window)
|
|
|
|
discard XCloseDisplay(display)
|
|
|
|
|
|
|
|
main()
|