diff --git a/.gitignore b/.gitignore index 9c75c44..15041ab 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,20 @@ cmake-build-*/ Makefile.in Makefile.am + +# Generated files +adie/help.cpp +adie/help.h +adie/icons.h +adie/icons.cpp +calculator/icons.cpp +calculator/icons.h +chart/icons.cpp +chart/icons.h +controlpanel/icons.cpp +controlpanel/icons.h +pathfinder/icons.cpp +pathfinder/icons.h +shutterbug/icons.cpp +shutterbug/icons.h + diff --git a/adie/Adie.cpp b/adie/Adie.cpp index aeab3c9..6a05431 100644 --- a/adie/Adie.cpp +++ b/adie/Adie.cpp @@ -62,6 +62,9 @@ FXIMPLEMENT(Adie,FXApp,AdieMap,ARRAYNUMBER(AdieMap)) Adie::Adie(const FXString& name):FXApp(name){ FXTRACE((10,"Adie::Adie(%s)\n",name.text())); + // File associations, shared between all windows + associations=new FXFileAssociations(this); + // Make some icons; these are shared between all text windows bigicon=new FXGIFIcon(this,big_gif); smallicon=new FXGIFIcon(this,small_gif); @@ -119,15 +122,149 @@ Adie::Adie(const FXString& name):FXApp(name){ // On unix, we need to catch SIGCHLD to harvest zombie child processes. //addSignal(SIGCHLD,this,ID_HARVEST,true); #endif + } - // File associations, shared between all windows - associations=new FXFileAssociations(this); + +// Get syntax for language name +Syntax* Adie::getSyntaxByName(const FXString& lang){ + FXTRACE((11,"Adie::getSyntaxByName(%s)\n",lang.text())); + if(!lang.empty()){ + for(FXint syn=0; syngetName()==lang){ + FXTRACE((11,"syntaxes[%d]: language: %s matched name: %s!\n",syn,syntaxes[syn]->getName().text(),lang.text())); + return syntaxes[syn]; + } + } + } + return nullptr; } -// Close all windows -long Adie::onCmdCloseAll(FXObject*,FXSelector,void*){ - while(0close(true)){} +// Get syntax by consulting registry +Syntax* Adie::getSyntaxByRegistry(const FXString& file){ + FXTRACE((11,"Adie::getSyntaxByRegistry(%s)\n",file.text())); + if(!file.empty()){ + FXString name=FXPath::name(file); + FXString lang=reg().readStringEntry("SYNTAX",name); + return getSyntaxByName(lang); + } + return nullptr; + } + + +// Get syntax by matching file patterns +Syntax* Adie::getSyntaxByPattern(const FXString& file){ + FXTRACE((11,"Adie::getSyntaxByPattern(%s)\n",file.text())); + if(!file.empty()){ + for(FXint syn=0; synmatchFilename(file)){ + FXTRACE((11,"syntaxes[%d]: language: %s matched file: %s!\n",syn,syntaxes[syn]->getName().text(),file.text())); + return syntaxes[syn]; + } + } + } + return nullptr; + } + + +// Get syntax by matching file contents +Syntax* Adie::getSyntaxByContents(const FXString& contents){ + FXTRACE((11,"Adie::getSyntaxByContents(%s)\n",contents.text())); + if(!contents.empty()){ + for(FXint syn=0; synmatchContents(contents)){ + FXTRACE((11,"syntaxes[%d]: language: %s matched contents: %s!\n",syn,syntaxes[syn]->getName().text(),contents.text())); + return syntaxes[syn]; + } + } + } + return nullptr; + } + + +// Generate unique name from given path +FXString Adie::unique(const FXString& path) const { + FXString name="untitled"; + FXString file; + for(FXint i=1; i<2147483647; i++){ + file=FXPath::absolute(path,name); + if(!findWindow(file)) break; + name.format("untitled%d",i); + } + return file; + } + + +// Find an as yet untitled, unedited window +TextWindow *Adie::findUnused() const { + for(FXint w=0; wisFilenameSet() && !windowlist[w]->isModified()){ + return windowlist[w]; + } + } + return nullptr; + } + + +// Find window, if any, currently editing the given file +TextWindow* Adie::findWindow(const FXString& file) const { + for(FXint w=0; wgetFilename()==file){ + return windowlist[w]; + } + } + return nullptr; + } + + +// Open window on file, creating new one if not already open +TextWindow* Adie::openFileWindow(const FXString& file,FXbool edit){ + FXTRACE((11,"Adie::openFileWindow(%s)\n",file.text())); + + // See if we already have this file + TextWindow * window=findWindow(file); + if(!window){ + + // Create new one if no unused windows + window=findUnused(); + if(!window){ + window=new TextWindow(this); + window->create(); + } + + // Open file in this window, setting syntax, bookmarks, etc. + if(window->loadFile(file)){ + window->readBookmarks(file); + window->readView(file); + window->setEditable(edit); + window->determineSyntax(); + window->parseModeline(); + window->setBrowserCurrentFile(file); + } + + // Make empty window with given filename + else{ + window->setFilename(file); + window->setFilenameSet(true); + window->determineSyntax(); + window->setBrowserCurrentFile(file); + } + } + + // Bring up the window + window->raise(); + window->setFocus(); + return window; + } + +/*******************************************************************************/ + +// Harvest the zombies :-) +long Adie::onSigHarvest(FXObject*,FXSelector,void*){ + fxmessage("Harvesting...\n"); +#ifndef WIN32 + while(waitpid(-1,nullptr,WNOHANG)>0){ } +#endif return 1; } @@ -147,30 +284,27 @@ long Adie::onUpdSyntaxPaths(FXObject* sender,FXSelector,void*){ } -// Harvest the zombies :-) -long Adie::onSigHarvest(FXObject*,FXSelector,void*){ - fxmessage("Harvesting...\n"); -#ifndef WIN32 - while(waitpid(-1,nullptr,WNOHANG)>0){ } -#endif +// Close all windows +long Adie::onCmdCloseAll(FXObject*,FXSelector,void*){ + while(0close(true)){} return 1; } - /*******************************************************************************/ // Print command line help static void printusage(){ fxmessage("Usage: adie [options] files...\n"); fxmessage(" options:\n"); - fxmessage(" -?, -h, --help Print help.\n"); - fxmessage(" -V, --version Print version number.\n"); - fxmessage(" -v, --view Start in view-only mode.\n"); - fxmessage(" -e, --edit Start in edit-mode.\n"); - fxmessage(" -l NUM, --line NUM Jump cursor position to line number.\n"); - fxmessage(" -c NUM, --col NUM Jump cursor position to column.\n"); - fxmessage(" -S SYNTAXFILE, --syntax SYNTAXFILE Load given syntax file.\n"); - fxmessage(" -L LANGUAGE, --lang LANGUAGE Force language mode.\n"); + fxmessage(" --help, -h Print help.\n"); + fxmessage(" --version Print version number.\n"); + fxmessage(" --view Start in view-only mode.\n"); + fxmessage(" --edit Start in edit-mode.\n"); + fxmessage(" --line=NUM Jump cursor position to line number.\n"); + fxmessage(" --column=NUM Jump cursor position to column.\n"); + fxmessage(" --syntax=SYNTAXFILE Load given syntax file.\n"); + fxmessage(" --lang=LANGUAGE Force language mode.\n"); + fxmessage(" --size=WxH+X+Y Force window size and placement.\n"); } @@ -195,12 +329,32 @@ static void printversion(){ } +// Parse line and column following filename, if any +static FXString parseFileAndLocation(const FXString& string,FXint& line,FXint& col){ + FXString result('\0',1024); + line=col=0; + if(string.scan("%1023[^:]:%d:%d",result.text(),&line,&col)==3){ + return result; + } + if(string.scan("%1023[^:]:%d",result.text(),&line)==2){ + return result; + } + return string; + } + + // Start the application FXint Adie::start(int argc,char** argv){ - FXString file,lang,execpath,iconpath,syntaxfile; + FXString name,execpath,iconpath,syntaxfile; + FXString file=FXPath::absolute("untitled"); TextWindow *window=nullptr; Syntax *syntax=nullptr; FXbool edit=true; + FXint geom=0; + FXint winx=0; + FXint winy=0; + FXint winw=0; + FXint winh=0; FXint line=0; FXint col=0; FXint arg=1; @@ -219,16 +373,6 @@ FXint Adie::start(int argc,char** argv){ FXTRACE((11,"execpath=%s\n",execpath.text())); - // See if override paths are provided in the registry - syntaxpaths=reg().readStringEntry("SETTINGS","syntaxpaths",execpath.text()); - - FXTRACE((11,"syntaxpaths=%s\n",syntaxpaths.text())); - - // Look for syntax file in the syntax paths - syntaxfile=FXPath::search(syntaxpaths,"Adie.stx"); - - FXTRACE((11,"syntaxfile=%s\n",syntaxfile.text())); - // Get icon search path iconpath=reg().readStringEntry("SETTINGS","iconpath",FXIconCache::defaultIconPath); @@ -237,45 +381,38 @@ FXint Adie::start(int argc,char** argv){ // Change icon search path associations->setIconPath(iconpath); - // Parse options first - while(arg=argc){ fxwarning("Adie: missing line number.\n"); return 1; } - sscanf(argv[arg],"%d",&line); - } - else if(compare(argv[arg],"-c")==0 || compare(argv[arg],"--col")==0){ - if(++arg>=argc){ fxwarning("Adie: missing column number.\n"); return 1; } - sscanf(argv[arg],"%d",&col); - } - else if(compare(argv[arg],"-S")==0 || compare(argv[arg],"--syntax")==0){ - if(++arg>=argc){ fxwarning("Adie: missing syntax file.\n"); return 1; } - syntaxfile=argv[arg]; - } - else if(compare(argv[arg],"-L")==0 || compare(argv[arg],"--lang")==0){ - if(++arg>=argc){ fxwarning("Adie: missing language mode.\n"); return 1; } - lang=argv[arg]; - } - else{ - fxwarning("Adie: unknown command line argument.\n"); - return 1; + if(FXString::compare(argv[arg],"--syntax=",9)==0){ + syntaxfile=argv[arg]+9; + arg++; + continue; } - arg++; + break; } + FXTRACE((11,"syntaxfile=%s\n",syntaxfile.text())); + // Load syntax file if(!syntaxfile.empty()){ if(!SyntaxParser::parseFile(syntaxes,syntaxfile)){ @@ -283,53 +420,101 @@ FXint Adie::start(int argc,char** argv){ } } - // Get syntax - syntax=getSyntaxByName(lang); - - // Parse filenames + // Load filenames while(argcreate(); + // File viewing only + if(FXString::compare(argv[arg],"--view")==0){ + edit=false; + arg++; + continue; + } - // Compute absolute path - file=FXPath::absolute(argv[arg]); + // File viewing and editing + if(FXString::compare(argv[arg],"--edit")==0){ + edit=true; + arg++; + continue; + } - // Start in directory with empty untitled file - if(FXStat::isDirectory(file)){ - file=unique(file); - window->setFilename(file); - window->setFilenameSet(false); - window->setBrowserCurrentFile(file); + // Get language + if(FXString::compare(argv[arg],"--lang=",7)==0){ + syntax=getSyntaxByName(argv[arg]+7); + arg++; + continue; } - // Start in directory with existing, accessible file - else if(FXStat::isFile(file) && window->loadFile(file)){ - window->readBookmarks(file); - window->readView(file); - window->setEditable(edit); - window->determineSyntax(); - window->parseModeline(); - if(line) window->visitLine(line,col); + // Window size + if(FXString::compare(argv[arg],"--size=",7)==0){ + geom=fxparsegeometry(argv[arg]+7,winx,winy,winw,winh); + arg++; + continue; } - // Start in directory with empty or inaccessible file - else{ - window->setFilename(file); - window->setFilenameSet(false); // Prompt for name when saving - window->determineSyntax(); - window->setBrowserCurrentFile(file); + // Get line number + if(FXString::compare(argv[arg],"--line=",7)==0){ + sscanf(argv[arg]+7,"%d",&line); + arg++; + continue; + } + + // Get column number + if(FXString::compare(argv[arg],"--column=",9)==0){ + sscanf(argv[arg]+9,"%d",&col); + arg++; + continue; + } + + // Parse optional line and column from end of filename + name=parseFileAndLocation(argv[arg],line,col); + + FXTRACE((11,"name=%s:%d:%d\n",file.text(),line,col)); + + // Get absolute filename + file=FXPath::absolute(name); + + FXTRACE((11,"file=%s\n",file.text())); + + // Open window + window=openFileWindow(file,edit); + + // Force position and/or size + if(geom){ + if(!(geom&1)) winx=window->getX(); + if(!(geom&2)) winy=window->getY(); + if(!(geom&4)) winw=window->getWidth(); + if(!(geom&8)) winh=window->getHeight(); + if(winx<0) winx+=window->getRoot()->getWidth()-winw; + if(winy<0) winy+=window->getRoot()->getHeight()-winh; + window->position(winx,winy,winw,winh); } // Override language mode? if(syntax){ window->setSyntax(syntax); } + + // Jump to desired line:column + if(line){ + window->visitLine(line,col); + } + + // Pop it up + window->show(PLACEMENT_DEFAULT); + + // Reset for next + edit=true; + geom=0; + winx=0; + winy=0; + winw=0; + winh=0; + line=0; + col=0; arg++; } - // Start in current directory with empty untitled file + // If no window loaded, make empty one if(!window){ // New window @@ -337,152 +522,34 @@ FXint Adie::start(int argc,char** argv){ window->create(); // Compute absolute path - file=FXPath::absolute("untitled"); window->setFilename(file); window->setFilenameSet(false); window->setBrowserCurrentFile(file); + // Force position and/or size + if(geom){ + if(!(geom&1)) winx=window->getX(); + if(!(geom&2)) winy=window->getY(); + if(!(geom&4)) winw=window->getWidth(); + if(!(geom&8)) winh=window->getHeight(); + if(winx<0) winx+=window->getRoot()->getWidth()-winw; + if(winy<0) winy+=window->getRoot()->getHeight()-winh; + window->position(winx,winy,winw,winh); + } + // Override language mode? if(syntax){ window->setSyntax(syntax); } + + // Pop it up + window->show(PLACEMENT_DEFAULT); } // Now run return run(); } - -// Generate unique name from given path -FXString Adie::unique(const FXString& path) const { - FXString name="untitled"; - FXString file; - for(FXint i=1; i<2147483647; i++){ - file=FXPath::absolute(path,name); - if(!findWindow(file)) break; - name.format("untitled%d",i); - } - return file; - } - - -// Find an as yet untitled, unedited window -TextWindow *Adie::findUnused() const { - for(FXint w=0; wisFilenameSet() && !windowlist[w]->isModified()){ - return windowlist[w]; - } - } - return nullptr; - } - - -// Find window, if any, currently editing the given file -TextWindow* Adie::findWindow(const FXString& file) const { - for(FXint w=0; wgetFilename()==file){ - return windowlist[w]; - } - } - return nullptr; - } - - -// Open file and jump to line, or just jump to line if already open -TextWindow* Adie::openFileWindow(const FXString& file,FXint lineno,FXint column){ - TextWindow *window=nullptr; - - FXTRACE((11,"Adie::openFileWindow(%s,%d,%d)\n",file.text(),lineno,column)); - - // See if we already have this file - window=findWindow(file); - if(!window){ - - // Create new one if no unused windows - window=findUnused(); - if(!window){ - window=new TextWindow(this); - window->create(); - } - - // Load the file - if(window->loadFile(file)){ - window->readBookmarks(file); - window->readView(file); - window->determineSyntax(); - window->parseModeline(); - } - } - - // Switch line number only - if(lineno){ - window->visitLine(lineno,column); - } - - // Bring up the window - window->raise(); - window->setFocus(); - return window; - } - - -// Get syntax for language name -Syntax* Adie::getSyntaxByName(const FXString& lang){ - FXTRACE((11,"Adie::getSyntaxByName(%s)\n",lang.text())); - if(!lang.empty()){ - for(FXint syn=0; syngetName()==lang){ - FXTRACE((11,"syntaxes[%d]: language: %s matched name: %s!\n",syn,syntaxes[syn]->getName().text(),lang.text())); - return syntaxes[syn]; - } - } - } - return nullptr; - } - - -// Get syntax by consulting registry -Syntax* Adie::getSyntaxByRegistry(const FXString& file){ - FXTRACE((11,"Adie::getSyntaxByRegistry(%s)\n",file.text())); - if(!file.empty()){ - FXString name=FXPath::name(file); - FXString lang=reg().readStringEntry("SYNTAX",name); - return getSyntaxByName(lang); - } - return nullptr; - } - - -// Get syntax by matching file patterns -Syntax* Adie::getSyntaxByPattern(const FXString& file){ - FXTRACE((11,"Adie::getSyntaxByPattern(%s)\n",file.text())); - if(!file.empty()){ - for(FXint syn=0; synmatchFilename(file)){ - FXTRACE((11,"syntaxes[%d]: language: %s matched file: %s!\n",syn,syntaxes[syn]->getName().text(),file.text())); - return syntaxes[syn]; - } - } - } - return nullptr; - } - - -// Get syntax by matching file contents -Syntax* Adie::getSyntaxByContents(const FXString& contents){ - FXTRACE((11,"Adie::getSyntaxByContents(%s)\n",contents.text())); - if(!contents.empty()){ - for(FXint syn=0; synmatchContents(contents)){ - FXTRACE((11,"syntaxes[%d]: language: %s matched contents: %s!\n",syn,syntaxes[syn]->getName().text(),contents.text())); - return syntaxes[syn]; - } - } - } - return nullptr; - } - - /*******************************************************************************/ // Clean up the mess diff --git a/adie/Adie.h b/adie/Adie.h index 8116f65..8e0c5ea 100644 --- a/adie/Adie.h +++ b/adie/Adie.h @@ -24,7 +24,7 @@ // Version #define VERSION_MAJOR 3 -#define VERSION_MINOR 5 +#define VERSION_MINOR 6 #define VERSION_PATCH 0 @@ -123,8 +123,8 @@ class Adie : public FXApp { // Find window, if any, currently editing the given file TextWindow* findWindow(const FXString& file) const; - // Open file and jump to line, or just jump to line/column if already open - TextWindow* openFileWindow(const FXString& file,FXint lineno=0,FXint column=0); + // Open window on file, creating new one if not already open + TextWindow* openFileWindow(const FXString& file,FXbool edit=true); // Get syntax for language name Syntax* getSyntaxByName(const FXString& lang); diff --git a/adie/Adie.stx b/adie/Adie.stx index 653daac..b072566 100644 --- a/adie/Adie.stx +++ b/adie/Adie.stx @@ -489,7 +489,7 @@ language "C++" end rule "Keyword" - pattern "\<(alignas|alignof|and_eq|and|asm|auto|bitand|bitor|break|case|catch|class|compl|constexpr|const_cast|const|continue|decltype|default|delete|do|dynamic_cast|else|enum|explicit|export|extern|final|for|friend|goto|if|inline|mutable|namespace|new|noexcept|not_eq|not|nullptr|operator|or_eq|or|override|private|protected|public|reinterpret_cast|return|sizeof|static_assert|static_cast|static|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|using|virtual|volatile|while|xor_eq|xor|true|false|maybe)\>" + pattern "\<(alignas|alignof|and_eq|and|asm|auto|bitand|bitor|break|case|catch|class|compl|concept|consteval|constexpr|constinit|const_cast|const|continue|decltype|default|delete|do|dynamic_cast|else|enum|explicit|export|extern|final|for|friend|goto|if|inline|mutable|namespace|new|noexcept|not_eq|not|nullptr|operator|or_eq|or|override|private|protected|public|reinterpret_cast|return|sizeof|static_assert|static_cast|static_assert|static|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|using|virtual|volatile|while|xor_eq|xor|true|false|maybe)\>" style "red" end @@ -501,7 +501,7 @@ language "C++" end rule "Type" - pattern "\<(unsigned|signed|int|short|long|float|double|bool|void|char16_t|char32_t|char|wchar_t)\>" + pattern "\<(unsigned|signed|int|short|long|float|double|bool|void|char8_t|char16_t|char32_t|char|wchar_t)\>" style "blue" end @@ -707,6 +707,104 @@ language "C" end +# Rust programming language +language "Rust" + + # File patterns for this language mode + filesmatch "*.rs" + + contextlines 1 + + # Word delimiters + delimiters "~.,/\`'!@#$%^&*()-=+{}|[]\":;<>?" + + # All C-like languages use similar color schemes + group "C-Like" + + # Comment + rule "Comment" + open "//" + close "$" + style "darkgreen" + rule "FIXME" + pattern "FIXME" + style "fuchsia" + end + end + + # String + rule "String" + open "\"" + close "\"" + stop "$" + style "blue" + rule "OctalEscape" + pattern "\\[0-7]{1,3}" + style "carrot" + end + rule "HexEscape" + pattern "\\x\h\h" + style "carrot" + end + rule "ControlEscape" + pattern "\\." + style "carrot" + end + end + + # Char constant + rule "Char" + open "'" + close "'" + stop "$" + style "blue" + rule "OctalEscape" + pattern "\\[0-7]{1,3}" + style "carrot" + end + rule "HexEscape" + pattern "\\x\h\h" + style "carrot" + end + rule "ControlEscape" + pattern "\\." + style "carrot" + end + end + + # Special macros + rule "Keyword" + pattern "\<(as|async|await|break|const|continue|crate|dyn|else|enum|extern|false|fn|for|if|impl|in|let|loop|match|mod|move|mut|pub|ref|return|Self|self|static|struct|super|trait|true|type|union|unsafe|use|where|while|abstract|become|box|do|final|macro|override|priv|try|typeof|unsized|virtual|yield)\>" + style "red" + end + + rule "Number" + pattern "\<(((\.\d++|\d++((\.\d*+)?|(?=[Ee][+-]?\d++)))([eE][+-]?+\d++)?)(f(32|64))?|([1-9][0-9_]*+|0[xX]\h[\h_]*+|0o[0-7][0-7_]*+|0b[01][01_]*+|b'\\?.')([iu](8|16|32|64|128|size))?)\>" + style "blue" + end + + rule "Type" + pattern "\<(i8|u8|i16|u16|i32|u32|i64|u64|i128|i128|isize|usize|f32|f64|bool|char)\>" + style "blue" + end + + rule "Braces" + pattern "(\{|\})" + style "red" + end + + rule "Parentheses" + pattern "(\(|\))" + style "red" + end + + rule "Operator" + pattern "(\[|\]|\+\+|\+=|\+|--|-=|->\*|->|-|==|=|&&|&=|&|\|\||\|=|\||\^=|\^|<<=|<<|<=|<|>>=|>>|>=|>|!=|!|~=|~|\*=|\*|/=|/|%=|%|\?|:|\.\.\.|\.\.=|\.|;|,|@)" + style "red" + end +end + + # Fortran Programming Language language "Fortran" @@ -1532,7 +1630,9 @@ end # Python language "Python" filesmatch "*.py" + contentsmatch "\A#!(.*?)python" delimiters "~.,/\`'!@#$%^&*()-=+{}|[]\":;<>?" + contextlines 1 # Numbers @@ -2209,7 +2309,7 @@ language "Shell" filesmatch "*.sh,.bashrc" # Or contents - contentsmatch "\A#(.*?)(ba)?sh" + contentsmatch "\A#!(.*?)(ba)?sh" contextlines 1 rule "Comment" diff --git a/adie/FindInFiles.cpp b/adie/FindInFiles.cpp index db5c9cf..8ec4522 100644 --- a/adie/FindInFiles.cpp +++ b/adie/FindInFiles.cpp @@ -91,6 +91,12 @@ static const FXchar skey[20][3]={ }; +// Registry keys for folder strings +static const FXchar fkey[20][3]={ + "FA","FB","FC","FD","FE","FF","FG","FH","FI","FJ","FK","FL","FM","FN","FO","FP","FQ","FR","FS","FT" + }; + + // Registry keys for file pattern options static const FXchar pkey[20][3]={ "PA","PB","PC","PD","PE","PF","PG","PH","PI","PJ","PK","PL","PM","PN","PO","PP","PQ","PR","PS","PT" @@ -300,6 +306,7 @@ void FindInFiles::readRegistry(){ for(FXint i=0; i<20; ++i){ searchHistory[i]=getApp()->reg().readStringEntry(sectionName,skey[i],FXString::null); if(searchHistory[i].empty()) break; + folderHistory[i]=getApp()->reg().readStringEntry(sectionName,fkey[i],FXString::null); patternHistory[i]=getApp()->reg().readUIntEntry(sectionName,pkey[i],0); optionsHistory[i]=getApp()->reg().readUIntEntry(sectionName,mkey[i],SearchExact); } @@ -318,11 +325,13 @@ void FindInFiles::writeRegistry(){ for(FXint i=0; i<20; ++i){ if(!searchHistory[i].empty()){ getApp()->reg().writeStringEntry(sectionName,skey[i],searchHistory[i].text()); + getApp()->reg().writeStringEntry(sectionName,fkey[i],folderHistory[i].text()); getApp()->reg().writeUIntEntry(sectionName,pkey[i],patternHistory[i]); getApp()->reg().writeUIntEntry(sectionName,mkey[i],optionsHistory[i]); } else{ getApp()->reg().deleteEntry(sectionName,skey[i]); + getApp()->reg().deleteEntry(sectionName,fkey[i]); getApp()->reg().deleteEntry(sectionName,pkey[i]); getApp()->reg().deleteEntry(sectionName,mkey[i]); } @@ -331,16 +340,18 @@ void FindInFiles::writeRegistry(){ // Add string to history buffer -void FindInFiles::appendHistory(const FXString& text,FXuint patt,FXuint opts){ +void FindInFiles::appendHistory(const FXString& text,const FXString& dir,FXuint patt,FXuint opts){ if(!text.empty()){ if(text!=searchHistory[0]){ for(FXint i=19; i>0; i--){ swap(searchHistory[i],searchHistory[i-1]); + swap(folderHistory[i],folderHistory[i-1]); swap(patternHistory[i],patternHistory[i-1]); swap(optionsHistory[i],optionsHistory[i-1]); } } searchHistory[0]=text; + folderHistory[0]=dir; patternHistory[0]=patt; optionsHistory[0]=opts; index=0; @@ -563,7 +574,7 @@ long FindInFiles::onCmdSearch(FXObject*,FXSelector,void*){ if(!(getSearchMode()&SearchRegex)) rexmode|=FXRex::Verbatim; // Verbatim match if(getSearchMode()&SeachHidden) opts|=FXDir::HiddenFiles|FXDir::HiddenDirs; // Visit hidden files and directories if(!(getSearchMode()&SearchRecurse)) limit=2; // Don't recurse - appendHistory(getSearchText(),getCurrentPattern(),getSearchMode()); + appendHistory(getSearchText(),getDirectory(),getCurrentPattern(),getSearchMode()); proceed=1; visitor.traverse(getDirectory(),getSearchText(),getPattern(),rexmode,opts,limit); setSearchingText(tr("")); @@ -650,10 +661,12 @@ long FindInFiles::onCmdHistoryUp(FXObject*,FXSelector,void*){ ++index; if(index==0){ savedsearchtext=getSearchText(); + savedsearchfolder=getDirectory(); savedsearchmode=getSearchMode(); savedcurrentpattern=getCurrentPattern(); } setSearchText(searchHistory[index]); + setDirectory(folderHistory[index]); setCurrentPattern(patternHistory[index]); setSearchMode(optionsHistory[index]); } @@ -670,11 +683,13 @@ long FindInFiles::onCmdHistoryDn(FXObject*,FXSelector,void*){ --index; if(0<=index){ setSearchText(searchHistory[index]); + setDirectory(folderHistory[index]); setCurrentPattern(patternHistory[index]); setSearchMode(optionsHistory[index]); } else{ setSearchText(savedsearchtext); + setDirectory(savedsearchfolder); setSearchMode(savedsearchmode); setCurrentPattern(savedcurrentpattern); } @@ -717,7 +732,10 @@ long FindInFiles::onCmdFileDblClicked(FXObject*,FXSelector,void* ptr){ FXint lineno=0; FXint column=0; if(locations->getItem(which)->getText().scan("%1023[^:]:%d:%d",name,&lineno,&column)==3){ - getApp()->openFileWindow(FXPath::absolute(getDirectory(),name),lineno,column); + FXString filename=FXPath::absolute(getDirectory(),name); + TextWindow* window=getApp()->openFileWindow(filename); + window->visitLine(lineno,column); + window->show(PLACEMENT_DEFAULT); } } return 1; diff --git a/adie/FindInFiles.h b/adie/FindInFiles.h index b4e9414..d880204 100644 --- a/adie/FindInFiles.h +++ b/adie/FindInFiles.h @@ -71,10 +71,12 @@ class FindInFiles : public FXDialogBox { FXLabel *searching; // Show file being scanned FXString filePattern; // Search files matching pattern FXString searchHistory[20]; // Search string history + FXString folderHistory[20]; // Search folder history FXuint patternHistory[20]; // Search wildcard history FXuint optionsHistory[20]; // Search option history FXuint searchmode; // Search options - FXString savedsearchtext; // Saved seach text + FXString savedsearchtext; // Saved search text + FXString savedsearchfolder; // Saved search folder FXuint savedsearchmode; // Saved search mode FXuint savedcurrentpattern; // Saved search pattern FXint index; // History index @@ -88,7 +90,7 @@ class FindInFiles : public FXDialogBox { private: void readRegistry(); void writeRegistry(); - void appendHistory(const FXString& text,FXuint patt,FXuint opts); + void appendHistory(const FXString& text,const FXString& dir,FXuint patt,FXuint opts); public: long onUpdStop(FXObject*,FXSelector,void*); long onCmdStop(FXObject*,FXSelector,void*); diff --git a/adie/Modeline.cpp b/adie/Modeline.cpp index 7b1e8cc..8712a68 100644 --- a/adie/Modeline.cpp +++ b/adie/Modeline.cpp @@ -164,7 +164,7 @@ FXbool Modeline::parseEmacsModeline(const FXchar* s){ while(*s!='\0' && *s!=';' && *s!='\t' && *s!=' '){ val+=*s++; } - if(comparecase(key,"Mode")==0){ + if(FXString::comparecase(key,"Mode")==0){ setLanguage(val); } else if(key=="tab-width"){ diff --git a/adie/Syntax.cpp b/adie/Syntax.cpp index da744a7..ee50b7a 100644 --- a/adie/Syntax.cpp +++ b/adie/Syntax.cpp @@ -39,6 +39,9 @@ 3 Contents of the file (at least, the first fragment of the contents), matches against regular expression patten from the Language. + 4 Parsing the language and other settings from a "modeline" embedded + in the text file. + o Language sets delimiters in text editor. o Language sets syntax rules to be used for colorizing text. @@ -70,8 +73,8 @@ potentially huge portion of text in the event that the user is editing the text and no text currently matches the closing pattern. - 5 NestedRule. This rule matches a single regex pattern. The subrules - of the NestedRule are applied only to the range matched by their + 5 SpanRule. This rule matches a single regex pattern. The subrules + of the SpanRule are applied only to the range matched by their parent; thus, there is no need for a closing regex. o The pattern in a SimpleRule must be non-empty, i.e. it must match a non-zero @@ -80,44 +83,15 @@ o Each rule has its own style index. This is important for the incremental restyling algorithm. Each rule also has a link to its immediate parent - rule, thus. Thus, during editing, we can identify the ancestor rules - so as to minimally recolor the text. The algorithm backs up in wider and - wider ranges about the changed text until a starting pattern of an ancestor + rule. Thus, during editing, we can identify the ancestor rules so as to + minimally recolor the text. The algorithm backs up in wider and wider + ranges about the changed text until a starting pattern of an ancestor rule is matched again. In most cases, this search doesn't go very deep, and only small chunks of text need recolorizing. o Rules MAY have the same NAMES even though they are different rules. That merely means these rules will have the same style. It says nothing about what is matched or how the colorizer works. - - - SyntaxParser is a simple recursive descent parser. The style language has - very few lexical elements: comments, spaces, numbers, strings, and identifiers. - - o Comments. Comments are lines preceeded by a '#'. All text after the - '#' is skipped until the end of the line. - - o Spaces. Spaces are not significant, except inside strings. Spaces are - simply skipped. - - o Numbers. Only decimal integer numbers are supported. - - o Strings. Strings are any text between double quotes ('"'). There are no - escape sequences, except to enter a double quote ('\"'). This is so as - to keep regular expressions somewhat legible. Note that the regular - expression engine *does* support escape sequences, so matching special - characters is quite simple. - - o Identifiers. As with most programming languages, identifiers start with - a letter, followed by letters or digits. Only the following identifiers - are recognized as language elements: - - language, rule, filesmatch, contentsmatch, contextlines, contextchars, - delimiters, pattern, openpattern, closepattern, stoppattern, end. - - [There may be more in the future]. - - - We currently don't use capturing parentheses capabilities; bracketing rules - seem sufficient for most languages. Perhaps this will change. */ /*******************************************************************************/ @@ -129,7 +103,7 @@ static inline void fillstyle(FXchar* textstyle,FXchar style,FXint f,FXint t){ // Constructor -Rule::Rule(const FXString& nam,const FXString& sty,FXint par,FXint idx):name(nam),style(sty),parent(par),index(idx){ +Rule::Rule(const FXString& nam,const FXString& sty,FXival par,FXival idx):name(nam),style(sty),parent(par),index(idx){ } @@ -152,8 +126,8 @@ Rule::~Rule(){ /*******************************************************************************/ // Constructor -DefaultRule::DefaultRule(const FXString& nam,const FXString& sty,FXint par,FXint idx):Rule(nam,sty,par,idx){ - FXTRACE((10,"DefaultRule::DefaultRule(\"%s\",\"%s\",%d,%d)\n",nam.text(),sty.text(),parent,index)); +DefaultRule::DefaultRule(const FXString& nam,const FXString& sty,FXival par,FXival idx):Rule(nam,sty,par,idx){ + FXTRACE((10,"DefaultRule::DefaultRule(\"%s\",\"%s\",%ld,%ld)\n",nam.text(),sty.text(),parent,index)); } @@ -168,7 +142,7 @@ FXbool DefaultRule::stylizeBody(const FXchar* text,FXchar* textstyle,FXint len,F FXint begin,end; FXuchar c; head=pos; while(posstylize(text,textstyle,len,pos,begin,end)){ pos=end; goto nxt; } } c=text[pos]; @@ -194,8 +168,8 @@ DefaultRule::~DefaultRule(){ /*******************************************************************************/ // Constructor -SimpleRule::SimpleRule(const FXString& nam,const FXString& sty,const FXString& rex,FXint par,FXint idx):Rule(nam,sty,par,idx),pattern(rex,FXRex::Newline|FXRex::NotEmpty){ - FXTRACE((10,"SimpleRule::SimpleRule(\"%s\",\"%s\",\"%s\",%d,%d)\n",nam.text(),sty.text(),rex.text(),parent,index)); +SimpleRule::SimpleRule(const FXString& nam,const FXString& sty,const FXString& rex,FXival par,FXival idx):Rule(nam,sty,par,idx),pattern(rex,FXRex::Newline|FXRex::NotEmpty){ + FXTRACE((10,"SimpleRule::SimpleRule(\"%s\",\"%s\",\"%s\",%ld,%ld)\n",nam.text(),sty.text(),rex.text(),parent,index)); } @@ -223,8 +197,8 @@ SimpleRule::~SimpleRule(){ /*******************************************************************************/ // Constructor -BracketRule::BracketRule(const FXString& nam,const FXString& sty,const FXString& brex,const FXString& erex,FXint par,FXint idx):Rule(nam,sty,par,idx),open(brex,FXRex::Newline),close(erex,FXRex::Newline){ - FXTRACE((10,"BracketRule::BracketRule(\"%s\",\"%s\",\"%s\",\"%s\",%d,%d)\n",nam.text(),sty.text(),brex.text(),erex.text(),parent,index)); +BracketRule::BracketRule(const FXString& nam,const FXString& sty,const FXString& brex,const FXString& erex,FXival par,FXival idx):Rule(nam,sty,par,idx),open(brex,FXRex::Newline),close(erex,FXRex::Newline){ + FXTRACE((10,"BracketRule::BracketRule(\"%s\",\"%s\",\"%s\",\"%s\",%ld,%ld)\n",nam.text(),sty.text(),brex.text(),erex.text(),parent,index)); } @@ -245,7 +219,7 @@ FXbool BracketRule::stylizeBody(const FXchar* text,FXchar* textstyle,FXint len,F FXint begin,end; FXuchar c; head=pos; while(posstylize(text,textstyle,len,pos,begin,end)){ pos=end; goto nxt; } } if(close.amatch(text,len,pos,FXRex::Normal,&begin,&tail,1)){ @@ -275,8 +249,8 @@ BracketRule::~BracketRule(){ /*******************************************************************************/ // Constructor -SafeBracketRule::SafeBracketRule(const FXString& nam,const FXString& sty,const FXString& brex,const FXString& erex,const FXString& srex,FXint par,FXint idx):BracketRule(nam,sty,brex,erex,par,idx),stop(srex,FXRex::Newline){ - FXTRACE((10,"SafeBracketRule::SafeBracketRule(\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",%d,%d)\n",nam.text(),sty.text(),brex.text(),erex.text(),srex.text(),parent,index)); +SafeBracketRule::SafeBracketRule(const FXString& nam,const FXString& sty,const FXString& brex,const FXString& erex,const FXString& srex,FXival par,FXival idx):BracketRule(nam,sty,brex,erex,par,idx),stop(srex,FXRex::Newline){ + FXTRACE((10,"SafeBracketRule::SafeBracketRule(\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",%ld,%ld)\n",nam.text(),sty.text(),brex.text(),erex.text(),srex.text(),parent,index)); } @@ -301,7 +275,7 @@ FXbool SafeBracketRule::stylizeBody(const FXchar* text,FXchar* textstyle,FXint l fillstyle(textstyle,index,begin,tail); return true; } - for(FXint node=0; nodestylize(text,textstyle,len,pos,begin,end)){ pos=end; goto nxt; } } if(close.amatch(text,len,pos,FXRex::Normal,&begin,&tail,1)){ @@ -331,8 +305,8 @@ SafeBracketRule::~SafeBracketRule(){ /*******************************************************************************/ // Constructor -SpanRule::SpanRule(const FXString& nam,const FXString& sty,const FXString& rex,FXint par,FXint idx):Rule(nam,sty,par,idx),pattern(rex,FXRex::Newline|FXRex::NotEmpty){ - FXTRACE((10,"SpanRule::SpanRule(\"%s\",\"%s\",\"%s\",%d,%d)\n",nam.text(),sty.text(),rex.text(),parent,index)); +SpanRule::SpanRule(const FXString& nam,const FXString& sty,const FXString& rex,FXival par,FXival idx):Rule(nam,sty,par,idx),pattern(rex,FXRex::Newline|FXRex::NotEmpty){ + FXTRACE((10,"SpanRule::SpanRule(\"%s\",\"%s\",\"%s\",%ld,%ld)\n",nam.text(),sty.text(),rex.text(),parent,index)); } @@ -353,7 +327,7 @@ FXbool SpanRule::stylizeBody(const FXchar* text,FXchar* textstyle,FXint len,FXin FXint begin,end; FXuchar c; head=pos; while(posstylize(text,textstyle,len,pos,begin,end)){ pos=end; goto nxt; } } c=text[pos]; @@ -389,7 +363,7 @@ Syntax::Syntax(const FXString& lang,const FXString& grp):language(lang),group(gr // Find rule given name FXint Syntax::getNamedRule(const FXString& name) const { - for(FXint i=0; igetName()==name) return i; } return -1; @@ -410,8 +384,8 @@ FXbool Syntax::matchContents(const FXString& text) const { // Append default rule -FXint Syntax::appendDefault(const FXString& name,const FXString& style,FXint parent){ - FXint index=rules.no(); +FXival Syntax::appendDefault(const FXString& name,const FXString& style,FXival parent){ + FXival index=rules.no(); FXASSERT(0<=parent && parentgetParent(); @@ -498,5 +472,5 @@ FXint Syntax::commonAncestor(FXint a,FXint b) const { // Clean up Syntax::~Syntax(){ FXTRACE((10,"Syntax::~Syntax()\n")); - for(FXint node=0; node. This is to keep patterns moderately sane and avoid multiple - levels of escaping. + + - SyntaxParser is a simple recursive descent parser. The style language has + very few lexical elements: comments, spaces, numbers, strings, and identifiers. + + o Comments. Comments are lines preceeded by a '#'. All text after the + '#' is skipped until the end of the line. + + o Spaces. Spaces are not significant, except inside strings. Spaces are + simply skipped. + + o Numbers. Only decimal integer numbers are supported. + + o Strings. Strings are any text between double quotes ('"'). There are no + escape sequences, except to enter a double quote ('\"'). + + For instance "\"quoted\"" means "quoted" but "line\n" means line\n, not + line. This is to keep patterns moderately sane and avoid multiple + levels of escaping, since the regular expression engine already has its + own escape mechanisms. + + o Keywords. As with most programming languages, keywords start with + a letter, followed by letters or digits. + - Syntax patterns syntax: Syntax = { Language }* @@ -71,9 +89,6 @@ Number = [0-9]+ - - Note that only quotes (") need to be escaped; this is because otherwise, patterns - get really complicated as the regular expression engine also needs special characters - to be escaped. */ /*******************************************************************************/ diff --git a/adie/TextWindow.cpp b/adie/TextWindow.cpp index 44422da..cbaacf5 100644 --- a/adie/TextWindow.cpp +++ b/adie/TextWindow.cpp @@ -321,8 +321,8 @@ FXDEFMAP(TextWindow) TextWindowMap[]={ FXMAPFUNC(SEL_COMMAND,TextWindow::ID_SYNTAX,TextWindow::onCmdSyntax), FXMAPFUNC(SEL_UPDATE,TextWindow::ID_RESTYLE,TextWindow::onUpdRestyle), FXMAPFUNC(SEL_COMMAND,TextWindow::ID_RESTYLE,TextWindow::onCmdRestyle), - FXMAPFUNCS(SEL_UPDATE,TextWindow::ID_WINDOW_1,TextWindow::ID_WINDOW_10,TextWindow::onUpdWindow), - FXMAPFUNCS(SEL_COMMAND,TextWindow::ID_WINDOW_1,TextWindow::ID_WINDOW_10,TextWindow::onCmdWindow), + FXMAPFUNCS(SEL_UPDATE,TextWindow::ID_WINDOW_1,TextWindow::ID_WINDOW_15,TextWindow::onUpdWindow), + FXMAPFUNCS(SEL_COMMAND,TextWindow::ID_WINDOW_1,TextWindow::ID_WINDOW_15,TextWindow::onCmdWindow), FXMAPFUNCS(SEL_UPDATE,TextWindow::ID_SYNTAX_FIRST,TextWindow::ID_SYNTAX_LAST,TextWindow::onUpdSyntaxSwitch), FXMAPFUNCS(SEL_COMMAND,TextWindow::ID_SYNTAX_FIRST,TextWindow::ID_SYNTAX_LAST,TextWindow::onCmdSyntaxSwitch), @@ -457,6 +457,7 @@ TextWindow::TextWindow(Adie* a):FXMainWindow(a,"Adie",nullptr,nullptr,DECOR_ALL, // Recent files mrufiles.setTarget(this); mrufiles.setSelector(ID_OPEN_RECENT); + mrufiles.setMaxFiles(15); // Initialize file name filename="untitled"; @@ -503,8 +504,8 @@ void TextWindow::createMenubar(){ // File Menu entries new FXMenuCommand(filemenu,tr("&New...\tCtl-N\tCreate new document."),getApp()->newicon,this,ID_NEW); new FXMenuCommand(filemenu,tr("&Open...\tCtl-O\tOpen document file."),getApp()->openicon,this,ID_OPEN); + new FXMenuCommand(filemenu,tr("S&witch...\t\tSwitch to other file."),nullptr,this,ID_SWITCH); new FXMenuCommand(filemenu,tr("Open Selected... \tCtl-Y\tOpen highlighted document file."),nullptr,this,ID_OPEN_SELECTED); - new FXMenuCommand(filemenu,tr("Switch...\t\tSwitch to other file."),nullptr,this,ID_SWITCH); new FXMenuCommand(filemenu,tr("&Reopen...\t\tReopen file."),getApp()->reloadicon,this,ID_REOPEN); new FXMenuCommand(filemenu,tr("&Save\tCtl-S\tSave changes to file."),getApp()->saveicon,this,ID_SAVE); new FXMenuCommand(filemenu,tr("Save &As...\tShift-Ctl-S\tSave document under a different file name."),getApp()->saveasicon,this,ID_SAVEAS); @@ -528,6 +529,11 @@ void TextWindow::createMenubar(){ new FXMenuCommand(filemenu,"&8",nullptr,&mrufiles,FXRecentFiles::ID_FILE_8); new FXMenuCommand(filemenu,"&9",nullptr,&mrufiles,FXRecentFiles::ID_FILE_9); new FXMenuCommand(filemenu,"1&0",nullptr,&mrufiles,FXRecentFiles::ID_FILE_10); + new FXMenuCommand(filemenu,"11",nullptr,&mrufiles,FXRecentFiles::ID_FILE_11); + new FXMenuCommand(filemenu,"12",nullptr,&mrufiles,FXRecentFiles::ID_FILE_12); + new FXMenuCommand(filemenu,"13",nullptr,&mrufiles,FXRecentFiles::ID_FILE_13); + new FXMenuCommand(filemenu,"14",nullptr,&mrufiles,FXRecentFiles::ID_FILE_14); + new FXMenuCommand(filemenu,"15",nullptr,&mrufiles,FXRecentFiles::ID_FILE_15); new FXMenuCommand(filemenu,tr("&Clear Recent Files"),nullptr,&mrufiles,FXRecentFiles::ID_CLEAR); new FXMenuSeparator(filemenu,&mrufiles,FXRecentFiles::ID_ANYFILES); new FXMenuCommand(filemenu,tr("&Quit\tCtl-Q\tQuit program."),getApp()->quiticon,getApp(),Adie::ID_CLOSEALL); @@ -645,8 +651,8 @@ void TextWindow::createMenubar(){ new FXMenuTitle(menubar,tr("&Options"),nullptr,optionmenu); // Options menu - new FXMenuCommand(optionmenu,tr("Preferences...\t\tChange preferences."),getApp()->configicon,this,ID_PREFERENCES); - new FXMenuCommand(optionmenu,tr("Font...\t\tChange text font."),getApp()->fontsicon,this,ID_FONT); + new FXMenuCommand(optionmenu,tr("&Preferences...\t\tChange preferences."),getApp()->configicon,this,ID_PREFERENCES); + new FXMenuCommand(optionmenu,tr("&Font...\t\tChange text font."),getApp()->fontsicon,this,ID_FONT); new FXMenuCheck(optionmenu,tr("Insert &tabs\t\tToggle insert tabs."),this,ID_INSERTTABS); new FXMenuCheck(optionmenu,tr("&Word wrap\t\tToggle word wrap mode."),this,ID_TOGGLE_WRAP); new FXMenuCheck(optionmenu,tr("&Overstrike\t\tToggle overstrike mode."),editor,FXText::ID_TOGGLE_OVERSTRIKE); @@ -664,11 +670,11 @@ void TextWindow::createMenubar(){ new FXMenuTitle(menubar,tr("&View"),nullptr,viewmenu); // View Menu entries - new FXMenuCheck(viewmenu,tr("File Browser\t\tDisplay file list."),this,ID_TOGGLE_BROWSER); - new FXMenuCheck(viewmenu,tr("Error Logger\t\tDisplay error logger."),loggerframe,FXWindow::ID_TOGGLESHOWN); - new FXMenuCheck(viewmenu,tr("Toolbar\t\tDisplay toolbar."),toolbar,FXWindow::ID_TOGGLESHOWN); - new FXMenuCheck(viewmenu,tr("Searchbar\t\tDisplay search bar."),searchbar,FXWindow::ID_TOGGLESHOWN); - new FXMenuCheck(viewmenu,tr("Status line\t\tDisplay status line."),statusbar,FXWindow::ID_TOGGLESHOWN); + new FXMenuCheck(viewmenu,tr("&File Browser\t\tDisplay file list."),this,ID_TOGGLE_BROWSER); + new FXMenuCheck(viewmenu,tr("&Error Logger\t\tDisplay error logger."),loggerframe,FXWindow::ID_TOGGLESHOWN); + new FXMenuCheck(viewmenu,tr("&Toolbar\t\tDisplay toolbar."),toolbar,FXWindow::ID_TOGGLESHOWN); + new FXMenuCheck(viewmenu,tr("&Searchbar\t\tDisplay search bar."),searchbar,FXWindow::ID_TOGGLESHOWN); + new FXMenuCheck(viewmenu,tr("Status &line\t\tDisplay status line."),statusbar,FXWindow::ID_TOGGLESHOWN); new FXMenuCheck(viewmenu,tr("Undo Counters\t\tShow undo/redo counters on status line."),undoredoblock,FXWindow::ID_TOGGLESHOWN); new FXMenuCheck(viewmenu,tr("Clock\t\tShow clock on status line."),clock,FXWindow::ID_TOGGLESHOWN); @@ -687,6 +693,11 @@ void TextWindow::createMenubar(){ new FXMenuRadio(windowmenu,"&8",this,ID_WINDOW_8); new FXMenuRadio(windowmenu,"&9",this,ID_WINDOW_9); new FXMenuRadio(windowmenu,"1&0",this,ID_WINDOW_10); + new FXMenuRadio(windowmenu,"11",this,ID_WINDOW_11); + new FXMenuRadio(windowmenu,"12",this,ID_WINDOW_12); + new FXMenuRadio(windowmenu,"13",this,ID_WINDOW_13); + new FXMenuRadio(windowmenu,"14",this,ID_WINDOW_14); + new FXMenuRadio(windowmenu,"15",this,ID_WINDOW_15); // Help menu helpmenu=new FXMenuPane(this); @@ -874,7 +885,6 @@ void TextWindow::create(){ if(!urilistType){urilistType=getApp()->registerDragType(urilistTypeName);} getApp()->addTimeout(this,ID_CLOCKTIME,CLOCKTIMER); editor->setFocus(); - show(PLACEMENT_DEFAULT); } @@ -1621,8 +1631,7 @@ long TextWindow::onCmdPreferences(FXObject*,FXSelector,void*){ Preferences preferences(this); preferences.setPatternList(getPatternList()); preferences.setSyntax(getSyntax()); -// if(preferences.execute(PLACEMENT_OWNER)){ - if(preferences.execute()){ + if(preferences.execute(PLACEMENT_OWNER)){ setPatternList(preferences.getPatternList()); } return 1; @@ -1634,8 +1643,7 @@ long TextWindow::onCmdFont(FXObject*,FXSelector,void*){ FXFontDialog fontdlg(this,tr("Change Font"),DECOR_BORDER|DECOR_TITLE); FXFontDesc fontdesc=editor->getFont()->getFontDesc(); fontdlg.setFontDesc(fontdesc); -// if(fontdlg.execute(PLACEMENT_OWNER)){ - if(fontdlg.execute()){ + if(fontdlg.execute(PLACEMENT_OWNER)){ FXFont *oldfont=font; fontdesc=fontdlg.getFontDesc(); font=new FXFont(getApp(),fontdesc); @@ -1691,13 +1699,14 @@ long TextWindow::onUpdReopen(FXObject* sender,FXSelector,void* ptr){ // New long TextWindow::onCmdNew(FXObject*,FXSelector,void*){ - TextWindow *window=new TextWindow(getApp()); FXString file=getApp()->unique(FXPath::directory(filename)); + TextWindow *window=new TextWindow(getApp()); + window->create(); window->setFilename(file); window->setBrowserCurrentFile(file); - window->create(); window->raise(); window->setFocus(); + window->show(PLACEMENT_DEFAULT); return 1; } @@ -1711,7 +1720,6 @@ long TextWindow::onCmdOpen(FXObject*,FXSelector,void*){ opendialog.setPatternList(getPatternList()); opendialog.setCurrentPattern(getCurrentPattern()); opendialog.setFilename(file); -// if(opendialog.execute(PLACEMENT_OWNER)){ if(opendialog.execute()){ setCurrentPattern(opendialog.getCurrentPattern()); file=opendialog.getFilename(); @@ -1727,6 +1735,7 @@ long TextWindow::onCmdOpen(FXObject*,FXSelector,void*){ window->readView(file); window->determineSyntax(); window->parseModeline(); + window->setBrowserCurrentFile(file); } else{ FXMessageBox::error(window,MBOX_OK,tr("Error Loading File"),tr("Unable to load file: %s"),file.text()); @@ -1734,6 +1743,7 @@ long TextWindow::onCmdOpen(FXObject*,FXSelector,void*){ } window->raise(); window->setFocus(); + window->show(PLACEMENT_DEFAULT); } return 1; } @@ -1857,6 +1867,7 @@ long TextWindow::onCmdOpenSelected(FXObject*,FXSelector,void*){ window->readView(file); window->determineSyntax(); window->parseModeline(); + window->setBrowserCurrentFile(file); } else{ getApp()->beep(); @@ -1872,6 +1883,7 @@ long TextWindow::onCmdOpenSelected(FXObject*,FXSelector,void*){ // Bring up the window window->raise(); window->setFocus(); + window->show(PLACEMENT_DEFAULT); return 1; } } @@ -1896,6 +1908,7 @@ long TextWindow::onCmdOpenRecent(FXObject*,FXSelector,void* ptr){ window->readView(file); window->determineSyntax(); window->parseModeline(); + window->setBrowserCurrentFile(file); } else{ mrufiles.removeFile(file); @@ -1905,6 +1918,7 @@ long TextWindow::onCmdOpenRecent(FXObject*,FXSelector,void* ptr){ } window->raise(); window->setFocus(); + window->show(PLACEMENT_DEFAULT); return 1; } @@ -1940,7 +1954,6 @@ long TextWindow::onCmdSwitch(FXObject*,FXSelector,void*){ opendialog.setPatternList(getPatternList()); opendialog.setCurrentPattern(getCurrentPattern()); opendialog.setFilename(file); -// if(opendialog.execute(PLACEMENT_OWNER)){ if(opendialog.execute()){ setCurrentPattern(opendialog.getCurrentPattern()); file=opendialog.getFilename(); @@ -1949,6 +1962,7 @@ long TextWindow::onCmdSwitch(FXObject*,FXSelector,void*){ readView(file); determineSyntax(); parseModeline(); + setBrowserCurrentFile(file); } else{ getApp()->beep(); @@ -1972,6 +1986,7 @@ long TextWindow::onTextDNDDrop(FXObject*,FXSelector,void*){ readView(file); determineSyntax(); parseModeline(); + setBrowserCurrentFile(file); } else{ getApp()->beep(); @@ -2006,7 +2021,6 @@ long TextWindow::onCmdReplaceFile(FXObject*,FXSelector,void*){ opendialog.setPatternList(getPatternList()); opendialog.setCurrentPattern(getCurrentPattern()); opendialog.setDirectory(FXPath::directory(getFilename())); -// if(opendialog.execute(PLACEMENT_OWNER)){ if(opendialog.execute()){ setCurrentPattern(opendialog.getCurrentPattern()); file=opendialog.getFilename(); @@ -2032,7 +2046,6 @@ long TextWindow::onCmdExtractFile(FXObject*,FXSelector,void*){ savedialog.setCurrentPattern(getCurrentPattern()); savedialog.setDirectory(FXPath::directory(getFilename())); savedialog.setFilename(file); -// if(savedialog.execute(PLACEMENT_OWNER)){ if(savedialog.execute()){ setCurrentPattern(savedialog.getCurrentPattern()); file=savedialog.getFilename(); @@ -2061,7 +2074,6 @@ FXbool TextWindow::saveChanges(){ savedialog.setPatternList(getPatternList()); savedialog.setCurrentPattern(getCurrentPattern()); savedialog.setFilename(file); -// if(!savedialog.execute(PLACEMENT_OWNER)) return false; if(!savedialog.execute()) return false; setCurrentPattern(savedialog.getCurrentPattern()); file=savedialog.getFilename(); @@ -2108,7 +2120,6 @@ long TextWindow::onCmdSaveAs(FXObject*,FXSelector,void*){ savedialog.setPatternList(getPatternList()); savedialog.setCurrentPattern(getCurrentPattern()); savedialog.setFilename(file); -// if(savedialog.execute(PLACEMENT_OWNER)){ if(savedialog.execute()){ setCurrentPattern(savedialog.getCurrentPattern()); file=savedialog.getFilename(); @@ -2134,7 +2145,6 @@ long TextWindow::onCmdSaveTo(FXObject*,FXSelector,void*){ savedialog.setPatternList(getPatternList()); savedialog.setCurrentPattern(getCurrentPattern()); savedialog.setFilename(file); -// if(savedialog.execute(PLACEMENT_OWNER)){ if(savedialog.execute()){ file=savedialog.getFilename(); if(FXStat::exists(file)){ @@ -2222,7 +2232,6 @@ long TextWindow::onUpdate(FXObject* sender,FXSelector sel,void* ptr){ long TextWindow::onCmdPrint(FXObject*,FXSelector,void*){ FXPrintDialog dlg(this,tr("Print File")); FXPrinter printer; -// if(dlg.execute(PLACEMENT_OWNER)){ if(dlg.execute()){ dlg.getPrinter(printer); FXTRACE((100,"Printer = %s\n",printer.name.text())); @@ -2424,7 +2433,7 @@ long TextWindow::onUpdShowActive(FXObject* sender,FXSelector,void*){ // Toggle strip returns mode long TextWindow::onCmdStripReturns(FXObject*,FXSelector,void* ptr){ - stripcr=(FXbool)(FXuval)ptr; + stripcr=!!ptr; return 1; } @@ -2438,7 +2447,7 @@ long TextWindow::onUpdStripReturns(FXObject* sender,FXSelector,void*){ // Enable warning if file changed externally long TextWindow::onCmdWarnChanged(FXObject*,FXSelector,void* ptr){ - warnchanged=(FXbool)(FXuval)ptr; + warnchanged=!!ptr; return 1; } @@ -2452,7 +2461,7 @@ long TextWindow::onUpdWarnChanged(FXObject* sender,FXSelector,void*){ // Set initial size flag long TextWindow::onCmdUseInitialSize(FXObject*,FXSelector,void* ptr){ - initialsize=(FXbool)(FXuval)ptr; + initialsize=!!ptr; return 1; } @@ -2474,7 +2483,7 @@ long TextWindow::onCmdSetInitialSize(FXObject*,FXSelector,void*){ // Toggle strip spaces mode long TextWindow::onCmdStripSpaces(FXObject*,FXSelector,void* ptr){ - stripsp=(FXbool)(FXuval)ptr; + stripsp=!!ptr; return 1; } @@ -2488,7 +2497,7 @@ long TextWindow::onUpdStripSpaces(FXObject* sender,FXSelector,void*){ // Toggle append newline mode long TextWindow::onCmdAppendNewline(FXObject*,FXSelector,void* ptr){ - appendnl=(FXbool)(FXuval)ptr; + appendnl=!!ptr; return 1; } @@ -2503,7 +2512,7 @@ long TextWindow::onUpdAppendNewline(FXObject* sender,FXSelector,void*){ // Toggle append carriage return mode long TextWindow::onCmdAppendCarriageReturn(FXObject*,FXSelector,void* ptr){ - appendcr=(FXbool)(FXuval)ptr; + appendcr=!!ptr; return 1; } @@ -3013,7 +3022,6 @@ FXbool TextWindow::doneCommand(){ long TextWindow::onCmdShellDialog(FXObject*,FXSelector,void*){ if(!shellCommand){ FXInputDialog dialog(this,tr("Execute Command"),tr("&Execute shell command:"),nullptr,INPUTDIALOG_STRING,0,0,400,0); -// if(dialog.execute(PLACEMENT_OWNER)){ if(dialog.execute()){ // Get command @@ -3041,7 +3049,6 @@ long TextWindow::onUpdShellDialog(FXObject* sender,FXSelector,void*){ long TextWindow::onCmdShellFilter(FXObject*,FXSelector,void*){ if(!shellCommand){ FXInputDialog dialog(this,tr("Filter Selection"),tr("&Filter selection with shell command:"),nullptr,INPUTDIALOG_STRING,0,0,400,0); -// if(dialog.execute(PLACEMENT_OWNER)){ if(dialog.execute()){ // Get command diff --git a/adie/TextWindow.h b/adie/TextWindow.h index 89b62c1..48885ee 100644 --- a/adie/TextWindow.h +++ b/adie/TextWindow.h @@ -457,6 +457,11 @@ class TextWindow : public FXMainWindow { ID_WINDOW_8, ID_WINDOW_9, ID_WINDOW_10, + ID_WINDOW_11, + ID_WINDOW_12, + ID_WINDOW_13, + ID_WINDOW_14, + ID_WINDOW_15, ID_SYNTAX_FIRST, ID_SYNTAX_LAST=ID_SYNTAX_FIRST+100, ID_STYLE_NORMAL_FG_FIRST, diff --git a/adie/adie.1 b/adie/adie.1 index 3560cf7..d2fea4e 100644 --- a/adie/adie.1 +++ b/adie/adie.1 @@ -26,38 +26,38 @@ at the same place in the file, and the text will be colorized like last time. .SH OPTIONS .TP -\fB\-?\fR, \fB\-h\fR, or \fB\--help\fR +\fB\-h\fR, or \fB\--help\fR Print summary usage information of all the supported options. .TP -\fB\-v\fR \fB\--view\fR +\fB\--view\fR Open the file for viewing only. Editor commands which change the text are not allowed. .TP -\fB\-e\fR \fB\--edit\fR +\fB\--edit\fR Open the file for editing. .TP -\fB\-V\fR \fB\--version\fR +\fB\--version\fR Display version and license information. .TP -\fB\-l\fR\fI \fR \fB\--line\fR\fI \fR +\fR \fB\--line=\fR\fI\fR Jump to given line number after opening file for editing. .TP -\fB\-c\fR\fI \fR \fB\--col\fR\fI \fR +\fR \fB\--column=\fR\fI\fR Jump to given column number after opening file for editing; often used in addition to the previous parameter to jump to a particular place in the text. .TP -\fB\-S\fR\fI \fR \fB\--syntax\fR\fI \fR +\fR \fB\--syntax=\fR\fI\fR Load the syntax rules from the given syntax file rather than searching for the syntax file in the usual places (a file called "Adie.stx" in one of the $PATH directories, or the syntax file listed in the configuration settings). .TP -\fB\-L\fR\fI \fR \fB\--lang\fR\fI \fR +\fB\--lang=\fR\fI\fR After loading the file, switch to the given programming language for syntax coloring. The normal rules for determining the file's syntax (file extension of content maching) are ignored. diff --git a/controlpanel/ControlPanel.cpp b/controlpanel/ControlPanel.cpp index 6f416f1..d2142e5 100644 --- a/controlpanel/ControlPanel.cpp +++ b/controlpanel/ControlPanel.cpp @@ -321,7 +321,7 @@ FXDesktopSetup::FXDesktopSetup(FXApp *ap):FXMainWindow(ap,FXString::null,nullptr new FXCheckButton(packer,tr("Change directory\t\tChange directory before running command."),this,ID_CHANGE_DIRECTORY,ICON_BEFORE_TEXT|LAYOUT_LEFT|LAYOUT_SIDE_BOTTOM); new FXButton(packer,"...",nullptr,this,ID_SELECT_COMMAND,LAYOUT_SIDE_RIGHT|LAYOUT_CENTER_Y|FRAME_RAISED|FRAME_THICK); FXTextField* command=new FXTextField(packer,2,&target_filebinding_command,FXDataTarget::ID_VALUE,LAYOUT_SIDE_LEFT|LAYOUT_FILL_X|LAYOUT_CENTER_Y|FRAME_SUNKEN|FRAME_THICK); - command->setTipText(tr("Path to program associated with the file\nCommand line arguments are assembled from the selected file(s) as follows:\n %f Replaced by current filename;\n %F Replaced by selected filenames;\n %u Replaced by URL encoding of current filename;\n %U Replaced by URL encoding of selected files;\n %d Replaced by current working directory;\n %% Replaced by simply '%'.")); + command->setTipText(tr("Path to program associated with the file\nCommand line arguments are assembled from the selected file(s) as follows:\n %f Replaced by current pathname;\n %F Replaced by selected pathnames;\n %n Replaced by current filename;\n %N Replaced by selected filenames;\n %u Replaced by URL encoding of current filename;\n %U Replaced by URL encoding of selected files;\n %d Replaced by current working directory;\n %% Replaced by simply '%'.")); new FXSeparator(vframe7,SEPARATOR_GROOVE|LAYOUT_FILL_X); // Mime types @@ -351,7 +351,9 @@ FXDesktopSetup::FXDesktopSetup(FXApp *ap):FXMainWindow(ap,FXString::null,nullptr /// Miscellaneous Parameters Panel /// FXHorizontalFrame* hframe5=new FXHorizontalFrame(switcher,LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,0,0,0,0,0,0); - FXMatrix* matrix2=new FXMatrix(hframe5,3,LAYOUT_FILL_Y|MATRIX_BY_COLUMNS,0,0,0,0,DEFAULT_SPACING,DEFAULT_SPACING,DEFAULT_SPACING,DEFAULT_SPACING); + + // First column of settings + FXMatrix* matrix2=new FXMatrix(hframe5,3,LAYOUT_FILL_X|LAYOUT_FILL_Y|MATRIX_BY_COLUMNS,0,0,0,0,DEFAULT_SPACING,DEFAULT_SPACING,DEFAULT_SPACING,DEFAULT_SPACING); // Type speed new FXLabel(matrix2,tr("Typing Speed\t\tTyping Speed"),nullptr,LAYOUT_RIGHT|LAYOUT_CENTER_Y); @@ -428,26 +430,52 @@ FXDesktopSetup::FXDesktopSetup(FXApp *ap):FXMainWindow(ap,FXString::null,nullptr FXSpinner* spinner11=new FXSpinner(matrix2,4,&target_wheellines,FXDataTarget::ID_VALUE,FRAME_SUNKEN|FRAME_THICK); spinner11->setRange(1,100); + // Vertical separator new FXSeparator(hframe5,SEPARATOR_GROOVE|LAYOUT_FILL_Y); - FXMatrix* matrix3=new FXMatrix(hframe5,2,LAYOUT_FILL_Y|MATRIX_BY_COLUMNS,0,0,0,0,DEFAULT_SPACING,DEFAULT_SPACING,DEFAULT_SPACING,DEFAULT_SPACING); + // Second column of settings + FXMatrix* matrix3=new FXMatrix(hframe5,2,LAYOUT_FILL_X|LAYOUT_FILL_Y|MATRIX_BY_COLUMNS,0,0,0,0,DEFAULT_SPACING,DEFAULT_SPACING,DEFAULT_SPACING,DEFAULT_SPACING); // Maximum colors spinner - new FXLabel(matrix3,tr("Maximum Colors Allocated")); + new FXLabel(matrix3,tr("Maximum Colors Allocated"),nullptr,LAYOUT_RIGHT|LAYOUT_CENTER_Y); FXSpinner* spinner12=new FXSpinner(matrix3,3,&target_maxcolors,FXDataTarget::ID_VALUE,FRAME_SUNKEN|FRAME_THICK); spinner12->setRange(1,256); // Gamma correction spinner - new FXLabel(matrix3,tr("Gamma Correction")); + new FXLabel(matrix3,tr("Gamma Correction"),nullptr,LAYOUT_RIGHT|LAYOUT_CENTER_Y); FXRealSpinner* spinner13=new FXRealSpinner(matrix3,3,&target_gamma,FXDataTarget::ID_VALUE,FRAME_SUNKEN|FRAME_THICK); spinner13->setRange(0.0,5.0); spinner13->setIncrement(0.1); // Scrollbar size spinner - new FXLabel(matrix3,tr("Scrollbar Size")); + new FXLabel(matrix3,tr("Scrollbar Size"),nullptr,LAYOUT_RIGHT|LAYOUT_CENTER_Y); FXSpinner* spinner14=new FXSpinner(matrix3,3,&target_barsize,FXDataTarget::ID_VALUE,FRAME_SUNKEN|FRAME_THICK); spinner14->setRange(5,100); + // Xft hint style + new FXLabel(matrix3,tr("Xft font hint style"),nullptr,LAYOUT_RIGHT|LAYOUT_CENTER_Y); + FXListBox* list2=new FXListBox(matrix3,&target_hintstyle,FXDataTarget::ID_VALUE,FRAME_SUNKEN|FRAME_THICK|LAYOUT_TOP); + list2->fillItems(tr("None\nSlight\nMedium\nFull")); + list2->setNumVisible(4); + + // Xft sub-pixel rendering + new FXLabel(matrix3,tr("Xft font sub-pixel rendering"),nullptr,LAYOUT_RIGHT|LAYOUT_CENTER_Y); + FXListBox* list3=new FXListBox(matrix3,&target_subpixel,FXDataTarget::ID_VALUE,FRAME_SUNKEN|FRAME_THICK|LAYOUT_TOP); + list3->fillItems(tr("Unknown\nRGB\nBGR\nVRGB\nVBGR\nNone")); + list3->setNumVisible(6); + + // Xft font hinting + new FXLabel(matrix3,tr("Xft font hinting"),nullptr,LAYOUT_RIGHT|LAYOUT_CENTER_Y); + new FXCheckButton(matrix3,FXString::null,&target_hinting,FXDataTarget::ID_VALUE); + + // Xft font autohint + new FXLabel(matrix3,tr("Xft font autohint"),nullptr,LAYOUT_RIGHT|LAYOUT_CENTER_Y); + new FXCheckButton(matrix3,FXString::null,&target_autohint,FXDataTarget::ID_VALUE); + + // Xft font anti-aliasing + new FXLabel(matrix3,tr("Xft font anti-aliasing"),nullptr,LAYOUT_RIGHT|LAYOUT_CENTER_Y); + new FXCheckButton(matrix3,FXString::null,&target_antialias,FXDataTarget::ID_VALUE); + // Close button etc. new FXSeparator(main,SEPARATOR_GROOVE|LAYOUT_FILL_X); FXHorizontalFrame *closebox=new FXHorizontalFrame(main,LAYOUT_BOTTOM|LAYOUT_FILL_X,0,0,0,0,DEFAULT_SPACING,DEFAULT_SPACING,DEFAULT_SPACING,DEFAULT_SPACING); @@ -490,6 +518,13 @@ FXDesktopSetup::FXDesktopSetup(FXApp *ap):FXMainWindow(ap,FXString::null,nullptr maxcolors=125; gamma=1.0; + // Fonts stuff + subpixel=0; + hintstyle=3; + hinting=true; + autohint=false; + antialias=true; + filebinding.flags=0; // Color data targets associations @@ -519,6 +554,11 @@ FXDesktopSetup::FXDesktopSetup(FXApp *ap):FXMainWindow(ap,FXString::null,nullptr target_barsize.connect(barSize); target_maxcolors.connect(maxcolors); target_gamma.connect(gamma); + target_subpixel.connect(subpixel); + target_hintstyle.connect(hintstyle); + target_hinting.connect(hinting); + target_autohint.connect(autohint); + target_antialias.connect(antialias); // File data target associations target_filebinding_description.connect(filebinding.description); @@ -1222,6 +1262,29 @@ FXbool FXDesktopSetup::readSettingsFile(const FXString& file){ // Display tweaks maxcolors=desktopsettings.readUIntEntry("SETTINGS","maxcolors",125); gamma=desktopsettings.readRealEntry("SETTINGS","displaygamma",1.0); + + // Xft font sub-pixel rendering + const FXchar *rgba=desktopsettings.readStringEntry("Xft","rgba","unknown"); + if(rgba[0]=='u') subpixel=0; + else if(rgba[0]=='r') subpixel=1; + else if(rgba[0]=='b') subpixel=2; + else if(rgba[0]=='v' && rgba[1]=='r') subpixel=3; + else if(rgba[0]=='v' && rgba[1]=='b') subpixel=4; + else if(rgba[0]=='n') subpixel=5; + else subpixel=0; + + // Xft font hint level + const FXchar *hints=desktopsettings.readStringEntry("Xft","hintstyle","full"); + if(hints[0]=='s') hintstyle=1; + else if(hints[0]=='m') hintstyle=2; + else if(hints[0]=='f') hintstyle=3; + else if(hints[0]=='n') hintstyle=0; + else hintstyle=0; + + // Xft font flags + hinting=desktopsettings.readBoolEntry("Xft","hinting",true); + autohint=desktopsettings.readBoolEntry("Xft","autohint",false); + antialias=desktopsettings.readBoolEntry("Xft","antialias",true); return true; } return false; @@ -1272,6 +1335,30 @@ FXbool FXDesktopSetup::writeSettingsFile(const FXString& file){ desktopsettings.writeUIntEntry("SETTINGS","maxcolors",maxcolors); desktopsettings.writeRealEntry("SETTINGS","displaygamma",gamma); + // Xft font sub-pixel rendering + const FXchar *rgba="unknown"; + if(subpixel==0) rgba="unknown"; + else if(subpixel==1) rgba="rgb"; + else if(subpixel==2) rgba="bgr"; + else if(subpixel==3) rgba="vrgb"; + else if(subpixel==4) rgba="vbgr"; + else if(subpixel==5) rgba="none"; + desktopsettings.writeStringEntry("Xft","rgba",rgba); + + // Xft font hint level + const FXchar *hints="full"; + if(hintstyle==1) hints="slight"; + else if(hintstyle==2) hints="medium"; + else if(hintstyle==3) hints="full"; + else if(hintstyle==0) hints="none"; + desktopsettings.writeStringEntry("Xft","hintstyle",hints); + + // Xft font flags + desktopsettings.writeBoolEntry("Xft","hinting",hinting); + desktopsettings.writeBoolEntry("Xft","autohint",autohint); + desktopsettings.writeBoolEntry("Xft","antialias",antialias); + + // Write file if(FXDir::createDirectories(FXPath::upLevel(file))){ if(desktopsettings.unparseFile(file)){ diff --git a/controlpanel/ControlPanel.h b/controlpanel/ControlPanel.h index 46c6cf7..c30384d 100644 --- a/controlpanel/ControlPanel.h +++ b/controlpanel/ControlPanel.h @@ -126,6 +126,11 @@ class FXDesktopSetup : public FXMainWindow { FXint wheelLines; FXint barSize; FXfloat gamma; + FXint subpixel; + FXint hintstyle; + FXbool hinting; + FXbool autohint; + FXbool antialias; FXFileBinding filebinding; // Current file binding private: FXDataTarget target_base; // Color targets @@ -152,6 +157,11 @@ class FXDesktopSetup : public FXMainWindow { FXDataTarget target_barsize; // Scroll bar size FXDataTarget target_maxcolors; // Maximum colors FXDataTarget target_gamma; // Display gamma value + FXDataTarget target_subpixel; // Xft font subpixel mode + FXDataTarget target_hintstyle; // Xft font hint style + FXDataTarget target_hinting; // Xft font hinting + FXDataTarget target_autohint; // Xft autohint + FXDataTarget target_antialias; // Xft anti-aliasing FXDataTarget target_filebinding_description; FXDataTarget target_filebinding_command; FXDataTarget target_iconpath; diff --git a/doc/news.html b/doc/news.html index 8e48e53..b9a32cb 100644 --- a/doc/news.html +++ b/doc/news.html @@ -15,6 +15,56 @@ + +

+
+October 10 - FOX DEVELOPMENT 1.7.80 +
+

+ +

    +
  • New Visual C++ 2015 build project files for FOX distribution; you should be able to import them to any post-2015 version +of Visual Studio.
  • +
  • Conversions to smaller integer sizes in FXVariant now saturate to maximum (unsigned) values; success-flag will +be set false if saturation happens.
  • +
  • ControlPanel has new section for configuring "sub-pixel rendering" feature for Linux font system.
  • +
  • New feature in JSON parser/unparser is to allow saving in JSON5 mode; default is still regular JSON mode.
  • +
  • JSON unparser allow setting preferred quote type.
  • +
  • JSON unparser allows unicode identifiers for keys.
  • +
  • Minor bug in JSON parser when parsing and unescaping string: ensure we're using the correct quote type (JSON5 allows two +quote types).
  • +
  • Improved matrix to quaternion code.
  • +
  • In FXVariantMap, space reserved for 32-bit machines was updated.
  • +
  • FXVariant now has some API's to remove item from map (if map type), or array (if array type).
  • +
  • Allow for a few more items in Adie's window list and recent file list.
  • +
  • Minor updates to Adie man page for new commands format.
  • +
  • Adie FindInFiles now remembers previous search directory when scrolling back to prior search commands.
  • +
  • Can start Adie with given window size now.
  • +
  • Slightly simpler syntax is possible to open file onto given line number (and column).
  • +
  • Allow ascii mode when reading registry on Windows; is command line parameter in FXApp.
  • +
  • Silenced numerous warnings introduced enabling new compiler flags.
  • +
  • Small layout problem fixed in PathFinder.
  • +
  • Updated VC++ Studio project files: 64-bit build now default..
  • +
  • Some bug fixes in fxendian bit manipulation APIs.
  • +
  • API added to find system directory.
  • +
  • Also __snprintf() and __vsnprintf() now handle denormal floats even when library was compiled for release (with FTZ/DAZ).
  • +
  • Bug fixes in FXText.
  • +
  • Minor warning fixes.
  • +
  • More user-friendly type-names in FXVariant.
  • +
  • Fixes in FXReadWriteLock for MacOS.
  • +
  • Calling adopt() on FXSettings sets both instances to modified, as it should have.
  • +
  • FXColorDialog remembers its size from last time it was used.
  • +
  • FXFileSelector/FXFileDialog change: in SELECTFILE_MULTIPLE and SELECTFILE_MULTIPLE_ALL more user-friendly +encoding of multiple filenames in text box using commas ','.
  • +
  • Adie editor Find In Files remembers search-folder as well as previous search-parameters in search-history scrollback.
  • +
  • Launching Adie with not just file, but optionally line and column number as well. Handy for compiler warnings.
  • +
  • Also, can pass geometry specification on command-line to bring up Adie with given window size and location.
  • +
  • FOX applications can now load registry settings from text file on windows, thanks to new command-option parsed by FXApp.
  • +
  • Use some intrinsic x86-64 (or x86) instructions for bit-manipulations where possible.
  • +
  • Backward scanning UTF8 API, plus many other UTF8 APIs now inlined; some macroes replaced by inlines.
  • +
+ +

diff --git a/glviewer/FXGLShape.cpp b/glviewer/FXGLShape.cpp index 2b732ed..7cf38a9 100644 --- a/glviewer/FXGLShape.cpp +++ b/glviewer/FXGLShape.cpp @@ -209,10 +209,10 @@ FXbool FXGLShape::drag(FXGLViewer* viewer,FXint fx,FXint fy,FXint tx,FXint ty){ return true; } +#ifdef HAVE_GL_H // Draw void FXGLShape::draw(FXGLViewer* viewer){ -#ifdef HAVE_GL_H // Save attributes and matrix // glPushAttrib(GL_ENABLE_BIT|GL_CURRENT_BIT|GL_LIGHTING_BIT|GL_POINT_BIT|GL_LINE_BIT|GL_POLYGON_BIT); @@ -356,9 +356,16 @@ void FXGLShape::draw(FXGLViewer* viewer){ // Restore attributes and matrix glPopMatrix(); glPopAttrib(); -#endif } +#else + +// Draw +void FXGLShape::draw(FXGLViewer*){ + } + +#endif + // Draw for hit void FXGLShape::hit(FXGLViewer* viewer){ diff --git a/glviewer/glviewer.cpp b/glviewer/glviewer.cpp index 1e36b28..193095d 100644 --- a/glviewer/glviewer.cpp +++ b/glviewer/glviewer.cpp @@ -975,7 +975,7 @@ int main(int argc,char *argv[]){ // Here we begin -int main(int argc,char *argv[]){ +int main(int,char*[]){ fxmessage("The FOX Library was compiled without OpenGL\n"); return 0; } diff --git a/include/FXArray.h b/include/FXArray.h index de4f9ef..ca8935c 100644 --- a/include/FXArray.h +++ b/include/FXArray.h @@ -269,8 +269,8 @@ class FXArray : public FXArrayBase { } /// Remove all objects - void clear(){ - no(0); + FXbool clear(){ + return no(0); } /// Delete data diff --git a/include/FXBMPIcon.h b/include/FXBMPIcon.h index 53136b6..dfb2f03 100644 --- a/include/FXBMPIcon.h +++ b/include/FXBMPIcon.h @@ -49,7 +49,7 @@ class FXAPI FXBMPIcon : public FXIcon { public: /// Construct icon from memory stream formatted in Microsoft BMP format - FXBMPIcon(FXApp* a,const void *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1); + FXBMPIcon(FXApp* a,const FXuchar *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1); /// Save pixels into stream in Microsoft bitmap format virtual FXbool savePixels(FXStream& store) const; diff --git a/include/FXBMPImage.h b/include/FXBMPImage.h index 3265312..e484a01 100644 --- a/include/FXBMPImage.h +++ b/include/FXBMPImage.h @@ -49,7 +49,7 @@ class FXAPI FXBMPImage : public FXImage { public: /// Construct image from memory stream formatted in Microsoft BMP format - FXBMPImage(FXApp* a,const void *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1); + FXBMPImage(FXApp* a,const FXuchar *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1); /// Save pixels into stream in Microsoft bitmap format virtual FXbool savePixels(FXStream& store) const; diff --git a/include/FXBitmap.h b/include/FXBitmap.h index 87ee635..2d08ae9 100644 --- a/include/FXBitmap.h +++ b/include/FXBitmap.h @@ -81,7 +81,7 @@ class FXAPI FXBitmap : public FXDrawable { * large bitmaps to instruct render() to use shared memory to communicate * with the server. */ - FXBitmap(FXApp* a,const void *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1); + FXBitmap(FXApp* a,const FXuchar *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1); /// Change options void setOptions(FXuint opts); diff --git a/include/FXCURCursor.h b/include/FXCURCursor.h index e36d44c..8ce92a6 100644 --- a/include/FXCURCursor.h +++ b/include/FXCURCursor.h @@ -44,7 +44,7 @@ class FXAPI FXCURCursor : public FXCursor { * Construct a cursor from memory stream in Microsoft CUR format. * The image is limited to 32x32 pixels. */ - FXCURCursor(FXApp* a,const void* pix); + FXCURCursor(FXApp* a,const FXuchar* pix); /// Save pixel data only, in CUR format virtual FXbool savePixels(FXStream& store) const; diff --git a/include/FXColorDialog.h b/include/FXColorDialog.h index a42c5d8..15a75ed 100644 --- a/include/FXColorDialog.h +++ b/include/FXColorDialog.h @@ -48,6 +48,8 @@ class FXAPI FXColorDialog : public FXDialogBox { static const FXchar sectionName[]; protected: FXColorDialog(){} + void readRegistry(); + void writeRegistry(); private: FXColorDialog(const FXColorDialog&); FXColorDialog &operator=(const FXColorDialog&); diff --git a/include/FXComboBox.h b/include/FXComboBox.h index e814be6..edd58ec 100644 --- a/include/FXComboBox.h +++ b/include/FXComboBox.h @@ -206,7 +206,7 @@ class FXAPI FXComboBox : public FXPacker { * passing SEARCH_PREFIX causes searching for a prefix of the item name. * Return -1 if no matching item is found. */ - FXint findItem(const FXString& text,FXint start=-1,FXuint flags=SEARCH_FORWARD|SEARCH_WRAP) const; + FXint findItem(const FXString& string,FXint start=-1,FXuint flags=SEARCH_FORWARD|SEARCH_WRAP) const; /** * Search items by associated user data, beginning from item start. If the diff --git a/include/FXDDSIcon.h b/include/FXDDSIcon.h index 72b3e0f..62f4eff 100644 --- a/include/FXDDSIcon.h +++ b/include/FXDDSIcon.h @@ -45,7 +45,7 @@ class FXAPI FXDDSIcon : public FXIcon { public: /// Construct icon from memory stream formatted in DDS format - FXDDSIcon(FXApp* a,const void *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1); + FXDDSIcon(FXApp* a,const FXuchar *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1); /// Save pixels into stream in DDS format virtual FXbool savePixels(FXStream& store) const; diff --git a/include/FXDDSImage.h b/include/FXDDSImage.h index eae4fc2..2e6712b 100644 --- a/include/FXDDSImage.h +++ b/include/FXDDSImage.h @@ -45,7 +45,7 @@ class FXAPI FXDDSImage : public FXImage { public: /// Construct image from memory stream formatted in DDS format - FXDDSImage(FXApp* a,const void *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1); + FXDDSImage(FXApp* a,const FXuchar *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1); /// Save pixels into stream in DDS format virtual FXbool savePixels(FXStream& store) const; diff --git a/include/FXDictionary.h b/include/FXDictionary.h index cd7fab4..46625ec 100644 --- a/include/FXDictionary.h +++ b/include/FXDictionary.h @@ -37,7 +37,7 @@ class FXAPI FXDictionary { protected: struct Entry { FXString key; // Key - FXptr data; // Value + void* data; // Value FXuint hash; // Hash of key }; protected: @@ -94,43 +94,43 @@ class FXAPI FXDictionary { FXbool has(const FXString& ky) const { return has(ky.text()); } /// Return reference to slot assocated with given key - FXptr& at(const FXchar* ky); + void*& at(const FXchar* ky); /// Return constant reference to slot assocated with given key - const FXptr& at(const FXchar* ky) const; + void *const& at(const FXchar* ky) const; /// Return reference to slot assocated with given key - FXptr& at(const FXString& ky){ return at(ky.text()); } + void*& at(const FXString& ky){ return at(ky.text()); } /// Return constant reference to slot assocated with given key - const FXptr& at(const FXString& ky) const { return at(ky.text()); } + void *const& at(const FXString& ky) const { return at(ky.text()); } /// Return reference to slot assocated with given key - FXptr& operator[](const FXchar* ky){ return at(ky); } + void*& operator[](const FXchar* ky){ return at(ky); } /// Return constant reference to slot assocated with given key - const FXptr& operator[](const FXchar* ky) const { return at(ky); } + void *const& operator[](const FXchar* ky) const { return at(ky); } /// Return reference to slot assocated with given key - FXptr& operator[](const FXString& ky){ return at(ky); } + void*& operator[](const FXString& ky){ return at(ky); } /// Return constant reference to slot assocated with given key - const FXptr& operator[](const FXString& ky) const { return at(ky); } + void *const& operator[](const FXString& ky) const { return at(ky); } /// Insert association with given key; return old value, if any - FXptr insert(const FXchar* ky,FXptr ptr=nullptr){ return swap(ptr,at(ky)); } + void* insert(const FXchar* ky,void* ptr=nullptr){ return swap(ptr,at(ky)); } /// Insert association with given key; return old value, if any - FXptr insert(const FXString& ky,FXptr ptr=nullptr){ return swap(ptr,at(ky)); } + void* insert(const FXString& ky,void* ptr=nullptr){ return swap(ptr,at(ky)); } /// Remove association with given key; return old value, if any - FXptr remove(const FXchar* ky); + void* remove(const FXchar* ky); /// Remove association with given key; return old value, if any - FXptr remove(const FXString& ky){ return remove(ky.text()); } + void* remove(const FXString& ky){ return remove(ky.text()); } /// Erase data at pos in the table; return old value, if any - FXptr erase(FXival pos); + void* erase(FXival pos); /// Return true if slot is empty. FXbool empty(FXival pos) const { return table[pos].key.empty(); } @@ -139,13 +139,13 @@ class FXAPI FXDictionary { const FXString& key(FXival pos) const { return table[pos].key; } /// Return reference to slot at position pos - FXptr& data(FXival pos){ return table[pos].data; } + void*& data(FXival pos){ return table[pos].data; } /// Return constant reference to slot at position pos - const FXptr& data(FXival pos) const { return table[pos].data; } + void *const& data(FXival pos) const { return table[pos].data; } /// Clear entire table - void clear(); + FXbool clear(); /// Destroy table ~FXDictionary(); diff --git a/include/FXDirDialog.h b/include/FXDirDialog.h index 213bec5..6843bd5 100644 --- a/include/FXDirDialog.h +++ b/include/FXDirDialog.h @@ -42,6 +42,8 @@ class FXAPI FXDirDialog : public FXDialogBox { FXDECLARE(FXDirDialog) protected: FXDirSelector *dirbox; // Directory selection widget +protected: + static const FXchar sectionName[]; protected: FXDirDialog(){} void initdialog(); diff --git a/include/FXDirList.h b/include/FXDirList.h index 67702f9..7e81e70 100644 --- a/include/FXDirList.h +++ b/include/FXDirList.h @@ -280,13 +280,16 @@ class FXAPI FXDirList : public FXTreeList { virtual FXbool expandTree(FXTreeItem* tree,FXbool notify=false); /// Change wildcard matching pattern - void setPattern(const FXString& ptrn,FXbool notify=false); + FXbool selectMatching(const FXString& ptrn="*",FXuint mode=FXPath::PathName|FXPath::NoEscape,FXbool notify=false); + + /// Change wildcard matching pattern + void setPattern(const FXString& ptrn="*",FXbool notify=false); /// Return wildcard pattern FXString getPattern() const { return pattern; } /// Change wildcard matching mode (see FXPath) - void setMatchMode(FXuint mode,FXbool notify=false); + void setMatchMode(FXuint mode=FXPath::PathName|FXPath::NoEscape,FXbool notify=false); /// Return wildcard matching mode FXuint getMatchMode() const { return matchmode; } diff --git a/include/FXDisplay.h b/include/FXDisplay.h index 8bc2fbb..43397c4 100644 --- a/include/FXDisplay.h +++ b/include/FXDisplay.h @@ -28,6 +28,8 @@ namespace FX { * Display class. */ class FXAPI FXDisplay { +private: + FXptr display; // Display private: FXDisplay(const FXDisplay&); FXDisplay &operator=(const FXDisplay&); diff --git a/include/FXEXEIcon.h b/include/FXEXEIcon.h index 420cddb..a7781a9 100644 --- a/include/FXEXEIcon.h +++ b/include/FXEXEIcon.h @@ -45,7 +45,7 @@ class FXAPI FXEXEIcon : public FXIcon { public: /// Construct icon from memory stream comprising Microsoft Windows executable - FXEXEIcon(FXApp* a,const void *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1,FXint ri=-1,FXint rt=3); + FXEXEIcon(FXApp* a,const FXuchar *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1,FXint ri=-1,FXint rt=3); /// Set resource group (type) to load from void setResType(FXint rt){ rtype=rt; } diff --git a/include/FXEXEImage.h b/include/FXEXEImage.h index 868d8de..4f007e6 100644 --- a/include/FXEXEImage.h +++ b/include/FXEXEImage.h @@ -44,7 +44,7 @@ class FXAPI FXEXEImage : public FXImage { public: /// Construct image from memory stream comprising Microsoft Windows executable - FXEXEImage(FXApp* a,const void *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1,FXint ri=-1,FXint rt=3); + FXEXEImage(FXApp* a,const FXuchar *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1,FXint ri=-1,FXint rt=3); /// Set resource group (type) to load from void setResType(FXint rt){ rtype=rt; } diff --git a/include/FXFileDialog.h b/include/FXFileDialog.h index 30aa03f..fdd83a3 100644 --- a/include/FXFileDialog.h +++ b/include/FXFileDialog.h @@ -42,8 +42,8 @@ class FXAPI FXFileDialog : public FXDialogBox { static const FXchar sectionName[]; protected: FXFileDialog(){} - void loadSettings(); - void saveSettings(); + void readRegistry(); + void writeRegistry(); private: FXFileDialog(const FXFileDialog&); FXFileDialog &operator=(const FXFileDialog&); @@ -55,6 +55,12 @@ class FXAPI FXFileDialog : public FXDialogBox { /// Construct free-floating file dialog box FXFileDialog(FXApp* a,const FXString& name,FXuint opts=0,FXint x=0,FXint y=0,FXint w=500,FXint h=300); + /// Create server-side resources + virtual void create(); + + /// Destroy server-side resources + virtual void destroy(); + /// Change file name void setFilename(const FXString& path); diff --git a/include/FXFileList.h b/include/FXFileList.h index 94a4ff9..8b59b8c 100644 --- a/include/FXFileList.h +++ b/include/FXFileList.h @@ -163,6 +163,7 @@ class FXAPI FXFileList : public FXIconList { void delete_files(const FXString& files); void copy_files(const FXString& directory,const FXString& files); void move_files(const FXString& directory,const FXString& files); + static FXint compareSectionNatural(const FXchar* s1,const FXchar* s2,FXint s,FXbool ci=false); private: FXFileList(const FXFileList&); FXFileList &operator=(const FXFileList&); @@ -330,14 +331,17 @@ class FXAPI FXFileList : public FXIconList { /// Return the mode bits for this item FXuint getItemMode(FXint index) const; + /// Select files matching wildcard pattern + FXbool selectMatching(const FXString& ptrn="*",FXuint mode=FXPath::PathName|FXPath::NoEscape,FXbool notify=false); + /// Change wildcard matching pattern - void setPattern(const FXString& ptrn,FXbool notify=false); + void setPattern(const FXString& ptrn="*",FXbool notify=false); /// Return wildcard pattern FXString getPattern() const { return pattern; } /// Change wildcard matching mode (see FXPath) - void setMatchMode(FXuint mode,FXbool notify=false); + void setMatchMode(FXuint mode=FXPath::PathName|FXPath::NoEscape,FXbool notify=false); /// Return wildcard matching mode FXuint getMatchMode() const { return matchmode; } diff --git a/include/FXFileSelector.h b/include/FXFileSelector.h index cf6d8da..ef09ff7 100644 --- a/include/FXFileSelector.h +++ b/include/FXFileSelector.h @@ -155,6 +155,9 @@ class FXAPI FXFileSelector : public FXPacker { /// Constructor FXFileSelector(FXComposite *p,FXObject* tgt=nullptr,FXSelector sel=0,FXuint opts=0,FXint x=0,FXint y=0,FXint w=0,FXint h=0); + /// Create server-side resources + virtual void create(); + /// Return a pointer to the "Accept" button FXButton *acceptButton() const { return accept; } @@ -284,7 +287,7 @@ class FXAPI FXFileSelector : public FXPacker { FXbool getReadOnly() const; /// Allow or disallow navigation - void allowNavigation(FXbool flag){ navigable=flag; } + void allowNavigation(FXbool flag); /// Is navigation allowed? FXbool allowNavigation() const { return navigable; } diff --git a/include/FXFoldingList.h b/include/FXFoldingList.h index 2dd2608..80a13de 100644 --- a/include/FXFoldingList.h +++ b/include/FXFoldingList.h @@ -486,7 +486,7 @@ class FXAPI FXFoldingList : public FXScrollArea { * passing SEARCH_PREFIX causes searching for a prefix of the item name. * Return NULL if no matching item is found. */ - FXFoldingItem* findItem(const FXString& text,FXFoldingItem* start=nullptr,FXuint flags=SEARCH_FORWARD|SEARCH_WRAP) const; + FXFoldingItem* findItem(const FXString& string,FXFoldingItem* start=nullptr,FXuint flags=SEARCH_FORWARD|SEARCH_WRAP) const; /** * Search items by associated user data, beginning from item start. If the diff --git a/include/FXGIFCursor.h b/include/FXGIFCursor.h index d6c9629..7506af6 100644 --- a/include/FXGIFCursor.h +++ b/include/FXGIFCursor.h @@ -46,7 +46,7 @@ class FXAPI FXGIFCursor : public FXCursor { * format does not specify a hot spot. The image must be smaller than * 32x32 pixels. */ - FXGIFCursor(FXApp* a,const void* pix,FXint hx=0,FXint hy=0); + FXGIFCursor(FXApp* a,const FXuchar* pix,FXint hx=0,FXint hy=0); /// Save pixel data only, in GIF format virtual FXbool savePixels(FXStream& store) const; diff --git a/include/FXGIFIcon.h b/include/FXGIFIcon.h index 140eb33..957e135 100644 --- a/include/FXGIFIcon.h +++ b/include/FXGIFIcon.h @@ -42,7 +42,7 @@ class FXAPI FXGIFIcon : public FXIcon { public: /// Construct an icon from memory stream formatted as GIF format - FXGIFIcon(FXApp* a,const void *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1); + FXGIFIcon(FXApp* a,const FXuchar *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1); /// Save pixels into stream in GIF format virtual FXbool savePixels(FXStream& store) const; diff --git a/include/FXGIFImage.h b/include/FXGIFImage.h index c4fe456..d1be628 100644 --- a/include/FXGIFImage.h +++ b/include/FXGIFImage.h @@ -42,7 +42,7 @@ class FXAPI FXGIFImage : public FXImage { public: /// Construct an image from memory stream formatted as CompuServe GIF format - FXGIFImage(FXApp* a,const void *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1); + FXGIFImage(FXApp* a,const FXuchar *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1); /// Save pixels into stream in [un]GIF format virtual FXbool savePixels(FXStream& store) const; diff --git a/include/FXHash.h b/include/FXHash.h index 57af600..041613d 100644 --- a/include/FXHash.h +++ b/include/FXHash.h @@ -33,8 +33,8 @@ namespace FX { class FXAPI FXHash { protected: struct Entry { - FXptr key; - FXptr data; + const void *key; + void *data; }; protected: Entry *table; @@ -96,68 +96,73 @@ class FXAPI FXHash { /** * Find position of given key, returning -1 if not found. */ - FXival find(FXptr ky) const; + FXival find(const void* ky) const; + + /** + * Check if key is mapped. + */ + FXbool has(const void* ky) const { return 0<=find(ky); } /** * Return reference to slot assocated with given key. */ - FXptr& at(FXptr ky); + void*& at(const void* ky); /** * Return constant reference to slot assocated with given key. */ - const FXptr& at(FXptr ky) const; + void *const& at(const void* ky) const; /** * Return reference to slot assocated with given key. */ - FXptr& operator[](FXptr ky){ return at(ky); } + void*& operator[](const void* ky){ return at(ky); } /** * Return constant reference to slot assocated with given key. */ - const FXptr& operator[](FXptr ky) const { return at(ky); } + void *const& operator[](const void* ky) const { return at(ky); } /** * Replace key in table, overwriting the old value if the * given key already exists. Returns the old value of the key. */ - FXptr insert(FXptr ky,FXptr ptr=nullptr){ return swap(ptr,at(ky)); } + void* insert(const void* ky,void* ptr=nullptr){ return swap(ptr,at(ky)); } /** * Remove key from the table. Returns the old value of the key. */ - FXptr remove(FXptr ky); + void* remove(const void* ky); /** * Erase entry from table at pos, returning old value. */ - FXptr erase(FXival pos); + void* erase(FXival pos); /** * Return true if slot is not occupied by a key. */ - FXbool empty(FXival pos) const { return (table[pos].key==(FXptr)0L)||(table[pos].key==(FXptr)-1L); } + FXbool empty(FXival pos) const { return (table[pos].key==nullptr)||(table[pos].key==(const void*)-1L); } /** * Return key at position pos. */ - FXptr key(FXival pos) const { return table[pos].key; } + const void* key(FXival pos) const { return table[pos].key; } /** * Return reference to data pointer at position pos. */ - FXptr& data(FXival pos){ return table[pos].data; } + void*& data(FXival pos){ return table[pos].data; } /** * Return constant reference data pointer at position pos. */ - const FXptr& data(FXival pos) const { return table[pos].data; } + void *const& data(FXival pos) const { return table[pos].data; } /** * Clear hash table. */ - void clear(); + FXbool clear(); /// Destructor ~FXHash(); diff --git a/include/FXHashOf.h b/include/FXHashOf.h index 8198041..1196d59 100644 --- a/include/FXHashOf.h +++ b/include/FXHashOf.h @@ -47,37 +47,40 @@ class FXHashOf : public FXHash { FXHashOf& adopt(FXHashOf& other){ return reinterpret_cast&>(FXHash::adopt(other)); } /// Find position of given key, returning -1 if not found. - FXival find(KEYTYPE* ky) const { return FXHash::find((FXptr)ky); } + FXival find(KEYTYPE* ky) const { return FXHash::find(ky); } + + /// Check if key is mapped. + FXbool has(KEYTYPE* ky) const { return FXHash::has(ky); } /// Return reference to slot assocated with given key - VALUETYPE*& at(KEYTYPE* ky){ return (VALUETYPE*&)FXHash::at((FXptr)ky); } + VALUETYPE*& at(KEYTYPE* ky){ return reinterpret_cast(FXHash::at(ky)); } /// Return constant reference to slot assocated with given key - VALUETYPE *const& at(KEYTYPE* ky) const { return (VALUETYPE *const&)FXHash::at((FXptr)ky); } + VALUETYPE *const& at(KEYTYPE* ky) const { return reinterpret_cast(FXHash::at(ky)); } /// Return reference to slot assocated with given key - VALUETYPE*& operator[](KEYTYPE* ky){ return (VALUETYPE*&)FXHash::at((FXptr)ky); } + VALUETYPE*& operator[](KEYTYPE* ky){ return reinterpret_cast(FXHash::at(ky)); } /// Return constant reference to slot assocated with given key - VALUETYPE *const& operator[](KEYTYPE* ky) const { return (VALUETYPE *const&)FXHash::at((FXptr)ky); } + VALUETYPE *const& operator[](KEYTYPE* ky) const { return reinterpret_cast(FXHash::at(ky)); } /// Insert association with given key; return old value, if any - VALUETYPE* insert(KEYTYPE* ky,VALUETYPE* ptr=nullptr){ return (VALUETYPE*)FXHash::insert((FXptr)ky,(FXptr)ptr); } + VALUETYPE* insert(KEYTYPE* ky,VALUETYPE* ptr=nullptr){ return reinterpret_cast(FXHash::insert(ky,ptr)); } /// Remove association with given key; return old value, if any - VALUETYPE* remove(KEYTYPE* ky){ return (VALUETYPE*)FXHash::remove((FXptr)ky); } + VALUETYPE* remove(KEYTYPE* ky){ return reinterpret_cast(FXHash::remove(ky)); } /// Erase data at pos in the table; return old value, if any - VALUETYPE* erase(FXival pos){ return (VALUETYPE*)FXHash::erase(pos); } + VALUETYPE* erase(FXival pos){ return reinterpret_cast(FXHash::erase(pos)); } /// Return key at position pos - KEYTYPE* key(FXival pos) const { return (KEYTYPE*)FXHash::key(pos); } + KEYTYPE* key(FXival pos) const { return reinterpret_cast(FXHash::key(pos)); } /// Return reference to slot at position pos - VALUETYPE*& data(FXival pos){ return (VALUETYPE*&)FXHash::data(pos); } + VALUETYPE*& data(FXival pos){ return reinterpret_cast(FXHash::data(pos)); } /// Return constant reference to slot at position pos - VALUETYPE *const& data(FXival pos) const { return (VALUETYPE *const&)FXHash::data(pos); } + VALUETYPE *const& data(FXival pos) const { return reinterpret_cast(FXHash::data(pos)); } }; } diff --git a/include/FXICOIcon.h b/include/FXICOIcon.h index 4d2967c..a2a778f 100644 --- a/include/FXICOIcon.h +++ b/include/FXICOIcon.h @@ -42,7 +42,7 @@ class FXAPI FXICOIcon : public FXIcon { public: /// Construct icon from memory stream formatted in Microsoft icon format - FXICOIcon(FXApp* a,const void *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1); + FXICOIcon(FXApp* a,const FXuchar *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1); /// Save pixels into stream in Microsoft icon format format virtual FXbool savePixels(FXStream& store) const; diff --git a/include/FXICOImage.h b/include/FXICOImage.h index 424ea55..06670f1 100644 --- a/include/FXICOImage.h +++ b/include/FXICOImage.h @@ -42,7 +42,7 @@ class FXAPI FXICOImage : public FXImage { public: /// Construct image from memory stream formatted in Microsoft icon format - FXICOImage(FXApp* a,const void *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1); + FXICOImage(FXApp* a,const FXuchar *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1); /// Save pixels into stream in Microsoft icon format virtual FXbool savePixels(FXStream& store) const; diff --git a/include/FXIFFIcon.h b/include/FXIFFIcon.h index 10d1006..a16af63 100644 --- a/include/FXIFFIcon.h +++ b/include/FXIFFIcon.h @@ -44,7 +44,7 @@ class FXAPI FXIFFIcon : public FXIcon { public: /// Construct an icon from memory stream formatted as IFF format - FXIFFIcon(FXApp* a,const void *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1); + FXIFFIcon(FXApp* a,const FXuchar *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1); /// Save pixels into stream in IFF format virtual FXbool savePixels(FXStream& store) const; diff --git a/include/FXIFFImage.h b/include/FXIFFImage.h index 5116f84..6d22086 100644 --- a/include/FXIFFImage.h +++ b/include/FXIFFImage.h @@ -44,7 +44,7 @@ class FXAPI FXIFFImage : public FXImage { public: /// Construct an image from memory stream formatted as IFF format - FXIFFImage(FXApp* a,const void *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1); + FXIFFImage(FXApp* a,const FXuchar *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1); /// Save pixels into stream in IFF format virtual FXbool savePixels(FXStream& store) const; diff --git a/include/FXIconList.h b/include/FXIconList.h index 5f6b522..878c008 100644 --- a/include/FXIconList.h +++ b/include/FXIconList.h @@ -456,7 +456,7 @@ class FXAPI FXIconList : public FXScrollArea { * passing SEARCH_PREFIX causes searching for a prefix of the item name. * Return -1 if no matching item is found. */ - FXint findItem(const FXString& text,FXint start=-1,FXuint flags=SEARCH_FORWARD|SEARCH_WRAP) const; + FXint findItem(const FXString& string,FXint start=-1,FXuint flags=SEARCH_FORWARD|SEARCH_WRAP) const; /** * Search items by associated user data, beginning from item start. If the diff --git a/include/FXIconSource.h b/include/FXIconSource.h index 74b1c49..2daabe6 100644 --- a/include/FXIconSource.h +++ b/include/FXIconSource.h @@ -85,7 +85,7 @@ class FXAPI FXIconSource : public FXObject { * versions will attempt to inspect the first few bytes of the stream * to divine the icon format if the parameter is omitted]. */ - virtual FXIcon *loadIconData(FXApp* app,const void *pixels,const FXString& type=FXString::null) const; + virtual FXIcon *loadIconData(FXApp* app,const FXuchar *pixels,const FXString& type=FXString::null) const; /** * Load an icon of a given type (e.g. "gif") from an already open stream. @@ -126,7 +126,7 @@ class FXAPI FXIconSource : public FXObject { * versions will attempt to inspect the first few bytes of the stream * to divine the icon format if the parameter is omitted]. */ - virtual FXImage *loadImageData(FXApp* app,const void *pixels,const FXString& type=FXString::null) const; + virtual FXImage *loadImageData(FXApp* app,const FXuchar *pixels,const FXString& type=FXString::null) const; /** * Load an image of a given type (e.g. "gif") from an already open stream. @@ -147,7 +147,7 @@ class FXAPI FXIconSource : public FXObject { /** * Load an icon from pixels and scale it such that its dimensions does not exceed given size. */ - virtual FXIcon *loadScaledIconData(FXApp* app,const void *pixels,FXint size=32,FXint qual=0,const FXString& type=FXString::null) const; + virtual FXIcon *loadScaledIconData(FXApp* app,const FXuchar *pixels,FXint size=32,FXint qual=0,const FXString& type=FXString::null) const; /** * Load icon from stream and scale it such that its dimensions does not exceed given size. @@ -163,7 +163,7 @@ class FXAPI FXIconSource : public FXObject { /** * Load image and scale it such that its dimensions does not exceed given size. */ - virtual FXImage *loadScaledImageData(FXApp* app,const void *pixels,FXint size=32,FXint qual=0,const FXString& type=FXString::null) const; + virtual FXImage *loadScaledImageData(FXApp* app,const FXuchar *pixels,FXint size=32,FXint qual=0,const FXString& type=FXString::null) const; /** * Load image and scale it such that its dimensions does not exceed given size. diff --git a/include/FXJP2Icon.h b/include/FXJP2Icon.h index e76ea30..f458392 100644 --- a/include/FXJP2Icon.h +++ b/include/FXJP2Icon.h @@ -44,7 +44,7 @@ class FXAPI FXJP2Icon : public FXIcon { public: /// Construct an icon from memory stream formatted in JPEG-2000 format - FXJP2Icon(FXApp *a,const void *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1,FXint q=100); + FXJP2Icon(FXApp *a,const FXuchar *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1,FXint q=100); /// True if format is supported static const FXbool supported; diff --git a/include/FXJP2Image.h b/include/FXJP2Image.h index bb7536d..d30831f 100644 --- a/include/FXJP2Image.h +++ b/include/FXJP2Image.h @@ -44,7 +44,7 @@ class FXAPI FXJP2Image : public FXImage { public: /// Construct an image from memory stream formatted in JPEG-2000 format - FXJP2Image(FXApp *a,const void *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1,FXint q=100); + FXJP2Image(FXApp *a,const FXuchar *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1,FXint q=100); /// True if format is supported static const FXbool supported; diff --git a/include/FXJPGIcon.h b/include/FXJPGIcon.h index 8a29768..82af68c 100644 --- a/include/FXJPGIcon.h +++ b/include/FXJPGIcon.h @@ -44,7 +44,7 @@ class FXAPI FXJPGIcon : public FXIcon { public: /// Construct an icon from memory stream formatted in JPEG format - FXJPGIcon(FXApp *a,const void *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1,FXint q=75); + FXJPGIcon(FXApp *a,const FXuchar *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1,FXint q=75); /// True if format is supported static const FXbool supported; diff --git a/include/FXJPGImage.h b/include/FXJPGImage.h index 5c97891..25c8113 100644 --- a/include/FXJPGImage.h +++ b/include/FXJPGImage.h @@ -44,7 +44,7 @@ class FXAPI FXJPGImage : public FXImage { public: /// Construct an image from memory stream formatted in JPEG format - FXJPGImage(FXApp *a,const void *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1,FXint q=75); + FXJPGImage(FXApp *a,const FXuchar *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1,FXint q=75); /// True if format is supported static const FXbool supported; diff --git a/include/FXJSON.h b/include/FXJSON.h index ba4101e..f66408b 100644 --- a/include/FXJSON.h +++ b/include/FXJSON.h @@ -21,6 +21,10 @@ #ifndef FXJSON_H #define FXJSON_H +#ifndef FXPARSEBUFFER_H +#include "FXParseBuffer.h" +#endif + namespace FX { @@ -31,37 +35,49 @@ namespace FX { * in a well-defined and human-readable file format. * The base class implements serialization/deserialization to/from an external * buffer. +* * Subclasses FXJSONFile and FXJSONString serialize from/to strings and disk- * based files, respectively. * The new JSON5 standard may also be parsed, allowing for single- and multi-line -* nested comments to be embedded in the input. +* nested comments to be embedded in the input, and makes quotation of variable +* names optional. In addition, JSON5 also allows use of single quotes (') as +* well as double quotes ("). +* * Syntax errors in the input cause the parser to return an error, and allow * diagnosis of the problem and its location in the file by line number, column * number, and byte-offset from the start of the file. -* When writing a json stream, the generated output may be formatter in different +* +* When writing a json stream, the generated output may be formatted in different * ways. The flow-mode controls the overall layout of the resulting text output; * when flow is set to Stream, all output is generated with no formatting to * improve human legibility. This is the most space-friendly format possible. * If flow is set to Compact, a human readable, compact format, aiming to * maximize the amount of information on each line is generated. -* When flow is set to Pretty, a nicely indented, but extremely airy output +* When flow is set to Pretty, a nicely indented, but extremely "airy" output * results, and the resulting document will contain many, many lines with * little data. +* * Numeric values are printed with configurable precision; (default=15 digits * which results in minimal information loss for real numbers). * For Pretty flow format, output may be indented in multiples of the indent * level (default=2). Depending on flow setting, lines may be wrapped at a * maximum number of columns (default=80). -* Output strings containing reserved characters may be escaped; for UTF8 -* characters, there are 3 options for escaping. When escape mode is 0, UTF8 -* characters are passed unescaped. In escape mode 1, UTF8 characters are -* escaped as \xXX, and in escape mode 2, UTF8 will be escaed using Unicode -* escape sequences \uXXXX or \uXXXX\uXXXX (two surrogate-pairs escape codes -* for code points exceeding 16 bits). +* Output strings containing reserved characters may have to be escaped. +* For UTF8 characters, there are 3 options for escaping. +* +* - Escape mode 0: UTF8 characters are passed unescaped. +* - Escape mode 1: UTF8 characters are escaped as \xXX. +* - Escape mode 2: UTF8 will be escaed using Unicode escape sequences of +* the for \uXXXX or \uXXXX\uXXXX (two surrogate-pairs escape codes +* for code points exceeding 16 bits). +* * The default setting is to allow UTF8 characters in the output, but be aware * that such outputs need UTF8-capable viewer software to be rendered properly. +* Finally, in JSON5 mode (version set to 5), variable names may be written as +* unquoted strings if their syntax allows for it; in JSON5 mode, single quotes +* may be selected to improve human legibility. */ -class FXAPI FXJSON { +class FXAPI FXJSON : public FXParseBuffer { public: enum Error { ErrOK, /// No errors @@ -82,38 +98,26 @@ class FXAPI FXJSON { Compact, /// Compact, human readable output (default) Pretty /// Pretty printed, indented output }; - enum Direction { - Stop = 0, /// Not active - Save = 1, /// Save to device - Load = 2 /// Load from device - }; protected: - FXchar *begptr; // Text buffer begin ptr - FXchar *endptr; // Text buffer end ptr - FXchar *wptr; // Text buffer write ptr - FXchar *rptr; // Text buffer read ptr - FXchar *sptr; // Text buffer scan ptr - FXString value; // Token value - FXlong offset; // Position from start - FXint token; // Token - FXint column; // Column number - FXint indent; // Indent level - FXint line; // Line number - Direction dir; // Direction - FXint wrap; // Line wrap column - FXuchar flow; // Output flow - FXuchar prec; // Float precision - FXuchar fmt; // Float format - FXuchar esc; // Escape mode - FXuchar dent; // Indentation amount + FXString value; // Token value + FXlong offset; // Position from start + FXint token; // Token + FXint column; // Column number + FXint indent; // Indent level + FXint line; // Line number + FXint wrap; // Line wrap column + FXchar quote; // Quote type used + FXuchar flow; // Output flow + FXuchar prec; // Float precision + FXuchar fmt; // Float format + FXuchar esc; // Escape mode + FXuchar dent; // Indentation amount + FXuchar ver; // Version private: FXint next(); FXint ident(); FXint string(); FXint number(); - FXbool need(FXival count); - FXbool emit(const FXchar* str,FXival count); - FXbool emit(FXchar ch,FXival count); Error loadMap(FXVariant& var); Error loadArray(FXVariant& var); Error loadVariant(FXVariant& var); @@ -245,14 +249,16 @@ class FXAPI FXJSON { FXint getEscapeMode() const { return esc; } /** - * Read at least count bytes into buffer; return bytes available, or -1 for error. + * Change json version. */ - virtual FXival fill(FXival count); + void setVersion(FXint v){ ver=v; } + FXint getVersion() const { return ver; } /** - * Write at least count bytes from buffer; return space available, or -1 for error. + * Change quote type, either (') or ("). */ - virtual FXival flush(FXival count); + void setQuote(FXint q){ quote=q; } + FXint getQuote() const { return quote; } /** * Close stream and delete buffer, if owned. diff --git a/include/FXList.h b/include/FXList.h index f449c99..9b24268 100644 --- a/include/FXList.h +++ b/include/FXList.h @@ -149,9 +149,6 @@ class FXAPI FXListItem : public FXObject { typedef FXint (*FXListSortFunc)(const FXListItem*,const FXListItem*); -/// Explicit template specialization -//extern FXAPI template class FXObjectListOf; - /// List of FXListItem's typedef FXObjectListOf FXListItemList; diff --git a/include/FXListBox.h b/include/FXListBox.h index e56d8cf..5207d2d 100644 --- a/include/FXListBox.h +++ b/include/FXListBox.h @@ -177,7 +177,7 @@ class FXAPI FXListBox : public FXPacker { * passing SEARCH_PREFIX causes searching for a prefix of the item name. * Return -1 if no matching item is found. */ - FXint findItem(const FXString& text,FXint start=-1,FXuint flags=SEARCH_FORWARD|SEARCH_WRAP) const; + FXint findItem(const FXString& string,FXint start=-1,FXuint flags=SEARCH_FORWARD|SEARCH_WRAP) const; /** * Search items by associated user data, beginning from item start. If the diff --git a/include/FXObject.h b/include/FXObject.h index f0a714e..9dcbe1f 100644 --- a/include/FXObject.h +++ b/include/FXObject.h @@ -30,7 +30,6 @@ namespace FX { class FXStream; - /// Macro to set up class declaration #define FXDECLARE(classname) \ public: \ diff --git a/include/FXObjectList.h b/include/FXObjectList.h index 3efcde6..a28fc0d 100644 --- a/include/FXObjectList.h +++ b/include/FXObjectList.h @@ -163,7 +163,7 @@ class FXAPI FXObjectList { FXbool pop(); /// Remove all objects - void clear(); + FXbool clear(); /// Save to a stream void save(FXStream& store) const; diff --git a/include/FXPCXIcon.h b/include/FXPCXIcon.h index c08dec9..3ac29e8 100644 --- a/include/FXPCXIcon.h +++ b/include/FXPCXIcon.h @@ -41,7 +41,7 @@ class FXAPI FXPCXIcon : public FXIcon { public: /// Construct icon from memory stream formatted in PCX file format - FXPCXIcon(FXApp* a,const void *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1); + FXPCXIcon(FXApp* a,const FXuchar *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1); /// Save pixels into stream in PCX file format virtual FXbool savePixels(FXStream& store) const; diff --git a/include/FXPCXImage.h b/include/FXPCXImage.h index d638249..2e1cfde 100644 --- a/include/FXPCXImage.h +++ b/include/FXPCXImage.h @@ -41,7 +41,7 @@ class FXAPI FXPCXImage : public FXImage { public: /// Construct image from memory stream formatted in PCX file - FXPCXImage(FXApp* a,const void *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1); + FXPCXImage(FXApp* a,const FXuchar *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1); /// Save pixels into stream in PCX file virtual FXbool savePixels(FXStream& store) const; diff --git a/include/FXPNGIcon.h b/include/FXPNGIcon.h index 779e35a..39db6da 100644 --- a/include/FXPNGIcon.h +++ b/include/FXPNGIcon.h @@ -42,7 +42,7 @@ class FXAPI FXPNGIcon : public FXIcon { public: /// Construct an icon from memory stream formatted in PNG format - FXPNGIcon(FXApp *a,const void *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1); + FXPNGIcon(FXApp *a,const FXuchar *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1); /// True if format is supported static const FXbool supported; diff --git a/include/FXPNGImage.h b/include/FXPNGImage.h index 70e5662..70b720a 100644 --- a/include/FXPNGImage.h +++ b/include/FXPNGImage.h @@ -42,7 +42,7 @@ class FXAPI FXPNGImage : public FXImage { public: /// Construct an image from memory stream formatted in PNG format - FXPNGImage(FXApp *a,const void *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1); + FXPNGImage(FXApp *a,const FXuchar *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1); /// True if format is supported static const FXbool supported; diff --git a/include/FXPPMIcon.h b/include/FXPPMIcon.h index 8156eea..c612928 100644 --- a/include/FXPPMIcon.h +++ b/include/FXPPMIcon.h @@ -42,7 +42,7 @@ class FXAPI FXPPMIcon : public FXIcon { public: /// Construct icon from memory stream formatted in Portable Pixmap format - FXPPMIcon(FXApp* a,const void *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1); + FXPPMIcon(FXApp* a,const FXuchar *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1); /// Save pixels into stream in Portable Pixmap format virtual FXbool savePixels(FXStream& store) const; diff --git a/include/FXPPMImage.h b/include/FXPPMImage.h index 71f33b6..1b465ff 100644 --- a/include/FXPPMImage.h +++ b/include/FXPPMImage.h @@ -42,7 +42,7 @@ class FXAPI FXPPMImage : public FXImage { public: /// Construct icon from memory stream formatted in Portable Pixmap format - FXPPMImage(FXApp* a,const void *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1); + FXPPMImage(FXApp* a,const FXuchar *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1); /// Save pixels into stream in Portable Pixmap format virtual FXbool savePixels(FXStream& store) const; diff --git a/include/FXParseBuffer.h b/include/FXParseBuffer.h new file mode 100644 index 0000000..c069bfc --- /dev/null +++ b/include/FXParseBuffer.h @@ -0,0 +1,94 @@ +/******************************************************************************** +* * +* P a r s e - B u f f e r * +* * +********************************************************************************* +* Copyright (C) 2013,2022 by Jeroen van der Zijp. All Rights Reserved. * +********************************************************************************* +* This library is free software; you can redistribute it and/or modify * +* it under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 3 of the License, or * +* (at your option) any later version. * +* * +* This library is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU Lesser General Public License for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see * +********************************************************************************/ +#ifndef FXPARSEBUFFER_H +#define FXPARSEBUFFER_H + +namespace FX { + + +/** +* FXParseBuffer manages pointers to a buffer for various file format +* parsers. It is intended to be subclassed for the particular syntax. +* Additional subclasses are expected to override fill() and flush() to +* read or write to different destinations. The default implementation +* works on in-memory buffer containing the entire dataset. +*/ +class FXAPI FXParseBuffer { +public: + enum Direction { + Stop = 0, /// Not active + Save = 1, /// Save to device + Load = 2 /// Load from device + }; +protected: + FXchar *begptr; // Begin of buffer + FXchar *endptr; // End of buffer + FXchar *wptr; // Write pointer + FXchar *rptr; // Read pointer + FXchar *sptr; // Scan pointer + Direction dir; // Direction +protected: + FXbool need(FXival count); + FXbool emit(FXchar ch,FXint count); + FXbool emit(const FXchar* str,FXint count); +private: + FXParseBuffer(const FXParseBuffer&); + FXParseBuffer &operator=(const FXParseBuffer&); +public: + + /** + * Initialize parse buffer to empty. + */ + FXParseBuffer(); + + /** + * Initialize parse buffer with given size and direction. + * Read pointer, scan pointer, and write pointer are set to + * beginning of buffer, unless direction is Load. When direction + * is Load, the write pointer is set to the end of the buffer. + */ + FXParseBuffer(FXchar* buffer,FXuval sz=4096,Direction d=Load); + + /// Open parse buffer with given size and direction + FXbool open(FXchar* buffer=nullptr,FXuval sz=4096,Direction d=Load); + + /// Return current direction + Direction direction() const { return dir; } + + /// Return current buffer size + FXuval size() const { return endptr-begptr; } + + /// Read at least count bytes into buffer; return bytes available, or -1 for error + virtual FXival fill(FXival count); + + /// Write at least count bytes from buffer; return space available, or -1 for error + virtual FXival flush(FXival count); + + /// Close parse buffer + FXbool close(); + + /// Clean up and close buffer + virtual ~FXParseBuffer(); + }; + +} + +#endif diff --git a/include/FXPath.h b/include/FXPath.h index 0dcd163..b703fb4 100644 --- a/include/FXPath.h +++ b/include/FXPath.h @@ -96,7 +96,7 @@ namespace FXPath { extern FXAPI FXString expand(const FXString& file,FXint level=4); /** - * Convert a foreign path(s) or paths to local conventions, + * Convert a foreign path(s) or paths to local conventions, * replacing environment variables etc. */ extern FXAPI FXString convert(const FXString& path); diff --git a/include/FXPopup.h b/include/FXPopup.h index 214404f..bbf0ff3 100644 --- a/include/FXPopup.h +++ b/include/FXPopup.h @@ -174,7 +174,7 @@ class FXAPI FXPopup : public FXShell { virtual void popdown(); /// Return current grab owner - FXWindow* getGrabOwner() const; + FXWindow* getGrabOwner(); // /// Popup the menu and grab to the given owner // virtual FXint popup(FXint x,FXint y,FXint w=0,FXint h=0); diff --git a/include/FXPtrList.h b/include/FXPtrList.h index 318370b..eaf6232 100644 --- a/include/FXPtrList.h +++ b/include/FXPtrList.h @@ -159,7 +159,7 @@ class FXAPI FXPtrList { FXbool pop(); /// Remove all objects - void clear(); + FXbool clear(); /// Destructor ~FXPtrList(); diff --git a/include/FXRASIcon.h b/include/FXRASIcon.h index d5b65ad..6ecb9c9 100644 --- a/include/FXRASIcon.h +++ b/include/FXRASIcon.h @@ -42,7 +42,7 @@ class FXAPI FXRASIcon : public FXIcon { public: /// Construct icon from memory stream formatted in SUN Raster Image format - FXRASIcon(FXApp* a,const void *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1); + FXRASIcon(FXApp* a,const FXuchar *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1); /// Save pixels into stream in SUN Raster Image format virtual FXbool savePixels(FXStream& store) const; diff --git a/include/FXRASImage.h b/include/FXRASImage.h index 942797a..3063dec 100644 --- a/include/FXRASImage.h +++ b/include/FXRASImage.h @@ -42,7 +42,7 @@ class FXAPI FXRASImage : public FXImage { public: /// Construct image from memory stream formatted in SUN Raster Image format - FXRASImage(FXApp* a,const void *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1); + FXRASImage(FXApp* a,const FXuchar *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1); /// Save pixels into stream in SUN Raster Image format virtual FXbool savePixels(FXStream& store) const; diff --git a/include/FXRGBIcon.h b/include/FXRGBIcon.h index 6ee8f3d..330e824 100644 --- a/include/FXRGBIcon.h +++ b/include/FXRGBIcon.h @@ -42,7 +42,7 @@ class FXAPI FXRGBIcon : public FXIcon { public: /// Construct icon from memory stream formatted in IRIS-RGB format - FXRGBIcon(FXApp* a,const void *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1); + FXRGBIcon(FXApp* a,const FXuchar *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1); /// Save pixels into stream in IRIS-RGB format virtual FXbool savePixels(FXStream& store) const; diff --git a/include/FXRGBImage.h b/include/FXRGBImage.h index 035dcdb..ebed537 100644 --- a/include/FXRGBImage.h +++ b/include/FXRGBImage.h @@ -42,7 +42,7 @@ class FXAPI FXRGBImage : public FXImage { public: /// Construct image from memory stream formatted in IRIS-RGB format - FXRGBImage(FXApp* a,const void *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1); + FXRGBImage(FXApp* a,const FXuchar *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1); /// Save pixels into stream in IRIS-RGB format virtual FXbool savePixels(FXStream& store) const; diff --git a/include/FXReverseDictionary.h b/include/FXReverseDictionary.h index 0e1ab87..2147bd1 100644 --- a/include/FXReverseDictionary.h +++ b/include/FXReverseDictionary.h @@ -39,8 +39,8 @@ namespace FX { class FXAPI FXReverseDictionary { protected: struct Entry { - FXptr key; // Key - FXString data; // Value + const void* key; + FXString data; }; protected: Entry* table; // Hash table @@ -84,37 +84,37 @@ class FXAPI FXReverseDictionary { FXReverseDictionary& adopt(FXReverseDictionary& other); /// Find position of given key, returning -1 if not found - FXival find(FXptr ky) const; + FXival find(const void* ky) const; /// Check if key is mapped - FXbool has(FXptr ky) const { return 0<=find(ky); } + FXbool has(const void* ky) const { return 0<=find(ky); } /// Return reference to slot assocated with given key - FXString& at(FXptr ky); + FXString& at(const void* ky); /// Return constant reference to slot assocated with given key - const FXString& at(FXptr ky) const; + const FXString& at(const void* ky) const; /// Return reference to slot assocated with given key - FXString& operator[](FXptr ky){ return at(ky); } + FXString& operator[](const void* ky){ return at(ky); } /// Return constant reference to slot assocated with given key - const FXString& operator[](FXptr ky) const { return at(ky); } + const FXString& operator[](const void* ky) const { return at(ky); } /// Insert association with given key; return old value, if any - FXString insert(FXptr ky,const FXString& str=FXString::null){ FXString ret(str); return swap(at(ky),ret); } + FXString insert(const void* ky,const FXString& str=FXString::null){ FXString ret(str); return swap(ret,at(ky)); } /// Remove association with given key; return old value, if any - FXString remove(FXptr ky); + FXString remove(const void* ky); /// Erase data at pos in the table; return old value, if any FXString erase(FXival pos); /// Return true if slot is empty. - FXbool empty(FXival pos) const { return (table[pos].key==(FXptr)0L)||(table[pos].key==(FXptr)-1L); } + FXbool empty(FXival pos) const { return (table[pos].key==nullptr)||(table[pos].key==(const void*)-1L); } /// Return key at position pos - FXptr key(FXival pos) const { return table[pos].key; } + const void* key(FXival pos) const { return table[pos].key; } /// Return reference to slot at position pos FXString& data(FXival pos){ return table[pos].data; } @@ -123,7 +123,7 @@ class FXAPI FXReverseDictionary { const FXString& data(FXival pos) const { return table[pos].data; } /// Clear entire table - void clear(); + FXbool clear(); /// Destroy table ~FXReverseDictionary(); diff --git a/include/FXReverseDictionaryOf.h b/include/FXReverseDictionaryOf.h index cd84e6c..ed7b45c 100644 --- a/include/FXReverseDictionaryOf.h +++ b/include/FXReverseDictionaryOf.h @@ -47,34 +47,34 @@ class FXReverseDictionaryOf : public FXReverseDictionary { FXReverseDictionaryOf& adopt(FXReverseDictionaryOf& other){ return reinterpret_cast&>(FXReverseDictionary::adopt(other)); } /// Find position of given key, returning -1 if not found - FXival find(TYPE* ky) const { return FXReverseDictionary::find((FXptr)ky); } + FXival find(TYPE* ky) const { return FXReverseDictionary::find(ky); } /// Check if key is mapped - FXbool has(TYPE* ky) const { return FXReverseDictionary::has((FXptr)ky); } + FXbool has(TYPE* ky) const { return FXReverseDictionary::has(ky); } /// Return reference to slot assocated with given key - FXString& at(TYPE* ky){ return FXReverseDictionary::at((FXptr)ky); } + FXString& at(TYPE* ky){ return FXReverseDictionary::at(ky); } /// Return constant reference to slot assocated with given key - const FXString& at(TYPE* ky) const { return FXReverseDictionary::at((FXptr)ky); } + const FXString& at(TYPE* ky) const { return FXReverseDictionary::at(ky); } /// Return reference to slot assocated with given key - FXString& operator[](TYPE* ky){ return FXReverseDictionary::at((FXptr)ky); } + FXString& operator[](TYPE* ky){ return FXReverseDictionary::at(ky); } /// Return constant reference to slot assocated with given key - const FXString& operator[](TYPE* ky) const { return FXReverseDictionary::at((FXptr)ky); } + const FXString& operator[](TYPE* ky) const { return FXReverseDictionary::at(ky); } /// Insert association with given key; return old value, if any - FXString insert(TYPE* ky,const FXString& str=FXString::null){ return FXReverseDictionary::insert((FXptr)ky,str); } + FXString insert(TYPE* ky,const FXString& str=FXString::null){ return FXReverseDictionary::insert(ky,str); } /// Remove association with given key; return old value, if any - FXString remove(TYPE* ky){ return FXReverseDictionary::remove((FXptr)ky); } + FXString remove(TYPE* ky){ return FXReverseDictionary::remove(ky); } /// Erase data at pos in the table; return old value, if any FXString erase(FXival pos){ return FXReverseDictionary::erase(pos); } /// Return key at position pos - TYPE* key(FXival pos) const { return (TYPE*)table[pos].key; } + TYPE* key(FXival pos) const { return reinterpret_cast(FXReverseDictionary::key(pos)); } /// Return reference to slot at position pos FXString& data(FXival pos){ return FXReverseDictionary::data(pos); } diff --git a/include/FXString.h b/include/FXString.h index d4ae3fe..a19b29f 100644 --- a/include/FXString.h +++ b/include/FXString.h @@ -48,8 +48,6 @@ class FXAPI FXString { static const FXchar value2Digit[36]; static const FXschar digit2Value[256]; public: - static const FXschar utfBytes[256]; -public: /// Construct empty string FXString(); @@ -84,9 +82,15 @@ class FXAPI FXString { /// Change the length of the string to len FXbool length(FXint len); - /// Return wide character starting at offset p + /// Return wide character starting at p FXwchar wc(FXint p) const; + /// Return wide character at p and advance to next + FXwchar wcnxt(FXint& p) const; + + /// Retreat to wide character previous to p and return it + FXwchar wcprv(FXint& p) const; + /// Increment byte offset by one utf8 character FXint inc(FXint p) const; @@ -99,9 +103,6 @@ class FXAPI FXString { /// Decrement byte offset by n utf8 characters FXint dec(FXint p,FXint n) const; - /// Return extent of utf8 character at position - FXint extent(FXint p) const { return utfBytes[(FXuchar)str[p]]; } - /// Count number of utf8 characters FXint count() const; @@ -589,43 +590,93 @@ class FXAPI FXString { /// Compute hash value of string static FXuint hash(const FXchar* s); + /// Compute hash value of string + static FXuint hash(const FXchar* s,FXint n); + + /// Compare + static FXint compare(const FXchar* s1,const FXchar* s2); + static FXint compare(const FXchar* s1,const FXString& s2); + static FXint compare(const FXString& s1,const FXchar* s2); + static FXint compare(const FXString& s1,const FXString& s2); + + /// Compare up to n + static FXint compare(const FXchar* s1,const FXchar* s2,FXint n); + static FXint compare(const FXchar* s1,const FXString& s2,FXint n); + static FXint compare(const FXString& s1,const FXchar* s2,FXint n); + static FXint compare(const FXString& s1,const FXString& s2,FXint n); + + /// Compare case insensitive + static FXint comparecase(const FXchar* s1,const FXchar* s2); + static FXint comparecase(const FXchar* s1,const FXString& s2); + static FXint comparecase(const FXString& s1,const FXchar* s2); + static FXint comparecase(const FXString& s1,const FXString& s2); + + /// Compare case insensitive up to n + static FXint comparecase(const FXchar* s1,const FXchar* s2,FXint n); + static FXint comparecase(const FXchar* s1,const FXString& s2,FXint n); + static FXint comparecase(const FXString& s1,const FXchar* s2,FXint n); + static FXint comparecase(const FXString& s1,const FXString& s2,FXint n); + + /// Compare with natural interpretation of decimal numbers + static FXint comparenatural(const FXchar* s1,const FXchar* s2); + static FXint comparenatural(const FXchar* s1,const FXString& s2); + static FXint comparenatural(const FXString& s1,const FXchar* s2); + static FXint comparenatural(const FXString& s1,const FXString& s2); + + /// Compare case insensitive with natural interpretation of decimal numbers + static FXint comparenaturalcase(const FXchar* s1,const FXchar* s2); + static FXint comparenaturalcase(const FXchar* s1,const FXString& s2); + static FXint comparenaturalcase(const FXString& s1,const FXchar* s2); + static FXint comparenaturalcase(const FXString& s1,const FXString& s2); + /** * Check if the string contains special characters or leading or trailing whitespace, * or contains UTF8 if flag!=0. */ - static FXbool shouldEscape(const FXString& str,FXchar lquote=0,FXchar rquote=0,FXint flag=0); + static FXbool shouldEscape(const FXchar* str,FXchar lquote='\0',FXchar rquote='\0',FXint flag=0); + static FXbool shouldEscape(const FXchar* str,FXint num,FXchar lquote='\0',FXchar rquote='\0',FXint flag=0); + static FXbool shouldEscape(const FXString& str,FXchar lquote='\0',FXchar rquote='\0',FXint flag=0); /** * Escape special characters. * Optionally enclose return value with left and right quotes. - * Flag: 0 don't encode UTF8 multi-byte characters. - * Flag: 1 encodes UTF8 multi-byte characters to a sequence of hexadecimals of the form \xXX. - * Flag: 2 encodes UTF8 multi-byte characters to the form \uXXXX or \uXXXX\uYYYY. - * Ill-formed UTF8 will be encoded as hexadecimals \xXX regardless even if \uXXXX is requested. + * Flag: 0 don't escape UTF8 multi-byte characters. + * Flag: 1 escapes UTF8 multi-byte characters to a sequence of hexadecimals of the form \xXX. + * Flag: 2 escapes UTF8 multi-byte characters to the form \uXXXX or \uXXXX\uYYYY. + * Ill-formed UTF8 will be escaped as hexadecimals \xXX regardless even if \uXXXX is requested. * Quotes will be escaped if quoting is performed. */ - static FXString escape(const FXString& str,FXchar lquote=0,FXchar rquote=0,FXint flag=0); + static FXString escape(const FXchar* str,FXchar lquote='\0',FXchar rquote='\0',FXint flag=0); + static FXString escape(const FXchar* str,FXint num,FXchar lquote='\0',FXchar rquote='\0',FXint flag=0); + static FXString escape(const FXString& str,FXchar lquote='\0',FXchar rquote='\0',FXint flag=0); /** * Unescape special characters, * Optionally remove surrounding left and right quotes. - * In particular, decode \xXX to the hexadecimal character XX, \uXXXX to the multi-byte - * UTF8 sequence representing unicode character XXXX, and decode \t, \n, etc. + * In particular, unescape \xXX to the hexadecimal character XX, \uXXXX to the multi-byte + * UTF8 sequence representing unicode character XXXX, and unescape \t, \n, etc. * Handle surrogate pairs of the form \uXXXX\uYYYY properly. */ - static FXString unescape(const FXString& str,FXchar lquote=0,FXchar rquote=0); + static FXString unescape(const FXchar* str,FXchar lquote='\0',FXchar rquote='\0'); + static FXString unescape(const FXchar* str,FXint num,FXchar lquote='\0',FXchar rquote='\0'); + static FXString unescape(const FXString& str,FXchar lquote='\0',FXchar rquote='\0'); /** * Expand tabs with the equivalent amount of spaces. * UTF8 encoded characters are counted as one column. */ - static FXString detab(const FXString& text,FXint tabcols=8); + static FXString detab(const FXchar* str,FXint tabcols); + static FXString detab(const FXchar* str,FXint num,FXint tabcols); + static FXString detab(const FXString& str,FXint tabcols); + /** * Compress runs of more than 2 spaces with tabs. * UTF8 characters are counted as one column. */ - static FXString entab(const FXString& text,FXint tabcols=8); + static FXString entab(const FXchar* str,FXint tabcols); + static FXString entab(const FXchar* str,FXint num,FXint tabcols); + static FXString entab(const FXString& str,FXint tabcols); /** * Retabbify lines of text. @@ -634,7 +685,9 @@ class FXAPI FXString { * or rightward. UTF8 characters are counted as one column, and trailing space will be * deleted. */ - static FXString tabbify(const FXString& text,FXint tabcols=8,FXint indent=0,FXint outdent=0,FXint shift=0,FXbool tabs=false); + static FXString tabbify(const FXchar* str,FXint tabcols,FXint indent,FXint outdent,FXint shift,FXbool tabs); + static FXString tabbify(const FXchar* str,FXint num,FXint tabcols,FXint indent,FXint outdent,FXint shift,FXbool tabs); + static FXString tabbify(const FXString& str,FXint tabcols,FXint indent,FXint outdent,FXint shift,FXbool tabs); /** * Return normalized string, i.e. reordering of diacritical marks. @@ -673,71 +726,35 @@ inline FXString& swap(FXString& dst,FXString& src){ } -/// Compare -extern FXAPI FXint compare(const FXchar* s1,const FXchar* s2); -extern FXAPI FXint compare(const FXchar* s1,const FXString& s2); -extern FXAPI FXint compare(const FXString& s1,const FXchar* s2); -extern FXAPI FXint compare(const FXString& s1,const FXString& s2); - -/// Compare up to n -extern FXAPI FXint compare(const FXchar* s1,const FXchar* s2,FXint n); -extern FXAPI FXint compare(const FXchar* s1,const FXString& s2,FXint n); -extern FXAPI FXint compare(const FXString& s1,const FXchar* s2,FXint n); -extern FXAPI FXint compare(const FXString& s1,const FXString& s2,FXint n); - -/// Compare case insensitive -extern FXAPI FXint comparecase(const FXchar* s1,const FXchar* s2); -extern FXAPI FXint comparecase(const FXchar* s1,const FXString& s2); -extern FXAPI FXint comparecase(const FXString& s1,const FXchar* s2); -extern FXAPI FXint comparecase(const FXString& s1,const FXString& s2); - -/// Compare case insensitive up to n -extern FXAPI FXint comparecase(const FXchar* s1,const FXchar* s2,FXint n); -extern FXAPI FXint comparecase(const FXchar* s1,const FXString& s2,FXint n); -extern FXAPI FXint comparecase(const FXString& s1,const FXchar* s2,FXint n); -extern FXAPI FXint comparecase(const FXString& s1,const FXString& s2,FXint n); - -/// Compare with natural interpretation -extern FXAPI FXint compareversion(const FXchar* s1,const FXchar* s2); -extern FXAPI FXint compareversion(const FXchar* s1,const FXString& s2); -extern FXAPI FXint compareversion(const FXString& s1,const FXchar* s2); -extern FXAPI FXint compareversion(const FXString& s1,const FXString& s2); - -/// Compare case insensitive with natural interpretation -extern FXAPI FXint compareversioncase(const FXchar* s1,const FXchar* s2); -extern FXAPI FXint compareversioncase(const FXchar* s1,const FXString& s2); -extern FXAPI FXint compareversioncase(const FXString& s1,const FXchar* s2); -extern FXAPI FXint compareversioncase(const FXString& s1,const FXString& s2); - /// Equality operators -extern FXAPI FXbool operator==(const FXString& s1,const FXString& s2); -extern FXAPI FXbool operator==(const FXString& s1,const FXchar* s2); -extern FXAPI FXbool operator==(const FXchar* s1,const FXString& s2); +static inline FXbool operator==(const FXString& s1,const FXString& s2){ return FXString::compare(s1.text(),s2.text())==0; } +static inline FXbool operator==(const FXString& s1,const FXchar* s2){ return FXString::compare(s1.text(),s2)==0; } +static inline FXbool operator==(const FXchar* s1,const FXString& s2){ return FXString::compare(s1,s2.text())==0; } /// Inequality operators -extern FXAPI FXbool operator!=(const FXString& s1,const FXString& s2); -extern FXAPI FXbool operator!=(const FXString& s1,const FXchar* s2); -extern FXAPI FXbool operator!=(const FXchar* s1,const FXString& s2); +static inline FXbool operator!=(const FXString& s1,const FXString& s2){ return FXString::compare(s1.text(),s2.text())!=0; } +static inline FXbool operator!=(const FXString& s1,const FXchar* s2){ return FXString::compare(s1.text(),s2)!=0; } +static inline FXbool operator!=(const FXchar* s1,const FXString& s2){ return FXString::compare(s1,s2.text())!=0; } /// Lexicographic less than operators -extern FXAPI FXbool operator<(const FXString& s1,const FXString& s2); -extern FXAPI FXbool operator<(const FXString& s1,const FXchar* s2); -extern FXAPI FXbool operator<(const FXchar* s1,const FXString& s2); +static inline FXbool operator<(const FXString& s1,const FXString& s2){ return FXString::compare(s1.text(),s2.text())<0; } +static inline FXbool operator<(const FXString& s1,const FXchar* s2){ return FXString::compare(s1.text(),s2)<0; } +static inline FXbool operator<(const FXchar* s1,const FXString& s2){ return FXString::compare(s1,s2.text())<0; } /// Lexicographic less than or equal operators -extern FXAPI FXbool operator<=(const FXString& s1,const FXString& s2); -extern FXAPI FXbool operator<=(const FXString& s1,const FXchar* s2); -extern FXAPI FXbool operator<=(const FXchar* s1,const FXString& s2); +static inline FXbool operator<=(const FXString& s1,const FXString& s2){ return FXString::compare(s1.text(),s2.text())<=0; } +static inline FXbool operator<=(const FXString& s1,const FXchar* s2){ return FXString::compare(s1.text(),s2)<=0; } +static inline FXbool operator<=(const FXchar* s1,const FXString& s2){ return FXString::compare(s1,s2.text())<=0; } /// Lexicographic greater than operators -extern FXAPI FXbool operator>(const FXString& s1,const FXString& s2); -extern FXAPI FXbool operator>(const FXString& s1,const FXchar* s2); -extern FXAPI FXbool operator>(const FXchar* s1,const FXString& s2); +static inline FXbool operator>(const FXString& s1,const FXString& s2){ return FXString::compare(s1.text(),s2.text())>0; } +static inline FXbool operator>(const FXString& s1,const FXchar* s2){ return FXString::compare(s1.text(),s2)>0; } +static inline FXbool operator>(const FXchar* s1,const FXString& s2){ return FXString::compare(s1,s2.text())>0; } /// Lexicographic greater than or equal operators -extern FXAPI FXbool operator>=(const FXString& s1,const FXString& s2); -extern FXAPI FXbool operator>=(const FXString& s1,const FXchar* s2); -extern FXAPI FXbool operator>=(const FXchar* s1,const FXString& s2); +static inline FXbool operator>=(const FXString& s1,const FXString& s2){ return FXString::compare(s1.text(),s2.text())>=0; } +static inline FXbool operator>=(const FXString& s1,const FXchar* s2){ return FXString::compare(s1.text(),s2)>=0; } +static inline FXbool operator>=(const FXchar* s1,const FXString& s2){ return FXString::compare(s1,s2.text())>=0; } /// Concatenate FXString and FXString extern FXAPI FXString operator+(const FXString& s1,const FXString& s2); diff --git a/include/FXStringDictionary.h b/include/FXStringDictionary.h index 0eae989..af36eb2 100644 --- a/include/FXStringDictionary.h +++ b/include/FXStringDictionary.h @@ -114,22 +114,22 @@ class FXAPI FXStringDictionary { const FXString& operator[](const FXString& ky) const { return at(ky); } /// Insert association with given key; return reference to the string - void insert(const FXchar* ky,const FXchar* str,FXbool mrk=false){ at(ky,mrk)=str; } + FXbool insert(const FXchar* ky,const FXchar* str,FXbool mrk=false){ at(ky,mrk)=str; return true; } /// Insert association with given key; return reference to the string - void insert(const FXString& ky,const FXchar* str,FXbool mrk=false){ at(ky,mrk)=str; } + FXbool insert(const FXString& ky,const FXchar* str,FXbool mrk=false){ at(ky,mrk)=str; return true; } /// Insert association with given key; return reference to the string - void insert(const FXString& ky,const FXString& str,FXbool mrk=false){ at(ky,mrk)=str; } + FXbool insert(const FXString& ky,const FXString& str,FXbool mrk=false){ at(ky,mrk)=str; return true; } /// Remove association with given key - void remove(const FXchar* ky); + FXbool remove(const FXchar* ky); /// Remove association with given key - void remove(const FXString& ky){ remove(ky.text()); } + FXbool remove(const FXString& ky){ return remove(ky.text()); } /// Erase data at pos in the table - void erase(FXival pos); + FXbool erase(FXival pos); /// Return true if slot is empty. FXbool empty(FXival pos) const { return table[pos].key.empty(); } @@ -147,7 +147,7 @@ class FXAPI FXStringDictionary { FXuint mark(FXival pos) const { return table[pos].mark; } /// Clear entire table - void clear(); + FXbool clear(); /// Destroy table ~FXStringDictionary(); diff --git a/include/FXSystem.h b/include/FXSystem.h index 1e9f8cc..9bde8fb 100644 --- a/include/FXSystem.h +++ b/include/FXSystem.h @@ -176,12 +176,15 @@ namespace FXSystem { /// Return the home directory for the current user extern FXAPI FXString getHomeDirectory(); - /// Return the home directory for a given user - extern FXAPI FXString getUserDirectory(const FXString& user); - /// Return temporary directory extern FXAPI FXString getTempDirectory(); + /// Return system directory + extern FXAPI FXString getSystemDirectory(); + + /// Return the home directory for a given user + extern FXAPI FXString getUserDirectory(const FXString& user); + /// Return host name extern FXAPI FXString getHostName(); diff --git a/include/FXTGAIcon.h b/include/FXTGAIcon.h index 314542c..729d9f9 100644 --- a/include/FXTGAIcon.h +++ b/include/FXTGAIcon.h @@ -42,7 +42,7 @@ class FXAPI FXTGAIcon : public FXIcon { public: /// Construct icon from memory stream formatted in TARGA format - FXTGAIcon(FXApp* a,const void *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1); + FXTGAIcon(FXApp* a,const FXuchar *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1); /// Save pixels into stream in TARGA format virtual FXbool savePixels(FXStream& store) const; diff --git a/include/FXTGAImage.h b/include/FXTGAImage.h index 9f51cfb..1646580 100644 --- a/include/FXTGAImage.h +++ b/include/FXTGAImage.h @@ -42,7 +42,7 @@ class FXAPI FXTGAImage : public FXImage { public: /// Construct image from memory stream formatted in TARGA file - FXTGAImage(FXApp* a,const void *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1); + FXTGAImage(FXApp* a,const FXuchar *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1); /// Save pixels into stream in TARGA file virtual FXbool savePixels(FXStream& store) const; diff --git a/include/FXTIFIcon.h b/include/FXTIFIcon.h index ad91ebc..0b2db2c 100644 --- a/include/FXTIFIcon.h +++ b/include/FXTIFIcon.h @@ -44,7 +44,7 @@ class FXAPI FXTIFIcon : public FXIcon { public: /// Construct an icon from memory stream formatted in TIFF format - FXTIFIcon(FXApp *a,const void *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1); + FXTIFIcon(FXApp *a,const FXuchar *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1); /// True if format is supported static const FXbool supported; diff --git a/include/FXTIFImage.h b/include/FXTIFImage.h index e8b10bf..8e5418b 100644 --- a/include/FXTIFImage.h +++ b/include/FXTIFImage.h @@ -44,7 +44,7 @@ class FXAPI FXTIFImage : public FXImage { public: /// Construct an image from memory stream formatted in TIFF format - FXTIFImage(FXApp *a,const void *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1); + FXTIFImage(FXApp *a,const FXuchar *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1); /// True if format is supported static const FXbool supported; diff --git a/include/FXTabBar.h b/include/FXTabBar.h index 4363e6e..ca8e3d8 100644 --- a/include/FXTabBar.h +++ b/include/FXTabBar.h @@ -39,7 +39,6 @@ enum { }; - /** * The tab bar layout manager arranges tab items side by side, * and raises the active tab item above the neighboring tab items. diff --git a/include/FXTable.h b/include/FXTable.h index 8cdfcd0..d0d11f5 100644 --- a/include/FXTable.h +++ b/include/FXTable.h @@ -344,10 +344,10 @@ class FXAPI FXTable : public FXScrollArea { virtual void setItemFromControl(FXint r,FXint c,FXWindow* control); protected: enum { - MOUSE_NONE, - MOUSE_SCROLL, - MOUSE_DRAG, - MOUSE_SELECT + MOUSE_NONE, // Nop + MOUSE_SCROLL, // Scrolling + MOUSE_DRAG, // Dragging + MOUSE_SELECT // Selecting }; private: FXTable(const FXTable&); @@ -444,7 +444,6 @@ class FXAPI FXTable : public FXScrollArea { long onUpdAcceptInput(FXObject*,FXSelector,void*); long onCmdCancelInput(FXObject*,FXSelector,void*); public: - enum { ID_HORZ_GRID=FXScrollArea::ID_LAST, ID_VERT_GRID, @@ -481,7 +480,6 @@ class FXAPI FXTable : public FXScrollArea { ID_DELETE_SEL, ID_LAST }; - public: /** diff --git a/include/FXText.h b/include/FXText.h index 4f9718b..520fa93 100644 --- a/include/FXText.h +++ b/include/FXText.h @@ -223,6 +223,7 @@ class FXAPI FXText : public FXScrollArea { FXint posFromRow(FXint row) const; FXint columnFromPos(FXint start,FXint pos) const; FXint posFromColumn(FXint start,FXint col) const; + FXint indentOfLine(FXint start,FXint pos) const; FXbool isdelimiter(FXwchar w) const; FXint measureText(FXint start,FXint end,FXint& wmax,FXint& hmax) const; void calcVisRows(FXint s,FXint e); @@ -251,7 +252,6 @@ class FXAPI FXText : public FXScrollArea { void updateLines(FXint startpos,FXint endpos) const; void updateRange(FXint startpos,FXint endpos) const; FXint shiftText(FXint startpos,FXint endpos,FXint shift,FXbool notify); - FXint caseShift(FXint startpos,FXint endpos,FXint upper,FXbool notify); FXbool deletePendingSelection(FXbool notify); protected: enum { @@ -264,22 +264,6 @@ class FXAPI FXText : public FXScrollArea { MOUSE_DRAG, // Dragging text MOUSE_TRYDRAG // Tentative drag }; -protected: - enum { - STYLE_MASK = 0x00FF, // Mask color table - STYLE_TEXT = 0x0100, // Draw some content - STYLE_SELECTED = 0x0200, // Selected - STYLE_CONTROL = 0x0400, // Control character - STYLE_HILITE = 0x0800, // Highlighted - STYLE_ACTIVE = 0x1000, // Active - STYLE_INSERT = 0x2000 // Column insert - }; -public: - enum { - STYLE_UNDERLINE = 0x0001, /// Underline text - STYLE_STRIKEOUT = 0x0002, /// Strike out text - STYLE_BOLD = 0x0004 /// Bold text - }; private: FXText(const FXText&); FXText& operator=(const FXText&); @@ -425,21 +409,38 @@ class FXAPI FXText : public FXScrollArea { long onCmdToggleOverstrike(FXObject*,FXSelector,void*); long onUpdToggleOverstrike(FXObject*,FXSelector,void*); public: - static const FXchar textDelimiters[]; -public: + /// Internal style flags + enum { + STYLE_MASK = 0x00FF, // Mask color table + STYLE_TEXT = 0x0100, // Draw some content + STYLE_SELECTED = 0x0200, // Selected + STYLE_CONTROL = 0x0400, // Control character + STYLE_HILITE = 0x0800, // Highlighted + STYLE_ACTIVE = 0x1000, // Active + STYLE_INSERT = 0x2000 // Column insert + }; + + /// Text highlight style flags + enum { + STYLE_UNDERLINE = 0x0001, // Underline text + STYLE_STRIKEOUT = 0x0002, // Strike out text + STYLE_BOLD = 0x0004 // Bold text + }; /// Selection modes enum { - SelectNone, /// Select nothing - SelectChars, /// Select characters - SelectWords, /// Select words - SelectRows, /// Select rows - SelectLines /// Select lines + SelectNone, // Select nothing + SelectChars, // Select characters + SelectWords, // Select words + SelectRows, // Select rows + SelectLines // Select lines }; -public: + /// Default text delimiters + static const FXchar textDelimiters[]; +public: enum { ID_CURSOR_TOP=FXScrollArea::ID_LAST, ID_CURSOR_BOTTOM, @@ -532,7 +533,6 @@ class FXAPI FXText : public FXScrollArea { ID_FLASH, ID_LAST }; - public: /// Construct multi-line text widget @@ -688,7 +688,6 @@ class FXAPI FXText : public FXScrollArea { */ FXint countLines(FXint start,FXint end) const; - /// Change the text in the buffer to new text virtual FXint setText(const FXchar* text,FXint num,FXbool notify=false); virtual FXint setText(const FXString& text,FXbool notify=false); @@ -697,6 +696,21 @@ class FXAPI FXText : public FXScrollArea { virtual FXint setStyledText(const FXchar* text,FXint num,FXint style=0,FXbool notify=false); virtual FXint setStyledText(const FXString& text,FXint style=0,FXbool notify=false); + /// Change style of text range + virtual FXint changeStyle(FXint pos,FXint num,FXint style); + + /// Change style of text range from style-array + virtual FXint changeStyle(FXint pos,const FXchar* style,FXint num); + virtual FXint changeStyle(FXint pos,const FXString& style); + + /// Append n bytes of text at the end of the buffer + virtual FXint appendText(const FXchar *text,FXint num,FXbool notify=false); + virtual FXint appendText(const FXString& text,FXbool notify=false); + + /// Append n bytes of text at the end of the buffer + virtual FXint appendStyledText(const FXchar *text,FXint num,FXint style=0,FXbool notify=false); + virtual FXint appendStyledText(const FXString& text,FXint style=0,FXbool notify=false); + /// Replace del bytes at pos by ins characters of text virtual FXint replaceText(FXint pos,FXint del,const FXchar *text,FXint ins,FXbool notify=false); virtual FXint replaceText(FXint pos,FXint del,const FXString& text,FXbool notify=false); @@ -713,22 +727,6 @@ class FXAPI FXText : public FXScrollArea { virtual FXint replaceStyledTextBlock(FXint startpos,FXint endpos,FXint startcol,FXint endcol,const FXchar *text,FXint num,FXint style=0,FXbool notify=false); virtual FXint replaceStyledTextBlock(FXint startpos,FXint endpos,FXint startcol,FXint endcol,const FXString& text,FXint style=0,FXbool notify=false); - /// Overstrike text block - virtual FXint overstrikeTextBlock(FXint startpos,FXint endpos,FXint startcol,FXint endcol,const FXchar *text,FXint num,FXbool notify=false); - virtual FXint overstrikeTextBlock(FXint startpos,FXint endpos,FXint startcol,FXint endcol,const FXString& text,FXbool notify=false); - - /// Overstrike styled text block - virtual FXint overstrikeStyledTextBlock(FXint startpos,FXint endpos,FXint startcol,FXint endcol,const FXchar *text,FXint num,FXint style=0,FXbool notify=false); - virtual FXint overstrikeStyledTextBlock(FXint startpos,FXint endpos,FXint startcol,FXint endcol,const FXString& text,FXint style=0,FXbool notify=false); - - /// Append n bytes of text at the end of the buffer - virtual FXint appendText(const FXchar *text,FXint num,FXbool notify=false); - virtual FXint appendText(const FXString& text,FXbool notify=false); - - /// Append n bytes of text at the end of the buffer - virtual FXint appendStyledText(const FXchar *text,FXint num,FXint style=0,FXbool notify=false); - virtual FXint appendStyledText(const FXString& text,FXint style=0,FXbool notify=false); - /// Insert n bytes of text at position pos into the buffer virtual FXint insertText(FXint pos,const FXchar *text,FXint num,FXbool notify=false); virtual FXint insertText(FXint pos,const FXString& text,FXbool notify=false); @@ -745,22 +743,23 @@ class FXAPI FXText : public FXScrollArea { virtual FXint insertStyledTextBlock(FXint startpos,FXint endpos,FXint startcol,const FXchar *text,FXint num,FXint style=0,FXbool notify=false); virtual FXint insertStyledTextBlock(FXint startpos,FXint endpos,FXint startcol,const FXString& text,FXint style=0,FXbool notify=false); - /// Change style of text range - virtual FXint changeStyle(FXint pos,FXint num,FXint style); + /// Overstrike text block + virtual FXint overstrikeTextBlock(FXint startpos,FXint endpos,FXint startcol,const FXchar *text,FXint num,FXbool notify=false); + virtual FXint overstrikeTextBlock(FXint startpos,FXint endpos,FXint startcol,const FXString& text,FXbool notify=false); - /// Change style of text range from style-array - virtual FXint changeStyle(FXint pos,const FXchar* style,FXint num); - virtual FXint changeStyle(FXint pos,const FXString& style); + /// Overstrike styled text block + virtual FXint overstrikeStyledTextBlock(FXint startpos,FXint endpos,FXint startcol,const FXchar *text,FXint num,FXint style=0,FXbool notify=false); + virtual FXint overstrikeStyledTextBlock(FXint startpos,FXint endpos,FXint startcol,const FXString& text,FXint style=0,FXbool notify=false); - /// Remove n bytes of text at position pos from the buffer - virtual FXint removeText(FXint pos,FXint num,FXbool notify=false); - /// Remove columns startcol to endcol from lines starting at startpos to endpos - virtual FXint removeTextBlock(FXint startpos,FXint endpos,FXint startcol,FXint endcol,FXbool notify=false); + /// Return entire text as string + FXString getText() const; - /// Remove all text from the buffer - virtual FXint clearText(FXbool notify=false); + /// Retrieve text into buffer + void getText(FXchar* text,FXint num) const; + /// Retrieve text into string + void getText(FXString& text) const; /// Extract n bytes of text from position pos into already allocated buffer void extractText(FXchar *text,FXint pos,FXint num) const; @@ -786,14 +785,15 @@ class FXAPI FXText : public FXScrollArea { /// Return text columns startcol to endcol from lines starting at startpos to endpos FXString extractTextBlock(FXint startpos,FXint endpos,FXint startcol,FXint endcol) const; - /// Return entire text as string - FXString getText() const; - /// Retrieve text into buffer - void getText(FXchar* text,FXint num) const; + /// Remove n bytes of text at position pos from the buffer + virtual FXint removeText(FXint pos,FXint num,FXbool notify=false); - /// Retrieve text into string - void getText(FXString& text) const; + /// Remove columns startcol to endcol from lines starting at startpos to endpos + virtual FXint removeTextBlock(FXint startpos,FXint endpos,FXint startcol,FXint endcol,FXbool notify=false); + + /// Remove all text from the buffer + virtual FXint clearText(FXbool notify=false); /// Select all text @@ -814,6 +814,7 @@ class FXAPI FXText : public FXScrollArea { /// Kill or deselect primary selection virtual FXbool killSelection(FXbool notify=false); + /// Return true if position pos is selected FXbool isPosSelected(FXint pos) const; @@ -832,9 +833,6 @@ class FXAPI FXText : public FXScrollArea { /// Return selection end column FXint getSelEndColumn() const { return select.endcol; } - /// Get selected text - FXString getSelectedText() const; - /// Copy primary selection to clipboard FXbool copySelection(); @@ -854,6 +852,9 @@ class FXAPI FXText : public FXScrollArea { /// Replace primary selection by other text FXbool replaceSelection(const FXString& text,FXbool notify=false); + /// Get selected text + FXString getSelectedText() const; + /// Highlight len characters starting at given position pos FXbool setHighlight(FXint start,FXint len); @@ -911,6 +912,7 @@ class FXAPI FXText : public FXScrollArea { /// Return screen y-coordinate of unconstrained (row,col). FXint getYOfRowColumn(FXint row,FXint col) const; + /// Set the cursor position virtual void setCursorPos(FXint pos,FXbool notify=false); @@ -932,6 +934,7 @@ class FXAPI FXText : public FXScrollArea { /// Return cursor row, i.e. indent position FXint getCursorColumn() const { return cursorcol; } + /// Set the anchor position void setAnchorPos(FXint pos); @@ -947,6 +950,7 @@ class FXAPI FXText : public FXScrollArea { /// Return anchor row FXint getAnchorColumn() const { return anchorcol; } + /// Move cursor to position, and scroll into view void moveCursor(FXint pos,FXbool notify=false); @@ -959,6 +963,7 @@ class FXAPI FXText : public FXScrollArea { /// Move cursor to row and column, and extend the block selection to this point void moveCursorRowColumnAndSelect(FXint row,FXint col,FXbool notify=false); + /** * Search for string in text buffer, returning the extent of the string in beg and end. * The search starts from the given starting position, scans forward (SEARCH_FORWARD) or @@ -973,6 +978,7 @@ class FXAPI FXText : public FXScrollArea { */ FXbool findText(const FXString& string,FXint* beg=nullptr,FXint* end=nullptr,FXint start=0,FXuint flags=SEARCH_FORWARD|SEARCH_WRAP|SEARCH_EXACT,FXint npar=1); + /// Change text widget style void setTextStyle(FXuint style); @@ -1111,12 +1117,6 @@ class FXAPI FXText : public FXScrollArea { /// Return current value of the style table. FXHiliteStyle* getHiliteStyles() const { return hilitestyles; } - /// Change delimiters of words - void setDelimiters(const FXchar* delims=textDelimiters){ delimiters=delims; } - - /// Return word delimiters - const FXchar* getDelimiters() const { return delimiters; } - /** * Change brace and parenthesis match highlighting time, in nanoseconds. * If highlighting for a small interval, only flash if the matching brace @@ -1130,6 +1130,12 @@ class FXAPI FXText : public FXScrollArea { /// Return brace and parenthesis match highlighting time, in nanoseconds FXTime getHiliteMatchTime() const { return matchtime; } + /// Change delimiters of words + void setDelimiters(const FXchar* delims=textDelimiters){ delimiters=delims; } + + /// Return word delimiters + const FXchar* getDelimiters() const { return delimiters; } + /// Set help text void setHelpText(const FXString& text){ help=text; } diff --git a/include/FXTextField.h b/include/FXTextField.h index 65bf7bc..07ea0f9 100644 --- a/include/FXTextField.h +++ b/include/FXTextField.h @@ -189,7 +189,6 @@ class FXAPI FXTextField : public FXFrame { static const FXchar textDelimiters[]; public: - enum{ ID_CURSOR_HOME=FXFrame::ID_LAST, ID_CURSOR_END, @@ -224,7 +223,6 @@ class FXAPI FXTextField : public FXFrame { ID_AUTOSCROLL, ID_LAST }; - public: /// Construct text field wide enough to display ncols columns diff --git a/include/FXThread.h b/include/FXThread.h index 863fafb..3fd39e8 100644 --- a/include/FXThread.h +++ b/include/FXThread.h @@ -165,6 +165,11 @@ class FXAPI FXThread : public FXRunnable { */ static void yield(); + /** + * Processor pause/back-off. + */ + static void pause(); + /** * Return time in nanoseconds since Epoch (Jan 1, 1970). */ diff --git a/include/FXTreeList.h b/include/FXTreeList.h index 2db892d..990004f 100644 --- a/include/FXTreeList.h +++ b/include/FXTreeList.h @@ -429,7 +429,7 @@ class FXAPI FXTreeList : public FXScrollArea { * passing SEARCH_PREFIX causes searching for a prefix of the item name. * Return NULL if no matching item is found. */ - FXTreeItem* findItem(const FXString& name,FXTreeItem* start=nullptr,FXuint flags=SEARCH_FORWARD|SEARCH_WRAP) const; + FXTreeItem* findItem(const FXString& string,FXTreeItem* start=nullptr,FXuint flags=SEARCH_FORWARD|SEARCH_WRAP) const; /** * Search items by associated user data, beginning from item start. If the diff --git a/include/FXTreeListBox.h b/include/FXTreeListBox.h index 8f9ce13..83274c0 100644 --- a/include/FXTreeListBox.h +++ b/include/FXTreeListBox.h @@ -186,7 +186,7 @@ class FXAPI FXTreeListBox : public FXPacker { * passing SEARCH_PREFIX causes searching for a prefix of the item name. * Return NULL if no matching item is found. */ - FXTreeItem* findItem(const FXString& text,FXTreeItem* start=nullptr,FXuint flags=SEARCH_FORWARD|SEARCH_WRAP) const; + FXTreeItem* findItem(const FXString& string,FXTreeItem* start=nullptr,FXuint flags=SEARCH_FORWARD|SEARCH_WRAP) const; /** * Search items by associated user data, beginning from item start. If the diff --git a/include/FXVariant.h b/include/FXVariant.h index 4648b5d..6a8efa8 100644 --- a/include/FXVariant.h +++ b/include/FXVariant.h @@ -43,38 +43,37 @@ class FXVariantArray; */ class FXAPI FXVariant { public: - enum VType { - VNull=0, // Simple types - VBool, - VChar, - VInt, - VUInt, - VLong, - VULong, - VFloat, - VDouble, - VPointer, - VString, // Complex types - VArray, - VMap + enum Type { + NullType=0, // Simple types + BoolType, + CharType, + IntType, + UIntType, + LongType, + ULongType, + FloatType, + DoubleType, + PointerType, + StringType, // Complex types + ArrayType, + MapType }; private: - union VValue { - FXlong i; // Signed integral types - FXulong u; // Unsigned integral types - FXdouble d; // Floating point types - FXchar* s; // Character string - FXptr p; // Pointer types + union Value { + FXlong i; // Signed integral types + FXulong u; // Unsigned integral types + FXdouble d; // Floating point types + FXchar* s; // Character string + FXptr p; // Pointer types }; private: - VValue value; // Current value - VType type; // Type of value + Value value; // Current value + Type type; // Type of value private: - FXVariant& copy(const FXVariant& other); - FXVariant& init(VType t); + FXbool init(Type t); public: - /// Default constructor makes Null type + /// Default constructor makes null type FXVariant(); /// Copy constructor @@ -113,17 +112,11 @@ class FXAPI FXVariant { /// Construct and initialize with string explicit FXVariant(const FXString& val); - /// Construct and initialize with array - explicit FXVariant(const FXVariantArray& val); - - /// Construct and initialize with map - explicit FXVariant(const FXVariantMap& val); - /// Change type - void setType(VType t); + void setType(Type t); /// Return type - VType getType() const { return type; } + Type getType() const { return type; } /// Return size of array FXival no() const; @@ -132,43 +125,52 @@ class FXAPI FXVariant { FXbool no(FXival n); /// Is it a null? - FXbool isNull() const { return type==VNull; } + FXbool isNull() const { return type==NullType; } /// Is it a bool? - FXbool isBool() const { return type==VBool; } + FXbool isBool() const { return type==BoolType; } /// Is it a character? - FXbool isChar() const { return type==VChar; } + FXbool isChar() const { return type==CharType; } /// Is it a int? - FXbool isInt() const { return type==VInt; } + FXbool isInt() const { return type==IntType; } /// Is it a unsigned int? - FXbool isUInt() const { return type==VUInt; } + FXbool isUInt() const { return type==UIntType; } /// Is it a long? - FXbool isLong() const { return type==VLong; } + FXbool isLong() const { return type==LongType; } /// Is it a unsigned long? - FXbool isULong() const { return type==VULong; } + FXbool isULong() const { return type==ULongType; } /// Is it a float? - FXbool isFloat() const { return type==VFloat; } + FXbool isFloat() const { return type==FloatType; } /// Is it a double? - FXbool isDouble() const { return type==VDouble; } + FXbool isDouble() const { return type==DoubleType; } + + /// Is it a integer (bool, char, ..., or long)? + FXbool isInteger() const { return BoolType<=type && type<=ULongType; } + + /// Is it a real (float or double)? + FXbool isReal() const { return FloatType<=type && type<=DoubleType; } + + /// Is it any kind of number? + FXbool isNumber() const { return BoolType<=type && type<=DoubleType; } /// Is it a pointer? - FXbool isPtr() const { return type==VPointer; } + FXbool isPtr() const { return type==PointerType; } /// Is it a string? - FXbool isString() const { return type==VString; } + FXbool isString() const { return type==StringType; } /// Is it a array? - FXbool isArray() const { return type==VArray; } + FXbool isArray() const { return type==ArrayType; } /// Is it a map? - FXbool isMap() const { return type==VMap; } + FXbool isMap() const { return type==MapType; } /// Convert to bool; always OK FXbool toBool() const; @@ -272,24 +274,15 @@ class FXAPI FXVariant { /// Assign with string FXVariant& operator=(const FXString& val); - /// Assign with array - FXVariant& operator=(const FXVariantArray& val); - - /// Assign with map - FXVariant& operator=(const FXVariantMap& val); - /// Assign with variant FXVariant& operator=(const FXVariant& val); + /// Assign with variant + FXVariant& assign(const FXVariant& other); + /// Adopt variant from another FXVariant& adopt(FXVariant& other); - /// Adopt variant array - FXVariant& adopt(FXVariantArray& other); - - /// Adopt a variant map - FXVariant& adopt(FXVariantMap& other); - /// Return value of object member FXVariant& at(const FXchar* key); @@ -334,56 +327,62 @@ class FXAPI FXVariant { /// Check if key is mapped FXbool has(const FXString& key) const { return has(key.text()); } - /// Return the value of the variant as a pointer; variant type MUST be a VPointer + /// Return the value of the variant as a pointer; variant type MUST be PointerType FXptr& asPtr(){ return value.p; } - /// Return the value of the variant as a pointer; variant type MUST be a VPointer + /// Return the value of the variant as a pointer; variant type MUST be PointerType const FXptr& asPtr() const { return value.p; } - /// Return the value of the variant as a long; variant type MUST be a VLong + /// Return the value of the variant as a long; variant type MUST be LongType FXlong& asLong(){ return value.i; } - /// Return the value of the variant as a long; variant type MUST be a VLong + /// Return the value of the variant as a long; variant type MUST be LongType const FXlong& asLong() const { return value.i; } - /// Return the value of the variant as an unsigned long; variant type MUST be a VULong + /// Return the value of the variant as an unsigned long; variant type MUST be ULongType FXulong& asULong(){ return value.u; } - /// Return the value of the variant as an unsigned long; variant type MUST be a VULong + /// Return the value of the variant as an unsigned long; variant type MUST be ULongType const FXulong& asULong() const { return value.u; } - /// Return the value of the variant as a double; variant type MUST be a VDouble + /// Return the value of the variant as a double; variant type MUST be DoubleType FXdouble& asDouble(){ return value.d; } - /// Return the value of the variant as a double; variant type MUST be a VDouble + /// Return the value of the variant as a double; variant type MUST be DoubleType const FXdouble& asDouble() const { return value.d; } - /// Return the value of the variant as a char pointer; variant type MUST be a VString + /// Return the value of the variant as a char pointer; variant type MUST be StringType const FXchar* asChars() const { return value.s; } - /// Return the value of the variant as a string-reference; variant type MUST be a VString + /// Return the value of the variant as a string-reference; variant type MUST be StringType FXString& asString(){ return *reinterpret_cast(&value.p); } - /// Return the value of the variant as a const string-reference; variant type MUST be a VString + /// Return the value of the variant as a const string-reference; variant type MUST be StringType const FXString& asString() const { return *reinterpret_cast(&value.p); } - /// Return the value of the variant as an array-reference; variant type MUST be a VArray + /// Return the value of the variant as an array-reference; variant type MUST be ArrayType FXVariantArray& asArray(){ return *reinterpret_cast(&value.p); } - /// Return the value of the variant as a const array-reference; variant type MUST be a VArray + /// Return the value of the variant as a const array-reference; variant type MUST be ArrayType const FXVariantArray& asArray() const { return *reinterpret_cast(&value.p); } - /// Return the value of the variant as an map-reference; variant type MUST be VMap + /// Return the value of the variant as an map-reference; variant type MUST be MapType FXVariantMap& asMap(){ return *reinterpret_cast(&value.p); } - /// Return the value of the variant as a const map-reference; variant type MUST be VMap + /// Return the value of the variant as a const map-reference; variant type MUST be MapType const FXVariantMap& asMap() const { return *reinterpret_cast(&value.p); } - /// Clear the data - void clear(); + /// Remove variant at key from map + FXbool remove(const FXchar* key); - /// Reset to null - void reset(); + /// Remove variant at key from map + FXbool remove(const FXString& key){ return remove(key.text()); } + + /// Erase variant at idx from array + FXbool erase(FXival idx); + + /// Clear the data + FXbool clear(); /// Default constant variant static const FXVariant null; diff --git a/include/FXVariantMap.h b/include/FXVariantMap.h index f4723d5..996e830 100644 --- a/include/FXVariantMap.h +++ b/include/FXVariantMap.h @@ -113,13 +113,13 @@ class FXAPI FXVariantMap { const FXVariant& operator[](const FXString& ky) const { return at(ky); } /// Remove entry from the table - void remove(const FXchar* ky); + FXbool remove(const FXchar* ky); /// Remove entry from the table - void remove(const FXString& ky){ remove(ky.text()); } + FXbool remove(const FXString& ky){ return remove(ky.text()); } /// Erase entry at pos in the table - void erase(FXival pos); + FXbool erase(FXival pos); /// Return true if slot at pos is empty. FXbool empty(FXival pos) const { return table[pos].key.empty(); } @@ -135,7 +135,7 @@ class FXAPI FXVariantMap { const FXVariant& data(FXival pos) const { return table[pos].data; } /// Clear the table - void clear(); + FXbool clear(); /// Destructor ~FXVariantMap(); diff --git a/include/FXWEBPIcon.h b/include/FXWEBPIcon.h index 8928233..1504834 100644 --- a/include/FXWEBPIcon.h +++ b/include/FXWEBPIcon.h @@ -42,7 +42,7 @@ class FXAPI FXWEBPIcon : public FXIcon { public: /// Construct an icon from memory stream formatted in WEBP format - FXWEBPIcon(FXApp *a,const void *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1); + FXWEBPIcon(FXApp *a,const FXuchar *pix=nullptr,FXColor clr=FXRGB(192,192,192),FXuint opts=0,FXint w=1,FXint h=1); /// True if format is supported static const FXbool supported; diff --git a/include/FXWEBPImage.h b/include/FXWEBPImage.h index 192ffde..09b64a7 100644 --- a/include/FXWEBPImage.h +++ b/include/FXWEBPImage.h @@ -42,7 +42,7 @@ class FXAPI FXWEBPImage : public FXImage { public: /// Construct an image from memory stream formatted in WEBP format - FXWEBPImage(FXApp *a,const void *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1); + FXWEBPImage(FXApp *a,const FXuchar *pix=nullptr,FXuint opts=0,FXint w=1,FXint h=1); /// True if format is supported static const FXbool supported; diff --git a/include/FXWindow.h b/include/FXWindow.h index 1228280..3112315 100644 --- a/include/FXWindow.h +++ b/include/FXWindow.h @@ -232,8 +232,6 @@ class FXAPI FXWindow : public FXDrawable { }; public: - - // Message handlers long onPaint(FXObject*,FXSelector,void*); long onMap(FXObject*,FXSelector,void*); long onUnmap(FXObject*,FXSelector,void*); @@ -288,10 +286,7 @@ class FXAPI FXWindow : public FXDrawable { long onCmdUpdate(FXObject*,FXSelector,void*); long onUpdYes(FXObject*,FXSelector,void*); long onCmdDelete(FXObject*,FXSelector,void*); - public: - - // Message ID's common to most Windows enum { ID_NONE, ID_HIDE, @@ -348,7 +343,6 @@ class FXAPI FXWindow : public FXDrawable { ID_MDI_PREV, ID_LAST }; - public: // Predefined DND type names diff --git a/include/FXXML.h b/include/FXXML.h index 13b65f6..0f20966 100644 --- a/include/FXXML.h +++ b/include/FXXML.h @@ -21,6 +21,9 @@ #ifndef FXXML_H #define FXXML_H +#ifndef FXPARSEBUFFER_H +#include "FXParseBuffer.h" +#endif namespace FX { @@ -28,7 +31,7 @@ namespace FX { /** * The XML serializer loads or saves data to xml text file. */ -class FXAPI FXXML { +class FXAPI FXXML : public FXParseBuffer { public: enum Error { ErrOK, /// No errors @@ -47,11 +50,6 @@ class FXAPI FXXML { ErrNoMatch, /// Start and end tag not matching ErrEof /// Unexpected end of file }; - enum Direction { - Stop = 0, /// Not active - Save = 1, /// Save to device - Load = 2 /// Load from device - }; enum { CRLF = 0x0001, /// CRLF, LFCR, CR, LF map to LF REFS = 0x0002, /// Character references processed @@ -66,22 +64,13 @@ class FXAPI FXXML { protected: class Element; // Element info protected: - FXchar *begptr; // Text buffer begin ptr - FXchar *endptr; // Text buffer end ptr - FXchar *wptr; // Text buffer write ptr - FXchar *rptr; // Text buffer read ptr - FXchar *sptr; // Text buffer scan ptr FXlong offset; // Position from start Element *current; // Current element instance FXint column; // Column number FXint line; // Line number - Direction dir; // Direction FXString vers; // Version FXuint enc; // Encoding private: - FXbool need(FXival n); - FXbool emit(const FXchar* str,FXint count); - FXbool emit(FXchar ch,FXint count); FXuint guess(); void spaces(); FXbool name(); @@ -209,16 +198,6 @@ class FXAPI FXXML { /// Returns error code for given error static const FXchar* getError(Error err){ return errors[err]; } - /** - * Read at least count bytes into buffer; return bytes available, or -1 for error. - */ - virtual FXival fill(FXival count); - - /** - * Write at least count bytes from buffer; return space available, or -1 for error. - */ - virtual FXival flush(FXival count); - /** * Close stream and delete buffer, if owned. */ diff --git a/include/fx.h b/include/fx.h index ae2d3dd..f76fcac 100644 --- a/include/fx.h +++ b/include/fx.h @@ -29,9 +29,25 @@ #include #include +// Intrinsics +#if defined(WIN32) +#if (_MSC_VER >= 1400) // VC++ 2005 or newer +#if defined(_M_IX86) || defined(_M_X64) +#include +#endif +#endif +#else +#if defined(__GNUC__) || defined(__INTEL_COMPILER) +#if defined(__i386__) || defined(__x86_64__) +#include +#endif +#endif +#endif + // FOX defines #include "fxver.h" #include "fxdefs.h" +#include "fxchar.h" #include "fxkeys.h" #include "fxmath.h" #include "fxendian.h" @@ -98,6 +114,7 @@ #include "FXDate.h" #include "FXURL.h" #include "FXStringDictionary.h" +#include "FXParseBuffer.h" #include "FXJSON.h" #include "FXJSONFile.h" #include "FXXML.h" diff --git a/include/fxchar.h b/include/fxchar.h new file mode 100644 index 0000000..8e6b58f --- /dev/null +++ b/include/fxchar.h @@ -0,0 +1,318 @@ +/******************************************************************************** +* * +* U n i c o d e C h a r a c t e r E n c o d i n g S u p p o r t * +* * +********************************************************************************* +* Copyright (C) 1997,2022 by Jeroen van der Zijp. All Rights Reserved. * +********************************************************************************* +* This library is free software; you can redistribute it and/or modify * +* it under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 3 of the License, or * +* (at your option) any later version. * +* * +* This library is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU Lesser General Public License for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see * +********************************************************************************/ +#ifndef FXCHAR_H +#define FXCHAR_H + + +namespace FX { + + +/*************************** UTF8 Support Functions **************************/ + +/// Test if character c is at the start of a UTF8 sequence +static inline FXbool isUTF8(FXchar c){ + return (c&0xC0)!=0x80; + } + +/// Check if c is leader of a UTF8 multi-byte sequence +static inline FXbool leadUTF8(FXchar c){ + return (c&0xC0)==0xC0; + } + +/// Check if c is follower of a UTF8 multi-byte sequence +static inline FXbool followUTF8(FXchar c){ + return (c&0xC0)==0x80; + } + +/// Check if c is part of multi-byte UTF8 sequence +static inline FXbool seqUTF8(FXchar c){ + return (c&0x80)==0x80; + } + +/// Length of UTF8 character, in bytes +static inline FXival lenUTF8(FXchar c){ + return ((0xE5000000>>((c>>3)&0x1E))&3)+1; + } + +/// Length of UTF8 character, in bytes +static inline FXival wclen(const FXchar *ptr){ + return lenUTF8(*ptr); + } + +/// Return wide character from UTF8 string +static inline FXwchar wc(const FXchar* ptr){ + FXwchar w=(FXuchar)ptr[0]; + if(0xC0<=w){ w = (w<<6) ^ (FXuchar)ptr[1] ^ 0x3080; + if(0x800<=w){ w = (w<<6) ^ (FXuchar)ptr[2] ^ 0x20080; + if(0x10000<=w){ w = (w<<6) ^ (FXuchar)ptr[3] ^ 0x400080; }}} + return w; + } + +/// Return wide character from 1-byte UTF8 string +static inline FXwchar wc1(const FXchar* ptr){ + return (FXuchar)ptr[0]; + } + +/// Return wide character from 2-byte UTF8 string +static inline FXwchar wc2(const FXchar* ptr){ + return ((FXuchar)ptr[0]<<6)^((FXuchar)ptr[1])^0x3080; + } + +/// Return wide character from 3-byte UTF8 string +static inline FXwchar wc3(const FXchar* ptr){ + return ((FXuchar)ptr[0]<<12)^((FXuchar)ptr[1]<<6)^((FXuchar)ptr[2])^0x0E2080; + } + +/// Return wide character from 4-byte UTF8 string +static inline FXwchar wc4(const FXchar* ptr){ + return ((FXuchar)ptr[0]<<18)^((FXuchar)ptr[1]<<12)^((FXuchar)ptr[2]<<6)^((FXuchar)ptr[3])^0x3C82080; + } + +/// Return wide character from UTF8 string, and go to next wide character +static inline FXwchar wcnxt(const FXchar*& ptr){ + FXwchar w=(FXuchar)*ptr++; + if(0xC0<=w){ w = (w<<6) ^ (FXuchar)*ptr++ ^ 0x3080; + if(0x800<=w){ w = (w<<6) ^ (FXuchar)*ptr++ ^ 0x20080; + if(0x10000<=w){ w = (w<<6) ^ (FXuchar)*ptr++ ^ 0x400080; }}} + return w; + } + +/// Return wide character from UTF8 string, and go to next wide character +static inline FXwchar wcnxt(FXchar*& ptr){ + FXwchar w=(FXuchar)*ptr++; + if(0xC0<=w){ w = (w<<6) ^ (FXuchar)*ptr++ ^ 0x3080; + if(0x800<=w){ w = (w<<6) ^ (FXuchar)*ptr++ ^ 0x20080; + if(0x10000<=w){ w = (w<<6) ^ (FXuchar)*ptr++ ^ 0x400080; }}} + return w; + } + +/// Go to previous wide character from UTF8 string, and return it +static inline FXwchar wcprv(const FXchar*& ptr){ + FXwchar w=(FXuchar)*--ptr; + if(0x80<=w){ w = ((FXuchar)*--ptr<<6) ^ w ^ 0x3080; + if(0x1000<=w){ w = ((FXuchar)*--ptr<<12) ^ w ^ 0xE1000; + if(0x20000<=w){ w = ((FXuchar)*--ptr<<18) ^ w ^ 0x3C60000; }}} + return w; + } + +/// Go to previous wide character from UTF8 string, and return it +static inline FXwchar wcprv(FXchar*& ptr){ + FXwchar w=(FXuchar)*--ptr; + if(0x80<=w){ w = ((FXuchar)*--ptr<<6) ^ w ^ 0x3080; + if(0x1000<=w){ w = ((FXuchar)*--ptr<<12) ^ w ^ 0xE1000; + if(0x20000<=w){ w = ((FXuchar)*--ptr<<18) ^ w ^ 0x3C60000; }}} + return w; + } + +/// Increment to start of next wide character in utf8 string +static inline const FXchar* wcinc(const FXchar* ptr){ + return (isUTF8(*++ptr) || isUTF8(*++ptr) || isUTF8(*++ptr) || ++ptr), ptr; + } + +/// Increment to start of next wide character in utf8 string +static inline FXchar* wcinc(FXchar* ptr){ + return (isUTF8(*++ptr) || isUTF8(*++ptr) || isUTF8(*++ptr) || ++ptr), ptr; + } + +/// Decrement to start of previous wide character in utf8 string +static inline const FXchar* wcdec(const FXchar* ptr){ + return (isUTF8(*--ptr) || isUTF8(*--ptr) || isUTF8(*--ptr) || --ptr), ptr; + } + +/// Decrement to start of previous wide character in utf8 string +static inline FXchar* wcdec(FXchar* ptr){ + return (isUTF8(*--ptr) || isUTF8(*--ptr) || isUTF8(*--ptr) || --ptr), ptr; + } + +/// Adjust ptr to point to leader of multi-byte sequence +static inline const FXchar* wcstart(const FXchar* ptr){ + return (isUTF8(*ptr) || isUTF8(*--ptr) || isUTF8(*--ptr) || --ptr), ptr; + } + +/// Adjust ptr to point to leader of multi-byte sequence +static inline FXchar* wcstart(FXchar* ptr){ + return (isUTF8(*ptr) || isUTF8(*--ptr) || isUTF8(*--ptr) || --ptr), ptr; + } + +/************************** UTF16 Support Functions **************************/ + +/// Test if character c is at start of UTF16 sequence +static inline FXbool isUTF16(FXnchar c){ + return (c&0xFC00)!=0xDC00; + } + +/// Check if c is leader of a UTF16 surrogate pair sequence +static inline FXbool leadUTF16(FXnchar c){ + return (c&0xFC00)==0xD800; + } + +/// Check if c is follower of a UTF16 surrogate pair sequence +static inline FXbool followUTF16(FXnchar c){ + return (c&0xFC00)==0xDC00; + } + +/// Check if c is part of multi-word UTF16 sequence +static inline FXbool seqUTF16(FXnchar c){ + return (c&0xF800)==0xD800; + } + +/// Length of UTF16 character, in words +static inline FXival lenUTF16(FXnchar c){ + return leadUTF16(c)+1; + } + +/// Return number of words of narrow character at ptr +static inline FXival wclen(const FXnchar *ptr){ + return lenUTF16(*ptr); + } + +/// Return wide character from utf16 string +static inline FXwchar wc(const FXnchar* ptr){ + FXwchar w=ptr[0]; + if(leadUTF16(w)){ w = (w<<10) + ptr[1] - 0x35FDC00; } + return w; + } + +/// Return wide character from 1-word utf16 string +static inline FXwchar wc1(const FXnchar* ptr){ + return ptr[0]; + } + +/// Return wide character from 2-word utf16 string +static inline FXwchar wc2(const FXnchar* ptr){ + return (ptr[0]<<10)+ptr[1]-0x35FDC00; + } + +/// Return wide character from UTF16 string, and go to next wide character +static inline FXwchar wcnxt(const FXnchar*& ptr){ + FXwchar w=*ptr++; + if(leadUTF16(w)){ w = (w<<10) + *ptr++ - 0x35FDC00; } + return w; + } + +/// Return wide character from UTF16 string, and go to next wide character +static inline FXwchar wcnxt(FXnchar*& ptr){ + FXwchar w=*ptr++; + if(leadUTF16(w)){ w = (w<<10) + *ptr++ - 0x35FDC00; } + return w; + } + +/// Go to previous wide character from UTF16 string, and return it +static inline FXwchar wcprv(const FXnchar*& ptr){ + FXwchar w=*--ptr; + if(followUTF16(w)){ w = (*--ptr<<10) + w - 0x35FDC00; } + return w; + } + +/// Go to previous wide character from UTF16 string, and return it +static inline FXwchar wcprv(FXnchar*& ptr){ + FXwchar w=*--ptr; + if(followUTF16(w)){ w = (*--ptr<<10) + w - 0x35FDC00; } + return w; + } + +/// Safely go to begin of next utf8 character +static inline const FXnchar* wcinc(const FXnchar* ptr){ + return (isUTF16(*++ptr) || ++ptr), ptr; + } + +/// Safely go to begin of next utf8 character +static inline FXnchar* wcinc(FXnchar* ptr){ + return (isUTF16(*++ptr) || ++ptr), ptr; + } + +/// Safely go to begin of previous utf8 character +static inline const FXnchar* wcdec(const FXnchar* ptr){ + return (isUTF16(*--ptr) || --ptr), ptr; + } + +/// Safely go to begin of previous utf8 character +static inline FXnchar* wcdec(FXnchar* ptr){ + return (isUTF16(*--ptr) || --ptr), ptr; + } + +/// Adjust ptr to point to leader of surrogate pair sequence +static inline const FXnchar* wcstart(const FXnchar *ptr){ + return (isUTF16(*ptr) || --ptr), ptr; + } + +/// Adjust ptr to point to leader of surrogate pair sequence +static inline FXnchar* wcstart(FXnchar *ptr){ + return (isUTF16(*ptr) || --ptr), ptr; + } + +/// Test if c is a legal utf32 character +static inline FXbool isUTF32(FXwchar c){ + return c<0x110000; + } + +/*********************** Measure Encoding Conversions **********************/ + +/// Return number of bytes for utf8 representation of wide character w +static inline FXival wc2utf(FXwchar w){ return 1+(0x80<=w)+(0x800<=w)+(0x10000<=w); } + +/// Return number of narrow characters for utf16 representation of wide character w +static inline FXival wc2nc(FXwchar w){ return 1+(0x10000<=w); } + +/// Return number of bytes for utf8 representation of wide character string +extern FXAPI FXival wcs2utf(const FXwchar* src,FXival srclen); +extern FXAPI FXival wcs2utf(const FXwchar* src); + +/// Return number of bytes for utf8 representation of narrow character string +extern FXAPI FXival ncs2utf(const FXnchar* src,FXival srclen); +extern FXAPI FXival ncs2utf(const FXnchar* src); + +/// Return number of wide characters for utf8 character string +extern FXAPI FXival utf2wcs(const FXchar src,FXival srclen); +extern FXAPI FXival utf2wcs(const FXchar *src); + +/// Return number of narrow characters for utf8 character string +extern FXAPI FXival utf2ncs(const FXchar *src,FXival srclen); +extern FXAPI FXival utf2ncs(const FXchar *src); + + +/************************ Encoding Conversions ******************************/ + +/// Convert wide character to utf8 string; return number of items written to dst +extern FXAPI FXival wc2utf(FXchar *dst,FXwchar w); + +/// Convert wide character to narrow character string; return number of items written to dst +extern FXAPI FXival wc2nc(FXnchar *dst,FXwchar w); + +/// Convert wide character string to utf8 string; return number of items written to dst +extern FXAPI FXival wcs2utf(FXchar *dst,const FXwchar* src,FXival dstlen,FXival srclen); +extern FXAPI FXival wcs2utf(FXchar *dst,const FXwchar* src,FXival dstlen); + +/// Convert narrow character string to utf8 string; return number of items written to dst +extern FXAPI FXival ncs2utf(FXchar *dst,const FXnchar* src,FXival dstlen,FXival srclen); +extern FXAPI FXival ncs2utf(FXchar *dst,const FXnchar* src,FXival dstlen); + +/// Convert utf8 string to wide character string; return number of items written to dst +extern FXAPI FXival utf2wcs(FXwchar *dst,const FXchar* src,FXival dstlen,FXival srclen); +extern FXAPI FXival utf2wcs(FXwchar *dst,const FXchar* src,FXival dstlen); + +/// Convert utf8 string to narrow character string; return number of items written to dst +extern FXAPI FXival utf2ncs(FXnchar *dst,const FXchar* src,FXival dstlen,FXival srclen); +extern FXAPI FXival utf2ncs(FXnchar *dst,const FXchar* src,FXival dstlen); + +} + +#endif diff --git a/include/fxdefs.h b/include/fxdefs.h index 08dd9ac..5078451 100644 --- a/include/fxdefs.h +++ b/include/fxdefs.h @@ -239,32 +239,6 @@ union _XEvent; namespace FX { -/// Third logic state: unknown/indeterminate -enum { maybe=2 }; - - -/// Exponent display -enum FXExponent { - EXP_NEVER=0, /// Never use exponential notation - EXP_ALWAYS=1, /// Always use exponential notation - EXP_AUTO=2 /// Use exponential notation if needed - }; - - -/// Search modes for search/replace dialogs -enum { - SEARCH_BACKWARD = 1, /// Search backward - SEARCH_FORWARD = 2, /// Search forward - SEARCH_NOWRAP = 0, /// Don't wrap (default) - SEARCH_WRAP = 4, /// Wrap around to start - SEARCH_EXACT = 0, /// Exact match (default) - SEARCH_IGNORECASE = 8, /// Ignore case - SEARCH_REGEX = 16, /// Regular expression match - SEARCH_PREFIX = 32, /// Prefix of subject string - SEARCH_SUFFIX = 64 /// Suffix of subject string - }; - - /********************************* Typedefs **********************************/ // Forward declarations @@ -377,7 +351,7 @@ typedef _XEvent FXRawEvent; #endif -/// Drag and drop data type +// Drag and drop data type #ifdef WIN32 typedef FXushort FXDragType; #else @@ -385,9 +359,24 @@ typedef FXID FXDragType; #endif -/// A time in the far, far future +// Third logic state: unknown/indeterminate +enum { maybe=2 }; + +// A time in the far, far future const FXTime forever=FXLONG(9223372036854775807); +// Search modes for search/replace dialogs +enum { + SEARCH_BACKWARD = 1, /// Search backward + SEARCH_FORWARD = 2, /// Search forward + SEARCH_NOWRAP = 0, /// Don't wrap (default) + SEARCH_WRAP = 4, /// Wrap around to start + SEARCH_EXACT = 0, /// Exact match (default) + SEARCH_IGNORECASE = 8, /// Ignore case + SEARCH_REGEX = 16, /// Regular expression match + SEARCH_PREFIX = 32, /// Prefix of subject string + SEARCH_SUFFIX = 64 /// Suffix of subject string + }; /********************************** Macros ***********************************/ @@ -457,35 +446,6 @@ const FXTime forever=FXLONG(9223372036854775807); /// Get ID from selector #define FXSELID(s) ((FX::FXushort)((s)&0xffff)) -/// Test if character c is at the start of a utf8 sequence (not a follower byte) -#define FXISUTF8(c) (((c)&0xC0)!=0x80) - -/// Check if c is leader/follower of a utf8 multi-byte sequence -#define FXISLEADUTF8(c) (((c)&0xC0)==0xC0) -#define FXISFOLLOWUTF8(c) (((c)&0xC0)==0x80) - -/// Check if c is part of a utf8 multi-byte sequence -#define FXISSEQUTF8(c) (((c)&0x80)==0x80) - -/// Number of FXchars in utf8 sequence -#define FXUTF8LEN(c) (((0xE5000000>>((((FXuchar)(c))>>4)<<1))&3)+1) - -/// Test if character c is at start of utf16 sequence (not a follower from surrogate pair) -#define FXISUTF16(c) (((c)&0xFC00)!=0xDC00) - -/// Check if c is leader/follower of a utf16 surrogate pair sequence -#define FXISLEADUTF16(c) (((c)&0xFC00)==0xD800) -#define FXISFOLLOWUTF16(c) (((c)&0xFC00)==0xDC00) - -/// Check if c is part of a utf16 surrogate pair sequence -#define FXISSEQUTF16(c) (((c)&0xF800)==0xD800) - -/// Number of FXnchars in utf16 sequence -#define FXUTF16LEN(c) (FXISLEADUTF16(c)+1) - -/// Test if c is a legal utf32 character -#define FXISUTF32(c) ((c)<0x110000) - /// Average of two FXColor ca and FXColor cb #define FXAVGCOLOR(ca,cb) (((ca)&(cb))+((((ca)^(cb))&0xFEFEFEFE)>>1)) @@ -777,106 +737,9 @@ extern FXAPI void setTraceLevel(FXuint level,FXbool flag=true); /// extern FXAPI FXbool setTraceTopics(const FXchar* topics,FXbool flag=true); -/// Return wide character from utf8 string at ptr -extern FXAPI FXwchar wc(const FXchar *ptr); - -/// Return wide character from utf16 string at ptr -extern FXAPI FXwchar wc(const FXnchar *ptr); - - -/// Increment to start of next wide character in utf8 string -extern FXAPI const FXchar* wcinc(const FXchar* ptr); - -/// Increment to start of next wide character in utf8 string -extern FXAPI FXchar* wcinc(FXchar* ptr); - -/// Increment to start of next wide character in utf16 string -extern FXAPI const FXnchar* wcinc(const FXnchar* ptr); - -/// Increment to start of next wide character in utf16 string -extern FXAPI FXnchar* wcinc(FXnchar* ptr); - -/// Decrement to start of previous wide character in utf8 string -extern FXAPI const FXchar* wcdec(const FXchar* ptr); - -/// Decrement to start of previous wide character in utf8 string -extern FXAPI FXchar* wcdec(FXchar* ptr); - -/// Decrement to start of previous wide character in utf16 string -extern FXAPI const FXnchar* wcdec(const FXnchar* ptr); - -/// Decrement to start of previous wide character in utf16 string -extern FXAPI FXnchar* wcdec(FXnchar* ptr); - -/// Adjust ptr to point to leader of multi-byte sequence -extern FXAPI const FXchar* wcstart(const FXchar* ptr); - -/// Adjust ptr to point to leader of multi-byte sequence -extern FXAPI FXchar* wcstart(FXchar* ptr); - -/// Adjust ptr to point to leader of surrogate pair sequence -extern FXAPI const FXnchar* wcstart(const FXnchar *ptr); - -/// Adjust ptr to point to leader of surrogate pair sequence -extern FXAPI FXnchar* wcstart(FXnchar *ptr); - -/// Return number of FXchar's of wide character at ptr -extern FXAPI FXival wclen(const FXchar *ptr); - -/// Return number of FXnchar's of narrow character at ptr -extern FXAPI FXival wclen(const FXnchar *ptr); - -/// Check if valid utf8 wide character representation; returns length or 0 -extern FXAPI FXival wcvalid(const FXchar* ptr); - -/// Check if valid utf16 wide character representation; returns length or 0 -extern FXAPI FXival wcvalid(const FXnchar* ptr); - - -/// Return number of bytes for utf8 representation of wide character w -extern FXAPI FXival wc2utf(FXwchar w); - -/// Return number of narrow characters for utf16 representation of wide character w -extern FXAPI FXival wc2nc(FXwchar w); - -/// Return number of bytes for utf8 representation of wide character string -extern FXAPI FXival wcs2utf(const FXwchar* src,FXival srclen); -extern FXAPI FXival wcs2utf(const FXwchar* src); - -/// Return number of bytes for utf8 representation of narrow character string -extern FXAPI FXival ncs2utf(const FXnchar* src,FXival srclen); -extern FXAPI FXival ncs2utf(const FXnchar* src); - -/// Return number of wide characters for utf8 character string -extern FXAPI FXival utf2wcs(const FXchar src,FXival srclen); -extern FXAPI FXival utf2wcs(const FXchar *src); - -/// Return number of narrow characters for utf8 character string -extern FXAPI FXival utf2ncs(const FXchar *src,FXival srclen); -extern FXAPI FXival utf2ncs(const FXchar *src); - - -/// Convert wide character to utf8 string; return number of items written to dst -extern FXAPI FXival wc2utf(FXchar *dst,FXwchar w); - -/// Convert wide character to narrow character string; return number of items written to dst -extern FXAPI FXival wc2nc(FXnchar *dst,FXwchar w); - -/// Convert wide character string to utf8 string; return number of items written to dst -extern FXAPI FXival wcs2utf(FXchar *dst,const FXwchar* src,FXival dstlen,FXival srclen); -extern FXAPI FXival wcs2utf(FXchar *dst,const FXwchar* src,FXival dstlen); - -/// Convert narrow character string to utf8 string; return number of items written to dst -extern FXAPI FXival ncs2utf(FXchar *dst,const FXnchar* src,FXival dsrlen,FXival srclen); -extern FXAPI FXival ncs2utf(FXchar *dst,const FXnchar* src,FXival dsrlen); - -/// Convert utf8 string to wide character string; return number of items written to dst -extern FXAPI FXival utf2wcs(FXwchar *dst,const FXchar* src,FXival dsrlen,FXival srclen); -extern FXAPI FXival utf2wcs(FXwchar *dst,const FXchar* src,FXival dsrlen); +/// Get operating system version string +extern FXAPI FXival fxosversion(FXchar version[],FXival len); -/// Convert utf8 string to narrow character string; return number of items written to dst -extern FXAPI FXival utf2ncs(FXnchar *dst,const FXchar* src,FXival dsrlen,FXival srclen); -extern FXAPI FXival utf2ncs(FXnchar *dst,const FXchar* src,FXival dsrlen); } diff --git a/include/fxendian.h b/include/fxendian.h index bca4730..7e4e5fc 100644 --- a/include/fxendian.h +++ b/include/fxendian.h @@ -140,6 +140,8 @@ static inline FXulong msb64(FXulong x){ static inline FXuint pop32(FXuint x){ #if ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))) return __builtin_popcount(x); +#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) + return __popcnt(x); #else x=x-((x>>1)&0x55555555); x=(x&0x33333333)+((x>>2)&0x33333333); @@ -156,6 +158,8 @@ static inline FXulong pop64(FXulong x){ #else return __builtin_popcountll(x); #endif +#elif defined(_MSC_VER) && (defined(_M_X64)) + return __popcnt64(x); #else x=x-((x>>1)&FXULONG(0x5555555555555555)); x=(x&FXULONG(0x3333333333333333))+((x>>2)&FXULONG(0x3333333333333333)); @@ -168,13 +172,17 @@ static inline FXulong pop64(FXulong x){ static inline FXuint clz32(FXuint x){ #if ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))) return __builtin_clz(x); +#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) + unsigned long result; + _BitScanReverse(&result,x); + return 31-result; #else FXuint f,e,d,c,b; - f=!(x&0xffff0000)<<4; x<<=f; - e=!(x&0xff000000)<<3; x<<=e; - d=!(x&0xf0000000)<<2; x<<=d; - c=!(x&0xC0000000)<<1; x<<=c; - b=!(x&0x80000000); + f=(((FXint)(x-0x00010000))>>31)&16; x<<=f; + e=(((FXint)(x-0x01000000))>>31)&8; x<<=e; + d=(((FXint)(x-0x10000000))>>31)&4; x<<=d; + c=(((FXint)(x-0x40000000))>>31)&2; x<<=c; + b=(((FXint)(x-0x80000000))>>31)&1; return f+e+d+c+b; #endif } @@ -188,14 +196,18 @@ static inline FXulong clz64(FXulong x){ #else return __builtin_clzll(x); #endif +#elif defined(_MSC_VER) && defined(_M_X64) + unsigned long result; + _BitScanReverse64(&result,x); + return 63-result; #else FXulong g,f,e,d,c,b; - g=!(x&FXULONG(0xffffffff00000000))<<8; x<<=g; - f=!(x&FXULONG(0xffff000000000000))<<4; x<<=f; - e=!(x&FXULONG(0xff00000000000000))<<3; x<<=e; - d=!(x&FXULONG(0xf000000000000000))<<2; x<<=d; - c=!(x&FXULONG(0xC000000000000000))<<1; x<<=c; - b=!(x&FXULONG(0x8000000000000000)); + g=(((FXlong)(x-FXULONG(0x0000000100000000)))>>63)&32; x<<=g; + f=(((FXlong)(x-FXULONG(0x0001000000000000)))>>63)&16; x<<=f; + e=(((FXlong)(x-FXULONG(0x0100000000000000)))>>63)&8; x<<=e; + d=(((FXlong)(x-FXULONG(0x1000000000000000)))>>63)&4; x<<=d; + c=(((FXlong)(x-FXULONG(0x4000000000000000)))>>63)&2; x<<=c; + b=(((FXlong)(x-FXULONG(0x8000000000000000)))>>63)&1; return g+f+e+d+c+b; #endif } @@ -205,14 +217,12 @@ static inline FXulong clz64(FXulong x){ static inline FXuint ctz32(FXuint x){ #if ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))) return __builtin_ctz(x); +#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) + unsigned long result; + _BitScanForward(&result,x); + return result; #else - FXuint f,e,d,c,b; - f=!(x&0x0000ffff)<<4; x>>=f; - e=!(x&0x000000ff)<<3; x>>=e; - d=!(x&0x0000000f)<<2; x>>=d; - c=!(x&0x00000003)<<1; x>>=c; - b=!(x&0x00000001); - return f+e+d+c+b; + return 31-clz32(x&-x); #endif } @@ -225,15 +235,12 @@ static inline FXulong ctz64(FXulong x){ #else return __builtin_ctzll(x); #endif +#elif defined(_MSC_VER) && defined(_M_X64) + unsigned long result; + _BitScanForward64(&result,x); + return result; #else - FXulong g,f,e,d,c,b; - g=!(x&FXULONG(0x00000000ffffffff))<<8; x>>=g; - f=!(x&FXULONG(0x000000000000ffff))<<4; x>>=f; - e=!(x&FXULONG(0x00000000000000ff))<<3; x>>=e; - d=!(x&FXULONG(0x000000000000000f))<<2; x>>=d; - c=!(x&FXULONG(0x0000000000000003))<<1; x>>=c; - b=!(x&FXULONG(0x0000000000000001)); - return g+f+e+d+c+b; + return 63-clz64(x&-x); #endif } diff --git a/include/fxmath.h b/include/fxmath.h index 2565baf..8f89716 100644 --- a/include/fxmath.h +++ b/include/fxmath.h @@ -166,7 +166,7 @@ #endif // Systems below are missing these functions -#if defined(__sun__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) +#if defined(__sun__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__APPLE__) #define NO_EXP10F #define NO_EXP10 #endif @@ -600,6 +600,39 @@ static inline FXdouble stepify(FXdouble x,FXdouble s){ } +/// Single precision zig-zag function, period 1 +static inline FXfloat zigzag(FXfloat x){ + return Math::fabs(2.0f*(x-Math::nearbyint(x))); + } + +/// Single precision zig-zag function, period 1 +static inline FXdouble zigzag(FXdouble x){ + return Math::fabs(2.0*(x-Math::nearbyint(x))); + } + + +/// Single precision sawtooth function, period 1 +static inline FXfloat sawtooth(FXfloat x){ + return x-Math::floor(x); + } + +/// Single precision sawtooth function, period 1 +static inline FXdouble sawtooth(FXdouble x){ + return x-Math::floor(x); + } + + +/// Single precision revserse sawtooth function, period 1 +static inline FXfloat rsawtooth(FXfloat x){ + return Math::ceil(x)-x; + } + +/// Single precision revserse sawtooth function, period 1 +static inline FXdouble rsawtooth(FXdouble x){ + return Math::ceil(x)-x; + } + + /// Single precision sine static inline FXfloat sin(FXfloat x){ return ::sinf(x); diff --git a/include/fxver.h b/include/fxver.h index 9860590..1aa1e37 100644 --- a/include/fxver.h +++ b/include/fxver.h @@ -5,7 +5,7 @@ /// FOX version #define FOX_MAJOR 1 #define FOX_MINOR 7 -#define FOX_LEVEL 79 +#define FOX_LEVEL 80 #endif diff --git a/include/xincs.h b/include/xincs.h index 34b1a20..86abb38 100644 --- a/include/xincs.h +++ b/include/xincs.h @@ -200,6 +200,9 @@ #ifdef HAVE_SYS_INOTIFY_H #include #endif +#ifdef HAVE_SYS_UTSNAME_H +#include +#endif #ifdef HAVE_SYS_SYSCTL_H #if !defined(__linux__) #include diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index d8dc0c7..52bf8f2 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -59,6 +59,7 @@ set(HEADERS ../include/FXCalendarView.h ../include/FXCallback.h ../include/FXCanvas.h + ../include/fxchar.h ../include/FXCheckButton.h ../include/FXChoiceBox.h ../include/FXColorBar.h @@ -241,6 +242,7 @@ set(HEADERS ../include/FXOptionMenu.h ../include/FXPacker.h ../include/FXParallel.h + ../include/FXParseBuffer.h ../include/FXPath.h ../include/FXPCXIcon.h ../include/FXPCXImage.h @@ -413,6 +415,7 @@ set(SOURCES FXCalendar.cpp FXCalendarView.cpp FXCanvas.cpp + fxchar.cpp FXCheckButton.cpp FXChoiceBox.cpp FXColorBar.cpp @@ -589,7 +592,9 @@ set(SOURCES FXObject.cpp FXObjectList.cpp FXOptionMenu.cpp + fxosver.cpp FXPacker.cpp + FXParseBuffer.cpp fxparsegeometry.cpp FXPath.cpp FXPCXIcon.cpp diff --git a/lib/FXAccelTable.cpp b/lib/FXAccelTable.cpp index 7c4f49c..533501b 100644 --- a/lib/FXAccelTable.cpp +++ b/lib/FXAccelTable.cpp @@ -21,6 +21,7 @@ #include "xincs.h" #include "fxver.h" #include "fxdefs.h" +#include "fxchar.h" #include "fxkeys.h" #include "fxmath.h" #include "fxascii.h" @@ -323,11 +324,11 @@ FXHotKey FXAccelTable::parseAccel(const FXchar* string){ while(*ptr){ // Modifier - if(comparecase(ptr,"ctl",3)==0){ mods|=CONTROLMASK; ptr+=3; } - else if(comparecase(ptr,"ctrl",4)==0){ mods|=CONTROLMASK; ptr+=4; } - else if(comparecase(ptr,"alt",3)==0){ mods|=ALTMASK; ptr+=3; } - else if(comparecase(ptr,"meta",4)==0){ mods|=METAMASK; ptr+=4; } - else if(comparecase(ptr,"shift",5)==0){ mods|=SHIFTMASK; ptr+=5; } + if(FXString::comparecase(ptr,"ctl",3)==0){ mods|=CONTROLMASK; ptr+=3; } + else if(FXString::comparecase(ptr,"ctrl",4)==0){ mods|=CONTROLMASK; ptr+=4; } + else if(FXString::comparecase(ptr,"alt",3)==0){ mods|=ALTMASK; ptr+=3; } + else if(FXString::comparecase(ptr,"meta",4)==0){ mods|=METAMASK; ptr+=4; } + else if(FXString::comparecase(ptr,"shift",5)==0){ mods|=SHIFTMASK; ptr+=5; } else break; // Separator @@ -335,61 +336,61 @@ FXHotKey FXAccelTable::parseAccel(const FXchar* string){ } // Test for some special keys - if(comparecase(ptr,"home",4)==0){ + if(FXString::comparecase(ptr,"home",4)==0){ code=KEY_Home; } - else if(comparecase(ptr,"end",3)==0){ + else if(FXString::comparecase(ptr,"end",3)==0){ code=KEY_End; } - else if(comparecase(ptr,"pgup",4)==0){ + else if(FXString::comparecase(ptr,"pgup",4)==0){ code=KEY_Page_Up; } - else if(comparecase(ptr,"pgdn",4)==0){ + else if(FXString::comparecase(ptr,"pgdn",4)==0){ code=KEY_Page_Down; } - else if(comparecase(ptr,"left",4)==0){ + else if(FXString::comparecase(ptr,"left",4)==0){ code=KEY_Left; } - else if(comparecase(ptr,"right",5)==0){ + else if(FXString::comparecase(ptr,"right",5)==0){ code=KEY_Right; } - else if(comparecase(ptr,"up",2)==0){ + else if(FXString::comparecase(ptr,"up",2)==0){ code=KEY_Up; } - else if(comparecase(ptr,"down",4)==0){ + else if(FXString::comparecase(ptr,"down",4)==0){ code=KEY_Down; } - else if(comparecase(ptr,"ins",3)==0){ + else if(FXString::comparecase(ptr,"ins",3)==0){ code=KEY_Insert; } - else if(comparecase(ptr,"del",3)==0){ + else if(FXString::comparecase(ptr,"del",3)==0){ code=KEY_Delete; } - else if(comparecase(ptr,"delete",6)==0){ + else if(FXString::comparecase(ptr,"delete",6)==0){ code=KEY_Delete; } - else if(comparecase(ptr,"esc",3)==0){ + else if(FXString::comparecase(ptr,"esc",3)==0){ code=KEY_Escape; } - else if(comparecase(ptr,"tab",3)==0){ + else if(FXString::comparecase(ptr,"tab",3)==0){ code=KEY_Tab; } - else if(comparecase(ptr,"return",6)==0){ + else if(FXString::comparecase(ptr,"return",6)==0){ code=KEY_Return; } - else if(comparecase(ptr,"enter",5)==0){ + else if(FXString::comparecase(ptr,"enter",5)==0){ code=KEY_Return; } - else if(comparecase(ptr,"back",4)==0){ + else if(FXString::comparecase(ptr,"back",4)==0){ code=KEY_BackSpace; } - else if(comparecase(ptr,"backspace",9)==0){ + else if(FXString::comparecase(ptr,"backspace",9)==0){ code=KEY_BackSpace; } - else if(comparecase(ptr,"spc",3)==0){ + else if(FXString::comparecase(ptr,"spc",3)==0){ code=KEY_space; } - else if(comparecase(ptr,"space",5)==0){ + else if(FXString::comparecase(ptr,"space",5)==0){ code=KEY_space; } diff --git a/lib/FXApp.cpp b/lib/FXApp.cpp index 651319a..cbc8e2a 100644 --- a/lib/FXApp.cpp +++ b/lib/FXApp.cpp @@ -22,6 +22,7 @@ #include "fxver.h" #include "fxdefs.h" #include "fxmath.h" +#include "fxchar.h" #include "fxkeys.h" #include "fxascii.h" #include "FXArray.h" @@ -1193,7 +1194,7 @@ long SpaceNav::onMotion(FXObject *, FXSelector, void *vp){ num_inputs = sizeof_buffer/sizeof(RAWINPUT); if (bufAlloc < num_inputs) { bufAlloc = num_inputs; - FXRESIZE(&inpBuffer, RAWINPUT, bufAlloc); + resizeElms(inpBuffer,bufAlloc); } #endif num_inputs = GetRawInputBuffer(inpBuffer, &sizeof_buffer, sizeof(RAWINPUTHEADER)); @@ -1660,7 +1661,7 @@ FXbool FXApp::openDisplay(const FXchar* dpy){ wmNetWindowType=XInternAtom((Display*)display,"_NET_WM_WINDOW_TYPE",0); // Register window types - XInternAtoms((Display*)display,(char**)windowTypeAtoms,14,0,wmWindowTypes); + XInternAtoms((Display*)display,const_cast(windowTypeAtoms),14,0,wmWindowTypes); // Session management wmWindowRole=XInternAtom((Display*)display,"WM_WINDOW_ROLE",0); @@ -3481,6 +3482,7 @@ FXbool FXApp::dispatchEvent(FXRawEvent& ev){ // WM_PROTOCOLS if(ev.xclient.message_type==wmProtocols){ if((FXID)ev.xclient.data.l[0]==wmDeleteWindow){ // WM_DELETE_WINDOW + FXTRACE((100,"WM_DELETE_WINDOW\n")); event.type=SEL_CLOSE; if(!invocation || invocation->modality==MODAL_FOR_NONE || (invocation->window && invocation->window->isOwnerOf(window))){ if(window->handle(this,FXSEL(SEL_CLOSE,0),&event)) refresh(); @@ -3491,11 +3493,11 @@ FXbool FXApp::dispatchEvent(FXRawEvent& ev){ } else if((FXID)ev.xclient.data.l[0]==wmSaveYourself){ // WM_SAVE_YOURSELF FXTRACE((100,"WM_SAVE_YOURSELF\n")); -/* - XSetCommand((Display*)display,ev.xany.window,(char**)appArgv,appArgc); - XChangeProperty((Display*)display,ev.xany.window,wmCommand,XA_STRING,8,PropModeReplace,(unsigned char*)"",0); + //XSetCommand((Display*)display,ev.xany.window,(char**)appArgv,appArgc); + //XChangeProperty((Display*)display,ev.xany.window,wmCommand,XA_STRING,8,PropModeReplace,(unsigned char*)"",0); event.type=SEL_SESSION_NOTIFY; return !window->handle(this,FXSEL(SEL_SESSION_NOTIFY,0),&event); // Return 1 if OK to terminate +/* case WM_ENDSESSION: // Session will now end for sure event.type=SEL_SESSION_CLOSED; @@ -3504,6 +3506,7 @@ FXbool FXApp::dispatchEvent(FXRawEvent& ev){ */ } else if((FXID)ev.xclient.data.l[0]==wmQuitApp){ // WM_QUIT_APP + FXTRACE((100,"WM_QUIT_APP\n")); event.type=SEL_CLOSE; if(!invocation || invocation->modality==MODAL_FOR_NONE || (invocation->window && invocation->window->isOwnerOf(window))){ if(window->handle(this,FXSEL(SEL_CLOSE,0),&event)) refresh(); @@ -4215,7 +4218,7 @@ static void getSystemFont(FXFontDesc& fontdesc){ HDC hDC=CreateCompatibleDC(nullptr); fontdesc.size=-10*MulDiv(ncm.lfMenuFont.lfHeight,72,GetDeviceCaps(hDC,LOGPIXELSY)); DeleteDC(hDC); - fontdesc.weight=ncm.lfMenuFont.lfWeight/10; + fontdesc.weight=(FXushort)ncm.lfMenuFont.lfWeight/10; fontdesc.slant=ncm.lfMenuFont.lfItalic?FXFont::Italic:FXFont::Straight; fontdesc.encoding=FONTENCODING_DEFAULT; fontdesc.setwidth=0; @@ -4290,14 +4293,14 @@ void FXApp::init(int& argc,char** argv,FXbool connect){ #ifndef WIN32 // Start synchronized mode - if(compare(argv[j],"-sync")==0){ + if(FXString::compare(argv[j],"-sync")==0){ synchronize=true; j++; continue; } // Do not use X shared memory extension, even if available - if(compare(argv[j],"-noshm")==0){ + if(FXString::compare(argv[j],"-noshm")==0){ shmi=false; shmp=false; j++; @@ -4305,7 +4308,7 @@ void FXApp::init(int& argc,char** argv,FXbool connect){ } // Force use X shared memory extension, if available - if(compare(argv[j],"-shm")==0){ + if(FXString::compare(argv[j],"-shm")==0){ shmi=true; shmp=true; j++; @@ -4313,7 +4316,7 @@ void FXApp::init(int& argc,char** argv,FXbool connect){ } // Alternative display - if(compare(argv[j],"-display")==0){ + if(FXString::compare(argv[j],"-display")==0){ if(++j>=argc){ fxwarning("%s:init: missing argument for -display.\n",getClassName()); ::exit(1); @@ -4323,7 +4326,7 @@ void FXApp::init(int& argc,char** argv,FXbool connect){ } // Set input method - if(compare(argv[j],"-im")==0){ + if(FXString::compare(argv[j],"-im")==0){ if(++j>=argc){ fxwarning("%s:init: missing argument for -im.\n",getClassName()); ::exit(1); @@ -4333,7 +4336,7 @@ void FXApp::init(int& argc,char** argv,FXbool connect){ } // Input style - if(compare(argv[j],"-is")==0){ + if(FXString::compare(argv[j],"-is")==0){ if(++j>=argc){ fxwarning("%s:init: missing argument for -is.\n",getClassName()); ::exit(1); @@ -4345,7 +4348,7 @@ void FXApp::init(int& argc,char** argv,FXbool connect){ #endif // Set trace level - if(compare(argv[j],"-tracelevel")==0){ + if(FXString::compare(argv[j],"-tracelevel")==0){ if(++j>=argc){ fxwarning("%s:init: missing argument for -tracelevel.\n",getClassName()); ::exit(1); @@ -4355,7 +4358,7 @@ void FXApp::init(int& argc,char** argv,FXbool connect){ } // Set trace level - if(compare(argv[j],"-tracetopics")==0){ + if(FXString::compare(argv[j],"-tracetopics")==0){ if(++j>=argc){ fxwarning("%s:init: missing argument for -tracetopics.\n",getClassName()); ::exit(1); @@ -4365,7 +4368,7 @@ void FXApp::init(int& argc,char** argv,FXbool connect){ } // Set per-user configuration directory - if(compare(argv[j],"-config")==0){ + if(FXString::compare(argv[j],"-config")==0){ if(++j>=argc){ fxwarning("%s:init: missing argument for -config.\n",getClassName()); ::exit(1); @@ -4374,8 +4377,15 @@ void FXApp::init(int& argc,char** argv,FXbool connect){ continue; } + // Set ascii based registery (Windows) + if(FXString::compare(argv[j],"-ascii")==0){ + registry.setAsciiMode(true); + j++; + continue; + } + // Set maximum number of colors - if(compare(argv[j],"-maxcolors")==0){ + if(FXString::compare(argv[j],"-maxcolors")==0){ if(++j>=argc){ fxwarning("%s:init: missing argument for -maxcolors.\n",getClassName()); ::exit(1); @@ -5235,7 +5245,7 @@ Alt key seems to repeat. if(clipboardWindow){ event.type=SEL_CLIPBOARD_REQUEST; event.time=GetMessageTime(); - event.target=wParam; + event.target=(FXDragType)wParam; clipboardWindow->handle(this,FXSEL(SEL_CLIPBOARD_REQUEST,0),&event); FXTRACE((100,"Window %d being requested for CLIPBOARD DATA of type %d\n",hwnd,wParam)); } diff --git a/lib/FXArray.cpp b/lib/FXArray.cpp index 8b027ad..3d7b420 100644 --- a/lib/FXArray.cpp +++ b/lib/FXArray.cpp @@ -39,7 +39,7 @@ // Special empty array value -#define EMPTY ((FXptr)(__array__empty__+1)) +#define EMPTY (const_cast((const void*)(__array__empty__+1))) using namespace FX; diff --git a/lib/FXBMPIcon.cpp b/lib/FXBMPIcon.cpp index 035027a..37242f6 100644 --- a/lib/FXBMPIcon.cpp +++ b/lib/FXBMPIcon.cpp @@ -68,9 +68,9 @@ FXIMPLEMENT(FXBMPIcon,FXIcon,nullptr,0) // Initialize nicely -FXBMPIcon::FXBMPIcon(FXApp* a,const void *pix,FXColor clr,FXuint opts,FXint w,FXint h):FXIcon(a,nullptr,clr,opts,w,h){ +FXBMPIcon::FXBMPIcon(FXApp* a,const FXuchar *pix,FXColor clr,FXuint opts,FXint w,FXint h):FXIcon(a,nullptr,clr,opts,w,h){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXBMPImage.cpp b/lib/FXBMPImage.cpp index 42fdc48..b84e072 100644 --- a/lib/FXBMPImage.cpp +++ b/lib/FXBMPImage.cpp @@ -66,9 +66,9 @@ FXIMPLEMENT(FXBMPImage,FXImage,nullptr,0) // Initialize -FXBMPImage::FXBMPImage(FXApp* a,const void *pix,FXuint opts,FXint w,FXint h):FXImage(a,nullptr,opts,w,h){ +FXBMPImage::FXBMPImage(FXApp* a,const FXuchar *pix,FXuint opts,FXint w,FXint h):FXImage(a,nullptr,opts,w,h){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXBitmap.cpp b/lib/FXBitmap.cpp index 094c955..45aba0b 100644 --- a/lib/FXBitmap.cpp +++ b/lib/FXBitmap.cpp @@ -93,11 +93,11 @@ FXBitmap::FXBitmap(){ // Initialize -FXBitmap::FXBitmap(FXApp* a,const void *pix,FXuint opts,FXint w,FXint h):FXDrawable(a,w,h){ +FXBitmap::FXBitmap(FXApp* a,const FXuchar *pix,FXuint opts,FXint w,FXint h):FXDrawable(a,w,h){ FXTRACE((100,"FXBitmap::FXBitmap %p\n",this)); FXASSERT((opts&~(BITMAP_OWNED|BITMAP_MASK))==0); visual=getApp()->getMonoVisual(); - data=(FXuchar*)pix; + data=const_cast(pix); bytewidth=(width+7)>>3; options=opts; if(!data && (options&BITMAP_OWNED)){ diff --git a/lib/FXCURCursor.cpp b/lib/FXCURCursor.cpp index a5e61f8..a636f98 100644 --- a/lib/FXCURCursor.cpp +++ b/lib/FXCURCursor.cpp @@ -64,9 +64,9 @@ FXIMPLEMENT(FXCURCursor,FXCursor,nullptr,0) // Constructor -FXCURCursor::FXCURCursor(FXApp* a,const void *pix):FXCursor(a,nullptr,0,0,0,0){ +FXCURCursor::FXCURCursor(FXApp* a,const FXuchar *pix):FXCursor(a,nullptr,0,0,0,0){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); fxloadICO(ms,data,width,height,hotx,hoty); options|=CURSOR_OWNED; } diff --git a/lib/FXColorDialog.cpp b/lib/FXColorDialog.cpp index d3513d3..9cef5c5 100644 --- a/lib/FXColorDialog.cpp +++ b/lib/FXColorDialog.cpp @@ -100,7 +100,21 @@ FXColorDialog::FXColorDialog(FXApp* a,const FXString& name,FXuint opts,FXint x,F // Create server-side resources void FXColorDialog::create(){ - setActivePanel(getApp()->reg().readIntEntry(sectionName,"activecolorpane",COLORTAB_COLOR_RING)); + readRegistry(); + FXDialogBox::create(); + } + + +// Destroy server-side resources +void FXColorDialog::destroy(){ + FXDialogBox::destroy(); + writeRegistry(); + } + +// Load settings from registry +void FXColorDialog::readRegistry(){ + setWidth(getApp()->reg().readIntEntry(sectionName,"width",getWidth())); + setHeight(getApp()->reg().readIntEntry(sectionName,"height",getHeight())); setWellColor( 0,getApp()->reg().readColorEntry(sectionName,"WA",FXRGBA(255,255,255,255))); setWellColor( 1,getApp()->reg().readColorEntry(sectionName,"WB",FXRGBA(204,204,204,255))); setWellColor( 2,getApp()->reg().readColorEntry(sectionName,"WC",FXRGBA(153,153,153,255))); @@ -125,13 +139,14 @@ void FXColorDialog::create(){ setWellColor(21,getApp()->reg().readColorEntry(sectionName,"WV",FXRGBA(175,175,255,255))); setWellColor(22,getApp()->reg().readColorEntry(sectionName,"WW",FXRGBA(175,255,255,255))); setWellColor(23,getApp()->reg().readColorEntry(sectionName,"WX",FXRGBA(255,255,175,255))); - FXDialogBox::create(); + setActivePanel(getApp()->reg().readIntEntry(sectionName,"activecolorpane",COLORTAB_COLOR_RING)); } -// Destroy server-side resources -void FXColorDialog::destroy(){ - getApp()->reg().writeIntEntry(sectionName,"activecolorpane",getActivePanel()); +// Save settings to registry +void FXColorDialog::writeRegistry(){ + getApp()->reg().writeIntEntry(sectionName,"width",getWidth()); + getApp()->reg().writeIntEntry(sectionName,"height",getHeight()); getApp()->reg().writeColorEntry(sectionName,"WA",getWellColor( 0)); getApp()->reg().writeColorEntry(sectionName,"WB",getWellColor( 1)); getApp()->reg().writeColorEntry(sectionName,"WC",getWellColor( 2)); @@ -156,7 +171,7 @@ void FXColorDialog::destroy(){ getApp()->reg().writeColorEntry(sectionName,"WV",getWellColor(21)); getApp()->reg().writeColorEntry(sectionName,"WW",getWellColor(22)); getApp()->reg().writeColorEntry(sectionName,"WX",getWellColor(23)); - FXDialogBox::destroy(); + getApp()->reg().writeIntEntry(sectionName,"activecolorpane",getActivePanel()); } diff --git a/lib/FXColorRing.cpp b/lib/FXColorRing.cpp index 830a3a3..b3d5a49 100644 --- a/lib/FXColorRing.cpp +++ b/lib/FXColorRing.cpp @@ -117,6 +117,11 @@ using namespace FX; namespace FX { +// Special single-precision versions +const FXfloat pi=3.1415926535897932384626433833f; +const FXfloat dtor=0.0174532925199432957692369077f; +const FXfloat rtod=57.295779513082320876798154814f; + // Map FXDEFMAP(FXColorRing) FXColorRingMap[]={ FXMAPFUNC(SEL_PAINT,0,FXColorRing::onPaint), @@ -264,15 +269,15 @@ void FXColorRing::updatering(){ FXint o2,i2,r2,rx,ry,x,y; // Hue angle in radians - a=(hsv[0]-180.0f)*DTOR; + a=(hsv[0]-180.0f)*dtor; // Calculate triangle points clrx=(FXint)(ringinner*Math::cos(a)+0.5f); clry=(FXint)(ringinner*Math::sin(a)+0.5f); - blkx=(FXint)(ringinner*Math::cos(a+2.0f*PI/3.0f)+0.5f); - blky=(FXint)(ringinner*Math::sin(a+2.0f*PI/3.0f)+0.5f); - whtx=(FXint)(ringinner*Math::cos(a-2.0f*PI/3.0f)+0.5f); - whty=(FXint)(ringinner*Math::sin(a-2.0f*PI/3.0f)+0.5f); + blkx=(FXint)(ringinner*Math::cos(a+2.0f*pi/3.0f)+0.5f); + blky=(FXint)(ringinner*Math::sin(a+2.0f*pi/3.0f)+0.5f); + whtx=(FXint)(ringinner*Math::cos(a-2.0f*pi/3.0f)+0.5f); + whty=(FXint)(ringinner*Math::sin(a-2.0f*pi/3.0f)+0.5f); // To test for ring o2=ringouter*ringouter; @@ -294,7 +299,7 @@ void FXColorRing::updatering(){ if(i2<=r2){ // Compute color - fxhsv_to_rgb(r,g,b,Math::atan2((FXfloat)ry,(FXfloat)rx)*RTOD+180.0f,1.0f,1.0f); + fxhsv_to_rgb(r,g,b,Math::atan2((FXfloat)ry,(FXfloat)rx)*rtod+180.0f,1.0f,1.0f); dial->setPixel(x,y,FXRGB(255.0f*r,255.0f*g,255.0f*b)); continue; } @@ -330,13 +335,13 @@ FXbool FXColorRing::inHueRing(FXint x,FXint y) const { // Compute hue from position on ring x, y FXfloat FXColorRing::hueFromXY(FXint x,FXint y) const { - return Math::atan2((FXfloat)(y-dialy-ringouter),(FXfloat)(x-dialx-ringouter))*RTOD+180.0f; + return Math::atan2((FXfloat)(y-dialy-ringouter),(FXfloat)(x-dialx-ringouter))*rtod+180.0f; } // Compute position on ring from hue void FXColorRing::hueToXY(FXint& x,FXint& y,FXfloat hue) const { - FXfloat a=(hue-180.0f)*DTOR; + FXfloat a=(hue-180.0f)*dtor; FXfloat r=ringouter-ringwidth*0.5f; x=dialx+ringouter+(FXint)(r*Math::cos(a)+0.5f); y=dialy+ringouter+(FXint)(r*Math::sin(a)+0.5f); diff --git a/lib/FXColorWheel.cpp b/lib/FXColorWheel.cpp index fc69588..cc2486e 100644 --- a/lib/FXColorWheel.cpp +++ b/lib/FXColorWheel.cpp @@ -59,6 +59,11 @@ using namespace FX; namespace FX { +// Special single-precision versions +const FXfloat pi=3.1415926535897932384626433833f; +const FXfloat dtor=0.0174532925199432957692369077f; +const FXfloat rtod=57.295779513082320876798154814f; + // Map FXDEFMAP(FXColorWheel) FXColorWheelMap[]={ FXMAPFUNC(SEL_PAINT,0,FXColorWheel::onPaint), @@ -165,7 +170,7 @@ void FXColorWheel::layout(){ // Compute x,y location from hue and saturation FXbool FXColorWheel::hstoxy(FXint& x,FXint& y,FXfloat h,FXfloat s) const { FXfloat r=dial->getWidth()*0.5f; - FXfloat a=(h-180.0f)*DTOR; + FXfloat a=(h-180.0f)*dtor; x=(FXint)(s*r*Math::cos(a)+r+0.5f); y=(FXint)(s*r*Math::sin(a)+r+0.5f); return true; @@ -181,7 +186,7 @@ FXbool FXColorWheel::xytohs(FXfloat& h,FXfloat& s,FXint x,FXint y) const { h=0.0f; s=0.0f; if(0.0f>1; - eq=comparecase(temp,colorName[m]); + eq=FXString::comparecase(temp,colorName[m]); if(eq==0) return colorValue[m]; if(eq<0) h=m-1; else l=m+1; } diff --git a/lib/FXComboBox.cpp b/lib/FXComboBox.cpp index bb93b3e..fc8d586 100644 --- a/lib/FXComboBox.cpp +++ b/lib/FXComboBox.cpp @@ -539,8 +539,8 @@ void FXComboBox::clearItems(FXbool notify){ // Get item by name -FXint FXComboBox::findItem(const FXString& text,FXint start,FXuint flgs) const { - return list->findItem(text,start,flgs); +FXint FXComboBox::findItem(const FXString& string,FXint start,FXuint flgs) const { + return list->findItem(string,start,flgs); } diff --git a/lib/FXComposeContext.cpp b/lib/FXComposeContext.cpp index 10d4fba..d5bb154 100644 --- a/lib/FXComposeContext.cpp +++ b/lib/FXComposeContext.cpp @@ -287,13 +287,13 @@ void FXComposeContext::create(){ if(!window || !window->id()){ fxerror("FXComposeContext: illegal window parameter\n"); } // Get input style - if(comparecase(getApp()->inputstyle,"onthespot")==0) + if(FXString::comparecase(getApp()->inputstyle,"onthespot")==0) style=XIMPreeditCallbacks|XIMStatusNothing; - else if(comparecase(getApp()->inputstyle,"overthespot")==0) + else if(FXString::comparecase(getApp()->inputstyle,"overthespot")==0) style=XIMPreeditPosition|XIMStatusNothing; - else if(comparecase(getApp()->inputstyle,"offthespot")==0) + else if(FXString::comparecase(getApp()->inputstyle,"offthespot")==0) style=XIMPreeditArea|XIMStatusArea; - else if(comparecase(getApp()->inputstyle,"root")==0) + else if(FXString::comparecase(getApp()->inputstyle,"root")==0) style=XIMPreeditNothing|XIMStatusNothing; else style=XIMPreeditNone|XIMStatusNone; diff --git a/lib/FXCursor.cpp b/lib/FXCursor.cpp index 55a8b3e..7d30e28 100644 --- a/lib/FXCursor.cpp +++ b/lib/FXCursor.cpp @@ -111,7 +111,7 @@ FXCursor::FXCursor(FXApp* a,const FXuchar* src,const FXuchar* msk,FXint w,FXint // Make cursor from FXColor pixels FXCursor::FXCursor(FXApp* a,const FXColor *pix,FXint w,FXint h,FXint hx,FXint hy):FXId(a){ FXTRACE((TOPIC_CONSTRUCT,"FXCursor::FXCursor %p\n",this)); - data=(FXColor*)pix; + data=const_cast(pix); width=w; height=h; hotx=FXCLAMP(0,hx,width-1); diff --git a/lib/FXDCWindow.cpp b/lib/FXDCWindow.cpp index 4a8982e..1520b93 100644 --- a/lib/FXDCWindow.cpp +++ b/lib/FXDCWindow.cpp @@ -21,6 +21,7 @@ #include "xincs.h" #include "fxver.h" #include "fxdefs.h" +#include "fxchar.h" #include "fxmath.h" #include "fxkeys.h" #include "FXArray.h" @@ -148,7 +149,7 @@ namespace FX { * MS-Windows * ********************************************************************************/ -#ifdef WIN32 +#if defined(WIN32) // This one is not defined in the Cygwin header files #ifndef PS_JOIN_MASK @@ -1862,14 +1863,14 @@ void FXDCWindow::drawPoint(FXint x,FXint y){ // Draw points void FXDCWindow::drawPoints(const FXPoint* points,FXuint npoints){ if(!surface){ fxerror("FXDCWindow::drawPoints: DC not connected to drawable.\n"); } - XDrawPoints((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,(XPoint*)points,npoints,CoordModeOrigin); + XDrawPoints((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,const_cast((const XPoint*)points),npoints,CoordModeOrigin); } // Draw points relative void FXDCWindow::drawPointsRel(const FXPoint* points,FXuint npoints){ if(!surface){ fxerror("FXDCWindow::drawPointsRel: DC not connected to drawable.\n"); } - XDrawPoints((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,(XPoint*)points,npoints,CoordModePrevious); + XDrawPoints((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,const_cast((const XPoint*)points),npoints,CoordModePrevious); } @@ -1883,21 +1884,21 @@ void FXDCWindow::drawLine(FXint x1,FXint y1,FXint x2,FXint y2){ // Draw lines void FXDCWindow::drawLines(const FXPoint* points,FXuint npoints){ if(!surface){ fxerror("FXDCWindow::drawLines: DC not connected to drawable.\n"); } - XDrawLines((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,(XPoint*)points,npoints,CoordModeOrigin); + XDrawLines((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,const_cast((const XPoint*)points),npoints,CoordModeOrigin); } // Draw lines relative void FXDCWindow::drawLinesRel(const FXPoint* points,FXuint npoints){ if(!surface){ fxerror("FXDCWindow::drawLinesRel: DC not connected to drawable.\n"); } - XDrawLines((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,(XPoint*)points,npoints,CoordModePrevious); + XDrawLines((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,const_cast((const XPoint*)points),npoints,CoordModePrevious); } // Draw line segments void FXDCWindow::drawLineSegments(const FXSegment* segments,FXuint nsegments){ if(!surface){ fxerror("FXDCWindow::drawLineSegments: DC not connected to drawable.\n"); } - XDrawSegments((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,(XSegment*)segments,nsegments); + XDrawSegments((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,const_cast((const XSegment*)segments),nsegments); } @@ -1911,7 +1912,7 @@ void FXDCWindow::drawRectangle(FXint x,FXint y,FXint w,FXint h){ // Draw rectangles void FXDCWindow::drawRectangles(const FXRectangle* rectangles,FXuint nrectangles){ if(!surface){ fxerror("FXDCWindow::drawRectangles: DC not connected to drawable.\n"); } - XDrawRectangles((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,(XRectangle*)rectangles,nrectangles); + XDrawRectangles((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,const_cast((const XRectangle*)rectangles),nrectangles); } @@ -1962,7 +1963,7 @@ void FXDCWindow::drawArc(FXint x,FXint y,FXint w,FXint h,FXint ang1,FXint ang2){ // Draw arcs void FXDCWindow::drawArcs(const FXArc* arcs,FXuint narcs){ if(!surface){ fxerror("FXDCWindow::drawArcs: DC not connected to drawable.\n"); } - XDrawArcs((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,(XArc*)arcs,narcs); + XDrawArcs((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,const_cast((const XArc*)arcs),narcs); } @@ -1983,7 +1984,7 @@ void FXDCWindow::fillRectangle(FXint x,FXint y,FXint w,FXint h){ // Fill rectangles void FXDCWindow::fillRectangles(const FXRectangle* rectangles,FXuint nrectangles){ if(!surface){ fxerror("FXDCWindow::fillRectangles: DC not connected to drawable.\n"); } - XFillRectangles((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,(XRectangle*)rectangles,nrectangles); + XFillRectangles((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,const_cast((const XRectangle*)rectangles),nrectangles); } @@ -2034,7 +2035,7 @@ void FXDCWindow::fillChord(FXint x,FXint y,FXint w,FXint h,FXint ang1,FXint ang2 void FXDCWindow::fillChords(const FXArc* chords,FXuint nchords){ if(!surface){ fxerror("FXDCWindow::fillChords: DC not connected to drawable.\n"); } XSetArcMode((Display*)getApp()->getDisplay(),(GC)ctx,ArcChord); - XFillArcs((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,(XArc*)chords,nchords); + XFillArcs((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,const_cast((const XArc*)chords),nchords); XSetArcMode((Display*)getApp()->getDisplay(),(GC)ctx,ArcPieSlice); } @@ -2049,7 +2050,7 @@ void FXDCWindow::fillArc(FXint x,FXint y,FXint w,FXint h,FXint ang1,FXint ang2){ // Fill arcs void FXDCWindow::fillArcs(const FXArc* arcs,FXuint narcs){ if(!surface){ fxerror("FXDCWindow::fillArcs: DC not connected to drawable.\n"); } - XFillArcs((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,(XArc*)arcs,narcs); + XFillArcs((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,const_cast((const XArc*)arcs),narcs); } @@ -2063,42 +2064,42 @@ void FXDCWindow::fillEllipse(FXint x,FXint y,FXint w,FXint h){ // Fill polygon void FXDCWindow::fillPolygon(const FXPoint* points,FXuint npoints){ if(!surface){ fxerror("FXDCWindow::fillArcs: DC not connected to drawable.\n"); } - XFillPolygon((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,(XPoint*)points,npoints,Convex,CoordModeOrigin); + XFillPolygon((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,const_cast((const XPoint*)points),npoints,Convex,CoordModeOrigin); } // Fill concave polygon void FXDCWindow::fillConcavePolygon(const FXPoint* points,FXuint npoints){ if(!surface){ fxerror("FXDCWindow::fillConcavePolygon: DC not connected to drawable.\n"); } - XFillPolygon((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,(XPoint*)points,npoints,Nonconvex,CoordModeOrigin); + XFillPolygon((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,const_cast((const XPoint*)points),npoints,Nonconvex,CoordModeOrigin); } // Fill complex polygon void FXDCWindow::fillComplexPolygon(const FXPoint* points,FXuint npoints){ if(!surface){ fxerror("FXDCWindow::fillComplexPolygon: DC not connected to drawable.\n"); } - XFillPolygon((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,(XPoint*)points,npoints,Complex,CoordModeOrigin); + XFillPolygon((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,const_cast((const XPoint*)points),npoints,Complex,CoordModeOrigin); } // Fill polygon relative void FXDCWindow::fillPolygonRel(const FXPoint* points,FXuint npoints){ if(!surface){ fxerror("FXDCWindow::fillPolygonRel: DC not connected to drawable.\n"); } - XFillPolygon((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,(XPoint*)points,npoints,Convex,CoordModePrevious); + XFillPolygon((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,const_cast((const XPoint*)points),npoints,Convex,CoordModePrevious); } // Fill concave polygon relative void FXDCWindow::fillConcavePolygonRel(const FXPoint* points,FXuint npoints){ if(!surface){ fxerror("FXDCWindow::fillConcavePolygonRel: DC not connected to drawable.\n"); } - XFillPolygon((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,(XPoint*)points,npoints,Nonconvex,CoordModePrevious); + XFillPolygon((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,const_cast((const XPoint*)points),npoints,Nonconvex,CoordModePrevious); } // Fill complex polygon relative void FXDCWindow::fillComplexPolygonRel(const FXPoint* points,FXuint npoints){ if(!surface){ fxerror("FXDCWindow::fillComplexPolygonRel: DC not connected to drawable.\n"); } - XFillPolygon((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,(XPoint*)points,npoints,Complex,CoordModePrevious); + XFillPolygon((Display*)getApp()->getDisplay(),surface->id(),(GC)ctx,const_cast((const XPoint*)points),npoints,Complex,CoordModePrevious); } diff --git a/lib/FXDDSIcon.cpp b/lib/FXDDSIcon.cpp index 15f67b8..afde2b6 100644 --- a/lib/FXDDSIcon.cpp +++ b/lib/FXDDSIcon.cpp @@ -70,9 +70,9 @@ FXIMPLEMENT(FXDDSIcon,FXIcon,nullptr,0) // Initialize nicely -FXDDSIcon::FXDDSIcon(FXApp* a,const void *pix,FXColor clr,FXuint opts,FXint w,FXint h):FXIcon(a,nullptr,clr,opts,w,h){ +FXDDSIcon::FXDDSIcon(FXApp* a,const FXuchar *pix,FXColor clr,FXuint opts,FXint w,FXint h):FXIcon(a,nullptr,clr,opts,w,h){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXDDSImage.cpp b/lib/FXDDSImage.cpp index c92b409..5d43cfa 100644 --- a/lib/FXDDSImage.cpp +++ b/lib/FXDDSImage.cpp @@ -69,9 +69,9 @@ FXIMPLEMENT(FXDDSImage,FXImage,nullptr,0) // Initialize -FXDDSImage::FXDDSImage(FXApp* a,const void *pix,FXuint opts,FXint w,FXint h):FXImage(a,nullptr,opts,w,h){ +FXDDSImage::FXDDSImage(FXApp* a,const FXuchar *pix,FXuint opts,FXint w,FXint h):FXImage(a,nullptr,opts,w,h){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXDictionary.cpp b/lib/FXDictionary.cpp index d4c25b2..5880abe 100644 --- a/lib/FXDictionary.cpp +++ b/lib/FXDictionary.cpp @@ -57,7 +57,7 @@ - Similar to FXVariantMap; reimplemented to support plain void* as payload. */ -#define EMPTY ((Entry*)(__dictionary__empty__+3)) +#define EMPTY (const_cast((const Entry*)(__dictionary__empty__+3))) #define BSHIFT 5 using namespace FX; @@ -134,14 +134,14 @@ FXbool FXDictionary::resize(FXival n){ // Construct empty dictionary FXDictionary::FXDictionary():table(EMPTY){ - FXASSERT(sizeof(FXDictionary)==sizeof(FXptr)); + FXASSERT(sizeof(FXDictionary)==sizeof(void*)); FXASSERT(sizeof(Entry)<=sizeof(FXival)*3); } // Construct from another dictionary FXDictionary::FXDictionary(const FXDictionary& other):table(EMPTY){ - FXASSERT(sizeof(FXDictionary)==sizeof(FXptr)); + FXASSERT(sizeof(FXDictionary)==sizeof(void*)); FXASSERT(sizeof(Entry)<=sizeof(FXival)*3); if(1>=BSHIFT; } @@ -258,15 +258,15 @@ FXptr FXDictionary::remove(const FXchar* ky){ used(used()-1); if(__unlikely(used()<=(no()>>2))) resize(no()>>1); } - return old; +x:return old; } // Erase data at pos in the table; return old value, if any -FXptr FXDictionary::erase(FXival pos){ +void* FXDictionary::erase(FXival pos){ if(__unlikely(pos<0 || no()<=pos)){ throw FXRangeException("FXDictionary::erase: argument out of range\n"); } if(!table[pos].key.empty()){ - FXptr old=table[pos].data; + void* old=table[pos].data; table[pos].key.clear(); // Void the slot (not empty!) table[pos].data=nullptr; used(used()-1); @@ -278,8 +278,8 @@ FXptr FXDictionary::erase(FXival pos){ // Clear entire table -void FXDictionary::clear(){ - no(1); +FXbool FXDictionary::clear(){ + return no(1); } diff --git a/lib/FXDir.cpp b/lib/FXDir.cpp index 84c2143..da06480 100644 --- a/lib/FXDir.cpp +++ b/lib/FXDir.cpp @@ -21,6 +21,7 @@ #include "xincs.h" #include "fxver.h" #include "fxdefs.h" +#include "fxchar.h" #include "fxmath.h" #include "FXArray.h" #include "FXHash.h" diff --git a/lib/FXDirBox.cpp b/lib/FXDirBox.cpp index 555c41b..74fdc52 100644 --- a/lib/FXDirBox.cpp +++ b/lib/FXDirBox.cpp @@ -197,9 +197,9 @@ FXString FXDirBox::getItemPathname(FXTreeItem *item) const { static FXTreeItem* findItemChild(FXTreeItem* item,const FXString& name){ while(item){ #ifdef WIN32 - if(comparecase(name,item->getText())==0) return item; + if(FXString::comparecase(name,item->getText())==0) return item; #else - if(compare(name,item->getText())==0) return item; + if(FXString::compare(name,item->getText())==0) return item; #endif item=item->getNext(); } @@ -391,7 +391,7 @@ FXTreeItem* FXDirBox::getPathnameItem(const FXString& path){ it=appendItem(nullptr,drivename,icon,icon); // Rest of path under this root - if(comparecase(path,drivename,end)==0) item=it; + if(FXString::comparecase(path,drivename,end)==0) item=it; } drivemask>>=1; } @@ -412,7 +412,7 @@ FXTreeItem* FXDirBox::getPathnameItem(const FXString& path){ it=appendItem(nullptr,"\\\\",icon,icon); // Rest of path under this root maybe - if(comparecase(path,"\\\\",end)==0) item=it; + if(FXString::comparecase(path,"\\\\",end)==0) item=it; */ // Got root? if(item){ diff --git a/lib/FXDirDialog.cpp b/lib/FXDirDialog.cpp index 2461601..266a6ea 100644 --- a/lib/FXDirDialog.cpp +++ b/lib/FXDirDialog.cpp @@ -31,6 +31,7 @@ #include "FXSize.h" #include "FXPoint.h" #include "FXRectangle.h" +#include "FXPath.h" #include "FXStat.h" #include "FXFile.h" #include "FXStringDictionary.h" @@ -67,6 +68,11 @@ using namespace FX; namespace FX { + +// File dialog registry section name +const FXchar FXDirDialog::sectionName[]="Directory Dialog"; + + // Object implementation FXIMPLEMENT(FXDirDialog,FXDialogBox,nullptr,0) @@ -90,16 +96,16 @@ void FXDirDialog::initdialog(){ dirbox->acceptButton()->setSelector(FXDialogBox::ID_ACCEPT); dirbox->cancelButton()->setTarget(this); dirbox->cancelButton()->setSelector(FXDialogBox::ID_CANCEL); - setWidth(getApp()->reg().readIntEntry("Directory Dialog","width",getWidth())); - setHeight(getApp()->reg().readIntEntry("Directory Dialog","height",getHeight())); + setWidth(getApp()->reg().readIntEntry(sectionName,"width",getWidth())); + setHeight(getApp()->reg().readIntEntry(sectionName,"height",getHeight())); } // Hide window and save settings void FXDirDialog::hide(){ FXDialogBox::hide(); - getApp()->reg().writeIntEntry("Directory Dialog","width",getWidth()); - getApp()->reg().writeIntEntry("Directory Dialog","height",getHeight()); + getApp()->reg().writeIntEntry(sectionName,"width",getWidth()); + getApp()->reg().writeIntEntry(sectionName,"height",getHeight()); } diff --git a/lib/FXDirList.cpp b/lib/FXDirList.cpp index 2114b70..1dfc49b 100644 --- a/lib/FXDirList.cpp +++ b/lib/FXDirList.cpp @@ -268,32 +268,52 @@ FXTreeItem* FXDirList::createItem(const FXString& text,FXIcon* oi,FXIcon* ci,voi // Sort ascending order, keeping directories first FXint FXDirList::ascending(const FXTreeItem* pa,const FXTreeItem* pb){ FXint diff=static_cast(pb)->isDirectory() - static_cast(pa)->isDirectory(); - return diff ? diff : compare(pa->label,pb->label); + return diff ? diff : FXString::comparenatural(pa->label,pb->label); } // Sort descending order, keeping directories first FXint FXDirList::descending(const FXTreeItem* pa,const FXTreeItem* pb){ FXint diff=static_cast(pb)->isDirectory() - static_cast(pa)->isDirectory(); - return diff ? diff : compare(pb->label,pa->label); + return diff ? diff : FXString::comparenatural(pb->label,pa->label); } // Sort ascending order, case insensitive, keeping directories first FXint FXDirList::ascendingCase(const FXTreeItem* pa,const FXTreeItem* pb){ FXint diff=static_cast(pb)->isDirectory() - static_cast(pa)->isDirectory(); - return diff ? diff : comparecase(pa->label,pb->label); + return diff ? diff : FXString::comparenaturalcase(pa->label,pb->label); } // Sort descending order, case insensitive, keeping directories first FXint FXDirList::descendingCase(const FXTreeItem* pa,const FXTreeItem* pb){ FXint diff=static_cast(pb)->isDirectory() - static_cast(pa)->isDirectory(); - return diff ? diff : comparecase(pb->label,pa->label); + return diff ? diff : FXString::comparenaturalcase(pb->label,pa->label); } /*******************************************************************************/ +// Select files matching wildcard pattern +FXbool FXDirList::selectMatching(const FXString& ptrn,FXuint mode,FXbool notify){ + FXTreeItem *item=getFirstItem(); + FXbool changes=false; + while(item){ + if(FXPath::match(getItemText(item),ptrn,mode)){ + changes|=selectItem(item,notify); + } + if(item->getFirst()){ + item=item->getFirst(); + } + else{ + while(!item->getNext() && item->getParent()) item=item->getParent(); + item=item->getNext(); + } + } + return changes; + } + + // Return uri-list of selected files FXString FXDirList::getSelectedFiles() const { FXTreeItem *item=getFirstItem(); @@ -839,7 +859,7 @@ void FXDirList::listRootItems(FXbool force,FXbool notify){ // Find it, and take it out from the old list if found for(FXDirItem** pp=po; (item=*pp)!=nullptr; pp=&item->link){ - if(comparecase(item->label,name)==0){ + if(FXString::comparecase(item->label,name)==0){ *pp=item->link; item->link=nullptr; goto fnd; } @@ -1029,7 +1049,7 @@ FXbool FXDirList::listChildItems(FXDirItem *par,FXbool force,FXbool notify){ // Find it, and take it out from the old list if found for(FXDirItem** pp=po; (olditem=*pp)!=nullptr; pp=&olditem->link){ - if(compare(olditem->label,name)==0){ + if(FXString::compare(olditem->label,name)==0){ *pp=olditem->link; olditem->link=nullptr; break; } @@ -1126,9 +1146,9 @@ FXbool FXDirList::listChildItems(FXDirItem *par,FXbool force,FXbool notify){ static FXTreeItem* findChildItem(FXTreeItem* item,const FXString& name){ while(item){ #ifdef WIN32 - if(comparecase(name,item->getText())==0) return item; + if(FXString::comparecase(name,item->getText())==0) return item; #else - if(compare(name,item->getText())==0) return item; + if(FXString::compare(name,item->getText())==0) return item; #endif item=item->getNext(); } diff --git a/lib/FXDirWatch.cpp b/lib/FXDirWatch.cpp index 079c439..f4c4f09 100644 --- a/lib/FXDirWatch.cpp +++ b/lib/FXDirWatch.cpp @@ -21,6 +21,7 @@ #include "xincs.h" #include "fxver.h" #include "fxdefs.h" +#include "fxchar.h" #include "fxmath.h" #include "FXException.h" #include "FXArray.h" diff --git a/lib/FXDispatcher.cpp b/lib/FXDispatcher.cpp index b6b42b1..c033a5d 100644 --- a/lib/FXDispatcher.cpp +++ b/lib/FXDispatcher.cpp @@ -40,6 +40,28 @@ will not establish a handler callback, and thus when such a signal is raised, it must be filtered via overrides of dispatchSignal prior to being processed by this implementation of dispatchSignal(); otherwise, a core dump may result. + + - Sample usage: + + disp->addInterval(TimeoutCallback::create(target),dt,ptr); + + FIXME maybe this is better: + + disp->addInterval(FXObject* tgt,FXSelector sel,FXTime ns=1000000000,FXptr ptr=nullptr); + + OK, if message map only contains function-pointers [method_call() template-generated + function call addresses], then we can look up this method-call: + + long (*caller)(FXObject*,FXSelector,void*); + + caller=metaClass.search(sel); + + We can store caller into callback struct! + + Then: + + caller(target,this,FXSEL(SEL_TIMEOUT,message),userdata); + */ using namespace FX; @@ -239,6 +261,7 @@ FXbool FXDispatcher::dispatchTimeout(FXTime due){ return false; } + /*******************************************************************************/ // Add idle callback be executed when dispatch about to block. diff --git a/lib/FXDisplay.cpp b/lib/FXDisplay.cpp index 771fad3..42fa217 100644 --- a/lib/FXDisplay.cpp +++ b/lib/FXDisplay.cpp @@ -35,7 +35,7 @@ namespace FX { /*******************************************************************************/ // Construct display -FXDisplay::FXDisplay(){ +FXDisplay::FXDisplay():display(nullptr){ } diff --git a/lib/FXEXEIcon.cpp b/lib/FXEXEIcon.cpp index d97a636..95e20d1 100644 --- a/lib/FXEXEIcon.cpp +++ b/lib/FXEXEIcon.cpp @@ -64,9 +64,9 @@ FXIMPLEMENT(FXEXEIcon,FXIcon,nullptr,0) // Initialize nicely -FXEXEIcon::FXEXEIcon(FXApp* a,const void *pix,FXColor clr,FXuint opts,FXint w,FXint h,FXint ri,FXint rt):FXIcon(a,nullptr,clr,opts,w,h),rtype(rt),rid(ri){ +FXEXEIcon::FXEXEIcon(FXApp* a,const FXuchar *pix,FXColor clr,FXuint opts,FXint w,FXint h,FXint ri,FXint rt):FXIcon(a,nullptr,clr,opts,w,h),rtype(rt),rid(ri){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXEXEImage.cpp b/lib/FXEXEImage.cpp index 9aea96f..e76986a 100644 --- a/lib/FXEXEImage.cpp +++ b/lib/FXEXEImage.cpp @@ -65,9 +65,9 @@ FXIMPLEMENT(FXEXEImage,FXImage,nullptr,0) // Initialize -FXEXEImage::FXEXEImage(FXApp* a,const void *pix,FXuint opts,FXint w,FXint h,FXint ri,FXint rt):FXImage(a,nullptr,opts,w,h),rtype(rt),rid(ri){ +FXEXEImage::FXEXEImage(FXApp* a,const FXuchar *pix,FXuint opts,FXint w,FXint h,FXint ri,FXint rt):FXImage(a,nullptr,opts,w,h),rtype(rt),rid(ri){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXEventDispatcher.cpp b/lib/FXEventDispatcher.cpp index bab5c03..b172353 100644 --- a/lib/FXEventDispatcher.cpp +++ b/lib/FXEventDispatcher.cpp @@ -217,9 +217,9 @@ FXbool FXEventDispatcher::dispatch(FXTime blocking,FXuint flags){ FXbool FXEventDispatcher::dispatch(FXTime blocking,FXuint flags){ if(internals){ FXTime now,due,delay,interval; - FXuint sig,nxt,mode,ms; + FXuint sig,nxt,ms,mode,ticks; FXInputHandle hnd; - FXRawEvent event; + FXRawEvent event,ev; // Loop till we got something while(1){ @@ -253,8 +253,56 @@ FXbool FXEventDispatcher::dispatch(FXTime blocking,FXuint flags){ if(flags&DispatchEvents){ if(XEventsQueued((Display*)display,QueuedAfterFlush)){ XNextEvent((Display*)display,&event); -// FIXME compress events - if(dispatchEvent(event)) return true; // Event activity +#if 0 +#if 0 + // Event was filtered by input method; get next one + if(xim && XFilterEvent(&ev,None)){ + goto a; + } + if(xim && getFocusWindow() && XFilterEvent(&ev,(Window)getFocusWindow()->id())){ // FIXME + goto a; + } +#endif + // Passing in focuswindow to XFilterEvent just didn't work on Gnome3 with either scim or ibus + if(xim && getFocusWindow() && XFilterEvent(&ev,None)){ // [Patch from Roland Baudin] FIXME but also need to deal with keyboard grabs + return false; + } +#endif + // Compress motion events + if(event.xany.type==MotionNotify){ + while(XPending((Display*)display)){ + XPeekEvent((Display*)display,&ev); + if((ev.xany.type!=MotionNotify) || (event.xmotion.window!=ev.xmotion.window) || (event.xmotion.state != ev.xmotion.state)) break; + XNextEvent((Display*)display,&event); + } + } + + // Compress wheel events + else if((event.xany.type==ButtonPress) && (event.xbutton.button==Button4 || event.xbutton.button==Button5)){ + ticks=1; + while(XPending((Display*)display)){ + XPeekEvent((Display*)display,&ev); + if((ev.xany.type!=ButtonPress && ev.xany.type!=ButtonRelease) || (event.xany.window!=ev.xany.window) || (event.xbutton.button != ev.xbutton.button)) break; + ticks+=(ev.xany.type==ButtonPress); + XNextEvent((Display*)display,&event); + } + event.xbutton.subwindow=(Window)ticks; // Stick it here for later + } + + // Compress configure events + else if(event.xany.type==ConfigureNotify){ + while(XCheckTypedWindowEvent((Display*)display,event.xconfigure.window,ConfigureNotify,&ev)){ + event.xconfigure.width=ev.xconfigure.width; + event.xconfigure.height=ev.xconfigure.height; + if(ev.xconfigure.send_event){ + event.xconfigure.x=ev.xconfigure.x; + event.xconfigure.y=ev.xconfigure.y; + } + } + } + + // Event activity + if(dispatchEvent(event)) return true; continue; } } @@ -333,8 +381,8 @@ FXbool FXEventDispatcher::dispatch(FXTime blocking,FXuint flags){ FXbool FXEventDispatcher::dispatch(FXTime blocking,FXuint flags){ if(internals){ FXTime now,due,delay,interval; - FXuint sig,nxt,mode; - FXRawEvent event; + FXuint sig,nxt,mode,ticks; + FXRawEvent event,ev; #if (_POSIX_C_SOURCE >= 200112L) struct timespec delta; #else @@ -373,8 +421,56 @@ FXbool FXEventDispatcher::dispatch(FXTime blocking,FXuint flags){ if(flags&DispatchEvents){ if(XEventsQueued((Display*)display,QueuedAfterFlush)){ XNextEvent((Display*)display,&event); -// FIXME compress events - if(dispatchEvent(event)) return true; // Event activity +#if 0 +#if 0 + // Event was filtered by input method; get next one + if(xim && XFilterEvent(&ev,None)){ + goto a; + } + if(xim && getFocusWindow() && XFilterEvent(&ev,(Window)getFocusWindow()->id())){ // FIXME + goto a; + } +#endif + // Passing in focuswindow to XFilterEvent just didn't work on Gnome3 with either scim or ibus + if(xim && getFocusWindow() && XFilterEvent(&ev,None)){ // [Patch from Roland Baudin] FIXME but also need to deal with keyboard grabs + return false; + } +#endif + // Compress motion events + if(event.xany.type==MotionNotify){ + while(XPending((Display*)display)){ + XPeekEvent((Display*)display,&ev); + if((ev.xany.type!=MotionNotify) || (event.xmotion.window!=ev.xmotion.window) || (event.xmotion.state != ev.xmotion.state)) break; + XNextEvent((Display*)display,&event); + } + } + + // Compress wheel events + else if((event.xany.type==ButtonPress) && (event.xbutton.button==Button4 || event.xbutton.button==Button5)){ + ticks=1; + while(XPending((Display*)display)){ + XPeekEvent((Display*)display,&ev); + if((ev.xany.type!=ButtonPress && ev.xany.type!=ButtonRelease) || (event.xany.window!=ev.xany.window) || (event.xbutton.button != ev.xbutton.button)) break; + ticks+=(ev.xany.type==ButtonPress); + XNextEvent((Display*)display,&event); + } + event.xbutton.subwindow=(Window)ticks; // Stick it here for later + } + + // Compress configure events + else if(event.xany.type==ConfigureNotify){ + while(XCheckTypedWindowEvent((Display*)display,event.xconfigure.window,ConfigureNotify,&ev)){ + event.xconfigure.width=ev.xconfigure.width; + event.xconfigure.height=ev.xconfigure.height; + if(ev.xconfigure.send_event){ + event.xconfigure.x=ev.xconfigure.x; + event.xconfigure.y=ev.xconfigure.y; + } + } + } + + // Event activity + if(dispatchEvent(event)) return true; continue; } } diff --git a/lib/FXEventLoop.cpp b/lib/FXEventLoop.cpp index df70298..ca2cd48 100644 --- a/lib/FXEventLoop.cpp +++ b/lib/FXEventLoop.cpp @@ -42,7 +42,6 @@ - The member variable invocation holds the address of the variable containing the innermost model loop currently running; so we can locate all model loops through invocation. - */ using namespace FX; @@ -141,6 +140,12 @@ FXEventLoop::~FXEventLoop(){ #if 0 +// Perform a single event dispatch +FXbool FXEventLoop::runOneEvent(FXTime blocking,FXuint flags){ + return dispatcher && dispatcher->dispatch(blocking,flags); + } + + // Run application FXint FXEventLoop::run(){ @@ -178,17 +183,6 @@ FXint FXEventLoop::runModalWhileEvents(FXWindow* window,FXTime blocking){ } -// Perform one event dispatch -FXbool FXEventLoop::runOneEvent(FXTime blocking){ - FXRawEvent ev; - if(getNextEvent(ev,blocking)){ - dispatchEvent(ev); - return true; - } - return false; - } - - // Run modal event loop, blocking events to all windows, until stopModal is called. FXint FXEventLoop::runModal(){ FXEventLoop inv(&invocation); diff --git a/lib/FXExpression.cpp b/lib/FXExpression.cpp index ed924f7..273b88d 100644 --- a/lib/FXExpression.cpp +++ b/lib/FXExpression.cpp @@ -44,10 +44,13 @@ #define MAXSTACKDEPTH 128 +// Empty expression +#define EMPTY (const_cast(FXExpression::initial)) + // Access to argument #if defined(__i386__) || defined(__x86_64__) // No alignment limits on shorts #define SETARG(p,val) (*((FXshort*)(p))=(val)) -#define GETARG(p) (*((FXshort*)(p))) +#define GETARG(p) (*((const FXshort*)(p))) #elif (FOX_BIGENDIAN == 1) // Big-endian machines #define SETARG(p,val) (*((p)+0)=(val)>>8,*((p)+1)=(val)) #define GETARG(p) ((FXshort)((*((p)+0)<<8)+(*((p)+1)))) @@ -909,13 +912,13 @@ const FXchar *const FXExpression::errors[]={ // Construct empty expression object -FXExpression::FXExpression():code((FXuchar*)(void*)initial){ +FXExpression::FXExpression():code(EMPTY){ FXTRACE((TOPIC_CONSTRUCT,"FXExpression::FXExpression()\n")); } // Copy regex object -FXExpression::FXExpression(const FXExpression& orig):code((FXuchar*)(void*)initial){ +FXExpression::FXExpression(const FXExpression& orig):code(EMPTY){ FXTRACE((TOPIC_CONSTRUCT,"FXExpression::FXExpression(FXExpression)\n")); if(orig.code!=initial){ dupElms(code,orig.code,GETARG(orig.code)); @@ -924,7 +927,7 @@ FXExpression::FXExpression(const FXExpression& orig):code((FXuchar*)(void*)initi // Compile expression from pattern; fail if error -FXExpression::FXExpression(const FXchar* expression,const FXchar* variables,FXExpression::Error* error):code((FXuchar*)(void*)initial){ +FXExpression::FXExpression(const FXchar* expression,const FXchar* variables,FXExpression::Error* error):code(EMPTY){ FXTRACE((TOPIC_CONSTRUCT,"FXExpression::FXExpression(%s,%s,%p)\n",expression,variables,error)); FXExpression::Error err=parse(expression,variables); if(error){ *error=err; } @@ -932,7 +935,7 @@ FXExpression::FXExpression(const FXchar* expression,const FXchar* variables,FXEx // Compile expression from pattern; fail if error -FXExpression::FXExpression(const FXString& expression,const FXString& variables,FXExpression::Error* error):code((FXuchar*)(void*)initial){ +FXExpression::FXExpression(const FXString& expression,const FXString& variables,FXExpression::Error* error):code(EMPTY){ FXTRACE((TOPIC_CONSTRUCT,"FXExpression::FXExpression(%s,%s,%p)\n",expression.text(),variables.text(),error)); FXExpression::Error err=parse(expression.text(),variables.text()); if(error){ *error=err; } @@ -943,7 +946,7 @@ FXExpression::FXExpression(const FXString& expression,const FXString& variables, FXExpression& FXExpression::operator=(const FXExpression& orig){ if(code!=orig.code){ if(code!=initial) freeElms(code); - code=(FXuchar*)(void*)initial; + code=EMPTY; if(orig.code!=initial){ dupElms(code,orig.code,GETARG(orig.code)); } @@ -1024,7 +1027,7 @@ FXdouble FXExpression::evaluate(const FXdouble *args) const { case OP_BRF: pc+=*sp-- ? 2 : GETARG(pc); break; case OP_BRT: pc+=*sp-- ? GETARG(pc) : 2; break; #if defined(__i386__) || defined(__x86_64__) || defined(WIN32) || defined(__minix) - case OP_NUM: *++sp=*((FXdouble*)pc); pc+=8; break; + case OP_NUM: *++sp=*((const FXdouble*)pc); pc+=8; break; #else case OP_NUM: ++sp; ((FXuchar*)sp)[0]=*pc++; ((FXuchar*)sp)[1]=*pc++; ((FXuchar*)sp)[2]=*pc++; ((FXuchar*)sp)[3]=*pc++; ((FXuchar*)sp)[4]=*pc++; ((FXuchar*)sp)[5]=*pc++; ((FXuchar*)sp)[6]=*pc++; ((FXuchar*)sp)[7]=*pc++; break; #endif @@ -1103,9 +1106,9 @@ FXStream& operator>>(FXStream& store,FXExpression& s){ // Clear the expression void FXExpression::clear(){ - if(code!=initial){ + if(code!=EMPTY){ freeElms(code); - code=(FXuchar*)(void*)initial; + code=EMPTY; } } diff --git a/lib/FXFile.cpp b/lib/FXFile.cpp index 1927a8d..3eaf918 100644 --- a/lib/FXFile.cpp +++ b/lib/FXFile.cpp @@ -21,6 +21,7 @@ #include "xincs.h" #include "fxver.h" #include "fxdefs.h" +#include "fxchar.h" #include "fxmath.h" #include "fxascii.h" #include "FXArray.h" diff --git a/lib/FXFileDialog.cpp b/lib/FXFileDialog.cpp index d1b0bdf..8c6ef58 100644 --- a/lib/FXFileDialog.cpp +++ b/lib/FXFileDialog.cpp @@ -70,7 +70,6 @@ namespace FX { const FXchar FXFileDialog::sectionName[]="File Dialog"; - // Object implementation FXIMPLEMENT(FXFileDialog,FXDialogBox,nullptr,0) @@ -82,7 +81,6 @@ FXFileDialog::FXFileDialog(FXWindow* own,const FXString& name,FXuint opts,FXint filebox->acceptButton()->setSelector(FXDialogBox::ID_ACCEPT); filebox->cancelButton()->setTarget(this); filebox->cancelButton()->setSelector(FXDialogBox::ID_CANCEL); - loadSettings(); } @@ -93,12 +91,25 @@ FXFileDialog::FXFileDialog(FXApp* a,const FXString& name,FXuint opts,FXint x,FXi filebox->acceptButton()->setSelector(FXDialogBox::ID_ACCEPT); filebox->cancelButton()->setTarget(this); filebox->cancelButton()->setSelector(FXDialogBox::ID_CANCEL); - loadSettings(); + } + + +// Create server-side resources +void FXFileDialog::create(){ + readRegistry(); + FXDialogBox::create(); + } + + +// Destroy server-side resources +void FXFileDialog::destroy(){ + FXDialogBox::destroy(); + writeRegistry(); } // Load settings from registry -void FXFileDialog::loadSettings(){ +void FXFileDialog::readRegistry(){ setWidth(getApp()->reg().readIntEntry(sectionName,"width",getWidth())); setHeight(getApp()->reg().readIntEntry(sectionName,"height",getHeight())); setFileBoxStyle(getApp()->reg().readUIntEntry(sectionName,"style",getFileBoxStyle())); @@ -107,7 +118,7 @@ void FXFileDialog::loadSettings(){ // Save settings to registry -void FXFileDialog::saveSettings(){ +void FXFileDialog::writeRegistry(){ getApp()->reg().writeIntEntry(sectionName,"width",getWidth()); getApp()->reg().writeIntEntry(sectionName,"height",getHeight()); getApp()->reg().writeUIntEntry(sectionName,"style",getFileBoxStyle()); @@ -395,7 +406,7 @@ void FXFileDialog::load(FXStream& store){ // Cleanup FXFileDialog::~FXFileDialog(){ - saveSettings(); + destroy(); filebox=(FXFileSelector*)-1L; } diff --git a/lib/FXFileList.cpp b/lib/FXFileList.cpp index 25c0c90..41fe29c 100644 --- a/lib/FXFileList.cpp +++ b/lib/FXFileList.cpp @@ -295,12 +295,73 @@ FXIconItem *FXFileList::createItem(const FXString& text,FXIcon *big,FXIcon* mini /*******************************************************************************/ +// Compare string and string with natural interpretation of decimal numbers +FXint FXFileList::compareSectionNatural(const FXchar* s1,const FXchar* s2,FXint s,FXbool ci){ + const FXchar *ns1,*ne1,*ns2,*ne2; + FXint diff=0,c1=0,c2=0,d; + for(d=s; d && *s1; d-=(*s1++=='\t')){} + for(d=s; d && *s2; d-=(*s2++=='\t')){} + while((c1=(FXuchar)*s1)>=' ' && (c2=(FXuchar)*s2)>=' '){ + + // Both are numbers: special treatment + if(c1<='9' && c2<='9' && '0'<=c1 && '0'<=c2){ + + // Parse over leading zeroes + for(ns1=s1; *ns1=='0'; ++ns1){ } + for(ns2=s2; *ns2=='0'; ++ns2){ } + + // Use number of leading zeroes as tie-breaker + if(diff==0){ diff=(ns1-s1)-(ns2-s2); } + + // Parse over numbers + for(ne1=ns1; '0'<=*ne1 && *ne1<='9'; ++ne1){ } + for(ne2=ns2; '0'<=*ne2 && *ne2<='9'; ++ne2){ } + + // Check length difference of the numbers + if((d=(ne1-ns1)-(ne2-ns2))!=0){ return d; } + + // Compare the numbers + while(ns1(b)->isDirectory() - static_cast(a)->isDirectory(); if(diff==0){ - diff=compareSection(a->label.text(),b->label.text(),0); + diff=compareSectionNatural(a->label.text(),b->label.text(),0,false); } return diff; } @@ -310,7 +371,7 @@ FXint FXFileList::ascending(const FXIconItem* a,const FXIconItem* b){ FXint FXFileList::descending(const FXIconItem* a,const FXIconItem* b){ FXint diff=static_cast(b)->isDirectory() - static_cast(a)->isDirectory(); if(diff==0){ - diff=compareSection(b->label.text(),a->label.text(),0); + diff=compareSectionNatural(b->label.text(),a->label.text(),0,false); } return diff; } @@ -320,7 +381,7 @@ FXint FXFileList::descending(const FXIconItem* a,const FXIconItem* b){ FXint FXFileList::ascendingCase(const FXIconItem* a,const FXIconItem* b){ FXint diff=static_cast(b)->isDirectory() - static_cast(a)->isDirectory(); if(diff==0){ - diff=compareSectionCase(a->label.text(),b->label.text(),0); + diff=compareSectionNatural(a->label.text(),b->label.text(),0,true); } return diff; } @@ -330,7 +391,7 @@ FXint FXFileList::ascendingCase(const FXIconItem* a,const FXIconItem* b){ FXint FXFileList::descendingCase(const FXIconItem* a,const FXIconItem* b){ FXint diff=static_cast(b)->isDirectory() - static_cast(a)->isDirectory(); if(diff==0){ - diff=compareSectionCase(b->label.text(),a->label.text(),0); + diff=compareSectionNatural(b->label.text(),a->label.text(),0,true); } return diff; } @@ -390,7 +451,7 @@ FXint FXFileList::descendingSize(const FXIconItem* a,const FXIconItem* b){ // Compare file time FXint FXFileList::ascendingTime(const FXIconItem* a,const FXIconItem* b){ - FXint diff=(FXint)((FXFileItem*)b)->isDirectory() - (FXint)((FXFileItem*)a)->isDirectory(); + FXint diff=(FXint)((const FXFileItem*)b)->isDirectory() - (FXint)((const FXFileItem*)a)->isDirectory(); if(diff==0){ diff=FXSGNZ(static_cast(a)->date - static_cast(b)->date); if(diff==0){ @@ -403,7 +464,7 @@ FXint FXFileList::ascendingTime(const FXIconItem* a,const FXIconItem* b){ // Reversed compare file time FXint FXFileList::descendingTime(const FXIconItem* a,const FXIconItem* b){ - FXint diff=(FXint)((FXFileItem*)b)->isDirectory() - (FXint)((FXFileItem*)a)->isDirectory(); + FXint diff=(FXint)((const FXFileItem*)b)->isDirectory() - (FXint)((const FXFileItem*)a)->isDirectory(); if(diff==0){ diff=FXSGNZ(static_cast(b)->date - static_cast(a)->date); if(diff==0){ @@ -467,11 +528,23 @@ FXint FXFileList::descendingGroup(const FXIconItem* a,const FXIconItem* b){ /*******************************************************************************/ +// Select files matching wildcard pattern +FXbool FXFileList::selectMatching(const FXString& ptrn,FXuint mode,FXbool notify){ + FXbool changes=false; + for(FXint i=0; ihandle(this,FXSEL(SEL_COMMAND,ID_ENABLE),nullptr); return 1; } @@ -1297,8 +1370,8 @@ static FXbool fileequal(const FXchar* p1,const FXchar* p2){ c1=*p1++; c2=*p2++; } - while(c1==c2 && c1!='\0' && c1!='\t'); - return (c1=='\0' || c1=='\t') && (c2=='\0' || c2=='\t'); + while((c1==c2) && ('\t'size,modtm.text(),usrid.text(),grpid.text(),attrs.text(),lnknm.text()); + label.format("%s\t%s\t%'lld\t%s\t%s\t%s\t%s\t%s",name.text(),extension.text(),newitem->size,modtm.text(),usrid.text(),grpid.text(),attrs.text(),lnknm.text()); // New label newitem->setText(label); @@ -1658,6 +1731,7 @@ void FXFileList::setPattern(const FXString& ptrn,FXbool notify){ } } + // Change file match mode void FXFileList::setMatchMode(FXuint mode,FXbool notify){ if(matchmode!=mode){ diff --git a/lib/FXFileSelector.cpp b/lib/FXFileSelector.cpp index 2914031..b654557 100644 --- a/lib/FXFileSelector.cpp +++ b/lib/FXFileSelector.cpp @@ -320,128 +320,86 @@ FXFileSelector::FXFileSelector(FXComposite *p,FXObject* tgt,FXSelector sel,FXuin } +// Create server-side resources +void FXFileSelector::create(){ + FXPacker::create(); + if(selectmode==SELECTFILE_ANY){ + filename->setFocus(); + filename->selectAll(); + } + } + + // Count number of files in encoded list of filenames FXint FXFileSelector::countFilenames(const FXString& string){ - FXint result=0; - FXint p=0; - while(p' '){ - if(string[p]=='\''){ + FXint result=0,p=0; + do{ + while(string[p]){ + if(string[p]==','){ + if(string[p+1]!=',') break; p++; - while(p=string.length()) goto x; - p++; - } - else{ - while(p' '){ - p++; - } } - result++; - continue; + p++; } - p++; + result++; } -x:return result; + while(string[p++]==','); + return result; } -// Decode the n-th filename from string containing multiple, possibly quoted, -// filenames surrounded by whitespace. -// Return the empty string if n exceeds the number of filenames present, or if -// unmatching quotes are encountered. +// Decode the n-th filename from string containing multiple filenames +// Return the empty string if n exceeds the number of filenames present FXString FXFileSelector::decodeFilename(const FXString& string,FXint n){ FXString result; - FXint p=0; - while(p=string.length()) goto x; // Bail if missing quote! - p++; // Skip trailing quote + FXint p=0,pp,q; + do{ + pp=p; + q=0; + while(string[p]){ + if(string[p]==','){ + if(string[p+1]!=',') break; + p++; } - - // Parse over normal file - else{ - while(p' '){ + p++; + q++; + } + if(--n<0){ + result.length(q); + p=pp; + q=0; + while(string[p]){ + if(string[p]==','){ + if(string[p+1]!=',') break; p++; - q++; } + result[q++]=string[p++]; } - - // Found n-th filename encoding; decode it - if(--n<0){ - result.length(q); - p=pp; - q=0; - - // Parse and decode file - if(string[p]=='\''){ - p++; // Skip opening quote - while(p' '){ - result[q++]=string[p++]; - } - } - - // Check for fit - FXASSERT(q<=result.length()); - break; - } - continue; + FXASSERT(q<=result.length()); + break; } - p++; } -x:return result; + while(string[p++]==','); + return result; } -// Enquote filename if it contains spaces, control characters; also force -// quoting if "'" or "\" appear, and escape them as "\'" and "\\". -// Leave normal filenames consisting of uninterrupted sequence of printable -// characters unchanged. +// Encode a filename +// Filenames that contain a ',' will replace it with ',,'. FXString FXFileSelector::encodeFilename(const FXString& string){ - FXint p,q,e; - FXuchar c; FXString result; - p=q=e=0; - while(pgetNumItems(); i++){ - if(filebox->isItemSelected(i) && !filebox->isItemDirectory(i)){ - if(!text.empty()) text+=' '; + for(FXint i=0; igetNumItems(); i++){ + if(!filebox->isItemDirectory(i) && filebox->isItemSelected(i)){ + if(!text.empty()) text+=','; text+=encodeFilename(filebox->getItemFilename(i)); } } filename->setText(text); } else if(selectmode==SELECTFILE_MULTIPLE_ALL){ - for(i=0; igetNumItems(); i++){ - if(filebox->isItemSelected(i) && !filebox->isItemNavigational(i)){ - if(!text.empty()) text+=' '; + for(FXint i=0; igetNumItems(); i++){ + if(!filebox->isItemNavigational(i) && filebox->isItemSelected(i)){ + if(!text.empty()) text+=','; text+=encodeFilename(filebox->getItemFilename(i)); } } @@ -488,21 +445,20 @@ long FXFileSelector::onCmdItemSelected(FXObject*,FXSelector,void* ptr){ // Change in items which are selected long FXFileSelector::onCmdItemDeselected(FXObject*,FXSelector,void*){ - FXint i; FXString text; if(selectmode==SELECTFILE_MULTIPLE){ - for(i=0; igetNumItems(); i++){ - if(filebox->isItemSelected(i) && !filebox->isItemDirectory(i)){ - if(!text.empty()) text+=' '; + for(FXint i=0; igetNumItems(); i++){ + if(!filebox->isItemDirectory(i) && filebox->isItemSelected(i)){ + if(!text.empty()) text+=','; text+=encodeFilename(filebox->getItemFilename(i)); } } filename->setText(text); } else if(selectmode==SELECTFILE_MULTIPLE_ALL){ - for(i=0; igetNumItems(); i++){ - if(filebox->isItemSelected(i) && !filebox->isItemNavigational(i)){ - if(!text.empty()) text+=' '; + for(FXint i=0; igetNumItems(); i++){ + if(!filebox->isItemNavigational(i) && filebox->isItemSelected(i)){ + if(!text.empty()) text+=','; text+=encodeFilename(filebox->getItemFilename(i)); } } @@ -517,8 +473,8 @@ long FXFileSelector::onCmdItemDeselected(FXObject*,FXSelector,void*){ // Double-clicked item in file list long FXFileSelector::onCmdItemDblClicked(FXObject*,FXSelector,void* ptr){ - FXSelector sel=accept->getSelector(); FXObject *tgt=accept->getTarget(); + FXSelector sel=accept->getSelector(); FXint index=(FXint)(FXival)ptr; if(0<=index){ @@ -539,8 +495,8 @@ long FXFileSelector::onCmdItemDblClicked(FXObject*,FXSelector,void* ptr){ // Hit the accept button or enter in text field long FXFileSelector::onCmdAccept(FXObject*,FXSelector,void*){ - FXSelector sel=accept->getSelector(); FXObject *tgt=accept->getTarget(); + FXSelector sel=accept->getSelector(); // Get (first) filename or directory FXString path=getFilename(); @@ -625,7 +581,7 @@ long FXFileSelector::onCmdAccept(FXObject*,FXSelector,void*){ // and select the directory we just came from in that directory; this allows // a quick jump back into the original directory in case we went up too far. long FXFileSelector::onCmdDirectoryUp(FXObject*,FXSelector,void*){ - if(!FXPath::isTopDirectory(getDirectory()) && allowNavigation()){ + if(allowNavigation() && !FXPath::isTopDirectory(getDirectory())){ FXString dir(getDirectory()); setDirectory(FXPath::upLevel(dir)); filebox->setCurrentFile(dir); @@ -864,7 +820,6 @@ long FXFileSelector::onCmdRemove(FXObject*,FXSelector,void*){ return 1; } -// FIXME maybe should sensitize based on text, not items // Sensitize when files are selected long FXFileSelector::onUpdSelected(FXObject* sender,FXSelector,void*){ @@ -1074,19 +1029,24 @@ void FXFileSelector::setFilename(const FXString& path){ FXString name(FXPath::name(fullname)); filebox->setCurrentFile(fullname); dirbox->setDirectory(filebox->getDirectory()); - filename->setText(name); + if(selectmode==SELECTFILE_MULTIPLE_ALL || selectmode==SELECTFILE_MULTIPLE){ + filename->setText(encodeFilename(name)); + } + else{ + filename->setText(name); + } } // Get complete path + filename FXString FXFileSelector::getFilename() const { - FXString file=filename->getText(); - if(!file.empty()){ + FXString name=filename->getText(); + if(!name.empty()){ if(selectmode==SELECTFILE_MULTIPLE_ALL || selectmode==SELECTFILE_MULTIPLE){ - return FXPath::absolute(getDirectory(),decodeFilename(file)); + return FXPath::absolute(getDirectory(),decodeFilename(name)); } else{ - return FXPath::absolute(getDirectory(),file); + return FXPath::absolute(getDirectory(),name); } } return FXString::null; @@ -1095,22 +1055,22 @@ FXString FXFileSelector::getFilename() const { // Return empty-string terminated list of selected file names, or NULL FXString* FXFileSelector::getFilenames() const { - FXString file=filename->getText(); + FXString names=filename->getText(); FXString *filelist=nullptr; - if(!file.empty()){ + if(!names.empty()){ if(selectmode==SELECTFILE_MULTIPLE || selectmode==SELECTFILE_MULTIPLE_ALL){ - FXint n=countFilenames(file); + FXint n=countFilenames(names); if(n){ filelist=new FXString [n+1]; for(FXint i=0; igetCheck(); + return readonly->getCheck()==true; + } + + +// Allow or disallow navigation +void FXFileSelector::allowNavigation(FXbool flag){ + filebox->showParents(flag,true); + navigable=flag; } @@ -1347,10 +1314,12 @@ FXString FXFileSelector::getTimeFormat() const { } -// Change file associations +// Change file associations. +// Share associations between filebox and dirbox widgets. +// Optionally, share associations between other parts of the application as well. void FXFileSelector::setAssociations(FXFileAssociations* assoc,FXbool owned){ filebox->setAssociations(assoc,owned); - dirbox->setAssociations(assoc,false); // Shared file associations + dirbox->setAssociations(assoc,false); } diff --git a/lib/FXFoldingList.cpp b/lib/FXFoldingList.cpp index e7ca41e..ca588dd 100644 --- a/lib/FXFoldingList.cpp +++ b/lib/FXFoldingList.cpp @@ -295,7 +295,7 @@ FXint FXFoldingItem::getNumChildren() const { // Get item (logically) below this one FXFoldingItem* FXFoldingItem::getBelow() const { - FXFoldingItem* item=(FXFoldingItem*)this; + FXFoldingItem* item=const_cast(this); if(first) return first; while(!item->next && item->parent) item=item->parent; return item->next; @@ -1992,7 +1992,9 @@ FXint FXFoldingList::compareSection(const FXchar *p,const FXchar* q,FXint s){ c1=(FXuchar) *p++; c2=(FXuchar) *q++; } - while('\t'getText(),text,len)==0) return item; + if((*comparefunc)(item->getText().text(),string.text(),len)==0) return item; item=item->getAbove(); } if(start && !(flgs&SEARCH_WRAP)) return nullptr; for(item=lastitem; item->getLast(); item=item->getLast()){} while(item!=start){ - if((*comparefunc)(item->getText(),text,len)==0) return item; + if((*comparefunc)(item->getText().text(),string.text(),len)==0) return item; item=item->getAbove(); } } else{ item=start; while(item!=nullptr){ - if((*comparefunc)(item->getText(),text,len)==0) return item; + if((*comparefunc)(item->getText().text(),string.text(),len)==0) return item; item=item->getBelow(); } if(start && !(flgs&SEARCH_WRAP)) return nullptr; item=firstitem; while(item!=start){ - if((*comparefunc)(item->getText(),text,len)==0) return item; + if((*comparefunc)(item->getText().text(),string.text(),len)==0) return item; item=item->getBelow(); } } diff --git a/lib/FXFont.cpp b/lib/FXFont.cpp index 5b86219..51e8b96 100644 --- a/lib/FXFont.cpp +++ b/lib/FXFont.cpp @@ -21,6 +21,7 @@ #include "xincs.h" #include "fxver.h" #include "fxdefs.h" +#include "fxchar.h" #include "fxmath.h" #include "fxascii.h" #include "FXArray.h" @@ -414,9 +415,7 @@ void* FXFont::match(const FXString& wantfamily,const FXString& wantforge,FXuint FXbool fc_autohint=getApp()->reg().readBoolEntry("Xft","autohint",false); FXbool fc_antialias=getApp()->reg().readBoolEntry("Xft","antialias",true); FXint fc_rgba=FC_RGBA_UNKNOWN; -#ifdef FC_HINT_STYLE FXint fc_hintstyle=FC_HINT_FULL; -#endif int pp,sw,wt,sl; double a,s,c,sz; FcPattern *pattern,*p; @@ -438,21 +437,19 @@ void* FXFont::match(const FXString& wantfamily,const FXString& wantforge,FXuint else if(rgba[0]=='b') fc_rgba=FC_RGBA_BGR; else if(rgba[0]=='v' && rgba[1]=='r') fc_rgba=FC_RGBA_VRGB; else if(rgba[0]=='v' && rgba[1]=='b') fc_rgba=FC_RGBA_VBGR; + else if(rgba[0]=='n') fc_rgba=FC_RGBA_NONE; -#ifdef FC_HINT_STYLE if(hs[0]=='s') fc_hintstyle=FC_HINT_SLIGHT; - else if(hs[0]=='m') fc_hintstyle=FC_HINT_SLIGHT; + else if(hs[0]=='m') fc_hintstyle=FC_HINT_MEDIUM; else if(hs[0]=='f') fc_hintstyle=FC_HINT_FULL; -#endif + else if(hs[0]=='n') fc_hintstyle=FC_HINT_NONE; // Set additional hints FcPatternAddBool(pattern,FC_HINTING,fc_hinting); FcPatternAddBool(pattern,FC_ANTIALIAS,fc_antialias); FcPatternAddBool(pattern,FC_AUTOHINT,fc_autohint); FcPatternAddInteger(pattern,FC_RGBA,fc_rgba); -#ifdef FC_HINT_STYLE FcPatternAddInteger(pattern,FC_HINT_STYLE,fc_hintstyle); -#endif // Set family if(!wantfamily.empty()){ @@ -2665,7 +2662,7 @@ static FXString findbyvalue(const ENTRY* table,FXint n,FXuint value){ // Search for name and return value static FXuint findbyname(const ENTRY* table,FXint n,const FXString& name){ - for(int i=0; iappendItem(fonts[f].face,nullptr,(void*)(FXuval)fonts[f].flags); - if(compare(selected.face,fonts[f].face)==0) selindex=f; + if(FXString::compare(selected.face,fonts[f].face)==0) selindex=f; } if(selindex==-1) selindex=0; if(0getNumItems()){ diff --git a/lib/FXGIFCursor.cpp b/lib/FXGIFCursor.cpp index 37aa122..ba6d018 100644 --- a/lib/FXGIFCursor.cpp +++ b/lib/FXGIFCursor.cpp @@ -67,9 +67,9 @@ FXIMPLEMENT(FXGIFCursor,FXCursor,nullptr,0) // Constructor -FXGIFCursor::FXGIFCursor(FXApp* a,const void *pix,FXint hx,FXint hy):FXCursor(a,nullptr,0,0,0,0){ +FXGIFCursor::FXGIFCursor(FXApp* a,const FXuchar *pix,FXint hx,FXint hy):FXCursor(a,nullptr,0,0,0,0){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); fxloadGIF(ms,data,width,height,true); hotx=FXCLAMP(0,hx,width-1); hoty=FXCLAMP(0,hy,height-1); diff --git a/lib/FXGIFIcon.cpp b/lib/FXGIFIcon.cpp index 614e318..d9e56aa 100644 --- a/lib/FXGIFIcon.cpp +++ b/lib/FXGIFIcon.cpp @@ -68,9 +68,9 @@ FXIMPLEMENT(FXGIFIcon,FXIcon,nullptr,0) // Initialize nicely -FXGIFIcon::FXGIFIcon(FXApp* a,const void *pix,FXColor clr,FXuint opts,FXint w,FXint h):FXIcon(a,nullptr,clr,opts,w,h){ +FXGIFIcon::FXGIFIcon(FXApp* a,const FXuchar *pix,FXColor clr,FXuint opts,FXint w,FXint h):FXIcon(a,nullptr,clr,opts,w,h){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXGIFImage.cpp b/lib/FXGIFImage.cpp index aa2a1f1..b9efffe 100644 --- a/lib/FXGIFImage.cpp +++ b/lib/FXGIFImage.cpp @@ -67,9 +67,9 @@ FXIMPLEMENT(FXGIFImage,FXImage,nullptr,0) // Initialize -FXGIFImage::FXGIFImage(FXApp* a,const void *pix,FXuint opts,FXint w,FXint h):FXImage(a,nullptr,opts,w,h){ +FXGIFImage::FXGIFImage(FXApp* a,const FXuchar *pix,FXuint opts,FXint w,FXint h):FXImage(a,nullptr,opts,w,h){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXHash.cpp b/lib/FXHash.cpp index 7f2ed99..230c13f 100644 --- a/lib/FXHash.cpp +++ b/lib/FXHash.cpp @@ -76,9 +76,9 @@ will not cause a table resize (except when the table is near empty, of course). */ -#define EMPTY ((Entry*)(__hash__empty__+3)) +#define EMPTY (const_cast((const Entry*)(__hash__empty__+3))) #define HASH(x) ((FXival)(x)^(((FXival)(x))>>13)) -#define VOID ((FXptr)-1L) +#define VOID ((const void*)-1L) #define LEGAL(p) ((p)!=nullptr && (p)!=VOID) #define BSHIFT 5 @@ -95,21 +95,6 @@ extern const FXival __hash__empty__[]; const FXival __hash__empty__[7]={1,0,1,0,0}; -// Make empty table -FXHash::FXHash():table(EMPTY){ - } - - -// Construct from another table -FXHash::FXHash(const FXHash& other):table(EMPTY){ - if(__likely(10); // At least one free slot if(elbat.no(n)){ if(1>=BSHIFT; } - elbat.table[x].key=key; - elbat.table[x].data=data; + elbat.table[x].key=ky; + elbat.table[x].data=da; } } elbat.free(n-used()); // All non-empty slots now free @@ -172,6 +158,25 @@ FXbool FXHash::resize(FXival n){ } +// Make empty table +FXHash::FXHash():table(EMPTY){ + FXASSERT_STATIC(sizeof(FXHash)==sizeof(void*)); + FXASSERT_STATIC(sizeof(Entry)<=sizeof(FXival)*2); + } + + +// Construct from another table +FXHash::FXHash(const FXHash& other):table(EMPTY){ + FXASSERT_STATIC(sizeof(FXHash)==sizeof(void*)); + FXASSERT_STATIC(sizeof(Entry)<=sizeof(FXival)*2); + if(__likely(1>=BSHIFT; @@ -209,19 +214,19 @@ FXival FXHash::find(FXptr ky) const { // Return reference to slot assocated with given key -FXptr& FXHash::at(FXptr ky){ +void*& FXHash::at(const void* ky){ if(__likely(LEGAL(ky))){ FXuval p,b,h,x; p=b=h=HASH(ky); while(table[x=p&(no()-1)].key){ - if(table[x].key==ky) goto x; // Replace existing slot + if(__likely(table[x].key==ky)) goto x; // Replace existing slot p=(p<<2)+p+b+1; b>>=BSHIFT; } if(__unlikely(free()<=1+(no()>>2)) && __unlikely(!resize(no()<<1))){ throw FXMemoryException("FXHash::at: out of memory\n"); } p=b=h; while(table[x=p&(no()-1)].key){ - if(table[x].key==VOID) goto y; // Put into voided slot + if(__likely(table[x].key==VOID)) goto y; // Put into voided slot p=(p<<2)+p+b+1; b>>=BSHIFT; } @@ -230,17 +235,17 @@ y: used(used()+1); table[x].key=ky; x: return table[x].data; } - return *((FXptr*)nullptr); // Can NOT be referenced; will generate segfault! + return *((void**)nullptr); // Can NOT be referenced; will generate segfault! } // Return constant reference to slot assocated with given key -const FXptr& FXHash::at(FXptr ky) const { +void *const& FXHash::at(const void* ky) const { if(__likely(LEGAL(ky))){ FXuval p,b,x; p=b=HASH(ky); while(table[x=p&(no()-1)].key){ - if(table[x].key==ky) return table[x].data; // Return existing slot + if(__likely(table[x].key==ky)) return table[x].data; // Return existing slot p=(p<<2)+p+b+1; b>>=BSHIFT; } @@ -250,33 +255,33 @@ const FXptr& FXHash::at(FXptr ky) const { // Remove association from the table -FXptr FXHash::remove(FXptr ky){ - FXptr old=nullptr; +void* FXHash::remove(const void* ky){ + void* old=nullptr; if(__likely(LEGAL(ky))){ FXuval p,b,x; p=b=HASH(ky); while(table[x=p&(no()-1)].key!=ky){ - if(table[x].key==nullptr) return nullptr; + if(table[x].key==nullptr) goto x; p=(p<<2)+p+b+1; b>>=BSHIFT; } old=table[x].data; - table[x].key=VOID; // Void the slot (not empty!) + table[x].key=VOID; // Void the slot (not empty!) table[x].data=nullptr; used(used()-1); if(__unlikely(used()<=(no()>>2))) resize(no()>>1); } - return old; +x:return old; } // Erase data at pos in the table, returning old pointer -FXptr FXHash::erase(FXival pos){ - FXptr old=nullptr; +void* FXHash::erase(FXival pos){ + void* old=nullptr; if(__unlikely(pos<0 || no()<=pos)){ throw FXRangeException("FXHash::erase: argument out of range\n"); } if(__likely(LEGAL(table[pos].key))){ old=table[pos].data; - table[pos].key=VOID; // Void the slot (not empty!) + table[pos].key=VOID; // Void the slot (not empty!) table[pos].data=nullptr; used(used()-1); if(__unlikely(used()<=(no()>>2))) resize(no()>>1); @@ -286,8 +291,8 @@ FXptr FXHash::erase(FXival pos){ // Clear hash table, marking all slots as free -void FXHash::clear(){ - no(1); +FXbool FXHash::clear(){ + return no(1); } diff --git a/lib/FXHorizontalFrame.cpp b/lib/FXHorizontalFrame.cpp index 67bf260..d711648 100644 --- a/lib/FXHorizontalFrame.cpp +++ b/lib/FXHorizontalFrame.cpp @@ -47,7 +47,6 @@ - Tabbing order takes widget layout into account */ - using namespace FX; /*******************************************************************************/ @@ -83,7 +82,7 @@ FXint FXHorizontalFrame::getDefaultWidth(){ if(hints&LAYOUT_FIX_WIDTH) w=child->getWidth(); else if(options&PACK_UNIFORM_WIDTH) w=mw; else w=child->getDefaultWidth(); - if((hints&LAYOUT_RIGHT)&&(hints&LAYOUT_CENTER_X)){ // LAYOUT_FIX_X + if((hints&LAYOUT_RIGHT)&&(hints&LAYOUT_CENTER_X)){ w=child->getX()+w; if(w>wmax) wmax=w; } @@ -111,7 +110,7 @@ FXint FXHorizontalFrame::getDefaultHeight(){ if(hints&LAYOUT_FIX_HEIGHT) h=child->getHeight(); else if(options&PACK_UNIFORM_HEIGHT) h=mh; else h=child->getDefaultHeight(); - if((hints&LAYOUT_BOTTOM)&&(hints&LAYOUT_CENTER_Y)){ // LAYOUT_FIX_Y + if((hints&LAYOUT_BOTTOM)&&(hints&LAYOUT_CENTER_Y)){ h=child->getY()+h; if(h>hmax) hmax=h; } @@ -151,7 +150,7 @@ void FXHorizontalFrame::layout(){ for(child=getFirst(); child; child=child->getNext()){ if(child->shown()){ hints=child->getLayoutHints(); - if(!((hints&LAYOUT_RIGHT)&&(hints&LAYOUT_CENTER_X))){ // LAYOUT_FIX_X + if(!((hints&LAYOUT_RIGHT)&&(hints&LAYOUT_CENTER_X))){ if(hints&LAYOUT_FIX_WIDTH) w=child->getWidth(); else if(options&PACK_UNIFORM_WIDTH) w=mw; else w=child->getDefaultWidth(); @@ -193,7 +192,7 @@ void FXHorizontalFrame::layout(){ if(hints&LAYOUT_FIX_WIDTH) w=child->getWidth(); else if(options&PACK_UNIFORM_WIDTH) w=mw; else w=child->getDefaultWidth(); - if(!((hints&LAYOUT_RIGHT)&&(hints&LAYOUT_CENTER_X))){ // LAYOUT_FIX_X + if(!((hints&LAYOUT_RIGHT)&&(hints&LAYOUT_CENTER_X))){ extra_space=0; total_space=0; if((hints&LAYOUT_FILL_X) && !(hints&LAYOUT_FIX_WIDTH)){ diff --git a/lib/FXICOIcon.cpp b/lib/FXICOIcon.cpp index de6b7fb..a4c6683 100644 --- a/lib/FXICOIcon.cpp +++ b/lib/FXICOIcon.cpp @@ -64,9 +64,9 @@ FXIMPLEMENT(FXICOIcon,FXIcon,nullptr,0) // Initialize nicely -FXICOIcon::FXICOIcon(FXApp* a,const void *pix,FXColor clr,FXuint opts,FXint w,FXint h):FXIcon(a,nullptr,clr,opts,w,h){ +FXICOIcon::FXICOIcon(FXApp* a,const FXuchar *pix,FXColor clr,FXuint opts,FXint w,FXint h):FXIcon(a,nullptr,clr,opts,w,h){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXICOImage.cpp b/lib/FXICOImage.cpp index 0682a25..8b9dcd9 100644 --- a/lib/FXICOImage.cpp +++ b/lib/FXICOImage.cpp @@ -65,9 +65,9 @@ FXIMPLEMENT(FXICOImage,FXImage,nullptr,0) // Initialize -FXICOImage::FXICOImage(FXApp* a,const void *pix,FXuint opts,FXint w,FXint h):FXImage(a,nullptr,opts,w,h){ +FXICOImage::FXICOImage(FXApp* a,const FXuchar *pix,FXuint opts,FXint w,FXint h):FXImage(a,nullptr,opts,w,h){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXIFFIcon.cpp b/lib/FXIFFIcon.cpp index c774ba2..f32a6fb 100644 --- a/lib/FXIFFIcon.cpp +++ b/lib/FXIFFIcon.cpp @@ -64,9 +64,9 @@ FXIMPLEMENT(FXIFFIcon,FXIcon,nullptr,0) // Initialize nicely -FXIFFIcon::FXIFFIcon(FXApp* a,const void *pix,FXColor clr,FXuint opts,FXint w,FXint h):FXIcon(a,nullptr,clr,opts,w,h){ +FXIFFIcon::FXIFFIcon(FXApp* a,const FXuchar *pix,FXColor clr,FXuint opts,FXint w,FXint h):FXIcon(a,nullptr,clr,opts,w,h){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXIFFImage.cpp b/lib/FXIFFImage.cpp index d943a79..41a896b 100644 --- a/lib/FXIFFImage.cpp +++ b/lib/FXIFFImage.cpp @@ -66,9 +66,9 @@ FXIMPLEMENT(FXIFFImage,FXImage,nullptr,0) // Initialize -FXIFFImage::FXIFFImage(FXApp* a,const void *pix,FXuint opts,FXint w,FXint h):FXImage(a,nullptr,opts,w,h){ +FXIFFImage::FXIFFImage(FXApp* a,const FXuchar *pix,FXuint opts,FXint w,FXint h):FXImage(a,nullptr,opts,w,h){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXIconList.cpp b/lib/FXIconList.cpp index b6e8bca..a6e250e 100644 --- a/lib/FXIconList.cpp +++ b/lib/FXIconList.cpp @@ -1134,16 +1134,16 @@ FXint FXIconList::getItemAt(FXint x,FXint y) const { // Compare strings up to n -static FXint comp(const FXString& s1,const FXString& s2,FXint n){ - const FXuchar *p1=(const FXuchar *)s1.text(); - const FXuchar *p2=(const FXuchar *)s2.text(); - FXint c1,c2; +static FXint comp(const FXchar* s1,const FXchar* s2,FXint n){ if(0getText(),text,len)==0) return index; + if((*comparefunc)(items[index]->getText().text(),string.text(),len)==0) return index; } if(!(flgs&SEARCH_WRAP)) return -1; for(index=items.no()-1; startgetText(),text,len)==0) return index; + if((*comparefunc)(items[index]->getText().text(),string.text(),len)==0) return index; } } else{ if(start<0) start=0; for(index=start; indexgetText(),text,len)==0) return index; + if((*comparefunc)(items[index]->getText().text(),string.text(),len)==0) return index; } if(!(flgs&SEARCH_WRAP)) return -1; for(index=0; indexgetText(),text,len)==0) return index; + if((*comparefunc)(items[index]->getText().text(),string.text(),len)==0) return index; } } } @@ -1916,10 +1916,12 @@ FXint FXIconList::compareSection(const FXchar *p,const FXchar* q,FXint s){ for(x=s; x && *p; x-=(*p++=='\t')){} for(x=s; x && *q; x-=(*q++=='\t')){} do{ - c1=(FXuchar) *p++; - c2=(FXuchar) *q++; + c1=*p++; + c2=*q++; } - while('\t'(pixels)); icon=loadIconStream(app,store,type); store.close(); } @@ -486,11 +486,11 @@ FXImage *FXIconSource::loadImageFile(FXApp* app,const FXString& filename,const F // Load from data array -FXImage *FXIconSource::loadImageData(FXApp* app,const void *pixels,const FXString& type) const { +FXImage *FXIconSource::loadImageData(FXApp* app,const FXuchar *pixels,const FXString& type) const { FXImage *image=nullptr; if(pixels){ FXMemoryStream store; - store.open(FXStreamLoad,(FXuchar*)pixels); + store.open(FXStreamLoad,const_cast(pixels)); image=loadImageStream(app,store,type); store.close(); } @@ -522,7 +522,7 @@ FXIcon *FXIconSource::loadScaledIconFile(FXApp* app,const FXString& filename,FXi // Load from data array -FXIcon *FXIconSource::loadScaledIconData(FXApp* app,const void *pixels,FXint size,FXint qual,const FXString& type) const { +FXIcon *FXIconSource::loadScaledIconData(FXApp* app,const FXuchar *pixels,FXint size,FXint qual,const FXString& type) const { return (FXIcon*)scaleToSize(loadIconData(app,pixels,type),size,qual); } @@ -540,7 +540,7 @@ FXImage *FXIconSource::loadScaledImageFile(FXApp* app,const FXString& filename,F // Load from data array -FXImage *FXIconSource::loadScaledImageData(FXApp* app,const void *pixels,FXint size,FXint qual,const FXString& type) const { +FXImage *FXIconSource::loadScaledImageData(FXApp* app,const FXuchar *pixels,FXint size,FXint qual,const FXString& type) const { return (FXImage*)scaleToSize(loadImageData(app,pixels,type),size,qual); } diff --git a/lib/FXImage.cpp b/lib/FXImage.cpp index ca60be1..8a01c5c 100644 --- a/lib/FXImage.cpp +++ b/lib/FXImage.cpp @@ -207,7 +207,7 @@ FXImage::FXImage(FXApp* a,const FXColor *pix,FXuint opts,FXint w,FXint h):FXDraw FXTRACE((TOPIC_CONSTRUCT,"FXImage::FXImage %p\n",this)); FXASSERT((opts&~(IMAGE_OWNED|IMAGE_MASK))==0); visual=getApp()->getDefaultVisual(); - data=(FXColor*)pix; + data=const_cast(pix); options=opts; if(!data && (options&IMAGE_OWNED)){ // This is confusing use of IMAGE_OWNED if(!callocElms(data,width*height)){ throw FXMemoryException("unable to construct image"); } diff --git a/lib/FXJP2Icon.cpp b/lib/FXJP2Icon.cpp index b7d3c34..4ec1993 100644 --- a/lib/FXJP2Icon.cpp +++ b/lib/FXJP2Icon.cpp @@ -72,9 +72,9 @@ const FXbool FXJP2Icon::supported=false; // Initialize -FXJP2Icon::FXJP2Icon(FXApp* a,const void *pix,FXColor clr,FXuint opts,FXint w,FXint h,FXint q):FXIcon(a,nullptr,clr,opts,w,h),quality(q){ +FXJP2Icon::FXJP2Icon(FXApp* a,const FXuchar *pix,FXColor clr,FXuint opts,FXint w,FXint h,FXint q):FXIcon(a,nullptr,clr,opts,w,h),quality(q){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXJP2Image.cpp b/lib/FXJP2Image.cpp index 44c82ab..c7ebb3c 100644 --- a/lib/FXJP2Image.cpp +++ b/lib/FXJP2Image.cpp @@ -72,9 +72,9 @@ const FXbool FXJP2Image::supported=false; // Initialize -FXJP2Image::FXJP2Image(FXApp* a,const void *pix,FXuint opts,FXint w,FXint h,FXint q):FXImage(a,nullptr,opts,w,h),quality(q){ +FXJP2Image::FXJP2Image(FXApp* a,const FXuchar *pix,FXuint opts,FXint w,FXint h,FXint q):FXImage(a,nullptr,opts,w,h),quality(q){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXJPGIcon.cpp b/lib/FXJPGIcon.cpp index ea15465..f5b6581 100644 --- a/lib/FXJPGIcon.cpp +++ b/lib/FXJPGIcon.cpp @@ -72,9 +72,9 @@ const FXbool FXJPGIcon::supported=false; // Initialize -FXJPGIcon::FXJPGIcon(FXApp* a,const void *pix,FXColor clr,FXuint opts,FXint w,FXint h,FXint q):FXIcon(a,nullptr,clr,opts,w,h),quality(q){ +FXJPGIcon::FXJPGIcon(FXApp* a,const FXuchar *pix,FXColor clr,FXuint opts,FXint w,FXint h,FXint q):FXIcon(a,nullptr,clr,opts,w,h),quality(q){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXJPGImage.cpp b/lib/FXJPGImage.cpp index f9aa897..7ca161d 100644 --- a/lib/FXJPGImage.cpp +++ b/lib/FXJPGImage.cpp @@ -72,9 +72,9 @@ const FXbool FXJPGImage::supported=false; // Initialize -FXJPGImage::FXJPGImage(FXApp* a,const void *pix,FXuint opts,FXint w,FXint h,FXint q):FXImage(a,nullptr,opts,w,h),quality(q){ +FXJPGImage::FXJPGImage(FXApp* a,const FXuchar *pix,FXuint opts,FXint w,FXint h,FXint q):FXImage(a,nullptr,opts,w,h),quality(q){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXJSON.cpp b/lib/FXJSON.cpp index ee008a0..ca31012 100644 --- a/lib/FXJSON.cpp +++ b/lib/FXJSON.cpp @@ -21,16 +21,14 @@ #include "xincs.h" #include "fxver.h" #include "fxdefs.h" +#include "fxchar.h" #include "fxmath.h" #include "fxascii.h" #include "fxunicode.h" #include "FXElement.h" #include "FXArray.h" #include "FXString.h" -#include "FXIO.h" -#include "FXIODevice.h" -#include "FXStat.h" -#include "FXFile.h" +#include "FXParseBuffer.h" #include "FXException.h" #include "FXVariant.h" #include "FXVariantArray.h" @@ -208,17 +206,11 @@ as those character sequences are not actually equal to those few UTF8 sequences we care about! - - FIXME would be nice if we had a JSON5 mode for output; keys saved as unquoted - strings, if and only if no escape is needed. + - When saving, ver=5 forces JSON5 output mode. In this mode, keys are written w/o + quotes if possible, and strings may be written either with single quotes (') or + double quotes ("). */ -// Get wide character from utf8 -#define WC1(p) ((FXuchar)(p)[0]) -#define WC2(p) (((FXuchar)(p)[0]<<6)^((FXuchar)(p)[1])^0x3080) -#define WC3(p) (((FXuchar)(p)[0]<<12)^((FXuchar)(p)[1]<<6)^((FXuchar)(p)[2])^0x0E2080) -#define WC4(p) (((FXuchar)(p)[0]<<18)^((FXuchar)(p)[1]<<12)^((FXuchar)(p)[2]<<6)^((FXuchar)(p)[3])^0x3C82080) - - using namespace FX; /*******************************************************************************/ @@ -276,13 +268,13 @@ static const union{ FXulong u; FXdouble f; } nan={FXULONG(0x7fffffffffffffff)}; // Construct JSON serializer -FXJSON::FXJSON():begptr(nullptr),endptr(nullptr),wptr(nullptr),rptr(nullptr),sptr(nullptr),offset(0),token(TK_EOF),column(0),indent(0),line(1),dir(Stop),wrap(80),flow(Compact),prec(15),fmt(2),esc(0),dent(2){ +FXJSON::FXJSON():offset(0),token(TK_EOF),column(0),indent(0),line(1),wrap(80),quote('"'),flow(Compact),prec(16),fmt(2),esc(0),dent(2),ver(4){ FXTRACE((100,"FXJSON::FXJSON\n")); } // Construct and open for loading -FXJSON::FXJSON(FXchar* buffer,FXuval sz,Direction d):begptr(nullptr),endptr(nullptr),wptr(nullptr),rptr(nullptr),sptr(nullptr),offset(0),token(TK_EOF),column(0),indent(0),line(1),dir(Stop),wrap(80),flow(Compact),prec(16),fmt(2),esc(0),dent(2){ +FXJSON::FXJSON(FXchar* buffer,FXuval sz,Direction d):FXParseBuffer(buffer,sz,d),offset(0),token(TK_EOF),column(0),indent(0),line(1),wrap(80),quote('"'),flow(Compact),prec(16),fmt(2),esc(0),dent(2),ver(4){ FXTRACE((100,"FXJSON::FXJSON(%p,%lu,%s)\n",buffer,sz,(d==Save)?"Save":(d==Load)?"Load":"Stop")); open(buffer,sz,d); } @@ -291,20 +283,13 @@ FXJSON::FXJSON(FXchar* buffer,FXuval sz,Direction d):begptr(nullptr),endptr(null // Open JSON stream for given direction and set its buffer FXbool FXJSON::open(FXchar* buffer,FXuval sz,Direction d){ FXTRACE((101,"FXJSON::open(%p,%lu,%s)\n",buffer,sz,(d==Save)?"Save":(d==Load)?"Load":"Stop")); - FXASSERT(dir==Stop); - if((dir==Stop) && (d!=Stop) && (0wptr){ - if(wptr==endptr){ - if(fill(count)<0) return false; - } - return sptr=endptr){ - if(flush(count)<=0) return false; - } - FXASSERT(wptr=endptr){ - if(flush(count)<=0) return false; - } - FXASSERT(wptrwptr && wptr==endptr){ // Big token case 0xDF: if(sptr+1>=wptr) return TK_EOF; // Premature EOF if((sptr[1]&192)!=128) return TK_ERROR; // Non-follower - cc=Unicode::charCategory(WC2(sptr)); + cc=Unicode::charCategory(wc2(sptr)); if(ccwptr && wptr==endptr){ // Big token if(sptr+2>=wptr) return TK_EOF; // Premature EOF if((sptr[1]&192)!=128) return TK_ERROR; // Non-follower if((sptr[2]&192)!=128) return TK_ERROR; // Non-follower - cc=Unicode::charCategory(WC3(sptr)); + cc=Unicode::charCategory(wc3(sptr)); if(ccwptr && wptr==endptr){ // Big token if((sptr[1]&192)!=128) return TK_ERROR; // Non-follower if((sptr[2]&192)!=128) return TK_ERROR; if((sptr[3]&192)!=128) return TK_ERROR; - cc=Unicode::charCategory(WC4(sptr)); + cc=Unicode::charCategory(wc4(sptr)); if(cc; - // Object implementation FXIMPLEMENT(FXListItem,FXObject,nullptr,0) @@ -1463,25 +1460,25 @@ long FXList::onTripleClicked(FXObject*,FXSelector,void* ptr){ // Sort items in ascending order FXint FXList::ascending(const FXListItem* a,const FXListItem* b){ - return compare(a->getText(),b->getText()); + return FXString::compare(a->getText(),b->getText()); } // Sort items in descending order FXint FXList::descending(const FXListItem* a,const FXListItem* b){ - return compare(b->getText(),a->getText()); + return FXString::compare(b->getText(),a->getText()); } // Sort ascending order, case insensitive FXint FXList::ascendingCase(const FXListItem* a,const FXListItem* b){ - return comparecase(a->getText(),b->getText()); + return FXString::comparecase(a->getText(),b->getText()); } // Sort descending order, case insensitive FXint FXList::descendingCase(const FXListItem* a,const FXListItem* b){ - return comparecase(b->getText(),a->getText()); + return FXString::comparecase(b->getText(),a->getText()); } @@ -1898,33 +1895,33 @@ void FXList::clearItems(FXbool notify){ } -typedef FXint (*FXCompareFunc)(const FXString&,const FXString&,FXint); +typedef FXint (*FXCompareFunc)(const FXchar*,const FXchar*,FXint); // Get item by name FXint FXList::findItem(const FXString& string,FXint start,FXuint flgs) const { - FXCompareFunc comparefunc=(flgs&SEARCH_IGNORECASE) ? (FXCompareFunc)comparecase : (FXCompareFunc)compare; + FXCompareFunc comparefunc=(flgs&SEARCH_IGNORECASE) ? (FXCompareFunc)FXString::comparecase : (FXCompareFunc)FXString::compare; FXint index,len; if(0getText(),string,len)==0) return index; + if((*comparefunc)(items[index]->getText().text(),string.text(),len)==0) return index; } if(!(flgs&SEARCH_WRAP)) return -1; for(index=items.no()-1; startgetText(),string,len)==0) return index; + if((*comparefunc)(items[index]->getText().text(),string.text(),len)==0) return index; } } else{ if(start<0) start=0; for(index=start; indexgetText(),string,len)==0) return index; + if((*comparefunc)(items[index]->getText().text(),string.text(),len)==0) return index; } if(!(flgs&SEARCH_WRAP)) return -1; for(index=0; indexgetText(),string,len)==0) return index; + if((*comparefunc)(items[index]->getText().text(),string.text(),len)==0) return index; } } } diff --git a/lib/FXListBox.cpp b/lib/FXListBox.cpp index 73a41cb..9518e14 100644 --- a/lib/FXListBox.cpp +++ b/lib/FXListBox.cpp @@ -516,8 +516,8 @@ void FXListBox::clearItems(FXbool notify){ // Get item by name -FXint FXListBox::findItem(const FXString& text,FXint start,FXuint flgs) const { - return list->findItem(text,start,flgs); +FXint FXListBox::findItem(const FXString& string,FXint start,FXuint flgs) const { + return list->findItem(string,start,flgs); } diff --git a/lib/FXMainWindow.cpp b/lib/FXMainWindow.cpp index 777449b..6b88338 100644 --- a/lib/FXMainWindow.cpp +++ b/lib/FXMainWindow.cpp @@ -76,7 +76,7 @@ void FXMainWindow::create(){ if(getApp()->isInitialized()){ #ifndef WIN32 // Set the WM_COMMAND hint on non-owned toplevel windows - XSetCommand(DISPLAY(getApp()),xid,(char**)getApp()->getArgv(),getApp()->getArgc()); + XSetCommand(DISPLAY(getApp()),xid,const_cast((const char *const *)getApp()->getArgv()),getApp()->getArgc()); #endif } } diff --git a/lib/FXMenuButton.cpp b/lib/FXMenuButton.cpp index 64516c1..e90a6b5 100644 --- a/lib/FXMenuButton.cpp +++ b/lib/FXMenuButton.cpp @@ -21,6 +21,7 @@ #include "xincs.h" #include "fxver.h" #include "fxdefs.h" +#include "fxchar.h" #include "fxkeys.h" #include "fxmath.h" #include "FXArray.h" diff --git a/lib/FXMenuCaption.cpp b/lib/FXMenuCaption.cpp index e14f7ee..f11ad08 100644 --- a/lib/FXMenuCaption.cpp +++ b/lib/FXMenuCaption.cpp @@ -21,6 +21,7 @@ #include "xincs.h" #include "fxver.h" #include "fxdefs.h" +#include "fxchar.h" #include "fxmath.h" #include "fxkeys.h" #include "FXArray.h" diff --git a/lib/FXMenuCascade.cpp b/lib/FXMenuCascade.cpp index 8623fa4..0d9e0db 100644 --- a/lib/FXMenuCascade.cpp +++ b/lib/FXMenuCascade.cpp @@ -21,6 +21,7 @@ #include "xincs.h" #include "fxver.h" #include "fxdefs.h" +#include "fxchar.h" #include "fxmath.h" #include "fxkeys.h" #include "FXArray.h" diff --git a/lib/FXMenuCheck.cpp b/lib/FXMenuCheck.cpp index c070161..b7c641e 100644 --- a/lib/FXMenuCheck.cpp +++ b/lib/FXMenuCheck.cpp @@ -21,6 +21,7 @@ #include "xincs.h" #include "fxver.h" #include "fxdefs.h" +#include "fxchar.h" #include "fxmath.h" #include "fxkeys.h" #include "FXArray.h" diff --git a/lib/FXMenuCommand.cpp b/lib/FXMenuCommand.cpp index d1cee65..2ba9edd 100644 --- a/lib/FXMenuCommand.cpp +++ b/lib/FXMenuCommand.cpp @@ -21,6 +21,7 @@ #include "xincs.h" #include "fxver.h" #include "fxdefs.h" +#include "fxchar.h" #include "fxmath.h" #include "fxkeys.h" #include "FXArray.h" diff --git a/lib/FXMenuRadio.cpp b/lib/FXMenuRadio.cpp index 262355a..5f03174 100644 --- a/lib/FXMenuRadio.cpp +++ b/lib/FXMenuRadio.cpp @@ -21,6 +21,7 @@ #include "xincs.h" #include "fxver.h" #include "fxdefs.h" +#include "fxchar.h" #include "fxmath.h" #include "fxkeys.h" #include "FXArray.h" diff --git a/lib/FXMenuTitle.cpp b/lib/FXMenuTitle.cpp index 4fe2c45..2a44537 100644 --- a/lib/FXMenuTitle.cpp +++ b/lib/FXMenuTitle.cpp @@ -21,6 +21,7 @@ #include "xincs.h" #include "fxver.h" #include "fxdefs.h" +#include "fxchar.h" #include "fxmath.h" #include "fxkeys.h" #include "FXArray.h" diff --git a/lib/FXObject.cpp b/lib/FXObject.cpp index 5d87cf1..bcadc12 100644 --- a/lib/FXObject.cpp +++ b/lib/FXObject.cpp @@ -48,6 +48,32 @@ namespace FX { /*******************************************************************************/ +/// EXPERIMENT /// + + +typedef long (*NewMethod)(FX::FXObject*,FX::FXObject*,FX::FXSelector,void*); + +struct NewMapEntry { + FX::FXSelector keylo; + FX::FXSelector keyhi; + FX::NewMethod method; + }; + +extern const NewMapEntry messagemap[]; + + +template +static long method_call(FX::FXObject* tgt,FX::FXObject* obj,FX::FXSelector sel,void* ptr){ + return (tgt->*mfn)(obj,sel,ptr); + } + +const NewMapEntry messagemap[]={ + {100,200,&method_call}, + }; + + +/// EXPERIMENT /// + // Have to do this one `by hand' as it has no base class const FXMetaClass FXObject::metaClass("FXObject",FXObject::manufacture,nullptr,nullptr,0,0); diff --git a/lib/FXObjectList.cpp b/lib/FXObjectList.cpp index 768f748..e41ff0d 100644 --- a/lib/FXObjectList.cpp +++ b/lib/FXObjectList.cpp @@ -46,7 +46,7 @@ #define ROUNDUP(n) (((n)+ROUNDVAL-1)&-ROUNDVAL) // Special empty object list value -#define EMPTY ((FXObject**)(__objectlist__empty__+1)) +#define EMPTY (const_cast((FXObject *const *)(__objectlist__empty__+1))) using namespace FX; @@ -407,8 +407,8 @@ FXbool FXObjectList::pop(){ // Clear the list -void FXObjectList::clear(){ - no(0); +FXbool FXObjectList::clear(){ + return no(0); } diff --git a/lib/FXPCXIcon.cpp b/lib/FXPCXIcon.cpp index d588317..4e0dd7d 100644 --- a/lib/FXPCXIcon.cpp +++ b/lib/FXPCXIcon.cpp @@ -69,9 +69,9 @@ FXIMPLEMENT(FXPCXIcon,FXIcon,nullptr,0) // Initialize nicely -FXPCXIcon::FXPCXIcon(FXApp* a,const void *pix,FXColor clr,FXuint opts,FXint w,FXint h):FXIcon(a,nullptr,clr,opts,w,h){ +FXPCXIcon::FXPCXIcon(FXApp* a,const FXuchar *pix,FXColor clr,FXuint opts,FXint w,FXint h):FXIcon(a,nullptr,clr,opts,w,h){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXPCXImage.cpp b/lib/FXPCXImage.cpp index c07d296..8e0ba58 100644 --- a/lib/FXPCXImage.cpp +++ b/lib/FXPCXImage.cpp @@ -67,9 +67,9 @@ FXIMPLEMENT(FXPCXImage,FXImage,nullptr,0) // Initialize -FXPCXImage::FXPCXImage(FXApp* a,const void *pix,FXuint opts,FXint w,FXint h):FXImage(a,nullptr,opts,w,h){ +FXPCXImage::FXPCXImage(FXApp* a,const FXuchar *pix,FXuint opts,FXint w,FXint h):FXImage(a,nullptr,opts,w,h){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXPNGIcon.cpp b/lib/FXPNGIcon.cpp index 50c9432..0845725 100644 --- a/lib/FXPNGIcon.cpp +++ b/lib/FXPNGIcon.cpp @@ -72,9 +72,9 @@ const FXbool FXPNGIcon::supported=false; // Initialize -FXPNGIcon::FXPNGIcon(FXApp* a,const void *pix,FXColor clr,FXuint opts,FXint w,FXint h):FXIcon(a,nullptr,clr,opts,w,h){ +FXPNGIcon::FXPNGIcon(FXApp* a,const FXuchar *pix,FXColor clr,FXuint opts,FXint w,FXint h):FXIcon(a,nullptr,clr,opts,w,h){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXPNGImage.cpp b/lib/FXPNGImage.cpp index 554fb46..2738950 100644 --- a/lib/FXPNGImage.cpp +++ b/lib/FXPNGImage.cpp @@ -73,9 +73,9 @@ const FXbool FXPNGImage::supported=false; // Initialize -FXPNGImage::FXPNGImage(FXApp* a,const void *pix,FXuint opts,FXint w,FXint h):FXImage(a,nullptr,opts,w,h){ +FXPNGImage::FXPNGImage(FXApp* a,const FXuchar *pix,FXuint opts,FXint w,FXint h):FXImage(a,nullptr,opts,w,h){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXPPMIcon.cpp b/lib/FXPPMIcon.cpp index bcab6ad..81dfaaa 100644 --- a/lib/FXPPMIcon.cpp +++ b/lib/FXPPMIcon.cpp @@ -66,9 +66,9 @@ FXIMPLEMENT(FXPPMIcon,FXIcon,nullptr,0) // Initialize nicely -FXPPMIcon::FXPPMIcon(FXApp* a,const void *pix,FXColor clr,FXuint opts,FXint w,FXint h):FXIcon(a,nullptr,clr,opts,w,h){ +FXPPMIcon::FXPPMIcon(FXApp* a,const FXuchar *pix,FXColor clr,FXuint opts,FXint w,FXint h):FXIcon(a,nullptr,clr,opts,w,h){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXPPMImage.cpp b/lib/FXPPMImage.cpp index 8d324d9..8906374 100644 --- a/lib/FXPPMImage.cpp +++ b/lib/FXPPMImage.cpp @@ -66,9 +66,9 @@ FXIMPLEMENT(FXPPMImage,FXImage,nullptr,0) // Initialize -FXPPMImage::FXPPMImage(FXApp* a,const void *pix,FXuint opts,FXint w,FXint h):FXImage(a,nullptr,opts,w,h){ +FXPPMImage::FXPPMImage(FXApp* a,const FXuchar *pix,FXuint opts,FXint w,FXint h):FXImage(a,nullptr,opts,w,h){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXParseBuffer.cpp b/lib/FXParseBuffer.cpp new file mode 100644 index 0000000..689f076 --- /dev/null +++ b/lib/FXParseBuffer.cpp @@ -0,0 +1,189 @@ +/******************************************************************************** +* * +* P a r s e - B u f f e r * +* * +********************************************************************************* +* Copyright (C) 2013,2022 by Jeroen van der Zijp. All Rights Reserved. * +********************************************************************************* +* This library is free software; you can redistribute it and/or modify * +* it under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 3 of the License, or * +* (at your option) any later version. * +* * +* This library is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU Lesser General Public License for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see * +********************************************************************************/ +#include "xincs.h" +#include "fxver.h" +#include "fxdefs.h" +#include "fxmath.h" +#include "fxascii.h" +#include "fxunicode.h" +#include "FXElement.h" +#include "FXArray.h" +#include "FXString.h" +#include "FXIO.h" +#include "FXIODevice.h" +#include "FXStat.h" +#include "FXFile.h" +#include "FXException.h" +#include "FXParseBuffer.h" + +/* + Notes: + + - When reading, the read pointer (rptr) represents the oldest character we intend + to keep when the buffer is being filled. The scan pointer (sptr) represents the + next character about to be parsed; it should not catch up with the write pointer + (wptr) which is where new data is being read from storage (when reading). + - When writing, the write pointer is where new data will be dropped into the + buffer, and the read pointer is pointing to the first byte not yet saved to + storage. + - One may read from memory as if it were a file, simply by passing a non-0 length; + the size of the buffer must be at least equal to length, but may be the same. + - End-of-file is signified as a partially filled buffer; thus, subclasses must + initialize rptr, wptr, and sptr to endptr at the start. +*/ + +using namespace FX; + +/*******************************************************************************/ + +namespace FX { + + +// Initialize parse buffer +FXParseBuffer::FXParseBuffer():begptr(nullptr),endptr(nullptr),wptr(nullptr),rptr(nullptr),sptr(nullptr),dir(Stop){ + } + + +// Initialize parse buffer with given size and direction +FXParseBuffer::FXParseBuffer(FXchar* buffer,FXuval sz,Direction d):begptr(nullptr),endptr(nullptr),wptr(nullptr),rptr(nullptr),sptr(nullptr),dir(Stop){ + open(buffer,sz,d); + } + + +// Open parse buffer with given size and direction +FXbool FXParseBuffer::open(FXchar* buffer,FXuval sz,Direction d){ + if((dir==Stop) && (d!=Stop) && (0wptr){ + if(wptr==endptr){ + if(fill(count)<0) return false; + } + return sptr=endptr){ + if(flush(count)<=0) return false; + } + FXASSERT(wptr=endptr){ + if(flush(count)<=0) return false; + } + FXASSERT(wptr(args),const_cast(env)); } // Kick off with just arguments else{ - ::execv(exec,(char* const*)args); + ::execv(exec,const_cast(args)); } // Failed to kick off child diff --git a/lib/FXPtrList.cpp b/lib/FXPtrList.cpp index 0cd730e..cd6a23a 100644 --- a/lib/FXPtrList.cpp +++ b/lib/FXPtrList.cpp @@ -40,7 +40,7 @@ #define ROUNDUP(n) (((n)+ROUNDVAL-1)&-ROUNDVAL) // Special empty pointer list value -#define EMPTY ((FXptr*)(__ptrlist__empty__+1)) +#define EMPTY (const_cast((const FXptr*)(__ptrlist__empty__+1))) using namespace FX; @@ -401,8 +401,8 @@ FXbool FXPtrList::pop(){ // Clear the list -void FXPtrList::clear(){ - no(0); +FXbool FXPtrList::clear(){ + return no(0); } diff --git a/lib/FXQuatd.cpp b/lib/FXQuatd.cpp index 10a93d4..79b245a 100644 --- a/lib/FXQuatd.cpp +++ b/lib/FXQuatd.cpp @@ -354,38 +354,47 @@ void FXQuatd::getYawRollPitch(FXdouble& yaw,FXdouble& roll,FXdouble& pitch) cons // Set quaternion from axes +// "Converting a Rotation Matrix to a Quaternion," Mike Day, Insomniac Games. void FXQuatd::setAxes(const FXVec3d& ex,const FXVec3d& ey,const FXVec3d& ez){ - FXdouble trace=ex.x+ey.y+ez.z; - FXdouble scale; - if(trace>0.0){ - scale=Math::sqrt(1.0+trace); - w=0.5*scale; - scale=0.5/scale; - x=(ey.z-ez.y)*scale; - y=(ez.x-ex.z)*scale; - z=(ex.y-ey.x)*scale; - } - else if(ex.x>ey.y && ex.x>ez.z){ - scale=2.0*Math::sqrt(1.0+ex.x-ey.y-ez.z); - x=0.25*scale; - y=(ex.y+ey.x)/scale; - z=(ex.z+ez.x)/scale; - w=(ey.z-ez.y)/scale; - } - else if(ey.y>ez.z){ - scale=2.0*Math::sqrt(1.0+ey.y-ex.x-ez.z); - y=0.25*scale; - x=(ex.y+ey.x)/scale; - z=(ey.z+ez.y)/scale; - w=(ez.x-ex.z)/scale; + FXdouble t; + if(ez.z<0.0){ + if(ex.x>ey.y){ + t=1.0+ex.x-ey.y-ez.z; + x=t; + y=ex.y+ey.x; + z=ez.x+ex.z; + w=ey.z-ez.y; + } + else{ + t=1.0-ex.x+ey.y-ez.z; + x=ex.y+ey.x; + y=t; + z=ey.z+ez.y; + w=ez.x-ex.z; + } } else{ - scale=2.0*Math::sqrt(1.0+ez.z-ex.x-ey.y); - z=0.25*scale; - x=(ex.z+ez.x)/scale; - y=(ey.z+ez.y)/scale; - w=(ex.y-ey.x)/scale; + if(ex.x<-ey.y){ + t=1.0-ex.x-ey.y+ez.z; + x=ez.x+ex.z; + y=ey.z+ez.y; + z=t; + w=ex.y-ey.x; + } + else{ + t=1.0+ex.x+ey.y+ez.z; + x=ey.z-ez.y; + y=ez.x-ex.z; + z=ex.y-ey.x; + w=t; + } } + FXASSERT(t>0.0); + t=0.5/Math::sqrt(t); + x*=t; + y*=t; + z*=t; + w*=t; } @@ -484,7 +493,7 @@ FXQuatd FXQuatd::pow(FXdouble t) const { // Rotation unit-quaternion and vector v . q = (q . v . q*) where q* is // the conjugate of q. // -// The Rodriques Formula for rotating a vector V about a unit-axis K is: +// The Rodriques Formula for rotating a vector V over angle A about a unit-vector K: // // V' = K (K . V) + (K x V) sin(A) - K x (K x V) cos(A) // diff --git a/lib/FXQuatf.cpp b/lib/FXQuatf.cpp index fd9248d..ab4cb4a 100644 --- a/lib/FXQuatf.cpp +++ b/lib/FXQuatf.cpp @@ -353,38 +353,47 @@ void FXQuatf::getYawRollPitch(FXfloat& yaw,FXfloat& roll,FXfloat& pitch) const { // Set quaternion from axes +// "Converting a Rotation Matrix to a Quaternion," Mike Day, Insomniac Games. void FXQuatf::setAxes(const FXVec3f& ex,const FXVec3f& ey,const FXVec3f& ez){ - FXfloat trace=ex.x+ey.y+ez.z; - FXfloat scale; - if(trace>0.0f){ - scale=Math::sqrt(1.0f+trace); - w=0.5f*scale; - scale=0.5f/scale; - x=(ey.z-ez.y)*scale; - y=(ez.x-ex.z)*scale; - z=(ex.y-ey.x)*scale; - } - else if(ex.x>ey.y && ex.x>ez.z){ - scale=2.0f*Math::sqrt(1.0f+ex.x-ey.y-ez.z); - x=0.25f*scale; - y=(ex.y+ey.x)/scale; - z=(ex.z+ez.x)/scale; - w=(ey.z-ez.y)/scale; - } - else if(ey.y>ez.z){ - scale=2.0f*Math::sqrt(1.0f+ey.y-ex.x-ez.z); - y=0.25f*scale; - x=(ex.y+ey.x)/scale; - z=(ey.z+ez.y)/scale; - w=(ez.x-ex.z)/scale; + FXfloat t; + if(ez.z<0.0f){ + if(ex.x>ey.y){ + t=1.0f+ex.x-ey.y-ez.z; + x=t; + y=ex.y+ey.x; + z=ez.x+ex.z; + w=ey.z-ez.y; + } + else{ + t=1.0f-ex.x+ey.y-ez.z; + x=ex.y+ey.x; + y=t; + z=ey.z+ez.y; + w=ez.x-ex.z; + } } else{ - scale=2.0f*Math::sqrt(1.0f+ez.z-ex.x-ey.y); - z=0.25f*scale; - x=(ex.z+ez.x)/scale; - y=(ey.z+ez.y)/scale; - w=(ex.y-ey.x)/scale; + if(ex.x<-ey.y){ + t=1.0f-ex.x-ey.y+ez.z; + x=ez.x+ex.z; + y=ey.z+ez.y; + z=t; + w=ex.y-ey.x; + } + else{ + t=1.0f+ex.x+ey.y+ez.z; + x=ey.z-ez.y; + y=ez.x-ex.z; + z=ex.y-ey.x; + w=t; + } } + FXASSERT(t>0.0f); + t=0.5f/Math::sqrt(t); + x*=t; + y*=t; + z*=t; + w*=t; } @@ -483,7 +492,7 @@ FXQuatf FXQuatf::pow(FXfloat t) const { // Rotation unit-quaternion and vector v . q = (q . v . q*) where q* is // the conjugate of q. // -// The Rodriques Formula for rotating a vector V about a unit-axis K is: +// The Rodriques Formula for rotating a vector V over angle A about a unit-vector K: // // V' = K (K . V) + (K x V) sin(A) - K x (K x V) cos(A) // diff --git a/lib/FXRASIcon.cpp b/lib/FXRASIcon.cpp index dc889e1..6e386c3 100644 --- a/lib/FXRASIcon.cpp +++ b/lib/FXRASIcon.cpp @@ -65,9 +65,9 @@ FXIMPLEMENT(FXRASIcon,FXIcon,nullptr,0) // Initialize nicely -FXRASIcon::FXRASIcon(FXApp* a,const void *pix,FXColor clr,FXuint opts,FXint w,FXint h):FXIcon(a,nullptr,clr,opts,w,h){ +FXRASIcon::FXRASIcon(FXApp* a,const FXuchar *pix,FXColor clr,FXuint opts,FXint w,FXint h):FXIcon(a,nullptr,clr,opts,w,h){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXRASImage.cpp b/lib/FXRASImage.cpp index ebd71db..dc80ae4 100644 --- a/lib/FXRASImage.cpp +++ b/lib/FXRASImage.cpp @@ -66,9 +66,9 @@ FXIMPLEMENT(FXRASImage,FXImage,nullptr,0) // Initialize -FXRASImage::FXRASImage(FXApp* a,const void *pix,FXuint opts,FXint w,FXint h):FXImage(a,nullptr,opts,w,h){ +FXRASImage::FXRASImage(FXApp* a,const FXuchar *pix,FXuint opts,FXint w,FXint h):FXImage(a,nullptr,opts,w,h){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXRGBIcon.cpp b/lib/FXRGBIcon.cpp index 447995f..d4ba3e5 100644 --- a/lib/FXRGBIcon.cpp +++ b/lib/FXRGBIcon.cpp @@ -65,9 +65,9 @@ FXIMPLEMENT(FXRGBIcon,FXIcon,nullptr,0) // Initialize nicely -FXRGBIcon::FXRGBIcon(FXApp* a,const void *pix,FXColor clr,FXuint opts,FXint w,FXint h):FXIcon(a,nullptr,clr,opts,w,h){ +FXRGBIcon::FXRGBIcon(FXApp* a,const FXuchar *pix,FXColor clr,FXuint opts,FXint w,FXint h):FXIcon(a,nullptr,clr,opts,w,h){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXRGBImage.cpp b/lib/FXRGBImage.cpp index caa468b..c546748 100644 --- a/lib/FXRGBImage.cpp +++ b/lib/FXRGBImage.cpp @@ -65,9 +65,9 @@ FXIMPLEMENT(FXRGBImage,FXImage,nullptr,0) // Initialize -FXRGBImage::FXRGBImage(FXApp* a,const void *pix,FXuint opts,FXint w,FXint h):FXImage(a,nullptr,opts,w,h){ +FXRGBImage::FXRGBImage(FXApp* a,const FXuchar *pix,FXuint opts,FXint w,FXint h):FXImage(a,nullptr,opts,w,h){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXReadWriteLock.cpp b/lib/FXReadWriteLock.cpp index 6daab73..7472b79 100644 --- a/lib/FXReadWriteLock.cpp +++ b/lib/FXReadWriteLock.cpp @@ -79,7 +79,7 @@ FXReadWriteLock::FXReadWriteLock(){ // machine and mail it to: jeroen@fox-toolkit.net!! //FXTRACE((150,"sizeof(pthread_rwlock_t)=%d\n",sizeof(pthread_rwlock_t))); FXASSERT_STATIC(sizeof(data)>=sizeof(pthread_rwlock_t)); - pthread_rwlock_init((pthread_rwlock_t*)data,&rwlockatt); + pthread_rwlock_init((pthread_rwlock_t*)data,nullptr); #endif } diff --git a/lib/FXRegion.cpp b/lib/FXRegion.cpp index ef773a6..59535af 100644 --- a/lib/FXRegion.cpp +++ b/lib/FXRegion.cpp @@ -72,7 +72,7 @@ FXRegion::FXRegion(const FXRectangle& rect){ region=(void*)CreateRectRgn(rect.x,rect.y,rect.x+rect.w,rect.y+rect.h); #else region=XCreateRegion(); - XUnionRectWithRegion((XRectangle*)&rect,(Region)region,(Region)region); + XUnionRectWithRegion(const_cast((const XRectangle*)&rect),(Region)region,(Region)region); #endif } @@ -88,7 +88,7 @@ FXRegion::FXRegion(const FXPoint* points,FXuint npoints,FXbool winding){ } region=(void*)CreatePolygonRgn(pts,npoints,winding?WINDING:ALTERNATE); #else - region=XPolygonRegion((XPoint*)points,npoints,winding?WindingRule:EvenOddRule); + region=XPolygonRegion(const_cast((const XPoint*)points),npoints,winding?WindingRule:EvenOddRule); #endif } diff --git a/lib/FXRegistry.cpp b/lib/FXRegistry.cpp index b31e0e0..81f5c4d 100644 --- a/lib/FXRegistry.cpp +++ b/lib/FXRegistry.cpp @@ -134,7 +134,7 @@ o On UNIX systems, the XDG standard is followed; this means the location of the Per-User settings should controlled by $XDG_CONFIG_HOME. If this environment variable set, the root for the Per-User settings tree for all FOX applications - is $XDG_CONFIG_HOME/foxrc. + is $XDG_CONFIG_HOME/fox.rc. o Otherwise, it will have the default value: "~/.config". @@ -162,7 +162,7 @@ // Default locations and names #if defined(WIN32) #define FOXRC "fox.ini" -#define SYSTEMDIRS "\\Program Files;\\Windows" +#define SYSTEMDIRS "C:\\Program Files;C:\\Windows" #define USERDIR "%USERPROFILE%\\fox" #define FILEEXT ".ini" #else @@ -411,8 +411,8 @@ x: continue; // Read registry FXbool FXRegistry::read(){ FXbool ok=false; - FXString path; if(ascii){ + FXString path; // Read system-wide settings from systemdirs if(!systemdirs.empty()){ diff --git a/lib/FXReverseDictionary.cpp b/lib/FXReverseDictionary.cpp index fd22e35..d1c95fa 100644 --- a/lib/FXReverseDictionary.cpp +++ b/lib/FXReverseDictionary.cpp @@ -35,7 +35,7 @@ #define EMPTY (const_cast((const Entry*)(__reversedictionary__empty__+3))) #define HASH(x) ((FXival)(x)^(((FXival)(x))>>13)) -#define VOID ((FXptr)-1L) +#define VOID ((const void*)-1L) #define LEGAL(p) ((p)!=nullptr && (p)!=VOID) #define BSHIFT 5 @@ -89,7 +89,7 @@ FXbool FXReverseDictionary::resize(FXival n){ FXASSERT((n-used())>0); if(elbat.no(n)){ if(1(FXRex::fallback)) + // Access to opcode #define SETOP(p,op) (*(p)=(op)) @@ -527,7 +531,7 @@ // Access to argument #if defined(__i386__) || defined(__x86_64__) // No alignment limits on shorts #define SETARG(p,val) (*((FXshort*)(p))=(val)) -#define GETARG(p) (*((FXshort*)(p))) +#define GETARG(p) (*((const FXshort*)(p))) #elif (FOX_BIGENDIAN == 1) // Big-endian machines #define SETARG(p,val) (*((p)+0)=(val)>>8,*((p)+1)=(val)) #define GETARG(p) ((FXshort)((*((p)+0)<<8)+(*((p)+1)))) @@ -4639,15 +4643,16 @@ const FXuchar FXRex::fallback[]={ #endif }; +//const_cast(fallback) // Construct empty regular expression object -FXRex::FXRex():code((FXuchar*)(void*)fallback){ +FXRex::FXRex():code(EMPTY){ FXTRACE((TOPIC_CONSTRUCT,"FXRex::FXRex()\n")); } // Copy regex object -FXRex::FXRex(const FXRex& orig):code((FXuchar*)(void*)fallback){ +FXRex::FXRex(const FXRex& orig):code(EMPTY){ FXTRACE((TOPIC_CONSTRUCT,"FXRex::FXRex(FXRex)\n")); if(orig.code!=fallback){ dupElms(code,orig.code,GETARG(orig.code)); @@ -4656,7 +4661,7 @@ FXRex::FXRex(const FXRex& orig):code((FXuchar*)(void*)fallback){ // Compile expression from pattern; fail if error -FXRex::FXRex(const FXchar* pattern,FXint mode,FXRex::Error* error):code((FXuchar*)(void*)fallback){ +FXRex::FXRex(const FXchar* pattern,FXint mode,FXRex::Error* error):code(EMPTY){ FXTRACE((TOPIC_CONSTRUCT,"FXRex::FXRex(%s,%u,%p)\n",pattern,mode,error)); FXRex::Error err=parse(pattern,mode); if(error){ *error=err; } @@ -4664,7 +4669,7 @@ FXRex::FXRex(const FXchar* pattern,FXint mode,FXRex::Error* error):code((FXuchar // Compile expression from pattern; fail if error -FXRex::FXRex(const FXString& pattern,FXint mode,FXRex::Error* error):code((FXuchar*)(void*)fallback){ +FXRex::FXRex(const FXString& pattern,FXint mode,FXRex::Error* error):code(EMPTY){ FXTRACE((TOPIC_CONSTRUCT,"FXRex::FXRex(%s,%u,%p)\n",pattern.text(),mode,error)); FXRex::Error err=parse(pattern.text(),mode); if(error){ *error=err; } @@ -4913,9 +4918,9 @@ FXStream& operator>>(FXStream& store,FXRex& s){ // Clear program void FXRex::clear(){ - if(code!=fallback){ + if(code!=EMPTY){ freeElms(code); - code=(FXuchar*)(void*)fallback; + code=EMPTY; } } diff --git a/lib/FXRootWindow.cpp b/lib/FXRootWindow.cpp index 9f64f1e..b2b694e 100644 --- a/lib/FXRootWindow.cpp +++ b/lib/FXRootWindow.cpp @@ -135,23 +135,19 @@ void FXRootWindow::create(){ // Obtain desktop window size width=GetSystemMetrics(SM_CXVIRTUALSCREEN); height=GetSystemMetrics(SM_CYVIRTUALSCREEN); -#if 0 - HDC hdc=::GetDC((HWND)xid); - width=GetDeviceCaps(hdc,HORZRES); - height=GetDeviceCaps(hdc,VERTRES); - ::ReleaseDC((HWND)xid,hdc); -#endif - // Size bigger than all display screens - //getMaxScreenSize(width,height); - // Size bigger than all display screens - //width=GetSystemMetrics(SM_CXVIRTUALSCREEN); - //height=GetSystemMetrics(SM_CYVIRTUALSCREEN); + //HDC hdc=::GetDC((HWND)xid); + //width=GetDeviceCaps(hdc,HORZRES); + //height=GetDeviceCaps(hdc,VERTRES); + //::ReleaseDC((HWND)xid,hdc); // Size of primary display screen //width=GetSystemMetrics(SM_CXSCREEN); //height=GetSystemMetrics(SM_CYSCREEN); + // Size bigger than all display screens + //getMaxScreenSize(width,height); + // Store for xid to C++ object mapping getApp()->hash.insert((void*)xid,this); @@ -203,36 +199,13 @@ void FXRootWindow::destroy(){ } -#if 0 -// Get default width -FXint FXRootWindow::getDefaultWidth(){ -#ifdef WIN32 - HDC hdc=::GetDC(GetDesktopWindow()); - FXint w=GetDeviceCaps(hdc,HORZRES); - ::ReleaseDC(GetDesktopWindow(),hdc); - return w; -#else - return DisplayWidth(DISPLAY(getApp()),DefaultScreen(DISPLAY(getApp()))); -#endif - } - - -// Get default height -FXint FXRootWindow::getDefaultHeight(){ -#ifdef WIN32 - HDC hdc=::GetDC(GetDesktopWindow()); - FXint h=GetDeviceCaps(hdc,VERTRES); - ::ReleaseDC(GetDesktopWindow(),hdc); - return h; -#else - return DisplayHeight(DISPLAY(getApp()),DefaultScreen(DISPLAY(getApp()))); -#endif - } -#endif - // Get default width FXint FXRootWindow::getDefaultWidth(){ #ifdef WIN32 +// HDC hdc=::GetDC(GetDesktopWindow()); +// FXint w=GetDeviceCaps(hdc,HORZRES); +// ::ReleaseDC(GetDesktopWindow(),hdc); +// return w; return GetSystemMetrics(SM_CXVIRTUALSCREEN); #else return DisplayWidth(DISPLAY(getApp()),DefaultScreen(DISPLAY(getApp()))); @@ -242,6 +215,10 @@ FXint FXRootWindow::getDefaultWidth(){ // Get default height FXint FXRootWindow::getDefaultHeight(){ #ifdef WIN32 +// HDC hdc=::GetDC(GetDesktopWindow()); +// FXint h=GetDeviceCaps(hdc,VERTRES); +// ::ReleaseDC(GetDesktopWindow(),hdc); +// return h; return GetSystemMetrics(SM_CYVIRTUALSCREEN); #else return DisplayHeight(DISPLAY(getApp()),DefaultScreen(DISPLAY(getApp()))); diff --git a/lib/FXSettings.cpp b/lib/FXSettings.cpp index 926d1e0..c819ed2 100644 --- a/lib/FXSettings.cpp +++ b/lib/FXSettings.cpp @@ -58,7 +58,7 @@ */ -#define EMPTY ((Entry*)(__settings__empty__+3)) +#define EMPTY (const_cast((const Entry*)(__settings__empty__+3))) #define BSHIFT 5 using namespace FX; @@ -176,6 +176,7 @@ FXSettings& FXSettings::adopt(FXSettings& other){ if(__likely(table!=other.table)){ swap(table,other.table); other.clear(); + other.modified=true; modified=true; } return *this; @@ -798,14 +799,14 @@ FXbool FXSettings::writeColorEntry(const FXString& section,const FXString& name, FXbool FXSettings::readBoolEntry(const FXchar* section,const FXchar* name,FXbool def) const { const FXString& value=at(section).at(name); if(!value.empty()){ - if(comparecase(value,"true")==0) return true; - else if(comparecase(value,"false")==0) return false; - else if(comparecase(value,"yes")==0) return true; - else if(comparecase(value,"no")==0) return false; - else if(comparecase(value,"on")==0) return true; - else if(comparecase(value,"off")==0) return false; - else if(comparecase(value,"1")==0) return true; - else if(comparecase(value,"0")==0) return false; + if(FXString::comparecase(value,"true")==0) return true; + if(FXString::comparecase(value,"false")==0) return false; + if(FXString::comparecase(value,"yes")==0) return true; + if(FXString::comparecase(value,"no")==0) return false; + if(FXString::comparecase(value,"on")==0) return true; + if(FXString::comparecase(value,"off")==0) return false; + if(FXString::comparecase(value,"1")==0) return true; + if(FXString::comparecase(value,"0")==0) return false; } return def; } diff --git a/lib/FXStat.cpp b/lib/FXStat.cpp index d87f1b5..f9878b9 100644 --- a/lib/FXStat.cpp +++ b/lib/FXStat.cpp @@ -21,6 +21,7 @@ #include "xincs.h" #include "fxver.h" #include "fxdefs.h" +#include "fxchar.h" #include "fxmath.h" #include "fxascii.h" #include "FXArray.h" diff --git a/lib/FXStream.cpp b/lib/FXStream.cpp index 80e628a..9077085 100644 --- a/lib/FXStream.cpp +++ b/lib/FXStream.cpp @@ -788,11 +788,12 @@ FXStream& FXStream::load(FXdouble* p,FXuval n){ // Add object without saving or loading FXStream& FXStream::addObject(const FXObject* v){ if(v){ + void* ref=(void*)(FXuval)seq++; if(dir==FXStreamSave){ - hash.insert((FXptr)v,(FXptr)(FXuval)seq++); + hash.insert(v,ref); } else if(dir==FXStreamLoad){ - hash.insert((FXptr)(FXuval)seq++,(FXptr)v); + hash.insert(ref,const_cast(v)); } } return *this; @@ -804,21 +805,22 @@ FXStream& FXStream::addObject(const FXObject* v){ // Save object FXStream& FXStream::saveObject(const FXObject* v){ - const FXMetaClass *cls; - const FXchar *name; - FXuint tag,zero=0; if(dir!=FXStreamSave){ fxerror("FXStream::saveObject: wrong stream direction.\n"); } if(code==FXStreamOK){ + const FXMetaClass *cls; + const FXchar *name; + FXuint tag,zero=0; + void* ref; if(v==nullptr){ // Its a NULL - *this << zero; + *this << zero; // Save special null-object tag return *this; } - tag=(FXuint)(FXuval)hash.at((FXptr)v); // Already in table - if(tag){ + ref=hash.at(v); // Reference from table + tag=(FXuint)(FXuval)ref; + if(tag){ // Already in table *this << tag; return *this; } - hash.insert((FXptr)v,(FXptr)(FXuval)seq++); // Add to table cls=v->getMetaClass(); name=cls->getClassName(); tag=strlen(name)+1; @@ -826,11 +828,13 @@ FXStream& FXStream::saveObject(const FXObject* v){ code=FXStreamFormat; return *this; } + ref=(void*)(FXuval)seq++; // New reference + hash.insert(v,ref); // Map object to reference *this << tag; // Save tag - *this << zero; - save(name,tag); + *this << zero; // Save escape code + save(name,tag); // Save class name FXTRACE((100,"%08ld: saveObject(%s)\n",(FXuval)pos,v->getClassName())); - v->save(*this); + v->save(*this); // Save object } return *this; } @@ -840,18 +844,20 @@ FXStream& FXStream::saveObject(const FXObject* v){ // Load object FXStream& FXStream::loadObject(FXObject*& v){ - const FXMetaClass *cls; - FXchar name[MAXCLASSNAME+1]; - FXuint tag,esc; if(dir!=FXStreamLoad){ fxerror("FXStream::loadObject: wrong stream direction.\n"); } if(code==FXStreamOK){ + FXchar name[MAXCLASSNAME+1]; + const FXMetaClass *cls; + FXuint tag,esc; + void* ref; *this >> tag; if(tag==0){ // Was a NULL v=nullptr; return *this; } if(tag>=0x80000000){ - v=(FXObject*)hash.at((FXptr)(FXuval)tag); + ref=(void*)(FXuval)tag; + v=(FXObject*)hash.at(ref); // Object referenced by tag if(!v){ code=FXStreamFormat; // Bad format in stream } @@ -866,14 +872,15 @@ FXStream& FXStream::loadObject(FXObject*& v){ code=FXStreamFormat; // Bad format in stream return *this; } - load(name,tag); // Load name + load(name,tag); // Load class name cls=FXMetaClass::getMetaClassFromName(name); - if(cls==nullptr){ // No FXMetaClass with this class name + if(cls==nullptr){ // We don't have a class with this name code=FXStreamUnknown; // Unknown class return *this; } - v=cls->makeInstance(); // Build some object!! - hash.insert((FXptr)(FXuval)seq++,(FXptr)v); // Add to table + ref=(void*)(FXuval)seq++; // New reference + v=cls->makeInstance(); // Make instance of class + hash.insert(ref,v); // Map reference to object FXTRACE((100,"%08ld: loadObject(%s)\n",(FXuval)pos,v->getClassName())); v->load(*this); } diff --git a/lib/FXString.cpp b/lib/FXString.cpp index 81236eb..55143a0 100644 --- a/lib/FXString.cpp +++ b/lib/FXString.cpp @@ -21,6 +21,7 @@ #include "xincs.h" #include "fxver.h" #include "fxdefs.h" +#include "fxchar.h" #include "fxmath.h" #include "fxascii.h" #include "fxunicode.h" @@ -78,7 +79,7 @@ #define ROUNDUP(n) (((n)+ROUNDVAL-1)&-ROUNDVAL) // Special empty string value -#define EMPTY ((FXchar*)(void*)(__string__empty__+1)) +#define EMPTY (const_cast((const FXchar*)(__string__empty__+1))) using namespace FX; @@ -134,27 +135,6 @@ const FXschar FXString::digit2Value[256]={ }; -// Length of a utf8 character representation -const FXschar FXString::utfBytes[256]={ - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, - 4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1 - }; - - // Furnish our own versions extern FXAPI FXint __vsscanf(const FXchar* string,const FXchar* format,va_list arg_ptr); extern FXAPI FXint __vsnprintf(FXchar* string,FXint length,const FXchar* format,va_list args); @@ -193,659 +173,6 @@ static inline FXint strlen(const FXwchar *src){ /*******************************************************************************/ -// Return wide character from utf8 string at ptr -FXwchar wc(const FXchar* ptr){ - FXwchar w=(FXuchar)ptr[0]; - if(__unlikely(0xC0<=w)){ w=(w<<6)^(FXuchar)ptr[1]^0x3080; - if(__unlikely(0x800<=w)){ w=(w<<6)^(FXuchar)ptr[2]^0x20080; - if(__unlikely(0x10000<=w)){ w=(w<<6)^(FXuchar)ptr[3]^0x400080; }}} - return w; - } - - -// Return wide character from utf16 string at ptr -FXwchar wc(const FXnchar* ptr){ - FXwchar w=ptr[0]; - if(__unlikely(FXISLEADUTF16(w))){ w=SURROGATE_OFFSET+(w<<10)+ptr[1]; } - return w; - } - - -// Increment to start of next wide character in utf8 string -const FXchar* wcinc(const FXchar* ptr){ - return (FXISUTF8(*++ptr) || FXISUTF8(*++ptr) || FXISUTF8(*++ptr) || ++ptr), ptr; - } - - -// Increment to start of next wide character in utf8 string -FXchar* wcinc(FXchar* ptr){ - return (FXISUTF8(*++ptr) || FXISUTF8(*++ptr) || FXISUTF8(*++ptr) || ++ptr), ptr; - } - - -// Increment to start of next wide character in utf16 string -const FXnchar* wcinc(const FXnchar* ptr){ - return (FXISUTF16(*++ptr) || ++ptr), ptr; - } - - -// Increment to start of next wide character in utf16 string -FXnchar* wcinc(FXnchar* ptr){ - return (FXISUTF16(*++ptr) || ++ptr), ptr; - } - - -// Decrement to start of previous wide character in utf8 string -const FXchar* wcdec(const FXchar* ptr){ - return (FXISUTF8(*--ptr) || FXISUTF8(*--ptr) || FXISUTF8(*--ptr) || --ptr), ptr; - } - -// Decrement to start of previous wide character in utf8 string -FXchar* wcdec(FXchar* ptr){ - return (FXISUTF8(*--ptr) || FXISUTF8(*--ptr) || FXISUTF8(*--ptr) || --ptr), ptr; - } - - -// Decrement to start of previous wide character in utf16 string -const FXnchar* wcdec(const FXnchar* ptr){ - return (FXISUTF16(*--ptr) || --ptr), ptr; - } - - -// Decrement to start of previous wide character in utf16 string -FXnchar* wcdec(FXnchar* ptr){ - return (FXISUTF16(*--ptr) || --ptr), ptr; - } - - -// Return start of utf8 character containing position -const FXchar* wcstart(const FXchar* ptr){ - return (FXISUTF8(*ptr) || FXISUTF8(*--ptr) || FXISUTF8(*--ptr) || --ptr), ptr; - } - - -// Adjust ptr to point to leader of multi-byte sequence -FXchar* wcstart(FXchar* ptr){ - return (FXISUTF8(*ptr) || FXISUTF8(*--ptr) || FXISUTF8(*--ptr) || --ptr), ptr; - } - - -// Adjust ptr to point to leader of surrogate pair sequence -const FXnchar* wcstart(const FXnchar *ptr){ - return (FXISUTF16(*ptr) || --ptr), ptr; - } - - -// Adjust ptr to point to leader of surrogate pair sequence -FXnchar* wcstart(FXnchar *ptr){ - return (FXISUTF16(*ptr) || --ptr), ptr; - } - - -// Return number of FXchar's of wide character at ptr -FXival wclen(const FXchar *ptr){ - return FXUTF8LEN(*ptr); - } - - -// Return number of FXnchar's of narrow character at ptr -FXival wclen(const FXnchar *ptr){ - return FXUTF16LEN(*ptr); - } - - -// Return true if valid utf8 character sequence -FXival wcvalid(const FXchar* ptr){ - if((FXuchar)ptr[0]<0x80) return 1; - if((FXuchar)ptr[0]<0xC0) return 0; - if((FXuchar)ptr[1]<0x80) return 0; - if((FXuchar)ptr[1]>0xBF) return 0; - if((FXuchar)ptr[0]<0xE0) return 2; - if((FXuchar)ptr[2]<0x80) return 0; - if((FXuchar)ptr[2]>0xBF) return 0; - if((FXuchar)ptr[0]<0xF0) return 3; - if((FXuchar)ptr[3]<0x80) return 0; - if((FXuchar)ptr[3]>0xBF) return 0; - if((FXuchar)ptr[0]>0xF7) return 0; - return 4; - } - - -// Return true if valid utf16 character sequence -FXival wcvalid(const FXnchar* ptr){ - if(ptr[0]<0xD800) return 1; - if(ptr[0]>0xDFFF) return 1; - if(ptr[0]>0xDBFF) return 0; - if(ptr[1]<0xDC00) return 0; - if(ptr[1]>0xDFFF) return 0; - return 2; - } - -/*******************************************************************************/ - -// Return number of bytes for utf8 representation of wide character w -FXival wc2utf(FXwchar w){ - return (w>=0x80)+(w>=0x800)+(w>=0x10000)+1; - } - - -// Return number of narrow characters for utf16 representation of wide character w -FXival wc2nc(FXwchar w){ - return (w>=0x10000)+1; - } - - -// Return number of bytes for utf8 representation of wide character string -FXival wcs2utf(const FXwchar* src,FXival srclen){ - const FXwchar* srcend=src+srclen; - FXival p=0; - FXwchar w; - while(src=srcend)) break; - if(__unlikely(!FXISFOLLOWUTF16(*src))) break; - w=SURROGATE_OFFSET+(w<<10)+*src++; - } - p+=wc2utf(w); - } - return p; - } - - -// Return number of bytes for utf8 representation of narrow character string -FXival ncs2utf(const FXnchar *src){ - FXival p=0; - FXnchar w; - while((w=*src++)!=0){ - if(FXISLEADUTF16(w)){ - if(__unlikely(!FXISFOLLOWUTF16(*src))) break; - w=SURROGATE_OFFSET+(w<<10)+*src++; - } - p+=wc2utf(w); - } - return p; - } - - -// Return number of wide characters for utf8 character string -FXival utf2wcs(const FXchar *src,FXival srclen){ - const FXchar* srcend=src+srclen; - FXival p=0; - FXuchar c; - while(src=srcend)) break; - if(__unlikely(!FXISFOLLOWUTF8(src[1]))) break; - if(0xE0<=c){ - if(__unlikely(src+2>=srcend)) break; - if(__unlikely(!FXISFOLLOWUTF8(src[2]))) break; - if(0xF0<=c){ - if(__unlikely(src+3>=srcend)) break; - if(__unlikely(!FXISFOLLOWUTF8(src[3]))) break; - src++; - } - src++; - } - src++; - } - src++; - p++; - } - return p; - } - - -// Return number of wide characters for utf8 character string -FXival utf2wcs(const FXchar *src){ - FXival p=0; - FXuchar c; - while((c=src[0])!=0){ - if(0xC0<=c){ - if(__unlikely(!FXISFOLLOWUTF8(src[1]))) break; - if(0xE0<=c){ - if(__unlikely(!FXISFOLLOWUTF8(src[2]))) break; - if(0xF0<=c){ - if(__unlikely(!FXISFOLLOWUTF8(src[3]))) break; - src++; - } - src++; - } - src++; - } - src++; - p++; - } - return p; - } - - -// Return number of narrow characters for utf8 character string -FXival utf2ncs(const FXchar *src,FXival len){ - const FXchar* end=src+len; - FXival p=0; - FXuchar c; - while(src=end)) break; - if(__unlikely(!FXISFOLLOWUTF8(src[1]))) break; - if(0xE0<=c){ - if(__unlikely(src+2>=end)) break; - if(__unlikely(!FXISFOLLOWUTF8(src[2]))) break; - if(0xF0<=c){ - if(__unlikely(src+3>=end)) break; - if(__unlikely(!FXISFOLLOWUTF8(src[3]))) break; - src++; - p++; - } - src++; - } - src++; - } - src++; - p++; - } - return p; - } - - -// Return number of narrow characters for utf8 character string -FXival utf2ncs(const FXchar *src){ - FXival p=0; - FXuchar c; - while((c=src[0])!=0){ - if(0xC0<=c){ - if(__unlikely(!FXISFOLLOWUTF8(src[1]))) break; - if(0xE0<=c){ - if(__unlikely(!FXISFOLLOWUTF8(src[2]))) break; - if(0xF0<=c){ - if(__unlikely(!FXISFOLLOWUTF8(src[3]))) break; - src++; - p++; - } - src++; - } - src++; - } - src++; - p++; - } - return p; - } - - -// Convert wide character to utf8 string -FXival wc2utf(FXchar *dst,FXwchar w){ - if(__likely(w<0x80)){ - dst[0]=w; - return 1; - } - if(__likely(w<0x800)){ - dst[0]=(w>>6)|0xC0; - dst[1]=(w&0x3F)|0x80; - return 2; - } - if(__likely(w<0x10000)){ - dst[0]=(w>>12)|0xE0; - dst[1]=((w>>6)&0x3F)|0x80; - dst[2]=(w&0x3F)|0x80; - return 3; - } - dst[0]=(w>>18)|0xF0; - dst[1]=((w>>12)&0x3F)|0x80; - dst[2]=((w>>6)&0x3F)|0x80; - dst[3]=(w&0x3F)|0x80; - return 4; - } - - -// Convert wide character to narrow character string -FXival wc2nc(FXnchar *dst,FXwchar w){ - if(__likely(w<0x10000)){ - dst[0]=w; - return 1; - } - dst[0]=LEAD_OFFSET+(w>>10); - dst[1]=TAIL_OFFSET+(w&0x3FF); - return 2; - } - - -// Convert wide character string to utf8 string -FXival wcs2utf(FXchar *dst,const FXwchar* src,FXival dstlen,FXival srclen){ - const FXwchar* srcend=src+srclen; - FXchar* ptrend=dst+dstlen; - FXchar* ptr=dst; - FXwchar w; - while(src=ptrend)) break; - *ptr++=w; - continue; - } - if(w<0x800){ - if(__unlikely(ptr+1>=ptrend)) break; - *ptr++=(w>>6)|0xC0; - *ptr++=(w&0x3F)|0x80; - continue; - } - if(w<0x10000){ - if(__unlikely(ptr+2>=ptrend)) break; - *ptr++=(w>>12)|0xE0; - *ptr++=((w>>6)&0x3F)|0x80; - *ptr++=(w&0x3F)|0x80; - continue; - } - if(w<0x110000){ - if(__unlikely(ptr+3>=ptrend)) break; - *ptr++=(w>>18)|0xF0; - *ptr++=((w>>12)&0x3F)|0x80; - *ptr++=((w>>6)&0x3F)|0x80; - *ptr++=(w&0x3F)|0x80; - continue; - } - break; - } - if(ptr=ptrend)) break; - *ptr++=w; - continue; - } - if(w<0x800){ - if(__unlikely(ptr+1>=ptrend)) break; - *ptr++=(w>>6)|0xC0; - *ptr++=(w&0x3F)|0x80; - continue; - } - if(w<0x10000){ - if(__unlikely(ptr+2>=ptrend)) break; - *ptr++=(w>>12)|0xE0; - *ptr++=((w>>6)&0x3F)|0x80; - *ptr++=(w&0x3F)|0x80; - continue; - } - if(w<0x110000){ - if(__unlikely(ptr+3>=ptrend)) break; - *ptr++=(w>>18)|0xF0; - *ptr++=((w>>12)&0x3F)|0x80; - *ptr++=((w>>6)&0x3F)|0x80; - *ptr++=(w&0x3F)|0x80; - continue; - } - break; - } - if(ptr=ptrend)) break; - *ptr++=w; - continue; - } - if(w<0x800){ - if(__unlikely(ptr+1>=ptrend)) break; - *ptr++=(w>>6)|0xC0; - *ptr++=(w&0x3F)|0x80; - continue; - } - if(!FXISLEADUTF16(w)){ - if(__unlikely(ptr+2>=ptrend)) break; - *ptr++=(w>>12)|0xE0; - *ptr++=((w>>6)&0x3F)|0x80; - *ptr++=(w&0x3F)|0x80; - continue; - } - if(src=ptrend)) break; - w=SURROGATE_OFFSET+(w<<10)+*src++; - *ptr++=(w>>18)|0xF0; - *ptr++=((w>>12)&0x3F)|0x80; - *ptr++=((w>>6)&0x3F)|0x80; - *ptr++=(w&0x3F)|0x80; - continue; - } - break; - } - if(ptr=ptrend)) break; - *ptr++=w; - continue; - } - if(w<0x800){ - if(__unlikely(ptr+1>=ptrend)) break; - *ptr++=(w>>6)|0xC0; - *ptr++=(w&0x3F)|0x80; - continue; - } - if(!FXISSEQUTF16(w)){ - if(__unlikely(ptr+2>=ptrend)) break; - *ptr++=(w>>12)|0xE0; - *ptr++=((w>>6)&0x3F)|0x80; - *ptr++=(w&0x3F)|0x80; - continue; - } - if(FXISFOLLOWUTF16(*src)){ - if(__unlikely(ptr+3>=ptrend)) break; - w=SURROGATE_OFFSET+(w<<10)+*src++; - *ptr++=(w>>18)|0xF0; - *ptr++=((w>>12)&0x3F)|0x80; - *ptr++=((w>>6)&0x3F)|0x80; - *ptr++=(w&0x3F)|0x80; - continue; - } - break; - } - if(ptr=srcend)) break; - c=*src++; - if(__unlikely(!FXISFOLLOWUTF8(c))) break; - w=(w<<6) ^ c ^ 0x3080; - if(0x800<=w){ - if(__unlikely(src>=srcend)) break; - c=*src++; - if(__unlikely(!FXISFOLLOWUTF8(c))) break; - w=(w<<6) ^ c ^ 0x20080; - if(0x10000<=w){ - if(__unlikely(src>=srcend)) break; - c=*src++; - if(__unlikely(!FXISFOLLOWUTF8(c))) break; - w=(w<<6) ^ c ^ 0x400080; - } - } - } - if(__unlikely(ptr>=ptrend)) break; - *ptr++=w; - } - if(ptr=ptrend)) break; - *ptr++=w; - } - if(ptr=srcend)) break; - c=*src++; - if(__unlikely(!FXISFOLLOWUTF8(c))) break; - w=(w<<6) ^ c ^ 0x3080; - if(0x800<=w){ - if(__unlikely(src>=srcend)) break; - c=*src++; - if(__unlikely(!FXISFOLLOWUTF8(c))) break; - w=(w<<6) ^ c ^ 0x20080; - if(0x10000<=w){ - if(__unlikely(src>=srcend)) break; - c=*src++; - if(__unlikely(!FXISFOLLOWUTF8(c))) break; - w=(w<<6) ^ c ^ 0x400080; - if(__unlikely(ptr+1>=ptrend)) break; - *ptr++=LEAD_OFFSET+(w>>10); - *ptr++=TAIL_OFFSET+(w&0x3FF); - continue; - } - } - } - if(__unlikely(ptr>=ptrend)) break; - *ptr++=w; - } - if(ptr=ptrend)) break; - *ptr++=LEAD_OFFSET+(w>>10); - *ptr++=TAIL_OFFSET+(w&0x3FF); - continue; - } - } - } - if(__unlikely(ptr>=ptrend)) break; - *ptr++=w; - } - if(ptr=length() || FXISUTF8(str[p]) || ++p>=length() || FXISUTF8(str[p]) || ++p>=length() || FXISUTF8(str[p]) || ++p), p; + return (++p>=length() || isUTF8(str[p]) || ++p>=length() || isUTF8(str[p]) || ++p>=length() || isUTF8(str[p]) || ++p), p; } @@ -976,7 +323,7 @@ FXint FXString::inc(FXint p,FXint n) const { // Decrement byte offset by one utf8 character FXint FXString::dec(FXint p) const { - return (--p<=0 || FXISUTF8(str[p]) || --p<=0 || FXISUTF8(str[p]) || --p<=0 || FXISUTF8(str[p]) || --p), p; + return (--p<=0 || isUTF8(str[p]) || --p<=0 || isUTF8(str[p]) || --p<=0 || isUTF8(str[p]) || --p), p; } @@ -991,7 +338,7 @@ FXint FXString::dec(FXint p,FXint n) const { FXint FXString::count(FXint start,FXint end) const { FXint cnt=0; while(startlen) pos=len; while(0<=pos){ if(str[pos]==c){ - if(!compare(str+pos,substr,n)){ + if(!FXString::compare(str+pos,substr,n)){ return pos; } } @@ -2460,7 +1814,7 @@ FXString& FXString::fromULong(FXulong number,FXint base){ // Formatting for reals -static const char conversionformat[8][8]={"%.*lF","%.*lE","%.*lG","%.*lF","%'.*lF","%'.*lE","%'.*lG","%'.*lF"}; +static const char conversionformat[8][8]={"%.*lF","%.*lE","%.*lG","%.*lA","%'.*lF","%'.*lE","%'.*lG","%.*lA"}; // Convert from float @@ -2491,90 +1845,397 @@ FXString FXString::value(FXuint num,FXint base){ } -// Return string by converting a long integer -FXString FXString::value(FXlong num,FXint base){ - FXString result; - return result.fromLong(num,base); +// Return string by converting a long integer +FXString FXString::value(FXlong num,FXint base){ + FXString result; + return result.fromLong(num,base); + } + + +// Return string by converting an unsigned long +FXString FXString::value(FXulong num,FXint base){ + FXString result; + return result.fromULong(num,base); + } + + +// Return string by converting a float +FXString FXString::value(FXfloat num,FXint prec,FXint fmt){ + FXString result; + return result.fromFloat(num,prec,fmt); + } + + +// Return string by converting a double +FXString FXString::value(FXdouble num,FXint prec,FXint fmt){ + FXString result; + return result.fromDouble(num,prec,fmt); + } + + +// Return string from printf-like format arguments +FXString FXString::value(const FXchar* fmt,...){ + FXString result; + va_list args; + va_start(args,fmt); + result.vformat(fmt,args); + va_end(args); + return result; + } + + +// Return string from vprintf-like format arguments +FXString FXString::vvalue(const FXchar* fmt,va_list args){ + FXString result; + result.vformat(fmt,args); + return result; + } + +/*******************************************************************************/ + +// Compute hash value of string +FXuint FXString::hash(const FXchar* s,FXint n){ + FXuint result=0x811C9DC5; + FXuchar c; + if(0>10); @@ -3047,19 +2708,31 @@ nml2: result[q++]=c; // Normal characters return result; } + +// Escape special characters +FXString FXString::escape(const FXchar* str,FXchar lquote,FXchar rquote,FXint flag){ + return FXString::escape(str,strlen(str),lquote,rquote,flag); + } + + +// Escape special characters +FXString FXString::escape(const FXString& str,FXchar lquote,FXchar rquote,FXint flag){ + return FXString::escape(str.text(),str.length(),lquote,rquote,flag); + } + /*******************************************************************************/ // Unescape special characters in a string; optionally strip quote characters -FXString FXString::unescape(const FXString& str,FXchar lquote,FXchar rquote){ +FXString FXString::unescape(const FXchar* str,FXint num,FXchar lquote,FXchar rquote){ FXString result; FXint p,q,w,c; p=q=c=0; if(str[p]==lquote && lquote) p++; // Opening quote - while(p>(FXStream& store,FXString& s){ /*******************************************************************************/ -// Compare string and string -FXint compare(const FXchar* s1,const FXchar* s2){ - FXint c1,c2; - do{ - c1=(FXuchar) *s1++; - c2=(FXuchar) *s2++; - } - while(c1 && (c1==c2)); - return c1-c2; - } - - -// Compare string and FXString -FXint compare(const FXchar* s1,const FXString& s2){ - return compare(s1,s2.text()); - } - - -// Compare FXString and string -FXint compare(const FXString& s1,const FXchar* s2){ - return compare(s1.text(),s2); - } - - -// Compare FXString and FXString -FXint compare(const FXString& s1,const FXString& s2){ - return compare(s1.text(),s2.text()); - } - - -// Compare string and string, up to n -FXint compare(const FXchar* s1,const FXchar* s2,FXint n){ - if(0(const FXString& s1,const FXString& s2){ - return compare(s1.text(),s2.text())>0; - } - -FXbool operator>(const FXString& s1,const FXchar* s2){ - return compare(s1.text(),s2)>0; - } - -FXbool operator>(const FXchar* s1,const FXString& s2){ - return compare(s1,s2.text())>0; - } - -FXbool operator>=(const FXString& s1,const FXString& s2){ - return compare(s1.text(),s2.text())>=0; - } - -FXbool operator>=(const FXString& s1,const FXchar* s2){ - return compare(s1.text(),s2)>=0; - } - -FXbool operator>=(const FXchar* s1,const FXString& s2){ - return compare(s1,s2.text())>=0; - } - - -/*******************************************************************************/ - // Concatenate two FXStrings FXString operator+(const FXString& s1,const FXString& s2){ FXString result(s1); diff --git a/lib/FXStringDictionary.cpp b/lib/FXStringDictionary.cpp index e7aa9af..95a9d5b 100644 --- a/lib/FXStringDictionary.cpp +++ b/lib/FXStringDictionary.cpp @@ -40,7 +40,7 @@ its not a very large class, but one which has high use. */ -#define EMPTY ((Entry*)(__stringdictionary__empty__+3)) +#define EMPTY (const_cast((const Entry*)(__stringdictionary__empty__+3))) #define BSHIFT 5 using namespace FX; @@ -225,14 +225,14 @@ const FXString& FXStringDictionary::at(const FXchar* ky) const { // Remove string associated with given key -void FXStringDictionary::remove(const FXchar* ky){ +FXbool FXStringDictionary::remove(const FXchar* ky){ if(__unlikely(!ky || !*ky)){ throw FXRangeException("FXStringDictionary::remove: null or empty key\n"); } if(__likely(!empty())){ FXuval p,b,h,x; p=b=h=FXString::hash(ky); FXASSERT(h); while(table[x=p&(no()-1)].hash!=h || table[x].key!=ky){ - if(!table[x].hash) return; + if(!table[x].hash) return false; p=(p<<2)+p+b+1; b>>=BSHIFT; } @@ -240,25 +240,29 @@ void FXStringDictionary::remove(const FXchar* ky){ table[x].data.clear(); used(used()-1); if(__unlikely(used()<=(no()>>2))) resize(no()>>1); + return true; } + return false; } // Erase string at pos in the table -void FXStringDictionary::erase(FXival pos){ +FXbool FXStringDictionary::erase(FXival pos){ if(__unlikely(pos<0 || no()<=pos)){ throw FXRangeException("FXStringDictionary::erase: argument out of range\n"); } if(!table[pos].key.empty()){ table[pos].key.clear(); // Void the slot (not empty!) table[pos].data.clear(); used(used()-1); if(__unlikely(used()<=(no()>>2))) resize(no()>>1); + return true; } + return false; } // Clear entire table -void FXStringDictionary::clear(){ - no(1); +FXbool FXStringDictionary::clear(){ + return no(1); } diff --git a/lib/FXSystem.cpp b/lib/FXSystem.cpp index 35c0609..a5b3dc6 100644 --- a/lib/FXSystem.cpp +++ b/lib/FXSystem.cpp @@ -21,6 +21,7 @@ #include "xincs.h" #include "fxver.h" #include "fxdefs.h" +#include "fxchar.h" #include "fxmath.h" #include "fxascii.h" #include "FXArray.h" @@ -362,6 +363,36 @@ FXString FXSystem::getHomeDirectory(){ return FXSystem::getUserDirectory(FXString::null); } + +// Return temporary directory. +FXString FXSystem::getTempDirectory(){ +#if defined(WIN32) + TCHAR buffer[MAXPATHLEN]; + DWORD len=GetTempPath(MAXPATHLEN,buffer); + if(1(pix)); loadPixels(ms); } } diff --git a/lib/FXTGAImage.cpp b/lib/FXTGAImage.cpp index 636587f..371c38b 100644 --- a/lib/FXTGAImage.cpp +++ b/lib/FXTGAImage.cpp @@ -65,9 +65,9 @@ FXIMPLEMENT(FXTGAImage,FXImage,nullptr,0) // Initialize -FXTGAImage::FXTGAImage(FXApp* a,const void *pix,FXuint opts,FXint w,FXint h):FXImage(a,nullptr,opts,w,h){ +FXTGAImage::FXTGAImage(FXApp* a,const FXuchar *pix,FXuint opts,FXint w,FXint h):FXImage(a,nullptr,opts,w,h){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXTIFIcon.cpp b/lib/FXTIFIcon.cpp index 838343f..cea87cf 100644 --- a/lib/FXTIFIcon.cpp +++ b/lib/FXTIFIcon.cpp @@ -72,9 +72,9 @@ const FXbool FXTIFIcon::supported=false; // Initialize -FXTIFIcon::FXTIFIcon(FXApp* a,const void *pix,FXColor clr,FXuint opts,FXint w,FXint h):FXIcon(a,nullptr,clr,opts,w,h),codec(0){ +FXTIFIcon::FXTIFIcon(FXApp* a,const FXuchar *pix,FXColor clr,FXuint opts,FXint w,FXint h):FXIcon(a,nullptr,clr,opts,w,h),codec(0){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXTIFImage.cpp b/lib/FXTIFImage.cpp index 26ad6d6..d9c012d 100644 --- a/lib/FXTIFImage.cpp +++ b/lib/FXTIFImage.cpp @@ -72,9 +72,9 @@ const FXbool FXTIFImage::supported=false; // Initialize -FXTIFImage::FXTIFImage(FXApp* a,const void *pix,FXuint opts,FXint w,FXint h):FXImage(a,nullptr,opts,w,h),codec(0){ +FXTIFImage::FXTIFImage(FXApp* a,const FXuchar *pix,FXuint opts,FXint w,FXint h):FXImage(a,nullptr,opts,w,h),codec(0){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXText.cpp b/lib/FXText.cpp index ff93759..aa497f9 100644 --- a/lib/FXText.cpp +++ b/lib/FXText.cpp @@ -23,6 +23,7 @@ #include "fxdefs.h" #include "fxmath.h" #include "fxkeys.h" +#include "fxchar.h" #include "fxascii.h" #include "fxunicode.h" #include "FXColors.h" @@ -544,7 +545,7 @@ void FXText::setOverstrike(FXbool over){ // Check if w is delimiter FXbool FXText::isdelimiter(FXwchar w) const { FXchar wcs[5]={'\0','\0','\0','\0','\0'}; - if(__unlikely(128<=w)){ + if(128<=w){ wc2utf(wcs,w); return (strstr(delimiters,wcs)!=nullptr); } @@ -617,9 +618,9 @@ FXwchar FXText::getChar(FXint pos) const { FXASSERT(0<=pos && pos<=length); const FXuchar* ptr=(FXuchar*)&buffer[pos+((gapend-gapstart)&((~pos+gapstart)>>31))]; FXwchar w=ptr[0]; - if(__unlikely(0xC0<=w)){ w=(w<<6)^ptr[1]^0x3080; - if(__unlikely(0x800<=w)){ w=(w<<6)^ptr[2]^0x20080; - if(__unlikely(0x10000<=w)){ w=(w<<6)^ptr[3]^0x400080; }}} + if(0xC0<=w){ w=(w<<6)^ptr[1]^0x3080; + if(0x800<=w){ w=(w<<6)^ptr[2]^0x20080; + if(0x10000<=w){ w=(w<<6)^ptr[3]^0x400080; }}} return w; } @@ -627,7 +628,7 @@ FXwchar FXText::getChar(FXint pos) const { // Get length of wide character at position pos FXint FXText::getCharLen(FXint pos) const { FXASSERT(0<=pos && pos<=length); - return FXUTF8LEN(buffer[pos+((gapend-gapstart)&((~pos+gapstart)>>31))]); + return lenUTF8(buffer[pos+((gapend-gapstart)&((~pos+gapstart)>>31))]); } @@ -637,13 +638,22 @@ FXint FXText::getStyle(FXint pos) const { return (FXuchar)sbuffer[pos+((gapend-gapstart)&((~pos+gapstart)>>31))]; } + /*******************************************************************************/ +// Make a valid position, at the start of a wide character +FXint FXText::validPos(FXint pos) const { + const FXchar* ptr=&buffer[(gapend-gapstart)&((~pos+gapstart)>>31)]; + if(pos<=0) return 0; + if(pos>=length) return length; + return (isUTF8(ptr[pos]) || --pos<=0 || isUTF8(ptr[pos]) || --pos<=0 || isUTF8(ptr[pos]) || --pos), pos; + } + // Decrement; a wide character does not cross the gap, so if pos is at // or below below the gap, we read from the segment below the gap FXint FXText::dec(FXint pos) const { const FXchar* ptr=&buffer[(gapend-gapstart)&((gapstart-pos)>>31)]; - return (--pos<=0 || FXISUTF8(ptr[pos]) || --pos<=0 || FXISUTF8(ptr[pos]) || --pos<=0 || FXISUTF8(ptr[pos]) || --pos), pos; + return (--pos<=0 || isUTF8(ptr[pos]) || --pos<=0 || isUTF8(ptr[pos]) || --pos<=0 || isUTF8(ptr[pos]) || --pos), pos; } @@ -651,7 +661,7 @@ FXint FXText::dec(FXint pos) const { // start under the gap the last character accessed is below the gap FXint FXText::inc(FXint pos) const { const FXchar* ptr=&buffer[(gapend-gapstart)&((~pos+gapstart)>>31)]; - return (++pos>=length || FXISUTF8(ptr[pos]) || ++pos>=length || FXISUTF8(ptr[pos]) || ++pos>=length || FXISUTF8(ptr[pos]) || ++pos), pos; + return (++pos>=length || isUTF8(ptr[pos]) || ++pos>=length || isUTF8(ptr[pos]) || ++pos>=length || isUTF8(ptr[pos]) || ++pos), pos; } /*******************************************************************************/ @@ -668,8 +678,8 @@ FXint FXText::inc(FXint pos) const { // Character width FXint FXText::charWidth(FXwchar ch,FXint indent) const { - if(__likely(' '<=ch)) return font->getCharWidth(ch); - if(__likely(ch=='\t')) return (tabwidth-indent%tabwidth); + if(' '<=ch) return font->getCharWidth(ch); + if(ch=='\t') return (tabwidth-indent%tabwidth); return font->getCharWidth('^')+font->getCharWidth(ch|0x40); } @@ -778,6 +788,19 @@ FXint FXText::posFromColumn(FXint start,FXint col) const { return start; } + +// Determine logical indent of text on line at start, up to +// given position pos. +FXint FXText::indentOfLine(FXint start,FXint pos) const { + FXint indent=0; FXuchar c; + FXASSERT(0<=start && pos<=length); + while(start>31)]; - if(pos<=0) return 0; - if(pos>=length) return length; - return (FXISUTF8(ptr[pos]) || --pos<=0 || FXISUTF8(ptr[pos]) || --pos<=0 || FXISUTF8(ptr[pos]) || --pos), pos; - } - /*******************************************************************************/ // Count number of columns; start should be on a row start @@ -1096,12 +1111,12 @@ FXint FXText::countCols(FXint start,FXint end) const { FXASSERT(0<=start && start<=end && end<=length); while(startgetFontHeight(); return result; @@ -1263,7 +1278,7 @@ void FXText::recompute(){ // Update text dimensions in terms of pixels and rows; note one extra // row always added, as there is always at least one row, even though // it may be empty of any characters. - textWidth=FXMAX(ww1,ww2); + textWidth=Math::imax(ww1,ww2); textHeight=hh1+hh2+hh; nrows=toprow+botrow+1; @@ -1504,10 +1519,10 @@ FXbool FXText::findText(const FXString& string,FXint* beg,FXint* end,FXint start // Search forward if(flgs&SEARCH_FORWARD){ if(start<=length){ - if(rex.search(buffer,length,FXMAX(start,0),length,FXRex::Normal,beg,end,npar)>=0) return true; + if(rex.search(buffer,length,Math::imax(start,0),length,FXRex::Normal,beg,end,npar)>=0) return true; } if((flgs&SEARCH_WRAP) && (start>0)){ - if(rex.search(buffer,length,0,FXMIN(start,length),FXRex::Normal,beg,end,npar)>=0) return true; + if(rex.search(buffer,length,0,Math::imin(start,length),FXRex::Normal,beg,end,npar)>=0) return true; } return false; } @@ -1515,10 +1530,10 @@ FXbool FXText::findText(const FXString& string,FXint* beg,FXint* end,FXint start // Search backward if(flgs&SEARCH_BACKWARD){ if(0<=start){ - if(rex.search(buffer,length,FXMIN(start,length),0,FXRex::Normal,beg,end,npar)>=0) return true; + if(rex.search(buffer,length,Math::imin(start,length),0,FXRex::Normal,beg,end,npar)>=0) return true; } if((flgs&SEARCH_WRAP) && (start=0) return true; + if(rex.search(buffer,length,length,Math::imax(start,0),FXRex::Normal,beg,end,npar)>=0) return true; } return false; } @@ -1949,8 +1964,8 @@ void FXText::setCursorPos(FXint pos,FXbool notify){ // Set cursor row, column void FXText::setCursorRowColumn(FXint row,FXint col,FXbool notify){ - row=FXCLAMP(0,row,nrows-1); - col=FXMAX(col,0); + row=Math::iclamp(0,row,nrows-1); + col=Math::imax(col,0); if((row!=cursorrow) || (col!=cursorvcol)){ FXint newstart=posFromRow(row); // Row start of new row FXint newpos=posFromColumn(newstart,col); // Position of column on that row @@ -2025,8 +2040,8 @@ void FXText::setAnchorPos(FXint pos){ // Set anchor row and column void FXText::setAnchorRowColumn(FXint row,FXint col){ - row=FXCLAMP(0,row,nrows-1); - col=FXMAX(col,0); + row=Math::iclamp(0,row,nrows-1); + col=Math::imax(col,0); if((row!=anchorrow) || (col!=anchorvcol)){ FXint newstart=posFromRow(row); // Row start of new row FXint newpos=posFromColumn(newstart,col); // Position of column on that row @@ -2157,7 +2172,7 @@ void FXText::mutation(FXint pos,FXint ncins,FXint ncdel,FXint nrins,FXint nrdel) // Changed text begins above first and ends below last visible line else{ - toprow=FXMAX(0,FXMIN(toprow,nrows-nvisrows)); + toprow=Math::iclamp(0,toprow,nrows-nvisrows); toppos=nextRow(0,toprow); keeppos=toppos; pos_y=-toprow*th; @@ -2242,7 +2257,7 @@ FXint FXText::changeEnd(FXint pos) const { } -// Replace m characters at pos by n characters +// Replace #del characters at pos by #ins characters void FXText::replace(FXint pos,FXint del,const FXchar *text,FXint ins,FXint style){ FXint nrdel,nrins,ncdel,ncins,wbeg,wend,diff,wdel,hdel,wins,hins,cursorstartpos,anchorstartpos; @@ -2264,7 +2279,7 @@ void FXText::replace(FXint pos,FXint del,const FXchar *text,FXint ins,FXint styl // Move the gap to current position movegap(pos); - // Grow the gap if needed + // Grow the gap if too small if(diff>(gapend-gapstart)){ sizegap(diff+MINSIZE); } // Modify the buffer @@ -2274,7 +2289,7 @@ void FXText::replace(FXint pos,FXint del,const FXchar *text,FXint ins,FXint styl gapend+=del; length+=diff; - // Shrink the gap to avoid getting too large + // Shrink the gap if too large if(MAXSIZE<(gapend-gapstart)){ sizegap(MAXSIZE); } // Measure stuff after change @@ -2291,7 +2306,7 @@ void FXText::replace(FXint pos,FXint del,const FXchar *text,FXint ins,FXint styl // Fix text metrics textHeight=textHeight+hins-hdel; - textWidth=FXMAX(textWidth,wins); + textWidth=Math::imax(textWidth,wins); // Keep anchorpos at same place relative to its surrounding text. // When inside the changed region, move it to the end of the change. @@ -2468,23 +2483,13 @@ FXint FXText::replaceStyledText(FXint pos,FXint del,const FXString& text,FXint s /*******************************************************************************/ -// Count number of characters equal to ch -static FXint countchars(const FXchar* beg,const FXchar* end,FXchar ch){ - FXint result=0; - while(begselect.endcol; } +/*******************************************************************************/ // Get selected text FXString FXText::getSelectedText() const { @@ -3589,7 +3746,6 @@ FXString FXText::getSelectedText() const { return FXString::null; } -/*******************************************************************************/ // Copy selection to clipboard FXbool FXText::copySelection(){ @@ -3615,21 +3771,18 @@ FXbool FXText::cutSelection(FXbool notify){ // Replace selection by other text FXbool FXText::replaceSelection(const FXString& text,FXbool notify){ - if(select.startpos<=select.endpos){ - FXint pos,cols,ins; - if(select.startcol<=select.endcol){ - cols=maxcolumns(text.text(),text.text()+text.length(),tabcolumns); - ins=replaceTextBlock(select.startpos,select.endpos,select.startcol,select.endcol,text,notify); - pos=posFromColumn(lineStart(select.startpos+ins),select.startcol+cols); - moveCursor(pos,notify); - return true; - } - if(select.startposselect.endcol) && (select.startposselect.endcol) && (select.startposselect.endpos) || (cursorpos<=select.startpos) || (select.endpos<=cursorpos)){ + if(!isPosSelected(cursorpos,cursorvcol)){ FXString string; // Try UTF-8, then UTF-16, then 8859-1 if(getDNDData(FROM_SELECTION,utf8Type,string) || getDNDData(FROM_SELECTION,utf16Type,string) || getDNDData(FROM_SELECTION,stringType,string)){ - FXint pos=cursorpos; - FXint ins; + FXint pos=cursorpos,ins; + + // Insert at vertical cursor + if((select.startcol<=select.endcol) && (select.startpos<=select.endpos)){ + FXint cols=maxColumns(string,tabcolumns); + if(isOverstrike()){ + ins=overstrikeTextBlock(select.startpos,select.endpos,select.startcol,string,notify); + } + else{ + ins=insertTextBlock(select.startpos,select.endpos,select.startcol,string,notify); + } + pos=posFromColumn(lineStart(select.startpos+ins),select.startcol+cols); + makePositionVisible(pos); + setCursorPos(pos,notify); + setAnchorPos(pos); + flashMatching(); + return true; + } // Overstrike mode, extent if(isOverstrike()){ // FIXME should overstrike always be block-mode? @@ -3703,8 +3869,7 @@ FXbool FXText::pasteClipboard(FXbool notify){ // Try UTF-8, then UTF-16, then 8859-1 if(getDNDData(FROM_CLIPBOARD,utf8Type,string) || getDNDData(FROM_CLIPBOARD,utf16Type,string) || getDNDData(FROM_CLIPBOARD,stringType,string)){ - FXint pos=cursorpos; - FXint ins; + FXint pos=cursorpos,ins; // De-DOS #ifdef WIN32 @@ -3716,6 +3881,20 @@ FXbool FXText::pasteClipboard(FXbool notify){ return true; } + // Insert at vertical cursor + if((select.startcol<=select.endcol) && (select.startpos<=select.endpos)){ + FXint cols=maxColumns(string,tabcolumns); + if(isOverstrike()){ + ins=overstrikeTextBlock(select.startpos,select.endpos,select.startcol,string,notify); + } + else{ + ins=insertTextBlock(select.startpos,select.endpos,select.startcol,string,notify); + } + pos=posFromColumn(lineStart(select.startpos+ins),select.startcol+cols); + moveCursor(pos,notify); + return true; + } + // Overstrike if(isOverstrike()){ // FIXME should overstrike always be block-mode? ins=overstruck(pos,pos,string.text(),string.length()); @@ -3724,7 +3903,7 @@ FXbool FXText::pasteClipboard(FXbool notify){ return true; } - // Default is insert + // Default is to insert at cursor ins=insertText(pos,string,notify); moveCursor(pos+ins,notify); return true; @@ -3833,9 +4012,9 @@ void FXText::eraseCursor(FXDCWindow& dc) const { dc.setFont(font); dc.setForeground(backColor); dc.fillRectangle(cursorx-2,cursory,tw+4,th); - cx=FXMAX(cursorx-2,getVisibleX()+marginleft); + cx=Math::imax(cursorx-2,getVisibleX()+marginleft); cy=getVisibleY()+margintop; - cw=FXMIN(cursorx+tw+2,getVisibleX()+getVisibleWidth()-marginright)-cx; + cw=Math::imin(cursorx+tw+2,getVisibleX()+getVisibleWidth()-marginright)-cx; ch=getVisibleHeight()-margintop-marginbottom; dc.setClipRectangle(cx,cy,cw,ch); FXASSERT(toprow<=cursorrow && cursorrowhandle(this,(select.startpos<=select.endpos)?FXSEL(SEL_COMMAND,ID_ENABLE):FXSEL(SEL_COMMAND,ID_DISABLE),nullptr); + FXbool selection=((select.startcolselect.endcol) && (select.startposhandle(this,selection?FXSEL(SEL_COMMAND,ID_ENABLE):FXSEL(SEL_COMMAND,ID_DISABLE),nullptr); return 1; } // Update somebody who works on the selection and change the text long FXText::onUpdHaveEditableSelection(FXObject* sender,FXSelector,void*){ - sender->handle(this,isEditable() && (select.startpos<=select.endpos)?FXSEL(SEL_COMMAND,ID_ENABLE):FXSEL(SEL_COMMAND,ID_DISABLE),nullptr); + FXbool selection=((select.startcolselect.endcol) && (select.startposhandle(this,isEditable() && selection?FXSEL(SEL_COMMAND,ID_ENABLE):FXSEL(SEL_COMMAND,ID_DISABLE),nullptr); return 1; } @@ -5407,7 +5588,7 @@ long FXText::onCmdCursorDown(FXObject*,FXSelector,void*){ // Page up long FXText::onCmdCursorPageUp(FXObject*,FXSelector,void*){ FXint col=(0<=prefcol) ? prefcol : cursorcol; - FXint lines=FXMAX(nvisrows-2,1); + FXint lines=Math::imax(nvisrows-2,1); setTopLine(prevRow(toppos,lines)); moveCursor(posFromColumn(prevRow(cursorpos,lines),col),true); prefcol=col; @@ -5418,7 +5599,7 @@ long FXText::onCmdCursorPageUp(FXObject*,FXSelector,void*){ // Page down long FXText::onCmdCursorPageDown(FXObject*,FXSelector,void*){ FXint col=(0<=prefcol) ? prefcol : cursorcol; - FXint lines=FXMAX(nvisrows-2,1); + FXint lines=Math::imax(nvisrows-2,1); setTopLine(nextRow(toppos,lines)); moveCursor(posFromColumn(nextRow(cursorpos,lines),col),true); prefcol=col; @@ -5503,7 +5684,7 @@ long FXText::onCmdCursorShiftDown(FXObject*,FXSelector,void*){ // Process cursor shift+page up long FXText::onCmdCursorShiftPageUp(FXObject*,FXSelector,void*){ FXint col=(0<=prefcol) ? prefcol : cursorcol; - FXint lines=FXMAX(nvisrows-2,1); + FXint lines=Math::imax(nvisrows-2,1); setTopLine(prevRow(toppos,lines)); moveCursorAndSelect(posFromColumn(prevRow(cursorpos,lines),col),SelectChars,true); prefcol=col; @@ -5514,7 +5695,7 @@ long FXText::onCmdCursorShiftPageUp(FXObject*,FXSelector,void*){ // Process cursor shift+page down long FXText::onCmdCursorShiftPageDown(FXObject*,FXSelector,void*){ FXint col=(0<=prefcol) ? prefcol : cursorcol; - FXint lines=FXMAX(nvisrows-2,1); + FXint lines=Math::imax(nvisrows-2,1); setTopLine(nextRow(toppos,lines)); moveCursorAndSelect(posFromColumn(nextRow(cursorpos,lines),col),SelectChars,true); prefcol=col; @@ -5610,7 +5791,7 @@ long FXText::onCmdInsertString(FXObject*,FXSelector,void* ptr){ FXint len=strlen(txt); FXint beg=cursorpos; FXint end=cursorpos; - FXint rows,cols,ins; + FXint rows,ins; FXString rep; // Position is selected @@ -5621,15 +5802,14 @@ long FXText::onCmdInsertString(FXObject*,FXSelector,void* ptr){ // Block selection if(select.startcol=select.endcol){ - start=lineStart(select.startpos); - string="\n"+extractText(start,select.startpos-start); - n=string.find_first_not_of(" \t\v\n"); - if(0<=n) string.trunc(n); +// Create indent string +static FXString makeIndentString(FXint indent,FXint tabcols){ + FXString result(' ',indent+1); + result[0]='\n'; + if(0select.endcol){ + FXint pos,start,indent; + pos=cursorpos; + if(isPosSelected(cursorpos)){ + pos=select.endpos; + } + start=lineStart(pos); + indent=indentOfLine(start,pos); // Indent to up to position, or first non-blank + string=makeIndentString(indent,(options&TEXT_NO_TABS)?0:tabcolumns); } return onCmdInsertString(this,FXSEL(SEL_COMMAND,ID_INSERT_STRING),(void*)string.text()); } @@ -5992,20 +6188,35 @@ long FXText::onCmdDeleteAll(FXObject*,FXSelector,void*){ /*******************************************************************************/ +// Shift block of lines from position start up to end by given indent +FXint FXText::shiftText(FXint startpos,FXint endpos,FXint shift,FXbool notify){ + if(0<=startpos && startposbeep(); @@ -6031,26 +6242,23 @@ long FXText::onCmdShiftText(FXObject*,FXSelector sel,void*){ // Make selected text upper case long FXText::onCmdChangeCase(FXObject*,FXSelector sel,void*){ if(isEditable()){ - FXint startpos,endpos,len; - FXint upper=(FXSELID(sel)==ID_UPPER_CASE); FXint curc=getCursorColumn(); FXint curr=getCursorRow(); - if(select.startpos<=select.endpos){ - startpos=select.startpos; - endpos=select.endpos; + if((select.startcolselect.endcol) && (select.startposbeep(); - } + getApp()->beep(); return 1; } @@ -6404,7 +6612,7 @@ void FXText::setWrapColumns(FXint cols){ // Set tab columns void FXText::setTabColumns(FXint cols){ - cols=FXCLAMP(1,cols,MAXTABCOLUMNS); + cols=Math::iclamp(1,cols,MAXTABCOLUMNS); if(cols!=tabcolumns){ tabcolumns=cols; tabwidth=tabcolumns*font->getTextWidth(" ",1); diff --git a/lib/FXTextCodec.cpp b/lib/FXTextCodec.cpp index d14e34e..e0210b6 100644 --- a/lib/FXTextCodec.cpp +++ b/lib/FXTextCodec.cpp @@ -21,6 +21,7 @@ #include "xincs.h" #include "fxver.h" #include "fxdefs.h" +#include "fxchar.h" #include "FXArray.h" #include "FXHash.h" #include "FXStream.h" diff --git a/lib/FXTextField.cpp b/lib/FXTextField.cpp index 443d6fe..60f836a 100644 --- a/lib/FXTextField.cpp +++ b/lib/FXTextField.cpp @@ -22,6 +22,7 @@ #include "fxver.h" #include "fxdefs.h" #include "fxkeys.h" +#include "fxchar.h" #include "fxmath.h" #include "fxascii.h" #include "fxunicode.h" @@ -426,7 +427,7 @@ FXint FXTextField::index(FXint x) const { else xx=mm-font->getTextWidth(contents.text(),contents.length())/2; xx+=shift; for(pos=0; posgetTextWidth(&contents[pos],contents.extent(pos)); + cw=font->getTextWidth(&contents[pos],wclen(&contents[pos])); if(x<(xx+(cw>>1))) break; xx+=cw; } diff --git a/lib/FXThread.cpp b/lib/FXThread.cpp index 349eb8a..dd1593a 100644 --- a/lib/FXThread.cpp +++ b/lib/FXThread.cpp @@ -21,6 +21,7 @@ #include "xincs.h" #include "fxver.h" #include "fxdefs.h" +#include "fxchar.h" #include "fxmath.h" #include "FXException.h" #include "FXString.h" @@ -285,6 +286,21 @@ void FXThread::yield(){ } +// Processor pause/back-off +void FXThread::pause(){ +#if defined(_WIN32) +#if defined(_MSC_VER) + YieldProcessor(); +#endif +#elif (defined(__GNUC__) || defined(__INTEL_COMPILER)) && (defined(__i386__) || defined(__x86_64__)) + __asm__ __volatile__("rep; nop\n" : : : "memory" ); +// _mm_pause(); +#elif defined(__GNUC__) && defined(__aarch64__) + __asm__ __volatile__("yield" ::: "memory"); +#endif + } + + #if defined(WIN32) // Convert 100ns since 01/01/1601 to ns since 01/01/1970 @@ -486,6 +502,7 @@ FXint FXThread::processors(){ SYSTEM_INFO info={{0}}; GetSystemInfo(&info); return info.dwNumberOfProcessors; +//return GetActiveProcessorCount(ALL_PROCESSOR_GROUPS); #elif defined(_SC_NPROCESSORS_ONLN) // Linux int result; if((result=sysconf(_SC_NPROCESSORS_ONLN))>0){ diff --git a/lib/FXTopWindow.cpp b/lib/FXTopWindow.cpp index ce82517..a42ce8c 100644 --- a/lib/FXTopWindow.cpp +++ b/lib/FXTopWindow.cpp @@ -21,6 +21,7 @@ #include "xincs.h" #include "fxver.h" #include "fxdefs.h" +#include "fxchar.h" #include "fxmath.h" #include "FXArray.h" #include "FXHash.h" @@ -238,8 +239,8 @@ void FXTopWindow::create(){ // In a perfect world this would be set in FXTopWindow, but for some strange reasons // some window-managers (e.g. fvwm) this will be too late and they will not recognize them. XClassHint hint; - hint.res_name=(char*)getApp()->getAppName().text(); // "FoxApp" - hint.res_class=(char*)getApp()->getVendorName().text(); // "FoxWindow" + hint.res_name=const_cast(getApp()->getAppName().text()); // "FoxApp" + hint.res_class=const_cast(getApp()->getVendorName().text()); // "FoxWindow" XSetClassHint((Display*)getApp()->getDisplay(),xid,&hint); // Set client machine name and application pid @@ -1533,12 +1534,14 @@ long FXTopWindow::onCmdClose(FXObject*,FXSelector,void*){ // Session is about to close, give opportunity to save data long FXTopWindow::onSessionNotify(FXObject*,FXSelector,void* ptr){ + FXTRACE((100,"%s::onSessionNotify %p\n",getClassName(),this)); return target && target->tryHandle(this,FXSEL(SEL_SESSION_NOTIFY,message),ptr); } // Session has closed, close the window with prejudice long FXTopWindow::onSessionClosed(FXObject*,FXSelector,void* ptr){ + FXTRACE((100,"%s::onSessionClosed %p\n",getClassName(),this)); if(target) target->tryHandle(this,FXSEL(SEL_SESSION_CLOSED,message),ptr); close(false); return 1; diff --git a/lib/FXTreeList.cpp b/lib/FXTreeList.cpp index fc50842..7973b91 100644 --- a/lib/FXTreeList.cpp +++ b/lib/FXTreeList.cpp @@ -262,7 +262,7 @@ FXint FXTreeItem::getNumChildren() const { // Get item (logically) below this one FXTreeItem* FXTreeItem::getBelow() const { - FXTreeItem* item=(FXTreeItem*)this; + FXTreeItem* item=const_cast(this); if(first) return first; while(!item->next && item->parent) item=item->parent; return item->next; @@ -1854,25 +1854,25 @@ long FXTreeList::onTripleClicked(FXObject*,FXSelector,void* ptr){ // Sort items in ascending order FXint FXTreeList::ascending(const FXTreeItem* a,const FXTreeItem* b){ - return compare(a->getText(),b->getText()); + return FXString::compare(a->getText(),b->getText()); } // Sort items in descending order FXint FXTreeList::descending(const FXTreeItem* a,const FXTreeItem* b){ - return compare(b->getText(),a->getText()); + return FXString::compare(b->getText(),a->getText()); } // Sort ascending order, case insensitive FXint FXTreeList::ascendingCase(const FXTreeItem* a,const FXTreeItem* b){ - return comparecase(a->getText(),b->getText()); + return FXString::comparecase(a->getText(),b->getText()); } // Sort descending order, case insensitive FXint FXTreeList::descendingCase(const FXTreeItem* a,const FXTreeItem* b){ - return comparecase(b->getText(),a->getText()); + return FXString::comparecase(b->getText(),a->getText()); } @@ -2444,39 +2444,39 @@ void FXTreeList::clearItems(FXbool notify){ } -typedef FXint (*FXCompareFunc)(const FXString&,const FXString&,FXint); +typedef FXint (*FXCompareFunc)(const FXchar*,const FXchar*,FXint); // Get item by name -FXTreeItem* FXTreeList::findItem(const FXString& text,FXTreeItem* start,FXuint flgs) const { - FXCompareFunc comparefunc=(flgs&SEARCH_IGNORECASE) ? (FXCompareFunc)comparecase : (FXCompareFunc)compare; +FXTreeItem* FXTreeList::findItem(const FXString& string,FXTreeItem* start,FXuint flgs) const { + FXCompareFunc comparefunc=(flgs&SEARCH_IGNORECASE) ? (FXCompareFunc)FXString::comparecase : (FXCompareFunc)FXString::compare; FXTreeItem *item; FXint len; if(firstitem){ - len=(flgs&SEARCH_PREFIX)?text.length():2147483647; + len=(flgs&SEARCH_PREFIX)?string.length():2147483647; if(flgs&SEARCH_BACKWARD){ item=start; while(item!=nullptr){ - if((*comparefunc)(item->getText(),text,len)==0) return item; + if((*comparefunc)(item->getText().text(),string.text(),len)==0) return item; item=item->getAbove(); } if(start && !(flgs&SEARCH_WRAP)) return nullptr; for(item=lastitem; item->getLast(); item=item->getLast()){} while(item!=start){ - if((*comparefunc)(item->getText(),text,len)==0) return item; + if((*comparefunc)(item->getText().text(),string.text(),len)==0) return item; item=item->getAbove(); } } else{ item=start; while(item!=nullptr){ - if((*comparefunc)(item->getText(),text,len)==0) return item; + if((*comparefunc)(item->getText().text(),string.text(),len)==0) return item; item=item->getBelow(); } if(start && !(flgs&SEARCH_WRAP)) return nullptr; item=firstitem; while(item!=start){ - if((*comparefunc)(item->getText(),text,len)==0) return item; + if((*comparefunc)(item->getText().text(),string.text(),len)==0) return item; item=item->getBelow(); } } diff --git a/lib/FXTreeListBox.cpp b/lib/FXTreeListBox.cpp index 23e37df..279e5f3 100644 --- a/lib/FXTreeListBox.cpp +++ b/lib/FXTreeListBox.cpp @@ -549,8 +549,8 @@ void FXTreeListBox::clearItems(FXbool notify){ // Get item by name -FXTreeItem* FXTreeListBox::findItem(const FXString& text,FXTreeItem* start,FXuint flgs) const { - return tree->findItem(text,start,flgs); +FXTreeItem* FXTreeListBox::findItem(const FXString& string,FXTreeItem* start,FXuint flgs) const { + return tree->findItem(string,start,flgs); } diff --git a/lib/FXURL.cpp b/lib/FXURL.cpp index 3fa2827..201b5aa 100644 --- a/lib/FXURL.cpp +++ b/lib/FXURL.cpp @@ -438,7 +438,7 @@ FXString FXURL::fileToURL(const FXString& file){ // Return filename from URL, empty if url is not a local file FXString FXURL::fileFromURL(const FXString& string){ - if(comparecase(string,"file:",5)==0){ + if(FXString::comparecase(string,"file:",5)==0){ #ifdef WIN32 URL url(string); if(url.host[0]=nsrc) return 0; if(__unlikely(0x80<=w)){ if(__unlikely(w<0xC0)) return 0; if(__unlikely(n>=nsrc)) return 0; - if(__unlikely(!FXISFOLLOWUTF8(src[n]))) return 0; + if(__unlikely(!followUTF8(src[n]))) return 0; w=(w<<6)^(FXuchar)src[n++]^0x3080; if(__unlikely(0x800<=w)){ if(__unlikely(n>=nsrc)) return 0; - if(__unlikely(!FXISFOLLOWUTF8(src[n]))) return 0; + if(__unlikely(!followUTF8(src[n]))) return 0; w=(w<<6)^(FXuchar)src[n++]^0x20080; if(__unlikely(0x10000<=w)){ if(__unlikely(n>=nsrc)) return 0; - if(__unlikely(!FXISFOLLOWUTF8(src[n]))) return 0; + if(__unlikely(!followUTF8(src[n]))) return 0; w=(w<<6)^(FXuchar)src[n++]^0x400080; if(__unlikely(0x110000<=w)) return 0; } diff --git a/lib/FXUndoList.cpp b/lib/FXUndoList.cpp index 1cca603..ad0fb9c 100644 --- a/lib/FXUndoList.cpp +++ b/lib/FXUndoList.cpp @@ -55,7 +55,7 @@ - To keep track of when we get back to an "unmodified" state, a mark can be set. The mark is basically a counter which is incremented with every undo record added, and decremented when undoing a command. - When we get back to 0, we are back to the unmodified state. + When we get back to 0, we are back to the "unmodified" state. If, after setting the mark, we have called undo(), then the mark can be reached by calling redo(). diff --git a/lib/FXVariant.cpp b/lib/FXVariant.cpp index 3ae09ef..fe836c4 100644 --- a/lib/FXVariant.cpp +++ b/lib/FXVariant.cpp @@ -74,6 +74,17 @@ the size of the biggest type, anyway. */ +// Largest and smallest long values +#ifndef LLONG_MAX +#define LLONG_MAX FXLONG(9223372036854775807) +#endif +#ifndef LLONG_MIN +#define LLONG_MIN (-LLONG_MAX-FXLONG(1)) +#endif +#ifndef ULLONG_MAX +#define ULLONG_MAX FXULONG(18446744073709551615) +#endif + using namespace FX; namespace FX { @@ -85,228 +96,268 @@ const FXVariant FXVariant::null; // Initialize with default value for type t -FXVariant& FXVariant::init(VType t){ - type=t; - switch(type){ - case VNull: - case VBool: - case VChar: - case VInt: - case VUInt: - case VLong: - case VULong: - case VPointer: +FXbool FXVariant::init(Type t){ + switch(t){ + case BoolType: + case CharType: + case IntType: + case UIntType: + case LongType: + case ULongType: + case PointerType: value.u=0; - break; - case VFloat: - case VDouble: + type=t; + return true; + case FloatType: + case DoubleType: value.d=0.0; - break; - case VString: + type=t; + return true; + case StringType: construct(reinterpret_cast(&value.p)); - break; - case VArray: + type=t; + return true; + case ArrayType: construct(reinterpret_cast(&value.p)); - break; - case VMap: + type=t; + return true; + case MapType: construct(reinterpret_cast(&value.p)); - break; + type=t; + return true; + default: + return true; } - return *this; + return true; + } + + +// Clear the data +FXbool FXVariant::clear(){ + switch(type){ + case BoolType: + case CharType: + case IntType: + case UIntType: + case LongType: + case ULongType: + case PointerType: + case FloatType: + case DoubleType: + value.u=0L; + type=NullType; + return true; + case StringType: + destruct(reinterpret_cast(&value.p)); + value.u=0L; + type=NullType; + return true; + case ArrayType: + destruct(reinterpret_cast(&value.p)); + value.u=0L; + type=NullType; + return true; + case MapType: + destruct(reinterpret_cast(&value.p)); + value.u=0L; + type=NullType; + return true; + default: + return true; + } + return true; } // Make a copy -FXVariant& FXVariant::copy(const FXVariant& other){ +FXVariant& FXVariant::assign(const FXVariant& other){ if(this!=&other){ - reset(); - type=other.type; - switch(type){ - case VNull: - case VBool: - case VChar: - case VInt: - case VUInt: - case VLong: - case VULong: - case VFloat: - case VDouble: - case VPointer: + clear(); + switch(other.type){ + case BoolType: + case CharType: + case IntType: + case UIntType: + case LongType: + case ULongType: + case FloatType: + case DoubleType: + case PointerType: value=other.value; - break; - case VString: + type=other.type; + return *this; + case StringType: construct(reinterpret_cast(&value.p),*reinterpret_cast(&other.value.p)); - break; - case VArray: + type=other.type; + return *this; + case ArrayType: construct(reinterpret_cast(&value.p),*reinterpret_cast(&other.value.p)); - break; - case VMap: + type=other.type; + return *this; + case MapType: construct(reinterpret_cast(&value.p),*reinterpret_cast(&other.value.p)); - break; + type=other.type; + return *this; + default: + return *this; } } return *this; } + +// Adopt variant from another +FXVariant& FXVariant::adopt(FXVariant& other){ + if(this!=&other){ + swap(value,other.value); + swap(type,other.type); + other.clear(); + } + return *this; + } + /*******************************************************************************/ -// Initialize Null variant -FXVariant::FXVariant():type(VNull){ +// Initialize null variant +FXVariant::FXVariant():type(NullType){ FXASSERT(sizeof(value)>=sizeof(FXString) && sizeof(value)>=sizeof(FXVariantArray) && sizeof(value)>=sizeof(FXVariantMap)); value.u=0; } // Copy constructor -FXVariant::FXVariant(const FXVariant& other):type(VNull){ +FXVariant::FXVariant(const FXVariant& other):type(NullType){ FXASSERT(sizeof(value)>=sizeof(FXString) && sizeof(value)>=sizeof(FXVariantArray) && sizeof(value)>=sizeof(FXVariantMap)); - copy(other); + assign(other); } // Construct and initialize with bool -FXVariant::FXVariant(FXbool val):type(VBool){ +FXVariant::FXVariant(FXbool val):type(BoolType){ FXASSERT(sizeof(value)>=sizeof(FXString) && sizeof(value)>=sizeof(FXVariantArray) && sizeof(value)>=sizeof(FXVariantMap)); value.u=val; } // Construct and initialize with char -FXVariant::FXVariant(FXchar val):type(VChar){ +FXVariant::FXVariant(FXchar val):type(CharType){ FXASSERT(sizeof(value)>=sizeof(FXString) && sizeof(value)>=sizeof(FXVariantArray) && sizeof(value)>=sizeof(FXVariantMap)); value.u=val; } // Construct and initialize with int -FXVariant::FXVariant(FXint val):type(VInt){ +FXVariant::FXVariant(FXint val):type(IntType){ FXASSERT(sizeof(value)>=sizeof(FXString) && sizeof(value)>=sizeof(FXVariantArray) && sizeof(value)>=sizeof(FXVariantMap)); value.i=val; } // Construct and initialize with unsigned int -FXVariant::FXVariant(FXuint val):type(VUInt){ +FXVariant::FXVariant(FXuint val):type(UIntType){ FXASSERT(sizeof(value)>=sizeof(FXString) && sizeof(value)>=sizeof(FXVariantArray) && sizeof(value)>=sizeof(FXVariantMap)); value.u=val; } // Construct and initialize with long -FXVariant::FXVariant(FXlong val):type(VLong){ +FXVariant::FXVariant(FXlong val):type(LongType){ FXASSERT(sizeof(value)>=sizeof(FXString) && sizeof(value)>=sizeof(FXVariantArray) && sizeof(value)>=sizeof(FXVariantMap)); value.i=val; } // Construct and initialize with unsigned long -FXVariant::FXVariant(FXulong val):type(VULong){ +FXVariant::FXVariant(FXulong val):type(ULongType){ FXASSERT(sizeof(value)>=sizeof(FXString) && sizeof(value)>=sizeof(FXVariantArray) && sizeof(value)>=sizeof(FXVariantMap)); value.u=val; } // Construct and initialize with float -FXVariant::FXVariant(FXfloat val):type(VFloat){ +FXVariant::FXVariant(FXfloat val):type(FloatType){ FXASSERT(sizeof(value)>=sizeof(FXString) && sizeof(value)>=sizeof(FXVariantArray) && sizeof(value)>=sizeof(FXVariantMap)); value.d=val; } // Construct and initialize with double -FXVariant::FXVariant(FXdouble val):type(VDouble){ +FXVariant::FXVariant(FXdouble val):type(DoubleType){ FXASSERT(sizeof(value)>=sizeof(FXString) && sizeof(value)>=sizeof(FXVariantArray) && sizeof(value)>=sizeof(FXVariantMap)); value.d=val; } // Construct and initialize with pointer -FXVariant::FXVariant(FXptr val):type(VPointer){ +FXVariant::FXVariant(FXptr val):type(PointerType){ FXASSERT(sizeof(value)>=sizeof(FXString) && sizeof(value)>=sizeof(FXVariantArray) && sizeof(value)>=sizeof(FXVariantMap)); value.p=val; } // Construct and initialize with string -FXVariant::FXVariant(const FXchar *val):type(VString){ +FXVariant::FXVariant(const FXchar *val):type(StringType){ FXASSERT(sizeof(value)>=sizeof(FXString) && sizeof(value)>=sizeof(FXVariantArray) && sizeof(value)>=sizeof(FXVariantMap)); construct(reinterpret_cast(&value.p),val); } // Construct and initialize with string -FXVariant::FXVariant(const FXString& val):type(VString){ +FXVariant::FXVariant(const FXString& val):type(StringType){ FXASSERT(sizeof(value)>=sizeof(FXString) && sizeof(value)>=sizeof(FXVariantArray) && sizeof(value)>=sizeof(FXVariantMap)); construct(reinterpret_cast(&value.p),val); } - -// Construct and initialize with array -FXVariant::FXVariant(const FXVariantArray& val):type(VArray){ - FXASSERT(sizeof(value)>=sizeof(FXString) && sizeof(value)>=sizeof(FXVariantArray) && sizeof(value)>=sizeof(FXVariantMap)); - construct(reinterpret_cast(&value.p),val); - } - - -// Construct and initialize with map -FXVariant::FXVariant(const FXVariantMap& val):type(VMap){ - FXASSERT(sizeof(value)>=sizeof(FXString) && sizeof(value)>=sizeof(FXVariantArray) && sizeof(value)>=sizeof(FXVariantMap)); - construct(reinterpret_cast(&value.p),val); - } - /*******************************************************************************/ // Change type -void FXVariant::setType(VType t){ - reset(); +void FXVariant::setType(Type t){ + clear(); init(t); } // Return size of array FXival FXVariant::no() const { - return (type==VArray) ? reinterpret_cast(&value.p)->no() : 0; + return (type==ArrayType) ? reinterpret_cast(&value.p)->no() : 0; } // Change number of elements in array FXbool FXVariant::no(FXival n){ - if(type!=VArray){ - reset(); - init(VArray); - } + if(type!=ArrayType){ clear(); init(ArrayType); } return reinterpret_cast(&value.p)->no(n); } // Check if key is mapped FXbool FXVariant::has(const FXchar* key) const { - return (type==VMap) && (reinterpret_cast(&value.p)->has(key)); + return (type==MapType) && (reinterpret_cast(&value.p)->has(key)); } // Convert to bool FXbool FXVariant::toBool() const { switch(type){ - case VBool: - case VChar: - case VInt: - case VUInt: - case VLong: - case VULong: - case VPointer: - return !!value.u; - case VFloat: - case VDouble: - return !!value.d; - case VString: - return !reinterpret_cast(&value.p)->empty(); // True for non-empty string - case VArray: - return !!reinterpret_cast(&value.p)->no(); // True for non-empty array - case VMap: - return !reinterpret_cast(&value.p)->empty(); // True for non-empty map + case BoolType: + case CharType: + case IntType: + case UIntType: + case LongType: + case ULongType: + case PointerType: + return !!value.u; // True if non-0 + case FloatType: + case DoubleType: + return !!value.d; // True if non-0 + case StringType: + return !asString().empty(); // True for non-empty string + case ArrayType: + return !!asArray().no(); // True for non-empty array + case MapType: + return !asMap().empty(); // True for non-empty map default: - return false; + return false; // Always false } return false; } @@ -314,137 +365,205 @@ FXbool FXVariant::toBool() const { // Convert to pointer FXptr FXVariant::toPtr() const { - return (type==VPointer) ? value.p : nullptr; + return (type==PointerType) ? value.p : nullptr; // NULL anything not a pointer } // Convert to int FXint FXVariant::toInt(FXbool* ok) const { - return (FXint)toLong(ok); + FXbool flag=false; + FXlong result=0; + switch(type){ + case BoolType: + case CharType: + case IntType: + case UIntType: + case LongType: + case ULongType: + result=value.i; + if(__unlikely(result>INT_MAX)){ result=INT_MAX; break; } + if(__unlikely(result=2147483648.0)){ result=INT_MAX; break; } + result=Math::lrint(value.d); // Nearest int + flag=true; + break; + case StringType: + return asString().toInt(10,ok); + default: + break; + } + if(__unlikely(ok)){ *ok=flag; } + return (FXint)result; } // Convert to unsigned int FXuint FXVariant::toUInt(FXbool* ok) const { - return (FXuint)toULong(ok); + FXbool flag=false; + FXlong result=0; + switch(type){ + case BoolType: + case CharType: + case IntType: + case UIntType: + case LongType: + case ULongType: + result=value.i; + if(__unlikely(result<=0)){ result=0; break; } + if(__unlikely(result>=UINT_MAX)){ result=UINT_MAX; break; } + flag=true; + break; + case FloatType: + case DoubleType: + if(__unlikely(value.d<0.0)){ result=0; break; } + if(__unlikely(value.d>=4294967296.0)){ result=UINT_MAX; break; } + result=Math::lrint(value.d); // Nearest unsigned int + flag=true; + break; + case StringType: + return asString().toUInt(10,ok); + default: + break; + } + if(__unlikely(ok)){ *ok=flag; } + return (FXuint)result; } // Convert to long FXlong FXVariant::toLong(FXbool* ok) const { + FXbool flag=false; + FXlong result=0; switch(type){ - case VBool: - case VChar: - case VInt: - case VUInt: - case VLong: - case VULong: - if(ok) *ok=true; - return value.i; - case VFloat: - case VDouble: - if(ok) *ok=true; - return (FXlong)value.d; - case VString: - return reinterpret_cast(&value.p)->toLong(10,ok); + case BoolType: + case CharType: + case IntType: + case UIntType: + case LongType: + case ULongType: + result=value.i; + flag=true; + break; + case FloatType: + case DoubleType: + if(__unlikely(value.d<-9223372036854775808.0)){ result=LLONG_MIN; break; } + if(__unlikely(value.d>=9223372036854775808.0)){ result=LLONG_MAX; break; } + result=Math::lrint(value.d); // Nearest long + flag=true; + break; + case StringType: + return asString().toLong(10,ok); default: - if(ok) *ok=false; - return 0; + break; } - return 0; + if(__unlikely(ok)){ *ok=flag; } + return result; } // Convert to unsigned long FXulong FXVariant::toULong(FXbool* ok) const { + FXbool flag=false; + FXulong result=0; switch(type){ - case VBool: - case VChar: - case VInt: - case VUInt: - case VLong: - case VULong: - if(ok) *ok=true; - return value.u; - case VFloat: - case VDouble: - if(ok) *ok=true; - return (FXulong)value.d; - case VString: - return reinterpret_cast(&value.p)->toULong(10,ok); + case BoolType: + case CharType: + case IntType: + case UIntType: + case LongType: + case ULongType: + result=value.u; + flag=true; + break; + case FloatType: + case DoubleType: + if(__unlikely(value.d<0.0)){ result=0; break; } + if(__unlikely(value.d>=18446744073709551616.0)){ result=ULLONG_MAX; break; } + result=(FXulong)(value.d+0.5); // Nearest unsigned long + flag=true; + break; + case StringType: + return asString().toULong(10,ok); default: - if(ok) *ok=false; - return 0; + break; } - return 0; + if(__unlikely(ok)){ *ok=flag; } + return result; } // Convert to float FXfloat FXVariant::toFloat(FXbool* ok) const { + FXbool flag=false; + FXfloat result=0.0f; switch(type){ - case VBool: - case VInt: - case VLong: - if(ok) *ok=true; - return (FXfloat)value.i; - case VChar: - case VUInt: - case VULong: - if(ok) *ok=true; -#if _MSC_VER <= 1200 - return (FXfloat)(FXuint)value.u; -#else - return (FXfloat)value.u; -#endif - case VFloat: - case VDouble: - if(ok) *ok=true; - return (FXfloat)value.d; - case VString: - return reinterpret_cast(&value.p)->toFloat(ok); + case BoolType: + case IntType: + case LongType: + result=(FXfloat)value.i; + flag=true; + break; + case CharType: + case UIntType: + case ULongType: + result=(FXfloat)value.u; + flag=true; + break; + case FloatType: + case DoubleType: + result=(FXfloat)value.d; + flag=true; + break; + case StringType: + return asString().toFloat(ok); default: - if(ok) *ok=false; - return 0.0f; + break; } - return 0.0f; + if(__unlikely(ok)){ *ok=flag; } + return result; } // Convert to double FXdouble FXVariant::toDouble(FXbool* ok) const { + FXbool flag=false; + FXdouble result=0.0; switch(type){ - case VBool: - case VInt: - case VLong: - if(ok) *ok=true; - return (FXdouble)value.i; - case VChar: - case VUInt: - case VULong: - if(ok) *ok=true; -#if _MSC_VER <= 1200 - return (FXdouble)(FXuint)value.u; -#else - return (FXdouble)value.u; -#endif - case VFloat: - case VDouble: - if(ok) *ok=true; - return value.d; - case VString: - return reinterpret_cast(&value.p)->toDouble(ok); + case BoolType: + case IntType: + case LongType: + result=(FXdouble)value.i; + flag=true; + break; + case CharType: + case UIntType: + case ULongType: + result=(FXdouble)value.u; + flag=true; + break; + case FloatType: + case DoubleType: + result=value.d; + flag=true; + break; + case StringType: + return asString().toDouble(ok); default: - if(ok) *ok=false; - return 0.0; + break; } - return 0.0; + if(__unlikely(ok)){ *ok=flag; } + return result; } // Convert to char pointer const FXchar* FXVariant::toChars() const { - return (type==VString) ? value.s : FXString::null; + return (type==StringType) ? value.s : FXString::null; } @@ -452,27 +571,27 @@ const FXchar* FXVariant::toChars() const { FXString FXVariant::toString(FXbool* ok) const { const FXchar truth[2][6]={"false","true"}; switch(type){ - case VBool: + case BoolType: if(ok) *ok=true; return FXString(truth[value.u&1]); - case VChar: + case CharType: if(ok) *ok=true; return FXString((FXchar)value.u,1); - case VInt: - case VLong: + case IntType: + case LongType: if(ok) *ok=true; return FXString::value(value.i); - case VUInt: - case VULong: + case UIntType: + case ULongType: if(ok) *ok=true; return FXString::value(value.u); - case VFloat: - case VDouble: + case FloatType: + case DoubleType: if(ok) *ok=true; return FXString::value(value.d,16); - case VString: + case StringType: if(ok) *ok=true; - return *reinterpret_cast(&value.p); + return asString(); default: if(ok) *ok=false; return FXString::null; @@ -484,216 +603,154 @@ FXString FXVariant::toString(FXbool* ok) const { // Assign with bool FXVariant& FXVariant::operator=(FXbool val){ - reset(); + clear(); value.u=val; - type=VBool; + type=BoolType; return *this; } // Assign with char FXVariant& FXVariant::operator=(FXchar val){ - reset(); + clear(); value.u=val; - type=VChar; + type=CharType; return *this; } // Assign with int FXVariant& FXVariant::operator=(FXint val){ - reset(); + clear(); value.i=val; - type=VInt; + type=IntType; return *this; } // Assign with unsigned int FXVariant& FXVariant::operator=(FXuint val){ - reset(); + clear(); value.u=val; - type=VUInt; + type=UIntType; return *this; } // Assign with long FXVariant& FXVariant::operator=(FXlong val){ - reset(); + clear(); value.i=val; - type=VLong; + type=LongType; return *this; } // Assign with unsigned long FXVariant& FXVariant::operator=(FXulong val){ - reset(); + clear(); value.u=val; - type=VULong; + type=ULongType; return *this; } // Assign with float FXVariant& FXVariant::operator=(FXfloat val){ - reset(); + clear(); value.d=val; - type=VFloat; + type=FloatType; return *this; } // Assign with double FXVariant& FXVariant::operator=(FXdouble val){ - reset(); + clear(); value.d=val; - type=VDouble; + type=DoubleType; return *this; } // Assign with pointer FXVariant& FXVariant::operator=(FXptr val){ - reset(); + clear(); value.p=val; - type=VPointer; + type=PointerType; return *this; } // Assign with string FXVariant& FXVariant::operator=(const FXchar* val){ - reset(); + clear(); construct(reinterpret_cast(&value.p),val); - type=VString; + type=StringType; return *this; } // Assign with string FXVariant& FXVariant::operator=(const FXString& val){ - reset(); + clear(); construct(reinterpret_cast(&value.p),val); - type=VString; + type=StringType; return *this; } -// Assign with array -FXVariant& FXVariant::operator=(const FXVariantArray& val){ - reset(); - construct(reinterpret_cast(&value.p),val); - type=VArray; - return *this; - } - - -// Assign with map -FXVariant& FXVariant::operator=(const FXVariantMap& val){ - reset(); - construct(reinterpret_cast(&value.p),val); - type=VMap; - return *this; - } - -/*******************************************************************************/ - // Assign with variant FXVariant& FXVariant::operator=(const FXVariant& val){ - return copy(val); + return assign(val); } +/*******************************************************************************/ -// Adopt variant from another -FXVariant& FXVariant::adopt(FXVariant& other){ - if(this!=&other){ - reset(); - init(other.type); - switch(type){ - case VNull: - case VBool: - case VChar: - case VInt: - case VUInt: - case VLong: - case VULong: - case VPointer: - case VFloat: - case VDouble: - value=other.value; - break; - case VString: - reinterpret_cast(&value.p)->adopt(*reinterpret_cast(&other.value.p)); - break; - case VArray: - reinterpret_cast(&value.p)->adopt(*reinterpret_cast(&other.value.p)); - break; - case VMap: - reinterpret_cast(&value.p)->adopt(*reinterpret_cast(&other.value.p)); - break; - } - other.reset(); +// Remove entry from the table +FXbool FXVariant::remove(const FXchar* key){ + if(type==MapType && key){ + return reinterpret_cast(&value.p)->remove(key); } - return *this; - } - - -// Adopt variant array -FXVariant& FXVariant::adopt(FXVariantArray& other){ - reset(); - init(VArray); - reinterpret_cast(&value.p)->adopt(other); - return *this; + return false; } -// Adopt a variant map -FXVariant& FXVariant::adopt(FXVariantMap& other){ - reset(); - init(VMap); - reinterpret_cast(&value.p)->adopt(other); - return *this; +// Erase entry at pos in the table +FXbool FXVariant::erase(FXival idx){ + if(type==ArrayType && 0<=idx && reinterpret_cast(&value.p)->no()){ + return reinterpret_cast(&value.p)->erase(idx); + } + return false; } /*******************************************************************************/ // Return value of object member FXVariant& FXVariant::at(const FXchar* key){ - if(type!=VMap){ - reset(); - init(VMap); - } + if(type!=MapType){ clear(); init(MapType); } return reinterpret_cast(&value.p)->at(key); } // Return value of object member const FXVariant& FXVariant::at(const FXchar* key) const { - if(type==VMap){ - return reinterpret_cast(&value.p)->at(key); - } - return FXVariant::null; + if(type!=MapType){ return FXVariant::null; } + return reinterpret_cast(&value.p)->at(key); } // Return value of object member FXVariant& FXVariant::at(const FXString& key){ - if(type!=VMap){ - reset(); - init(VMap); - } + if(type!=MapType){ clear(); init(MapType); } return reinterpret_cast(&value.p)->at(key); } // Return value of object member const FXVariant& FXVariant::at(const FXString& key) const { - if(type==VMap){ - return reinterpret_cast(&value.p)->at(key); - } - return FXVariant::null; + if(type!=MapType){ return FXVariant::null; } + return reinterpret_cast(&value.p)->at(key); } /*******************************************************************************/ @@ -701,10 +758,7 @@ const FXVariant& FXVariant::at(const FXString& key) const { // Return value of array member FXVariant& FXVariant::at(FXival idx){ if(idx<0){ throw FXRangeException("FXVariant: index out of range\n"); } - if(type!=VArray){ - reset(); - init(VArray); - } + if(type!=ArrayType){ clear(); init(ArrayType); } if(idx>=reinterpret_cast(&value.p)->no()){ if(!reinterpret_cast(&value.p)->append(FXVariant::null,idx-reinterpret_cast(&value.p)->no()+1)){ throw FXMemoryException("FXVariant: out of memory\n"); @@ -717,7 +771,7 @@ FXVariant& FXVariant::at(FXival idx){ // Return value of array member const FXVariant& FXVariant::at(FXival idx) const { if(idx<0){ throw FXRangeException("FXVariant: index out of range\n"); } - if(type==VArray && idx(&value.p)->no()){ + if(type==ArrayType && idx(&value.p)->no()){ return reinterpret_cast(&value.p)->at(idx); } return FXVariant::null; @@ -725,68 +779,9 @@ const FXVariant& FXVariant::at(FXival idx) const { /*******************************************************************************/ -// Clear the data -void FXVariant::clear(){ - switch(type){ - case VNull: - case VBool: - case VChar: - case VInt: - case VUInt: - case VLong: - case VULong: - case VPointer: - value.u=0; - break; - case VFloat: - case VDouble: - value.d=0.0; - break; - case VString: - reinterpret_cast(&value.p)->clear(); - break; - case VArray: - reinterpret_cast(&value.p)->clear(); - break; - case VMap: - reinterpret_cast(&value.p)->clear(); - break; - } - } - - -// Reset to Null -void FXVariant::reset(){ - switch(type){ - case VNull: - case VBool: - case VChar: - case VInt: - case VUInt: - case VLong: - case VULong: - case VFloat: - case VDouble: - case VPointer: - break; - case VString: - destruct(reinterpret_cast(&value.p)); - break; - case VArray: - destruct(reinterpret_cast(&value.p)); - break; - case VMap: - destruct(reinterpret_cast(&value.p)); - break; - } - value.u=0; - type=VNull; - } - - // Destroy FXVariant::~FXVariant(){ - reset(); + clear(); } } diff --git a/lib/FXVariantMap.cpp b/lib/FXVariantMap.cpp index 2a62028..c75f9cb 100644 --- a/lib/FXVariantMap.cpp +++ b/lib/FXVariantMap.cpp @@ -60,7 +60,7 @@ - Similar to FXDictionary; reimplemented to support FXVariant as payload. */ -#define EMPTY ((Entry*)(__variantmap__empty__+3)) +#define EMPTY (const_cast((const Entry*)(__variantmap__empty__+3))) #define BSHIFT 5 using namespace FX; @@ -73,7 +73,7 @@ namespace FX { // Empty dictionary table value extern const FXint __string__empty__[]; extern const FXival __variantmap__empty__[]; -const FXival __variantmap__empty__[8]={1,0,1,(FXival)(__string__empty__+1),0,0,0,0}; +const FXival __variantmap__empty__[12]={1,0,1,(FXival)(__string__empty__+1),0,0,0,0,0,0,0,0}; // Adjust the size of the table @@ -138,14 +138,14 @@ FXbool FXVariantMap::resize(FXival n){ // Construct empty map FXVariantMap::FXVariantMap():table(EMPTY){ FXASSERT(sizeof(FXVariantMap)==sizeof(FXptr)); - FXASSERT(sizeof(Entry)<=sizeof(FXival)*4); + FXASSERT(sizeof(Entry)<=sizeof(FXival)*8); } // Construct from another map FXVariantMap::FXVariantMap(const FXVariantMap& other):table(EMPTY){ FXASSERT(sizeof(FXVariantMap)==sizeof(FXptr)); - FXASSERT(sizeof(Entry)<=sizeof(FXival)*4); + FXASSERT(sizeof(Entry)<=sizeof(FXival)*8); if(1>=BSHIFT; } @@ -258,25 +258,29 @@ void FXVariantMap::remove(const FXchar* ky){ table[x].data.clear(); // Clear the variant used(used()-1); if(__unlikely(used()<=(no()>>2))) resize(no()>>1); + return true; } + return false; } // Erase entry at pos in the table -void FXVariantMap::erase(FXival pos){ +FXbool FXVariantMap::erase(FXival pos){ if(__unlikely(pos<0 || no()<=pos)){ throw FXRangeException("FXVariantMap::erase: argument out of range\n"); } if(!table[pos].key.empty()){ table[pos].key.clear(); // Void the slot (not empty!) table[pos].data.clear(); // Clear the variant used(used()-1); if(__unlikely(used()<=(no()>>2))) resize(no()>>1); + return true; } + return false; } // Clear the table -void FXVariantMap::clear(){ - no(1); +FXbool FXVariantMap::clear(){ + return no(1); } diff --git a/lib/FXVerticalFrame.cpp b/lib/FXVerticalFrame.cpp index bacda8c..a065140 100644 --- a/lib/FXVerticalFrame.cpp +++ b/lib/FXVerticalFrame.cpp @@ -49,7 +49,6 @@ using namespace FX; - /*******************************************************************************/ namespace FX { @@ -83,7 +82,7 @@ FXint FXVerticalFrame::getDefaultWidth(){ if(hints&LAYOUT_FIX_WIDTH) w=child->getWidth(); else if(options&PACK_UNIFORM_WIDTH) w=mw; else w=child->getDefaultWidth(); - if((hints&LAYOUT_RIGHT)&&(hints&LAYOUT_CENTER_X)){ // LAYOUT_FIX_X + if((hints&LAYOUT_RIGHT)&&(hints&LAYOUT_CENTER_X)){ w=child->getX()+w; if(w>wmax) wmax=w; } @@ -110,7 +109,7 @@ FXint FXVerticalFrame::getDefaultHeight(){ if(hints&LAYOUT_FIX_HEIGHT) h=child->getHeight(); else if(options&PACK_UNIFORM_HEIGHT) h=mh; else h=child->getDefaultHeight(); - if((hints&LAYOUT_BOTTOM)&&(hints&LAYOUT_CENTER_Y)){ // LAYOUT_FIX_Y + if((hints&LAYOUT_BOTTOM)&&(hints&LAYOUT_CENTER_Y)){ h=child->getY()+h; if(h>hmax) hmax=h; } @@ -151,7 +150,7 @@ void FXVerticalFrame::layout(){ for(child=getFirst(); child; child=child->getNext()){ if(child->shown()){ hints=child->getLayoutHints(); - if(!((hints&LAYOUT_BOTTOM)&&(hints&LAYOUT_CENTER_Y))){ // LAYOUT_FIX_Y + if(!((hints&LAYOUT_BOTTOM)&&(hints&LAYOUT_CENTER_Y))){ if(hints&LAYOUT_FIX_HEIGHT) h=child->getHeight(); else if(options&PACK_UNIFORM_HEIGHT) h=mh; else h=child->getDefaultHeight(); @@ -193,7 +192,7 @@ void FXVerticalFrame::layout(){ if(hints&LAYOUT_FIX_HEIGHT) h=child->getHeight(); else if(options&PACK_UNIFORM_HEIGHT) h=mh; else h=child->getDefaultHeight(); - if(!((hints&LAYOUT_BOTTOM)&&(hints&LAYOUT_CENTER_Y))){ // LAYOUT_FIX_Y + if(!((hints&LAYOUT_BOTTOM)&&(hints&LAYOUT_CENTER_Y))){ extra_space=0; total_space=0; if((hints&LAYOUT_FILL_Y) && !(hints&LAYOUT_FIX_HEIGHT)){ @@ -229,7 +228,7 @@ void FXVerticalFrame::layout(){ } if(hints&LAYOUT_BOTTOM){ y=bottom-h-extra_space; - bottom=bottom-h-hspacing-total_space; + bottom=bottom-h-vspacing-total_space; } else{ y=top+extra_space; diff --git a/lib/FXWEBPIcon.cpp b/lib/FXWEBPIcon.cpp index e057607..7835b62 100644 --- a/lib/FXWEBPIcon.cpp +++ b/lib/FXWEBPIcon.cpp @@ -67,9 +67,9 @@ const FXbool FXWEBPIcon::supported=false; // Initialize -FXWEBPIcon::FXWEBPIcon(FXApp* a,const void *pix,FXColor clr,FXuint opts,FXint w,FXint h):FXIcon(a,nullptr,clr,opts,w,h){ +FXWEBPIcon::FXWEBPIcon(FXApp* a,const FXuchar *pix,FXColor clr,FXuint opts,FXint w,FXint h):FXIcon(a,nullptr,clr,opts,w,h){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXWEBPImage.cpp b/lib/FXWEBPImage.cpp index 6a818d0..cbc9240 100644 --- a/lib/FXWEBPImage.cpp +++ b/lib/FXWEBPImage.cpp @@ -67,9 +67,9 @@ const FXbool FXWEBPImage::supported=false; // Initialize -FXWEBPImage::FXWEBPImage(FXApp* a,const void *pix,FXuint opts,FXint w,FXint h):FXImage(a,nullptr,opts,w,h){ +FXWEBPImage::FXWEBPImage(FXApp* a,const FXuchar *pix,FXuint opts,FXint w,FXint h):FXImage(a,nullptr,opts,w,h){ if(pix){ - FXMemoryStream ms(FXStreamLoad,(FXuchar*)pix); + FXMemoryStream ms(FXStreamLoad,const_cast(pix)); loadPixels(ms); } } diff --git a/lib/FXWindow.cpp b/lib/FXWindow.cpp index baba099..f12969a 100644 --- a/lib/FXWindow.cpp +++ b/lib/FXWindow.cpp @@ -455,7 +455,7 @@ FXWindow::WindowClass FXWindow::getWindowClass() const { // Return a pointer to the shell window FXWindow* FXWindow::getShell() const { - FXWindow *win=(FXWindow*)this; + FXWindow *win=const_cast(this); FXWindow *p; while((p=win->parent)!=nullptr && p->parent) win=p; return win; @@ -464,7 +464,7 @@ FXWindow* FXWindow::getShell() const { // Return a pointer to the root window FXWindow* FXWindow::getRoot() const { - FXWindow *win=(FXWindow*)this; + FXWindow *win=const_cast(this); while(win->parent) win=win->parent; return win; } @@ -1120,7 +1120,7 @@ void FXWindow::setDefault(FXuchar flag){ // Find default window FXWindow* FXWindow::findDefault() const { - FXWindow *win=(FXWindow*)this; + FXWindow *win=const_cast(this); while(1){ if(win->isDefault()) return win; if(win->getFirst()){ win=win->getFirst(); continue; } @@ -1156,7 +1156,7 @@ void FXWindow::setInitial(FXbool flag){ // Find initial window FXWindow* FXWindow::findInitial() const { - FXWindow *win=(FXWindow*)this; + FXWindow *win=const_cast(this); while(1){ if(win->isInitial()) return win; if(win->getFirst()){ win=win->getFirst(); continue; } diff --git a/lib/FXXML.cpp b/lib/FXXML.cpp index 83bec0e..69cb31d 100644 --- a/lib/FXXML.cpp +++ b/lib/FXXML.cpp @@ -21,14 +21,14 @@ #include "xincs.h" #include "fxver.h" #include "fxdefs.h" +#include "fxchar.h" #include "fxmath.h" #include "fxascii.h" #include "fxunicode.h" #include "FXElement.h" #include "FXArray.h" #include "FXString.h" -#include "FXStat.h" -#include "FXFile.h" +#include "FXParseBuffer.h" #include "FXException.h" #include "FXStringDictionary.h" #include "FXCallback.h" @@ -591,13 +591,13 @@ FXbool FXXML::encode(FXString& dst,const FXString& src,FXuint flags){ /*******************************************************************************/ // Construct XML parser instance -FXXML::FXXML():begptr(nullptr),endptr(nullptr),wptr(nullptr),rptr(nullptr),sptr(nullptr),offset(0),current(nullptr),column(0),line(1),dir(Stop),enc(UTF8){ +FXXML::FXXML():offset(0),current(nullptr),column(0),line(1),enc(UTF8){ FXTRACE((100,"FXXML::FXXML\n")); } // Construct XML parser instance and pass it external buffer -FXXML::FXXML(FXchar* buffer,FXuval sz,Direction d):begptr(nullptr),endptr(nullptr),wptr(nullptr),rptr(nullptr),sptr(nullptr),offset(0),current(nullptr),column(0),line(1),dir(Stop),enc(UTF8){ +FXXML::FXXML(FXchar* buffer,FXuval sz,Direction d):FXParseBuffer(buffer,sz,d),offset(0),current(nullptr),column(0),line(1),enc(UTF8){ FXTRACE((100,"FXXML::FXXML(%p,%ld,%s)\n",buffer,sz,d==Load?"Load":d==Save?"Save":"Stop")); open(buffer,sz,d); } @@ -606,18 +606,12 @@ FXXML::FXXML(FXchar* buffer,FXuval sz,Direction d):begptr(nullptr),endptr(nullpt // Open XML stream for given direction d FXbool FXXML::open(FXchar* buffer,FXuval sz,Direction d){ FXTRACE((101,"FXXML::open(%p,%ld,%s)\n",buffer,sz,d==Load?"Load":d==Save?"Save":"Stop")); - FXASSERT(dir==Stop); - if((dir==Stop) && (d!=Stop) && (0wptr){ - if(wptr==endptr){ - if(fill(count)<0) return false; - } - return sptr=endptr){ - if(flush(count)<=0) return false; - } - FXASSERT(wptr=endptr){ - if(flush(count)<=0) return false; - } - FXASSERT(wptr\n"; @@ -899,7 +825,7 @@ FXbool FXXML::name(){ if(nameStartChar(sptr[0])){ rptr=sptr; do{ - column+=FXISUTF8(*sptr); // Increment if UTF8 leader only + column+=isUTF8(*sptr); // Increment if UTF8 leader only offset++; sptr++; if(sptr>=wptr) return false; @@ -927,7 +853,7 @@ FXbool FXXML::match(FXchar ch){ // Match name with given name str of length len FXbool FXXML::match(const FXchar* str,FXint len){ if(name() && rptr+len==sptr){ - return compare(rptr,str,len)==0; + return FXString::compare(rptr,str,len)==0; } return false; } @@ -978,7 +904,7 @@ nxt: if((sptr-rptr)>=(endptr-begptr-MAXTOKEN)){ str.append(rptr,sptr-rptr); rptr=sptr; } - column+=FXISUTF8(*sptr); // Increment if UTF8 leader only + column+=isUTF8(*sptr); // Increment if UTF8 leader only offset++; sptr++; continue; @@ -1300,7 +1226,7 @@ nxt: if((sptr-rptr)>=(endptr-begptr-MAXTOKEN)){ data.append(rptr,sptr-rptr); // Add another chunk rptr=sptr; } - column+=FXISUTF8(*sptr); // Increment if UTF8 leader only + column+=isUTF8(*sptr); // Increment if UTF8 leader only offset++; sptr++; continue; @@ -1352,7 +1278,7 @@ nxt: if((sptr-rptr)>=(endptr-begptr-MAXTOKEN)){ text.append(rptr,sptr-rptr); // Pass comment undecoded rptr=sptr; } - column+=FXISUTF8(*sptr); // Increment if UTF8 leader only + column+=isUTF8(*sptr); // Increment if UTF8 leader only offset++; sptr++; continue; @@ -1513,7 +1439,7 @@ nxt: if((sptr-rptr)>=(endptr-begptr-MAXTOKEN)){ if((err=charactersCB(text))!=ErrOK) return err; rptr=sptr; } - column+=FXISUTF8(*sptr); // Increment if UTF8 leader only + column+=isUTF8(*sptr); // Increment if UTF8 leader only offset++; sptr++; continue; @@ -1635,7 +1561,7 @@ FXXML::Error FXXML::parsecontents(Element& elm){ // Eat text rptr=sptr; } - column+=FXISUTF8(*sptr); // Increment if UTF8 leader only + column+=isUTF8(*sptr); // Increment if UTF8 leader only offset++; sptr++; continue; @@ -1771,23 +1697,9 @@ FXXML::Error FXXML::parse(){ // Close it FXbool FXXML::close(){ FXTRACE((101,"XML::close()\n")); - if(dir!=Stop){ - if((dir==Load) || 0<=flush(0)){ // Error during final flush is possible - begptr=nullptr; - endptr=nullptr; - rptr=nullptr; - sptr=nullptr; - wptr=nullptr; - current=nullptr; - dir=Stop; - return true; - } - begptr=nullptr; - endptr=nullptr; - wptr=nullptr; - rptr=nullptr; - sptr=nullptr; - dir=Stop; + if(FXParseBuffer::close()){ + current=nullptr; + return true; } return false; } diff --git a/lib/FXXMLFile.cpp b/lib/FXXMLFile.cpp index 16c3e7f..eadbc5b 100644 --- a/lib/FXXMLFile.cpp +++ b/lib/FXXMLFile.cpp @@ -21,11 +21,13 @@ #include "xincs.h" #include "fxver.h" #include "fxdefs.h" +#include "fxchar.h" #include "fxmath.h" #include "fxascii.h" #include "FXElement.h" #include "FXArray.h" #include "FXString.h" +#include "FXParseBuffer.h" #include "FXIO.h" #include "FXIODevice.h" #include "FXStat.h" @@ -70,7 +72,7 @@ FXXMLFile::FXXMLFile(const FXString& filename,Direction d,FXuval sz){ // Open archive for operation FXbool FXXMLFile::open(FXInputHandle h,Direction d,FXuval sz){ - FXTRACE((101,"FXXMLFile::open(%lx,%s,%lu)\n",h,(d==Save)?"Save":(d==Load)?"Load":"Stop",sz)); + FXTRACE((101,"FXXMLFile::open(%lx,%s,%lu)\n",(FXuval)h,(d==Save)?"Save":(d==Load)?"Load":"Stop",sz)); FXchar *buffer; if(allocElms(buffer,sz)){ if(file.open(h,(d==Save)?FXIO::Writing:FXIO::Reading)){ diff --git a/lib/FXXMLString.cpp b/lib/FXXMLString.cpp index da26e87..0b96ebb 100644 --- a/lib/FXXMLString.cpp +++ b/lib/FXXMLString.cpp @@ -21,6 +21,7 @@ #include "xincs.h" #include "fxver.h" #include "fxdefs.h" +#include "fxchar.h" #include "fxmath.h" #include "fxascii.h" #include "fxunicode.h" @@ -57,21 +58,21 @@ FXXMLString::FXXMLString(){ // Create XML file i/o object and open it FXXMLString::FXXMLString(const FXString& string,Direction d){ - FXTRACE((100,"FXXMLString::FXXMLString(\"%.*s\",%s)\n",FXMIN(string.length(),16),string.text(),(d==Save)?"Save":(d==Load)?"Load":"Stop")); + FXTRACE((100,"FXXMLString::FXXMLString(\"%.*s\",%s)\n",(FXint)FXMIN(string.length(),16),string.text(),(d==Save)?"Save":(d==Load)?"Load":"Stop")); open(string,d); } // Create XML file i/o object and open it FXXMLString::FXXMLString(const FXchar* string,FXuval length,Direction d){ - FXTRACE((100,"FXXMLString::FXXMLString(\"%.*s\",%lu,%s)\n",FXMIN(length,16),string,length,(d==Save)?"Save":(d==Load)?"Load":"Stop")); + FXTRACE((100,"FXXMLString::FXXMLString(\"%.*s\",%lu,%s)\n",(FXint)FXMIN(length,16),string,length,(d==Save)?"Save":(d==Load)?"Load":"Stop")); open(string,length,d); } // Open XML for load or save FXbool FXXMLString::open(const FXString& string,Direction d){ - FXTRACE((101,"FXXMLString::open(\"%.*s\",%s)\n",FXMIN(string.length(),16),string.text(),(d==Save)?"Save":(d==Load)?"Load":"Stop")); + FXTRACE((101,"FXXMLString::open(\"%.*s\",%s)\n",(FXint)FXMIN(string.length(),16),string.text(),(d==Save)?"Save":(d==Load)?"Load":"Stop")); FXASSERT(dir==Stop); buffer=string; if(FXXML::open(buffer.text(),buffer.length(),d)){ @@ -84,7 +85,7 @@ FXbool FXXMLString::open(const FXString& string,Direction d){ // Open JSON character string of length for direction d FXbool FXXMLString::open(const FXchar* string,FXuval length,Direction d){ - FXTRACE((101,"FXXMLString::open(\"%.*s\",%lu,%s)\n",FXMIN(length,16),string,length,(d==Save)?"Save":(d==Load)?"Load":"Stop")); + FXTRACE((101,"FXXMLString::open(\"%.*s\",%lu,%s)\n",(FXint)FXMIN(length,16),string,length,(d==Save)?"Save":(d==Load)?"Load":"Stop")); FXASSERT(dir==Stop); buffer.assign(string,length); if(FXXML::open(buffer.text(),buffer.length(),d)){ diff --git a/lib/fxbase64.cpp b/lib/fxbase64.cpp index 7c57858..cbd5197 100644 --- a/lib/fxbase64.cpp +++ b/lib/fxbase64.cpp @@ -26,7 +26,9 @@ Notes: - Encode/decode binary data to or from base64 ascii. - New implementation should be both faster and safer. - - + - Encode 3 bytes of source into 4 bytes to destination, allowing + binary data to be safely transmitted using only 64 safe printable letters, + numbers, and other printable ASCII symbols. */ using namespace FX; diff --git a/lib/fxbase85.cpp b/lib/fxbase85.cpp index ed0724a..d38ee4c 100644 --- a/lib/fxbase85.cpp +++ b/lib/fxbase85.cpp @@ -31,6 +31,8 @@ - Which base85 is most useful? Adobe, rfc1924, Z85, - 85^5 = 4384852500, which is just larger than 256^4=4294967295; thus, 5 bytes needed to encode each 4 bytes. + - Encode 4 bytes of source into 5 bytes of destination, using only 85 printable + ASCII symbols. */ diff --git a/lib/fxchar.cpp b/lib/fxchar.cpp new file mode 100644 index 0000000..c3208f2 --- /dev/null +++ b/lib/fxchar.cpp @@ -0,0 +1,595 @@ +/******************************************************************************** +* * +* U n i c o d e C h a r a c t e r E n c o d i n g S u p p o r t * +* * +********************************************************************************* +* Copyright (C) 1997,2022 by Jeroen van der Zijp. All Rights Reserved. * +********************************************************************************* +* This library is free software; you can redistribute it and/or modify * +* it under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 3 of the License, or * +* (at your option) any later version. * +* * +* This library is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU Lesser General Public License for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see * +********************************************************************************/ +#include "xincs.h" +#include "fxver.h" +#define __NEW_DEFS__ 1 +#include "fxdefs.h" +#include "fxchar.h" +#include "fxmath.h" +#include "fxascii.h" +#include "fxunicode.h" + + +/* + Notes: + + - UTF-8 Encoding scheme: + + Hex Range Binary Encoding + ----------------------- ----------------------------- ----------------------------------- + U-00000000 - U-0000007F 0000 0000 0000 0000 0xxx xxxx 0xxxxxxx + U-00000080 - U-000007FF 0000 0000 0000 0yyy yyxx xxxx 110yyyyy 10xxxxxx + U-00000800 - U-0000FFFF 0000 0000 zzzz yyyy yyxx xxxx 1110zzzz 10yyyyyy 10xxxxxx + U-00010000 - U-001FFFFF 000u uuzz zzzz yyyy yyxx xxxx 11110uuu 10zzzzzz 10yyyyyy 10xxxxxx + + - UTF-16 Encoding scheme: + + Hex Range Binary Encoding + ----------------------- ----------------------------- ----------------------------------- + U-00000000 - U-0000FFFF 0000 0000 xxxx xxxx xxxx xxxx xxxxxxxx xxxxxxxx + U-00010000 - U-0010FFFF 000y yyyy yyyy yyxx xxxx xxxx 110110zz zzzzzzzz 110111xx xxxxxxxx + + The range U-D800 - U-DFFF is reserved for surrogate pairs; Leading-surrogates or high-surrogates + are from U-D800 to U-DBFF, and trailing-surrogates or low-surrogates are from U-DC00 to U-DFFF. + Surrogates CH and CL are computed as follows for U > 0x10000: + + CH = (U >> 10) + 0xD800 + CL = (U & 0x3FF) + 0xDC00 + +*/ + + +using namespace FX; + +/*******************************************************************************/ + +namespace FX { + +// For conversion from UTF16 to UTF32 +const FXint SURROGATE_OFFSET=0x10000-(0xD800<<10)-0xDC00; + +// For conversion of UTF32 to UTF16 +const FXint LEAD_OFFSET=0xD800-(0x10000>>10); + +// For conversion of UTF32 to UTF16 +const FXint TAIL_OFFSET=0xDC00; + +/*******************************************************************************/ + +// Return non-zero if valid utf8 character sequence +FXival wcvalid(const FXchar* ptr){ + if((FXuchar)ptr[0]<0x80) return 1; + if((FXuchar)ptr[0]<0xC0) return 0; + if((FXuchar)ptr[1]<0x80) return 0; + if((FXuchar)ptr[1]>0xBF) return 0; + if((FXuchar)ptr[0]<0xE0) return 2; + if((FXuchar)ptr[2]<0x80) return 0; + if((FXuchar)ptr[2]>0xBF) return 0; + if((FXuchar)ptr[0]<0xF0) return 3; + if((FXuchar)ptr[0]>0xF7) return 0; + if((FXuchar)ptr[3]<0x80) return 0; + if((FXuchar)ptr[3]>0xBF) return 0; + return 4; + } + + +// Return non-zero if valid utf16 character sequence +FXival wcvalid(const FXnchar* ptr){ + if(ptr[0]<0xD800) return 1; + if(ptr[0]>0xDFFF) return 1; + if(ptr[0]>0xDBFF) return 0; + if(ptr[1]<0xDC00) return 0; + if(ptr[1]>0xDFFF) return 0; + return 2; + } + +/*******************************************************************************/ + +// Return number of bytes for utf8 representation of wide character string +FXival wcs2utf(const FXwchar* src,FXival srclen){ + const FXwchar* srcend=src+srclen; + FXival p=0; + FXwchar w; + while(src=srcend) break; + if(!followUTF16(*src)) break; + w=SURROGATE_OFFSET+(w<<10)+*src++; + } + p+=wc2utf(w); + } + return p; + } + + +// Return number of bytes for utf8 representation of narrow character string +FXival ncs2utf(const FXnchar *src){ + FXival p=0; + FXnchar w; + while((w=*src++)!=0){ + if(leadUTF16(w)){ + if(!followUTF16(*src)) break; + w=SURROGATE_OFFSET+(w<<10)+*src++; + } + p+=wc2utf(w); + } + return p; + } + + +// Return number of wide characters for utf8 character string +FXival utf2wcs(const FXchar *src,FXival srclen){ + const FXchar* srcend=src+srclen; + FXival p=0; + FXuchar c; + while(src=srcend) break; + if(!followUTF8(src[1])) break; + if(0xE0<=c){ + if(src+2>=srcend) break; + if(!followUTF8(src[2])) break; + if(0xF0<=c){ + if(src+3>=srcend) break; + if(!followUTF8(src[3])) break; + src++; + } + src++; + } + src++; + } + src++; + p++; + } + return p; + } + + +// Return number of wide characters for utf8 character string +FXival utf2wcs(const FXchar *src){ + FXival p=0; + FXuchar c; + while((c=src[0])!=0){ + if(0xC0<=c){ + if(!followUTF8(src[1])) break; + if(0xE0<=c){ + if(!followUTF8(src[2])) break; + if(0xF0<=c){ + if(!followUTF8(src[3])) break; + src++; + } + src++; + } + src++; + } + src++; + p++; + } + return p; + } + + +// Return number of narrow characters for utf8 character string +FXival utf2ncs(const FXchar *src,FXival len){ + const FXchar* end=src+len; + FXival p=0; + FXuchar c; + while(src=end) break; + if(!followUTF8(src[1])) break; + if(0xE0<=c){ + if(src+2>=end) break; + if(!followUTF8(src[2])) break; + if(0xF0<=c){ + if(src+3>=end) break; + if(!followUTF8(src[3])) break; + src++; + p++; + } + src++; + } + src++; + } + src++; + p++; + } + return p; + } + + +// Return number of narrow characters for utf8 character string +FXival utf2ncs(const FXchar *src){ + FXival p=0; + FXuchar c; + while((c=src[0])!=0){ + if(0xC0<=c){ + if(!followUTF8(src[1])) break; + if(0xE0<=c){ + if(!followUTF8(src[2])) break; + if(0xF0<=c){ + if(!followUTF8(src[3])) break; + src++; + p++; + } + src++; + } + src++; + } + src++; + p++; + } + return p; + } + +/*******************************************************************************/ + +// Convert wide character to utf8 string +FXival wc2utf(FXchar *dst,FXwchar w){ + if(0x80<=w){ + if(0x800<=w){ + if(0x10000<=w){ + dst[0]=(w>>18)|0xF0; + dst[1]=((w>>12)&0x3F)|0x80; + dst[2]=((w>>6)&0x3F)|0x80; + dst[3]=(w&0x3F)|0x80; + return 4; + } + dst[0]=(w>>12)|0xE0; + dst[1]=((w>>6)&0x3F)|0x80; + dst[2]=(w&0x3F)|0x80; + return 3; + } + dst[0]=(w>>6)|0xC0; + dst[1]=(w&0x3F)|0x80; + return 2; + } + dst[0]=w; + return 1; + } + + +// Convert wide character to narrow character string +FXival wc2nc(FXnchar *dst,FXwchar w){ + if(0x10000<=w){ + dst[0]=LEAD_OFFSET+(w>>10); + dst[1]=TAIL_OFFSET+(w&0x3FF); + return 2; + } + dst[0]=w; + return 1; + } + + +// Convert wide character string to utf8 string +FXival wcs2utf(FXchar *dst,const FXwchar* src,FXival dstlen,FXival srclen){ + const FXwchar* srcend=src+srclen; + FXchar* ptrend=dst+dstlen; + FXchar* ptr=dst; + FXwchar w; + while(src=ptrend) break; + *ptr++=(w>>18)|0xF0; + *ptr++=((w>>12)&0x3F)|0x80; + *ptr++=((w>>6)&0x3F)|0x80; + *ptr++=(w&0x3F)|0x80; + continue; + } + if(ptr+2>=ptrend) break; + *ptr++=(w>>12)|0xE0; + *ptr++=((w>>6)&0x3F)|0x80; + *ptr++=(w&0x3F)|0x80; + continue; + } + if(ptr+1>=ptrend) break; + *ptr++=(w>>6)|0xC0; + *ptr++=(w&0x3F)|0x80; + continue; + } + if(ptr>=ptrend) break; + *ptr++=w; + } + if(ptr=ptrend) break; + *ptr++=(w>>18)|0xF0; + *ptr++=((w>>12)&0x3F)|0x80; + *ptr++=((w>>6)&0x3F)|0x80; + *ptr++=(w&0x3F)|0x80; + continue; + } + if(ptr+2>=ptrend) break; + *ptr++=(w>>12)|0xE0; + *ptr++=((w>>6)&0x3F)|0x80; + *ptr++=(w&0x3F)|0x80; + continue; + } + if(ptr+1>=ptrend) break; + *ptr++=(w>>6)|0xC0; + *ptr++=(w&0x3F)|0x80; + continue; + } + if(ptr>=ptrend) break; + *ptr++=w; + } + if(ptr=srcend) break; + if(!followUTF16(*src)) break; + if(ptr+3>=ptrend) break; + w=SURROGATE_OFFSET+(w<<10)+*src++; + *ptr++=(w>>18)|0xF0; + *ptr++=((w>>12)&0x3F)|0x80; + *ptr++=((w>>6)&0x3F)|0x80; + *ptr++=(w&0x3F)|0x80; + continue; + } + if(ptr+2>=ptrend) break; + *ptr++=(w>>12)|0xE0; + *ptr++=((w>>6)&0x3F)|0x80; + *ptr++=(w&0x3F)|0x80; + continue; + } + if(ptr+1>=ptrend) break; + *ptr++=(w>>6)|0xC0; + *ptr++=(w&0x3F)|0x80; + continue; + } + if(ptr>=ptrend) break; + *ptr++=w; + } + if(ptr=ptrend) break; + w=SURROGATE_OFFSET+(w<<10)+*src++; + *ptr++=(w>>18)|0xF0; + *ptr++=((w>>12)&0x3F)|0x80; + *ptr++=((w>>6)&0x3F)|0x80; + *ptr++=(w&0x3F)|0x80; + continue; + } + if(ptr+2>=ptrend) break; + *ptr++=(w>>12)|0xE0; + *ptr++=((w>>6)&0x3F)|0x80; + *ptr++=(w&0x3F)|0x80; + continue; + } + if(ptr+1>=ptrend) break; + *ptr++=(w>>6)|0xC0; + *ptr++=(w&0x3F)|0x80; + continue; + } + if(ptr>=ptrend) break; + *ptr++=w; + } + if(ptr=srcend) break; + c=*src++; + if(!followUTF8(c)) break; + w=(w<<6) ^ c ^ 0x3080; + if(0x800<=w){ + if(src>=srcend) break; + c=*src++; + if(!followUTF8(c)) break; + w=(w<<6) ^ c ^ 0x20080; + if(0x10000<=w){ + if(src>=srcend) break; + c=*src++; + if(!followUTF8(c)) break; + w=(w<<6) ^ c ^ 0x400080; + } + } + } + if(ptr>=ptrend) break; + *ptr++=w; + } + if(ptr=ptrend) break; + *ptr++=w; + } + if(ptr=srcend) break; + c=*src++; + if(!followUTF8(c)) break; + w=(w<<6) ^ c ^ 0x3080; + if(0x800<=w){ + if(src>=srcend) break; + c=*src++; + if(!followUTF8(c)) break; + w=(w<<6) ^ c ^ 0x20080; + if(0x10000<=w){ + if(src>=srcend) break; + c=*src++; + if(!followUTF8(c)) break; + if(ptr+1>=ptrend) break; + w=(w<<6) ^ c ^ 0x400080; + *ptr++=LEAD_OFFSET+(w>>10); + *ptr++=TAIL_OFFSET+(w&0x3FF); + continue; + } + } + } + if(ptr>=ptrend) break; + *ptr++=w; + } + if(ptr=ptrend) break; + w=(w<<6) ^ c ^ 0x400080; + *ptr++=LEAD_OFFSET+(w>>10); + *ptr++=TAIL_OFFSET+(w&0x3FF); + continue; + } + } + } + if(ptr>=ptrend) break; + *ptr++=w; + } + if(ptr - -// Return clock ticks from performance counter [HPUX C++ IA64 version]. -FXTime fxgetticks(){ - FXTime ret; - ret = _Asm_mov_from_ar (_AREG_ITC); - return ret; - } - -#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__)) -// Return clock ticks from performance counter [GCC PPC version]. -FXTime fxgetticks(){ - FXuint tbl,tbu0,tbu1; - do{ - asm ("mftbu %0" : "=r"(tbu0)); - asm ("mftb %0" : "=r"(tbl)); - asm ("mftbu %0" : "=r"(tbu1)); - } - while(tbu0!=tbu1); - return (((FXTime)tbu0) << 32) | tbl; - } - -#elif defined(__GNUC__) && (defined(__hppa__) || defined(__hppa)) +#elif !defined(__INTEL_COMPILER) && defined(__GNUC__) && defined(__ia64__) -// Return clock ticks from performance counter [GCC PA-RISC version]. +// Return clock ticks from performance counter [GCC IA64 version]. FXTime fxgetticks(){ FXTime value; - asm ("mfctl 16, %0": "=r" (value)); // FIXME not tested! + asm ("mov %0=ar.itc" : "=r" (value)); return value; } -#elif !defined(__GNUC__) && (defined(__hppa__) || defined(__hppa)) -#include - -// Return clock ticks from performance counter [HP-C++ PA-RISC version]. -FXTime fxgetticks(){ - FXTime ret; - _MFCTL(16, ret); - return ret; - } - -#elif defined(__GNUC__) && defined(__alpha__) +#elif defined(__GNUC__) && (defined(__powerpc64__) || defined(__ppc64__)) -// Return clock ticks from performance counter [GCC ALPHA version]; FXTime fxgetticks(){ FXTime value; - asm ("rpcc %0" : "=r"(value)); // Only 32-bits accurate! - return (value & 0xFFFFFFFF); - } - -#elif (defined(__DECC) || defined(__DECCXX)) && defined(__alpha) -#include - -// Return clock ticks from performance counter [DEC C++ ALPHA version]; -FXTime fxgetticks(){ - FXTime value; - value = asm("rpcc %v0"); - return (value & 0xFFFFFFFF); // Only 32-bits accurate! - } - -#elif (defined(__IRIX__) || defined(_SGI)) && defined(CLOCK_SGI_CYCLE) - -// Return clock ticks from performance counter [SGI/IRIX version]; -FXTime fxgetticks(){ - const FXTime seconds=1000000000; - struct timespec tp; - clock_gettime(CLOCK_SGI_CYCLE,&tp); - return tp.tv_sec*seconds+tp.tv_nsec; + asm volatile("mfspr %0, 268" : "=r"(value)); + return value; } -#elif defined(__GNUC__) && defined(__sparc_v9__) +#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__)) -// Return clock ticks from performance counter [GCC SPARC V9 version]. +// Return clock ticks from performance counter [GCC PPC version]. FXTime fxgetticks(){ - FXTime value; - asm ("rd %%tick, %0" : "=r" (value)); - return value; + FXuint tbl, tbu0, tbu1; + asm volatile("mftbu %0 \n\t" + "mftb %1 \n\t" + "mftbu %2 \n\t" : "=r"(tbu0), "=r"(tbl), "=r"(tbu1)); + tbl&=-(FXint)(tbu0==tbu1); + return (static_cast(tbu1) << 32) | tbl; + return (((FXTime)tbu1) << 32) | tbl; } #elif (_POSIX_C_SOURCE >= 199309L) @@ -167,7 +130,7 @@ FXTime fxgetticks(){ const FXTime seconds=1000000000; struct timespec ts; clock_gettime(CLOCK_MONOTONIC,&ts); - return ts.tv_sec*seconds+ts.tv_nsec; // NOT accurate! + return ts.tv_sec*seconds+ts.tv_nsec; } #else @@ -178,7 +141,7 @@ FXTime fxgetticks(){ const FXTime microseconds=1000; struct timeval tv; gettimeofday(&tv,nullptr); - return tv.tv_sec*seconds+tv.tv_usec*microseconds; // NOT accurate! + return tv.tv_sec*seconds+tv.tv_usec*microseconds; } #endif diff --git a/lib/fxjpegio.cpp b/lib/fxjpegio.cpp index 4b780ce..361ab6e 100644 --- a/lib/fxjpegio.cpp +++ b/lib/fxjpegio.cpp @@ -376,9 +376,9 @@ FXbool fxsaveJPG(FXStream& store,const FXColor* data,FXint width,FXint height,FX while(dstinfo.next_scanline * +********************************************************************************/ +#include "xincs.h" +#include "fxver.h" +#include "fxdefs.h" + + +/* + Notes: +*/ + + +using namespace FX; + +/*******************************************************************************/ + +namespace FX { + +extern FXAPI FXint __snprintf(FXchar* string,FXint length,const FXchar* format,...); + +#if defined(WIN32) + +// RtlGetVersion grabs the version information use it because +// GetVersionEx is now deprecated. +typedef LONG (WINAPI *PFN_RTLGETVERSION)(OSVERSIONINFOEXW*); + +// Declare the stub function +static LONG WINAPI RtlGetVersionStub(OSVERSIONINFOEXW* osv); + +// Pointer to RtlGetVersion, initially pointing to the stub function +static PFN_RTLGETVERSION fxRtlGetVersion=RtlGetVersionStub; + +// Low-level routine to grab OS version +static LONG WINAPI RtlGetVersionStub(OSVERSIONINFOEXW* osv){ + if(fxRtlGetVersion==RtlGetVersionStub){ + HMODULE ntdllDll=GetModuleHandleA("ntdll.dll"); + FXASSERT(ntdllDll); + fxRtlGetVersion=(PFN_RTLGETVERSION)GetProcAddress(ntdllDll,"RtlGetVersion"); + FXASSERT(fxRtlGetVersion); + } + return fxRtlGetVersion(osv); + } + + +// Get operating system version string +FXival fxosversion(FXchar version[],FXival len){ + if(0= _WIN32_WINNT_VISTA) + DWORD len=GetFileVersionInfoSizeExW(FILE_VER_GET_NEUTRAL,path,&handle); +#else + DWORD len=GetFileVersionInfoSizeW(path,&handle); +#endif + if(!len) return false; + + std::unique_ptr buff( new (std::nothrow) uint8_t[ len ] ); + + if(!buff) return false; + +#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA) + if(!GetFileVersionInfoExW(FILE_VER_GET_NEUTRAL,path,0,len,buff.get() ) ) return false; +#else + if(!GetFileVersionInfoW( path, 0, len, buff.get() ) ) return false; +#endif + + VS_FIXEDFILEINFO *vInfo=nullptr; + UINT infoSize; + + if(!VerQueryValueW(buff.get(),L"\\",reinterpret_cast(&vInfo),&infoSize)) return false; + + if(!infoSize) return false; + + swprintf_s( version, maxlen, L"%u.%u.%u.%u",HIWORD( vInfo->dwFileVersionMS ),LOWORD(vInfo->dwFileVersionMS),HIWORD(vInfo->dwFileVersionLS),LOWORD(vInfo->dwFileVersionLS) ); + + return true; + } + +#endif + +#elif defined(HAVE_UNAME) + +// Get operating system version string +FXival fxosversion(FXchar version[],FXival len){ // FIXME will change + if(0=0; rgb--){ - pp=((FXuchar*)(data+y*width))+rgb; + pp=((const FXuchar*)(data+y*width))+rgb; Last=*pp; pp+=4; RLECount=1; diff --git a/lib/fxprintf.cpp b/lib/fxprintf.cpp index 513d90c..35d1c56 100644 --- a/lib/fxprintf.cpp +++ b/lib/fxprintf.cpp @@ -1160,37 +1160,37 @@ static FXchar* fmtlng(FXchar* buffer,FXint& len,FXlong value,FXint base,FXint pr } } - // Convert to string using base - if(!(flags&FLG_THOUSAND)){ + // Output decimal with thousands separator + if(flags&FLG_THOUSAND){ do{ + ++digs; --precision; - n=number/base; - *--ptr=digits[number-n*base]; + n=number/10; + *--ptr=digits[number-n*10]; number=n; + if(digs%3==0 && number) *--ptr=','; } while(number); - while(0=0; i--){ for(j=0; j LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US VS_VERSION_INFO VERSIONINFO -FILEVERSION 1,7,79,0 +FILEVERSION 1,7,80,0 FILEFLAGSMASK VS_FFI_FILEFLAGSMASK #ifdef _DEBUG FILEFLAGS VS_FF_DEBUG @@ -18,12 +18,12 @@ BLOCK "040904b0" BEGIN VALUE "CompanyName", "Jeroen van der Zijp\0" VALUE "FileDescription", "FOX GUI Library\0" -VALUE "FileVersion", "1.7.79.0\0" +VALUE "FileVersion", "1.7.80.0\0" VALUE "InternalName", "FOXDLL-1.@FOX_MINOR_VERSION\0" VALUE "LegalCopyright", "GNU Lesser General Public License Version 3 and License Addendum\0" VALUE "OriginalFilename", "FOXDLL-1.@FOX_MINOR_VERSION.dll\0" VALUE "ProductName", "FOX GUI Library\0" -VALUE "ProductVersion", "1.7.79.0\0" +VALUE "ProductVersion", "1.7.80.0\0" END END BLOCK "VarFileInfo" diff --git a/pathfinder/PathFinder.cpp b/pathfinder/PathFinder.cpp index a62f390..700eef8 100644 --- a/pathfinder/PathFinder.cpp +++ b/pathfinder/PathFinder.cpp @@ -326,7 +326,7 @@ PathFinderMain::PathFinderMain(FXApp* a):FXMainWindow(a,"PathFinder",nullptr,nul // Header above folders FXHorizontalFrame *header1=new FXHorizontalFrame(group1,LAYOUT_FILL_X|FRAME_RAISED|FRAME_THICK,0,0,0,0, 0,0,0,0, 0,0); new FXLabel(header1,tr("Folders"),nullptr,LAYOUT_FILL_X|JUSTIFY_LEFT); - new FXButton(header1,"",closeicon,group1,FXWindow::ID_HIDE,BUTTON_TOOLBAR|FRAME_RAISED,0,0,0,0, 0,0,0,0); + new FXButton(header1,"",closeicon,group1,FXWindow::ID_HIDE,BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y,0,0,0,0, 0,0,0,0); // Folder List dirlist=new FXDirList(group1,this,ID_DIRECTORYLIST,LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_TOP|LAYOUT_RIGHT|TREELIST_SHOWS_LINES|TREELIST_SHOWS_BOXES|TREELIST_BROWSESELECT|DIRLIST_NO_OWN_ASSOC); @@ -338,9 +338,9 @@ PathFinderMain::PathFinderMain(FXApp* a):FXMainWindow(a,"PathFinder",nullptr,nul FXLabel* fileslabel=new FXLabel(header2,tr("Files in: "),nullptr,LAYOUT_FILL_X|JUSTIFY_LEFT); fileslabel->setTarget(this); fileslabel->setSelector(ID_UPDATE_FILES); - new FXButton(header2,tr("\tRotate left\tRotate image leftward 90 degrees."),rotatelefticon,this,ID_IMAGE_ROTATE_LEFT,BUTTON_TOOLBAR|FRAME_RAISED,0,0,0,0,0,0,0,0); - new FXButton(header2,tr("\tRotate right\tRotate image rightward 90 degrees."),rotaterighticon,this,ID_IMAGE_ROTATE_RIGHT,BUTTON_TOOLBAR|FRAME_RAISED,0,0,0,0,0,0,0,0); - new FXButton(header2,FXString::null,closeicon,this,ID_CLOSE_PREVIEW,BUTTON_TOOLBAR|FRAME_RAISED,0,0,0,0, 0,0,0,0); + new FXButton(header2,tr("\tRotate left\tRotate image leftward 90 degrees."),rotatelefticon,this,ID_IMAGE_ROTATE_LEFT,BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y,0,0,0,0,0,0,0,0); + new FXButton(header2,tr("\tRotate right\tRotate image rightward 90 degrees."),rotaterighticon,this,ID_IMAGE_ROTATE_RIGHT,BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y,0,0,0,0,0,0,0,0); + new FXButton(header2,FXString::null,closeicon,this,ID_CLOSE_PREVIEW,BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y,0,0,0,0, 0,0,0,0); // Switcher to either image or filelist switcher=new FXSwitcher(group2,LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,0,0, 0,0,0,0); @@ -377,9 +377,9 @@ PathFinderMain::PathFinderMain(FXApp* a):FXMainWindow(a,"PathFinder",nullptr,nul new FXMenuCommand(editmenu,tr("Delete\t\tDelete Selected files."),deleteicon,this,ID_DELETE); new FXMenuCommand(editmenu,tr("&Paste\tCtl-V\tPaste from clipboard."),pasteicon,filelist,FXFileList::ID_PASTE_SEL); new FXMenuSeparator(editmenu); - new FXMenuCommand(editmenu,tr("Select files\tCtl-S\tSelect files matching wildcard."),nullptr,this,ID_WILDCARD_SELECT); - new FXMenuCommand(editmenu,tr("&Select All\tCtl-A\tSelect all icons."),nullptr,filelist,FXFileList::ID_SELECT_ALL); - new FXMenuCommand(editmenu,tr("&Deselect All\t\tDeselect all icons."),nullptr,filelist,FXFileList::ID_DESELECT_ALL); + new FXMenuCommand(editmenu,tr("&Select All\tCtl-A\tSelect all files."),nullptr,filelist,FXFileList::ID_SELECT_ALL); + new FXMenuCommand(editmenu,tr("Select &Wildcard\tCtl-S\tSelect files matching wildcard."),nullptr,this,ID_WILDCARD_SELECT); + new FXMenuCommand(editmenu,tr("&Deselect All\t\tDeselect all files."),nullptr,filelist,FXFileList::ID_DESELECT_ALL); new FXMenuCommand(editmenu,tr("&Invert Selection\t\tInvert selection."),nullptr,filelist,FXFileList::ID_SELECT_INVERSE); // Go Menu Pane @@ -440,7 +440,7 @@ PathFinderMain::PathFinderMain(FXApp* a):FXMainWindow(a,"PathFinder",nullptr,nul new FXMenuRadio(sortmenu,tr("&Name\t\tSort by file name."),filelist,FXFileList::ID_SORT_BY_NAME); new FXMenuRadio(sortmenu,tr("&Type\t\tSort by file type."),filelist,FXFileList::ID_SORT_BY_TYPE); new FXMenuRadio(sortmenu,tr("&Size\t\tSort by file size."),filelist,FXFileList::ID_SORT_BY_SIZE); - new FXMenuRadio(sortmenu,tr("T&ime\t\tSort by modification time."),filelist,FXFileList::ID_SORT_BY_TIME); + new FXMenuRadio(sortmenu,tr("&Date\t\tSort by modification time."),filelist,FXFileList::ID_SORT_BY_TIME); new FXMenuRadio(sortmenu,tr("&User\t\tSort by user name."),filelist,FXFileList::ID_SORT_BY_USER); new FXMenuRadio(sortmenu,tr("&Group\t\tSort by group name."),filelist,FXFileList::ID_SORT_BY_GROUP); new FXMenuSeparator(sortmenu); @@ -1061,8 +1061,10 @@ FXbool PathFinderMain::executeCommandline(const FXString& commandline){ // // The special codes are as follows: // -// %f or %s Replaced by (quoted) current filename -// %F Replaced by the (quoted) selected filenames +// %f or %s Replaced by (quoted) current full path name +// %F Replaced by the (quoted) selected full path names +// %n Replaced by the (quoted) current file name +// %N Replaced by the (quoted) selected file names // %u Replaced by (quoted) URL-encoded of the current filename // %U Replaced by the (quoted) URL-encoded selected filenames // %d Replaced by current working directory @@ -1106,6 +1108,22 @@ FXString PathFinderMain::makeCommandline(const FXString& executable) const { f++; } continue; + case 'n': // Name only + f=files; + if(f && !f->empty()){ + if(!commandline.empty()) commandline+=' '; + commandline+=FXPath::enquote(FXPath::name(*f)); + f++; + } + continue; + case 'N': // Multiple files, names only + f=files; + while(f && !f->empty()){ + if(!commandline.empty()) commandline+=' '; + commandline+=FXPath::enquote(FXPath::name(*f)); + f++; + } + continue; case 'u': // URL-ified filename f=files; if(f && !f->empty()){ @@ -1898,27 +1916,14 @@ long PathFinderMain::onCmdPreferences(FXObject*,FXSelector,void*){ // Select files matching wildcard long PathFinderMain::onCmdWildcardSelect(FXObject*,FXSelector,void*){ FXChoiceBox choices(this,tr("Select Files Matching"),tr("Select files matching wildcard pattern"),nullptr,getPatternList(),DECOR_TITLE|DECOR_BORDER|DECOR_RESIZE,0,0,400,300); - FXint pick=choices.execute(PLACEMENT_CURSOR); + FXint pick=choices.execute(PLACEMENT_OWNER); if(0<=pick && filelist->getNumItems()){ FXString wildcard=FXFileSelector::patternFromText(pattern->getItemText(pick)); - FXint anch=-1,curr=-1; - for(FXint i=0; igetNumItems(); i++){ - if(filelist->isItemNavigational(i)) continue; #if defined(WIN32) - if(FXPath::match(filelist->getItemFilename(i),wildcard,(FXPath::PathName|FXPath::NoEscape|FXPath::CaseFold))){ - if(anch<0){ anch=i; } curr=i; - filelist->selectItem(i,true); - } + filelist->selectMatching(wildcard,(FXPath::PathName|FXPath::NoEscape|FXPath::CaseFold),true); #else - if(FXPath::match(filelist->getItemFilename(i),wildcard,(FXPath::PathName|FXPath::NoEscape))){ - if(anch<0){ anch=i; } curr=i; - filelist->selectItem(i,true); - } + filelist->selectMatching(wildcard,(FXPath::PathName|FXPath::NoEscape),true); #endif - filelist->setAnchorItem(anch); - filelist->setCurrentItem(curr,true); - filelist->makeItemVisible(curr); - } } return 1; } @@ -2120,62 +2125,62 @@ FXbool PathFinderMain::previewImage(const FXString& filename){ FXImage *old=nullptr; // Determine type of image - if(comparecase(ext,"gif")==0){ + if(FXString::comparecase(ext,"gif")==0){ img=new FXGIFImage(getApp(),nullptr,IMAGE_KEEP|IMAGE_SHMI|IMAGE_SHMP); } - else if(comparecase(ext,"bmp")==0){ + else if(FXString::comparecase(ext,"bmp")==0){ img=new FXBMPImage(getApp(),nullptr,IMAGE_KEEP|IMAGE_SHMI|IMAGE_SHMP); } - else if(comparecase(ext,"xpm")==0){ + else if(FXString::comparecase(ext,"xpm")==0){ img=new FXXPMImage(getApp(),nullptr,IMAGE_KEEP|IMAGE_SHMI|IMAGE_SHMP); } - else if(comparecase(ext,"pcx")==0){ + else if(FXString::comparecase(ext,"pcx")==0){ img=new FXPCXImage(getApp(),nullptr,IMAGE_KEEP|IMAGE_SHMI|IMAGE_SHMP); } - else if(comparecase(ext,"ico")==0 || comparecase(ext,"cur")==0){ + else if(FXString::comparecase(ext,"ico")==0 || FXString::comparecase(ext,"cur")==0){ img=new FXICOImage(getApp(),nullptr,IMAGE_KEEP|IMAGE_SHMI|IMAGE_SHMP); } - else if(comparecase(ext,"tga")==0){ + else if(FXString::comparecase(ext,"tga")==0){ img=new FXTGAImage(getApp(),nullptr,IMAGE_KEEP|IMAGE_SHMI|IMAGE_SHMP); } - else if(comparecase(ext,"rgb")==0){ + else if(FXString::comparecase(ext,"rgb")==0){ img=new FXRGBImage(getApp(),nullptr,IMAGE_KEEP|IMAGE_SHMI|IMAGE_SHMP); } - else if(comparecase(ext,"pbm")==0 || comparecase(ext,"pgm")==0 || comparecase(ext,"pnm")==0 || comparecase(ext,"ppm")==0){ + else if(FXString::comparecase(ext,"pbm")==0 || FXString::comparecase(ext,"pgm")==0 || FXString::comparecase(ext,"pnm")==0 || FXString::comparecase(ext,"ppm")==0){ img=new FXPPMImage(getApp(),nullptr,IMAGE_KEEP|IMAGE_SHMI|IMAGE_SHMP); } - else if(comparecase(ext,"xbm")==0){ + else if(FXString::comparecase(ext,"xbm")==0){ img=new FXXBMImage(getApp(),nullptr,nullptr,IMAGE_KEEP|IMAGE_SHMI|IMAGE_SHMP); } - else if(comparecase(ext,"ppm")==0){ + else if(FXString::comparecase(ext,"ppm")==0){ img=new FXPPMImage(getApp(),nullptr,IMAGE_KEEP|IMAGE_SHMI|IMAGE_SHMP); } - else if(comparecase(ext,"iff")==0 || comparecase(ext,"lbm")==0){ + else if(FXString::comparecase(ext,"iff")==0 || FXString::comparecase(ext,"lbm")==0){ img=new FXIFFImage(getApp(),nullptr,IMAGE_KEEP|IMAGE_SHMI|IMAGE_SHMP); } - else if(comparecase(ext,"ras")==0){ + else if(FXString::comparecase(ext,"ras")==0){ img=new FXRASImage(getApp(),nullptr,IMAGE_KEEP|IMAGE_SHMI|IMAGE_SHMP); } - else if(comparecase(ext,"dds")==0){ + else if(FXString::comparecase(ext,"dds")==0){ img=new FXDDSImage(getApp(),nullptr,IMAGE_KEEP|IMAGE_SHMI|IMAGE_SHMP); } #ifdef HAVE_PNG_H - else if(comparecase(ext,"png")==0){ + else if(FXString::comparecase(ext,"png")==0){ img=new FXPNGImage(getApp(),nullptr,IMAGE_KEEP|IMAGE_SHMI|IMAGE_SHMP); } #endif #ifdef HAVE_JPEG_H - else if(comparecase(ext,"jpg")==0){ + else if(FXString::comparecase(ext,"jpg")==0){ img=new FXJPGImage(getApp(),nullptr,IMAGE_KEEP|IMAGE_SHMI|IMAGE_SHMP); } #endif #ifdef HAVE_TIFF_H - else if(comparecase(ext,"tif")==0 || comparecase(ext,"tiff")==0){ + else if(FXString::comparecase(ext,"tif")==0 || FXString::comparecase(ext,"tiff")==0){ img=new FXTIFImage(getApp(),nullptr,IMAGE_KEEP|IMAGE_SHMI|IMAGE_SHMP); } #endif #ifdef HAVE_WEBP_H - else if(comparecase(ext,"webp")==0){ + else if(FXString::comparecase(ext,"webp")==0){ img=new FXWEBPImage(getApp(),nullptr,IMAGE_KEEP|IMAGE_SHMI|IMAGE_SHMP); } #endif diff --git a/pathfinder/Preferences.cpp b/pathfinder/Preferences.cpp index 1df2fe7..0704b1c 100644 --- a/pathfinder/Preferences.cpp +++ b/pathfinder/Preferences.cpp @@ -105,7 +105,7 @@ Preferences::Preferences(PathFinderMain *own):FXDialogBox(own,"PathFinder Prefer new FXLabel(matrix2,tr("Editor command:"),nullptr,JUSTIFY_LEFT|LAYOUT_CENTER_Y|LAYOUT_FILL_X); editor=new FXTextField(matrix2,6,nullptr,0,FRAME_SUNKEN|FRAME_THICK|LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN,0,0,0,0, 2,2,2,2); - editor->setTipText(tr("Path to text editor program\nCommand line arguments are assembled from the selected file(s) as follows:\n %f Replaced by current filename;\n %F Replaced by selected filenames;\n %u Replaced by URL encoding of current filename;\n %U Replaced by URL encoding of selected files;\n %d Replaced by current working directory;\n %% Replaced by simply '%'.")); + editor->setTipText(tr("Path to text editor program\nCommand line arguments are assembled from the selected file(s) as follows:\n %f Replaced by current pathname;\n %F Replaced by selected pathnames;\n %n Replaced by current filename;\n %N Replaced by selected filenames;\n %u Replaced by URL encoding of current filename;\n %U Replaced by URL encoding of selected files;\n %d Replaced by current working directory;\n %% Replaced by simply '%'.")); new FXButton(matrix2,tr("\tBrowse..."),dir,this,ID_BROWSE_EDITOR,FRAME_RAISED|FRAME_THICK|LAYOUT_CENTER_Y); new FXLabel(matrix2,tr("Terminal command:"),nullptr,JUSTIFY_LEFT|LAYOUT_CENTER_Y|LAYOUT_FILL_X); @@ -160,7 +160,7 @@ Preferences::Preferences(PathFinderMain *own):FXDialogBox(own,"PathFinder Prefer FXHorizontalFrame *commandset=new FXHorizontalFrame(commandgroup,LAYOUT_SIDE_TOP|LAYOUT_FILL_X); new FXButton(commandset,tr("\tBrowse..."),dir,this,ID_BROWSE_COMMAND,LAYOUT_RIGHT|LAYOUT_CENTER_Y|FRAME_RAISED|FRAME_THICK); command=new FXTextField(commandset,40,this,ID_COMMAND,LAYOUT_FILL_X|LAYOUT_CENTER_Y|FRAME_SUNKEN|FRAME_THICK); - command->setTipText(tr("Path to program associated with the file\nCommand line arguments are assembled from the selected file(s) as follows:\n %f Replaced by current filename;\n %F Replaced by selected filenames;\n %u Replaced by URL encoding of current filename;\n %U Replaced by URL encoding of selected files;\n %d Replaced by current working directory;\n %% Replaced by simply '%'.")); + command->setTipText(tr("Path to program associated with the file\nCommand line arguments are assembled from the selected file(s) as follows:\n %f Replaced by current pathname;\n %F Replaced by selected pathnames;\n %n Replaced by current filename;\n %N Replaced by selected filenames;\n %u Replaced by URL encoding of current filename;\n %U Replaced by URL encoding of selected files;\n %d Replaced by current working directory;\n %% Replaced by simply '%'.")); runinterminal=new FXCheckButton(commandgroup,tr("Run in terminal\t\tRun command in terminal."),this,ID_RUN_IN_TERMINAL,ICON_BEFORE_TEXT|LAYOUT_SIDE_LEFT); changedirectory=new FXCheckButton(commandgroup,tr("Change directory\t\tChange directory before running command."),this,ID_CHANGE_DIRECTORY,ICON_BEFORE_TEXT|LAYOUT_SIDE_LEFT); diff --git a/tests/codecs.cpp b/tests/codecs.cpp index 70c9ebc..25c8076 100644 --- a/tests/codecs.cpp +++ b/tests/codecs.cpp @@ -15,6 +15,7 @@ #include "FXUTF16Codec.h" #include "FXUTF32Codec.h" #include "FXUTF8Codec.h" + /* @@ -35,142 +36,473 @@ FXUTF32Codec utf32; FXUTF32BECodec utf32be; FXUTF32LECodec utf32le; - +const FXschar utf8Len[256]={ + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, + 4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1 + }; // UTF8 string of 1, 2, 3, 4, 5, and 6 bytes const FXchar utfteststring[]="\x7f\xdf\xbf\xef\xbf\xbf\xf7\xbf\xbf\xbf\xfb\xbf\xbf\xbf\xbf\xfd\xbf\xbf\xbf\xbf\xbf"; +/*******************************************************************************/ + +// Turns out this is the best one (when NO branch predict) +static inline void inc3(const FXchar*& ptr){ + FXival c=(FXuchar)*ptr; + ptr-=((191-c)>>63)+((223-c)>>63)+((239-c)>>63)-1; + } + + +static inline FXival utf8len(FXival c){ + return 1-((191-c)>>63)-((223-c)>>63)-((239-c)>>63); + } + + +// Turns out this is the best one (when NO branch predict) +// inc3 and inc4 are very close on Zen3 +static inline void inc4(const FXchar*& ptr){ + FXuchar c=*ptr; + ptr+=(((0xE5000000>>((c>>4)<<1))&3)+1); + } + + +static inline void inc5(const FXchar*& ptr){ + FXuchar c=*ptr++; + if(0xC0<=c){ ptr++; + if(0xE0<=c){ ptr++; + if(0xF0<=c){ ptr++; }}} + } + + +// The best one yet (when branch predict) +static inline void inc6(const FXchar*& ptr){ + if(0xC0<=(FXuchar)*ptr){ if(0xE0<=(FXuchar)*ptr){ if(0xF0<=(FXuchar)*ptr){ ptr++; } ptr++; } ptr++; } ptr++; + } + + +// Not horrible but needs table... +static inline void inc7(const FXchar*& ptr){ + ptr+=utf8Len[(FXuchar)*ptr]; + } + // Test roundtrip for codec void roundtriptest(FXTextCodec *codec){ FXchar dst[32],src[32]; - FXint c,n,i,j; + FXint i,j; FXwchar wc; - printf("Roundtrip test for: %s..\n",codec->name()); + fxmessage("Roundtrip test for: %s..\n",codec->name()); for(i=0; i<256; i++){ src[0]=i; codec->mb2wc(wc,src,1); codec->wc2mb(dst,32,wc); j=(FXuchar)dst[0]; - printf("0x%02x -> 0x%04x -> 0x%02x %s\n",i,wc,j,(i!=j)?"BAD":""); + fxmessage("0x%02x -> 0x%04x -> 0x%02x %s\n",i,wc,j,(i!=j)?"BAD":""); } - printf("Roundtrip test done!\n"); + fxmessage("Roundtrip test done!\n"); } // Test utf8 roundtrip for codec void utf8roundtriptest(FXTextCodec *codec){ FXchar dst[32],src[32]; - FXint c,n,i,j; - FXwchar wc; - printf("UTF8 Roundtrip test for: %s..\n",codec->name()); + FXint n,i,j; + fxmessage("UTF8 Roundtrip test for: %s..\n",codec->name()); for(i=0; i<256; i++){ src[0]=i; memset(dst,0,sizeof(dst)); n=codec->mb2utf(dst,32,src,1); - if(n<=0) printf("mb2utf(0x%02x) gave error %d\n",i,n); + if(n<=0) fxmessage("mb2utf(0x%02x) gave error %d\n",i,n); memset(src,0,sizeof(src)); n=codec->utf2mb(src,32,dst,n); - if(n<=0) printf("utf2mb(0x%02x) gave error %d\n",i,n); + if(n<=0) fxmessage("utf2mb(0x%02x) gave error %d\n",i,n); j=(FXuchar)src[0]; - if(i!=j) printf("0x%02x -> utf8 -> 0x%02x\n",i,j); + if(i!=j) fxmessage("0x%02x -> utf8 -> 0x%02x\n",i,j); } - printf("UTF8 Roundtrip test done!\n"); + fxmessage("UTF8 Roundtrip test done!\n"); } // Test buffer -static FXchar buffer[1024]; +static FXchar buffer[1024]; // Start the whole thing -int main(int,char**){ - FXTime beg,end; +int main(int argc,char *argv[]){ + const FXchar *ptr; + FXnchar scratch[32]; + FXnchar hctarcs[32]; FXwchar w1,w2; - FXint n,m; + FXint n,m,s; + FXint mode=0; // Round-trip tests - printf("Testing utf2wccvt(wc2utfcvt(wc)) == wc\n"); + fxmessage("**** Testing utf2wcs(wcs2utf(str))\n"); + + // Probability distributions + if(1 data('\0',100000000); + FXchar* head=data.data(); + FXchar* tail=data.data()+data.no(); + FXchar* p=head; + FXTime beg,end; + long count,sum; + + fxmessage("ARRAY: head=%p tail=%p\n",head,tail); + + count=0; + sum=0; + while(p+4<=tail){ + if(mode==0){ // Uniformly 1,2,3, or 4 + w1=rnd.randLong()&3; + switch(w1){ + case 0: + w1=rnd.randLong()%0x80; + break; + case 1: + w1=0x80+rnd.randLong()%(0x800-0x80); + break; + case 2: + w1=0x800+rnd.randLong()%(0x10000-0x800); + break; + case 3: + w1=0x10000+rnd.randLong()%(0x110000-0x10000); + break; + } + } + else if(mode==1){ // Up to 1 + w1=rnd.randLong()%0x80; + } + else if(mode==2){ // Up to 2 + w1=rnd.randLong()%0x800; + } + else if(mode==3){ // Up to 3 + w1=rnd.randLong()%0x10000; + } + else if(mode==4){ // Up to 4 + w1=rnd.randLong()%0x110000; + } + p+=wc2utf(p,w1); + sum+=w1; + count++; + } + fxmessage("ARRAY: count=%'ld sum=%'ld end=%p\n",count,sum,p); + + fxmessage("**** wcinc: move forward\n"); + count=0; + sum=0; + ptr=head; + beg=fxgetticks(); + do{ + sum+=wcnxt(ptr); + count++; + } + while(ptr+4<=tail); + end=fxgetticks(); + fxmessage("wcinc: count=%'ld sum=%'ld end=%p\n",count,sum,ptr); + fxmessage("wcinc: %'ld ticks %'ld chars %.2lf ticks/char\n",(long)(end-beg),count,(FXdouble)(end-beg)/count); + + fxmessage("**** wcdec: move backward\n"); + count=0; + sum=0; + beg=fxgetticks(); + do{ + sum+=wcprv(ptr); + count++; + } + while(head=argc){ fxwarning("rex: missing capture levels.\n"); return 1; } sscanf(argv[arg],"%d",&ncap); } - else if(compare(argv[arg],"-?")==0 || compare(argv[arg],"-h")==0 || compare(argv[arg],"--help")==0){ + else if(FXString::compare(argv[arg],"-?")==0 || FXString::compare(argv[arg],"-h")==0 || FXString::compare(argv[arg],"--help")==0){ printusage(); return 0; } - else if(compare(argv[arg],"-tracetopics")==0){ + else if(FXString::compare(argv[arg],"-tracetopics")==0){ if(++arg>=argc){ fxwarning("rex: missing argument for -tracetopics.\n"); return 0; } setTraceTopics(argv[arg++]); continue; diff --git a/tests/tabbook.cpp b/tests/tabbook.cpp index 0636131..aa79531 100644 --- a/tests/tabbook.cpp +++ b/tests/tabbook.cpp @@ -119,12 +119,14 @@ TabBookWindow::TabBookWindow(FXApp *a):FXMainWindow(a,"Tab Book Test",nullptr,nu fileframe=new FXHorizontalFrame(tabbook,FRAME_THICK|FRAME_RAISED); boxframe=new FXHorizontalFrame(fileframe,FRAME_THICK|FRAME_SUNKEN|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,0,0, 0,0,0,0); filelist=new FXFileList(boxframe,nullptr,0,ICONLIST_EXTENDEDSELECT|LAYOUT_FILL_X|LAYOUT_FILL_Y); + filelist->setDirectory(FXSystem::getHomeDirectory()); // Third item is a directory list tab3=new FXTabItem(tabbook,"T&ree List\tSwitch to third panel",nullptr); dirframe=new FXHorizontalFrame(tabbook,FRAME_THICK|FRAME_RAISED); boxframe=new FXHorizontalFrame(dirframe,FRAME_THICK|FRAME_SUNKEN|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,0,0, 0,0,0,0); dirlist=new FXDirList(boxframe,nullptr,0,DIRLIST_SHOWFILES|TREELIST_SHOWS_LINES|TREELIST_SHOWS_BOXES|LAYOUT_FILL_X|LAYOUT_FILL_Y); + dirlist->setDirectory(FXSystem::getHomeDirectory()); // Fourth item is text tab4=new FXTabItem(tabbook,"Text\tSwitch to fourth panel",nullptr); diff --git a/tests/timefmt.cpp b/tests/timefmt.cpp index 396a463..94bc343 100644 --- a/tests/timefmt.cpp +++ b/tests/timefmt.cpp @@ -368,7 +368,7 @@ int main(int argc,char* argv[]){ for(FXint d=0; d<=365; ++d){ FXSystem::systemTimeFromTime(st,z); string=FXSystem::systemTimeFormat(st,"%Y-%m-%d %H:%M:%S"); - fxmessage("date=%s dst=%d\n",string.text(),FXSystem::daylightSavingsActive(z)); + fxmessage("date=%s dst=%lld\n",string.text(),FXSystem::daylightSavingsActive(z)); z+=DAY; } fxmessage("\n"); diff --git a/tests/variant.cpp b/tests/variant.cpp index 33a57f5..9eb0f27 100644 --- a/tests/variant.cpp +++ b/tests/variant.cpp @@ -13,6 +13,9 @@ void printusage(const char* prog){ fxmessage(" --dent Set indentation amount.\n"); fxmessage(" --wrap Set line wrap columns.\n"); fxmessage(" --esc Set unicode escape mode (0=OFF,1=\\xHH,2=\\uHHHH).\n"); + fxmessage(" --ver 5 Set JSON version (currently, 1...5).\n"); + fxmessage(" --single-quotes Set single quotes mode (JSON5 only).\n"); + fxmessage(" --double-quotes Set double quotes mode.\n"); fxmessage(" -h, --help Print help.\n"); } @@ -26,7 +29,10 @@ int main(int argc,char *argv[]){ FXint flow; FXint dent; FXint wrap; + FXint quote; FXint esc; + FXint ver; + FXbool ok=true; // JSON I/O FXJSONFile json; @@ -40,7 +46,18 @@ int main(int argc,char *argv[]){ flow=json.getOutputFlow(); dent=json.getIndentation(); wrap=json.getLineWrap(); + quote=json.getQuote(); esc=json.getEscapeMode(); + ver=json.getVersion(); + + fxmessage("sizeof(FXVariant) = %ld\n",sizeof(FXVariant)); + fxmessage("sizeof(FXVariantMap) = %ld\n",sizeof(FXVariantMap)); + fxmessage("sizeof(FXVariantArray) = %ld\n",sizeof(FXVariantArray)); + fxmessage("sizeof(FXString) = %ld\n",sizeof(FXString)); + fxmessage("sizeof(FXHash) = %ld\n",sizeof(FXHash)); + fxmessage("sizeof(FXStringDictionary) = %ld\n",sizeof(FXStringDictionary)); + fxmessage("sizeof(FXDictionary) = %ld\n",sizeof(FXDictionary)); + fxmessage("sizeof(FXReverseDictionary) = %ld\n",sizeof(FXReverseDictionary)); // Grab a few arguments for(FXint arg=1; arg=argc){ fxmessage("Missing escape mode argument.\n"); exit(1); } esc=strtoul(argv[arg],nullptr,0); } + else if(strcmp(argv[arg],"--ver")==0){ + if(++arg>=argc){ fxmessage("Missing version argument.\n"); exit(1); } + ver=strtoul(argv[arg],nullptr,0); + } + else if(strcmp(argv[arg],"--single-quotes")==0){ + quote='\''; + } + else if(strcmp(argv[arg],"--double-quotes")==0){ + quote='"'; + } else{ fxmessage("Bad argument.\n"); printusage(argv[0]); @@ -114,8 +141,8 @@ int main(int argc,char *argv[]){ var["map"]["more"]["c"]=299792458.0; var["map"]["more"]["answer"]=42.0; var["map"]["more"]["letter"]="Unicode: \xC3\xBC Hex:\377\xff\b\n\f\v\""; - var["emptymap"].setType(FXVariant::VMap); - var["emptyarray"].setType(FXVariant::VArray); + var["emptymap"].setType(FXVariant::MapType); + var["emptyarray"].setType(FXVariant::ArrayType); for(FXival i=0; i<100; ++i){ var["bigarray"][i]=Math::sin(0.005*i/PI); } @@ -131,7 +158,7 @@ int main(int argc,char *argv[]){ } fxmessage("Start load from: %s\n",loadfile); FXJSON::Error loaderr=json.load(var); - fxmessage("Loaded %lld bytes, %lld lines\n",json.getOffset(),json.getLine()); + fxmessage("Loaded %lld bytes, %d lines\n",json.getOffset(),json.getLine()); if(loaderr!=FXJSON::ErrOK){ fxmessage("Error: %s:%d:%d: %s\n",loadfile,json.getLine(),json.getColumn(),FXJSON::getError(loaderr)); } @@ -151,6 +178,8 @@ int main(int argc,char *argv[]){ json.setOutputFlow(flow); json.setLineWrap(wrap); json.setEscapeMode(esc); + json.setQuote(quote); + json.setVersion(ver); // Report float precision used to save fxmessage("Precision: %d format: %d flow: %d dent: %d wrap: %d\n",precision,format,flow,dent,wrap); @@ -162,7 +191,7 @@ int main(int argc,char *argv[]){ } fxmessage("Start save to: %s\n",savefile); FXJSON::Error saveerr=json.save(var); - fxmessage("Stored %lld bytes, %lld lines\n",json.getOffset(),json.getLine()); + fxmessage("Stored %lld bytes, %d lines\n",json.getOffset(),json.getLine()); if(saveerr!=FXJSON::ErrOK){ fxmessage("Error: %s:%d:%d: %s\n",savefile,json.getLine(),json.getColumn(),FXJSON::getError(saveerr)); } diff --git a/utils/reswrap.cpp b/utils/reswrap.cpp index 07e81f9..575db7c 100644 --- a/utils/reswrap.cpp +++ b/utils/reswrap.cpp @@ -221,7 +221,7 @@ static void prologue(OPTIONS* opts){ } } if(opts->comments){ - clock=time(nullptr); + clock=time(NULL); strftime(date,sizeof(date),"%Y/%m/%d %H:%M:%S",localtime(&clock)); fprintf(opts->outfile,"/*********** Generated on %s by reswrap version %s *********/\n\n",date,version); } @@ -680,7 +680,7 @@ int main(int argc,char **argv){ /* Process resource file */ if(!processresourcefile(argv[arg],resource,&opts)){ - fprintf(stderr,"reswrap: error reading resource file: %s\n",argv[arg]); + fprintf(stderr,"reswrap: error reading resource file: \"%s\"\n",argv[arg]); break; }