diff options
91 files changed, 5705 insertions, 2383 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 6e0cafd74..2a7d8a551 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -131,7 +131,7 @@ type nkFormalParams, # formal parameters nkOfInherit, # inherited from symbol - nkModule, # the syntax tree of a module + nkImportAs, # a 'as' b in an import statement nkProcDef, # a proc nkMethodDef, # a method nkConverterDef, # a converter @@ -231,7 +231,8 @@ type sfVolatile, # variable is volatile sfRegister, # variable should be placed in a register sfPure, # object is "pure" that means it has no type-information - + # enum is "pure", its values need qualified access + # variable is "pure"; it's an explicit "global" sfNoSideEffect, # proc has no side effects sfSideEffect, # proc may have side effects; cannot prove it has none sfMainModule, # module is the main module @@ -386,7 +387,7 @@ type tfNeedsInit, # type constains a "not nil" constraint somewhere or some # other type so that it requires inititalization tfHasShared, # type constains a "shared" constraint modifier somewhere - tfHasMeta, # type has "typedesc" or "expr" somewhere + tfHasMeta, # type has "typedesc" or "expr" somewhere; or uses '|' tfHasGCedMem, # type contains GC'ed memory TTypeFlags* = set[TTypeFlag] @@ -640,6 +641,11 @@ type # this is because in incremental compilation, when a module is about to # be replaced with a newer version, we must decrement the usage count # of all previously used generics. + # For 'import as' we copy the module symbol but shallowCopy the 'tab' + # and set the 'usedGenerics' to ... XXX gah! Better set module.name + # instead? But this doesn't work either. --> We need an skModuleAlias? + # No need, just leave it as skModule but set the owner accordingly and + # check for the owner when touching 'usedGenerics'. usedGenerics*: seq[PInstantiation] tab*: TStrTable # interface table for modules else: nil @@ -1105,7 +1111,7 @@ proc copyType(t: PType, owner: PSym, keepId: bool): PType = proc copySym(s: PSym, keepId: bool = false): PSym = result = newSym(s.kind, s.name, s.owner, s.info) - result.ast = nil # BUGFIX; was: s.ast which made problems + #result.ast = nil # BUGFIX; was: s.ast which made problems result.typ = s.typ if keepId: result.id = s.id @@ -1120,6 +1126,20 @@ proc copySym(s: PSym, keepId: bool = false): PSym = result.position = s.position result.loc = s.loc result.annex = s.annex # BUGFIX + +proc createModuleAlias*(s: PSym, newIdent: PIdent, info: TLineInfo): PSym = + result = newSym(s.kind, newIdent, s.owner, info) + # keep ID! + result.ast = s.ast + result.id = s.id + result.flags = s.flags + system.shallowCopy(result.tab, s.tab) + result.options = s.options + result.position = s.position + result.loc = s.loc + result.annex = s.annex + # XXX once usedGenerics is used, ensure module aliases keep working! + assert s.usedGenerics == nil proc newSym(symKind: TSymKind, Name: PIdent, owner: PSym, info: TLineInfo): PSym = @@ -1190,7 +1210,7 @@ proc newSons(father: PNode, length: int) = setlen(father.sons, length) proc propagateToOwner*(owner, elem: PType) = - const HaveTheirOwnEmpty = {tySequence, tySet} + const HaveTheirOwnEmpty = {tySequence, tySet} owner.flags = owner.flags + (elem.flags * {tfHasShared, tfHasMeta, tfHasGCedMem}) if tfNotNil in elem.flags: diff --git a/compiler/c2nim/c2nim.nim b/compiler/c2nim/c2nim.nim index 029f9ecda..df1e42f23 100644 --- a/compiler/c2nim/c2nim.nim +++ b/compiler/c2nim/c2nim.nim @@ -19,6 +19,7 @@ c2nim - C to Nimrod source converter Usage: c2nim [options] inputfile [options] Options: -o, --out:FILE set output filename + --cpp process C++ input file --dynlib:SYMBOL import from dynlib: SYMBOL will be used for the import --header:HEADER_FILE import from a HEADER_FILE (discouraged!) --cdecl annotate procs with ``{.cdecl.}`` @@ -31,6 +32,8 @@ Options: --skipinclude do not convert ``#include`` to ``import`` --typeprefixes generate ``T`` and ``P`` type prefixes --skipcomments do not copy comments + --ignoreRValueRefs translate C++'s ``T&&`` to ``T`` instead ``of var T`` + --keepBodies keep C++'s method bodies -v, --version write c2nim's version -h, --help show this help """ diff --git a/compiler/c2nim/clex.nim b/compiler/c2nim/clex.nim index 5b648392f..f949b97cb 100644 --- a/compiler/c2nim/clex.nim +++ b/compiler/c2nim/clex.nim @@ -82,6 +82,8 @@ type pxParLe, pxBracketLe, pxCurlyLe, # this order is important pxParRi, pxBracketRi, pxCurlyRi, # for macro argument parsing! pxComma, pxSemiColon, pxColon, + pxAngleRi # '>' but determined to be the end of a + # template's angle bracket TTokKinds* = set[TTokKind] type @@ -202,6 +204,7 @@ proc TokKindToStr*(k: TTokKind): string = of pxColon: result = ":" of pxCurlyLe: result = "{" of pxCurlyRi: result = "}" + of pxAngleRi: result = "> [end of template]" proc `$`(tok: TToken): string = case tok.xkind diff --git a/compiler/c2nim/cparse.nim b/compiler/c2nim/cparse.nim index b964ed976..44be556db 100644 --- a/compiler/c2nim/cparse.nim +++ b/compiler/c2nim/cparse.nim @@ -1,7 +1,7 @@ # # # c2nim - C to Nimrod source converter -# (c) Copyright 2012 Andreas Rumpf +# (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -11,7 +11,11 @@ ## It translates a C source file into a Nimrod AST. Then the renderer can be ## used to convert the AST to its text representation. -# XXX cleanup of declaration handling. +# TODO +# - document 'cpp' mode +# - implement handling of '::': function declarations +# - C++'s "operator" still needs some love +# - support '#if' in classes import os, llstream, renderer, clex, idents, strutils, pegs, ast, astalgo, msgs, @@ -24,14 +28,17 @@ type pfStdCall, ## annotate procs with stdcall pfSkipInclude, ## skip all ``#include`` pfTypePrefixes, ## all generated types start with 'T' or 'P' - pfSkipComments ## do not generate comments + pfSkipComments, ## do not generate comments + pfCpp, ## process C++ + pfIgnoreRValueRefs, ## transform C++'s 'T&&' to 'T' + pfKeepBodies ## do not skip C++ method bodies - TMacro {.final.} = object + TMacro = object name: string params: int # number of parameters body: seq[ref TToken] # can contain pxMacroParam tokens - TParserOptions {.final.} = object + TParserOptions = object flags: set[TParserFlag] prefixes, suffixes: seq[string] mangleRules: seq[tuple[pattern: TPeg, frmt: string]] @@ -39,9 +46,10 @@ type dynlibSym, header: string macros: seq[TMacro] toMangle: PStringTable + classes: PStringTable PParserOptions* = ref TParserOptions - TParser* {.final.} = object + TParser* = object lex: TLexer tok: ref TToken # current token options: PParserOptions @@ -49,6 +57,7 @@ type inTypeDef: int scopeCounter: int hasDeadCodeElimPragma: bool + currentClass: PNode # type that needs to be added as 'this' parameter TReplaceTuple* = array[0..1, string] @@ -63,10 +72,11 @@ proc newParserOptions*(): PParserOptions = result.dynlibSym = "" result.header = "" result.toMangle = newStringTable(modeCaseSensitive) + result.classes = newStringTable(modeCaseSensitive) proc setOption*(parserOptions: PParserOptions, key: string, val=""): bool = result = true - case key + case key.normalize of "ref": incl(parserOptions.flags, pfRefs) of "dynlib": parserOptions.dynlibSym = val of "header": parserOptions.header = val @@ -77,6 +87,10 @@ proc setOption*(parserOptions: PParserOptions, key: string, val=""): bool = of "skipinclude": incl(parserOptions.flags, pfSkipInclude) of "typeprefixes": incl(parserOptions.flags, pfTypePrefixes) of "skipcomments": incl(parserOptions.flags, pfSkipComments) + of "cpp": incl(parserOptions.flags, pfCpp) + of "keepbodies": incl(parserOptions.flags, pfKeepBodies) + of "ignorervaluerefs": incl(parserOptions.flags, pfIgnoreRValueRefs) + of "class": parserOptions.classes[val] = "true" else: result = false proc ParseUnit*(p: var TParser): PNode @@ -94,6 +108,7 @@ proc OpenParser(p: var TParser, filename: string, new(p.tok) proc parMessage(p: TParser, msg: TMsgKind, arg = "") = + #assert false lexMessage(p.lex, msg, arg) proc CloseParser(p: var TParser) = CloseLexer(p.lex) @@ -116,6 +131,13 @@ proc rawGetTok(p: var TParser) = p.tok.next = t p.tok = t +proc insertAngleRi(currentToken: ref TToken) = + var t: ref TToken + new(t) + t.xkind = pxAngleRi + t.next = currentToken.next + currentToken.next = t + proc findMacro(p: TParser): int = for i in 0..high(p.options.macros): if p.tok.s == p.options.macros[i].name: return i @@ -215,22 +237,22 @@ proc getTok(p: var TParser, n: PNode) = getTok(p) skipCom(p, n) -proc ExpectIdent(p: TParser) = +proc expectIdent(p: TParser) = if p.tok.xkind != pxSymbol: parMessage(p, errIdentifierExpected, $(p.tok[])) -proc Eat(p: var TParser, xkind: TTokKind, n: PNode) = +proc eat(p: var TParser, xkind: TTokKind, n: PNode) = if p.tok.xkind == xkind: getTok(p, n) else: parMessage(p, errTokenExpected, TokKindToStr(xkind)) -proc Eat(p: var TParser, xkind: TTokKind) = +proc eat(p: var TParser, xkind: TTokKind) = if p.tok.xkind == xkind: getTok(p) else: parMessage(p, errTokenExpected, TokKindToStr(xkind)) -proc Eat(p: var TParser, tok: string, n: PNode) = +proc eat(p: var TParser, tok: string, n: PNode) = if p.tok.s == tok: getTok(p, n) else: parMessage(p, errTokenExpected, tok) -proc Opt(p: var TParser, xkind: TTokKind, n: PNode) = +proc opt(p: var TParser, xkind: TTokKind, n: PNode) = if p.tok.xkind == xkind: getTok(p, n) proc addSon(father, a, b: PNode) = @@ -342,10 +364,18 @@ proc fieldIdent(ident: string, p: TParser): PNode = addSon(result, pragmas) addSon(pragmas, newIdentStrLitPair("importc", ident, p)) -proc DoImport(ident: string, pragmas: PNode, p: TParser) = +proc doImport(ident: string, pragmas: PNode, p: TParser) = if p.options.dynlibSym.len > 0 or p.options.header.len > 0: addImportToPragma(pragmas, ident, p) +proc doImportCpp(ident: string, pragmas: PNode, p: TParser) = + if p.options.dynlibSym.len > 0 or p.options.header.len > 0: + addSon(pragmas, newIdentStrLitPair("importcpp", ident, p)) + if p.options.dynlibSym.len > 0: + addSon(pragmas, newIdentPair("dynlib", p.options.dynlibSym, p)) + else: + addSon(pragmas, newIdentStrLitPair("header", p.options.header, p)) + proc newBinary(opr: string, a, b: PNode, p: TParser): PNode = result = newNodeP(nkInfix, p) addSon(result, newIdentNodeP(getIdent(opr), p)) @@ -396,7 +426,7 @@ proc assignmentExpression(p: var TParser): PNode proc compoundStatement(p: var TParser): PNode proc statement(p: var TParser): PNode -proc declKeyword(s: string): bool = +proc declKeyword(p: TParser, s: string): bool = # returns true if it is a keyword that introduces a declaration case s of "extern", "static", "auto", "register", "const", "volatile", "restrict", @@ -404,6 +434,8 @@ proc declKeyword(s: string): bool = "__safecall", "void", "struct", "union", "enum", "typedef", "short", "int", "long", "float", "double", "signed", "unsigned", "char": result = true + of "class": + result = p.options.flags.contains(pfCpp) proc stmtKeyword(s: string): bool = case s @@ -423,9 +455,74 @@ proc skipConst(p: var TParser) = (p.tok.s == "const" or p.tok.s == "volatile" or p.tok.s == "restrict"): getTok(p, nil) +proc isTemplateAngleBracket(p: var TParser): bool = + if pfCpp notin p.options.flags: return false + saveContext(p) + getTok(p, nil) # skip "<" + var i: array[pxParLe..pxCurlyLe, int] + var angles = 0 + while true: + let kind = p.tok.xkind + case kind + of pxEof: break + of pxParLe, pxBracketLe, pxCurlyLe: inc(i[kind]) + of pxGt, pxAngleRi: + # end of arguments? + if i[pxParLe] == 0 and i[pxBracketLe] == 0 and i[pxCurlyLe] == 0 and + angles == 0: + # mark as end token: + p.tok.xkind = pxAngleRi + result = true; + break + if angles > 0: dec(angles) + of pxShr: + # >> can end a template too: + if i[pxParLe] == 0 and i[pxBracketLe] == 0 and i[pxCurlyLe] == 0 and + angles == 1: + p.tok.xkind = pxAngleRi + insertAngleRi(p.tok) + result = true + break + if angles > 1: dec(angles, 2) + of pxLt: inc(angles) + of pxParRi, pxBracketRi, pxCurlyRi: + let kind = pred(kind, 3) + if i[kind] > 0: dec(i[kind]) + else: break + of pxSemicolon: break + else: discard + getTok(p, nil) + backtrackContext(p) + +proc optAngle(p: var TParser, n: PNode): PNode = + if p.tok.xkind == pxLt and isTemplateAngleBracket(p): + getTok(p) + result = newNodeP(nkBracketExpr, p) + result.add(n) + while true: + let a = assignmentExpression(p) + if not a.isNil: result.add(a) + if p.tok.xkind != pxComma: break + getTok(p) + eat(p, pxAngleRi) + else: + result = n + +proc optScope(p: var TParser, n: PNode): PNode = + result = n + if pfCpp in p.options.flags: + while p.tok.xkind == pxScope: + let a = result + result = newNodeP(nkDotExpr, p) + result.add(a) + getTok(p, result) + expectIdent(p) + result.add(mangledIdent(p.tok.s, p)) + getTok(p, result) + proc typeAtom(p: var TParser): PNode = skipConst(p) - ExpectIdent(p) + expectIdent(p) case p.tok.s of "void": result = newNodeP(nkNilLit, p) # little hack @@ -451,6 +548,8 @@ proc typeAtom(p: var TParser): PNode = else: result = mangledIdent(p.tok.s, p) getTok(p, result) + result = optScope(p, result) + result = optAngle(p, result) proc newPointerTy(p: TParser, typ: PNode): PNode = if pfRefs in p.options.flags: @@ -458,16 +557,31 @@ proc newPointerTy(p: TParser, typ: PNode): PNode = else: result = newNodeP(nkPtrTy, p) result.addSon(typ) - + proc pointer(p: var TParser, a: PNode): PNode = result = a var i = 0 skipConst(p) - while p.tok.xkind == pxStar: - inc(i) - getTok(p, result) - skipConst(p) - result = newPointerTy(p, result) + while true: + if p.tok.xkind == pxStar: + inc(i) + getTok(p, result) + skipConst(p) + result = newPointerTy(p, result) + elif p.tok.xkind == pxAmp and pfCpp in p.options.flags: + getTok(p, result) + skipConst(p) + let b = result + result = newNodeP(nkVarTy, p) + result.add(b) + elif p.tok.xkind == pxAmpAmp and pfCpp in p.options.flags: + getTok(p, result) + skipConst(p) + if pfIgnoreRvalueRefs notin p.options.flags: + let b = result + result = newNodeP(nkVarTy, p) + result.add(b) + else: break if a.kind == nkIdent and a.ident.s == "char": if i >= 2: result = newIdentNodeP("cstringArray", p) @@ -553,9 +667,9 @@ proc takeOnlyFirstField(p: TParser, isUnion: bool): bool = # if we generate an interface to a header file, *all* fields can be # generated: result = isUnion and p.options.header.len == 0 - + proc parseStructBody(p: var TParser, isUnion: bool, - kind: TNodeKind = nkRecList): PNode = + kind: TNodeKind = nkRecList): PNode = result = newNodeP(kind, p) eat(p, pxCurlyLe, result) while p.tok.xkind notin {pxEof, pxCurlyRi}: @@ -682,7 +796,7 @@ proc addTypeDef(section, name, t: PNode) = proc otherTypeDef(p: var TParser, section, typ: PNode) = var name: PNode var t = typ - if p.tok.xkind == pxStar: + if p.tok.xkind in {pxStar, pxAmp, pxAmpAmp}: t = pointer(p, t) if p.tok.xkind == pxParLe: # function pointer: typedef typ (*name)(); @@ -819,6 +933,12 @@ proc parseTypeDef(p: var TParser): PNode = of "struct": parseTypedefStruct(p, result, isUnion=false) of "union": parseTypedefStruct(p, result, isUnion=true) of "enum": parseTypedefEnum(p, result) + of "class": + if pfCpp in p.options.flags: + parseTypedefStruct(p, result, isUnion=false) + else: + var t = typeAtom(p) + otherTypeDef(p, result, t) else: var t = typeAtom(p) otherTypeDef(p, result, t) @@ -871,22 +991,16 @@ proc parseVarDecl(p: var TParser, baseTyp, typ: PNode, addSon(result, def) eat(p, pxSemicolon) -when false: - proc declaration(p: var TParser, father: PNode) = - # general syntax to parse is:: - # - # baseType ::= typeIdent | ((struct|union|enum) ident ("{" body "}" )? - # | "{" body "}") - # declIdent ::= "(" "*" ident ")" formalParams ("=" exprNoComma)? - # | ident ((formalParams ("{" statements "}")?)|"=" - # exprNoComma|(typeSuffix("=" exprNoComma)? ))? - # declaration ::= baseType (pointers)? declIdent ("," declIdent)* - var pragmas = newNodeP(nkPragma, p) - - skipDeclarationSpecifiers(p) - parseCallConv(p, pragmas) - skipDeclarationSpecifiers(p) - expectIdent(p) +proc declarationName(p: var TParser): string = + expectIdent(p) + result = p.tok.s + getTok(p) # skip identifier + while p.tok.xkind == pxScope and pfCpp in p.options.flags: + getTok(p) # skip "::" + expectIdent(p) + result.add("::") + result.add(p.tok.s) + getTok(p) proc declaration(p: var TParser): PNode = result = newNodeP(nkProcDef, p) @@ -908,17 +1022,18 @@ proc declaration(p: var TParser): PNode = result = parseFunctionPointerDecl(p, rettyp) eat(p, pxSemicolon) return - ExpectIdent(p) - var origName = p.tok.s - getTok(p) # skip identifier - case p.tok.xkind - of pxParLe: + var origName = declarationName(p) + case p.tok.xkind + of pxParLe: # really a function! var name = mangledIdent(origName, p) var params = newNodeP(nkFormalParams, p) addReturnType(params, rettyp) parseFormalParams(p, params, pragmas) - + if pfCpp in p.options.flags and p.tok.xkind == pxSymbol and + p.tok.s == "const": + addSon(pragmas, newIdentNodeP("noSideEffect", p)) + getTok(p) if pfCDecl in p.options.flags: addSon(pragmas, newIdentNodeP("cdecl", p)) elif pfStdcall in p.options.flags: @@ -1027,10 +1142,10 @@ proc isDefinitelyAType(p: var TParser): bool = while true: case p.tok.xkind of pxSymbol: - if declKeyword(p.tok.s): return true + if declKeyword(p, p.tok.s): return true elif starFound: return false else: inc(words) - of pxStar: + of pxStar, pxAmp, pxAmpAmp: starFound = true of pxParRi: return words == 0 or words > 1 or starFound else: return false @@ -1071,6 +1186,7 @@ proc primaryExpression(p: var TParser): PNode = else: result = mangledIdent(p.tok.s, p) getTok(p, result) + result = optScope(p, result) of pxIntLit: result = newIntNodeP(nkIntLit, p.tok.iNumber, p) setBaseFlags(result, p.tok.base) @@ -1205,6 +1321,10 @@ proc postfixExpression(p: var TParser): PNode = addSon(result, newIdentNodeP("dec", p)) gettok(p, result) addSon(result, a) + of pxLt: + if isTemplateAngleBracket(p): + result = optAngle(p, result) + else: break else: break proc unaryExpression(p: var TParser): PNode = @@ -1222,9 +1342,24 @@ proc unaryExpression(p: var TParser): PNode = result = newNodeP(nkCall, p) addSon(result, newIdentNodeP("sizeof", p)) getTok(p, result) - if p.tok.xkind == pxParLe: + if p.tok.xkind == pxParLe: getTok(p, result) - addson(result, typeDesc(p)) + addSon(result, typeDesc(p)) + eat(p, pxParRi, result) + else: + addSon(result, unaryExpression(p)) + elif p.tok.s == "new" or p.tok.s == "delete" and pfCpp in p.options.flags: + var opr = p.tok.s + result = newNodeP(nkCall, p) + getTok(p, result) + if p.tok.xkind == pxBracketLe: + getTok(p) + eat(p, pxBracketRi) + opr.add("Array") + addSon(result, newIdentNodeP(opr, p)) + if p.tok.xkind == pxParLe: + getTok(p, result) + addSon(result, typeDesc(p)) eat(p, pxParRi, result) else: addSon(result, unaryExpression(p)) @@ -1455,14 +1590,14 @@ proc parseDoWhile(p: var TParser): PNode = proc declarationOrStatement(p: var TParser): PNode = if p.tok.xkind != pxSymbol: result = expressionStatement(p) - elif declKeyword(p.tok.s): + elif declKeyword(p, p.tok.s): result = declaration(p) else: # ordinary identifier: saveContext(p) getTok(p) # skip identifier to look ahead - case p.tok.xkind - of pxSymbol, pxStar: + case p.tok.xkind + of pxSymbol, pxStar, pxLt, pxAmp, pxAmpAmp: # we parse # a b # a * b @@ -1500,7 +1635,7 @@ proc parseTrailingDefinedIdents(p: var TParser, result, baseTyp: PNode) = if sonsLen(varSection) > 0: addSon(result, varSection) -proc parseStandaloneStruct(p: var TParser, isUnion: bool): PNode = +proc parseStandaloneStruct(p: var TParser, isUnion: bool): PNode = result = newNodeP(nkStmtList, p) saveContext(p) getTok(p, result) # skip "struct" or "union" @@ -1630,11 +1765,290 @@ proc compoundStatement(p: var TParser): PNode = if a.kind == nkEmpty: break embedStmts(result, a) if sonsLen(result) == 0: - # translate ``{}`` to Nimrod's ``nil`` statement - result = newNodeP(nkNilLit, p) + # translate ``{}`` to Nimrod's ``discard`` statement + result = newNodeP(nkDiscardStmt, p) + result.add(ast.emptyNode) dec(p.scopeCounter) eat(p, pxCurlyRi) +proc skipInheritKeyw(p: var TParser) = + if p.tok.xkind == pxSymbol and (p.tok.s == "private" or + p.tok.s == "protected" or + p.tok.s == "public"): + getTok(p) + +proc parseConstructor(p: var TParser, pragmas: PNode, + isDestructor=false): PNode = + var origName = p.tok.s + getTok(p) + + result = newNodeP(nkProcDef, p) + var rettyp = if isDestructor: newNodeP(nkNilLit, p) + else: mangledIdent(origName, p) + + let oname = if isDestructor: "destroy" & origName + else: "construct" & origName + var name = mangledIdent(oname, p) + var params = newNodeP(nkFormalParams, p) + addReturnType(params, rettyp) + if p.tok.xkind == pxParLe: + parseFormalParams(p, params, pragmas) + if p.tok.xkind == pxSymbol and p.tok.s == "const": + addSon(pragmas, newIdentNodeP("noSideEffect", p)) + if pfCDecl in p.options.flags: + addSon(pragmas, newIdentNodeP("cdecl", p)) + elif pfStdcall in p.options.flags: + addSon(pragmas, newIdentNodeP("stdcall", p)) + if p.tok.xkind == pxColon: + # skip initializer list: + while true: + getTok(p) + discard expression(p) + if p.tok.xkind != pxComma: break + # no pattern, no exceptions: + addSon(result, exportSym(p, name, origName), ast.emptyNode, ast.emptyNode) + addSon(result, params, pragmas, ast.emptyNode) # no exceptions + addSon(result, ast.emptyNode) # no body + case p.tok.xkind + of pxSemicolon: getTok(p) + of pxCurlyLe: + let body = compoundStatement(p) + if pfKeepBodies in p.options.flags: + result.sons[bodyPos] = body + else: + parMessage(p, errTokenExpected, ";") + if result.sons[bodyPos].kind == nkEmpty: + DoImport((if isDestructor: "~" else: "") & origName, pragmas, p) + elif isDestructor: + addSon(pragmas, newIdentNodeP("destructor", p)) + if sonsLen(result.sons[pragmasPos]) == 0: + result.sons[pragmasPos] = ast.emptyNode + +proc parseMethod(p: var TParser, origName: string, rettyp, pragmas: PNode, + isStatic: bool): PNode = + result = newNodeP(nkProcDef, p) + var params = newNodeP(nkFormalParams, p) + addReturnType(params, rettyp) + var thisDef = newNodeP(nkIdentDefs, p) + if not isStatic: + # declare 'this': + var t = newNodeP(nkVarTy, p) + t.add(p.currentClass) + addSon(thisDef, newIdentNodeP("this", p), t, ast.emptyNode) + params.add(thisDef) + parseFormalParams(p, params, pragmas) + if p.tok.xkind == pxSymbol and p.tok.s == "const": + addSon(pragmas, newIdentNodeP("noSideEffect", p)) + getTok(p, result) + if not isStatic: + # fix the type of the 'this' parameter: + thisDef.sons[1] = thisDef.sons[1].sons[0] + if pfCDecl in p.options.flags: + addSon(pragmas, newIdentNodeP("cdecl", p)) + elif pfStdcall in p.options.flags: + addSon(pragmas, newIdentNodeP("stdcall", p)) + # no pattern, no exceptions: + let methodName = newIdentNodeP(origName, p) + addSon(result, exportSym(p, methodName, origName), + ast.emptyNode, ast.emptyNode) + addSon(result, params, pragmas, ast.emptyNode) # no exceptions + addSon(result, ast.emptyNode) # no body + case p.tok.xkind + of pxSemicolon: getTok(p) + of pxCurlyLe: + let body = compoundStatement(p) + if pfKeepBodies in p.options.flags: + result.sons[bodyPos] = body + else: + parMessage(p, errTokenExpected, ";") + if result.sons[bodyPos].kind == nkEmpty: + if isStatic: DoImport(origName, pragmas, p) + else: DoImportCpp(origName, pragmas, p) + if sonsLen(result.sons[pragmasPos]) == 0: + result.sons[pragmasPos] = ast.emptyNode + +proc parseStandaloneClass(p: var TParser, isStruct: bool): PNode + +proc followedByParLe(p: var TParser): bool = + saveContext(p) + getTok(p) # skip Identifier + result = p.tok.xkind == pxParLe + backtrackContext(p) + +proc parseOperator(p: var TParser, origName: var string): bool = + getTok(p) # skip 'operator' keyword + case p.tok.xkind + of pxAmp..pxArrow: + # ordinary operator symbol: + origName.add(TokKindToStr(p.tok.xkind)) + getTok(p) + of pxSymbol: + if p.tok.s == "new" or p.tok.s == "delete": + origName.add(p.tok.s) + getTok(p) + if p.tok.xkind == pxBracketLe: + getTok(p) + eat(p, pxBracketRi) + origName.add("[]") + else: + # type converter + let x = typeAtom(p) + if x.kind == nkIdent: + origName.add(x.ident.s) + else: + parMessage(p, errGenerated, "operator symbol expected") + result = true + of pxParLe: + getTok(p) + eat(p, pxParRi) + origName.add("()") + of pxBracketLe: + getTok(p) + eat(p, pxBracketRi) + origName.add("[]") + else: + parMessage(p, errGenerated, "operator symbol expected") + +proc parseClass(p: var TParser; isStruct: bool; stmtList: PNode): PNode = + result = newNodeP(nkObjectTy, p) + addSon(result, ast.emptyNode, ast.emptyNode) # no pragmas, no inheritance + + var recList = newNodeP(nkRecList, p) + addSon(result, recList) + if p.tok.xkind == pxColon: + getTok(p, result) + skipInheritKeyw(p) + var baseTyp = typeAtom(p) + var inh = newNodeP(nkOfInherit, p) + inh.add(baseTyp) + if p.tok.xkind == pxComma: + parMessage(p, errGenerated, "multiple inheritance is not supported") + while p.tok.xkind == pxComma: + getTok(p) + skipInheritKeyw(p) + discard typeAtom(p) + result.sons[0] = inh + + eat(p, pxCurlyLe, result) + var private = not isStruct + var pragmas = newNodeP(nkPragma, p) + while p.tok.xkind notin {pxEof, pxCurlyRi}: + skipCom(p, stmtList) + if p.tok.xkind == pxSymbol and (p.tok.s == "private" or + p.tok.s == "protected"): + getTok(p, result) + eat(p, pxColon, result) + private = true + elif p.tok.xkind == pxSymbol and p.tok.s == "public": + getTok(p, result) + eat(p, pxColon, result) + private = false + if p.tok.xkind == pxSymbol and (p.tok.s == "friend" or p.tok.s == "using"): + # we skip friend declarations: + while p.tok.xkind notin {pxEof, pxSemicolon}: getTok(p) + eat(p, pxSemicolon) + elif p.tok.xkind == pxSymbol and p.tok.s == "enum": + let x = enumSpecifier(p) + if not private or pfKeepBodies in p.options.flags: stmtList.add(x) + elif p.tok.xkind == pxSymbol and p.tok.s == "typedef": + let x = parseTypeDef(p) + if not private or pfKeepBodies in p.options.flags: stmtList.add(x) + elif p.tok.xkind == pxSymbol and(p.tok.s == "struct" or p.tok.s == "class"): + let x = parseStandaloneClass(p, isStruct=p.tok.s == "struct") + if not private or pfKeepBodies in p.options.flags: stmtList.add(x) + elif p.tok.xkind == pxSymbol and p.tok.s == "union": + let x = parseStandaloneStruct(p, isUnion=true) + if not private or pfKeepBodies in p.options.flags: stmtList.add(x) + else: + if pragmas.len != 0: pragmas = newNodeP(nkPragma, p) + parseCallConv(p, pragmas) + var isStatic = false + if p.tok.xkind == pxSymbol and p.tok.s == "virtual": + getTok(p, stmtList) + if p.tok.xkind == pxSymbol and p.tok.s == "explicit": + getTok(p, stmtList) + if p.tok.xkind == pxSymbol and p.tok.s == "static": + getTok(p, stmtList) + isStatic = true + parseCallConv(p, pragmas) + if p.tok.xkind == pxSymbol and p.tok.s == p.currentClass.ident.s and + followedByParLe(p): + # constructor + let cons = parseConstructor(p, pragmas) + if not private or pfKeepBodies in p.options.flags: stmtList.add(cons) + elif p.tok.xkind == pxTilde: + # destructor + getTok(p, stmtList) + if p.tok.xkind == pxSymbol and p.tok.s == p.currentClass.ident.s: + let des = parseConstructor(p, pragmas, isDestructor=true) + if not private or pfKeepBodies in p.options.flags: stmtList.add(des) + else: + parMessage(p, errGenerated, "invalid destructor") + else: + # field declaration or method: + var baseTyp = typeAtom(p) + while true: + var def = newNodeP(nkIdentDefs, p) + var t = pointer(p, baseTyp) + let canBeMethod = p.tok.xkind != pxParLe + var origName: string + if p.tok.xkind == pxSymbol: + origName = p.tok.s + if p.tok.s == "operator": + var isConverter = parseOperator(p, origName) + let meth = parseMethod(p, origName, t, pragmas, isStatic) + if not private or pfKeepBodies in p.options.flags: + if isConverter: meth.kind = nkConverterDef + stmtList.add(meth) + break + var i = parseField(p, nkRecList) + if canBeMethod and p.tok.xkind == pxParLe: + let meth = parseMethod(p, origName, t, pragmas, isStatic) + if not private or pfKeepBodies in p.options.flags: + stmtList.add(meth) + else: + t = parseTypeSuffix(p, t) + addSon(def, i, t, ast.emptyNode) + if not isStatic: addSon(recList, def) + if p.tok.xkind != pxComma: break + getTok(p, def) + if p.tok.xkind == pxSemicolon: + getTok(p, lastSon(recList)) + eat(p, pxCurlyRi, result) + +proc parseStandaloneClass(p: var TParser, isStruct: bool): PNode = + result = newNodeP(nkStmtList, p) + saveContext(p) + getTok(p, result) # skip "class" or "struct" + var origName = "" + let oldClass = p.currentClass + if p.tok.xkind == pxSymbol: + markTypeIdent(p, nil) + origName = p.tok.s + getTok(p, result) + p.currentClass = mangledIdent(origName, p) + else: + p.currentClass = nil + if p.tok.xkind in {pxCurlyLe, pxSemiColon, pxColon}: + if origName.len > 0: + p.options.classes[origName] = "true" + + var typeSection = newNodeP(nkTypeSection, p) + addSon(result, typeSection) + + var name = mangledIdent(origName, p) + var t = parseClass(p, isStruct, result) + addTypeDef(typeSection, structPragmas(p, name, origName), t) + parseTrailingDefinedIdents(p, result, name) + else: + var t = parseTuple(p, isUnion=false) + parseTrailingDefinedIdents(p, result, t) + else: + backtrackContext(p) + result = declaration(p) + p.currentClass = oldClass + + include cpp proc statement(p: var TParser): PNode = @@ -1681,14 +2095,36 @@ proc statement(p: var TParser): PNode = eat(p, pxSemicolon) of "enum": result = enumSpecifier(p) of "typedef": result = parseTypeDef(p) - of "struct": result = parseStandaloneStruct(p, isUnion=false) - of "union": result = parseStandaloneStruct(p, isUnion=true) + of "union": result = parseStandaloneStruct(p, isUnion=true) + of "struct": + if pfCpp in p.options.flags: + result = parseStandaloneClass(p, isStruct=true) + else: + result = parseStandaloneStruct(p, isUnion=false) + of "class": + if pfCpp in p.options.flags: + result = parseStandaloneClass(p, isStruct=false) + else: + result = declarationOrStatement(p) + of "namespace": + if pfCpp in p.options.flags: + while p.tok.xkind notin {pxEof, pxCurlyLe}: getTok(p) + result = compoundStatement(p) + else: + result = declarationOrStatement(p) + of "using": + if pfCpp in p.options.flags: + while p.tok.xkind notin {pxEof, pxSemicolon}: getTok(p) + eat(p, pxSemicolon) + result = newNodeP(nkNilLit, p) + else: + result = declarationOrStatement(p) else: result = declarationOrStatement(p) of pxCurlyLe: result = compoundStatement(p) of pxDirective, pxDirectiveParLe: result = parseDir(p) - of pxLineComment, pxStarComment: + of pxLineComment, pxStarComment: result = newNodeP(nkCommentStmt, p) skipCom(p, result) of pxSemicolon: @@ -1703,10 +2139,10 @@ proc statement(p: var TParser): PNode = result = expressionStatement(p) assert result != nil -proc parseUnit(p: var TParser): PNode = +proc parseUnit(p: var TParser): PNode = result = newNodeP(nkStmtList, p) getTok(p) # read first token - while p.tok.xkind != pxEof: + while p.tok.xkind != pxEof: var s = statement(p) if s.kind != nkEmpty: embedStmts(result, s) diff --git a/compiler/c2nim/cpp.nim b/compiler/c2nim/cpp.nim index 439b000e7..2ce64e59b 100644 --- a/compiler/c2nim/cpp.nim +++ b/compiler/c2nim/cpp.nim @@ -26,7 +26,7 @@ proc skipLine(p: var TParser) = proc parseDefineBody(p: var TParser, tmplDef: PNode): string = if p.tok.xkind == pxCurlyLe or (p.tok.xkind == pxSymbol and ( - declKeyword(p.tok.s) or stmtKeyword(p.tok.s))): + declKeyword(p, p.tok.s) or stmtKeyword(p.tok.s))): addSon(tmplDef, statement(p)) result = "stmt" elif p.tok.xkind in {pxLineComment, pxNewLine}: @@ -323,7 +323,7 @@ proc parseDir(p: var TParser): PNode = discard setOption(p.options, p.tok.s) getTok(p) eatNewLine(p, nil) - of "dynlib", "header", "prefix", "suffix": + of "dynlib", "header", "prefix", "suffix", "class": var key = p.tok.s getTok(p) if p.tok.xkind != pxStrLit: ExpectIdent(p) diff --git a/compiler/c2nim/tests/matrix.h b/compiler/c2nim/tests/matrix.h new file mode 100644 index 000000000..715e9e43b --- /dev/null +++ b/compiler/c2nim/tests/matrix.h @@ -0,0 +1,240 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wx/matrix.h +// Purpose: wxTransformMatrix class. NOT YET USED +// Author: Chris Breeze, Julian Smart +// Modified by: Klaas Holwerda +// Created: 01/02/97 +// RCS-ID: $Id$ +// Copyright: (c) Julian Smart, Chris Breeze +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_MATRIXH__ +#define _WX_MATRIXH__ + +//! headerfiles="matrix.h wx/object.h" +#include "wx/object.h" +#include "wx/math.h" + +//! codefiles="matrix.cpp" + +// A simple 3x3 matrix. This may be replaced by a more general matrix +// class some day. +// +// Note: this is intended to be used in wxDC at some point to replace +// the current system of scaling/translation. It is not yet used. + +#def WXDLLIMPEXP_CORE +#header "wxmatrix.h" + +//:definition +// A 3x3 matrix to do 2D transformations. +// It can be used to map data to window coordinates, +// and also for manipulating your own data. +// For example drawing a picture (composed of several primitives) +// at a certain coordinate and angle within another parent picture. +// At all times m_isIdentity is set if the matrix itself is an Identity matrix. +// It is used where possible to optimize calculations. +class WXDLLIMPEXP_CORE wxTransformMatrix: public wxObject<string, string<ubyte>> +{ +public: + wxTransformMatrix(void); + wxTransformMatrix(const wxTransformMatrix& mat); + + ~wxTransformMatrix(void); + + //get the value in the matrix at col,row + //rows are horizontal (second index of m_matrix member) + //columns are vertical (first index of m_matrix member) + double GetValue(int col, int row) const; + + //set the value in the matrix at col,row + //rows are horizontal (second index of m_matrix member) + //columns are vertical (first index of m_matrix member) + void SetValue(int col, int row, double value); + + void operator = (const wxTransformMatrix& mat); + bool operator == (const wxTransformMatrix& mat) const; + bool operator != (const module::gah::wxTransformMatrix& mat) const; + + //multiply every element by t + wxTransformMatrix& operator*=(const double& t); + //divide every element by t + wxTransformMatrix& operator/=(const double& t); + //add matrix m to this t + wxTransformMatrix& operator+=(const wxTransformMatrix& m); + //subtract matrix m from this + wxTransformMatrix& operator-=(const wxTransformMatrix& m); + //multiply matrix m with this + wxTransformMatrix& operator*=(const wxTransformMatrix& m); + + // constant operators + + //multiply every element by t and return result + wxTransformMatrix operator*(const double& t) const; + //divide this matrix by t and return result + wxTransformMatrix operator/(const double& t) const; + //add matrix m to this and return result + wxTransformMatrix operator+(const wxTransformMatrix& m) const; + //subtract matrix m from this and return result + wxTransformMatrix operator-(const wxTransformMatrix& m) const; + //multiply this by matrix m and return result + wxTransformMatrix operator*(const wxTransformMatrix& m) const; + wxTransformMatrix operator-() const; + + //rows are horizontal (second index of m_matrix member) + //columns are vertical (first index of m_matrix member) + double& operator()(int col, int row); + + //rows are horizontal (second index of m_matrix member) + //columns are vertical (first index of m_matrix member) + double operator()(int col, int row) const; + + // Invert matrix + bool Invert(void); + + // Make into identity matrix + bool Identity(void); + + // Is the matrix the identity matrix? + // Only returns a flag, which is set whenever an operation + // is done. + inline bool IsIdentity(void) const { return m_isIdentity; } + + // This does an actual check. + inline bool IsIdentity1(void) const ; + + //Scale by scale (isotropic scaling i.e. the same in x and y): + //!ex: + //!code: | scale 0 0 | + //!code: matrix' = | 0 scale 0 | x matrix + //!code: | 0 0 scale | + bool Scale(double scale); + + //Scale with center point and x/y scale + // + //!ex: + //!code: | xs 0 xc(1-xs) | + //!code: matrix' = | 0 ys yc(1-ys) | x matrix + //!code: | 0 0 1 | + wxTransformMatrix& Scale(const double &xs, const double &ys,const double &xc, const double &yc); + + // mirror a matrix in x, y + //!ex: + //!code: | -1 0 0 | + //!code: matrix' = | 0 -1 0 | x matrix + //!code: | 0 0 1 | + wxTransformMatrix<float>& Mirror(bool x=true, bool y=false); + // Translate by dx, dy: + //!ex: + //!code: | 1 0 dx | + //!code: matrix' = | 0 1 dy | x matrix + //!code: | 0 0 1 | + bool Translate(double x, double y); + + // Rotate clockwise by the given number of degrees: + //!ex: + //!code: | cos sin 0 | + //!code: matrix' = | -sin cos 0 | x matrix + //!code: | 0 0 1 | + bool Rotate(double angle); + + //Rotate counter clockwise with point of rotation + // + //!ex: + //!code: | cos(r) -sin(r) x(1-cos(r))+y(sin(r)| + //!code: matrix' = | sin(r) cos(r) y(1-cos(r))-x(sin(r)| x matrix + //!code: | 0 0 1 | + wxTransformMatrix& Rotate(const double &r, const double &x, const double &y); + + // Transform X value from logical to device + inline double TransformX(double x) const; + + // Transform Y value from logical to device + inline double TransformY(double y) const; + + // Transform a point from logical to device coordinates + bool TransformPoint(double x, double y, double& tx, double& ty) const; + + // Transform a point from device to logical coordinates. + // Example of use: + // wxTransformMatrix mat = dc.GetTransformation(); + // mat.Invert(); + // mat.InverseTransformPoint(x, y, x1, y1); + // OR (shorthand:) + // dc.LogicalToDevice(x, y, x1, y1); + // The latter is slightly less efficient if we're doing several + // conversions, since the matrix is inverted several times. + // N.B. 'this' matrix is the inverse at this point + bool InverseTransformPoint(double x, double y, double& tx, double& ty) const; + + double Get_scaleX(); + double Get_scaleY(); + double GetRotation(); + void SetRotation(double rotation); + + +public: + double m_matrix[3][3]; + bool m_isIdentity; +}; + + +/* +Chris Breeze reported, that +some functions of wxTransformMatrix cannot work because it is not +known if he matrix has been inverted. Be careful when using it. +*/ + +// Transform X value from logical to device +// warning: this function can only be used for this purpose +// because no rotation is involved when mapping logical to device coordinates +// mirror and scaling for x and y will be part of the matrix +// if you have a matrix that is rotated, eg a shape containing a matrix to place +// it in the logical coordinate system, use TransformPoint +inline double wxTransformMatrix::TransformX(double x) const +{ + //normally like this, but since no rotation is involved (only mirror and scale) + //we can do without Y -> m_matrix[1]{0] is -sin(rotation angle) and therefore zero + //(x * m_matrix[0][0] + y * m_matrix[1][0] + m_matrix[2][0])) + return (m_isIdentity ? x : (x * m_matrix[0][0] + m_matrix[2][0])); +} + +// Transform Y value from logical to device +// warning: this function can only be used for this purpose +// because no rotation is involved when mapping logical to device coordinates +// mirror and scaling for x and y will be part of the matrix +// if you have a matrix that is rotated, eg a shape containing a matrix to place +// it in the logical coordinate system, use TransformPoint +inline double wxTransformMatrix::TransformY(double y) const +{ + //normally like this, but since no rotation is involved (only mirror and scale) + //we can do without X -> m_matrix[0]{1] is sin(rotation angle) and therefore zero + //(x * m_matrix[0][1] + y * m_matrix[1][1] + m_matrix[2][1])) + return (m_isIdentity ? y : (y * m_matrix[1][1] + m_matrix[2][1])); +} + + +// Is the matrix the identity matrix? +// Each operation checks whether the result is still the identity matrix and sets a flag. +inline bool wxTransformMatrix::IsIdentity1(void) const +{ + return + ( wxIsSameDouble(m_matrix[0][0], 1.0) && + wxIsSameDouble(m_matrix[1][1], 1.0) && + wxIsSameDouble(m_matrix[2][2], 1.0) && + wxIsSameDouble(m_matrix[1][0], 0.0) && + wxIsSameDouble(m_matrix[2][0], 0.0) && + wxIsSameDouble(m_matrix[0][1], 0.0) && + wxIsSameDouble(m_matrix[2][1], 0.0) && + wxIsSameDouble(m_matrix[0][2], 0.0) && + wxIsSameDouble(m_matrix[1][2], 0.0) ); +} + +// Calculates the determinant of a 2 x 2 matrix +inline double wxCalculateDet(double a11, double a21, double a12, double a22) +{ + return a11 * a22 - a12 * a21; +} + +#endif // _WX_MATRIXH__ diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 6b3906226..c50fd4536 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -304,7 +304,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = of tyObject: # XXX: check for subtyping? if needsComplexAssignment(ty): - if asgnComplexity(ty.n) <= 4: + if ty.sons[0].isNil and asgnComplexity(ty.n) <= 4: discard getTypeDesc(p.module, ty) internalAssert ty.n != nil genOptAsgnObject(p, dest, src, flags, ty.n) @@ -1017,7 +1017,6 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) = rawGenNew(p, tmp, nil) t = t.sons[0].skipTypes(abstractInst) r = ropef("(*$1)", r) - # XXX object initialization? but not necessary for temps, is it? discard getTypeDesc(p.module, t) for i in 1 .. <e.len: let it = e.sons[i] diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 8115abc2f..75cabf414 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -151,8 +151,9 @@ proc genSingleVar(p: BProc, a: PNode) = var targetProc = p var immediateAsgn = a.sons[2].kind != nkEmpty if sfGlobal in v.flags: - if v.owner.kind != skModule: - targetProc = p.module.postInitProc + if sfPure in v.flags: + # v.owner.kind != skModule: + targetProc = p.module.preInitProc assignGlobalVar(targetProc, v) # XXX: be careful here. # Global variables should not be zeromem-ed within loops @@ -855,7 +856,11 @@ proc genAsmStmt(p: BProc, t: PNode) = assert(t.kind == nkAsmStmt) genLineDir(p, t) var s = genAsmOrEmitStmt(p, t, isAsmStmt=true) - lineF(p, cpsStmts, CC[ccompiler].asmStmtFrmt, [s]) + if p.prc == nil: + # top level asm statement? + appf(p.module.s[cfsProcHeaders], CC[ccompiler].asmStmtFrmt, [s]) + else: + lineF(p, cpsStmts, CC[ccompiler].asmStmtFrmt, [s]) proc genEmit(p: BProc, t: PNode) = genLineDir(p, t) diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 0c3f2da84..910e675e1 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -384,12 +384,6 @@ proc initLocalVar(p: BProc, v: PSym, immediateAsgn: bool) = if not immediateAsgn: constructLoc(p, v.loc) -proc initTemp(p: BProc, tmp: var TLoc) = - # XXX: This is still suspicious. - # Objects should always be constructed? - if containsGarbageCollectedRef(tmp.t) or isInvalidReturnType(tmp.t): - constructLoc(p, tmp) - proc getTemp(p: BProc, t: PType, result: var TLoc) = inc(p.labels) if gCmd == cmdCompileToLLVM: @@ -402,7 +396,7 @@ proc getTemp(p: BProc, t: PType, result: var TLoc) = result.t = getUniqueType(t) result.s = OnStack result.flags = {} - initTemp(p, result) + constructLoc(p, result) proc keepAlive(p: BProc, toKeepAlive: TLoc) = when false: @@ -767,6 +761,7 @@ proc genProcAux(m: BModule, prc: PSym) = if skipTypes(res.typ, abstractInst).kind == tyArray: incl(res.loc.flags, lfIndirect) res.loc.s = OnUnknown + for i in countup(1, sonsLen(prc.typ.n) - 1): var param = prc.typ.n.sons[i].sym if param.typ.isCompileTimeOnly: continue @@ -774,7 +769,9 @@ proc genProcAux(m: BModule, prc: PSym) = closureSetup(p, prc) genStmts(p, prc.getBody) # modifies p.locals, p.init, etc. var generatedProc: PRope - if sfPure in prc.flags: + if sfPure in prc.flags: + if hasNakedDeclspec in extccomp.CC[extccomp.ccompiler].props: + header = con("__declspec(naked) ", header) generatedProc = rfmt(nil, "$N$1 {$n$2$3$4}$N$N", header, p.s(cpsLocals), p.s(cpsInit), p.s(cpsStmts)) else: @@ -807,8 +804,11 @@ proc genProcPrototype(m: BModule, sym: PSym) = app(m.s[cfsVars], rfmt(nil, "extern $1 $2;$n", getTypeDesc(m, sym.loc.t), mangleDynLibProc(sym))) if gCmd == cmdCompileToLLVM: incl(sym.loc.flags, lfIndirect) - elif not ContainsOrIncl(m.declaredProtos, sym.id): - app(m.s[cfsProcHeaders], rfmt(nil, "$1;$n", genProcHeader(m, sym))) + elif not ContainsOrIncl(m.declaredProtos, sym.id): + var header = genProcHeader(m, sym) + if sfPure in sym.flags and hasNakedAttribute in CC[ccompiler].props: + header.app(" __attribute__((naked))") + app(m.s[cfsProcHeaders], rfmt(nil, "$1;$n", header)) proc genProcNoForward(m: BModule, prc: PSym) = fillProcLoc(prc) @@ -998,12 +998,15 @@ proc genMainProc(m: BModule) = gBreakpoints, mainModInit, toRope(m.labels)]) if optNoMain notin gGlobalOptions: appcg(m, m.s[cfsProcs], otherMain, []) - -proc getInitName(m: PSym): PRope = - result = ropeff("$1Init", "@$1Init", [toRope(m.name.s)]) -proc getDatInitName(m: PSym): PRope = - result = ropeff("$1DatInit", "@$1DatInit", [toRope(m.name.s)]) +proc getSomeInitName(m: PSym, suffix: string): PRope = + if {sfSystemModule, sfMainModule} * m.flags == {}: + result = m.info.toFullPath.getPackageName.mangle.toRope + result.app m.name.s + result.app suffix + +proc getInitName(m: PSym): PRope = getSomeInitName(m, "Init") +proc getDatInitName(m: PSym): PRope = getSomeInitName(m, "DatInit") proc registerModuleToMain(m: PSym) = var @@ -1173,7 +1176,7 @@ proc resetCgenModules* = for m in cgenModules(): resetModule(m) proc rawNewModule(module: PSym): BModule = - result = rawNewModule(module, module.filename) + result = rawNewModule(module, module.position.int32.toFullPath) proc newModule(module: PSym): BModule = # we should create only one cgen module for each module sym @@ -1216,7 +1219,7 @@ proc writeHeader(m: BModule) = writeRope(result, m.filename) proc getCFile(m: BModule): string = - result = changeFileExt(completeCFilePath(m.cfilename), cExt) + result = changeFileExt(completeCFilePath(m.cfilename.withPackageName), cExt) proc myOpenCached(module: PSym, rd: PRodReader): PPassContext = assert optSymbolFiles in gGlobalOptions diff --git a/compiler/commands.nim b/compiler/commands.nim index ca0c309bd..d3266930b 100644 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -11,7 +11,7 @@ import os, msgs, options, nversion, condsyms, strutils, extccomp, platform, lists, - wordrecg, parseutils, babelcmd + wordrecg, parseutils, babelcmd, idents proc writeCommandLineUsage*() @@ -512,6 +512,13 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) = gListFullPaths = true of "dynliboverride": dynlibOverride(switch, arg, pass, info) + of "cs": + expectArg(switch, arg, pass, info) + case arg + of "partial": idents.firstCharIsCS = true + of "none": idents.firstCharIsCS = false + else: LocalError(info, errGenerated, + "'partial' or 'none' expected, but found " & arg) else: if strutils.find(switch, '.') >= 0: options.setConfigVar(switch, arg) else: InvalidCmdLineOption(pass, switch, info) diff --git a/compiler/evals.nim b/compiler/evals.nim index f8336fce7..7e2c8a41d 100644 --- a/compiler/evals.nim +++ b/compiler/evals.nim @@ -162,10 +162,11 @@ var gNestedEvals: int # count the recursive calls to ``evalAux`` to prevent # endless recursion -proc evalWhile(c: PEvalContext, n: PNode): PNode = - while true: +proc evalWhile(c: PEvalContext, n: PNode): PNode = + while true: evalX(n.sons[0], {}) - if getOrdValue(result) == 0: break + if getOrdValue(result) == 0: + result = emptyNode; break result = evalAux(c, n.sons[1], {}) case result.kind of nkBreakStmt: @@ -304,7 +305,7 @@ proc allocSlot(c: PStackFrame; sym: PSym): int = setLen(c.slots, max(result+1, c.slots.len)) proc setSlot(c: PStackFrame, sym: PSym, val: PNode) = - assert sym.owner == c.prc + assert sym.owner == c.prc or sfFromGeneric in sym.flags let idx = allocSlot(c, sym) c.slots[idx] = val @@ -377,7 +378,7 @@ proc evalVariable(c: PStackFrame, sym: PSym, flags: TEvalFlags): PNode = #result = emptyNode proc evalGlobalVar(c: PEvalContext, s: PSym, flags: TEvalFlags): PNode = - if sfCompileTime in s.flags or c.mode == emRepl: + if sfCompileTime in s.flags or c.mode == emRepl or s.kind == skForVar: result = IdNodeTableGet(c.globals, s) if result != nil: if not aliasNeeded(result, flags): @@ -549,7 +550,9 @@ proc evalSym(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode = of skProc, skConverter, skMacro, skType: result = n #result = s.getBody - of skVar, skLet, skForVar, skTemp, skResult: + of skForVar: + result = evalGlobalVar(c, s, flags) + of skVar, skLet, skTemp, skResult: if sfGlobal notin s.flags: result = evalVariable(c.tos, s, flags) else: @@ -1396,7 +1399,7 @@ proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode = of nkChckRangeF, nkChckRange64, nkChckRange: result = evalRangeChck(c, n) of nkStringToCString: result = evalConvStrToCStr(c, n) of nkCStringToString: result = evalConvCStrToStr(c, n) - of nkStmtListExpr, nkStmtList, nkModule: + of nkStmtListExpr, nkStmtList: for i in countup(0, sonsLen(n) - 1): result = evalAux(c, n.sons[i], flags) case result.kind @@ -1455,7 +1458,7 @@ proc evalConstExprAux*(p: PEvalContext, module, prc: PSym, e: PNode): PNode = proc setupMacroParam(x: PNode): PNode = result = x - if result.kind == nkHiddenStdConv: result = result.sons[1] + if result.kind in {nkHiddenSubConv, nkHiddenStdConv}: result = result.sons[1] proc evalMacroCall(c: PEvalContext, n, nOrig: PNode, sym: PSym): PNode = # XXX GlobalError() is ugly here, but I don't know a better solution for now diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index 488ed18fb..d7f3386e3 100644 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -23,7 +23,9 @@ type hasCpp, # CC is/contains a C++ compiler hasAssume, # CC has __assume (Visual C extension) hasGcGuard, # CC supports GC_GUARD to keep stack roots - hasGnuAsm # CC's asm uses the absurd GNU assembler syntax + hasGnuAsm, # CC's asm uses the absurd GNU assembler syntax + hasNakedDeclspec, # CC has __declspec(naked) + hasNakedAttribute # CC has __attribute__((naked)) TInfoCCProps* = set[TInfoCCProp] TInfoCC* = tuple[ name: string, # the short name of the compiler @@ -73,7 +75,8 @@ compiler gcc: debug: "", pic: "-fPIC", asmStmtFrmt: "asm($1);$n", - props: {hasSwitchRange, hasComputedGoto, hasCpp, hasGcGuard, hasGnuAsm}) + props: {hasSwitchRange, hasComputedGoto, hasCpp, hasGcGuard, hasGnuAsm, + hasNakedAttribute}) compiler gpp: result = gcc() @@ -120,7 +123,7 @@ compiler vcc: debug: " /GZ /Zi ", pic: "", asmStmtFrmt: "__asm{$n$1$n}$n", - props: {hasCpp, hasAssume}) + props: {hasCpp, hasAssume, hasNakedDeclspec}) compiler icl: # Intel compilers try to imitate the native ones (gcc and msvc) @@ -298,13 +301,13 @@ const gpp()] const - hExt* = "h" + hExt* = ".h" var cCompiler* = ccGcc # the used compiler - cExt* = "c" # extension of generated C/C++ files - # (can be changed to .cpp later) + cExt* = ".c" # extension of generated C/C++ files + # (can be changed to .cpp later) cIncludes*: seq[string] = @[] # directories to search for included files cLibs*: seq[string] = @[] # directories to search for lib files @@ -518,7 +521,7 @@ proc footprint(filename: string): TCrc32 = getCompileCFileCmd(filename, true) proc externalFileChanged(filename: string): bool = - var crcFile = toGeneratedFile(filename, "crc") + var crcFile = toGeneratedFile(filename.withPackageName, "crc") var currentCrc = int(footprint(filename)) var f: TFile if open(f, crcFile, fmRead): diff --git a/compiler/hlo.nim b/compiler/hlo.nim index 152fd4414..1492ed76f 100644 --- a/compiler/hlo.nim +++ b/compiler/hlo.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2012 Andreas Rumpf +# (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -30,8 +30,6 @@ proc evalPattern(c: PContext, n, orig: PNode): PNode = if optHints in gOptions and hintPattern in gNotes: Message(orig.info, hintPattern, rule & " --> '" & renderTree(result, {renderNoComments}) & "'") - # check the resulting AST for optimization rules again: - result = hlo(c, result) proc applyPatterns(c: PContext, n: PNode): PNode = result = n @@ -44,6 +42,7 @@ proc applyPatterns(c: PContext, n: PNode): PNode = let x = applyRule(c, pattern, result) if not isNil(x): assert x.kind in {nkStmtList, nkCall} + # better be safe than sorry, so check evalTemplateCounter too: inc(evalTemplateCounter) if evalTemplateCounter > 100: GlobalError(n.info, errTemplateInstantiationTooNested) @@ -60,11 +59,18 @@ proc applyPatterns(c: PContext, n: PNode): PNode = c.patterns[i] = pattern proc hlo(c: PContext, n: PNode): PNode = + inc(c.hloLoopDetector) + # simply stop and do not perform any further transformations: + if c.hloLoopDetector > 300: return n case n.kind of nkMacroDef, nkTemplateDef, procDefs: # already processed (special cases in semstmts.nim) result = n else: + if n.kind in {nkFastAsgn, nkAsgn, nkIdentDefs, nkVarTuple} and + n.sons[0].kind == nkSym and sfGlobal in n.sons[0].sym.flags: + # do not optimize 'var g {.global} = re(...)' again! + return n result = applyPatterns(c, n) if result == n: # no optimization applied, try subtrees: @@ -74,18 +80,23 @@ proc hlo(c: PContext, n: PNode): PNode = if h != a: result.sons[i] = h else: # perform type checking, so that the replacement still fits: - if n.typ == nil and (result.typ == nil or - result.typ.kind in {tyStmt, tyEmpty}): + if isEmptyType(n.typ) and isEmptyType(result.typ): nil else: result = fitNode(c, n.typ, result) + # optimization has been applied so check again: + result = commonOptimizations(c.module, result) + result = hlo(c, result) + result = commonOptimizations(c.module, result) proc hloBody(c: PContext, n: PNode): PNode = # fast exit: if c.patterns.len == 0 or optPatterns notin gOptions: return n + c.hloLoopDetector = 0 result = hlo(c, n) proc hloStmt(c: PContext, n: PNode): PNode = # fast exit: if c.patterns.len == 0 or optPatterns notin gOptions: return n + c.hloLoopDetector = 0 result = hlo(c, n) diff --git a/compiler/idents.nim b/compiler/idents.nim index f0935c204..1e6f9d2fd 100644 --- a/compiler/idents.nim +++ b/compiler/idents.nim @@ -24,10 +24,13 @@ type s*: string next*: PIdent # for hash-table chaining h*: THash # hash value of s - + +var firstCharIsCS*: bool var buckets*: array[0..4096 * 2 - 1, PIdent] proc cmpIgnoreStyle(a, b: cstring, blen: int): int = + if firstCharIsCS: + if a[0] != b[0]: return 1 var i = 0 var j = 0 result = 1 diff --git a/compiler/importer.nim b/compiler/importer.nim index 7159072f7..8b854bcc6 100644 --- a/compiler/importer.nim +++ b/compiler/importer.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2012 Andreas Rumpf +# (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -27,17 +27,28 @@ proc getModuleName*(n: PNode): string = result = n.ident.s of nkSym: result = n.sym.name.s - else: + of nkInfix: + if n.sons[0].kind == nkIdent and n.sons[0].ident.id == getIdent("as").id: + # XXX hack ahead: + n.kind = nkImportAs + n.sons[0] = n.sons[1] + n.sons[1] = n.sons[2] + n.sons.setLen(2) + return getModuleName(n.sons[0]) # hacky way to implement 'x / y /../ z': result = renderTree(n, {renderNoComments}).replace(" ") - #localError(n.info, errGenerated, - # "invalide module name: '$1'" % renderTree(n)) - #result = "" + of nkDotExpr: + result = renderTree(n, {renderNoComments}).replace(".", "/") + of nkImportAs: + result = getModuleName(n.sons[0]) + else: + localError(n.info, errGenerated, "invalid module name: '$1'" % n.renderTree) + result = "" proc checkModuleName*(n: PNode): int32 = # This returns the full canonical path for a given module import let modulename = n.getModuleName - let fullPath = findModule(modulename) + let fullPath = findModule(modulename, n.info.toFullPath) if fullPath.len == 0: LocalError(n.info, errCannotOpenFile, modulename) result = InvalidFileIDX @@ -135,15 +146,28 @@ proc importForwarded(c: PContext, n: PNode, exceptSet: TIntSet) = for i in 0 ..safeLen(n)-1: importForwarded(c, n.sons[i], exceptSet) +proc importModuleAs(n: PNode, realModule: PSym): PSym = + result = realModule + if n.kind != nkImportAs: discard + elif n.len != 2 or n.sons[1].kind != nkIdent: + localError(n.info, errGenerated, "module alias must be an identifier") + elif n.sons[1].ident.id != realModule.name.id: + # some misguided guy will write 'import abc.foo as foo' ... + result = createModuleAlias(realModule, n.sons[1].ident, n.sons[1].info) + +proc myImportModule(c: PContext, n: PNode): PSym = + var f = checkModuleName(n) + if f != InvalidFileIDX: + result = importModuleAs(n, gImportModule(c.module, f)) + if sfDeprecated in result.flags: + Message(n.info, warnDeprecated, result.name.s) + proc evalImport(c: PContext, n: PNode): PNode = result = n var emptySet: TIntSet for i in countup(0, sonsLen(n) - 1): - var f = checkModuleName(n.sons[i]) - if f != InvalidFileIDX: - var m = gImportModule(c.module, f) - if sfDeprecated in m.flags: - Message(n.sons[i].info, warnDeprecated, m.name.s) + var m = myImportModule(c, n.sons[i]) + if m != nil: # ``addDecl`` needs to be done before ``importAllSymbols``! addDecl(c, m) # add symbol to symbol table of module importAllSymbolsExcept(c, m, emptySet) @@ -152,21 +176,19 @@ proc evalImport(c: PContext, n: PNode): PNode = proc evalFrom(c: PContext, n: PNode): PNode = result = n checkMinSonsLen(n, 2) - var f = checkModuleName(n.sons[0]) - if f != InvalidFileIDX: - var m = gImportModule(c.module, f) + var m = myImportModule(c, n.sons[0]) + if m != nil: n.sons[0] = newSymNode(m) addDecl(c, m) # add symbol to symbol table of module - for i in countup(1, sonsLen(n) - 1): + for i in countup(1, sonsLen(n) - 1): if n.sons[i].kind != nkNilLit: importSymbol(c, n.sons[i], m) proc evalImportExcept*(c: PContext, n: PNode): PNode = result = n checkMinSonsLen(n, 2) - var f = checkModuleName(n.sons[0]) - if f != InvalidFileIDX: - var m = gImportModule(c.module, f) + var m = myImportModule(c, n.sons[0]) + if m != nil: n.sons[0] = newSymNode(m) addDecl(c, m) # add symbol to symbol table of module var exceptSet = initIntSet() diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index fc186c379..54ee43069 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -302,12 +302,12 @@ const # magic checked op; magic unchecked op; checked op; unchecked op ["", "", "($1 <= $2)", "($1 <= $2)"], # LeB ["", "", "($1 < $2)", "($1 < $2)"], # LtB ["", "", "($1 == $2)", "($1 == $2)"], # EqRef - ["", "", "($1 == $2)", "($1 == $2)"], # EqProc ["", "", "($1 == $2)", "($1 == $2)"], # EqUntracedRef ["", "", "($1 <= $2)", "($1 <= $2)"], # LePtr ["", "", "($1 < $2)", "($1 < $2)"], # LtPtr ["", "", "($1 == $2)", "($1 == $2)"], # EqCString ["", "", "($1 != $2)", "($1 != $2)"], # Xor + ["", "", "($1 == $2)", "($1 == $2)"], # EqProc ["NegInt", "", "NegInt($1)", "-($1)"], # UnaryMinusI ["NegInt64", "", "NegInt64($1)", "-($1)"], # UnaryMinusI64 ["AbsInt", "", "AbsInt($1)", "Math.abs($1)"], # AbsI @@ -402,12 +402,12 @@ const # magic checked op; magic unchecked op; checked op; unchecked op ["", "", "($1 <= $2)", "($1 <= $2)"], # LeB ["", "", "($1 < $2)", "($1 < $2)"], # LtB ["", "", "($1 == $2)", "($1 == $2)"], # EqRef - ["", "", "($1 == $2)", "($1 == $2)"], # EqProc ["", "", "($1 == $2)", "($1 == $2)"], # EqUntracedRef ["", "", "($1 <= $2)", "($1 <= $2)"], # LePtr ["", "", "($1 < $2)", "($1 < $2)"], # LtPtr ["", "", "($1 == $2)", "($1 == $2)"], # EqCString ["", "", "($1 != $2)", "($1 != $2)"], # Xor + ["", "", "($1 == $2)", "($1 == $2)"], # EqProc ["NegInt", "", "NegInt($1)", "-($1)"], # UnaryMinusI ["NegInt64", "", "NegInt64($1)", "-($1)"], # UnaryMinusI64 ["AbsInt", "", "AbsInt($1)", "Math.abs($1)"], # AbsI @@ -451,6 +451,15 @@ proc binaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) = r.res = ropef(frmt, [x.rdLoc, y.rdLoc]) r.kind = resExpr +proc ternaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) = + var x, y, z: TCompRes + useMagic(p, magic) + gen(p, n.sons[1], x) + gen(p, n.sons[2], y) + gen(p, n.sons[3], z) + r.res = ropef(frmt, [x.rdLoc, y.rdLoc, z.rdLoc]) + r.kind = resExpr + proc unaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) = useMagic(p, magic) gen(p, n.sons[1], r) @@ -984,7 +993,7 @@ proc genSym(p: PProc, n: PNode, r: var TCompRes) = of skProc, skConverter, skMethod: discard mangleName(s) r.res = s.loc.r - if lfNoDecl in s.loc.flags or s.magic != mNone or isGenericRoutine(s) or + if lfNoDecl in s.loc.flags or s.magic != mNone or {sfImportc, sfInfixCall} * s.flags != {}: nil elif s.kind == skMethod and s.getBody.kind == nkEmpty: @@ -1351,6 +1360,10 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) = of mEcho: genEcho(p, n, r) of mSlurp, mStaticExec: localError(n.info, errXMustBeCompileTime, n.sons[0].sym.name.s) + of mCopyStr: binaryExpr(p, n, r, "", "($1.slice($2,-1))") + of mCopyStrLast: ternaryExpr(p, n, r, "", "($1.slice($2, ($3)+1).concat(0))") + of mNewString: unaryExpr(p, n, r, "mnewString", "mnewString($1)") + of mNewStringOfCap: unaryExpr(p, n, r, "mnewString", "mnewString(0)") else: genCall(p, n, r) #else internalError(e.info, 'genMagic: ' + magicToStr[op]); @@ -1400,7 +1413,7 @@ proc genObjConstr(p: PProc, n: PNode, r: var TCompRes) = var a: TCompRes r.res = toRope("{") r.kind = resExpr - for i in countup(0, sonsLen(n) - 1): + for i in countup(1, sonsLen(n) - 1): if i > 0: app(r.res, ", ") var it = n.sons[i] InternalAssert it.kind == nkExprColonExpr @@ -1583,7 +1596,7 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) = let s = n.sons[namePos].sym discard mangleName(s) r.res = s.loc.r - if lfNoDecl in s.loc.flags or s.magic != mNone or isGenericRoutine(s): nil + if lfNoDecl in s.loc.flags or s.magic != mNone: nil elif not p.g.generatedSyms.containsOrIncl(s.id): app(p.locals, genProc(p, s)) of nkMetaNode: gen(p, n.sons[0], r) diff --git a/compiler/nimrod.cfg b/compiler/nimrod.cfg index fbebe1cec..ac8f732f1 100644 --- a/compiler/nimrod.cfg +++ b/compiler/nimrod.cfg @@ -2,7 +2,7 @@ mainModule:"nimrod.nim" -gc:markAndSweep +# gc:markAndSweep hint[XDeclaredButNotUsed]:off path:"llvm" diff --git a/compiler/nimrod.ini b/compiler/nimrod.ini index 22623993c..0dc44a7c9 100644 --- a/compiler/nimrod.ini +++ b/compiler/nimrod.ini @@ -1,8 +1,16 @@ [Project] Name: "Nimrod" Version: "$version" -OS: "windows;linux;macosx;solaris;freebsd;netbsd;openbsd" -CPU: "i386;amd64;powerpc64;arm" # ;sparc +Platforms: """ + windows: i386;amd64 + linux: i386;amd64;powerpc64;arm;sparc;mips + macosx: i386;amd64;powerpc64 + solaris: i386;amd64;sparc + freebsd: i386;amd64 + netbsd: i386;amd64 + openbsd: i386;amd64 + haiku: i386;amd64 +""" Authors: "Andreas Rumpf" Description: """This is the Nimrod Compiler. Nimrod is a new statically typed, diff --git a/compiler/nversion.nim b/compiler/nversion.nim index 498f418ab..db38354ce 100644 --- a/compiler/nversion.nim +++ b/compiler/nversion.nim @@ -18,5 +18,5 @@ const VersionPatch* = 3 VersionAsString* = $VersionMajor & "." & $VersionMinor & "." & $VersionPatch - RodFileVersion* = "1212" # modify this if the rod-format changes! + RodFileVersion* = "1214" # modify this if the rod-format changes! diff --git a/compiler/options.nim b/compiler/options.nim index 3c91d4439..ea6b91321 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -208,7 +208,31 @@ proc removeTrailingDirSep*(path: string): string = proc getGeneratedPath: string = result = if nimcacheDir.len > 0: nimcacheDir else: gProjectPath.shortenDir / genSubDir - + +proc getPackageName*(path: string): string = + var q = 1 + var b = 0 + if path[len(path)-1] in {dirsep, altsep}: q = 2 + for i in countdown(len(path)-q, 0): + if path[i] in {dirsep, altsep}: + if b == 0: b = i + else: + let x = path.substr(i+1, b-1) + case x.normalize + of "lib", "src", "source", "package", "pckg", "library", "private": + b = i + else: + return x.replace('.', '_') + result = "" + +proc withPackageName*(path: string): string = + let x = path.getPackageName + if x.len == 0: + result = path + else: + let (p, file, ext) = path.splitFile + result = (p / (x & '_' & file)) & ext + proc toGeneratedFile*(path, ext: string): string = ## converts "/home/a/mymodule.nim", "rod" to "/home/a/nimcache/mymodule.rod" var (head, tail) = splitPath(path) @@ -261,9 +285,13 @@ proc FindFile*(f: string): string {.procvar.} = if result.len == 0: result = f.toLower.rawFindFile2 -proc findModule*(modulename: string): string {.inline.} = +proc findModule*(modulename, currentModule: string): string = # returns path to module - result = FindFile(AddFileExt(modulename, nimExt)) + let m = addFileExt(modulename, nimExt) + let currentPath = currentModule.splitFile.dir + result = currentPath / m + if not existsFile(result): + result = FindFile(m) proc libCandidates*(s: string, dest: var seq[string]) = var le = strutils.find(s, '(') diff --git a/compiler/parser.nim b/compiler/parser.nim index 0d9d27e02..e8439466a 100644 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -1088,6 +1088,17 @@ proc parseExprStmt(p: var TParser): PNode = addSon(result, b) if b.kind == nkElse: break +proc parseModuleName(p: var TParser, kind: TNodeKind): PNode = + result = parseExpr(p) + when false: + # parseExpr already handles 'as' syntax ... + if p.tok.tokType == tkAs and kind == nkImportStmt: + let a = result + result = newNodeP(nkImportAs, p) + getTok(p) + result.add(a) + result.add(parseExpr(p)) + proc parseImport(p: var TParser, kind: TNodeKind): PNode = #| importStmt = 'import' optInd expr #| ((comma expr)* @@ -1095,7 +1106,7 @@ proc parseImport(p: var TParser, kind: TNodeKind): PNode = result = newNodeP(kind, p) getTok(p) # skip `import` or `export` optInd(p, result) - var a = parseExpr(p) + var a = parseModuleName(p, kind) addSon(result, a) if p.tok.tokType in {tkComma, tkExcept}: if p.tok.tokType == tkExcept: @@ -1104,10 +1115,10 @@ proc parseImport(p: var TParser, kind: TNodeKind): PNode = optInd(p, result) while true: # was: while p.tok.tokType notin {tkEof, tkSad, tkDed}: - a = parseExpr(p) - if a.kind == nkEmpty: break + a = parseModuleName(p, kind) + if a.kind == nkEmpty: break addSon(result, a) - if p.tok.tokType != tkComma: break + if p.tok.tokType != tkComma: break getTok(p) optInd(p, a) #expectNl(p) @@ -1128,11 +1139,11 @@ proc parseIncludeStmt(p: var TParser): PNode = #expectNl(p) proc parseFromStmt(p: var TParser): PNode = - #| fromStmt = 'from' expr 'import' optInd expr (comma expr)* + #| fromStmt = 'from' moduleName 'import' optInd expr (comma expr)* result = newNodeP(nkFromStmt, p) getTok(p) # skip `from` optInd(p, result) - var a = parseExpr(p) + var a = parseModuleName(p, nkImportStmt) addSon(result, a) #optInd(p, a); eat(p, tkImport) optInd(p, result) @@ -1429,7 +1440,7 @@ proc parseSection(p: var TParser, kind: TNodeKind, skipComment(p, result) while sameInd(p): case p.tok.tokType - of tkSymbol, tkAccent: + of tkSymbol, tkAccent, tkParLe: var a = defparser(p) skipComment(p, a) addSon(result, a) @@ -1787,7 +1798,9 @@ proc parseStmt(p: var TParser): PNode = if p.tok.indent == p.currInd: nil elif p.tok.tokType == tkSemicolon: - while p.tok.tokType == tkSemicolon: getTok(p) + getTok(p) + if p.tok.indent < 0 or p.tok.indent == p.currInd: discard + else: break else: if p.tok.indent > p.currInd: parMessage(p, errInvalidIndentation) @@ -1840,7 +1853,10 @@ proc parseTopLevelStmt(p: var TParser): PNode = else: parMessage(p, errInvalidIndentation) p.firstTok = false case p.tok.tokType - of tkSemicolon: getTok(p) + of tkSemicolon: + getTok(p) + if p.tok.indent <= 0: discard + else: parMessage(p, errInvalidIndentation) of tkEof: break else: result = complexOrSimpleStmt(p) diff --git a/compiler/patterns.nim b/compiler/patterns.nim index ff7f18ac0..b7792100f 100644 --- a/compiler/patterns.nim +++ b/compiler/patterns.nim @@ -237,15 +237,6 @@ proc addToArgList(result, n: PNode) = else: for i in 0 .. <n.len: result.add(n.sons[i]) -when false: - proc procPatternMatches*(c: PContext, s: PSym, n: PNode): bool = - ## for AST-based overloading: - var ctx: TPatternContext - ctx.owner = s - ctx.c = c - ctx.formals = sonsLen(s.typ)-1 - result = matches(ctx, s.ast.sons[patternPos], n) - proc applyRule*(c: PContext, s: PSym, n: PNode): PNode = ## returns a tree to semcheck if the rule triggered; nil otherwise var ctx: TPatternContext diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index aeffcdc4c..8c2425de3 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -569,6 +569,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, of wGlobal: noVal(it) incl(sym.flags, sfGlobal) + incl(sym.flags, sfPure) of wMerge: noval(it) incl(sym.flags, sfMerge) diff --git a/compiler/pretty.nim b/compiler/pretty.nim index 4545e1c55..5036a16a3 100644 --- a/compiler/pretty.nim +++ b/compiler/pretty.nim @@ -55,6 +55,10 @@ proc overwriteFiles*() = except EIO: rawMessage(errCannotOpenFile, newFile) +proc `=~`(s: string, a: openArray[string]): bool = + for x in a: + if s.startsWith(x): return true + proc beautifyName(s: string, k: TSymKind): string = result = newStringOfCap(s.len) var i = 0 @@ -64,7 +68,13 @@ proc beautifyName(s: string, k: TSymKind): string = when removeTP: if s[0] == 'T' and s[1] in {'A'..'Z'}: i = 1 - result.add toUpper(s[i]) + if s =~ ["int", "uint", "cint", "cuint", "clong", "cstring", "string", + "char", "byte", "bool", "openArray", "seq", "array", "void", + "pointer", "float", "csize", "cdouble", "cchar", "cschar", + "cshort", "cu"]: + result.add s[i] + else: + result.add toUpper(s[i]) of skConst, skEnumField: # for 'const' we keep how it's spelt; either upper case or lower case: result.add s[0] diff --git a/compiler/renderer.nim b/compiler/renderer.nim index efa4ecaba..f6fb0f8c0 100644 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -448,6 +448,7 @@ proc lsub(n: PNode): int = of nkPragma: result = lcomma(n) + 4 of nkCommentStmt: result = len(n.comment) of nkOfBranch: result = lcomma(n, 0, - 2) + lsub(lastSon(n)) + len("of_:_") + of nkImportAs: result = lsub(n.sons[0]) + len("_as_") + lsub(n.sons[1]) of nkElifBranch: result = lsons(n) + len("elif_:_") of nkElse: result = lsub(n.sons[0]) + len("else:_") of nkFinally: result = lsub(n.sons[0]) + len("finally:_") @@ -1191,6 +1192,11 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = putWithSpace(g, tkColon, ":") gcoms(g) gstmts(g, lastSon(n), c) + of nkImportAs: + gsub(g, n.sons[0]) + put(g, tkSpaces, Space) + putWithSpace(g, tkAs, "as") + gsub(g, n.sons[1]) of nkBindStmt: putWithSpace(g, tkBind, "bind") gcomma(g, n, c) diff --git a/compiler/rodread.nim b/compiler/rodread.nim index 562eaebab..6e6b83260 100644 --- a/compiler/rodread.nim +++ b/compiler/rodread.nim @@ -140,6 +140,7 @@ type memfile: TMemFile # unfortunately there is no point in time where we # can close this! XXX methods*: TSymSeq + origFile: string inViewMode: bool PRodReader* = ref TRodReader @@ -558,6 +559,9 @@ proc processRodFile(r: PRodReader, crc: TCrc32) = inc(r.pos) # skip ':' r.moduleID = decodeVInt(r.s, r.pos) setID(r.moduleID) + of "ORIGFILE": + inc(r.pos) + r.origFile = decodeStr(r.s, r.pos) of "OPTIONS": inc(r.pos) # skip ':' r.options = cast[TOptions](int32(decodeVInt(r.s, r.pos))) @@ -585,7 +589,7 @@ proc processRodFile(r: PRodReader, crc: TCrc32) = inc(r.line) while r.s[r.pos] != ')': let relativePath = decodeStr(r.s, r.pos) - let resolvedPath = relativePath.findModule + let resolvedPath = relativePath.findModule(r.origFile) let finalPath = if resolvedPath.len > 0: resolvedPath else: relativePath r.files.add(finalPath.fileInfoIdx) inc(r.pos) # skip #10 @@ -818,7 +822,7 @@ proc checkDep(fileIdx: int32): TReasonForRecompile = gMods[fileIdx].reason = rrNone # we need to set it here to avoid cycles result = rrNone var r: PRodReader = nil - var rodfile = toGeneratedFile(filename, RodExt) + var rodfile = toGeneratedFile(filename.withPackageName, RodExt) r = newRodReader(rodfile, crc, fileIdx) if r == nil: result = (if ExistsFile(rodfile): rrRodInvalid else: rrRodDoesNotExist) @@ -1036,6 +1040,10 @@ proc viewFile(rodfile: string) = r.moduleID = decodeVInt(r.s, r.pos) setID(r.moduleID) outf.writeln("ID:", $r.moduleID) + of "ORIGFILE": + inc(r.pos) + r.origFile = decodeStr(r.s, r.pos) + outf.writeln("ORIGFILE:", r.origFile) of "OPTIONS": inc(r.pos) # skip ':' r.options = cast[TOptions](int32(decodeVInt(r.s, r.pos))) @@ -1058,13 +1066,13 @@ proc viewFile(rodfile: string) = outf.write(" ", w) if r.s[r.pos] == ' ': inc(r.pos) outf.write("\n") - of "FILES": + of "FILES": inc(r.pos, 2) # skip "(\10" inc(r.line) outf.write("FILES(\n") while r.s[r.pos] != ')': let relativePath = decodeStr(r.s, r.pos) - let resolvedPath = relativePath.findModule + let resolvedPath = relativePath.findModule(r.origFile) let finalPath = if resolvedPath.len > 0: resolvedPath else: relativePath r.files.add(finalPath.fileInfoIdx) inc(r.pos) # skip #10 diff --git a/compiler/rodwrite.nim b/compiler/rodwrite.nim index 496fa49cf..2e52aeaa7 100644 --- a/compiler/rodwrite.nim +++ b/compiler/rodwrite.nim @@ -34,6 +34,7 @@ type sstack: TSymSeq # a stack of symbols to process tstack: TTypeSeq # a stack of types to process files: TStringSeq + origFile: string PRodWriter = ref TRodWriter @@ -81,6 +82,7 @@ proc newRodWriter(crc: TCrc32, module: PSym): PRodWriter = result.converters = "" result.methods = "" result.init = "" + result.origFile = module.info.toFilename result.data = newStringOfCap(12_000) proc addModDep(w: PRodWriter, dep: string) = @@ -91,7 +93,7 @@ const rodNL = "\x0A" proc addInclDep(w: PRodWriter, dep: string) = - var resolved = dep.findModule + var resolved = dep.findModule(w.module.info.toFullPath) encodeVInt(fileIdx(w, dep), w.inclDeps) add(w.inclDeps, " ") encodeVInt(crcFromFile(resolved), w.inclDeps) @@ -421,7 +423,8 @@ proc addStmt(w: PRodWriter, n: PNode) = proc writeRod(w: PRodWriter) = processStacks(w, true) var f: TFile - if not open(f, completeGeneratedFilePath(changeFileExt(w.filename, "rod")), + if not open(f, completeGeneratedFilePath(changeFileExt( + w.filename.withPackageName, RodExt)), fmWrite): #echo "couldn't write rod file for: ", w.filename return @@ -433,6 +436,11 @@ proc writeRod(w: PRodWriter) = encodeVInt(w.module.id, id) f.write(id) f.write(rodNL) + + var orig = "ORIGFILE:" + encodeStr(w.origFile, orig) + f.write(orig) + f.write(rodNL) var crc = "CRC:" encodeVInt(w.crc, crc) diff --git a/compiler/semcall.nim b/compiler/semcall.nim index c8f150922..9e9614796 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -34,13 +34,12 @@ proc sameMethodDispatcher(a, b: PSym): bool = proc determineType(c: PContext, s: PSym) -proc - pickBestCandidate(c: PContext, headSymbol: PNode, - n, orig: PNode, - initialBinding: PNode, - filter: TSymKinds, - best, alt: var TCandidate, - errors: var seq[string]) = +proc pickBestCandidate(c: PContext, headSymbol: PNode, + n, orig: PNode, + initialBinding: PNode, + filter: TSymKinds, + best, alt: var TCandidate, + errors: var seq[string]) = var o: TOverloadIter var sym = initOverloadIter(o, c, headSymbol) var symScope = o.lastOverloadScope diff --git a/compiler/semdata.nim b/compiler/semdata.nim index 4c066f5fa..121bf297d 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -85,6 +85,7 @@ type # naming it multiple times generics*: seq[TInstantiationPair] # pending list of instantiated generics to compile lastGenericIdx*: int # used for the generics stack + hloLoopDetector*: int # used to prevent endless loops in the HLO proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair = result.genericSym = s diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 2681150e0..47e07d402 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -36,7 +36,7 @@ proc semOperand(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = result = semExpr(c, n, flags) - if result.kind == nkEmpty: + if result.isNil or result.kind == nkEmpty: # do not produce another redundant error message: #raiseRecoverableError("") result = errorNode(c, n) @@ -686,7 +686,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = result = n.sons[0] result.kind = nkCall for i in countup(1, sonsLen(n) - 1): addSon(result, n.sons[i]) - return semDirectOp(c, result, flags) + return semExpr(c, result, flags) else: n.sons[0] = semExpr(c, n.sons[0]) let nOrig = n.copyTree @@ -786,9 +786,11 @@ proc semEcho(c: PContext, n: PNode): PNode = checkMinSonsLen(n, 1) for i in countup(1, sonsLen(n) - 1): var arg = semExprWithType(c, n.sons[i]) - n.sons[i] = semExprWithType(c, buildStringify(c, arg)) - let t = n.sons[i].typ - if t == nil or t.skipTypes(abstractInst).kind != tyString: + arg = semExprWithType(c, buildStringify(c, arg)) + n.sons[i] = arg + let t = arg.typ + if (t == nil or t.skipTypes(abstractInst).kind != tyString) and + arg.kind != nkEmpty: LocalError(n.info, errGenerated, "implicitly invoked '$' does not return string") let t = n.sons[0].typ @@ -807,7 +809,8 @@ proc buildEchoStmt(c: PContext, n: PNode): PNode = var arg = buildStringify(c, n) # problem is: implicit '$' is not checked for semantics yet. So we give up # and check 'arg' for semantics again: - addSon(result, semExpr(c, arg)) + arg = semExpr(c, arg) + if arg != nil: addSon(result, arg) proc semExprNoType(c: PContext, n: PNode): PNode = result = semExpr(c, n, {efWantStmt}) @@ -1018,8 +1021,8 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode = var arr = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar, tyPtr, tyRef}) case arr.kind of tyArray, tyOpenArray, tyVarargs, tyArrayConstr, tySequence, tyString, - tyCString: - checkSonsLen(n, 2) + tyCString: + if n.len != 2: return nil n.sons[0] = makeDeref(n.sons[0]) for i in countup(1, sonsLen(n) - 1): n.sons[i] = semExprWithType(c, n.sons[i], diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 0ce58ba5c..ed6787a16 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -574,9 +574,14 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode = fc.c = c semForObjectFields(fc, tupleTypeA.n, n, stmts) Dec(c.p.nestedLoopCounter) - var b = newNodeI(nkBreakStmt, n.info) - b.add(ast.emptyNode) - stmts.add(b) + # for TR macros this 'while true: ...; break' loop is pretty bad, so + # we avoid it now if we can: + if hasSonWith(stmts, nkBreakStmt): + var b = newNodeI(nkBreakStmt, n.info) + b.add(ast.emptyNode) + stmts.add(b) + else: + result = stmts proc addForVarDecl(c: PContext, v: PSym) = if warnShadowIdent in gNotes: diff --git a/compiler/semthreads.nim b/compiler/semthreads.nim index 6f24e1f6d..595ab0454 100644 --- a/compiler/semthreads.nim +++ b/compiler/semthreads.nim @@ -333,13 +333,11 @@ proc analyse(c: PProcCtx, n: PNode): TThreadOwner = result = toNil for i in countup(0, sonsLen(n) - 1): var it = n.sons[i] - case it.kind - of nkElifExpr: + if it.len == 2: discard analyse(c, it.sons[0]) aggregateOwner(result, analyse(c, it.sons[1])) - of nkElseExpr: + else: aggregateOwner(result, analyse(c, it.sons[0])) - else: internalError(n.info, "analyseIfExpr()") of nkStmtListExpr, nkBlockExpr: var n = if n.kind == nkBlockExpr: n.sons[1] else: n var L = sonsLen(n) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 64140274e..b9893d037 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -608,7 +608,9 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, if genericParams.sons[i].sym.name.id == finalTypId.id: return genericParams.sons[i].typ - var s = newSym(skType, finalTypId, typeClass.sym, info) + let owner = if typeClass.sym != nil: typeClass.sym + else: getCurrOwner() + var s = newSym(skType, finalTypId, owner, info) if typId == nil: s.flags.incl(sfAnon) s.linkTo(typeClass) s.position = genericParams.len @@ -922,6 +924,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = result.addSonSkipIntLit(t1) result.addSonSkipIntLit(t2) result.flags.incl(if op.id == ord(wAnd): tfAll else: tfAny) + result.flags.incl(tfHasMeta) elif op.id == ord(wNot): checkSonsLen(n, 3) result = semTypeNode(c, n.sons[1], prev) diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index b638449d2..61c31a4fe 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -211,6 +211,7 @@ proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType = result = ReplaceTypeVarsT(cl, lastSon(t)) of tyInt: result = skipIntLit(t) + # XXX now there are also float literals else: if t.kind == tyArray: let idxt = t.sons[0] diff --git a/compiler/transf.nim b/compiler/transf.nim index a81457b39..206c21c3d 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -588,6 +588,36 @@ proc dontInlineConstant(orig, cnst: PNode): bool {.inline.} = result = orig.kind == nkSym and cnst.kind in {nkCurly, nkPar, nkBracket} and cnst.len != 0 +proc commonOptimizations*(c: PSym, n: PNode): PNode = + result = n + for i in 0 .. < n.safeLen: + result.sons[i] = commonOptimizations(c, n.sons[i]) + var op = getMergeOp(n) + if (op != nil) and (op.magic != mNone) and (sonsLen(n) >= 3): + result = newNodeIT(nkCall, n.info, n.typ) + add(result, n.sons[0]) + var args = newNode(nkArgList) + flattenTreeAux(args, n, op) + var j = 0 + while j < sonsLen(args): + var a = args.sons[j] + inc(j) + if isConstExpr(a): + while j < sonsLen(args): + let b = args.sons[j] + if not isConstExpr(b): break + a = evalOp(op.magic, result, a, b, nil) + inc(j) + add(result, a) + if len(result) == 2: result = result[1] + else: + var cnst = getConstExpr(c, n) + # we inline constants if they are not complex constants: + if cnst != nil and not dontInlineConstant(n, cnst): + result = cnst + else: + result = n + proc transform(c: PTransf, n: PNode): PTransNode = case n.kind of nkSym: diff --git a/compiler/vm.nim b/compiler/vm.nim index e13d91e77..7705746de 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -231,11 +231,11 @@ proc compile(c: PCtx, s: PSym): int = result = vmgen.genProc(c, s) #c.echoCode -proc execute(c: PCtx, start: int) = +proc rawExecute(c: PCtx, start: int, tos: PStackFrame) = var pc = start + var tos = tos var regs: TNodeSeq # alias to tos.slots for performance - var tos: PStackFrame - newSeq(regs, c.prc.maxSlots) + move(regs, tos.slots) while true: {.computedGoto.} let instr = c.code[pc] @@ -841,6 +841,11 @@ proc execute(c: PCtx, start: int) = regs[ra].strVal = typ.typeToString(preferExported) inc pc +proc execute(c: PCtx, start: int) = + var tos = PStackFrame(prc: nil, comesFrom: 0, next: nil) + newSeq(tos.slots, c.prc.maxSlots) + rawExecute(c, start, tos) + proc evalStmt*(c: PCtx, n: PNode) = let start = genStmt(c, n) # execute new instructions; this redundant opcEof check saves us lots @@ -890,7 +895,7 @@ proc evalStaticExpr*(module: PSym, e: PNode, prc: PSym): PNode = proc setupMacroParam(x: PNode): PNode = result = x - if result.kind == nkHiddenStdConv: result = result.sons[1] + if result.kind in {nkHiddenSubConv, nkHiddenStdConv}: result = result.sons[1] proc evalMacroCall(c: PEvalContext, n, nOrig: PNode, sym: PSym): PNode = # XXX GlobalError() is ugly here, but I don't know a better solution for now @@ -899,21 +904,21 @@ proc evalMacroCall(c: PEvalContext, n, nOrig: PNode, sym: PSym): PNode = GlobalError(n.info, errTemplateInstantiationTooNested) c.callsite = nOrig - var s = newStackFrame() - s.call = n - s.prc = sym + let body = optBody(c, sym) + let start = genStmt(c, body) + + var tos = PStackFrame(prc: sym, comesFrom: 0, next: nil) + newSeq(tos.slots, c.prc.maxSlots) + # setup arguments: var L = n.safeLen if L == 0: L = 1 - setlen(s.slots, L) + InternalAssert tos.slots.len >= L # return value: - s.slots[0] = newNodeIT(nkNilLit, n.info, sym.typ.sons[0]) + tos.slots[0] = newNodeIT(nkNilLit, n.info, sym.typ.sons[0]) # setup parameters: - for i in 1 .. < L: s.slots[i] = setupMacroParam(n.sons[i]) - pushStackFrame(c, s) - discard eval(c, optBody(c, sym)) - result = s.slots[0] - popStackFrame(c) + for i in 1 .. < L: tos.slots[i] = setupMacroParam(n.sons[i]) + rawExecute(c, start, tos) + result = tos.slots[0] if cyclicTree(result): GlobalError(n.info, errCyclicTree) dec(evalTemplateCounter) c.callsite = nil - diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim index 515f2975b..d4b3d891d 100644 --- a/compiler/vmdef.nim +++ b/compiler/vmdef.nim @@ -162,6 +162,9 @@ type callsite*: PNode TPosition* = distinct int + + PEvalContext* = PCtx + proc newCtx*(module: PSym): PCtx = PCtx(code: @[], debug: @[], diff --git a/doc/advopt.txt b/doc/advopt.txt index baf67cc67..1452b9eef 100644 --- a/doc/advopt.txt +++ b/doc/advopt.txt @@ -85,4 +85,6 @@ Advanced options: --parallelBuild=0|1|... perform a parallel build value = number of processors (0 for auto-detect) --verbosity:0|1|2|3 set Nimrod's verbosity level (1 is default) + --cs:none|partial set case sensitivity level (default: none); + do not use! this setting affects the whole language -v, --version show detailed version information diff --git a/doc/apis.txt b/doc/apis.txt index 67534dec8..d76bd721e 100644 --- a/doc/apis.txt +++ b/doc/apis.txt @@ -74,6 +74,7 @@ coordinate coord rectangle rect point point symbol sym +literal lit string str identifier ident indentation indent diff --git a/doc/c2nim.txt b/doc/c2nim.txt index f894c2f92..7dec8b995 100644 --- a/doc/c2nim.txt +++ b/doc/c2nim.txt @@ -10,13 +10,7 @@ Introduction ============ -.. raw:: html - <blockquote><p> - "Ich bin der König aller Blinden. - Glaubt ihr wirklich ihr selbst könnt sehen? - Kniet euch alle nieder in den Dreck, - bis ich befehle aufzustehen." - </p></blockquote> + "We all make choices. But in the end our choices make us." c2nim is a tool to translate Ansi C code to Nimrod. The output is diff --git a/doc/grammar.txt b/doc/grammar.txt index 741e9b907..7fe2b56aa 100644 --- a/doc/grammar.txt +++ b/doc/grammar.txt @@ -104,11 +104,12 @@ exprStmt = simpleExpr | IND{=} 'except' exprList ':' stmt | IND{=} 'else' ':' stmt )* ))? -importStmt = 'import' optInd expr - ((comma expr)* +moduleName = expr ('as' expr)? +importStmt = 'import' optInd moduleName + ((comma moduleName)* / 'except' optInd (expr ^+ comma)) includeStmt = 'include' optInd expr ^+ comma -fromStmt = 'from' expr 'import' optInd expr (comma expr)* +fromStmt = 'from' moduleName 'import' optInd expr (comma expr)* returnStmt = 'return' optInd expr? raiseStmt = 'raise' optInd expr? yieldStmt = 'yield' optInd expr? diff --git a/doc/manual.txt b/doc/manual.txt index 914e6eaf5..4351d7232 100644 --- a/doc/manual.txt +++ b/doc/manual.txt @@ -2018,11 +2018,11 @@ Example: The `when`:idx: statement is almost identical to the ``if`` statement with some exceptions: -* Each ``expr`` has to be a constant expression (of type ``bool``). +* Each condition (``expr``) has to be a constant expression (of type ``bool``). * The statements do not open a new scope. * The statements that belong to the expression that evaluated to true are translated by the compiler, the other statements are not checked for - semantics! However, each ``expr`` is checked for semantics. + semantics! However, each condition is checked for semantics. The ``when`` statement enables conditional compilation techniques. As a special syntactic extension, the ``when`` construct is also available @@ -2268,7 +2268,7 @@ A `table constructor`:idx: is syntactic sugar for an array constructor: {"key1": "value1", "key2", "key3": "value2"} # is the same as: - [("key1", "value1"), ("key2", "value2"), ("key3", "value")] + [("key1", "value1"), ("key2", "value2"), ("key3", "value2")] The empty table can be written ``{:}`` (in contrast to the empty set @@ -2565,9 +2565,6 @@ Overloading of the subscript operator ------------------------------------- The ``[]`` subscript operator for arrays/openarrays/sequences can be overloaded. -Overloading support is only possible if the first parameter has no type that -already supports the built-in ``[]`` notation. Currently the compiler -does not check this restriction. Multi-methods @@ -3301,13 +3298,11 @@ Specifically, the type class will be matched if: a) all of the expressions within the body can be compiled for the tested type b) all statically evaluatable boolean expressions in the body must be true -Please note that the `is` operator allows you to easily verify the precise type +Please note that the ``is`` operator allows you to easily verify the precise type signatures of the required operations, but since type inference and default parameters are still applied in the provided block, it's also possible to encode usage protocols that doesn't reveal implementation details. -.. code-block:: nimrod - Much like generics, the user defined type classes will be instantiated exactly once for each tested type and any static code included within them will also be executed once. @@ -3327,7 +3322,7 @@ from the proc body. This is usually used with the ``auto`` type class: The return type will be treated as additional generic param and can be explicitly specified at call sites as any other generic param. -Future versions of nimrod may also support overloading based on the return type +Future versions of Nimrod may also support overloading based on the return type of the overloads. In such settings, the expected result type at call sites may also influence the inferred return type. @@ -3398,8 +3393,9 @@ templates: The "types" of templates can be the symbols ``expr`` (stands for *expression*), ``stmt`` (stands for *statement*) or ``typedesc`` (stands for *type -description*). These are no real types, they just help the compiler parsing. -Real types can be used too; this implies that expressions are expected. +description*). These are "meta types", they can only be used in certain +contexts. Real types can be used too; this implies that expressions are +expected. Ordinary vs immediate templates @@ -3868,7 +3864,7 @@ values inside containers and so on. For example, here is how one can create a type-safe wrapper for the unsafe `printf` function from C: .. code-block:: nimrod - macro safePrintF(formatString: string{lit}, args: vararg[expr]): expr = + macro safePrintF(formatString: string{lit}, args: varargs[expr]): expr = var i = 0 for c in formatChars(formatString): var expectedType = case c @@ -4196,10 +4192,10 @@ implemented with term rewriting: template optP2{p(x, y, false)}(x, y: expr): expr = x - y -Example: hoisting +Example: Hoisting ----------------- -The following example how some form of hoisting can be implemented: +The following example shows how some form of hoisting can be implemented: .. code-block:: nimrod import pegs @@ -4267,7 +4263,7 @@ optimization for types that have copying semantics: var t: TTable # overloading resolution ensures that the optimized []= is called here: - t["abc"] = "xyz" + t[f()] = g() @@ -4326,6 +4322,36 @@ module name followed by an ``except`` to prevent some symbols to be imported: echo "$1" % "abc" +Module names in imports +~~~~~~~~~~~~~~~~~~~~~~~ + +A module alias can be introduced via the ``as`` keyword: + +.. code-block:: nimrod + import strutils as su, sequtils as qu + + echo su.format("$1", "lalelu") + +The original module name is then not accessible. The +notations ``path/to/module`` or ``path.to.module`` or ``"path/to/module"`` +can be used to refer to a module in subdirectories: + +.. code-block:: nimrod + import lib.pure.strutils, lib/pure/os, "lib/pure/times" + +Note that the module name is still ``strutils`` and not ``lib.pure.strutils`` +and so one **cannot** do: + +.. code-block:: nimrod + import lib.pure.strutils + echo lib.pure.strutils + +Likewise the following does not make sense as the name is ``strutils`` already: + +.. code-block:: nimrod + import lib.pure.strutils as strutils + + From import statement ~~~~~~~~~~~~~~~~~~~~~ @@ -4471,7 +4497,7 @@ proc with no side effects: destructor pragma ----------------- -The `destructor` pragma is used to mark a proc to act as a type destructor. +The `destructor`:idx: pragma is used to mark a proc to act as a type destructor. The proc must have a single parameter with a concrete type (the name of a generic type is allowed too). @@ -4645,9 +4671,12 @@ NoStackFrame pragma ------------------- A proc can be marked with the `noStackFrame`:idx: pragma to tell the compiler it should not generate a stack frame for the proc. There are also no exit -statements like ``return result;`` generated. This is useful for procs that -only consist of an assembler statement. +statements like ``return result;`` generated and the generated C function is +declared as ``__declspec(naked)`` or ``__attribute__((naked))`` (depending on +the used C compiler). +**Note**: This pragma should only be used by procs which consist solely of assembler +statements. error pragma ------------ @@ -5085,9 +5114,9 @@ string expressions in general: proc getDllName: string = result = "mylib.dll" - if ExistsFile(result): return + if existsFile(result): return result = "mylib2.dll" - if ExistsFile(result): return + if existsFile(result): return quit("could not load dynamic library") proc myImport(s: cstring) {.cdecl, importc, dynlib: getDllName().} diff --git a/doc/nimrodc.txt b/doc/nimrodc.txt index dd320019f..d494a0922 100644 --- a/doc/nimrodc.txt +++ b/doc/nimrodc.txt @@ -111,6 +111,31 @@ The default build of a project is a `debug build`:idx:. To compile a `release build`:idx: define the ``release`` symbol:: nimrod c -d:release myproject.nim + + +Search path handling +-------------------- + +Nimrod has the concept of a global `search path`:idx: (PATH) that is queried to +determine where to find imported modules or include files. If multiple files are +found an ambiguity error is produced. + +``nimrod dump`` shows the contents of the PATH. + +However before the PATH is used the current directory is checked for the +file's existance. So if PATH contains ``$lib`` and ``$lib/bar`` and the +directory structure looks like this:: + + $lib/x.nim + $lib/bar/x.nim + foo/x.nim + foo/main.nim + other.nim + +And ``main`` imports ``x``, ``foo/x`` is imported. If ``other`` imports ``x`` +then both ``$lib/x.nim`` and ``$lib/bar/x.nim`` match and so the compiler +should reject it. Currently however this check is not implemented and instead +the first matching file is used. Generated C code directory @@ -485,6 +510,19 @@ The `volatile`:idx: pragma is for variables only. It declares the variable as in C/C++). **Note**: This pragma will not exist for the LLVM backend. + + +DynlibOverride +============== + +By default Nimrod's ``dynlib`` pragma causes the compiler to generate +``GetProcAddress`` (or their Unix counterparts) +calls to bind to a DLL. With the `dynlibOverride`:idx: command line switch this +can be prevented and then via ``--passL`` the static library can be linked +against. For instance, to link statically against Lua this command might work +on Linux:: + + nimrod c --dynlibOverride:lua --passL:liblua.lib program.nim Nimrod idetools integration diff --git a/examples/talk/dsl.nim b/examples/talk/dsl.nim new file mode 100644 index 000000000..4dfab5cd7 --- /dev/null +++ b/examples/talk/dsl.nim @@ -0,0 +1,33 @@ + +import strutils + +template html(name: expr, matter: stmt) {.immediate.} = + proc name(): string = + result = "<html>" + matter + result.add("</html>") + +template nestedTag(tag: expr) {.immediate.} = + template tag(matter: stmt) {.immediate.} = + result.add("<" & astToStr(tag) & ">") + matter + result.add("</" & astToStr(tag) & ">") + +template simpleTag(tag: expr) {.immediate.} = + template tag(matter: expr) {.immediate.} = + result.add("<$1>$2</$1>" % [astToStr(tag), matter]) + +nestedTag body +nestedTag head +nestedTag ul +simpleTag title +simpleTag li + +html mainPage: + head: + title "now look at this" + body: + ul: + li "Nimrod is quite capable" + +echo mainPage() diff --git a/examples/talk/formatoptimizer.nim b/examples/talk/formatoptimizer.nim new file mode 100644 index 000000000..db11d112d --- /dev/null +++ b/examples/talk/formatoptimizer.nim @@ -0,0 +1,55 @@ +## This is the example that optimizes a modified "hello world" + +import macros + +proc invalidFormatString() = + echo "invalidFormatString" + +template formatImpl(handleChar: expr) = + var i = 0 + while i < f.len: + if f[i] == '$': + case f[i+1] + of '1'..'9': + var j = 0 + i += 1 + while f[i] in {'0'..'9'}: + j = j * 10 + ord(f[i]) - ord('0') + i += 1 + result.add(a[j-1]) + else: + invalidFormatString() + else: + result.add(handleChar(f[i])) + i += 1 + +proc `%`*(f: string, a: openArray[string]): string = + template identity(x: expr): expr = x + result = "" + formatImpl(identity) + +macro optFormat{`%`(f, a)}(f: string{lit}, a: openArray[string]): expr = + result = newNimNode(nnkBracket) + #newCall("&") + let f = f.strVal + formatImpl(newLit) + result = nestList(!"&", result) + +template optAdd1{x = y; add(x, z)}(x, y, z: string) = + x = y & z + +#template optAdd2{x.add(y); x.add(z)}(x, y, z: string) = +# x.add(y & z) + +proc `/&` [T: object](x: T): string = + result = "(" + for name, value in fieldPairs(x): + result.add("$1: $2\n" % [name, $value]) + result.add(")") + +type + MyObject = object + a, b: int + s: string +let obj = MyObject(a: 3, b: 4, s: "abc") +echo(/&obj) diff --git a/examples/talk/hoisting.nim b/examples/talk/hoisting.nim new file mode 100644 index 000000000..df13ba2cb --- /dev/null +++ b/examples/talk/hoisting.nim @@ -0,0 +1,23 @@ +type + Regex = distinct string + +const maxSubpatterns = 10 + +proc re(x: string): Regex = + result = Regex(x) + +proc match(s: string, pattern: Regex, captures: var openArray[string]): bool = + true + +template optRe{re(x)}(x: string{lit}): Regex = + var g {.global.} = re(x) + g + +template `=~`(s: string, pattern: Regex): bool = + when not definedInScope(matches): + var matches {.inject.}: array[maxSubPatterns, string] + match(s, pattern, matches) + +for line in lines("input.txt"): + if line =~ re"(\w+)=(\w+)": + echo "key-value pair; key: ", matches[0], " value: ", matches[1] diff --git a/examples/talk/lazyeval.nim b/examples/talk/lazyeval.nim new file mode 100644 index 000000000..77d963834 --- /dev/null +++ b/examples/talk/lazyeval.nim @@ -0,0 +1,12 @@ + +const + debug = true + +template log(msg: string) = + if debug: + echo msg +var + x = 1 + y = 2 + +log("x: " & $x & ", y: " & $y) diff --git a/examples/talk/quasiquote.nim b/examples/talk/quasiquote.nim new file mode 100644 index 000000000..df4003e6e --- /dev/null +++ b/examples/talk/quasiquote.nim @@ -0,0 +1,11 @@ + +import macros + +macro check(ex: expr): stmt = + var info = ex.lineinfo + var expString = ex.toStrLit + result = quote do: + if not `ex`: + echo `info`, ": Check failed: ", `expString` + +check 1 < 2 diff --git a/examples/talk/tags.nim b/examples/talk/tags.nim new file mode 100644 index 000000000..d47b09e07 --- /dev/null +++ b/examples/talk/tags.nim @@ -0,0 +1,8 @@ + +template htmlTag(tag: expr) {.immediate.} = + proc tag(): string = "<" & astToStr(tag) & ">" + +htmlTag(br) +htmlTag(html) + +echo br() diff --git a/lib/core/macros.nim b/lib/core/macros.nim index 9ac6b0082..fc93a157d 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -38,7 +38,7 @@ type nnkObjUpConv, nnkChckRangeF, nnkChckRange64, nnkChckRange, nnkStringToCString, nnkCStringToString, nnkAsgn, nnkFastAsgn, nnkGenericParams, nnkFormalParams, nnkOfInherit, - nnkModule, nnkProcDef, nnkMethodDef, nnkConverterDef, + nnkImportAs, nnkProcDef, nnkMethodDef, nnkConverterDef, nnkMacroDef, nnkTemplateDef, nnkIteratorDef, nnkOfBranch, nnkElifBranch, nnkExceptBranch, nnkElse, nnkAsmStmt, nnkPragma, nnkPragmaBlock, nnkIfStmt, nnkWhenStmt, @@ -336,6 +336,26 @@ proc newCall*(theProc: string, result.add(newIdentNode(theProc)) result.add(args) +proc newLit*(c: char): PNimrodNode {.compileTime.} = + ## produces a new character literal node. + result = newNimNode(nnkCharLit) + result.intVal = ord(c) + +proc newLit*(i: biggestInt): PNimrodNode {.compileTime.} = + ## produces a new integer literal node. + result = newNimNode(nnkIntLit) + result.intVal = i + +proc newLit*(f: biggestFloat): PNimrodNode {.compileTime.} = + ## produces a new float literal node. + result = newNimNode(nnkFloatLit) + result.floatVal = f + +proc newLit*(s: string): PNimrodNode {.compileTime.} = + ## produces a new string literal node. + result = newNimNode(nnkStrLit) + result.strVal = s + proc nestList*(theProc: TNimrodIdent, x: PNimrodNode): PNimrodNode {.compileTime.} = ## nests the list `x` into a tree of call expressions: @@ -677,7 +697,7 @@ proc addIdentIfAbsent*(dest: PNimrodNode, ident: string) {.compiletime.} = of nnkIdent: if ident.eqIdent($node): return of nnkExprColonExpr: - if ident.eqIdent($ node[0]): return + if ident.eqIdent($node[0]): return else: nil dest.add(ident(ident)) diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim index cf260e9b7..107129b7a 100644 --- a/lib/posix/posix.nim +++ b/lib/posix/posix.nim @@ -81,6 +81,9 @@ else: ## A type representing a directory stream. type + TSocketHandle* = cint # The type used to represent socket descripters + # Should this be distinct? Is this the right place? + Tdirent* {.importc: "struct dirent", header: "<dirent.h>", final, pure.} = object ## dirent_t struct d_ino*: TIno ## File serial number. diff --git a/lib/pure/asyncio.nim b/lib/pure/asyncio.nim index 4ff6e0ced..48a22bbe8 100644 --- a/lib/pure/asyncio.nim +++ b/lib/pure/asyncio.nim @@ -89,13 +89,13 @@ import sockets, os ## getSocket(s).accept(client) when defined(windows): - from winlean import TTimeVal, TFdSet, FD_ZERO, FD_SET, FD_ISSET, select + from winlean import TTimeVal, TSocketHandle, TFdSet, FD_ZERO, FD_SET, FD_ISSET, select else: - from posix import TTimeVal, TFdSet, FD_ZERO, FD_SET, FD_ISSET, select + from posix import TTimeVal, TSocketHandle, TFdSet, FD_ZERO, FD_SET, FD_ISSET, select type TDelegate* = object - fd*: cint + fd*: TSocketHandle deleVal*: PObject handleRead*: proc (h: PObject) {.nimcall.} diff --git a/lib/pure/basic2d.nim b/lib/pure/basic2d.nim new file mode 100644 index 000000000..f8391a368 --- /dev/null +++ b/lib/pure/basic2d.nim @@ -0,0 +1,855 @@ +# +# +# Nimrod's Runtime Library +# (c) Copyright 2013 Robert Persson +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +import math +import strutils + + +## Basic 2d support with vectors, points, matrices and some basic utilities. +## Vectors are implemented as direction vectors, ie. when transformed with a matrix +## the translation part of matrix is ignored. +## Operators `+` , `-` , `*` , `/` , `+=` , `-=` , `*=` and `/=` are implemented for vectors and scalars. +## +## Quick start example: +## +## # Create a matrix wich first rotates, then scales and at last translates +## +## var m:TMatrix2d=rotate(DEG90) & scale(2.0) & move(100.0,200.0) +## +## # Create a 2d point at (100,0) and a vector (5,2) +## +## var pt:TPoint2d=point2d(100.0,0.0) +## +## var vec:TVector2d=vector2d(5.0,2.0) +## +## +## pt &= m # transforms pt in place +## +## var pt2:TPoint2d=pt & m #concatenates pt with m and returns a new point +## +## var vec2:TVector2d=vec & m #concatenates vec with m and returns a new vector + + +const + DEG360* = PI * 2.0 + ## 360 degrees in radians. + DEG270* = PI * 1.5 + ## 270 degrees in radians. + DEG180* = PI + ## 180 degrees in radians. + DEG90* = PI / 2.0 + ## 90 degrees in radians. + DEG60* = PI / 3.0 + ## 60 degrees in radians. + DEG45* = PI / 4.0 + ## 45 degrees in radians. + DEG30* = PI / 6.0 + ## 30 degrees in radians. + DEG15* = PI / 12.0 + ## 15 degrees in radians. + RAD2DEGCONST = 180.0 / PI + ## used internally by DegToRad and RadToDeg + +type + TMatrix2d* = object + ## Implements a row major 2d matrix, which means + ## transformations are applied the order they are concatenated. + ## The rightmost column of the 3x3 matrix is left out since normally + ## not used for geometric transformations in 2d. + ax*,ay*,bx*,by*,tx*,ty*:float + TPoint2d* = object + ## Implements a non-homegeneous 2d point stored as + ## an `x` coordinate and an `y` coordinate. + x*,y*:float + TVector2d* = object + ## Implements a 2d **direction vector** stored as + ## an `x` coordinate and an `y` coordinate. Direction vector means, + ## that when transforming a vector with a matrix, the translational + ## part of the matrix is ignored. + x*,y*:float + + + +# Some forward declarations... +proc matrix2d*(ax,ay,bx,by,tx,ty:float):TMatrix2d {.noInit.} + ## Creates a new matrix. + ## `ax`,`ay` is the local x axis + ## `bx`,`by` is the local y axis + ## `tx`,`ty` is the translation +proc vector2d*(x,y:float):TVector2d {.noInit,inline.} + ## Returns a new vector (`x`,`y`) +proc point2d*(x,y:float):TPoint2d {.noInit,inline.} + ## Returns a new point (`x`,`y`) + + + +let + IDMATRIX*:TMatrix2d=matrix2d(1.0,0.0,0.0,1.0,0.0,0.0) + ## Quick access to an identity matrix + ORIGO*:TPoint2d=Point2d(0.0,0.0) + ## Quick acces to point (0,0) + XAXIS*:TVector2d=vector2d(1.0,0.0) + ## Quick acces to an 2d x-axis unit vector + YAXIS*:TVector2d=vector2d(0.0,1.0) + ## Quick acces to an 2d y-axis unit vector + + +# *************************************** +# Private utils +# *************************************** + +proc rtos(val:float):string= + return formatFloat(val,ffDefault,0) + +proc safeArccos(v:float):float= + ## assumes v is in range 0.0-1.0, but clamps + ## the value to avoid out of domain errors + ## due to rounding issues + return arccos(clamp(v,-1.0,1.0)) + + +template makeBinOpVector(s:expr)= + ## implements binary operators + , - , * and / for vectors + proc s*(a,b:TVector2d):TVector2d {.inline,noInit.} = vector2d(s(a.x,b.x),s(a.y,b.y)) + proc s*(a:TVector2d,b:float):TVector2d {.inline,noInit.} = vector2d(s(a.x,b),s(a.y,b)) + proc s*(a:float,b:TVector2d):TVector2d {.inline,noInit.} = vector2d(s(a,b.x),s(a,b.y)) + +template makeBinOpAssignVector(s:expr)= + ## implements inplace binary operators += , -= , /= and *= for vectors + proc s*(a:var TVector2d,b:TVector2d) {.inline.} = s(a.x,b.x) ; s(a.y,b.y) + proc s*(a:var TVector2d,b:float) {.inline.} = s(a.x,b) ; s(a.y,b) + + +# *************************************** +# TMatrix2d implementation +# *************************************** + +proc setElements*(t:var TMatrix2d,ax,ay,bx,by,tx,ty:float) {.inline.}= + ## Sets arbitrary elements in an existing matrix. + t.ax=ax + t.ay=ay + t.bx=bx + t.by=by + t.tx=tx + t.ty=ty + +proc matrix2d*(ax,ay,bx,by,tx,ty:float):TMatrix2d = + result.setElements(ax,ay,bx,by,tx,ty) + +proc `&`*(a,b:TMatrix2d):TMatrix2d {.noInit.} = #concatenate matrices + ## Concatenates matrices returning a new matrix. + + # | a.AX a.AY 0 | | b.AX b.AY 0 | + # | a.BX a.BY 0 | * | b.BX b.BY 0 | + # | a.TX a.TY 1 | | b.TX b.TY 1 | + result.setElements( + a.ax * b.ax + a.ay * b.bx, + a.ax * b.ay + a.ay * b.by, + a.bx * b.ax + a.by * b.bx, + a.bx * b.ay + a.by * b.by, + a.tx * b.ax + a.ty * b.bx + b.tx, + a.tx * b.ay + a.ty * b.by + b.ty) + + +proc scale*(s:float):TMatrix2d {.noInit.} = + ## Returns a new scale matrix. + result.setElements(s,0,0,s,0,0) + +proc scale*(s:float,org:TPoint2d):TMatrix2d {.noInit.} = + ## Returns a new scale matrix using, `org` as scale origin. + result.setElements(s,0,0,s,org.x-s*org.x,org.y-s*org.y) + +proc stretch*(sx,sy:float):TMatrix2d {.noInit.} = + ## Returns new a stretch matrix, which is a + ## scale matrix with non uniform scale in x and y. + result.setElements(sx,0,0,sy,0,0) + +proc stretch*(sx,sy:float,org:TPoint2d):TMatrix2d {.noInit.} = + ## Returns a new stretch matrix, which is a + ## scale matrix with non uniform scale in x and y. + ## `org` is used as stretch origin. + result.setElements(sx,0,0,sy,org.x-sx*org.x,org.y-sy*org.y) + +proc move*(dx,dy:float):TMatrix2d {.noInit.} = + ## Returns a new translation matrix. + result.setElements(1,0,0,1,dx,dy) + +proc move*(v:TVector2d):TMatrix2d {.noInit.} = + ## Returns a new translation matrix from a vector. + result.setElements(1,0,0,1,v.x,v.y) + +proc rotate*(rad:float):TMatrix2d {.noInit.} = + ## Returns a new rotation matrix, which + ## represents a rotation by `rad` radians + let + s=sin(rad) + c=cos(rad) + result.setElements(c,s,-s,c,0,0) + +proc rotate*(rad:float,org:TPoint2d):TMatrix2d {.noInit.} = + ## Returns a new rotation matrix, which + ## represents a rotation by `rad` radians around + ## the origin `org` + let + s=sin(rad) + c=cos(rad) + result.setElements(c,s,-s,c,org.x+s*org.y-c*org.x,org.y-c*org.y-s*org.x) + +proc mirror*(v:TVector2d):TMatrix2d {.noInit.} = + ## Returns a new mirror matrix, mirroring + ## around the line that passes through origo and + ## has the direction of `v` + let + sqx=v.x*v.x + sqy=v.y*v.y + nd=1.0/(sqx+sqy) #used to normalize invector + xy2=v.x*v.y*2.0*nd + sqd=nd*(sqx-sqy) + + if nd==inf or nd==neginf: + return IDMATRIX #mirroring around a zero vector is arbitrary=>just use identity + + result.setElements( + sqd,xy2, + xy2,-sqd, + 0.0,0.0) + +proc mirror*(org:TPoint2d,v:TVector2d):TMatrix2d {.noInit.} = + ## Returns a new mirror matrix, mirroring + ## around the line that passes through `org` and + ## has the direction of `v` + let + sqx=v.x*v.x + sqy=v.y*v.y + nd=1.0/(sqx+sqy) #used to normalize invector + xy2=v.x*v.y*2.0*nd + sqd=nd*(sqx-sqy) + + if nd==inf or nd==neginf: + return IDMATRIX #mirroring around a zero vector is arbitrary=>just use identity + + result.setElements( + sqd,xy2, + xy2,-sqd, + org.x-org.y*xy2-org.x*sqd,org.y-org.x*xy2+org.y*sqd) + + + +proc skew*(xskew,yskew:float):TMatrix2d {.noInit.} = + ## Returns a new skew matrix, which has its + ## x axis rotated `xskew` radians from the local x axis, and + ## y axis rotated `yskew` radians from the local y axis + result.setElements(cos(yskew),sin(yskew),-sin(xskew),cos(xskew),0,0) + + +proc `$`* (t:TMatrix2d):string {.noInit.} = + ## Returns a string representation of the matrix + return rtos(t.ax) & "," & rtos(t.ay) & + "," & rtos(t.bx) & "," & rtos(t.by) & + "," & rtos(t.tx) & "," & rtos(t.ty) + +proc isUniform*(t:TMatrix2d,tol=1.0e-6):bool= + ## Checks if the transform is uniform, that is + ## perpendicular axes of equal lenght, which means (for example) + ## it cannot transform a circle into an ellipse. + ## `tol` is used as tolerance for both equal length comparison + ## and perp. comparison. + + #dot product=0 means perpendicular coord. system: + if abs(t.ax*t.bx+t.ay*t.by)<=tol: + #subtract squared lengths of axes to check if uniform scaling: + if abs((t.ax*t.ax+t.ay*t.ay)-(t.bx*t.bx+t.by*t.by))<=tol: + return true + return false + +proc determinant*(t:TMatrix2d):float= + ## Computes the determinant of the matrix. + + #NOTE: equivalent with perp.dot product for two 2d vectors + return t.ax*t.by-t.bx*t.ay + +proc isMirroring* (m:TMatrix2d):bool= + ## Checks if the `m` is a mirroring matrix, + ## which means it will reverse direction of a curve transformed with it + return m.determinant<0.0 + +proc inverse*(m:TMatrix2d):TMatrix2d {.noInit.} = + ## Returns a new matrix, which is the inverse of the matrix + ## If the matrix is not invertible (determinant=0), an EDivByZero + ## will be raised. + let d=m.determinant + if d==0.0: + raise newException(EDivByZero,"Cannot invert a zero determinant matrix") + + result.setElements( + m.by/d,-m.ay/d, + -m.bx/d,m.ax/d, + (m.bx*m.ty-m.by*m.tx)/d, + (m.ay*m.tx-m.ax*m.ty)/d) + +proc equals*(m1:TMatrix2d,m2:TMatrix2d,tol=1.0e-6):bool= + ## Checks if all elements of `m1`and `m2` is equal within + ## a given tolerance `tol`. + return + abs(m1.ax-m2.ax)<=tol and + abs(m1.ay-m2.ay)<=tol and + abs(m1.bx-m2.bx)<=tol and + abs(m1.by-m2.by)<=tol and + abs(m1.tx-m2.tx)<=tol and + abs(m1.ty-m2.ty)<=tol + +proc `=~`*(m1,m2:TMatrix2d):bool= + ## Checks if `m1`and `m2` is aproximately equal, using a + ## tolerance of 1e-6. + equals(m1,m2) + +proc isIdentity*(m:TMatrix2d,tol=1.0e-6):bool= + ## Checks is a matrix is approximately an identity matrix, + ## using `tol` as tolerance for each element. + return equals(m,IDMATRIX,tol) + +proc apply*(m:TMatrix2d,x,y:var float,translate=false)= + ## Applies transformation `m` onto `x`,`y`, optionally + ## using the translation part of the matrix. + if translate: # positional style transform + let newx=x*m.ax+y*m.bx+m.tx + y=x*m.ay+y*m.by+m.ty + x=newx + else: # delta style transform + let newx=x*m.ax+y*m.bx + y=x*m.ay+y*m.by + x=newx + + + +# *************************************** +# TVector2d implementation +# *************************************** +proc vector2d*(x,y:float):TVector2d = #forward decl. + result.x=x + result.y=y + +proc polarVector2d*(ang:float,len:float):TVector2d {.noInit.} = + ## Returns a new vector with angle `ang` and magnitude `len` + result.x=cos(ang)*len + result.y=sin(ang)*len + +proc slopeVector2d*(slope:float,len:float):TVector2d {.noInit.} = + ## Returns a new vector having slope (dy/dx) given by + ## `slope`, and a magnitude of `len` + let ang=arctan(slope) + result.x=cos(ang)*len + result.y=sin(ang)*len + +proc len*(v:TVector2d):float {.inline.}= + ## Returns the length of the vector. + sqrt(v.x*v.x+v.y*v.y) + +proc `len=`*(v:var TVector2d,newlen:float) {.noInit.} = + ## Sets the length of the vector, keeping its angle. + let fac=newlen/v.len + + if newlen==0.0: + v.x=0.0 + v.y=0.0 + return + + if fac==inf or fac==neginf: + #to short for float accuracy + #do as good as possible: + v.x=newlen + v.y=0.0 + else: + v.x*=fac + v.y*=fac + +proc sqrLen*(v:TVector2d):float {.inline.}= + ## Computes the squared length of the vector, which is + ## faster than computing the absolute length. + v.x*v.x+v.y*v.y + +proc angle*(v:TVector2d):float= + ## Returns the angle of the vector. + ## (The counter clockwise plane angle between posetive x axis and `v`) + result=arctan2(v.y,v.x) + if result<0.0: result+=DEG360 + +proc `$` *(v:TVector2d):string= + ## String representation of `v` + result=rtos(v.x) + result.add(",") + result.add(rtos(v.y)) + + +proc `&` *(v:TVector2d,m:TMatrix2d):TVector2d {.noInit.} = + ## Concatenate vector `v` with a transformation matrix. + ## Transforming a vector ignores the translational part + ## of the matrix. + + # | AX AY 0 | + # | X Y 1 | * | BX BY 0 | + # | 0 0 1 | + result.x=v.x*m.ax+v.y*m.bx + result.y=v.x*m.ay+v.y*m.by + + +proc `&=`*(v:var TVector2d,m:TMatrix2d) {.inline.}= + ## Applies transformation `m` onto `v` in place. + ## Transforming a vector ignores the translational part + ## of the matrix. + + # | AX AY 0 | + # | X Y 1 | * | BX BY 0 | + # | 0 0 1 | + let newx=v.x*m.ax+v.y*m.bx + v.y=v.x*m.ay+v.y*m.by + v.x=newx + + +proc tryNormalize*(v:var TVector2d):bool= + ## Modifies `v` to have a length of 1.0, keeping its angle. + ## If `v` has zero length (and thus no angle), it is left unmodified and + ## false is returned, otherwise true is returned. + + let mag=v.len + + if mag==0.0: + return false + + v.x/=mag + v.y/=mag + return true + + +proc normalize*(v:var TVector2d) {.inline.}= + ## Modifies `v` to have a length of 1.0, keeping its angle. + ## If `v` has zero length, an EDivByZero will be raised. + if not tryNormalize(v): + raise newException(EDivByZero,"Cannot normalize zero length vector") + +proc transformNorm*(v:var TVector2d,t:TMatrix2d)= + ## Applies a normal direction transformation `t` onto `v` in place. + ## The resulting vector is *not* normalized. Transforming a vector ignores the + ## translational part of the matrix. If the matrix is not invertible + ## (determinant=0), an EDivByZero will be raised. + + # transforming a normal is done by transforming + # by the transpose of the inverse of the original matrix + # this can be heavily optimized by precompute and inline + # | | AX AY 0 | ^-1| ^T + # | X Y 1 | * | | BX BY 0 | | + # | | 0 0 1 | | + let d=t.determinant + if(d==0.0): + raise newException(EDivByZero,"Matrix is not invertible") + let newx = (t.by*v.x-t.ay*v.y)/d + v.y = (t.ax*v.y-t.bx*v.x)/d + v.x = newx + +proc transformInv*(v:var TVector2d,t:TMatrix2d)= + ## Applies inverse of a transformation `t` to `v` in place. + ## This is faster than creating an inverse matrix and apply() it. + ## Transforming a vector ignores the translational part + ## of the matrix. If the matrix is not invertible (determinant=0), an EDivByZero + ## will be raised. + let d=t.determinant + + if(d==0.0): + raise newException(EDivByZero,"Matrix is not invertible") + + let newx=(t.by*v.x-t.bx*v.y)/d + v.y = (t.ax*v.y-t.ay*v.x)/d + v.x = newx + +proc transformNormInv*(v:var TVector2d,t:TMatrix2d)= + ## Applies an inverse normal direction transformation `t` onto `v` in place. + ## This is faster than creating an inverse + ## matrix and transformNorm(...) it. Transforming a vector ignores the + ## translational part of the matrix. + + # normal inverse transform is done by transforming + # by the inverse of the transpose of the inverse of the org. matrix + # which is equivalent with transforming with the transpose. + # | | | AX AY 0 |^-1|^T|^-1 | AX BX 0 | + # | X Y 1 | * | | | BX BY 0 | | | = | X Y 1 | * | AY BY 0 | + # | | | 0 0 1 | | | | 0 0 1 | + # This can be heavily reduced to: + let newx=t.ay*v.y+t.ax*v.x + v.y=t.by*v.y+t.bx*v.x + v.x=newx + +proc rotate90*(v:var TVector2d) {.inline.}= + ## Quickly rotates vector `v` 90 degrees counter clockwise, + ## without using any trigonometrics. + swap(v.x,v.y) + v.x= -v.x + +proc rotate180*(v:var TVector2d){.inline.}= + ## Quickly rotates vector `v` 180 degrees counter clockwise, + ## without using any trigonometrics. + v.x= -v.x + v.y= -v.y + +proc rotate270*(v:var TVector2d) {.inline.}= + ## Quickly rotates vector `v` 270 degrees counter clockwise, + ## without using any trigonometrics. + swap(v.x,v.y) + v.y= -v.y + +proc rotate*(v:var TVector2d,rad:float) = + ## Rotates vector `v` `rad` radians in place. + let + s=sin(rad) + c=cos(rad) + newx=c*v.x-s*v.y + v.y=c*v.y+s*v.x + v.x=newx + +proc scale*(v:var TVector2d,fac:float){.inline.}= + ## Scales vector `v` `rad` radians in place. + v.x*=fac + v.y*=fac + +proc stretch*(v:var TVector2d,facx,facy:float){.inline.}= + ## Stretches vector `v` `facx` times horizontally, + ## and `facy` times vertically. + v.x*=facx + v.y*=facy + +proc mirror*(v:var TVector2d,mirrvec:TVector2d)= + ## Mirrors vector `v` using `mirrvec` as mirror direction. + let + sqx=mirrvec.x*mirrvec.x + sqy=mirrvec.y*mirrvec.y + nd=1.0/(sqx+sqy) #used to normalize invector + xy2=mirrvec.x*mirrvec.y*2.0*nd + sqd=nd*(sqx-sqy) + + if nd==inf or nd==neginf: + return #mirroring around a zero vector is arbitrary=>keep as is is fastest + + let newx=xy2*v.y+sqd*v.x + v.y=v.x*xy2-sqd*v.y + v.x=newx + + +proc `-` *(v:TVector2d):TVector2d= + ## Negates a vector + result.x= -v.x + result.y= -v.y + +# declare templated binary operators +makeBinOpVector(`+`) +makeBinOpVector(`-`) +makeBinOpVector(`*`) +makeBinOpVector(`/`) +makeBinOpAssignVector(`+=`) +makeBinOpAssignVector(`-=`) +makeBinOpAssignVector(`*=`) +makeBinOpAssignVector(`/=`) + + +proc dot*(v1,v2:TVector2d):float= + ## Computes the dot product of two vectors. + ## Returns 0.0 if the vectors are perpendicular. + return v1.x*v2.x+v1.y*v2.y + +proc cross*(v1,v2:TVector2d):float= + ## Computes the cross product of two vectors, also called + ## the 'perpendicular dot product' in 2d. Returns 0.0 if the vectors + ## are parallel. + return v1.x*v2.y-v1.y*v2.x + +proc equals*(v1,v2:TVector2d,tol=1.0e-6):bool= + ## Checks if two vectors approximately equals with a tolerance. + return abs(v2.x-v1.x)<=tol and abs(v2.y-v1.y)<=tol + +proc `=~` *(v1,v2:TVector2d):bool= + ## Checks if two vectors approximately equals with a + ## hardcoded tolerance 1e-6 + equals(v1,v2) + +proc angleTo*(v1,v2:TVector2d):float= + ## Returns the smallest of the two possible angles + ## between `v1` and `v2` in radians. + var + nv1=v1 + nv2=v2 + if not nv1.tryNormalize or not nv2.tryNormalize: + return 0.0 # zero length vector has zero angle to any other vector + return safeArccos(dot(nv1,nv2)) + +proc angleCCW*(v1,v2:TVector2d):float= + ## Returns the counter clockwise plane angle from `v1` to `v2`, + ## in range 0 - 2*PI + let a=v1.angleTo(v2) + if v1.cross(v2)>=0.0: + return a + return DEG360-a + +proc angleCW*(v1,v2:TVector2d):float= + ## Returns the clockwise plane angle from `v1` to `v2`, + ## in range 0 - 2*PI + let a=v1.angleTo(v2) + if v1.cross(v2)<=0.0: + return a + return DEG360-a + +proc turnAngle*(v1,v2:TVector2d):float= + ## Returns the amount v1 should be rotated (in radians) to equal v2, + ## in range -PI to PI + let a=v1.angleTo(v2) + if v1.cross(v2)<=0.0: + return -a + return a + +proc bisect*(v1,v2:TVector2d):TVector2d {.noInit.}= + ## Computes the bisector between v1 and v2 as a normalized vector. + ## If one of the input vectors has zero length, a normalized version + ## of the other is returned. If both input vectors has zero length, + ## an arbitrary normalized vector is returned. + var + vmag1=v1.len + vmag2=v2.len + + # zero length vector equals arbitrary vector, just change to magnitude to one to + # avoid zero division + if vmag1==0.0: + if vmag2==0: #both are zero length return any normalized vector + return XAXIS + vmag1=1.0 + if vmag2==0.0: vmag2=1.0 + + let + x1=v1.x/vmag1 + y1=v1.y/vmag1 + x2=v2.x/vmag2 + y2=v2.y/vmag2 + + result.x=(x1 + x2) * 0.5 + result.y=(y1 + y2) * 0.5 + + if not result.tryNormalize(): + # This can happen if vectors are colinear. In this special case + # there are actually two bisectors, we select just + # one of them (x1,y1 rotated 90 degrees ccw). + result.x = -y1 + result.y = x1 + + + +# *************************************** +# TPoint2d implementation +# *************************************** + +proc point2d*(x,y:float):TPoint2d = + result.x=x + result.y=y + +proc sqrDist*(a,b:TPoint2d):float= + ## Computes the squared distance between `a` and `b` + let dx=b.x-a.x + let dy=b.y-a.y + result=dx*dx+dy*dy + +proc dist*(a,b:TPoint2d):float {.inline.}= + ## Computes the absolute distance between `a` and `b` + result=sqrt(sqrDist(a,b)) + +proc angle*(a,b:TPoint2d):float= + ## Computes the angle of the vector `b`-`a` + let dx=b.x-a.x + let dy=b.y-a.y + result=arctan2(dy,dx) + if result<0: + result += DEG360 + +proc `$` *(p:TPoint2d):string= + ## String representation of `p` + result=rtos(p.x) + result.add(",") + result.add(rtos(p.y)) + +proc `&`*(p:TPoint2d,t:TMatrix2d):TPoint2d {.noInit,inline.} = + ## Concatenates a point `p` with a transform `t`, + ## resulting in a new, transformed point. + + # | AX AY 0 | + # | X Y 1 | * | BX BY 0 | + # | TX TY 1 | + result.x=p.x*t.ax+p.y*t.bx+t.tx + result.y=p.x*t.ay+p.y*t.by+t.ty + +proc `&=` *(p:var TPoint2d,t:TMatrix2d) {.inline.}= + ## Applies transformation `t` onto `p` in place. + let newx=p.x*t.ax+p.y*t.bx+t.tx + p.y=p.x*t.ay+p.y*t.by+t.ty + p.x=newx + + +proc transformInv*(p:var TPoint2d,t:TMatrix2d){.inline.}= + ## Applies the inverse of transformation `t` onto `p` in place. + ## If the matrix is not invertable (determinant=0) , EDivByZero will + ## be raised. + + # | AX AY 0 | ^-1 + # | X Y 1 | * | BX BY 0 | + # | TX TY 1 | + let d=t.determinant + if d==0.0: + raise newException(EDivByZero,"Cannot invert a zero determinant matrix") + let + newx= (t.bx*t.ty-t.by*t.tx+p.x*t.by-p.y*t.bx)/d + p.y = -(t.ax*t.ty-t.ay*t.tx+p.x*t.ay-p.y*t.ax)/d + p.x=newx + + +proc `+`*(p:TPoint2d,v:TVector2d):TPoint2d {.noInit,inline.} = + ## Adds a vector `v` to a point `p`, resulting + ## in a new point. + result.x=p.x+v.x + result.y=p.y+v.y + +proc `+=`*(p:var TPoint2d,v:TVector2d) {.noInit,inline.} = + ## Adds a vector `v` to a point `p` in place. + p.x+=v.x + p.y+=v.y + +proc `-`*(p:TPoint2d,v:TVector2d):TPoint2d {.noInit,inline.} = + ## Subtracts a vector `v` from a point `p`, resulting + ## in a new point. + result.x=p.x-v.x + result.y=p.y-v.y + +proc `-`*(p1,p2:TPoint2d):TVector2d {.noInit,inline.} = + ## Subtracts `p2`from `p1` resulting in a difference vector. + result.x=p1.x-p2.x + result.y=p1.y-p2.y + +proc `-=`*(p:var TPoint2d,v:TVector2d) {.noInit,inline.} = + ## Subtracts a vector `v` from a point `p` in place. + p.x-=v.x + p.y-=v.y + +proc equals(p1,p2:TPoint2d,tol=1.0e-6):bool {.inline.}= + ## Checks if two points approximately equals with a tolerance. + return abs(p2.x-p1.x)<=tol and abs(p2.y-p1.y)<=tol + +proc `=~`*(p1,p2:TPoint2d):bool {.inline.}= + ## Checks if two vectors approximately equals with a + ## hardcoded tolerance 1e-6 + equals(p1,p2) + +proc polar*(p:TPoint2d,ang,dist:float):TPoint2d {.noInit.} = + ## Returns a point with a given angle and distance away from `p` + result.x=p.x+cos(ang)*dist + result.y=p.y+sin(ang)*dist + +proc rotate*(p:var TPoint2d,rad:float)= + ## Rotates a point in place `rad` radians around origo. + let + c=cos(rad) + s=sin(rad) + newx=p.x*c-p.y*s + p.y=p.y*c+p.x*s + p.x=newx + +proc rotate*(p:var TPoint2d,rad:float,org:TPoint2d)= + ## Rotates a point in place `rad` radians using `org` as + ## center of rotation. + let + c=cos(rad) + s=sin(rad) + newx=(p.x - org.x) * c - (p.y - org.y) * s + org.x + p.y=(p.y - org.y) * c + (p.x - org.x) * s + org.y + p.x=newx + +proc scale*(p:var TPoint2d,fac:float) {.inline.}= + ## Scales a point in place `fac` times with world origo as origin. + p.x*=fac + p.y*=fac + +proc scale*(p:var TPoint2d,fac:float,org:TPoint2d){.inline.}= + ## Scales the point in place `fac` times with `org` as origin. + p.x=(p.x - org.x) * fac + org.x + p.y=(p.y - org.y) * fac + org.y + +proc stretch*(p:var TPoint2d,facx,facy:float){.inline.}= + ## Scales a point in place non uniformly `facx` and `facy` times with + ## world origo as origin. + p.x*=facx + p.y*=facy + +proc stretch*(p:var TPoint2d,facx,facy:float,org:TPoint2d){.inline.}= + ## Scales the point in place non uniformly `facx` and `facy` times with + ## `org` as origin. + p.x=(p.x - org.x) * facx + org.x + p.y=(p.y - org.y) * facy + org.y + +proc move*(p:var TPoint2d,dx,dy:float){.inline.}= + ## Translates a point `dx`, `dy` in place. + p.x+=dx + p.y+=dy + +proc move*(p:var TPoint2d,v:TVector2d){.inline.}= + ## Translates a point with vector `v` in place. + p.x+=v.x + p.y+=v.y + +proc sgnArea*(a,b,c:TPoint2d):float= + ## Computes the signed area of the triangle thru points `a`,`b` and `c` + ## result>0.0 for counter clockwise triangle + ## result<0.0 for clockwise triangle + ## This is commonly used to determinate side of a point with respect to a line. + return ((b.x - c.x) * (b.y - a.y)-(b.y - c.y) * (b.x - a.x))*0.5 + +proc area*(a,b,c:TPoint2d):float= + ## Computes the area of the triangle thru points `a`,`b` and `c` + return abs(sgnArea(a,b,c)) + +proc closestPoint*(p:TPoint2d,pts:varargs[TPoint2d]):TPoint2d= + ## Returns a point selected from `pts`, that has the closest + ## euclidean distance to `p` + assert(pts.len>0) # must have at least one point + + var + bestidx=0 + bestdist=p.sqrdist(pts[0]) + curdist:float + + for idx in 1..high(pts): + curdist=p.sqrdist(pts[idx]) + if curdist<bestdist: + bestidx=idx + bestdist=curdist + + result=pts[bestidx] + + +# *************************************** +# Misc. math utilities that should +# probably be in another module. +# *************************************** +proc normAngle*(ang:float):float= + ## Returns an angle in radians, that is equal to `ang`, + ## but in the range 0 to <2*PI + if ang>=0.0 and ang<DEG360: + return ang + + return ang mod DEG360 + +proc degToRad*(deg:float):float {.inline.}= + ## converts `deg` degrees to radians + deg / RAD2DEGCONST + +proc radToDeg*(rad:float):float {.inline.}= + ## converts `rad` radians to degrees + rad * RAD2DEGCONST + + \ No newline at end of file diff --git a/lib/pure/basic3d.nim b/lib/pure/basic3d.nim new file mode 100644 index 000000000..540d53fd9 --- /dev/null +++ b/lib/pure/basic3d.nim @@ -0,0 +1,1040 @@ +# +# +# Nimrod's Runtime Library +# (c) Copyright 2013 Robert Persson +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +import math +import strutils +import times + + +## Basic 3d support with vectors, points, matrices and some basic utilities. +## Vectors are implemented as direction vectors, ie. when transformed with a matrix +## the translation part of matrix is ignored. The coordinate system used is +## right handed, because its compatible with 2d coordinate system (rotation around +## zaxis equals 2d rotation). +## Operators `+` , `-` , `*` , `/` , `+=` , `-=` , `*=` and `/=` are implemented +## for vectors and scalars. +## +## +## Quick start example: +## +## # Create a matrix wich first rotates, then scales and at last translates +## +## var m:TMatrix3d=rotate(PI,vector3d(1,1,2.5)) & scale(2.0) & move(100.0,200.0,300.0) +## +## # Create a 3d point at (100,150,200) and a vector (5,2,3) +## +## var pt:TPoint3d=point3d(100.0,150.0,200.0) +## +## var vec:TVector3d=vector3d(5.0,2.0,3.0) +## +## +## pt &= m # transforms pt in place +## +## var pt2:TPoint3d=pt & m #concatenates pt with m and returns a new point +## +## var vec2:TVector3d=vec & m #concatenates vec with m and returns a new vector + + + +type + TMatrix3d* =object + ## Implements a row major 3d matrix, which means + ## transformations are applied the order they are concatenated. + ## This matrix is stored as an 4x4 matrix: + ## [ ax ay az aw ] + ## [ bx by bz bw ] + ## [ cx cy cz cw ] + ## [ tx ty tz tw ] + ax*,ay*,az*,aw*, bx*,by*,bz*,bw*, cx*,cy*,cz*,cw*, tx*,ty*,tz*,tw*:float + TPoint3d* = object + ## Implements a non-homegeneous 2d point stored as + ## an `x` , `y` and `z` coordinate. + x*,y*,z*:float + TVector3d* = object + ## Implements a 3d **direction vector** stored as + ## an `x` , `y` and `z` coordinate. Direction vector means, + ## that when transforming a vector with a matrix, the translational + ## part of the matrix is ignored. + x*,y*,z*:float + + + +# Some forward declarations +proc matrix3d*(ax,ay,az,aw,bx,by,bz,bw,cx,cy,cz,cw,tx,ty,tz,tw:float):TMatrix3d {.noInit.} + ## Creates a new 4x4 3d transformation matrix. + ## `ax` , `ay` , `az` is the local x axis. + ## `bx` , `by` , `bz` is the local y axis. + ## `cx` , `cy` , `cz` is the local z axis. + ## `tx` , `ty` , `tz` is the translation. +proc vector3d*(x,y,z:float):TVector3d {.noInit,inline.} + ## Returns a new 3d vector (`x`,`y`,`z`) +proc point3d*(x,y,z:float):TPoint3d {.noInit,inline.} + ## Returns a new 4d point (`x`,`y`,`z`) +proc tryNormalize*(v:var TVector3d):bool + ## Modifies `v` to have a length of 1.0, keeping its angle. + ## If `v` has zero length (and thus no angle), it is left unmodified and false is + ## returned, otherwise true is returned. + + + +let + IDMATRIX*:TMatrix3d=matrix3d( + 1.0,0.0,0.0,0.0, + 0.0,1.0,0.0,0.0, + 0.0,0.0,1.0,0.0, + 0.0,0.0,0.0,1.0) + ## Quick access to a 3d identity matrix + ORIGO*:TPoint3d=point3d(0.0,0.0,0.0) + ## Quick access to point (0,0) + XAXIS*:TVector3d=vector3d(1.0,0.0,0.0) + ## Quick access to an 3d x-axis unit vector + YAXIS*:TVector3d=vector3d(0.0,1.0,0.0) + ## Quick access to an 3d y-axis unit vector + ZAXIS*:TVector3d=vector3d(0.0,0.0,1.0) + ## Quick access to an 3d z-axis unit vector + + + +# *************************************** +# Private utils +# *************************************** + +proc rtos(val:float):string= + return formatFloat(val,ffDefault,0) + +proc safeArccos(v:float):float= + ## assumes v is in range 0.0-1.0, but clamps + ## the value to avoid out of domain errors + ## due to rounding issues + return arccos(clamp(v,-1.0,1.0)) + +template makeBinOpVector(s:expr)= + ## implements binary operators + , - , * and / for vectors + proc s*(a,b:TVector3d):TVector3d {.inline,noInit.} = + vector3d(s(a.x,b.x),s(a.y,b.y),s(a.z,b.z)) + proc s*(a:TVector3d,b:float):TVector3d {.inline,noInit.} = + vector3d(s(a.x,b),s(a.y,b),s(a.z,b)) + proc s*(a:float,b:TVector3d):TVector3d {.inline,noInit.} = + vector3d(s(a,b.x),s(a,b.y),s(a,b.z)) + +template makeBinOpAssignVector(s:expr)= + ## implements inplace binary operators += , -= , /= and *= for vectors + proc s*(a:var TVector3d,b:TVector3d) {.inline.} = + s(a.x,b.x) ; s(a.y,b.y) ; s(a.z,b.z) + proc s*(a:var TVector3d,b:float) {.inline.} = + s(a.x,b) ; s(a.y,b) ; s(a.z,b) + + + +# *************************************** +# TMatrix3d implementation +# *************************************** + +proc setElements*(t:var TMatrix3d,ax,ay,az,aw,bx,by,bz,bw,cx,cy,cz,cw,tx,ty,tz,tw:float) {.inline.}= + ## Sets arbitrary elements in an exisitng matrix. + t.ax=ax + t.ay=ay + t.az=az + t.aw=aw + t.bx=bx + t.by=by + t.bz=bz + t.bw=bw + t.cx=cx + t.cy=cy + t.cz=cz + t.cw=cw + t.tx=tx + t.ty=ty + t.tz=tz + t.tw=tw + +proc matrix3d*(ax,ay,az,aw,bx,by,bz,bw,cx,cy,cz,cw,tx,ty,tz,tw:float):TMatrix3d = + result.setElements(ax,ay,az,aw,bx,by,bz,bw,cx,cy,cz,cw,tx,ty,tz,tw) + +proc `&`*(a,b:TMatrix3d):TMatrix3d {.noinit.} = + ## Concatenates matrices returning a new matrix. + result.setElements( + a.aw*b.tx+a.az*b.cx+a.ay*b.bx+a.ax*b.ax, + a.aw*b.ty+a.az*b.cy+a.ay*b.by+a.ax*b.ay, + a.aw*b.tz+a.az*b.cz+a.ay*b.bz+a.ax*b.az, + a.aw*b.tw+a.az*b.cw+a.ay*b.bw+a.ax*b.aw, + + a.bw*b.tx+a.bz*b.cx+a.by*b.bx+a.bx*b.ax, + a.bw*b.ty+a.bz*b.cy+a.by*b.by+a.bx*b.ay, + a.bw*b.tz+a.bz*b.cz+a.by*b.bz+a.bx*b.az, + a.bw*b.tw+a.bz*b.cw+a.by*b.bw+a.bx*b.aw, + + a.cw*b.tx+a.cz*b.cx+a.cy*b.bx+a.cx*b.ax, + a.cw*b.ty+a.cz*b.cy+a.cy*b.by+a.cx*b.ay, + a.cw*b.tz+a.cz*b.cz+a.cy*b.bz+a.cx*b.az, + a.cw*b.tw+a.cz*b.cw+a.cy*b.bw+a.cx*b.aw, + + a.tw*b.tx+a.tz*b.cx+a.ty*b.bx+a.tx*b.ax, + a.tw*b.ty+a.tz*b.cy+a.ty*b.by+a.tx*b.ay, + a.tw*b.tz+a.tz*b.cz+a.ty*b.bz+a.tx*b.az, + a.tw*b.tw+a.tz*b.cw+a.ty*b.bw+a.tx*b.aw) + + +proc scale*(s:float):TMatrix3d {.noInit.} = + ## Returns a new scaling matrix. + result.setElements(s,0,0,0, 0,s,0,0, 0,0,s,0, 0,0,0,1) + +proc scale*(s:float,org:TPoint3d):TMatrix3d {.noInit.} = + ## Returns a new scaling matrix using, `org` as scale origin. + result.setElements(s,0,0,0, 0,s,0,0, 0,0,s,0, + org.x-s*org.x,org.y-s*org.y,org.z-s*org.z,1.0) + +proc stretch*(sx,sy,sz:float):TMatrix3d {.noInit.} = + ## Returns new a stretch matrix, which is a + ## scale matrix with non uniform scale in x,y and z. + result.setElements(sx,0,0,0, 0,sy,0,0, 0,0,sz,0, 0,0,0,1) + +proc stretch*(sx,sy,sz:float,org:TPoint3d):TMatrix3d {.noInit.} = + ## Returns a new stretch matrix, which is a + ## scale matrix with non uniform scale in x,y and z. + ## `org` is used as stretch origin. + result.setElements(sx,0,0,0, 0,sy,0,0, 0,0,sz,0, org.x-sx*org.x,org.y-sy*org.y,org.z-sz*org.z,1) + +proc move*(dx,dy,dz:float):TMatrix3d {.noInit.} = + ## Returns a new translation matrix. + result.setElements(1,0,0,0, 0,1,0,0, 0,0,1,0, dx,dy,dz,1) + +proc move*(v:TVector3d):TMatrix3d {.noInit.} = + ## Returns a new translation matrix from a vector. + result.setElements(1,0,0,0, 0,1,0,0, 0,0,1,0, v.x,v.y,v.z,1) + + +proc rotate*(angle:float,axis:TVector3d):TMatrix3d {.noInit.}= + ## Creates a rotation matrix that rotates `angle` radians over + ## `axis`, which passes through origo. + + # see PDF document http://inside.mines.edu/~gmurray/ArbitraryAxisRotation/ArbitraryAxisRotation.pdf + # for how this is computed + + var normax=axis + if not normax.tryNormalize: #simplifies matrix computation below a lot + raise newException(EDivByZero,"Cannot rotate around zero length axis") + + let + cs=cos(angle) + si=sin(angle) + omc=1.0-cs + usi=normax.x*si + vsi=normax.y*si + wsi=normax.z*si + u2=normax.x*normax.x + v2=normax.y*normax.y + w2=normax.z*normax.z + uvomc=normax.x*normax.y*omc + uwomc=normax.x*normax.z*omc + vwomc=normax.y*normax.z*omc + + result.setElements( + u2+(1.0-u2)*cs, uvomc+wsi, uwomc-vsi, 0.0, + uvomc-wsi, v2+(1.0-v2)*cs, vwomc+usi, 0.0, + uwomc+vsi, vwomc-usi, w2+(1.0-w2)*cs, 0.0, + 0.0,0.0,0.0,1.0) + +proc rotate*(angle:float,org:TPoint3d,axis:TVector3d):TMatrix3d {.noInit.}= + ## Creates a rotation matrix that rotates `angle` radians over + ## `axis`, which passes through `org`. + + # see PDF document http://inside.mines.edu/~gmurray/ArbitraryAxisRotation/ArbitraryAxisRotation.pdf + # for how this is computed + + var normax=axis + if not normax.tryNormalize: #simplifies matrix computation below a lot + raise newException(EDivByZero,"Cannot rotate around zero length axis") + + let + u=normax.x + v=normax.y + w=normax.z + u2=u*u + v2=v*v + w2=w*w + cs=cos(angle) + omc=1.0-cs + si=sin(angle) + a=org.x + b=org.y + c=org.z + usi=u*si + vsi=v*si + wsi=w*si + uvomc=normax.x*normax.y*omc + uwomc=normax.x*normax.z*omc + vwomc=normax.y*normax.z*omc + + result.setElements( + u2+(v2+w2)*cs, uvomc+wsi, uwomc-vsi, 0.0, + uvomc-wsi, v2+(u2+w2)*cs, vwomc+usi, 0.0, + uwomc+vsi, vwomc-usi, w2+(u2+v2)*cs, 0.0, + (a*(v2+w2)-u*(b*v+c*w))*omc+(b*w-c*v)*si, + (b*(u2+w2)-v*(a*u+c*w))*omc+(c*u-a*w)*si, + (c*(u2+v2)-w*(a*u+b*v))*omc+(a*v-b*u)*si,1.0) + + +proc rotateX*(angle:float):TMatrix3d {.noInit.}= + ## Creates a matrix that rotates around the x-axis with `angle` radians, + ## which is also called a 'roll' matrix. + let + c=cos(angle) + s=sin(angle) + result.setElements( + 1,0,0,0, + 0,c,s,0, + 0,-s,c,0, + 0,0,0,1) + +proc rotateY*(angle:float):TMatrix3d {.noInit.}= + ## Creates a matrix that rotates around the y-axis with `angle` radians, + ## which is also called a 'pitch' matrix. + let + c=cos(angle) + s=sin(angle) + result.setElements( + c,0,-s,0, + 0,1,0,0, + s,0,c,0, + 0,0,0,1) + +proc rotateZ*(angle:float):TMatrix3d {.noInit.}= + ## Creates a matrix that rotates around the z-axis with `angle` radians, + ## which is also called a 'yaw' matrix. + let + c=cos(angle) + s=sin(angle) + result.setElements( + c,s,0,0, + -s,c,0,0, + 0,0,1,0, + 0,0,0,1) + +proc isUniform*(m:TMatrix3d,tol=1.0e-6):bool= + ## Checks if the transform is uniform, that is + ## perpendicular axes of equal lenght, which means (for example) + ## it cannot transform a sphere into an ellipsoid. + ## `tol` is used as tolerance for both equal length comparison + ## and perpendicular comparison. + + #dot product=0 means perpendicular coord. system, check xaxis vs yaxis and xaxis vs zaxis + if abs(m.ax*m.bx+m.ay*m.by+m.az*m.bz)<=tol and # x vs y + abs(m.ax*m.cx+m.ay*m.cy+m.az*m.cz)<=tol and #x vs z + abs(m.bx*m.cx+m.by*m.cy+m.bz*m.cz)<=tol: #y vs z + + #subtract squared lengths of axes to check if uniform scaling: + let + sqxlen=(m.ax*m.ax+m.ay*m.ay+m.az*m.az) + sqylen=(m.bx*m.bx+m.by*m.by+m.bz*m.bz) + sqzlen=(m.cx*m.cx+m.cy*m.cy+m.cz*m.cz) + if abs(sqxlen-sqylen)<=tol and abs(sqxlen-sqzlen)<=tol: + return true + return false + + + +proc mirror*(planeperp:TVector3d):TMatrix3d {.noInit.}= + ## Creates a matrix that mirrors over the plane that has `planeperp` as normal, + ## and passes through origo. `planeperp` does not need to be normalized. + + # https://en.wikipedia.org/wiki/Transformation_matrix + var n=planeperp + if not n.tryNormalize: + raise newException(EDivByZero,"Cannot mirror over a plane with a zero length normal") + + let + a=n.x + b=n.y + c=n.z + ab=a*b + ac=a*c + bc=b*c + + result.setElements( + 1-2*a*a , -2*ab,-2*ac,0, + -2*ab , 1-2*b*b, -2*bc, 0, + -2*ac, -2*bc, 1-2*c*c,0, + 0,0,0,1) + + +proc mirror*(org:TPoint3d,planeperp:TVector3d):TMatrix3d {.noInit.}= + ## Creates a matrix that mirrors over the plane that has `planeperp` as normal, + ## and passes through `org`. `planeperp` does not need to be normalized. + + # constructs a mirror M like the simpler mirror matrix constructor + # above but premultiplies with the inverse traslation of org + # and postmultiplies with the translation of org. + # With some fiddling this becomes reasonably simple: + var n=planeperp + if not n.tryNormalize: + raise newException(EDivByZero,"Cannot mirror over a plane with a zero length normal") + + let + a=n.x + b=n.y + c=n.z + ab=a*b + ac=a*c + bc=b*c + aa=a*a + bb=b*b + cc=c*c + tx=org.x + ty=org.y + tz=org.z + + result.setElements( + 1-2*aa , -2*ab,-2*ac,0, + -2*ab , 1-2*bb, -2*bc, 0, + -2*ac, -2*bc, 1-2*cc,0, + 2*(ac*tz+ab*ty+aa*tx), + 2*(bc*tz+bb*ty+ab*tx), + 2*(cc*tz+bc*ty+ac*tx) ,1) + + +proc determinant*(m:TMatrix3d):float= + ## Computes the determinant of matrix `m`. + + # This computation is gotten from ratsimp(optimize(determinant(m))) + # in maxima CAS + let + O1=m.cx*m.tw-m.cw*m.tx + O2=m.cy*m.tw-m.cw*m.ty + O3=m.cx*m.ty-m.cy*m.tx + O4=m.cz*m.tw-m.cw*m.tz + O5=m.cx*m.tz-m.cz*m.tx + O6=m.cy*m.tz-m.cz*m.ty + + return (O1*m.ay-O2*m.ax-O3*m.aw)*m.bz+ + (-O1*m.az+O4*m.ax+O5*m.aw)*m.by+ + (O2*m.az-O4*m.ay-O6*m.aw)*m.bx+ + (O3*m.az-O5*m.ay+O6*m.ax)*m.bw + + +proc inverse*(m:TMatrix3d):TMatrix3d {.noInit.}= + ## Computes the inverse of matrix `m`. If the matrix + ## determinant is zero, thus not invertible, a EDivByZero + ## will be raised. + + # this computation comes from optimize(invert(m)) in maxima CAS + + let + det=m.determinant + O2=m.cy*m.tw-m.cw*m.ty + O3=m.cz*m.tw-m.cw*m.tz + O4=m.cy*m.tz-m.cz*m.ty + O5=m.by*m.tw-m.bw*m.ty + O6=m.bz*m.tw-m.bw*m.tz + O7=m.by*m.tz-m.bz*m.ty + O8=m.by*m.cw-m.bw*m.cy + O9=m.bz*m.cw-m.bw*m.cz + O10=m.by*m.cz-m.bz*m.cy + O11=m.cx*m.tw-m.cw*m.tx + O12=m.cx*m.tz-m.cz*m.tx + O13=m.bx*m.tw-m.bw*m.tx + O14=m.bx*m.tz-m.bz*m.tx + O15=m.bx*m.cw-m.bw*m.cx + O16=m.bx*m.cz-m.bz*m.cx + O17=m.cx*m.ty-m.cy*m.tx + O18=m.bx*m.ty-m.by*m.tx + O19=m.bx*m.cy-m.by*m.cx + + if det==0.0: + raise newException(EDivByZero,"Cannot normalize zero length vector") + + result.setElements( + (m.bw*O4+m.by*O3-m.bz*O2)/det , (-m.aw*O4-m.ay*O3+m.az*O2)/det, + (m.aw*O7+m.ay*O6-m.az*O5)/det , (-m.aw*O10-m.ay*O9+m.az*O8)/det, + (-m.bw*O12-m.bx*O3+m.bz*O11)/det , (m.aw*O12+m.ax*O3-m.az*O11)/det, + (-m.aw*O14-m.ax*O6+m.az*O13)/det , (m.aw*O16+m.ax*O9-m.az*O15)/det, + (m.bw*O17+m.bx*O2-m.by*O11)/det , (-m.aw*O17-m.ax*O2+m.ay*O11)/det, + (m.aw*O18+m.ax*O5-m.ay*O13)/det , (-m.aw*O19-m.ax*O8+m.ay*O15)/det, + (-m.bx*O4+m.by*O12-m.bz*O17)/det , (m.ax*O4-m.ay*O12+m.az*O17)/det, + (-m.ax*O7+m.ay*O14-m.az*O18)/det , (m.ax*O10-m.ay*O16+m.az*O19)/det) + + +proc equals*(m1:TMatrix3d,m2:TMatrix3d,tol=1.0e-6):bool= + ## Checks if all elements of `m1`and `m2` is equal within + ## a given tolerance `tol`. + return + abs(m1.ax-m2.ax)<=tol and + abs(m1.ay-m2.ay)<=tol and + abs(m1.az-m2.az)<=tol and + abs(m1.aw-m2.aw)<=tol and + abs(m1.bx-m2.bx)<=tol and + abs(m1.by-m2.by)<=tol and + abs(m1.bz-m2.bz)<=tol and + abs(m1.bw-m2.bw)<=tol and + abs(m1.cx-m2.cx)<=tol and + abs(m1.cy-m2.cy)<=tol and + abs(m1.cz-m2.cz)<=tol and + abs(m1.cw-m2.cw)<=tol and + abs(m1.tx-m2.tx)<=tol and + abs(m1.ty-m2.ty)<=tol and + abs(m1.tz-m2.tz)<=tol and + abs(m1.tw-m2.tw)<=tol + +proc `=~`*(m1,m2:TMatrix3d):bool= + ## Checks if `m1` and `m2` is aproximately equal, using a + ## tolerance of 1e-6. + equals(m1,m2) + +proc transpose*(m:TMatrix3d):TMatrix3d {.noInit.}= + ## Returns the transpose of `m` + result.setElements(m.ax,m.bx,m.cx,m.tx,m.ay,m.by,m.cy,m.ty,m.az,m.bz,m.cz,m.tz,m.aw,m.bw,m.cw,m.tw) + +proc getXAxis*(m:TMatrix3d):TVector3d {.noInit.}= + ## Gets the local x axis of `m` + result.x=m.ax + result.y=m.ay + result.z=m.az + +proc getYAxis*(m:TMatrix3d):TVector3d {.noInit.}= + ## Gets the local y axis of `m` + result.x=m.bx + result.y=m.by + result.z=m.bz + +proc getZAxis*(m:TMatrix3d):TVector3d {.noInit.}= + ## Gets the local y axis of `m` + result.x=m.cx + result.y=m.cy + result.z=m.cz + + +proc `$`*(m:TMatrix3d):string= + ## String representation of `m` + return rtos(m.ax) & "," & rtos(m.ay) & "," &rtos(m.az) & "," & rtos(m.aw) & + "\n" & rtos(m.bx) & "," & rtos(m.by) & "," &rtos(m.bz) & "," & rtos(m.bw) & + "\n" & rtos(m.cx) & "," & rtos(m.cy) & "," &rtos(m.cz) & "," & rtos(m.cw) & + "\n" & rtos(m.tx) & "," & rtos(m.ty) & "," &rtos(m.tz) & "," & rtos(m.tw) + +proc apply*(m:TMatrix3d, x,y,z:var float, translate=false)= + ## Applies transformation `m` onto `x` , `y` , `z` , optionally + ## using the translation part of the matrix. + let + oldx=x + oldy=y + oldz=z + + x=m.cx*oldz+m.bx*oldy+m.ax*oldx + y=m.cy*oldz+m.by*oldy+m.ay*oldx + z=m.cz*oldz+m.bz*oldy+m.az*oldx + + if translate: + x+=m.tx + y+=m.ty + z+=m.tz + +# *************************************** +# TVector3d implementation +# *************************************** +proc Vector3d*(x,y,z:float):TVector3d= + result.x=x + result.y=y + result.z=z + +proc len*(v:TVector3d):float= + ## Returns the length of the vector `v`. + sqrt(v.x*v.x+v.y*v.y+v.z*v.z) + +proc `len=`*(v:var TVector3d,newlen:float) {.noInit.} = + ## Sets the length of the vector, keeping its direction. + ## If the vector has zero length before changing it's length, + ## an arbitrary vector of the requested length is returned. + + let fac=newlen/v.len + + if newlen==0.0: + v.x=0.0 + v.y=0.0 + v.z=0.0 + return + + if fac==inf or fac==neginf: + #to short for float accuracy + #do as good as possible: + v.x=newlen + v.y=0.0 + v.z=0.0 + else: + v.x*=fac + v.y*=fac + v.z*=fac + + +proc sqrLen*(v:TVector3d):float {.inline.}= + ## Computes the squared length of the vector, which is + ## faster than computing the absolute length. + return v.x*v.x+v.y*v.y+v.z*v.z + +proc `$` *(v:TVector3d):string= + ## String representation of `v` + result=rtos(v.x) + result.add(",") + result.add(rtos(v.y)) + result.add(",") + result.add(rtos(v.z)) + +proc `&` *(v:TVector3d,m:TMatrix3d):TVector3d {.noInit.} = + ## Concatenate vector `v` with a transformation matrix. + ## Transforming a vector ignores the translational part + ## of the matrix. + + # | AX AY AZ AW | + # | X Y Z 1 | * | BX BY BZ BW | + # | CX CY CZ CW | + # | 0 0 0 1 | + let + newx=m.cx*v.z+m.bx*v.y+m.ax*v.x + newy=m.cy*v.z+m.by*v.y+m.ay*v.x + result.z=m.cz*v.z+m.bz*v.y+m.az*v.x + result.y=newy + result.x=newx + + +proc `&=` *(v:var TVector3d,m:TMatrix3d) {.noInit.} = + ## Applies transformation `m` onto `v` in place. + ## Transforming a vector ignores the translational part + ## of the matrix. + + # | AX AY AZ AW | + # | X Y Z 1 | * | BX BY BZ BW | + # | CX CY CZ CW | + # | 0 0 0 1 | + + let + newx=m.cx*v.z+m.bx*v.y+m.ax*v.x + newy=m.cy*v.z+m.by*v.y+m.ay*v.x + v.z=m.cz*v.z+m.bz*v.y+m.az*v.x + v.y=newy + v.x=newx + +proc transformNorm*(v:var TVector3d,m:TMatrix3d)= + ## Applies a normal direction transformation `m` onto `v` in place. + ## The resulting vector is *not* normalized. Transforming a vector ignores the + ## translational part of the matrix. If the matrix is not invertible + ## (determinant=0), an EDivByZero will be raised. + + # transforming a normal is done by transforming + # by the transpose of the inverse of the original matrix + + # Major reason this simple function is here is that this function can be optimized in the future, + # (possibly by hardware) as well as having a consistent API with the 2d version. + v&=transpose(inverse(m)) + +proc transformInv*(v:var TVector3d,m:TMatrix3d)= + ## Applies the inverse of `m` on vector `v`. Transforming a vector ignores + ## the translational part of the matrix. Transforming a vector ignores the + ## translational part of the matrix. + ## If the matrix is not invertible (determinant=0), an EDivByZero + ## will be raised. + + # Major reason this simple function is here is that this function can be optimized in the future, + # (possibly by hardware) as well as having a consistent API with the 2d version. + v&=m.inverse + +proc transformNormInv*(vec:var TVector3d,m:TMatrix3d)= + ## Applies an inverse normal direction transformation `m` onto `v` in place. + ## This is faster than creating an inverse + ## matrix and transformNorm(...) it. Transforming a vector ignores the + ## translational part of the matrix. + + # see vector2d:s equivalent for a deeper look how/why this works + vec&=m.transpose + +proc tryNormalize*(v:var TVector3d):bool= + ## Modifies `v` to have a length of 1.0, keeping its angle. + ## If `v` has zero length (and thus no angle), it is left unmodified and false is + ## returned, otherwise true is returned. + let mag=v.len + + if mag==0.0: + return false + + v.x/=mag + v.y/=mag + v.z/=mag + + return true + +proc normalize*(v:var TVector3d) {.inline.}= + ## Modifies `v` to have a length of 1.0, keeping its angle. + ## If `v` has zero length, an EDivByZero will be raised. + if not tryNormalize(v): + raise newException(EDivByZero,"Cannot normalize zero length vector") + +proc rotate*(vec:var TVector3d,angle:float,axis:TVector3d)= + ## Rotates `vec` in place, with `angle` radians over `axis`, which passes + ## through origo. + + # see PDF document http://inside.mines.edu/~gmurray/ArbitraryAxisRotation/ArbitraryAxisRotation.pdf + # for how this is computed + + var normax=axis + if not normax.tryNormalize: + raise newException(EDivByZero,"Cannot rotate around zero length axis") + + let + cs=cos(angle) + si=sin(angle) + omc=1.0-cs + u=normax.x + v=normax.y + w=normax.z + x=vec.x + y=vec.y + z=vec.z + uxyzomc=(u*x+v*y+w*z)*omc + + vec.x=u*uxyzomc+x*cs+(v*z-w*y)*si + vec.y=v*uxyzomc+y*cs+(w*x-u*z)*si + vec.z=w*uxyzomc+z*cs+(u*y-v*x)*si + +proc scale*(v:var TVector3d,s:float)= + ## Scales the vector in place with factor `s` + v.x*=s + v.y*=s + v.z*=s + +proc stretch*(v:var TVector3d,sx,sy,sz:float)= + ## Scales the vector non uniformly with factors `sx` , `sy` , `sz` + v.x*=sx + v.y*=sy + v.z*=sz + +proc mirror*(v:var TVector3d,planeperp:TVector3d)= + ## Computes the mirrored vector of `v` over the plane + ## that has `planeperp` as normal direction. + ## `planeperp` does not need to be normalized. + + var n=planeperp + n.normalize + + let + x=v.x + y=v.y + z=v.z + a=n.x + b=n.y + c=n.z + ac=a*c + ab=a*b + bc=b*c + + v.x= -2*(ac*z+ab*y+a*a*x)+x + v.y= -2*(bc*z+b*b*y+ab*x)+y + v.z= -2*(c*c*z+bc*y+ac*x)+z + + +proc `-` *(v:TVector3d):TVector3d= + ## Negates a vector + result.x= -v.x + result.y= -v.y + result.z= -v.z + +# declare templated binary operators +makeBinOpVector(`+`) +makeBinOpVector(`-`) +makeBinOpVector(`*`) +makeBinOpVector(`/`) +makeBinOpAssignVector(`+=`) +makeBinOpAssignVector(`-=`) +makeBinOpAssignVector(`*=`) +makeBinOpAssignVector(`/=`) + +proc dot*(v1,v2:TVector3d):float {.inline.}= + ## Computes the dot product of two vectors. + ## Returns 0.0 if the vectors are perpendicular. + return v1.x*v2.x+v1.y*v2.y+v1.z*v2.z + +proc cross*(v1,v2:TVector3d):TVector3d {.inline.}= + ## Computes the cross product of two vectors. + ## The result is a vector which is perpendicular + ## to the plane of `v1` and `v2`, which means + ## cross(xaxis,yaxis)=zaxis. The magnitude of the result is + ## zero if the vectors are colinear. + result.x = (v1.y * v2.z) - (v2.y * v1.z) + result.y = (v1.z * v2.x) - (v2.z * v1.x) + result.z = (v1.x * v2.y) - (v2.x * v1.y) + +proc equals*(v1,v2:TVector3d,tol=1.0e-6):bool= + ## Checks if two vectors approximately equals with a tolerance. + return abs(v2.x-v1.x)<=tol and abs(v2.y-v1.y)<=tol and abs(v2.z-v1.z)<=tol + +proc `=~` *(v1,v2:TVector3d):bool= + ## Checks if two vectors approximately equals with a + ## hardcoded tolerance 1e-6 + equals(v1,v2) + +proc angleTo*(v1,v2:TVector3d):float= + ## Returns the smallest angle between v1 and v2, + ## which is in range 0-PI + var + nv1=v1 + nv2=v2 + if not nv1.tryNormalize or not nv2.tryNormalize: + return 0.0 # zero length vector has zero angle to any other vector + return safeArccos(dot(nv1,nv2)) + +proc arbitraryAxis*(norm:TVector3d):TMatrix3d {.noInit.}= + ## Computes the rotation matrix that would transform + ## world z vector into `norm`. The inverse of this matrix + ## is useful to tranform a planar 3d object to 2d space. + ## This is the same algorithm used to interpret DXF and DWG files. + const lim=1.0/64.0 + var ax,ay,az:TVector3d + if abs(norm.x)<lim and abs(norm.y)<lim: + ax=cross(YAXIS,norm) + else: + ax=cross(ZAXIS,norm) + + ax.normalize() + ay=cross(norm,ax) + ay.normalize() + az=cross(ax,ay) + + result.setElements( + ax.x,ax.y,ax.z,0.0, + ay.x,ay.y,ay.z,0.0, + az.x,az.y,az.z,0.0, + 0.0,0.0,0.0,1.0) + +proc bisect*(v1,v2:TVector3d):TVector3d {.noInit.}= + ## Computes the bisector between v1 and v2 as a normalized vector. + ## If one of the input vectors has zero length, a normalized version + ## of the other is returned. If both input vectors has zero length, + ## an arbitrary normalized vector `v1`is returned. + var + vmag1=v1.len + vmag2=v2.len + + # zero length vector equals arbitrary vector, just change + # magnitude to one to avoid zero division + if vmag1==0.0: + if vmag2==0: #both are zero length return any normalized vector + return XAXIS + vmag1=1.0 + if vmag2==0.0: vmag2=1.0 + + let + x1=v1.x/vmag1 + y1=v1.y/vmag1 + z1=v1.z/vmag1 + x2=v2.x/vmag2 + y2=v2.y/vmag2 + z2=v2.z/vmag2 + + result.x=(x1 + x2) * 0.5 + result.y=(y1 + y2) * 0.5 + result.z=(z1 + z2) * 0.5 + + if not result.tryNormalize(): + # This can happen if vectors are colinear. In this special case + # there are actually inifinitely many bisectors, we select just + # one of them. + result=v1.cross(XAXIS) + if result.sqrlen<1.0e-9: + result=v1.cross(YAXIS) + if result.sqrlen<1.0e-9: + result=v1.cross(ZAXIS) # now we should be guaranteed to have succeeded + result.normalize + + + +# *************************************** +# TPoint3d implementation +# *************************************** +proc Point3d*(x,y,z:float):TPoint3d= + result.x=x + result.y=y + result.z=z + +proc sqrDist*(a,b:TPoint3d):float= + ## Computes the squared distance between `a`and `b` + let dx=b.x-a.x + let dy=b.y-a.y + let dz=b.z-a.z + result=dx*dx+dy*dy+dz*dz + +proc dist*(a,b:TPoint3d):float {.inline.}= + ## Computes the absolute distance between `a`and `b` + result=sqrt(sqrDist(a,b)) + +proc `$` *(p:TPoint3d):string= + ## String representation of `p` + result=rtos(p.x) + result.add(",") + result.add(rtos(p.y)) + result.add(",") + result.add(rtos(p.z)) + +proc `&`*(p:TPoint3d,m:TMatrix3d):TPoint3d= + ## Concatenates a point `p` with a transform `m`, + ## resulting in a new, transformed point. + result.z=m.cz*p.z+m.bz*p.y+m.az*p.x+m.tz + result.y=m.cy*p.z+m.by*p.y+m.ay*p.x+m.ty + result.x=m.cx*p.z+m.bx*p.y+m.ax*p.x+m.tx + +proc `&=` *(p:var TPoint3d,m:TMatrix3d)= + ## Applies transformation `m` onto `p` in place. + let + x=p.x + y=p.y + z=p.z + p.x=m.cx*z+m.bx*y+m.ax*x+m.tx + p.y=m.cy*z+m.by*y+m.ay*x+m.ty + p.z=m.cz*z+m.bz*y+m.az*x+m.tz + +proc transformInv*(p:var TPoint3d,m:TMatrix3d)= + ## Applies the inverse of transformation `m` onto `p` in place. + ## If the matrix is not invertable (determinant=0) , EDivByZero will + ## be raised. + + # can possibly be more optimized in the future so use this function when possible + p&=inverse(m) + + +proc `+`*(p:TPoint3d,v:TVector3d):TPoint3d {.noInit,inline.} = + ## Adds a vector `v` to a point `p`, resulting + ## in a new point. + result.x=p.x+v.x + result.y=p.y+v.y + result.z=p.z+v.z + +proc `+=`*(p:var TPoint3d,v:TVector3d) {.noInit,inline.} = + ## Adds a vector `v` to a point `p` in place. + p.x+=v.x + p.y+=v.y + p.z+=v.z + +proc `-`*(p:TPoint3d,v:TVector3d):TPoint3d {.noInit,inline.} = + ## Subtracts a vector `v` from a point `p`, resulting + ## in a new point. + result.x=p.x-v.x + result.y=p.y-v.y + result.z=p.z-v.z + +proc `-`*(p1,p2:TPoint3d):TVector3d {.noInit,inline.} = + ## Subtracts `p2`from `p1` resulting in a difference vector. + result.x=p1.x-p2.x + result.y=p1.y-p2.y + result.z=p1.z-p2.z + +proc `-=`*(p:var TPoint3d,v:TVector3d) {.noInit,inline.} = + ## Subtracts a vector `v` from a point `p` in place. + p.x-=v.x + p.y-=v.y + p.z-=v.z + +proc equals(p1,p2:TPoint3d,tol=1.0e-6):bool {.inline.}= + ## Checks if two points approximately equals with a tolerance. + return abs(p2.x-p1.x)<=tol and abs(p2.y-p1.y)<=tol and abs(p2.z-p1.z)<=tol + +proc `=~`*(p1,p2:TPoint3d):bool {.inline.}= + ## Checks if two vectors approximately equals with a + ## hardcoded tolerance 1e-6 + equals(p1,p2) + +proc rotate*(p:var TPoint3d,rad:float,axis:TVector3d)= + ## Rotates point `p` in place `rad` radians about an axis + ## passing through origo. + + var v=vector3d(p.x,p.y,p.z) + v.rotate(rad,axis) # reuse this code here since doing the same thing and quite complicated + p.x=v.x + p.y=v.y + p.z=v.z + +proc rotate*(p:var TPoint3d,angle:float,org:TPoint3d,axis:TVector3d)= + ## Rotates point `p` in place `rad` radians about an axis + ## passing through `org` + + # see PDF document http://inside.mines.edu/~gmurray/ArbitraryAxisRotation/ArbitraryAxisRotation.pdf + # for how this is computed + + var normax=axis + normax.normalize + + let + cs=cos(angle) + omc=1.0-cs + si=sin(angle) + u=normax.x + v=normax.y + w=normax.z + a=org.x + b=org.y + c=org.z + x=p.x + y=p.y + z=p.z + uu=u*u + vv=v*v + ww=w*w + ux=u*p.x + vy=v*p.y + wz=w*p.z + au=a*u + bv=b*v + cw=c*w + uxmvymwz=ux-vy-wz + + p.x=(a*(vv+ww)-u*(bv+cw-uxmvymwz))*omc + x*cs + (b*w+v*z-c*v-w*y)*si + p.y=(b*(uu+ww)-v*(au+cw-uxmvymwz))*omc + y*cs + (c*u-a*w+w*x-u*z)*si + p.z=(c*(uu+vv)-w*(au+bv-uxmvymwz))*omc + z*cs + (a*v+u*y-b*u-v*x)*si + +proc scale*(p:var TPoint3d,fac:float) {.inline.}= + ## Scales a point in place `fac` times with world origo as origin. + p.x*=fac + p.y*=fac + p.z*=fac + +proc scale*(p:var TPoint3d,fac:float,org:TPoint3d){.inline.}= + ## Scales the point in place `fac` times with `org` as origin. + p.x=(p.x - org.x) * fac + org.x + p.y=(p.y - org.y) * fac + org.y + p.z=(p.z - org.z) * fac + org.z + +proc stretch*(p:var TPoint3d,facx,facy,facz:float){.inline.}= + ## Scales a point in place non uniformly `facx` , `facy` , `facz` times + ## with world origo as origin. + p.x*=facx + p.y*=facy + p.z*=facz + +proc stretch*(p:var TPoint3d,facx,facy,facz:float,org:TPoint3d){.inline.}= + ## Scales the point in place non uniformly `facx` , `facy` , `facz` times + ## with `org` as origin. + p.x=(p.x - org.x) * facx + org.x + p.y=(p.y - org.y) * facy + org.y + p.z=(p.z - org.z) * facz + org.z + + +proc move*(p:var TPoint3d,dx,dy,dz:float){.inline.}= + ## Translates a point `dx` , `dy` , `dz` in place. + p.x+=dx + p.y+=dy + p.z+=dz + +proc move*(p:var TPoint3d,v:TVector3d){.inline.}= + ## Translates a point with vector `v` in place. + p.x+=v.x + p.y+=v.y + p.z+=v.z + +proc area*(a,b,c:TPoint3d):float {.inline.}= + ## Computes the area of the triangle thru points `a` , `b` and `c` + + # The area of a planar 3d quadliteral is the magnitude of the cross + # product of two edge vectors. Taking this time 0.5 gives the triangle area. + return cross(b-a,c-a).len*0.5 + diff --git a/lib/pure/ftpclient.nim b/lib/pure/ftpclient.nim index 7893eafa0..b6127a9bc 100644 --- a/lib/pure/ftpclient.nim +++ b/lib/pure/ftpclient.nim @@ -129,7 +129,8 @@ proc expectReply(ftp: PFTPClient): TaintedString = proc send*(ftp: PFTPClient, m: string): TaintedString = ## Send a message to the server, and wait for a primary reply. ## ``\c\L`` is added for you. - ftp.getCSock().send(m & "\c\L") + blockingOperation(ftp.getCSock()): + ftp.getCSock().send(m & "\c\L") return ftp.expectReply() proc assertReply(received: TaintedString, expected: string) = diff --git a/lib/pure/os.nim b/lib/pure/os.nim index 43bdb16ee..a39ca7b83 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -544,33 +544,31 @@ proc SplitPath*(path: string): tuple[head, tail: string] {. result.head = "" result.tail = path +proc parentDirPos(path: string): int = + var q = 1 + if path[len(path)-1] in {dirsep, altsep}: q = 2 + for i in countdown(len(path)-q, 0): + if path[i] in {dirsep, altsep}: return i + result = -1 + proc parentDir*(path: string): string {. noSideEffect, rtl, extern: "nos$1".} = ## Returns the parent directory of `path`. ## ## This is often the same as the ``head`` result of ``splitPath``. - ## If there is no parent, ``path`` is returned. + ## If there is no parent, "" is returned. ## | Example: ``parentDir("/usr/local/bin") == "/usr/local"``. ## | Example: ``parentDir("/usr/local/bin/") == "/usr/local"``. - var - sepPos = -1 - q = 1 - if path[len(path)-1] in {dirsep, altsep}: - q = 2 - for i in countdown(len(path)-q, 0): - if path[i] in {dirsep, altsep}: - sepPos = i - break + let sepPos = parentDirPos(path) if sepPos >= 0: result = substr(path, 0, sepPos-1) else: - result = path + result = "" proc isRootDir*(path: string): bool {. noSideEffect, rtl, extern: "nos$1".} = ## Checks whether a given `path` is a root directory - var p = parentDir(path) - result = p == path or p.len == 0 + result = parentDirPos(path) < 0 iterator parentDirs*(path: string, fromRoot=false, inclusive=true): string = ## Walks over all parent directories of a given `path` @@ -591,14 +589,20 @@ iterator parentDirs*(path: string, fromRoot=false, inclusive=true): string = else: for i in countup(0, path.len - 2): # ignore the last / # deal with non-normalized paths such as /foo//bar//baz - if path[i] in {dirsep, altsep} and (i == 0 or path[i-1] notin {dirsep, altsep}): + if path[i] in {dirsep, altsep} and + (i == 0 or path[i-1] notin {dirsep, altsep}): yield path.substr(0, i) if inclusive: yield path proc `/../` * (head, tail: string): string {.noSideEffect.} = - ## The same as ``parentDir(head) / tail`` - return parentDir(head) / tail + ## The same as ``parentDir(head) / tail`` unless there is no parent directory. + ## Then ``head / tail`` is performed instead. + let sepPos = parentDirPos(head) + if sepPos >= 0: + result = substr(head, 0, sepPos-1) / tail + else: + result = head / tail proc normExt(ext: string): string = if ext == "" or ext[0] == extSep: result = ext # no copy needed here diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index b9bde73bc..a3d72d73c 100644 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -24,10 +24,10 @@ type TProcess = object of TObject when defined(windows): FProcessHandle: Thandle - inputHandle, outputHandle, errorHandle: TFileHandle + inHandle, outHandle, errHandle: TFileHandle id: THandle else: - inputHandle, outputHandle, errorHandle: TFileHandle + inHandle, outHandle, errHandle: TFileHandle inStream, outStream, errStream: PStream id: TPid exitCode: cint @@ -113,23 +113,47 @@ proc peekExitCode*(p: PProcess): int {.tags: [].} ## return -1 if the process is still running. Otherwise the process' exit code proc inputStream*(p: PProcess): PStream {.rtl, extern: "nosp$1", tags: [].} - ## returns ``p``'s input stream for writing to + ## returns ``p``'s input stream for writing to. ## ## **Warning**: The returned `PStream` should not be closed manually as it ## is closed when closing the PProcess ``p``. proc outputStream*(p: PProcess): PStream {.rtl, extern: "nosp$1", tags: [].} - ## returns ``p``'s output stream for reading from + ## returns ``p``'s output stream for reading from. ## ## **Warning**: The returned `PStream` should not be closed manually as it ## is closed when closing the PProcess ``p``. proc errorStream*(p: PProcess): PStream {.rtl, extern: "nosp$1", tags: [].} - ## returns ``p``'s output stream for reading from + ## returns ``p``'s error stream for reading from. ## ## **Warning**: The returned `PStream` should not be closed manually as it ## is closed when closing the PProcess ``p``. +proc inputHandle*(p: PProcess): TFileHandle {.rtl, extern: "nosp$1", + tags: [].} = + ## returns ``p``'s input file handle for writing to. + ## + ## **Warning**: The returned `TFileHandle` should not be closed manually as + ## it is closed when closing the PProcess ``p``. + result = p.inHandle + +proc outputHandle*(p: PProcess): TFileHandle {.rtl, extern: "nosp$1", + tags: [].} = + ## returns ``p``'s output file handle for reading from. + ## + ## **Warning**: The returned `TFileHandle` should not be closed manually as + ## it is closed when closing the PProcess ``p``. + result = p.outHandle + +proc errorHandle*(p: PProcess): TFileHandle {.rtl, extern: "nosp$1", + tags: [].} = + ## returns ``p``'s error file handle for reading from. + ## + ## **Warning**: The returned `TFileHandle` should not be closed manually as + ## it is closed when closing the PProcess ``p``. + result = p.errHandle + when defined(macosx) or defined(bsd): const CTL_HW = 6 @@ -339,16 +363,16 @@ when defined(Windows) and not defined(useNimRtl): HE = HO else: CreatePipeHandles(HE, Si.hStdError) - result.inputHandle = TFileHandle(hi) - result.outputHandle = TFileHandle(ho) - result.errorHandle = TFileHandle(he) + result.inHandle = TFileHandle(hi) + result.outHandle = TFileHandle(ho) + result.errHandle = TFileHandle(he) else: SI.hStdError = GetStdHandle(STD_ERROR_HANDLE) SI.hStdInput = GetStdHandle(STD_INPUT_HANDLE) SI.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE) - result.inputHandle = TFileHandle(si.hStdInput) - result.outputHandle = TFileHandle(si.hStdOutput) - result.errorHandle = TFileHandle(si.hStdError) + result.inHandle = TFileHandle(si.hStdInput) + result.outHandle = TFileHandle(si.hStdOutput) + result.errHandle = TFileHandle(si.hStdError) var cmdl: cstring when false: # poUseShell in options: @@ -389,9 +413,9 @@ when defined(Windows) and not defined(useNimRtl): proc close(p: PProcess) = when false: # somehow this does not work on Windows: - discard CloseHandle(p.inputHandle) - discard CloseHandle(p.outputHandle) - discard CloseHandle(p.errorHandle) + discard CloseHandle(p.inHandle) + discard CloseHandle(p.outHandle) + discard CloseHandle(p.errHandle) discard CloseHandle(p.FProcessHandle) proc suspend(p: PProcess) = @@ -425,13 +449,13 @@ when defined(Windows) and not defined(useNimRtl): return res proc inputStream(p: PProcess): PStream = - result = newFileHandleStream(p.inputHandle) + result = newFileHandleStream(p.inHandle) proc outputStream(p: PProcess): PStream = - result = newFileHandleStream(p.outputHandle) + result = newFileHandleStream(p.outHandle) proc errorStream(p: PProcess): PStream = - result = newFileHandleStream(p.errorHandle) + result = newFileHandleStream(p.errHandle) proc execCmd(command: string): int = var @@ -626,20 +650,20 @@ elif not defined(useNimRtl): if poParentStreams in options: # does not make much sense, but better than nothing: - result.inputHandle = 0 - result.outputHandle = 1 + result.inHandle = 0 + result.outHandle = 1 if poStdErrToStdOut in options: - result.errorHandle = result.outputHandle + result.errHandle = result.outHandle else: - result.errorHandle = 2 + result.errHandle = 2 else: - result.inputHandle = p_stdin[writeIdx] - result.outputHandle = p_stdout[readIdx] + result.inHandle = p_stdin[writeIdx] + result.outHandle = p_stdout[readIdx] if poStdErrToStdOut in options: - result.errorHandle = result.outputHandle + result.errHandle = result.outHandle discard close(p_stderr[readIdx]) else: - result.errorHandle = p_stderr[readIdx] + result.errHandle = p_stderr[readIdx] discard close(p_stderr[writeIdx]) discard close(p_stdin[readIdx]) discard close(p_stdout[writeIdx]) @@ -648,9 +672,9 @@ elif not defined(useNimRtl): if p.inStream != nil: close(p.inStream) if p.outStream != nil: close(p.outStream) if p.errStream != nil: close(p.errStream) - discard close(p.inputHandle) - discard close(p.outputHandle) - discard close(p.errorHandle) + discard close(p.inHandle) + discard close(p.outHandle) + discard close(p.errHandle) proc suspend(p: PProcess) = if kill(-p.id, SIGSTOP) != 0'i32: OSError(OSLastError()) @@ -696,17 +720,17 @@ elif not defined(useNimRtl): proc inputStream(p: PProcess): PStream = if p.inStream == nil: - createStream(p.inStream, p.inputHandle, fmWrite) + createStream(p.inStream, p.inHandle, fmWrite) return p.inStream proc outputStream(p: PProcess): PStream = if p.outStream == nil: - createStream(p.outStream, p.outputHandle, fmRead) + createStream(p.outStream, p.outHandle, fmRead) return p.outStream proc errorStream(p: PProcess): PStream = if p.errStream == nil: - createStream(p.errStream, p.errorHandle, fmRead) + createStream(p.errStream, p.errHandle, fmRead) return p.errStream proc csystem(cmd: cstring): cint {.nodecl, importc: "system".} @@ -717,14 +741,14 @@ elif not defined(useNimRtl): proc createFdSet(fd: var TFdSet, s: seq[PProcess], m: var int) = FD_ZERO(fd) for i in items(s): - m = max(m, int(i.outputHandle)) - FD_SET(cint(i.outputHandle), fd) + m = max(m, int(i.outHandle)) + FD_SET(cint(i.outHandle), fd) proc pruneProcessSet(s: var seq[PProcess], fd: var TFdSet) = var i = 0 var L = s.len while i < L: - if FD_ISSET(cint(s[i].outputHandle), fd) != 0'i32: + if FD_ISSET(cint(s[i].outHandle), fd) != 0'i32: s[i] = s[L-1] dec(L) else: diff --git a/lib/pure/sockets.nim b/lib/pure/sockets.nim index 73a189fee..516d0d8bc 100644 --- a/lib/pure/sockets.nim +++ b/lib/pure/sockets.nim @@ -11,11 +11,11 @@ ## of sockets. Sockets are buffered by default meaning that data will be ## received in ``BufferSize`` (4000) sized chunks, buffering ## behaviour can be disabled by setting the ``buffered`` parameter when calling -## the ``socket`` function to `False`. Be aware that some functions may not yet +## the ``socket`` function to `false`. Be aware that some functions may not yet ## support buffered sockets (mainly the recvFrom function). ## ## Most procedures raise EOS on error, but some may return ``-1`` or a boolean -## ``False``. +## ``false``. ## ## SSL is supported through the OpenSSL library. This support can be activated ## by compiling with the ``-d:ssl`` switch. When an SSL socket is used it will @@ -62,7 +62,7 @@ const type TSocketImpl = object ## socket type - fd: cint + fd: TSocketHandle case isBuffered: bool # determines whether this socket is buffered. of true: buffer: array[0..BufferSize, char] @@ -126,7 +126,7 @@ type ETimeout* = object of ESynch -proc newTSocket(fd: int32, isBuff: bool): TSocket = +proc newTSocket(fd: TSocketHandle, isBuff: bool): TSocket = new(result) result.fd = fd result.isBuffered = isBuff @@ -1605,17 +1605,17 @@ when defined(Windows): const IOCPARM_MASK = 127 IOC_IN = int(-2147483648) - FIONBIO = int(IOC_IN or ((sizeof(int) and IOCPARM_MASK) shl 16) or - (102 shl 8) or 126) + FIONBIO = IOC_IN.int32 or ((sizeof(int32) and IOCPARM_MASK) shl 16) or + (102 shl 8) or 126 - proc ioctlsocket(s: TWinSocket, cmd: clong, + proc ioctlsocket(s: TSocketHandle, cmd: clong, argptr: ptr clong): cint {. stdcall, importc:"ioctlsocket", dynlib: "ws2_32.dll".} proc setBlocking(s: TSocket, blocking: bool) = when defined(Windows): var mode = clong(ord(not blocking)) # 1 for non-blocking, 0 for blocking - if ioctlsocket(TWinSocket(s.fd), FIONBIO, addr(mode)) == -1: + if ioctlsocket(TSocketHandle(s.fd), FIONBIO, addr(mode)) == -1: OSError(OSLastError()) else: # BSD sockets var x: int = fcntl(s.fd, F_GETFL, 0) @@ -1656,7 +1656,7 @@ proc connect*(socket: TSocket, address: string, port = TPort(0), timeout: int, proc isSSL*(socket: TSocket): bool = return socket.isSSL ## Determines whether ``socket`` is a SSL socket. -proc getFD*(socket: TSocket): cint = return socket.fd +proc getFD*(socket: TSocket): TSocketHandle = return socket.fd ## Returns the socket's file descriptor when defined(Windows): diff --git a/lib/pure/xmlparser.nim b/lib/pure/xmlparser.nim index 355053e0d..16bbe1455 100644 --- a/lib/pure/xmlparser.nim +++ b/lib/pure/xmlparser.nim @@ -110,7 +110,7 @@ proc parseXml*(s: PStream, filename: string, of xmlElementOpen, xmlElementStart: result = parse(x, errors) break - of xmlComment, xmlWhitespace, xmlSpecial: nil # just skip it + of xmlComment, xmlWhitespace, xmlSpecial, xmlPI: nil # just skip it of xmlError: errors.add(errorMsg(x)) else: diff --git a/lib/system.nim b/lib/system.nim index 4ff1f1577..b2d19a885 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -77,17 +77,6 @@ type TNumber* = TInteger|TReal ## type class matching all number types - -type - ## helper types for writing implicitly generic procs - T1* = expr - T2* = expr - T3* = expr - T4* = expr - T5* = expr - type1* = typedesc - type2* = typedesc - type3* = typedesc proc defined*(x: expr): bool {.magic: "Defined", noSideEffect.} ## Special compile-time procedure that checks whether `x` is @@ -860,7 +849,7 @@ const ## a string that describes the application type. Possible values: ## "console", "gui", "lib". - seqShallowFlag = 1 shl (sizeof(int)*8-1) + seqShallowFlag = low(int) proc compileOption*(option: string): bool {. magic: "CompileOption", noSideEffect.} @@ -1009,6 +998,13 @@ type ## compiler supports. Currently this is ``float64``, but it is ## platform-dependant in general. +when defined(windows): + type clong* {.importc: "long", nodecl.} = int32 + ## This is the same as the type ``long`` in *C*. +else: + type clong* {.importc: "long", nodecl.} = int + ## This is the same as the type ``long`` in *C*. + type # these work for most platforms: cchar* {.importc: "char", nodecl.} = char ## This is the same as the type ``char`` in *C*. @@ -1020,8 +1016,6 @@ type # these work for most platforms: ## This is the same as the type ``int`` in *C*. csize* {.importc: "size_t", nodecl.} = int ## This is the same as the type ``size_t`` in *C*. - clong* {.importc: "long", nodecl.} = int - ## This is the same as the type ``long`` in *C*. clonglong* {.importc: "long long", nodecl.} = int64 ## This is the same as the type ``long long`` in *C*. cfloat* {.importc: "float", nodecl.} = float32 @@ -1797,7 +1791,7 @@ when defined(JS): elif hostOS != "standalone": {.push stack_trace:off, profiler:off.} - proc add*(x: var string, y: cstring) {.noStackFrame.} = + proc add*(x: var string, y: cstring) = var i = 0 while y[i] != '\0': add(x, y[i]) @@ -2509,7 +2503,7 @@ proc astToStr*[T](x: T): string {.magic: "AstToStr", noSideEffect.} ## converts the AST of `x` into a string representation. This is very useful ## for debugging. -proc InstantiationInfo*(index = -1, fullPaths = false): tuple[ +proc instantiationInfo*(index = -1, fullPaths = false): tuple[ filename: string, line: int] {. magic: "InstantiationInfo", noSideEffect.} ## provides access to the compiler's instantiation stack line information. ## @@ -2540,7 +2534,7 @@ proc InstantiationInfo*(index = -1, fullPaths = false): tuple[ ## testException(EInvalidIndex, tester(1)) ## # --> Test failure at example.nim:20 with 'tester(1)' -template CurrentSourcePath*: string = InstantiationInfo(-1, true).filename +template currentSourcePath*: string = instantiationInfo(-1, true).filename ## returns the full file-system path of the current source proc raiseAssert*(msg: string) {.noinline.} = @@ -2560,7 +2554,7 @@ template assert*(cond: bool, msg = "") = ## raises an ``EAssertionFailure`` exception. However, the compiler may ## not generate any code at all for ``assert`` if it is advised to do so. ## Use ``assert`` for debugging purposes only. - bind InstantiationInfo, hiddenRaiseAssert + bind instantiationInfo, hiddenRaiseAssert when compileOption("assertions"): {.line.}: if not cond: @@ -2569,8 +2563,8 @@ template assert*(cond: bool, msg = "") = template doAssert*(cond: bool, msg = "") = ## same as `assert` but is always turned on and not affected by the ## ``--assertions`` command line switch. - bind InstantiationInfo - {.line: InstantiationInfo().}: + bind instantiationInfo + {.line: instantiationInfo().}: if not cond: raiseAssert(astToStr(cond) & ' ' & msg) diff --git a/lib/system/assign.nim b/lib/system/assign.nim index 19d4ebf57..3b43abcd1 100644 --- a/lib/system/assign.nim +++ b/lib/system/assign.nim @@ -73,6 +73,8 @@ proc genericAssignAux(dest, src: Pointer, mt: PNimType, shallow: bool) = # sequence reallocations: var pint = cast[ptr PNimType](dest) pint[] = cast[ptr PNimType](src)[] + if mt.base != nil: + genericAssignAux(dest, src, mt.base, shallow) genericAssignAux(dest, src, mt.node, shallow) of tyTuple: genericAssignAux(dest, src, mt.node, shallow) diff --git a/lib/system/channels.nim b/lib/system/channels.nim index f5bcdec03..d0294322a 100644 --- a/lib/system/channels.nim +++ b/lib/system/channels.nim @@ -120,7 +120,9 @@ proc storeAux(dest, src: Pointer, mt: PNimType, t: PRawChannel, # copy type field: var pint = cast[ptr PNimType](dest) # XXX use dynamic type here! - pint[] = mt + pint[] = mt + if mt.base != nil: + storeAux(dest, src, mt.base, t, mode) storeAux(dest, src, mt.node, t, mode) of tyTuple: storeAux(dest, src, mt.node, t, mode) diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim index 03200c8e2..7937d9738 100644 --- a/lib/system/excpt.nim +++ b/lib/system/excpt.nim @@ -27,8 +27,6 @@ else: proc writeToStdErr(msg: CString) = discard MessageBoxA(0, msg, nil, 0) -proc registerSignalHandler() - proc chckIndx(i, a, b: int): int {.inline, compilerproc.} proc chckRange(i, a, b: int): int {.inline, compilerproc.} proc chckRangeF(x, a, b: float): float {.inline, compilerproc.} @@ -278,46 +276,46 @@ when defined(endb): var dbgAborting: bool # whether the debugger wants to abort -proc signalHandler(sig: cint) {.exportc: "signalHandler", noconv.} = - template processSignal(s, action: expr) {.immediate.} = - if s == SIGINT: action("SIGINT: Interrupted by Ctrl-C.\n") - elif s == SIGSEGV: - action("SIGSEGV: Illegal storage access. (Attempt to read from nil?)\n") - elif s == SIGABRT: - when defined(endb): - if dbgAborting: return # the debugger wants to abort - action("SIGABRT: Abnormal termination.\n") - elif s == SIGFPE: action("SIGFPE: Arithmetic error.\n") - elif s == SIGILL: action("SIGILL: Illegal operation.\n") - elif s == SIGBUS: - action("SIGBUS: Illegal storage access. (Attempt to read from nil?)\n") - else: action("unknown signal\n") - - # print stack trace and quit - when hasSomeStackTrace: - GC_disable() - var buf = newStringOfCap(2000) - rawWriteStackTrace(buf) - processSignal(sig, buf.add) # nice hu? currying a la nimrod :-) - writeToStdErr(buf) - GC_enable() - else: - var msg: cstring - template asgn(y: expr) = msg = y - processSignal(sig, asgn) - writeToStdErr(msg) - when defined(endb): dbgAborting = True - quit(1) # always quit when SIGABRT - -proc registerSignalHandler() = - c_signal(SIGINT, signalHandler) - c_signal(SIGSEGV, signalHandler) - c_signal(SIGABRT, signalHandler) - c_signal(SIGFPE, signalHandler) - c_signal(SIGILL, signalHandler) - c_signal(SIGBUS, signalHandler) - when not defined(noSignalHandler): + proc signalHandler(sig: cint) {.exportc: "signalHandler", noconv.} = + template processSignal(s, action: expr) {.immediate.} = + if s == SIGINT: action("SIGINT: Interrupted by Ctrl-C.\n") + elif s == SIGSEGV: + action("SIGSEGV: Illegal storage access. (Attempt to read from nil?)\n") + elif s == SIGABRT: + when defined(endb): + if dbgAborting: return # the debugger wants to abort + action("SIGABRT: Abnormal termination.\n") + elif s == SIGFPE: action("SIGFPE: Arithmetic error.\n") + elif s == SIGILL: action("SIGILL: Illegal operation.\n") + elif s == SIGBUS: + action("SIGBUS: Illegal storage access. (Attempt to read from nil?)\n") + else: action("unknown signal\n") + + # print stack trace and quit + when hasSomeStackTrace: + GC_disable() + var buf = newStringOfCap(2000) + rawWriteStackTrace(buf) + processSignal(sig, buf.add) # nice hu? currying a la nimrod :-) + writeToStdErr(buf) + GC_enable() + else: + var msg: cstring + template asgn(y: expr) = msg = y + processSignal(sig, asgn) + writeToStdErr(msg) + when defined(endb): dbgAborting = True + quit(1) # always quit when SIGABRT + + proc registerSignalHandler() = + c_signal(SIGINT, signalHandler) + c_signal(SIGSEGV, signalHandler) + c_signal(SIGABRT, signalHandler) + c_signal(SIGFPE, signalHandler) + c_signal(SIGILL, signalHandler) + c_signal(SIGBUS, signalHandler) + registerSignalHandler() # call it in initialization section proc setControlCHook(hook: proc () {.noconv.}) = diff --git a/lib/system/gc.nim b/lib/system/gc.nim index f5b68b9db..c5d4d2aa2 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -25,6 +25,10 @@ const # reaches this threshold # this seems to be a good value withRealTime = defined(useRealtimeGC) + useMarkForDebug = defined(gcGenerational) + useBackupGc = false # use a simple M&S GC to collect + # cycles instead of the complex + # algorithm when withRealTime and not defined(getTicks): include "system/timers" @@ -42,8 +46,10 @@ const colorMask = 0b011 type TWalkOp = enum + waMarkGlobal, # part of the backup/debug mark&sweep + waMarkPrecise, # part of the backup/debug mark&sweep waZctDecRef, waPush, waCycleDecRef, waMarkGray, waScan, waScanBlack, - waCollectWhite + waCollectWhite, TFinalizer {.compilerproc.} = proc (self: pointer) {.nimcall.} # A ref type can have a finalizer that is called before the object's @@ -71,6 +77,8 @@ type maxPause: TNanos # max allowed pause in nanoseconds; active if > 0 region: TMemRegion # garbage collected region stat: TGcStat + when useMarkForDebug or useBackupGc: + marked: TCellSet var gch {.rtlThreadVar.}: TGcHeap @@ -80,7 +88,7 @@ when not defined(useNimRtl): template acquire(gch: TGcHeap) = when hasThreadSupport and hasSharedHeap: - AcquireSys(HeapLock) + acquireSys(HeapLock) template release(gch: TGcHeap) = when hasThreadSupport and hasSharedHeap: @@ -128,7 +136,7 @@ template setColor(c, col) = else: c.refcount = c.refCount and not colorMask or col -proc writeCell(msg: CString, c: PCell) = +proc writeCell(msg: cstring, c: PCell) = var kind = -1 if c.typ != nil: kind = ord(c.typ.kind) when leakDetector: @@ -159,6 +167,8 @@ else: template `++`(x: expr): stmt = Inc(x, rcIncrement) proc prepareDealloc(cell: PCell) = + when useMarkForDebug: + gcAssert(cell notin gch.marked, "Cell still alive!") if cell.typ.finalizer != nil: # the finalizer could invoke something that # allocates memory; this could trigger a garbage @@ -172,21 +182,21 @@ proc prepareDealloc(cell: PCell) = proc rtlAddCycleRoot(c: PCell) {.rtl, inl.} = # we MUST access gch as a global here, because this crosses DLL boundaries! when hasThreadSupport and hasSharedHeap: - AcquireSys(HeapLock) + acquireSys(HeapLock) when cycleGC: if c.color != rcPurple: c.setColor(rcPurple) incl(gch.cycleRoots, c) when hasThreadSupport and hasSharedHeap: - ReleaseSys(HeapLock) + releaseSys(HeapLock) proc rtlAddZCT(c: PCell) {.rtl, inl.} = # we MUST access gch as a global here, because this crosses DLL boundaries! when hasThreadSupport and hasSharedHeap: - AcquireSys(HeapLock) + acquireSys(HeapLock) addZCT(gch.zct, c) when hasThreadSupport and hasSharedHeap: - ReleaseSys(HeapLock) + releaseSys(HeapLock) proc decRef(c: PCell) {.inline.} = gcAssert(isAllocatedPtr(gch.region, c), "decRef: interiorPtr") @@ -249,7 +259,7 @@ proc unsureAsgnRef(dest: ppointer, src: pointer) {.compilerProc.} = # unsureAsgnRef updates the reference counters only if dest is not on the # stack. It is used by the code generator if it cannot decide wether a # reference is in the stack or not (this can happen for var parameters). - if not IsOnStack(dest): + if not isOnStack(dest): if src != nil: incRef(usrToCell(src)) # XXX finally use assembler for the stack checking instead! # the test for '!= nil' is correct, but I got tired of the segfaults @@ -277,6 +287,27 @@ proc initGC() = init(gch.tempStack) init(gch.cycleRoots) init(gch.decStack) + when useMarkForDebug or useBackupGc: + init(gch.marked) + +when useMarkForDebug or useBackupGc: + type + TGlobalMarkerProc = proc () {.nimcall.} + var + globalMarkersLen: int + globalMarkers: array[0.. 7_000, TGlobalMarkerProc] + + proc nimRegisterGlobalMarker(markerProc: TGlobalMarkerProc) {.compilerProc.} = + if globalMarkersLen <= high(globalMarkers): + globalMarkers[globalMarkersLen] = markerProc + inc globalMarkersLen + else: + echo "[GC] cannot register global variable; too many global variables" + quit 1 + +proc cellsetReset(s: var TCellSet) = + deinit(s) + init(s) proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) = var d = cast[TAddress](dest) @@ -534,7 +565,7 @@ proc collectWhite(s: PCell) = forAllChildren(s, waCollectWhite) freeCyclicCell(gch, s) -proc MarkRoots(gch: var TGcHeap) = +proc markRoots(gch: var TGcHeap) = var tabSize = 0 for s in elements(gch.cycleRoots): #writeCell("markRoot", s) @@ -548,6 +579,38 @@ proc MarkRoots(gch: var TGcHeap) = freeCyclicCell(gch, s) gch.stat.cycleTableSize = max(gch.stat.cycleTableSize, tabSize) +when useBackupGc: + proc sweep(gch: var TGcHeap) = + for x in allObjects(gch.region): + if isCell(x): + # cast to PCell is correct here: + var c = cast[PCell](x) + if c notin gch.marked: freeCyclicCell(gch, c) + +when useMarkForDebug or useBackupGc: + proc markS(gch: var TGcHeap, c: PCell) = + incl(gch.marked, c) + gcAssert gch.tempStack.len == 0, "stack not empty!" + forAllChildren(c, waMarkPrecise) + while gch.tempStack.len > 0: + dec gch.tempStack.len + var d = gch.tempStack.d[gch.tempStack.len] + if not containsOrIncl(gch.marked, d): + forAllChildren(d, waMarkPrecise) + + proc markGlobals(gch: var TGcHeap) = + for i in 0 .. < globalMarkersLen: globalMarkers[i]() + + proc stackMarkS(gch: var TGcHeap, p: pointer) {.inline.} = + # the addresses are not as cells on the stack, so turn them to cells: + var cell = usrToCell(p) + var c = cast[TAddress](cell) + if c >% PageSize: + # fast check: does it look like a cell? + var objStart = cast[PCell](interiorAllocatedPtr(gch.region, cell)) + if objStart != nil: + markS(gch, objStart) + proc doOperation(p: pointer, op: TWalkOp) = if p == nil: return var c: PCell = usrToCell(p) @@ -580,12 +643,26 @@ proc doOperation(p: pointer, op: TWalkOp) = if c.color != rcBlack: scanBlack(c) of waCollectWhite: collectWhite(c) + of waMarkGlobal: + when useMarkForDebug or useBackupGc: + when hasThreadSupport: + # could point to a cell which we don't own and don't want to touch/trace + if isAllocatedPtr(gch.region, c): + markS(gch, c) + else: + markS(gch, c) + of waMarkPrecise: + when useMarkForDebug or useBackupGc: + add(gch.tempStack, c) proc nimGCvisit(d: pointer, op: int) {.compilerRtl.} = doOperation(d, TWalkOp(op)) proc CollectZCT(gch: var TGcHeap): bool +when useMarkForDebug or useBackupGc: + proc markStackAndRegistersForSweep(gch: var TGcHeap) {.noinline, cdecl.} + proc collectRoots(gch: var TGcHeap) = for s in elements(gch.cycleRoots): excl(gch.cycleRoots, s) @@ -594,13 +671,18 @@ proc collectRoots(gch: var TGcHeap) = proc collectCycles(gch: var TGcHeap) = # ensure the ZCT 'color' is not used: while gch.zct.len > 0: discard collectZCT(gch) - markRoots(gch) - # scanRoots: - for s in elements(gch.cycleRoots): scan(s) - collectRoots(gch) + when useBackupGc: + cellsetReset(gch.marked) + markStackAndRegistersForSweep(gch) + markGlobals(gch) + sweep(gch) + else: + markRoots(gch) + # scanRoots: + for s in elements(gch.cycleRoots): scan(s) + collectRoots(gch) - Deinit(gch.cycleRoots) - Init(gch.cycleRoots) + cellsetReset(gch.cycleRoots) # alive cycles need to be kept in 'cycleRoots' if they are referenced # from the stack; otherwise the write barrier will add the cycle root again # anyway: @@ -695,7 +777,7 @@ when defined(sparc): # For SPARC architecture. var x = cast[TAddress](p) result = a <=% x and x <=% b - proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} = + template forEachStackSlot(gch, gcMark: expr) {.immediate, dirty.} = when defined(sparcv9): asm """"flushw \n" """ else: @@ -731,7 +813,7 @@ elif stackIncreases: # a little hack to get the size of a TJmpBuf in the generated C code # in a platform independant way - proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} = + template forEachStackSlot(gch, gcMark: expr) {.immediate, dirty.} = var registers: C_JmpBuf if c_setjmp(registers) == 0'i32: # To fill the C stack with registers. var max = cast[TAddress](gch.stackBottom) @@ -754,7 +836,7 @@ else: var x = cast[TAddress](p) result = a <=% x and x <=% b - proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} = + template forEachStackSlot(gch, gcMark: expr) {.immediate, dirty.} = # We use a jmp_buf buffer that is in the C stack. # Used to traverse the stack and registers assuming # that 'setjmp' will save registers in the C stack. @@ -778,12 +860,19 @@ else: while sp <=% max: gcMark(gch, cast[ppointer](sp)[]) sp = sp +% sizeof(pointer) + +proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} = + forEachStackSlot(gch, gcMark) + +when useMarkForDebug or useBackupGc: + proc markStackAndRegistersForSweep(gch: var TGcHeap) = + forEachStackSlot(gch, stackMarkS) # ---------------------------------------------------------------------------- # end of non-portable code # ---------------------------------------------------------------------------- -proc CollectZCT(gch: var TGcHeap): bool = +proc collectZCT(gch: var TGcHeap): bool = # Note: Freeing may add child objects to the ZCT! So essentially we do # deep freeing, which is bad for incremental operation. In order to # avoid a deep stack, we move objects to keep the ZCT small. @@ -880,10 +969,19 @@ proc collectCTBody(gch: var TGcHeap) = if gch.maxPause > 0 and duration > gch.maxPause: c_fprintf(c_stdout, "[GC] missed deadline: %ld\n", duration) +when useMarkForDebug or useBackupGc: + proc markForDebug(gch: var TGcHeap) = + markStackAndRegistersForSweep(gch) + markGlobals(gch) + proc collectCT(gch: var TGcHeap) = if (gch.zct.len >= ZctThreshold or (cycleGC and getOccupiedMem(gch.region)>=gch.cycleThreshold) or alwaysGC) and gch.recGcLock == 0: + when useMarkForDebug: + prepareForInteriorPointerChecking(gch.region) + cellsetReset(gch.marked) + markForDebug(gch) collectCTBody(gch) when withRealtime: diff --git a/lib/system/mmdisp.nim b/lib/system/mmdisp.nim index 9f37e95c1..c9801abad 100644 --- a/lib/system/mmdisp.nim +++ b/lib/system/mmdisp.nim @@ -313,7 +313,7 @@ else: # XXX use 'compileOption' here include "system/gc_ms" elif defined(gcGenerational): - include "system/gc_genms" + include "system/gc" else: include "system/gc" diff --git a/lib/system/repr.nim b/lib/system/repr.nim index 3c9ce73ac..a51864ac2 100644 --- a/lib/system/repr.nim +++ b/lib/system/repr.nim @@ -117,7 +117,8 @@ proc reprSet(p: pointer, typ: PNimType): string {.compilerRtl.} = type TReprClosure {.final.} = object # we cannot use a global variable here # as this wouldn't be thread-safe - marked: TCellSet + when defined(TCellSet): + marked: TCellSet recdepth: int # do not recurse endlessly indent: int # indentation @@ -127,12 +128,13 @@ when not defined(useNimRtl): # have to do it here ... when hasThreadSupport and hasSharedHeap and defined(heapLock): AcquireSys(HeapLock) - Init(cl.marked) + when defined(TCellSet): + Init(cl.marked) cl.recdepth = -1 # default is to display everything! cl.indent = 0 proc deinitReprClosure(cl: var TReprClosure) = - Deinit(cl.marked) + when defined(TCellSet): Deinit(cl.marked) when hasThreadSupport and hasSharedHeap and defined(heapLock): ReleaseSys(HeapLock) @@ -195,16 +197,17 @@ when not defined(useNimRtl): proc reprRef(result: var string, p: pointer, typ: PNimType, cl: var TReprClosure) = # we know that p is not nil here: - when defined(boehmGC) or defined(nogc): - var cell = cast[PCell](p) - else: - var cell = usrToCell(p) - add result, "ref " & reprPointer(p) - if cell notin cl.marked: - # only the address is shown: - incl(cl.marked, cell) - add result, " --> " - reprAux(result, p, typ.base, cl) + when defined(TCellSet): + when defined(boehmGC) or defined(nogc): + var cell = cast[PCell](p) + else: + var cell = usrToCell(p) + add result, "ref " & reprPointer(p) + if cell notin cl.marked: + # only the address is shown: + incl(cl.marked, cell) + add result, " --> " + reprAux(result, p, typ.base, cl) proc reprAux(result: var string, p: pointer, typ: PNimType, cl: var TReprClosure) = diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim index d448d2b10..40b24cc0a 100644 --- a/lib/windows/winlean.nim +++ b/lib/windows/winlean.nim @@ -390,11 +390,11 @@ type h_length*: int16 h_addr_list*: cstringArray - TWinSocket* = cint + TSocketHandle* = int # Make distinct? Is this the right place for this? TFdSet* {.pure, final.} = object fd_count*: cint # unsigned - fd_array*: array[0..FD_SETSIZE-1, TWinSocket] + fd_array*: array[0..FD_SETSIZE-1, TSocketHandle] TTimeval* {.pure, final.} = object tv_sec*, tv_usec*: int32 @@ -426,45 +426,45 @@ proc gethostbyaddr*(ip: ptr TInAddr, len: cuint, theType: cint): ptr THostEnt {. proc gethostbyname*(name: cstring): ptr THostEnt {. stdcall, importc: "gethostbyname", dynlib: ws2dll.} -proc socket*(af, typ, protocol: cint): TWinSocket {. +proc socket*(af, typ, protocol: cint): TSocketHandle {. stdcall, importc: "socket", dynlib: ws2dll.} -proc closesocket*(s: TWinSocket): cint {. +proc closesocket*(s: TSocketHandle): cint {. stdcall, importc: "closesocket", dynlib: ws2dll.} -proc accept*(s: TWinSocket, a: ptr TSockAddr, addrlen: ptr TSockLen): TWinSocket {. +proc accept*(s: TSocketHandle, a: ptr TSockAddr, addrlen: ptr TSockLen): TSocketHandle {. stdcall, importc: "accept", dynlib: ws2dll.} -proc bindSocket*(s: TWinSocket, name: ptr TSockAddr, namelen: TSockLen): cint {. +proc bindSocket*(s: TSocketHandle, name: ptr TSockAddr, namelen: TSockLen): cint {. stdcall, importc: "bind", dynlib: ws2dll.} -proc connect*(s: TWinSocket, name: ptr TSockAddr, namelen: TSockLen): cint {. +proc connect*(s: TSocketHandle, name: ptr TSockAddr, namelen: TSockLen): cint {. stdcall, importc: "connect", dynlib: ws2dll.} -proc getsockname*(s: TWinSocket, name: ptr TSockAddr, +proc getsockname*(s: TSocketHandle, name: ptr TSockAddr, namelen: ptr TSockLen): cint {. stdcall, importc: "getsockname", dynlib: ws2dll.} -proc getsockopt*(s: TWinSocket, level, optname: cint, optval: pointer, +proc getsockopt*(s: TSocketHandle, level, optname: cint, optval: pointer, optlen: ptr TSockLen): cint {. stdcall, importc: "getsockopt", dynlib: ws2dll.} -proc setsockopt*(s: TWinSocket, level, optname: cint, optval: pointer, +proc setsockopt*(s: TSocketHandle, level, optname: cint, optval: pointer, optlen: TSockLen): cint {. stdcall, importc: "setsockopt", dynlib: ws2dll.} -proc listen*(s: TWinSocket, backlog: cint): cint {. +proc listen*(s: TSocketHandle, backlog: cint): cint {. stdcall, importc: "listen", dynlib: ws2dll.} -proc recv*(s: TWinSocket, buf: pointer, len, flags: cint): cint {. +proc recv*(s: TSocketHandle, buf: pointer, len, flags: cint): cint {. stdcall, importc: "recv", dynlib: ws2dll.} -proc recvfrom*(s: TWinSocket, buf: cstring, len, flags: cint, +proc recvfrom*(s: TSocketHandle, buf: cstring, len, flags: cint, fromm: ptr TSockAddr, fromlen: ptr Tsocklen): cint {. stdcall, importc: "recvfrom", dynlib: ws2dll.} proc select*(nfds: cint, readfds, writefds, exceptfds: ptr TFdSet, timeout: ptr TTimeval): cint {. stdcall, importc: "select", dynlib: ws2dll.} -proc send*(s: TWinSocket, buf: pointer, len, flags: cint): cint {. +proc send*(s: TSocketHandle, buf: pointer, len, flags: cint): cint {. stdcall, importc: "send", dynlib: ws2dll.} -proc sendto*(s: TWinSocket, buf: pointer, len, flags: cint, +proc sendto*(s: TSocketHandle, buf: pointer, len, flags: cint, to: ptr TSockAddr, tolen: Tsocklen): cint {. stdcall, importc: "sendto", dynlib: ws2dll.} -proc shutdown*(s: TWinSocket, how: cint): cint {. +proc shutdown*(s: TSocketHandle, how: cint): cint {. stdcall, importc: "shutdown", dynlib: ws2dll.} proc getnameinfo*(a1: ptr Tsockaddr, a2: Tsocklen, @@ -475,13 +475,13 @@ proc getnameinfo*(a1: ptr Tsockaddr, a2: Tsocklen, proc inet_addr*(cp: cstring): int32 {. stdcall, importc: "inet_addr", dynlib: ws2dll.} -proc WSAFDIsSet(s: TWinSocket, FDSet: var TFDSet): bool {. +proc WSAFDIsSet(s: TSocketHandle, FDSet: var TFDSet): bool {. stdcall, importc: "__WSAFDIsSet", dynlib: ws2dll.} -proc FD_ISSET*(Socket: TWinSocket, FDSet: var TFDSet): cint = +proc FD_ISSET*(Socket: TSocketHandle, FDSet: var TFDSet): cint = result = if WSAFDIsSet(Socket, FDSet): 1'i32 else: 0'i32 -proc FD_SET*(Socket: TWinSocket, FDSet: var TFDSet) = +proc FD_SET*(Socket: TSocketHandle, FDSet: var TFDSet) = if FDSet.fd_count < FD_SETSIZE: FDSet.fd_array[int(FDSet.fd_count)] = Socket inc(FDSet.fd_count) diff --git a/lib/wrappers/opengl/glx.nim b/lib/wrappers/opengl/glx.nim index 76c052d70..ae5ca75b5 100644 --- a/lib/wrappers/opengl/glx.nim +++ b/lib/wrappers/opengl/glx.nim @@ -36,23 +36,23 @@ else: const dllname = "libGL.so" const - GLX_USE_GL* = 1 - GLX_BUFFER_SIZE* = 2 - GLX_LEVEL* = 3 - GLX_RGBA* = 4 - GLX_DOUBLEBUFFER* = 5 - GLX_STEREO* = 6 - GLX_AUX_BUFFERS* = 7 - GLX_RED_SIZE* = 8 - GLX_GREEN_SIZE* = 9 - GLX_BLUE_SIZE* = 10 - GLX_ALPHA_SIZE* = 11 - GLX_DEPTH_SIZE* = 12 - GLX_STENCIL_SIZE* = 13 - GLX_ACCUM_RED_SIZE* = 14 - GLX_ACCUM_GREEN_SIZE* = 15 - GLX_ACCUM_BLUE_SIZE* = 16 - GLX_ACCUM_ALPHA_SIZE* = 17 # GLX_EXT_visual_info extension + GLX_USE_GL* = 1'i32 + GLX_BUFFER_SIZE* = 2'i32 + GLX_LEVEL* = 3'i32 + GLX_RGBA* = 4'i32 + GLX_DOUBLEBUFFER* = 5'i32 + GLX_STEREO* = 6'i32 + GLX_AUX_BUFFERS* = 7'i32 + GLX_RED_SIZE* = 8'i32 + GLX_GREEN_SIZE* = 9'i32 + GLX_BLUE_SIZE* = 10'i32 + GLX_ALPHA_SIZE* = 11'i32 + GLX_DEPTH_SIZE* = 12'i32 + GLX_STENCIL_SIZE* = 13'i32 + GLX_ACCUM_RED_SIZE* = 14'i32 + GLX_ACCUM_GREEN_SIZE* = 15'i32 + GLX_ACCUM_BLUE_SIZE* = 16'i32 + GLX_ACCUM_ALPHA_SIZE* = 17'i32 # GLX_EXT_visual_info extension GLX_X_VISUAL_TYPE_EXT* = 0x00000022 GLX_TRANSPARENT_TYPE_EXT* = 0x00000023 GLX_TRANSPARENT_INDEX_VALUE_EXT* = 0x00000024 diff --git a/lib/wrappers/opengl/opengl.nim b/lib/wrappers/opengl/opengl.nim index 771a2ac96..6549cc6f9 100644 --- a/lib/wrappers/opengl/opengl.nim +++ b/lib/wrappers/opengl/opengl.nim @@ -592,16 +592,24 @@ type # Datatypes corresponding to GL's types TGL(name)( TGLVectorf2* = array[0..1, GLfloat] TGLVectord2* = array[0..1, GLdouble] TGLVectorp2* = array[0..1, Pointer] + TGLVectorb3* = array[0..2, GLbyte] TGLVectorub3* = array[0..2, GLubyte] TGLVectori3* = array[0..2, GLint] + TGLVectorui3* = array[0..2, GLuint] TGLVectorf3* = array[0..2, GLfloat] TGLVectord3* = array[0..2, GLdouble] TGLVectorp3* = array[0..2, Pointer] + TGLVectors3* = array[0..2, GLshort] + TGLVectorus3* = array[0..2, GLushort] + TGLVectorb4* = array[0..3, GLbyte] TGLVectorub4* = array[0..3, GLubyte] TGLVectori4* = array[0..3, GLint] + TGLVectorui4* = array[0..3, GLuint] TGLVectorf4* = array[0..3, GLfloat] TGLVectord4* = array[0..3, GLdouble] TGLVectorp4* = array[0..3, Pointer] + TGLVectors4* = array[0..3, GLshort] + TGLVectorus4* = array[0..3, GLshort] TGLArrayf4* = TGLVectorf4 TGLArrayf3* = TGLVectorf3 TGLArrayd3* = TGLVectord3 @@ -5304,40 +5312,55 @@ proc glClearIndex*(c: GLfloat){.stdcall, importc, ogl.} proc glClipPlane*(plane: GLenum, equation: PGLdouble){.stdcall, importc, ogl.} proc glColor3b*(red: GLbyte, green: GLbyte, blue: GLbyte){.stdcall, importc, ogl.} proc glColor3bv*(v: PGLbyte){.stdcall, importc, ogl.} +proc glColor3bv*(v: TGLVectorb3){.stdcall, importc, ogl.} proc glColor3d*(red: GLdouble, green: GLdouble, blue: GLdouble){.stdcall, importc, ogl.} proc glColor3dv*(v: PGLdouble){.stdcall, importc, ogl.} +proc glColor3dv*(v: TGLVectord3){.stdcall, importc, ogl.} proc glColor3f*(red: GLfloat, green: GLfloat, blue: GLfloat){.stdcall, importc, ogl.} proc glColor3fv*(v: PGLfloat){.stdcall, importc, ogl.} +proc glColor3fv*(v: TGLVectorf3){.stdcall, importc, ogl.} proc glColor3i*(red: GLint, green: GLint, blue: GLint){.stdcall, importc, ogl.} proc glColor3iv*(v: PGLint){.stdcall, importc, ogl.} +proc glColor3iv*(v: TGLVectori3){.stdcall, importc, ogl.} proc glColor3s*(red: GLshort, green: GLshort, blue: GLshort){.stdcall, importc, ogl.} proc glColor3sv*(v: PGLshort){.stdcall, importc, ogl.} +proc glColor3sv*(v: TGLVectors3){.stdcall, importc, ogl.} proc glColor3ub*(red: GLubyte, green: GLubyte, blue: GLubyte){.stdcall, importc, ogl.} proc glColor3ubv*(v: PGLubyte){.stdcall, importc, ogl.} +proc glColor3ubv*(v: TGLVectorub3){.stdcall, importc, ogl.} proc glColor3ui*(red: GLuint, green: GLuint, blue: GLuint){.stdcall, importc, ogl.} proc glColor3uiv*(v: PGLuint){.stdcall, importc, ogl.} +proc glColor3uiv*(v: TGLVectorui3){.stdcall, importc, ogl.} proc glColor3us*(red: GLushort, green: GLushort, blue: GLushort){.stdcall, importc, ogl.} proc glColor3usv*(v: PGLushort){.stdcall, importc, ogl.} +proc glColor3usv*(v: TGLVectorus3){.stdcall, importc, ogl.} proc glColor4b*(red: GLbyte, green: GLbyte, blue: GLbyte, alpha: GLbyte){. stdcall, importc, ogl.} proc glColor4bv*(v: PGLbyte){.stdcall, importc, ogl.} +proc glColor4bv*(v: TGLVectorb4){.stdcall, importc, ogl.} proc glColor4d*(red: GLdouble, green: GLdouble, blue: GLdouble, alpha: GLdouble){. stdcall, importc, ogl.} proc glColor4dv*(v: PGLdouble){.stdcall, importc, ogl.} +proc glColor4dv*(v: TGLVectord4){.stdcall, importc, ogl.} proc glColor4f*(red: GLfloat, green: GLfloat, blue: GLfloat, alpha: GLfloat){. stdcall, importc, ogl.} proc glColor4fv*(v: PGLfloat){.stdcall, importc, ogl.} +proc glColor4fv*(v: TGLVectorf4){.stdcall, importc, ogl.} proc glColor4i*(red: GLint, green: GLint, blue: GLint, alpha: GLint){.stdcall, importc, ogl.} proc glColor4iv*(v: PGLint){.stdcall, importc, ogl.} +proc glColor4iv*(v: TGLVectori4){.stdcall, importc, ogl.} proc glColor4s*(red: GLshort, green: GLshort, blue: GLshort, alpha: GLshort){. stdcall, importc, ogl.} proc glColor4sv*(v: PGLshort){.stdcall, importc, ogl.} +proc glColor4sv*(v: TGLVectors4){.stdcall, importc, ogl.} proc glColor4ub*(red: GLubyte, green: GLubyte, blue: GLubyte, alpha: GLubyte){. stdcall, importc, ogl.} proc glColor4ubv*(v: PGLubyte){.stdcall, importc, ogl.} +proc glColor4ubv*(v: TGLVectorub4){.stdcall, importc, ogl.} proc glColor4ui*(red: GLuint, green: GLuint, blue: GLuint, alpha: GLuint){. stdcall, importc, ogl.} proc glColor4uiv*(v: PGLuint){.stdcall, importc, ogl.} +proc glColor4uiv*(v: TGLVectorui4){.stdcall, importc, ogl.} proc glColor4us*(red: GLushort, green: GLushort, blue: GLushort, alpha: GLushort){. stdcall, importc, ogl.} proc glColor4usv*(v: PGLushort){.stdcall, importc, ogl.} diff --git a/lib/wrappers/x11/keysym.nim b/lib/wrappers/x11/keysym.nim index b1fe13b80..c001ab622 100644 --- a/lib/wrappers/x11/keysym.nim +++ b/lib/wrappers/x11/keysym.nim @@ -11,9 +11,10 @@ # #* default keysyms * +import x const - XK_VoidSymbol* = 0x00FFFFFF # void symbol + XK_VoidSymbol*: TKeySym = 0x00FFFFFF # void symbol when defined(XK_MISCELLANY) or true: const @@ -22,186 +23,186 @@ when defined(XK_MISCELLANY) or true: # * programming, but could have been arbitrary (at the cost of lookup # * tables in client code. # * - XK_BackSpace* = 0x0000FF08 # back space, back char - XK_Tab* = 0x0000FF09 - XK_Linefeed* = 0x0000FF0A # Linefeed, LF - XK_Clear* = 0x0000FF0B - XK_Return* = 0x0000FF0D # Return, enter - XK_Pause* = 0x0000FF13 # Pause, hold - XK_Scroll_Lock* = 0x0000FF14 - XK_Sys_Req* = 0x0000FF15 - XK_Escape* = 0x0000FF1B - XK_Delete* = 0x0000FFFF # Delete, rubout + XK_BackSpace*: TKeySym = 0x0000FF08 # back space, back char + XK_Tab*: TKeySym = 0x0000FF09 + XK_Linefeed*: TKeySym = 0x0000FF0A # Linefeed, LF + XK_Clear*: TKeySym = 0x0000FF0B + XK_Return*: TKeySym = 0x0000FF0D # Return, enter + XK_Pause*: TKeySym = 0x0000FF13 # Pause, hold + XK_Scroll_Lock*: TKeySym = 0x0000FF14 + XK_Sys_Req*: TKeySym = 0x0000FF15 + XK_Escape*: TKeySym = 0x0000FF1B + XK_Delete*: TKeySym = 0x0000FFFF # Delete, rubout \ # International & multi-key character composition - XK_Multi_key* = 0x0000FF20 # Multi-key character compose - XK_Codeinput* = 0x0000FF37 - XK_SingleCandidate* = 0x0000FF3C - XK_MultipleCandidate* = 0x0000FF3D - XK_PreviousCandidate* = 0x0000FF3E # Japanese keyboard support - XK_Kanji* = 0x0000FF21 # Kanji, Kanji convert - XK_Muhenkan* = 0x0000FF22 # Cancel Conversion - XK_Henkan_Mode* = 0x0000FF23 # Start/Stop Conversion - XK_Henkan* = 0x0000FF23 # Alias for Henkan_Mode - XK_Romaji* = 0x0000FF24 # to Romaji - XK_Hiragana* = 0x0000FF25 # to Hiragana - XK_Katakana* = 0x0000FF26 # to Katakana - XK_Hiragana_Katakana* = 0x0000FF27 # Hiragana/Katakana toggle - XK_Zenkaku* = 0x0000FF28 # to Zenkaku - XK_Hankaku* = 0x0000FF29 # to Hankaku - XK_Zenkaku_Hankaku* = 0x0000FF2A # Zenkaku/Hankaku toggle - XK_Touroku* = 0x0000FF2B # Add to Dictionary - XK_Massyo* = 0x0000FF2C # Delete from Dictionary - XK_Kana_Lock* = 0x0000FF2D # Kana Lock - XK_Kana_Shift* = 0x0000FF2E # Kana Shift - XK_Eisu_Shift* = 0x0000FF2F # Alphanumeric Shift - XK_Eisu_toggle* = 0x0000FF30 # Alphanumeric toggle - XK_Kanji_Bangou* = 0x0000FF37 # Codeinput - XK_Zen_Koho* = 0x0000FF3D # Multiple/All Candidate(s) - XK_Mae_Koho* = 0x0000FF3E # Previous Candidate + XK_Multi_key*: TKeySym = 0x0000FF20 # Multi-key character compose + XK_Codeinput*: TKeySym = 0x0000FF37 + XK_SingleCandidate*: TKeySym = 0x0000FF3C + XK_MultipleCandidate*: TKeySym = 0x0000FF3D + XK_PreviousCandidate*: TKeySym = 0x0000FF3E # Japanese keyboard support + XK_Kanji*: TKeySym = 0x0000FF21 # Kanji, Kanji convert + XK_Muhenkan*: TKeySym = 0x0000FF22 # Cancel Conversion + XK_Henkan_Mode*: TKeySym = 0x0000FF23 # Start/Stop Conversion + XK_Henkan*: TKeySym = 0x0000FF23 # Alias for Henkan_Mode + XK_Romaji*: TKeySym = 0x0000FF24 # to Romaji + XK_Hiragana*: TKeySym = 0x0000FF25 # to Hiragana + XK_Katakana*: TKeySym = 0x0000FF26 # to Katakana + XK_Hiragana_Katakana*: TKeySym = 0x0000FF27 # Hiragana/Katakana toggle + XK_Zenkaku*: TKeySym = 0x0000FF28 # to Zenkaku + XK_Hankaku*: TKeySym = 0x0000FF29 # to Hankaku + XK_Zenkaku_Hankaku*: TKeySym = 0x0000FF2A # Zenkaku/Hankaku toggle + XK_Touroku*: TKeySym = 0x0000FF2B # Add to Dictionary + XK_Massyo*: TKeySym = 0x0000FF2C # Delete from Dictionary + XK_Kana_Lock*: TKeySym = 0x0000FF2D # Kana Lock + XK_Kana_Shift*: TKeySym = 0x0000FF2E # Kana Shift + XK_Eisu_Shift*: TKeySym = 0x0000FF2F # Alphanumeric Shift + XK_Eisu_toggle*: TKeySym = 0x0000FF30 # Alphanumeric toggle + XK_Kanji_Bangou*: TKeySym = 0x0000FF37 # Codeinput + XK_Zen_Koho*: TKeySym = 0x0000FF3D # Multiple/All Candidate(s) + XK_Mae_Koho*: TKeySym = 0x0000FF3E # Previous Candidate \ # = $FF31 thru = $FF3F are under XK_KOREAN # Cursor control & motion - XK_Home* = 0x0000FF50 - XK_Left* = 0x0000FF51 # Move left, left arrow - XK_Up* = 0x0000FF52 # Move up, up arrow - XK_Right* = 0x0000FF53 # Move right, right arrow - XK_Down* = 0x0000FF54 # Move down, down arrow - XK_Prior* = 0x0000FF55 # Prior, previous - XK_Page_Up* = 0x0000FF55 - XK_Next* = 0x0000FF56 # Next - XK_Page_Down* = 0x0000FF56 - XK_End* = 0x0000FF57 # EOL - XK_Begin* = 0x0000FF58 # BOL + XK_Home*: TKeySym = 0x0000FF50 + XK_Left*: TKeySym = 0x0000FF51 # Move left, left arrow + XK_Up*: TKeySym = 0x0000FF52 # Move up, up arrow + XK_Right*: TKeySym = 0x0000FF53 # Move right, right arrow + XK_Down*: TKeySym = 0x0000FF54 # Move down, down arrow + XK_Prior*: TKeySym = 0x0000FF55 # Prior, previous + XK_Page_Up*: TKeySym = 0x0000FF55 + XK_Next*: TKeySym = 0x0000FF56 # Next + XK_Page_Down*: TKeySym = 0x0000FF56 + XK_End*: TKeySym = 0x0000FF57 # EOL + XK_Begin*: TKeySym = 0x0000FF58 # BOL \ # Misc Functions - XK_Select* = 0x0000FF60 # Select, mark - XK_Print* = 0x0000FF61 - XK_Execute* = 0x0000FF62 # Execute, run, do - XK_Insert* = 0x0000FF63 # Insert, insert here - XK_Undo* = 0x0000FF65 # Undo, oops - XK_Redo* = 0x0000FF66 # redo, again - XK_Menu* = 0x0000FF67 - XK_Find* = 0x0000FF68 # Find, search - XK_Cancel* = 0x0000FF69 # Cancel, stop, abort, exit - XK_Help* = 0x0000FF6A # Help - XK_Break* = 0x0000FF6B - XK_Mode_switch* = 0x0000FF7E # Character set switch - XK_script_switch* = 0x0000FF7E # Alias for mode_switch - XK_Num_Lock* = 0x0000FF7F # Keypad Functions, keypad numbers cleverly chosen to map to ascii - XK_KP_Space* = 0x0000FF80 # space - XK_KP_Tab* = 0x0000FF89 - XK_KP_Enter* = 0x0000FF8D # enter - XK_KP_F1* = 0x0000FF91 # PF1, KP_A, ... - XK_KP_F2* = 0x0000FF92 - XK_KP_F3* = 0x0000FF93 - XK_KP_F4* = 0x0000FF94 - XK_KP_Home* = 0x0000FF95 - XK_KP_Left* = 0x0000FF96 - XK_KP_Up* = 0x0000FF97 - XK_KP_Right* = 0x0000FF98 - XK_KP_Down* = 0x0000FF99 - XK_KP_Prior* = 0x0000FF9A - XK_KP_Page_Up* = 0x0000FF9A - XK_KP_Next* = 0x0000FF9B - XK_KP_Page_Down* = 0x0000FF9B - XK_KP_End* = 0x0000FF9C - XK_KP_Begin* = 0x0000FF9D - XK_KP_Insert* = 0x0000FF9E - XK_KP_Delete* = 0x0000FF9F - XK_KP_Equal* = 0x0000FFBD # equals - XK_KP_Multiply* = 0x0000FFAA - XK_KP_Add* = 0x0000FFAB - XK_KP_Separator* = 0x0000FFAC # separator, often comma - XK_KP_Subtract* = 0x0000FFAD - XK_KP_Decimal* = 0x0000FFAE - XK_KP_Divide* = 0x0000FFAF - XK_KP_0* = 0x0000FFB0 - XK_KP_1* = 0x0000FFB1 - XK_KP_2* = 0x0000FFB2 - XK_KP_3* = 0x0000FFB3 - XK_KP_4* = 0x0000FFB4 - XK_KP_5* = 0x0000FFB5 - XK_KP_6* = 0x0000FFB6 - XK_KP_7* = 0x0000FFB7 - XK_KP_8* = 0x0000FFB8 - XK_KP_9* = 0x0000FFB9 #* + XK_Select*: TKeySym = 0x0000FF60 # Select, mark + XK_Print*: TKeySym = 0x0000FF61 + XK_Execute*: TKeySym = 0x0000FF62 # Execute, run, do + XK_Insert*: TKeySym = 0x0000FF63 # Insert, insert here + XK_Undo*: TKeySym = 0x0000FF65 # Undo, oops + XK_Redo*: TKeySym = 0x0000FF66 # redo, again + XK_Menu*: TKeySym = 0x0000FF67 + XK_Find*: TKeySym = 0x0000FF68 # Find, search + XK_Cancel*: TKeySym = 0x0000FF69 # Cancel, stop, abort, exit + XK_Help*: TKeySym = 0x0000FF6A # Help + XK_Break*: TKeySym = 0x0000FF6B + XK_Mode_switch*: TKeySym = 0x0000FF7E # Character set switch + XK_script_switch*: TKeySym = 0x0000FF7E # Alias for mode_switch + XK_Num_Lock*: TKeySym = 0x0000FF7F # Keypad Functions, keypad numbers cleverly chosen to map to ascii + XK_KP_Space*: TKeySym = 0x0000FF80 # space + XK_KP_Tab*: TKeySym = 0x0000FF89 + XK_KP_Enter*: TKeySym = 0x0000FF8D # enter + XK_KP_F1*: TKeySym = 0x0000FF91 # PF1, KP_A, ... + XK_KP_F2*: TKeySym = 0x0000FF92 + XK_KP_F3*: TKeySym = 0x0000FF93 + XK_KP_F4*: TKeySym = 0x0000FF94 + XK_KP_Home*: TKeySym = 0x0000FF95 + XK_KP_Left*: TKeySym = 0x0000FF96 + XK_KP_Up*: TKeySym = 0x0000FF97 + XK_KP_Right*: TKeySym = 0x0000FF98 + XK_KP_Down*: TKeySym = 0x0000FF99 + XK_KP_Prior*: TKeySym = 0x0000FF9A + XK_KP_Page_Up*: TKeySym = 0x0000FF9A + XK_KP_Next*: TKeySym = 0x0000FF9B + XK_KP_Page_Down*: TKeySym = 0x0000FF9B + XK_KP_End*: TKeySym = 0x0000FF9C + XK_KP_Begin*: TKeySym = 0x0000FF9D + XK_KP_Insert*: TKeySym = 0x0000FF9E + XK_KP_Delete*: TKeySym = 0x0000FF9F + XK_KP_Equal*: TKeySym = 0x0000FFBD # equals + XK_KP_Multiply*: TKeySym = 0x0000FFAA + XK_KP_Add*: TKeySym = 0x0000FFAB + XK_KP_Separator*: TKeySym = 0x0000FFAC # separator, often comma + XK_KP_Subtract*: TKeySym = 0x0000FFAD + XK_KP_Decimal*: TKeySym = 0x0000FFAE + XK_KP_Divide*: TKeySym = 0x0000FFAF + XK_KP_0*: TKeySym = 0x0000FFB0 + XK_KP_1*: TKeySym = 0x0000FFB1 + XK_KP_2*: TKeySym = 0x0000FFB2 + XK_KP_3*: TKeySym = 0x0000FFB3 + XK_KP_4*: TKeySym = 0x0000FFB4 + XK_KP_5*: TKeySym = 0x0000FFB5 + XK_KP_6*: TKeySym = 0x0000FFB6 + XK_KP_7*: TKeySym = 0x0000FFB7 + XK_KP_8*: TKeySym = 0x0000FFB8 + XK_KP_9*: TKeySym = 0x0000FFB9 #*\ # * Auxilliary Functions; note the duplicate definitions for left and right # * function keys; Sun keyboards and a few other manufactures have such # * function key groups on the left and/or right sides of the keyboard. # * We've not found a keyboard with more than 35 function keys total. # * - XK_F1* = 0x0000FFBE - XK_F2* = 0x0000FFBF - XK_F3* = 0x0000FFC0 - XK_F4* = 0x0000FFC1 - XK_F5* = 0x0000FFC2 - XK_F6* = 0x0000FFC3 - XK_F7* = 0x0000FFC4 - XK_F8* = 0x0000FFC5 - XK_F9* = 0x0000FFC6 - XK_F10* = 0x0000FFC7 - XK_F11* = 0x0000FFC8 - XK_L1* = 0x0000FFC8 - XK_F12* = 0x0000FFC9 - XK_L2* = 0x0000FFC9 - XK_F13* = 0x0000FFCA - XK_L3* = 0x0000FFCA - XK_F14* = 0x0000FFCB - XK_L4* = 0x0000FFCB - XK_F15* = 0x0000FFCC - XK_L5* = 0x0000FFCC - XK_F16* = 0x0000FFCD - XK_L6* = 0x0000FFCD - XK_F17* = 0x0000FFCE - XK_L7* = 0x0000FFCE - XK_F18* = 0x0000FFCF - XK_L8* = 0x0000FFCF - XK_F19* = 0x0000FFD0 - XK_L9* = 0x0000FFD0 - XK_F20* = 0x0000FFD1 - XK_L10* = 0x0000FFD1 - XK_F21* = 0x0000FFD2 - XK_R1* = 0x0000FFD2 - XK_F22* = 0x0000FFD3 - XK_R2* = 0x0000FFD3 - XK_F23* = 0x0000FFD4 - XK_R3* = 0x0000FFD4 - XK_F24* = 0x0000FFD5 - XK_R4* = 0x0000FFD5 - XK_F25* = 0x0000FFD6 - XK_R5* = 0x0000FFD6 - XK_F26* = 0x0000FFD7 - XK_R6* = 0x0000FFD7 - XK_F27* = 0x0000FFD8 - XK_R7* = 0x0000FFD8 - XK_F28* = 0x0000FFD9 - XK_R8* = 0x0000FFD9 - XK_F29* = 0x0000FFDA - XK_R9* = 0x0000FFDA - XK_F30* = 0x0000FFDB - XK_R10* = 0x0000FFDB - XK_F31* = 0x0000FFDC - XK_R11* = 0x0000FFDC - XK_F32* = 0x0000FFDD - XK_R12* = 0x0000FFDD - XK_F33* = 0x0000FFDE - XK_R13* = 0x0000FFDE - XK_F34* = 0x0000FFDF - XK_R14* = 0x0000FFDF - XK_F35* = 0x0000FFE0 - XK_R15* = 0x0000FFE0 # Modifiers - XK_Shift_L* = 0x0000FFE1 # Left shift - XK_Shift_R* = 0x0000FFE2 # Right shift - XK_Control_L* = 0x0000FFE3 # Left control - XK_Control_R* = 0x0000FFE4 # Right control - XK_Caps_Lock* = 0x0000FFE5 # Caps lock - XK_Shift_Lock* = 0x0000FFE6 # Shift lock - XK_Meta_L* = 0x0000FFE7 # Left meta - XK_Meta_R* = 0x0000FFE8 # Right meta - XK_Alt_L* = 0x0000FFE9 # Left alt - XK_Alt_R* = 0x0000FFEA # Right alt - XK_Super_L* = 0x0000FFEB # Left super - XK_Super_R* = 0x0000FFEC # Right super - XK_Hyper_L* = 0x0000FFED # Left hyper - XK_Hyper_R* = 0x0000FFEE # Right hyper + XK_F1*: TKeySym = 0x0000FFBE + XK_F2*: TKeySym = 0x0000FFBF + XK_F3*: TKeySym = 0x0000FFC0 + XK_F4*: TKeySym = 0x0000FFC1 + XK_F5*: TKeySym = 0x0000FFC2 + XK_F6*: TKeySym = 0x0000FFC3 + XK_F7*: TKeySym = 0x0000FFC4 + XK_F8*: TKeySym = 0x0000FFC5 + XK_F9*: TKeySym = 0x0000FFC6 + XK_F10*: TKeySym = 0x0000FFC7 + XK_F11*: TKeySym = 0x0000FFC8 + XK_L1*: TKeySym = 0x0000FFC8 + XK_F12*: TKeySym = 0x0000FFC9 + XK_L2*: TKeySym = 0x0000FFC9 + XK_F13*: TKeySym = 0x0000FFCA + XK_L3*: TKeySym = 0x0000FFCA + XK_F14*: TKeySym = 0x0000FFCB + XK_L4*: TKeySym = 0x0000FFCB + XK_F15*: TKeySym = 0x0000FFCC + XK_L5*: TKeySym = 0x0000FFCC + XK_F16*: TKeySym = 0x0000FFCD + XK_L6*: TKeySym = 0x0000FFCD + XK_F17*: TKeySym = 0x0000FFCE + XK_L7*: TKeySym = 0x0000FFCE + XK_F18*: TKeySym = 0x0000FFCF + XK_L8*: TKeySym = 0x0000FFCF + XK_F19*: TKeySym = 0x0000FFD0 + XK_L9*: TKeySym = 0x0000FFD0 + XK_F20*: TKeySym = 0x0000FFD1 + XK_L10*: TKeySym = 0x0000FFD1 + XK_F21*: TKeySym = 0x0000FFD2 + XK_R1*: TKeySym = 0x0000FFD2 + XK_F22*: TKeySym = 0x0000FFD3 + XK_R2*: TKeySym = 0x0000FFD3 + XK_F23*: TKeySym = 0x0000FFD4 + XK_R3*: TKeySym = 0x0000FFD4 + XK_F24*: TKeySym = 0x0000FFD5 + XK_R4*: TKeySym = 0x0000FFD5 + XK_F25*: TKeySym = 0x0000FFD6 + XK_R5*: TKeySym = 0x0000FFD6 + XK_F26*: TKeySym = 0x0000FFD7 + XK_R6*: TKeySym = 0x0000FFD7 + XK_F27*: TKeySym = 0x0000FFD8 + XK_R7*: TKeySym = 0x0000FFD8 + XK_F28*: TKeySym = 0x0000FFD9 + XK_R8*: TKeySym = 0x0000FFD9 + XK_F29*: TKeySym = 0x0000FFDA + XK_R9*: TKeySym = 0x0000FFDA + XK_F30*: TKeySym = 0x0000FFDB + XK_R10*: TKeySym = 0x0000FFDB + XK_F31*: TKeySym = 0x0000FFDC + XK_R11*: TKeySym = 0x0000FFDC + XK_F32*: TKeySym = 0x0000FFDD + XK_R12*: TKeySym = 0x0000FFDD + XK_F33*: TKeySym = 0x0000FFDE + XK_R13*: TKeySym = 0x0000FFDE + XK_F34*: TKeySym = 0x0000FFDF + XK_R14*: TKeySym = 0x0000FFDF + XK_F35*: TKeySym = 0x0000FFE0 + XK_R15*: TKeySym = 0x0000FFE0 # Modifiers + XK_Shift_L*: TKeySym = 0x0000FFE1 # Left shift + XK_Shift_R*: TKeySym = 0x0000FFE2 # Right shift + XK_Control_L*: TKeySym = 0x0000FFE3 # Left control + XK_Control_R*: TKeySym = 0x0000FFE4 # Right control + XK_Caps_Lock*: TKeySym = 0x0000FFE5 # Caps lock + XK_Shift_Lock*: TKeySym = 0x0000FFE6 # Shift lock + XK_Meta_L*: TKeySym = 0x0000FFE7 # Left meta + XK_Meta_R*: TKeySym = 0x0000FFE8 # Right meta + XK_Alt_L*: TKeySym = 0x0000FFE9 # Left alt + XK_Alt_R*: TKeySym = 0x0000FFEA # Right alt + XK_Super_L*: TKeySym = 0x0000FFEB # Left super + XK_Super_R*: TKeySym = 0x0000FFEC # Right super + XK_Hyper_L*: TKeySym = 0x0000FFED # Left hyper + XK_Hyper_R*: TKeySym = 0x0000FFEE # Right hyper # XK_MISCELLANY #* # * ISO 9995 Function and Modifier Keys @@ -210,108 +211,108 @@ when defined(XK_MISCELLANY) or true: when defined(XK_XKB_KEYS) or true: const - XK_ISO_Lock* = 0x0000FE01 - XK_ISO_Level2_Latch* = 0x0000FE02 - XK_ISO_Level3_Shift* = 0x0000FE03 - XK_ISO_Level3_Latch* = 0x0000FE04 - XK_ISO_Level3_Lock* = 0x0000FE05 - XK_ISO_Group_Shift* = 0x0000FF7E # Alias for mode_switch - XK_ISO_Group_Latch* = 0x0000FE06 - XK_ISO_Group_Lock* = 0x0000FE07 - XK_ISO_Next_Group* = 0x0000FE08 - XK_ISO_Next_Group_Lock* = 0x0000FE09 - XK_ISO_Prev_Group* = 0x0000FE0A - XK_ISO_Prev_Group_Lock* = 0x0000FE0B - XK_ISO_First_Group* = 0x0000FE0C - XK_ISO_First_Group_Lock* = 0x0000FE0D - XK_ISO_Last_Group* = 0x0000FE0E - XK_ISO_Last_Group_Lock* = 0x0000FE0F - XK_ISO_Left_Tab* = 0x0000FE20 - XK_ISO_Move_Line_Up* = 0x0000FE21 - XK_ISO_Move_Line_Down* = 0x0000FE22 - XK_ISO_Partial_Line_Up* = 0x0000FE23 - XK_ISO_Partial_Line_Down* = 0x0000FE24 - XK_ISO_Partial_Space_Left* = 0x0000FE25 - XK_ISO_Partial_Space_Right* = 0x0000FE26 - XK_ISO_Set_Margin_Left* = 0x0000FE27 - XK_ISO_Set_Margin_Right* = 0x0000FE28 - XK_ISO_Release_Margin_Left* = 0x0000FE29 - XK_ISO_Release_Margin_Right* = 0x0000FE2A - XK_ISO_Release_Both_Margins* = 0x0000FE2B - XK_ISO_Fast_Cursor_Left* = 0x0000FE2C - XK_ISO_Fast_Cursor_Right* = 0x0000FE2D - XK_ISO_Fast_Cursor_Up* = 0x0000FE2E - XK_ISO_Fast_Cursor_Down* = 0x0000FE2F - XK_ISO_Continuous_Underline* = 0x0000FE30 - XK_ISO_Discontinuous_Underline* = 0x0000FE31 - XK_ISO_Emphasize* = 0x0000FE32 - XK_ISO_Center_Object* = 0x0000FE33 - XK_ISO_Enter* = 0x0000FE34 - XK_dead_grave* = 0x0000FE50 - XK_dead_acute* = 0x0000FE51 - XK_dead_circumflex* = 0x0000FE52 - XK_dead_tilde* = 0x0000FE53 - XK_dead_macron* = 0x0000FE54 - XK_dead_breve* = 0x0000FE55 - XK_dead_abovedot* = 0x0000FE56 - XK_dead_diaeresis* = 0x0000FE57 - XK_dead_abovering* = 0x0000FE58 - XK_dead_doubleacute* = 0x0000FE59 - XK_dead_caron* = 0x0000FE5A - XK_dead_cedilla* = 0x0000FE5B - XK_dead_ogonek* = 0x0000FE5C - XK_dead_iota* = 0x0000FE5D - XK_dead_voiced_sound* = 0x0000FE5E - XK_dead_semivoiced_sound* = 0x0000FE5F - XK_dead_belowdot* = 0x0000FE60 - XK_dead_hook* = 0x0000FE61 - XK_dead_horn* = 0x0000FE62 - XK_First_Virtual_Screen* = 0x0000FED0 - XK_Prev_Virtual_Screen* = 0x0000FED1 - XK_Next_Virtual_Screen* = 0x0000FED2 - XK_Last_Virtual_Screen* = 0x0000FED4 - XK_Terminate_Server* = 0x0000FED5 - XK_AccessX_Enable* = 0x0000FE70 - XK_AccessX_Feedback_Enable* = 0x0000FE71 - XK_RepeatKeys_Enable* = 0x0000FE72 - XK_SlowKeys_Enable* = 0x0000FE73 - XK_BounceKeys_Enable* = 0x0000FE74 - XK_StickyKeys_Enable* = 0x0000FE75 - XK_MouseKeys_Enable* = 0x0000FE76 - XK_MouseKeys_Accel_Enable* = 0x0000FE77 - XK_Overlay1_Enable* = 0x0000FE78 - XK_Overlay2_Enable* = 0x0000FE79 - XK_AudibleBell_Enable* = 0x0000FE7A - XK_Pointer_Left* = 0x0000FEE0 - XK_Pointer_Right* = 0x0000FEE1 - XK_Pointer_Up* = 0x0000FEE2 - XK_Pointer_Down* = 0x0000FEE3 - XK_Pointer_UpLeft* = 0x0000FEE4 - XK_Pointer_UpRight* = 0x0000FEE5 - XK_Pointer_DownLeft* = 0x0000FEE6 - XK_Pointer_DownRight* = 0x0000FEE7 - XK_Pointer_Button_Dflt* = 0x0000FEE8 - XK_Pointer_Button1* = 0x0000FEE9 - XK_Pointer_Button2* = 0x0000FEEA - XK_Pointer_Button3* = 0x0000FEEB - XK_Pointer_Button4* = 0x0000FEEC - XK_Pointer_Button5* = 0x0000FEED - XK_Pointer_DblClick_Dflt* = 0x0000FEEE - XK_Pointer_DblClick1* = 0x0000FEEF - XK_Pointer_DblClick2* = 0x0000FEF0 - XK_Pointer_DblClick3* = 0x0000FEF1 - XK_Pointer_DblClick4* = 0x0000FEF2 - XK_Pointer_DblClick5* = 0x0000FEF3 - XK_Pointer_Drag_Dflt* = 0x0000FEF4 - XK_Pointer_Drag1* = 0x0000FEF5 - XK_Pointer_Drag2* = 0x0000FEF6 - XK_Pointer_Drag3* = 0x0000FEF7 - XK_Pointer_Drag4* = 0x0000FEF8 - XK_Pointer_Drag5* = 0x0000FEFD - XK_Pointer_EnableKeys* = 0x0000FEF9 - XK_Pointer_Accelerate* = 0x0000FEFA - XK_Pointer_DfltBtnNext* = 0x0000FEFB - XK_Pointer_DfltBtnPrev* = 0x0000FEFC + XK_ISO_Lock*: TKeySym = 0x0000FE01 + XK_ISO_Level2_Latch*: TKeySym = 0x0000FE02 + XK_ISO_Level3_Shift*: TKeySym = 0x0000FE03 + XK_ISO_Level3_Latch*: TKeySym = 0x0000FE04 + XK_ISO_Level3_Lock*: TKeySym = 0x0000FE05 + XK_ISO_Group_Shift*: TKeySym = 0x0000FF7E # Alias for mode_switch + XK_ISO_Group_Latch*: TKeySym = 0x0000FE06 + XK_ISO_Group_Lock*: TKeySym = 0x0000FE07 + XK_ISO_Next_Group*: TKeySym = 0x0000FE08 + XK_ISO_Next_Group_Lock*: TKeySym = 0x0000FE09 + XK_ISO_Prev_Group*: TKeySym = 0x0000FE0A + XK_ISO_Prev_Group_Lock*: TKeySym = 0x0000FE0B + XK_ISO_First_Group*: TKeySym = 0x0000FE0C + XK_ISO_First_Group_Lock*: TKeySym = 0x0000FE0D + XK_ISO_Last_Group*: TKeySym = 0x0000FE0E + XK_ISO_Last_Group_Lock*: TKeySym = 0x0000FE0F + XK_ISO_Left_Tab*: TKeySym = 0x0000FE20 + XK_ISO_Move_Line_Up*: TKeySym = 0x0000FE21 + XK_ISO_Move_Line_Down*: TKeySym = 0x0000FE22 + XK_ISO_Partial_Line_Up*: TKeySym = 0x0000FE23 + XK_ISO_Partial_Line_Down*: TKeySym = 0x0000FE24 + XK_ISO_Partial_Space_Left*: TKeySym = 0x0000FE25 + XK_ISO_Partial_Space_Right*: TKeySym = 0x0000FE26 + XK_ISO_Set_Margin_Left*: TKeySym = 0x0000FE27 + XK_ISO_Set_Margin_Right*: TKeySym = 0x0000FE28 + XK_ISO_Release_Margin_Left*: TKeySym = 0x0000FE29 + XK_ISO_Release_Margin_Right*: TKeySym = 0x0000FE2A + XK_ISO_Release_Both_Margins*: TKeySym = 0x0000FE2B + XK_ISO_Fast_Cursor_Left*: TKeySym = 0x0000FE2C + XK_ISO_Fast_Cursor_Right*: TKeySym = 0x0000FE2D + XK_ISO_Fast_Cursor_Up*: TKeySym = 0x0000FE2E + XK_ISO_Fast_Cursor_Down*: TKeySym = 0x0000FE2F + XK_ISO_Continuous_Underline*: TKeySym = 0x0000FE30 + XK_ISO_Discontinuous_Underline*: TKeySym = 0x0000FE31 + XK_ISO_Emphasize*: TKeySym = 0x0000FE32 + XK_ISO_Center_Object*: TKeySym = 0x0000FE33 + XK_ISO_Enter*: TKeySym = 0x0000FE34 + XK_dead_grave*: TKeySym = 0x0000FE50 + XK_dead_acute*: TKeySym = 0x0000FE51 + XK_dead_circumflex*: TKeySym = 0x0000FE52 + XK_dead_tilde*: TKeySym = 0x0000FE53 + XK_dead_macron*: TKeySym = 0x0000FE54 + XK_dead_breve*: TKeySym = 0x0000FE55 + XK_dead_abovedot*: TKeySym = 0x0000FE56 + XK_dead_diaeresis*: TKeySym = 0x0000FE57 + XK_dead_abovering*: TKeySym = 0x0000FE58 + XK_dead_doubleacute*: TKeySym = 0x0000FE59 + XK_dead_caron*: TKeySym = 0x0000FE5A + XK_dead_cedilla*: TKeySym = 0x0000FE5B + XK_dead_ogonek*: TKeySym = 0x0000FE5C + XK_dead_iota*: TKeySym = 0x0000FE5D + XK_dead_voiced_sound*: TKeySym = 0x0000FE5E + XK_dead_semivoiced_sound*: TKeySym = 0x0000FE5F + XK_dead_belowdot*: TKeySym = 0x0000FE60 + XK_dead_hook*: TKeySym = 0x0000FE61 + XK_dead_horn*: TKeySym = 0x0000FE62 + XK_First_Virtual_Screen*: TKeySym = 0x0000FED0 + XK_Prev_Virtual_Screen*: TKeySym = 0x0000FED1 + XK_Next_Virtual_Screen*: TKeySym = 0x0000FED2 + XK_Last_Virtual_Screen*: TKeySym = 0x0000FED4 + XK_Terminate_Server*: TKeySym = 0x0000FED5 + XK_AccessX_Enable*: TKeySym = 0x0000FE70 + XK_AccessX_Feedback_Enable*: TKeySym = 0x0000FE71 + XK_RepeatKeys_Enable*: TKeySym = 0x0000FE72 + XK_SlowKeys_Enable*: TKeySym = 0x0000FE73 + XK_BounceKeys_Enable*: TKeySym = 0x0000FE74 + XK_StickyKeys_Enable*: TKeySym = 0x0000FE75 + XK_MouseKeys_Enable*: TKeySym = 0x0000FE76 + XK_MouseKeys_Accel_Enable*: TKeySym = 0x0000FE77 + XK_Overlay1_Enable*: TKeySym = 0x0000FE78 + XK_Overlay2_Enable*: TKeySym = 0x0000FE79 + XK_AudibleBell_Enable*: TKeySym = 0x0000FE7A + XK_Pointer_Left*: TKeySym = 0x0000FEE0 + XK_Pointer_Right*: TKeySym = 0x0000FEE1 + XK_Pointer_Up*: TKeySym = 0x0000FEE2 + XK_Pointer_Down*: TKeySym = 0x0000FEE3 + XK_Pointer_UpLeft*: TKeySym = 0x0000FEE4 + XK_Pointer_UpRight*: TKeySym = 0x0000FEE5 + XK_Pointer_DownLeft*: TKeySym = 0x0000FEE6 + XK_Pointer_DownRight*: TKeySym = 0x0000FEE7 + XK_Pointer_Button_Dflt*: TKeySym = 0x0000FEE8 + XK_Pointer_Button1*: TKeySym = 0x0000FEE9 + XK_Pointer_Button2*: TKeySym = 0x0000FEEA + XK_Pointer_Button3*: TKeySym = 0x0000FEEB + XK_Pointer_Button4*: TKeySym = 0x0000FEEC + XK_Pointer_Button5*: TKeySym = 0x0000FEED + XK_Pointer_DblClick_Dflt*: TKeySym = 0x0000FEEE + XK_Pointer_DblClick1*: TKeySym = 0x0000FEEF + XK_Pointer_DblClick2*: TKeySym = 0x0000FEF0 + XK_Pointer_DblClick3*: TKeySym = 0x0000FEF1 + XK_Pointer_DblClick4*: TKeySym = 0x0000FEF2 + XK_Pointer_DblClick5*: TKeySym = 0x0000FEF3 + XK_Pointer_Drag_Dflt*: TKeySym = 0x0000FEF4 + XK_Pointer_Drag1*: TKeySym = 0x0000FEF5 + XK_Pointer_Drag2*: TKeySym = 0x0000FEF6 + XK_Pointer_Drag3*: TKeySym = 0x0000FEF7 + XK_Pointer_Drag4*: TKeySym = 0x0000FEF8 + XK_Pointer_Drag5*: TKeySym = 0x0000FEFD + XK_Pointer_EnableKeys*: TKeySym = 0x0000FEF9 + XK_Pointer_Accelerate*: TKeySym = 0x0000FEFA + XK_Pointer_DfltBtnNext*: TKeySym = 0x0000FEFB + XK_Pointer_DfltBtnPrev*: TKeySym = 0x0000FEFC #* # * 3270 Terminal Keys # * Byte 3 = = $FD @@ -319,36 +320,36 @@ when defined(XK_XKB_KEYS) or true: when defined(XK_3270) or true: const - XK_3270_Duplicate* = 0x0000FD01 - XK_3270_FieldMark* = 0x0000FD02 - XK_3270_Right2* = 0x0000FD03 - XK_3270_Left2* = 0x0000FD04 - XK_3270_BackTab* = 0x0000FD05 - XK_3270_EraseEOF* = 0x0000FD06 - XK_3270_EraseInput* = 0x0000FD07 - XK_3270_Reset* = 0x0000FD08 - XK_3270_Quit* = 0x0000FD09 - XK_3270_PA1* = 0x0000FD0A - XK_3270_PA2* = 0x0000FD0B - XK_3270_PA3* = 0x0000FD0C - XK_3270_Test* = 0x0000FD0D - XK_3270_Attn* = 0x0000FD0E - XK_3270_CursorBlink* = 0x0000FD0F - XK_3270_AltCursor* = 0x0000FD10 - XK_3270_KeyClick* = 0x0000FD11 - XK_3270_Jump* = 0x0000FD12 - XK_3270_Ident* = 0x0000FD13 - XK_3270_Rule* = 0x0000FD14 - XK_3270_Copy* = 0x0000FD15 - XK_3270_Play* = 0x0000FD16 - XK_3270_Setup* = 0x0000FD17 - XK_3270_Record* = 0x0000FD18 - XK_3270_ChangeScreen* = 0x0000FD19 - XK_3270_DeleteWord* = 0x0000FD1A - XK_3270_ExSelect* = 0x0000FD1B - XK_3270_CursorSelect* = 0x0000FD1C - XK_3270_PrintScreen* = 0x0000FD1D - XK_3270_Enter* = 0x0000FD1E + XK_3270_Duplicate*: TKeySym = 0x0000FD01 + XK_3270_FieldMark*: TKeySym = 0x0000FD02 + XK_3270_Right2*: TKeySym = 0x0000FD03 + XK_3270_Left2*: TKeySym = 0x0000FD04 + XK_3270_BackTab*: TKeySym = 0x0000FD05 + XK_3270_EraseEOF*: TKeySym = 0x0000FD06 + XK_3270_EraseInput*: TKeySym = 0x0000FD07 + XK_3270_Reset*: TKeySym = 0x0000FD08 + XK_3270_Quit*: TKeySym = 0x0000FD09 + XK_3270_PA1*: TKeySym = 0x0000FD0A + XK_3270_PA2*: TKeySym = 0x0000FD0B + XK_3270_PA3*: TKeySym = 0x0000FD0C + XK_3270_Test*: TKeySym = 0x0000FD0D + XK_3270_Attn*: TKeySym = 0x0000FD0E + XK_3270_CursorBlink*: TKeySym = 0x0000FD0F + XK_3270_AltCursor*: TKeySym = 0x0000FD10 + XK_3270_KeyClick*: TKeySym = 0x0000FD11 + XK_3270_Jump*: TKeySym = 0x0000FD12 + XK_3270_Ident*: TKeySym = 0x0000FD13 + XK_3270_Rule*: TKeySym = 0x0000FD14 + XK_3270_Copy*: TKeySym = 0x0000FD15 + XK_3270_Play*: TKeySym = 0x0000FD16 + XK_3270_Setup*: TKeySym = 0x0000FD17 + XK_3270_Record*: TKeySym = 0x0000FD18 + XK_3270_ChangeScreen*: TKeySym = 0x0000FD19 + XK_3270_DeleteWord*: TKeySym = 0x0000FD1A + XK_3270_ExSelect*: TKeySym = 0x0000FD1B + XK_3270_CursorSelect*: TKeySym = 0x0000FD1C + XK_3270_PrintScreen*: TKeySym = 0x0000FD1D + XK_3270_Enter*: TKeySym = 0x0000FD1E #* # * Latin 1 # * Byte 3 = 0 @@ -356,201 +357,201 @@ when defined(XK_3270) or true: when defined(XK_LATIN1) or true: const - XK_space* = 0x00000020 - XK_exclam* = 0x00000021 - XK_quotedbl* = 0x00000022 - XK_numbersign* = 0x00000023 - XK_dollar* = 0x00000024 - XK_percent* = 0x00000025 - XK_ampersand* = 0x00000026 - XK_apostrophe* = 0x00000027 - XK_quoteright* = 0x00000027 # deprecated - XK_parenleft* = 0x00000028 - XK_parenright* = 0x00000029 - XK_asterisk* = 0x0000002A - XK_plus* = 0x0000002B - XK_comma* = 0x0000002C - XK_minus* = 0x0000002D - XK_period* = 0x0000002E - XK_slash* = 0x0000002F - XK_0* = 0x00000030 - XK_1* = 0x00000031 - XK_2* = 0x00000032 - XK_3* = 0x00000033 - XK_4* = 0x00000034 - XK_5* = 0x00000035 - XK_6* = 0x00000036 - XK_7* = 0x00000037 - XK_8* = 0x00000038 - XK_9* = 0x00000039 - XK_colon* = 0x0000003A - XK_semicolon* = 0x0000003B - XK_less* = 0x0000003C - XK_equal* = 0x0000003D - XK_greater* = 0x0000003E - XK_question* = 0x0000003F - XK_at* = 0x00000040 - XKc_A* = 0x00000041 - XKc_B* = 0x00000042 - XKc_C* = 0x00000043 - XKc_D* = 0x00000044 - XKc_E* = 0x00000045 - XKc_F* = 0x00000046 - XKc_G* = 0x00000047 - XKc_H* = 0x00000048 - XKc_I* = 0x00000049 - XKc_J* = 0x0000004A - XKc_K* = 0x0000004B - XKc_L* = 0x0000004C - XKc_M* = 0x0000004D - XKc_N* = 0x0000004E - XKc_O* = 0x0000004F - XKc_P* = 0x00000050 - XKc_Q* = 0x00000051 - XKc_R* = 0x00000052 - XKc_S* = 0x00000053 - XKc_T* = 0x00000054 - XKc_U* = 0x00000055 - XKc_V* = 0x00000056 - XKc_W* = 0x00000057 - XKc_X* = 0x00000058 - XKc_Y* = 0x00000059 - XKc_Z* = 0x0000005A - XK_bracketleft* = 0x0000005B - XK_backslash* = 0x0000005C - XK_bracketright* = 0x0000005D - XK_asciicircum* = 0x0000005E - XK_underscore* = 0x0000005F - XK_grave* = 0x00000060 - XK_quoteleft* = 0x00000060 # deprecated - XK_a* = 0x00000061 - XK_b* = 0x00000062 - XK_c* = 0x00000063 - XK_d* = 0x00000064 - XK_e* = 0x00000065 - XK_f* = 0x00000066 - XK_g* = 0x00000067 - XK_h* = 0x00000068 - XK_i* = 0x00000069 - XK_j* = 0x0000006A - XK_k* = 0x0000006B - XK_l* = 0x0000006C - XK_m* = 0x0000006D - XK_n* = 0x0000006E - XK_o* = 0x0000006F - XK_p* = 0x00000070 - XK_q* = 0x00000071 - XK_r* = 0x00000072 - XK_s* = 0x00000073 - XK_t* = 0x00000074 - XK_u* = 0x00000075 - XK_v* = 0x00000076 - XK_w* = 0x00000077 - XK_x* = 0x00000078 - XK_y* = 0x00000079 - XK_z* = 0x0000007A - XK_braceleft* = 0x0000007B - XK_bar* = 0x0000007C - XK_braceright* = 0x0000007D - XK_asciitilde* = 0x0000007E - XK_nobreakspace* = 0x000000A0 - XK_exclamdown* = 0x000000A1 - XK_cent* = 0x000000A2 - XK_sterling* = 0x000000A3 - XK_currency* = 0x000000A4 - XK_yen* = 0x000000A5 - XK_brokenbar* = 0x000000A6 - XK_section* = 0x000000A7 - XK_diaeresis* = 0x000000A8 - XK_copyright* = 0x000000A9 - XK_ordfeminine* = 0x000000AA - XK_guillemotleft* = 0x000000AB # left angle quotation mark - XK_notsign* = 0x000000AC - XK_hyphen* = 0x000000AD - XK_registered* = 0x000000AE - XK_macron* = 0x000000AF - XK_degree* = 0x000000B0 - XK_plusminus* = 0x000000B1 - XK_twosuperior* = 0x000000B2 - XK_threesuperior* = 0x000000B3 - XK_acute* = 0x000000B4 - XK_mu* = 0x000000B5 - XK_paragraph* = 0x000000B6 - XK_periodcentered* = 0x000000B7 - XK_cedilla* = 0x000000B8 - XK_onesuperior* = 0x000000B9 - XK_masculine* = 0x000000BA - XK_guillemotright* = 0x000000BB # right angle quotation mark - XK_onequarter* = 0x000000BC - XK_onehalf* = 0x000000BD - XK_threequarters* = 0x000000BE - XK_questiondown* = 0x000000BF - XKc_Agrave* = 0x000000C0 - XKc_Aacute* = 0x000000C1 - XKc_Acircumflex* = 0x000000C2 - XKc_Atilde* = 0x000000C3 - XKc_Adiaeresis* = 0x000000C4 - XKc_Aring* = 0x000000C5 - XKc_AE* = 0x000000C6 - XKc_Ccedilla* = 0x000000C7 - XKc_Egrave* = 0x000000C8 - XKc_Eacute* = 0x000000C9 - XKc_Ecircumflex* = 0x000000CA - XKc_Ediaeresis* = 0x000000CB - XKc_Igrave* = 0x000000CC - XKc_Iacute* = 0x000000CD - XKc_Icircumflex* = 0x000000CE - XKc_Idiaeresis* = 0x000000CF - XKc_ETH* = 0x000000D0 - XKc_Ntilde* = 0x000000D1 - XKc_Ograve* = 0x000000D2 - XKc_Oacute* = 0x000000D3 - XKc_Ocircumflex* = 0x000000D4 - XKc_Otilde* = 0x000000D5 - XKc_Odiaeresis* = 0x000000D6 - XK_multiply* = 0x000000D7 - XKc_Ooblique* = 0x000000D8 - XKc_Oslash* = XKc_Ooblique - XKc_Ugrave* = 0x000000D9 - XKc_Uacute* = 0x000000DA - XKc_Ucircumflex* = 0x000000DB - XKc_Udiaeresis* = 0x000000DC - XKc_Yacute* = 0x000000DD - XKc_THORN* = 0x000000DE - XK_ssharp* = 0x000000DF - XK_agrave* = 0x000000E0 - XK_aacute* = 0x000000E1 - XK_acircumflex* = 0x000000E2 - XK_atilde* = 0x000000E3 - XK_adiaeresis* = 0x000000E4 - XK_aring* = 0x000000E5 - XK_ae* = 0x000000E6 - XK_ccedilla* = 0x000000E7 - XK_egrave* = 0x000000E8 - XK_eacute* = 0x000000E9 - XK_ecircumflex* = 0x000000EA - XK_ediaeresis* = 0x000000EB - XK_igrave* = 0x000000EC - XK_iacute* = 0x000000ED - XK_icircumflex* = 0x000000EE - XK_idiaeresis* = 0x000000EF - XK_eth* = 0x000000F0 - XK_ntilde* = 0x000000F1 - XK_ograve* = 0x000000F2 - XK_oacute* = 0x000000F3 - XK_ocircumflex* = 0x000000F4 - XK_otilde* = 0x000000F5 - XK_odiaeresis* = 0x000000F6 - XK_division* = 0x000000F7 - XK_oslash* = 0x000000F8 - XK_ooblique* = XK_oslash - XK_ugrave* = 0x000000F9 - XK_uacute* = 0x000000FA - XK_ucircumflex* = 0x000000FB - XK_udiaeresis* = 0x000000FC - XK_yacute* = 0x000000FD - XK_thorn* = 0x000000FE - XK_ydiaeresis* = 0x000000FF + XK_space*: TKeySym = 0x00000020 + XK_exclam*: TKeySym = 0x00000021 + XK_quotedbl*: TKeySym = 0x00000022 + XK_numbersign*: TKeySym = 0x00000023 + XK_dollar*: TKeySym = 0x00000024 + XK_percent*: TKeySym = 0x00000025 + XK_ampersand*: TKeySym = 0x00000026 + XK_apostrophe*: TKeySym = 0x00000027 + XK_quoteright*: TKeySym = 0x00000027 # deprecated + XK_parenleft*: TKeySym = 0x00000028 + XK_parenright*: TKeySym = 0x00000029 + XK_asterisk*: TKeySym = 0x0000002A + XK_plus*: TKeySym = 0x0000002B + XK_comma*: TKeySym = 0x0000002C + XK_minus*: TKeySym = 0x0000002D + XK_period*: TKeySym = 0x0000002E + XK_slash*: TKeySym = 0x0000002F + XK_0*: TKeySym = 0x00000030 + XK_1*: TKeySym = 0x00000031 + XK_2*: TKeySym = 0x00000032 + XK_3*: TKeySym = 0x00000033 + XK_4*: TKeySym = 0x00000034 + XK_5*: TKeySym = 0x00000035 + XK_6*: TKeySym = 0x00000036 + XK_7*: TKeySym = 0x00000037 + XK_8*: TKeySym = 0x00000038 + XK_9*: TKeySym = 0x00000039 + XK_colon*: TKeySym = 0x0000003A + XK_semicolon*: TKeySym = 0x0000003B + XK_less*: TKeySym = 0x0000003C + XK_equal*: TKeySym = 0x0000003D + XK_greater*: TKeySym = 0x0000003E + XK_question*: TKeySym = 0x0000003F + XK_at*: TKeySym = 0x00000040 + XKc_A*: TKeySym = 0x00000041 + XKc_B*: TKeySym = 0x00000042 + XKc_C*: TKeySym = 0x00000043 + XKc_D*: TKeySym = 0x00000044 + XKc_E*: TKeySym = 0x00000045 + XKc_F*: TKeySym = 0x00000046 + XKc_G*: TKeySym = 0x00000047 + XKc_H*: TKeySym = 0x00000048 + XKc_I*: TKeySym = 0x00000049 + XKc_J*: TKeySym = 0x0000004A + XKc_K*: TKeySym = 0x0000004B + XKc_L*: TKeySym = 0x0000004C + XKc_M*: TKeySym = 0x0000004D + XKc_N*: TKeySym = 0x0000004E + XKc_O*: TKeySym = 0x0000004F + XKc_P*: TKeySym = 0x00000050 + XKc_Q*: TKeySym = 0x00000051 + XKc_R*: TKeySym = 0x00000052 + XKc_S*: TKeySym = 0x00000053 + XKc_T*: TKeySym = 0x00000054 + XKc_U*: TKeySym = 0x00000055 + XKc_V*: TKeySym = 0x00000056 + XKc_W*: TKeySym = 0x00000057 + XKc_X*: TKeySym = 0x00000058 + XKc_Y*: TKeySym = 0x00000059 + XKc_Z*: TKeySym = 0x0000005A + XK_bracketleft*: TKeySym = 0x0000005B + XK_backslash*: TKeySym = 0x0000005C + XK_bracketright*: TKeySym = 0x0000005D + XK_asciicircum*: TKeySym = 0x0000005E + XK_underscore*: TKeySym = 0x0000005F + XK_grave*: TKeySym = 0x00000060 + XK_quoteleft*: TKeySym = 0x00000060 # deprecated + XK_a*: TKeySym = 0x00000061 + XK_b*: TKeySym = 0x00000062 + XK_c*: TKeySym = 0x00000063 + XK_d*: TKeySym = 0x00000064 + XK_e*: TKeySym = 0x00000065 + XK_f*: TKeySym = 0x00000066 + XK_g*: TKeySym = 0x00000067 + XK_h*: TKeySym = 0x00000068 + XK_i*: TKeySym = 0x00000069 + XK_j*: TKeySym = 0x0000006A + XK_k*: TKeySym = 0x0000006B + XK_l*: TKeySym = 0x0000006C + XK_m*: TKeySym = 0x0000006D + XK_n*: TKeySym = 0x0000006E + XK_o*: TKeySym = 0x0000006F + XK_p*: TKeySym = 0x00000070 + XK_q*: TKeySym = 0x00000071 + XK_r*: TKeySym = 0x00000072 + XK_s*: TKeySym = 0x00000073 + XK_t*: TKeySym = 0x00000074 + XK_u*: TKeySym = 0x00000075 + XK_v*: TKeySym = 0x00000076 + XK_w*: TKeySym = 0x00000077 + XK_x*: TKeySym = 0x00000078 + XK_y*: TKeySym = 0x00000079 + XK_z*: TKeySym = 0x0000007A + XK_braceleft*: TKeySym = 0x0000007B + XK_bar*: TKeySym = 0x0000007C + XK_braceright*: TKeySym = 0x0000007D + XK_asciitilde*: TKeySym = 0x0000007E + XK_nobreakspace*: TKeySym = 0x000000A0 + XK_exclamdown*: TKeySym = 0x000000A1 + XK_cent*: TKeySym = 0x000000A2 + XK_sterling*: TKeySym = 0x000000A3 + XK_currency*: TKeySym = 0x000000A4 + XK_yen*: TKeySym = 0x000000A5 + XK_brokenbar*: TKeySym = 0x000000A6 + XK_section*: TKeySym = 0x000000A7 + XK_diaeresis*: TKeySym = 0x000000A8 + XK_copyright*: TKeySym = 0x000000A9 + XK_ordfeminine*: TKeySym = 0x000000AA + XK_guillemotleft*: TKeySym = 0x000000AB # left angle quotation mark + XK_notsign*: TKeySym = 0x000000AC + XK_hyphen*: TKeySym = 0x000000AD + XK_registered*: TKeySym = 0x000000AE + XK_macron*: TKeySym = 0x000000AF + XK_degree*: TKeySym = 0x000000B0 + XK_plusminus*: TKeySym = 0x000000B1 + XK_twosuperior*: TKeySym = 0x000000B2 + XK_threesuperior*: TKeySym = 0x000000B3 + XK_acute*: TKeySym = 0x000000B4 + XK_mu*: TKeySym = 0x000000B5 + XK_paragraph*: TKeySym = 0x000000B6 + XK_periodcentered*: TKeySym = 0x000000B7 + XK_cedilla*: TKeySym = 0x000000B8 + XK_onesuperior*: TKeySym = 0x000000B9 + XK_masculine*: TKeySym = 0x000000BA + XK_guillemotright*: TKeySym = 0x000000BB # right angle quotation mark + XK_onequarter*: TKeySym = 0x000000BC + XK_onehalf*: TKeySym = 0x000000BD + XK_threequarters*: TKeySym = 0x000000BE + XK_questiondown*: TKeySym = 0x000000BF + XKc_Agrave*: TKeySym = 0x000000C0 + XKc_Aacute*: TKeySym = 0x000000C1 + XKc_Acircumflex*: TKeySym = 0x000000C2 + XKc_Atilde*: TKeySym = 0x000000C3 + XKc_Adiaeresis*: TKeySym = 0x000000C4 + XKc_Aring*: TKeySym = 0x000000C5 + XKc_AE*: TKeySym = 0x000000C6 + XKc_Ccedilla*: TKeySym = 0x000000C7 + XKc_Egrave*: TKeySym = 0x000000C8 + XKc_Eacute*: TKeySym = 0x000000C9 + XKc_Ecircumflex*: TKeySym = 0x000000CA + XKc_Ediaeresis*: TKeySym = 0x000000CB + XKc_Igrave*: TKeySym = 0x000000CC + XKc_Iacute*: TKeySym = 0x000000CD + XKc_Icircumflex*: TKeySym = 0x000000CE + XKc_Idiaeresis*: TKeySym = 0x000000CF + XKc_ETH*: TKeySym = 0x000000D0 + XKc_Ntilde*: TKeySym = 0x000000D1 + XKc_Ograve*: TKeySym = 0x000000D2 + XKc_Oacute*: TKeySym = 0x000000D3 + XKc_Ocircumflex*: TKeySym = 0x000000D4 + XKc_Otilde*: TKeySym = 0x000000D5 + XKc_Odiaeresis*: TKeySym = 0x000000D6 + XK_multiply*: TKeySym = 0x000000D7 + XKc_Ooblique*: TKeySym = 0x000000D8 + XKc_Oslash*: TKeySym = XKc_Ooblique + XKc_Ugrave*: TKeySym = 0x000000D9 + XKc_Uacute*: TKeySym = 0x000000DA + XKc_Ucircumflex*: TKeySym = 0x000000DB + XKc_Udiaeresis*: TKeySym = 0x000000DC + XKc_Yacute*: TKeySym = 0x000000DD + XKc_THORN*: TKeySym = 0x000000DE + XK_ssharp*: TKeySym = 0x000000DF + XK_agrave*: TKeySym = 0x000000E0 + XK_aacute*: TKeySym = 0x000000E1 + XK_acircumflex*: TKeySym = 0x000000E2 + XK_atilde*: TKeySym = 0x000000E3 + XK_adiaeresis*: TKeySym = 0x000000E4 + XK_aring*: TKeySym = 0x000000E5 + XK_ae*: TKeySym = 0x000000E6 + XK_ccedilla*: TKeySym = 0x000000E7 + XK_egrave*: TKeySym = 0x000000E8 + XK_eacute*: TKeySym = 0x000000E9 + XK_ecircumflex*: TKeySym = 0x000000EA + XK_ediaeresis*: TKeySym = 0x000000EB + XK_igrave*: TKeySym = 0x000000EC + XK_iacute*: TKeySym = 0x000000ED + XK_icircumflex*: TKeySym = 0x000000EE + XK_idiaeresis*: TKeySym = 0x000000EF + XK_eth*: TKeySym = 0x000000F0 + XK_ntilde*: TKeySym = 0x000000F1 + XK_ograve*: TKeySym = 0x000000F2 + XK_oacute*: TKeySym = 0x000000F3 + XK_ocircumflex*: TKeySym = 0x000000F4 + XK_otilde*: TKeySym = 0x000000F5 + XK_odiaeresis*: TKeySym = 0x000000F6 + XK_division*: TKeySym = 0x000000F7 + XK_oslash*: TKeySym = 0x000000F8 + XK_ooblique*: TKeySym = XK_oslash + XK_ugrave*: TKeySym = 0x000000F9 + XK_uacute*: TKeySym = 0x000000FA + XK_ucircumflex*: TKeySym = 0x000000FB + XK_udiaeresis*: TKeySym = 0x000000FC + XK_yacute*: TKeySym = 0x000000FD + XK_thorn*: TKeySym = 0x000000FE + XK_ydiaeresis*: TKeySym = 0x000000FF # XK_LATIN1 #* # * Latin 2 @@ -559,63 +560,63 @@ when defined(XK_LATIN1) or true: when defined(XK_LATIN2) or true: const - XKc_Aogonek* = 0x000001A1 - XK_breve* = 0x000001A2 - XKc_Lstroke* = 0x000001A3 - XKc_Lcaron* = 0x000001A5 - XKc_Sacute* = 0x000001A6 - XKc_Scaron* = 0x000001A9 - XKc_Scedilla* = 0x000001AA - XKc_Tcaron* = 0x000001AB - XKc_Zacute* = 0x000001AC - XKc_Zcaron* = 0x000001AE - XKc_Zabovedot* = 0x000001AF - XK_aogonek* = 0x000001B1 - XK_ogonek* = 0x000001B2 - XK_lstroke* = 0x000001B3 - XK_lcaron* = 0x000001B5 - XK_sacute* = 0x000001B6 - XK_caron* = 0x000001B7 - XK_scaron* = 0x000001B9 - XK_scedilla* = 0x000001BA - XK_tcaron* = 0x000001BB - XK_zacute* = 0x000001BC - XK_doubleacute* = 0x000001BD - XK_zcaron* = 0x000001BE - XK_zabovedot* = 0x000001BF - XKc_Racute* = 0x000001C0 - XKc_Abreve* = 0x000001C3 - XKc_Lacute* = 0x000001C5 - XKc_Cacute* = 0x000001C6 - XKc_Ccaron* = 0x000001C8 - XKc_Eogonek* = 0x000001CA - XKc_Ecaron* = 0x000001CC - XKc_Dcaron* = 0x000001CF - XKc_Dstroke* = 0x000001D0 - XKc_Nacute* = 0x000001D1 - XKc_Ncaron* = 0x000001D2 - XKc_Odoubleacute* = 0x000001D5 - XKc_Rcaron* = 0x000001D8 - XKc_Uring* = 0x000001D9 - XKc_Udoubleacute* = 0x000001DB - XKc_Tcedilla* = 0x000001DE - XK_racute* = 0x000001E0 - XK_abreve* = 0x000001E3 - XK_lacute* = 0x000001E5 - XK_cacute* = 0x000001E6 - XK_ccaron* = 0x000001E8 - XK_eogonek* = 0x000001EA - XK_ecaron* = 0x000001EC - XK_dcaron* = 0x000001EF - XK_dstroke* = 0x000001F0 - XK_nacute* = 0x000001F1 - XK_ncaron* = 0x000001F2 - XK_odoubleacute* = 0x000001F5 - XK_udoubleacute* = 0x000001FB - XK_rcaron* = 0x000001F8 - XK_uring* = 0x000001F9 - XK_tcedilla* = 0x000001FE - XK_abovedot* = 0x000001FF + XKc_Aogonek*: TKeySym = 0x000001A1 + XK_breve*: TKeySym = 0x000001A2 + XKc_Lstroke*: TKeySym = 0x000001A3 + XKc_Lcaron*: TKeySym = 0x000001A5 + XKc_Sacute*: TKeySym = 0x000001A6 + XKc_Scaron*: TKeySym = 0x000001A9 + XKc_Scedilla*: TKeySym = 0x000001AA + XKc_Tcaron*: TKeySym = 0x000001AB + XKc_Zacute*: TKeySym = 0x000001AC + XKc_Zcaron*: TKeySym = 0x000001AE + XKc_Zabovedot*: TKeySym = 0x000001AF + XK_aogonek*: TKeySym = 0x000001B1 + XK_ogonek*: TKeySym = 0x000001B2 + XK_lstroke*: TKeySym = 0x000001B3 + XK_lcaron*: TKeySym = 0x000001B5 + XK_sacute*: TKeySym = 0x000001B6 + XK_caron*: TKeySym = 0x000001B7 + XK_scaron*: TKeySym = 0x000001B9 + XK_scedilla*: TKeySym = 0x000001BA + XK_tcaron*: TKeySym = 0x000001BB + XK_zacute*: TKeySym = 0x000001BC + XK_doubleacute*: TKeySym = 0x000001BD + XK_zcaron*: TKeySym = 0x000001BE + XK_zabovedot*: TKeySym = 0x000001BF + XKc_Racute*: TKeySym = 0x000001C0 + XKc_Abreve*: TKeySym = 0x000001C3 + XKc_Lacute*: TKeySym = 0x000001C5 + XKc_Cacute*: TKeySym = 0x000001C6 + XKc_Ccaron*: TKeySym = 0x000001C8 + XKc_Eogonek*: TKeySym = 0x000001CA + XKc_Ecaron*: TKeySym = 0x000001CC + XKc_Dcaron*: TKeySym = 0x000001CF + XKc_Dstroke*: TKeySym = 0x000001D0 + XKc_Nacute*: TKeySym = 0x000001D1 + XKc_Ncaron*: TKeySym = 0x000001D2 + XKc_Odoubleacute*: TKeySym = 0x000001D5 + XKc_Rcaron*: TKeySym = 0x000001D8 + XKc_Uring*: TKeySym = 0x000001D9 + XKc_Udoubleacute*: TKeySym = 0x000001DB + XKc_Tcedilla*: TKeySym = 0x000001DE + XK_racute*: TKeySym = 0x000001E0 + XK_abreve*: TKeySym = 0x000001E3 + XK_lacute*: TKeySym = 0x000001E5 + XK_cacute*: TKeySym = 0x000001E6 + XK_ccaron*: TKeySym = 0x000001E8 + XK_eogonek*: TKeySym = 0x000001EA + XK_ecaron*: TKeySym = 0x000001EC + XK_dcaron*: TKeySym = 0x000001EF + XK_dstroke*: TKeySym = 0x000001F0 + XK_nacute*: TKeySym = 0x000001F1 + XK_ncaron*: TKeySym = 0x000001F2 + XK_odoubleacute*: TKeySym = 0x000001F5 + XK_udoubleacute*: TKeySym = 0x000001FB + XK_rcaron*: TKeySym = 0x000001F8 + XK_uring*: TKeySym = 0x000001F9 + XK_tcedilla*: TKeySym = 0x000001FE + XK_abovedot*: TKeySym = 0x000001FF # XK_LATIN2 #* # * Latin 3 @@ -624,28 +625,28 @@ when defined(XK_LATIN2) or true: when defined(XK_LATIN3) or true: const - XKc_Hstroke* = 0x000002A1 - XKc_Hcircumflex* = 0x000002A6 - XKc_Iabovedot* = 0x000002A9 - XKc_Gbreve* = 0x000002AB - XKc_Jcircumflex* = 0x000002AC - XK_hstroke* = 0x000002B1 - XK_hcircumflex* = 0x000002B6 - XK_idotless* = 0x000002B9 - XK_gbreve* = 0x000002BB - XK_jcircumflex* = 0x000002BC - XKc_Cabovedot* = 0x000002C5 - XKc_Ccircumflex* = 0x000002C6 - XKc_Gabovedot* = 0x000002D5 - XKc_Gcircumflex* = 0x000002D8 - XKc_Ubreve* = 0x000002DD - XKc_Scircumflex* = 0x000002DE - XK_cabovedot* = 0x000002E5 - XK_ccircumflex* = 0x000002E6 - XK_gabovedot* = 0x000002F5 - XK_gcircumflex* = 0x000002F8 - XK_ubreve* = 0x000002FD - XK_scircumflex* = 0x000002FE + XKc_Hstroke*: TKeySym = 0x000002A1 + XKc_Hcircumflex*: TKeySym = 0x000002A6 + XKc_Iabovedot*: TKeySym = 0x000002A9 + XKc_Gbreve*: TKeySym = 0x000002AB + XKc_Jcircumflex*: TKeySym = 0x000002AC + XK_hstroke*: TKeySym = 0x000002B1 + XK_hcircumflex*: TKeySym = 0x000002B6 + XK_idotless*: TKeySym = 0x000002B9 + XK_gbreve*: TKeySym = 0x000002BB + XK_jcircumflex*: TKeySym = 0x000002BC + XKc_Cabovedot*: TKeySym = 0x000002C5 + XKc_Ccircumflex*: TKeySym = 0x000002C6 + XKc_Gabovedot*: TKeySym = 0x000002D5 + XKc_Gcircumflex*: TKeySym = 0x000002D8 + XKc_Ubreve*: TKeySym = 0x000002DD + XKc_Scircumflex*: TKeySym = 0x000002DE + XK_cabovedot*: TKeySym = 0x000002E5 + XK_ccircumflex*: TKeySym = 0x000002E6 + XK_gabovedot*: TKeySym = 0x000002F5 + XK_gcircumflex*: TKeySym = 0x000002F8 + XK_ubreve*: TKeySym = 0x000002FD + XK_scircumflex*: TKeySym = 0x000002FE # XK_LATIN3 #* # * Latin 4 @@ -654,42 +655,42 @@ when defined(XK_LATIN3) or true: when defined(XK_LATIN4) or true: const - XK_kra* = 0x000003A2 - XK_kappa* = 0x000003A2 # deprecated - XKc_Rcedilla* = 0x000003A3 - XKc_Itilde* = 0x000003A5 - XKc_Lcedilla* = 0x000003A6 - XKc_Emacron* = 0x000003AA - XKc_Gcedilla* = 0x000003AB - XKc_Tslash* = 0x000003AC - XK_rcedilla* = 0x000003B3 - XK_itilde* = 0x000003B5 - XK_lcedilla* = 0x000003B6 - XK_emacron* = 0x000003BA - XK_gcedilla* = 0x000003BB - XK_tslash* = 0x000003BC - XKc_ENG* = 0x000003BD - XK_eng* = 0x000003BF - XKc_Amacron* = 0x000003C0 - XKc_Iogonek* = 0x000003C7 - XKc_Eabovedot* = 0x000003CC - XKc_Imacron* = 0x000003CF - XKc_Ncedilla* = 0x000003D1 - XKc_Omacron* = 0x000003D2 - XKc_Kcedilla* = 0x000003D3 - XKc_Uogonek* = 0x000003D9 - XKc_Utilde* = 0x000003DD - XKc_Umacron* = 0x000003DE - XK_amacron* = 0x000003E0 - XK_iogonek* = 0x000003E7 - XK_eabovedot* = 0x000003EC - XK_imacron* = 0x000003EF - XK_ncedilla* = 0x000003F1 - XK_omacron* = 0x000003F2 - XK_kcedilla* = 0x000003F3 - XK_uogonek* = 0x000003F9 - XK_utilde* = 0x000003FD - XK_umacron* = 0x000003FE + XK_kra*: TKeySym = 0x000003A2 + XK_kappa*: TKeySym = 0x000003A2 # deprecated + XKc_Rcedilla*: TKeySym = 0x000003A3 + XKc_Itilde*: TKeySym = 0x000003A5 + XKc_Lcedilla*: TKeySym = 0x000003A6 + XKc_Emacron*: TKeySym = 0x000003AA + XKc_Gcedilla*: TKeySym = 0x000003AB + XKc_Tslash*: TKeySym = 0x000003AC + XK_rcedilla*: TKeySym = 0x000003B3 + XK_itilde*: TKeySym = 0x000003B5 + XK_lcedilla*: TKeySym = 0x000003B6 + XK_emacron*: TKeySym = 0x000003BA + XK_gcedilla*: TKeySym = 0x000003BB + XK_tslash*: TKeySym = 0x000003BC + XKc_ENG*: TKeySym = 0x000003BD + XK_eng*: TKeySym = 0x000003BF + XKc_Amacron*: TKeySym = 0x000003C0 + XKc_Iogonek*: TKeySym = 0x000003C7 + XKc_Eabovedot*: TKeySym = 0x000003CC + XKc_Imacron*: TKeySym = 0x000003CF + XKc_Ncedilla*: TKeySym = 0x000003D1 + XKc_Omacron*: TKeySym = 0x000003D2 + XKc_Kcedilla*: TKeySym = 0x000003D3 + XKc_Uogonek*: TKeySym = 0x000003D9 + XKc_Utilde*: TKeySym = 0x000003DD + XKc_Umacron*: TKeySym = 0x000003DE + XK_amacron*: TKeySym = 0x000003E0 + XK_iogonek*: TKeySym = 0x000003E7 + XK_eabovedot*: TKeySym = 0x000003EC + XK_imacron*: TKeySym = 0x000003EF + XK_ncedilla*: TKeySym = 0x000003F1 + XK_omacron*: TKeySym = 0x000003F2 + XK_kcedilla*: TKeySym = 0x000003F3 + XK_uogonek*: TKeySym = 0x000003F9 + XK_utilde*: TKeySym = 0x000003FD + XK_umacron*: TKeySym = 0x000003FE # XK_LATIN4 #* # * Latin-8 @@ -698,32 +699,32 @@ when defined(XK_LATIN4) or true: when defined(XK_LATIN8) or true: const - XKc_Babovedot* = 0x000012A1 - XK_babovedot* = 0x000012A2 - XKc_Dabovedot* = 0x000012A6 - XKc_Wgrave* = 0x000012A8 - XKc_Wacute* = 0x000012AA - XK_dabovedot* = 0x000012AB - XKc_Ygrave* = 0x000012AC - XKc_Fabovedot* = 0x000012B0 - XK_fabovedot* = 0x000012B1 - XKc_Mabovedot* = 0x000012B4 - XK_mabovedot* = 0x000012B5 - XKc_Pabovedot* = 0x000012B7 - XK_wgrave* = 0x000012B8 - XK_pabovedot* = 0x000012B9 - XK_wacute* = 0x000012BA - XKc_Sabovedot* = 0x000012BB - XK_ygrave* = 0x000012BC - XKc_Wdiaeresis* = 0x000012BD - XK_wdiaeresis* = 0x000012BE - XK_sabovedot* = 0x000012BF - XKc_Wcircumflex* = 0x000012D0 - XKc_Tabovedot* = 0x000012D7 - XKc_Ycircumflex* = 0x000012DE - XK_wcircumflex* = 0x000012F0 - XK_tabovedot* = 0x000012F7 - XK_ycircumflex* = 0x000012FE + XKc_Babovedot*: TKeySym = 0x000012A1 + XK_babovedot*: TKeySym = 0x000012A2 + XKc_Dabovedot*: TKeySym = 0x000012A6 + XKc_Wgrave*: TKeySym = 0x000012A8 + XKc_Wacute*: TKeySym = 0x000012AA + XK_dabovedot*: TKeySym = 0x000012AB + XKc_Ygrave*: TKeySym = 0x000012AC + XKc_Fabovedot*: TKeySym = 0x000012B0 + XK_fabovedot*: TKeySym = 0x000012B1 + XKc_Mabovedot*: TKeySym = 0x000012B4 + XK_mabovedot*: TKeySym = 0x000012B5 + XKc_Pabovedot*: TKeySym = 0x000012B7 + XK_wgrave*: TKeySym = 0x000012B8 + XK_pabovedot*: TKeySym = 0x000012B9 + XK_wacute*: TKeySym = 0x000012BA + XKc_Sabovedot*: TKeySym = 0x000012BB + XK_ygrave*: TKeySym = 0x000012BC + XKc_Wdiaeresis*: TKeySym = 0x000012BD + XK_wdiaeresis*: TKeySym = 0x000012BE + XK_sabovedot*: TKeySym = 0x000012BF + XKc_Wcircumflex*: TKeySym = 0x000012D0 + XKc_Tabovedot*: TKeySym = 0x000012D7 + XKc_Ycircumflex*: TKeySym = 0x000012DE + XK_wcircumflex*: TKeySym = 0x000012F0 + XK_tabovedot*: TKeySym = 0x000012F7 + XK_ycircumflex*: TKeySym = 0x000012FE # XK_LATIN8 #* # * Latin-9 (a.k.a. Latin-0) @@ -732,9 +733,9 @@ when defined(XK_LATIN8) or true: when defined(XK_LATIN9) or true: const - XKc_OE* = 0x000013BC - XK_oe* = 0x000013BD - XKc_Ydiaeresis* = 0x000013BE + XKc_OE*: TKeySym = 0x000013BC + XK_oe*: TKeySym = 0x000013BD + XKc_Ydiaeresis*: TKeySym = 0x000013BE # XK_LATIN9 #* # * Katakana @@ -743,76 +744,76 @@ when defined(XK_LATIN9) or true: when defined(XK_KATAKANA) or true: const - XK_overline* = 0x0000047E - XK_kana_fullstop* = 0x000004A1 - XK_kana_openingbracket* = 0x000004A2 - XK_kana_closingbracket* = 0x000004A3 - XK_kana_comma* = 0x000004A4 - XK_kana_conjunctive* = 0x000004A5 - XK_kana_middledot* = 0x000004A5 # deprecated - XKc_kana_WO* = 0x000004A6 - XK_kana_a* = 0x000004A7 - XK_kana_i* = 0x000004A8 - XK_kana_u* = 0x000004A9 - XK_kana_e* = 0x000004AA - XK_kana_o* = 0x000004AB - XK_kana_ya* = 0x000004AC - XK_kana_yu* = 0x000004AD - XK_kana_yo* = 0x000004AE - XK_kana_tsu* = 0x000004AF - XK_kana_tu* = 0x000004AF # deprecated - XK_prolongedsound* = 0x000004B0 - XKc_kana_A* = 0x000004B1 - XKc_kana_I* = 0x000004B2 - XKc_kana_U* = 0x000004B3 - XKc_kana_E* = 0x000004B4 - XKc_kana_O* = 0x000004B5 - XKc_kana_KA* = 0x000004B6 - XKc_kana_KI* = 0x000004B7 - XKc_kana_KU* = 0x000004B8 - XKc_kana_KE* = 0x000004B9 - XKc_kana_KO* = 0x000004BA - XKc_kana_SA* = 0x000004BB - XKc_kana_SHI* = 0x000004BC - XKc_kana_SU* = 0x000004BD - XKc_kana_SE* = 0x000004BE - XKc_kana_SO* = 0x000004BF - XKc_kana_TA* = 0x000004C0 - XKc_kana_CHI* = 0x000004C1 - XKc_kana_TI* = 0x000004C1 # deprecated - XKc_kana_TSU* = 0x000004C2 - XKc_kana_TU* = 0x000004C2 # deprecated - XKc_kana_TE* = 0x000004C3 - XKc_kana_TO* = 0x000004C4 - XKc_kana_NA* = 0x000004C5 - XKc_kana_NI* = 0x000004C6 - XKc_kana_NU* = 0x000004C7 - XKc_kana_NE* = 0x000004C8 - XKc_kana_NO* = 0x000004C9 - XKc_kana_HA* = 0x000004CA - XKc_kana_HI* = 0x000004CB - XKc_kana_FU* = 0x000004CC - XKc_kana_HU* = 0x000004CC # deprecated - XKc_kana_HE* = 0x000004CD - XKc_kana_HO* = 0x000004CE - XKc_kana_MA* = 0x000004CF - XKc_kana_MI* = 0x000004D0 - XKc_kana_MU* = 0x000004D1 - XKc_kana_ME* = 0x000004D2 - XKc_kana_MO* = 0x000004D3 - XKc_kana_YA* = 0x000004D4 - XKc_kana_YU* = 0x000004D5 - XKc_kana_YO* = 0x000004D6 - XKc_kana_RA* = 0x000004D7 - XKc_kana_RI* = 0x000004D8 - XKc_kana_RU* = 0x000004D9 - XKc_kana_RE* = 0x000004DA - XKc_kana_RO* = 0x000004DB - XKc_kana_WA* = 0x000004DC - XKc_kana_N* = 0x000004DD - XK_voicedsound* = 0x000004DE - XK_semivoicedsound* = 0x000004DF - XK_kana_switch* = 0x0000FF7E # Alias for mode_switch + XK_overline*: TKeySym = 0x0000047E + XK_kana_fullstop*: TKeySym = 0x000004A1 + XK_kana_openingbracket*: TKeySym = 0x000004A2 + XK_kana_closingbracket*: TKeySym = 0x000004A3 + XK_kana_comma*: TKeySym = 0x000004A4 + XK_kana_conjunctive*: TKeySym = 0x000004A5 + XK_kana_middledot*: TKeySym = 0x000004A5 # deprecated + XKc_kana_WO*: TKeySym = 0x000004A6 + XK_kana_a*: TKeySym = 0x000004A7 + XK_kana_i*: TKeySym = 0x000004A8 + XK_kana_u*: TKeySym = 0x000004A9 + XK_kana_e*: TKeySym = 0x000004AA + XK_kana_o*: TKeySym = 0x000004AB + XK_kana_ya*: TKeySym = 0x000004AC + XK_kana_yu*: TKeySym = 0x000004AD + XK_kana_yo*: TKeySym = 0x000004AE + XK_kana_tsu*: TKeySym = 0x000004AF + XK_kana_tu*: TKeySym = 0x000004AF # deprecated + XK_prolongedsound*: TKeySym = 0x000004B0 + XKc_kana_A*: TKeySym = 0x000004B1 + XKc_kana_I*: TKeySym = 0x000004B2 + XKc_kana_U*: TKeySym = 0x000004B3 + XKc_kana_E*: TKeySym = 0x000004B4 + XKc_kana_O*: TKeySym = 0x000004B5 + XKc_kana_KA*: TKeySym = 0x000004B6 + XKc_kana_KI*: TKeySym = 0x000004B7 + XKc_kana_KU*: TKeySym = 0x000004B8 + XKc_kana_KE*: TKeySym = 0x000004B9 + XKc_kana_KO*: TKeySym = 0x000004BA + XKc_kana_SA*: TKeySym = 0x000004BB + XKc_kana_SHI*: TKeySym = 0x000004BC + XKc_kana_SU*: TKeySym = 0x000004BD + XKc_kana_SE*: TKeySym = 0x000004BE + XKc_kana_SO*: TKeySym = 0x000004BF + XKc_kana_TA*: TKeySym = 0x000004C0 + XKc_kana_CHI*: TKeySym = 0x000004C1 + XKc_kana_TI*: TKeySym = 0x000004C1 # deprecated + XKc_kana_TSU*: TKeySym = 0x000004C2 + XKc_kana_TU*: TKeySym = 0x000004C2 # deprecated + XKc_kana_TE*: TKeySym = 0x000004C3 + XKc_kana_TO*: TKeySym = 0x000004C4 + XKc_kana_NA*: TKeySym = 0x000004C5 + XKc_kana_NI*: TKeySym = 0x000004C6 + XKc_kana_NU*: TKeySym = 0x000004C7 + XKc_kana_NE*: TKeySym = 0x000004C8 + XKc_kana_NO*: TKeySym = 0x000004C9 + XKc_kana_HA*: TKeySym = 0x000004CA + XKc_kana_HI*: TKeySym = 0x000004CB + XKc_kana_FU*: TKeySym = 0x000004CC + XKc_kana_HU*: TKeySym = 0x000004CC # deprecated + XKc_kana_HE*: TKeySym = 0x000004CD + XKc_kana_HO*: TKeySym = 0x000004CE + XKc_kana_MA*: TKeySym = 0x000004CF + XKc_kana_MI*: TKeySym = 0x000004D0 + XKc_kana_MU*: TKeySym = 0x000004D1 + XKc_kana_ME*: TKeySym = 0x000004D2 + XKc_kana_MO*: TKeySym = 0x000004D3 + XKc_kana_YA*: TKeySym = 0x000004D4 + XKc_kana_YU*: TKeySym = 0x000004D5 + XKc_kana_YO*: TKeySym = 0x000004D6 + XKc_kana_RA*: TKeySym = 0x000004D7 + XKc_kana_RI*: TKeySym = 0x000004D8 + XKc_kana_RU*: TKeySym = 0x000004D9 + XKc_kana_RE*: TKeySym = 0x000004DA + XKc_kana_RO*: TKeySym = 0x000004DB + XKc_kana_WA*: TKeySym = 0x000004DC + XKc_kana_N*: TKeySym = 0x000004DD + XK_voicedsound*: TKeySym = 0x000004DE + XK_semivoicedsound*: TKeySym = 0x000004DF + XK_kana_switch*: TKeySym = 0x0000FF7E # Alias for mode_switch # XK_KATAKANA #* # * Arabic @@ -821,97 +822,97 @@ when defined(XK_KATAKANA) or true: when defined(XK_ARABIC) or true: const - XK_Farsi_0* = 0x00000590 - XK_Farsi_1* = 0x00000591 - XK_Farsi_2* = 0x00000592 - XK_Farsi_3* = 0x00000593 - XK_Farsi_4* = 0x00000594 - XK_Farsi_5* = 0x00000595 - XK_Farsi_6* = 0x00000596 - XK_Farsi_7* = 0x00000597 - XK_Farsi_8* = 0x00000598 - XK_Farsi_9* = 0x00000599 - XK_Arabic_percent* = 0x000005A5 - XK_Arabic_superscript_alef* = 0x000005A6 - XK_Arabic_tteh* = 0x000005A7 - XK_Arabic_peh* = 0x000005A8 - XK_Arabic_tcheh* = 0x000005A9 - XK_Arabic_ddal* = 0x000005AA - XK_Arabic_rreh* = 0x000005AB - XK_Arabic_comma* = 0x000005AC - XK_Arabic_fullstop* = 0x000005AE - XK_Arabic_0* = 0x000005B0 - XK_Arabic_1* = 0x000005B1 - XK_Arabic_2* = 0x000005B2 - XK_Arabic_3* = 0x000005B3 - XK_Arabic_4* = 0x000005B4 - XK_Arabic_5* = 0x000005B5 - XK_Arabic_6* = 0x000005B6 - XK_Arabic_7* = 0x000005B7 - XK_Arabic_8* = 0x000005B8 - XK_Arabic_9* = 0x000005B9 - XK_Arabic_semicolon* = 0x000005BB - XK_Arabic_question_mark* = 0x000005BF - XK_Arabic_hamza* = 0x000005C1 - XK_Arabic_maddaonalef* = 0x000005C2 - XK_Arabic_hamzaonalef* = 0x000005C3 - XK_Arabic_hamzaonwaw* = 0x000005C4 - XK_Arabic_hamzaunderalef* = 0x000005C5 - XK_Arabic_hamzaonyeh* = 0x000005C6 - XK_Arabic_alef* = 0x000005C7 - XK_Arabic_beh* = 0x000005C8 - XK_Arabic_tehmarbuta* = 0x000005C9 - XK_Arabic_teh* = 0x000005CA - XK_Arabic_theh* = 0x000005CB - XK_Arabic_jeem* = 0x000005CC - XK_Arabic_hah* = 0x000005CD - XK_Arabic_khah* = 0x000005CE - XK_Arabic_dal* = 0x000005CF - XK_Arabic_thal* = 0x000005D0 - XK_Arabic_ra* = 0x000005D1 - XK_Arabic_zain* = 0x000005D2 - XK_Arabic_seen* = 0x000005D3 - XK_Arabic_sheen* = 0x000005D4 - XK_Arabic_sad* = 0x000005D5 - XK_Arabic_dad* = 0x000005D6 - XK_Arabic_tah* = 0x000005D7 - XK_Arabic_zah* = 0x000005D8 - XK_Arabic_ain* = 0x000005D9 - XK_Arabic_ghain* = 0x000005DA - XK_Arabic_tatweel* = 0x000005E0 - XK_Arabic_feh* = 0x000005E1 - XK_Arabic_qaf* = 0x000005E2 - XK_Arabic_kaf* = 0x000005E3 - XK_Arabic_lam* = 0x000005E4 - XK_Arabic_meem* = 0x000005E5 - XK_Arabic_noon* = 0x000005E6 - XK_Arabic_ha* = 0x000005E7 - XK_Arabic_heh* = 0x000005E7 # deprecated - XK_Arabic_waw* = 0x000005E8 - XK_Arabic_alefmaksura* = 0x000005E9 - XK_Arabic_yeh* = 0x000005EA - XK_Arabic_fathatan* = 0x000005EB - XK_Arabic_dammatan* = 0x000005EC - XK_Arabic_kasratan* = 0x000005ED - XK_Arabic_fatha* = 0x000005EE - XK_Arabic_damma* = 0x000005EF - XK_Arabic_kasra* = 0x000005F0 - XK_Arabic_shadda* = 0x000005F1 - XK_Arabic_sukun* = 0x000005F2 - XK_Arabic_madda_above* = 0x000005F3 - XK_Arabic_hamza_above* = 0x000005F4 - XK_Arabic_hamza_below* = 0x000005F5 - XK_Arabic_jeh* = 0x000005F6 - XK_Arabic_veh* = 0x000005F7 - XK_Arabic_keheh* = 0x000005F8 - XK_Arabic_gaf* = 0x000005F9 - XK_Arabic_noon_ghunna* = 0x000005FA - XK_Arabic_heh_doachashmee* = 0x000005FB - XK_Farsi_yeh* = 0x000005FC - XK_Arabic_farsi_yeh* = XK_Farsi_yeh - XK_Arabic_yeh_baree* = 0x000005FD - XK_Arabic_heh_goal* = 0x000005FE - XK_Arabic_switch* = 0x0000FF7E # Alias for mode_switch + XK_Farsi_0*: TKeySym = 0x00000590 + XK_Farsi_1*: TKeySym = 0x00000591 + XK_Farsi_2*: TKeySym = 0x00000592 + XK_Farsi_3*: TKeySym = 0x00000593 + XK_Farsi_4*: TKeySym = 0x00000594 + XK_Farsi_5*: TKeySym = 0x00000595 + XK_Farsi_6*: TKeySym = 0x00000596 + XK_Farsi_7*: TKeySym = 0x00000597 + XK_Farsi_8*: TKeySym = 0x00000598 + XK_Farsi_9*: TKeySym = 0x00000599 + XK_Arabic_percent*: TKeySym = 0x000005A5 + XK_Arabic_superscript_alef*: TKeySym = 0x000005A6 + XK_Arabic_tteh*: TKeySym = 0x000005A7 + XK_Arabic_peh*: TKeySym = 0x000005A8 + XK_Arabic_tcheh*: TKeySym = 0x000005A9 + XK_Arabic_ddal*: TKeySym = 0x000005AA + XK_Arabic_rreh*: TKeySym = 0x000005AB + XK_Arabic_comma*: TKeySym = 0x000005AC + XK_Arabic_fullstop*: TKeySym = 0x000005AE + XK_Arabic_0*: TKeySym = 0x000005B0 + XK_Arabic_1*: TKeySym = 0x000005B1 + XK_Arabic_2*: TKeySym = 0x000005B2 + XK_Arabic_3*: TKeySym = 0x000005B3 + XK_Arabic_4*: TKeySym = 0x000005B4 + XK_Arabic_5*: TKeySym = 0x000005B5 + XK_Arabic_6*: TKeySym = 0x000005B6 + XK_Arabic_7*: TKeySym = 0x000005B7 + XK_Arabic_8*: TKeySym = 0x000005B8 + XK_Arabic_9*: TKeySym = 0x000005B9 + XK_Arabic_semicolon*: TKeySym = 0x000005BB + XK_Arabic_question_mark*: TKeySym = 0x000005BF + XK_Arabic_hamza*: TKeySym = 0x000005C1 + XK_Arabic_maddaonalef*: TKeySym = 0x000005C2 + XK_Arabic_hamzaonalef*: TKeySym = 0x000005C3 + XK_Arabic_hamzaonwaw*: TKeySym = 0x000005C4 + XK_Arabic_hamzaunderalef*: TKeySym = 0x000005C5 + XK_Arabic_hamzaonyeh*: TKeySym = 0x000005C6 + XK_Arabic_alef*: TKeySym = 0x000005C7 + XK_Arabic_beh*: TKeySym = 0x000005C8 + XK_Arabic_tehmarbuta*: TKeySym = 0x000005C9 + XK_Arabic_teh*: TKeySym = 0x000005CA + XK_Arabic_theh*: TKeySym = 0x000005CB + XK_Arabic_jeem*: TKeySym = 0x000005CC + XK_Arabic_hah*: TKeySym = 0x000005CD + XK_Arabic_khah*: TKeySym = 0x000005CE + XK_Arabic_dal*: TKeySym = 0x000005CF + XK_Arabic_thal*: TKeySym = 0x000005D0 + XK_Arabic_ra*: TKeySym = 0x000005D1 + XK_Arabic_zain*: TKeySym = 0x000005D2 + XK_Arabic_seen*: TKeySym = 0x000005D3 + XK_Arabic_sheen*: TKeySym = 0x000005D4 + XK_Arabic_sad*: TKeySym = 0x000005D5 + XK_Arabic_dad*: TKeySym = 0x000005D6 + XK_Arabic_tah*: TKeySym = 0x000005D7 + XK_Arabic_zah*: TKeySym = 0x000005D8 + XK_Arabic_ain*: TKeySym = 0x000005D9 + XK_Arabic_ghain*: TKeySym = 0x000005DA + XK_Arabic_tatweel*: TKeySym = 0x000005E0 + XK_Arabic_feh*: TKeySym = 0x000005E1 + XK_Arabic_qaf*: TKeySym = 0x000005E2 + XK_Arabic_kaf*: TKeySym = 0x000005E3 + XK_Arabic_lam*: TKeySym = 0x000005E4 + XK_Arabic_meem*: TKeySym = 0x000005E5 + XK_Arabic_noon*: TKeySym = 0x000005E6 + XK_Arabic_ha*: TKeySym = 0x000005E7 + XK_Arabic_heh*: TKeySym = 0x000005E7 # deprecated + XK_Arabic_waw*: TKeySym = 0x000005E8 + XK_Arabic_alefmaksura*: TKeySym = 0x000005E9 + XK_Arabic_yeh*: TKeySym = 0x000005EA + XK_Arabic_fathatan*: TKeySym = 0x000005EB + XK_Arabic_dammatan*: TKeySym = 0x000005EC + XK_Arabic_kasratan*: TKeySym = 0x000005ED + XK_Arabic_fatha*: TKeySym = 0x000005EE + XK_Arabic_damma*: TKeySym = 0x000005EF + XK_Arabic_kasra*: TKeySym = 0x000005F0 + XK_Arabic_shadda*: TKeySym = 0x000005F1 + XK_Arabic_sukun*: TKeySym = 0x000005F2 + XK_Arabic_madda_above*: TKeySym = 0x000005F3 + XK_Arabic_hamza_above*: TKeySym = 0x000005F4 + XK_Arabic_hamza_below*: TKeySym = 0x000005F5 + XK_Arabic_jeh*: TKeySym = 0x000005F6 + XK_Arabic_veh*: TKeySym = 0x000005F7 + XK_Arabic_keheh*: TKeySym = 0x000005F8 + XK_Arabic_gaf*: TKeySym = 0x000005F9 + XK_Arabic_noon_ghunna*: TKeySym = 0x000005FA + XK_Arabic_heh_doachashmee*: TKeySym = 0x000005FB + XK_Farsi_yeh*: TKeySym = 0x000005FC + XK_Arabic_farsi_yeh*: TKeySym = XK_Farsi_yeh + XK_Arabic_yeh_baree*: TKeySym = 0x000005FD + XK_Arabic_heh_goal*: TKeySym = 0x000005FE + XK_Arabic_switch*: TKeySym = 0x0000FF7E # Alias for mode_switch # XK_ARABIC #* # * Cyrillic @@ -920,145 +921,145 @@ when defined(XK_ARABIC) or true: when defined(XK_CYRILLIC) or true: const - XKc_Cyrillic_GHE_bar* = 0x00000680 - XK_Cyrillic_ghe_bar* = 0x00000690 - XKc_Cyrillic_ZHE_descender* = 0x00000681 - XK_Cyrillic_zhe_descender* = 0x00000691 - XKc_Cyrillic_KA_descender* = 0x00000682 - XK_Cyrillic_ka_descender* = 0x00000692 - XKc_Cyrillic_KA_vertstroke* = 0x00000683 - XK_Cyrillic_ka_vertstroke* = 0x00000693 - XKc_Cyrillic_EN_descender* = 0x00000684 - XK_Cyrillic_en_descender* = 0x00000694 - XKc_Cyrillic_U_straight* = 0x00000685 - XK_Cyrillic_u_straight* = 0x00000695 - XKc_Cyrillic_U_straight_bar* = 0x00000686 - XK_Cyrillic_u_straight_bar* = 0x00000696 - XKc_Cyrillic_HA_descender* = 0x00000687 - XK_Cyrillic_ha_descender* = 0x00000697 - XKc_Cyrillic_CHE_descender* = 0x00000688 - XK_Cyrillic_che_descender* = 0x00000698 - XKc_Cyrillic_CHE_vertstroke* = 0x00000689 - XK_Cyrillic_che_vertstroke* = 0x00000699 - XKc_Cyrillic_SHHA* = 0x0000068A - XK_Cyrillic_shha* = 0x0000069A - XKc_Cyrillic_SCHWA* = 0x0000068C - XK_Cyrillic_schwa* = 0x0000069C - XKc_Cyrillic_I_macron* = 0x0000068D - XK_Cyrillic_i_macron* = 0x0000069D - XKc_Cyrillic_O_bar* = 0x0000068E - XK_Cyrillic_o_bar* = 0x0000069E - XKc_Cyrillic_U_macron* = 0x0000068F - XK_Cyrillic_u_macron* = 0x0000069F - XK_Serbian_dje* = 0x000006A1 - XK_Macedonia_gje* = 0x000006A2 - XK_Cyrillic_io* = 0x000006A3 - XK_Ukrainian_ie* = 0x000006A4 - XK_Ukranian_je* = 0x000006A4 # deprecated - XK_Macedonia_dse* = 0x000006A5 - XK_Ukrainian_i* = 0x000006A6 - XK_Ukranian_i* = 0x000006A6 # deprecated - XK_Ukrainian_yi* = 0x000006A7 - XK_Ukranian_yi* = 0x000006A7 # deprecated - XK_Cyrillic_je* = 0x000006A8 - XK_Serbian_je* = 0x000006A8 # deprecated - XK_Cyrillic_lje* = 0x000006A9 - XK_Serbian_lje* = 0x000006A9 # deprecated - XK_Cyrillic_nje* = 0x000006AA - XK_Serbian_nje* = 0x000006AA # deprecated - XK_Serbian_tshe* = 0x000006AB - XK_Macedonia_kje* = 0x000006AC - XK_Ukrainian_ghe_with_upturn* = 0x000006AD - XK_Byelorussian_shortu* = 0x000006AE - XK_Cyrillic_dzhe* = 0x000006AF - XK_Serbian_dze* = 0x000006AF # deprecated - XK_numerosign* = 0x000006B0 - XKc_Serbian_DJE* = 0x000006B1 - XKc_Macedonia_GJE* = 0x000006B2 - XKc_Cyrillic_IO* = 0x000006B3 - XKc_Ukrainian_IE* = 0x000006B4 - XKc_Ukranian_JE* = 0x000006B4 # deprecated - XKc_Macedonia_DSE* = 0x000006B5 - XKc_Ukrainian_I* = 0x000006B6 - XKc_Ukranian_I* = 0x000006B6 # deprecated - XKc_Ukrainian_YI* = 0x000006B7 - XKc_Ukranian_YI* = 0x000006B7 # deprecated - XKc_Cyrillic_JE* = 0x000006B8 - XKc_Serbian_JE* = 0x000006B8 # deprecated - XKc_Cyrillic_LJE* = 0x000006B9 - XKc_Serbian_LJE* = 0x000006B9 # deprecated - XKc_Cyrillic_NJE* = 0x000006BA - XKc_Serbian_NJE* = 0x000006BA # deprecated - XKc_Serbian_TSHE* = 0x000006BB - XKc_Macedonia_KJE* = 0x000006BC - XKc_Ukrainian_GHE_WITH_UPTURN* = 0x000006BD - XKc_Byelorussian_SHORTU* = 0x000006BE - XKc_Cyrillic_DZHE* = 0x000006BF - XKc_Serbian_DZE* = 0x000006BF # deprecated - XK_Cyrillic_yu* = 0x000006C0 - XK_Cyrillic_a* = 0x000006C1 - XK_Cyrillic_be* = 0x000006C2 - XK_Cyrillic_tse* = 0x000006C3 - XK_Cyrillic_de* = 0x000006C4 - XK_Cyrillic_ie* = 0x000006C5 - XK_Cyrillic_ef* = 0x000006C6 - XK_Cyrillic_ghe* = 0x000006C7 - XK_Cyrillic_ha* = 0x000006C8 - XK_Cyrillic_i* = 0x000006C9 - XK_Cyrillic_shorti* = 0x000006CA - XK_Cyrillic_ka* = 0x000006CB - XK_Cyrillic_el* = 0x000006CC - XK_Cyrillic_em* = 0x000006CD - XK_Cyrillic_en* = 0x000006CE - XK_Cyrillic_o* = 0x000006CF - XK_Cyrillic_pe* = 0x000006D0 - XK_Cyrillic_ya* = 0x000006D1 - XK_Cyrillic_er* = 0x000006D2 - XK_Cyrillic_es* = 0x000006D3 - XK_Cyrillic_te* = 0x000006D4 - XK_Cyrillic_u* = 0x000006D5 - XK_Cyrillic_zhe* = 0x000006D6 - XK_Cyrillic_ve* = 0x000006D7 - XK_Cyrillic_softsign* = 0x000006D8 - XK_Cyrillic_yeru* = 0x000006D9 - XK_Cyrillic_ze* = 0x000006DA - XK_Cyrillic_sha* = 0x000006DB - XK_Cyrillic_e* = 0x000006DC - XK_Cyrillic_shcha* = 0x000006DD - XK_Cyrillic_che* = 0x000006DE - XK_Cyrillic_hardsign* = 0x000006DF - XKc_Cyrillic_YU* = 0x000006E0 - XKc_Cyrillic_A* = 0x000006E1 - XKc_Cyrillic_BE* = 0x000006E2 - XKc_Cyrillic_TSE* = 0x000006E3 - XKc_Cyrillic_DE* = 0x000006E4 - XKc_Cyrillic_IE* = 0x000006E5 - XKc_Cyrillic_EF* = 0x000006E6 - XKc_Cyrillic_GHE* = 0x000006E7 - XKc_Cyrillic_HA* = 0x000006E8 - XKc_Cyrillic_I* = 0x000006E9 - XKc_Cyrillic_SHORTI* = 0x000006EA - XKc_Cyrillic_KA* = 0x000006EB - XKc_Cyrillic_EL* = 0x000006EC - XKc_Cyrillic_EM* = 0x000006ED - XKc_Cyrillic_EN* = 0x000006EE - XKc_Cyrillic_O* = 0x000006EF - XKc_Cyrillic_PE* = 0x000006F0 - XKc_Cyrillic_YA* = 0x000006F1 - XKc_Cyrillic_ER* = 0x000006F2 - XKc_Cyrillic_ES* = 0x000006F3 - XKc_Cyrillic_TE* = 0x000006F4 - XKc_Cyrillic_U* = 0x000006F5 - XKc_Cyrillic_ZHE* = 0x000006F6 - XKc_Cyrillic_VE* = 0x000006F7 - XKc_Cyrillic_SOFTSIGN* = 0x000006F8 - XKc_Cyrillic_YERU* = 0x000006F9 - XKc_Cyrillic_ZE* = 0x000006FA - XKc_Cyrillic_SHA* = 0x000006FB - XKc_Cyrillic_E* = 0x000006FC - XKc_Cyrillic_SHCHA* = 0x000006FD - XKc_Cyrillic_CHE* = 0x000006FE - XKc_Cyrillic_HARDSIGN* = 0x000006FF + XKc_Cyrillic_GHE_bar*: TKeySym = 0x00000680 + XK_Cyrillic_ghe_bar*: TKeySym = 0x00000690 + XKc_Cyrillic_ZHE_descender*: TKeySym = 0x00000681 + XK_Cyrillic_zhe_descender*: TKeySym = 0x00000691 + XKc_Cyrillic_KA_descender*: TKeySym = 0x00000682 + XK_Cyrillic_ka_descender*: TKeySym = 0x00000692 + XKc_Cyrillic_KA_vertstroke*: TKeySym = 0x00000683 + XK_Cyrillic_ka_vertstroke*: TKeySym = 0x00000693 + XKc_Cyrillic_EN_descender*: TKeySym = 0x00000684 + XK_Cyrillic_en_descender*: TKeySym = 0x00000694 + XKc_Cyrillic_U_straight*: TKeySym = 0x00000685 + XK_Cyrillic_u_straight*: TKeySym = 0x00000695 + XKc_Cyrillic_U_straight_bar*: TKeySym = 0x00000686 + XK_Cyrillic_u_straight_bar*: TKeySym = 0x00000696 + XKc_Cyrillic_HA_descender*: TKeySym = 0x00000687 + XK_Cyrillic_ha_descender*: TKeySym = 0x00000697 + XKc_Cyrillic_CHE_descender*: TKeySym = 0x00000688 + XK_Cyrillic_che_descender*: TKeySym = 0x00000698 + XKc_Cyrillic_CHE_vertstroke*: TKeySym = 0x00000689 + XK_Cyrillic_che_vertstroke*: TKeySym = 0x00000699 + XKc_Cyrillic_SHHA*: TKeySym = 0x0000068A + XK_Cyrillic_shha*: TKeySym = 0x0000069A + XKc_Cyrillic_SCHWA*: TKeySym = 0x0000068C + XK_Cyrillic_schwa*: TKeySym = 0x0000069C + XKc_Cyrillic_I_macron*: TKeySym = 0x0000068D + XK_Cyrillic_i_macron*: TKeySym = 0x0000069D + XKc_Cyrillic_O_bar*: TKeySym = 0x0000068E + XK_Cyrillic_o_bar*: TKeySym = 0x0000069E + XKc_Cyrillic_U_macron*: TKeySym = 0x0000068F + XK_Cyrillic_u_macron*: TKeySym = 0x0000069F + XK_Serbian_dje*: TKeySym = 0x000006A1 + XK_Macedonia_gje*: TKeySym = 0x000006A2 + XK_Cyrillic_io*: TKeySym = 0x000006A3 + XK_Ukrainian_ie*: TKeySym = 0x000006A4 + XK_Ukranian_je*: TKeySym = 0x000006A4 # deprecated + XK_Macedonia_dse*: TKeySym = 0x000006A5 + XK_Ukrainian_i*: TKeySym = 0x000006A6 + XK_Ukranian_i*: TKeySym = 0x000006A6 # deprecated + XK_Ukrainian_yi*: TKeySym = 0x000006A7 + XK_Ukranian_yi*: TKeySym = 0x000006A7 # deprecated + XK_Cyrillic_je*: TKeySym = 0x000006A8 + XK_Serbian_je*: TKeySym = 0x000006A8 # deprecated + XK_Cyrillic_lje*: TKeySym = 0x000006A9 + XK_Serbian_lje*: TKeySym = 0x000006A9 # deprecated + XK_Cyrillic_nje*: TKeySym = 0x000006AA + XK_Serbian_nje*: TKeySym = 0x000006AA # deprecated + XK_Serbian_tshe*: TKeySym = 0x000006AB + XK_Macedonia_kje*: TKeySym = 0x000006AC + XK_Ukrainian_ghe_with_upturn*: TKeySym = 0x000006AD + XK_Byelorussian_shortu*: TKeySym = 0x000006AE + XK_Cyrillic_dzhe*: TKeySym = 0x000006AF + XK_Serbian_dze*: TKeySym = 0x000006AF # deprecated + XK_numerosign*: TKeySym = 0x000006B0 + XKc_Serbian_DJE*: TKeySym = 0x000006B1 + XKc_Macedonia_GJE*: TKeySym = 0x000006B2 + XKc_Cyrillic_IO*: TKeySym = 0x000006B3 + XKc_Ukrainian_IE*: TKeySym = 0x000006B4 + XKc_Ukranian_JE*: TKeySym = 0x000006B4 # deprecated + XKc_Macedonia_DSE*: TKeySym = 0x000006B5 + XKc_Ukrainian_I*: TKeySym = 0x000006B6 + XKc_Ukranian_I*: TKeySym = 0x000006B6 # deprecated + XKc_Ukrainian_YI*: TKeySym = 0x000006B7 + XKc_Ukranian_YI*: TKeySym = 0x000006B7 # deprecated + XKc_Cyrillic_JE*: TKeySym = 0x000006B8 + XKc_Serbian_JE*: TKeySym = 0x000006B8 # deprecated + XKc_Cyrillic_LJE*: TKeySym = 0x000006B9 + XKc_Serbian_LJE*: TKeySym = 0x000006B9 # deprecated + XKc_Cyrillic_NJE*: TKeySym = 0x000006BA + XKc_Serbian_NJE*: TKeySym = 0x000006BA # deprecated + XKc_Serbian_TSHE*: TKeySym = 0x000006BB + XKc_Macedonia_KJE*: TKeySym = 0x000006BC + XKc_Ukrainian_GHE_WITH_UPTURN*: TKeySym = 0x000006BD + XKc_Byelorussian_SHORTU*: TKeySym = 0x000006BE + XKc_Cyrillic_DZHE*: TKeySym = 0x000006BF + XKc_Serbian_DZE*: TKeySym = 0x000006BF # deprecated + XK_Cyrillic_yu*: TKeySym = 0x000006C0 + XK_Cyrillic_a*: TKeySym = 0x000006C1 + XK_Cyrillic_be*: TKeySym = 0x000006C2 + XK_Cyrillic_tse*: TKeySym = 0x000006C3 + XK_Cyrillic_de*: TKeySym = 0x000006C4 + XK_Cyrillic_ie*: TKeySym = 0x000006C5 + XK_Cyrillic_ef*: TKeySym = 0x000006C6 + XK_Cyrillic_ghe*: TKeySym = 0x000006C7 + XK_Cyrillic_ha*: TKeySym = 0x000006C8 + XK_Cyrillic_i*: TKeySym = 0x000006C9 + XK_Cyrillic_shorti*: TKeySym = 0x000006CA + XK_Cyrillic_ka*: TKeySym = 0x000006CB + XK_Cyrillic_el*: TKeySym = 0x000006CC + XK_Cyrillic_em*: TKeySym = 0x000006CD + XK_Cyrillic_en*: TKeySym = 0x000006CE + XK_Cyrillic_o*: TKeySym = 0x000006CF + XK_Cyrillic_pe*: TKeySym = 0x000006D0 + XK_Cyrillic_ya*: TKeySym = 0x000006D1 + XK_Cyrillic_er*: TKeySym = 0x000006D2 + XK_Cyrillic_es*: TKeySym = 0x000006D3 + XK_Cyrillic_te*: TKeySym = 0x000006D4 + XK_Cyrillic_u*: TKeySym = 0x000006D5 + XK_Cyrillic_zhe*: TKeySym = 0x000006D6 + XK_Cyrillic_ve*: TKeySym = 0x000006D7 + XK_Cyrillic_softsign*: TKeySym = 0x000006D8 + XK_Cyrillic_yeru*: TKeySym = 0x000006D9 + XK_Cyrillic_ze*: TKeySym = 0x000006DA + XK_Cyrillic_sha*: TKeySym = 0x000006DB + XK_Cyrillic_e*: TKeySym = 0x000006DC + XK_Cyrillic_shcha*: TKeySym = 0x000006DD + XK_Cyrillic_che*: TKeySym = 0x000006DE + XK_Cyrillic_hardsign*: TKeySym = 0x000006DF + XKc_Cyrillic_YU*: TKeySym = 0x000006E0 + XKc_Cyrillic_A*: TKeySym = 0x000006E1 + XKc_Cyrillic_BE*: TKeySym = 0x000006E2 + XKc_Cyrillic_TSE*: TKeySym = 0x000006E3 + XKc_Cyrillic_DE*: TKeySym = 0x000006E4 + XKc_Cyrillic_IE*: TKeySym = 0x000006E5 + XKc_Cyrillic_EF*: TKeySym = 0x000006E6 + XKc_Cyrillic_GHE*: TKeySym = 0x000006E7 + XKc_Cyrillic_HA*: TKeySym = 0x000006E8 + XKc_Cyrillic_I*: TKeySym = 0x000006E9 + XKc_Cyrillic_SHORTI*: TKeySym = 0x000006EA + XKc_Cyrillic_KA*: TKeySym = 0x000006EB + XKc_Cyrillic_EL*: TKeySym = 0x000006EC + XKc_Cyrillic_EM*: TKeySym = 0x000006ED + XKc_Cyrillic_EN*: TKeySym = 0x000006EE + XKc_Cyrillic_O*: TKeySym = 0x000006EF + XKc_Cyrillic_PE*: TKeySym = 0x000006F0 + XKc_Cyrillic_YA*: TKeySym = 0x000006F1 + XKc_Cyrillic_ER*: TKeySym = 0x000006F2 + XKc_Cyrillic_ES*: TKeySym = 0x000006F3 + XKc_Cyrillic_TE*: TKeySym = 0x000006F4 + XKc_Cyrillic_U*: TKeySym = 0x000006F5 + XKc_Cyrillic_ZHE*: TKeySym = 0x000006F6 + XKc_Cyrillic_VE*: TKeySym = 0x000006F7 + XKc_Cyrillic_SOFTSIGN*: TKeySym = 0x000006F8 + XKc_Cyrillic_YERU*: TKeySym = 0x000006F9 + XKc_Cyrillic_ZE*: TKeySym = 0x000006FA + XKc_Cyrillic_SHA*: TKeySym = 0x000006FB + XKc_Cyrillic_E*: TKeySym = 0x000006FC + XKc_Cyrillic_SHCHA*: TKeySym = 0x000006FD + XKc_Cyrillic_CHE*: TKeySym = 0x000006FE + XKc_Cyrillic_HARDSIGN*: TKeySym = 0x000006FF # XK_CYRILLIC #* # * Greek @@ -1067,81 +1068,81 @@ when defined(XK_CYRILLIC) or true: when defined(XK_GREEK) or true: const - XKc_Greek_ALPHAaccent* = 0x000007A1 - XKc_Greek_EPSILONaccent* = 0x000007A2 - XKc_Greek_ETAaccent* = 0x000007A3 - XKc_Greek_IOTAaccent* = 0x000007A4 - XKc_Greek_IOTAdieresis* = 0x000007A5 - XKc_Greek_IOTAdiaeresis* = XKc_Greek_IOTAdieresis # old typo - XKc_Greek_OMICRONaccent* = 0x000007A7 - XKc_Greek_UPSILONaccent* = 0x000007A8 - XKc_Greek_UPSILONdieresis* = 0x000007A9 - XKc_Greek_OMEGAaccent* = 0x000007AB - XK_Greek_accentdieresis* = 0x000007AE - XK_Greek_horizbar* = 0x000007AF - XK_Greek_alphaaccent* = 0x000007B1 - XK_Greek_epsilonaccent* = 0x000007B2 - XK_Greek_etaaccent* = 0x000007B3 - XK_Greek_iotaaccent* = 0x000007B4 - XK_Greek_iotadieresis* = 0x000007B5 - XK_Greek_iotaaccentdieresis* = 0x000007B6 - XK_Greek_omicronaccent* = 0x000007B7 - XK_Greek_upsilonaccent* = 0x000007B8 - XK_Greek_upsilondieresis* = 0x000007B9 - XK_Greek_upsilonaccentdieresis* = 0x000007BA - XK_Greek_omegaaccent* = 0x000007BB - XKc_Greek_ALPHA* = 0x000007C1 - XKc_Greek_BETA* = 0x000007C2 - XKc_Greek_GAMMA* = 0x000007C3 - XKc_Greek_DELTA* = 0x000007C4 - XKc_Greek_EPSILON* = 0x000007C5 - XKc_Greek_ZETA* = 0x000007C6 - XKc_Greek_ETA* = 0x000007C7 - XKc_Greek_THETA* = 0x000007C8 - XKc_Greek_IOTA* = 0x000007C9 - XKc_Greek_KAPPA* = 0x000007CA - XKc_Greek_LAMDA* = 0x000007CB - XKc_Greek_LAMBDA* = 0x000007CB - XKc_Greek_MU* = 0x000007CC - XKc_Greek_NU* = 0x000007CD - XKc_Greek_XI* = 0x000007CE - XKc_Greek_OMICRON* = 0x000007CF - XKc_Greek_PI* = 0x000007D0 - XKc_Greek_RHO* = 0x000007D1 - XKc_Greek_SIGMA* = 0x000007D2 - XKc_Greek_TAU* = 0x000007D4 - XKc_Greek_UPSILON* = 0x000007D5 - XKc_Greek_PHI* = 0x000007D6 - XKc_Greek_CHI* = 0x000007D7 - XKc_Greek_PSI* = 0x000007D8 - XKc_Greek_OMEGA* = 0x000007D9 - XK_Greek_alpha* = 0x000007E1 - XK_Greek_beta* = 0x000007E2 - XK_Greek_gamma* = 0x000007E3 - XK_Greek_delta* = 0x000007E4 - XK_Greek_epsilon* = 0x000007E5 - XK_Greek_zeta* = 0x000007E6 - XK_Greek_eta* = 0x000007E7 - XK_Greek_theta* = 0x000007E8 - XK_Greek_iota* = 0x000007E9 - XK_Greek_kappa* = 0x000007EA - XK_Greek_lamda* = 0x000007EB - XK_Greek_lambda* = 0x000007EB - XK_Greek_mu* = 0x000007EC - XK_Greek_nu* = 0x000007ED - XK_Greek_xi* = 0x000007EE - XK_Greek_omicron* = 0x000007EF - XK_Greek_pi* = 0x000007F0 - XK_Greek_rho* = 0x000007F1 - XK_Greek_sigma* = 0x000007F2 - XK_Greek_finalsmallsigma* = 0x000007F3 - XK_Greek_tau* = 0x000007F4 - XK_Greek_upsilon* = 0x000007F5 - XK_Greek_phi* = 0x000007F6 - XK_Greek_chi* = 0x000007F7 - XK_Greek_psi* = 0x000007F8 - XK_Greek_omega* = 0x000007F9 - XK_Greek_switch* = 0x0000FF7E # Alias for mode_switch + XKc_Greek_ALPHAaccent*: TKeySym = 0x000007A1 + XKc_Greek_EPSILONaccent*: TKeySym = 0x000007A2 + XKc_Greek_ETAaccent*: TKeySym = 0x000007A3 + XKc_Greek_IOTAaccent*: TKeySym = 0x000007A4 + XKc_Greek_IOTAdieresis*: TKeySym = 0x000007A5 + XKc_Greek_IOTAdiaeresis*: TKeySym = XKc_Greek_IOTAdieresis # old typo + XKc_Greek_OMICRONaccent*: TKeySym = 0x000007A7 + XKc_Greek_UPSILONaccent*: TKeySym = 0x000007A8 + XKc_Greek_UPSILONdieresis*: TKeySym = 0x000007A9 + XKc_Greek_OMEGAaccent*: TKeySym = 0x000007AB + XK_Greek_accentdieresis*: TKeySym = 0x000007AE + XK_Greek_horizbar*: TKeySym = 0x000007AF + XK_Greek_alphaaccent*: TKeySym = 0x000007B1 + XK_Greek_epsilonaccent*: TKeySym = 0x000007B2 + XK_Greek_etaaccent*: TKeySym = 0x000007B3 + XK_Greek_iotaaccent*: TKeySym = 0x000007B4 + XK_Greek_iotadieresis*: TKeySym = 0x000007B5 + XK_Greek_iotaaccentdieresis*: TKeySym = 0x000007B6 + XK_Greek_omicronaccent*: TKeySym = 0x000007B7 + XK_Greek_upsilonaccent*: TKeySym = 0x000007B8 + XK_Greek_upsilondieresis*: TKeySym = 0x000007B9 + XK_Greek_upsilonaccentdieresis*: TKeySym = 0x000007BA + XK_Greek_omegaaccent*: TKeySym = 0x000007BB + XKc_Greek_ALPHA*: TKeySym = 0x000007C1 + XKc_Greek_BETA*: TKeySym = 0x000007C2 + XKc_Greek_GAMMA*: TKeySym = 0x000007C3 + XKc_Greek_DELTA*: TKeySym = 0x000007C4 + XKc_Greek_EPSILON*: TKeySym = 0x000007C5 + XKc_Greek_ZETA*: TKeySym = 0x000007C6 + XKc_Greek_ETA*: TKeySym = 0x000007C7 + XKc_Greek_THETA*: TKeySym = 0x000007C8 + XKc_Greek_IOTA*: TKeySym = 0x000007C9 + XKc_Greek_KAPPA*: TKeySym = 0x000007CA + XKc_Greek_LAMDA*: TKeySym = 0x000007CB + XKc_Greek_LAMBDA*: TKeySym = 0x000007CB + XKc_Greek_MU*: TKeySym = 0x000007CC + XKc_Greek_NU*: TKeySym = 0x000007CD + XKc_Greek_XI*: TKeySym = 0x000007CE + XKc_Greek_OMICRON*: TKeySym = 0x000007CF + XKc_Greek_PI*: TKeySym = 0x000007D0 + XKc_Greek_RHO*: TKeySym = 0x000007D1 + XKc_Greek_SIGMA*: TKeySym = 0x000007D2 + XKc_Greek_TAU*: TKeySym = 0x000007D4 + XKc_Greek_UPSILON*: TKeySym = 0x000007D5 + XKc_Greek_PHI*: TKeySym = 0x000007D6 + XKc_Greek_CHI*: TKeySym = 0x000007D7 + XKc_Greek_PSI*: TKeySym = 0x000007D8 + XKc_Greek_OMEGA*: TKeySym = 0x000007D9 + XK_Greek_alpha*: TKeySym = 0x000007E1 + XK_Greek_beta*: TKeySym = 0x000007E2 + XK_Greek_gamma*: TKeySym = 0x000007E3 + XK_Greek_delta*: TKeySym = 0x000007E4 + XK_Greek_epsilon*: TKeySym = 0x000007E5 + XK_Greek_zeta*: TKeySym = 0x000007E6 + XK_Greek_eta*: TKeySym = 0x000007E7 + XK_Greek_theta*: TKeySym = 0x000007E8 + XK_Greek_iota*: TKeySym = 0x000007E9 + XK_Greek_kappa*: TKeySym = 0x000007EA + XK_Greek_lamda*: TKeySym = 0x000007EB + XK_Greek_lambda*: TKeySym = 0x000007EB + XK_Greek_mu*: TKeySym = 0x000007EC + XK_Greek_nu*: TKeySym = 0x000007ED + XK_Greek_xi*: TKeySym = 0x000007EE + XK_Greek_omicron*: TKeySym = 0x000007EF + XK_Greek_pi*: TKeySym = 0x000007F0 + XK_Greek_rho*: TKeySym = 0x000007F1 + XK_Greek_sigma*: TKeySym = 0x000007F2 + XK_Greek_finalsmallsigma*: TKeySym = 0x000007F3 + XK_Greek_tau*: TKeySym = 0x000007F4 + XK_Greek_upsilon*: TKeySym = 0x000007F5 + XK_Greek_phi*: TKeySym = 0x000007F6 + XK_Greek_chi*: TKeySym = 0x000007F7 + XK_Greek_psi*: TKeySym = 0x000007F8 + XK_Greek_omega*: TKeySym = 0x000007F9 + XK_Greek_switch*: TKeySym = 0x0000FF7E # Alias for mode_switch # XK_GREEK #* # * Technical @@ -1150,55 +1151,55 @@ when defined(XK_GREEK) or true: when defined(XK_TECHNICAL) or true: const - XK_leftradical* = 0x000008A1 - XK_topleftradical* = 0x000008A2 - XK_horizconnector* = 0x000008A3 - XK_topintegral* = 0x000008A4 - XK_botintegral* = 0x000008A5 - XK_vertconnector* = 0x000008A6 - XK_topleftsqbracket* = 0x000008A7 - XK_botleftsqbracket* = 0x000008A8 - XK_toprightsqbracket* = 0x000008A9 - XK_botrightsqbracket* = 0x000008AA - XK_topleftparens* = 0x000008AB - XK_botleftparens* = 0x000008AC - XK_toprightparens* = 0x000008AD - XK_botrightparens* = 0x000008AE - XK_leftmiddlecurlybrace* = 0x000008AF - XK_rightmiddlecurlybrace* = 0x000008B0 - XK_topleftsummation* = 0x000008B1 - XK_botleftsummation* = 0x000008B2 - XK_topvertsummationconnector* = 0x000008B3 - XK_botvertsummationconnector* = 0x000008B4 - XK_toprightsummation* = 0x000008B5 - XK_botrightsummation* = 0x000008B6 - XK_rightmiddlesummation* = 0x000008B7 - XK_lessthanequal* = 0x000008BC - XK_notequal* = 0x000008BD - XK_greaterthanequal* = 0x000008BE - XK_integral* = 0x000008BF - XK_therefore* = 0x000008C0 - XK_variation* = 0x000008C1 - XK_infinity* = 0x000008C2 - XK_nabla* = 0x000008C5 - XK_approximate* = 0x000008C8 - XK_similarequal* = 0x000008C9 - XK_ifonlyif* = 0x000008CD - XK_implies* = 0x000008CE - XK_identical* = 0x000008CF - XK_radical* = 0x000008D6 - XK_includedin* = 0x000008DA - XK_includes* = 0x000008DB - XK_intersection* = 0x000008DC - XK_union* = 0x000008DD - XK_logicaland* = 0x000008DE - XK_logicalor* = 0x000008DF - XK_partialderivative* = 0x000008EF - XK_function* = 0x000008F6 - XK_leftarrow* = 0x000008FB - XK_uparrow* = 0x000008FC - XK_rightarrow* = 0x000008FD - XK_downarrow* = 0x000008FE + XK_leftradical*: TKeySym = 0x000008A1 + XK_topleftradical*: TKeySym = 0x000008A2 + XK_horizconnector*: TKeySym = 0x000008A3 + XK_topintegral*: TKeySym = 0x000008A4 + XK_botintegral*: TKeySym = 0x000008A5 + XK_vertconnector*: TKeySym = 0x000008A6 + XK_topleftsqbracket*: TKeySym = 0x000008A7 + XK_botleftsqbracket*: TKeySym = 0x000008A8 + XK_toprightsqbracket*: TKeySym = 0x000008A9 + XK_botrightsqbracket*: TKeySym = 0x000008AA + XK_topleftparens*: TKeySym = 0x000008AB + XK_botleftparens*: TKeySym = 0x000008AC + XK_toprightparens*: TKeySym = 0x000008AD + XK_botrightparens*: TKeySym = 0x000008AE + XK_leftmiddlecurlybrace*: TKeySym = 0x000008AF + XK_rightmiddlecurlybrace*: TKeySym = 0x000008B0 + XK_topleftsummation*: TKeySym = 0x000008B1 + XK_botleftsummation*: TKeySym = 0x000008B2 + XK_topvertsummationconnector*: TKeySym = 0x000008B3 + XK_botvertsummationconnector*: TKeySym = 0x000008B4 + XK_toprightsummation*: TKeySym = 0x000008B5 + XK_botrightsummation*: TKeySym = 0x000008B6 + XK_rightmiddlesummation*: TKeySym = 0x000008B7 + XK_lessthanequal*: TKeySym = 0x000008BC + XK_notequal*: TKeySym = 0x000008BD + XK_greaterthanequal*: TKeySym = 0x000008BE + XK_integral*: TKeySym = 0x000008BF + XK_therefore*: TKeySym = 0x000008C0 + XK_variation*: TKeySym = 0x000008C1 + XK_infinity*: TKeySym = 0x000008C2 + XK_nabla*: TKeySym = 0x000008C5 + XK_approximate*: TKeySym = 0x000008C8 + XK_similarequal*: TKeySym = 0x000008C9 + XK_ifonlyif*: TKeySym = 0x000008CD + XK_implies*: TKeySym = 0x000008CE + XK_identical*: TKeySym = 0x000008CF + XK_radical*: TKeySym = 0x000008D6 + XK_includedin*: TKeySym = 0x000008DA + XK_includes*: TKeySym = 0x000008DB + XK_intersection*: TKeySym = 0x000008DC + XK_union*: TKeySym = 0x000008DD + XK_logicaland*: TKeySym = 0x000008DE + XK_logicalor*: TKeySym = 0x000008DF + XK_partialderivative*: TKeySym = 0x000008EF + XK_function*: TKeySym = 0x000008F6 + XK_leftarrow*: TKeySym = 0x000008FB + XK_uparrow*: TKeySym = 0x000008FC + XK_rightarrow*: TKeySym = 0x000008FD + XK_downarrow*: TKeySym = 0x000008FE # XK_TECHNICAL #* # * Special @@ -1207,30 +1208,30 @@ when defined(XK_TECHNICAL) or true: when defined(XK_SPECIAL): const - XK_blank* = 0x000009DF - XK_soliddiamond* = 0x000009E0 - XK_checkerboard* = 0x000009E1 - XK_ht* = 0x000009E2 - XK_ff* = 0x000009E3 - XK_cr* = 0x000009E4 - XK_lf* = 0x000009E5 - XK_nl* = 0x000009E8 - XK_vt* = 0x000009E9 - XK_lowrightcorner* = 0x000009EA - XK_uprightcorner* = 0x000009EB - XK_upleftcorner* = 0x000009EC - XK_lowleftcorner* = 0x000009ED - XK_crossinglines* = 0x000009EE - XK_horizlinescan1* = 0x000009EF - XK_horizlinescan3* = 0x000009F0 - XK_horizlinescan5* = 0x000009F1 - XK_horizlinescan7* = 0x000009F2 - XK_horizlinescan9* = 0x000009F3 - XK_leftt* = 0x000009F4 - XK_rightt* = 0x000009F5 - XK_bott* = 0x000009F6 - XK_topt* = 0x000009F7 - XK_vertbar* = 0x000009F8 + XK_blank*: TKeySym = 0x000009DF + XK_soliddiamond*: TKeySym = 0x000009E0 + XK_checkerboard*: TKeySym = 0x000009E1 + XK_ht*: TKeySym = 0x000009E2 + XK_ff*: TKeySym = 0x000009E3 + XK_cr*: TKeySym = 0x000009E4 + XK_lf*: TKeySym = 0x000009E5 + XK_nl*: TKeySym = 0x000009E8 + XK_vt*: TKeySym = 0x000009E9 + XK_lowrightcorner*: TKeySym = 0x000009EA + XK_uprightcorner*: TKeySym = 0x000009EB + XK_upleftcorner*: TKeySym = 0x000009EC + XK_lowleftcorner*: TKeySym = 0x000009ED + XK_crossinglines*: TKeySym = 0x000009EE + XK_horizlinescan1*: TKeySym = 0x000009EF + XK_horizlinescan3*: TKeySym = 0x000009F0 + XK_horizlinescan5*: TKeySym = 0x000009F1 + XK_horizlinescan7*: TKeySym = 0x000009F2 + XK_horizlinescan9*: TKeySym = 0x000009F3 + XK_leftt*: TKeySym = 0x000009F4 + XK_rightt*: TKeySym = 0x000009F5 + XK_bott*: TKeySym = 0x000009F6 + XK_topt*: TKeySym = 0x000009F7 + XK_vertbar*: TKeySym = 0x000009F8 # XK_SPECIAL #* # * Publishing @@ -1239,89 +1240,89 @@ when defined(XK_SPECIAL): when defined(XK_PUBLISHING) or true: const - XK_emspace* = 0x00000AA1 - XK_enspace* = 0x00000AA2 - XK_em3space* = 0x00000AA3 - XK_em4space* = 0x00000AA4 - XK_digitspace* = 0x00000AA5 - XK_punctspace* = 0x00000AA6 - XK_thinspace* = 0x00000AA7 - XK_hairspace* = 0x00000AA8 - XK_emdash* = 0x00000AA9 - XK_endash* = 0x00000AAA - XK_signifblank* = 0x00000AAC - XK_ellipsis* = 0x00000AAE - XK_doubbaselinedot* = 0x00000AAF - XK_onethird* = 0x00000AB0 - XK_twothirds* = 0x00000AB1 - XK_onefifth* = 0x00000AB2 - XK_twofifths* = 0x00000AB3 - XK_threefifths* = 0x00000AB4 - XK_fourfifths* = 0x00000AB5 - XK_onesixth* = 0x00000AB6 - XK_fivesixths* = 0x00000AB7 - XK_careof* = 0x00000AB8 - XK_figdash* = 0x00000ABB - XK_leftanglebracket* = 0x00000ABC - XK_decimalpoint* = 0x00000ABD - XK_rightanglebracket* = 0x00000ABE - XK_marker* = 0x00000ABF - XK_oneeighth* = 0x00000AC3 - XK_threeeighths* = 0x00000AC4 - XK_fiveeighths* = 0x00000AC5 - XK_seveneighths* = 0x00000AC6 - XK_trademark* = 0x00000AC9 - XK_signaturemark* = 0x00000ACA - XK_trademarkincircle* = 0x00000ACB - XK_leftopentriangle* = 0x00000ACC - XK_rightopentriangle* = 0x00000ACD - XK_emopencircle* = 0x00000ACE - XK_emopenrectangle* = 0x00000ACF - XK_leftsinglequotemark* = 0x00000AD0 - XK_rightsinglequotemark* = 0x00000AD1 - XK_leftdoublequotemark* = 0x00000AD2 - XK_rightdoublequotemark* = 0x00000AD3 - XK_prescription* = 0x00000AD4 - XK_minutes* = 0x00000AD6 - XK_seconds* = 0x00000AD7 - XK_latincross* = 0x00000AD9 - XK_hexagram* = 0x00000ADA - XK_filledrectbullet* = 0x00000ADB - XK_filledlefttribullet* = 0x00000ADC - XK_filledrighttribullet* = 0x00000ADD - XK_emfilledcircle* = 0x00000ADE - XK_emfilledrect* = 0x00000ADF - XK_enopencircbullet* = 0x00000AE0 - XK_enopensquarebullet* = 0x00000AE1 - XK_openrectbullet* = 0x00000AE2 - XK_opentribulletup* = 0x00000AE3 - XK_opentribulletdown* = 0x00000AE4 - XK_openstar* = 0x00000AE5 - XK_enfilledcircbullet* = 0x00000AE6 - XK_enfilledsqbullet* = 0x00000AE7 - XK_filledtribulletup* = 0x00000AE8 - XK_filledtribulletdown* = 0x00000AE9 - XK_leftpointer* = 0x00000AEA - XK_rightpointer* = 0x00000AEB - XK_club* = 0x00000AEC - XK_diamond* = 0x00000AED - XK_heart* = 0x00000AEE - XK_maltesecross* = 0x00000AF0 - XK_dagger* = 0x00000AF1 - XK_doubledagger* = 0x00000AF2 - XK_checkmark* = 0x00000AF3 - XK_ballotcross* = 0x00000AF4 - XK_musicalsharp* = 0x00000AF5 - XK_musicalflat* = 0x00000AF6 - XK_malesymbol* = 0x00000AF7 - XK_femalesymbol* = 0x00000AF8 - XK_telephone* = 0x00000AF9 - XK_telephonerecorder* = 0x00000AFA - XK_phonographcopyright* = 0x00000AFB - XK_caret* = 0x00000AFC - XK_singlelowquotemark* = 0x00000AFD - XK_doublelowquotemark* = 0x00000AFE - XK_cursor* = 0x00000AFF + XK_emspace*: TKeySym = 0x00000AA1 + XK_enspace*: TKeySym = 0x00000AA2 + XK_em3space*: TKeySym = 0x00000AA3 + XK_em4space*: TKeySym = 0x00000AA4 + XK_digitspace*: TKeySym = 0x00000AA5 + XK_punctspace*: TKeySym = 0x00000AA6 + XK_thinspace*: TKeySym = 0x00000AA7 + XK_hairspace*: TKeySym = 0x00000AA8 + XK_emdash*: TKeySym = 0x00000AA9 + XK_endash*: TKeySym = 0x00000AAA + XK_signifblank*: TKeySym = 0x00000AAC + XK_ellipsis*: TKeySym = 0x00000AAE + XK_doubbaselinedot*: TKeySym = 0x00000AAF + XK_onethird*: TKeySym = 0x00000AB0 + XK_twothirds*: TKeySym = 0x00000AB1 + XK_onefifth*: TKeySym = 0x00000AB2 + XK_twofifths*: TKeySym = 0x00000AB3 + XK_threefifths*: TKeySym = 0x00000AB4 + XK_fourfifths*: TKeySym = 0x00000AB5 + XK_onesixth*: TKeySym = 0x00000AB6 + XK_fivesixths*: TKeySym = 0x00000AB7 + XK_careof*: TKeySym = 0x00000AB8 + XK_figdash*: TKeySym = 0x00000ABB + XK_leftanglebracket*: TKeySym = 0x00000ABC + XK_decimalpoint*: TKeySym = 0x00000ABD + XK_rightanglebracket*: TKeySym = 0x00000ABE + XK_marker*: TKeySym = 0x00000ABF + XK_oneeighth*: TKeySym = 0x00000AC3 + XK_threeeighths*: TKeySym = 0x00000AC4 + XK_fiveeighths*: TKeySym = 0x00000AC5 + XK_seveneighths*: TKeySym = 0x00000AC6 + XK_trademark*: TKeySym = 0x00000AC9 + XK_signaturemark*: TKeySym = 0x00000ACA + XK_trademarkincircle*: TKeySym = 0x00000ACB + XK_leftopentriangle*: TKeySym = 0x00000ACC + XK_rightopentriangle*: TKeySym = 0x00000ACD + XK_emopencircle*: TKeySym = 0x00000ACE + XK_emopenrectangle*: TKeySym = 0x00000ACF + XK_leftsinglequotemark*: TKeySym = 0x00000AD0 + XK_rightsinglequotemark*: TKeySym = 0x00000AD1 + XK_leftdoublequotemark*: TKeySym = 0x00000AD2 + XK_rightdoublequotemark*: TKeySym = 0x00000AD3 + XK_prescription*: TKeySym = 0x00000AD4 + XK_minutes*: TKeySym = 0x00000AD6 + XK_seconds*: TKeySym = 0x00000AD7 + XK_latincross*: TKeySym = 0x00000AD9 + XK_hexagram*: TKeySym = 0x00000ADA + XK_filledrectbullet*: TKeySym = 0x00000ADB + XK_filledlefttribullet*: TKeySym = 0x00000ADC + XK_filledrighttribullet*: TKeySym = 0x00000ADD + XK_emfilledcircle*: TKeySym = 0x00000ADE + XK_emfilledrect*: TKeySym = 0x00000ADF + XK_enopencircbullet*: TKeySym = 0x00000AE0 + XK_enopensquarebullet*: TKeySym = 0x00000AE1 + XK_openrectbullet*: TKeySym = 0x00000AE2 + XK_opentribulletup*: TKeySym = 0x00000AE3 + XK_opentribulletdown*: TKeySym = 0x00000AE4 + XK_openstar*: TKeySym = 0x00000AE5 + XK_enfilledcircbullet*: TKeySym = 0x00000AE6 + XK_enfilledsqbullet*: TKeySym = 0x00000AE7 + XK_filledtribulletup*: TKeySym = 0x00000AE8 + XK_filledtribulletdown*: TKeySym = 0x00000AE9 + XK_leftpointer*: TKeySym = 0x00000AEA + XK_rightpointer*: TKeySym = 0x00000AEB + XK_club*: TKeySym = 0x00000AEC + XK_diamond*: TKeySym = 0x00000AED + XK_heart*: TKeySym = 0x00000AEE + XK_maltesecross*: TKeySym = 0x00000AF0 + XK_dagger*: TKeySym = 0x00000AF1 + XK_doubledagger*: TKeySym = 0x00000AF2 + XK_checkmark*: TKeySym = 0x00000AF3 + XK_ballotcross*: TKeySym = 0x00000AF4 + XK_musicalsharp*: TKeySym = 0x00000AF5 + XK_musicalflat*: TKeySym = 0x00000AF6 + XK_malesymbol*: TKeySym = 0x00000AF7 + XK_femalesymbol*: TKeySym = 0x00000AF8 + XK_telephone*: TKeySym = 0x00000AF9 + XK_telephonerecorder*: TKeySym = 0x00000AFA + XK_phonographcopyright*: TKeySym = 0x00000AFB + XK_caret*: TKeySym = 0x00000AFC + XK_singlelowquotemark*: TKeySym = 0x00000AFD + XK_doublelowquotemark*: TKeySym = 0x00000AFE + XK_cursor*: TKeySym = 0x00000AFF # XK_PUBLISHING #* # * APL @@ -1330,25 +1331,25 @@ when defined(XK_PUBLISHING) or true: when defined(XK_APL) or true: const - XK_leftcaret* = 0x00000BA3 - XK_rightcaret* = 0x00000BA6 - XK_downcaret* = 0x00000BA8 - XK_upcaret* = 0x00000BA9 - XK_overbar* = 0x00000BC0 - XK_downtack* = 0x00000BC2 - XK_upshoe* = 0x00000BC3 - XK_downstile* = 0x00000BC4 - XK_underbar* = 0x00000BC6 - XK_jot* = 0x00000BCA - XK_quad* = 0x00000BCC - XK_uptack* = 0x00000BCE - XK_circle* = 0x00000BCF - XK_upstile* = 0x00000BD3 - XK_downshoe* = 0x00000BD6 - XK_rightshoe* = 0x00000BD8 - XK_leftshoe* = 0x00000BDA - XK_lefttack* = 0x00000BDC - XK_righttack* = 0x00000BFC + XK_leftcaret*: TKeySym = 0x00000BA3 + XK_rightcaret*: TKeySym = 0x00000BA6 + XK_downcaret*: TKeySym = 0x00000BA8 + XK_upcaret*: TKeySym = 0x00000BA9 + XK_overbar*: TKeySym = 0x00000BC0 + XK_downtack*: TKeySym = 0x00000BC2 + XK_upshoe*: TKeySym = 0x00000BC3 + XK_downstile*: TKeySym = 0x00000BC4 + XK_underbar*: TKeySym = 0x00000BC6 + XK_jot*: TKeySym = 0x00000BCA + XK_quad*: TKeySym = 0x00000BCC + XK_uptack*: TKeySym = 0x00000BCE + XK_circle*: TKeySym = 0x00000BCF + XK_upstile*: TKeySym = 0x00000BD3 + XK_downshoe*: TKeySym = 0x00000BD6 + XK_rightshoe*: TKeySym = 0x00000BD8 + XK_leftshoe*: TKeySym = 0x00000BDA + XK_lefttack*: TKeySym = 0x00000BDC + XK_righttack*: TKeySym = 0x00000BFC # XK_APL #* # * Hebrew @@ -1357,46 +1358,46 @@ when defined(XK_APL) or true: when defined(XK_HEBREW) or true: const - XK_hebrew_doublelowline* = 0x00000CDF - XK_hebrew_aleph* = 0x00000CE0 - XK_hebrew_bet* = 0x00000CE1 - XK_hebrew_beth* = 0x00000CE1 # deprecated - XK_hebrew_gimel* = 0x00000CE2 - XK_hebrew_gimmel* = 0x00000CE2 # deprecated - XK_hebrew_dalet* = 0x00000CE3 - XK_hebrew_daleth* = 0x00000CE3 # deprecated - XK_hebrew_he* = 0x00000CE4 - XK_hebrew_waw* = 0x00000CE5 - XK_hebrew_zain* = 0x00000CE6 - XK_hebrew_zayin* = 0x00000CE6 # deprecated - XK_hebrew_chet* = 0x00000CE7 - XK_hebrew_het* = 0x00000CE7 # deprecated - XK_hebrew_tet* = 0x00000CE8 - XK_hebrew_teth* = 0x00000CE8 # deprecated - XK_hebrew_yod* = 0x00000CE9 - XK_hebrew_finalkaph* = 0x00000CEA - XK_hebrew_kaph* = 0x00000CEB - XK_hebrew_lamed* = 0x00000CEC - XK_hebrew_finalmem* = 0x00000CED - XK_hebrew_mem* = 0x00000CEE - XK_hebrew_finalnun* = 0x00000CEF - XK_hebrew_nun* = 0x00000CF0 - XK_hebrew_samech* = 0x00000CF1 - XK_hebrew_samekh* = 0x00000CF1 # deprecated - XK_hebrew_ayin* = 0x00000CF2 - XK_hebrew_finalpe* = 0x00000CF3 - XK_hebrew_pe* = 0x00000CF4 - XK_hebrew_finalzade* = 0x00000CF5 - XK_hebrew_finalzadi* = 0x00000CF5 # deprecated - XK_hebrew_zade* = 0x00000CF6 - XK_hebrew_zadi* = 0x00000CF6 # deprecated - XK_hebrew_qoph* = 0x00000CF7 - XK_hebrew_kuf* = 0x00000CF7 # deprecated - XK_hebrew_resh* = 0x00000CF8 - XK_hebrew_shin* = 0x00000CF9 - XK_hebrew_taw* = 0x00000CFA - XK_hebrew_taf* = 0x00000CFA # deprecated - XK_Hebrew_switch* = 0x0000FF7E # Alias for mode_switch + XK_hebrew_doublelowline*: TKeySym = 0x00000CDF + XK_hebrew_aleph*: TKeySym = 0x00000CE0 + XK_hebrew_bet*: TKeySym = 0x00000CE1 + XK_hebrew_beth*: TKeySym = 0x00000CE1 # deprecated + XK_hebrew_gimel*: TKeySym = 0x00000CE2 + XK_hebrew_gimmel*: TKeySym = 0x00000CE2 # deprecated + XK_hebrew_dalet*: TKeySym = 0x00000CE3 + XK_hebrew_daleth*: TKeySym = 0x00000CE3 # deprecated + XK_hebrew_he*: TKeySym = 0x00000CE4 + XK_hebrew_waw*: TKeySym = 0x00000CE5 + XK_hebrew_zain*: TKeySym = 0x00000CE6 + XK_hebrew_zayin*: TKeySym = 0x00000CE6 # deprecated + XK_hebrew_chet*: TKeySym = 0x00000CE7 + XK_hebrew_het*: TKeySym = 0x00000CE7 # deprecated + XK_hebrew_tet*: TKeySym = 0x00000CE8 + XK_hebrew_teth*: TKeySym = 0x00000CE8 # deprecated + XK_hebrew_yod*: TKeySym = 0x00000CE9 + XK_hebrew_finalkaph*: TKeySym = 0x00000CEA + XK_hebrew_kaph*: TKeySym = 0x00000CEB + XK_hebrew_lamed*: TKeySym = 0x00000CEC + XK_hebrew_finalmem*: TKeySym = 0x00000CED + XK_hebrew_mem*: TKeySym = 0x00000CEE + XK_hebrew_finalnun*: TKeySym = 0x00000CEF + XK_hebrew_nun*: TKeySym = 0x00000CF0 + XK_hebrew_samech*: TKeySym = 0x00000CF1 + XK_hebrew_samekh*: TKeySym = 0x00000CF1 # deprecated + XK_hebrew_ayin*: TKeySym = 0x00000CF2 + XK_hebrew_finalpe*: TKeySym = 0x00000CF3 + XK_hebrew_pe*: TKeySym = 0x00000CF4 + XK_hebrew_finalzade*: TKeySym = 0x00000CF5 + XK_hebrew_finalzadi*: TKeySym = 0x00000CF5 # deprecated + XK_hebrew_zade*: TKeySym = 0x00000CF6 + XK_hebrew_zadi*: TKeySym = 0x00000CF6 # deprecated + XK_hebrew_qoph*: TKeySym = 0x00000CF7 + XK_hebrew_kuf*: TKeySym = 0x00000CF7 # deprecated + XK_hebrew_resh*: TKeySym = 0x00000CF8 + XK_hebrew_shin*: TKeySym = 0x00000CF9 + XK_hebrew_taw*: TKeySym = 0x00000CFA + XK_hebrew_taf*: TKeySym = 0x00000CFA # deprecated + XK_Hebrew_switch*: TKeySym = 0x0000FF7E # Alias for mode_switch # XK_HEBREW #* # * Thai @@ -1405,90 +1406,90 @@ when defined(XK_HEBREW) or true: when defined(XK_THAI) or true: const - XK_Thai_kokai* = 0x00000DA1 - XK_Thai_khokhai* = 0x00000DA2 - XK_Thai_khokhuat* = 0x00000DA3 - XK_Thai_khokhwai* = 0x00000DA4 - XK_Thai_khokhon* = 0x00000DA5 - XK_Thai_khorakhang* = 0x00000DA6 - XK_Thai_ngongu* = 0x00000DA7 - XK_Thai_chochan* = 0x00000DA8 - XK_Thai_choching* = 0x00000DA9 - XK_Thai_chochang* = 0x00000DAA - XK_Thai_soso* = 0x00000DAB - XK_Thai_chochoe* = 0x00000DAC - XK_Thai_yoying* = 0x00000DAD - XK_Thai_dochada* = 0x00000DAE - XK_Thai_topatak* = 0x00000DAF - XK_Thai_thothan* = 0x00000DB0 - XK_Thai_thonangmontho* = 0x00000DB1 - XK_Thai_thophuthao* = 0x00000DB2 - XK_Thai_nonen* = 0x00000DB3 - XK_Thai_dodek* = 0x00000DB4 - XK_Thai_totao* = 0x00000DB5 - XK_Thai_thothung* = 0x00000DB6 - XK_Thai_thothahan* = 0x00000DB7 - XK_Thai_thothong* = 0x00000DB8 - XK_Thai_nonu* = 0x00000DB9 - XK_Thai_bobaimai* = 0x00000DBA - XK_Thai_popla* = 0x00000DBB - XK_Thai_phophung* = 0x00000DBC - XK_Thai_fofa* = 0x00000DBD - XK_Thai_phophan* = 0x00000DBE - XK_Thai_fofan* = 0x00000DBF - XK_Thai_phosamphao* = 0x00000DC0 - XK_Thai_moma* = 0x00000DC1 - XK_Thai_yoyak* = 0x00000DC2 - XK_Thai_rorua* = 0x00000DC3 - XK_Thai_ru* = 0x00000DC4 - XK_Thai_loling* = 0x00000DC5 - XK_Thai_lu* = 0x00000DC6 - XK_Thai_wowaen* = 0x00000DC7 - XK_Thai_sosala* = 0x00000DC8 - XK_Thai_sorusi* = 0x00000DC9 - XK_Thai_sosua* = 0x00000DCA - XK_Thai_hohip* = 0x00000DCB - XK_Thai_lochula* = 0x00000DCC - XK_Thai_oang* = 0x00000DCD - XK_Thai_honokhuk* = 0x00000DCE - XK_Thai_paiyannoi* = 0x00000DCF - XK_Thai_saraa* = 0x00000DD0 - XK_Thai_maihanakat* = 0x00000DD1 - XK_Thai_saraaa* = 0x00000DD2 - XK_Thai_saraam* = 0x00000DD3 - XK_Thai_sarai* = 0x00000DD4 - XK_Thai_saraii* = 0x00000DD5 - XK_Thai_saraue* = 0x00000DD6 - XK_Thai_sarauee* = 0x00000DD7 - XK_Thai_sarau* = 0x00000DD8 - XK_Thai_sarauu* = 0x00000DD9 - XK_Thai_phinthu* = 0x00000DDA - XK_Thai_maihanakat_maitho* = 0x00000DDE - XK_Thai_baht* = 0x00000DDF - XK_Thai_sarae* = 0x00000DE0 - XK_Thai_saraae* = 0x00000DE1 - XK_Thai_sarao* = 0x00000DE2 - XK_Thai_saraaimaimuan* = 0x00000DE3 - XK_Thai_saraaimaimalai* = 0x00000DE4 - XK_Thai_lakkhangyao* = 0x00000DE5 - XK_Thai_maiyamok* = 0x00000DE6 - XK_Thai_maitaikhu* = 0x00000DE7 - XK_Thai_maiek* = 0x00000DE8 - XK_Thai_maitho* = 0x00000DE9 - XK_Thai_maitri* = 0x00000DEA - XK_Thai_maichattawa* = 0x00000DEB - XK_Thai_thanthakhat* = 0x00000DEC - XK_Thai_nikhahit* = 0x00000DED - XK_Thai_leksun* = 0x00000DF0 - XK_Thai_leknung* = 0x00000DF1 - XK_Thai_leksong* = 0x00000DF2 - XK_Thai_leksam* = 0x00000DF3 - XK_Thai_leksi* = 0x00000DF4 - XK_Thai_lekha* = 0x00000DF5 - XK_Thai_lekhok* = 0x00000DF6 - XK_Thai_lekchet* = 0x00000DF7 - XK_Thai_lekpaet* = 0x00000DF8 - XK_Thai_lekkao* = 0x00000DF9 + XK_Thai_kokai*: TKeySym = 0x00000DA1 + XK_Thai_khokhai*: TKeySym = 0x00000DA2 + XK_Thai_khokhuat*: TKeySym = 0x00000DA3 + XK_Thai_khokhwai*: TKeySym = 0x00000DA4 + XK_Thai_khokhon*: TKeySym = 0x00000DA5 + XK_Thai_khorakhang*: TKeySym = 0x00000DA6 + XK_Thai_ngongu*: TKeySym = 0x00000DA7 + XK_Thai_chochan*: TKeySym = 0x00000DA8 + XK_Thai_choching*: TKeySym = 0x00000DA9 + XK_Thai_chochang*: TKeySym = 0x00000DAA + XK_Thai_soso*: TKeySym = 0x00000DAB + XK_Thai_chochoe*: TKeySym = 0x00000DAC + XK_Thai_yoying*: TKeySym = 0x00000DAD + XK_Thai_dochada*: TKeySym = 0x00000DAE + XK_Thai_topatak*: TKeySym = 0x00000DAF + XK_Thai_thothan*: TKeySym = 0x00000DB0 + XK_Thai_thonangmontho*: TKeySym = 0x00000DB1 + XK_Thai_thophuthao*: TKeySym = 0x00000DB2 + XK_Thai_nonen*: TKeySym = 0x00000DB3 + XK_Thai_dodek*: TKeySym = 0x00000DB4 + XK_Thai_totao*: TKeySym = 0x00000DB5 + XK_Thai_thothung*: TKeySym = 0x00000DB6 + XK_Thai_thothahan*: TKeySym = 0x00000DB7 + XK_Thai_thothong*: TKeySym = 0x00000DB8 + XK_Thai_nonu*: TKeySym = 0x00000DB9 + XK_Thai_bobaimai*: TKeySym = 0x00000DBA + XK_Thai_popla*: TKeySym = 0x00000DBB + XK_Thai_phophung*: TKeySym = 0x00000DBC + XK_Thai_fofa*: TKeySym = 0x00000DBD + XK_Thai_phophan*: TKeySym = 0x00000DBE + XK_Thai_fofan*: TKeySym = 0x00000DBF + XK_Thai_phosamphao*: TKeySym = 0x00000DC0 + XK_Thai_moma*: TKeySym = 0x00000DC1 + XK_Thai_yoyak*: TKeySym = 0x00000DC2 + XK_Thai_rorua*: TKeySym = 0x00000DC3 + XK_Thai_ru*: TKeySym = 0x00000DC4 + XK_Thai_loling*: TKeySym = 0x00000DC5 + XK_Thai_lu*: TKeySym = 0x00000DC6 + XK_Thai_wowaen*: TKeySym = 0x00000DC7 + XK_Thai_sosala*: TKeySym = 0x00000DC8 + XK_Thai_sorusi*: TKeySym = 0x00000DC9 + XK_Thai_sosua*: TKeySym = 0x00000DCA + XK_Thai_hohip*: TKeySym = 0x00000DCB + XK_Thai_lochula*: TKeySym = 0x00000DCC + XK_Thai_oang*: TKeySym = 0x00000DCD + XK_Thai_honokhuk*: TKeySym = 0x00000DCE + XK_Thai_paiyannoi*: TKeySym = 0x00000DCF + XK_Thai_saraa*: TKeySym = 0x00000DD0 + XK_Thai_maihanakat*: TKeySym = 0x00000DD1 + XK_Thai_saraaa*: TKeySym = 0x00000DD2 + XK_Thai_saraam*: TKeySym = 0x00000DD3 + XK_Thai_sarai*: TKeySym = 0x00000DD4 + XK_Thai_saraii*: TKeySym = 0x00000DD5 + XK_Thai_saraue*: TKeySym = 0x00000DD6 + XK_Thai_sarauee*: TKeySym = 0x00000DD7 + XK_Thai_sarau*: TKeySym = 0x00000DD8 + XK_Thai_sarauu*: TKeySym = 0x00000DD9 + XK_Thai_phinthu*: TKeySym = 0x00000DDA + XK_Thai_maihanakat_maitho*: TKeySym = 0x00000DDE + XK_Thai_baht*: TKeySym = 0x00000DDF + XK_Thai_sarae*: TKeySym = 0x00000DE0 + XK_Thai_saraae*: TKeySym = 0x00000DE1 + XK_Thai_sarao*: TKeySym = 0x00000DE2 + XK_Thai_saraaimaimuan*: TKeySym = 0x00000DE3 + XK_Thai_saraaimaimalai*: TKeySym = 0x00000DE4 + XK_Thai_lakkhangyao*: TKeySym = 0x00000DE5 + XK_Thai_maiyamok*: TKeySym = 0x00000DE6 + XK_Thai_maitaikhu*: TKeySym = 0x00000DE7 + XK_Thai_maiek*: TKeySym = 0x00000DE8 + XK_Thai_maitho*: TKeySym = 0x00000DE9 + XK_Thai_maitri*: TKeySym = 0x00000DEA + XK_Thai_maichattawa*: TKeySym = 0x00000DEB + XK_Thai_thanthakhat*: TKeySym = 0x00000DEC + XK_Thai_nikhahit*: TKeySym = 0x00000DED + XK_Thai_leksun*: TKeySym = 0x00000DF0 + XK_Thai_leknung*: TKeySym = 0x00000DF1 + XK_Thai_leksong*: TKeySym = 0x00000DF2 + XK_Thai_leksam*: TKeySym = 0x00000DF3 + XK_Thai_leksi*: TKeySym = 0x00000DF4 + XK_Thai_lekha*: TKeySym = 0x00000DF5 + XK_Thai_lekhok*: TKeySym = 0x00000DF6 + XK_Thai_lekchet*: TKeySym = 0x00000DF7 + XK_Thai_lekpaet*: TKeySym = 0x00000DF8 + XK_Thai_lekkao*: TKeySym = 0x00000DF9 # XK_THAI #* # * Korean @@ -1497,114 +1498,114 @@ when defined(XK_THAI) or true: when defined(XK_KOREAN) or true: const - XK_Hangul* = 0x0000FF31 # Hangul start/stop(toggle) - XK_Hangul_Start* = 0x0000FF32 # Hangul start - XK_Hangul_End* = 0x0000FF33 # Hangul end, English start - XK_Hangul_Hanja* = 0x0000FF34 # Start Hangul->Hanja Conversion - XK_Hangul_Jamo* = 0x0000FF35 # Hangul Jamo mode - XK_Hangul_Romaja* = 0x0000FF36 # Hangul Romaja mode - XK_Hangul_Codeinput* = 0x0000FF37 # Hangul code input mode - XK_Hangul_Jeonja* = 0x0000FF38 # Jeonja mode - XK_Hangul_Banja* = 0x0000FF39 # Banja mode - XK_Hangul_PreHanja* = 0x0000FF3A # Pre Hanja conversion - XK_Hangul_PostHanja* = 0x0000FF3B # Post Hanja conversion - XK_Hangul_SingleCandidate* = 0x0000FF3C # Single candidate - XK_Hangul_MultipleCandidate* = 0x0000FF3D # Multiple candidate - XK_Hangul_PreviousCandidate* = 0x0000FF3E # Previous candidate - XK_Hangul_Special* = 0x0000FF3F # Special symbols - XK_Hangul_switch* = 0x0000FF7E # Alias for mode_switch + XK_Hangul*: TKeySym = 0x0000FF31 # Hangul start/stop(toggle) + XK_Hangul_Start*: TKeySym = 0x0000FF32 # Hangul start + XK_Hangul_End*: TKeySym = 0x0000FF33 # Hangul end, English start + XK_Hangul_Hanja*: TKeySym = 0x0000FF34 # Start Hangul->Hanja Conversion + XK_Hangul_Jamo*: TKeySym = 0x0000FF35 # Hangul Jamo mode + XK_Hangul_Romaja*: TKeySym = 0x0000FF36 # Hangul Romaja mode + XK_Hangul_Codeinput*: TKeySym = 0x0000FF37 # Hangul code input mode + XK_Hangul_Jeonja*: TKeySym = 0x0000FF38 # Jeonja mode + XK_Hangul_Banja*: TKeySym = 0x0000FF39 # Banja mode + XK_Hangul_PreHanja*: TKeySym = 0x0000FF3A # Pre Hanja conversion + XK_Hangul_PostHanja*: TKeySym = 0x0000FF3B # Post Hanja conversion + XK_Hangul_SingleCandidate*: TKeySym = 0x0000FF3C # Single candidate + XK_Hangul_MultipleCandidate*: TKeySym = 0x0000FF3D # Multiple candidate + XK_Hangul_PreviousCandidate*: TKeySym = 0x0000FF3E # Previous candidate + XK_Hangul_Special*: TKeySym = 0x0000FF3F # Special symbols + XK_Hangul_switch*: TKeySym = 0x0000FF7E # Alias for mode_switch \ # Hangul Consonant Characters - XK_Hangul_Kiyeog* = 0x00000EA1 - XK_Hangul_SsangKiyeog* = 0x00000EA2 - XK_Hangul_KiyeogSios* = 0x00000EA3 - XK_Hangul_Nieun* = 0x00000EA4 - XK_Hangul_NieunJieuj* = 0x00000EA5 - XK_Hangul_NieunHieuh* = 0x00000EA6 - XK_Hangul_Dikeud* = 0x00000EA7 - XK_Hangul_SsangDikeud* = 0x00000EA8 - XK_Hangul_Rieul* = 0x00000EA9 - XK_Hangul_RieulKiyeog* = 0x00000EAA - XK_Hangul_RieulMieum* = 0x00000EAB - XK_Hangul_RieulPieub* = 0x00000EAC - XK_Hangul_RieulSios* = 0x00000EAD - XK_Hangul_RieulTieut* = 0x00000EAE - XK_Hangul_RieulPhieuf* = 0x00000EAF - XK_Hangul_RieulHieuh* = 0x00000EB0 - XK_Hangul_Mieum* = 0x00000EB1 - XK_Hangul_Pieub* = 0x00000EB2 - XK_Hangul_SsangPieub* = 0x00000EB3 - XK_Hangul_PieubSios* = 0x00000EB4 - XK_Hangul_Sios* = 0x00000EB5 - XK_Hangul_SsangSios* = 0x00000EB6 - XK_Hangul_Ieung* = 0x00000EB7 - XK_Hangul_Jieuj* = 0x00000EB8 - XK_Hangul_SsangJieuj* = 0x00000EB9 - XK_Hangul_Cieuc* = 0x00000EBA - XK_Hangul_Khieuq* = 0x00000EBB - XK_Hangul_Tieut* = 0x00000EBC - XK_Hangul_Phieuf* = 0x00000EBD - XK_Hangul_Hieuh* = 0x00000EBE # Hangul Vowel Characters - XK_Hangul_A* = 0x00000EBF - XK_Hangul_AE* = 0x00000EC0 - XK_Hangul_YA* = 0x00000EC1 - XK_Hangul_YAE* = 0x00000EC2 - XK_Hangul_EO* = 0x00000EC3 - XK_Hangul_E* = 0x00000EC4 - XK_Hangul_YEO* = 0x00000EC5 - XK_Hangul_YE* = 0x00000EC6 - XK_Hangul_O* = 0x00000EC7 - XK_Hangul_WA* = 0x00000EC8 - XK_Hangul_WAE* = 0x00000EC9 - XK_Hangul_OE* = 0x00000ECA - XK_Hangul_YO* = 0x00000ECB - XK_Hangul_U* = 0x00000ECC - XK_Hangul_WEO* = 0x00000ECD - XK_Hangul_WE* = 0x00000ECE - XK_Hangul_WI* = 0x00000ECF - XK_Hangul_YU* = 0x00000ED0 - XK_Hangul_EU* = 0x00000ED1 - XK_Hangul_YI* = 0x00000ED2 - XK_Hangul_I* = 0x00000ED3 # Hangul syllable-final (JongSeong) Characters - XK_Hangul_J_Kiyeog* = 0x00000ED4 - XK_Hangul_J_SsangKiyeog* = 0x00000ED5 - XK_Hangul_J_KiyeogSios* = 0x00000ED6 - XK_Hangul_J_Nieun* = 0x00000ED7 - XK_Hangul_J_NieunJieuj* = 0x00000ED8 - XK_Hangul_J_NieunHieuh* = 0x00000ED9 - XK_Hangul_J_Dikeud* = 0x00000EDA - XK_Hangul_J_Rieul* = 0x00000EDB - XK_Hangul_J_RieulKiyeog* = 0x00000EDC - XK_Hangul_J_RieulMieum* = 0x00000EDD - XK_Hangul_J_RieulPieub* = 0x00000EDE - XK_Hangul_J_RieulSios* = 0x00000EDF - XK_Hangul_J_RieulTieut* = 0x00000EE0 - XK_Hangul_J_RieulPhieuf* = 0x00000EE1 - XK_Hangul_J_RieulHieuh* = 0x00000EE2 - XK_Hangul_J_Mieum* = 0x00000EE3 - XK_Hangul_J_Pieub* = 0x00000EE4 - XK_Hangul_J_PieubSios* = 0x00000EE5 - XK_Hangul_J_Sios* = 0x00000EE6 - XK_Hangul_J_SsangSios* = 0x00000EE7 - XK_Hangul_J_Ieung* = 0x00000EE8 - XK_Hangul_J_Jieuj* = 0x00000EE9 - XK_Hangul_J_Cieuc* = 0x00000EEA - XK_Hangul_J_Khieuq* = 0x00000EEB - XK_Hangul_J_Tieut* = 0x00000EEC - XK_Hangul_J_Phieuf* = 0x00000EED - XK_Hangul_J_Hieuh* = 0x00000EEE # Ancient Hangul Consonant Characters - XK_Hangul_RieulYeorinHieuh* = 0x00000EEF - XK_Hangul_SunkyeongeumMieum* = 0x00000EF0 - XK_Hangul_SunkyeongeumPieub* = 0x00000EF1 - XK_Hangul_PanSios* = 0x00000EF2 - XK_Hangul_KkogjiDalrinIeung* = 0x00000EF3 - XK_Hangul_SunkyeongeumPhieuf* = 0x00000EF4 - XK_Hangul_YeorinHieuh* = 0x00000EF5 # Ancient Hangul Vowel Characters - XK_Hangul_AraeA* = 0x00000EF6 - XK_Hangul_AraeAE* = 0x00000EF7 # Ancient Hangul syllable-final (JongSeong) Characters - XK_Hangul_J_PanSios* = 0x00000EF8 - XK_Hangul_J_KkogjiDalrinIeung* = 0x00000EF9 - XK_Hangul_J_YeorinHieuh* = 0x00000EFA # Korean currency symbol - XK_Korean_Won* = 0x00000EFF + XK_Hangul_Kiyeog*: TKeySym = 0x00000EA1 + XK_Hangul_SsangKiyeog*: TKeySym = 0x00000EA2 + XK_Hangul_KiyeogSios*: TKeySym = 0x00000EA3 + XK_Hangul_Nieun*: TKeySym = 0x00000EA4 + XK_Hangul_NieunJieuj*: TKeySym = 0x00000EA5 + XK_Hangul_NieunHieuh*: TKeySym = 0x00000EA6 + XK_Hangul_Dikeud*: TKeySym = 0x00000EA7 + XK_Hangul_SsangDikeud*: TKeySym = 0x00000EA8 + XK_Hangul_Rieul*: TKeySym = 0x00000EA9 + XK_Hangul_RieulKiyeog*: TKeySym = 0x00000EAA + XK_Hangul_RieulMieum*: TKeySym = 0x00000EAB + XK_Hangul_RieulPieub*: TKeySym = 0x00000EAC + XK_Hangul_RieulSios*: TKeySym = 0x00000EAD + XK_Hangul_RieulTieut*: TKeySym = 0x00000EAE + XK_Hangul_RieulPhieuf*: TKeySym = 0x00000EAF + XK_Hangul_RieulHieuh*: TKeySym = 0x00000EB0 + XK_Hangul_Mieum*: TKeySym = 0x00000EB1 + XK_Hangul_Pieub*: TKeySym = 0x00000EB2 + XK_Hangul_SsangPieub*: TKeySym = 0x00000EB3 + XK_Hangul_PieubSios*: TKeySym = 0x00000EB4 + XK_Hangul_Sios*: TKeySym = 0x00000EB5 + XK_Hangul_SsangSios*: TKeySym = 0x00000EB6 + XK_Hangul_Ieung*: TKeySym = 0x00000EB7 + XK_Hangul_Jieuj*: TKeySym = 0x00000EB8 + XK_Hangul_SsangJieuj*: TKeySym = 0x00000EB9 + XK_Hangul_Cieuc*: TKeySym = 0x00000EBA + XK_Hangul_Khieuq*: TKeySym = 0x00000EBB + XK_Hangul_Tieut*: TKeySym = 0x00000EBC + XK_Hangul_Phieuf*: TKeySym = 0x00000EBD + XK_Hangul_Hieuh*: TKeySym = 0x00000EBE # Hangul Vowel Characters + XK_Hangul_A*: TKeySym = 0x00000EBF + XK_Hangul_AE*: TKeySym = 0x00000EC0 + XK_Hangul_YA*: TKeySym = 0x00000EC1 + XK_Hangul_YAE*: TKeySym = 0x00000EC2 + XK_Hangul_EO*: TKeySym = 0x00000EC3 + XK_Hangul_E*: TKeySym = 0x00000EC4 + XK_Hangul_YEO*: TKeySym = 0x00000EC5 + XK_Hangul_YE*: TKeySym = 0x00000EC6 + XK_Hangul_O*: TKeySym = 0x00000EC7 + XK_Hangul_WA*: TKeySym = 0x00000EC8 + XK_Hangul_WAE*: TKeySym = 0x00000EC9 + XK_Hangul_OE*: TKeySym = 0x00000ECA + XK_Hangul_YO*: TKeySym = 0x00000ECB + XK_Hangul_U*: TKeySym = 0x00000ECC + XK_Hangul_WEO*: TKeySym = 0x00000ECD + XK_Hangul_WE*: TKeySym = 0x00000ECE + XK_Hangul_WI*: TKeySym = 0x00000ECF + XK_Hangul_YU*: TKeySym = 0x00000ED0 + XK_Hangul_EU*: TKeySym = 0x00000ED1 + XK_Hangul_YI*: TKeySym = 0x00000ED2 + XK_Hangul_I*: TKeySym = 0x00000ED3 # Hangul syllable-final (JongSeong) Characters + XK_Hangul_J_Kiyeog*: TKeySym = 0x00000ED4 + XK_Hangul_J_SsangKiyeog*: TKeySym = 0x00000ED5 + XK_Hangul_J_KiyeogSios*: TKeySym = 0x00000ED6 + XK_Hangul_J_Nieun*: TKeySym = 0x00000ED7 + XK_Hangul_J_NieunJieuj*: TKeySym = 0x00000ED8 + XK_Hangul_J_NieunHieuh*: TKeySym = 0x00000ED9 + XK_Hangul_J_Dikeud*: TKeySym = 0x00000EDA + XK_Hangul_J_Rieul*: TKeySym = 0x00000EDB + XK_Hangul_J_RieulKiyeog*: TKeySym = 0x00000EDC + XK_Hangul_J_RieulMieum*: TKeySym = 0x00000EDD + XK_Hangul_J_RieulPieub*: TKeySym = 0x00000EDE + XK_Hangul_J_RieulSios*: TKeySym = 0x00000EDF + XK_Hangul_J_RieulTieut*: TKeySym = 0x00000EE0 + XK_Hangul_J_RieulPhieuf*: TKeySym = 0x00000EE1 + XK_Hangul_J_RieulHieuh*: TKeySym = 0x00000EE2 + XK_Hangul_J_Mieum*: TKeySym = 0x00000EE3 + XK_Hangul_J_Pieub*: TKeySym = 0x00000EE4 + XK_Hangul_J_PieubSios*: TKeySym = 0x00000EE5 + XK_Hangul_J_Sios*: TKeySym = 0x00000EE6 + XK_Hangul_J_SsangSios*: TKeySym = 0x00000EE7 + XK_Hangul_J_Ieung*: TKeySym = 0x00000EE8 + XK_Hangul_J_Jieuj*: TKeySym = 0x00000EE9 + XK_Hangul_J_Cieuc*: TKeySym = 0x00000EEA + XK_Hangul_J_Khieuq*: TKeySym = 0x00000EEB + XK_Hangul_J_Tieut*: TKeySym = 0x00000EEC + XK_Hangul_J_Phieuf*: TKeySym = 0x00000EED + XK_Hangul_J_Hieuh*: TKeySym = 0x00000EEE # Ancient Hangul Consonant Characters + XK_Hangul_RieulYeorinHieuh*: TKeySym = 0x00000EEF + XK_Hangul_SunkyeongeumMieum*: TKeySym = 0x00000EF0 + XK_Hangul_SunkyeongeumPieub*: TKeySym = 0x00000EF1 + XK_Hangul_PanSios*: TKeySym = 0x00000EF2 + XK_Hangul_KkogjiDalrinIeung*: TKeySym = 0x00000EF3 + XK_Hangul_SunkyeongeumPhieuf*: TKeySym = 0x00000EF4 + XK_Hangul_YeorinHieuh*: TKeySym = 0x00000EF5 # Ancient Hangul Vowel Characters + XK_Hangul_AraeA*: TKeySym = 0x00000EF6 + XK_Hangul_AraeAE*: TKeySym = 0x00000EF7 # Ancient Hangul syllable-final (JongSeong) Characters + XK_Hangul_J_PanSios*: TKeySym = 0x00000EF8 + XK_Hangul_J_KkogjiDalrinIeung*: TKeySym = 0x00000EF9 + XK_Hangul_J_YeorinHieuh*: TKeySym = 0x00000EFA # Korean currency symbol + XK_Korean_Won*: TKeySym = 0x00000EFF # XK_KOREAN #* # * Armenian @@ -1613,108 +1614,108 @@ when defined(XK_KOREAN) or true: when defined(XK_ARMENIAN) or true: const - XK_Armenian_eternity* = 0x000014A1 - XK_Armenian_ligature_ew* = 0x000014A2 - XK_Armenian_full_stop* = 0x000014A3 - XK_Armenian_verjaket* = 0x000014A3 - XK_Armenian_parenright* = 0x000014A4 - XK_Armenian_parenleft* = 0x000014A5 - XK_Armenian_guillemotright* = 0x000014A6 - XK_Armenian_guillemotleft* = 0x000014A7 - XK_Armenian_em_dash* = 0x000014A8 - XK_Armenian_dot* = 0x000014A9 - XK_Armenian_mijaket* = 0x000014A9 - XK_Armenian_separation_mark* = 0x000014AA - XK_Armenian_but* = 0x000014AA - XK_Armenian_comma* = 0x000014AB - XK_Armenian_en_dash* = 0x000014AC - XK_Armenian_hyphen* = 0x000014AD - XK_Armenian_yentamna* = 0x000014AD - XK_Armenian_ellipsis* = 0x000014AE - XK_Armenian_exclam* = 0x000014AF - XK_Armenian_amanak* = 0x000014AF - XK_Armenian_accent* = 0x000014B0 - XK_Armenian_shesht* = 0x000014B0 - XK_Armenian_question* = 0x000014B1 - XK_Armenian_paruyk* = 0x000014B1 - XKc_Armenian_AYB* = 0x000014B2 - XK_Armenian_ayb* = 0x000014B3 - XKc_Armenian_BEN* = 0x000014B4 - XK_Armenian_ben* = 0x000014B5 - XKc_Armenian_GIM* = 0x000014B6 - XK_Armenian_gim* = 0x000014B7 - XKc_Armenian_DA* = 0x000014B8 - XK_Armenian_da* = 0x000014B9 - XKc_Armenian_YECH* = 0x000014BA - XK_Armenian_yech* = 0x000014BB - XKc_Armenian_ZA* = 0x000014BC - XK_Armenian_za* = 0x000014BD - XKc_Armenian_E* = 0x000014BE - XK_Armenian_e* = 0x000014BF - XKc_Armenian_AT* = 0x000014C0 - XK_Armenian_at* = 0x000014C1 - XKc_Armenian_TO* = 0x000014C2 - XK_Armenian_to* = 0x000014C3 - XKc_Armenian_ZHE* = 0x000014C4 - XK_Armenian_zhe* = 0x000014C5 - XKc_Armenian_INI* = 0x000014C6 - XK_Armenian_ini* = 0x000014C7 - XKc_Armenian_LYUN* = 0x000014C8 - XK_Armenian_lyun* = 0x000014C9 - XKc_Armenian_KHE* = 0x000014CA - XK_Armenian_khe* = 0x000014CB - XKc_Armenian_TSA* = 0x000014CC - XK_Armenian_tsa* = 0x000014CD - XKc_Armenian_KEN* = 0x000014CE - XK_Armenian_ken* = 0x000014CF - XKc_Armenian_HO* = 0x000014D0 - XK_Armenian_ho* = 0x000014D1 - XKc_Armenian_DZA* = 0x000014D2 - XK_Armenian_dza* = 0x000014D3 - XKc_Armenian_GHAT* = 0x000014D4 - XK_Armenian_ghat* = 0x000014D5 - XKc_Armenian_TCHE* = 0x000014D6 - XK_Armenian_tche* = 0x000014D7 - XKc_Armenian_MEN* = 0x000014D8 - XK_Armenian_men* = 0x000014D9 - XKc_Armenian_HI* = 0x000014DA - XK_Armenian_hi* = 0x000014DB - XKc_Armenian_NU* = 0x000014DC - XK_Armenian_nu* = 0x000014DD - XKc_Armenian_SHA* = 0x000014DE - XK_Armenian_sha* = 0x000014DF - XKc_Armenian_VO* = 0x000014E0 - XK_Armenian_vo* = 0x000014E1 - XKc_Armenian_CHA* = 0x000014E2 - XK_Armenian_cha* = 0x000014E3 - XKc_Armenian_PE* = 0x000014E4 - XK_Armenian_pe* = 0x000014E5 - XKc_Armenian_JE* = 0x000014E6 - XK_Armenian_je* = 0x000014E7 - XKc_Armenian_RA* = 0x000014E8 - XK_Armenian_ra* = 0x000014E9 - XKc_Armenian_SE* = 0x000014EA - XK_Armenian_se* = 0x000014EB - XKc_Armenian_VEV* = 0x000014EC - XK_Armenian_vev* = 0x000014ED - XKc_Armenian_TYUN* = 0x000014EE - XK_Armenian_tyun* = 0x000014EF - XKc_Armenian_RE* = 0x000014F0 - XK_Armenian_re* = 0x000014F1 - XKc_Armenian_TSO* = 0x000014F2 - XK_Armenian_tso* = 0x000014F3 - XKc_Armenian_VYUN* = 0x000014F4 - XK_Armenian_vyun* = 0x000014F5 - XKc_Armenian_PYUR* = 0x000014F6 - XK_Armenian_pyur* = 0x000014F7 - XKc_Armenian_KE* = 0x000014F8 - XK_Armenian_ke* = 0x000014F9 - XKc_Armenian_O* = 0x000014FA - XK_Armenian_o* = 0x000014FB - XKc_Armenian_FE* = 0x000014FC - XK_Armenian_fe* = 0x000014FD - XK_Armenian_apostrophe* = 0x000014FE - XK_Armenian_section_sign* = 0x000014FF + XK_Armenian_eternity*: TKeySym = 0x000014A1 + XK_Armenian_ligature_ew*: TKeySym = 0x000014A2 + XK_Armenian_full_stop*: TKeySym = 0x000014A3 + XK_Armenian_verjaket*: TKeySym = 0x000014A3 + XK_Armenian_parenright*: TKeySym = 0x000014A4 + XK_Armenian_parenleft*: TKeySym = 0x000014A5 + XK_Armenian_guillemotright*: TKeySym = 0x000014A6 + XK_Armenian_guillemotleft*: TKeySym = 0x000014A7 + XK_Armenian_em_dash*: TKeySym = 0x000014A8 + XK_Armenian_dot*: TKeySym = 0x000014A9 + XK_Armenian_mijaket*: TKeySym = 0x000014A9 + XK_Armenian_separation_mark*: TKeySym = 0x000014AA + XK_Armenian_but*: TKeySym = 0x000014AA + XK_Armenian_comma*: TKeySym = 0x000014AB + XK_Armenian_en_dash*: TKeySym = 0x000014AC + XK_Armenian_hyphen*: TKeySym = 0x000014AD + XK_Armenian_yentamna*: TKeySym = 0x000014AD + XK_Armenian_ellipsis*: TKeySym = 0x000014AE + XK_Armenian_exclam*: TKeySym = 0x000014AF + XK_Armenian_amanak*: TKeySym = 0x000014AF + XK_Armenian_accent*: TKeySym = 0x000014B0 + XK_Armenian_shesht*: TKeySym = 0x000014B0 + XK_Armenian_question*: TKeySym = 0x000014B1 + XK_Armenian_paruyk*: TKeySym = 0x000014B1 + XKc_Armenian_AYB*: TKeySym = 0x000014B2 + XK_Armenian_ayb*: TKeySym = 0x000014B3 + XKc_Armenian_BEN*: TKeySym = 0x000014B4 + XK_Armenian_ben*: TKeySym = 0x000014B5 + XKc_Armenian_GIM*: TKeySym = 0x000014B6 + XK_Armenian_gim*: TKeySym = 0x000014B7 + XKc_Armenian_DA*: TKeySym = 0x000014B8 + XK_Armenian_da*: TKeySym = 0x000014B9 + XKc_Armenian_YECH*: TKeySym = 0x000014BA + XK_Armenian_yech*: TKeySym = 0x000014BB + XKc_Armenian_ZA*: TKeySym = 0x000014BC + XK_Armenian_za*: TKeySym = 0x000014BD + XKc_Armenian_E*: TKeySym = 0x000014BE + XK_Armenian_e*: TKeySym = 0x000014BF + XKc_Armenian_AT*: TKeySym = 0x000014C0 + XK_Armenian_at*: TKeySym = 0x000014C1 + XKc_Armenian_TO*: TKeySym = 0x000014C2 + XK_Armenian_to*: TKeySym = 0x000014C3 + XKc_Armenian_ZHE*: TKeySym = 0x000014C4 + XK_Armenian_zhe*: TKeySym = 0x000014C5 + XKc_Armenian_INI*: TKeySym = 0x000014C6 + XK_Armenian_ini*: TKeySym = 0x000014C7 + XKc_Armenian_LYUN*: TKeySym = 0x000014C8 + XK_Armenian_lyun*: TKeySym = 0x000014C9 + XKc_Armenian_KHE*: TKeySym = 0x000014CA + XK_Armenian_khe*: TKeySym = 0x000014CB + XKc_Armenian_TSA*: TKeySym = 0x000014CC + XK_Armenian_tsa*: TKeySym = 0x000014CD + XKc_Armenian_KEN*: TKeySym = 0x000014CE + XK_Armenian_ken*: TKeySym = 0x000014CF + XKc_Armenian_HO*: TKeySym = 0x000014D0 + XK_Armenian_ho*: TKeySym = 0x000014D1 + XKc_Armenian_DZA*: TKeySym = 0x000014D2 + XK_Armenian_dza*: TKeySym = 0x000014D3 + XKc_Armenian_GHAT*: TKeySym = 0x000014D4 + XK_Armenian_ghat*: TKeySym = 0x000014D5 + XKc_Armenian_TCHE*: TKeySym = 0x000014D6 + XK_Armenian_tche*: TKeySym = 0x000014D7 + XKc_Armenian_MEN*: TKeySym = 0x000014D8 + XK_Armenian_men*: TKeySym = 0x000014D9 + XKc_Armenian_HI*: TKeySym = 0x000014DA + XK_Armenian_hi*: TKeySym = 0x000014DB + XKc_Armenian_NU*: TKeySym = 0x000014DC + XK_Armenian_nu*: TKeySym = 0x000014DD + XKc_Armenian_SHA*: TKeySym = 0x000014DE + XK_Armenian_sha*: TKeySym = 0x000014DF + XKc_Armenian_VO*: TKeySym = 0x000014E0 + XK_Armenian_vo*: TKeySym = 0x000014E1 + XKc_Armenian_CHA*: TKeySym = 0x000014E2 + XK_Armenian_cha*: TKeySym = 0x000014E3 + XKc_Armenian_PE*: TKeySym = 0x000014E4 + XK_Armenian_pe*: TKeySym = 0x000014E5 + XKc_Armenian_JE*: TKeySym = 0x000014E6 + XK_Armenian_je*: TKeySym = 0x000014E7 + XKc_Armenian_RA*: TKeySym = 0x000014E8 + XK_Armenian_ra*: TKeySym = 0x000014E9 + XKc_Armenian_SE*: TKeySym = 0x000014EA + XK_Armenian_se*: TKeySym = 0x000014EB + XKc_Armenian_VEV*: TKeySym = 0x000014EC + XK_Armenian_vev*: TKeySym = 0x000014ED + XKc_Armenian_TYUN*: TKeySym = 0x000014EE + XK_Armenian_tyun*: TKeySym = 0x000014EF + XKc_Armenian_RE*: TKeySym = 0x000014F0 + XK_Armenian_re*: TKeySym = 0x000014F1 + XKc_Armenian_TSO*: TKeySym = 0x000014F2 + XK_Armenian_tso*: TKeySym = 0x000014F3 + XKc_Armenian_VYUN*: TKeySym = 0x000014F4 + XK_Armenian_vyun*: TKeySym = 0x000014F5 + XKc_Armenian_PYUR*: TKeySym = 0x000014F6 + XK_Armenian_pyur*: TKeySym = 0x000014F7 + XKc_Armenian_KE*: TKeySym = 0x000014F8 + XK_Armenian_ke*: TKeySym = 0x000014F9 + XKc_Armenian_O*: TKeySym = 0x000014FA + XK_Armenian_o*: TKeySym = 0x000014FB + XKc_Armenian_FE*: TKeySym = 0x000014FC + XK_Armenian_fe*: TKeySym = 0x000014FD + XK_Armenian_apostrophe*: TKeySym = 0x000014FE + XK_Armenian_section_sign*: TKeySym = 0x000014FF # XK_ARMENIAN #* # * Georgian @@ -1723,45 +1724,45 @@ when defined(XK_ARMENIAN) or true: when defined(XK_GEORGIAN) or true: const - XK_Georgian_an* = 0x000015D0 - XK_Georgian_ban* = 0x000015D1 - XK_Georgian_gan* = 0x000015D2 - XK_Georgian_don* = 0x000015D3 - XK_Georgian_en* = 0x000015D4 - XK_Georgian_vin* = 0x000015D5 - XK_Georgian_zen* = 0x000015D6 - XK_Georgian_tan* = 0x000015D7 - XK_Georgian_in* = 0x000015D8 - XK_Georgian_kan* = 0x000015D9 - XK_Georgian_las* = 0x000015DA - XK_Georgian_man* = 0x000015DB - XK_Georgian_nar* = 0x000015DC - XK_Georgian_on* = 0x000015DD - XK_Georgian_par* = 0x000015DE - XK_Georgian_zhar* = 0x000015DF - XK_Georgian_rae* = 0x000015E0 - XK_Georgian_san* = 0x000015E1 - XK_Georgian_tar* = 0x000015E2 - XK_Georgian_un* = 0x000015E3 - XK_Georgian_phar* = 0x000015E4 - XK_Georgian_khar* = 0x000015E5 - XK_Georgian_ghan* = 0x000015E6 - XK_Georgian_qar* = 0x000015E7 - XK_Georgian_shin* = 0x000015E8 - XK_Georgian_chin* = 0x000015E9 - XK_Georgian_can* = 0x000015EA - XK_Georgian_jil* = 0x000015EB - XK_Georgian_cil* = 0x000015EC - XK_Georgian_char* = 0x000015ED - XK_Georgian_xan* = 0x000015EE - XK_Georgian_jhan* = 0x000015EF - XK_Georgian_hae* = 0x000015F0 - XK_Georgian_he* = 0x000015F1 - XK_Georgian_hie* = 0x000015F2 - XK_Georgian_we* = 0x000015F3 - XK_Georgian_har* = 0x000015F4 - XK_Georgian_hoe* = 0x000015F5 - XK_Georgian_fi* = 0x000015F6 + XK_Georgian_an*: TKeySym = 0x000015D0 + XK_Georgian_ban*: TKeySym = 0x000015D1 + XK_Georgian_gan*: TKeySym = 0x000015D2 + XK_Georgian_don*: TKeySym = 0x000015D3 + XK_Georgian_en*: TKeySym = 0x000015D4 + XK_Georgian_vin*: TKeySym = 0x000015D5 + XK_Georgian_zen*: TKeySym = 0x000015D6 + XK_Georgian_tan*: TKeySym = 0x000015D7 + XK_Georgian_in*: TKeySym = 0x000015D8 + XK_Georgian_kan*: TKeySym = 0x000015D9 + XK_Georgian_las*: TKeySym = 0x000015DA + XK_Georgian_man*: TKeySym = 0x000015DB + XK_Georgian_nar*: TKeySym = 0x000015DC + XK_Georgian_on*: TKeySym = 0x000015DD + XK_Georgian_par*: TKeySym = 0x000015DE + XK_Georgian_zhar*: TKeySym = 0x000015DF + XK_Georgian_rae*: TKeySym = 0x000015E0 + XK_Georgian_san*: TKeySym = 0x000015E1 + XK_Georgian_tar*: TKeySym = 0x000015E2 + XK_Georgian_un*: TKeySym = 0x000015E3 + XK_Georgian_phar*: TKeySym = 0x000015E4 + XK_Georgian_khar*: TKeySym = 0x000015E5 + XK_Georgian_ghan*: TKeySym = 0x000015E6 + XK_Georgian_qar*: TKeySym = 0x000015E7 + XK_Georgian_shin*: TKeySym = 0x000015E8 + XK_Georgian_chin*: TKeySym = 0x000015E9 + XK_Georgian_can*: TKeySym = 0x000015EA + XK_Georgian_jil*: TKeySym = 0x000015EB + XK_Georgian_cil*: TKeySym = 0x000015EC + XK_Georgian_char*: TKeySym = 0x000015ED + XK_Georgian_xan*: TKeySym = 0x000015EE + XK_Georgian_jhan*: TKeySym = 0x000015EF + XK_Georgian_hae*: TKeySym = 0x000015F0 + XK_Georgian_he*: TKeySym = 0x000015F1 + XK_Georgian_hie*: TKeySym = 0x000015F2 + XK_Georgian_we*: TKeySym = 0x000015F3 + XK_Georgian_har*: TKeySym = 0x000015F4 + XK_Georgian_hoe*: TKeySym = 0x000015F5 + XK_Georgian_fi*: TKeySym = 0x000015F6 # XK_GEORGIAN #* # * Azeri (and other Turkic or Caucasian languages of ex-USSR) @@ -1771,35 +1772,35 @@ when defined(XK_GEORGIAN) or true: when defined(XK_CAUCASUS) or true: # latin const - XKc_Ccedillaabovedot* = 0x000016A2 - XKc_Xabovedot* = 0x000016A3 - XKc_Qabovedot* = 0x000016A5 - XKc_Ibreve* = 0x000016A6 - XKc_IE* = 0x000016A7 - XKc_UO* = 0x000016A8 - XKc_Zstroke* = 0x000016A9 - XKc_Gcaron* = 0x000016AA - XKc_Obarred* = 0x000016AF - XK_ccedillaabovedot* = 0x000016B2 - XK_xabovedot* = 0x000016B3 - XKc_Ocaron* = 0x000016B4 - XK_qabovedot* = 0x000016B5 - XK_ibreve* = 0x000016B6 - XK_ie* = 0x000016B7 - XK_uo* = 0x000016B8 - XK_zstroke* = 0x000016B9 - XK_gcaron* = 0x000016BA - XK_ocaron* = 0x000016BD - XK_obarred* = 0x000016BF - XKc_SCHWA* = 0x000016C6 - XK_schwa* = 0x000016F6 # those are not really Caucasus, but I put them here for now + XKc_Ccedillaabovedot*: TKeySym = 0x000016A2 + XKc_Xabovedot*: TKeySym = 0x000016A3 + XKc_Qabovedot*: TKeySym = 0x000016A5 + XKc_Ibreve*: TKeySym = 0x000016A6 + XKc_IE*: TKeySym = 0x000016A7 + XKc_UO*: TKeySym = 0x000016A8 + XKc_Zstroke*: TKeySym = 0x000016A9 + XKc_Gcaron*: TKeySym = 0x000016AA + XKc_Obarred*: TKeySym = 0x000016AF + XK_ccedillaabovedot*: TKeySym = 0x000016B2 + XK_xabovedot*: TKeySym = 0x000016B3 + XKc_Ocaron*: TKeySym = 0x000016B4 + XK_qabovedot*: TKeySym = 0x000016B5 + XK_ibreve*: TKeySym = 0x000016B6 + XK_ie*: TKeySym = 0x000016B7 + XK_uo*: TKeySym = 0x000016B8 + XK_zstroke*: TKeySym = 0x000016B9 + XK_gcaron*: TKeySym = 0x000016BA + XK_ocaron*: TKeySym = 0x000016BD + XK_obarred*: TKeySym = 0x000016BF + XKc_SCHWA*: TKeySym = 0x000016C6 + XK_schwa*: TKeySym = 0x000016F6 # those are not really Caucasus, but I put them here for now\ # For Inupiak - XKc_Lbelowdot* = 0x000016D1 - XKc_Lstrokebelowdot* = 0x000016D2 - XK_lbelowdot* = 0x000016E1 - XK_lstrokebelowdot* = 0x000016E2 # For Guarani - XKc_Gtilde* = 0x000016D3 - XK_gtilde* = 0x000016E3 + XKc_Lbelowdot*: TKeySym = 0x000016D1 + XKc_Lstrokebelowdot*: TKeySym = 0x000016D2 + XK_lbelowdot*: TKeySym = 0x000016E1 + XK_lstrokebelowdot*: TKeySym = 0x000016E2 # For Guarani + XKc_Gtilde*: TKeySym = 0x000016D3 + XK_gtilde*: TKeySym = 0x000016E3 # XK_CAUCASUS #* # * Vietnamese @@ -1808,118 +1809,118 @@ when defined(XK_CAUCASUS) or true: when defined(XK_VIETNAMESE) or true: const - XKc_Abelowdot* = 0x00001EA0 - XK_abelowdot* = 0x00001EA1 - XKc_Ahook* = 0x00001EA2 - XK_ahook* = 0x00001EA3 - XKc_Acircumflexacute* = 0x00001EA4 - XK_acircumflexacute* = 0x00001EA5 - XKc_Acircumflexgrave* = 0x00001EA6 - XK_acircumflexgrave* = 0x00001EA7 - XKc_Acircumflexhook* = 0x00001EA8 - XK_acircumflexhook* = 0x00001EA9 - XKc_Acircumflextilde* = 0x00001EAA - XK_acircumflextilde* = 0x00001EAB - XKc_Acircumflexbelowdot* = 0x00001EAC - XK_acircumflexbelowdot* = 0x00001EAD - XKc_Abreveacute* = 0x00001EAE - XK_abreveacute* = 0x00001EAF - XKc_Abrevegrave* = 0x00001EB0 - XK_abrevegrave* = 0x00001EB1 - XKc_Abrevehook* = 0x00001EB2 - XK_abrevehook* = 0x00001EB3 - XKc_Abrevetilde* = 0x00001EB4 - XK_abrevetilde* = 0x00001EB5 - XKc_Abrevebelowdot* = 0x00001EB6 - XK_abrevebelowdot* = 0x00001EB7 - XKc_Ebelowdot* = 0x00001EB8 - XK_ebelowdot* = 0x00001EB9 - XKc_Ehook* = 0x00001EBA - XK_ehook* = 0x00001EBB - XKc_Etilde* = 0x00001EBC - XK_etilde* = 0x00001EBD - XKc_Ecircumflexacute* = 0x00001EBE - XK_ecircumflexacute* = 0x00001EBF - XKc_Ecircumflexgrave* = 0x00001EC0 - XK_ecircumflexgrave* = 0x00001EC1 - XKc_Ecircumflexhook* = 0x00001EC2 - XK_ecircumflexhook* = 0x00001EC3 - XKc_Ecircumflextilde* = 0x00001EC4 - XK_ecircumflextilde* = 0x00001EC5 - XKc_Ecircumflexbelowdot* = 0x00001EC6 - XK_ecircumflexbelowdot* = 0x00001EC7 - XKc_Ihook* = 0x00001EC8 - XK_ihook* = 0x00001EC9 - XKc_Ibelowdot* = 0x00001ECA - XK_ibelowdot* = 0x00001ECB - XKc_Obelowdot* = 0x00001ECC - XK_obelowdot* = 0x00001ECD - XKc_Ohook* = 0x00001ECE - XK_ohook* = 0x00001ECF - XKc_Ocircumflexacute* = 0x00001ED0 - XK_ocircumflexacute* = 0x00001ED1 - XKc_Ocircumflexgrave* = 0x00001ED2 - XK_ocircumflexgrave* = 0x00001ED3 - XKc_Ocircumflexhook* = 0x00001ED4 - XK_ocircumflexhook* = 0x00001ED5 - XKc_Ocircumflextilde* = 0x00001ED6 - XK_ocircumflextilde* = 0x00001ED7 - XKc_Ocircumflexbelowdot* = 0x00001ED8 - XK_ocircumflexbelowdot* = 0x00001ED9 - XKc_Ohornacute* = 0x00001EDA - XK_ohornacute* = 0x00001EDB - XKc_Ohorngrave* = 0x00001EDC - XK_ohorngrave* = 0x00001EDD - XKc_Ohornhook* = 0x00001EDE - XK_ohornhook* = 0x00001EDF - XKc_Ohorntilde* = 0x00001EE0 - XK_ohorntilde* = 0x00001EE1 - XKc_Ohornbelowdot* = 0x00001EE2 - XK_ohornbelowdot* = 0x00001EE3 - XKc_Ubelowdot* = 0x00001EE4 - XK_ubelowdot* = 0x00001EE5 - XKc_Uhook* = 0x00001EE6 - XK_uhook* = 0x00001EE7 - XKc_Uhornacute* = 0x00001EE8 - XK_uhornacute* = 0x00001EE9 - XKc_Uhorngrave* = 0x00001EEA - XK_uhorngrave* = 0x00001EEB - XKc_Uhornhook* = 0x00001EEC - XK_uhornhook* = 0x00001EED - XKc_Uhorntilde* = 0x00001EEE - XK_uhorntilde* = 0x00001EEF - XKc_Uhornbelowdot* = 0x00001EF0 - XK_uhornbelowdot* = 0x00001EF1 - XKc_Ybelowdot* = 0x00001EF4 - XK_ybelowdot* = 0x00001EF5 - XKc_Yhook* = 0x00001EF6 - XK_yhook* = 0x00001EF7 - XKc_Ytilde* = 0x00001EF8 - XK_ytilde* = 0x00001EF9 - XKc_Ohorn* = 0x00001EFA # U+01a0 - XK_ohorn* = 0x00001EFB # U+01a1 - XKc_Uhorn* = 0x00001EFC # U+01af - XK_uhorn* = 0x00001EFD # U+01b0 - XK_combining_tilde* = 0x00001E9F # U+0303 - XK_combining_grave* = 0x00001EF2 # U+0300 - XK_combining_acute* = 0x00001EF3 # U+0301 - XK_combining_hook* = 0x00001EFE # U+0309 - XK_combining_belowdot* = 0x00001EFF # U+0323 + XKc_Abelowdot*: TKeySym = 0x00001EA0 + XK_abelowdot*: TKeySym = 0x00001EA1 + XKc_Ahook*: TKeySym = 0x00001EA2 + XK_ahook*: TKeySym = 0x00001EA3 + XKc_Acircumflexacute*: TKeySym = 0x00001EA4 + XK_acircumflexacute*: TKeySym = 0x00001EA5 + XKc_Acircumflexgrave*: TKeySym = 0x00001EA6 + XK_acircumflexgrave*: TKeySym = 0x00001EA7 + XKc_Acircumflexhook*: TKeySym = 0x00001EA8 + XK_acircumflexhook*: TKeySym = 0x00001EA9 + XKc_Acircumflextilde*: TKeySym = 0x00001EAA + XK_acircumflextilde*: TKeySym = 0x00001EAB + XKc_Acircumflexbelowdot*: TKeySym = 0x00001EAC + XK_acircumflexbelowdot*: TKeySym = 0x00001EAD + XKc_Abreveacute*: TKeySym = 0x00001EAE + XK_abreveacute*: TKeySym = 0x00001EAF + XKc_Abrevegrave*: TKeySym = 0x00001EB0 + XK_abrevegrave*: TKeySym = 0x00001EB1 + XKc_Abrevehook*: TKeySym = 0x00001EB2 + XK_abrevehook*: TKeySym = 0x00001EB3 + XKc_Abrevetilde*: TKeySym = 0x00001EB4 + XK_abrevetilde*: TKeySym = 0x00001EB5 + XKc_Abrevebelowdot*: TKeySym = 0x00001EB6 + XK_abrevebelowdot*: TKeySym = 0x00001EB7 + XKc_Ebelowdot*: TKeySym = 0x00001EB8 + XK_ebelowdot*: TKeySym = 0x00001EB9 + XKc_Ehook*: TKeySym = 0x00001EBA + XK_ehook*: TKeySym = 0x00001EBB + XKc_Etilde*: TKeySym = 0x00001EBC + XK_etilde*: TKeySym = 0x00001EBD + XKc_Ecircumflexacute*: TKeySym = 0x00001EBE + XK_ecircumflexacute*: TKeySym = 0x00001EBF + XKc_Ecircumflexgrave*: TKeySym = 0x00001EC0 + XK_ecircumflexgrave*: TKeySym = 0x00001EC1 + XKc_Ecircumflexhook*: TKeySym = 0x00001EC2 + XK_ecircumflexhook*: TKeySym = 0x00001EC3 + XKc_Ecircumflextilde*: TKeySym = 0x00001EC4 + XK_ecircumflextilde*: TKeySym = 0x00001EC5 + XKc_Ecircumflexbelowdot*: TKeySym = 0x00001EC6 + XK_ecircumflexbelowdot*: TKeySym = 0x00001EC7 + XKc_Ihook*: TKeySym = 0x00001EC8 + XK_ihook*: TKeySym = 0x00001EC9 + XKc_Ibelowdot*: TKeySym = 0x00001ECA + XK_ibelowdot*: TKeySym = 0x00001ECB + XKc_Obelowdot*: TKeySym = 0x00001ECC + XK_obelowdot*: TKeySym = 0x00001ECD + XKc_Ohook*: TKeySym = 0x00001ECE + XK_ohook*: TKeySym = 0x00001ECF + XKc_Ocircumflexacute*: TKeySym = 0x00001ED0 + XK_ocircumflexacute*: TKeySym = 0x00001ED1 + XKc_Ocircumflexgrave*: TKeySym = 0x00001ED2 + XK_ocircumflexgrave*: TKeySym = 0x00001ED3 + XKc_Ocircumflexhook*: TKeySym = 0x00001ED4 + XK_ocircumflexhook*: TKeySym = 0x00001ED5 + XKc_Ocircumflextilde*: TKeySym = 0x00001ED6 + XK_ocircumflextilde*: TKeySym = 0x00001ED7 + XKc_Ocircumflexbelowdot*: TKeySym = 0x00001ED8 + XK_ocircumflexbelowdot*: TKeySym = 0x00001ED9 + XKc_Ohornacute*: TKeySym = 0x00001EDA + XK_ohornacute*: TKeySym = 0x00001EDB + XKc_Ohorngrave*: TKeySym = 0x00001EDC + XK_ohorngrave*: TKeySym = 0x00001EDD + XKc_Ohornhook*: TKeySym = 0x00001EDE + XK_ohornhook*: TKeySym = 0x00001EDF + XKc_Ohorntilde*: TKeySym = 0x00001EE0 + XK_ohorntilde*: TKeySym = 0x00001EE1 + XKc_Ohornbelowdot*: TKeySym = 0x00001EE2 + XK_ohornbelowdot*: TKeySym = 0x00001EE3 + XKc_Ubelowdot*: TKeySym = 0x00001EE4 + XK_ubelowdot*: TKeySym = 0x00001EE5 + XKc_Uhook*: TKeySym = 0x00001EE6 + XK_uhook*: TKeySym = 0x00001EE7 + XKc_Uhornacute*: TKeySym = 0x00001EE8 + XK_uhornacute*: TKeySym = 0x00001EE9 + XKc_Uhorngrave*: TKeySym = 0x00001EEA + XK_uhorngrave*: TKeySym = 0x00001EEB + XKc_Uhornhook*: TKeySym = 0x00001EEC + XK_uhornhook*: TKeySym = 0x00001EED + XKc_Uhorntilde*: TKeySym = 0x00001EEE + XK_uhorntilde*: TKeySym = 0x00001EEF + XKc_Uhornbelowdot*: TKeySym = 0x00001EF0 + XK_uhornbelowdot*: TKeySym = 0x00001EF1 + XKc_Ybelowdot*: TKeySym = 0x00001EF4 + XK_ybelowdot*: TKeySym = 0x00001EF5 + XKc_Yhook*: TKeySym = 0x00001EF6 + XK_yhook*: TKeySym = 0x00001EF7 + XKc_Ytilde*: TKeySym = 0x00001EF8 + XK_ytilde*: TKeySym = 0x00001EF9 + XKc_Ohorn*: TKeySym = 0x00001EFA # U+01a0 + XK_ohorn*: TKeySym = 0x00001EFB # U+01a1 + XKc_Uhorn*: TKeySym = 0x00001EFC # U+01af + XK_uhorn*: TKeySym = 0x00001EFD # U+01b0 + XK_combining_tilde*: TKeySym = 0x00001E9F # U+0303 + XK_combining_grave*: TKeySym = 0x00001EF2 # U+0300 + XK_combining_acute*: TKeySym = 0x00001EF3 # U+0301 + XK_combining_hook*: TKeySym = 0x00001EFE # U+0309 + XK_combining_belowdot*: TKeySym = 0x00001EFF # U+0323 # XK_VIETNAMESE when defined(XK_CURRENCY) or true: const - XK_EcuSign* = 0x000020A0 - XK_ColonSign* = 0x000020A1 - XK_CruzeiroSign* = 0x000020A2 - XK_FFrancSign* = 0x000020A3 - XK_LiraSign* = 0x000020A4 - XK_MillSign* = 0x000020A5 - XK_NairaSign* = 0x000020A6 - XK_PesetaSign* = 0x000020A7 - XK_RupeeSign* = 0x000020A8 - XK_WonSign* = 0x000020A9 - XK_NewSheqelSign* = 0x000020AA - XK_DongSign* = 0x000020AB - XK_EuroSign* = 0x000020AC + XK_EcuSign*: TKeySym = 0x000020A0 + XK_ColonSign*: TKeySym = 0x000020A1 + XK_CruzeiroSign*: TKeySym = 0x000020A2 + XK_FFrancSign*: TKeySym = 0x000020A3 + XK_LiraSign*: TKeySym = 0x000020A4 + XK_MillSign*: TKeySym = 0x000020A5 + XK_NairaSign*: TKeySym = 0x000020A6 + XK_PesetaSign*: TKeySym = 0x000020A7 + XK_RupeeSign*: TKeySym = 0x000020A8 + XK_WonSign*: TKeySym = 0x000020A9 + XK_NewSheqelSign*: TKeySym = 0x000020AA + XK_DongSign*: TKeySym = 0x000020AB + XK_EuroSign*: TKeySym = 0x000020AC # implementation diff --git a/lib/wrappers/x11/xlib.nim b/lib/wrappers/x11/xlib.nim index e6010feb7..5ccacdd45 100644 --- a/lib/wrappers/x11/xlib.nim +++ b/lib/wrappers/x11/xlib.nim @@ -1811,210 +1811,217 @@ proc XSetAuthorization*(para1: cstring, para2: cint, para3: cstring, para4: cint # _Xmbtowc? # _Xwctomb? # -when defined(MACROS): - proc ConnectionNumber*(dpy: PDisplay): cint - proc RootWindow*(dpy: PDisplay, scr: cint): TWindow - proc DefaultScreen*(dpy: PDisplay): cint - proc DefaultRootWindow*(dpy: PDisplay): TWindow - proc DefaultVisual*(dpy: PDisplay, scr: cint): PVisual - proc DefaultGC*(dpy: PDisplay, scr: cint): TGC - proc BlackPixel*(dpy: PDisplay, scr: cint): culong - proc WhitePixel*(dpy: PDisplay, scr: cint): culong - proc QLength*(dpy: PDisplay): cint - proc DisplayWidth*(dpy: PDisplay, scr: cint): cint - proc DisplayHeight*(dpy: PDisplay, scr: cint): cint - proc DisplayWidthMM*(dpy: PDisplay, scr: cint): cint - proc DisplayHeightMM*(dpy: PDisplay, scr: cint): cint - proc DisplayPlanes*(dpy: PDisplay, scr: cint): cint - proc DisplayCells*(dpy: PDisplay, scr: cint): cint - proc ScreenCount*(dpy: PDisplay): cint - proc ServerVendor*(dpy: PDisplay): cstring - proc ProtocolVersion*(dpy: PDisplay): cint - proc ProtocolRevision*(dpy: PDisplay): cint - proc VendorRelease*(dpy: PDisplay): cint - proc DisplayString*(dpy: PDisplay): cstring - proc DefaultDepth*(dpy: PDisplay, scr: cint): cint - proc DefaultColormap*(dpy: PDisplay, scr: cint): TColormap - proc BitmapUnit*(dpy: PDisplay): cint - proc BitmapBitOrder*(dpy: PDisplay): cint - proc BitmapPad*(dpy: PDisplay): cint - proc ImageByteOrder*(dpy: PDisplay): cint - proc NextRequest*(dpy: PDisplay): culong - proc LastKnownRequestProcessed*(dpy: PDisplay): culong - proc ScreenOfDisplay*(dpy: PDisplay, scr: cint): PScreen - proc DefaultScreenOfDisplay*(dpy: PDisplay): PScreen - proc DisplayOfScreen*(s: PScreen): PDisplay - proc RootWindowOfScreen*(s: PScreen): TWindow - proc BlackPixelOfScreen*(s: PScreen): culong - proc WhitePixelOfScreen*(s: PScreen): culong - proc DefaultColormapOfScreen*(s: PScreen): TColormap - proc DefaultDepthOfScreen*(s: PScreen): cint - proc DefaultGCOfScreen*(s: PScreen): TGC - proc DefaultVisualOfScreen*(s: PScreen): PVisual - proc WidthOfScreen*(s: PScreen): cint - proc HeightOfScreen*(s: PScreen): cint - proc WidthMMOfScreen*(s: PScreen): cint - proc HeightMMOfScreen*(s: PScreen): cint - proc PlanesOfScreen*(s: PScreen): cint - proc CellsOfScreen*(s: PScreen): cint - proc MinCmapsOfScreen*(s: PScreen): cint - proc MaxCmapsOfScreen*(s: PScreen): cint - proc DoesSaveUnders*(s: PScreen): TBool - proc DoesBackingStore*(s: PScreen): cint - proc EventMaskOfScreen*(s: PScreen): clong - proc XAllocID*(dpy: PDisplay): TXID +#when defined(MACROS): +proc ConnectionNumber*(dpy: PDisplay): cint +proc RootWindow*(dpy: PDisplay, scr: cint): TWindow +proc DefaultScreen*(dpy: PDisplay): cint +proc DefaultRootWindow*(dpy: PDisplay): TWindow +proc DefaultVisual*(dpy: PDisplay, scr: cint): PVisual +proc DefaultGC*(dpy: PDisplay, scr: cint): TGC +proc BlackPixel*(dpy: PDisplay, scr: cint): culong +proc WhitePixel*(dpy: PDisplay, scr: cint): culong +proc QLength*(dpy: PDisplay): cint +proc DisplayWidth*(dpy: PDisplay, scr: cint): cint +proc DisplayHeight*(dpy: PDisplay, scr: cint): cint +proc DisplayWidthMM*(dpy: PDisplay, scr: cint): cint +proc DisplayHeightMM*(dpy: PDisplay, scr: cint): cint +proc DisplayPlanes*(dpy: PDisplay, scr: cint): cint +proc DisplayCells*(dpy: PDisplay, scr: cint): cint +proc ScreenCount*(dpy: PDisplay): cint +proc ServerVendor*(dpy: PDisplay): cstring +proc ProtocolVersion*(dpy: PDisplay): cint +proc ProtocolRevision*(dpy: PDisplay): cint +proc VendorRelease*(dpy: PDisplay): cint +proc DisplayString*(dpy: PDisplay): cstring +proc DefaultDepth*(dpy: PDisplay, scr: cint): cint +proc DefaultColormap*(dpy: PDisplay, scr: cint): TColormap +proc BitmapUnit*(dpy: PDisplay): cint +proc BitmapBitOrder*(dpy: PDisplay): cint +proc BitmapPad*(dpy: PDisplay): cint +proc ImageByteOrder*(dpy: PDisplay): cint +proc NextRequest*(dpy: PDisplay): culong +proc LastKnownRequestProcessed*(dpy: PDisplay): culong +proc ScreenOfDisplay*(dpy: PDisplay, scr: cint): PScreen +proc DefaultScreenOfDisplay*(dpy: PDisplay): PScreen +proc DisplayOfScreen*(s: PScreen): PDisplay +proc RootWindowOfScreen*(s: PScreen): TWindow +proc BlackPixelOfScreen*(s: PScreen): culong +proc WhitePixelOfScreen*(s: PScreen): culong +proc DefaultColormapOfScreen*(s: PScreen): TColormap +proc DefaultDepthOfScreen*(s: PScreen): cint +proc DefaultGCOfScreen*(s: PScreen): TGC +proc DefaultVisualOfScreen*(s: PScreen): PVisual +proc WidthOfScreen*(s: PScreen): cint +proc HeightOfScreen*(s: PScreen): cint +proc WidthMMOfScreen*(s: PScreen): cint +proc HeightMMOfScreen*(s: PScreen): cint +proc PlanesOfScreen*(s: PScreen): cint +proc CellsOfScreen*(s: PScreen): cint +proc MinCmapsOfScreen*(s: PScreen): cint +proc MaxCmapsOfScreen*(s: PScreen): cint +proc DoesSaveUnders*(s: PScreen): TBool +proc DoesBackingStore*(s: PScreen): cint +proc EventMaskOfScreen*(s: PScreen): clong +proc XAllocID*(dpy: PDisplay): TXID # implementation -when defined(MACROS): - proc ConnectionNumber(dpy: PDisplay): cint = - ConnectionNumber = (PXPrivDisplay(dpy))[] .fd +#when defined(MACROS): +template privDisp : expr = cast[PXPrivDisplay](dpy) + +proc ConnectionNumber(dpy: PDisplay): cint = + privDisp.fd - proc RootWindow(dpy: PDisplay, scr: cint): TWindow = - RootWindow = (ScreenOfDisplay(dpy, scr))[] .root +proc RootWindow(dpy: PDisplay, scr: cint): TWindow = + ScreenOfDisplay(dpy, scr).root - proc DefaultScreen(dpy: PDisplay): cint = - DefaultScreen = (PXPrivDisplay(dpy))[] .default_screen +proc DefaultScreen(dpy: PDisplay): cint = + privDisp.default_screen - proc DefaultRootWindow(dpy: PDisplay): TWindow = - DefaultRootWindow = (ScreenOfDisplay(dpy, DefaultScreen(dpy)))[] .root +proc DefaultRootWindow(dpy: PDisplay): TWindow = + ScreenOfDisplay(dpy, DefaultScreen(dpy)).root - proc DefaultVisual(dpy: PDisplay, scr: cint): PVisual = - DefaultVisual = (ScreenOfDisplay(dpy, scr))[] .root_visual +proc DefaultVisual(dpy: PDisplay, scr: cint): PVisual = + ScreenOfDisplay(dpy, scr).root_visual - proc DefaultGC(dpy: PDisplay, scr: cint): TGC = - DefaultGC = (ScreenOfDisplay(dpy, scr))[] .default_gc +proc DefaultGC(dpy: PDisplay, scr: cint): TGC = + ScreenOfDisplay(dpy, scr).default_gc - proc BlackPixel(dpy: PDisplay, scr: cint): culong = - BlackPixel = (ScreenOfDisplay(dpy, scr))[] .black_pixel +proc BlackPixel(dpy: PDisplay, scr: cint): culong = + ScreenOfDisplay(dpy, scr).black_pixel - proc WhitePixel(dpy: PDisplay, scr: cint): culong = - WhitePixel = (ScreenOfDisplay(dpy, scr))[] .white_pixel +proc WhitePixel(dpy: PDisplay, scr: cint): culong = + ScreenOfDisplay(dpy, scr).white_pixel - proc QLength(dpy: PDisplay): cint = - QLength = (PXPrivDisplay(dpy))[] .qlen +proc QLength(dpy: PDisplay): cint = + privDisp.qlen - proc DisplayWidth(dpy: PDisplay, scr: cint): cint = - DisplayWidth = (ScreenOfDisplay(dpy, scr))[] .width +proc DisplayWidth(dpy: PDisplay, scr: cint): cint = + ScreenOfDisplay(dpy, scr).width - proc DisplayHeight(dpy: PDisplay, scr: cint): cint = - DisplayHeight = (ScreenOfDisplay(dpy, scr))[] .height +proc DisplayHeight(dpy: PDisplay, scr: cint): cint = + ScreenOfDisplay(dpy, scr).height - proc DisplayWidthMM(dpy: PDisplay, scr: cint): cint = - DisplayWidthMM = (ScreenOfDisplay(dpy, scr))[] .mwidth +proc DisplayWidthMM(dpy: PDisplay, scr: cint): cint = + ScreenOfDisplay(dpy, scr).mwidth - proc DisplayHeightMM(dpy: PDisplay, scr: cint): cint = - DisplayHeightMM = (ScreenOfDisplay(dpy, scr))[] .mheight +proc DisplayHeightMM(dpy: PDisplay, scr: cint): cint = + ScreenOfDisplay(dpy, scr).mheight - proc DisplayPlanes(dpy: PDisplay, scr: cint): cint = - DisplayPlanes = (ScreenOfDisplay(dpy, scr))[] .root_depth +proc DisplayPlanes(dpy: PDisplay, scr: cint): cint = + ScreenOfDisplay(dpy, scr).root_depth - proc DisplayCells(dpy: PDisplay, scr: cint): cint = - DisplayCells = (DefaultVisual(dpy, scr))[] .map_entries +proc DisplayCells(dpy: PDisplay, scr: cint): cint = + DefaultVisual(dpy, scr).map_entries - proc ScreenCount(dpy: PDisplay): cint = - ScreenCount = (PXPrivDisplay(dpy))[] .nscreens +proc ScreenCount(dpy: PDisplay): cint = + privDisp.nscreens - proc ServerVendor(dpy: PDisplay): cstring = - ServerVendor = (PXPrivDisplay(dpy))[] .vendor +proc ServerVendor(dpy: PDisplay): cstring = + privDisp.vendor - proc ProtocolVersion(dpy: PDisplay): cint = - ProtocolVersion = (PXPrivDisplay(dpy))[] .proto_major_version +proc ProtocolVersion(dpy: PDisplay): cint = + privDisp.proto_major_version - proc ProtocolRevision(dpy: PDisplay): cint = - ProtocolRevision = (PXPrivDisplay(dpy))[] .proto_minor_version +proc ProtocolRevision(dpy: PDisplay): cint = + privDisp.proto_minor_version - proc VendorRelease(dpy: PDisplay): cint = - VendorRelease = (PXPrivDisplay(dpy))[] .release +proc VendorRelease(dpy: PDisplay): cint = + privDisp.release - proc DisplayString(dpy: PDisplay): cstring = - DisplayString = (PXPrivDisplay(dpy))[] .display_name +proc DisplayString(dpy: PDisplay): cstring = + privDisp.display_name - proc DefaultDepth(dpy: PDisplay, scr: cint): cint = - DefaultDepth = (ScreenOfDisplay(dpy, scr))[] .root_depth +proc DefaultDepth(dpy: PDisplay, scr: cint): cint = + ScreenOfDisplay(dpy, scr).root_depth - proc DefaultColormap(dpy: PDisplay, scr: cint): TColormap = - DefaultColormap = (ScreenOfDisplay(dpy, scr))[] .cmap +proc DefaultColormap(dpy: PDisplay, scr: cint): TColormap = + ScreenOfDisplay(dpy, scr).cmap - proc BitmapUnit(dpy: PDisplay): cint = - BitmapUnit = (PXPrivDisplay(dpy))[] .bitmap_unit +proc BitmapUnit(dpy: PDisplay): cint = + privDisp.bitmap_unit - proc BitmapBitOrder(dpy: PDisplay): cint = - BitmapBitOrder = (PXPrivDisplay(dpy))[] .bitmap_bit_order +proc BitmapBitOrder(dpy: PDisplay): cint = + privDisp.bitmap_bit_order - proc BitmapPad(dpy: PDisplay): cint = - BitmapPad = (PXPrivDisplay(dpy))[] .bitmap_pad +proc BitmapPad(dpy: PDisplay): cint = + privDisp.bitmap_pad - proc ImageByteOrder(dpy: PDisplay): cint = - ImageByteOrder = (PXPrivDisplay(dpy))[] .byte_order +proc ImageByteOrder(dpy: PDisplay): cint = + privDisp.byte_order - proc NextRequest(dpy: PDisplay): culong = - NextRequest = ((PXPrivDisplay(dpy))[] .request) + 1 +import unsigned +proc NextRequest(dpy: PDisplay): culong = + privDisp.request + 1.culong - proc LastKnownRequestProcessed(dpy: PDisplay): culong = - LastKnownRequestProcessed = (PXPrivDisplay(dpy))[] .last_request_read +proc LastKnownRequestProcessed(dpy: PDisplay): culong = + privDisp.last_request_read - proc ScreenOfDisplay(dpy: PDisplay, scr: cint): PScreen = - ScreenOfDisplay = addr((((PXPrivDisplay(dpy))[] .screens)[scr])) +# from fowltek/pointer_arithm, required for ScreenOfDisplay() +proc offset[A] (some: ptr A; b: int): ptr A = + cast[ptr A](cast[int](some) + (b * sizeof(A))) +proc ScreenOfDisplay(dpy: PDisplay, scr: cint): PScreen = + #addr(((privDisp.screens)[scr])) + privDisp.screens.offset(scr.int) - proc DefaultScreenOfDisplay(dpy: PDisplay): PScreen = - DefaultScreenOfDisplay = ScreenOfDisplay(dpy, DefaultScreen(dpy)) +proc DefaultScreenOfDisplay(dpy: PDisplay): PScreen = + ScreenOfDisplay(dpy, DefaultScreen(dpy)) - proc DisplayOfScreen(s: PScreen): PDisplay = - DisplayOfScreen = s[] .display +proc DisplayOfScreen(s: PScreen): PDisplay = + s.display - proc RootWindowOfScreen(s: PScreen): TWindow = - RootWindowOfScreen = s[] .root +proc RootWindowOfScreen(s: PScreen): TWindow = + s.root - proc BlackPixelOfScreen(s: PScreen): culong = - BlackPixelOfScreen = s[] .black_pixel +proc BlackPixelOfScreen(s: PScreen): culong = + s.black_pixel - proc WhitePixelOfScreen(s: PScreen): culong = - WhitePixelOfScreen = s[] .white_pixel +proc WhitePixelOfScreen(s: PScreen): culong = + s.white_pixel - proc DefaultColormapOfScreen(s: PScreen): TColormap = - DefaultColormapOfScreen = s[] .cmap +proc DefaultColormapOfScreen(s: PScreen): TColormap = + s.cmap - proc DefaultDepthOfScreen(s: PScreen): cint = - DefaultDepthOfScreen = s[] .root_depth +proc DefaultDepthOfScreen(s: PScreen): cint = + s.root_depth - proc DefaultGCOfScreen(s: PScreen): TGC = - DefaultGCOfScreen = s[] .default_gc +proc DefaultGCOfScreen(s: PScreen): TGC = + s.default_gc - proc DefaultVisualOfScreen(s: PScreen): PVisual = - DefaultVisualOfScreen = s[] .root_visual +proc DefaultVisualOfScreen(s: PScreen): PVisual = + s.root_visual - proc WidthOfScreen(s: PScreen): cint = - WidthOfScreen = s[] .width +proc WidthOfScreen(s: PScreen): cint = + s.width - proc HeightOfScreen(s: PScreen): cint = - HeightOfScreen = s[] .height +proc HeightOfScreen(s: PScreen): cint = + s.height - proc WidthMMOfScreen(s: PScreen): cint = - WidthMMOfScreen = s[] .mwidth +proc WidthMMOfScreen(s: PScreen): cint = + s.mwidth - proc HeightMMOfScreen(s: PScreen): cint = - HeightMMOfScreen = s[] .mheight +proc HeightMMOfScreen(s: PScreen): cint = + s.mheight - proc PlanesOfScreen(s: PScreen): cint = - PlanesOfScreen = s[] .root_depth +proc PlanesOfScreen(s: PScreen): cint = + s.root_depth - proc CellsOfScreen(s: PScreen): cint = - CellsOfScreen = (DefaultVisualOfScreen(s))[] .map_entries +proc CellsOfScreen(s: PScreen): cint = + DefaultVisualOfScreen(s).map_entries - proc MinCmapsOfScreen(s: PScreen): cint = - MinCmapsOfScreen = s[] .min_maps +proc MinCmapsOfScreen(s: PScreen): cint = + s.min_maps - proc MaxCmapsOfScreen(s: PScreen): cint = - MaxCmapsOfScreen = s[] .max_maps +proc MaxCmapsOfScreen(s: PScreen): cint = + s.max_maps - proc DoesSaveUnders(s: PScreen): TBool = - DoesSaveUnders = s[] .save_unders +proc DoesSaveUnders(s: PScreen): TBool = + s.save_unders - proc DoesBackingStore(s: PScreen): cint = - DoesBackingStore = s[] .backing_store +proc DoesBackingStore(s: PScreen): cint = + s.backing_store - proc EventMaskOfScreen(s: PScreen): clong = - EventMaskOfScreen = s[] .root_input_mask +proc EventMaskOfScreen(s: PScreen): clong = + s.root_input_mask - proc XAllocID(dpy: PDisplay): TXID = - XAllocID = (PXPrivDisplay(dpy))[] .resource_alloc(dpy) +proc XAllocID(dpy: PDisplay): TXID = + privDisp.resource_alloc(dpy) diff --git a/lib/wrappers/x11/xutil.nim b/lib/wrappers/x11/xutil.nim index b66955927..9a3435aa5 100644 --- a/lib/wrappers/x11/xutil.nim +++ b/lib/wrappers/x11/xutil.nim @@ -1,6 +1,6 @@ import - x, xlib, keysym + x, xlib, keysym, unsigned #const # libX11* = "libX11.so" @@ -356,57 +356,57 @@ proc XWMGeometry*(para1: PDisplay, para2: cint, para3: cstring, para4: cstring, dynlib: libX11, importc.} proc XXorRegion*(para1: TRegion, para2: TRegion, para3: TRegion): cint{.cdecl, dynlib: libX11, importc.} -when defined(MACROS): - proc XDestroyImage*(ximage: PXImage): cint - proc XGetPixel*(ximage: PXImage, x, y: cint): culong - proc XPutPixel*(ximage: PXImage, x, y: cint, pixel: culong): cint - proc XSubImage*(ximage: PXImage, x, y: cint, width, height: cuint): PXImage - proc XAddPixel*(ximage: PXImage, value: clong): cint - proc IsKeypadKey*(keysym: TKeySym): bool - proc IsPrivateKeypadKey*(keysym: TKeySym): bool - proc IsCursorKey*(keysym: TKeySym): bool - proc IsPFKey*(keysym: TKeySym): bool - proc IsFunctionKey*(keysym: TKeySym): bool - proc IsMiscFunctionKey*(keysym: TKeySym): bool - proc IsModifierKey*(keysym: TKeySym): bool - #function XUniqueContext : TXContext; - #function XStringToContext(_string : Pchar) : TXContext; +#when defined(MACROS): +proc XDestroyImage*(ximage: PXImage): cint +proc XGetPixel*(ximage: PXImage, x, y: cint): culong +proc XPutPixel*(ximage: PXImage, x, y: cint, pixel: culong): cint +proc XSubImage*(ximage: PXImage, x, y: cint, width, height: cuint): PXImage +proc XAddPixel*(ximage: PXImage, value: clong): cint +proc IsKeypadKey*(keysym: TKeySym): bool +proc IsPrivateKeypadKey*(keysym: TKeySym): bool +proc IsCursorKey*(keysym: TKeySym): bool +proc IsPFKey*(keysym: TKeySym): bool +proc IsFunctionKey*(keysym: TKeySym): bool +proc IsMiscFunctionKey*(keysym: TKeySym): bool +proc IsModifierKey*(keysym: TKeySym): bool + #function XUniqueContext : TXContext; + #function XStringToContext(_string : Pchar) : TXContext; # implementation -when defined(MACROS): - proc XDestroyImage(ximage: PXImage): cint = - XDestroyImage = ximage[] .f.destroy_image(ximage) +#when defined(MACROS): +proc XDestroyImage(ximage: PXImage): cint = + ximage.f.destroy_image(ximage) - proc XGetPixel(ximage: PXImage, x, y: cint): culong = - XGetPixel = ximage[] .f.get_pixel(ximage, x, y) +proc XGetPixel(ximage: PXImage, x, y: cint): culong = + ximage.f.get_pixel(ximage, x, y) - proc XPutPixel(ximage: PXImage, x, y: cint, pixel: culong): cint = - XPutPixel = ximage[] .f.put_pixel(ximage, x, y, pixel) +proc XPutPixel(ximage: PXImage, x, y: cint, pixel: culong): cint = + ximage.f.put_pixel(ximage, x, y, pixel) - proc XSubImage(ximage: PXImage, x, y: cint, width, height: cuint): PXImage = - XSubImage = ximage[] .f.sub_image(ximage, x, y, width, height) +proc XSubImage(ximage: PXImage, x, y: cint, width, height: cuint): PXImage = + ximage.f.sub_image(ximage, x, y, width, height) - proc XAddPixel(ximage: PXImage, value: clong): cint = - XAddPixel = ximage[] .f.add_pixel(ximage, value) +proc XAddPixel(ximage: PXImage, value: clong): cint = + ximage.f.add_pixel(ximage, value) - proc IsKeypadKey(keysym: TKeySym): bool = - IsKeypadKey = (keysym >= XK_KP_Space) and (keysym <= XK_KP_Equal) +proc IsKeypadKey(keysym: TKeySym): bool = + (keysym >= XK_KP_Space) and (keysym <= XK_KP_Equal) - proc IsPrivateKeypadKey(keysym: TKeySym): bool = - IsPrivateKeypadKey = (keysym >= 0x11000000) and (keysym <= 0x1100FFFF) +proc IsPrivateKeypadKey(keysym: TKeySym): bool = + (keysym >= 0x11000000.TKeySym) and (keysym <= 0x1100FFFF.TKeySym) - proc IsCursorKey(keysym: TKeySym): bool = - IsCursorKey = (keysym >= XK_Home) and (keysym < XK_Select) +proc IsCursorKey(keysym: TKeySym): bool = + (keysym >= XK_Home) and (keysym < XK_Select) - proc IsPFKey(keysym: TKeySym): bool = - IsPFKey = (keysym >= XK_KP_F1) and (keysym <= XK_KP_F4) +proc IsPFKey(keysym: TKeySym): bool = + (keysym >= XK_KP_F1) and (keysym <= XK_KP_F4) - proc IsFunctionKey(keysym: TKeySym): bool = - IsFunctionKey = (keysym >= XK_F1) and (keysym <= XK_F35) +proc IsFunctionKey(keysym: TKeySym): bool = + (keysym >= XK_F1) and (keysym <= XK_F35) - proc IsMiscFunctionKey(keysym: TKeySym): bool = - IsMiscFunctionKey = (keysym >= XK_Select) and (keysym <= XK_Break) +proc IsMiscFunctionKey(keysym: TKeySym): bool = + (keysym >= XK_Select) and (keysym <= XK_Break) - proc IsModifierKey(keysym: TKeySym): bool = - IsModifierKey = ((keysym >= XK_Shift_L) And (keysym <= XK_Hyper_R)) Or - (keysym == XK_Mode_switch) Or (keysym == XK_Num_Lock) +proc IsModifierKey(keysym: TKeySym): bool = + ((keysym >= XK_Shift_L) And (keysym <= XK_Hyper_R)) Or + (keysym == XK_Mode_switch) Or (keysym == XK_Num_Lock) diff --git a/lib/wrappers/zip/zlib.nim b/lib/wrappers/zip/zlib.nim index de52a06e1..c4c6ac071 100644 --- a/lib/wrappers/zip/zlib.nim +++ b/lib/wrappers/zip/zlib.nim @@ -102,6 +102,7 @@ proc compress2*(dest: pbytef, destLen: puLongf, source: pbytef, proc uncompress*(dest: pbytef, destLen: puLongf, source: pbytef, sourceLen: uLong): cint{.cdecl, dynlib: libz, importc: "uncompress".} +proc compressBound*(sourceLen: uLong): uLong {.cdecl, dynlib: libz, importc.} proc gzopen*(path: cstring, mode: cstring): gzFile{.cdecl, dynlib: libz, importc: "gzopen".} proc gzdopen*(fd: int32, mode: cstring): gzFile{.cdecl, dynlib: libz, diff --git a/tests/js/testmagic.nim b/tests/js/testmagic.nim new file mode 100644 index 000000000..2c02d24be --- /dev/null +++ b/tests/js/testmagic.nim @@ -0,0 +1,10 @@ +discard """ + cmd: "nimrod js --hints:on -r $# $#" + output: '''true''' +""" + +# This file tests some magic + +var foo = cstring("foo") +var bar = cstring("foo") +echo(foo == bar) diff --git a/tests/manyloc/packages/noconflicts.nim b/tests/manyloc/packages/noconflicts.nim new file mode 100644 index 000000000..2183d01a8 --- /dev/null +++ b/tests/manyloc/packages/noconflicts.nim @@ -0,0 +1,16 @@ +discard """ + output: '''package1/strutils +package2/strutils +noconflicts +new os.nim''' +""" + +import package1/strutils as su1 +import package2.strutils as su2 + +import os + +su1.foo() +su2.foo() +echo "noconflicts" +yay() diff --git a/tests/manyloc/packages/noconflicts.nimrod.cfg b/tests/manyloc/packages/noconflicts.nimrod.cfg new file mode 100644 index 000000000..88974ab8c --- /dev/null +++ b/tests/manyloc/packages/noconflicts.nimrod.cfg @@ -0,0 +1 @@ +# Mark noconflicts as project file \ No newline at end of file diff --git a/tests/manyloc/packages/os.nim b/tests/manyloc/packages/os.nim new file mode 100644 index 000000000..8a59612f9 --- /dev/null +++ b/tests/manyloc/packages/os.nim @@ -0,0 +1,5 @@ + +# Overrides lib/pure/os.nim + +proc yay* = echo "new os.nim" + diff --git a/tests/manyloc/packages/package1/strutils.nim b/tests/manyloc/packages/package1/strutils.nim new file mode 100644 index 000000000..b283600ea --- /dev/null +++ b/tests/manyloc/packages/package1/strutils.nim @@ -0,0 +1,5 @@ + +# Overrides lib/pure/os.nim + +proc foo* = echo "package1/strutils" + diff --git a/tests/manyloc/packages/package2/strutils.nim b/tests/manyloc/packages/package2/strutils.nim new file mode 100644 index 000000000..1fb4abd41 --- /dev/null +++ b/tests/manyloc/packages/package2/strutils.nim @@ -0,0 +1,5 @@ + +# Overrides lib/pure/os.nim + +proc foo* = echo "package2/strutils" + diff --git a/tests/run/temit.nim b/tests/run/temit.nim index 460bc3443..ff8df0585 100644 --- a/tests/run/temit.nim +++ b/tests/run/temit.nim @@ -9,9 +9,9 @@ static int cvariable = 420; """.} -proc embedsC() {.noStackFrame.} = +proc embedsC() = var nimrodVar = 89 - {.emit: """fprintf(stdout, "%d\n", cvariable + (int)`nimrodVar`);""".} + {.emit: """printf("%d\n", cvariable + (int)`nimrodVar`);""".} embedsC() diff --git a/tests/compile/tindent1.nim b/tests/run/tindent1.nim index 0527b6e57..78a303783 100644 --- a/tests/compile/tindent1.nim +++ b/tests/run/tindent1.nim @@ -1,3 +1,6 @@ +discard """ + output: '''Success''' +""" const romanNumbers1 = [ @@ -22,3 +25,18 @@ const romanNumbers4 = [ ] +proc main = + var j = 0 + while j < 10: + inc(j); + + if j == 5: doAssert false + +var j = 0 +while j < 10: + inc(j); + +if j == 5: doAssert false + +main() +echo "Success" diff --git a/tests/run/tobjasgn.nim b/tests/run/tobjasgn.nim new file mode 100644 index 000000000..5f411063f --- /dev/null +++ b/tests/run/tobjasgn.nim @@ -0,0 +1,39 @@ +discard """ + output: '''0 +pre test a:test b:1 c:2 haha:3 +assignment test a:test b:1 c:2 haha:3 +''' +""" + +type TSomeObj = object of TObject + Variable: int + +var a = TSomeObj() + +echo a.Variable.`$` + +# bug #575 + +type + Something = object of Tobject + a: string + b, c: int32 + +type + Other = object of Something + haha: int + +proc `$`(x: Other): string = + result = "a:" & x.a & " b:" & $x.b & " c:" & $x.c & " haha:" & $x.haha + +var + t: Other + +t.a = "test" +t.b = 1 +t.c = 2 +t.haha = 3 + +echo "pre test ", $t +var x = t +echo "assignment test ", x diff --git a/tests/tester.nim b/tests/tester.nim index e10b89761..fe21fc9ee 100644 --- a/tests/tester.nim +++ b/tests/tester.nim @@ -402,6 +402,7 @@ proc main() = compileExample(r, "lib/pure/*.nim", p.cmdLineRest.string) compileExample(r, "examples/*.nim", p.cmdLineRest.string) compileExample(r, "examples/gtk/*.nim", p.cmdLineRest.string) + compileExample(r, "examples/talk/*.nim", p.cmdLineRest.string) compileSpecialTests(r, p.cmdLineRest.string) writeResults(compileJson, r) of "run": diff --git a/todo.txt b/todo.txt index 732045a5e..da7585500 100644 --- a/todo.txt +++ b/todo.txt @@ -6,14 +6,11 @@ version 0.9.4 - implement missing magics - implement overflow checking - implement the FFI - - implement on the fly CSE - make 'bind' default for templates and introduce 'mixin' - special rule for ``[]=`` - ``=`` should be overloadable; requires specialization for ``=``; general lift mechanism in the compiler is already implemented for 'fields' -- mocking support with ``tyProxy`` that does: fallback for ``.`` operator - - overloading of ``.``? Special case ``.=``? - built-in 'getImpl' - optimize 'genericReset'; 'newException' leads to code bloat - stack-less GC @@ -47,6 +44,7 @@ version 0.9.x * test libffi on windows * test: times.format with the FFI - document NimMain and check whether it works for threading +- 'quote' without 'do' doesn't work: parser/grammar issue; could be supported version 0.9.X @@ -126,7 +124,7 @@ GC CGEN ==== - codegen should use "NIM_CAST" macro and respect aliasing rules for GCC -- ``restrict`` pragma + backend support; computed goto support +- ``restrict`` pragma + backend support - 'const' objects including case objects @@ -160,3 +158,4 @@ Optimizations even further write barrier specialization - inlining of first class functions - proc specialization in the code gen for write barrier specialization +- VM/optimizer: implement on the fly CSE diff --git a/tools/niminst/buildbat.tmpl b/tools/niminst/buildbat.tmpl index f7ccbcbfa..36e1a3e79 100644 --- a/tools/niminst/buildbat.tmpl +++ b/tools/niminst/buildbat.tmpl @@ -5,7 +5,7 @@ SET CC=gcc SET LINKER=gcc SET COMP_FLAGS=?{c.ccompiler.flags} SET LINK_FLAGS=?{c.linker.flags} -SET BIN_DIR=?{firstBinPath(c).slashify} +SET BIN_DIR=?{firstBinPath(c).toWin} if EXIST ..\koch.nim SET BIN_DIR=..\bin @@ -16,9 +16,9 @@ REM call the compiler: # block win32: # var linkCmd = "" # for ff in items(c.cfiles[winIndex][cpuIndex]): -# let f = ff.slashify -ECHO %CC% %COMP_FLAGS% -Isrc -c ?{f} -o ?{changeFileExt(f, "o")} -%CC% %COMP_FLAGS% -Isrc -c ?{f} -o ?{changeFileExt(f, "o")} +# let f = ff.toWin +ECHO %CC% %COMP_FLAGS% -Inimcache -c ?{f} -o ?{changeFileExt(f, "o")} +%CC% %COMP_FLAGS% -Inimcache -c ?{f} -o ?{changeFileExt(f, "o")} # linkCmd.add(" " & changeFileExt(f, "o")) # end for diff --git a/tools/niminst/buildsh.tmpl b/tools/niminst/buildsh.tmpl index 244d73710..0fb4907cf 100644 --- a/tools/niminst/buildsh.tmpl +++ b/tools/niminst/buildsh.tmpl @@ -35,7 +35,7 @@ LINK_FLAGS="?{c.linker.flags}" ucpu=`uname -m` uos=`uname` # add(result, "# bin dir detection\n") -binDir=?{firstBinPath(c).slashify} +binDir=?{firstBinPath(c).toUnix} if [ -s ../koch.nim ]; then binDir="../bin" @@ -54,7 +54,7 @@ case $uos in myos="linux" LINK_FLAGS="$LINK_FLAGS -ldl -lm" ;; - *freebsd* ) + *freebsd* | *dragonfly* ) myos="freebsd" LINK_FLAGS="$LINK_FLAGS -lm" ;; @@ -127,13 +127,13 @@ case $myos in ?{c.cpus[cpuA-1]}) # var linkCmd = "" # for ff in items(c.cfiles[osA][cpuA]): -# let f = ff.slashify - echo "$CC $COMP_FLAGS -Isrc -c ?{f} -o ?{changeFileExt(f, "o")}" - $CC $COMP_FLAGS -Isrc -c ?{f} -o ?{changeFileExt(f, "o")} +# let f = ff.toUnix + echo "$CC $COMP_FLAGS -Inimcache -c ?{f} -o ?{changeFileExt(f, "o")}" + $CC $COMP_FLAGS -Inimcache -c ?{f} -o ?{changeFileExt(f, "o")} # add(linkCmd, " \\\n" & changeFileExt(f, "o")) # end for - echo "$LINKER -o ?{"$binDir"/toLower(c.name)} ?linkCmd $LINK_FLAGS" - $LINKER -o ?{"$binDir"/toLower(c.name)} ?linkCmd $LINK_FLAGS + echo "$LINKER -o ?{"$binDir/" & toLower(c.name)} ?linkCmd $LINK_FLAGS" + $LINKER -o ?{"$binDir/" & toLower(c.name)} ?linkCmd $LINK_FLAGS ;; # end for *) diff --git a/tools/niminst/deinstall.tmpl b/tools/niminst/deinstall.tmpl index c961ac07a..d9abf9228 100644 --- a/tools/niminst/deinstall.tmpl +++ b/tools/niminst/deinstall.tmpl @@ -40,11 +40,11 @@ if [ $# -eq 1 ] ; then echo "removing files..." #for ff in items(c.cat[fcUnixBin]): - #let f = ff.slashify + #let f = ff.toUnix rm -f $bindir/?f.skipRoot #end for #for ff in items(c.cat[fcConfig]): - #let f = ff.slashify + #let f = ff.toUnix rm -f $configdir/?f.skipRoot #end for rm -rf $docdir diff --git a/tools/niminst/inno.tmpl b/tools/niminst/inno.tmpl index 0219dea1f..40edcc790 100644 --- a/tools/niminst/inno.tmpl +++ b/tools/niminst/inno.tmpl @@ -21,7 +21,7 @@ Name: english; MessagesFile: compiler:Default.isl [Files] #for i in low(TFileCategory)..fcWindows: # for f in items(c.cat[i]): -Source: ${expandFilename(f).slashify}; DestDir: {app}\${splitFile(f).dir.slashify}; Flags: ignoreversion +Source: ${expandFilename(f).toWin}; DestDir: {app}\${splitFile(f).dir.toWin}; Flags: ignoreversion # end for #end for @@ -32,7 +32,7 @@ Name: {group}\Console for $c.displayName; Filename: {cmd} Name: {group}\$c.displayName; Filename: {app}\${c.name}.exe #end if #for f in items(c.cat[fcDocStart]): -Name: {group}\Documentation; Filename: {app}\${f.slashify} +Name: {group}\Documentation; Filename: {app}\${f.toWin} #end for Name: {group}\{cm:UninstallProgram,$c.displayName}; Filename: {uninstallexe} @@ -65,7 +65,7 @@ begin setArrayLength(result, $c.binPaths.len); #var i = 0 #for b in items(c.binPaths): - result[$i] := ExpandConstant('{app}') + '\${b.slashify}'; + result[$i] := ExpandConstant('{app}') + '\${b.toWin}'; #inc(i) #end for end; diff --git a/tools/niminst/install.tmpl b/tools/niminst/install.tmpl index 3eb07b8af..fa61eea5e 100644 --- a/tools/niminst/install.tmpl +++ b/tools/niminst/install.tmpl @@ -7,7 +7,7 @@ set -e if [ $# -eq 1 ] ; then # if c.cat[fcUnixBin].len > 0: - if test -f ?{c.cat[fcUnixBin][0].slashify} + if test -f ?{c.cat[fcUnixBin][0].toUnix} then echo "?c.displayName build detected" else @@ -65,35 +65,35 @@ if [ $# -eq 1 ] ; then # mk = unixDirVars[cat] & "/" & mk # if not createdDirs.hasKey(mk): # createdDirs[mk] = "true" - mkdir -p ?{mk.slashify} + mkdir -p ?{mk.toUnix} # end if # end if # end for #end for #for f in items(c.cat[fcUnixBin]): - cp ?f.slashify $bindir/?f.skipRoot.slashify - chmod 755 $bindir/?f.skipRoot.slashify + cp ?f.toUnix $bindir/?f.skipRoot.toUnix + chmod 755 $bindir/?f.skipRoot.toUnix #end for #for f in items(c.cat[fcConfig]): - cp ?f.slashify $configdir/?f.skipRoot.slashify - chmod 644 $configdir/?f.skipRoot.slashify + cp ?f.toUnix $configdir/?f.skipRoot.toUnix + chmod 644 $configdir/?f.skipRoot.toUnix #end for #for f in items(c.cat[fcData]): - if [ -f ?f.slashify ]; then - cp ?f.slashify $datadir/?f.skipRoot.slashify - chmod 644 $datadir/?f.skipRoot.slashify + if [ -f ?f.toUnix ]; then + cp ?f.toUnix $datadir/?f.skipRoot.toUnix + chmod 644 $datadir/?f.skipRoot.toUnix fi #end for #for f in items(c.cat[fcDoc]): - if [ -f ?f.slashify ]; then - cp ?f.slashify $docdir/?f.skipRoot.slashify - chmod 644 $docdir/?f.skipRoot.slashify + if [ -f ?f.toUnix ]; then + cp ?f.toUnix $docdir/?f.skipRoot.toUnix + chmod 644 $docdir/?f.skipRoot.toUnix fi #end for #for f in items(c.cat[fcLib]): - cp ?f.slashify $libdir/?f.skipRoot.slashify - chmod 644 $libdir/?f.skipRoot.slashify + cp ?f.toUnix $libdir/?f.skipRoot.toUnix + chmod 644 $libdir/?f.skipRoot.toUnix #end for echo "installation successful" diff --git a/tools/niminst/niminst.nim b/tools/niminst/niminst.nim index 4da734d13..25ec0d283 100644 --- a/tools/niminst/niminst.nim +++ b/tools/niminst/niminst.nim @@ -1,7 +1,7 @@ # # # The Nimrod Installation Generator -# (c) Copyright 2012 Andreas Rumpf +# (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -52,10 +52,12 @@ type cat: array[TFileCategory, seq[string]] binPaths, authors, oses, cpus: seq[string] cfiles: array[1..maxOS, array[1..maxCPU, seq[string]]] + platforms: array[1..maxOS, array[1..maxCPU, bool]] ccompiler, linker, innosetup: tuple[path, flags: string] name, displayName, version, description, license, infile, outdir: string libpath: string innoSetupFlag, installScript, uninstallScript: bool + explicitPlatforms: bool vars: PStringTable app: TAppType nimrodArgs: string @@ -102,8 +104,8 @@ proc firstBinPath(c: TConfigData): string = proc `\`(a, b: string): string = result = if a.len == 0: b else: a & '\\' & b -proc slashify(s: string): string = - when defined(unix): s.replace('\\', '/') else: s.replace('/', '\\') +template toUnix(s: string): string = s.replace('\\', '/') +template toWin(s: string): string = s.replace('/', '\\') proc skipRoot(f: string): string = # "abc/def/xyz" --> "def/xyz" @@ -126,7 +128,7 @@ const Version = "0.9" Usage = "niminst - Nimrod Installation Generator Version " & version & """ - (c) 2012 Andreas Rumpf + (c) 2013 Andreas Rumpf Usage: niminst [options] command[;command2...] ini-file[.ini] [compile_options] Command: @@ -221,10 +223,28 @@ proc yesno(p: var TCfgParser, v: string): bool = result = false else: quit(errorStr(p, "unknown value; use: yes|no")) +proc incl(s: var seq[string], x: string): int = + for i in 0.. <s.len: + if cmpIgnoreStyle(s[i], x) == 0: return i + s.add(x) + result = s.len-1 + +proc platforms(c: var TConfigData, v: string) = + for line in splitLines(v): + let p = line.find(": ") + if p <= 1: continue + let os = line.substr(0, p-1).strip + let cpus = line.substr(p+1).strip + c.oses.add(os) + for cpu in cpus.split(';'): + let cpuIdx = c.cpus.incl(cpu) + c.platforms[c.oses.len][cpuIdx+1] = true + proc parseIniFile(c: var TConfigData) = var p: TCfgParser section = "" + hasCpuOs = false var input = newFileStream(c.infile, fmRead) if input != nil: open(p, input, c.infile) @@ -244,8 +264,21 @@ proc parseIniFile(c: var TConfigData) = of "name": c.name = v of "displayname": c.displayName = v of "version": c.version = v - of "os": c.oses = split(v, {';'}) - of "cpu": c.cpus = split(v, {';'}) + of "os": + c.oses = split(v, {';'}) + hasCpuOs = true + if c.explicitPlatforms: + quit(errorStr(p, "you cannot have both 'platforms' and 'os'")) + of "cpu": + c.cpus = split(v, {';'}) + hasCpuOs = true + if c.explicitPlatforms: + quit(errorStr(p, "you cannot have both 'platforms' and 'cpu'")) + of "platforms": + platforms(c, v) + c.explicitPlatforms = true + if hasCpuOs: + quit(errorStr(p, "you cannot have both 'platforms' and 'os'")) of "authors": c.authors = split(v, {';'}) of "description": c.description = v of "app": @@ -359,7 +392,7 @@ proc readCFiles(c: var TConfigData, osA, cpuA: int) = quit("Cannot open: " & f) proc buildDir(os, cpu: int): string = - return "src" / ($os & "_" & $cpu) + return "nimcache" / ($os & "_" & $cpu) proc getOutputDir(c: var TConfigData): string = if c.outdir.len > 0: c.outdir else: "build" @@ -377,6 +410,8 @@ proc writeFile(filename, content, newline: string) = proc removeDuplicateFiles(c: var TConfigData) = for osA in countdown(c.oses.len, 1): for cpuA in countdown(c.cpus.len, 1): + if c.cfiles[osA][cpuA].isNil: c.cfiles[osA][cpuA] = @[] + if c.explicitPlatforms and not c.platforms[osA][cpuA]: continue for i in 0..c.cfiles[osA][cpuA].len-1: var dup = c.cfiles[osA][cpuA][i] var f = extractFilename(dup) @@ -397,21 +432,22 @@ proc writeInstallScripts(c: var TConfigData) = writeFile(deinstallShFile, generateDeinstallScript(c), "\10") proc srcdist(c: var TConfigData) = - if not existsDir(getOutputDir(c) / "src"): - createDir(getOutputDir(c) / "src") + if not existsDir(getOutputDir(c) / "nimcache"): + createDir(getOutputDir(c) / "nimcache") for x in walkFiles(c.libpath / "lib/*.h"): - echo(getOutputDir(c) / "src" / extractFilename(x)) - copyFile(dest=getOutputDir(c) / "src" / extractFilename(x), source=x) + echo(getOutputDir(c) / "nimcache" / extractFilename(x)) + copyFile(dest=getOutputDir(c) / "nimcache" / extractFilename(x), source=x) var winIndex = -1 var intel32Index = -1 var intel64Index = -1 for osA in 1..c.oses.len: let osname = c.oses[osA-1] - if osname.cmpIgnoreStyle("windows") == 0: winIndex = osA-1 + if osname.cmpIgnoreStyle("windows") == 0: winIndex = osA for cpuA in 1..c.cpus.len: + if c.explicitPlatforms and not c.platforms[osA][cpuA]: continue let cpuname = c.cpus[cpuA-1] - if cpuname.cmpIgnoreStyle("i386") == 0: intel32Index = cpuA-1 - elif cpuname.cmpIgnoreStyle("amd64") == 0: intel64Index = cpuA-1 + if cpuname.cmpIgnoreStyle("i386") == 0: intel32Index = cpuA + elif cpuname.cmpIgnoreStyle("amd64") == 0: intel64Index = cpuA var dir = getOutputDir(c) / buildDir(osA, cpuA) if existsDir(dir): removeDir(dir) createDir(dir) diff --git a/web/news.txt b/web/news.txt index d863b2ed8..1b492fa97 100644 --- a/web/news.txt +++ b/web/news.txt @@ -15,6 +15,7 @@ Library Additions ----------------- - Added ``macros.genSym`` builtin for AST generation. +- Added ``macros.newLit`` procs for easier AST generation. Changes affecting backwards compatibility @@ -26,6 +27,7 @@ Changes affecting backwards compatibility name but which take different parameters have been introduced. These procs now require an error code to be passed to them. This error code can be retrieved using the new ``OSLastError`` proc. +- ``os.parentDir`` now returns "" if there is no parent dir. Compiler Additions @@ -56,6 +58,13 @@ Language Additions - Support for user-defined type classes have been added. +Tools improvements +------------------ + +- c2nim can deal with a subset of C++. Use the ``--cpp`` command line option + to activate. + + 2013-05-20 New website design! ============================== |