Created
February 7, 2019 22:54
-
-
Save kropp/bd8628cce07c81a0c458be565bad4801 to your computer and use it in GitHub Desktop.
X11 app in Kotln/Native
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.github.kropp | |
import kotlinx.cinterop.* | |
import x11.* | |
const val APPLICATION_NAME = "spotlight" | |
const val SIZE = 800 | |
@ExperimentalUnsignedTypes | |
data class Size(val width: UInt, val height: UInt) { | |
companion object { | |
val EMPTY = Size(0u, 0u) | |
} | |
} | |
@ExperimentalUnsignedTypes | |
fun screenSize(display: CPointer<Display>): Size { | |
val screen = XDefaultScreenOfDisplay(display) ?: return Size.EMPTY | |
val screenWidth = screen.pointed.width.toUInt() | |
val screenHeight = screen.pointed.height.toUInt() | |
XFree(screen) | |
return Size(screenWidth, screenHeight) | |
} | |
@kotlin.ExperimentalUnsignedTypes | |
fun main() { | |
val display = XOpenDisplay(null) ?: error("Can't open display") | |
val screenNumber = XDefaultScreen(display) | |
val screen = screenSize(display) | |
val window = memScoped { | |
val visualInfo = alloc<XVisualInfo>() | |
XMatchVisualInfo(display, screenNumber, 32, TrueColor, visualInfo.ptr) | |
val attrs = alloc<XSetWindowAttributes> { | |
override_redirect = 1 | |
colormap = XCreateColormap(display, XDefaultRootWindow(display), visualInfo.visual, AllocNone) | |
border_pixel = 0UL | |
background_pixel = 0xffffffUL | |
}.ptr | |
XCreateWindow(display, XRootWindow(display, screenNumber), 0, 0, screen.width, screen.height, 0, visualInfo.depth, CopyFromParent.toUInt(), | |
visualInfo.visual, (CWColormap or CWBorderPixel or CWBackPixel or CWOverrideRedirect).toULong(), attrs) | |
} | |
XStoreName(display, window, APPLICATION_NAME) | |
XMapWindow(display, window) | |
XRaiseWindow(display, window) | |
XFlush(display) | |
val mouse = MousePointer(display, window) | |
memScoped { | |
val hint = alloc<XClassHint> { | |
res_name = APPLICATION_NAME.cstr.ptr | |
res_class = APPLICATION_NAME.cstr.ptr | |
} | |
XSetClassHint(display, window, hint.ptr) | |
} | |
val gc = memScoped { | |
val values = alloc<XGCValues> { graphics_exposures = False }.ptr | |
XCreateGC(display, window, 0UL, values) | |
} | |
memScoped { | |
// Keep the window on top | |
val e = alloc<XEvent> { | |
xclient.apply { | |
type = ClientMessage | |
message_type = XInternAtom(display, "_NET_WM_STATE", False) | |
this.display = display | |
this.window = window | |
format = 32 | |
serial = 0UL | |
data.l[0] = 1 | |
data.l[1] = XInternAtom(display, "_NET_WM_STATE_STAYS_ON_TOP", False).toLong() | |
} | |
} | |
XSendEvent(display, XRootWindow(display, screenNumber), False, SubstructureRedirectMask, e.ptr) | |
XSetForeground(display, gc, 0x55000000UL) | |
XFillRectangle(display, window, gc, 0, 0, screen.width, screen.height) | |
XFlush(display) | |
XSelectInput(display, window, PointerMotionMask or ButtonPressMask or ButtonReleaseMask or KeyPressMask or KeyReleaseMask) | |
val event = alloc<XEvent>() | |
mouse.hide() | |
while (true) { | |
XNextEvent(display, event.ptr) | |
XSetForeground(display, gc, 0xdd000000UL) | |
XFillRectangle(display, window, gc, 0, 0, screen.width, screen.height) | |
if (event.type == MotionNotify) { | |
XSetForeground(display, gc, 0x00000000UL) | |
XFillArc(display, window, gc, event.xmotion.x - SIZE / 2, event.xmotion.y - SIZE / 2, SIZE.toUInt(), SIZE.toUInt(), 0, 360 * 64) | |
XFlush(display) | |
} | |
} | |
} | |
} | |
@kotlin.ExperimentalUnsignedTypes | |
class MousePointer(private val display: CPointer<Display>, private val window: Window) { | |
fun hide() = memScoped { | |
val bitmap = XCreateBitmapFromData(display, window, ByteArray(8) { 0 }.toCValues(), 8, 8) | |
val black = alloc<XColor> { | |
red = 0U | |
green = 0U | |
blue = 0U | |
} | |
val cursor = XCreatePixmapCursor(display, bitmap, bitmap, black.ptr, black.ptr, 0, 0) | |
XDefineCursor(display, window, cursor) | |
XFreeCursor(display, cursor) | |
XFreePixmap(display, bitmap) | |
} | |
fun show() { | |
XUndefineCursor(display, window) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package = x11 | |
headers = X11/Xlib.h X11/Xutil.h X11/Xatom.h | |
headerFilter = X11/* | |
compilerOpts = -I/usr/include/ -I/usr/include/x86_64-linux-gnu | |
linkerOpts = -lX11 -L/usr/lib/x86_64-linux-gnu/ | |
noStringConversion = XCreateBitmapFromData |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment