Skip to content

Commit

Permalink
Merge pull request #2 from levovix0/master
Browse files Browse the repository at this point in the history
started x11
  • Loading branch information
treeform authored Oct 13, 2021
2 parents 5752745 + df87be7 commit 7cd9e61
Show file tree
Hide file tree
Showing 7 changed files with 1,168 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/windy.nim
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ export common

when defined(windows):
import windy/platforms/win32/platform
elif defined(linux):
import windy/platforms/x11/platform

type
App* = ref object
Expand Down
121 changes: 121 additions & 0 deletions src/windy/platforms/x11/platform.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import ../../common, x11, os

type
PlatformApp* = ref object
windows*: seq[PlatformWindow]
display: Display

PlatformWindow* = ref PlatformWindowObj
PlatformWindowObj = object
display: Display
handle: Window
ctx: GlxContext
gc: GC
ic: XIC
im: XIM

opened: bool


proc newPlatformApp*(): PlatformApp =
new result
result.display = XOpenDisplay(getEnv("DISPLAY"))
if result.display == nil:
raise WindyError.newException("Error opening X11 display, make sure the DISPLAY environment variable is set correctly")


proc `=destroy`(window: var PlatformWindowObj) =
if window.ic != nil: XDestroyIC(window.ic)
if window.im != nil: discard XCloseIM(window.im)
if window.gc != nil: discard window.display.XFreeGC(window.gc)
if window.handle != 0: discard window.display.XDestroyWindow(window.handle)

proc show*(window: PlatformWindow) =
window.display.XRaiseWindow(window.handle)

proc hide*(window: PlatformWindow) =
window.display.XLowerWindow(window.handle)

proc makeContextCurrent*(window: PlatformWindow) =
discard window.display.glXMakeCurrent(window.handle, window.ctx)

proc swapBuffers*(window: PlatformWindow) =
window.display.glXSwapBuffers(window.handle)

proc newWindow*(
app: PlatformApp,
windowTitle: string,
x, y, w, h: int
): PlatformWindow =
new result
result.display = app.display

let root = app.display.defaultRootWindow

var attribList = [GlxRgba, GlxDepthSize, 24, GlxDoublebuffer]
let vi = app.display.glXChooseVisual(0, attribList[0].addr)

let cmap = app.display.XCreateColormap(root, vi.visual, AllocNone)
var swa = XSetWindowAttributes(colormap: cmap)

result.handle = app.display.XCreateWindow(
root,
x.cint, y.cint,
w.cuint, h.cuint,
0,
vi.depth.cuint,
InputOutput,
vi.visual,
CwColormap or CwEventMask,
swa.addr
)

discard app.display.XMapWindow(result.handle)
var wmProtocols = [app.display.atom "WM_DELETE_WINDOW"]
discard app.display.XSetWMProtocols(result.handle, wmProtocols[0].addr, cint wmProtocols.len)

result.im = app.display.XOpenIM(nil, nil, nil)
result.ic = result.im.XCreateIC(
XNClientWindow,
result.handle,
XNFocusWindow,
result.handle,
XnInputStyle,
XimPreeditNothing or XimStatusNothing,
nil
)

var gcv: XGCValues
result.gc = app.display.XCreateGC(result.handle, GCForeground or GCBackground, gcv.addr)

result.ctx = app.display.glXCreateContext(vi, nil, 1)

if result.ctx == nil:
raise newException(WindyError, "Error creating OpenGL context")

hide result
makeContextCurrent result

app.windows.add result

proc newWindow*(
app: PlatformApp,
windowTitle: string,
width, height: int
): PlatformWindow =
app.newWindow(windowTitle, 0, 0, width, height)

proc poolEvents*(window: PlatformWindow) =
var ev: XEvent

proc checkEvent(d: Display, event: ptr XEvent, userData: pointer): cint {.cdecl.} =
if cast[int](event.xany.window) == cast[int](userData): 1 else: 0

while window.display.XCheckIfEvent(ev.addr, checkEvent, cast[pointer](window)) == 1:
case ev.theType

of ClientMessage:
if ev.xclient.data.l[0] == clong window.display.atom "WM_DELETE_WINDOW":
window.opened = false

else: discard
2 changes: 2 additions & 0 deletions src/windy/platforms/x11/x11.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import x11/[x, xlib, xevent, glx]
export x, xlib, xevent, glx
29 changes: 29 additions & 0 deletions src/windy/platforms/x11/x11/glx.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import x, xlib

type
GlxContext* = ptr object

const
GlxRgba* = 4'i32
GlxDoublebuffer* = 5'i32
GlxDepthSize* = 12'i32


const libGLX =
when defined(linux): "libGL.so.1"
elif defined(windows): "GL.dll"
elif defined(macosx): "/usr/X11R6/lib/libGL.dylib"
else: "libGL.so"

{.pragma: libglx, cdecl, dynlib: libGLX, importc.}


proc glXChooseVisual*(d: Display, screen: cint, attribList: ptr int32): ptr XVisualInfo {.libglx.}

proc glXCreateContext*(d: Display, vis: ptr XVisualInfo, shareList: GlxContext, direct: cint): GlxContext {.libglx.}
proc glXDestroyContext*(d: Display, this: GlxContext) {.libglx.}

proc glXMakeCurrent*(dpy: Display, drawable: Drawable, ctx: GlxContext): cint {.libglx.}
proc glXGetCurrentContext*(): GlxContext {.libglx.}

proc glXSwapBuffers*(dpy: Display, drawable: Drawable) {.libglx.}
Loading

0 comments on commit 7cd9e61

Please sign in to comment.