Browse Source

Merge branch 'master' of https://github.com/odin-lang/Odin

gingerBill 1 year ago
parent
commit
4adfc120ba

+ 1 - 1
build.bat

@@ -111,7 +111,7 @@ call build_vendor.bat
 if %errorlevel% neq 0 goto end_of_build
 if %errorlevel% neq 0 goto end_of_build
 
 
 rem If the demo doesn't run for you and your CPU is more than a decade old, try -microarch:native
 rem If the demo doesn't run for you and your CPU is more than a decade old, try -microarch:native
-if %release_mode% EQU 0 odin run examples/demo
+if %release_mode% EQU 0 odin run examples/demo -- Hellope World
 
 
 del *.obj > NUL 2> NUL
 del *.obj > NUL 2> NUL
 
 

+ 3 - 1
build_odin.sh

@@ -27,11 +27,13 @@ error() {
 if [ -z "$LLVM_CONFIG" ]; then
 if [ -z "$LLVM_CONFIG" ]; then
 	# darwin, linux, openbsd
 	# darwin, linux, openbsd
 	if   [ -n "$(command -v llvm-config-17)" ]; then LLVM_CONFIG="llvm-config-17"
 	if   [ -n "$(command -v llvm-config-17)" ]; then LLVM_CONFIG="llvm-config-17"
+	elif [ -n "$(command -v llvm-config-14)" ]; then LLVM_CONFIG="llvm-config-14"
 	elif [ -n "$(command -v llvm-config-13)" ]; then LLVM_CONFIG="llvm-config-13"
 	elif [ -n "$(command -v llvm-config-13)" ]; then LLVM_CONFIG="llvm-config-13"
 	elif [ -n "$(command -v llvm-config-12)" ]; then LLVM_CONFIG="llvm-config-12"
 	elif [ -n "$(command -v llvm-config-12)" ]; then LLVM_CONFIG="llvm-config-12"
 	elif [ -n "$(command -v llvm-config-11)" ]; then LLVM_CONFIG="llvm-config-11"
 	elif [ -n "$(command -v llvm-config-11)" ]; then LLVM_CONFIG="llvm-config-11"
 	# freebsd
 	# freebsd
 	elif [ -n "$(command -v llvm-config17)" ]; then  LLVM_CONFIG="llvm-config-17"
 	elif [ -n "$(command -v llvm-config17)" ]; then  LLVM_CONFIG="llvm-config-17"
+	elif [ -n "$(command -v llvm-config14)" ]; then  LLVM_CONFIG="llvm-config-14"
 	elif [ -n "$(command -v llvm-config13)" ]; then  LLVM_CONFIG="llvm-config-13"
 	elif [ -n "$(command -v llvm-config13)" ]; then  LLVM_CONFIG="llvm-config-13"
 	elif [ -n "$(command -v llvm-config12)" ]; then  LLVM_CONFIG="llvm-config-12"
 	elif [ -n "$(command -v llvm-config12)" ]; then  LLVM_CONFIG="llvm-config-12"
 	elif [ -n "$(command -v llvm-config11)" ]; then  LLVM_CONFIG="llvm-config-11"
 	elif [ -n "$(command -v llvm-config11)" ]; then  LLVM_CONFIG="llvm-config-11"
@@ -117,7 +119,7 @@ build_odin() {
 }
 }
 
 
 run_demo() {
 run_demo() {
-	./odin run examples/demo/demo.odin -file
+	./odin run examples/demo/demo.odin -file -- Hellope World
 }
 }
 
 
 if [ $# -eq 0 ]; then
 if [ $# -eq 0 ]; then

+ 1 - 1
core/math/big/internal.odin

@@ -2856,7 +2856,7 @@ internal_int_random :: proc(dest: ^Int, bits: int, r: ^rnd.Rand = nil, allocator
 		dest.digit[digits - 1] &= ((1 << uint(bits)) - 1)
 		dest.digit[digits - 1] &= ((1 << uint(bits)) - 1)
 	}
 	}
 	dest.used = digits
 	dest.used = digits
-	return nil
+	return internal_clamp(dest)
 }
 }
 internal_random :: proc { internal_int_random, }
 internal_random :: proc { internal_int_random, }
 
 

+ 11 - 11
core/math/math.odin

@@ -2312,17 +2312,17 @@ F32_NORMALIZE  :: 0
 F32_RADIX      :: 2
 F32_RADIX      :: 2
 F32_ROUNDS     :: 1
 F32_ROUNDS     :: 1
 
 
-F64_DIG        :: 15                       // # of decimal digits of precision
-F64_EPSILON    :: 2.2204460492503131e-016  // smallest such that 1.0+F64_EPSILON != 1.0
-F64_MANT_DIG   :: 53                       // # of bits in mantissa
-F64_MAX        :: 1.7976931348623158e+308  // max value
-F64_MAX_10_EXP :: 308                      // max decimal exponent
-F64_MAX_EXP    :: 1024                     // max binary exponent
-F64_MIN        :: 2.2250738585072014e-308  // min positive value
-F64_MIN_10_EXP :: -307                     // min decimal exponent
-F64_MIN_EXP    :: -1021                    // min binary exponent
-F64_RADIX      :: 2                        // exponent radix
-F64_ROUNDS     :: 1                        // addition rounding: near
+F64_DIG        :: 15                       // Number of representable decimal digits.
+F64_EPSILON    :: 2.2204460492503131e-016  // Smallest number such that `1.0 + F64_EPSILON != 1.0`.
+F64_MANT_DIG   :: 53                       // Number of bits in the mantissa.
+F64_MAX        :: 1.7976931348623158e+308  // Maximum representable value.
+F64_MAX_10_EXP :: 308                      // Maximum base-10 exponent yielding normalized value.
+F64_MAX_EXP    :: 1024                     // One greater than the maximum possible base-2 exponent yielding normalized value.
+F64_MIN        :: 2.2250738585072014e-308  // Minimum positive normalized value.
+F64_MIN_10_EXP :: -307                     // Minimum base-10 exponent yielding normalized value.
+F64_MIN_EXP    :: -1021                    // One greater than the minimum possible base-2 exponent yielding normalized value.
+F64_RADIX      :: 2                        // Exponent radix.
+F64_ROUNDS     :: 1                        // Addition rounding: near.
 
 
 
 
 F16_MASK  :: 0x1f
 F16_MASK  :: 0x1f

+ 1 - 1
core/mem/virtual/arena.odin

@@ -51,7 +51,7 @@ arena_init_growing :: proc(arena: ^Arena, reserved: uint = DEFAULT_ARENA_GROWING
 // Initialization of an `Arena` to be a `.Static` variant.
 // Initialization of an `Arena` to be a `.Static` variant.
 // A static arena contains a single `Memory_Block` allocated with virtual memory.
 // A static arena contains a single `Memory_Block` allocated with virtual memory.
 @(require_results)
 @(require_results)
-arena_init_static :: proc(arena: ^Arena, reserved: uint, commit_size: uint = DEFAULT_ARENA_STATIC_COMMIT_SIZE) -> (err: Allocator_Error) {
+arena_init_static :: proc(arena: ^Arena, reserved: uint = DEFAULT_ARENA_STATIC_RESERVE_SIZE, commit_size: uint = DEFAULT_ARENA_STATIC_COMMIT_SIZE) -> (err: Allocator_Error) {
 	arena.kind           = .Static
 	arena.kind           = .Static
 	arena.curr_block     = memory_block_alloc(commit_size, reserved, {}) or_return
 	arena.curr_block     = memory_block_alloc(commit_size, reserved, {}) or_return
 	arena.total_used     = 0
 	arena.total_used     = 0

+ 38 - 3
core/net/socket.odin

@@ -148,7 +148,29 @@ recv_udp :: proc(socket: UDP_Socket, buf: []byte) -> (bytes_read: int, remote_en
 	return _recv_udp(socket, buf)
 	return _recv_udp(socket, buf)
 }
 }
 
 
-recv :: proc{recv_tcp, recv_udp}
+/*
+	Receive data from into a buffer from any socket.
+
+	Note: `remote_endpoint` parameter is non-nil only if the socket type is UDP. On TCP sockets it
+	will always return `nil`.
+*/
+recv_any :: proc(socket: Any_Socket, buf: []byte) -> (
+	bytes_read: int,
+	remote_endpoint: Maybe(Endpoint),
+	err: Network_Error,
+) {
+	switch socktype in socket {
+	case TCP_Socket:
+		bytes_read, err := recv_tcp(socktype, buf)
+		return bytes_read, nil, err
+	case UDP_Socket:
+		bytes_read, endpoint, err := recv_udp(socktype, buf)
+		return bytes_read, endpoint, err
+	case: panic("Not supported")
+	}
+}
+
+recv :: proc{recv_tcp, recv_udp, recv_any}
 
 
 /*
 /*
 	Repeatedly sends data until the entire buffer is sent.
 	Repeatedly sends data until the entire buffer is sent.
@@ -168,7 +190,20 @@ send_udp :: proc(socket: UDP_Socket, buf: []byte, to: Endpoint) -> (bytes_writte
 	return _send_udp(socket, buf, to)
 	return _send_udp(socket, buf, to)
 }
 }
 
 
-send :: proc{send_tcp, send_udp}
+send_any :: proc(socket: Any_Socket, buf: []byte, to: Maybe(Endpoint) = nil) -> (
+	bytes_written: int,
+	err: Network_Error,
+) {
+	switch socktype in socket {
+	case TCP_Socket:
+		return send_tcp(socktype, buf)
+	case UDP_Socket:
+		return send_udp(socktype, buf, to.(Endpoint))
+	case: panic("Not supported")
+	}
+}
+
+send :: proc{send_tcp, send_udp, send_any}
 
 
 shutdown :: proc(socket: Any_Socket, manner: Shutdown_Manner) -> (err: Network_Error) {
 shutdown :: proc(socket: Any_Socket, manner: Shutdown_Manner) -> (err: Network_Error) {
 	return _shutdown(socket, manner)
 	return _shutdown(socket, manner)
@@ -180,4 +215,4 @@ set_option :: proc(socket: Any_Socket, option: Socket_Option, value: any, loc :=
 
 
 set_blocking :: proc(socket: Any_Socket, should_block: bool) -> (err: Network_Error) {
 set_blocking :: proc(socket: Any_Socket, should_block: bool) -> (err: Network_Error) {
 	return _set_blocking(socket, should_block)
 	return _set_blocking(socket, should_block)
-}
+}

+ 1 - 1
core/net/socket_linux.odin

@@ -125,7 +125,7 @@ _create_socket :: proc(family: Address_Family, protocol: Socket_Protocol) -> (An
 }
 }
 
 
 @(private)
 @(private)
-_dial_tcp_from_endpoint :: proc(endpoint: Endpoint, options := default_tcp_options) -> (tcp_sock: TCP_Socket, err: Network_Error) {
+_dial_tcp_from_endpoint :: proc(endpoint: Endpoint, options := default_tcp_options) -> (TCP_Socket, Network_Error) {
 	errno: linux.Errno
 	errno: linux.Errno
 	if endpoint.port == 0 {
 	if endpoint.port == 0 {
 		return 0, .Port_Required
 		return 0, .Port_Required

+ 10 - 1
core/odin/ast/clone.odin

@@ -7,7 +7,7 @@ import "core:reflect"
 import "core:odin/tokenizer"
 import "core:odin/tokenizer"
 _ :: intrinsics
 _ :: intrinsics
 
 
-new :: proc($T: typeid, pos, end: tokenizer.Pos) -> ^T {
+new_from_positions :: proc($T: typeid, pos, end: tokenizer.Pos) -> ^T {
 	n, _ := mem.new(T)
 	n, _ := mem.new(T)
 	n.pos = pos
 	n.pos = pos
 	n.end = end
 	n.end = end
@@ -23,6 +23,15 @@ new :: proc($T: typeid, pos, end: tokenizer.Pos) -> ^T {
 	return n
 	return n
 }
 }
 
 
+new_from_pos_and_end_node :: proc($T: typeid, pos: tokenizer.Pos, end: ^Node) -> ^T {
+	return new(T, pos, end != nil ? end.end : pos)
+}
+
+new :: proc {
+	new_from_positions,
+	new_from_pos_and_end_node,
+}
+
 clone :: proc{
 clone :: proc{
 	clone_node,
 	clone_node,
 	clone_expr,
 	clone_expr,

+ 51 - 47
core/odin/parser/parser.odin

@@ -786,8 +786,11 @@ parse_if_stmt :: proc(p: ^Parser) -> ^ast.If_Stmt {
 			else_stmt = ast.new(ast.Bad_Stmt, p.curr_tok.pos, end_pos(p.curr_tok))
 			else_stmt = ast.new(ast.Bad_Stmt, p.curr_tok.pos, end_pos(p.curr_tok))
 		}
 		}
 	}
 	}
-
-	end := body.end
+	
+	end: tokenizer.Pos
+	if body != nil {
+		end = body.end
+	}
 	if else_stmt != nil {
 	if else_stmt != nil {
 		end = else_stmt.end
 		end = else_stmt.end
 	}
 	}
@@ -850,7 +853,7 @@ parse_for_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
 				body = parse_body(p)
 				body = parse_body(p)
 			}
 			}
 
 
-			range_stmt := ast.new(ast.Range_Stmt, tok.pos, body.end)
+			range_stmt := ast.new(ast.Range_Stmt, tok.pos, body)
 			range_stmt.for_pos = tok.pos
 			range_stmt.for_pos = tok.pos
 			range_stmt.in_pos = in_tok.pos
 			range_stmt.in_pos = in_tok.pos
 			range_stmt.expr = rhs
 			range_stmt.expr = rhs
@@ -910,7 +913,7 @@ parse_for_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
 			rhs = assign_stmt.rhs[0]
 			rhs = assign_stmt.rhs[0]
 		}
 		}
 
 
-		range_stmt := ast.new(ast.Range_Stmt, tok.pos, body.end)
+		range_stmt := ast.new(ast.Range_Stmt, tok.pos, body)
 		range_stmt.for_pos = tok.pos
 		range_stmt.for_pos = tok.pos
 		range_stmt.vals = vals
 		range_stmt.vals = vals
 		range_stmt.in_pos = assign_stmt.op.pos
 		range_stmt.in_pos = assign_stmt.op.pos
@@ -920,7 +923,7 @@ parse_for_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
 	}
 	}
 
 
 	cond_expr := convert_stmt_to_expr(p, cond, "boolean expression")
 	cond_expr := convert_stmt_to_expr(p, cond, "boolean expression")
-	for_stmt := ast.new(ast.For_Stmt, tok.pos, body.end)
+	for_stmt := ast.new(ast.For_Stmt, tok.pos, body)
 	for_stmt.for_pos = tok.pos
 	for_stmt.for_pos = tok.pos
 	for_stmt.init = init
 	for_stmt.init = init
 	for_stmt.cond = cond_expr
 	for_stmt.cond = cond_expr
@@ -976,7 +979,7 @@ parse_switch_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
 			lhs[0] = new_blank_ident(p, tok.pos)
 			lhs[0] = new_blank_ident(p, tok.pos)
 			rhs[0] = parse_expr(p, true)
 			rhs[0] = parse_expr(p, true)
 
 
-			as := ast.new(ast.Assign_Stmt, tok.pos, rhs[0].end)
+			as := ast.new(ast.Assign_Stmt, tok.pos, rhs[0])
 			as.lhs = lhs
 			as.lhs = lhs
 			as.op  = in_tok
 			as.op  = in_tok
 			as.rhs = rhs
 			as.rhs = rhs
@@ -1010,14 +1013,14 @@ parse_switch_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
 	body.stmts = clauses[:]
 	body.stmts = clauses[:]
 
 
 	if is_type_switch {
 	if is_type_switch {
-		ts := ast.new(ast.Type_Switch_Stmt, tok.pos, body.end)
+		ts := ast.new(ast.Type_Switch_Stmt, tok.pos, body)
 		ts.tag  = tag
 		ts.tag  = tag
 		ts.body = body
 		ts.body = body
 		ts.switch_pos = tok.pos
 		ts.switch_pos = tok.pos
 		return ts
 		return ts
 	} else {
 	} else {
 		cond := convert_stmt_to_expr(p, tag, "switch expression")
 		cond := convert_stmt_to_expr(p, tag, "switch expression")
-		ts := ast.new(ast.Switch_Stmt, tok.pos, body.end)
+		ts := ast.new(ast.Switch_Stmt, tok.pos, body)
 		ts.init = init
 		ts.init = init
 		ts.cond = cond
 		ts.cond = cond
 		ts.body = body
 		ts.body = body
@@ -1044,7 +1047,7 @@ parse_attribute :: proc(p: ^Parser, tok: tokenizer.Token, open_kind, close_kind:
 			if p.curr_tok.kind == .Eq {
 			if p.curr_tok.kind == .Eq {
 				eq := expect_token(p, .Eq)
 				eq := expect_token(p, .Eq)
 				value := parse_value(p)
 				value := parse_value(p)
-				fv := ast.new(ast.Field_Value, elem.pos, value.end)
+				fv := ast.new(ast.Field_Value, elem.pos, value)
 				fv.field = elem
 				fv.field = elem
 				fv.sep   = eq.pos
 				fv.sep   = eq.pos
 				fv.value = value
 				fv.value = value
@@ -1137,7 +1140,7 @@ parse_foreign_block :: proc(p: ^Parser, tok: tokenizer.Token) -> ^ast.Foreign_Bl
 	body.stmts = decls[:]
 	body.stmts = decls[:]
 	body.close = close.pos
 	body.close = close.pos
 
 
-	decl := ast.new(ast.Foreign_Block_Decl, tok.pos, body.end)
+	decl := ast.new(ast.Foreign_Block_Decl, tok.pos, body)
 	decl.docs            = docs
 	decl.docs            = docs
 	decl.tok             = tok
 	decl.tok             = tok
 	decl.foreign_library = foreign_library
 	decl.foreign_library = foreign_library
@@ -1248,7 +1251,7 @@ parse_unrolled_for_loop :: proc(p: ^Parser, inline_tok: tokenizer.Token) -> ^ast
 		return ast.new(ast.Bad_Stmt, inline_tok.pos, end_pos(p.prev_tok))
 		return ast.new(ast.Bad_Stmt, inline_tok.pos, end_pos(p.prev_tok))
 	}
 	}
 
 
-	range_stmt := ast.new(ast.Inline_Range_Stmt, inline_tok.pos, body.end)
+	range_stmt := ast.new(ast.Inline_Range_Stmt, inline_tok.pos, body)
 	range_stmt.inline_pos = inline_tok.pos
 	range_stmt.inline_pos = inline_tok.pos
 	range_stmt.for_pos = for_tok.pos
 	range_stmt.for_pos = for_tok.pos
 	range_stmt.val0 = val0
 	range_stmt.val0 = val0
@@ -1304,7 +1307,7 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
 		case ^ast.Return_Stmt:
 		case ^ast.Return_Stmt:
 			error(p, s.pos, "you cannot defer a return statement")
 			error(p, s.pos, "you cannot defer a return statement")
 		}
 		}
-		ds := ast.new(ast.Defer_Stmt, tok.pos, stmt.end)
+		ds := ast.new(ast.Defer_Stmt, tok.pos, stmt)
 		ds.stmt = stmt
 		ds.stmt = stmt
 		return ds
 		return ds
 
 
@@ -1341,8 +1344,7 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
 		if tok.kind != .Fallthrough && p.curr_tok.kind == .Ident {
 		if tok.kind != .Fallthrough && p.curr_tok.kind == .Ident {
 			label = parse_ident(p)
 			label = parse_ident(p)
 		}
 		}
-		end := label.end if label != nil else end_pos(tok)
-		s := ast.new(ast.Branch_Stmt, tok.pos, end)
+		s := ast.new(ast.Branch_Stmt, tok.pos, label)
 		s.tok = tok
 		s.tok = tok
 		s.label = label
 		s.label = label
 		expect_semicolon(p, s)
 		expect_semicolon(p, s)
@@ -1366,7 +1368,7 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
 		if p.curr_tok.kind != .Colon {
 		if p.curr_tok.kind != .Colon {
 			end := list[len(list)-1]
 			end := list[len(list)-1]
 			expect_semicolon(p, end)
 			expect_semicolon(p, end)
-			us := ast.new(ast.Using_Stmt, tok.pos, end.end)
+			us := ast.new(ast.Using_Stmt, tok.pos, end)
 			us.list = list
 			us.list = list
 			return us
 			return us
 		}
 		}
@@ -1416,13 +1418,13 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
 			bd.tok  = tok
 			bd.tok  = tok
 			bd.name = name
 			bd.name = name
 			ce := parse_call_expr(p, bd)
 			ce := parse_call_expr(p, bd)
-			es := ast.new(ast.Expr_Stmt, ce.pos, ce.end)
+			es := ast.new(ast.Expr_Stmt, ce.pos, ce)
 			es.expr = ce
 			es.expr = ce
 			return es
 			return es
 
 
 		case "force_inline", "force_no_inline":
 		case "force_inline", "force_no_inline":
 			expr := parse_inlining_operand(p, true, tag)
 			expr := parse_inlining_operand(p, true, tag)
-			es := ast.new(ast.Expr_Stmt, expr.pos, expr.end)
+			es := ast.new(ast.Expr_Stmt, expr.pos, expr)
 			es.expr = expr
 			es.expr = expr
 			return es
 			return es
 		case "unroll":
 		case "unroll":
@@ -1444,7 +1446,8 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
 			return ast.new(ast.Bad_Stmt, tok.pos, end_pos(tag))
 			return ast.new(ast.Bad_Stmt, tok.pos, end_pos(tag))
 		case:
 		case:
 			stmt := parse_stmt(p)
 			stmt := parse_stmt(p)
-			te := ast.new(ast.Tag_Stmt, tok.pos, stmt.pos)
+			end := stmt.pos if stmt != nil else end_pos(tok)
+			te := ast.new(ast.Tag_Stmt, tok.pos, end)
 			te.op   = tok
 			te.op   = tok
 			te.name = name
 			te.name = name
 			te.stmt = stmt
 			te.stmt = stmt
@@ -1572,7 +1575,7 @@ convert_stmt_to_body :: proc(p: ^Parser, stmt: ^ast.Stmt) -> ^ast.Stmt {
 		error(p, stmt.pos, "expected a non-empty statement")
 		error(p, stmt.pos, "expected a non-empty statement")
 	}
 	}
 
 
-	bs := ast.new(ast.Block_Stmt, stmt.pos, stmt.end)
+	bs := ast.new(ast.Block_Stmt, stmt.pos, stmt)
 	bs.open = stmt.pos
 	bs.open = stmt.pos
 	bs.stmts = make([]^ast.Stmt, 1)
 	bs.stmts = make([]^ast.Stmt, 1)
 	bs.stmts[0] = stmt
 	bs.stmts[0] = stmt
@@ -1741,7 +1744,7 @@ parse_var_type :: proc(p: ^Parser, flags: ast.Field_Flags) -> ^ast.Expr {
 			error(p, tok.pos, "variadic field missing type after '..'")
 			error(p, tok.pos, "variadic field missing type after '..'")
 			type = ast.new(ast.Bad_Expr, tok.pos, end_pos(tok))
 			type = ast.new(ast.Bad_Expr, tok.pos, end_pos(tok))
 		}
 		}
-		e := ast.new(ast.Ellipsis, type.pos, type.end)
+		e := ast.new(ast.Ellipsis, type.pos, type)
 		e.expr = type
 		e.expr = type
 		return e
 		return e
 	}
 	}
@@ -1808,7 +1811,7 @@ parse_ident_list :: proc(p: ^Parser, allow_poly_names: bool) -> []^ast.Expr {
 			if is_blank_ident(ident) {
 			if is_blank_ident(ident) {
 				error(p, ident.pos, "invalid polymorphic type definition with a blank identifier")
 				error(p, ident.pos, "invalid polymorphic type definition with a blank identifier")
 			}
 			}
-			poly_name := ast.new(ast.Poly_Type, tok.pos, ident.end)
+			poly_name := ast.new(ast.Poly_Type, tok.pos, ident)
 			poly_name.type = ident
 			poly_name.type = ident
 			append(&list, poly_name)
 			append(&list, poly_name)
 		} else {
 		} else {
@@ -2154,7 +2157,7 @@ parse_inlining_operand :: proc(p: ^Parser, lhs: bool, tok: tokenizer.Token) -> ^
 		e.inlining = pi
 		e.inlining = pi
 	case:
 	case:
 		error(p, tok.pos, "'%s' must be followed by a procedure literal or call", tok.text)
 		error(p, tok.pos, "'%s' must be followed by a procedure literal or call", tok.text)
-		return ast.new(ast.Bad_Expr, tok.pos, expr.end)
+		return ast.new(ast.Bad_Expr, tok.pos, expr)
 	}
 	}
 	return expr
 	return expr
 }
 }
@@ -2204,7 +2207,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
 	case .Distinct:
 	case .Distinct:
 		tok := advance_token(p)
 		tok := advance_token(p)
 		type := parse_type(p)
 		type := parse_type(p)
-		dt := ast.new(ast.Distinct_Type, tok.pos, type.end)
+		dt := ast.new(ast.Distinct_Type, tok.pos, type)
 		dt.tok  = tok.kind
 		dt.tok  = tok.kind
 		dt.type = type
 		dt.type = type
 		return dt
 		return dt
@@ -2215,7 +2218,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
 		switch name.text {
 		switch name.text {
 		case "type":
 		case "type":
 			type := parse_type(p)
 			type := parse_type(p)
-			hp := ast.new(ast.Helper_Type, tok.pos, type.end)
+			hp := ast.new(ast.Helper_Type, tok.pos, type)
 			hp.tok  = tok.kind
 			hp.tok  = tok.kind
 			hp.type = type
 			hp.type = type
 			return hp
 			return hp
@@ -2319,7 +2322,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
 			tag_call := parse_call_expr(p, tag)
 			tag_call := parse_call_expr(p, tag)
 			type := parse_type(p)
 			type := parse_type(p)
 
 
-			rt := ast.new(ast.Relative_Type, tok.pos, type.end)
+			rt := ast.new(ast.Relative_Type, tok.pos, type)
 			rt.tag = tag_call
 			rt.tag = tag_call
 			rt.type = type
 			rt.type = type
 			return rt
 			return rt
@@ -2328,7 +2331,8 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
 			return parse_inlining_operand(p, lhs, name)
 			return parse_inlining_operand(p, lhs, name)
 		case:
 		case:
 			expr := parse_expr(p, lhs)
 			expr := parse_expr(p, lhs)
-			te := ast.new(ast.Tag_Expr, tok.pos, expr.pos)
+			end := expr.pos if expr != nil else end_pos(tok)
+			te := ast.new(ast.Tag_Expr, tok.pos, end)
 			te.op   = tok
 			te.op   = tok
 			te.name = name.text
 			te.name = name.text
 			te.expr = expr
 			te.expr = expr
@@ -2456,7 +2460,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
 	case .Pointer:
 	case .Pointer:
 		tok := expect_token(p, .Pointer)
 		tok := expect_token(p, .Pointer)
 		elem := parse_type(p)
 		elem := parse_type(p)
-		ptr := ast.new(ast.Pointer_Type, tok.pos, elem.end)
+		ptr := ast.new(ast.Pointer_Type, tok.pos, elem)
 		ptr.pointer = tok.pos
 		ptr.pointer = tok.pos
 		ptr.elem = elem
 		ptr.elem = elem
 		return ptr
 		return ptr
@@ -2470,7 +2474,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
 			tok := expect_token(p, .Pointer)
 			tok := expect_token(p, .Pointer)
 			close := expect_token(p, .Close_Bracket)
 			close := expect_token(p, .Close_Bracket)
 			elem := parse_type(p)
 			elem := parse_type(p)
-			t := ast.new(ast.Multi_Pointer_Type, open.pos, elem.end)
+			t := ast.new(ast.Multi_Pointer_Type, open.pos, elem)
 			t.open = open.pos
 			t.open = open.pos
 			t.pointer = tok.pos
 			t.pointer = tok.pos
 			t.close = close.pos
 			t.close = close.pos
@@ -2480,7 +2484,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
 			tok := expect_token(p, .Dynamic)
 			tok := expect_token(p, .Dynamic)
 			close := expect_token(p, .Close_Bracket)
 			close := expect_token(p, .Close_Bracket)
 			elem := parse_type(p)
 			elem := parse_type(p)
-			da := ast.new(ast.Dynamic_Array_Type, open.pos, elem.end)
+			da := ast.new(ast.Dynamic_Array_Type, open.pos, elem)
 			da.open = open.pos
 			da.open = open.pos
 			da.dynamic_pos = tok.pos
 			da.dynamic_pos = tok.pos
 			da.close = close.pos
 			da.close = close.pos
@@ -2500,7 +2504,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
 		}
 		}
 		close := expect_token(p, .Close_Bracket)
 		close := expect_token(p, .Close_Bracket)
 		elem := parse_type(p)
 		elem := parse_type(p)
-		at := ast.new(ast.Array_Type, open.pos, elem.end)
+		at := ast.new(ast.Array_Type, open.pos, elem)
 		at.open  = open.pos
 		at.open  = open.pos
 		at.len   = count
 		at.len   = count
 		at.close = close.pos
 		at.close = close.pos
@@ -2514,7 +2518,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
 		expect_token(p, .Close_Bracket)
 		expect_token(p, .Close_Bracket)
 		value := parse_type(p)
 		value := parse_type(p)
 
 
-		mt := ast.new(ast.Map_Type, tok.pos, value.end)
+		mt := ast.new(ast.Map_Type, tok.pos, value)
 		mt.tok_pos = tok.pos
 		mt.tok_pos = tok.pos
 		mt.key = key
 		mt.key = key
 		mt.value = value
 		mt.value = value
@@ -2755,7 +2759,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
 		expect_token(p, .Close_Bracket)
 		expect_token(p, .Close_Bracket)
 		elem := parse_type(p)
 		elem := parse_type(p)
 
 
-		mt := ast.new(ast.Matrix_Type, tok.pos, elem.end)
+		mt := ast.new(ast.Matrix_Type, tok.pos, elem)
 		mt.tok_pos = tok.pos
 		mt.tok_pos = tok.pos
 		mt.row_count = row_count
 		mt.row_count = row_count
 		mt.column_count = column_count
 		mt.column_count = column_count
@@ -2893,7 +2897,7 @@ parse_elem_list :: proc(p: ^Parser) -> []^ast.Expr {
 			eq := expect_token(p, .Eq)
 			eq := expect_token(p, .Eq)
 			value := parse_value(p)
 			value := parse_value(p)
 
 
-			fv := ast.new(ast.Field_Value, elem.pos, value.end)
+			fv := ast.new(ast.Field_Value, elem.pos, value)
 			fv.field = elem
 			fv.field = elem
 			fv.sep   = eq.pos
 			fv.sep   = eq.pos
 			fv.value = value
 			fv.value = value
@@ -2962,7 +2966,7 @@ parse_call_expr :: proc(p: ^Parser, operand: ^ast.Expr) -> ^ast.Expr {
 			}
 			}
 
 
 			value := parse_value(p)
 			value := parse_value(p)
-			fv := ast.new(ast.Field_Value, arg.pos, value.end)
+			fv := ast.new(ast.Field_Value, arg.pos, value)
 			fv.field = arg
 			fv.field = arg
 			fv.sep   = eq.pos
 			fv.sep   = eq.pos
 			fv.value = value
 			fv.value = value
@@ -2993,7 +2997,7 @@ parse_call_expr :: proc(p: ^Parser, operand: ^ast.Expr) -> ^ast.Expr {
 
 
 	o := ast.unparen_expr(operand)
 	o := ast.unparen_expr(operand)
 	if se, ok := o.derived.(^ast.Selector_Expr); ok && se.op.kind == .Arrow_Right {
 	if se, ok := o.derived.(^ast.Selector_Expr); ok && se.op.kind == .Arrow_Right {
-		sce := ast.new(ast.Selector_Call_Expr, ce.pos, ce.end)
+		sce := ast.new(ast.Selector_Call_Expr, ce.pos, ce)
 		sce.expr = o
 		sce.expr = o
 		sce.call = ce
 		sce.call = ce
 		return sce
 		return sce
@@ -3101,7 +3105,7 @@ parse_atom_expr :: proc(p: ^Parser, value: ^ast.Expr, lhs: bool) -> (operand: ^a
 			case .Ident:
 			case .Ident:
 				field := parse_ident(p)
 				field := parse_ident(p)
 
 
-				sel := ast.new(ast.Selector_Expr, operand.pos, field.end)
+				sel := ast.new(ast.Selector_Expr, operand.pos, field)
 				sel.expr  = operand
 				sel.expr  = operand
 				sel.op = tok
 				sel.op = tok
 				sel.field = field
 				sel.field = field
@@ -3127,7 +3131,7 @@ parse_atom_expr :: proc(p: ^Parser, value: ^ast.Expr, lhs: bool) -> (operand: ^a
 				type.op = question
 				type.op = question
 				type.expr = nil
 				type.expr = nil
 
 
-				ta := ast.new(ast.Type_Assertion, operand.pos, type.end)
+				ta := ast.new(ast.Type_Assertion, operand.pos, type)
 				ta.expr  = operand
 				ta.expr  = operand
 				ta.type  = type
 				ta.type  = type
 
 
@@ -3145,7 +3149,7 @@ parse_atom_expr :: proc(p: ^Parser, value: ^ast.Expr, lhs: bool) -> (operand: ^a
 			case .Ident:
 			case .Ident:
 				field := parse_ident(p)
 				field := parse_ident(p)
 
 
-				sel := ast.new(ast.Selector_Expr, operand.pos, field.end)
+				sel := ast.new(ast.Selector_Expr, operand.pos, field)
 				sel.expr  = operand
 				sel.expr  = operand
 				sel.op = tok
 				sel.op = tok
 				sel.field = field
 				sel.field = field
@@ -3225,7 +3229,7 @@ parse_unary_expr :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
 		close := expect_token(p, .Close_Paren)
 		close := expect_token(p, .Close_Paren)
 		expr := parse_unary_expr(p, lhs)
 		expr := parse_unary_expr(p, lhs)
 
 
-		tc := ast.new(ast.Type_Cast, tok.pos, expr.end)
+		tc := ast.new(ast.Type_Cast, tok.pos, expr)
 		tc.tok   = tok
 		tc.tok   = tok
 		tc.open  = open.pos
 		tc.open  = open.pos
 		tc.type  = type
 		tc.type  = type
@@ -3237,7 +3241,7 @@ parse_unary_expr :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
 		op := advance_token(p)
 		op := advance_token(p)
 		expr := parse_unary_expr(p, lhs)
 		expr := parse_unary_expr(p, lhs)
 
 
-		ac := ast.new(ast.Auto_Cast, op.pos, expr.end)
+		ac := ast.new(ast.Auto_Cast, op.pos, expr)
 		ac.op   = op
 		ac.op   = op
 		ac.expr = expr
 		ac.expr = expr
 		return ac
 		return ac
@@ -3247,8 +3251,8 @@ parse_unary_expr :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
 	     .And:
 	     .And:
 		op := advance_token(p)
 		op := advance_token(p)
 		expr := parse_unary_expr(p, lhs)
 		expr := parse_unary_expr(p, lhs)
-
-		ue := ast.new(ast.Unary_Expr, op.pos, expr.end)
+		
+		ue := ast.new(ast.Unary_Expr, op.pos, expr)
 		ue.op   = op
 		ue.op   = op
 		ue.expr = expr
 		ue.expr = expr
 		return ue
 		return ue
@@ -3258,7 +3262,7 @@ parse_unary_expr :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
 		error(p, op.pos, "unary '%s' operator is not supported", op.text)
 		error(p, op.pos, "unary '%s' operator is not supported", op.text)
 		expr := parse_unary_expr(p, lhs)
 		expr := parse_unary_expr(p, lhs)
 
 
-		ue := ast.new(ast.Unary_Expr, op.pos, expr.end)
+		ue := ast.new(ast.Unary_Expr, op.pos, expr)
 		ue.op   = op
 		ue.op   = op
 		ue.expr = expr
 		ue.expr = expr
 		return ue
 		return ue
@@ -3266,7 +3270,7 @@ parse_unary_expr :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
 	case .Period:
 	case .Period:
 		op := advance_token(p)
 		op := advance_token(p)
 		field := parse_ident(p)
 		field := parse_ident(p)
-		ise := ast.new(ast.Implicit_Selector_Expr, op.pos, field.end)
+		ise := ast.new(ast.Implicit_Selector_Expr, op.pos, field)
 		ise.field = field
 		ise.field = field
 		return ise
 		return ise
 
 
@@ -3407,7 +3411,7 @@ parse_simple_stmt :: proc(p: ^Parser, flags: Stmt_Allow_Flags) -> ^ast.Stmt {
 			error(p, p.curr_tok.pos, "no right-hand side in assignment statement")
 			error(p, p.curr_tok.pos, "no right-hand side in assignment statement")
 			return ast.new(ast.Bad_Stmt, start_tok.pos, end_pos(p.curr_tok))
 			return ast.new(ast.Bad_Stmt, start_tok.pos, end_pos(p.curr_tok))
 		}
 		}
-		stmt := ast.new(ast.Assign_Stmt, lhs[0].pos, rhs[len(rhs)-1].end)
+		stmt := ast.new(ast.Assign_Stmt, lhs[0].pos, rhs[len(rhs)-1])
 		stmt.lhs = lhs
 		stmt.lhs = lhs
 		stmt.op = op
 		stmt.op = op
 		stmt.rhs = rhs
 		stmt.rhs = rhs
@@ -3424,7 +3428,7 @@ parse_simple_stmt :: proc(p: ^Parser, flags: Stmt_Allow_Flags) -> ^ast.Stmt {
 			rhs := make([]^ast.Expr, 1)
 			rhs := make([]^ast.Expr, 1)
 			rhs[0] = expr
 			rhs[0] = expr
 
 
-			stmt := ast.new(ast.Assign_Stmt, lhs[0].pos, rhs[len(rhs)-1].end)
+			stmt := ast.new(ast.Assign_Stmt, lhs[0].pos, rhs[len(rhs)-1])
 			stmt.lhs = lhs
 			stmt.lhs = lhs
 			stmt.op = op
 			stmt.op = op
 			stmt.rhs = rhs
 			stmt.rhs = rhs
@@ -3466,7 +3470,7 @@ parse_simple_stmt :: proc(p: ^Parser, flags: Stmt_Allow_Flags) -> ^ast.Stmt {
 		error(p, op.pos, "postfix '%s' statement is not supported", op.text)
 		error(p, op.pos, "postfix '%s' statement is not supported", op.text)
 	}
 	}
 
 
-	es := ast.new(ast.Expr_Stmt, lhs[0].pos, lhs[0].end)
+	es := ast.new(ast.Expr_Stmt, lhs[0].pos, lhs[0])
 	es.expr = lhs[0]
 	es.expr = lhs[0]
 	return es
 	return es
 }
 }

+ 2 - 4
core/runtime/default_allocators_nil.odin

@@ -35,7 +35,7 @@ nil_allocator :: proc() -> Allocator {
 when ODIN_OS == .Freestanding {
 when ODIN_OS == .Freestanding {
 	default_allocator_proc :: nil_allocator_proc
 	default_allocator_proc :: nil_allocator_proc
 	default_allocator :: nil_allocator
 	default_allocator :: nil_allocator
-} 
+}
 
 
 
 
 
 
@@ -78,9 +78,7 @@ panic_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
 
 
 panic_allocator :: proc() -> Allocator {
 panic_allocator :: proc() -> Allocator {
 	return Allocator{
 	return Allocator{
-		procedure = nil_allocator_proc,
+		procedure = panic_allocator_proc,
 		data = nil,
 		data = nil,
 	}
 	}
 }
 }
-
-

+ 1 - 1
core/runtime/os_specific_darwin.odin

@@ -4,7 +4,7 @@ package runtime
 import "core:intrinsics"
 import "core:intrinsics"
 
 
 _os_write :: proc "contextless" (data: []byte) -> (int, _OS_Errno) {
 _os_write :: proc "contextless" (data: []byte) -> (int, _OS_Errno) {
-	ret := intrinsics.syscall(4, 1, uintptr(raw_data(data)), uintptr(len(data)))
+	ret := intrinsics.syscall(0x2000004, 1, uintptr(raw_data(data)), uintptr(len(data)))
 	if ret < 0 {
 	if ret < 0 {
 		return 0, _OS_Errno(-ret)
 		return 0, _OS_Errno(-ret)
 	}
 	}

+ 114 - 33
core/slice/slice.odin

@@ -49,7 +49,7 @@ to_bytes :: proc "contextless" (s: []$T) -> []byte {
 	```
 	```
 	```
 	```
 	small_items := []byte{1, 0, 0, 0, 0, 0, 0, 0,
 	small_items := []byte{1, 0, 0, 0, 0, 0, 0, 0,
-	                      2, 0, 0, 0}
+						  2, 0, 0, 0}
 	large_items := slice.reinterpret([]i64, small_items)
 	large_items := slice.reinterpret([]i64, small_items)
 	assert(len(large_items) == 1) // only enough bytes to make 1 x i64; two would need at least 8 bytes.
 	assert(len(large_items) == 1) // only enough bytes to make 1 x i64; two would need at least 8 bytes.
 	```
 	```
@@ -78,7 +78,7 @@ swap_between :: proc(a, b: $T/[]$E) {
 	n := builtin.min(len(a), len(b))
 	n := builtin.min(len(a), len(b))
 	if n >= 0 {
 	if n >= 0 {
 		ptr_swap_overlapping(&a[0], &b[0], size_of(E)*n)
 		ptr_swap_overlapping(&a[0], &b[0], size_of(E)*n)
-	}	
+	}
 }
 }
 
 
 
 
@@ -117,46 +117,93 @@ linear_search_proc :: proc(array: $A/[]$T, f: proc(T) -> bool) -> (index: int, f
 	return -1, false
 	return -1, false
 }
 }
 
 
+/*
+	Binary search searches the given slice for the given element.
+	If the slice is not sorted, the returned index is unspecified and meaningless.
+
+	If the value is found then the returned int is the index of the matching element.
+	If there are multiple matches, then any one of the matches could be returned.
+
+	If the value is not found then the returned int is the index where a matching
+	element could be inserted while maintaining sorted order.
+
+	# Examples
+
+	Looks up a series of four elements. The first is found, with a
+	uniquely determined position; the second and third are not
+	found; the fourth could match any position in `[1, 4]`.
+
+	```
+	index: int
+	found: bool
+
+	s := []i32{0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55}
+
+	index, found = slice.binary_search(s, 13)
+	assert(index == 9 && found == true)
+
+	index, found = slice.binary_search(s, 4)
+	assert(index == 7 && found == false)
+
+	index, found = slice.binary_search(s, 100)
+	assert(index == 13 && found == false)
+
+	index, found = slice.binary_search(s, 1)
+	assert(index >= 1 && index <= 4 && found == true)
+	```
+
+	For slices of more complex types see: binary_search_by
+*/
 @(require_results)
 @(require_results)
 binary_search :: proc(array: $A/[]$T, key: T) -> (index: int, found: bool)
 binary_search :: proc(array: $A/[]$T, key: T) -> (index: int, found: bool)
-	where intrinsics.type_is_ordered(T) #no_bounds_check {
-
-	n := len(array)
-	switch n {
-	case 0:
-		return -1, false
-	case 1:
-		if array[0] == key {
-			return 0, true
+	where intrinsics.type_is_ordered(T) #no_bounds_check
+{
+	// I would like to use binary_search_by(array, key, cmp) here, but it doesn't like it:
+	// Cannot assign value 'cmp' of type 'proc($E, $E) -> Ordering' to 'proc(i32, i32) -> Ordering' in argument
+	return binary_search_by(array, key, proc(key: T, element: T) -> Ordering {
+		switch {
+			case element < key: return .Less
+			case element > key: return .Greater
+			case:               return .Equal
 		}
 		}
-		return -1, false
-	}
+	})
+}
 
 
-	lo, hi := 0, n-1
+@(require_results)
+binary_search_by :: proc(array: $A/[]$T, key: T, f: proc(T, T) -> Ordering) -> (index: int, found: bool) #no_bounds_check {
+	// INVARIANTS:
+	// - 0 <= left <= (left + size = right) <= len(array)
+	// - f returns .Less    for everything in array[:left]
+	// - f returns .Greater for everything in array[right:]
+	size  := len(array)
+	left  := 0
+	right := size
 
 
-	for array[hi] != array[lo] && key >= array[lo] && key <= array[hi] {
-		when intrinsics.type_is_ordered_numeric(T) {
-			// NOTE(bill): This is technically interpolation search
-			m := lo + int((key - array[lo]) * T(hi - lo) / (array[hi] - array[lo]))
-		} else {
-			m := lo + (hi - lo)/2
-		}
-		switch {
-		case array[m] < key:
-			lo = m + 1
-		case key < array[m]:
-			hi = m - 1
-		case:
-			return m, true
+	for left < right {
+		mid := left + size / 2
+
+		// Steps to verify this is in-bounds:
+		// 1. We note that `size` is strictly positive due to the loop condition
+		// 2. Therefore `size/2 < size`
+		// 3. Adding `left` to both sides yields `(left + size/2) < (left + size)`
+		// 4. We know from the invariant that `left + size <= len(array)`
+		// 5. Therefore `left + size/2 < self.len()`
+		cmp := f(key, array[mid])
+
+		left  = mid + 1 if cmp == .Less    else left
+		right = mid     if cmp == .Greater else right
+
+		switch cmp {
+			case .Equal:   return mid, true
+			case .Less:    left  = mid + 1
+			case .Greater: right = mid
 		}
 		}
-	}
 
 
-	if key == array[lo] {
-		return lo, true
+		size = right - left
 	}
 	}
-	return -1, false
-}
 
 
+	return left, false
+}
 
 
 @(require_results)
 @(require_results)
 equal :: proc(a, b: $T/[]$E) -> bool where intrinsics.type_is_comparable(E) {
 equal :: proc(a, b: $T/[]$E) -> bool where intrinsics.type_is_comparable(E) {
@@ -463,6 +510,40 @@ min_max :: proc(s: $S/[]$T) -> (min, max: T, ok: bool) where intrinsics.type_is_
 	return
 	return
 }
 }
 
 
+// Find the index of the (first) minimum element in a slice.
+@(require_results)
+min_index :: proc(s: $S/[]$T) -> (min_index: int, ok: bool) where intrinsics.type_is_ordered(T) #optional_ok {
+	if len(s) == 0 {
+		return -1, false
+	}
+	min_index = 0
+	min_value := s[0]
+	for v, i in s[1:] {
+		if v < min_value {
+			min_value = v
+			min_index = i+1
+		}
+	}
+	return min_index, true
+}
+
+// Find the index of the (first) maximum element in a slice.
+@(require_results)
+max_index :: proc(s: $S/[]$T) -> (max_index: int, ok: bool) where intrinsics.type_is_ordered(T) #optional_ok {
+	if len(s) == 0 {
+		return -1, false
+	}
+	max_index = 0
+	max_value := s[0]
+	for v, i in s[1:] {
+		if v > max_value {
+			max_value = v
+			max_index = i+1
+		}
+	}
+	return max_index, true
+}
+
 @(require_results)
 @(require_results)
 any_of :: proc(s: $S/[]$T, value: T) -> bool where intrinsics.type_is_comparable(T) {
 any_of :: proc(s: $S/[]$T, value: T) -> bool where intrinsics.type_is_comparable(T) {
 	for v in s {
 	for v in s {

+ 1 - 0
core/strings/strings.odin

@@ -885,6 +885,7 @@ Splits a string into parts based on a separator. If n < count of seperators, the
 Inputs:
 Inputs:
 - s: The string to split.
 - s: The string to split.
 - sep: The separator string used to split the input string.
 - sep: The separator string used to split the input string.
+- n: The maximum amount of parts to split the string into.
 - allocator: (default is context.allocator)
 - allocator: (default is context.allocator)
 
 
 Returns:
 Returns:

+ 1 - 1
core/sys/linux/bits.odin

@@ -718,7 +718,7 @@ Perf_Event_Sample_Type_Bits :: enum {
 }
 }
 
 
 /// Describes field sets to include in mmaped page
 /// Describes field sets to include in mmaped page
-Perf_Read_Format :: enum {
+Perf_Read_Format_Bits :: enum {
 	TOTAL_TIME_ENABLED = 0,
 	TOTAL_TIME_ENABLED = 0,
 	TOTAL_TIME_RUNNING = 1,
 	TOTAL_TIME_RUNNING = 1,
 	ID                 = 2,
 	ID                 = 2,

+ 2 - 0
core/sys/linux/types.odin

@@ -283,6 +283,8 @@ Perf_Flags :: bit_set[Perf_Flags_Bits; uint]
 
 
 Perf_Event_Flags :: distinct bit_set[Perf_Event_Flags_Bits; u64]
 Perf_Event_Flags :: distinct bit_set[Perf_Event_Flags_Bits; u64]
 
 
+Perf_Read_Format :: distinct bit_set[Perf_Read_Format_Bits; u64]
+
 Perf_Cap_Flags :: distinct bit_set[Perf_Cap_Flags_Bits; u64]
 Perf_Cap_Flags :: distinct bit_set[Perf_Cap_Flags_Bits; u64]
 
 
 Perf_Event_Sample_Type :: bit_set[Perf_Event_Sample_Type_Bits; u64]
 Perf_Event_Sample_Type :: bit_set[Perf_Event_Sample_Type_Bits; u64]

+ 7 - 0
core/sys/windows/gdi32.odin

@@ -10,6 +10,8 @@ foreign gdi32 {
 	DeleteObject :: proc(ho: HGDIOBJ) -> BOOL ---
 	DeleteObject :: proc(ho: HGDIOBJ) -> BOOL ---
 	SetBkColor :: proc(hdc: HDC, color: COLORREF) -> COLORREF ---
 	SetBkColor :: proc(hdc: HDC, color: COLORREF) -> COLORREF ---
 
 
+	CreateCompatibleDC :: proc(hdc: HDC) -> HDC ---
+
 	CreateDIBPatternBrush :: proc(h: HGLOBAL, iUsage: UINT) -> HBRUSH ---
 	CreateDIBPatternBrush :: proc(h: HGLOBAL, iUsage: UINT) -> HBRUSH ---
 
 
 	CreateDIBitmap :: proc(
 	CreateDIBitmap :: proc(
@@ -81,6 +83,11 @@ foreign gdi32 {
 	GetTextMetricsW :: proc(hdc: HDC, lptm: LPTEXTMETRICW) -> BOOL ---
 	GetTextMetricsW :: proc(hdc: HDC, lptm: LPTEXTMETRICW) -> BOOL ---
 
 
 	CreateSolidBrush :: proc(color: COLORREF) -> HBRUSH ---
 	CreateSolidBrush :: proc(color: COLORREF) -> HBRUSH ---
+
+	GetObjectW :: proc(h: HANDLE, c: c_int, pv: LPVOID) -> int ---
+	CreateCompatibleBitmap :: proc(hdc: HDC, cx, cy: c_int) -> HBITMAP ---
+	BitBlt :: proc(hdc: HDC, x, y, cx, cy: c_int, hdcSrc: HDC, x1, y1: c_int, rop: DWORD) -> BOOL ---
+	GetDIBits :: proc(hdc: HDC, hbm: HBITMAP, start, cLines: UINT, lpvBits: LPVOID, lpbmi: ^BITMAPINFO, usage: UINT) -> int ---
 }
 }
 
 
 RGB :: #force_inline proc "contextless" (r, g, b: u8) -> COLORREF {
 RGB :: #force_inline proc "contextless" (r, g, b: u8) -> COLORREF {

+ 12 - 1
core/sys/windows/kernel32.odin

@@ -291,6 +291,14 @@ foreign kernel32 {
 		hTemplateFile: HANDLE,
 		hTemplateFile: HANDLE,
 	) -> HANDLE ---
 	) -> HANDLE ---
 
 
+	GetFileTime :: proc(
+		hFile: HANDLE,
+		lpCreationTime: LPFILETIME,
+		lpLastAccessTime: LPFILETIME,
+		lpLastWriteTime: LPFILETIME,
+	) -> BOOL ---
+	CompareFileTime :: proc(lpFileTime1: LPFILETIME, lpFileTime2: LPFILETIME) -> LONG ---
+
 	FindFirstFileW :: proc(fileName: LPCWSTR, findFileData: LPWIN32_FIND_DATAW) -> HANDLE ---
 	FindFirstFileW :: proc(fileName: LPCWSTR, findFileData: LPWIN32_FIND_DATAW) -> HANDLE ---
 	FindNextFileW :: proc(findFile: HANDLE, findFileData: LPWIN32_FIND_DATAW) -> BOOL ---
 	FindNextFileW :: proc(findFile: HANDLE, findFileData: LPWIN32_FIND_DATAW) -> BOOL ---
 	FindClose :: proc(findFile: HANDLE) -> BOOL ---
 	FindClose :: proc(findFile: HANDLE) -> BOOL ---
@@ -354,6 +362,9 @@ foreign kernel32 {
 	LocalReAlloc :: proc(mem: LPVOID, bytes: SIZE_T, flags: UINT) -> LPVOID ---
 	LocalReAlloc :: proc(mem: LPVOID, bytes: SIZE_T, flags: UINT) -> LPVOID ---
 	LocalFree :: proc(mem: LPVOID) -> LPVOID ---
 	LocalFree :: proc(mem: LPVOID) -> LPVOID ---
 
 
+	GlobalAlloc :: proc(flags: UINT, bytes: SIZE_T) -> LPVOID ---
+	GlobalReAlloc :: proc(mem: LPVOID, bytes: SIZE_T, flags: UINT) -> LPVOID ---
+	GlobalFree :: proc(mem: LPVOID) -> LPVOID ---
 
 
 	ReadDirectoryChangesW :: proc(
 	ReadDirectoryChangesW :: proc(
 		hDirectory: HANDLE,
 		hDirectory: HANDLE,
@@ -422,7 +433,7 @@ foreign kernel32 {
 	GetConsoleWindow :: proc() -> HWND ---
 	GetConsoleWindow :: proc() -> HWND ---
 	GetConsoleScreenBufferInfo :: proc(hConsoleOutput: HANDLE, lpConsoleScreenBufferInfo: PCONSOLE_SCREEN_BUFFER_INFO) -> BOOL ---
 	GetConsoleScreenBufferInfo :: proc(hConsoleOutput: HANDLE, lpConsoleScreenBufferInfo: PCONSOLE_SCREEN_BUFFER_INFO) -> BOOL ---
 	SetConsoleScreenBufferSize :: proc(hConsoleOutput: HANDLE, dwSize: COORD) -> BOOL ---
 	SetConsoleScreenBufferSize :: proc(hConsoleOutput: HANDLE, dwSize: COORD) -> BOOL ---
-	SetConsoleWindowInfo :: proc(hConsoleOutput: HANDLE, bAbsolute : BOOL, lpConsoleWindow: ^SMALL_RECT) -> BOOL ---
+	SetConsoleWindowInfo :: proc(hConsoleOutput: HANDLE, bAbsolute: BOOL, lpConsoleWindow: ^SMALL_RECT) -> BOOL ---
 	GetConsoleCursorInfo :: proc(hConsoleOutput: HANDLE, lpConsoleCursorInfo: PCONSOLE_CURSOR_INFO) -> BOOL ---
 	GetConsoleCursorInfo :: proc(hConsoleOutput: HANDLE, lpConsoleCursorInfo: PCONSOLE_CURSOR_INFO) -> BOOL ---
 	SetConsoleCursorInfo :: proc(hConsoleOutput: HANDLE, lpConsoleCursorInfo: PCONSOLE_CURSOR_INFO) -> BOOL ---
 	SetConsoleCursorInfo :: proc(hConsoleOutput: HANDLE, lpConsoleCursorInfo: PCONSOLE_CURSOR_INFO) -> BOOL ---
 
 

+ 10 - 0
core/sys/windows/types.odin

@@ -1971,6 +1971,16 @@ BITMAPINFO :: struct {
 	bmiColors: [1]RGBQUAD,
 	bmiColors: [1]RGBQUAD,
 }
 }
 
 
+BITMAP :: struct {
+	bmType:       LONG,
+	bmWidth:      LONG,
+	bmHeight:     LONG,
+	bmWidthBytes: LONG,
+	bmPlanes:     WORD,
+	bmBitsPixel:  WORD,
+	bmBits:       LPVOID,
+}
+
 // pixel types
 // pixel types
 PFD_TYPE_RGBA       :: 0
 PFD_TYPE_RGBA       :: 0
 PFD_TYPE_COLORINDEX :: 1
 PFD_TYPE_COLORINDEX :: 1

+ 3 - 0
core/sys/windows/user32.odin

@@ -161,6 +161,8 @@ foreign user32 {
 	MonitorFromRect   :: proc(lprc: LPRECT, dwFlags: Monitor_From_Flags) -> HMONITOR ---
 	MonitorFromRect   :: proc(lprc: LPRECT, dwFlags: Monitor_From_Flags) -> HMONITOR ---
 	MonitorFromWindow :: proc(hwnd: HWND, dwFlags: Monitor_From_Flags) -> HMONITOR ---
 	MonitorFromWindow :: proc(hwnd: HWND, dwFlags: Monitor_From_Flags) -> HMONITOR ---
 	EnumDisplayMonitors :: proc(hdc: HDC, lprcClip: LPRECT, lpfnEnum: Monitor_Enum_Proc, dwData: LPARAM) -> BOOL ---
 	EnumDisplayMonitors :: proc(hdc: HDC, lprcClip: LPRECT, lpfnEnum: Monitor_Enum_Proc, dwData: LPARAM) -> BOOL ---
+	
+	EnumWindows :: proc(lpEnumFunc: Window_Enum_Proc, lParam: LPARAM) -> BOOL ---
 
 
 	SetThreadDpiAwarenessContext :: proc(dpiContext: DPI_AWARENESS_CONTEXT) -> DPI_AWARENESS_CONTEXT ---
 	SetThreadDpiAwarenessContext :: proc(dpiContext: DPI_AWARENESS_CONTEXT) -> DPI_AWARENESS_CONTEXT ---
 	GetThreadDpiAwarenessContext :: proc() -> DPI_AWARENESS_CONTEXT ---
 	GetThreadDpiAwarenessContext :: proc() -> DPI_AWARENESS_CONTEXT ---
@@ -311,6 +313,7 @@ Monitor_From_Flags :: enum DWORD {
 }
 }
 
 
 Monitor_Enum_Proc :: #type proc "stdcall" (HMONITOR, HDC, LPRECT, LPARAM) -> BOOL
 Monitor_Enum_Proc :: #type proc "stdcall" (HMONITOR, HDC, LPRECT, LPARAM) -> BOOL
+Window_Enum_Proc :: #type proc "stdcall" (HWND, LPARAM) -> BOOL
 
 
 USER_DEFAULT_SCREEN_DPI                    :: 96
 USER_DEFAULT_SCREEN_DPI                    :: 96
 DPI_AWARENESS_CONTEXT                      :: distinct HANDLE
 DPI_AWARENESS_CONTEXT                      :: distinct HANDLE

+ 55 - 38
core/thread/thread.odin

@@ -116,26 +116,21 @@ run_with_data :: proc(data: rawptr, fn: proc(data: rawptr), init_context: Maybe(
 }
 }
 
 
 run_with_poly_data :: proc(data: $T, fn: proc(data: T), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal)
 run_with_poly_data :: proc(data: $T, fn: proc(data: T), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal)
-	where size_of(T) <= size_of(rawptr) {
+	where size_of(T) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
 	create_and_start_with_poly_data(data, fn, init_context, priority, true)
 	create_and_start_with_poly_data(data, fn, init_context, priority, true)
 }
 }
 
 
 run_with_poly_data2 :: proc(arg1: $T1, arg2: $T2, fn: proc(T1, T2), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal)
 run_with_poly_data2 :: proc(arg1: $T1, arg2: $T2, fn: proc(T1, T2), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal)
-	where size_of(T1) <= size_of(rawptr),
-	      size_of(T2) <= size_of(rawptr) {
+	where size_of(T1) + size_of(T2) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
 	create_and_start_with_poly_data2(arg1, arg2, fn, init_context, priority, true)
 	create_and_start_with_poly_data2(arg1, arg2, fn, init_context, priority, true)
 }
 }
 
 
 run_with_poly_data3 :: proc(arg1: $T1, arg2: $T2, arg3: $T3, fn: proc(arg1: T1, arg2: T2, arg3: T3), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal)
 run_with_poly_data3 :: proc(arg1: $T1, arg2: $T2, arg3: $T3, fn: proc(arg1: T1, arg2: T2, arg3: T3), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal)
-	where size_of(T1) <= size_of(rawptr),
-	      size_of(T2) <= size_of(rawptr),
-	      size_of(T3) <= size_of(rawptr) {
+	where size_of(T1) + size_of(T2) + size_of(T3) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
 	create_and_start_with_poly_data3(arg1, arg2, arg3, fn, init_context, priority, true)
 	create_and_start_with_poly_data3(arg1, arg2, arg3, fn, init_context, priority, true)
 }
 }
 run_with_poly_data4 :: proc(arg1: $T1, arg2: $T2, arg3: $T3, arg4: $T4, fn: proc(arg1: T1, arg2: T2, arg3: T3, arg4: T4), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal)
 run_with_poly_data4 :: proc(arg1: $T1, arg2: $T2, arg3: $T3, arg4: $T4, fn: proc(arg1: T1, arg2: T2, arg3: T3, arg4: T4), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal)
-	where size_of(T1) <= size_of(rawptr),
-	      size_of(T2) <= size_of(rawptr),
-	      size_of(T3) <= size_of(rawptr) {
+	where size_of(T1) + size_of(T2) + size_of(T3) + size_of(T4) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
 	create_and_start_with_poly_data4(arg1, arg2, arg3, arg4, fn, init_context, priority, true)
 	create_and_start_with_poly_data4(arg1, arg2, arg3, arg4, fn, init_context, priority, true)
 }
 }
 
 
@@ -178,7 +173,7 @@ create_and_start_with_data :: proc(data: rawptr, fn: proc(data: rawptr), init_co
 }
 }
 
 
 create_and_start_with_poly_data :: proc(data: $T, fn: proc(data: T), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, self_cleanup := false) -> ^Thread
 create_and_start_with_poly_data :: proc(data: $T, fn: proc(data: T), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, self_cleanup := false) -> ^Thread
-	where size_of(T) <= size_of(rawptr) {
+	where size_of(T) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
 	thread_proc :: proc(t: ^Thread) {
 	thread_proc :: proc(t: ^Thread) {
 		fn := cast(proc(T))t.data
 		fn := cast(proc(T))t.data
 		assert(t.user_index >= 1)
 		assert(t.user_index >= 1)
@@ -188,96 +183,118 @@ create_and_start_with_poly_data :: proc(data: $T, fn: proc(data: T), init_contex
 	t := create(thread_proc, priority)
 	t := create(thread_proc, priority)
 	t.data = rawptr(fn)
 	t.data = rawptr(fn)
 	t.user_index = 1
 	t.user_index = 1
+
 	data := data
 	data := data
-	mem.copy(&t.user_args[0], &data, size_of(data))
+
+	mem.copy(&t.user_args[0], &data, size_of(T))
+
 	if self_cleanup {
 	if self_cleanup {
 		t.flags += {.Self_Cleanup}
 		t.flags += {.Self_Cleanup}
 	}
 	}
+
 	t.init_context = init_context
 	t.init_context = init_context
 	start(t)
 	start(t)
 	return t
 	return t
 }
 }
 
 
 create_and_start_with_poly_data2 :: proc(arg1: $T1, arg2: $T2, fn: proc(T1, T2), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, self_cleanup := false) -> ^Thread
 create_and_start_with_poly_data2 :: proc(arg1: $T1, arg2: $T2, fn: proc(T1, T2), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, self_cleanup := false) -> ^Thread
-	where size_of(T1) <= size_of(rawptr),
-	      size_of(T2) <= size_of(rawptr) {
+	where size_of(T1) + size_of(T2) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
 	thread_proc :: proc(t: ^Thread) {
 	thread_proc :: proc(t: ^Thread) {
 		fn := cast(proc(T1, T2))t.data
 		fn := cast(proc(T1, T2))t.data
 		assert(t.user_index >= 2)
 		assert(t.user_index >= 2)
-		arg1 := (^T1)(&t.user_args[0])^
-		arg2 := (^T2)(&t.user_args[1])^
+		
+		user_args := mem.slice_to_bytes(t.user_args[:])
+		arg1 := (^T1)(raw_data(user_args))^
+		arg2 := (^T2)(raw_data(user_args[size_of(T1):]))^
+
 		fn(arg1, arg2)
 		fn(arg1, arg2)
 	}
 	}
 	t := create(thread_proc, priority)
 	t := create(thread_proc, priority)
 	t.data = rawptr(fn)
 	t.data = rawptr(fn)
 	t.user_index = 2
 	t.user_index = 2
+
 	arg1, arg2 := arg1, arg2
 	arg1, arg2 := arg1, arg2
-	mem.copy(&t.user_args[0], &arg1, size_of(arg1))
-	mem.copy(&t.user_args[1], &arg2, size_of(arg2))
+	user_args := mem.slice_to_bytes(t.user_args[:])
+
+	n := copy(user_args,     mem.ptr_to_bytes(&arg1))
+	_  = copy(user_args[n:], mem.ptr_to_bytes(&arg2))
+
 	if self_cleanup {
 	if self_cleanup {
 		t.flags += {.Self_Cleanup}
 		t.flags += {.Self_Cleanup}
 	}
 	}
+
 	t.init_context = init_context
 	t.init_context = init_context
 	start(t)
 	start(t)
 	return t
 	return t
 }
 }
 
 
 create_and_start_with_poly_data3 :: proc(arg1: $T1, arg2: $T2, arg3: $T3, fn: proc(arg1: T1, arg2: T2, arg3: T3), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, self_cleanup := false) -> ^Thread
 create_and_start_with_poly_data3 :: proc(arg1: $T1, arg2: $T2, arg3: $T3, fn: proc(arg1: T1, arg2: T2, arg3: T3), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, self_cleanup := false) -> ^Thread
-	where size_of(T1) <= size_of(rawptr),
-	      size_of(T2) <= size_of(rawptr),
-	      size_of(T3) <= size_of(rawptr) {
+	where size_of(T1) + size_of(T2) + size_of(T3) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
 	thread_proc :: proc(t: ^Thread) {
 	thread_proc :: proc(t: ^Thread) {
 		fn := cast(proc(T1, T2, T3))t.data
 		fn := cast(proc(T1, T2, T3))t.data
 		assert(t.user_index >= 3)
 		assert(t.user_index >= 3)
-		arg1 := (^T1)(&t.user_args[0])^
-		arg2 := (^T2)(&t.user_args[1])^
-		arg3 := (^T3)(&t.user_args[2])^
+
+		user_args := mem.slice_to_bytes(t.user_args[:])
+		arg1 := (^T1)(raw_data(user_args))^
+		arg2 := (^T2)(raw_data(user_args[size_of(T1):]))^
+		arg3 := (^T3)(raw_data(user_args[size_of(T1) + size_of(T2):]))^
+
 		fn(arg1, arg2, arg3)
 		fn(arg1, arg2, arg3)
 	}
 	}
 	t := create(thread_proc, priority)
 	t := create(thread_proc, priority)
 	t.data = rawptr(fn)
 	t.data = rawptr(fn)
 	t.user_index = 3
 	t.user_index = 3
+
 	arg1, arg2, arg3 := arg1, arg2, arg3
 	arg1, arg2, arg3 := arg1, arg2, arg3
-	mem.copy(&t.user_args[0], &arg1, size_of(arg1))
-	mem.copy(&t.user_args[1], &arg2, size_of(arg2))
-	mem.copy(&t.user_args[2], &arg3, size_of(arg3))
+	user_args := mem.slice_to_bytes(t.user_args[:])
+
+	n := copy(user_args,     mem.ptr_to_bytes(&arg1))
+	n += copy(user_args[n:], mem.ptr_to_bytes(&arg2))
+	_  = copy(user_args[n:], mem.ptr_to_bytes(&arg3))
+
 	if self_cleanup {
 	if self_cleanup {
 		t.flags += {.Self_Cleanup}
 		t.flags += {.Self_Cleanup}
 	}
 	}
+
 	t.init_context = init_context
 	t.init_context = init_context
 	start(t)
 	start(t)
 	return t
 	return t
 }
 }
 create_and_start_with_poly_data4 :: proc(arg1: $T1, arg2: $T2, arg3: $T3, arg4: $T4, fn: proc(arg1: T1, arg2: T2, arg3: T3, arg4: T4), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, self_cleanup := false) -> ^Thread
 create_and_start_with_poly_data4 :: proc(arg1: $T1, arg2: $T2, arg3: $T3, arg4: $T4, fn: proc(arg1: T1, arg2: T2, arg3: T3, arg4: T4), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, self_cleanup := false) -> ^Thread
-	where size_of(T1) <= size_of(rawptr),
-	      size_of(T2) <= size_of(rawptr),
-	      size_of(T3) <= size_of(rawptr) {
+	where size_of(T1) + size_of(T2) + size_of(T3) + size_of(T4) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
 	thread_proc :: proc(t: ^Thread) {
 	thread_proc :: proc(t: ^Thread) {
 		fn := cast(proc(T1, T2, T3, T4))t.data
 		fn := cast(proc(T1, T2, T3, T4))t.data
 		assert(t.user_index >= 4)
 		assert(t.user_index >= 4)
-		arg1 := (^T1)(&t.user_args[0])^
-		arg2 := (^T2)(&t.user_args[1])^
-		arg3 := (^T3)(&t.user_args[2])^
-		arg4 := (^T4)(&t.user_args[3])^
+
+		user_args := mem.slice_to_bytes(t.user_args[:])
+		arg1 := (^T1)(raw_data(user_args))^
+		arg2 := (^T2)(raw_data(user_args[size_of(T1):]))^
+		arg3 := (^T3)(raw_data(user_args[size_of(T1) + size_of(T2):]))^
+		arg4 := (^T4)(raw_data(user_args[size_of(T1) + size_of(T2) + size_of(T3):]))^
+
 		fn(arg1, arg2, arg3, arg4)
 		fn(arg1, arg2, arg3, arg4)
 	}
 	}
 	t := create(thread_proc, priority)
 	t := create(thread_proc, priority)
 	t.data = rawptr(fn)
 	t.data = rawptr(fn)
 	t.user_index = 4
 	t.user_index = 4
+
 	arg1, arg2, arg3, arg4 := arg1, arg2, arg3, arg4
 	arg1, arg2, arg3, arg4 := arg1, arg2, arg3, arg4
-	mem.copy(&t.user_args[0], &arg1, size_of(arg1))
-	mem.copy(&t.user_args[1], &arg2, size_of(arg2))
-	mem.copy(&t.user_args[2], &arg3, size_of(arg3))
-	mem.copy(&t.user_args[3], &arg4, size_of(arg4))
+	user_args := mem.slice_to_bytes(t.user_args[:])
+
+	n := copy(user_args,     mem.ptr_to_bytes(&arg1))
+	n += copy(user_args[n:], mem.ptr_to_bytes(&arg2))
+	n += copy(user_args[n:], mem.ptr_to_bytes(&arg3))
+	_  = copy(user_args[n:], mem.ptr_to_bytes(&arg4))
+
 	if self_cleanup {
 	if self_cleanup {
 		t.flags += {.Self_Cleanup}
 		t.flags += {.Self_Cleanup}
 	}
 	}
+
 	t.init_context = init_context
 	t.init_context = init_context
 	start(t)
 	start(t)
 	return t
 	return t
 }
 }
 
 
-
 _select_context_for_thread :: proc(init_context: Maybe(runtime.Context)) -> runtime.Context {
 _select_context_for_thread :: proc(init_context: Maybe(runtime.Context)) -> runtime.Context {
 	ctx, ok := init_context.?
 	ctx, ok := init_context.?
 	if !ok {
 	if !ok {

+ 5 - 1
examples/all/all_vendor.odin

@@ -39,6 +39,8 @@ import nvg       "vendor:nanovg"
 import nvg_gl    "vendor:nanovg/gl"
 import nvg_gl    "vendor:nanovg/gl"
 import fontstash "vendor:fontstash"
 import fontstash "vendor:fontstash"
 
 
+import xlib       "vendor:x11/xlib"
+
 _ :: botan_bindings
 _ :: botan_bindings
 _ :: botan_blake2b
 _ :: botan_blake2b
 _ :: keccak
 _ :: keccak
@@ -76,4 +78,6 @@ _ :: lua_5_4
 
 
 _ :: nvg
 _ :: nvg
 _ :: nvg_gl
 _ :: nvg_gl
-_ :: fontstash
+_ :: fontstash
+
+_ :: xlib

+ 7 - 1
examples/demo/demo.odin

@@ -44,7 +44,13 @@ the_basics :: proc() {
 	fmt.println("\n# the basics")
 	fmt.println("\n# the basics")
 
 
 	{ // The Basics
 	{ // The Basics
-		fmt.println("Hellope")
+
+		// os.args holds the path to the current executable and any arguments passed to it.
+		if len(os.args) == 1 {
+			fmt.printf("Hellope from %v.\n", os.args[0])
+		} else {
+			fmt.printf("%v, %v! from %v.\n", os.args[1], os.args[2], os.args[0])
+		}
 
 
 		// Lexical elements and literals
 		// Lexical elements and literals
 		// A comment
 		// A comment

+ 5 - 3
src/checker.cpp

@@ -6123,9 +6123,6 @@ gb_internal void check_parsed_files(Checker *c) {
 	TIME_SECTION("calculate global init order");
 	TIME_SECTION("calculate global init order");
 	calculate_global_init_order(c);
 	calculate_global_init_order(c);
 
 
-	TIME_SECTION("check test procedures");
-	check_test_procedures(c);
-
 	TIME_SECTION("add type info for type definitions");
 	TIME_SECTION("add type info for type definitions");
 	add_type_info_for_type_definitions(c);
 	add_type_info_for_type_definitions(c);
 	check_merge_queues_into_arrays(c);
 	check_merge_queues_into_arrays(c);
@@ -6136,6 +6133,11 @@ gb_internal void check_parsed_files(Checker *c) {
 	TIME_SECTION("generate minimum dependency set");
 	TIME_SECTION("generate minimum dependency set");
 	generate_minimum_dependency_set(c, c->info.entry_point);
 	generate_minimum_dependency_set(c, c->info.entry_point);
 
 
+	// NOTE(laytan): has to be ran after generate_minimum_dependency_set,
+	// because that collects the test procedures.
+	TIME_SECTION("check test procedures");
+	check_test_procedures(c);
+
 	TIME_SECTION("check bodies have all been checked");
 	TIME_SECTION("check bodies have all been checked");
 	check_unchecked_bodies(c);
 	check_unchecked_bodies(c);
 
 

+ 9 - 9
src/llvm_backend.cpp

@@ -21,8 +21,8 @@
 #include "llvm_backend_stmt.cpp"
 #include "llvm_backend_stmt.cpp"
 #include "llvm_backend_proc.cpp"
 #include "llvm_backend_proc.cpp"
 
 
-char *get_default_microarchitecture() {
-	char * default_march = "generic";
+String get_default_microarchitecture() {
+	String default_march = str_lit("generic");
 	if (build_context.metrics.arch == TargetArch_amd64) {
 	if (build_context.metrics.arch == TargetArch_amd64) {
 		// NOTE(bill): x86-64-v2 is more than enough for everyone
 		// NOTE(bill): x86-64-v2 is more than enough for everyone
 		//
 		//
@@ -32,9 +32,9 @@ char *get_default_microarchitecture() {
 		// x86-64-v4: AVX512F, AVX512BW, AVX512CD, AVX512DQ, AVX512VL
 		// x86-64-v4: AVX512F, AVX512BW, AVX512CD, AVX512DQ, AVX512VL
 		if (ODIN_LLVM_MINIMUM_VERSION_12) {
 		if (ODIN_LLVM_MINIMUM_VERSION_12) {
 			if (build_context.metrics.os == TargetOs_freestanding) {
 			if (build_context.metrics.os == TargetOs_freestanding) {
-				default_march = "x86-64";
+				default_march = str_lit("x86-64");
 			} else {
 			} else {
-				default_march = "x86-64-v2";
+				default_march = str_lit("x86-64-v2");
 			}
 			}
 		}
 		}
 	}
 	}
@@ -2509,16 +2509,16 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
 		code_mode = LLVMCodeModelKernel;
 		code_mode = LLVMCodeModelKernel;
 	}
 	}
 
 
-	char const *host_cpu_name = LLVMGetHostCPUName();
-	char const *llvm_cpu = get_default_microarchitecture();
+	String      host_cpu_name = copy_string(permanent_allocator(), make_string_c(LLVMGetHostCPUName()));
+	String      llvm_cpu      = get_default_microarchitecture();
 	char const *llvm_features = "";
 	char const *llvm_features = "";
 	if (build_context.microarch.len != 0) {
 	if (build_context.microarch.len != 0) {
 		if (build_context.microarch == "native") {
 		if (build_context.microarch == "native") {
 			llvm_cpu = host_cpu_name;
 			llvm_cpu = host_cpu_name;
 		} else {
 		} else {
-			llvm_cpu = alloc_cstring(permanent_allocator(), build_context.microarch);
+			llvm_cpu = copy_string(permanent_allocator(), build_context.microarch);
 		}
 		}
-		if (gb_strcmp(llvm_cpu, host_cpu_name) == 0) {
+		if (llvm_cpu == host_cpu_name) {
 			llvm_features = LLVMGetHostCPUFeatures();
 			llvm_features = LLVMGetHostCPUFeatures();
 		}
 		}
 	}
 	}
@@ -2578,7 +2578,7 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
 
 
 	for (auto const &entry : gen->modules) {
 	for (auto const &entry : gen->modules) {
 		LLVMTargetMachineRef target_machine = LLVMCreateTargetMachine(
 		LLVMTargetMachineRef target_machine = LLVMCreateTargetMachine(
-			target, target_triple, llvm_cpu,
+			target, target_triple, (const char *)llvm_cpu.text,
 			llvm_features,
 			llvm_features,
 			code_gen_level,
 			code_gen_level,
 			reloc_mode,
 			reloc_mode,

+ 140 - 134
src/main.cpp

@@ -199,19 +199,19 @@ gb_internal void print_usage_line(i32 indent, char const *fmt, ...) {
 }
 }
 
 
 gb_internal void usage(String argv0) {
 gb_internal void usage(String argv0) {
-	print_usage_line(0, "%.*s is a tool for managing Odin source code", LIT(argv0));
+	print_usage_line(0, "%.*s is a tool for managing Odin source code.", LIT(argv0));
 	print_usage_line(0, "Usage:");
 	print_usage_line(0, "Usage:");
 	print_usage_line(1, "%.*s command [arguments]", LIT(argv0));
 	print_usage_line(1, "%.*s command [arguments]", LIT(argv0));
 	print_usage_line(0, "Commands:");
 	print_usage_line(0, "Commands:");
-	print_usage_line(1, "build             compile directory of .odin files, as an executable.");
-	print_usage_line(1, "                  one must contain the program's entry point, all must be in the same package.");
-	print_usage_line(1, "run               same as 'build', but also then runs the newly compiled executable.");
-	print_usage_line(1, "check             parse, and type check a directory of .odin files");
-	print_usage_line(1, "strip-semicolon   parse, type check, and remove unneeded semicolons from the entire program");
-	print_usage_line(1, "test              build and runs procedures with the attribute @(test) in the initial package");
-	print_usage_line(1, "doc               generate documentation on a directory of .odin files");
-	print_usage_line(1, "version           print version");
-	print_usage_line(1, "report            print information useful to reporting a bug");
+	print_usage_line(1, "build             Compiles directory of .odin files, as an executable.");
+	print_usage_line(1, "                  One must contain the program's entry point, all must be in the same package.");
+	print_usage_line(1, "run               Same as 'build', but also then runs the newly compiled executable.");
+	print_usage_line(1, "check             Parses, and type checks a directory of .odin files.");
+	print_usage_line(1, "strip-semicolon   Parses, type checks, and removes unneeded semicolons from the entire program.");
+	print_usage_line(1, "test              Builds and runs procedures with the attribute @(test) in the initial package.");
+	print_usage_line(1, "doc               Generates documentation on a directory of .odin files.");
+	print_usage_line(1, "version           Prints version.");
+	print_usage_line(1, "report            Prints information useful to reporting a bug.");
 	print_usage_line(0, "");
 	print_usage_line(0, "");
 	print_usage_line(0, "For further details on a command, invoke command help:");
 	print_usage_line(0, "For further details on a command, invoke command help:");
 	print_usage_line(1, "e.g. `odin build -help` or `odin help build`");
 	print_usage_line(1, "e.g. `odin build -help` or `odin help build`");
@@ -1580,45 +1580,45 @@ gb_internal void remove_temp_files(lbGenerator *gen) {
 
 
 
 
 gb_internal void print_show_help(String const arg0, String const &command) {
 gb_internal void print_show_help(String const arg0, String const &command) {
-	print_usage_line(0, "%.*s is a tool for managing Odin source code", LIT(arg0));
+	print_usage_line(0, "%.*s is a tool for managing Odin source code.", LIT(arg0));
 	print_usage_line(0, "Usage:");
 	print_usage_line(0, "Usage:");
 	print_usage_line(1, "%.*s %.*s [arguments]", LIT(arg0), LIT(command));
 	print_usage_line(1, "%.*s %.*s [arguments]", LIT(arg0), LIT(command));
 	print_usage_line(0, "");
 	print_usage_line(0, "");
 
 
 	if (command == "build") {
 	if (command == "build") {
-		print_usage_line(1, "build   Compile directory of .odin files as an executable.");
+		print_usage_line(1, "build   Compiles directory of .odin files as an executable.");
 		print_usage_line(2, "One must contain the program's entry point, all must be in the same package.");
 		print_usage_line(2, "One must contain the program's entry point, all must be in the same package.");
 		print_usage_line(2, "Use `-file` to build a single file instead.");
 		print_usage_line(2, "Use `-file` to build a single file instead.");
 		print_usage_line(2, "Examples:");
 		print_usage_line(2, "Examples:");
-		print_usage_line(3, "odin build .                    # Build package in current directory");
-		print_usage_line(3, "odin build <dir>                # Build package in <dir>");
-		print_usage_line(3, "odin build filename.odin -file  # Build single-file package, must contain entry point.");
+		print_usage_line(3, "odin build .                     Builds package in current directory.");
+		print_usage_line(3, "odin build <dir>                 Builds package in <dir>.");
+		print_usage_line(3, "odin build filename.odin -file   Builds single-file package, must contain entry point.");
 	} else if (command == "run") {
 	} else if (command == "run") {
 		print_usage_line(1, "run     Same as 'build', but also then runs the newly compiled executable.");
 		print_usage_line(1, "run     Same as 'build', but also then runs the newly compiled executable.");
 		print_usage_line(2, "Append an empty flag and then the args, '-- <args>', to specify args for the output.");
 		print_usage_line(2, "Append an empty flag and then the args, '-- <args>', to specify args for the output.");
 		print_usage_line(2, "Examples:");
 		print_usage_line(2, "Examples:");
-		print_usage_line(3, "odin run .                    # Build and run package in current directory");
-		print_usage_line(3, "odin run <dir>                # Build and run package in <dir>");
-		print_usage_line(3, "odin run filename.odin -file  # Build and run single-file package, must contain entry point.");
+		print_usage_line(3, "odin run .                     Builds and runs package in current directory.");
+		print_usage_line(3, "odin run <dir>                 Builds and runs package in <dir>.");
+		print_usage_line(3, "odin run filename.odin -file   Builds and runs single-file package, must contain entry point.");
 	} else if (command == "check") {
 	} else if (command == "check") {
-		print_usage_line(1, "check   Parse and type check directory of .odin files");
+		print_usage_line(1, "check   Parses and type checks directory of .odin files.");
 		print_usage_line(2, "Examples:");
 		print_usage_line(2, "Examples:");
-		print_usage_line(3, "odin check .                    # Type check package in current directory");
-		print_usage_line(3, "odin check <dir>                # Type check package in <dir>");
-		print_usage_line(3, "odin check filename.odin -file  # Type check single-file package, must contain entry point.");
+		print_usage_line(3, "odin check .                     Type checks package in current directory.");
+		print_usage_line(3, "odin check <dir>                 Type checks package in <dir>.");
+		print_usage_line(3, "odin check filename.odin -file   Type checks single-file package, must contain entry point.");
 	} else if (command == "test") {
 	} else if (command == "test") {
-		print_usage_line(1, "test      Build and runs procedures with the attribute @(test) in the initial package");
+		print_usage_line(1, "test    Builds and runs procedures with the attribute @(test) in the initial package.");
 	} else if (command == "doc") {
 	} else if (command == "doc") {
-		print_usage_line(1, "doc       generate documentation from a directory of .odin files");
+		print_usage_line(1, "doc     Generates documentation from a directory of .odin files.");
 		print_usage_line(2, "Examples:");
 		print_usage_line(2, "Examples:");
-		print_usage_line(3, "odin doc .                    # Generate documentation on package in current directory");
-		print_usage_line(3, "odin doc <dir>                # Generate documentation on package in <dir>");
-		print_usage_line(3, "odin doc filename.odin -file  # Generate documentation on single-file package.");
+		print_usage_line(3, "odin doc .                     Generates documentation on package in current directory.");
+		print_usage_line(3, "odin doc <dir>                 Generates documentation on package in <dir>.");
+		print_usage_line(3, "odin doc filename.odin -file   Generates documentation on single-file package.");
 	} else if (command == "version") {
 	} else if (command == "version") {
-		print_usage_line(1, "version   print version");
+		print_usage_line(1, "version   Prints version.");
 	} else if (command == "strip-semicolon") {
 	} else if (command == "strip-semicolon") {
 		print_usage_line(1, "strip-semicolon");
 		print_usage_line(1, "strip-semicolon");
-		print_usage_line(2, "Parse and type check .odin file(s) and then remove unneeded semicolons from the entire project");
+		print_usage_line(2, "Parses and type checks .odin file(s) and then removes unneeded semicolons from the entire project.");
 	}
 	}
 
 
 	bool doc             = command == "doc";
 	bool doc             = command == "doc";
@@ -1642,237 +1642,240 @@ gb_internal void print_show_help(String const arg0, String const &command) {
 
 
 	if (doc) {
 	if (doc) {
 		print_usage_line(1, "-short");
 		print_usage_line(1, "-short");
-		print_usage_line(2, "Show shortened documentation for the packages");
+		print_usage_line(2, "Shows shortened documentation for the packages.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-all-packages");
 		print_usage_line(1, "-all-packages");
-		print_usage_line(2, "Generates documentation for all packages used in the current project");
+		print_usage_line(2, "Generates documentation for all packages used in the current project.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-doc-format");
 		print_usage_line(1, "-doc-format");
-		print_usage_line(2, "Generates documentation as the .odin-doc format (useful for external tooling)");
+		print_usage_line(2, "Generates documentation as the .odin-doc format (useful for external tooling).");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 	}
 	}
 
 
 	if (run_or_build) {
 	if (run_or_build) {
 		print_usage_line(1, "-out:<filepath>");
 		print_usage_line(1, "-out:<filepath>");
-		print_usage_line(2, "Set the file name of the outputted executable");
+		print_usage_line(2, "Sets the file name of the outputted executable.");
 		print_usage_line(2, "Example: -out:foo.exe");
 		print_usage_line(2, "Example: -out:foo.exe");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-o:<string>");
 		print_usage_line(1, "-o:<string>");
-		print_usage_line(2, "Set the optimization mode for compilation");
+		print_usage_line(2, "Sets the optimization mode for compilation.");
+		print_usage_line(2, "Available options:");
+		print_usage_line(3, "-o:none");
+		print_usage_line(3, "-o:minimal");
+		print_usage_line(3, "-o:size");
+		print_usage_line(3, "-o:speed");
 		if (LB_USE_NEW_PASS_SYSTEM) {
 		if (LB_USE_NEW_PASS_SYSTEM) {
-			print_usage_line(2, "Accepted values: none, minimal, size, speed, aggressive");
-		} else {
-			print_usage_line(2, "Accepted values: none, minimal, size, speed");
+			print_usage_line(3, "-o:aggressive");
 		}
 		}
-		print_usage_line(2, "Example: -o:speed");
-		print_usage_line(2, "The default is -o:minimal");
+		print_usage_line(2, "The default is -o:minimal.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 	}
 	}
 
 
 	if (check) {
 	if (check) {
 		print_usage_line(1, "-show-timings");
 		print_usage_line(1, "-show-timings");
-		print_usage_line(2, "Shows basic overview of the timings of different stages within the compiler in milliseconds");
+		print_usage_line(2, "Shows basic overview of the timings of different stages within the compiler in milliseconds.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-show-more-timings");
 		print_usage_line(1, "-show-more-timings");
-		print_usage_line(2, "Shows an advanced overview of the timings of different stages within the compiler in milliseconds");
+		print_usage_line(2, "Shows an advanced overview of the timings of different stages within the compiler in milliseconds.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-show-system-calls");
 		print_usage_line(1, "-show-system-calls");
-		print_usage_line(2, "Prints the whole command and arguments for calls to external tools like linker and assembler");
+		print_usage_line(2, "Prints the whole command and arguments for calls to external tools like linker and assembler.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-export-timings:<format>");
 		print_usage_line(1, "-export-timings:<format>");
-		print_usage_line(2, "Export timings to one of a few formats. Requires `-show-timings` or `-show-more-timings`");
+		print_usage_line(2, "Exports timings to one of a few formats. Requires `-show-timings` or `-show-more-timings`.");
 		print_usage_line(2, "Available options:");
 		print_usage_line(2, "Available options:");
-		print_usage_line(3, "-export-timings:json        Export compile time stats to JSON");
-		print_usage_line(3, "-export-timings:csv         Export compile time stats to CSV");
+		print_usage_line(3, "-export-timings:json   Exports compile time stats to JSON.");
+		print_usage_line(3, "-export-timings:csv    Exports compile time stats to CSV.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-export-timings-file:<filename>");
 		print_usage_line(1, "-export-timings-file:<filename>");
-		print_usage_line(2, "Specify the filename for `-export-timings`");
+		print_usage_line(2, "Specifies the filename for `-export-timings`.");
 		print_usage_line(2, "Example: -export-timings-file:timings.json");
 		print_usage_line(2, "Example: -export-timings-file:timings.json");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-thread-count:<integer>");
 		print_usage_line(1, "-thread-count:<integer>");
-		print_usage_line(2, "Override the number of threads the compiler will use to compile with");
+		print_usage_line(2, "Overrides the number of threads the compiler will use to compile with.");
 		print_usage_line(2, "Example: -thread-count:2");
 		print_usage_line(2, "Example: -thread-count:2");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 	}
 	}
 
 
 	if (check_only) {
 	if (check_only) {
 		print_usage_line(1, "-show-unused");
 		print_usage_line(1, "-show-unused");
-		print_usage_line(2, "Shows unused package declarations within the current project");
+		print_usage_line(2, "Shows unused package declarations within the current project.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 		print_usage_line(1, "-show-unused-with-location");
 		print_usage_line(1, "-show-unused-with-location");
-		print_usage_line(2, "Shows unused package declarations within the current project with the declarations source location");
+		print_usage_line(2, "Shows unused package declarations within the current project with the declarations source location.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 	}
 	}
 
 
 	if (run_or_build) {
 	if (run_or_build) {
 		print_usage_line(1, "-keep-temp-files");
 		print_usage_line(1, "-keep-temp-files");
-		print_usage_line(2, "Keeps the temporary files generated during compilation");
+		print_usage_line(2, "Keeps the temporary files generated during compilation.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 	} else if (strip_semicolon) {
 	} else if (strip_semicolon) {
 		print_usage_line(1, "-keep-temp-files");
 		print_usage_line(1, "-keep-temp-files");
-		print_usage_line(2, "Keeps the temporary files generated during stripping the unneeded semicolons from files");
+		print_usage_line(2, "Keeps the temporary files generated during stripping the unneeded semicolons from files.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 	}
 	}
 
 
 	if (check) {
 	if (check) {
 		print_usage_line(1, "-collection:<name>=<filepath>");
 		print_usage_line(1, "-collection:<name>=<filepath>");
-		print_usage_line(2, "Defines a library collection used for imports");
+		print_usage_line(2, "Defines a library collection used for imports.");
 		print_usage_line(2, "Example: -collection:shared=dir/to/shared");
 		print_usage_line(2, "Example: -collection:shared=dir/to/shared");
 		print_usage_line(2, "Usage in Code:");
 		print_usage_line(2, "Usage in Code:");
 		print_usage_line(3, "import \"shared:foo\"");
 		print_usage_line(3, "import \"shared:foo\"");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-define:<name>=<value>");
 		print_usage_line(1, "-define:<name>=<value>");
-		print_usage_line(2, "Defines a scalar boolean, integer or string as global constant");
+		print_usage_line(2, "Defines a scalar boolean, integer or string as global constant.");
 		print_usage_line(2, "Example: -define:SPAM=123");
 		print_usage_line(2, "Example: -define:SPAM=123");
-		print_usage_line(2, "To use:  #config(SPAM, default_value)");
+		print_usage_line(2, "Usage in code:");
+		print_usage_line(3, "#config(SPAM, default_value)");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 	}
 	}
 
 
 	if (build) {
 	if (build) {
 		print_usage_line(1, "-build-mode:<mode>");
 		print_usage_line(1, "-build-mode:<mode>");
-		print_usage_line(2, "Sets the build mode");
+		print_usage_line(2, "Sets the build mode.");
 		print_usage_line(2, "Available options:");
 		print_usage_line(2, "Available options:");
-		print_usage_line(3, "-build-mode:exe       Build as an executable");
-		print_usage_line(3, "-build-mode:dll       Build as a dynamically linked library");
-		print_usage_line(3, "-build-mode:shared    Build as a dynamically linked library");
-		print_usage_line(3, "-build-mode:obj       Build as an object file");
-		print_usage_line(3, "-build-mode:object    Build as an object file");
-		print_usage_line(3, "-build-mode:assembly  Build as an assembly file");
-		print_usage_line(3, "-build-mode:assembler Build as an assembly file");
-		print_usage_line(3, "-build-mode:asm       Build as an assembly file");
-		print_usage_line(3, "-build-mode:llvm-ir   Build as an LLVM IR file");
-		print_usage_line(3, "-build-mode:llvm      Build as an LLVM IR file");
+		print_usage_line(3, "-build-mode:exe         Builds as an executable.");
+		print_usage_line(3, "-build-mode:dll         Builds as a dynamically linked library.");
+		print_usage_line(3, "-build-mode:shared      Builds as a dynamically linked library.");
+		print_usage_line(3, "-build-mode:obj         Builds as an object file.");
+		print_usage_line(3, "-build-mode:object      Builds as an object file.");
+		print_usage_line(3, "-build-mode:assembly    Builds as an assembly file.");
+		print_usage_line(3, "-build-mode:assembler   Builds as an assembly file.");
+		print_usage_line(3, "-build-mode:asm         Builds as an assembly file.");
+		print_usage_line(3, "-build-mode:llvm-ir     Builds as an LLVM IR file.");
+		print_usage_line(3, "-build-mode:llvm        Builds as an LLVM IR file.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 	}
 	}
 
 
 	if (check) {
 	if (check) {
 		print_usage_line(1, "-target:<string>");
 		print_usage_line(1, "-target:<string>");
-		print_usage_line(2, "Sets the target for the executable to be built in");
+		print_usage_line(2, "Sets the target for the executable to be built in.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 	}
 	}
 
 
 	if (run_or_build) {
 	if (run_or_build) {
 		print_usage_line(1, "-debug");
 		print_usage_line(1, "-debug");
-		print_usage_line(2, "Enabled debug information, and defines the global constant ODIN_DEBUG to be 'true'");
+		print_usage_line(2, "Enables debug information, and defines the global constant ODIN_DEBUG to be 'true'.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-disable-assert");
 		print_usage_line(1, "-disable-assert");
-		print_usage_line(2, "Disable the code generation of the built-in run-time 'assert' procedure, and defines the global constant ODIN_DISABLE_ASSERT to be 'true'");
+		print_usage_line(2, "Disables the code generation of the built-in run-time 'assert' procedure, and defines the global constant ODIN_DISABLE_ASSERT to be 'true'.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-no-bounds-check");
 		print_usage_line(1, "-no-bounds-check");
-		print_usage_line(2, "Disables bounds checking program wide");
+		print_usage_line(2, "Disables bounds checking program wide.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-no-crt");
 		print_usage_line(1, "-no-crt");
-		print_usage_line(2, "Disables automatic linking with the C Run Time");
+		print_usage_line(2, "Disables automatic linking with the C Run Time.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-no-thread-local");
 		print_usage_line(1, "-no-thread-local");
-		print_usage_line(2, "Ignore @thread_local attribute, effectively treating the program as if it is single-threaded");
+		print_usage_line(2, "Ignores @thread_local attribute, effectively treating the program as if it is single-threaded.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-lld");
 		print_usage_line(1, "-lld");
-		print_usage_line(2, "Use the LLD linker rather than the default");
+		print_usage_line(2, "Uses the LLD linker rather than the default.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-use-separate-modules");
 		print_usage_line(1, "-use-separate-modules");
 		print_usage_line(1, "[EXPERIMENTAL]");
 		print_usage_line(1, "[EXPERIMENTAL]");
-		print_usage_line(2, "The backend generates multiple build units which are then linked together");
-		print_usage_line(2, "Normally, a single build unit is generated for a standard project");
+		print_usage_line(2, "The backend generates multiple build units which are then linked together.");
+		print_usage_line(2, "Normally, a single build unit is generated for a standard project.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 	}
 	}
 
 
 	if (check) {
 	if (check) {
 		print_usage_line(1, "-no-threaded-checker");
 		print_usage_line(1, "-no-threaded-checker");
-		print_usage_line(2, "Disabled multithreading in the semantic checker stage");
+		print_usage_line(2, "Disables multithreading in the semantic checker stage.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 	}
 	}
 
 
 	if (check) {
 	if (check) {
 		print_usage_line(1, "-vet");
 		print_usage_line(1, "-vet");
-		print_usage_line(2, "Do extra checks on the code");
+		print_usage_line(2, "Does extra checks on the code.");
 		print_usage_line(2, "Extra checks include:");
 		print_usage_line(2, "Extra checks include:");
-		print_usage_line(2, "-vet-unused");
-		print_usage_line(2, "-vet-shadowing");
-		print_usage_line(2, "-vet-using-stmt");
+		print_usage_line(3, "-vet-unused");
+		print_usage_line(3, "-vet-shadowing");
+		print_usage_line(3, "-vet-using-stmt");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-vet-unused");
 		print_usage_line(1, "-vet-unused");
-		print_usage_line(2, "Checks for unused declarations");
+		print_usage_line(2, "Checks for unused declarations.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-vet-shadowing");
 		print_usage_line(1, "-vet-shadowing");
-		print_usage_line(2, "Checks for variable shadowing within procedures");
+		print_usage_line(2, "Checks for variable shadowing within procedures.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-vet-using-stmt");
 		print_usage_line(1, "-vet-using-stmt");
-		print_usage_line(2, "Checks for the use of 'using' as a statement");
-		print_usage_line(2, "'using' is considered bad practice outside of immediate refactoring");
+		print_usage_line(2, "Checks for the use of 'using' as a statement.");
+		print_usage_line(2, "'using' is considered bad practice outside of immediate refactoring.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-vet-using-param");
 		print_usage_line(1, "-vet-using-param");
-		print_usage_line(2, "Checks for the use of 'using' on procedure parameters");
-		print_usage_line(2, "'using' is considered bad practice outside of immediate refactoring");
+		print_usage_line(2, "Checks for the use of 'using' on procedure parameters.");
+		print_usage_line(2, "'using' is considered bad practice outside of immediate refactoring.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-vet-style");
 		print_usage_line(1, "-vet-style");
-		print_usage_line(2, "Errs on missing trailing commas followed by a newline");
-		print_usage_line(2, "Errs on deprecated syntax");
-		print_usage_line(2, "Does not err on unneeded tokens (unlike -strict-style)");
+		print_usage_line(2, "Errs on missing trailing commas followed by a newline.");
+		print_usage_line(2, "Errs on deprecated syntax.");
+		print_usage_line(2, "Does not err on unneeded tokens (unlike -strict-style).");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-vet-semicolon");
 		print_usage_line(1, "-vet-semicolon");
-		print_usage_line(2, "Errs on unneeded semicolons");
+		print_usage_line(2, "Errs on unneeded semicolons.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 	}
 	}
 
 
 	if (check) {
 	if (check) {
 		print_usage_line(1, "-ignore-unknown-attributes");
 		print_usage_line(1, "-ignore-unknown-attributes");
-		print_usage_line(2, "Ignores unknown attributes");
-		print_usage_line(2, "This can be used with metaprogramming tools");
+		print_usage_line(2, "Ignores unknown attributes.");
+		print_usage_line(2, "This can be used with metaprogramming tools.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		if (command != "test") {
 		if (command != "test") {
 			print_usage_line(1, "-no-entry-point");
 			print_usage_line(1, "-no-entry-point");
-			print_usage_line(2, "Removes default requirement of an entry point (e.g. main procedure)");
+			print_usage_line(2, "Removes default requirement of an entry point (e.g. main procedure).");
 			print_usage_line(0, "");
 			print_usage_line(0, "");
 		}
 		}
 	}
 	}
 
 
 	if (test_only) {
 	if (test_only) {
 		print_usage_line(1, "-test-name:<string>");
 		print_usage_line(1, "-test-name:<string>");
-		print_usage_line(2, "Run specific test only by name");
+		print_usage_line(2, "Runs specific test only by name.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 	}
 	}
 
 
 	if (run_or_build) {
 	if (run_or_build) {
 		print_usage_line(1, "-minimum-os-version:<string>");
 		print_usage_line(1, "-minimum-os-version:<string>");
-		print_usage_line(2, "Sets the minimum OS version targeted by the application");
-		print_usage_line(2, "e.g. -minimum-os-version:12.0.0");
-		print_usage_line(2, "(Only used when target is Darwin)");
+		print_usage_line(2, "Sets the minimum OS version targeted by the application.");
+		print_usage_line(2, "Example: -minimum-os-version:12.0.0");
+		print_usage_line(2, "(Only used when target is Darwin.)");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-extra-linker-flags:<string>");
 		print_usage_line(1, "-extra-linker-flags:<string>");
-		print_usage_line(2, "Adds extra linker specific flags in a string");
+		print_usage_line(2, "Adds extra linker specific flags in a string.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-extra-assembler-flags:<string>");
 		print_usage_line(1, "-extra-assembler-flags:<string>");
-		print_usage_line(2, "Adds extra assembler specific flags in a string");
+		print_usage_line(2, "Adds extra assembler specific flags in a string.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-microarch:<string>");
 		print_usage_line(1, "-microarch:<string>");
-		print_usage_line(2, "Specifies the specific micro-architecture for the build in a string");
+		print_usage_line(2, "Specifies the specific micro-architecture for the build in a string.");
 		print_usage_line(2, "Examples:");
 		print_usage_line(2, "Examples:");
 		print_usage_line(3, "-microarch:sandybridge");
 		print_usage_line(3, "-microarch:sandybridge");
 		print_usage_line(3, "-microarch:native");
 		print_usage_line(3, "-microarch:native");
@@ -1880,74 +1883,77 @@ gb_internal void print_show_help(String const arg0, String const &command) {
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-reloc-mode:<string>");
 		print_usage_line(1, "-reloc-mode:<string>");
-		print_usage_line(2, "Specifies the reloc mode");
-		print_usage_line(2, "Options:");
-		print_usage_line(3, "default");
-		print_usage_line(3, "static");
-		print_usage_line(3, "pic");
-		print_usage_line(3, "dynamic-no-pic");
+		print_usage_line(2, "Specifies the reloc mode.");
+		print_usage_line(2, "Available options:");
+		print_usage_line(3, "-reloc-mode:default");
+		print_usage_line(3, "-reloc-mode:static");
+		print_usage_line(3, "-reloc-mode:pic");
+		print_usage_line(3, "-reloc-mode:dynamic-no-pic");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-disable-red-zone");
 		print_usage_line(1, "-disable-red-zone");
-		print_usage_line(2, "Disable red zone on a supported freestanding target");
+		print_usage_line(2, "Disables red zone on a supported freestanding target.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-dynamic-map-calls");
 		print_usage_line(1, "-dynamic-map-calls");
-		print_usage_line(2, "Use dynamic map calls to minimize code generation at the cost of runtime execution");
+		print_usage_line(2, "Uses dynamic map calls to minimize code generation at the cost of runtime execution.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 	}
 	}
 
 
 	if (check) {
 	if (check) {
 		print_usage_line(1, "-disallow-do");
 		print_usage_line(1, "-disallow-do");
-		print_usage_line(2, "Disallows the 'do' keyword in the project");
+		print_usage_line(2, "Disallows the 'do' keyword in the project.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-default-to-nil-allocator");
 		print_usage_line(1, "-default-to-nil-allocator");
-		print_usage_line(2, "Sets the default allocator to be the nil_allocator, an allocator which does nothing");
+		print_usage_line(2, "Sets the default allocator to be the nil_allocator, an allocator which does nothing.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-strict-style");
 		print_usage_line(1, "-strict-style");
-		print_usage_line(2, "Errs on unneeded tokens, such as unneeded semicolons");
-		print_usage_line(2, "Errs on missing trailing commas followed by a newline");
-		print_usage_line(2, "Errs on deprecated syntax");
+		print_usage_line(2, "Errs on unneeded tokens, such as unneeded semicolons.");
+		print_usage_line(2, "Errs on missing trailing commas followed by a newline.");
+		print_usage_line(2, "Errs on deprecated syntax.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-ignore-warnings");
 		print_usage_line(1, "-ignore-warnings");
-		print_usage_line(2, "Ignores warning messages");
+		print_usage_line(2, "Ignores warning messages.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-warnings-as-errors");
 		print_usage_line(1, "-warnings-as-errors");
-		print_usage_line(2, "Treats warning messages as error messages");
+		print_usage_line(2, "Treats warning messages as error messages.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-terse-errors");
 		print_usage_line(1, "-terse-errors");
-		print_usage_line(2, "Prints a terse error message without showing the code on that line and the location in that line");
+		print_usage_line(2, "Prints a terse error message without showing the code on that line and the location in that line.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-error-pos-style:<string>");
 		print_usage_line(1, "-error-pos-style:<string>");
-		print_usage_line(2, "Options are 'unix', 'odin' and 'default' (odin)");
-		print_usage_line(2, "'odin'    file/path(45:3)");
-		print_usage_line(2, "'unix'    file/path:45:3:");
+		print_usage_line(2, "Available options:");
+		print_usage_line(3, "-error-pos-style:unix      file/path:45:3:");
+		print_usage_line(3, "-error-pos-style:odin      file/path(45:3)");
+		print_usage_line(3, "-error-pos-style:default   (Defaults to 'odin'.)");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
-
 		print_usage_line(1, "-max-error-count:<integer>");
 		print_usage_line(1, "-max-error-count:<integer>");
-		print_usage_line(2, "Set the maximum number of errors that can be displayed before the compiler terminates");
-		print_usage_line(2, "Must be an integer >0");
-		print_usage_line(2, "If not set, the default max error count is %d", DEFAULT_MAX_ERROR_COLLECTOR_COUNT);
+		print_usage_line(2, "Sets the maximum number of errors that can be displayed before the compiler terminates.");
+		print_usage_line(2, "Must be an integer >0.");
+		print_usage_line(2, "If not set, the default max error count is %d.", DEFAULT_MAX_ERROR_COLLECTOR_COUNT);
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-foreign-error-procedures");
 		print_usage_line(1, "-foreign-error-procedures");
-		print_usage_line(2, "States that the error procedues used in the runtime are defined in a separate translation unit");
+		print_usage_line(2, "States that the error procedures used in the runtime are defined in a separate translation unit.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 	}
 	}
 
 
 	if (run_or_build) {
 	if (run_or_build) {
 		print_usage_line(1, "-sanitize:<string>");
 		print_usage_line(1, "-sanitize:<string>");
-		print_usage_line(1, "Enables sanitization analysis");
-		print_usage_line(1, "Options are 'address', 'memory', and 'thread'");
-		print_usage_line(1, "NOTE: This flag can be used multiple times");
+		print_usage_line(2, "Enables sanitization analysis.");
+		print_usage_line(2, "Available options:");
+		print_usage_line(3, "-sanitize:address");
+		print_usage_line(3, "-sanitize:memory");
+		print_usage_line(3, "-sanitize:thread");
+		print_usage_line(2, "NOTE: This flag can be used multiple times.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 	}
 	}
@@ -1956,27 +1962,27 @@ gb_internal void print_show_help(String const arg0, String const &command) {
 		#if defined(GB_SYSTEM_WINDOWS)
 		#if defined(GB_SYSTEM_WINDOWS)
 		print_usage_line(1, "-ignore-vs-search");
 		print_usage_line(1, "-ignore-vs-search");
 		print_usage_line(2, "[Windows only]");
 		print_usage_line(2, "[Windows only]");
-		print_usage_line(2, "Ignores the Visual Studio search for library paths");
+		print_usage_line(2, "Ignores the Visual Studio search for library paths.");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-resource:<filepath>");
 		print_usage_line(1, "-resource:<filepath>");
 		print_usage_line(2, "[Windows only]");
 		print_usage_line(2, "[Windows only]");
-		print_usage_line(2, "Defines the resource file for the executable");
+		print_usage_line(2, "Defines the resource file for the executable.");
 		print_usage_line(2, "Example: -resource:path/to/file.rc");
 		print_usage_line(2, "Example: -resource:path/to/file.rc");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-pdb-name:<filepath>");
 		print_usage_line(1, "-pdb-name:<filepath>");
 		print_usage_line(2, "[Windows only]");
 		print_usage_line(2, "[Windows only]");
-		print_usage_line(2, "Defines the generated PDB name when -debug is enabled");
+		print_usage_line(2, "Defines the generated PDB name when -debug is enabled.");
 		print_usage_line(2, "Example: -pdb-name:different.pdb");
 		print_usage_line(2, "Example: -pdb-name:different.pdb");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		print_usage_line(1, "-subsystem:<option>");
 		print_usage_line(1, "-subsystem:<option>");
 		print_usage_line(2, "[Windows only]");
 		print_usage_line(2, "[Windows only]");
-		print_usage_line(2, "Defines the subsystem for the application");
+		print_usage_line(2, "Defines the subsystem for the application.");
 		print_usage_line(2, "Available options:");
 		print_usage_line(2, "Available options:");
-		print_usage_line(3, "console");
-		print_usage_line(3, "windows");
+		print_usage_line(3, "-subsystem:console");
+		print_usage_line(3, "-subsystem:windows");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
 		#endif
 		#endif
@@ -2538,6 +2544,7 @@ int main(int arg_count, char const **arg_ptr) {
 		}
 		}
 	}
 	}
 
 
+	String default_march = get_default_microarchitecture();
 	if (print_microarch_list) {
 	if (print_microarch_list) {
 		if (build_context.microarch != "?") {
 		if (build_context.microarch != "?") {
 			gb_printf("Unknown microarchitecture '%.*s'.\n", LIT(build_context.microarch));
 			gb_printf("Unknown microarchitecture '%.*s'.\n", LIT(build_context.microarch));
@@ -2548,8 +2555,6 @@ int main(int arg_count, char const **arg_ptr) {
 		String march_list  = target_microarch_list[build_context.metrics.arch];
 		String march_list  = target_microarch_list[build_context.metrics.arch];
 		String_Iterator it = {march_list, 0};
 		String_Iterator it = {march_list, 0};
 
 
-		String default_march = make_string_c(get_default_microarchitecture());
-
 		for (;;) {
 		for (;;) {
 			String str = string_split_iterator(&it, ',');
 			String str = string_split_iterator(&it, ',');
 			if (str == "") break;
 			if (str == "") break;
@@ -2568,6 +2573,7 @@ int main(int arg_count, char const **arg_ptr) {
 	}
 	}
 
 
 	if (build_context.show_debug_messages) {
 	if (build_context.show_debug_messages) {
+		debugf("Selected microarch: %.*s\n", LIT(default_march));
 		for_array(i, build_context.build_paths) {
 		for_array(i, build_context.build_paths) {
 			String build_path = path_to_string(heap_allocator(), build_context.build_paths[i]);
 			String build_path = path_to_string(heap_allocator(), build_context.build_paths[i]);
 			debugf("build_paths[%ld]: %.*s\n", i, LIT(build_path));
 			debugf("build_paths[%ld]: %.*s\n", i, LIT(build_path));

+ 26 - 3
tests/core/Makefile

@@ -1,9 +1,26 @@
 ODIN=../../odin
 ODIN=../../odin
 PYTHON=$(shell which python3)
 PYTHON=$(shell which python3)
 
 
-all: download_test_assets image_test compress_test strings_test hash_test crypto_test noise_test encoding_test \
-	 math_test linalg_glsl_math_test filepath_test reflect_test os_exit_test i18n_test match_test c_libc_test net_test \
-	 fmt_test
+all: c_libc_test \
+	 compress_test \
+	 crypto_test \
+	 download_test_assets \
+	 encoding_test \
+	 filepath_test \
+	 fmt_test \
+	 hash_test \
+	 i18n_test \
+	 image_test \
+	 linalg_glsl_math_test \
+	 match_test \
+	 math_test \
+	 net_test \
+	 noise_test \
+	 os_exit_test \
+	 reflect_test \
+	 slice_test \
+	 strings_test \
+	 thread_test
 
 
 download_test_assets:
 download_test_assets:
 	$(PYTHON) download_assets.py
 	$(PYTHON) download_assets.py
@@ -44,6 +61,9 @@ filepath_test:
 reflect_test:
 reflect_test:
 	$(ODIN) run reflect/test_core_reflect.odin -file -collection:tests=.. -out:test_core_reflect
 	$(ODIN) run reflect/test_core_reflect.odin -file -collection:tests=.. -out:test_core_reflect
 
 
+slice_test:
+	$(ODIN) run slice/test_core_slice.odin -file -out:test_core_slice
+
 os_exit_test:
 os_exit_test:
 	$(ODIN) run os/test_core_os_exit.odin -file -out:test_core_os_exit && exit 1 || exit 0
 	$(ODIN) run os/test_core_os_exit.odin -file -out:test_core_os_exit && exit 1 || exit 0
 
 
@@ -61,3 +81,6 @@ net_test:
 
 
 fmt_test:
 fmt_test:
 	$(ODIN) run fmt -out:test_core_fmt
 	$(ODIN) run fmt -out:test_core_fmt
+
+thread_test:
+	$(ODIN) run thread -out:test_core_thread

+ 10 - 0
tests/core/build.bat

@@ -66,6 +66,11 @@ echo Running core:reflect tests
 echo ---
 echo ---
 %PATH_TO_ODIN% run reflect %COMMON% %COLLECTION% -out:test_core_reflect.exe || exit /b
 %PATH_TO_ODIN% run reflect %COMMON% %COLLECTION% -out:test_core_reflect.exe || exit /b
 
 
+echo ---
+echo Running core:slice tests
+echo ---
+%PATH_TO_ODIN% run slice %COMMON% -out:test_core_slice.exe || exit /b
+
 echo ---
 echo ---
 echo Running core:text/i18n tests
 echo Running core:text/i18n tests
 echo ---
 echo ---
@@ -85,3 +90,8 @@ echo ---
 echo Running core:container tests
 echo Running core:container tests
 echo ---
 echo ---
 %PATH_TO_ODIN% run container %COMMON% %COLLECTION% -out:test_core_container.exe || exit /b
 %PATH_TO_ODIN% run container %COMMON% %COLLECTION% -out:test_core_container.exe || exit /b
+
+echo ---
+echo Running core:thread tests
+echo ---
+%PATH_TO_ODIN% run thread %COMMON% %COLLECTION% -out:test_core_thread.exe || exit /b

+ 63 - 0
tests/core/slice/test_core_slice.odin

@@ -1,6 +1,7 @@
 package test_core_slice
 package test_core_slice
 
 
 import "core:slice"
 import "core:slice"
+import "core:strings"
 import "core:testing"
 import "core:testing"
 import "core:fmt"
 import "core:fmt"
 import "core:os"
 import "core:os"
@@ -30,6 +31,7 @@ when ODIN_TEST {
 main :: proc() {
 main :: proc() {
 	t := testing.T{}
 	t := testing.T{}
 	test_sort_with_indices(&t)
 	test_sort_with_indices(&t)
+	test_binary_search(&t)
 
 
 	fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
 	fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
 	if TEST_fail > 0 {
 	if TEST_fail > 0 {
@@ -180,3 +182,64 @@ test_sort_by_indices :: proc(t: ^testing.T) {
 		}
 		}
 	}
 	}
 }
 }
+
+@test
+test_binary_search :: proc(t: ^testing.T) {
+	builder := strings.Builder{}
+	defer strings.builder_destroy(&builder)
+
+	test_search :: proc(t: ^testing.T, b: ^strings.Builder, s: []i32, v: i32) -> (int, bool) {
+		log(t, fmt.sbprintf(b, "Searching for %v in %v", v, s))
+		strings.builder_reset(b)
+		index, found := slice.binary_search(s, v)
+		log(t, fmt.sbprintf(b, "index: %v, found: %v", index, found))
+		strings.builder_reset(b	)
+
+		return index, found
+	}
+
+	index: int
+	found: bool
+
+	s := []i32{0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55}
+
+	index, found = test_search(t, &builder, s, 13)
+	expect(t, index == 9, "Expected index to be 9.")
+	expect(t, found == true, "Expected found to be true.")
+
+	index, found = test_search(t, &builder, s, 4)
+	expect(t, index == 7, "Expected index to be 7.")
+	expect(t, found == false, "Expected found to be false.")
+
+	index, found = test_search(t, &builder, s, 100)
+	expect(t, index == 13, "Expected index to be 13.")
+	expect(t, found == false, "Expected found to be false.")
+
+	index, found = test_search(t, &builder, s, 1)
+	expect(t, index >= 1 && index <= 4, "Expected index to be 1, 2, 3, or 4.")
+	expect(t, found == true, "Expected found to be true.")
+
+	index, found = test_search(t, &builder, s, -1)
+	expect(t, index == 0, "Expected index to be 0.")
+	expect(t, found == false, "Expected found to be false.")
+
+	a := []i32{}
+
+	index, found = test_search(t, &builder, a, 13)
+	expect(t, index == 0, "Expected index to be 0.")
+	expect(t, found == false, "Expected found to be false.")
+
+	b := []i32{1}
+
+	index, found = test_search(t, &builder, b, 13)
+	expect(t, index == 1, "Expected index to be 1.")
+	expect(t, found == false, "Expected found to be false.")
+
+	index, found = test_search(t, &builder, b, 1)
+	expect(t, index == 0, "Expected index to be 0.")
+	expect(t, found == true, "Expected found to be true.")
+
+	index, found = test_search(t, &builder, b, 0)
+	expect(t, index == 0, "Expected index to be 0.")
+	expect(t, found == false, "Expected found to be false.")
+}

+ 84 - 0
tests/core/thread/test_core_thread.odin

@@ -0,0 +1,84 @@
+package test_core_thread
+
+import "core:testing"
+import "core:thread"
+import "core:fmt"
+import "core:os"
+
+TEST_count := 0
+TEST_fail  := 0
+
+t := &testing.T{}
+
+when ODIN_TEST {
+    expect  :: testing.expect
+    log     :: testing.log
+} else {
+    expect  :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
+        TEST_count += 1
+        if !condition {
+            TEST_fail += 1
+            fmt.printf("[%v] %v\n", loc, message)
+            return
+        }
+    }
+    log     :: proc(t: ^testing.T, v: any, loc := #caller_location) {
+        fmt.printf("[%v] ", loc)
+        fmt.printf("log: %v\n", v)
+    }
+}
+
+main :: proc() {
+	poly_data_test(t)
+
+	if TEST_fail > 0 {
+		os.exit(1)
+	}
+}
+
+@(test)
+poly_data_test :: proc(_t: ^testing.T) {
+	MAX :: size_of(rawptr) * thread.MAX_USER_ARGUMENTS
+
+	@static poly_data_test_t: ^testing.T
+	poly_data_test_t = _t
+
+	b: [MAX]byte = 8
+	t1 := thread.create_and_start_with_poly_data(b, proc(b: [MAX]byte) {
+		b_expect: [MAX]byte = 8
+		expect(poly_data_test_t, b == b_expect, "thread poly data not correct")
+	})
+	defer free(t1)
+
+	b1: [3]uintptr = 1
+	b2: [MAX / 2]byte = 3
+	t2 := thread.create_and_start_with_poly_data2(b1, b2, proc(b: [3]uintptr, b2: [MAX / 2]byte) {
+		b_expect: [3]uintptr = 1
+		b2_expect: [MAX / 2]byte = 3
+		expect(poly_data_test_t, b == b_expect,   "thread poly data not correct")
+		expect(poly_data_test_t, b2 == b2_expect, "thread poly data not correct")
+	})
+	defer free(t2)
+
+	t3 := thread.create_and_start_with_poly_data3(b1, b2, uintptr(333), proc(b: [3]uintptr, b2: [MAX / 2]byte, b3: uintptr) {
+		b_expect: [3]uintptr = 1
+		b2_expect: [MAX / 2]byte = 3
+
+		expect(poly_data_test_t, b == b_expect,   "thread poly data not correct")
+		expect(poly_data_test_t, b2 == b2_expect, "thread poly data not correct")
+		expect(poly_data_test_t, b3 == 333,       "thread poly data not correct")
+	})
+	defer free(t3)
+
+	t4 := thread.create_and_start_with_poly_data4(uintptr(111), b1, uintptr(333), u8(5), proc(n: uintptr, b: [3]uintptr, n2: uintptr, n4: u8) {
+		b_expect: [3]uintptr = 1
+
+		expect(poly_data_test_t, n == 111,        "thread poly data not correct")
+		expect(poly_data_test_t, b == b_expect,   "thread poly data not correct")
+		expect(poly_data_test_t, n2 == 333,       "thread poly data not correct")
+		expect(poly_data_test_t, n4 == 5,         "thread poly data not correct")
+	})
+	defer free(t4)
+
+	thread.join_multiple(t1, t2, t3, t4)
+}

BIN
vendor/raylib/linux/libraygui.a


BIN
vendor/raylib/linux/libraygui.so.3.6


+ 8 - 21
vendor/raylib/raygui.odin

@@ -16,23 +16,9 @@ when ODIN_OS == .Windows {
 	}
 	}
 } else when ODIN_OS == .Linux  {
 } else when ODIN_OS == .Linux  {
 	when RAYGUI_SHARED {
 	when RAYGUI_SHARED {
-		// Note(bumbread): can't panic here, because the users might be expecting to
-		// only use raylib. Let's have them get the error at link-time instead..
-		//#panic("Cannot link libraygui.so: not in the vendor collection")
-		// Note(bumbread): unless we import something the rest of the bindings will
-		// make a compile-time error. This is a bit ugly for now, but in the future
-		// raygui probably needs to be in a separate package.
-		foreign import lib {"_"}
+		foreign import lib "linux/libraygui.so"
 	} else {
 	} else {
-		// #panic("Cannot link libraygui.a: not in the vendor collection")
-		// TODO(bumbread): apparently this one was missing. This might need
-		// to get rebuilt for linux
-		// foreign import lib { 
-		// 	"linux/libraygui.a",
-		// 	// "system:dl",
-		// 	// "system:pthread",
-		// }
-		foreign import lib {"_"}
+		foreign import lib "linux/libraygui.a"
 	}
 	}
 } else when ODIN_OS == .Darwin {
 } else when ODIN_OS == .Darwin {
 	when ODIN_ARCH == .arm64 {
 	when ODIN_ARCH == .arm64 {
@@ -238,6 +224,7 @@ SCROLLBAR_RIGHT_SIDE :: 1
 
 
 @(default_calling_convention="c")
 @(default_calling_convention="c")
 foreign lib {
 foreign lib {
+	@(link_name="raylib_version") version: cstring
 	// Global gui state control functions
 	// Global gui state control functions
 	
 	
 	GuiEnable           :: proc() ---                                                                         // Enable gui controls (global state)
 	GuiEnable           :: proc() ---                                                                         // Enable gui controls (global state)
@@ -293,17 +280,17 @@ foreign lib {
 	// Basic controls set
 	// Basic controls set
 	
 	
 	GuiLabel            :: proc(bounds: Rectangle, text: cstring) -> c.int ---                                // Label control, shows text
 	GuiLabel            :: proc(bounds: Rectangle, text: cstring) -> c.int ---                                // Label control, shows text
-	GuiButton           :: proc(bounds: Rectangle, text: cstring) -> c.int ---                                // Button control, returns true when clicked
-	GuiLabelButton      :: proc(bounds: Rectangle, text: cstring) -> c.int ---                                // Label button control, show true when clicked
+	GuiButton           :: proc(bounds: Rectangle, text: cstring) -> bool ---                                 // Button control, returns true when clicked
+	GuiLabelButton      :: proc(bounds: Rectangle, text: cstring) -> bool ---                                // Label button control, show true when clicked
 	GuiToggle           :: proc(bounds: Rectangle, text: cstring, active: ^bool) -> c.int ---                 // Toggle Button control, returns true when active
 	GuiToggle           :: proc(bounds: Rectangle, text: cstring, active: ^bool) -> c.int ---                 // Toggle Button control, returns true when active
 	GuiToggleGroup      :: proc(bounds: Rectangle, text: cstring, active: ^c.int) -> c.int ---                // Toggle Group control, returns active toggle index
 	GuiToggleGroup      :: proc(bounds: Rectangle, text: cstring, active: ^c.int) -> c.int ---                // Toggle Group control, returns active toggle index
-	GuiCheckBox         :: proc(bounds: Rectangle, text: cstring, checked: ^bool) -> c.int ---                // Check Box control, returns true when active
+	GuiCheckBox         :: proc(bounds: Rectangle, text: cstring, checked: ^bool) -> bool ---                // Check Box control, returns true when active
 	GuiComboBox         :: proc(bounds: Rectangle, text: cstring, active: ^c.int) -> c.int ---                // Combo Box control, returns selected item index
 	GuiComboBox         :: proc(bounds: Rectangle, text: cstring, active: ^c.int) -> c.int ---                // Combo Box control, returns selected item index
 	
 	
-	GuiDropdownBox      :: proc(bounds: Rectangle, text: cstring, active: ^c.int, editMode: bool) -> c.int --- // Dropdown Box control, returns selected item
+	GuiDropdownBox      :: proc(bounds: Rectangle, text: cstring, active: ^c.int, editMode: bool) -> bool --- // Dropdown Box control, returns selected item
 	GuiSpinner          :: proc(bounds: Rectangle, text: cstring, value: ^c.int, minValue, maxValue: c.int, editMode: bool) -> c.int --- // Spinner control, returns selected value
 	GuiSpinner          :: proc(bounds: Rectangle, text: cstring, value: ^c.int, minValue, maxValue: c.int, editMode: bool) -> c.int --- // Spinner control, returns selected value
 	GuiValueBox         :: proc(bounds: Rectangle, text: cstring, value: ^c.int, minValue, maxValue: c.int, editMode: bool) -> c.int --- // Value Box control, updates input text with numbers
 	GuiValueBox         :: proc(bounds: Rectangle, text: cstring, value: ^c.int, minValue, maxValue: c.int, editMode: bool) -> c.int --- // Value Box control, updates input text with numbers
-	GuiTextBox          :: proc(bounds: Rectangle, text: cstring, textSize: c.int, editMode: bool) -> c.int --- // Text Box control, updates input text
+	GuiTextBox          :: proc(bounds: Rectangle, text: cstring, textSize: c.int, editMode: bool) -> bool --- // Text Box control, updates input text
 	
 	
 	GuiSlider           :: proc(bounds: Rectangle, textLeft: cstring, textRight: cstring, value: ^f32, minValue: f32, maxValue: f32) -> c.int --- // Slider control, returns selected value
 	GuiSlider           :: proc(bounds: Rectangle, textLeft: cstring, textRight: cstring, value: ^f32, minValue: f32, maxValue: f32) -> c.int --- // Slider control, returns selected value
 	GuiSliderBar        :: proc(bounds: Rectangle, textLeft: cstring, textRight: cstring, value: ^f32, minValue: f32, maxValue: f32) -> c.int --- // Slider Bar control, returns selected value
 	GuiSliderBar        :: proc(bounds: Rectangle, textLeft: cstring, textRight: cstring, value: ^f32, minValue: f32, maxValue: f32) -> c.int --- // Slider Bar control, returns selected value

+ 8 - 8
vendor/sdl2/sdl_pixels.odin

@@ -163,21 +163,21 @@ PixelFormatEnum :: enum u32 {
 	ABGR32 = ABGR8888 when ODIN_ENDIAN == .Big else RGBA8888,
 	ABGR32 = ABGR8888 when ODIN_ENDIAN == .Big else RGBA8888,
 
 
 	YV12 =      /**< Planar mode: Y + V + U  (3 planes) */
 	YV12 =      /**< Planar mode: Y + V + U  (3 planes) */
-		'Y'<<24 | 'V'<<16 | '1'<<8 | '2'<<0,
+		'Y'<<0 | 'V'<<8 | '1'<<16 | '2'<<24,
 	IYUV =      /**< Planar mode: Y + U + V  (3 planes) */
 	IYUV =      /**< Planar mode: Y + U + V  (3 planes) */
-		'I'<<24 | 'Y'<<16 | 'U'<<8 | 'V'<<0,
+		'I'<<0 | 'Y'<<8 | 'U'<<16 | 'V'<<24,
 	YUY2 =      /**< Packed mode: Y0+U0+Y1+V0 (1 plane) */
 	YUY2 =      /**< Packed mode: Y0+U0+Y1+V0 (1 plane) */
-		'Y'<<24 | 'U'<<16 | 'Y'<<8 | '2'<<0,
+		'Y'<<0 | 'U'<<8 | 'Y'<<16 | '2'<<24,
 	UYVY =      /**< Packed mode: U0+Y0+V0+Y1 (1 plane) */
 	UYVY =      /**< Packed mode: U0+Y0+V0+Y1 (1 plane) */
-		'U'<<24 | 'Y'<<16 | 'V'<<8 | 'Y'<<0,
+		'U'<<0 | 'Y'<<8 | 'V'<<16 | 'Y'<<24,
 	YVYU =      /**< Packed mode: Y0+V0+Y1+U0 (1 plane) */
 	YVYU =      /**< Packed mode: Y0+V0+Y1+U0 (1 plane) */
-		'Y'<<24 | 'V'<<16 | 'Y'<<8 | 'U'<<0,
+		'Y'<<0 | 'V'<<8 | 'Y'<<16 | 'U'<<24,
 	NV12 =      /**< Planar mode: Y + U/V interleaved  (2 planes) */
 	NV12 =      /**< Planar mode: Y + U/V interleaved  (2 planes) */
-		'N'<<24 | 'V'<<16 | '1'<<8 | '2'<<0,
+		'N'<<0 | 'V'<<8 | '1'<<16 | '2'<<24,
 	NV21 =      /**< Planar mode: Y + V/U interleaved  (2 planes) */
 	NV21 =      /**< Planar mode: Y + V/U interleaved  (2 planes) */
-		'N'<<24 | 'V'<<16 | '2'<<8 | '1'<<0,
+		'N'<<0 | 'V'<<8 | '2'<<16 | '1'<<24,
 	EXTERNAL_OES =      /**< Android video texture format */
 	EXTERNAL_OES =      /**< Android video texture format */
-		'O'<<24 | 'E'<<16 | 'S'<<8 | ' '<<0,
+		'O'<<0 | 'E'<<8 | 'S'<<16 | ' '<<24,
 }
 }
 
 
 
 

+ 4 - 0
vendor/x11/.gitignore

@@ -0,0 +1,4 @@
+
+# TODO(flysand): Remove this file.
+
+*.i

+ 651 - 0
vendor/x11/xlib/xlib_const.odin

@@ -0,0 +1,651 @@
+//+build linux, freebsd, openbsd
+package xlib
+
+// Special values for many types. Most of these constants
+// aren't attached to a specific type.
+
+None            :: 0
+ParentRelative  :: 1
+CopyFromParent  :: 0
+PointerWindow   :: 0
+InputFocus      :: 1
+PointerRoot     :: 1
+AnyPropertyType :: 0
+AnyKey          :: 0
+AnyButton       :: 0
+AllTemporary    :: 0
+CurrentTime     :: 0
+NoSymbol        :: 0
+
+XA_WM_CLASS          :: Atom(67)
+XA_WM_CLIENT_MACHINE :: Atom(36)
+XA_WM_COMMAND        :: Atom(34)
+XA_WM_HINTS          :: Atom(35)
+XA_WM_ICON_NAME      :: Atom(37)
+XA_WM_ICON_SIZE      :: Atom(38)
+XA_WM_NAME           :: Atom(39)
+XA_WM_NORMAL_HINTS   :: Atom(40)
+XA_WM_SIZE_HINTS     :: Atom(41)
+XA_WM_TRANSIENT_FOR  :: Atom(68)
+XA_WM_ZOOM_HINTS     :: Atom(42)
+
+// NOTE(flysand): Some implementations return Status as enum, other return it
+// as an integer. I will make it a status.
+Status :: enum i32 {
+	Success             = 0,
+	BadRequest          = 1,
+	BadValue            = 2,
+	BadWindow           = 3,
+	BadPixmap           = 4,
+	BadAtom             = 5,
+	BadCursor           = 6,
+	BadFont             = 7,
+	BadMatch            = 8,
+	BadDrawable         = 9,
+	BadAccess           = 10,
+	BadAlloc            = 11,
+	BadColor            = 12,
+	BadGC               = 13,
+	BadIDChoice         = 14,
+	BadName             = 15,
+	BadLength           = 16,
+	BadImplementation   = 17,
+	FirstExtensionError = 128,
+	LastExtensionError  = 255,
+}
+
+ByteOrder :: enum i32 {
+	LSBFirst = 0,
+	MSBFirst = 1,
+}
+
+Gravity :: enum i32 {
+	ForgetGravity    =  0,
+	UnmapGravity     =  0,
+	NorthWestGravity =  1,
+	NorthGravity     =  2,
+	NorthEastGravity =  3,
+	WestGravity      =  4,
+	CenterGravity    =  5,
+	EastGravity      =  6,
+	SouthWestGravity =  7,
+	SouthGravity     =  8,
+	SouthEastGravity =  9,
+	StaticGravity    = 10,
+}
+
+BackingStore :: enum i32 {
+	NotUseful  = 0,
+	WhenMapped = 1,
+	Always     = 2,
+}
+
+MouseButton :: enum i32 {
+	Button1 = 1,
+	Button2 = 2,
+	Button3 = 3,
+	Button4 = 4,
+	Button5 = 5,
+}
+
+EventMask :: bit_set[EventMaskBits; int]
+EventMaskBits :: enum i32 {
+	KeyPress             =  0,
+	KeyRelease           =  1,
+	ButtonPress          =  2,
+	ButtonRelease        =  3,
+	EnterWindow          =  4,
+	LeaveWindow          =  5,
+	PointerMotion        =  6,
+	PointerMotionHint    =  7,
+	Button1Motion        =  8,
+	Button2Motion        =  9,
+	Button3Motion        = 10,
+	Button4Motion        = 11,
+	Button5Motion        = 12,
+	ButtonMotion         = 13,
+	KeymapState          = 14,
+	Exposure             = 15,
+	VisibilityChange     = 16,
+	StructureNotify      = 17,
+	ResizeRedirect       = 18,
+	SubstructureNotify   = 19,
+	SubstructureRedirect = 20,
+	FocusChange          = 21,
+	PropertyChange       = 22,
+	ColormapChange       = 23,
+	OwnerGrabButton      = 24,
+}
+
+EventType :: enum i32 {
+	KeyPress         = 2,
+	KeyRelease       = 3,
+	ButtonPress      = 4,
+	ButtonRelease    = 5,
+	MotionNotify     = 6,
+	EnterNotify      = 7,
+	LeaveNotify      = 8,
+	FocusIn          = 9,
+	FocusOut         = 10,
+	KeymapNotify     = 11,
+	Expose           = 12,
+	GraphicsExpose   = 13,
+	NoExpose         = 14,
+	VisibilityNotify = 15,
+	CreateNotify     = 16,
+	DestroyNotify    = 17,
+	UnmapNotify      = 18,
+	MapNotify        = 19,
+	MapRequest       = 20,
+	ReparentNotify   = 21,
+	ConfigureNotify  = 22,
+	ConfigureRequest = 23,
+	GravityNotify    = 24,
+	ResizeRequest    = 25,
+	CirculateNotify  = 26,
+	CirculateRequest = 27,
+	PropertyNotify   = 28,
+	SelectionClear   = 29,
+	SelectionRequest = 30,
+	SelectionNotify  = 31,
+	ColormapNotify   = 32,
+	ClientMessage    = 33,
+	MappingNotify    = 34,
+	GenericEvent     = 35,
+}
+
+InputMask :: bit_set[InputMaskBits; i32]
+InputMaskBits :: enum {
+	ShiftMask   = 0,
+	LockMask    = 1,
+	ControlMask = 2,
+	Mod1Mask    = 3,
+	Mod2Mask    = 4,
+	Mod3Mask    = 5,
+	Mod4Mask    = 6,
+	Mod5Mask    = 7,
+	Button1Mask = 8,
+	Button2Mask = 9,
+	Button3Mask = 10,
+	Button4Mask = 11,
+	Button5Mask = 12,
+	AnyModifier = 15,
+}
+
+NotifyMode :: enum i32 {
+	NotifyNormal       = 0,
+	NotifyGrab         = 1,
+	NotifyUngrab       = 2,
+	NotifyWhileGrabbed = 3,
+}
+
+NotifyDetail :: enum i32 {
+	NotifyAncestor         = 0,
+	NotifyVirtual          = 1,
+	NotifyInferior         = 2,
+	NotifyNonlinear        = 3,
+	NotifyNonlinearVirtual = 4,
+	NotifyPointer          = 5,
+	NotifyPointerRoot      = 6,
+	NotifyDetailNone       = 7,
+}
+
+MappingRequest :: enum i32 {
+	MappingModifier = 0,
+	MappingKeyboard = 1,
+	MappingPointer  = 2,
+}
+
+VisibilityState :: enum i32 {
+	VisibilityUnobscured        = 0,
+	VisibilityPartiallyObscured = 1,
+	VisibilityFullyObscured     = 2,
+}
+
+ColormapState :: enum i32 {
+	ColormapUninstalled = 0,
+	ColormapInstalled   = 1,
+}
+
+PropertyState :: enum i32 {
+	PropertyNewValue = 0,
+	PropertyDelete   = 1,
+}
+
+CloseMode :: enum i32 {
+	DestroyAll      = 0,
+	RetainPermanent = 1,
+	RetainTemporary = 2,
+}
+
+EventQueueMode :: enum i32 {
+	QueuedAlready      = 0,
+	QueuedAfterReading = 1,
+	QueuedAfterFlush   = 2,
+}
+
+WindowAttributeMask :: bit_set[WindowAttributeMaskBits; int]
+WindowAttributeMaskBits :: enum {
+	CWBackPixmap       = 0,
+	CWBackPixel        = 1,
+	CWBorderPixmap     = 2,
+	CWBorderPixel      = 3,
+	CWBitGravity       = 4,
+	CWWinGravity       = 5,
+	CWBackingStore     = 6,
+	CWBackingPlanes    = 7,
+	CWBackingPixel     = 8,
+	CWOverrideRedirect = 9,
+	CWSaveUnder        = 10,
+	CWEventMask        = 11,
+	CWDontPropagate    = 12,
+	CWColormap         = 13,
+	CWCursor           = 14,
+}
+
+WindowClass :: enum i32 {
+	CopyFromParent = 0,
+	InputOutput    = 1,
+	InputOnly      = 2,
+}
+
+WindowChangesMask :: bit_set[WindowChangesMaskBits; i32]
+WindowChangesMaskBits :: enum {
+	CWX           = 0,
+	CWY           = 1,
+	CWWidth       = 2,
+	CWHeight      = 3,
+	CWBorderWidth = 4,
+	CWSibling     = 5,
+	CWStackMode   = 6,
+}
+
+WindowStacking :: enum i32 {
+	Above    = 0,
+	Below    = 1,
+	TopIf    = 2,
+	BottomIf = 3,
+	Opposite = 4,
+}
+
+CirculationDirection :: enum i32 {
+	RaiseLowest  = 0,
+	LowerHighest = 1,
+}
+
+CirculationRequest :: enum i32 {
+	PlaceOnTop    = 0,
+	PlaceOnBottom = 1,
+}
+
+WindowMapState :: enum i32 {
+	IsUnmapped   = 0,
+	IsUnviewable = 1,
+	IsViewable   = 2,
+}
+
+KeyMask :: enum u32 {
+	ShiftMask   = 0,
+	LockMask    = 1,
+	ControlMask = 2,
+	Mod1Mask    = 3,
+	Mod2Mask    = 4,
+	Mod3Mask    = 5,
+	Mod4Mask    = 6,
+	Mod5Mask    = 7,
+}
+
+CursorShape :: enum u32 {
+	XC_X_cursor            = 0,
+	XC_arrow               = 2,
+	XC_based_arrow_down    = 4,
+	XC_based_arrow_up      = 6,
+	XC_boat                = 8,
+	XC_bogosity            = 10,
+	XC_bottom_left_corner  = 12,
+	XC_bottom_right_corner = 14,
+	XC_bottom_side         = 16,
+	XC_bottom_tee          = 18,
+	XC_box_spiral          = 20,
+	XC_center_ptr          = 22,
+	XC_circle              = 24,
+	XC_clock               = 26,
+	XC_coffee_mug          = 28,
+	XC_cross               = 30,
+	XC_cross_reverse       = 32,
+	XC_crosshair           = 34,
+	XC_diamond_cross       = 36,
+	XC_dot                 = 38,
+	XC_dotbox              = 40,
+	XC_double_arrow        = 42,
+	XC_draft_large         = 44,
+	XC_draft_small         = 46,
+	XC_draped_box          = 48,
+	XC_exchange            = 50,
+	XC_fleur               = 52,
+	XC_gobbler             = 54,
+	XC_gumby               = 56,
+	XC_hand1               = 58,
+	XC_hand2               = 60,
+	XC_heart               = 62,
+	XC_icon                = 64,
+	XC_iron_cross          = 66,
+	XC_left_ptr            = 68,
+	XC_left_side           = 70,
+	XC_left_tee            = 72,
+	XC_leftbutton          = 74,
+	XC_ll_angle            = 76,
+	XC_lr_angle            = 78,
+	XC_man                 = 80,
+	XC_middlebutton        = 82,
+	XC_mouse               = 84,
+	XC_pencil              = 86,
+	XC_pirate              = 88,
+	XC_plus                = 90,
+	XC_question_arrow      = 92,
+	XC_right_ptr           = 94,
+	XC_right_side          = 96,
+	XC_right_tee           = 98,
+	XC_rightbutton         = 100,
+	XC_rtl_logo            = 102,
+	XC_sailboat            = 104,
+	XC_sb_down_arrow       = 106,
+	XC_sb_h_double_arrow   = 108,
+	XC_sb_left_arrow       = 110,
+	XC_sb_right_arrow      = 112,
+	XC_sb_up_arrow         = 114,
+	XC_sb_v_double_arrow   = 116,
+	XC_shuttle             = 118,
+	XC_sizing              = 120,
+	XC_spider              = 122,
+	XC_spraycan            = 124,
+	XC_star                = 126,
+	XC_target              = 128,
+	XC_tcross              = 130,
+	XC_top_left_arrow      = 132,
+	XC_top_left_corner     = 134,
+	XC_top_right_corner    = 136,
+	XC_top_side            = 138,
+	XC_top_tee             = 140,
+	XC_trek                = 142,
+	XC_ul_angle            = 144,
+	XC_umbrella            = 146,
+	XC_ur_angle            = 148,
+	XC_watch               = 150,
+	XC_xterm               = 152,
+	XC_num_glyphs          = 154,
+}
+
+ColorFormat :: enum u32 {
+	XcmsUndefinedFormat = 0x00000000,
+	XcmsCIEXYZFormat    = 0x00000001,
+	XcmsCIEuvYFormat    = 0x00000002,
+	XcmsCIExyYFormat    = 0x00000003,
+	XcmsCIELabFormat    = 0x00000004,
+	XcmsCIELuvFormat    = 0x00000005,
+	XcmsTekHVCFormat    = 0x00000006,
+	XcmsRGBFormat       = 0x80000000,
+	XcmsRGBiFormat      = 0x80000001,
+}
+
+ColormapAlloc :: enum i32 {
+	AllocNone = 0,
+	AllocAll  = 1,
+}
+
+ColorFlags :: bit_set[ColorFlagsBits; i32]
+ColorFlagsBits :: enum {
+	DoRed   = 0,
+	DoGreen = 1,
+	DoBlue  = 2,
+}
+
+GCAttributeMask :: bit_set[GCAttributeMaskBits; uint]
+GCAttributeMaskBits :: enum {
+	GCFunction         = 0,
+	GCPlaneMask        = 1,
+	GCForeground       = 2,
+	GCBackground       = 3,
+	GCLineWidth        = 4,
+	GCLineStyle        = 5,
+	GCCapStyle         = 6,
+	GCJoinStyle        = 7,
+	GCFillStyle        = 8,
+	GCFillRule         = 9,
+	GCTile             = 10,
+	GCStipple          = 11,
+	GCTileStipXOrigin  = 12,
+	GCTileStipYOrigin  = 13,
+	GCFont             = 14,
+	GCSubwindowMode    = 15,
+	GCGraphicsExposures= 16,
+	GCClipXOrigin      = 17,
+	GCClipYOrigin      = 18,
+	GCClipMask         = 19,
+	GCDashOffset       = 20,
+	GCDashList         = 21,
+	GCArcMode          = 22,
+}
+
+GCFunction :: enum i32 {
+	GXclear        = 0x0, // 0
+	GXand          = 0x1, // src & dst
+	GXandReverse   = 0x2, // src & ~dst
+	GXcopy         = 0x3, // src
+	GXandInverted  = 0x4, // ~src & dst
+	GXnoop         = 0x5, // dst
+	GXxor          = 0x6, // src ~ dst
+	GXor           = 0x7, // src | dst
+	GXnor          = 0x8, // ~src & ~dst
+	GXequiv        = 0x9, // ~src ~ dst
+	GXinvert       = 0xa, // ~dst
+	GXorReverse    = 0xb, // src | ~dst
+	GXcopyInverted = 0xc, // ~src
+	GXorInverted   = 0xd, // ~src | dst
+	GXnand         = 0xe, // ~src | ~dst
+	GXset          = 0xf, // 1
+}
+
+LineStyle :: enum i32 {
+	LineSolid      = 0,
+	LineOnOffDash  = 1,
+	LineDoubleDash = 2,
+}
+
+CapStyle :: enum i32 {
+	CapNotLast    = 0,
+	CapButt       = 1,
+	CapRound      = 2,
+	CapProjecting = 3,
+}
+
+JoinStyle :: enum i32 {
+	JoinMiter = 0,
+	JoinRound = 1,
+	JoinBevel = 2,
+}
+
+FillStyle :: enum i32 {
+	FillSolid          = 0,
+	FillTiled          = 1,
+	FillStippled       = 2,
+	FillOpaqueStippled = 3,
+}
+
+FillRule :: enum i32 {
+	EvenOddRule = 0,
+	WindingRule = 1,
+}
+
+ArcMode :: enum i32 {
+	ArcChord    = 0,
+	ArcPieSlice = 1,
+}
+
+SubwindowMode :: enum i32 {
+	ClipByChildren   = 0,
+	IncludeInferiors = 1,
+}
+
+CoordMode :: enum i32 {
+	CoordModeOrigin   = 0,
+	CoordModePrevious = 1,
+}
+
+Shape :: enum i32 {
+	Complex   = 0,
+	Nonconvex = 1,
+	Convex    = 2,
+}
+
+FontDirection :: enum i32 {
+	FontLeftToRight = 0,
+	FontRightToLeft = 1,
+}
+
+ImageFormat :: enum i32 {
+	XYBitmap = 0,
+	XYPixmap = 1,
+	ZPixmap  = 2,
+}
+
+SaveSetChangeMode :: enum i32 {
+	SetModeInsert = 0,
+	SetModeDelete = 1,
+}
+
+
+ScreenSaverBlanking :: enum i32 {
+	DontPreferBlanking = 0,
+	PreferBlanking     = 1,
+	DefaultBlanking    = 2,
+}
+
+ScreenSavingExposures :: enum i32 {
+	DontAllowExposures = 0,
+	AllowExposures     = 1,
+	DefaultExposures   = 2,
+}
+
+ScreenSaverForceMode :: enum i32 {
+	ScreenSaverReset  = 0,
+	ScreenSaverActive = 1,
+}
+
+AccessControlMode :: enum i32 {
+	DisableAccess = 0,
+	EnableAccess  = 1,
+}
+
+GrabMode :: enum i32 {
+	GrabModeSync  = 0,
+	GrabModeAsync = 1,
+}
+
+AllowEventsMode :: enum i32 {
+	AsyncPointer   = 0,
+	SyncPointer    = 1,
+	ReplayPointer  = 2,
+	AsyncKeyboard  = 3,
+	SyncKeyboard   = 4,
+	ReplayKeyboard = 5,
+	AsyncBoth      = 6,
+	SyncBoth       = 7,
+}
+
+FocusRevert :: enum i32 {
+	RevertToNone        = 0,
+	RevertToPointerRoot = 1,
+	RevertToParent      = 2,
+}
+
+KeyboardControlMask :: bit_set[KeyboardControlMaskBits; int]
+KeyboardControlMaskBits :: enum {
+	KBKeyClickPercent = 0,
+	KBBellPercent     = 1,
+	KBBellPitch       = 2,
+	KBBellDuration    = 3,
+	KBLed             = 4,
+	KBLedMode         = 5,
+	KBKey             = 6,
+	KBAutoRepeatMode  = 7,
+}
+
+KeyboardAutoRepeatMode :: enum i32 {
+	AutoRepeatModeOff     = 0,
+	AutoRepeatModeOn      = 1,
+	AutoRepeatModeDefault = 2,
+}
+
+KeyboardLedMode :: enum i32 {
+	LedModeOff = 0,
+	LedModeOn  = 1,
+}
+
+WMHints :: bit_set[WMHintsBits; uint]
+WMHintsBits :: enum {
+	InputHint        = 0,
+	StateHint        = 1,
+	IconPixmapHint   = 2,
+	IconWindowHint   = 3,
+	IconPositionHint = 4,
+	IconMaskHint     = 5,
+	WindowGroupHint  = 6,
+	XUrgencyHint     = 8,
+}
+
+WMHintState :: enum i32 {
+	WithdrawnState = 0,
+	NormalState    = 1,
+	IconicState    = 3,
+}
+
+AllHints :: WMHints{
+	.InputHint,
+	.StateHint,
+	.IconPixmapHint,
+	.IconWindowHint,
+	.IconPositionHint,
+	.IconMaskHint,
+	.WindowGroupHint,
+}
+
+SizeHints :: bit_set[SizeHintsBits; uint]
+SizeHintsBits :: enum {
+	USPosition  = 0,
+	USSize      = 1,
+	PPosition   = 2,
+	PSize       = 3,
+	PMinSize    = 4,
+	PMaxSize    = 5,
+	PResizeInc  = 6,
+	PAspect     = 7,
+	PBaseSize   = 8,
+	PWinGravity = 9,
+}
+
+VisualInfoMask :: bit_set[VisualInfoMaskBits; int]
+VisualInfoMaskBits :: enum {
+	VisualIDMask           = 0,
+	VisualScreenMask       = 1,
+	VisualDepthMask        = 2,
+	VisualClassMask        = 3,
+	VisualRedMaskMask      = 4,
+	VisualGreenMaskMask    = 5,
+	VisualBlueMaskMask     = 6,
+	VisualColormapSizeMask = 7,
+	VisualBitsPerRGBMask   = 8,
+}
+
+VisualNoMask  :: VisualInfoMask {}
+VisualAllMask :: VisualInfoMask {
+	.VisualIDMask,
+	.VisualScreenMask,
+	.VisualDepthMask,
+	.VisualClassMask,
+	.VisualRedMaskMask,
+	.VisualGreenMaskMask,
+	.VisualBlueMaskMask,
+	.VisualColormapSizeMask,
+	.VisualBitsPerRGBMask,
+}

+ 1681 - 0
vendor/x11/xlib/xlib_keysym.odin

@@ -0,0 +1,1681 @@
+//+build linux, freebsd, openbsd
+package xlib
+
+KeySym :: enum u32 {
+    XK_BackSpace                     = 0xff08,  /* Back space, back char */
+    XK_Tab                           = 0xff09,
+    XK_Linefeed                      = 0xff0a,  /* Linefeed, LF */
+    XK_Clear                         = 0xff0b,
+    XK_Return                        = 0xff0d,  /* Return, enter */
+    XK_Pause                         = 0xff13,  /* Pause, hold */
+    XK_Scroll_Lock                   = 0xff14,
+    XK_Sys_Req                       = 0xff15,
+    XK_Escape                        = 0xff1b,
+    XK_Delete                        = 0xffff,  /* Delete, rubout */
+    XK_Multi_key                     = 0xff20,  /* Multi-key character compose */
+    XK_Codeinput                     = 0xff37,
+    XK_SingleCandidate               = 0xff3c,
+    XK_MultipleCandidate             = 0xff3d,
+    XK_PreviousCandidate             = 0xff3e,
+    XK_Kanji                         = 0xff21,  /* Kanji, Kanji convert */
+    XK_Muhenkan                      = 0xff22,  /* Cancel Conversion */
+    XK_Henkan_Mode                   = 0xff23,  /* Start/Stop Conversion */
+    XK_Henkan                        = 0xff23,  /* Alias for Henkan_Mode */
+    XK_Romaji                        = 0xff24,  /* to Romaji */
+    XK_Hiragana                      = 0xff25,  /* to Hiragana */
+    XK_Katakana                      = 0xff26,  /* to Katakana */
+    XK_Hiragana_Katakana             = 0xff27,  /* Hiragana/Katakana toggle */
+    XK_Zenkaku                       = 0xff28,  /* to Zenkaku */
+    XK_Hankaku                       = 0xff29,  /* to Hankaku */
+    XK_Zenkaku_Hankaku               = 0xff2a,  /* Zenkaku/Hankaku toggle */
+    XK_Touroku                       = 0xff2b,  /* Add to Dictionary */
+    XK_Massyo                        = 0xff2c,  /* Delete from Dictionary */
+    XK_Kana_Lock                     = 0xff2d,  /* Kana Lock */
+    XK_Kana_Shift                    = 0xff2e,  /* Kana Shift */
+    XK_Eisu_Shift                    = 0xff2f,  /* Alphanumeric Shift */
+    XK_Eisu_toggle                   = 0xff30,  /* Alphanumeric toggle */
+    XK_Kanji_Bangou                  = 0xff37,  /* Codeinput */
+    XK_Zen_Koho                      = 0xff3d,  /* Multiple/All Candidate(s) */
+    XK_Mae_Koho                      = 0xff3e,  /* Previous Candidate */
+    XK_Home                          = 0xff50,
+    XK_Left                          = 0xff51,  /* Move left, left arrow */
+    XK_Up                            = 0xff52,  /* Move up, up arrow */
+    XK_Right                         = 0xff53,  /* Move right, right arrow */
+    XK_Down                          = 0xff54,  /* Move down, down arrow */
+    XK_Prior                         = 0xff55,  /* Prior, previous */
+    XK_Page_Up                       = 0xff55,
+    XK_Next                          = 0xff56,  /* Next */
+    XK_Page_Down                     = 0xff56,
+    XK_End                           = 0xff57,  /* EOL */
+    XK_Begin                         = 0xff58,  /* BOL */
+    XK_Select                        = 0xff60,  /* Select, mark */
+    XK_Print                         = 0xff61,
+    XK_Execute                       = 0xff62,  /* Execute, run, do */
+    XK_Insert                        = 0xff63,  /* Insert, insert here */
+    XK_Undo                          = 0xff65,
+    XK_Redo                          = 0xff66,  /* Redo, again */
+    XK_Menu                          = 0xff67,
+    XK_Find                          = 0xff68,  /* Find, search */
+    XK_Cancel                        = 0xff69,  /* Cancel, stop, abort, exit */
+    XK_Help                          = 0xff6a,  /* Help */
+    XK_Break                         = 0xff6b,
+    XK_Mode_switch                   = 0xff7e,  /* Character set switch */
+    XK_script_switch                 = 0xff7e,  /* Alias for mode_switch */
+    XK_Num_Lock                      = 0xff7f,
+    XK_KP_Space                      = 0xff80,  /* Space */
+    XK_KP_Tab                        = 0xff89,
+    XK_KP_Enter                      = 0xff8d,  /* Enter */
+    XK_KP_F1                         = 0xff91,  /* PF1, KP_A, ... */
+    XK_KP_F2                         = 0xff92,
+    XK_KP_F3                         = 0xff93,
+    XK_KP_F4                         = 0xff94,
+    XK_KP_Home                       = 0xff95,
+    XK_KP_Left                       = 0xff96,
+    XK_KP_Up                         = 0xff97,
+    XK_KP_Right                      = 0xff98,
+    XK_KP_Down                       = 0xff99,
+    XK_KP_Prior                      = 0xff9a,
+    XK_KP_Page_Up                    = 0xff9a,
+    XK_KP_Next                       = 0xff9b,
+    XK_KP_Page_Down                  = 0xff9b,
+    XK_KP_End                        = 0xff9c,
+    XK_KP_Begin                      = 0xff9d,
+    XK_KP_Insert                     = 0xff9e,
+    XK_KP_Delete                     = 0xff9f,
+    XK_KP_Equal                      = 0xffbd,  /* Equals */
+    XK_KP_Multiply                   = 0xffaa,
+    XK_KP_Add                        = 0xffab,
+    XK_KP_Separator                  = 0xffac,  /* Separator, often comma */
+    XK_KP_Subtract                   = 0xffad,
+    XK_KP_Decimal                    = 0xffae,
+    XK_KP_Divide                     = 0xffaf,
+    XK_KP_0                          = 0xffb0,
+    XK_KP_1                          = 0xffb1,
+    XK_KP_2                          = 0xffb2,
+    XK_KP_3                          = 0xffb3,
+    XK_KP_4                          = 0xffb4,
+    XK_KP_5                          = 0xffb5,
+    XK_KP_6                          = 0xffb6,
+    XK_KP_7                          = 0xffb7,
+    XK_KP_8                          = 0xffb8,
+    XK_KP_9                          = 0xffb9,
+    XK_F1                            = 0xffbe,
+    XK_F2                            = 0xffbf,
+    XK_F3                            = 0xffc0,
+    XK_F4                            = 0xffc1,
+    XK_F5                            = 0xffc2,
+    XK_F6                            = 0xffc3,
+    XK_F7                            = 0xffc4,
+    XK_F8                            = 0xffc5,
+    XK_F9                            = 0xffc6,
+    XK_F10                           = 0xffc7,
+    XK_F11                           = 0xffc8,
+    XK_L1                            = 0xffc8,
+    XK_F12                           = 0xffc9,
+    XK_L2                            = 0xffc9,
+    XK_F13                           = 0xffca,
+    XK_L3                            = 0xffca,
+    XK_F14                           = 0xffcb,
+    XK_L4                            = 0xffcb,
+    XK_F15                           = 0xffcc,
+    XK_L5                            = 0xffcc,
+    XK_F16                           = 0xffcd,
+    XK_L6                            = 0xffcd,
+    XK_F17                           = 0xffce,
+    XK_L7                            = 0xffce,
+    XK_F18                           = 0xffcf,
+    XK_L8                            = 0xffcf,
+    XK_F19                           = 0xffd0,
+    XK_L9                            = 0xffd0,
+    XK_F20                           = 0xffd1,
+    XK_L10                           = 0xffd1,
+    XK_F21                           = 0xffd2,
+    XK_R1                            = 0xffd2,
+    XK_F22                           = 0xffd3,
+    XK_R2                            = 0xffd3,
+    XK_F23                           = 0xffd4,
+    XK_R3                            = 0xffd4,
+    XK_F24                           = 0xffd5,
+    XK_R4                            = 0xffd5,
+    XK_F25                           = 0xffd6,
+    XK_R5                            = 0xffd6,
+    XK_F26                           = 0xffd7,
+    XK_R6                            = 0xffd7,
+    XK_F27                           = 0xffd8,
+    XK_R7                            = 0xffd8,
+    XK_F28                           = 0xffd9,
+    XK_R8                            = 0xffd9,
+    XK_F29                           = 0xffda,
+    XK_R9                            = 0xffda,
+    XK_F30                           = 0xffdb,
+    XK_R10                           = 0xffdb,
+    XK_F31                           = 0xffdc,
+    XK_R11                           = 0xffdc,
+    XK_F32                           = 0xffdd,
+    XK_R12                           = 0xffdd,
+    XK_F33                           = 0xffde,
+    XK_R13                           = 0xffde,
+    XK_F34                           = 0xffdf,
+    XK_R14                           = 0xffdf,
+    XK_F35                           = 0xffe0,
+    XK_R15                           = 0xffe0,
+    XK_Shift_L                       = 0xffe1,  /* Left shift */
+    XK_Shift_R                       = 0xffe2,  /* Right shift */
+    XK_Control_L                     = 0xffe3,  /* Left control */
+    XK_Control_R                     = 0xffe4,  /* Right control */
+    XK_Caps_Lock                     = 0xffe5,  /* Caps lock */
+    XK_Shift_Lock                    = 0xffe6,  /* Shift lock */
+    XK_Meta_L                        = 0xffe7,  /* Left meta */
+    XK_Meta_R                        = 0xffe8,  /* Right meta */
+    XK_Alt_L                         = 0xffe9,  /* Left alt */
+    XK_Alt_R                         = 0xffea,  /* Right alt */
+    XK_Super_L                       = 0xffeb,  /* Left super */
+    XK_Super_R                       = 0xffec,  /* Right super */
+    XK_Hyper_L                       = 0xffed,  /* Left hyper */
+    XK_Hyper_R                       = 0xffee,  /* Right hyper */
+    XK_ISO_Lock                      = 0xfe01,
+    XK_ISO_Level2_Latch              = 0xfe02,
+    XK_ISO_Level3_Shift              = 0xfe03,
+    XK_ISO_Level3_Latch              = 0xfe04,
+    XK_ISO_Level3_Lock               = 0xfe05,
+    XK_ISO_Group_Shift               = 0xff7e,  /* Alias for mode_switch */
+    XK_ISO_Group_Latch               = 0xfe06,
+    XK_ISO_Group_Lock                = 0xfe07,
+    XK_ISO_Next_Group                = 0xfe08,
+    XK_ISO_Next_Group_Lock           = 0xfe09,
+    XK_ISO_Prev_Group                = 0xfe0a,
+    XK_ISO_Prev_Group_Lock           = 0xfe0b,
+    XK_ISO_First_Group               = 0xfe0c,
+    XK_ISO_First_Group_Lock          = 0xfe0d,
+    XK_ISO_Last_Group                = 0xfe0e,
+    XK_ISO_Last_Group_Lock           = 0xfe0f,
+    XK_ISO_Left_Tab                  = 0xfe20,
+    XK_ISO_Move_Line_Up              = 0xfe21,
+    XK_ISO_Move_Line_Down            = 0xfe22,
+    XK_ISO_Partial_Line_Up           = 0xfe23,
+    XK_ISO_Partial_Line_Down         = 0xfe24,
+    XK_ISO_Partial_Space_Left        = 0xfe25,
+    XK_ISO_Partial_Space_Right       = 0xfe26,
+    XK_ISO_Set_Margin_Left           = 0xfe27,
+    XK_ISO_Set_Margin_Right          = 0xfe28,
+    XK_ISO_Release_Margin_Left       = 0xfe29,
+    XK_ISO_Release_Margin_Right      = 0xfe2a,
+    XK_ISO_Release_Both_Margins      = 0xfe2b,
+    XK_ISO_Fast_Cursor_Left          = 0xfe2c,
+    XK_ISO_Fast_Cursor_Right         = 0xfe2d,
+    XK_ISO_Fast_Cursor_Up            = 0xfe2e,
+    XK_ISO_Fast_Cursor_Down          = 0xfe2f,
+    XK_ISO_Continuous_Underline      = 0xfe30,
+    XK_ISO_Discontinuous_Underline   = 0xfe31,
+    XK_ISO_Emphasize                 = 0xfe32,
+    XK_ISO_Center_Object             = 0xfe33,
+    XK_ISO_Enter                     = 0xfe34,
+    XK_dead_grave                    = 0xfe50,
+    XK_dead_acute                    = 0xfe51,
+    XK_dead_circumflex               = 0xfe52,
+    XK_dead_tilde                    = 0xfe53,
+    XK_dead_macron                   = 0xfe54,
+    XK_dead_breve                    = 0xfe55,
+    XK_dead_abovedot                 = 0xfe56,
+    XK_dead_diaeresis                = 0xfe57,
+    XK_dead_abovering                = 0xfe58,
+    XK_dead_doubleacute              = 0xfe59,
+    XK_dead_caron                    = 0xfe5a,
+    XK_dead_cedilla                  = 0xfe5b,
+    XK_dead_ogonek                   = 0xfe5c,
+    XK_dead_iota                     = 0xfe5d,
+    XK_dead_voiced_sound             = 0xfe5e,
+    XK_dead_semivoiced_sound         = 0xfe5f,
+    XK_dead_belowdot                 = 0xfe60,
+    XK_dead_hook                     = 0xfe61,
+    XK_dead_horn                     = 0xfe62,
+    XK_First_Virtual_Screen          = 0xfed0,
+    XK_Prev_Virtual_Screen           = 0xfed1,
+    XK_Next_Virtual_Screen           = 0xfed2,
+    XK_Last_Virtual_Screen           = 0xfed4,
+    XK_Terminate_Server              = 0xfed5,
+    XK_AccessX_Enable                = 0xfe70,
+    XK_AccessX_Feedback_Enable       = 0xfe71,
+    XK_RepeatKeys_Enable             = 0xfe72,
+    XK_SlowKeys_Enable               = 0xfe73,
+    XK_BounceKeys_Enable             = 0xfe74,
+    XK_StickyKeys_Enable             = 0xfe75,
+    XK_MouseKeys_Enable              = 0xfe76,
+    XK_MouseKeys_Accel_Enable        = 0xfe77,
+    XK_Overlay1_Enable               = 0xfe78,
+    XK_Overlay2_Enable               = 0xfe79,
+    XK_AudibleBell_Enable            = 0xfe7a,
+    XK_Pointer_Left                  = 0xfee0,
+    XK_Pointer_Right                 = 0xfee1,
+    XK_Pointer_Up                    = 0xfee2,
+    XK_Pointer_Down                  = 0xfee3,
+    XK_Pointer_UpLeft                = 0xfee4,
+    XK_Pointer_UpRight               = 0xfee5,
+    XK_Pointer_DownLeft              = 0xfee6,
+    XK_Pointer_DownRight             = 0xfee7,
+    XK_Pointer_Button_Dflt           = 0xfee8,
+    XK_Pointer_Button1               = 0xfee9,
+    XK_Pointer_Button2               = 0xfeea,
+    XK_Pointer_Button3               = 0xfeeb,
+    XK_Pointer_Button4               = 0xfeec,
+    XK_Pointer_Button5               = 0xfeed,
+    XK_Pointer_DblClick_Dflt         = 0xfeee,
+    XK_Pointer_DblClick1             = 0xfeef,
+    XK_Pointer_DblClick2             = 0xfef0,
+    XK_Pointer_DblClick3             = 0xfef1,
+    XK_Pointer_DblClick4             = 0xfef2,
+    XK_Pointer_DblClick5             = 0xfef3,
+    XK_Pointer_Drag_Dflt             = 0xfef4,
+    XK_Pointer_Drag1                 = 0xfef5,
+    XK_Pointer_Drag2                 = 0xfef6,
+    XK_Pointer_Drag3                 = 0xfef7,
+    XK_Pointer_Drag4                 = 0xfef8,
+    XK_Pointer_Drag5                 = 0xfefd,
+    XK_Pointer_EnableKeys            = 0xfef9,
+    XK_Pointer_Accelerate            = 0xfefa,
+    XK_Pointer_DfltBtnNext           = 0xfefb,
+    XK_Pointer_DfltBtnPrev           = 0xfefc,
+    XK_3270_Duplicate                = 0xfd01,
+    XK_3270_FieldMark                = 0xfd02,
+    XK_3270_Right2                   = 0xfd03,
+    XK_3270_Left2                    = 0xfd04,
+    XK_3270_BackTab                  = 0xfd05,
+    XK_3270_EraseEOF                 = 0xfd06,
+    XK_3270_EraseInput               = 0xfd07,
+    XK_3270_Reset                    = 0xfd08,
+    XK_3270_Quit                     = 0xfd09,
+    XK_3270_PA1                      = 0xfd0a,
+    XK_3270_PA2                      = 0xfd0b,
+    XK_3270_PA3                      = 0xfd0c,
+    XK_3270_Test                     = 0xfd0d,
+    XK_3270_Attn                     = 0xfd0e,
+    XK_3270_CursorBlink              = 0xfd0f,
+    XK_3270_AltCursor                = 0xfd10,
+    XK_3270_KeyClick                 = 0xfd11,
+    XK_3270_Jump                     = 0xfd12,
+    XK_3270_Ident                    = 0xfd13,
+    XK_3270_Rule                     = 0xfd14,
+    XK_3270_Copy                     = 0xfd15,
+    XK_3270_Play                     = 0xfd16,
+    XK_3270_Setup                    = 0xfd17,
+    XK_3270_Record                   = 0xfd18,
+    XK_3270_ChangeScreen             = 0xfd19,
+    XK_3270_DeleteWord               = 0xfd1a,
+    XK_3270_ExSelect                 = 0xfd1b,
+    XK_3270_CursorSelect             = 0xfd1c,
+    XK_3270_PrintScreen              = 0xfd1d,
+    XK_3270_Enter                    = 0xfd1e,
+    XK_space                         = 0x0020,  /* U+0020 SPACE */
+    XK_exclam                        = 0x0021,  /* U+0021 EXCLAMATION MARK */
+    XK_quotedbl                      = 0x0022,  /* U+0022 QUOTATION MARK */
+    XK_numbersign                    = 0x0023,  /* U+0023 NUMBER SIGN */
+    XK_dollar                        = 0x0024,  /* U+0024 DOLLAR SIGN */
+    XK_percent                       = 0x0025,  /* U+0025 PERCENT SIGN */
+    XK_ampersand                     = 0x0026,  /* U+0026 AMPERSAND */
+    XK_apostrophe                    = 0x0027,  /* U+0027 APOSTROPHE */
+    XK_quoteright                    = 0x0027,  /* deprecated */
+    XK_parenleft                     = 0x0028,  /* U+0028 LEFT PARENTHESIS */
+    XK_parenright                    = 0x0029,  /* U+0029 RIGHT PARENTHESIS */
+    XK_asterisk                      = 0x002a,  /* U+002A ASTERISK */
+    XK_plus                          = 0x002b,  /* U+002B PLUS SIGN */
+    XK_comma                         = 0x002c,  /* U+002C COMMA */
+    XK_minus                         = 0x002d,  /* U+002D HYPHEN-MINUS */
+    XK_period                        = 0x002e,  /* U+002E FULL STOP */
+    XK_slash                         = 0x002f,  /* U+002F SOLIDUS */
+    XK_0                             = 0x0030,  /* U+0030 DIGIT ZERO */
+    XK_1                             = 0x0031,  /* U+0031 DIGIT ONE */
+    XK_2                             = 0x0032,  /* U+0032 DIGIT TWO */
+    XK_3                             = 0x0033,  /* U+0033 DIGIT THREE */
+    XK_4                             = 0x0034,  /* U+0034 DIGIT FOUR */
+    XK_5                             = 0x0035,  /* U+0035 DIGIT FIVE */
+    XK_6                             = 0x0036,  /* U+0036 DIGIT SIX */
+    XK_7                             = 0x0037,  /* U+0037 DIGIT SEVEN */
+    XK_8                             = 0x0038,  /* U+0038 DIGIT EIGHT */
+    XK_9                             = 0x0039,  /* U+0039 DIGIT NINE */
+    XK_colon                         = 0x003a,  /* U+003A COLON */
+    XK_semicolon                     = 0x003b,  /* U+003B SEMICOLON */
+    XK_less                          = 0x003c,  /* U+003C LESS-THAN SIGN */
+    XK_equal                         = 0x003d,  /* U+003D EQUALS SIGN */
+    XK_greater                       = 0x003e,  /* U+003E GREATER-THAN SIGN */
+    XK_question                      = 0x003f,  /* U+003F QUESTION MARK */
+    XK_at                            = 0x0040,  /* U+0040 COMMERCIAL AT */
+    XK_A                             = 0x0041,  /* U+0041 LATIN CAPITAL LETTER A */
+    XK_B                             = 0x0042,  /* U+0042 LATIN CAPITAL LETTER B */
+    XK_C                             = 0x0043,  /* U+0043 LATIN CAPITAL LETTER C */
+    XK_D                             = 0x0044,  /* U+0044 LATIN CAPITAL LETTER D */
+    XK_E                             = 0x0045,  /* U+0045 LATIN CAPITAL LETTER E */
+    XK_F                             = 0x0046,  /* U+0046 LATIN CAPITAL LETTER F */
+    XK_G                             = 0x0047,  /* U+0047 LATIN CAPITAL LETTER G */
+    XK_H                             = 0x0048,  /* U+0048 LATIN CAPITAL LETTER H */
+    XK_I                             = 0x0049,  /* U+0049 LATIN CAPITAL LETTER I */
+    XK_J                             = 0x004a,  /* U+004A LATIN CAPITAL LETTER J */
+    XK_K                             = 0x004b,  /* U+004B LATIN CAPITAL LETTER K */
+    XK_L                             = 0x004c,  /* U+004C LATIN CAPITAL LETTER L */
+    XK_M                             = 0x004d,  /* U+004D LATIN CAPITAL LETTER M */
+    XK_N                             = 0x004e,  /* U+004E LATIN CAPITAL LETTER N */
+    XK_O                             = 0x004f,  /* U+004F LATIN CAPITAL LETTER O */
+    XK_P                             = 0x0050,  /* U+0050 LATIN CAPITAL LETTER P */
+    XK_Q                             = 0x0051,  /* U+0051 LATIN CAPITAL LETTER Q */
+    XK_R                             = 0x0052,  /* U+0052 LATIN CAPITAL LETTER R */
+    XK_S                             = 0x0053,  /* U+0053 LATIN CAPITAL LETTER S */
+    XK_T                             = 0x0054,  /* U+0054 LATIN CAPITAL LETTER T */
+    XK_U                             = 0x0055,  /* U+0055 LATIN CAPITAL LETTER U */
+    XK_V                             = 0x0056,  /* U+0056 LATIN CAPITAL LETTER V */
+    XK_W                             = 0x0057,  /* U+0057 LATIN CAPITAL LETTER W */
+    XK_X                             = 0x0058,  /* U+0058 LATIN CAPITAL LETTER X */
+    XK_Y                             = 0x0059,  /* U+0059 LATIN CAPITAL LETTER Y */
+    XK_Z                             = 0x005a,  /* U+005A LATIN CAPITAL LETTER Z */
+    XK_bracketleft                   = 0x005b,  /* U+005B LEFT SQUARE BRACKET */
+    XK_backslash                     = 0x005c,  /* U+005C REVERSE SOLIDUS */
+    XK_bracketright                  = 0x005d,  /* U+005D RIGHT SQUARE BRACKET */
+    XK_asciicircum                   = 0x005e,  /* U+005E CIRCUMFLEX ACCENT */
+    XK_underscore                    = 0x005f,  /* U+005F LOW LINE */
+    XK_grave                         = 0x0060,  /* U+0060 GRAVE ACCENT */
+    XK_quoteleft                     = 0x0060,  /* deprecated */
+    XK_a                             = 0x0061,  /* U+0061 LATIN SMALL LETTER A */
+    XK_b                             = 0x0062,  /* U+0062 LATIN SMALL LETTER B */
+    XK_c                             = 0x0063,  /* U+0063 LATIN SMALL LETTER C */
+    XK_d                             = 0x0064,  /* U+0064 LATIN SMALL LETTER D */
+    XK_e                             = 0x0065,  /* U+0065 LATIN SMALL LETTER E */
+    XK_f                             = 0x0066,  /* U+0066 LATIN SMALL LETTER F */
+    XK_g                             = 0x0067,  /* U+0067 LATIN SMALL LETTER G */
+    XK_h                             = 0x0068,  /* U+0068 LATIN SMALL LETTER H */
+    XK_i                             = 0x0069,  /* U+0069 LATIN SMALL LETTER I */
+    XK_j                             = 0x006a,  /* U+006A LATIN SMALL LETTER J */
+    XK_k                             = 0x006b,  /* U+006B LATIN SMALL LETTER K */
+    XK_l                             = 0x006c,  /* U+006C LATIN SMALL LETTER L */
+    XK_m                             = 0x006d,  /* U+006D LATIN SMALL LETTER M */
+    XK_n                             = 0x006e,  /* U+006E LATIN SMALL LETTER N */
+    XK_o                             = 0x006f,  /* U+006F LATIN SMALL LETTER O */
+    XK_p                             = 0x0070,  /* U+0070 LATIN SMALL LETTER P */
+    XK_q                             = 0x0071,  /* U+0071 LATIN SMALL LETTER Q */
+    XK_r                             = 0x0072,  /* U+0072 LATIN SMALL LETTER R */
+    XK_s                             = 0x0073,  /* U+0073 LATIN SMALL LETTER S */
+    XK_t                             = 0x0074,  /* U+0074 LATIN SMALL LETTER T */
+    XK_u                             = 0x0075,  /* U+0075 LATIN SMALL LETTER U */
+    XK_v                             = 0x0076,  /* U+0076 LATIN SMALL LETTER V */
+    XK_w                             = 0x0077,  /* U+0077 LATIN SMALL LETTER W */
+    XK_x                             = 0x0078,  /* U+0078 LATIN SMALL LETTER X */
+    XK_y                             = 0x0079,  /* U+0079 LATIN SMALL LETTER Y */
+    XK_z                             = 0x007a,  /* U+007A LATIN SMALL LETTER Z */
+    XK_braceleft                     = 0x007b,  /* U+007B LEFT CURLY BRACKET */
+    XK_bar                           = 0x007c,  /* U+007C VERTICAL LINE */
+    XK_braceright                    = 0x007d,  /* U+007D RIGHT CURLY BRACKET */
+    XK_asciitilde                    = 0x007e,  /* U+007E TILDE */
+    XK_nobreakspace                  = 0x00a0,  /* U+00A0 NO-BREAK SPACE */
+    XK_exclamdown                    = 0x00a1,  /* U+00A1 INVERTED EXCLAMATION MARK */
+    XK_cent                          = 0x00a2,  /* U+00A2 CENT SIGN */
+    XK_sterling                      = 0x00a3,  /* U+00A3 POUND SIGN */
+    XK_currency                      = 0x00a4,  /* U+00A4 CURRENCY SIGN */
+    XK_yen                           = 0x00a5,  /* U+00A5 YEN SIGN */
+    XK_brokenbar                     = 0x00a6,  /* U+00A6 BROKEN BAR */
+    XK_section                       = 0x00a7,  /* U+00A7 SECTION SIGN */
+    XK_diaeresis                     = 0x00a8,  /* U+00A8 DIAERESIS */
+    XK_copyright                     = 0x00a9,  /* U+00A9 COPYRIGHT SIGN */
+    XK_ordfeminine                   = 0x00aa,  /* U+00AA FEMININE ORDINAL INDICATOR */
+    XK_guillemotleft                 = 0x00ab,  /* U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */
+    XK_notsign                       = 0x00ac,  /* U+00AC NOT SIGN */
+    XK_hyphen                        = 0x00ad,  /* U+00AD SOFT HYPHEN */
+    XK_registered                    = 0x00ae,  /* U+00AE REGISTERED SIGN */
+    XK_macron                        = 0x00af,  /* U+00AF MACRON */
+    XK_degree                        = 0x00b0,  /* U+00B0 DEGREE SIGN */
+    XK_plusminus                     = 0x00b1,  /* U+00B1 PLUS-MINUS SIGN */
+    XK_twosuperior                   = 0x00b2,  /* U+00B2 SUPERSCRIPT TWO */
+    XK_threesuperior                 = 0x00b3,  /* U+00B3 SUPERSCRIPT THREE */
+    XK_acute                         = 0x00b4,  /* U+00B4 ACUTE ACCENT */
+    XK_mu                            = 0x00b5,  /* U+00B5 MICRO SIGN */
+    XK_paragraph                     = 0x00b6,  /* U+00B6 PILCROW SIGN */
+    XK_periodcentered                = 0x00b7,  /* U+00B7 MIDDLE DOT */
+    XK_cedilla                       = 0x00b8,  /* U+00B8 CEDILLA */
+    XK_onesuperior                   = 0x00b9,  /* U+00B9 SUPERSCRIPT ONE */
+    XK_masculine                     = 0x00ba,  /* U+00BA MASCULINE ORDINAL INDICATOR */
+    XK_guillemotright                = 0x00bb,  /* U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */
+    XK_onequarter                    = 0x00bc,  /* U+00BC VULGAR FRACTION ONE QUARTER */
+    XK_onehalf                       = 0x00bd,  /* U+00BD VULGAR FRACTION ONE HALF */
+    XK_threequarters                 = 0x00be,  /* U+00BE VULGAR FRACTION THREE QUARTERS */
+    XK_questiondown                  = 0x00bf,  /* U+00BF INVERTED QUESTION MARK */
+    XK_Agrave                        = 0x00c0,  /* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE */
+    XK_Aacute                        = 0x00c1,  /* U+00C1 LATIN CAPITAL LETTER A WITH ACUTE */
+    XK_Acircumflex                   = 0x00c2,  /* U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
+    XK_Atilde                        = 0x00c3,  /* U+00C3 LATIN CAPITAL LETTER A WITH TILDE */
+    XK_Adiaeresis                    = 0x00c4,  /* U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS */
+    XK_Aring                         = 0x00c5,  /* U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE */
+    XK_AE                            = 0x00c6,  /* U+00C6 LATIN CAPITAL LETTER AE */
+    XK_Ccedilla                      = 0x00c7,  /* U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA */
+    XK_Egrave                        = 0x00c8,  /* U+00C8 LATIN CAPITAL LETTER E WITH GRAVE */
+    XK_Eacute                        = 0x00c9,  /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */
+    XK_Ecircumflex                   = 0x00ca,  /* U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
+    XK_Ediaeresis                    = 0x00cb,  /* U+00CB LATIN CAPITAL LETTER E WITH DIAERESIS */
+    XK_Igrave                        = 0x00cc,  /* U+00CC LATIN CAPITAL LETTER I WITH GRAVE */
+    XK_Iacute                        = 0x00cd,  /* U+00CD LATIN CAPITAL LETTER I WITH ACUTE */
+    XK_Icircumflex                   = 0x00ce,  /* U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
+    XK_Idiaeresis                    = 0x00cf,  /* U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS */
+    XK_ETH                           = 0x00d0,  /* U+00D0 LATIN CAPITAL LETTER ETH */
+    XK_Eth                           = 0x00d0,  /* deprecated */
+    XK_Ntilde                        = 0x00d1,  /* U+00D1 LATIN CAPITAL LETTER N WITH TILDE */
+    XK_Ograve                        = 0x00d2,  /* U+00D2 LATIN CAPITAL LETTER O WITH GRAVE */
+    XK_Oacute                        = 0x00d3,  /* U+00D3 LATIN CAPITAL LETTER O WITH ACUTE */
+    XK_Ocircumflex                   = 0x00d4,  /* U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
+    XK_Otilde                        = 0x00d5,  /* U+00D5 LATIN CAPITAL LETTER O WITH TILDE */
+    XK_Odiaeresis                    = 0x00d6,  /* U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS */
+    XK_multiply                      = 0x00d7,  /* U+00D7 MULTIPLICATION SIGN */
+    XK_Oslash                        = 0x00d8,  /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */
+    XK_Ooblique                      = 0x00d8,  /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */
+    XK_Ugrave                        = 0x00d9,  /* U+00D9 LATIN CAPITAL LETTER U WITH GRAVE */
+    XK_Uacute                        = 0x00da,  /* U+00DA LATIN CAPITAL LETTER U WITH ACUTE */
+    XK_Ucircumflex                   = 0x00db,  /* U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
+    XK_Udiaeresis                    = 0x00dc,  /* U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS */
+    XK_Yacute                        = 0x00dd,  /* U+00DD LATIN CAPITAL LETTER Y WITH ACUTE */
+    XK_THORN                         = 0x00de,  /* U+00DE LATIN CAPITAL LETTER THORN */
+    XK_Thorn                         = 0x00de,  /* deprecated */
+    XK_ssharp                        = 0x00df,  /* U+00DF LATIN SMALL LETTER SHARP S */
+    XK_agrave                        = 0x00e0,  /* U+00E0 LATIN SMALL LETTER A WITH GRAVE */
+    XK_aacute                        = 0x00e1,  /* U+00E1 LATIN SMALL LETTER A WITH ACUTE */
+    XK_acircumflex                   = 0x00e2,  /* U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX */
+    XK_atilde                        = 0x00e3,  /* U+00E3 LATIN SMALL LETTER A WITH TILDE */
+    XK_adiaeresis                    = 0x00e4,  /* U+00E4 LATIN SMALL LETTER A WITH DIAERESIS */
+    XK_aring                         = 0x00e5,  /* U+00E5 LATIN SMALL LETTER A WITH RING ABOVE */
+    XK_ae                            = 0x00e6,  /* U+00E6 LATIN SMALL LETTER AE */
+    XK_ccedilla                      = 0x00e7,  /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */
+    XK_egrave                        = 0x00e8,  /* U+00E8 LATIN SMALL LETTER E WITH GRAVE */
+    XK_eacute                        = 0x00e9,  /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */
+    XK_ecircumflex                   = 0x00ea,  /* U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX */
+    XK_ediaeresis                    = 0x00eb,  /* U+00EB LATIN SMALL LETTER E WITH DIAERESIS */
+    XK_igrave                        = 0x00ec,  /* U+00EC LATIN SMALL LETTER I WITH GRAVE */
+    XK_iacute                        = 0x00ed,  /* U+00ED LATIN SMALL LETTER I WITH ACUTE */
+    XK_icircumflex                   = 0x00ee,  /* U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX */
+    XK_idiaeresis                    = 0x00ef,  /* U+00EF LATIN SMALL LETTER I WITH DIAERESIS */
+    XK_eth                           = 0x00f0,  /* U+00F0 LATIN SMALL LETTER ETH */
+    XK_ntilde                        = 0x00f1,  /* U+00F1 LATIN SMALL LETTER N WITH TILDE */
+    XK_ograve                        = 0x00f2,  /* U+00F2 LATIN SMALL LETTER O WITH GRAVE */
+    XK_oacute                        = 0x00f3,  /* U+00F3 LATIN SMALL LETTER O WITH ACUTE */
+    XK_ocircumflex                   = 0x00f4,  /* U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX */
+    XK_otilde                        = 0x00f5,  /* U+00F5 LATIN SMALL LETTER O WITH TILDE */
+    XK_odiaeresis                    = 0x00f6,  /* U+00F6 LATIN SMALL LETTER O WITH DIAERESIS */
+    XK_division                      = 0x00f7,  /* U+00F7 DIVISION SIGN */
+    XK_oslash                        = 0x00f8,  /* U+00F8 LATIN SMALL LETTER O WITH STROKE */
+    XK_ooblique                      = 0x00f8,  /* U+00F8 LATIN SMALL LETTER O WITH STROKE */
+    XK_ugrave                        = 0x00f9,  /* U+00F9 LATIN SMALL LETTER U WITH GRAVE */
+    XK_uacute                        = 0x00fa,  /* U+00FA LATIN SMALL LETTER U WITH ACUTE */
+    XK_ucircumflex                   = 0x00fb,  /* U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX */
+    XK_udiaeresis                    = 0x00fc,  /* U+00FC LATIN SMALL LETTER U WITH DIAERESIS */
+    XK_yacute                        = 0x00fd,  /* U+00FD LATIN SMALL LETTER Y WITH ACUTE */
+    XK_thorn                         = 0x00fe,  /* U+00FE LATIN SMALL LETTER THORN */
+    XK_ydiaeresis                    = 0x00ff,  /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */
+    XK_Aogonek                       = 0x01a1,  /* U+0104 LATIN CAPITAL LETTER A WITH OGONEK */
+    XK_breve                         = 0x01a2,  /* U+02D8 BREVE */
+    XK_Lstroke                       = 0x01a3,  /* U+0141 LATIN CAPITAL LETTER L WITH STROKE */
+    XK_Lcaron                        = 0x01a5,  /* U+013D LATIN CAPITAL LETTER L WITH CARON */
+    XK_Sacute                        = 0x01a6,  /* U+015A LATIN CAPITAL LETTER S WITH ACUTE */
+    XK_Scaron                        = 0x01a9,  /* U+0160 LATIN CAPITAL LETTER S WITH CARON */
+    XK_Scedilla                      = 0x01aa,  /* U+015E LATIN CAPITAL LETTER S WITH CEDILLA */
+    XK_Tcaron                        = 0x01ab,  /* U+0164 LATIN CAPITAL LETTER T WITH CARON */
+    XK_Zacute                        = 0x01ac,  /* U+0179 LATIN CAPITAL LETTER Z WITH ACUTE */
+    XK_Zcaron                        = 0x01ae,  /* U+017D LATIN CAPITAL LETTER Z WITH CARON */
+    XK_Zabovedot                     = 0x01af,  /* U+017B LATIN CAPITAL LETTER Z WITH DOT ABOVE */
+    XK_aogonek                       = 0x01b1,  /* U+0105 LATIN SMALL LETTER A WITH OGONEK */
+    XK_ogonek                        = 0x01b2,  /* U+02DB OGONEK */
+    XK_lstroke                       = 0x01b3,  /* U+0142 LATIN SMALL LETTER L WITH STROKE */
+    XK_lcaron                        = 0x01b5,  /* U+013E LATIN SMALL LETTER L WITH CARON */
+    XK_sacute                        = 0x01b6,  /* U+015B LATIN SMALL LETTER S WITH ACUTE */
+    XK_caron                         = 0x01b7,  /* U+02C7 CARON */
+    XK_scaron                        = 0x01b9,  /* U+0161 LATIN SMALL LETTER S WITH CARON */
+    XK_scedilla                      = 0x01ba,  /* U+015F LATIN SMALL LETTER S WITH CEDILLA */
+    XK_tcaron                        = 0x01bb,  /* U+0165 LATIN SMALL LETTER T WITH CARON */
+    XK_zacute                        = 0x01bc,  /* U+017A LATIN SMALL LETTER Z WITH ACUTE */
+    XK_doubleacute                   = 0x01bd,  /* U+02DD DOUBLE ACUTE ACCENT */
+    XK_zcaron                        = 0x01be,  /* U+017E LATIN SMALL LETTER Z WITH CARON */
+    XK_zabovedot                     = 0x01bf,  /* U+017C LATIN SMALL LETTER Z WITH DOT ABOVE */
+    XK_Racute                        = 0x01c0,  /* U+0154 LATIN CAPITAL LETTER R WITH ACUTE */
+    XK_Abreve                        = 0x01c3,  /* U+0102 LATIN CAPITAL LETTER A WITH BREVE */
+    XK_Lacute                        = 0x01c5,  /* U+0139 LATIN CAPITAL LETTER L WITH ACUTE */
+    XK_Cacute                        = 0x01c6,  /* U+0106 LATIN CAPITAL LETTER C WITH ACUTE */
+    XK_Ccaron                        = 0x01c8,  /* U+010C LATIN CAPITAL LETTER C WITH CARON */
+    XK_Eogonek                       = 0x01ca,  /* U+0118 LATIN CAPITAL LETTER E WITH OGONEK */
+    XK_Ecaron                        = 0x01cc,  /* U+011A LATIN CAPITAL LETTER E WITH CARON */
+    XK_Dcaron                        = 0x01cf,  /* U+010E LATIN CAPITAL LETTER D WITH CARON */
+    XK_Dstroke                       = 0x01d0,  /* U+0110 LATIN CAPITAL LETTER D WITH STROKE */
+    XK_Nacute                        = 0x01d1,  /* U+0143 LATIN CAPITAL LETTER N WITH ACUTE */
+    XK_Ncaron                        = 0x01d2,  /* U+0147 LATIN CAPITAL LETTER N WITH CARON */
+    XK_Odoubleacute                  = 0x01d5,  /* U+0150 LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */
+    XK_Rcaron                        = 0x01d8,  /* U+0158 LATIN CAPITAL LETTER R WITH CARON */
+    XK_Uring                         = 0x01d9,  /* U+016E LATIN CAPITAL LETTER U WITH RING ABOVE */
+    XK_Udoubleacute                  = 0x01db,  /* U+0170 LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */
+    XK_Tcedilla                      = 0x01de,  /* U+0162 LATIN CAPITAL LETTER T WITH CEDILLA */
+    XK_racute                        = 0x01e0,  /* U+0155 LATIN SMALL LETTER R WITH ACUTE */
+    XK_abreve                        = 0x01e3,  /* U+0103 LATIN SMALL LETTER A WITH BREVE */
+    XK_lacute                        = 0x01e5,  /* U+013A LATIN SMALL LETTER L WITH ACUTE */
+    XK_cacute                        = 0x01e6,  /* U+0107 LATIN SMALL LETTER C WITH ACUTE */
+    XK_ccaron                        = 0x01e8,  /* U+010D LATIN SMALL LETTER C WITH CARON */
+    XK_eogonek                       = 0x01ea,  /* U+0119 LATIN SMALL LETTER E WITH OGONEK */
+    XK_ecaron                        = 0x01ec,  /* U+011B LATIN SMALL LETTER E WITH CARON */
+    XK_dcaron                        = 0x01ef,  /* U+010F LATIN SMALL LETTER D WITH CARON */
+    XK_dstroke                       = 0x01f0,  /* U+0111 LATIN SMALL LETTER D WITH STROKE */
+    XK_nacute                        = 0x01f1,  /* U+0144 LATIN SMALL LETTER N WITH ACUTE */
+    XK_ncaron                        = 0x01f2,  /* U+0148 LATIN SMALL LETTER N WITH CARON */
+    XK_odoubleacute                  = 0x01f5,  /* U+0151 LATIN SMALL LETTER O WITH DOUBLE ACUTE */
+    XK_udoubleacute                  = 0x01fb,  /* U+0171 LATIN SMALL LETTER U WITH DOUBLE ACUTE */
+    XK_rcaron                        = 0x01f8,  /* U+0159 LATIN SMALL LETTER R WITH CARON */
+    XK_uring                         = 0x01f9,  /* U+016F LATIN SMALL LETTER U WITH RING ABOVE */
+    XK_tcedilla                      = 0x01fe,  /* U+0163 LATIN SMALL LETTER T WITH CEDILLA */
+    XK_abovedot                      = 0x01ff,  /* U+02D9 DOT ABOVE */
+    XK_Hstroke                       = 0x02a1,  /* U+0126 LATIN CAPITAL LETTER H WITH STROKE */
+    XK_Hcircumflex                   = 0x02a6,  /* U+0124 LATIN CAPITAL LETTER H WITH CIRCUMFLEX */
+    XK_Iabovedot                     = 0x02a9,  /* U+0130 LATIN CAPITAL LETTER I WITH DOT ABOVE */
+    XK_Gbreve                        = 0x02ab,  /* U+011E LATIN CAPITAL LETTER G WITH BREVE */
+    XK_Jcircumflex                   = 0x02ac,  /* U+0134 LATIN CAPITAL LETTER J WITH CIRCUMFLEX */
+    XK_hstroke                       = 0x02b1,  /* U+0127 LATIN SMALL LETTER H WITH STROKE */
+    XK_hcircumflex                   = 0x02b6,  /* U+0125 LATIN SMALL LETTER H WITH CIRCUMFLEX */
+    XK_idotless                      = 0x02b9,  /* U+0131 LATIN SMALL LETTER DOTLESS I */
+    XK_gbreve                        = 0x02bb,  /* U+011F LATIN SMALL LETTER G WITH BREVE */
+    XK_jcircumflex                   = 0x02bc,  /* U+0135 LATIN SMALL LETTER J WITH CIRCUMFLEX */
+    XK_Cabovedot                     = 0x02c5,  /* U+010A LATIN CAPITAL LETTER C WITH DOT ABOVE */
+    XK_Ccircumflex                   = 0x02c6,  /* U+0108 LATIN CAPITAL LETTER C WITH CIRCUMFLEX */
+    XK_Gabovedot                     = 0x02d5,  /* U+0120 LATIN CAPITAL LETTER G WITH DOT ABOVE */
+    XK_Gcircumflex                   = 0x02d8,  /* U+011C LATIN CAPITAL LETTER G WITH CIRCUMFLEX */
+    XK_Ubreve                        = 0x02dd,  /* U+016C LATIN CAPITAL LETTER U WITH BREVE */
+    XK_Scircumflex                   = 0x02de,  /* U+015C LATIN CAPITAL LETTER S WITH CIRCUMFLEX */
+    XK_cabovedot                     = 0x02e5,  /* U+010B LATIN SMALL LETTER C WITH DOT ABOVE */
+    XK_ccircumflex                   = 0x02e6,  /* U+0109 LATIN SMALL LETTER C WITH CIRCUMFLEX */
+    XK_gabovedot                     = 0x02f5,  /* U+0121 LATIN SMALL LETTER G WITH DOT ABOVE */
+    XK_gcircumflex                   = 0x02f8,  /* U+011D LATIN SMALL LETTER G WITH CIRCUMFLEX */
+    XK_ubreve                        = 0x02fd,  /* U+016D LATIN SMALL LETTER U WITH BREVE */
+    XK_scircumflex                   = 0x02fe,  /* U+015D LATIN SMALL LETTER S WITH CIRCUMFLEX */
+    XK_kra                           = 0x03a2,  /* U+0138 LATIN SMALL LETTER KRA */
+    XK_kappa                         = 0x03a2,  /* deprecated */
+    XK_Rcedilla                      = 0x03a3,  /* U+0156 LATIN CAPITAL LETTER R WITH CEDILLA */
+    XK_Itilde                        = 0x03a5,  /* U+0128 LATIN CAPITAL LETTER I WITH TILDE */
+    XK_Lcedilla                      = 0x03a6,  /* U+013B LATIN CAPITAL LETTER L WITH CEDILLA */
+    XK_Emacron                       = 0x03aa,  /* U+0112 LATIN CAPITAL LETTER E WITH MACRON */
+    XK_Gcedilla                      = 0x03ab,  /* U+0122 LATIN CAPITAL LETTER G WITH CEDILLA */
+    XK_Tslash                        = 0x03ac,  /* U+0166 LATIN CAPITAL LETTER T WITH STROKE */
+    XK_rcedilla                      = 0x03b3,  /* U+0157 LATIN SMALL LETTER R WITH CEDILLA */
+    XK_itilde                        = 0x03b5,  /* U+0129 LATIN SMALL LETTER I WITH TILDE */
+    XK_lcedilla                      = 0x03b6,  /* U+013C LATIN SMALL LETTER L WITH CEDILLA */
+    XK_emacron                       = 0x03ba,  /* U+0113 LATIN SMALL LETTER E WITH MACRON */
+    XK_gcedilla                      = 0x03bb,  /* U+0123 LATIN SMALL LETTER G WITH CEDILLA */
+    XK_tslash                        = 0x03bc,  /* U+0167 LATIN SMALL LETTER T WITH STROKE */
+    XK_ENG                           = 0x03bd,  /* U+014A LATIN CAPITAL LETTER ENG */
+    XK_eng                           = 0x03bf,  /* U+014B LATIN SMALL LETTER ENG */
+    XK_Amacron                       = 0x03c0,  /* U+0100 LATIN CAPITAL LETTER A WITH MACRON */
+    XK_Iogonek                       = 0x03c7,  /* U+012E LATIN CAPITAL LETTER I WITH OGONEK */
+    XK_Eabovedot                     = 0x03cc,  /* U+0116 LATIN CAPITAL LETTER E WITH DOT ABOVE */
+    XK_Imacron                       = 0x03cf,  /* U+012A LATIN CAPITAL LETTER I WITH MACRON */
+    XK_Ncedilla                      = 0x03d1,  /* U+0145 LATIN CAPITAL LETTER N WITH CEDILLA */
+    XK_Omacron                       = 0x03d2,  /* U+014C LATIN CAPITAL LETTER O WITH MACRON */
+    XK_Kcedilla                      = 0x03d3,  /* U+0136 LATIN CAPITAL LETTER K WITH CEDILLA */
+    XK_Uogonek                       = 0x03d9,  /* U+0172 LATIN CAPITAL LETTER U WITH OGONEK */
+    XK_Utilde                        = 0x03dd,  /* U+0168 LATIN CAPITAL LETTER U WITH TILDE */
+    XK_Umacron                       = 0x03de,  /* U+016A LATIN CAPITAL LETTER U WITH MACRON */
+    XK_amacron                       = 0x03e0,  /* U+0101 LATIN SMALL LETTER A WITH MACRON */
+    XK_iogonek                       = 0x03e7,  /* U+012F LATIN SMALL LETTER I WITH OGONEK */
+    XK_eabovedot                     = 0x03ec,  /* U+0117 LATIN SMALL LETTER E WITH DOT ABOVE */
+    XK_imacron                       = 0x03ef,  /* U+012B LATIN SMALL LETTER I WITH MACRON */
+    XK_ncedilla                      = 0x03f1,  /* U+0146 LATIN SMALL LETTER N WITH CEDILLA */
+    XK_omacron                       = 0x03f2,  /* U+014D LATIN SMALL LETTER O WITH MACRON */
+    XK_kcedilla                      = 0x03f3,  /* U+0137 LATIN SMALL LETTER K WITH CEDILLA */
+    XK_uogonek                       = 0x03f9,  /* U+0173 LATIN SMALL LETTER U WITH OGONEK */
+    XK_utilde                        = 0x03fd,  /* U+0169 LATIN SMALL LETTER U WITH TILDE */
+    XK_umacron                       = 0x03fe,  /* U+016B LATIN SMALL LETTER U WITH MACRON */
+    XK_Babovedot                  = 0x1001e02,  /* U+1E02 LATIN CAPITAL LETTER B WITH DOT ABOVE */
+    XK_babovedot                  = 0x1001e03,  /* U+1E03 LATIN SMALL LETTER B WITH DOT ABOVE */
+    XK_Dabovedot                  = 0x1001e0a,  /* U+1E0A LATIN CAPITAL LETTER D WITH DOT ABOVE */
+    XK_Wgrave                     = 0x1001e80,  /* U+1E80 LATIN CAPITAL LETTER W WITH GRAVE */
+    XK_Wacute                     = 0x1001e82,  /* U+1E82 LATIN CAPITAL LETTER W WITH ACUTE */
+    XK_dabovedot                  = 0x1001e0b,  /* U+1E0B LATIN SMALL LETTER D WITH DOT ABOVE */
+    XK_Ygrave                     = 0x1001ef2,  /* U+1EF2 LATIN CAPITAL LETTER Y WITH GRAVE */
+    XK_Fabovedot                  = 0x1001e1e,  /* U+1E1E LATIN CAPITAL LETTER F WITH DOT ABOVE */
+    XK_fabovedot                  = 0x1001e1f,  /* U+1E1F LATIN SMALL LETTER F WITH DOT ABOVE */
+    XK_Mabovedot                  = 0x1001e40,  /* U+1E40 LATIN CAPITAL LETTER M WITH DOT ABOVE */
+    XK_mabovedot                  = 0x1001e41,  /* U+1E41 LATIN SMALL LETTER M WITH DOT ABOVE */
+    XK_Pabovedot                  = 0x1001e56,  /* U+1E56 LATIN CAPITAL LETTER P WITH DOT ABOVE */
+    XK_wgrave                     = 0x1001e81,  /* U+1E81 LATIN SMALL LETTER W WITH GRAVE */
+    XK_pabovedot                  = 0x1001e57,  /* U+1E57 LATIN SMALL LETTER P WITH DOT ABOVE */
+    XK_wacute                     = 0x1001e83,  /* U+1E83 LATIN SMALL LETTER W WITH ACUTE */
+    XK_Sabovedot                  = 0x1001e60,  /* U+1E60 LATIN CAPITAL LETTER S WITH DOT ABOVE */
+    XK_ygrave                     = 0x1001ef3,  /* U+1EF3 LATIN SMALL LETTER Y WITH GRAVE */
+    XK_Wdiaeresis                 = 0x1001e84,  /* U+1E84 LATIN CAPITAL LETTER W WITH DIAERESIS */
+    XK_wdiaeresis                 = 0x1001e85,  /* U+1E85 LATIN SMALL LETTER W WITH DIAERESIS */
+    XK_sabovedot                  = 0x1001e61,  /* U+1E61 LATIN SMALL LETTER S WITH DOT ABOVE */
+    XK_Wcircumflex                = 0x1000174,  /* U+0174 LATIN CAPITAL LETTER W WITH CIRCUMFLEX */
+    XK_Tabovedot                  = 0x1001e6a,  /* U+1E6A LATIN CAPITAL LETTER T WITH DOT ABOVE */
+    XK_Ycircumflex                = 0x1000176,  /* U+0176 LATIN CAPITAL LETTER Y WITH CIRCUMFLEX */
+    XK_wcircumflex                = 0x1000175,  /* U+0175 LATIN SMALL LETTER W WITH CIRCUMFLEX */
+    XK_tabovedot                  = 0x1001e6b,  /* U+1E6B LATIN SMALL LETTER T WITH DOT ABOVE */
+    XK_ycircumflex                = 0x1000177,  /* U+0177 LATIN SMALL LETTER Y WITH CIRCUMFLEX */
+    XK_OE                            = 0x13bc,  /* U+0152 LATIN CAPITAL LIGATURE OE */
+    XK_oe                            = 0x13bd,  /* U+0153 LATIN SMALL LIGATURE OE */
+    XK_Ydiaeresis                    = 0x13be,  /* U+0178 LATIN CAPITAL LETTER Y WITH DIAERESIS */
+    XK_overline                      = 0x047e,  /* U+203E OVERLINE */
+    XK_kana_fullstop                 = 0x04a1,  /* U+3002 IDEOGRAPHIC FULL STOP */
+    XK_kana_openingbracket           = 0x04a2,  /* U+300C LEFT CORNER BRACKET */
+    XK_kana_closingbracket           = 0x04a3,  /* U+300D RIGHT CORNER BRACKET */
+    XK_kana_comma                    = 0x04a4,  /* U+3001 IDEOGRAPHIC COMMA */
+    XK_kana_conjunctive              = 0x04a5,  /* U+30FB KATAKANA MIDDLE DOT */
+    XK_kana_middledot                = 0x04a5,  /* deprecated */
+    XK_kana_WO                       = 0x04a6,  /* U+30F2 KATAKANA LETTER WO */
+    XK_kana_a                        = 0x04a7,  /* U+30A1 KATAKANA LETTER SMALL A */
+    XK_kana_i                        = 0x04a8,  /* U+30A3 KATAKANA LETTER SMALL I */
+    XK_kana_u                        = 0x04a9,  /* U+30A5 KATAKANA LETTER SMALL U */
+    XK_kana_e                        = 0x04aa,  /* U+30A7 KATAKANA LETTER SMALL E */
+    XK_kana_o                        = 0x04ab,  /* U+30A9 KATAKANA LETTER SMALL O */
+    XK_kana_ya                       = 0x04ac,  /* U+30E3 KATAKANA LETTER SMALL YA */
+    XK_kana_yu                       = 0x04ad,  /* U+30E5 KATAKANA LETTER SMALL YU */
+    XK_kana_yo                       = 0x04ae,  /* U+30E7 KATAKANA LETTER SMALL YO */
+    XK_kana_tsu                      = 0x04af,  /* U+30C3 KATAKANA LETTER SMALL TU */
+    XK_kana_tu                       = 0x04af,  /* deprecated */
+    XK_prolongedsound                = 0x04b0,  /* U+30FC KATAKANA-HIRAGANA PROLONGED SOUND MARK */
+    XK_kana_A                        = 0x04b1,  /* U+30A2 KATAKANA LETTER A */
+    XK_kana_I                        = 0x04b2,  /* U+30A4 KATAKANA LETTER I */
+    XK_kana_U                        = 0x04b3,  /* U+30A6 KATAKANA LETTER U */
+    XK_kana_E                        = 0x04b4,  /* U+30A8 KATAKANA LETTER E */
+    XK_kana_O                        = 0x04b5,  /* U+30AA KATAKANA LETTER O */
+    XK_kana_KA                       = 0x04b6,  /* U+30AB KATAKANA LETTER KA */
+    XK_kana_KI                       = 0x04b7,  /* U+30AD KATAKANA LETTER KI */
+    XK_kana_KU                       = 0x04b8,  /* U+30AF KATAKANA LETTER KU */
+    XK_kana_KE                       = 0x04b9,  /* U+30B1 KATAKANA LETTER KE */
+    XK_kana_KO                       = 0x04ba,  /* U+30B3 KATAKANA LETTER KO */
+    XK_kana_SA                       = 0x04bb,  /* U+30B5 KATAKANA LETTER SA */
+    XK_kana_SHI                      = 0x04bc,  /* U+30B7 KATAKANA LETTER SI */
+    XK_kana_SU                       = 0x04bd,  /* U+30B9 KATAKANA LETTER SU */
+    XK_kana_SE                       = 0x04be,  /* U+30BB KATAKANA LETTER SE */
+    XK_kana_SO                       = 0x04bf,  /* U+30BD KATAKANA LETTER SO */
+    XK_kana_TA                       = 0x04c0,  /* U+30BF KATAKANA LETTER TA */
+    XK_kana_CHI                      = 0x04c1,  /* U+30C1 KATAKANA LETTER TI */
+    XK_kana_TI                       = 0x04c1,  /* deprecated */
+    XK_kana_TSU                      = 0x04c2,  /* U+30C4 KATAKANA LETTER TU */
+    XK_kana_TU                       = 0x04c2,  /* deprecated */
+    XK_kana_TE                       = 0x04c3,  /* U+30C6 KATAKANA LETTER TE */
+    XK_kana_TO                       = 0x04c4,  /* U+30C8 KATAKANA LETTER TO */
+    XK_kana_NA                       = 0x04c5,  /* U+30CA KATAKANA LETTER NA */
+    XK_kana_NI                       = 0x04c6,  /* U+30CB KATAKANA LETTER NI */
+    XK_kana_NU                       = 0x04c7,  /* U+30CC KATAKANA LETTER NU */
+    XK_kana_NE                       = 0x04c8,  /* U+30CD KATAKANA LETTER NE */
+    XK_kana_NO                       = 0x04c9,  /* U+30CE KATAKANA LETTER NO */
+    XK_kana_HA                       = 0x04ca,  /* U+30CF KATAKANA LETTER HA */
+    XK_kana_HI                       = 0x04cb,  /* U+30D2 KATAKANA LETTER HI */
+    XK_kana_FU                       = 0x04cc,  /* U+30D5 KATAKANA LETTER HU */
+    XK_kana_HU                       = 0x04cc,  /* deprecated */
+    XK_kana_HE                       = 0x04cd,  /* U+30D8 KATAKANA LETTER HE */
+    XK_kana_HO                       = 0x04ce,  /* U+30DB KATAKANA LETTER HO */
+    XK_kana_MA                       = 0x04cf,  /* U+30DE KATAKANA LETTER MA */
+    XK_kana_MI                       = 0x04d0,  /* U+30DF KATAKANA LETTER MI */
+    XK_kana_MU                       = 0x04d1,  /* U+30E0 KATAKANA LETTER MU */
+    XK_kana_ME                       = 0x04d2,  /* U+30E1 KATAKANA LETTER ME */
+    XK_kana_MO                       = 0x04d3,  /* U+30E2 KATAKANA LETTER MO */
+    XK_kana_YA                       = 0x04d4,  /* U+30E4 KATAKANA LETTER YA */
+    XK_kana_YU                       = 0x04d5,  /* U+30E6 KATAKANA LETTER YU */
+    XK_kana_YO                       = 0x04d6,  /* U+30E8 KATAKANA LETTER YO */
+    XK_kana_RA                       = 0x04d7,  /* U+30E9 KATAKANA LETTER RA */
+    XK_kana_RI                       = 0x04d8,  /* U+30EA KATAKANA LETTER RI */
+    XK_kana_RU                       = 0x04d9,  /* U+30EB KATAKANA LETTER RU */
+    XK_kana_RE                       = 0x04da,  /* U+30EC KATAKANA LETTER RE */
+    XK_kana_RO                       = 0x04db,  /* U+30ED KATAKANA LETTER RO */
+    XK_kana_WA                       = 0x04dc,  /* U+30EF KATAKANA LETTER WA */
+    XK_kana_N                        = 0x04dd,  /* U+30F3 KATAKANA LETTER N */
+    XK_voicedsound                   = 0x04de,  /* U+309B KATAKANA-HIRAGANA VOICED SOUND MARK */
+    XK_semivoicedsound               = 0x04df,  /* U+309C KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */
+    XK_kana_switch                   = 0xff7e,  /* Alias for mode_switch */
+    XK_Farsi_0                    = 0x10006f0,  /* U+06F0 EXTENDED ARABIC-INDIC DIGIT ZERO */
+    XK_Farsi_1                    = 0x10006f1,  /* U+06F1 EXTENDED ARABIC-INDIC DIGIT ONE */
+    XK_Farsi_2                    = 0x10006f2,  /* U+06F2 EXTENDED ARABIC-INDIC DIGIT TWO */
+    XK_Farsi_3                    = 0x10006f3,  /* U+06F3 EXTENDED ARABIC-INDIC DIGIT THREE */
+    XK_Farsi_4                    = 0x10006f4,  /* U+06F4 EXTENDED ARABIC-INDIC DIGIT FOUR */
+    XK_Farsi_5                    = 0x10006f5,  /* U+06F5 EXTENDED ARABIC-INDIC DIGIT FIVE */
+    XK_Farsi_6                    = 0x10006f6,  /* U+06F6 EXTENDED ARABIC-INDIC DIGIT SIX */
+    XK_Farsi_7                    = 0x10006f7,  /* U+06F7 EXTENDED ARABIC-INDIC DIGIT SEVEN */
+    XK_Farsi_8                    = 0x10006f8,  /* U+06F8 EXTENDED ARABIC-INDIC DIGIT EIGHT */
+    XK_Farsi_9                    = 0x10006f9,  /* U+06F9 EXTENDED ARABIC-INDIC DIGIT NINE */
+    XK_Arabic_percent             = 0x100066a,  /* U+066A ARABIC PERCENT SIGN */
+    XK_Arabic_superscript_alef    = 0x1000670,  /* U+0670 ARABIC LETTER SUPERSCRIPT ALEF */
+    XK_Arabic_tteh                = 0x1000679,  /* U+0679 ARABIC LETTER TTEH */
+    XK_Arabic_peh                 = 0x100067e,  /* U+067E ARABIC LETTER PEH */
+    XK_Arabic_tcheh               = 0x1000686,  /* U+0686 ARABIC LETTER TCHEH */
+    XK_Arabic_ddal                = 0x1000688,  /* U+0688 ARABIC LETTER DDAL */
+    XK_Arabic_rreh                = 0x1000691,  /* U+0691 ARABIC LETTER RREH */
+    XK_Arabic_comma                  = 0x05ac,  /* U+060C ARABIC COMMA */
+    XK_Arabic_fullstop            = 0x10006d4,  /* U+06D4 ARABIC FULL STOP */
+    XK_Arabic_0                   = 0x1000660,  /* U+0660 ARABIC-INDIC DIGIT ZERO */
+    XK_Arabic_1                   = 0x1000661,  /* U+0661 ARABIC-INDIC DIGIT ONE */
+    XK_Arabic_2                   = 0x1000662,  /* U+0662 ARABIC-INDIC DIGIT TWO */
+    XK_Arabic_3                   = 0x1000663,  /* U+0663 ARABIC-INDIC DIGIT THREE */
+    XK_Arabic_4                   = 0x1000664,  /* U+0664 ARABIC-INDIC DIGIT FOUR */
+    XK_Arabic_5                   = 0x1000665,  /* U+0665 ARABIC-INDIC DIGIT FIVE */
+    XK_Arabic_6                   = 0x1000666,  /* U+0666 ARABIC-INDIC DIGIT SIX */
+    XK_Arabic_7                   = 0x1000667,  /* U+0667 ARABIC-INDIC DIGIT SEVEN */
+    XK_Arabic_8                   = 0x1000668,  /* U+0668 ARABIC-INDIC DIGIT EIGHT */
+    XK_Arabic_9                   = 0x1000669,  /* U+0669 ARABIC-INDIC DIGIT NINE */
+    XK_Arabic_semicolon              = 0x05bb,  /* U+061B ARABIC SEMICOLON */
+    XK_Arabic_question_mark          = 0x05bf,  /* U+061F ARABIC QUESTION MARK */
+    XK_Arabic_hamza                  = 0x05c1,  /* U+0621 ARABIC LETTER HAMZA */
+    XK_Arabic_maddaonalef            = 0x05c2,  /* U+0622 ARABIC LETTER ALEF WITH MADDA ABOVE */
+    XK_Arabic_hamzaonalef            = 0x05c3,  /* U+0623 ARABIC LETTER ALEF WITH HAMZA ABOVE */
+    XK_Arabic_hamzaonwaw             = 0x05c4,  /* U+0624 ARABIC LETTER WAW WITH HAMZA ABOVE */
+    XK_Arabic_hamzaunderalef         = 0x05c5,  /* U+0625 ARABIC LETTER ALEF WITH HAMZA BELOW */
+    XK_Arabic_hamzaonyeh             = 0x05c6,  /* U+0626 ARABIC LETTER YEH WITH HAMZA ABOVE */
+    XK_Arabic_alef                   = 0x05c7,  /* U+0627 ARABIC LETTER ALEF */
+    XK_Arabic_beh                    = 0x05c8,  /* U+0628 ARABIC LETTER BEH */
+    XK_Arabic_tehmarbuta             = 0x05c9,  /* U+0629 ARABIC LETTER TEH MARBUTA */
+    XK_Arabic_teh                    = 0x05ca,  /* U+062A ARABIC LETTER TEH */
+    XK_Arabic_theh                   = 0x05cb,  /* U+062B ARABIC LETTER THEH */
+    XK_Arabic_jeem                   = 0x05cc,  /* U+062C ARABIC LETTER JEEM */
+    XK_Arabic_hah                    = 0x05cd,  /* U+062D ARABIC LETTER HAH */
+    XK_Arabic_khah                   = 0x05ce,  /* U+062E ARABIC LETTER KHAH */
+    XK_Arabic_dal                    = 0x05cf,  /* U+062F ARABIC LETTER DAL */
+    XK_Arabic_thal                   = 0x05d0,  /* U+0630 ARABIC LETTER THAL */
+    XK_Arabic_ra                     = 0x05d1,  /* U+0631 ARABIC LETTER REH */
+    XK_Arabic_zain                   = 0x05d2,  /* U+0632 ARABIC LETTER ZAIN */
+    XK_Arabic_seen                   = 0x05d3,  /* U+0633 ARABIC LETTER SEEN */
+    XK_Arabic_sheen                  = 0x05d4,  /* U+0634 ARABIC LETTER SHEEN */
+    XK_Arabic_sad                    = 0x05d5,  /* U+0635 ARABIC LETTER SAD */
+    XK_Arabic_dad                    = 0x05d6,  /* U+0636 ARABIC LETTER DAD */
+    XK_Arabic_tah                    = 0x05d7,  /* U+0637 ARABIC LETTER TAH */
+    XK_Arabic_zah                    = 0x05d8,  /* U+0638 ARABIC LETTER ZAH */
+    XK_Arabic_ain                    = 0x05d9,  /* U+0639 ARABIC LETTER AIN */
+    XK_Arabic_ghain                  = 0x05da,  /* U+063A ARABIC LETTER GHAIN */
+    XK_Arabic_tatweel                = 0x05e0,  /* U+0640 ARABIC TATWEEL */
+    XK_Arabic_feh                    = 0x05e1,  /* U+0641 ARABIC LETTER FEH */
+    XK_Arabic_qaf                    = 0x05e2,  /* U+0642 ARABIC LETTER QAF */
+    XK_Arabic_kaf                    = 0x05e3,  /* U+0643 ARABIC LETTER KAF */
+    XK_Arabic_lam                    = 0x05e4,  /* U+0644 ARABIC LETTER LAM */
+    XK_Arabic_meem                   = 0x05e5,  /* U+0645 ARABIC LETTER MEEM */
+    XK_Arabic_noon                   = 0x05e6,  /* U+0646 ARABIC LETTER NOON */
+    XK_Arabic_ha                     = 0x05e7,  /* U+0647 ARABIC LETTER HEH */
+    XK_Arabic_heh                    = 0x05e7,  /* deprecated */
+    XK_Arabic_waw                    = 0x05e8,  /* U+0648 ARABIC LETTER WAW */
+    XK_Arabic_alefmaksura            = 0x05e9,  /* U+0649 ARABIC LETTER ALEF MAKSURA */
+    XK_Arabic_yeh                    = 0x05ea,  /* U+064A ARABIC LETTER YEH */
+    XK_Arabic_fathatan               = 0x05eb,  /* U+064B ARABIC FATHATAN */
+    XK_Arabic_dammatan               = 0x05ec,  /* U+064C ARABIC DAMMATAN */
+    XK_Arabic_kasratan               = 0x05ed,  /* U+064D ARABIC KASRATAN */
+    XK_Arabic_fatha                  = 0x05ee,  /* U+064E ARABIC FATHA */
+    XK_Arabic_damma                  = 0x05ef,  /* U+064F ARABIC DAMMA */
+    XK_Arabic_kasra                  = 0x05f0,  /* U+0650 ARABIC KASRA */
+    XK_Arabic_shadda                 = 0x05f1,  /* U+0651 ARABIC SHADDA */
+    XK_Arabic_sukun                  = 0x05f2,  /* U+0652 ARABIC SUKUN */
+    XK_Arabic_madda_above         = 0x1000653,  /* U+0653 ARABIC MADDAH ABOVE */
+    XK_Arabic_hamza_above         = 0x1000654,  /* U+0654 ARABIC HAMZA ABOVE */
+    XK_Arabic_hamza_below         = 0x1000655,  /* U+0655 ARABIC HAMZA BELOW */
+    XK_Arabic_jeh                 = 0x1000698,  /* U+0698 ARABIC LETTER JEH */
+    XK_Arabic_veh                 = 0x10006a4,  /* U+06A4 ARABIC LETTER VEH */
+    XK_Arabic_keheh               = 0x10006a9,  /* U+06A9 ARABIC LETTER KEHEH */
+    XK_Arabic_gaf                 = 0x10006af,  /* U+06AF ARABIC LETTER GAF */
+    XK_Arabic_noon_ghunna         = 0x10006ba,  /* U+06BA ARABIC LETTER NOON GHUNNA */
+    XK_Arabic_heh_doachashmee     = 0x10006be,  /* U+06BE ARABIC LETTER HEH DOACHASHMEE */
+    XK_Farsi_yeh                  = 0x10006cc,  /* U+06CC ARABIC LETTER FARSI YEH */
+    XK_Arabic_farsi_yeh           = 0x10006cc,  /* U+06CC ARABIC LETTER FARSI YEH */
+    XK_Arabic_yeh_baree           = 0x10006d2,  /* U+06D2 ARABIC LETTER YEH BARREE */
+    XK_Arabic_heh_goal            = 0x10006c1,  /* U+06C1 ARABIC LETTER HEH GOAL */
+    XK_Arabic_switch                 = 0xff7e,  /* Alias for mode_switch */
+    XK_Cyrillic_GHE_bar           = 0x1000492,  /* U+0492 CYRILLIC CAPITAL LETTER GHE WITH STROKE */
+    XK_Cyrillic_ghe_bar           = 0x1000493,  /* U+0493 CYRILLIC SMALL LETTER GHE WITH STROKE */
+    XK_Cyrillic_ZHE_descender     = 0x1000496,  /* U+0496 CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER */
+    XK_Cyrillic_zhe_descender     = 0x1000497,  /* U+0497 CYRILLIC SMALL LETTER ZHE WITH DESCENDER */
+    XK_Cyrillic_KA_descender      = 0x100049a,  /* U+049A CYRILLIC CAPITAL LETTER KA WITH DESCENDER */
+    XK_Cyrillic_ka_descender      = 0x100049b,  /* U+049B CYRILLIC SMALL LETTER KA WITH DESCENDER */
+    XK_Cyrillic_KA_vertstroke     = 0x100049c,  /* U+049C CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE */
+    XK_Cyrillic_ka_vertstroke     = 0x100049d,  /* U+049D CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE */
+    XK_Cyrillic_EN_descender      = 0x10004a2,  /* U+04A2 CYRILLIC CAPITAL LETTER EN WITH DESCENDER */
+    XK_Cyrillic_en_descender      = 0x10004a3,  /* U+04A3 CYRILLIC SMALL LETTER EN WITH DESCENDER */
+    XK_Cyrillic_U_straight        = 0x10004ae,  /* U+04AE CYRILLIC CAPITAL LETTER STRAIGHT U */
+    XK_Cyrillic_u_straight        = 0x10004af,  /* U+04AF CYRILLIC SMALL LETTER STRAIGHT U */
+    XK_Cyrillic_U_straight_bar    = 0x10004b0,  /* U+04B0 CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE */
+    XK_Cyrillic_u_straight_bar    = 0x10004b1,  /* U+04B1 CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE */
+    XK_Cyrillic_HA_descender      = 0x10004b2,  /* U+04B2 CYRILLIC CAPITAL LETTER HA WITH DESCENDER */
+    XK_Cyrillic_ha_descender      = 0x10004b3,  /* U+04B3 CYRILLIC SMALL LETTER HA WITH DESCENDER */
+    XK_Cyrillic_CHE_descender     = 0x10004b6,  /* U+04B6 CYRILLIC CAPITAL LETTER CHE WITH DESCENDER */
+    XK_Cyrillic_che_descender     = 0x10004b7,  /* U+04B7 CYRILLIC SMALL LETTER CHE WITH DESCENDER */
+    XK_Cyrillic_CHE_vertstroke    = 0x10004b8,  /* U+04B8 CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE */
+    XK_Cyrillic_che_vertstroke    = 0x10004b9,  /* U+04B9 CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE */
+    XK_Cyrillic_SHHA              = 0x10004ba,  /* U+04BA CYRILLIC CAPITAL LETTER SHHA */
+    XK_Cyrillic_shha              = 0x10004bb,  /* U+04BB CYRILLIC SMALL LETTER SHHA */
+    XK_Cyrillic_SCHWA             = 0x10004d8,  /* U+04D8 CYRILLIC CAPITAL LETTER SCHWA */
+    XK_Cyrillic_schwa             = 0x10004d9,  /* U+04D9 CYRILLIC SMALL LETTER SCHWA */
+    XK_Cyrillic_I_macron          = 0x10004e2,  /* U+04E2 CYRILLIC CAPITAL LETTER I WITH MACRON */
+    XK_Cyrillic_i_macron          = 0x10004e3,  /* U+04E3 CYRILLIC SMALL LETTER I WITH MACRON */
+    XK_Cyrillic_O_bar             = 0x10004e8,  /* U+04E8 CYRILLIC CAPITAL LETTER BARRED O */
+    XK_Cyrillic_o_bar             = 0x10004e9,  /* U+04E9 CYRILLIC SMALL LETTER BARRED O */
+    XK_Cyrillic_U_macron          = 0x10004ee,  /* U+04EE CYRILLIC CAPITAL LETTER U WITH MACRON */
+    XK_Cyrillic_u_macron          = 0x10004ef,  /* U+04EF CYRILLIC SMALL LETTER U WITH MACRON */
+    XK_Serbian_dje                   = 0x06a1,  /* U+0452 CYRILLIC SMALL LETTER DJE */
+    XK_Macedonia_gje                 = 0x06a2,  /* U+0453 CYRILLIC SMALL LETTER GJE */
+    XK_Cyrillic_io                   = 0x06a3,  /* U+0451 CYRILLIC SMALL LETTER IO */
+    XK_Ukrainian_ie                  = 0x06a4,  /* U+0454 CYRILLIC SMALL LETTER UKRAINIAN IE */
+    XK_Ukranian_je                   = 0x06a4,  /* deprecated */
+    XK_Macedonia_dse                 = 0x06a5,  /* U+0455 CYRILLIC SMALL LETTER DZE */
+    XK_Ukrainian_i                   = 0x06a6,  /* U+0456 CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */
+    XK_Ukranian_i                    = 0x06a6,  /* deprecated */
+    XK_Ukrainian_yi                  = 0x06a7,  /* U+0457 CYRILLIC SMALL LETTER YI */
+    XK_Ukranian_yi                   = 0x06a7,  /* deprecated */
+    XK_Cyrillic_je                   = 0x06a8,  /* U+0458 CYRILLIC SMALL LETTER JE */
+    XK_Serbian_je                    = 0x06a8,  /* deprecated */
+    XK_Cyrillic_lje                  = 0x06a9,  /* U+0459 CYRILLIC SMALL LETTER LJE */
+    XK_Serbian_lje                   = 0x06a9,  /* deprecated */
+    XK_Cyrillic_nje                  = 0x06aa,  /* U+045A CYRILLIC SMALL LETTER NJE */
+    XK_Serbian_nje                   = 0x06aa,  /* deprecated */
+    XK_Serbian_tshe                  = 0x06ab,  /* U+045B CYRILLIC SMALL LETTER TSHE */
+    XK_Macedonia_kje                 = 0x06ac,  /* U+045C CYRILLIC SMALL LETTER KJE */
+    XK_Ukrainian_ghe_with_upturn     = 0x06ad,  /* U+0491 CYRILLIC SMALL LETTER GHE WITH UPTURN */
+    XK_Byelorussian_shortu           = 0x06ae,  /* U+045E CYRILLIC SMALL LETTER SHORT U */
+    XK_Cyrillic_dzhe                 = 0x06af,  /* U+045F CYRILLIC SMALL LETTER DZHE */
+    XK_Serbian_dze                   = 0x06af,  /* deprecated */
+    XK_numerosign                    = 0x06b0,  /* U+2116 NUMERO SIGN */
+    XK_Serbian_DJE                   = 0x06b1,  /* U+0402 CYRILLIC CAPITAL LETTER DJE */
+    XK_Macedonia_GJE                 = 0x06b2,  /* U+0403 CYRILLIC CAPITAL LETTER GJE */
+    XK_Cyrillic_IO                   = 0x06b3,  /* U+0401 CYRILLIC CAPITAL LETTER IO */
+    XK_Ukrainian_IE                  = 0x06b4,  /* U+0404 CYRILLIC CAPITAL LETTER UKRAINIAN IE */
+    XK_Ukranian_JE                   = 0x06b4,  /* deprecated */
+    XK_Macedonia_DSE                 = 0x06b5,  /* U+0405 CYRILLIC CAPITAL LETTER DZE */
+    XK_Ukrainian_I                   = 0x06b6,  /* U+0406 CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */
+    XK_Ukranian_I                    = 0x06b6,  /* deprecated */
+    XK_Ukrainian_YI                  = 0x06b7,  /* U+0407 CYRILLIC CAPITAL LETTER YI */
+    XK_Ukranian_YI                   = 0x06b7,  /* deprecated */
+    XK_Cyrillic_JE                   = 0x06b8,  /* U+0408 CYRILLIC CAPITAL LETTER JE */
+    XK_Serbian_JE                    = 0x06b8,  /* deprecated */
+    XK_Cyrillic_LJE                  = 0x06b9,  /* U+0409 CYRILLIC CAPITAL LETTER LJE */
+    XK_Serbian_LJE                   = 0x06b9,  /* deprecated */
+    XK_Cyrillic_NJE                  = 0x06ba,  /* U+040A CYRILLIC CAPITAL LETTER NJE */
+    XK_Serbian_NJE                   = 0x06ba,  /* deprecated */
+    XK_Serbian_TSHE                  = 0x06bb,  /* U+040B CYRILLIC CAPITAL LETTER TSHE */
+    XK_Macedonia_KJE                 = 0x06bc,  /* U+040C CYRILLIC CAPITAL LETTER KJE */
+    XK_Ukrainian_GHE_WITH_UPTURN     = 0x06bd,  /* U+0490 CYRILLIC CAPITAL LETTER GHE WITH UPTURN */
+    XK_Byelorussian_SHORTU           = 0x06be,  /* U+040E CYRILLIC CAPITAL LETTER SHORT U */
+    XK_Cyrillic_DZHE                 = 0x06bf,  /* U+040F CYRILLIC CAPITAL LETTER DZHE */
+    XK_Serbian_DZE                   = 0x06bf,  /* deprecated */
+    XK_Cyrillic_yu                   = 0x06c0,  /* U+044E CYRILLIC SMALL LETTER YU */
+    XK_Cyrillic_a                    = 0x06c1,  /* U+0430 CYRILLIC SMALL LETTER A */
+    XK_Cyrillic_be                   = 0x06c2,  /* U+0431 CYRILLIC SMALL LETTER BE */
+    XK_Cyrillic_tse                  = 0x06c3,  /* U+0446 CYRILLIC SMALL LETTER TSE */
+    XK_Cyrillic_de                   = 0x06c4,  /* U+0434 CYRILLIC SMALL LETTER DE */
+    XK_Cyrillic_ie                   = 0x06c5,  /* U+0435 CYRILLIC SMALL LETTER IE */
+    XK_Cyrillic_ef                   = 0x06c6,  /* U+0444 CYRILLIC SMALL LETTER EF */
+    XK_Cyrillic_ghe                  = 0x06c7,  /* U+0433 CYRILLIC SMALL LETTER GHE */
+    XK_Cyrillic_ha                   = 0x06c8,  /* U+0445 CYRILLIC SMALL LETTER HA */
+    XK_Cyrillic_i                    = 0x06c9,  /* U+0438 CYRILLIC SMALL LETTER I */
+    XK_Cyrillic_shorti               = 0x06ca,  /* U+0439 CYRILLIC SMALL LETTER SHORT I */
+    XK_Cyrillic_ka                   = 0x06cb,  /* U+043A CYRILLIC SMALL LETTER KA */
+    XK_Cyrillic_el                   = 0x06cc,  /* U+043B CYRILLIC SMALL LETTER EL */
+    XK_Cyrillic_em                   = 0x06cd,  /* U+043C CYRILLIC SMALL LETTER EM */
+    XK_Cyrillic_en                   = 0x06ce,  /* U+043D CYRILLIC SMALL LETTER EN */
+    XK_Cyrillic_o                    = 0x06cf,  /* U+043E CYRILLIC SMALL LETTER O */
+    XK_Cyrillic_pe                   = 0x06d0,  /* U+043F CYRILLIC SMALL LETTER PE */
+    XK_Cyrillic_ya                   = 0x06d1,  /* U+044F CYRILLIC SMALL LETTER YA */
+    XK_Cyrillic_er                   = 0x06d2,  /* U+0440 CYRILLIC SMALL LETTER ER */
+    XK_Cyrillic_es                   = 0x06d3,  /* U+0441 CYRILLIC SMALL LETTER ES */
+    XK_Cyrillic_te                   = 0x06d4,  /* U+0442 CYRILLIC SMALL LETTER TE */
+    XK_Cyrillic_u                    = 0x06d5,  /* U+0443 CYRILLIC SMALL LETTER U */
+    XK_Cyrillic_zhe                  = 0x06d6,  /* U+0436 CYRILLIC SMALL LETTER ZHE */
+    XK_Cyrillic_ve                   = 0x06d7,  /* U+0432 CYRILLIC SMALL LETTER VE */
+    XK_Cyrillic_softsign             = 0x06d8,  /* U+044C CYRILLIC SMALL LETTER SOFT SIGN */
+    XK_Cyrillic_yeru                 = 0x06d9,  /* U+044B CYRILLIC SMALL LETTER YERU */
+    XK_Cyrillic_ze                   = 0x06da,  /* U+0437 CYRILLIC SMALL LETTER ZE */
+    XK_Cyrillic_sha                  = 0x06db,  /* U+0448 CYRILLIC SMALL LETTER SHA */
+    XK_Cyrillic_e                    = 0x06dc,  /* U+044D CYRILLIC SMALL LETTER E */
+    XK_Cyrillic_shcha                = 0x06dd,  /* U+0449 CYRILLIC SMALL LETTER SHCHA */
+    XK_Cyrillic_che                  = 0x06de,  /* U+0447 CYRILLIC SMALL LETTER CHE */
+    XK_Cyrillic_hardsign             = 0x06df,  /* U+044A CYRILLIC SMALL LETTER HARD SIGN */
+    XK_Cyrillic_YU                   = 0x06e0,  /* U+042E CYRILLIC CAPITAL LETTER YU */
+    XK_Cyrillic_A                    = 0x06e1,  /* U+0410 CYRILLIC CAPITAL LETTER A */
+    XK_Cyrillic_BE                   = 0x06e2,  /* U+0411 CYRILLIC CAPITAL LETTER BE */
+    XK_Cyrillic_TSE                  = 0x06e3,  /* U+0426 CYRILLIC CAPITAL LETTER TSE */
+    XK_Cyrillic_DE                   = 0x06e4,  /* U+0414 CYRILLIC CAPITAL LETTER DE */
+    XK_Cyrillic_IE                   = 0x06e5,  /* U+0415 CYRILLIC CAPITAL LETTER IE */
+    XK_Cyrillic_EF                   = 0x06e6,  /* U+0424 CYRILLIC CAPITAL LETTER EF */
+    XK_Cyrillic_GHE                  = 0x06e7,  /* U+0413 CYRILLIC CAPITAL LETTER GHE */
+    XK_Cyrillic_HA                   = 0x06e8,  /* U+0425 CYRILLIC CAPITAL LETTER HA */
+    XK_Cyrillic_I                    = 0x06e9,  /* U+0418 CYRILLIC CAPITAL LETTER I */
+    XK_Cyrillic_SHORTI               = 0x06ea,  /* U+0419 CYRILLIC CAPITAL LETTER SHORT I */
+    XK_Cyrillic_KA                   = 0x06eb,  /* U+041A CYRILLIC CAPITAL LETTER KA */
+    XK_Cyrillic_EL                   = 0x06ec,  /* U+041B CYRILLIC CAPITAL LETTER EL */
+    XK_Cyrillic_EM                   = 0x06ed,  /* U+041C CYRILLIC CAPITAL LETTER EM */
+    XK_Cyrillic_EN                   = 0x06ee,  /* U+041D CYRILLIC CAPITAL LETTER EN */
+    XK_Cyrillic_O                    = 0x06ef,  /* U+041E CYRILLIC CAPITAL LETTER O */
+    XK_Cyrillic_PE                   = 0x06f0,  /* U+041F CYRILLIC CAPITAL LETTER PE */
+    XK_Cyrillic_YA                   = 0x06f1,  /* U+042F CYRILLIC CAPITAL LETTER YA */
+    XK_Cyrillic_ER                   = 0x06f2,  /* U+0420 CYRILLIC CAPITAL LETTER ER */
+    XK_Cyrillic_ES                   = 0x06f3,  /* U+0421 CYRILLIC CAPITAL LETTER ES */
+    XK_Cyrillic_TE                   = 0x06f4,  /* U+0422 CYRILLIC CAPITAL LETTER TE */
+    XK_Cyrillic_U                    = 0x06f5,  /* U+0423 CYRILLIC CAPITAL LETTER U */
+    XK_Cyrillic_ZHE                  = 0x06f6,  /* U+0416 CYRILLIC CAPITAL LETTER ZHE */
+    XK_Cyrillic_VE                   = 0x06f7,  /* U+0412 CYRILLIC CAPITAL LETTER VE */
+    XK_Cyrillic_SOFTSIGN             = 0x06f8,  /* U+042C CYRILLIC CAPITAL LETTER SOFT SIGN */
+    XK_Cyrillic_YERU                 = 0x06f9,  /* U+042B CYRILLIC CAPITAL LETTER YERU */
+    XK_Cyrillic_ZE                   = 0x06fa,  /* U+0417 CYRILLIC CAPITAL LETTER ZE */
+    XK_Cyrillic_SHA                  = 0x06fb,  /* U+0428 CYRILLIC CAPITAL LETTER SHA */
+    XK_Cyrillic_E                    = 0x06fc,  /* U+042D CYRILLIC CAPITAL LETTER E */
+    XK_Cyrillic_SHCHA                = 0x06fd,  /* U+0429 CYRILLIC CAPITAL LETTER SHCHA */
+    XK_Cyrillic_CHE                  = 0x06fe,  /* U+0427 CYRILLIC CAPITAL LETTER CHE */
+    XK_Cyrillic_HARDSIGN             = 0x06ff,  /* U+042A CYRILLIC CAPITAL LETTER HARD SIGN */
+    XK_Greek_ALPHAaccent             = 0x07a1,  /* U+0386 GREEK CAPITAL LETTER ALPHA WITH TONOS */
+    XK_Greek_EPSILONaccent           = 0x07a2,  /* U+0388 GREEK CAPITAL LETTER EPSILON WITH TONOS */
+    XK_Greek_ETAaccent               = 0x07a3,  /* U+0389 GREEK CAPITAL LETTER ETA WITH TONOS */
+    XK_Greek_IOTAaccent              = 0x07a4,  /* U+038A GREEK CAPITAL LETTER IOTA WITH TONOS */
+    XK_Greek_IOTAdieresis            = 0x07a5,  /* U+03AA GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
+    XK_Greek_IOTAdiaeresis           = 0x07a5,  /* old typo */
+    XK_Greek_OMICRONaccent           = 0x07a7,  /* U+038C GREEK CAPITAL LETTER OMICRON WITH TONOS */
+    XK_Greek_UPSILONaccent           = 0x07a8,  /* U+038E GREEK CAPITAL LETTER UPSILON WITH TONOS */
+    XK_Greek_UPSILONdieresis         = 0x07a9,  /* U+03AB GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */
+    XK_Greek_OMEGAaccent             = 0x07ab,  /* U+038F GREEK CAPITAL LETTER OMEGA WITH TONOS */
+    XK_Greek_accentdieresis          = 0x07ae,  /* U+0385 GREEK DIALYTIKA TONOS */
+    XK_Greek_horizbar                = 0x07af,  /* U+2015 HORIZONTAL BAR */
+    XK_Greek_alphaaccent             = 0x07b1,  /* U+03AC GREEK SMALL LETTER ALPHA WITH TONOS */
+    XK_Greek_epsilonaccent           = 0x07b2,  /* U+03AD GREEK SMALL LETTER EPSILON WITH TONOS */
+    XK_Greek_etaaccent               = 0x07b3,  /* U+03AE GREEK SMALL LETTER ETA WITH TONOS */
+    XK_Greek_iotaaccent              = 0x07b4,  /* U+03AF GREEK SMALL LETTER IOTA WITH TONOS */
+    XK_Greek_iotadieresis            = 0x07b5,  /* U+03CA GREEK SMALL LETTER IOTA WITH DIALYTIKA */
+    XK_Greek_iotaaccentdieresis      = 0x07b6,  /* U+0390 GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */
+    XK_Greek_omicronaccent           = 0x07b7,  /* U+03CC GREEK SMALL LETTER OMICRON WITH TONOS */
+    XK_Greek_upsilonaccent           = 0x07b8,  /* U+03CD GREEK SMALL LETTER UPSILON WITH TONOS */
+    XK_Greek_upsilondieresis         = 0x07b9,  /* U+03CB GREEK SMALL LETTER UPSILON WITH DIALYTIKA */
+    XK_Greek_upsilonaccentdieresis   = 0x07ba,  /* U+03B0 GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */
+    XK_Greek_omegaaccent             = 0x07bb,  /* U+03CE GREEK SMALL LETTER OMEGA WITH TONOS */
+    XK_Greek_ALPHA                   = 0x07c1,  /* U+0391 GREEK CAPITAL LETTER ALPHA */
+    XK_Greek_BETA                    = 0x07c2,  /* U+0392 GREEK CAPITAL LETTER BETA */
+    XK_Greek_GAMMA                   = 0x07c3,  /* U+0393 GREEK CAPITAL LETTER GAMMA */
+    XK_Greek_DELTA                   = 0x07c4,  /* U+0394 GREEK CAPITAL LETTER DELTA */
+    XK_Greek_EPSILON                 = 0x07c5,  /* U+0395 GREEK CAPITAL LETTER EPSILON */
+    XK_Greek_ZETA                    = 0x07c6,  /* U+0396 GREEK CAPITAL LETTER ZETA */
+    XK_Greek_ETA                     = 0x07c7,  /* U+0397 GREEK CAPITAL LETTER ETA */
+    XK_Greek_THETA                   = 0x07c8,  /* U+0398 GREEK CAPITAL LETTER THETA */
+    XK_Greek_IOTA                    = 0x07c9,  /* U+0399 GREEK CAPITAL LETTER IOTA */
+    XK_Greek_KAPPA                   = 0x07ca,  /* U+039A GREEK CAPITAL LETTER KAPPA */
+    XK_Greek_LAMDA                   = 0x07cb,  /* U+039B GREEK CAPITAL LETTER LAMDA */
+    XK_Greek_LAMBDA                  = 0x07cb,  /* U+039B GREEK CAPITAL LETTER LAMDA */
+    XK_Greek_MU                      = 0x07cc,  /* U+039C GREEK CAPITAL LETTER MU */
+    XK_Greek_NU                      = 0x07cd,  /* U+039D GREEK CAPITAL LETTER NU */
+    XK_Greek_XI                      = 0x07ce,  /* U+039E GREEK CAPITAL LETTER XI */
+    XK_Greek_OMICRON                 = 0x07cf,  /* U+039F GREEK CAPITAL LETTER OMICRON */
+    XK_Greek_PI                      = 0x07d0,  /* U+03A0 GREEK CAPITAL LETTER PI */
+    XK_Greek_RHO                     = 0x07d1,  /* U+03A1 GREEK CAPITAL LETTER RHO */
+    XK_Greek_SIGMA                   = 0x07d2,  /* U+03A3 GREEK CAPITAL LETTER SIGMA */
+    XK_Greek_TAU                     = 0x07d4,  /* U+03A4 GREEK CAPITAL LETTER TAU */
+    XK_Greek_UPSILON                 = 0x07d5,  /* U+03A5 GREEK CAPITAL LETTER UPSILON */
+    XK_Greek_PHI                     = 0x07d6,  /* U+03A6 GREEK CAPITAL LETTER PHI */
+    XK_Greek_CHI                     = 0x07d7,  /* U+03A7 GREEK CAPITAL LETTER CHI */
+    XK_Greek_PSI                     = 0x07d8,  /* U+03A8 GREEK CAPITAL LETTER PSI */
+    XK_Greek_OMEGA                   = 0x07d9,  /* U+03A9 GREEK CAPITAL LETTER OMEGA */
+    XK_Greek_alpha                   = 0x07e1,  /* U+03B1 GREEK SMALL LETTER ALPHA */
+    XK_Greek_beta                    = 0x07e2,  /* U+03B2 GREEK SMALL LETTER BETA */
+    XK_Greek_gamma                   = 0x07e3,  /* U+03B3 GREEK SMALL LETTER GAMMA */
+    XK_Greek_delta                   = 0x07e4,  /* U+03B4 GREEK SMALL LETTER DELTA */
+    XK_Greek_epsilon                 = 0x07e5,  /* U+03B5 GREEK SMALL LETTER EPSILON */
+    XK_Greek_zeta                    = 0x07e6,  /* U+03B6 GREEK SMALL LETTER ZETA */
+    XK_Greek_eta                     = 0x07e7,  /* U+03B7 GREEK SMALL LETTER ETA */
+    XK_Greek_theta                   = 0x07e8,  /* U+03B8 GREEK SMALL LETTER THETA */
+    XK_Greek_iota                    = 0x07e9,  /* U+03B9 GREEK SMALL LETTER IOTA */
+    XK_Greek_kappa                   = 0x07ea,  /* U+03BA GREEK SMALL LETTER KAPPA */
+    XK_Greek_lamda                   = 0x07eb,  /* U+03BB GREEK SMALL LETTER LAMDA */
+    XK_Greek_lambda                  = 0x07eb,  /* U+03BB GREEK SMALL LETTER LAMDA */
+    XK_Greek_mu                      = 0x07ec,  /* U+03BC GREEK SMALL LETTER MU */
+    XK_Greek_nu                      = 0x07ed,  /* U+03BD GREEK SMALL LETTER NU */
+    XK_Greek_xi                      = 0x07ee,  /* U+03BE GREEK SMALL LETTER XI */
+    XK_Greek_omicron                 = 0x07ef,  /* U+03BF GREEK SMALL LETTER OMICRON */
+    XK_Greek_pi                      = 0x07f0,  /* U+03C0 GREEK SMALL LETTER PI */
+    XK_Greek_rho                     = 0x07f1,  /* U+03C1 GREEK SMALL LETTER RHO */
+    XK_Greek_sigma                   = 0x07f2,  /* U+03C3 GREEK SMALL LETTER SIGMA */
+    XK_Greek_finalsmallsigma         = 0x07f3,  /* U+03C2 GREEK SMALL LETTER FINAL SIGMA */
+    XK_Greek_tau                     = 0x07f4,  /* U+03C4 GREEK SMALL LETTER TAU */
+    XK_Greek_upsilon                 = 0x07f5,  /* U+03C5 GREEK SMALL LETTER UPSILON */
+    XK_Greek_phi                     = 0x07f6,  /* U+03C6 GREEK SMALL LETTER PHI */
+    XK_Greek_chi                     = 0x07f7,  /* U+03C7 GREEK SMALL LETTER CHI */
+    XK_Greek_psi                     = 0x07f8,  /* U+03C8 GREEK SMALL LETTER PSI */
+    XK_Greek_omega                   = 0x07f9,  /* U+03C9 GREEK SMALL LETTER OMEGA */
+    XK_Greek_switch                  = 0xff7e,  /* Alias for mode_switch */
+    XK_leftradical                   = 0x08a1,  /* U+23B7 RADICAL SYMBOL BOTTOM */
+    XK_topleftradical                = 0x08a2,  /*(U+250C BOX DRAWINGS LIGHT DOWN AND RIGHT)*/
+    XK_horizconnector                = 0x08a3,  /*(U+2500 BOX DRAWINGS LIGHT HORIZONTAL)*/
+    XK_topintegral                   = 0x08a4,  /* U+2320 TOP HALF INTEGRAL */
+    XK_botintegral                   = 0x08a5,  /* U+2321 BOTTOM HALF INTEGRAL */
+    XK_vertconnector                 = 0x08a6,  /*(U+2502 BOX DRAWINGS LIGHT VERTICAL)*/
+    XK_topleftsqbracket              = 0x08a7,  /* U+23A1 LEFT SQUARE BRACKET UPPER CORNER */
+    XK_botleftsqbracket              = 0x08a8,  /* U+23A3 LEFT SQUARE BRACKET LOWER CORNER */
+    XK_toprightsqbracket             = 0x08a9,  /* U+23A4 RIGHT SQUARE BRACKET UPPER CORNER */
+    XK_botrightsqbracket             = 0x08aa,  /* U+23A6 RIGHT SQUARE BRACKET LOWER CORNER */
+    XK_topleftparens                 = 0x08ab,  /* U+239B LEFT PARENTHESIS UPPER HOOK */
+    XK_botleftparens                 = 0x08ac,  /* U+239D LEFT PARENTHESIS LOWER HOOK */
+    XK_toprightparens                = 0x08ad,  /* U+239E RIGHT PARENTHESIS UPPER HOOK */
+    XK_botrightparens                = 0x08ae,  /* U+23A0 RIGHT PARENTHESIS LOWER HOOK */
+    XK_leftmiddlecurlybrace          = 0x08af,  /* U+23A8 LEFT CURLY BRACKET MIDDLE PIECE */
+    XK_rightmiddlecurlybrace         = 0x08b0,  /* U+23AC RIGHT CURLY BRACKET MIDDLE PIECE */
+    XK_topleftsummation              = 0x08b1,
+    XK_botleftsummation              = 0x08b2,
+    XK_topvertsummationconnector     = 0x08b3,
+    XK_botvertsummationconnector     = 0x08b4,
+    XK_toprightsummation             = 0x08b5,
+    XK_botrightsummation             = 0x08b6,
+    XK_rightmiddlesummation          = 0x08b7,
+    XK_lessthanequal                 = 0x08bc,  /* U+2264 LESS-THAN OR EQUAL TO */
+    XK_notequal                      = 0x08bd,  /* U+2260 NOT EQUAL TO */
+    XK_greaterthanequal              = 0x08be,  /* U+2265 GREATER-THAN OR EQUAL TO */
+    XK_integral                      = 0x08bf,  /* U+222B INTEGRAL */
+    XK_therefore                     = 0x08c0,  /* U+2234 THEREFORE */
+    XK_variation                     = 0x08c1,  /* U+221D PROPORTIONAL TO */
+    XK_infinity                      = 0x08c2,  /* U+221E INFINITY */
+    XK_nabla                         = 0x08c5,  /* U+2207 NABLA */
+    XK_approximate                   = 0x08c8,  /* U+223C TILDE OPERATOR */
+    XK_similarequal                  = 0x08c9,  /* U+2243 ASYMPTOTICALLY EQUAL TO */
+    XK_ifonlyif                      = 0x08cd,  /* U+21D4 LEFT RIGHT DOUBLE ARROW */
+    XK_implies                       = 0x08ce,  /* U+21D2 RIGHTWARDS DOUBLE ARROW */
+    XK_identical                     = 0x08cf,  /* U+2261 IDENTICAL TO */
+    XK_radical                       = 0x08d6,  /* U+221A SQUARE ROOT */
+    XK_includedin                    = 0x08da,  /* U+2282 SUBSET OF */
+    XK_includes                      = 0x08db,  /* U+2283 SUPERSET OF */
+    XK_intersection                  = 0x08dc,  /* U+2229 INTERSECTION */
+    XK_union                         = 0x08dd,  /* U+222A UNION */
+    XK_logicaland                    = 0x08de,  /* U+2227 LOGICAL AND */
+    XK_logicalor                     = 0x08df,  /* U+2228 LOGICAL OR */
+    XK_partialderivative             = 0x08ef,  /* U+2202 PARTIAL DIFFERENTIAL */
+    XK_function                      = 0x08f6,  /* U+0192 LATIN SMALL LETTER F WITH HOOK */
+    XK_leftarrow                     = 0x08fb,  /* U+2190 LEFTWARDS ARROW */
+    XK_uparrow                       = 0x08fc,  /* U+2191 UPWARDS ARROW */
+    XK_rightarrow                    = 0x08fd,  /* U+2192 RIGHTWARDS ARROW */
+    XK_downarrow                     = 0x08fe,  /* U+2193 DOWNWARDS ARROW */
+    XK_blank                         = 0x09df,
+    XK_soliddiamond                  = 0x09e0,  /* U+25C6 BLACK DIAMOND */
+    XK_checkerboard                  = 0x09e1,  /* U+2592 MEDIUM SHADE */
+    XK_ht                            = 0x09e2,  /* U+2409 SYMBOL FOR HORIZONTAL TABULATION */
+    XK_ff                            = 0x09e3,  /* U+240C SYMBOL FOR FORM FEED */
+    XK_cr                            = 0x09e4,  /* U+240D SYMBOL FOR CARRIAGE RETURN */
+    XK_lf                            = 0x09e5,  /* U+240A SYMBOL FOR LINE FEED */
+    XK_nl                            = 0x09e8,  /* U+2424 SYMBOL FOR NEWLINE */
+    XK_vt                            = 0x09e9,  /* U+240B SYMBOL FOR VERTICAL TABULATION */
+    XK_lowrightcorner                = 0x09ea,  /* U+2518 BOX DRAWINGS LIGHT UP AND LEFT */
+    XK_uprightcorner                 = 0x09eb,  /* U+2510 BOX DRAWINGS LIGHT DOWN AND LEFT */
+    XK_upleftcorner                  = 0x09ec,  /* U+250C BOX DRAWINGS LIGHT DOWN AND RIGHT */
+    XK_lowleftcorner                 = 0x09ed,  /* U+2514 BOX DRAWINGS LIGHT UP AND RIGHT */
+    XK_crossinglines                 = 0x09ee,  /* U+253C BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */
+    XK_horizlinescan1                = 0x09ef,  /* U+23BA HORIZONTAL SCAN LINE-1 */
+    XK_horizlinescan3                = 0x09f0,  /* U+23BB HORIZONTAL SCAN LINE-3 */
+    XK_horizlinescan5                = 0x09f1,  /* U+2500 BOX DRAWINGS LIGHT HORIZONTAL */
+    XK_horizlinescan7                = 0x09f2,  /* U+23BC HORIZONTAL SCAN LINE-7 */
+    XK_horizlinescan9                = 0x09f3,  /* U+23BD HORIZONTAL SCAN LINE-9 */
+    XK_leftt                         = 0x09f4,  /* U+251C BOX DRAWINGS LIGHT VERTICAL AND RIGHT */
+    XK_rightt                        = 0x09f5,  /* U+2524 BOX DRAWINGS LIGHT VERTICAL AND LEFT */
+    XK_bott                          = 0x09f6,  /* U+2534 BOX DRAWINGS LIGHT UP AND HORIZONTAL */
+    XK_topt                          = 0x09f7,  /* U+252C BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */
+    XK_vertbar                       = 0x09f8,  /* U+2502 BOX DRAWINGS LIGHT VERTICAL */
+    XK_emspace                       = 0x0aa1,  /* U+2003 EM SPACE */
+    XK_enspace                       = 0x0aa2,  /* U+2002 EN SPACE */
+    XK_em3space                      = 0x0aa3,  /* U+2004 THREE-PER-EM SPACE */
+    XK_em4space                      = 0x0aa4,  /* U+2005 FOUR-PER-EM SPACE */
+    XK_digitspace                    = 0x0aa5,  /* U+2007 FIGURE SPACE */
+    XK_punctspace                    = 0x0aa6,  /* U+2008 PUNCTUATION SPACE */
+    XK_thinspace                     = 0x0aa7,  /* U+2009 THIN SPACE */
+    XK_hairspace                     = 0x0aa8,  /* U+200A HAIR SPACE */
+    XK_emdash                        = 0x0aa9,  /* U+2014 EM DASH */
+    XK_endash                        = 0x0aaa,  /* U+2013 EN DASH */
+    XK_signifblank                   = 0x0aac,  /*(U+2423 OPEN BOX)*/
+    XK_ellipsis                      = 0x0aae,  /* U+2026 HORIZONTAL ELLIPSIS */
+    XK_doubbaselinedot               = 0x0aaf,  /* U+2025 TWO DOT LEADER */
+    XK_onethird                      = 0x0ab0,  /* U+2153 VULGAR FRACTION ONE THIRD */
+    XK_twothirds                     = 0x0ab1,  /* U+2154 VULGAR FRACTION TWO THIRDS */
+    XK_onefifth                      = 0x0ab2,  /* U+2155 VULGAR FRACTION ONE FIFTH */
+    XK_twofifths                     = 0x0ab3,  /* U+2156 VULGAR FRACTION TWO FIFTHS */
+    XK_threefifths                   = 0x0ab4,  /* U+2157 VULGAR FRACTION THREE FIFTHS */
+    XK_fourfifths                    = 0x0ab5,  /* U+2158 VULGAR FRACTION FOUR FIFTHS */
+    XK_onesixth                      = 0x0ab6,  /* U+2159 VULGAR FRACTION ONE SIXTH */
+    XK_fivesixths                    = 0x0ab7,  /* U+215A VULGAR FRACTION FIVE SIXTHS */
+    XK_careof                        = 0x0ab8,  /* U+2105 CARE OF */
+    XK_figdash                       = 0x0abb,  /* U+2012 FIGURE DASH */
+    XK_leftanglebracket              = 0x0abc,  /*(U+27E8 MATHEMATICAL LEFT ANGLE BRACKET)*/
+    XK_decimalpoint                  = 0x0abd,  /*(U+002E FULL STOP)*/
+    XK_rightanglebracket             = 0x0abe,  /*(U+27E9 MATHEMATICAL RIGHT ANGLE BRACKET)*/
+    XK_marker                        = 0x0abf,
+    XK_oneeighth                     = 0x0ac3,  /* U+215B VULGAR FRACTION ONE EIGHTH */
+    XK_threeeighths                  = 0x0ac4,  /* U+215C VULGAR FRACTION THREE EIGHTHS */
+    XK_fiveeighths                   = 0x0ac5,  /* U+215D VULGAR FRACTION FIVE EIGHTHS */
+    XK_seveneighths                  = 0x0ac6,  /* U+215E VULGAR FRACTION SEVEN EIGHTHS */
+    XK_trademark                     = 0x0ac9,  /* U+2122 TRADE MARK SIGN */
+    XK_signaturemark                 = 0x0aca,  /*(U+2613 SALTIRE)*/
+    XK_trademarkincircle             = 0x0acb,
+    XK_leftopentriangle              = 0x0acc,  /*(U+25C1 WHITE LEFT-POINTING TRIANGLE)*/
+    XK_rightopentriangle             = 0x0acd,  /*(U+25B7 WHITE RIGHT-POINTING TRIANGLE)*/
+    XK_emopencircle                  = 0x0ace,  /*(U+25CB WHITE CIRCLE)*/
+    XK_emopenrectangle               = 0x0acf,  /*(U+25AF WHITE VERTICAL RECTANGLE)*/
+    XK_leftsinglequotemark           = 0x0ad0,  /* U+2018 LEFT SINGLE QUOTATION MARK */
+    XK_rightsinglequotemark          = 0x0ad1,  /* U+2019 RIGHT SINGLE QUOTATION MARK */
+    XK_leftdoublequotemark           = 0x0ad2,  /* U+201C LEFT DOUBLE QUOTATION MARK */
+    XK_rightdoublequotemark          = 0x0ad3,  /* U+201D RIGHT DOUBLE QUOTATION MARK */
+    XK_prescription                  = 0x0ad4,  /* U+211E PRESCRIPTION TAKE */
+    XK_minutes                       = 0x0ad6,  /* U+2032 PRIME */
+    XK_seconds                       = 0x0ad7,  /* U+2033 DOUBLE PRIME */
+    XK_latincross                    = 0x0ad9,  /* U+271D LATIN CROSS */
+    XK_hexagram                      = 0x0ada,
+    XK_filledrectbullet              = 0x0adb,  /*(U+25AC BLACK RECTANGLE)*/
+    XK_filledlefttribullet           = 0x0adc,  /*(U+25C0 BLACK LEFT-POINTING TRIANGLE)*/
+    XK_filledrighttribullet          = 0x0add,  /*(U+25B6 BLACK RIGHT-POINTING TRIANGLE)*/
+    XK_emfilledcircle                = 0x0ade,  /*(U+25CF BLACK CIRCLE)*/
+    XK_emfilledrect                  = 0x0adf,  /*(U+25AE BLACK VERTICAL RECTANGLE)*/
+    XK_enopencircbullet              = 0x0ae0,  /*(U+25E6 WHITE BULLET)*/
+    XK_enopensquarebullet            = 0x0ae1,  /*(U+25AB WHITE SMALL SQUARE)*/
+    XK_openrectbullet                = 0x0ae2,  /*(U+25AD WHITE RECTANGLE)*/
+    XK_opentribulletup               = 0x0ae3,  /*(U+25B3 WHITE UP-POINTING TRIANGLE)*/
+    XK_opentribulletdown             = 0x0ae4,  /*(U+25BD WHITE DOWN-POINTING TRIANGLE)*/
+    XK_openstar                      = 0x0ae5,  /*(U+2606 WHITE STAR)*/
+    XK_enfilledcircbullet            = 0x0ae6,  /*(U+2022 BULLET)*/
+    XK_enfilledsqbullet              = 0x0ae7,  /*(U+25AA BLACK SMALL SQUARE)*/
+    XK_filledtribulletup             = 0x0ae8,  /*(U+25B2 BLACK UP-POINTING TRIANGLE)*/
+    XK_filledtribulletdown           = 0x0ae9,  /*(U+25BC BLACK DOWN-POINTING TRIANGLE)*/
+    XK_leftpointer                   = 0x0aea,  /*(U+261C WHITE LEFT POINTING INDEX)*/
+    XK_rightpointer                  = 0x0aeb,  /*(U+261E WHITE RIGHT POINTING INDEX)*/
+    XK_club                          = 0x0aec,  /* U+2663 BLACK CLUB SUIT */
+    XK_diamond                       = 0x0aed,  /* U+2666 BLACK DIAMOND SUIT */
+    XK_heart                         = 0x0aee,  /* U+2665 BLACK HEART SUIT */
+    XK_maltesecross                  = 0x0af0,  /* U+2720 MALTESE CROSS */
+    XK_dagger                        = 0x0af1,  /* U+2020 DAGGER */
+    XK_doubledagger                  = 0x0af2,  /* U+2021 DOUBLE DAGGER */
+    XK_checkmark                     = 0x0af3,  /* U+2713 CHECK MARK */
+    XK_ballotcross                   = 0x0af4,  /* U+2717 BALLOT X */
+    XK_musicalsharp                  = 0x0af5,  /* U+266F MUSIC SHARP SIGN */
+    XK_musicalflat                   = 0x0af6,  /* U+266D MUSIC FLAT SIGN */
+    XK_malesymbol                    = 0x0af7,  /* U+2642 MALE SIGN */
+    XK_femalesymbol                  = 0x0af8,  /* U+2640 FEMALE SIGN */
+    XK_telephone                     = 0x0af9,  /* U+260E BLACK TELEPHONE */
+    XK_telephonerecorder             = 0x0afa,  /* U+2315 TELEPHONE RECORDER */
+    XK_phonographcopyright           = 0x0afb,  /* U+2117 SOUND RECORDING COPYRIGHT */
+    XK_caret                         = 0x0afc,  /* U+2038 CARET */
+    XK_singlelowquotemark            = 0x0afd,  /* U+201A SINGLE LOW-9 QUOTATION MARK */
+    XK_doublelowquotemark            = 0x0afe,  /* U+201E DOUBLE LOW-9 QUOTATION MARK */
+    XK_cursor                        = 0x0aff,
+    XK_leftcaret                     = 0x0ba3,  /*(U+003C LESS-THAN SIGN)*/
+    XK_rightcaret                    = 0x0ba6,  /*(U+003E GREATER-THAN SIGN)*/
+    XK_downcaret                     = 0x0ba8,  /*(U+2228 LOGICAL OR)*/
+    XK_upcaret                       = 0x0ba9,  /*(U+2227 LOGICAL AND)*/
+    XK_overbar                       = 0x0bc0,  /*(U+00AF MACRON)*/
+    XK_downtack                      = 0x0bc2,  /* U+22A5 UP TACK */
+    XK_upshoe                        = 0x0bc3,  /*(U+2229 INTERSECTION)*/
+    XK_downstile                     = 0x0bc4,  /* U+230A LEFT FLOOR */
+    XK_underbar                      = 0x0bc6,  /*(U+005F LOW LINE)*/
+    XK_jot                           = 0x0bca,  /* U+2218 RING OPERATOR */
+    XK_quad                          = 0x0bcc,  /* U+2395 APL FUNCTIONAL SYMBOL QUAD */
+    XK_uptack                        = 0x0bce,  /* U+22A4 DOWN TACK */
+    XK_circle                        = 0x0bcf,  /* U+25CB WHITE CIRCLE */
+    XK_upstile                       = 0x0bd3,  /* U+2308 LEFT CEILING */
+    XK_downshoe                      = 0x0bd6,  /*(U+222A UNION)*/
+    XK_rightshoe                     = 0x0bd8,  /*(U+2283 SUPERSET OF)*/
+    XK_leftshoe                      = 0x0bda,  /*(U+2282 SUBSET OF)*/
+    XK_lefttack                      = 0x0bdc,  /* U+22A2 RIGHT TACK */
+    XK_righttack                     = 0x0bfc,  /* U+22A3 LEFT TACK */
+    XK_hebrew_doublelowline          = 0x0cdf,  /* U+2017 DOUBLE LOW LINE */
+    XK_hebrew_aleph                  = 0x0ce0,  /* U+05D0 HEBREW LETTER ALEF */
+    XK_hebrew_bet                    = 0x0ce1,  /* U+05D1 HEBREW LETTER BET */
+    XK_hebrew_beth                   = 0x0ce1,  /* deprecated */
+    XK_hebrew_gimel                  = 0x0ce2,  /* U+05D2 HEBREW LETTER GIMEL */
+    XK_hebrew_gimmel                 = 0x0ce2,  /* deprecated */
+    XK_hebrew_dalet                  = 0x0ce3,  /* U+05D3 HEBREW LETTER DALET */
+    XK_hebrew_daleth                 = 0x0ce3,  /* deprecated */
+    XK_hebrew_he                     = 0x0ce4,  /* U+05D4 HEBREW LETTER HE */
+    XK_hebrew_waw                    = 0x0ce5,  /* U+05D5 HEBREW LETTER VAV */
+    XK_hebrew_zain                   = 0x0ce6,  /* U+05D6 HEBREW LETTER ZAYIN */
+    XK_hebrew_zayin                  = 0x0ce6,  /* deprecated */
+    XK_hebrew_chet                   = 0x0ce7,  /* U+05D7 HEBREW LETTER HET */
+    XK_hebrew_het                    = 0x0ce7,  /* deprecated */
+    XK_hebrew_tet                    = 0x0ce8,  /* U+05D8 HEBREW LETTER TET */
+    XK_hebrew_teth                   = 0x0ce8,  /* deprecated */
+    XK_hebrew_yod                    = 0x0ce9,  /* U+05D9 HEBREW LETTER YOD */
+    XK_hebrew_finalkaph              = 0x0cea,  /* U+05DA HEBREW LETTER FINAL KAF */
+    XK_hebrew_kaph                   = 0x0ceb,  /* U+05DB HEBREW LETTER KAF */
+    XK_hebrew_lamed                  = 0x0cec,  /* U+05DC HEBREW LETTER LAMED */
+    XK_hebrew_finalmem               = 0x0ced,  /* U+05DD HEBREW LETTER FINAL MEM */
+    XK_hebrew_mem                    = 0x0cee,  /* U+05DE HEBREW LETTER MEM */
+    XK_hebrew_finalnun               = 0x0cef,  /* U+05DF HEBREW LETTER FINAL NUN */
+    XK_hebrew_nun                    = 0x0cf0,  /* U+05E0 HEBREW LETTER NUN */
+    XK_hebrew_samech                 = 0x0cf1,  /* U+05E1 HEBREW LETTER SAMEKH */
+    XK_hebrew_samekh                 = 0x0cf1,  /* deprecated */
+    XK_hebrew_ayin                   = 0x0cf2,  /* U+05E2 HEBREW LETTER AYIN */
+    XK_hebrew_finalpe                = 0x0cf3,  /* U+05E3 HEBREW LETTER FINAL PE */
+    XK_hebrew_pe                     = 0x0cf4,  /* U+05E4 HEBREW LETTER PE */
+    XK_hebrew_finalzade              = 0x0cf5,  /* U+05E5 HEBREW LETTER FINAL TSADI */
+    XK_hebrew_finalzadi              = 0x0cf5,  /* deprecated */
+    XK_hebrew_zade                   = 0x0cf6,  /* U+05E6 HEBREW LETTER TSADI */
+    XK_hebrew_zadi                   = 0x0cf6,  /* deprecated */
+    XK_hebrew_qoph                   = 0x0cf7,  /* U+05E7 HEBREW LETTER QOF */
+    XK_hebrew_kuf                    = 0x0cf7,  /* deprecated */
+    XK_hebrew_resh                   = 0x0cf8,  /* U+05E8 HEBREW LETTER RESH */
+    XK_hebrew_shin                   = 0x0cf9,  /* U+05E9 HEBREW LETTER SHIN */
+    XK_hebrew_taw                    = 0x0cfa,  /* U+05EA HEBREW LETTER TAV */
+    XK_hebrew_taf                    = 0x0cfa,  /* deprecated */
+    XK_Hebrew_switch                 = 0xff7e,  /* Alias for mode_switch */
+    XK_Thai_kokai                    = 0x0da1,  /* U+0E01 THAI CHARACTER KO KAI */
+    XK_Thai_khokhai                  = 0x0da2,  /* U+0E02 THAI CHARACTER KHO KHAI */
+    XK_Thai_khokhuat                 = 0x0da3,  /* U+0E03 THAI CHARACTER KHO KHUAT */
+    XK_Thai_khokhwai                 = 0x0da4,  /* U+0E04 THAI CHARACTER KHO KHWAI */
+    XK_Thai_khokhon                  = 0x0da5,  /* U+0E05 THAI CHARACTER KHO KHON */
+    XK_Thai_khorakhang               = 0x0da6,  /* U+0E06 THAI CHARACTER KHO RAKHANG */
+    XK_Thai_ngongu                   = 0x0da7,  /* U+0E07 THAI CHARACTER NGO NGU */
+    XK_Thai_chochan                  = 0x0da8,  /* U+0E08 THAI CHARACTER CHO CHAN */
+    XK_Thai_choching                 = 0x0da9,  /* U+0E09 THAI CHARACTER CHO CHING */
+    XK_Thai_chochang                 = 0x0daa,  /* U+0E0A THAI CHARACTER CHO CHANG */
+    XK_Thai_soso                     = 0x0dab,  /* U+0E0B THAI CHARACTER SO SO */
+    XK_Thai_chochoe                  = 0x0dac,  /* U+0E0C THAI CHARACTER CHO CHOE */
+    XK_Thai_yoying                   = 0x0dad,  /* U+0E0D THAI CHARACTER YO YING */
+    XK_Thai_dochada                  = 0x0dae,  /* U+0E0E THAI CHARACTER DO CHADA */
+    XK_Thai_topatak                  = 0x0daf,  /* U+0E0F THAI CHARACTER TO PATAK */
+    XK_Thai_thothan                  = 0x0db0,  /* U+0E10 THAI CHARACTER THO THAN */
+    XK_Thai_thonangmontho            = 0x0db1,  /* U+0E11 THAI CHARACTER THO NANGMONTHO */
+    XK_Thai_thophuthao               = 0x0db2,  /* U+0E12 THAI CHARACTER THO PHUTHAO */
+    XK_Thai_nonen                    = 0x0db3,  /* U+0E13 THAI CHARACTER NO NEN */
+    XK_Thai_dodek                    = 0x0db4,  /* U+0E14 THAI CHARACTER DO DEK */
+    XK_Thai_totao                    = 0x0db5,  /* U+0E15 THAI CHARACTER TO TAO */
+    XK_Thai_thothung                 = 0x0db6,  /* U+0E16 THAI CHARACTER THO THUNG */
+    XK_Thai_thothahan                = 0x0db7,  /* U+0E17 THAI CHARACTER THO THAHAN */
+    XK_Thai_thothong                 = 0x0db8,  /* U+0E18 THAI CHARACTER THO THONG */
+    XK_Thai_nonu                     = 0x0db9,  /* U+0E19 THAI CHARACTER NO NU */
+    XK_Thai_bobaimai                 = 0x0dba,  /* U+0E1A THAI CHARACTER BO BAIMAI */
+    XK_Thai_popla                    = 0x0dbb,  /* U+0E1B THAI CHARACTER PO PLA */
+    XK_Thai_phophung                 = 0x0dbc,  /* U+0E1C THAI CHARACTER PHO PHUNG */
+    XK_Thai_fofa                     = 0x0dbd,  /* U+0E1D THAI CHARACTER FO FA */
+    XK_Thai_phophan                  = 0x0dbe,  /* U+0E1E THAI CHARACTER PHO PHAN */
+    XK_Thai_fofan                    = 0x0dbf,  /* U+0E1F THAI CHARACTER FO FAN */
+    XK_Thai_phosamphao               = 0x0dc0,  /* U+0E20 THAI CHARACTER PHO SAMPHAO */
+    XK_Thai_moma                     = 0x0dc1,  /* U+0E21 THAI CHARACTER MO MA */
+    XK_Thai_yoyak                    = 0x0dc2,  /* U+0E22 THAI CHARACTER YO YAK */
+    XK_Thai_rorua                    = 0x0dc3,  /* U+0E23 THAI CHARACTER RO RUA */
+    XK_Thai_ru                       = 0x0dc4,  /* U+0E24 THAI CHARACTER RU */
+    XK_Thai_loling                   = 0x0dc5,  /* U+0E25 THAI CHARACTER LO LING */
+    XK_Thai_lu                       = 0x0dc6,  /* U+0E26 THAI CHARACTER LU */
+    XK_Thai_wowaen                   = 0x0dc7,  /* U+0E27 THAI CHARACTER WO WAEN */
+    XK_Thai_sosala                   = 0x0dc8,  /* U+0E28 THAI CHARACTER SO SALA */
+    XK_Thai_sorusi                   = 0x0dc9,  /* U+0E29 THAI CHARACTER SO RUSI */
+    XK_Thai_sosua                    = 0x0dca,  /* U+0E2A THAI CHARACTER SO SUA */
+    XK_Thai_hohip                    = 0x0dcb,  /* U+0E2B THAI CHARACTER HO HIP */
+    XK_Thai_lochula                  = 0x0dcc,  /* U+0E2C THAI CHARACTER LO CHULA */
+    XK_Thai_oang                     = 0x0dcd,  /* U+0E2D THAI CHARACTER O ANG */
+    XK_Thai_honokhuk                 = 0x0dce,  /* U+0E2E THAI CHARACTER HO NOKHUK */
+    XK_Thai_paiyannoi                = 0x0dcf,  /* U+0E2F THAI CHARACTER PAIYANNOI */
+    XK_Thai_saraa                    = 0x0dd0,  /* U+0E30 THAI CHARACTER SARA A */
+    XK_Thai_maihanakat               = 0x0dd1,  /* U+0E31 THAI CHARACTER MAI HAN-AKAT */
+    XK_Thai_saraaa                   = 0x0dd2,  /* U+0E32 THAI CHARACTER SARA AA */
+    XK_Thai_saraam                   = 0x0dd3,  /* U+0E33 THAI CHARACTER SARA AM */
+    XK_Thai_sarai                    = 0x0dd4,  /* U+0E34 THAI CHARACTER SARA I */
+    XK_Thai_saraii                   = 0x0dd5,  /* U+0E35 THAI CHARACTER SARA II */
+    XK_Thai_saraue                   = 0x0dd6,  /* U+0E36 THAI CHARACTER SARA UE */
+    XK_Thai_sarauee                  = 0x0dd7,  /* U+0E37 THAI CHARACTER SARA UEE */
+    XK_Thai_sarau                    = 0x0dd8,  /* U+0E38 THAI CHARACTER SARA U */
+    XK_Thai_sarauu                   = 0x0dd9,  /* U+0E39 THAI CHARACTER SARA UU */
+    XK_Thai_phinthu                  = 0x0dda,  /* U+0E3A THAI CHARACTER PHINTHU */
+    XK_Thai_maihanakat_maitho        = 0x0dde,
+    XK_Thai_baht                     = 0x0ddf,  /* U+0E3F THAI CURRENCY SYMBOL BAHT */
+    XK_Thai_sarae                    = 0x0de0,  /* U+0E40 THAI CHARACTER SARA E */
+    XK_Thai_saraae                   = 0x0de1,  /* U+0E41 THAI CHARACTER SARA AE */
+    XK_Thai_sarao                    = 0x0de2,  /* U+0E42 THAI CHARACTER SARA O */
+    XK_Thai_saraaimaimuan            = 0x0de3,  /* U+0E43 THAI CHARACTER SARA AI MAIMUAN */
+    XK_Thai_saraaimaimalai           = 0x0de4,  /* U+0E44 THAI CHARACTER SARA AI MAIMALAI */
+    XK_Thai_lakkhangyao              = 0x0de5,  /* U+0E45 THAI CHARACTER LAKKHANGYAO */
+    XK_Thai_maiyamok                 = 0x0de6,  /* U+0E46 THAI CHARACTER MAIYAMOK */
+    XK_Thai_maitaikhu                = 0x0de7,  /* U+0E47 THAI CHARACTER MAITAIKHU */
+    XK_Thai_maiek                    = 0x0de8,  /* U+0E48 THAI CHARACTER MAI EK */
+    XK_Thai_maitho                   = 0x0de9,  /* U+0E49 THAI CHARACTER MAI THO */
+    XK_Thai_maitri                   = 0x0dea,  /* U+0E4A THAI CHARACTER MAI TRI */
+    XK_Thai_maichattawa              = 0x0deb,  /* U+0E4B THAI CHARACTER MAI CHATTAWA */
+    XK_Thai_thanthakhat              = 0x0dec,  /* U+0E4C THAI CHARACTER THANTHAKHAT */
+    XK_Thai_nikhahit                 = 0x0ded,  /* U+0E4D THAI CHARACTER NIKHAHIT */
+    XK_Thai_leksun                   = 0x0df0,  /* U+0E50 THAI DIGIT ZERO */
+    XK_Thai_leknung                  = 0x0df1,  /* U+0E51 THAI DIGIT ONE */
+    XK_Thai_leksong                  = 0x0df2,  /* U+0E52 THAI DIGIT TWO */
+    XK_Thai_leksam                   = 0x0df3,  /* U+0E53 THAI DIGIT THREE */
+    XK_Thai_leksi                    = 0x0df4,  /* U+0E54 THAI DIGIT FOUR */
+    XK_Thai_lekha                    = 0x0df5,  /* U+0E55 THAI DIGIT FIVE */
+    XK_Thai_lekhok                   = 0x0df6,  /* U+0E56 THAI DIGIT SIX */
+    XK_Thai_lekchet                  = 0x0df7,  /* U+0E57 THAI DIGIT SEVEN */
+    XK_Thai_lekpaet                  = 0x0df8,  /* U+0E58 THAI DIGIT EIGHT */
+    XK_Thai_lekkao                   = 0x0df9,  /* U+0E59 THAI DIGIT NINE */
+    XK_Hangul                        = 0xff31,  /* Hangul start/stop(toggle) */
+    XK_Hangul_Start                  = 0xff32,  /* Hangul start */
+    XK_Hangul_End                    = 0xff33,  /* Hangul end, English start */
+    XK_Hangul_Hanja                  = 0xff34,  /* Start Hangul->Hanja Conversion */
+    XK_Hangul_Jamo                   = 0xff35,  /* Hangul Jamo mode */
+    XK_Hangul_Romaja                 = 0xff36,  /* Hangul Romaja mode */
+    XK_Hangul_Codeinput              = 0xff37,  /* Hangul code input mode */
+    XK_Hangul_Jeonja                 = 0xff38,  /* Jeonja mode */
+    XK_Hangul_Banja                  = 0xff39,  /* Banja mode */
+    XK_Hangul_PreHanja               = 0xff3a,  /* Pre Hanja conversion */
+    XK_Hangul_PostHanja              = 0xff3b,  /* Post Hanja conversion */
+    XK_Hangul_SingleCandidate        = 0xff3c,  /* Single candidate */
+    XK_Hangul_MultipleCandidate      = 0xff3d,  /* Multiple candidate */
+    XK_Hangul_PreviousCandidate      = 0xff3e,  /* Previous candidate */
+    XK_Hangul_Special                = 0xff3f,  /* Special symbols */
+    XK_Hangul_switch                 = 0xff7e,  /* Alias for mode_switch */
+    XK_Hangul_Kiyeog                 = 0x0ea1,
+    XK_Hangul_SsangKiyeog            = 0x0ea2,
+    XK_Hangul_KiyeogSios             = 0x0ea3,
+    XK_Hangul_Nieun                  = 0x0ea4,
+    XK_Hangul_NieunJieuj             = 0x0ea5,
+    XK_Hangul_NieunHieuh             = 0x0ea6,
+    XK_Hangul_Dikeud                 = 0x0ea7,
+    XK_Hangul_SsangDikeud            = 0x0ea8,
+    XK_Hangul_Rieul                  = 0x0ea9,
+    XK_Hangul_RieulKiyeog            = 0x0eaa,
+    XK_Hangul_RieulMieum             = 0x0eab,
+    XK_Hangul_RieulPieub             = 0x0eac,
+    XK_Hangul_RieulSios              = 0x0ead,
+    XK_Hangul_RieulTieut             = 0x0eae,
+    XK_Hangul_RieulPhieuf            = 0x0eaf,
+    XK_Hangul_RieulHieuh             = 0x0eb0,
+    XK_Hangul_Mieum                  = 0x0eb1,
+    XK_Hangul_Pieub                  = 0x0eb2,
+    XK_Hangul_SsangPieub             = 0x0eb3,
+    XK_Hangul_PieubSios              = 0x0eb4,
+    XK_Hangul_Sios                   = 0x0eb5,
+    XK_Hangul_SsangSios              = 0x0eb6,
+    XK_Hangul_Ieung                  = 0x0eb7,
+    XK_Hangul_Jieuj                  = 0x0eb8,
+    XK_Hangul_SsangJieuj             = 0x0eb9,
+    XK_Hangul_Cieuc                  = 0x0eba,
+    XK_Hangul_Khieuq                 = 0x0ebb,
+    XK_Hangul_Tieut                  = 0x0ebc,
+    XK_Hangul_Phieuf                 = 0x0ebd,
+    XK_Hangul_Hieuh                  = 0x0ebe,
+    XK_Hangul_A                      = 0x0ebf,
+    XK_Hangul_AE                     = 0x0ec0,
+    XK_Hangul_YA                     = 0x0ec1,
+    XK_Hangul_YAE                    = 0x0ec2,
+    XK_Hangul_EO                     = 0x0ec3,
+    XK_Hangul_E                      = 0x0ec4,
+    XK_Hangul_YEO                    = 0x0ec5,
+    XK_Hangul_YE                     = 0x0ec6,
+    XK_Hangul_O                      = 0x0ec7,
+    XK_Hangul_WA                     = 0x0ec8,
+    XK_Hangul_WAE                    = 0x0ec9,
+    XK_Hangul_OE                     = 0x0eca,
+    XK_Hangul_YO                     = 0x0ecb,
+    XK_Hangul_U                      = 0x0ecc,
+    XK_Hangul_WEO                    = 0x0ecd,
+    XK_Hangul_WE                     = 0x0ece,
+    XK_Hangul_WI                     = 0x0ecf,
+    XK_Hangul_YU                     = 0x0ed0,
+    XK_Hangul_EU                     = 0x0ed1,
+    XK_Hangul_YI                     = 0x0ed2,
+    XK_Hangul_I                      = 0x0ed3,
+    XK_Hangul_J_Kiyeog               = 0x0ed4,
+    XK_Hangul_J_SsangKiyeog          = 0x0ed5,
+    XK_Hangul_J_KiyeogSios           = 0x0ed6,
+    XK_Hangul_J_Nieun                = 0x0ed7,
+    XK_Hangul_J_NieunJieuj           = 0x0ed8,
+    XK_Hangul_J_NieunHieuh           = 0x0ed9,
+    XK_Hangul_J_Dikeud               = 0x0eda,
+    XK_Hangul_J_Rieul                = 0x0edb,
+    XK_Hangul_J_RieulKiyeog          = 0x0edc,
+    XK_Hangul_J_RieulMieum           = 0x0edd,
+    XK_Hangul_J_RieulPieub           = 0x0ede,
+    XK_Hangul_J_RieulSios            = 0x0edf,
+    XK_Hangul_J_RieulTieut           = 0x0ee0,
+    XK_Hangul_J_RieulPhieuf          = 0x0ee1,
+    XK_Hangul_J_RieulHieuh           = 0x0ee2,
+    XK_Hangul_J_Mieum                = 0x0ee3,
+    XK_Hangul_J_Pieub                = 0x0ee4,
+    XK_Hangul_J_PieubSios            = 0x0ee5,
+    XK_Hangul_J_Sios                 = 0x0ee6,
+    XK_Hangul_J_SsangSios            = 0x0ee7,
+    XK_Hangul_J_Ieung                = 0x0ee8,
+    XK_Hangul_J_Jieuj                = 0x0ee9,
+    XK_Hangul_J_Cieuc                = 0x0eea,
+    XK_Hangul_J_Khieuq               = 0x0eeb,
+    XK_Hangul_J_Tieut                = 0x0eec,
+    XK_Hangul_J_Phieuf               = 0x0eed,
+    XK_Hangul_J_Hieuh                = 0x0eee,
+    XK_Hangul_RieulYeorinHieuh       = 0x0eef,
+    XK_Hangul_SunkyeongeumMieum      = 0x0ef0,
+    XK_Hangul_SunkyeongeumPieub      = 0x0ef1,
+    XK_Hangul_PanSios                = 0x0ef2,
+    XK_Hangul_KkogjiDalrinIeung      = 0x0ef3,
+    XK_Hangul_SunkyeongeumPhieuf     = 0x0ef4,
+    XK_Hangul_YeorinHieuh            = 0x0ef5,
+    XK_Hangul_AraeA                  = 0x0ef6,
+    XK_Hangul_AraeAE                 = 0x0ef7,
+    XK_Hangul_J_PanSios              = 0x0ef8,
+    XK_Hangul_J_KkogjiDalrinIeung    = 0x0ef9,
+    XK_Hangul_J_YeorinHieuh          = 0x0efa,
+    XK_Korean_Won                    = 0x0eff,  /*(U+20A9 WON SIGN)*/
+    XK_Armenian_ligature_ew       = 0x1000587,  /* U+0587 ARMENIAN SMALL LIGATURE ECH YIWN */
+    XK_Armenian_full_stop         = 0x1000589,  /* U+0589 ARMENIAN FULL STOP */
+    XK_Armenian_verjaket          = 0x1000589,  /* U+0589 ARMENIAN FULL STOP */
+    XK_Armenian_separation_mark   = 0x100055d,  /* U+055D ARMENIAN COMMA */
+    XK_Armenian_but               = 0x100055d,  /* U+055D ARMENIAN COMMA */
+    XK_Armenian_hyphen            = 0x100058a,  /* U+058A ARMENIAN HYPHEN */
+    XK_Armenian_yentamna          = 0x100058a,  /* U+058A ARMENIAN HYPHEN */
+    XK_Armenian_exclam            = 0x100055c,  /* U+055C ARMENIAN EXCLAMATION MARK */
+    XK_Armenian_amanak            = 0x100055c,  /* U+055C ARMENIAN EXCLAMATION MARK */
+    XK_Armenian_accent            = 0x100055b,  /* U+055B ARMENIAN EMPHASIS MARK */
+    XK_Armenian_shesht            = 0x100055b,  /* U+055B ARMENIAN EMPHASIS MARK */
+    XK_Armenian_question          = 0x100055e,  /* U+055E ARMENIAN QUESTION MARK */
+    XK_Armenian_paruyk            = 0x100055e,  /* U+055E ARMENIAN QUESTION MARK */
+    XK_Armenian_AYB               = 0x1000531,  /* U+0531 ARMENIAN CAPITAL LETTER AYB */
+    XK_Armenian_ayb               = 0x1000561,  /* U+0561 ARMENIAN SMALL LETTER AYB */
+    XK_Armenian_BEN               = 0x1000532,  /* U+0532 ARMENIAN CAPITAL LETTER BEN */
+    XK_Armenian_ben               = 0x1000562,  /* U+0562 ARMENIAN SMALL LETTER BEN */
+    XK_Armenian_GIM               = 0x1000533,  /* U+0533 ARMENIAN CAPITAL LETTER GIM */
+    XK_Armenian_gim               = 0x1000563,  /* U+0563 ARMENIAN SMALL LETTER GIM */
+    XK_Armenian_DA                = 0x1000534,  /* U+0534 ARMENIAN CAPITAL LETTER DA */
+    XK_Armenian_da                = 0x1000564,  /* U+0564 ARMENIAN SMALL LETTER DA */
+    XK_Armenian_YECH              = 0x1000535,  /* U+0535 ARMENIAN CAPITAL LETTER ECH */
+    XK_Armenian_yech              = 0x1000565,  /* U+0565 ARMENIAN SMALL LETTER ECH */
+    XK_Armenian_ZA                = 0x1000536,  /* U+0536 ARMENIAN CAPITAL LETTER ZA */
+    XK_Armenian_za                = 0x1000566,  /* U+0566 ARMENIAN SMALL LETTER ZA */
+    XK_Armenian_E                 = 0x1000537,  /* U+0537 ARMENIAN CAPITAL LETTER EH */
+    XK_Armenian_e                 = 0x1000567,  /* U+0567 ARMENIAN SMALL LETTER EH */
+    XK_Armenian_AT                = 0x1000538,  /* U+0538 ARMENIAN CAPITAL LETTER ET */
+    XK_Armenian_at                = 0x1000568,  /* U+0568 ARMENIAN SMALL LETTER ET */
+    XK_Armenian_TO                = 0x1000539,  /* U+0539 ARMENIAN CAPITAL LETTER TO */
+    XK_Armenian_to                = 0x1000569,  /* U+0569 ARMENIAN SMALL LETTER TO */
+    XK_Armenian_ZHE               = 0x100053a,  /* U+053A ARMENIAN CAPITAL LETTER ZHE */
+    XK_Armenian_zhe               = 0x100056a,  /* U+056A ARMENIAN SMALL LETTER ZHE */
+    XK_Armenian_INI               = 0x100053b,  /* U+053B ARMENIAN CAPITAL LETTER INI */
+    XK_Armenian_ini               = 0x100056b,  /* U+056B ARMENIAN SMALL LETTER INI */
+    XK_Armenian_LYUN              = 0x100053c,  /* U+053C ARMENIAN CAPITAL LETTER LIWN */
+    XK_Armenian_lyun              = 0x100056c,  /* U+056C ARMENIAN SMALL LETTER LIWN */
+    XK_Armenian_KHE               = 0x100053d,  /* U+053D ARMENIAN CAPITAL LETTER XEH */
+    XK_Armenian_khe               = 0x100056d,  /* U+056D ARMENIAN SMALL LETTER XEH */
+    XK_Armenian_TSA               = 0x100053e,  /* U+053E ARMENIAN CAPITAL LETTER CA */
+    XK_Armenian_tsa               = 0x100056e,  /* U+056E ARMENIAN SMALL LETTER CA */
+    XK_Armenian_KEN               = 0x100053f,  /* U+053F ARMENIAN CAPITAL LETTER KEN */
+    XK_Armenian_ken               = 0x100056f,  /* U+056F ARMENIAN SMALL LETTER KEN */
+    XK_Armenian_HO                = 0x1000540,  /* U+0540 ARMENIAN CAPITAL LETTER HO */
+    XK_Armenian_ho                = 0x1000570,  /* U+0570 ARMENIAN SMALL LETTER HO */
+    XK_Armenian_DZA               = 0x1000541,  /* U+0541 ARMENIAN CAPITAL LETTER JA */
+    XK_Armenian_dza               = 0x1000571,  /* U+0571 ARMENIAN SMALL LETTER JA */
+    XK_Armenian_GHAT              = 0x1000542,  /* U+0542 ARMENIAN CAPITAL LETTER GHAD */
+    XK_Armenian_ghat              = 0x1000572,  /* U+0572 ARMENIAN SMALL LETTER GHAD */
+    XK_Armenian_TCHE              = 0x1000543,  /* U+0543 ARMENIAN CAPITAL LETTER CHEH */
+    XK_Armenian_tche              = 0x1000573,  /* U+0573 ARMENIAN SMALL LETTER CHEH */
+    XK_Armenian_MEN               = 0x1000544,  /* U+0544 ARMENIAN CAPITAL LETTER MEN */
+    XK_Armenian_men               = 0x1000574,  /* U+0574 ARMENIAN SMALL LETTER MEN */
+    XK_Armenian_HI                = 0x1000545,  /* U+0545 ARMENIAN CAPITAL LETTER YI */
+    XK_Armenian_hi                = 0x1000575,  /* U+0575 ARMENIAN SMALL LETTER YI */
+    XK_Armenian_NU                = 0x1000546,  /* U+0546 ARMENIAN CAPITAL LETTER NOW */
+    XK_Armenian_nu                = 0x1000576,  /* U+0576 ARMENIAN SMALL LETTER NOW */
+    XK_Armenian_SHA               = 0x1000547,  /* U+0547 ARMENIAN CAPITAL LETTER SHA */
+    XK_Armenian_sha               = 0x1000577,  /* U+0577 ARMENIAN SMALL LETTER SHA */
+    XK_Armenian_VO                = 0x1000548,  /* U+0548 ARMENIAN CAPITAL LETTER VO */
+    XK_Armenian_vo                = 0x1000578,  /* U+0578 ARMENIAN SMALL LETTER VO */
+    XK_Armenian_CHA               = 0x1000549,  /* U+0549 ARMENIAN CAPITAL LETTER CHA */
+    XK_Armenian_cha               = 0x1000579,  /* U+0579 ARMENIAN SMALL LETTER CHA */
+    XK_Armenian_PE                = 0x100054a,  /* U+054A ARMENIAN CAPITAL LETTER PEH */
+    XK_Armenian_pe                = 0x100057a,  /* U+057A ARMENIAN SMALL LETTER PEH */
+    XK_Armenian_JE                = 0x100054b,  /* U+054B ARMENIAN CAPITAL LETTER JHEH */
+    XK_Armenian_je                = 0x100057b,  /* U+057B ARMENIAN SMALL LETTER JHEH */
+    XK_Armenian_RA                = 0x100054c,  /* U+054C ARMENIAN CAPITAL LETTER RA */
+    XK_Armenian_ra                = 0x100057c,  /* U+057C ARMENIAN SMALL LETTER RA */
+    XK_Armenian_SE                = 0x100054d,  /* U+054D ARMENIAN CAPITAL LETTER SEH */
+    XK_Armenian_se                = 0x100057d,  /* U+057D ARMENIAN SMALL LETTER SEH */
+    XK_Armenian_VEV               = 0x100054e,  /* U+054E ARMENIAN CAPITAL LETTER VEW */
+    XK_Armenian_vev               = 0x100057e,  /* U+057E ARMENIAN SMALL LETTER VEW */
+    XK_Armenian_TYUN              = 0x100054f,  /* U+054F ARMENIAN CAPITAL LETTER TIWN */
+    XK_Armenian_tyun              = 0x100057f,  /* U+057F ARMENIAN SMALL LETTER TIWN */
+    XK_Armenian_RE                = 0x1000550,  /* U+0550 ARMENIAN CAPITAL LETTER REH */
+    XK_Armenian_re                = 0x1000580,  /* U+0580 ARMENIAN SMALL LETTER REH */
+    XK_Armenian_TSO               = 0x1000551,  /* U+0551 ARMENIAN CAPITAL LETTER CO */
+    XK_Armenian_tso               = 0x1000581,  /* U+0581 ARMENIAN SMALL LETTER CO */
+    XK_Armenian_VYUN              = 0x1000552,  /* U+0552 ARMENIAN CAPITAL LETTER YIWN */
+    XK_Armenian_vyun              = 0x1000582,  /* U+0582 ARMENIAN SMALL LETTER YIWN */
+    XK_Armenian_PYUR              = 0x1000553,  /* U+0553 ARMENIAN CAPITAL LETTER PIWR */
+    XK_Armenian_pyur              = 0x1000583,  /* U+0583 ARMENIAN SMALL LETTER PIWR */
+    XK_Armenian_KE                = 0x1000554,  /* U+0554 ARMENIAN CAPITAL LETTER KEH */
+    XK_Armenian_ke                = 0x1000584,  /* U+0584 ARMENIAN SMALL LETTER KEH */
+    XK_Armenian_O                 = 0x1000555,  /* U+0555 ARMENIAN CAPITAL LETTER OH */
+    XK_Armenian_o                 = 0x1000585,  /* U+0585 ARMENIAN SMALL LETTER OH */
+    XK_Armenian_FE                = 0x1000556,  /* U+0556 ARMENIAN CAPITAL LETTER FEH */
+    XK_Armenian_fe                = 0x1000586,  /* U+0586 ARMENIAN SMALL LETTER FEH */
+    XK_Armenian_apostrophe        = 0x100055a,  /* U+055A ARMENIAN APOSTROPHE */
+    XK_Georgian_an                = 0x10010d0,  /* U+10D0 GEORGIAN LETTER AN */
+    XK_Georgian_ban               = 0x10010d1,  /* U+10D1 GEORGIAN LETTER BAN */
+    XK_Georgian_gan               = 0x10010d2,  /* U+10D2 GEORGIAN LETTER GAN */
+    XK_Georgian_don               = 0x10010d3,  /* U+10D3 GEORGIAN LETTER DON */
+    XK_Georgian_en                = 0x10010d4,  /* U+10D4 GEORGIAN LETTER EN */
+    XK_Georgian_vin               = 0x10010d5,  /* U+10D5 GEORGIAN LETTER VIN */
+    XK_Georgian_zen               = 0x10010d6,  /* U+10D6 GEORGIAN LETTER ZEN */
+    XK_Georgian_tan               = 0x10010d7,  /* U+10D7 GEORGIAN LETTER TAN */
+    XK_Georgian_in                = 0x10010d8,  /* U+10D8 GEORGIAN LETTER IN */
+    XK_Georgian_kan               = 0x10010d9,  /* U+10D9 GEORGIAN LETTER KAN */
+    XK_Georgian_las               = 0x10010da,  /* U+10DA GEORGIAN LETTER LAS */
+    XK_Georgian_man               = 0x10010db,  /* U+10DB GEORGIAN LETTER MAN */
+    XK_Georgian_nar               = 0x10010dc,  /* U+10DC GEORGIAN LETTER NAR */
+    XK_Georgian_on                = 0x10010dd,  /* U+10DD GEORGIAN LETTER ON */
+    XK_Georgian_par               = 0x10010de,  /* U+10DE GEORGIAN LETTER PAR */
+    XK_Georgian_zhar              = 0x10010df,  /* U+10DF GEORGIAN LETTER ZHAR */
+    XK_Georgian_rae               = 0x10010e0,  /* U+10E0 GEORGIAN LETTER RAE */
+    XK_Georgian_san               = 0x10010e1,  /* U+10E1 GEORGIAN LETTER SAN */
+    XK_Georgian_tar               = 0x10010e2,  /* U+10E2 GEORGIAN LETTER TAR */
+    XK_Georgian_un                = 0x10010e3,  /* U+10E3 GEORGIAN LETTER UN */
+    XK_Georgian_phar              = 0x10010e4,  /* U+10E4 GEORGIAN LETTER PHAR */
+    XK_Georgian_khar              = 0x10010e5,  /* U+10E5 GEORGIAN LETTER KHAR */
+    XK_Georgian_ghan              = 0x10010e6,  /* U+10E6 GEORGIAN LETTER GHAN */
+    XK_Georgian_qar               = 0x10010e7,  /* U+10E7 GEORGIAN LETTER QAR */
+    XK_Georgian_shin              = 0x10010e8,  /* U+10E8 GEORGIAN LETTER SHIN */
+    XK_Georgian_chin              = 0x10010e9,  /* U+10E9 GEORGIAN LETTER CHIN */
+    XK_Georgian_can               = 0x10010ea,  /* U+10EA GEORGIAN LETTER CAN */
+    XK_Georgian_jil               = 0x10010eb,  /* U+10EB GEORGIAN LETTER JIL */
+    XK_Georgian_cil               = 0x10010ec,  /* U+10EC GEORGIAN LETTER CIL */
+    XK_Georgian_char              = 0x10010ed,  /* U+10ED GEORGIAN LETTER CHAR */
+    XK_Georgian_xan               = 0x10010ee,  /* U+10EE GEORGIAN LETTER XAN */
+    XK_Georgian_jhan              = 0x10010ef,  /* U+10EF GEORGIAN LETTER JHAN */
+    XK_Georgian_hae               = 0x10010f0,  /* U+10F0 GEORGIAN LETTER HAE */
+    XK_Georgian_he                = 0x10010f1,  /* U+10F1 GEORGIAN LETTER HE */
+    XK_Georgian_hie               = 0x10010f2,  /* U+10F2 GEORGIAN LETTER HIE */
+    XK_Georgian_we                = 0x10010f3,  /* U+10F3 GEORGIAN LETTER WE */
+    XK_Georgian_har               = 0x10010f4,  /* U+10F4 GEORGIAN LETTER HAR */
+    XK_Georgian_hoe               = 0x10010f5,  /* U+10F5 GEORGIAN LETTER HOE */
+    XK_Georgian_fi                = 0x10010f6,  /* U+10F6 GEORGIAN LETTER FI */
+    XK_Xabovedot                  = 0x1001e8a,  /* U+1E8A LATIN CAPITAL LETTER X WITH DOT ABOVE */
+    XK_Ibreve                     = 0x100012c,  /* U+012C LATIN CAPITAL LETTER I WITH BREVE */
+    XK_Zstroke                    = 0x10001b5,  /* U+01B5 LATIN CAPITAL LETTER Z WITH STROKE */
+    XK_Gcaron                     = 0x10001e6,  /* U+01E6 LATIN CAPITAL LETTER G WITH CARON */
+    XK_Ocaron                     = 0x10001d1,  /* U+01D2 LATIN CAPITAL LETTER O WITH CARON */
+    XK_Obarred                    = 0x100019f,  /* U+019F LATIN CAPITAL LETTER O WITH MIDDLE TILDE */
+    XK_xabovedot                  = 0x1001e8b,  /* U+1E8B LATIN SMALL LETTER X WITH DOT ABOVE */
+    XK_ibreve                     = 0x100012d,  /* U+012D LATIN SMALL LETTER I WITH BREVE */
+    XK_zstroke                    = 0x10001b6,  /* U+01B6 LATIN SMALL LETTER Z WITH STROKE */
+    XK_gcaron                     = 0x10001e7,  /* U+01E7 LATIN SMALL LETTER G WITH CARON */
+    XK_ocaron                     = 0x10001d2,  /* U+01D2 LATIN SMALL LETTER O WITH CARON */
+    XK_obarred                    = 0x1000275,  /* U+0275 LATIN SMALL LETTER BARRED O */
+    XK_SCHWA                      = 0x100018f,  /* U+018F LATIN CAPITAL LETTER SCHWA */
+    XK_schwa                      = 0x1000259,  /* U+0259 LATIN SMALL LETTER SCHWA */
+    XK_Lbelowdot                  = 0x1001e36,  /* U+1E36 LATIN CAPITAL LETTER L WITH DOT BELOW */
+    XK_lbelowdot                  = 0x1001e37,  /* U+1E37 LATIN SMALL LETTER L WITH DOT BELOW */
+    XK_Abelowdot                  = 0x1001ea0,  /* U+1EA0 LATIN CAPITAL LETTER A WITH DOT BELOW */
+    XK_abelowdot                  = 0x1001ea1,  /* U+1EA1 LATIN SMALL LETTER A WITH DOT BELOW */
+    XK_Ahook                      = 0x1001ea2,  /* U+1EA2 LATIN CAPITAL LETTER A WITH HOOK ABOVE */
+    XK_ahook                      = 0x1001ea3,  /* U+1EA3 LATIN SMALL LETTER A WITH HOOK ABOVE */
+    XK_Acircumflexacute           = 0x1001ea4,  /* U+1EA4 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE */
+    XK_acircumflexacute           = 0x1001ea5,  /* U+1EA5 LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE */
+    XK_Acircumflexgrave           = 0x1001ea6,  /* U+1EA6 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE */
+    XK_acircumflexgrave           = 0x1001ea7,  /* U+1EA7 LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE */
+    XK_Acircumflexhook            = 0x1001ea8,  /* U+1EA8 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */
+    XK_acircumflexhook            = 0x1001ea9,  /* U+1EA9 LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */
+    XK_Acircumflextilde           = 0x1001eaa,  /* U+1EAA LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE */
+    XK_acircumflextilde           = 0x1001eab,  /* U+1EAB LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE */
+    XK_Acircumflexbelowdot        = 0x1001eac,  /* U+1EAC LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW */
+    XK_acircumflexbelowdot        = 0x1001ead,  /* U+1EAD LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW */
+    XK_Abreveacute                = 0x1001eae,  /* U+1EAE LATIN CAPITAL LETTER A WITH BREVE AND ACUTE */
+    XK_abreveacute                = 0x1001eaf,  /* U+1EAF LATIN SMALL LETTER A WITH BREVE AND ACUTE */
+    XK_Abrevegrave                = 0x1001eb0,  /* U+1EB0 LATIN CAPITAL LETTER A WITH BREVE AND GRAVE */
+    XK_abrevegrave                = 0x1001eb1,  /* U+1EB1 LATIN SMALL LETTER A WITH BREVE AND GRAVE */
+    XK_Abrevehook                 = 0x1001eb2,  /* U+1EB2 LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE */
+    XK_abrevehook                 = 0x1001eb3,  /* U+1EB3 LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE */
+    XK_Abrevetilde                = 0x1001eb4,  /* U+1EB4 LATIN CAPITAL LETTER A WITH BREVE AND TILDE */
+    XK_abrevetilde                = 0x1001eb5,  /* U+1EB5 LATIN SMALL LETTER A WITH BREVE AND TILDE */
+    XK_Abrevebelowdot             = 0x1001eb6,  /* U+1EB6 LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW */
+    XK_abrevebelowdot             = 0x1001eb7,  /* U+1EB7 LATIN SMALL LETTER A WITH BREVE AND DOT BELOW */
+    XK_Ebelowdot                  = 0x1001eb8,  /* U+1EB8 LATIN CAPITAL LETTER E WITH DOT BELOW */
+    XK_ebelowdot                  = 0x1001eb9,  /* U+1EB9 LATIN SMALL LETTER E WITH DOT BELOW */
+    XK_Ehook                      = 0x1001eba,  /* U+1EBA LATIN CAPITAL LETTER E WITH HOOK ABOVE */
+    XK_ehook                      = 0x1001ebb,  /* U+1EBB LATIN SMALL LETTER E WITH HOOK ABOVE */
+    XK_Etilde                     = 0x1001ebc,  /* U+1EBC LATIN CAPITAL LETTER E WITH TILDE */
+    XK_etilde                     = 0x1001ebd,  /* U+1EBD LATIN SMALL LETTER E WITH TILDE */
+    XK_Ecircumflexacute           = 0x1001ebe,  /* U+1EBE LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE */
+    XK_ecircumflexacute           = 0x1001ebf,  /* U+1EBF LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE */
+    XK_Ecircumflexgrave           = 0x1001ec0,  /* U+1EC0 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE */
+    XK_ecircumflexgrave           = 0x1001ec1,  /* U+1EC1 LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE */
+    XK_Ecircumflexhook            = 0x1001ec2,  /* U+1EC2 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */
+    XK_ecircumflexhook            = 0x1001ec3,  /* U+1EC3 LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */
+    XK_Ecircumflextilde           = 0x1001ec4,  /* U+1EC4 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE */
+    XK_ecircumflextilde           = 0x1001ec5,  /* U+1EC5 LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE */
+    XK_Ecircumflexbelowdot        = 0x1001ec6,  /* U+1EC6 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW */
+    XK_ecircumflexbelowdot        = 0x1001ec7,  /* U+1EC7 LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW */
+    XK_Ihook                      = 0x1001ec8,  /* U+1EC8 LATIN CAPITAL LETTER I WITH HOOK ABOVE */
+    XK_ihook                      = 0x1001ec9,  /* U+1EC9 LATIN SMALL LETTER I WITH HOOK ABOVE */
+    XK_Ibelowdot                  = 0x1001eca,  /* U+1ECA LATIN CAPITAL LETTER I WITH DOT BELOW */
+    XK_ibelowdot                  = 0x1001ecb,  /* U+1ECB LATIN SMALL LETTER I WITH DOT BELOW */
+    XK_Obelowdot                  = 0x1001ecc,  /* U+1ECC LATIN CAPITAL LETTER O WITH DOT BELOW */
+    XK_obelowdot                  = 0x1001ecd,  /* U+1ECD LATIN SMALL LETTER O WITH DOT BELOW */
+    XK_Ohook                      = 0x1001ece,  /* U+1ECE LATIN CAPITAL LETTER O WITH HOOK ABOVE */
+    XK_ohook                      = 0x1001ecf,  /* U+1ECF LATIN SMALL LETTER O WITH HOOK ABOVE */
+    XK_Ocircumflexacute           = 0x1001ed0,  /* U+1ED0 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE */
+    XK_ocircumflexacute           = 0x1001ed1,  /* U+1ED1 LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE */
+    XK_Ocircumflexgrave           = 0x1001ed2,  /* U+1ED2 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE */
+    XK_ocircumflexgrave           = 0x1001ed3,  /* U+1ED3 LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE */
+    XK_Ocircumflexhook            = 0x1001ed4,  /* U+1ED4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */
+    XK_ocircumflexhook            = 0x1001ed5,  /* U+1ED5 LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */
+    XK_Ocircumflextilde           = 0x1001ed6,  /* U+1ED6 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE */
+    XK_ocircumflextilde           = 0x1001ed7,  /* U+1ED7 LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE */
+    XK_Ocircumflexbelowdot        = 0x1001ed8,  /* U+1ED8 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW */
+    XK_ocircumflexbelowdot        = 0x1001ed9,  /* U+1ED9 LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW */
+    XK_Ohornacute                 = 0x1001eda,  /* U+1EDA LATIN CAPITAL LETTER O WITH HORN AND ACUTE */
+    XK_ohornacute                 = 0x1001edb,  /* U+1EDB LATIN SMALL LETTER O WITH HORN AND ACUTE */
+    XK_Ohorngrave                 = 0x1001edc,  /* U+1EDC LATIN CAPITAL LETTER O WITH HORN AND GRAVE */
+    XK_ohorngrave                 = 0x1001edd,  /* U+1EDD LATIN SMALL LETTER O WITH HORN AND GRAVE */
+    XK_Ohornhook                  = 0x1001ede,  /* U+1EDE LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE */
+    XK_ohornhook                  = 0x1001edf,  /* U+1EDF LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE */
+    XK_Ohorntilde                 = 0x1001ee0,  /* U+1EE0 LATIN CAPITAL LETTER O WITH HORN AND TILDE */
+    XK_ohorntilde                 = 0x1001ee1,  /* U+1EE1 LATIN SMALL LETTER O WITH HORN AND TILDE */
+    XK_Ohornbelowdot              = 0x1001ee2,  /* U+1EE2 LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW */
+    XK_ohornbelowdot              = 0x1001ee3,  /* U+1EE3 LATIN SMALL LETTER O WITH HORN AND DOT BELOW */
+    XK_Ubelowdot                  = 0x1001ee4,  /* U+1EE4 LATIN CAPITAL LETTER U WITH DOT BELOW */
+    XK_ubelowdot                  = 0x1001ee5,  /* U+1EE5 LATIN SMALL LETTER U WITH DOT BELOW */
+    XK_Uhook                      = 0x1001ee6,  /* U+1EE6 LATIN CAPITAL LETTER U WITH HOOK ABOVE */
+    XK_uhook                      = 0x1001ee7,  /* U+1EE7 LATIN SMALL LETTER U WITH HOOK ABOVE */
+    XK_Uhornacute                 = 0x1001ee8,  /* U+1EE8 LATIN CAPITAL LETTER U WITH HORN AND ACUTE */
+    XK_uhornacute                 = 0x1001ee9,  /* U+1EE9 LATIN SMALL LETTER U WITH HORN AND ACUTE */
+    XK_Uhorngrave                 = 0x1001eea,  /* U+1EEA LATIN CAPITAL LETTER U WITH HORN AND GRAVE */
+    XK_uhorngrave                 = 0x1001eeb,  /* U+1EEB LATIN SMALL LETTER U WITH HORN AND GRAVE */
+    XK_Uhornhook                  = 0x1001eec,  /* U+1EEC LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE */
+    XK_uhornhook                  = 0x1001eed,  /* U+1EED LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE */
+    XK_Uhorntilde                 = 0x1001eee,  /* U+1EEE LATIN CAPITAL LETTER U WITH HORN AND TILDE */
+    XK_uhorntilde                 = 0x1001eef,  /* U+1EEF LATIN SMALL LETTER U WITH HORN AND TILDE */
+    XK_Uhornbelowdot              = 0x1001ef0,  /* U+1EF0 LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW */
+    XK_uhornbelowdot              = 0x1001ef1,  /* U+1EF1 LATIN SMALL LETTER U WITH HORN AND DOT BELOW */
+    XK_Ybelowdot                  = 0x1001ef4,  /* U+1EF4 LATIN CAPITAL LETTER Y WITH DOT BELOW */
+    XK_ybelowdot                  = 0x1001ef5,  /* U+1EF5 LATIN SMALL LETTER Y WITH DOT BELOW */
+    XK_Yhook                      = 0x1001ef6,  /* U+1EF6 LATIN CAPITAL LETTER Y WITH HOOK ABOVE */
+    XK_yhook                      = 0x1001ef7,  /* U+1EF7 LATIN SMALL LETTER Y WITH HOOK ABOVE */
+    XK_Ytilde                     = 0x1001ef8,  /* U+1EF8 LATIN CAPITAL LETTER Y WITH TILDE */
+    XK_ytilde                     = 0x1001ef9,  /* U+1EF9 LATIN SMALL LETTER Y WITH TILDE */
+    XK_Ohorn                      = 0x10001a0,  /* U+01A0 LATIN CAPITAL LETTER O WITH HORN */
+    XK_ohorn                      = 0x10001a1,  /* U+01A1 LATIN SMALL LETTER O WITH HORN */
+    XK_Uhorn                      = 0x10001af,  /* U+01AF LATIN CAPITAL LETTER U WITH HORN */
+    XK_uhorn                      = 0x10001b0,  /* U+01B0 LATIN SMALL LETTER U WITH HORN */
+    XK_EcuSign                    = 0x10020a0,  /* U+20A0 EURO-CURRENCY SIGN */
+    XK_ColonSign                  = 0x10020a1,  /* U+20A1 COLON SIGN */
+    XK_CruzeiroSign               = 0x10020a2,  /* U+20A2 CRUZEIRO SIGN */
+    XK_FFrancSign                 = 0x10020a3,  /* U+20A3 FRENCH FRANC SIGN */
+    XK_LiraSign                   = 0x10020a4,  /* U+20A4 LIRA SIGN */
+    XK_MillSign                   = 0x10020a5,  /* U+20A5 MILL SIGN */
+    XK_NairaSign                  = 0x10020a6,  /* U+20A6 NAIRA SIGN */
+    XK_PesetaSign                 = 0x10020a7,  /* U+20A7 PESETA SIGN */
+    XK_RupeeSign                  = 0x10020a8,  /* U+20A8 RUPEE SIGN */
+    XK_WonSign                    = 0x10020a9,  /* U+20A9 WON SIGN */
+    XK_NewSheqelSign              = 0x10020aa,  /* U+20AA NEW SHEQEL SIGN */
+    XK_DongSign                   = 0x10020ab,  /* U+20AB DONG SIGN */
+    XK_EuroSign                   = 0x20ac,  /* U+20AC EURO SIGN */
+}
+

+ 1909 - 0
vendor/x11/xlib/xlib_procs.odin

@@ -0,0 +1,1909 @@
+//+build linux, openbsd, freebsd
+package xlib
+
+foreign import xlib "system:X11"
+foreign xlib {
+	@(link_name="_Xdebug") _Xdebug: i32
+}
+
+/* ----  X11/Xlib.h ---------------------------------------------------------*/
+
+@(default_calling_convention="c")
+foreign xlib {
+	// Free data allocated by Xlib
+	XFree              :: proc(ptr: rawptr) ---
+	// Opening/closing a display
+	XOpenDisplay       :: proc(name: cstring) -> ^Display ---
+	XCloseDisplay      :: proc(display: ^Display) ---
+	XSetCloseDownMode  :: proc(display: ^Display, mode: CloseMode) ---
+	// Generate a no-op request
+	XNoOp              :: proc(display: ^Display) ---
+	// Display macros (connection)
+	XConnectionNumber  :: proc(display: ^Display) -> i32 ---
+	XExtendedMaxRequestSize ::
+	                      proc(display: ^Display) -> int ---
+	XMaxRequestSize    :: proc(display: ^Display) -> int ---
+	XLastKnownRequestProcessed ::
+	                      proc(display: ^Display) -> uint ---
+	XNextRequest       :: proc(display: ^Display) -> uint ---
+	XProtocolVersion   :: proc(display: ^Display) -> i32 ---
+	XProtocolRevision  :: proc(display: ^Display) -> i32 ---
+	XQLength           :: proc(display: ^Display) -> i32 ---
+	XServerVendor      :: proc(display: ^Display) -> cstring ---
+	XVendorRelease     :: proc(display: ^Display) -> i32 ---
+	// Display macros (display properties)
+	XBlackPixel        :: proc(display: ^Display, screen_no: i32) -> uint ---
+	XWhitePixel        :: proc(display: ^Display, screen_no: i32) -> uint ---
+	XListDepths        :: proc(display: ^Display, screen_no: i32, count: ^i32) -> [^]i32 ---
+	XDisplayCells      :: proc(display: ^Display, screen_no: i32) -> i32 ---
+	XDisplayPlanes     :: proc(display: ^Display, screen_no: i32) -> i32 ---
+	XScreenOfDisplay   :: proc(display: ^Display, screen_no: i32) -> ^Screen ---
+	XDisplayString     :: proc(display: ^Display) -> cstring ---
+	// Display macros (defaults)
+	XDefaultColormap   :: proc(display: ^Display, screen_no: i32) -> Colormap ---
+	XDefaultDepth      :: proc(display: ^Display) -> i32 ---
+	XDefaultGC         :: proc(display: ^Display, screen_no: i32) -> GC ---
+	XDefaultRootWindow :: proc(display: ^Display) -> Window ---
+	XDefaultScreen     :: proc(display: ^Display) -> i32 ---
+	XDefaultVisual     :: proc(display: ^Display, screen_no: i32) -> ^Visual ---
+	XDefaultScreenOfDisplay ::
+	                      proc(display: ^Display) -> ^Screen ---
+	// Display macros (other)
+	XRootWindow        :: proc(display: ^Display, screen_no: i32) -> Window ---
+	XScreenCount       :: proc(display: ^Display) -> i32 ---
+	// Display image format macros
+	XListPixmapFormats :: proc(display: ^Display, count: ^i32) -> [^]XPixmapFormatValues ---
+	XImageByteOrder    :: proc(display: ^Display) -> ByteOrder ---
+	XBitmapUnit        :: proc(display: ^Display) -> i32 ---
+	XBitmapBitOrder    :: proc(display: ^Display) -> ByteOrder ---
+	XBitmapPad         :: proc(display: ^Display) -> i32 ---
+	XDisplayHeight     :: proc(display: ^Display, screen_no: i32) -> i32 ---
+	XDisplayHeightMM   :: proc(display: ^Display, screen_no: i32) -> i32 ---
+	XDisplayWidth      :: proc(display: ^Display, screen_no: i32) -> i32 ---
+	XDisplayWidthMM    :: proc(display: ^Display, screen_no: i32) -> i32 ---
+	// Screen macros
+	XBlackPixelsOfScreen :: proc(screen: ^Screen) -> uint ---
+	XWhitePixelsOfScreen :: proc(screen: ^Screen) -> uint ---
+	XCellsOfScreen       :: proc(screen: ^Screen) -> i32 ---
+	XDefaultColormapOfScreen :: proc(screen: ^Screen) -> Colormap ---
+	XDefaultDepthOfScreen    :: proc(screen: ^Screen) -> i32 ---
+	XDefaultGCOfScreen       :: proc(screen: ^Screen) -> GC ---
+	XDefaultVisualOfScreen   :: proc(screen: ^Screen) -> ^Visual ---
+	XDoesBackingStore    :: proc(screen: ^Screen) -> BackingStore ---
+	XDoesSaveUnders      :: proc(screen: ^Screen) -> b32 ---
+	XDisplayOfScreen     :: proc(screen: ^Screen) -> ^Display ---
+	XScreenNumberOfScreens :: proc(screen: ^Screen) -> i32 ---
+	XEventMaskOfScreen   :: proc(screen: ^Screen) -> EventMask ---
+	XWidthOfScreen       :: proc(screen: ^Screen) -> i32 ---
+	XHeightOfScreen      :: proc(screen: ^Screen) -> i32 ---
+	XWidthMMOfScreen     :: proc(screen: ^Screen) -> i32 ---
+	XHeightMMOfScreen    :: proc(screen: ^Screen) -> i32 ---
+	XMaxCmapsOfScreen    :: proc(screen: ^Screen) -> i32 ---
+	XMinCmapsOfScreen    :: proc(screen: ^Screen) -> i32 ---
+	XPlanesOfScreen      :: proc(screen: ^Screen) -> i32 ---
+	XRootWindowOfScreen  :: proc(screen: ^Screen) -> Window ---
+	// Threading functions
+	XInitThreads         :: proc() -> Status ---
+	XLockDisplay         :: proc(display: ^Display) ---
+	XUnlockDisplay       :: proc(display: ^Display) ---
+	// Internal connections
+	XAddConnectionWatch  :: proc(
+		display:   ^Display,
+		procedure: XConnectionWatchProc,
+		data:      rawptr,
+		) -> Status ---
+	XRemoveConnectionWatch :: proc(
+		display:   ^Display,
+		procedure: XConnectionWatchProc,
+		data:      rawptr,
+		) -> Status ---
+	XProcessInternalConnections :: proc(
+		display:   ^Display,
+		fd:        i32,
+		) ---
+	XInternalConnectionNumbers :: proc(
+		display:   ^Display,
+		fds:       ^[^]i32,
+		count:     ^i32,
+		) -> Status ---
+	// Windows functions
+	XVisualIDFromVisual :: proc(visual: ^Visual) -> VisualID ---
+	// Windows: creation/destruction
+	XCreateWindow :: proc(
+		display:   ^Display,
+		parent:    Window,
+		x:         i32,
+		y:         i32,
+		width:     u32,
+		height:    u32,
+		bordersz:  u32,
+		depth:     i32,
+		class:     WindowClass,
+		visual:    ^Visual,
+		attr_mask: WindowAttributeMask,
+		attr:      ^XSetWindowAttributes,
+		) -> Window ---
+	XCreateSimpleWindow :: proc(
+		display:   ^Display,
+		parent:    Window,
+		x:         i32,
+		y:         i32,
+		width:     u32,
+		height:    u32,
+		bordersz:  u32,
+		border:    int,
+		bg:        int,
+		) -> Window ---
+	XDestroyWindow     :: proc(display: ^Display, window: Window) ---
+	XDestroySubwindows :: proc(display: ^Display, window: Window) ---
+	// Windows: mapping/unmapping
+	XMapWindow         :: proc(display: ^Display, window: Window) ---
+	XMapRaised         :: proc(display: ^Display, window: Window) ---
+	XMapSubwindows     :: proc(display: ^Display, window: Window) ---
+	XUnmapWindow       :: proc(display: ^Display, window: Window) ---
+	XUnmapSubwindows   :: proc(display: ^Display, window: Window) ---
+	// Windows: configuring
+	XConfigureWindow :: proc(
+		display: ^Display,
+		window:  Window,
+		mask:    WindowChangesMask,
+		values:  XWindowChanges,
+		) ---
+	XMoveWindow :: proc(
+		display: ^Display,
+		window:  Window,
+		x:       i32,
+		y:       i32,
+		) ---
+	XResizeWindow :: proc(
+		display: ^Display,
+		window:  Window,
+		width:   u32,
+		height:  u32,
+		) ---
+	XMoveResizeWindow :: proc(
+		display: ^Display,
+		window:  Window,
+		x:       i32,
+		y:       i32,
+		width:   u32,
+		height:  u32,
+		) ---
+	XSetWindowBorderWidth :: proc(
+		display: ^Display,
+		window:  Window,
+		width:   u32,
+		) ---
+	// Window: changing stacking order
+	XRaiseWindow :: proc(display: ^Display, window: Window) ---
+	XLowerWindow :: proc(display: ^Display, window: Window) ---
+	XCirculateSubwindows :: proc(display: ^Display, window: Window, direction: CirculationDirection) ---
+	XCirculateSubwindowsUp :: proc(display: ^Display, window: Window) ---
+	XCirculateSubwindowsDown :: proc(display: ^Display, window: Window) ---
+	XRestackWindows :: proc(display: ^Display, windows: [^]Window, nwindows: i32) ---
+	// Window: changing attributes
+	XChangeWindowAttributes :: proc(
+		display:   ^Display,
+		window:    Window,
+		attr_mask: WindowAttributeMask,
+		attr:      XWindowAttributes,
+		) ---
+	XSetWindowBackground :: proc(
+		display:   ^Display,
+		window:    Window,
+		pixel:     uint,
+		) ---
+	XSetWindowBackgroundMap :: proc(
+		display:   ^Display,
+		window:    Window,
+		pixmap:    Pixmap,
+		) ---
+	XSetWindowColormap :: proc(
+		display:   ^Display,
+		window:    Window,
+		colormap:  Colormap,
+		) ---
+	XDefineCursor :: proc(
+		display:   ^Display,
+		window:    Window,
+		cursor:    Cursor,
+		) ---
+	XUndefineCursor :: proc(
+		display:   ^Display,
+		window:    Window,
+		) ---
+	// Windows: querying information
+	XQueryTree :: proc(
+		display:   ^Display,
+		window:    Window,
+		root:      ^Window,
+		parent:    ^Window,
+		children:  ^[^]Window,
+		nchildren: ^u32,
+		) -> Status ---
+	XGetWindowAttributes :: proc(
+		display: ^Display,
+		window:  Window,
+		attr:    ^XWindowAttributes,
+		) ---
+	XGetGeometry :: proc(
+		display:   ^Display,
+		drawable:  Drawable,
+		root:      ^Window,
+		x:         ^i32,
+		y:         ^i32,
+		width:     ^u32,
+		height:    ^u32,
+		border_sz: ^u32,
+		depth:     ^u32,
+		) -> Status ---
+	// Windows: translating screen coordinates
+	XTranslateCoordinates :: proc(
+		display: ^Display,
+		src_window: Window,
+		dst_window: Window,
+		src_x:      i32,
+		src_y:      i32,
+		dst_x:      ^i32,
+		dst_y:      ^i32,
+		) -> b32 ---
+	XQueryPointer :: proc(
+		display: ^Display,
+		window:  Window,
+		root:    ^Window,
+		child:   ^Window,
+		root_x:  ^i32,
+		root_y:  ^i32,
+		x:       ^i32,
+		y:       ^i32,
+		mask:    ^KeyMask,
+		) -> b32 ---
+	// Atoms
+	XInternAtom :: proc(
+		display:  ^Display,
+		name:     cstring,
+		existing: b32,
+		) -> Atom ---
+	XInternAtoms :: proc(
+		display: ^Display,
+		names:   [^]cstring,
+		count:   i32,
+		atoms:   [^]Atom,
+		) -> Status ---
+	XGetAtomName :: proc(
+		display: ^Display,
+		atom:    Atom,
+		) -> cstring ---
+	XGetAtomNames :: proc(
+		display: ^Display,
+		atoms:   [^]Atom,
+		count:   i32,
+		names:   [^]cstring,
+		) -> Status ---
+	// Windows: Obtaining and changing properties
+	XGetWindowProperty :: proc(
+		display:     ^Display,
+		window:      Window,
+		property:    Atom,
+		long_offs:   int,
+		long_len:    int,
+		delete:      b32,
+		req_type:    Atom,
+		act_type:    [^]Atom,
+		act_format:  [^]i32,
+		nitems:      [^]uint,
+		bytes_after: [^]uint,
+		props:       ^rawptr,
+	) -> i32 ---
+	XListProperties :: proc(
+		display:     ^Display,
+		window:      Window,
+		num:         ^i32,
+		) -> [^]Atom ---
+	XChangeProperty :: proc(
+		display:     ^Display,
+		window:      Window,
+		property:    Atom,
+		type:        Atom,
+		format:      i32,
+		mode:        i32,
+		data:        rawptr,
+		count:       i32,
+		) ---
+	XRotateWindowProperties :: proc(
+		display:     ^Display,
+		window:      Window,
+		props:       [^]Atom,
+		nprops:      i32,
+		npos:        i32,
+		) ---
+	XDeleteProperty :: proc(
+		display:     ^Display,
+		window:      Window,
+		prop:        Atom,
+		) ---
+	// Selections
+	XSetSelectionOwner :: proc(
+		display:     ^Display,
+		selection:   Atom,
+		owber:       Window,
+		time:        Time,
+		) ---
+	XGetSelectionOwner :: proc(
+		display:     ^Display,
+		selection:   Atom,
+		) -> Window ---
+	XConvertSelection :: proc(
+		display:     ^Display,
+		selection:   Atom,
+		target:      Atom,
+		property:    Atom,
+		requestor:   Window,
+		time:        Time,
+		) ---
+	// Creating and freeing pixmaps
+	XCreatePixmap :: proc(
+		display:   ^Display,
+		drawable:  Drawable,
+		width:     u32,
+		height:    u32,
+		depth:     u32,
+		) -> Pixmap ---
+	XFreePixmap :: proc(
+		display:   ^Display,
+		pixmap:    Pixmap,
+		) ---
+	// Creating recoloring and freeing cursors
+	XCreateFontCursor :: proc(
+		display:   ^Display,
+		shape:     CursorShape,
+		) -> Cursor ---
+	XCreateGlyphCursor :: proc(
+		display:   ^Display,
+		src_font:  Font,
+		mask_font: Font,
+		src_char:  u32,
+		mask_char: u32,
+		fg:        ^XColor,
+		bg:        ^XColor,
+		) -> Cursor ---
+	XCreatePixmapCursor :: proc(
+		display:   ^Display,
+		source:    Pixmap,
+		mask:      Pixmap,
+		fg:        XColor,
+		bg:        ^XColor,
+		x:         u32,
+		y:         u32,
+		) -> Cursor ---
+	XQueryBestCursor :: proc(
+		display:    ^Display,
+		drawable:   Drawable,
+		width:      u32,
+		height:     u32,
+		out_width:  ^u32,
+		out_height: ^u32,
+		) -> Status ---
+	XRecolorCursor :: proc(
+		display:    ^Display,
+		cursor:     Cursor,
+		fg:         ^XColor,
+		bg:         ^XColor,
+		) ---
+	XFreeCursor :: proc(display: ^Display, cursor: Cursor) ---
+	// Creation/destruction of colormaps
+	XCreateColormap :: proc(
+		display:  ^Display,
+		window:   Window,
+		visual:   ^Visual,
+		alloc:    ColormapAlloc,
+		) -> Colormap ---
+	XCopyColormapAndFree :: proc(
+		display:  ^Display,
+		colormap: Colormap,
+		) -> Colormap ---
+	XFreeColormap :: proc(
+		display:  ^Display,
+		colormap: Colormap,
+		) ---
+	// Mapping color names to values
+	XLookupColor :: proc(
+		display:  ^Display,
+		colomap:  Colormap,
+		name:     cstring,
+		exact:    ^XColor,
+		screen:   ^XColor,
+		) -> Status ---
+	XcmsLookupColor :: proc(
+		display:  ^Display,
+		colormap: Colormap,
+		name:     cstring,
+		exact:    XcmsColor,
+		screen:   XcmsColor,
+		format:   XcmsColorFormat,
+		) -> Status ---
+	// Allocating and freeing color cells
+	XAllocColor :: proc(
+		display:  ^Display,
+		colormap: Colormap,
+		screen:   ^XColor,
+		) -> Status ---
+	XcmsAllocColor :: proc(
+		display:  ^Display,
+		colormap: Colormap,
+		color:    ^XcmsColor,
+		format:   XcmsColorFormat,
+		) -> Status ---
+	XAllocNamedColor :: proc(
+		display:  ^Display,
+		colormap: Colormap,
+		name:     cstring,
+		screen:   ^XColor,
+		exact:    ^XColor,
+		) -> Status ---
+	XcmsAllocNamedColor :: proc(
+		display:  ^Display,
+		colormap: Colormap,
+		name:     cstring,
+		screen:   ^XcmsColor,
+		exact:    ^XcmsColor,
+		format:   XcmsColorFormat,
+		) -> Status ---
+	XAllocColorCells :: proc(
+		display:  ^Display,
+		colormap: Colormap,
+		contig:   b32,
+		pmasks:   [^]uint,
+		np:       u32,
+		pixels:   [^]uint,
+		npixels:  u32,
+		) -> Status ---
+	XAllocColorPlanes :: proc(
+		display:  ^Display,
+		colormap: Colormap,
+		contig:   b32,
+		pixels:   [^]uint,
+		ncolors:  i32,
+		nreds:    i32,
+		ngreens:  i32,
+		nblues:   i32,
+		rmask:    [^]uint,
+		gmask:    [^]uint,
+		bmask:    [^]uint,
+		) -> Status ---
+	XFreeColors :: proc(
+		display:  ^Display,
+		colormap: Colormap,
+		pixels:   [^]uint,
+		npixels:  i32,
+		planes:   uint,
+		) ---
+	// Modifying and querying colormap cells
+	XStoreColor :: proc(
+		display:  ^Display,
+		colormap: Colormap,
+		color:    ^XColor,
+		) ---
+	XStoreColors :: proc(
+		display:  ^Display,
+		colormap: Colormap,
+		color:    [^]XColor,
+		ncolors:  i32,
+		) ---
+	XcmsStoreColor :: proc(
+		display:  ^Display,
+		colormap: Colormap,
+		color:    ^XcmsColor,
+		) -> Status ---
+	XcmsStoreColors :: proc(
+		display:  ^Display,
+		colormap: Colormap,
+		colors:   [^]XcmsColor,
+		ncolors:  XcmsColor,
+		cflags:   [^]b32,
+		) -> Status ---
+	XStoreNamedColor :: proc(
+		display:  ^Display,
+		colormap: Colormap,
+		name:     cstring,
+		pixel:    uint,
+		flags:    ColorFlags,
+		) ---
+	XQueryColor :: proc(
+		display:  ^Display,
+		colormap: Colormap,
+		color:    ^XColor,
+		) ---
+	XQueryColors :: proc(
+		display:  ^Display,
+		colormap: Colormap,
+		colors:   [^]XColor,
+		ncolors:  i32,
+		) ---
+	XcmsQueryColor :: proc(
+		display:  ^Display,
+		colormap: Colormap,
+		color:    ^XcmsColor,
+		format:   XcmsColorFormat,
+		) -> Status ---
+	XcmsQueryColors :: proc(
+		display:  ^Display,
+		colormap: Colormap,
+		color:    [^]XcmsColor,
+		ncolors:  i32,
+		format:   XcmsColorFormat,
+		) -> Status ---
+	// Getting and setting the color conversion context (CCC) of a colormap
+	XcmsCCCOfColormap :: proc(
+		display:  ^Display,
+		colormap: Colormap,
+		) -> XcmsCCC ---
+	XcmsSetCCCOfColormap :: proc(
+		display:  ^Display,
+		colormap: Colormap,
+		ccc:      XcmsCCC) -> XcmsCCC ---
+	XcmsDefaultCCC :: proc(display:   ^Display, screen_no: i32) -> XcmsCCC ---
+	// Color conversion context macros
+	XcmsDisplayOfCCC :: proc(ccc: XcmsCCC) -> ^Display ---
+	XcmsVisualOfCCC  :: proc(ccc: XcmsCCC) -> ^Visual ---
+	XcmsScreenNumberOfCCC ::
+						proc(ccc: XcmsCCC) -> i32 ---
+	XcmsScreenWhitePointOfCCC ::
+						proc(ccc: XcmsCCC) -> XcmsColor ---
+	XcmsClientWhitePointOfCCC ::
+						proc(ccc: XcmsCCC) -> XcmsColor ---
+	// Modifying the attributes of color conversion context
+	XcmsSetWhitePoint :: proc(
+		ccc: XcmsCCC,
+		color: ^XcmsColor,
+		) -> Status ---
+	XcmsSetCompressionProc :: proc(
+		ccc: XcmsCCC,
+		cproc: XcmsCompressionProc,
+		data: rawptr,
+		) -> XcmsCompressionProc ---
+	XcmsSetWhiteAdjustProc :: proc(
+		ccc: XcmsCCC,
+		aproc: XcmsWhiteAdjustProc,
+		data: rawptr,
+		) -> XcmsWhiteAdjustProc ---
+	// Creating and freeing the color conversion context
+	XcmsCreateCCC :: proc(
+		display: ^Display,
+		screen_no: i32,
+		visual: ^Visual,
+		white_point: ^XcmsColor,
+		cproc: XcmsCompressionProc,
+		cdata: rawptr,
+		aproc: XcmsWhiteAdjustProc,
+		adata: rawptr,
+		) -> XcmsCCC ---
+	XcmsFreeCCC :: proc(ccc: XcmsCCC) ---
+	// Converting between colorspaces
+	XcmsConvertColors :: proc(
+		ccc:     XcmsCCC,
+		colors:  [^]XcmsColor,
+		ncolors: u32,
+		format:  XcmsColorFormat,
+		cflags:  [^]b32,
+		) -> Status ---
+	// Pre-defined gamut compression callbacks
+	XcmsCIELabClipL :: proc(
+		ctx:     XcmsCCC,
+		colors:  [^]XcmsColor,
+		ncolors: u32,
+		index:   u32,
+		flags:   [^]b32,
+		) -> Status ---
+	XcmsCIELabClipab :: proc(
+		ctx:     XcmsCCC,
+		colors:  [^]XcmsColor,
+		ncolors: u32,
+		index:   u32,
+		flags:   [^]b32,
+		) -> Status ---
+	XcmsCIELabClipLab :: proc(
+		ctx:     XcmsCCC,
+		colors:  [^]XcmsColor,
+		ncolors: u32,
+		index:   u32,
+		flags:   [^]b32,
+		) -> Status ---
+	XcmsCIELuvClipL :: proc(
+		ctx:     XcmsCCC,
+		colors:  [^]XcmsColor,
+		ncolors: u32,
+		index:   u32,
+		flags:   [^]b32,
+		) -> Status ---
+	XcmsCIELuvClipuv :: proc(
+		ctx:     XcmsCCC,
+		colors:  [^]XcmsColor,
+		ncolors: u32,
+		index:   u32,
+		flags:   [^]b32,
+		) -> Status ---
+	XcmsCIELuvClipLuv :: proc(
+		ctx:     XcmsCCC,
+		colors:  [^]XcmsColor,
+		ncolors: u32,
+		index:   u32,
+		flags:   [^]b32,
+		) -> Status ---
+	XcmsTekHVCClipV :: proc(
+		ctx:     XcmsCCC,
+		colors:  [^]XcmsColor,
+		ncolors: u32,
+		index:   u32,
+		flags:   [^]b32,
+		) -> Status ---
+	XcmsTekHVCClipC :: proc(
+		ctx:     XcmsCCC,
+		colors:  [^]XcmsColor,
+		ncolors: u32,
+		index:   u32,
+		flags:   [^]b32,
+		) -> Status ---
+	XcmsTekHVCClipVC :: proc(
+		ctx:     XcmsCCC,
+		colors:  [^]XcmsColor,
+		ncolors: u32,
+		index:   u32,
+		flags:   [^]b32,
+		) -> Status ---
+	// Pre-defined white-point adjustment procedures
+	XcmsCIELabWhiteShiftColors :: proc(
+		ctx:                 XcmsCCC,
+		initial_white_point: ^XcmsColor,
+		target_white_point:  ^XcmsColor,
+		target_format:       XcmsColorFormat,
+		colors:              [^]XcmsColor,
+		ncolors:             u32,
+		compression:         [^]b32,
+		) -> Status ---
+	XcmsCIELuvWhiteShiftColors :: proc(
+		ctx:                 XcmsCCC,
+		initial_white_point: ^XcmsColor,
+		target_white_point:  ^XcmsColor,
+		target_format:       XcmsColorFormat,
+		colors:              [^]XcmsColor,
+		ncolors:             u32,
+		compression:         [^]b32,
+		) -> Status ---
+	XcmsTekHVCWhiteShiftColors :: proc(
+		ctx:                 XcmsCCC,
+		initial_white_point: ^XcmsColor,
+		target_white_point:  ^XcmsColor,
+		target_format:       XcmsColorFormat,
+		colors:              [^]XcmsColor,
+		ncolors:             u32,
+		compression:         [^]b32,
+		) -> Status ---
+	// Color querying
+	XcmsQueryBlack :: proc(
+		ccc:    XcmsCCC,
+		format: XcmsColorFormat,
+		color:  ^XcmsColor,
+		) -> Status ---
+	XcmsQueryBlue :: proc(
+		ccc:    XcmsCCC,
+		format: XcmsColorFormat,
+		color:  ^XcmsColor,
+		) -> Status ---
+	XcmsQueryGreen :: proc(
+		ccc:    XcmsCCC,
+		format: XcmsColorFormat,
+		color:  ^XcmsColor,
+		) -> Status ---
+	XcmsQueryRed :: proc(
+		ccc:    XcmsCCC,
+		format: XcmsColorFormat,
+		color:  ^XcmsColor,
+		) -> Status ---
+	XcmsQueryWhite :: proc(
+		ccc:    XcmsCCC,
+		format: XcmsColorFormat,
+		color:  ^XcmsColor,
+		) -> Status ---
+	// CIELab queries
+	XcmsCIELabQueryMaxC :: proc(
+		ccc:   XcmsCCC,
+		hue:   XcmsFloat,
+		lstar: XcmsFloat,
+		color: ^XcmsColor,
+		) -> Status ---
+	XcmsCIELabQueryMaxL :: proc(
+		ccc:    XcmsCCC,
+		hue:    XcmsFloat,
+		chroma: XcmsFloat,
+		color:  ^XcmsColor,
+		) -> Status ---
+	XcmsCIELabQueryMaxLC :: proc(
+		ccc:    XcmsCCC,
+		hue:    XcmsFloat,
+		color:  ^XcmsColor,
+		) -> Status ---
+	XcmsCIELabQueryMinL :: proc(
+		ccc:    XcmsCCC,
+		hue:    XcmsFloat,
+		chroma: XcmsFloat,
+		color:  ^XcmsColor,
+		) -> Status ---
+	// CIEluv queries
+	XcmsCIELuvQueryMaxC :: proc(
+		ccc:   XcmsCCC,
+		hue:   XcmsFloat,
+		lstar: XcmsFloat,
+		color: ^XcmsColor,
+		) -> Status ---
+	XcmsCIELuvQueryMaxL :: proc(
+		ccc:    XcmsCCC,
+		hue:    XcmsFloat,
+		chroma: XcmsFloat,
+		color:  ^XcmsColor,
+		) -> Status ---
+	XcmsCIELuvQueryMaxLC :: proc(
+		ccc:   XcmsCCC,
+		hue:   XcmsFloat,
+		color: ^XcmsColor,
+		) -> Status ---
+	XcmsCIELuvQueryMinL :: proc(
+		ccc:    XcmsCCC,
+		hue:    XcmsFloat,
+		chroma: XcmsFloat,
+		color:  ^XcmsColor,
+		) -> Status ---
+	// TexHVX queries
+	XcmsTekHVCQueryMaxC :: proc(
+		ccc:   XcmsCCC,
+		hue:   XcmsFloat,
+		value: XcmsFloat,
+		color: ^XcmsColor,
+		) -> Status ---
+	XcmsTekHVCQueryMaxV :: proc(
+		ccc:    XcmsCCC,
+		hue:    XcmsFloat,
+		chroma: XcmsFloat,
+		color:  ^XcmsColor,
+		) -> Status ---
+	XcmsTekHVCQueryMaxVC :: proc(
+		ccc:    XcmsCCC,
+		hue:    XcmsFloat,
+		color:  ^XcmsColor,
+		) -> Status ---
+	XcmsTekHVCQueryMaxVSamples :: proc(
+		ccc:      XcmsCCC,
+		hue:      XcmsFloat,
+		colors:   [^]XcmsColor,
+		nsamples: u32,
+		) -> Status ---
+	XcmsTekHVCQueryMinV :: proc(
+		ccc:    XcmsCCC,
+		hue:    XcmsFloat,
+		chroma: XcmsFloat,
+		color:  ^XcmsColor,
+		) -> Status ---
+	// Graphics context functions
+	XCreateGC :: proc(
+		display:  ^Display,
+		drawable: Drawable,
+		mask:     GCAttributeMask,
+		attr:     ^XGCValues,
+		) -> GC ---
+	XCopyGC :: proc(
+		display:  ^Display,
+		src:      GC,
+		dst:      GC,
+		mask:     GCAttributeMask,
+		) ---
+	XChangeGC :: proc(
+		display:  ^Display,
+		gc:       GC,
+		mask:     GCAttributeMask,
+		values:   ^XGCValues,
+		) ---
+	XGetGCValues :: proc(
+		display:  ^Display,
+		gc:       GC,
+		mask:     GCAttributeMask,
+		values:   ^XGCValues,
+		) -> Status ---
+	XFreeGC :: proc(display: ^Display, gc: GC) ---
+	XGCContextFromGC :: proc(gc: GC) -> GContext ---
+	XFlushGC :: proc(display: ^Display, gc: GC) ---
+	// Convenience routines for GC
+	XSetState :: proc(
+		display: ^Display,
+		gc:      GC,
+		fg:      uint,
+		bg:      uint,
+		fn:      GCFunction,
+		pmask:   uint,
+		) ---
+	XSetForeground :: proc(
+		display: ^Display,
+		gc:      GC,
+		fg:      uint,
+		) ---
+	XSetBackground :: proc(
+		display: ^Display,
+		gc:      GC,
+		bg:      uint,
+		) ---
+	XSetFunction :: proc(
+		display: ^Display,
+		gc:      GC,
+		fn:      GCFunction,
+		) ---
+	XSetPlaneMask :: proc(
+		display: ^Display,
+		gc:      GC,
+		pmask:   uint,
+		) ---
+	XSetLineAttributes :: proc(
+		display:    ^Display,
+		gc:         GC,
+		width:      u32,
+		line_style: LineStyle,
+		cap_style:  CapStyle,
+		join_style: JoinStyle,
+		) ---
+	XSetDashes :: proc(
+		display:   ^Display,
+		gc:        GC,
+		dash_offs: i32,
+		dash_list: [^]i8,
+		n:         i32,
+		) ---
+	XSetFillStyle :: proc(
+		display: ^Display,
+		gc:      GC,
+		style:   FillStyle,
+		) ---
+	XSetFillRule :: proc(
+		display: ^Display,
+		gc:      GC,
+		rule:    FillRule,
+		) ---
+	XQueryBestSize :: proc(
+		display:    ^Display,
+		class:      i32,
+		which:      Drawable,
+		width:      u32,
+		height:     u32,
+		out_width:  ^u32,
+		out_height: ^u32,
+		) -> Status ---
+	XQueryBestTile :: proc(
+		display:    ^Display,
+		which:      Drawable,
+		width:      u32,
+		height:     u32,
+		out_width:  ^u32,
+		out_height: ^u32,
+		) -> Status ---
+	XQueryBestStripple :: proc(
+		display:    ^Display,
+		which:      Drawable,
+		width:      u32,
+		height:     u32,
+		out_width:  u32,
+		out_height: u32,
+		) -> Status ---
+	XSetTile       :: proc(display: ^Display, gc: GC, tile: Pixmap) ---
+	XSetStripple   :: proc(display: ^Display, gc: GC, stripple: Pixmap) ---
+	XSetTSOrigin   :: proc(display: ^Display, gc: GC, x: i32, y: i32) ---
+	XSetFont       :: proc(display: ^Display, gc: GC, font: Font) ---
+	XSetClipOrigin :: proc(display: ^Display, gc: GC, x: i32, y: i32) ---
+	XSetClipMask   :: proc(display: ^Display, gc: GC, pixmap: Pixmap) ---
+	XSetClipRectangles :: proc(
+		display:  ^Display,
+		gc:       GC,
+		x:        i32,
+		y:        i32,
+		rects:    [^]XRectangle,
+		n:        i32,
+		ordering: i32,
+		) ---
+	XSetArcMode           :: proc(display: ^Display, gc: GC, mode: ArcMode) ---
+	XSetSubwindowMode     :: proc(display: ^Display, gc: GC, mode: SubwindowMode) ---
+	XSetGraphicsExposures :: proc(display: ^Display, gc: GC, exp: b32) ---
+	// Graphics functions
+	XClearArea :: proc(
+		display: ^Display, 
+		window:  Window, 
+		x:       i32, 
+		y:       i32, 
+		width:   u32, 
+		height:  u32, 
+		exp:     b32,
+		) ---
+	XClearWindow :: proc(
+		display: ^Display,
+		window: Window,
+		) ---
+	XCopyArea :: proc(
+		display: ^Display,
+		src:     Drawable,
+		dst:     Drawable,
+		gc:      GC,
+		src_x:   i32,
+		src_y:   i32,
+		width:   u32,
+		height:  u32,
+		dst_x:   i32,
+		dst_y:   i32,
+		) ---
+	XCopyPlane :: proc(
+		display: ^Display,
+		src:     Drawable,
+		dst:     Drawable,
+		gc:      GC,
+		src_x:   i32,
+		src_y:   i32,
+		width:   u32,
+		height:  u32,
+		dst_x:   i32,
+		dst_y:   i32,
+		plane:   uint,
+		) ---
+	// Drawing lines, points, rectangles and arc
+	XDrawPoint :: proc(
+		display:  ^Display,
+		drawable: Drawable,
+		gc:       GC,
+		x:        i32,
+		y:        i32,
+		) ---
+	XDrawPoints :: proc(
+		display:  Display,
+		drawable: Drawable,
+		gc:       GC,
+		point:    [^]XPoint,
+		npoints:  i32,
+		mode:     CoordMode,
+		) ---
+	XDrawLine :: proc(
+		display:  ^Display,
+		drawable: Drawable,
+		gc:       GC,
+		x1:       i32,
+		y1:       i32,
+		x2:       i32,
+		y2:       i32,
+		) ---
+	XDrawLines :: proc(
+		display:  ^Display,
+		drawable: Drawable,
+		gc:       GC,
+		points:   [^]XPoint,
+		npoints:  i32,
+		) ---
+	XDrawSegments :: proc(
+		display:  ^Display,
+		drawable: Drawable,
+		gc:       GC,
+		segs:     [^]XSegment,
+		nsegs:    i32,
+		) ---
+	XDrawRectangle :: proc(
+		display:  ^Display,
+		drawable: Drawable,
+		gc:       GC,
+		x:        i32,
+		y:        i32,
+		width:    u32,
+		height:   u32,
+		) ---
+	XDrawRectangles :: proc(
+		display:  ^Display,
+		drawable: Drawable,
+		gc:       GC,
+		rects:    [^]XRectangle,
+		nrects:   i32,
+		) ---
+	XDrawArc :: proc(
+		display:  ^Display,
+		drawable: Drawable,
+		gc:       GC,
+		x:        i32,
+		y:        i32,
+		width:    u32,
+		height:   u32,
+		angle1:   i32,
+		angle2:   i32,
+		) ---
+	XDrawArcs :: proc(
+		display:  ^Display,
+		drawable: Drawable,
+		gc:       GC,
+		arcs:     [^]XArc,
+		narcs:    i32,
+		) ---
+	// Filling areas
+	XFillRectangle :: proc(
+		display:  ^Display,
+		drawable: Drawable,
+		gc:       GC,
+		x:        i32,
+		y:        i32,
+		width:    u32,
+		height:   u32,
+		) ---
+	XFillRectangles :: proc(
+		display:  ^Display,
+		drawable: Drawable,
+		gc:       GC,
+		rects:    [^]XRectangle,
+		nrects:   i32,
+		) ---
+	XFillPolygon :: proc(
+		display:  ^Display,
+		drawable: Drawable,
+		gc:       GC,
+		points:   [^]XPoint,
+		npoints:  i32,
+		shape:    Shape,
+		mode:     CoordMode,
+		) ---
+	XFillArc :: proc(
+		display:  ^Display,
+		drawable: Drawable,
+		gc:       GC,
+		x:        i32,
+		y:        i32,
+		width:    u32,
+		height:   u32,
+		angle1:   i32,
+		angle2:   i32,
+		) ---
+	XFillArcs :: proc(
+		display:  ^Display,
+		drawable: Drawable,
+		gc:       GC,
+		arcs:     [^]XArc,
+		narcs:    i32,
+		) ---
+	// Font metrics
+	XLoadFont        :: proc(display: ^Display, name: cstring) -> Font ---
+	XQueryFont       :: proc(display: ^Display, id: XID) -> ^XFontStruct ---
+	XLoadQueryFont   :: proc(display: ^Display, name: cstring) -> ^XFontStruct ---
+	XFreeFont        :: proc(display: ^Display, font_struct: ^XFontStruct) ---
+	XGetFontProperty :: proc(font_struct: ^XFontStruct, atom: Atom, ret: ^uint) -> b32 ---
+	XUnloadFont      :: proc(display: ^Display, font: Font) ---
+	XListFonts       :: proc(display: ^Display, pat: cstring, max: i32, count: ^i32) -> [^]cstring ---
+	XFreeFontNames   :: proc(display: ^Display, list: [^]cstring) ---
+	XListFontsWithInfo :: proc(
+		display: ^Display,
+		pat:     cstring,
+		max:     i32,
+		count:   ^i32,
+		info:    ^[^]XFontStruct,
+		) -> [^]cstring ---
+	XFreeFontInfo :: proc(names: [^]cstring, info: [^]XFontStruct, count: i32) ---
+	// Computing character string sizes
+	XTextWidth :: proc(font_struct: ^XFontStruct, string: [^]u8, count: i32) -> i32 ---
+	XTextWidth16 :: proc(font_struct: ^XFontStruct, string: [^]XChar2b, count: i32) -> i32 ---
+	XTextExtents :: proc(
+		font_struct: ^XFontStruct,
+		string:      [^]u8,
+		nchars:      i32,
+		direction:   ^FontDirection,
+		ascent:      ^i32,
+		descent:     ^i32,
+		ret:         ^XCharStruct,
+		) ---
+	XTextExtents16 :: proc(
+		font_struct: ^XFontStruct,
+		string:      [^]XChar2b,
+		nchars:      i32,
+		direction:   ^FontDirection,
+		ascent:      ^i32,
+		descent:     ^i32,
+		ret:         ^XCharStruct,
+		) ---
+	XQueryTextExtents :: proc(
+		display:     ^Display,
+		font_id:     XID,
+		string:      [^]u8,
+		nchars:      i32,
+		direction:   ^FontDirection,
+		ascent:      ^i32,
+		descent:     ^i32,
+		ret:         ^XCharStruct,
+		) ---
+	XQueryTextExtents16 :: proc(
+		display:     ^Display,
+		font_id:     XID,
+		string:      [^]XChar2b,
+		nchars:      i32,
+		direction:   ^FontDirection,
+		ascent:      ^i32,
+		descent:     ^i32,
+		ret:         ^XCharStruct,
+		) ---
+	// Drawing complex text
+	XDrawText :: proc(
+		display:  ^Display,
+		drawable: Drawable,
+		gc:       GC,
+		x:        i32,
+		y:        i32,
+		items:    XTextItem,
+		nitems:   i32,
+		) ---
+	XDrawText16 :: proc(
+		display:  ^Display,
+		drawable: Drawable,
+		gc:       GC,
+		x:        i32,
+		y:        i32,
+		items:    XTextItem16,
+		nitems:   i32,
+		) ---
+	// Drawing text characters
+	XDrawString :: proc(
+		display:  ^Display,
+		drawable: Drawable,
+		gc:       GC,
+		x:        i32,
+		y:        i32,
+		string:   [^]u8,
+		length:   i32,
+		) ---
+	XDrawString16 :: proc(
+		display:  ^Display,
+		drawable: Drawable,
+		gc:       GC,
+		x:        i32,
+		y:        i32,
+		string:   [^]XChar2b,
+		length:   i32,
+		) ---
+	XDrawImageString :: proc(
+		display:  ^Display,
+		drawable: Drawable,
+		gc:       GC,
+		x:        i32,
+		y:        i32,
+		string:   [^]u8,
+		length:   i32,
+		) ---
+	XDrawImageString16 :: proc(
+		display:  ^Display,
+		drawable: Drawable,
+		gc:       GC,
+		x:        i32,
+		y:        i32,
+		string:   [^]XChar2b,
+		length:   i32,
+		) ---
+	// Transferring images between client and server
+	XInitImage :: proc(image: ^XImage) -> Status ---
+	XPutImage :: proc(
+		display:  ^Display,
+		drawable: Drawable,
+		gc:       GC,
+		image:    ^XImage,
+		src_x:    i32,
+		src_y:    i32,
+		dst_x:    i32,
+		dst_y:    i32,
+		width:    u32,
+		height:   u32,
+		) ---
+	XGetImage :: proc(
+		display:  ^Display,
+		drawable: Drawable,
+		x:        i32,
+		y:        i32,
+		width:    u32,
+		height:   u32,
+		mask:     uint,
+		format:   ImageFormat,
+		) -> ^XImage ---
+	XGetSubImage :: proc(
+		display:  ^Display,
+		drawable: Drawable,
+		src_x:    i32,
+		src_y:    i32,
+		width:    u32,
+		height:   u32,
+		mask:     uint,
+		format:   ImageFormat,
+		dst:      ^XImage,
+		dst_x:    i32,
+		dst_y:    i32,
+		) -> ^XImage ---
+	// Window and session manager functions
+	XReparentWindow :: proc(
+		display: ^Display,
+		window:  Window,
+		parent:  Window,
+		x:       i32,
+		y:       i32,
+		) ---
+	XChangeSaveSet :: proc(
+		display: ^Display,
+		window:  Window,
+		mode:    SaveSetChangeMode,
+		) ---
+	XAddToSaveSet :: proc(
+		display: ^Display,
+		window:  Window,
+		) ---
+	XRemoveFromSaveSet :: proc(
+		display: ^Display,
+		window:  Window,
+		) ---
+	// Managing installed colormaps
+	XInstallColormap        :: proc(display: ^Display, colormap: Colormap) ---
+	XUninstallColormap      :: proc(display: ^Display, colormap: Colormap) ---
+	XListInstalledColormaps :: proc(display: ^Display, window: Window, n: ^i32) -> [^]Colormap ---
+	// Setting and retrieving font search paths
+	XSetFontPath            :: proc(display: ^Display, dirs: [^]cstring, ndirs: i32) ---
+	XGetFontPath            :: proc(display: ^Display, npaths: ^i32) -> [^]cstring ---
+	XFreeFontPath           :: proc(list: [^]cstring) ---
+	// Grabbing the server
+	XGrabServer             :: proc(display: ^Display) ---
+	XUngrabServer           :: proc(display: ^Display) ---
+	// Killing clients
+	XKillClient             :: proc(display: ^Display, resource: XID) ---
+	// Controlling the screen saver
+	XSetScreenSaver :: proc(
+		display:   ^Display,
+		timeout:   i32,
+		interval:  i32,
+		blanking:  ScreenSaverBlanking,
+		exposures: ScreenSavingExposures,
+		) ---
+	XForceScreenSaver    :: proc(display: ^Display, mode: ScreenSaverForceMode) ---
+	XActivateScreenSaver :: proc(display: ^Display) ---
+	XResetScreenSaver    :: proc(display: ^Display) ---
+	XGetScreenSaver :: proc(
+		display: ^Display,
+		timeout: ^i32,
+		interval: ^i32,
+		blanking: ^ScreenSaverBlanking,
+		exposures: ^ScreenSavingExposures,
+		) ---
+	// Controlling host address
+	XAddHost     :: proc(display: ^Display, addr: ^XHostAddress) ---
+	XAddHosts    :: proc(display: ^Display, hosts: [^]XHostAddress, nhosts: i32) ---
+	XListHosts   :: proc(display: ^Display, nhosts: ^i32, state: [^]b32) -> [^]XHostAddress ---
+	XRemoveHost  :: proc(display: ^Display, host: XHostAddress) ---
+	XRemoveHosts :: proc(display: ^Display, hosts: [^]XHostAddress, nhosts: i32) ---
+	// Access control list
+	XSetAccessControl     :: proc(display: ^Display, mode: AccessControlMode) ---
+	XEnableAccessControl  :: proc(display: ^Display) ---
+	XDisableAccessControl :: proc(display: ^Display) ---
+	// Events
+	XSelectInput  :: proc(display: ^Display, window: Window, mask: EventMask) ---
+	XFlush        :: proc(display: ^Display) ---
+	XSync         :: proc(display: ^Display) ---
+	XEventsQueued :: proc(display: ^Display, mode: EventQueueMode) -> i32 ---
+	XPending      :: proc(display: ^Display) -> i32 ---
+	XNextEvent    :: proc(display: ^Display, event: ^XEvent) ---
+	XPeekEvent    :: proc(display: ^Display, event: ^XEvent) ---
+	// Selecting events using a predicate procedure
+	XIfEvent :: proc(
+		display:   ^Display,
+		event:     ^XEvent,
+		predicate: #type proc "c" (display: ^Display, event: ^XEvent, ctx: rawptr) -> b32,
+		ctx:       rawptr,
+		) ---
+	XCheckIfEvent :: proc(
+		display:   ^Display,
+		event:     ^XEvent,
+		predicate: #type proc "c" (display: ^Display, event: ^XEvent, ctx: rawptr) -> b32,
+		arg:       rawptr,
+		) -> b32 ---
+	XPeekIfEvent :: proc(
+		display:   ^Display,
+		event:     ^XEvent,
+		predicate: #type proc "c" (display: ^Display, event: ^XEvent, ctx: rawptr) -> b32,
+		ctx:       rawptr,
+		) ---
+	// Selecting events using a window or event mask
+	XWindowEvent :: proc(
+		display:   ^Display,
+		window:    Window,
+		mask:      EventMask,
+		event:     ^XEvent,
+		) ---
+	XCheckWindowEvent :: proc(
+		display:   ^Display,
+		window:    Window,
+		mask:      EventMask,
+		event:     ^XEvent,
+		) -> b32 ---
+	XMaskEvent :: proc(
+		display: ^Display,
+		mask:    EventMask,
+		event:   ^XEvent,
+		) ---
+	XCheckMaskEvent :: proc(
+		display: ^Display,
+		mask:    EventMask,
+		event:   ^XEvent,
+		) -> b32 ---
+	XCheckTypedEvent :: proc(
+		display: ^Display,
+		type:    EventType,
+		event:   ^XEvent,
+		) -> b32 ---
+	XCheckTypedWindowEvent :: proc(
+		display: ^Display,
+		window:  Window,
+		type:    EventType,
+		event:   ^XEvent,
+		) -> b32 ---
+	// Putting events back
+	XPutBackEvent :: proc(
+		display: ^Display,
+		event:   ^XEvent,
+		) ---
+	// Sending events to other applications
+	XSendEvent :: proc(
+		display:   ^Display,
+		window:    Window,
+		propagate: b32,
+		mask:      EventMask,
+		event:     ^XEvent,
+		) -> Status ---
+	// Getting the history of pointer motion
+	XDisplayMotionBufferSize :: proc(display: ^Display) -> uint ---
+	XGetMotionEvents :: proc(
+		display: ^Display,
+		window: Window,
+		start: Time,
+		stop: Time,
+		nevents: ^i32,
+		) -> [^]XTimeCoord ---
+	// Enabling or disabling synchronization
+	XSetAfterFunction :: proc(
+		display:   ^Display,
+		procedure: #type proc "c" (display: ^Display) -> i32,
+		) -> i32 ---
+	XSynchronize :: proc(
+		display: ^Display,
+		onoff: b32,
+		) -> i32 ---
+	// Error handling
+	XSetErrorHandler :: proc(
+		handler: #type proc "c" (display: ^Display, event: ^XErrorEvent) -> i32,
+		) -> i32 ---
+	XGetErrorText :: proc(
+		display: ^Display,
+		code: i32,
+		buffer: [^]u8,
+		size: i32,
+		) ---
+	XGetErrorDatabaseText :: proc(
+		display: ^Display,
+		name: cstring,
+		message: cstring,
+		default_string: cstring,
+		buffer: [^]u8,
+		size: i32,
+		) ---
+	XDisplayName :: proc(string: cstring) -> cstring ---
+	XSetIOErrorHandler :: proc(
+		handler: #type proc "c" (display: ^Display) -> i32,
+		) -> i32 ---
+	// Pointer grabbing
+	XGrabPointer :: proc(
+		display:       ^Display,
+		grab_window:   Window,
+		owner_events:  b32,
+		mask:          EventMask,
+		pointer_mode:  GrabMode,
+		keyboard_mode: GrabMode,
+		confine_to:    Window,
+		cursor:        Cursor,
+		time:          Time,
+		) -> i32 ---
+	XUngrabPointer :: proc(
+		display:       ^Display,
+		time:          Time,
+		) -> i32 ---
+	XChangeActivePointerGrab :: proc(
+		display:       ^Display,
+		event_mask:    EventMask,
+		cursor:        Cursor,
+		time:          Time,
+		) ---
+	XGrabButton :: proc(
+		display:       ^Display,
+		button:        u32,
+		modifiers:     InputMask,
+		grab_window:   Window,
+		owner_events:  b32,
+		event_mask:    EventMask,
+		pointer_mode:  GrabMode,
+		keyboard_mode: GrabMode,
+		confine_to:    Window,
+		cursor:        Cursor,
+		) ---
+	XUngrabButton :: proc(
+		display:       ^Display,
+		button:        u32,
+		modifiers:     InputMask,
+		grab_window:   Window,
+		) ---
+	XGrabKeyboard :: proc(
+		display:       ^Display,
+		grab_window:   Window,
+		owner_events:  b32,
+		pointer_mode:  GrabMode,
+		keyboard_mode: GrabMode,
+		time:          Time,
+		) -> i32 ---
+	XUngrabKeyboard :: proc(
+		display:       ^Display,
+		time:          Time,
+		) ---
+	XGrabKey :: proc(
+		display:       ^Display,
+		keycode:       i32,
+		modifiers:     InputMask,
+		grab_window:   Window,
+		owner_events:  b32,
+		pointer_mode:  GrabMode,
+		keyboard_mode: GrabMode,
+		) ---
+	XUngrabKey :: proc(
+		display:       ^Display,
+		keycode:       i32,
+		modifiers:     InputMask,
+		grab_window:   Window,
+		) ---
+	// Resuming event processing
+	XAllowEvents :: proc(display: ^Display, evend_mode: AllowEventsMode, time: Time) ---
+	// Moving the pointer
+	XWarpPointer :: proc(
+		display:    ^Display,
+		src_window: Window,
+		dst_window: Window,
+		src_x:      i32,
+		src_y:      i32,
+		src_width:  u32,
+		src_height: u32,
+		dst_x:      i32,
+		dst_y:      i32,
+		) ---
+	// Controlling input focus
+	XSetInputFocus :: proc(
+		display: ^Display,
+		focus: Window,
+		revert_to: FocusRevert,
+		time: Time,
+		) ---
+	XGetInputFocus :: proc(
+		display: ^Display,
+		focus: ^Window,
+		revert_to: ^FocusRevert,
+		) ---
+	// Manipulating the keyboard and pointer settings
+	XChangeKeyboardControl :: proc(
+		display: ^Display,
+		mask: KeyboardControlMask,
+		values: ^XKeyboardControl,
+		) ---
+	XGetKeyboardControl :: proc(
+		display: ^Display,
+		values: ^XKeyboardState,
+		) ---
+	XAutoRepeatOn  :: proc(display: ^Display) ---
+	XAutoRepeatOff :: proc(display: ^Display) ---
+	XBell          :: proc(display: ^Display, percent: i32) ---
+	XQueryKeymap   :: proc(display: ^Display, keys: [^]u32) ---
+	XSetPointerMapping :: proc(display: ^Display, map_should_not_be_a_keyword: [^]u8, nmap: i32) -> i32 ---
+	XGetPointerMapping :: proc(display: ^Display, map_should_not_be_a_keyword: [^]u8, nmap: i32) -> i32 ---
+	XChangePointerControl :: proc(
+		display:           ^Display,
+		do_accel:          b32,
+		do_threshold:      b32,
+		accel_numerator:   i32,
+		accel_denominator: i32,
+		threshold:         i32,
+		) ---
+	XGetPointerControl :: proc(
+		display: ^Display,
+		accel_numerator:   ^i32,
+		accel_denominator: ^i32,
+		threshold:         ^i32,
+		) ---
+	// Manipulating the keyboard encoding
+	XDisplayKeycodes :: proc(
+		display:      ^Display,
+		min_keycodes: ^i32,
+		max_keycodes: ^i32,
+		) ---
+	XGetKeyboardMapping :: proc(
+		display:     ^Display,
+		first:       KeyCode,
+		count:       i32,
+		keysyms_per: ^i32,
+		) -> ^KeySym ---
+	XChangeKeyboardMapping :: proc(
+		display:     ^Display,
+		first:       KeyCode,
+		keysyms_per: i32,
+		keysyms:     [^]KeySym,
+		num_codes:   i32,
+		) ---
+	XNewModifiermap :: proc(max_keys_per_mode: i32) -> ^XModifierKeymap ---
+	XInsertModifiermapEntry :: proc(
+		modmap:        ^XModifierKeymap,
+		keycode_entry: KeyCode,
+		modifier:      i32,
+		) -> ^XModifierKeymap ---
+	XDeleteModifiermapEntry :: proc(
+		modmap: ^XModifierKeymap,
+		keycode_entry: KeyCode,
+		modifier: i32,
+		) -> ^XModifierKeymap ---
+	XFreeModifiermap :: proc(modmap: ^XModifierKeymap) ---
+	XSetModifierMapping :: proc(display: ^Display, modmap: ^XModifierKeymap) -> i32 ---
+	XGetModifierMapping :: proc(display: ^Display) -> ^XModifierKeymap ---
+	// Manipulating top-level windows
+	XIconifyWindow :: proc(
+		dipslay:   ^Display,
+		window:    Window,
+		screen_no: i32,
+		) -> Status ---
+	XWithdrawWindow :: proc(
+		dipslay:   ^Display,
+		window:    Window,
+		screen_no: i32,
+		) -> Status ---
+	XReconfigureWMWindow :: proc(
+		dipslay:   ^Display,
+		window:    Window,
+		screen_no: i32,
+		mask:      WindowChangesMask,
+		changes:   ^XWindowChanges,
+		) -> Status ---
+	// Getting and setting the WM_NAME property
+	XSetWMName :: proc(
+		display:   ^Display,
+		window:    Window,
+		prop:      ^XTextProperty,
+		) ---
+	XGetWMName :: proc(
+		display: ^Display,
+		window:  Window,
+		prop:    ^XTextProperty,
+		) -> Status ---
+	XStoreName :: proc(
+		display: ^Display,
+		window:  Window,
+		name:    cstring,
+		) ---
+	XFetchName :: proc(
+		display: ^Display,
+		window:  Window,
+		name:    ^cstring,
+		) -> Status ---
+	XSetWMIconName :: proc(
+		display: ^Display,
+		window:  Window,
+		prop:    ^XTextProperty,
+		) ---
+	XGetWMIconName :: proc(
+		display: ^Display,
+		window:  Window,
+		prop:    ^XTextProperty,
+		) -> Status ---
+	XSetIconName :: proc(
+		display: ^Display,
+		window:  Window,
+		name:    cstring,
+		) ---
+	XGetIconName :: proc(
+		display: ^Display,
+		window:  Window,
+		prop:    ^cstring,
+		) -> Status ---
+	// Setting and reading WM_HINTS property
+	XAllocWMHints :: proc() -> ^XWMHints ---
+	XSetWMHints :: proc(
+		display: ^Display,
+		window:  Window,
+		hints:   ^XWMHints,
+		) ---
+	XGetWMHints :: proc(
+		display: ^Display,
+		window:  Window,
+		) -> ^XWMHints ---
+	// Setting and reading MW_NORMAL_HINTS property
+	XAllocSizeHints :: proc() -> ^XSizeHints ---
+	XSetWMNormalHints :: proc(
+		display: ^Display,
+		window:  Window,
+		hints:   ^XSizeHints,
+		) ---
+	XGetWMNormalHints :: proc(
+		display: ^Display,
+		window: Window,
+		hints: ^XSizeHints,
+		flags: ^SizeHints,
+		) -> Status ---
+	XSetWMSizeHints :: proc(
+		display: ^Display,
+		window:  Window,
+		hints:   ^XSizeHints,
+		prop:    Atom,
+		) ---
+	XGetWMSizeHints :: proc(
+		display: ^Display,
+		window:  Window,
+		hints:   ^XSizeHints,
+		masks:   ^SizeHints,
+		prop:    Atom,
+		) -> Status ---
+	// Setting and reading the WM_CLASS property
+	XAllocClassHint :: proc() -> ^XClassHint ---
+	XSetClassHint :: proc(
+		display: ^Display,
+		window:  Window,
+		hint:    ^XClassHint,
+		) ---
+	XGetClassHint :: proc(
+		display: ^Display,
+		window:  Window,
+		hint:    ^XClassHint,
+		) -> Status ---
+	// Setting and reading WM_TRANSIENT_FOR property
+	XSetTransientForHint :: proc(
+		display:     ^Display,
+		window:      Window,
+		prop_window: Window,
+		) ---
+	XGetTransientForHint :: proc(
+		display:     ^Display,
+		window:      Window,
+		prop_window: ^Window,
+		) -> Status ---
+	// Setting and reading the WM_PROTOCOLS property
+	XSetWMProtocols :: proc(
+		display:   ^Display,
+		window:    Window,
+		protocols: [^]Atom,
+		count:     i32,
+		) -> Status ---
+	XGetWMProtocols :: proc(
+		display:   ^Display,
+		window:    Window,
+		protocols: ^[^]Atom,
+		count:     ^i32,
+		) -> Status ---
+	// Setting and reading the WM_COLORMAP_WINDOWS property
+	XSetWMColormapWindows :: proc(
+		display:          ^Display,
+		window:           Window,
+		colormap_windows: [^]Window,
+		count:            i32,
+		) -> Status ---
+	XGetWMColormapWindows :: proc(
+		display:          ^Display,
+		window:           Window,
+		colormap_windows: ^[^]Window,
+		count:            ^i32,
+		) -> Status ---
+	// Setting and reading the WM_ICON_SIZE_PROPERTY
+	XAllocIconSize :: proc() -> ^XIconSize ---
+	XSetIconSizes :: proc(
+		display:   ^Display,
+		window:    Window,
+		size_list: [^]XIconSize,
+		count:     i32,
+		) ---
+	XGetIconSizes :: proc(
+		display:   ^Display,
+		window:    Window,
+		size_list: ^[^]XIconSize,
+		count:     ^i32,
+		) -> Status ---
+	// Using window manager convenience functions
+	XmbSetWMProperties :: proc(
+		display:      ^Display,
+		window:       Window,
+		window_name:  cstring,
+		icon_name:    cstring,
+		argv:         [^]cstring,
+		argc:         i32,
+		normal_hints: ^XSizeHints,
+		wm_hints:     ^XWMHints,
+		class_hints:  ^XClassHint,
+		) ---
+	XSetWMProperties :: proc(
+		display:      ^Display,
+		window:       Window,
+		window_name:  ^XTextProperty,
+		argv:         [^]cstring,
+		argc:         i32,
+		normal_hints: ^XSizeHints,
+		wm_hints:     ^XWMHints,
+		class_hints:  ^XWMHints,
+		) ---
+	// Client to session manager communication
+	XSetCommand :: proc(
+		display: ^Display,
+		window:  Window,
+		argv:    [^]cstring,
+		argc:    i32,
+		) ---
+	XGetCommand :: proc(
+		display: ^Display,
+		window:  Window,
+		argv:    ^[^]cstring,
+		argc:    ^i32,
+		) -> Status ---
+	XSetWMClientMachine :: proc(
+		display: ^Display,
+		window:  Window,
+		prop:    ^XTextProperty,
+		) ---
+	XGetWMClientMachine :: proc(
+		display: ^Display,
+		window:  Window,
+		prop:    ^XTextProperty,
+		) -> Status ---
+	XSetRGBColormaps :: proc(
+		display:  ^Display,
+		window:   Window,
+		colormap: ^XStandardColormap,
+		prop:     Atom,
+		) ---
+	XGetRGBColormaps :: proc(
+		display:  ^Display,
+		window:   Window,
+		colormap: ^[^]XStandardColormap,
+		count:    ^i32,
+		prop:     Atom,
+		) -> Status ---
+	// Keyboard utility functions
+	XLookupKeysym :: proc(
+		event: ^XKeyEvent,
+		index: i32,
+		) -> KeySym ---
+	XKeycodeToKeysym :: proc(
+		display: ^Display,
+		keycode: KeyCode,
+		index: i32,
+		) -> KeySym ---
+	XKeysymToKeycode :: proc(
+		display: ^Display,
+		keysym: KeySym,
+		) -> KeyCode ---
+	XRefreshKeyboardMapping :: proc(event_map: ^XMappingEvent) ---
+	XConvertCase :: proc(
+		keysym: KeySym,
+		lower:  ^KeySym,
+		upper:  ^KeySym,
+		) ---
+	XStringToKeysym :: proc(str: cstring) -> KeySym ---
+	XKeysymToString :: proc(keysym: KeySym) -> cstring ---
+	XLookupString :: proc(
+		event: ^XKeyEvent,
+		buffer: [^]u8,
+		count: i32,
+		keysym: ^KeySym,
+		status: ^XComposeStatus,
+		) -> i32 ---
+	XRebindKeysym :: proc(
+		display: ^Display,
+		keysym: KeySym,
+		list: [^]KeySym,
+		mod_count: i32,
+		string: [^]u8,
+		num_bytes: i32,
+		) ---
+	// Allocating permanent storage
+	XPermalloc :: proc(size: u32) -> rawptr ---
+	// Parsing the window geometry
+	XParseGeometry :: proc(
+		parsestring: cstring,
+		x_ret:       ^i32,
+		y_ret:       ^i32,
+		width:       ^u32,
+		height:      ^u32,
+		) -> i32 ---
+	XWMGeometry :: proc(
+		display:   ^Display,
+		screen_no: i32,
+		user_geom: cstring,
+		def_geom:  cstring,
+		bwidth:    u32,
+		hints:     ^XSizeHints,
+		x_ret:     ^i32,
+		y_ret:     ^i32,
+		w_ret:     ^u32,
+		h_ret:     ^u32,
+		grav:      ^Gravity,
+		) -> i32 ---
+	// Creating, copying and destroying regions
+	XCreateRegion :: proc() -> Region ---
+	XPolygonRegion :: proc(
+		points: [^]XPoint,
+		n:      i32,
+		fill:   FillRule,
+		) -> Region ---
+	XSetRegion :: proc(
+		display: ^Display,
+		gc:      GC,
+		region:  Region,
+		) ---
+	XDestroyRegion :: proc(r: Region) ---
+	// Moving or shrinking regions
+	XOffsetRegion :: proc(region: Region, dx, dy: i32) ---
+	XShrinkRegion :: proc(region: Region, dx, dy: i32) ---
+	// Computing with regions
+	XClipBox :: proc(region: Region, rect: ^XRectangle) ---
+	XIntersectRegion :: proc(sra, srb, ret: Region) ---
+	XUnionRegion :: proc(sra, srb, ret: Region) ---
+	XUnionRectWithRegion :: proc(rect: ^XRectangle, src, dst: Region) ---
+	XSubtractRegion :: proc(sra, srb, ret: Region) ---
+	XXorRegion :: proc(sra, srb, ret: Region) ---
+	XEmptyRegion :: proc(reg: Region) -> b32 ---
+	XEqualRegion :: proc(a,b: Region) -> b32 ---
+	XPointInRegion :: proc(reg: Region, x,y: i32) -> b32 ---
+	XRectInRegion :: proc(reg: Region, x,y: i32, w,h: u32) -> b32 ---
+	// Using cut buffers
+	XStoreBytes :: proc(display: ^Display, bytes: [^]u8, nbytes: i32) ---
+	XStoreBuffer :: proc(display: ^Display, bytes: [^]u8, nbytes: i32, buffer: i32) ---
+	XFetchBytes :: proc(display: ^Display, nbytes: ^i32) -> [^]u8 ---
+	XFetchBuffer :: proc(display: ^Display, nbytes: ^i32, buffer: i32) -> [^]u8 ---
+	// Determining the appropriate visual types
+	XGetVisualInfo :: proc(
+		display: ^Display,
+		mask:    VisualInfoMask,
+		info:    ^XVisualInfo,
+		nret:    ^i32,
+		) -> [^]XVisualInfo ---
+	XMatchVisualInfo :: proc(
+		display:   ^Display,
+		screen_no: i32,
+		depth:     i32,
+		class:     i32,
+		ret:       ^XVisualInfo,
+		) -> Status ---
+	// Manipulating images
+	XCreateImage :: proc(
+		display: ^Display,
+		visual:  ^Visual,
+		depth:   u32,
+		format:  ImageFormat,
+		offset:  i32,
+		data:    rawptr,
+		width:   u32,
+		height:  u32,
+		pad:     i32,
+		stride:  i32,
+		) -> ^XImage ---
+	XGetPixel :: proc(
+		image: ^XImage,
+		x:     i32,
+		y:     i32,
+		) -> uint ---
+	XPutPixel :: proc(
+		image: ^XImage,
+		x:     i32,
+		y:     i32,
+		pixel: uint,
+		) ---
+	XSubImage :: proc(
+		image: ^XImage,
+		x: i32,
+		y: i32,
+		w: u32,
+		h: u32,
+		) -> ^XImage ---
+	XAddPixel :: proc(
+		image: ^XImage,
+		value: int,
+		) ---
+	XDestroyImage :: proc(image: ^XImage) ---
+}

+ 1307 - 0
vendor/x11/xlib/xlib_types.odin

@@ -0,0 +1,1307 @@
+//+build linux, freebsd, openbsd
+package xlib
+
+// Since this is a unix-only library we make a few simplifying assumptions
+import "core:c"
+#assert(size_of(int)  == size_of(c.long))
+#assert(size_of(uint) == size_of(c.ulong))
+#assert(size_of(i32)  == size_of(c.int))
+#assert(size_of(u32)  == size_of(c.uint))
+
+/* ----  X11/X.h ------------------------------------------------------------*/
+
+XID      :: distinct uint
+Mask     :: distinct uint
+Atom     :: distinct uint
+VisualID :: distinct uint
+Time     :: distinct uint
+
+Window   :: XID
+Drawable :: XID
+Font     :: XID
+Pixmap   :: XID
+Cursor   :: XID
+Colormap :: XID
+GContext :: XID
+
+KeyCode  :: u8
+
+/* ----  X11/Xlib.h ---------------------------------------------------------*/
+
+XExtData :: struct {
+	number:                i32,
+	next:                  ^XExtData,
+	free_private:          #type proc "c" (extension: ^XExtData) -> Status,
+	private_data:          rawptr,
+}
+
+XExtCodes :: struct {
+	extension:             i32,
+	major_opcode:          i32,
+	first_event:           i32,
+	first_error:           i32,
+}
+
+XPixmapFormatValues :: struct {
+    depth:                 i32,
+    bits_per_pixel:        i32,
+    scanline_pad:          i32,
+}
+
+XGCValues :: struct {
+	function:              GCFunction,
+	plane_mask:            uint,
+	foreground:            uint,
+	background:            uint,
+	line_width:            i32,
+	line_style:            LineStyle,
+	cap_style:             CapStyle,
+	join_style:            JoinStyle,
+	fill_style:            FillStyle,
+	fill_rule:             FillRule,
+	arc_mode:              ArcMode,
+	tile:                  Pixmap,
+	stipple:               Pixmap,
+	ts_x_origin:           i32,
+	ts_y_origin:           i32,
+	font:                  Font,
+	subwindow_mode:        SubwindowMode,
+	graphics_exposures:    b32,
+	clip_x_origin:         i32,
+	clip_y_origin:         i32,
+	clip_mask:             Pixmap,
+	dash_offset:           i32,
+	dashes:                i8,
+}
+
+GC :: distinct rawptr
+
+Visual :: struct {
+	ext_data:              ^XExtData,
+	visualid:              VisualID,
+	class:                 i32,
+	red_mask:              uint,
+	green_mask:            uint,
+	blue_mask:             uint,
+	bits_per_rgb:          i32,
+	map_entries:           i32,
+}
+
+Depth :: struct {
+	depth:                 i32,
+	nvisuals:              i32,
+	visuals:               ^Visual,
+}
+
+XDisplay :: distinct struct {}
+
+Screen :: struct {
+	ext_data:              ^XExtData,
+	display:               ^XDisplay,
+	root:                  Window,
+	width:                 i32,
+	height:                i32,
+	mwidth:                i32,
+	mheight:               i32,
+	ndepths:               i32,
+	depths:                ^Depth,
+	root_depth:            i32,
+	root_visual:           ^Visual,
+	default_gc:            GC,
+	cmap:                  Colormap,
+	white_pixel:           uint,
+	black_pixel:           uint,
+	max_maps:              i32,
+	min_maps:              i32,
+	backing_store:         i32,
+	save_unders:           i32,
+	root_input_mask:       int,
+}
+
+ScreenFormat :: struct {
+	ext_data:              ^XExtData,
+	depth:                 i32,
+	bits_per_pixel:        i32,
+	scanline_pad:          i32,
+}
+
+XSetWindowAttributes :: struct {
+    background_pixmap:     Pixmap,
+    background_pixel:      uint,
+    border_pixmap:         Pixmap,
+    border_pixel:          uint,
+    bit_gravity:           Gravity,
+    win_gravity:           Gravity,
+    backing_store:         BackingStore,
+    backing_planes:        uint,
+    backing_pixel:         uint,
+    save_under:            b32,
+    event_mask:            EventMask,
+    do_not_propagate_mask: EventMask,
+    override_redirect:     b32,
+    colormap:              Colormap,
+    cursor:                Cursor,
+}
+
+XWindowAttributes :: struct {
+    x:                     i32,
+    y:                     i32,
+    width:                 i32,
+    height:                i32,
+    border_width:          i32,
+    depth:                 i32,
+    visual:                ^Visual,
+    root:                  Window,
+    class:                 WindowClass,
+    bit_gravity:           Gravity,
+    win_gravity:           Gravity,
+    backing_store:         BackingStore,
+    backing_planes:        uint,
+    backing_pixel:         uint,
+    save_under:            b32,
+    colormap:              Colormap,
+    map_installed:         b32,
+    map_state:             WindowMapState,
+    all_event_masks:       EventMask,
+    your_event_mask:       EventMask,
+    do_not_propagate_mask: EventMask,
+    override_redirect:     b32,
+    screen:                ^Screen,
+}
+
+XHostAddress :: struct {
+	family:                i32,
+	length:                i32,
+	address:               rawptr,
+}
+
+XServerInterpretedAddress :: struct {
+	typelength:            i32,
+	valuelength:           i32,
+	type:                  [^]u8,
+	value:                 [^]u8,
+}
+
+XImage :: struct {
+    width:                 i32,
+    height:                i32,
+    xoffset:               i32,
+    format:                ImageFormat,
+    data:                  rawptr,
+    byte_order:            i32,
+    bitmap_unit:           i32,
+    bitmap_bit_order:      ByteOrder,
+    bitmap_pad:            i32,
+    depth:                 i32,
+    bytes_per_line:        i32,
+    bits_per_pixel:        i32,
+    red_mask:              uint,
+    green_mask:            uint,
+    blue_mask:             uint,
+    obdata:                rawptr,
+    f: struct {
+    	create_image: proc "c" (
+    		display: ^Display,
+    		visual: ^Visual,
+    		depth: u32,
+    		format: i32,
+    		offset: i32,
+    		data: rawptr,
+    		width: u32,
+    		height: u32,
+    		pad: i32,
+    		stride: i32) -> ^XImage,
+    	destroy_image: proc "c" (image: ^XImage) -> i32,
+    	get_pixel: proc "c" (image: ^XImage) -> uint,
+    	put_pixel: proc "c" (image: ^XImage, x: i32, y: i32, pixel: uint) -> i32,
+    	sub_image: proc "c" (image: ^XImage, x: i32, y: i32, w: u32, h: u32) -> ^XImage,
+    	add_pixel: proc "c" (image: ^XImage, val: int) -> i32,
+	},
+}
+
+XWindowChanges :: struct {
+    x:                     i32,
+    y:                     i32,
+    width:                 i32,
+    height:                i32,
+    border_width:          i32,
+    sibling:               Window,
+    stack_mode:            WindowStacking,
+}
+
+XColor :: struct {
+	pixel:  uint,
+	red:    u16,
+	green:  u16,
+	blue:   u16,
+	flags:  u8,
+	pad:    u8,
+}
+
+XSegment :: struct {
+    x1:     i16,
+    y1:     i16,
+    x2:     i16,
+    y2:     i16,
+}
+
+XPoint :: struct {
+    x:      i16,
+    y:      i16,
+}
+
+XRectangle :: struct {
+    x:      i16,
+    y:      i16,
+    width:  u16,
+    height: u16,
+}
+
+XArc :: struct {
+    x:      i16,
+    y:      i16,
+    width:  u16,
+    height: u16,
+    angle1: i16,
+    angle2: i16,
+}
+
+XKeyboardControl :: struct {
+    key_click_percent:  i32,
+    bell_percent:       i32,
+    bell_pitch:         i32,
+    bell_duration:      i32,
+    led:                i32,
+    led_mode:           KeyboardLedMode,
+    key:                i32,
+    auto_repeat_mode:   KeyboardAutoRepeatMode,
+}
+
+XKeyboardState :: struct {
+	key_click_percent:  i32,
+	bell_percent:       i32,
+	bell_pitch:         u32,
+	bell_duration:      u32,
+	led_mask:           uint,
+	global_auto_repeat: i32,
+	auto_repeats:       [32]u8,
+}
+
+XTimeCoord :: struct {
+	time:               Time,
+	x:                  i16,
+	y:                  i16,
+}
+
+XModifierKeymap :: struct {
+	max_keypermod:      i32,
+	modifiermap:        ^KeyCode,
+}
+
+Display :: distinct struct {}
+
+XKeyEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	window:            Window,
+	root:              Window,
+	subwindow:         Window,
+	time:              Time,
+	x:                 i32,
+	y:                 i32,
+	x_root:            i32,
+	y_root:            i32,
+	state:             InputMask,
+	keycode:           u32,
+	same_screen:       b32,
+}
+
+XKeyPressedEvent  :: XKeyEvent
+XKeyReleasedEvent :: XKeyEvent
+
+XButtonEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	window:            Window,
+	root:              Window,
+	subwindow:         Window,
+	time:              Time,
+	x:                 i32,
+	y:                 i32,
+	x_root:            i32,
+	y_root:            i32,
+	state:             InputMask,
+	button:            MouseButton,
+	same_screen:       b32,
+}
+
+XButtonPressedEvent  :: XButtonEvent
+XButtonReleasedEvent :: XButtonEvent
+
+XMotionEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	window:            Window,
+	root:              Window,
+	subwindow:         Window,
+	time:              Time,
+	x:                 i32,
+	y:                 i32,
+	x_root:            i32,
+	y_root:            i32,
+	state:             InputMask,
+	is_hint:           b8,
+	same_screen:       b32,
+}
+
+XPointerMovedEvent :: XMotionEvent
+
+XCrossingEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	window:            Window,
+	root:              Window,
+	subwindow:         Window,
+	time:              Time,
+	x:                 i32,
+	y:                 i32,
+	x_root:            i32,
+	y_root:            i32,
+	mode:              NotifyMode,
+	detail:            NotifyDetail,
+	same_screen:       b32,
+	focus:             i32,
+	state:             InputMask,
+}
+
+XEnterWindowEvent :: XCrossingEvent
+XLeaveWindowEvent :: XCrossingEvent
+
+XFocusChangeEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	window:            Window,
+	mode:              NotifyMode,
+	detail:            NotifyDetail,
+}
+
+XFocusInEvent  :: XFocusChangeEvent
+XFocusOutEvent :: XFocusChangeEvent
+
+XKeymapEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	window:            Window,
+	key_vector:        [32]u8,
+}
+
+XExposeEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	window:            Window,
+	x:                 i32,
+	y:                 i32,
+	width:             i32,
+	height:            i32,
+	count:             i32,
+}
+
+XGraphicsExposeEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	drawable:          Drawable,
+	x:                 i32,
+	y:                 i32,
+	width:             i32,
+	height:            i32,
+	count:             i32,
+	major_code:        i32,
+	minor_code:        i32,
+}
+
+XNoExposeEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	drawable:          Drawable,
+	major_code:        i32,
+	minor_code:        i32,
+}
+
+XVisibilityEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	window:            Window,
+	state:             VisibilityState,
+}
+
+XCreateWindowEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	parent:            Window,
+	window:            Window,
+	x:                 i32,
+	y:                 i32,
+	width:             i32,
+	height:            i32,
+	border_width:      i32,
+	override_redirect: b32,
+}
+
+XDestroyWindowEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	event:             Window,
+	window:            Window,
+}
+
+XUnmapEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	event:             Window,
+	window:            Window,
+	from_configure:    b32,
+}
+
+XMapEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	event:             Window,
+	window:            Window,
+	override_redirect: b32,
+}
+
+XMapRequestEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	parent:            Window,
+	window:            Window,
+}
+
+XReparentEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	event:             Window,
+	window:            Window,
+	parent:            Window,
+	x:                 i32,
+	y:                 i32,
+	override_redirect: b32,
+}
+
+XConfigureEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	event:             Window,
+	window:            Window,
+	x:                 i32,
+	y:                 i32,
+	width:             i32,
+	height:            i32,
+	border_width:      i32,
+	above:             Window,
+	override_redirect: b32,
+}
+
+XGravityEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	event:             Window,
+	window:            Window,
+	x:                 i32,
+	y:                 i32,
+}
+
+XResizeRequestEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	window:            Window,
+	width:             i32,
+	height:            i32,
+}
+
+XConfigureRequestEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	parent:            Window,
+	window:            Window,
+	x:                 i32,
+	y:                 i32,
+	width:             i32,
+	height:            i32,
+	border_width:      i32,
+	above:             Window,
+	detail:            WindowStacking,
+	value_mask:        uint,
+}
+
+XCirculateEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	event:             Window,
+	window:            Window,
+	place:             CirculationRequest,
+}
+
+XCirculateRequestEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	parent:            Window,
+	window:            Window,
+	place:             CirculationRequest,
+}
+
+XPropertyEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	window:            Window,
+	atom:              Atom,
+	time:              Time,
+	state:             PropertyState,
+}
+
+XSelectionClearEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	window:            Window,
+	selection:         Atom,
+	time:              Time,
+}
+
+XSelectionRequestEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	owner:             Window,
+	requestor:         Window,
+	selection:         Atom,
+	target:            Atom,
+	property:          Atom,
+	time:              Time,
+}
+
+XSelectionEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	requestor:         Window,
+	selection:         Atom,
+	target:            Atom,
+	property:          Atom,
+	time:              Time,
+}
+
+XColormapEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	window:            Window,
+	colormap:          Colormap,
+	new:               b32,
+	state:             ColormapState,
+}
+
+XClientMessageEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	window:            Window,
+	message_type:      Atom,
+	format:            i32,
+	data: struct #raw_union {
+		b: [20]i8,
+		s: [10]i16,
+		l: [5]int,
+	},
+}
+
+XMappingEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	window:            Window,
+	request:           MappingRequest,
+	first_keycode:     i32,
+	count:             i32,
+}
+
+XErrorEvent :: struct {
+	type:              EventType,
+	display:           ^Display,
+	resourceid:        XID,
+	serial:            uint,
+	error_code:        u8,
+	request_code:      u8,
+	minor_code:        u8,
+}
+
+XAnyEvent :: struct {
+	type:              EventType,
+	serial:            uint,
+	send_event:        b32,
+	display:           ^Display,
+	window:            Window,
+}
+
+XGenericEvent :: struct {
+    type:              EventType,
+    serial:            uint,
+    send_event:        b32,
+    display:           ^Display,
+    extension:         i32,
+    evtype:            i32,
+}
+
+XGenericEventCookie :: struct {
+    type:              EventType,
+    serial:            uint,
+    send_event:        b32,
+    display:           Display,
+    extension:         i32,
+    evtype:            i32,
+    cookie:            u32,
+    data:              rawptr,
+}
+
+XEvent :: struct #raw_union {
+	type:              EventType,
+	xany:              XAnyEvent,
+	xkey:              XKeyEvent,
+	xbutton:           XButtonEvent,
+	xmotion:           XMotionEvent,
+	xcrossing:         XCrossingEvent,
+	xfocus:            XFocusChangeEvent,
+	xexpose:           XExposeEvent,
+	xgraphicsexpose:   XGraphicsExposeEvent,
+	xnoexpose:         XNoExposeEvent,
+	xvisibility:       XVisibilityEvent,
+	xcreatewindow:     XCreateWindowEvent,
+	xdestroywindow:    XDestroyWindowEvent,
+	xunmap:            XUnmapEvent,
+	xmap:              XMapEvent,
+	xmaprequest:       XMapRequestEvent,
+	xreparent:         XReparentEvent,
+	xconfigure:        XConfigureEvent,
+	xgravity:          XGravityEvent,
+	xresizerequest:    XResizeRequestEvent,
+	xconfigurerequest: XConfigureRequestEvent,
+	xcirculate:        XCirculateEvent,
+	xcirculaterequest: XCirculateRequestEvent,
+	xproperty:         XPropertyEvent,
+	xselectionclear:   XSelectionClearEvent,
+	xselectionrequest: XSelectionRequestEvent,
+	xselection:        XSelectionEvent,
+	xcolormap:         XColormapEvent,
+	xclient:           XClientMessageEvent,
+	xmapping:          XMappingEvent,
+	xerror:            XErrorEvent,
+	xkeymap:           XKeymapEvent,
+	xgeneric:          XGenericEvent,
+	xcookie:           XGenericEventCookie,
+	_:                 [24]int,
+}
+
+XCharStruct :: struct {
+    lbearing:          i16,
+    rbearing:          i16,
+    width:             i16,
+    ascent:            i16,
+    descent:           i16,
+    attributes:        u16,
+}
+
+XFontProp :: struct {
+    name:              Atom,
+    card32:            uint,
+}
+
+XFontStruct :: struct {
+    ext_data:          ^XExtData,
+    fid:               Font,
+    direction:         u32,
+    min_char_or_byte2: u32,
+    max_char_or_byte2: u32,
+    min_byte1:         u32,
+    max_byte1:         u32,
+    all_chars_exist:   i32,
+    default_char:      u32,
+    n_properties:      i32,
+    properties:        ^XFontProp,
+    min_bounds:        XCharStruct,
+    max_bounds:        XCharStruct,
+    per_char:          ^XCharStruct,
+    ascent:            i32,
+    descent:           i32,
+}
+
+XTextItem :: struct {
+    chars:  [^]u8,
+    nchars: i32,
+    delta:  i32,
+    font:   Font,
+}
+
+XChar2b :: struct {
+    byte1: u8,
+    byte2: u8,
+}
+
+XTextItem16 :: struct {
+    chars:  ^XChar2b,
+    nchars: i32,
+    delta:  i32,
+    font:   Font,
+}
+
+XEDataObject :: struct #raw_union {
+	display:            ^Display,
+	gc:                 GC,
+	visual:             ^Visual,
+	screen:             ^Screen,
+	pixmap_format:      ^ScreenFormat,
+	font:               ^XFontStruct,
+}
+
+XFontSetExtents :: struct {
+    max_ink_extent:     XRectangle,
+    max_logical_extent: XRectangle,
+}
+
+XOM      :: distinct rawptr
+XOC      :: distinct rawptr
+XFontSet :: XOC
+
+XmbTextItem :: struct {
+    chars:    [^]u8,
+    nchars:   i32,
+    delta:    i32,
+    font_set: XFontSet,
+}
+
+XwcTextItem :: struct {
+    chars:    [^]rune,
+    nchars:   i32,
+    delta:    i32,
+    font_set: XFontSet,
+}
+
+XOMCharSetList :: struct {
+    charset_count: i32,
+    charset_list: [^]cstring,
+}
+
+XOrientation :: enum i32 {
+    XOMOrientation_LTR_TTB = 0,
+    XOMOrientation_RTL_TTB = 1,
+    XOMOrientation_TTB_LTR = 2,
+    XOMOrientation_TTB_RTL = 3,
+    XOMOrientation_Context = 4,
+}
+
+XOMOrientation :: struct {
+    num_orientation:  i32,
+    orientation:      [^]XOrientation,
+}
+
+XOMFontInfo :: struct {
+    num_font:         i32,
+    font_struct_list: [^]^XFontStruct,
+    font_name_list:   [^]cstring,
+}
+
+XIM :: distinct rawptr
+XIC :: distinct rawptr
+
+XIMProc :: #type proc "c" (xim: XIM, client_data: rawptr, call_data: rawptr)
+XICProc :: #type proc "c" (xim: XIM, client_data: rawptr, call_data: rawptr)
+XIDProc :: #type proc "c" (xim: XIM, client_data: rawptr, call_data: rawptr)
+
+XIMStyle :: uint
+
+XIMStyles :: struct {
+    count_styles:     u16,
+    supported_styles: [^]XIMStyle,
+}
+
+XVaNestedList :: distinct rawptr
+
+XIMCallback :: struct {
+    client_data: rawptr,
+    callback:    XIMProc,
+}
+
+XICCallback :: struct {
+    client_data: rawptr,
+    callback:    XICProc,
+}
+
+XIMFeedback :: uint
+
+XIMText :: struct {
+    length:            u16,
+    feedback:          ^XIMFeedback,
+    encoding_is_wchar: b32,
+    string: struct #raw_union {
+		multi_byte: [^]u8,
+		wide_char:  [^]rune,
+    },
+}
+
+XIMPreeditState :: uint
+
+XIMPreeditStateNotifyCallbackStruct :: struct {
+    state: XIMPreeditState,
+}
+
+XIMResetState :: uint
+
+XIMStringConversionFeedback :: uint
+
+XIMStringConversionText :: struct {
+    length: u16,
+    feedback: ^XIMStringConversionFeedback,
+    encoding_is_wchar: b32,
+    string: struct #raw_union {
+		mbs: [^]u8,
+		wcs: [^]rune,
+    },
+}
+
+XIMStringConversionPosition  :: u16
+XIMStringConversionType      :: u16
+XIMStringConversionOperation :: u16
+
+XIMCaretDirection :: enum i32 {
+    XIMForwardChar      = 0,
+    XIMBackwardChar     = 1,
+    XIMForwardWord      = 2,
+    XIMBackwardWord     = 3,
+    XIMCaretUp          = 4,
+    XIMCaretDown        = 5,
+    XIMNextLine         = 6,
+    XIMPreviousLine     = 7,
+    XIMLineStart        = 8,
+    XIMLineEnd          = 9,
+    XIMAbsolutePosition = 10,
+    XIMDontChang        = 11,
+}
+
+XIMStringConversionCallbackStruct :: struct {
+    position:  XIMStringConversionPosition,
+    direction: XIMCaretDirection,
+    operation: XIMStringConversionOperation,
+    factor:    u16,
+    text:      ^XIMStringConversionText,
+}
+
+XIMPreeditDrawCallbackStruct :: struct {
+    caret:      i32,
+    chg_first:  i32,
+    chg_length: i32,
+    text:       ^XIMText,
+}
+
+XIMCaretStyle :: enum i32 {
+    XIMIsInvisible,
+    XIMIsPrimary,
+    XIMIsSecondary,
+}
+
+XIMPreeditCaretCallbackStruct :: struct {
+    position:  i32,
+    direction: XIMCaretDirection,
+    style:     XIMCaretStyle,
+}
+
+XIMStatusDataType :: enum {
+    XIMTextType,
+    XIMBitmapType,
+}
+
+XIMStatusDrawCallbackStruct :: struct {
+    type: XIMStatusDataType,
+    data: struct #raw_union {
+		text: ^XIMText,
+		bitmap: Pixmap,
+    },
+}
+
+XIMHotKeyTrigger :: struct {
+    keysym:        KeySym,
+    modifier:      i32,
+    modifier_mask: i32,
+}
+
+XIMHotKeyTriggers :: struct {
+    num_hot_key: i32,
+    key:         [^]XIMHotKeyTrigger,
+}
+
+XIMHotKeyState :: uint
+
+XIMValuesList :: struct {
+    count_values: u16,
+    supported_values: [^]cstring,
+}
+
+XConnectionWatchProc :: #type proc "c" (
+	display: ^Display,
+	client_data: rawptr,
+	fd: i32,
+	opening: b32,
+	watch_data: rawptr)
+
+/* ----  X11/Xcms.h ---------------------------------------------------------*/
+
+XcmsColorFormat :: uint
+
+XcmsFloat :: f64
+
+XcmsRGB :: struct {
+    red:   u16,
+    green: u16,
+    blue:  u16,
+}
+
+XcmsRGBi :: struct {
+    red:   XcmsFloat,
+    green: XcmsFloat,
+    blue:  XcmsFloat,
+}
+
+XcmsCIEXYZ :: struct {
+    X: XcmsFloat,
+    Y: XcmsFloat,
+    Z: XcmsFloat,
+}
+
+XcmsCIEuvY :: struct {
+    u_prime: XcmsFloat,
+    v_prime: XcmsFloat,
+    Y:       XcmsFloat,
+}
+
+XcmsCIExyY :: struct {
+    x: XcmsFloat,
+    y: XcmsFloat,
+    Y: XcmsFloat,
+}
+
+XcmsCIELab :: struct {
+    L_star: XcmsFloat,
+    a_star: XcmsFloat,
+    b_star: XcmsFloat,
+}
+
+XcmsCIELuv :: struct {
+    L_star: XcmsFloat,
+    u_star: XcmsFloat,
+    v_star: XcmsFloat,
+}
+
+XcmsTekHVC :: struct {
+    H: XcmsFloat,
+    V: XcmsFloat,
+    C: XcmsFloat,
+}
+
+XcmsPad :: struct {
+    _: XcmsFloat,
+    _: XcmsFloat,
+    _: XcmsFloat,
+    _: XcmsFloat,
+}
+
+XcmsColor :: struct {
+    spec: struct #raw_union {
+		RGB:    XcmsRGB,
+		RGBi:   XcmsRGBi,
+		CIEXYZ: XcmsCIEXYZ,
+		CIEuvY: XcmsCIEuvY,
+		CIExyY: XcmsCIExyY,
+		CIELab: XcmsCIELab,
+		CIELuv: XcmsCIELuv,
+		TekHVC: XcmsTekHVC,
+		_:      XcmsPad,
+    },
+    pixel:  uint,
+    format: XcmsColorFormat,
+}
+
+XcmsPerScrnInfo :: struct {
+    screenWhitePt: XcmsColor,
+    functionSet:   rawptr,
+    screenData:    rawptr,
+    state:         u8,
+    _:             [3]u8,
+}
+
+XcmsCCC :: distinct rawptr
+
+XcmsCompressionProc :: #type proc "c" (
+	ctx: XcmsCCC,
+	colors: [^]XcmsColor,
+	ncolors: u32,
+	index: u32,
+	flags: [^]b32) -> Status
+
+XcmsWhiteAdjustProc :: #type proc "c" (
+	ctx: XcmsCCC,
+	initial_white_point: ^XcmsColor,
+	target_white_point:  ^XcmsColor,
+	target_format:       XcmsColorFormat,
+	colors:              [^]XcmsColor,
+	ncolors:             u32,
+	compression: [^]b32) -> Status
+
+XcmsCCCRec :: struct {
+    dpy:                  ^Display,
+    screenNumber:         i32,
+    visual:               ^Visual,
+    clientWhitePt:        XcmsColor,
+    gamutCompProc:        XcmsCompressionProc,
+    gamutCompClientData:  rawptr,
+    whitePtAdjProc:       XcmsWhiteAdjustProc,
+    whitePtAdjClientData: rawptr,
+    pPerScrnInfo:         ^XcmsPerScrnInfo,
+}
+
+XcmsScreenInitProc :: #type proc "c" (
+	display: ^Display,
+	screen_number: i32,
+	screen_info: ^XcmsPerScrnInfo) -> i32
+
+XcmsScreenFreeProc :: #type proc "c" (screen: rawptr)
+
+XcmsDDConversionProc :: #type proc "c" (
+	ctx: XcmsCCC,
+	colors: [^]XcmsColor,
+	ncolors: u32,
+	compressed: [^]b32) -> i32
+
+XcmsDIConversionProc :: #type proc "c" (
+	ctx: XcmsCCC,
+	white_point: ^XcmsColor,
+	colors: ^XcmsColor,
+	ncolors: u32) -> i32
+
+
+XcmsConversionProc :: XcmsDIConversionProc
+XcmsFuncListPtr    :: [^]XcmsConversionProc
+
+XcmsParseStringProc :: #type proc "c" (color_string: cstring, color: ^XcmsColor) -> i32
+
+XcmsColorSpace :: struct {
+    prefix:        cstring,
+    id:            XcmsColorFormat,
+    parseString:   XcmsParseStringProc,
+    to_CIEXYZ:     XcmsFuncListPtr,
+    from_CIEXYZ:   XcmsFuncListPtr,
+    inverse_flag:  i32,
+}
+
+XcmsFunctionSet :: struct {
+    DDColorSpaces: [^]^XcmsColorSpace,
+    screenInitProc: XcmsScreenInitProc,
+    screenFreeProc: XcmsScreenFreeProc,
+}
+
+
+/* ----  X11/Xutil.h --------------------------------------------------------*/
+
+XSizeHints :: struct {
+	flags:         SizeHints,
+	x:             i32,
+	y:             i32,
+	width:         i32,
+	height:        i32,
+	min_width:     i32,
+	min_height:    i32,
+	max_width:     i32,
+	max_height:    i32,
+	width_inc:     i32,
+	height_inc:    i32,
+	min_aspect:    struct {x,y: i32},
+	max_aspect:    struct {x,y: i32},
+	base_width:    i32,
+	base_height:   i32,
+	win_gravity:   i32,
+}
+
+XWMHints :: struct {
+	flags:         WMHints,
+	input:         b32,
+	initial_state: WMHintState,
+	icon_pixmap:   Pixmap,
+	icon_window:   Window,
+	icon_x:        i32,
+	icon_y:        i32,
+	icon_mask:     Pixmap,
+	window_group:  XID,
+}
+
+XTextProperty :: struct {
+    value:         [^]u8,
+    encoding:      Atom,
+    format:        int,
+    nitems:        uint,
+}
+
+XICCEncodingStyle :: enum i32 {
+    XStringStyle,
+    XCompoundTextStyle,
+    XTextStyle,
+    XStdICCTextStyle,
+    XUTF8StringStyle,
+}
+
+XIconSize :: struct {
+	min_width:     i32,
+	min_height:    i32,
+	max_width:     i32,
+	max_height:    i32,
+	width_inc:     i32,
+	height_inc:    i32,
+}
+
+XClassHint :: struct {
+	res_name:      cstring,
+	res_class:     cstring,
+}
+
+XComposeStatus :: struct {
+    compose_ptr:   rawptr,
+    chars_matched: i32,
+}
+
+Region :: distinct rawptr
+
+XVisualInfo :: struct {
+	visual:        ^Visual,
+	visualid:      VisualID,
+	screen:        i32,
+	depth:         i32,
+	class:         i32,
+	red_mask:      uint,
+	green_mask:    uint,
+	blue_mask:     uint,
+	colormap_size: i32,
+	bits_per_rgb:  i32,
+}
+
+XStandardColormap :: struct {
+	colormap:      Colormap,
+	red_max:       uint,
+	red_mult:      uint,
+	green_max:     uint,
+	green_mult:    uint,
+	blue_max:      uint,
+	blue_mult:     uint,
+	base_pixel:    uint,
+	visualid:      VisualID,
+	killid:        XID,
+}
+
+XContext :: i32
+
+/* ----  X11/Xresource.h ----------------------------------------------------*/
+
+XrmQuark     :: i32
+XrmQuarkList :: [^]i32
+XrmString    :: cstring
+
+XrmBinding :: enum i32 {
+	XrmBindTightly,
+	XrmBindLoosely,
+}
+
+XrmBindingList :: [^]XrmBinding
+
+XrmName           :: XrmQuark
+XrmNameList       :: XrmQuarkList
+XrmClass          :: XrmQuark
+XrmClassList      :: XrmQuarkList
+XrmRepresentation :: XrmQuark
+
+XrmValue :: struct {
+    size: u32,
+    addr: rawptr,
+}
+XrmValuePtr   :: [^]XrmValue
+
+XrmHashBucket :: distinct rawptr
+XrmHashTable  :: [^]XrmHashBucket
+XrmSearchList :: [^]XrmHashTable
+XrmDatabase   :: distinct rawptr
+
+XrmOptionKind :: enum {
+    XrmoptionNoArg,
+    XrmoptionIsArg,
+    XrmoptionStickyArg,
+    XrmoptionSepArg,
+    XrmoptionResArg,
+    XrmoptionSkipArg,
+    XrmoptionSkipLine,
+    XrmoptionSkipNArgs,
+}
+
+XrmOptionDescRec :: struct {
+    option:    cstring,
+    specifier: cstring,
+    argKind:   XrmOptionKind,
+    value:     rawptr,
+}
+
+XrmOptionDescList :: [^]XrmOptionDescRec