Commit f54ce89a authored by pyb's avatar pyb

Initial commit to git : zen v 0.5

parents
This diff is collapsed.
This is zen, the Hackable X server.
In just 5500 lines of Common Lisp.
INSTRUCTIONS :
You will need :
Linux.
A decent OpenGL driver, and therefore, unfortunately, a running X server :) (to create a GLX context)
SBCL with cl-opengl, CFFI, CLX, Skippy, CL-PPCRE, bordeaux-threads
Starting zen :
1) Identify the mouse and keyboard devices /dev/input/event<n> by reading /proc/bus/input/devices. Modify your input-devices.lisp accordingly.
2) sudo chmod ugo+r /dev/input/*
3) In SBCL , (compile-file "data/keys")
4) Load "start.lisp" in sbcl
5) (start)
... and if (when) you crash :
6) (rst)
Testing apps : in a terminal,
export DISPLAY=127.0.0.1:3
Then start your app.
FUN WITH ZEN
The 3 most interesting/fun things to hack on right now are :
- Optimization. The low hanging fruit is here for you to pick up :)
(require 'sb-sprof)
(sb-sprof:start-profiling :sample-interval 0.001 :threads :all :sampling t))
<run a slow app>
(sb-sprof:stop-profiling)
(sb-sprof:report)
<see what happens>
- Simplifying : zen could definitely become even leaner than it is now.
- XRender implementation
(but potentially a big job)
[Of course, there are also a large number of work items to turn zen into a 'production server', but that was never the point ! ]
LIMITATIONS
You will notice that zen is quite slow and buggy. Please feel free to report : zen crashes, and app crashes/exits that could be caused by X protocol bugs.
Most noticeable issing features :
- All kinds of grabs
- Various old fashioned rendering requests : CopyPlanes ; Arcs, and more
- Most GC fields are ignored
- see also a whole section of unimplemented requests.
* The bad (do not read this code !) :
Font support : no use improving on this, as modern apps render them client-side anyway.
SW cursor : no use improving on this either, this is a hack that wouldn't belong in a production server.
CONTACT
[email protected]
All the files in this package are (c) 2011 Pierre-Yves Baccou, unless specified otherwise.
(define-constant +event-bits+
'((#x00000001 . :KeyPress)
(#x00000002 . :KeyRelease)
(#x00000004 . :ButtonPress)
(#x00000008 . :ButtonRelease)
(#x00000010 . :EnterWindow)
(#x00000020 . :LeaveWindow)
(#x00000040 . :PointerMotion)
(#x00000080 . :PointerMotionHint)
(#x00000100 . :Button1Motion)
(#x00000200 . :Button2Motion)
(#x00000400 . :Button3Motion)
(#x00000800 . :Button4Motion)
(#x00001000 . :Button5Motion)
(#x00002000 . :ButtonMotion)
(#x00004000 . :KeymapState)
(#x00008000 . :Exposure)
(#x00010000 . :VisibilityChange)
(#x00020000 . :StructureNotify)
(#x00040000 . :ResizeRedirect)
(#x00080000 . :SubstructureNotify)
(#x00100000 . :SubstructureRedirect)
(#x00200000 . :FocusChange)
(#x00400000 . :PropertyChange)
(#x00800000 . :ColormapChange)
(#x01000000 . :OwnerGrabButton)))
(define-constant +keybutmask-bits+
'((#x0001 . :Shift)
(#x0002 . :Lock)
(#x0004 . :Control)
(#x0008 . :Mod1)
(#x0010 . :Mod2)
(#x0020 . :Mod3)
(#x0040 . :Mod4)
(#x0080 . :Mod5)
(#x0100 . :Button1)
(#x0200 . :Button2)
(#x0400 . :Button3)
(#x0800 . :Button4)
(#x1000 . :Button5)
(#x8000 . :AnyModifier)))
(define-constant SETofEVENT
`(BITMASK CARD32 ,+event-bits+))
(define-constant SETofDEVICEEVENT
`(BITMASK CARD16 ,+event-bits+)) ; smaller mask fits in 2 bytes
(define-constant SETofPOINTEREVENT
`(BITMASK CARD16 ,+event-bits+)) ; smaller mask fits in 2 bytes
(define-constant SETofKEYMASK
`(BITMASK CARD16 ,+keybutmask-bits+)) ; smaller mask fits in 2 bytes
(define-constant +createwindow-mask-values+
`((#x00000001 . ((or (ENUM CARD32 ((0 . nil)
(1 . :ParentRelative)))
PIXMAP)
background-pixmap))
(#x00000002 . (CARD32 background-pixel))
(#x00000004 . ((or (ENUM CARD32 ((0 . :CopyFromParent)))
PIXMAP)
border-pixmap))
(#x00000008 . (CARD32 border-pixel))
(#x00000010 . ((ENUM CARD8 ((0 . :Forget)
(1 . :NorthWest)
(2 . :North)
(3 . :NorthEast)
(4 . :West)
(5 . :Center)
(6 . :East)
(7 . :SouthWest)
(8 . :South)
(9 . :SouthEast)
(10 . :Static)))
bit-gravity))
(#x00000020 . ((ENUM CARD8 ((0 . :Unmap)
(1 . :NorthWest)
(2 . :North)
(3 . :NorthEast)
(4 . :West)
(5 . :Center)
(6 . :East)
(7 . :SouthWest)
(8 . :South)
(9 . :SouthEast)
(10 . :Static)))
win-gravity))
(#x00000040 . ((ENUM CARD8 ((0 . :NotUseful)
(1 . :WhenMapped)
(2 . :Always)))
backing-store))
(#x00000080 . (CARD32 backing-planes))
(#x00000100 . (CARD32 backing-pixel))
(#x00000200 . (BOOL/4 override-redirect))
(#x00000400 . (BOOL/4 save-under))
(#x00000800 . (,SETofEVENT event-mask))
(#x00001000 . (,SETofDEVICEEVENT do-not-propagate-mask))
(#x00002000 . ((or (ENUM CARD32 ((0 . :CopyFromParent)))
COLORMAP)
colormap))
(#x00004000 . ((or (ENUM CARD32 ((0 . nil)))
CURSOR)
cursor))))
(define-constant +createGC-mask-values+
'((#x00000001 . ((ENUM CARD8/4 ((0 . :Clear)
(1 . :And)
(2 . :AndReverse)
(3 . :Copy)
(4 . :AndInverted)
(5 . :NoOp)
(6 . :Xor)
(7 . :Or)
(8 . :Nor)
(9 . :Equiv)
(10 . :Invert)
(11 . :OrReverse)
(12 . :CopyInverted)
(13 . :OrInverted)
(14 . :Nand)
(15 . :Set)))
function))
(#x00000002 . (CARD32 plane-mask))
(#x00000004 . (CARD32 foreground))
(#x00000008 . (CARD32 background))
(#x00000010 . (CARD16/4 line-width))
(#x00000020 . ((ENUM CARD8/4 ((0 . :Solid)
(1 . :OnOffDash)
(2 . :DoubleDash)))
line-style))
(#x00000040 . ((ENUM CARD8/4 ((0 . :NotLast)
(1 . :Butt)
(2 . :Round)
(3 . :Projecting)))
cap-style))
(#x00000080 . ((ENUM CARD8/4 ((0 . :Miter)
(1 . :Round)
(2 . :Bevel)))
join-style))
(#x00000100 . ((ENUM CARD8/4 ((0 . :Solid)
(1 . :Tiled)
(2 . :Stippled)
(3 . :OpaqueStippled)))
fill-style))
(#x00000200 . ((ENUM CARD8/4 ((0 . :EvenOdd)
(1 . :Winding)))
fill-rule))
(#x00000400 . (PIXMAP tile))
(#x00000800 . (PIXMAP stipple))
(#x00001000 . (INT16/4 tile-stipple-x-origin))
(#x00002000 . (INT16/4 tile-stipple-y-origin))
(#x00004000 . (FONT font))
(#x00008000 . ((ENUM CARD8/4 ((0 . :ClipByChildren)
(1 . :IncludeInferiors)))
subwindow-mode))
(#x00010000 . (BOOL/4 graphics-exposures))
(#x00020000 . (INT16/4 clip-x-origin))
(#x00040000 . (INT16/4 clip-y-origin))
(#x00080000 . ((or (ENUM CARD32 ((0 . nil)))
PIXMAP)
clip-mask))
(#x00100000 . (CARD16/4 dash-offset))
(#x00200000 . (CARD8/4 dashes))
(#x00400000 . ((ENUM CARD8/4 ((0 . :Chord)
(1 . :PieSlice)))
arc-mode))))
(define-constant +copyGC-mask-values+
(mapcar #'(lambda (item)
(bind (mask . (fn var))
item
(cons mask var)))
+createGC-mask-values+))
(intern-atom "PRIMARY")
(intern-atom "SECONDARY")
(intern-atom "ARC")
(intern-atom "ATOM")
(intern-atom "BITMAP")
(intern-atom "CARDINAL")
(intern-atom "COLORMAP")
(intern-atom "CURSOR")
(intern-atom "CUT_BUFFER0")
(intern-atom "CUT_BUFFER1")
(intern-atom "CUT_BUFFER2")
(intern-atom "CUT_BUFFER3")
(intern-atom "CUT_BUFFER4")
(intern-atom "CUT_BUFFER5")
(intern-atom "CUT_BUFFER6")
(intern-atom "CUT_BUFFER7")
(intern-atom "DRAWABLE")
(intern-atom "FONT")
(intern-atom "INTEGER")
(intern-atom "PIXMAP")
(intern-atom "POINT")
(intern-atom "RECTANGLE")
(intern-atom "RESOURCE_MANAGER")
(intern-atom "RGB_COLOR_MAP")
(intern-atom "RGB_BEST_MAP")
(intern-atom "RGB_BLUE_MAP")
(intern-atom "RGB_DEFAULT_MAP")
(intern-atom "RGB_GRAY_MAP")
(intern-atom "RGB_GREEN_MAP")
(intern-atom "RGB_RED_MAP")
(intern-atom "STRING")
(intern-atom "VISUALID")
(intern-atom "WINDOW")
(intern-atom "WM_COMMAND")
(intern-atom "WM_HINTS")
(intern-atom "WM_CLIENT_MACHINE")
(intern-atom "WM_ICON_NAME")
(intern-atom "WM_ICON_SIZE")
(intern-atom "WM_NAME")
(intern-atom "WM_NORMAL_HINTS")
(intern-atom "WM_SIZE_HINTS")
(intern-atom "WM_ZOOM_HINTS")
(intern-atom "MIN_SPACE")
(intern-atom "NORM_SPACE")
(intern-atom "MAX_SPACE")
(intern-atom "END_SPACE")
(intern-atom "SUPERSCRIPT_X")
(intern-atom "SUPERSCRIPT_Y")
(intern-atom "SUBSCRIPT_X")
(intern-atom "SUBSCRIPT_Y")
(intern-atom "UNDERLINE_POSITION")
(intern-atom "UNDERLINE_THICKNESS")
(intern-atom "STRIKEOUT_ASCENT")
(intern-atom "STRIKEOUT_DESCENT")
(intern-atom "ITALIC_ANGLE")
(intern-atom "X_HEIGHT")
(intern-atom "QUAD_WIDTH")
(intern-atom "WEIGHT")
(intern-atom "POINT_SIZE")
(intern-atom "RESOLUTION")
(intern-atom "COPYRIGHT")
(intern-atom "NOTICE")
(intern-atom "FONT_NAME")
(intern-atom "FAMILY_NAME")
(intern-atom "FULL_NAME")
(intern-atom "CAP_HEIGHT")
(intern-atom "WM_CLASS")
(intern-atom "WM_TRANSIENT_FOR")
This diff is collapsed.
;; (C) 2011 Pierre-Yves Baccou
(require "util" "util/util")
(eval-when (:compile-toplevel :load-toplevel :execute)
(enable-braces '(nil nil)))
(define-constant +error-codes+
'((1 . :Request)
(2 . :Value)
(3 . :Window)
(4 . :Pixmap)
(5 . :XAtom)
(6 . :Cursor)
(7 . :Font)
(8 . :Match)
(9 . :Drawable)
(10 . :Access)
(11 . :Alloc)
(12 . :Colormap)
(13 . :gc)
(14 . :Idchoice)
(15 . :Name)
(16 . :Length)
(17 . :Implementation)))
;; disable sqbraces.
(eval-when (:compile-toplevel :load-toplevel :execute)
(setf *readtable* (copy-readtable nil)))
;; (C) 2011 Pierre-Yves Baccou
;; Note : _all_ nils are :Nones.
(eval-when (:compile-toplevel :load-toplevel :execute)
;
(require "util" "util/util")
;
(enable-braces '(nil nil))
);
(defmacro interpret-events (&rest protos)
(cons 'progn
(mapcar #'(lambda (proto)
`(deftranslator/event ,(first proto) ,@(rest proto)))
protos)))
(deftranslator/event :Error ; errors can be seen as events here
(1 {error} 0)
(1 (CARD8 code))
(2 (CARD16 sequence-number))
(4 (CARD32 resource)) ; can be the bad id, the bad atom or the bad value
(2 (CARD16 minor-opcode))
(1 (CARD8 major-opcode))
(21 {unused}))
(interpret-events
;
(:KeyPress
(1 {code} 2)
(1 (KEYCODE detail))
(2 (CARD16 sequence-number))
(4 (TIMESTAMP time))
(4 (WINDOW root))
(4 (WINDOW eventwin))
(4 ((or (ENUM CARD32 ((0 . nil)))
WINDOW)
child))
(2 (INT16 root-x))
(2 (INT16 root-y))
(2 (INT16 event-x))
(2 (INT16 event-y))
(2 (#.SETofKEYMASK state))
(1 (BOOL same-screen))
(1 {unused}))
(:KeyRelease
(1 {code} 3)
(1 (KEYCODE detail))
(2 (CARD16 sequence-number))
(4 (TIMESTAMP time))
(4 (WINDOW root))
(4 (WINDOW eventwin))
(4 ((or (ENUM CARD32 ((0 . nil)))
WINDOW)
child))
(2 (INT16 root-x))
(2 (INT16 root-y))
(2 (INT16 event-x))
(2 (INT16 event-y))
(2 (#.SETofKEYMASK state))
(1 (BOOL same-screen))
(1 {unused}))
(:ButtonPress
(1 {code} 4)
(1 (BUTTON detail))
(2 (CARD16 sequence-number))
(4 (TIMESTAMP time))
(4 (WINDOW root))
(4 (WINDOW eventwin))
(4 ((or (ENUM CARD32 ((0 . nil)))
WINDOW)
child))
(2 (INT16 root-x))
(2 (INT16 root-y))
(2 (INT16 event-x))
(2 (INT16 event-y))
(2 (#.SETofKEYMASK state))
(1 (BOOL same-screen))
(1 {unused}))
(:ButtonRelease
(1 {code} 5)
(1 (BUTTON detail))
(2 (CARD16 sequence-number))
(4 (TIMESTAMP time))
(4 (WINDOW root))
(4 (WINDOW eventwin))
(4 ((or (ENUM CARD32 ((0 . nil)))
WINDOW)
child))
(2 (INT16 root-x))
(2 (INT16 root-y))
(2 (INT16 event-x))
(2 (INT16 event-y))
(2 (#.SETofKEYMASK state))
(1 (BOOL same-screen))
(1 {unused}))
(:MotionNotify
(1 {code} 6)
(1 ((ENUM CARD8 ((0 . :Normal)
(1 . :Hint)))
detail))
(2 (CARD16 sequence-number))
(4 (TIMESTAMP time))
(4 (WINDOW root))
(4 (WINDOW eventwin))
(4 ((or (ENUM CARD32 ((0 . nil)))
WINDOW)
child))
(2 (INT16 root-x))
(2 (INT16 root-y))
(2 (INT16 event-x))
(2 (INT16 event-y))
(2 (#.SETofKEYMASK state))
(1 (BOOL same-screen))
(1 {unused}))
(:EnterNotify
(1 {code} 7)
(1 ((ENUM CARD8 ((0 . :Ancestor)
(1 . :Virtual)
(2 . :Inferior)
(3 . :Nonlinear)
(4 . :NonlinearVirtual)))
detail))
(2 (CARD16 sequence-number))
(4 (TIMESTAMP time))
(4 (WINDOW root))
(4 (WINDOW eventwin))
(4 ((or (ENUM CARD32 ((0 . nil)))
WINDOW)
child))
(2 (INT16 root-x))
(2 (INT16 root-y))
(2 (INT16 event-x))
(2 (INT16 event-y))
(2 (#.SETofKEYMASK state))
(1 ((ENUM CARD8 ((0 . :Normal)
(1 . :Grab)
(2 . :Ungrab)))
mode))
(1 ((BITMASK CARD8 ((#x01 . :focus)
(#x02 . :same-screen)))
same-screen/focus)))
(:LeaveNotify
(1 {code} 8)
(1 ((ENUM CARD8 ((0 . :Ancestor)
(1 . :Virtual)
(2 . :Inferior)
(3 . :Nonlinear)
(4 . :NonlinearVirtual)))
detail))
(2 (CARD16 sequence-number))
(4 (TIMESTAMP time))
(4 (WINDOW root))
(4 (WINDOW eventwin))
(4 ((or (ENUM CARD32 ((0 . nil)))
WINDOW)
child))
(2 (INT16 root-x))
(2 (INT16 root-y))
(2 (INT16 event-x))
(2 (INT16 event-y))
(2 (#.SETofKEYMASK state))
(1 ((ENUM CARD8 ((0 . :Normal)
(1 . :Grab)
(2 . :Ungrab)))
mode))
(1 ((BITMASK CARD8 ((#x01 . :focus)
(#x02 . :same-screen)))
same-screen/focus)))
(:FocusIn
(1 {code} 9)
(1 ((ENUM CARD8 ((0 . :Ancestor)
(1 . :Virtual)
(2 . :Inferior)
(3 . :Nonlinear)
(4 . :NonlinearVirtual)
(5 . :Pointer)
(6 . :PointerRoot)
(7 . nil)))
detail))
(2 (CARD16 sequence-number))
(4 (WINDOW window))
(1 ((ENUM CARD8 ((0 . :Normal)
(1 . :Grab)
(2 . :Ungrab)
(3 . :WhileGrabbed)))
mode))
(23 {unused}))
(:FocusOut
(1 {code} 10)
(1 ((ENUM CARD8 ((0 . :Ancestor)
(1 . :Virtual)
(2 . :Inferior)
(3 . :Nonlinear)
(4 . :NonlinearVirtual)
(5 . :Pointer)
(6 . :PointerRoot)
(7 . nil)))
detail))
(2 (CARD16 sequence-number))
(4 (WINDOW window))
(1 ((ENUM CARD8 ((0 . :Normal)
(1 . :Grab)
(2 . :Ungrab)
(3 . :WhileGrabbed)))
mode))
(23 {unused}))
(:KeymapNotify
(1 {code} 11)
(31 (list CARD8) keys)) ; (byte for keycodes 0\-7 is omitted))
(:Expose
(1 {code} 12)
(1 {unused})
(2 (CARD16 sequence-number))
(4 (WINDOW window))
(2 (CARD16 x))
(2 (CARD16 y))
(2 (CARD16 width))
(2 (CARD16 height))
(2 (CARD16 count))
(14 {unused}))
(:GraphicsExposure
(1 {code} 13)
(1 {unused})
(2 (CARD16 sequence-number))
(4 (DRAWABLE drawable))
(2 (CARD16 x))
(2 (CARD16 y))