dclib-color.c 132 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357
  1. /***************************************************************************
  2. * *
  3. * _____ ____ *
  4. * | __ \ / __ \ _ _ _____ *
  5. * | | \ \ / / \_\ | | | | _ \ *
  6. * | | \ \| | | | | | |_| | *
  7. * | | | || | | | | | ___/ *
  8. * | | / /| | __ | | | | _ \ *
  9. * | |__/ / \ \__/ / | |___| | |_| | *
  10. * |_____/ \____/ |_____|_|_____/ *
  11. * *
  12. * Wiimms source code library *
  13. * *
  14. ***************************************************************************
  15. * *
  16. * Copyright (c) 2012-2022 by Dirk Clemens <wiimm@wiimm.de> *
  17. * *
  18. ***************************************************************************
  19. * *
  20. * This library is free software; you can redistribute it and/or modify *
  21. * it under the terms of the GNU General Public License as published by *
  22. * the Free Software Foundation; either version 2 of the License, or *
  23. * (at your option) any later version. *
  24. * *
  25. * This library is distributed in the hope that it will be useful, *
  26. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  27. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  28. * GNU General Public License for more details. *
  29. * *
  30. * See file gpl-2.0.txt or http://www.gnu.org/licenses/gpl-2.0.txt *
  31. * *
  32. ***************************************************************************/
  33. #define _GNU_SOURCE 1
  34. #include <unistd.h>
  35. #include <stdio.h>
  36. #include <stddef.h>
  37. #include <errno.h>
  38. #include <signal.h>
  39. #include <sys/ioctl.h>
  40. //#include <ncurses/curses.h>
  41. //#include <term.h>
  42. #include "dclib-color.h"
  43. #include "dclib-basics.h"
  44. #include "dclib-utf8.h"
  45. #ifdef DCLIB_TERMINAL
  46. #include "dclib-terminal.h"
  47. #endif
  48. //
  49. ///////////////////////////////////////////////////////////////////////////////
  50. /////////////// color modes ///////////////
  51. ///////////////////////////////////////////////////////////////////////////////
  52. const KeywordTab_t color_mode_keywords[] =
  53. {
  54. { COLMD_OFF, "OFF", "NONE", 0 },
  55. { COLMD_OFF, "NO-COLORS", "NOCOLORS", 0 },
  56. { COLMD_OFF, "0-COLORS", "0COLORS", 0 },
  57. { COLMD_AUTO, "AUTO", 0, 0 },
  58. { COLMD_ON, "ON", 0, 0 },
  59. { COLMD_8_COLORS, "8-COLORS", "8COLORS", 0 },
  60. { COLMD_256_COLORS, "256-COLORS", "256COLORS", 0 },
  61. {0,0,0,0}
  62. };
  63. ColorMode_t opt_colorize = COLMD_AUTO;
  64. ///////////////////////////////////////////////////////////////////////////////
  65. int ScanOptColorize ( ColorMode_t *opt, ccp arg, ccp err_prefix )
  66. {
  67. if (!opt)
  68. opt = &opt_colorize;
  69. if (!arg)
  70. {
  71. if ( *opt < COLMD_ON )
  72. *opt = COLMD_ON;
  73. return 0;
  74. }
  75. int abbrev;
  76. const KeywordTab_t *key = ScanKeyword(&abbrev,arg,color_mode_keywords);
  77. if (!key)
  78. return PrintKeywordError( color_mode_keywords, arg, abbrev,
  79. err_prefix ? err_prefix : "Option --color: ",
  80. "keyword");
  81. *opt = key->id;
  82. return 0;
  83. }
  84. ///////////////////////////////////////////////////////////////////////////////
  85. ccp GetColorModeName ( ColorMode_t col_mode, ccp res_not_found )
  86. {
  87. return GetKewordNameById(color_mode_keywords,col_mode,res_not_found);
  88. }
  89. ///////////////////////////////////////////////////////////////////////////////
  90. ColorMode_t NormalizeColorMode ( ColorMode_t col_mode, int n_colors )
  91. {
  92. // returns COLMD_OFF or COLMD_8_COLORS or COLMD_256_COLORS
  93. switch (col_mode)
  94. {
  95. case COLMD_OFF:
  96. case COLMD_8_COLORS:
  97. case COLMD_256_COLORS:
  98. return col_mode;
  99. case COLMD_ON:
  100. return n_colors < 256 ? COLMD_8_COLORS : COLMD_256_COLORS;
  101. default:
  102. //case COLMD_AUTO:
  103. return n_colors < 8 ? COLMD_OFF
  104. : n_colors < 256 ? COLMD_8_COLORS : COLMD_256_COLORS;
  105. }
  106. }
  107. ///////////////////////////////////////////////////////////////////////////////
  108. ColorMode_t NormalizeColorModeByTermName
  109. (
  110. ColorMode_t col_mode, // predefind mode
  111. ccp term_name // find "256color" in terminal name.
  112. // if NULL: use getenv("TERM")
  113. // assume 8 or 256 colors!
  114. )
  115. {
  116. if (!term_name)
  117. term_name = getenv("TERM");
  118. const int n_colors = term_name && strstr(term_name,"256color") ? 256 : 8;
  119. return NormalizeColorMode(col_mode,n_colors);
  120. }
  121. ///////////////////////////////////////////////////////////////////////////////
  122. ColorMode_t GetNextColorMode ( ColorMode_t col_mode )
  123. {
  124. switch(col_mode)
  125. {
  126. case COLMD_8_COLORS: return COLMD_256_COLORS;
  127. case COLMD_256_COLORS: return COLMD_OFF;
  128. default: return COLMD_8_COLORS;
  129. }
  130. }
  131. ///////////////////////////////////////////////////////////////////////////////
  132. ColorMode_t GetPrevColorMode ( ColorMode_t col_mode )
  133. {
  134. switch(col_mode)
  135. {
  136. case COLMD_8_COLORS: return COLMD_OFF;
  137. case COLMD_256_COLORS: return COLMD_8_COLORS;
  138. default: return COLMD_256_COLORS;
  139. }
  140. }
  141. //
  142. ///////////////////////////////////////////////////////////////////////////////
  143. /////////////// print lines with autobreak ///////////////
  144. ///////////////////////////////////////////////////////////////////////////////
  145. void PutLines
  146. (
  147. FILE * f, // valid output stream
  148. int indent, // indent of output
  149. int fw, // field width of output
  150. int first_line, // length without prefix of already printed first line
  151. ccp prefix, // NULL or prefix for each line
  152. ccp text, // text to print
  153. ccp eol // End-Of-Line text. If NULL -> LF
  154. )
  155. {
  156. DASSERT(f);
  157. DASSERT( indent >= 0 );
  158. if (!prefix)
  159. prefix = "";
  160. if (!eol)
  161. eol = "\n";
  162. TRACE("PutLines(,%d,%d,%d,%.10s,%.20s)\n",indent,fw,first_line,prefix,text);
  163. fw -= strlen(prefix);
  164. if ( fw < 10 )
  165. fw = 10;
  166. ccp prefix1 = "";
  167. int indent1, fw1;
  168. if ( indent > first_line )
  169. {
  170. indent1 = indent - first_line;
  171. fw1 = fw - indent;
  172. }
  173. else
  174. {
  175. indent1 = 0;
  176. fw1 = fw - first_line;
  177. }
  178. fw -= indent;
  179. if ( fw < 20 )
  180. fw = 20;
  181. if ( fw1 < 20 )
  182. {
  183. fputs(eol,f);
  184. indent1 = indent;
  185. fw1 = fw;
  186. prefix1 = prefix;
  187. }
  188. while ( *text )
  189. {
  190. // skip blank and control
  191. if ( *text == '\n' )
  192. {
  193. // don't skip spaces behind a LF ==> needed for tables
  194. while ( *text > 0 && *text < ' ' )
  195. text++;
  196. }
  197. else
  198. {
  199. // but ignore spaces on an automatic line break
  200. while ( *text > 0 && *text <= ' ' )
  201. text++;
  202. }
  203. // setup
  204. ccp start = text, last_blank = text;
  205. ccp max = text + fw1;
  206. while ( text < max && *text && *text != '\n' )
  207. {
  208. if ( *text > 0 && *text <= ' ' )
  209. last_blank = text;
  210. text++;
  211. }
  212. // set back to last blank
  213. if ( last_blank > start && (u8)*text > ' ' )
  214. text = last_blank;
  215. // print out
  216. if ( *text || text > start )
  217. fprintf(f,"%s%*s%.*s%s",
  218. prefix1, indent1, "",
  219. (int)(text-start), start, eol );
  220. // use standard values for next lines
  221. indent1 = indent;
  222. fw1 = fw;
  223. prefix1 = prefix;
  224. }
  225. }
  226. ///////////////////////////////////////////////////////////////////////////////
  227. void PrintArgLines
  228. (
  229. FILE * f, // valid output stream
  230. int indent, // indent of output
  231. int fw, // field width of output
  232. int first_line, // length without prefix of already printed first line
  233. ccp prefix, // NULL or prefix for each line
  234. ccp format, // format string for vsnprintf()
  235. va_list arg // parameters for 'format'
  236. )
  237. {
  238. DASSERT(f);
  239. DASSERT(format);
  240. char buf[10000];
  241. va_list arg2;
  242. va_copy(arg2,arg);
  243. int stat = vsnprintf(buf,sizeof(buf),format,arg2);
  244. va_end(arg2);
  245. if ( stat < sizeof(buf) )
  246. {
  247. PutLines(f,indent,fw,first_line,prefix,buf,0);
  248. return;
  249. }
  250. //--- buffer too small, use dynamic memory
  251. noPRINT("PrintArgGrowBuffer() -> MALLOC(%u)\n",stat+1);
  252. char *temp = MALLOC(stat+1);
  253. vsnprintf(temp,stat+1,format,arg);
  254. va_end(arg);
  255. PutLines(f,indent,fw,first_line,prefix,temp,0);
  256. FREE(temp);
  257. }
  258. ///////////////////////////////////////////////////////////////////////////////
  259. void PrintLines
  260. (
  261. FILE * f, // valid output stream
  262. int indent, // indent of output
  263. int fw, // field width of output
  264. int first_line, // length without prefix of already printed first line
  265. ccp prefix, // NULL or prefix for each line
  266. ccp format, // format string for vsnprintf()
  267. ... // arguments for 'vsnprintf(format,...)'
  268. )
  269. {
  270. DASSERT(f);
  271. DASSERT(format);
  272. va_list arg;
  273. va_start(arg,format);
  274. PrintArgLines(f,indent,fw,first_line,prefix,format,arg);
  275. va_end(arg);
  276. }
  277. //
  278. ///////////////////////////////////////////////////////////////////////////////
  279. /////////////// print colored lines with autobreak ///////////////
  280. ///////////////////////////////////////////////////////////////////////////////
  281. uint PutColoredLines
  282. (
  283. // returns the number of written lines
  284. FILE * f, // valid output stream
  285. const ColorSet_t *colset, // NULL or color set
  286. int indent, // indent of output
  287. int fw, // field width; indent+prefix+eol don't count
  288. ccp prefix, // NULL or prefix for each line
  289. ccp eol, // End-Of-Line text. If NULL -> LF
  290. ccp text // text to print
  291. )
  292. {
  293. DASSERT(f);
  294. DASSERT(text);
  295. //--- normalize params
  296. indent = NormalizeIndent(indent);
  297. if ( fw < 1 || fw > 1000 )
  298. fw = 1000;
  299. else if ( fw < 20 )
  300. fw = 20;
  301. if (!eol)
  302. eol = "\n";
  303. if (!prefix)
  304. prefix = "";
  305. indent += strlen(prefix);
  306. if (!colset)
  307. colset = GetFileColorSet(f);
  308. //--- setup tabs
  309. u8 is_tab[200];
  310. memset(is_tab,0,sizeof(is_tab));
  311. //--- prepare output buffer
  312. char buf[10000];
  313. char *buf_end = buf + 3*sizeof(buf)/4;
  314. int cont_indent = -1;
  315. uint n_lines = 0, n_space = 0;
  316. uint column = 0;
  317. ccp next_col = 0;
  318. enum { GB_NONE, GB_SIGN, GB_COMMA, GB_SPACE } gb_mode = GB_NONE;
  319. struct gb_save_t
  320. {
  321. ccp text; // text position before code assignment
  322. char *dest; // destination
  323. ccp col_active; // NULL or active color by last "{name}"
  324. ccp col_embed; // NULL or active color "{name|text}"
  325. };
  326. struct gb_save_t cur = { text, buf, 0, 0 };
  327. struct gb_save_t save = cur; // only valid if gb_mode != GB_NONE
  328. //--- main loop
  329. for(;;)
  330. {
  331. #ifdef TEST
  332. if ( n_lines > 1000 )
  333. return n_lines;
  334. #endif
  335. cur.text = text;
  336. u32 code = ScanUTF8AnsiChar(&text);
  337. switch(code)
  338. {
  339. case 0:
  340. if (!column)
  341. return n_lines;
  342. // fall through
  343. case '\r':
  344. if ( *text == '\n' )
  345. code = *text++;
  346. // fall through
  347. case '\n':
  348. cur.text = text;
  349. new_line:
  350. *cur.dest = 0;
  351. fprintf(f,"%-*s%s%s%s", indent,prefix, buf,
  352. cur.col_active || cur.col_embed ? colset->reset : "", eol );
  353. cur.dest = buf;
  354. text = cur.text;
  355. n_lines++;
  356. column = 0;
  357. n_space = 0;
  358. gb_mode = GB_NONE;
  359. if ( code == '\n' )
  360. cont_indent = -1;
  361. else if (!code)
  362. return n_lines;
  363. else if ( cont_indent > 0 )
  364. n_space = cont_indent;
  365. if ( cur.col_embed )
  366. cur.dest = StringCopyE(cur.dest,buf+sizeof(buf),cur.col_embed);
  367. else if ( cur.col_active )
  368. cur.dest = StringCopyE(cur.dest,buf+sizeof(buf),cur.col_active);
  369. break;
  370. case '{':
  371. if ( *text == '{' )
  372. {
  373. text++;
  374. goto is_char;
  375. }
  376. else if ( *text == '}' )
  377. {
  378. cur.dest = StringCopyE(cur.dest,buf+sizeof(buf),colset->reset);
  379. cur.col_active = cur.col_embed = 0;
  380. text++;
  381. }
  382. else
  383. {
  384. ccp name = text;
  385. while ( *text && *text != '|' && *text != '}' )
  386. text++;
  387. if (!*text)
  388. break;
  389. ccp col = "";
  390. char namebuf[20];
  391. const uint nlen = text - name;
  392. if ( nlen < sizeof(namebuf) )
  393. {
  394. memcpy(namebuf,name,nlen);
  395. namebuf[nlen] = 0;
  396. col = GetColorByName(colset,namebuf);
  397. }
  398. if (*col)
  399. {
  400. //cur.dest = StringCopyE(cur.dest,buf+sizeof(buf),col);
  401. next_col = col;
  402. if ( *text == '}' )
  403. cur.col_active = col;
  404. else
  405. cur.col_embed = col;
  406. }
  407. else if ( *text == '|' )
  408. cur.col_embed = ""; // to detect the closing '}'
  409. text++;
  410. }
  411. break;
  412. case '}':
  413. if (!cur.col_embed)
  414. goto is_char;
  415. cur.col_embed = 0;
  416. cur.dest = StringCopyE(cur.dest,buf+sizeof(buf),
  417. cur.col_active ? cur.col_active : colset->reset );
  418. break;
  419. case '\t':
  420. case ' ':
  421. if ( !n_space++ && column )
  422. {
  423. gb_mode = column < fw/2 ? GB_COMMA : GB_SPACE;
  424. save = cur;
  425. }
  426. if ( code == '\t' )
  427. {
  428. uint pos;
  429. for ( pos = column + n_space; pos < sizeof(is_tab); pos++ )
  430. if (is_tab[pos])
  431. {
  432. n_space = pos - column;
  433. break;
  434. }
  435. }
  436. break;
  437. case '|':
  438. if ( *text == '|' )
  439. {
  440. text++;
  441. goto is_char;
  442. }
  443. else if ( *text == '+' )
  444. {
  445. text++;
  446. uint pos = column + n_space;
  447. if ( pos < sizeof(is_tab) )
  448. is_tab[pos] = 1;
  449. }
  450. else if ( *text == '-' )
  451. {
  452. uint pos = column + n_space;
  453. if ( pos < sizeof(is_tab) )
  454. is_tab[pos] = 0;
  455. }
  456. else if ( *text == '[' )
  457. {
  458. text++;
  459. memset(is_tab,0,sizeof(is_tab));
  460. for(;;)
  461. {
  462. while ( *text == ',' )
  463. text++;
  464. char *end;
  465. uint num = str2ul(text,&end,10);
  466. if ( text == end )
  467. break;
  468. text = end;
  469. if ( num < sizeof(is_tab) )
  470. is_tab[num] = 1;
  471. if ( *text == '*' )
  472. {
  473. text++;
  474. uint delta = str2ul(text,&end,10);
  475. if ( text == end )
  476. break;
  477. if ( delta > 0 )
  478. for ( ; num < sizeof(is_tab); num += delta )
  479. is_tab[num] = 1;
  480. }
  481. }
  482. if ( *text == ']' )
  483. text++;
  484. //HexDump16(stderr,0,0,is_tab,sizeof(is_tab));
  485. }
  486. else
  487. {
  488. if ( *text == '>' )
  489. text++;
  490. cont_indent = column + n_space;
  491. if ( cont_indent > fw/2 )
  492. cont_indent = fw/2;
  493. }
  494. break;
  495. case '+':
  496. case '-':
  497. case '=':
  498. case '/':
  499. if ( gb_mode <= GB_SIGN )
  500. {
  501. gb_mode = GB_SIGN;
  502. save = cur;
  503. }
  504. // fall through
  505. default:
  506. is_char:
  507. column += n_space;
  508. if ( column >= fw )
  509. {
  510. // auto break line
  511. if ( gb_mode > GB_NONE )
  512. cur = save;
  513. while ( *cur.text == ' ' )
  514. cur.text++;
  515. goto new_line;
  516. }
  517. while ( n_space > 0 )
  518. *cur.dest++ = ' ', n_space--;
  519. if (next_col)
  520. {
  521. cur.dest = StringCopyE(cur.dest,buf+sizeof(buf),next_col);
  522. next_col = 0;
  523. }
  524. cur.dest = PrintUTF8Char(cur.dest,code);
  525. if ( cur.dest > buf_end )
  526. goto new_line; // should never happen!
  527. column++;
  528. if ( gb_mode <= GB_COMMA && ( code == ',' || code == ';' ))
  529. {
  530. gb_mode = GB_COMMA;
  531. save = cur;
  532. save.text++;
  533. }
  534. break;
  535. }
  536. }
  537. }
  538. ///////////////////////////////////////////////////////////////////////////////
  539. uint PrintArgColoredLines
  540. (
  541. // returns the number of written lines
  542. FILE * f, // valid output stream
  543. const ColorSet_t *colset, // NULL or color set
  544. int indent, // indent of output
  545. int fw, // field width; indent+prefix+eol don't count
  546. ccp prefix, // NULL or prefix for each line
  547. ccp eol, // End-Of-Line text. If NULL -> LF
  548. ccp format, // format string for vsnprintf()
  549. va_list arg // parameters for 'format'
  550. )
  551. {
  552. DASSERT(f);
  553. DASSERT(format);
  554. char buf[10000];
  555. va_list arg2;
  556. va_copy(arg2,arg);
  557. int stat = vsnprintf(buf,sizeof(buf),format,arg2);
  558. va_end(arg2);
  559. if ( stat < sizeof(buf) )
  560. return PutColoredLines(f,colset,indent,fw,prefix,eol,buf);
  561. //--- buffer too small, use dynamic memory
  562. noPRINT("PrintArgGrowBuffer() -> MALLOC(%u)\n",stat+1);
  563. char *temp = MALLOC(stat+1);
  564. stat = vsnprintf(temp,stat+1,format,arg);
  565. const uint res = PutColoredLines(f,colset,indent,fw,prefix,eol,temp);
  566. FREE(temp);
  567. return res;
  568. }
  569. ///////////////////////////////////////////////////////////////////////////////
  570. uint PrintColoredLines
  571. (
  572. // returns the number of written lines
  573. FILE * f, // valid output stream
  574. const ColorSet_t *colset, // NULL or color set
  575. int indent, // indent of output
  576. int fw, // field width; indent+prefix+eol don't count
  577. ccp prefix, // NULL or prefix for each line
  578. ccp eol, // End-Of-Line text. If NULL -> LF
  579. ccp format, // format string for vsnprintf()
  580. ... // arguments for 'vsnprintf(format,...)'
  581. )
  582. {
  583. DASSERT(f);
  584. DASSERT(format);
  585. va_list arg;
  586. va_start(arg,format);
  587. const uint res
  588. = PrintArgColoredLines(f,colset,indent,fw,prefix,eol,format,arg);
  589. va_end(arg);
  590. return res;
  591. }
  592. //
  593. ///////////////////////////////////////////////////////////////////////////////
  594. /////////////// global commands: TESTCOLORS ///////////////
  595. ///////////////////////////////////////////////////////////////////////////////
  596. // [[color_info_t]]
  597. typedef struct color_info_t
  598. {
  599. bool valid; // >0: data below is valid
  600. u8 m_index; // index of 0..255 for "\e[*m"
  601. s8 m_red; // -1:invalid, 0..5: red value of 'm_index'
  602. s8 m_green; // -1:invalid, 0..5: green value of 'm_index'
  603. s8 m_blue; // -1:invalid, 0..5: blue value of 'm_index'
  604. s8 m_gray; // -1:invalid, 0..23: gray value of 'm_index'
  605. u32 ref_color; // reference colors, based on 'm_index';
  606. u32 src_color; // scanned color
  607. }
  608. color_info_t;
  609. ///////////////////////////////////////////////////////////////////////////////
  610. static bool AssignColorInfo ( color_info_t *ci, u32 rgb )
  611. {
  612. DASSERT(ci);
  613. memset(ci,0,sizeof(*ci));
  614. ci->src_color = rgb & 0xffffff;
  615. ci->m_index = ConvertColorRGBToM256(ci->src_color);
  616. ci->ref_color = ConvertColorM256ToRGB(ci->m_index);
  617. const uint r = ci->ref_color >> 16 & 0xff;
  618. const uint g = ci->ref_color >> 8 & 0xff;
  619. const uint b = ci->ref_color & 0xff;
  620. ci->m_red = SingleColorToM6(r);
  621. ci->m_green = SingleColorToM6(g);
  622. ci->m_blue = SingleColorToM6(b);
  623. ci->m_gray = ( r + g + b + 21 ) / 30;
  624. if ( ci->m_gray > 23 )
  625. ci->m_gray = 23;
  626. else if ( ci->m_gray > 0 )
  627. ci->m_gray--;
  628. return ci->valid = 1;
  629. }
  630. ///////////////////////////////////////////////////////////////////////////////
  631. static bool ScanColorInfo ( color_info_t *ci, ccp arg )
  632. {
  633. DASSERT(ci);
  634. memset(ci,0,sizeof(*ci));
  635. if ( arg && *arg )
  636. {
  637. arg = SkipControls(arg);
  638. ulong num, r, g, b;
  639. if ( *arg >= 'g' && *arg <= 'z' )
  640. {
  641. const char mode = *arg;
  642. arg = SkipControls(arg+1);
  643. num = str2ul(arg,0,10);
  644. switch (mode)
  645. {
  646. case 'm':
  647. return AssignColorInfo(ci,ConvertColorM256ToRGB(num));
  648. case 'g':
  649. return AssignColorInfo(ci,ConvertColorM256ToRGB(232 + num % 24));
  650. case 'c':
  651. r = num / 100 % 10;
  652. g = num / 10 % 10;
  653. b = num % 10;
  654. goto rgb5;
  655. }
  656. }
  657. else
  658. {
  659. char *end;
  660. num = str2ul(arg,&end,16);
  661. ci->valid = true;
  662. if ( end - arg <= 3 )
  663. {
  664. r = num >> 8 & 15;
  665. g = num >> 4 & 15;
  666. b = num & 15;
  667. rgb5:
  668. if ( r > 5 ) r = 5;
  669. if ( g > 5 ) g = 5;
  670. if ( b > 5 ) b = 5;
  671. return AssignColorInfo(ci,ConvertColorM256ToRGB(16 + 36*r + 6*g + b));
  672. }
  673. return AssignColorInfo(ci,num);
  674. }
  675. }
  676. return ci->valid;
  677. }
  678. ///////////////////////////////////////////////////////////////////////////////
  679. static void PrintColorInfo ( FILE *f, color_info_t *ci )
  680. {
  681. DASSERT(f);
  682. DASSERT(ci);
  683. if (ci->valid)
  684. fprintf(f," %06x -> %06x : %3u : %u,%u,%u : %2u"
  685. " \e[48;5;16;38;5;%um test \e[0m"
  686. " \e[48;5;244;38;5;%um test \e[0m"
  687. " \e[48;5;231;38;5;%um test \e[0m "
  688. " \e[38;5;16;48;5;%um test \e[0m"
  689. " \e[38;5;244;48;5;%um test \e[0m"
  690. " \e[38;5;231;48;5;%um test \e[0m\n",
  691. ci->src_color, ci->ref_color,
  692. ci->m_index, ci->m_red, ci->m_green, ci->m_blue, ci->m_gray,
  693. ci->m_index, ci->m_index, ci->m_index,
  694. ci->m_index, ci->m_index, ci->m_index );
  695. else
  696. fputs(" --\n",f);
  697. }
  698. ///////////////////////////////////////////////////////////////////////////////
  699. enumError Command_TESTCOLORS ( int argc, char ** argv )
  700. {
  701. #if HAVE_PRINT
  702. // to force an order-check
  703. GetColorOffsetByName("blue");
  704. #endif
  705. printf("TEST COLORS: %u arguments:\n",argc);
  706. bool sep = true;
  707. int idx;
  708. for ( idx = 0; idx < argc; idx++ )
  709. {
  710. ccp minus = strchr(argv[idx],'-');
  711. if ( minus || sep )
  712. {
  713. putchar('\n');
  714. sep = false;
  715. if ( strlen(argv[idx]) == 1 )
  716. continue;
  717. }
  718. color_info_t ci1;
  719. ScanColorInfo(&ci1,argv[idx]);
  720. PrintColorInfo(stdout,&ci1);
  721. if (!minus)
  722. continue;
  723. color_info_t ci2;
  724. ScanColorInfo(&ci2,minus+1);
  725. if ( ci2.ref_color == ci1.ref_color )
  726. continue;
  727. int r1 = ci1.ref_color >> 16 & 0xff;
  728. int g1 = ci1.ref_color >> 8 & 0xff;
  729. int b1 = ci1.ref_color & 0xff;
  730. int r2 = ci2.ref_color >> 16 & 0xff;
  731. int g2 = ci2.ref_color >> 8 & 0xff;
  732. int b2 = ci2.ref_color & 0xff;
  733. int n_steps = abs( r2 - r1 );
  734. int diff = abs( g2 - g1 );
  735. if ( n_steps < diff )
  736. n_steps = diff;
  737. diff = abs( b2 - b1 );
  738. if ( n_steps < diff )
  739. n_steps = diff;
  740. u8 prev_m = ci1.m_index;
  741. u32 prev_rgb = ci1.ref_color;
  742. int i;
  743. for ( i = 1; i <= n_steps; i++ )
  744. {
  745. uint r = ( r2 - r1 ) * i / n_steps + r1;
  746. uint g = ( g2 - g1 ) * i / n_steps + g1;
  747. uint b = ( b2 - b1 ) * i / n_steps + b1;
  748. u8 new_m = ConvertColorRGB3ToM256(r,g,b);
  749. if ( prev_m != new_m )
  750. {
  751. prev_m = new_m;
  752. color_info_t ci3;
  753. AssignColorInfo(&ci3,r<<16|g<<8|b);
  754. if ( prev_rgb != ci3.ref_color )
  755. {
  756. prev_rgb = ci3.src_color = ci3.ref_color;
  757. PrintColorInfo(stdout,&ci3);
  758. }
  759. }
  760. }
  761. sep = true;
  762. }
  763. putchar('\n');
  764. return ERR_OK;
  765. }
  766. //
  767. ///////////////////////////////////////////////////////////////////////////////
  768. /////////////// color helpers ///////////////
  769. ///////////////////////////////////////////////////////////////////////////////
  770. //
  771. // https://en.wikipedia.org/wiki/ANSI_escape_code
  772. // https://jonasjacek.github.io/colors/
  773. //
  774. // 0..15: 000000 800000 008000 808000 000080 800080 008080 c0c0c0
  775. // 808080 ff0000 00ff00 ffff00 0000ff ff00ff 00ffff ffffff
  776. // => real colors varies on implementation
  777. //
  778. // 6x6x6: 0 95 135 175 215 255 == 00 5f 87 af d7 ff
  779. //
  780. // gray: 8 18 28 ... 238 == 08 12 1c 26 30 3a ... e4 ee f8
  781. //
  782. ///////////////////////////////////////////////////////////////////////////////
  783. //
  784. // mkw-ana testcol 000000-ffffff
  785. // mkw-ana testcol 500-550 550-050 050-055 055-005 005-505 505-500
  786. //
  787. ///////////////////////////////////////////////////////////////////////////////
  788. u32 ColorTab_M0_M15[16] =
  789. {
  790. 0x000000, 0x800000, 0x008000, 0x808000,
  791. 0x000080, 0x800080, 0x008080, 0xc0c0c0,
  792. 0x808080, 0xff0000, 0x00ff00, 0xffff00,
  793. 0x0000ff, 0xff00ff, 0x00ffff, 0xffffff,
  794. };
  795. ///////////////////////////////////////////////////////////////////////////////
  796. u8 ConvertColorRGB3ToM256 ( u8 r, u8 g, u8 b )
  797. {
  798. // 0..5
  799. const int r6 = SingleColorToM6(r);
  800. const int g6 = SingleColorToM6(g);
  801. const int b6 = SingleColorToM6(b);
  802. u8 m256 = 36*r6 + 6*g6 + b6 + 16;
  803. uint delta = abs ( ( r6 ? 55 + 40 * r6 : 0 ) - r )
  804. + abs ( ( g6 ? 55 + 40 * g6 : 0 ) - g )
  805. + abs ( ( b6 ? 55 + 40 * b6 : 0 ) - b );
  806. //printf("%02x>%u %02x>%u %02x>%u : m=%u delta=%d\n",r,r6,g,g6,b,b6,m256,delta);
  807. int m, gray, prev = 0x1000000;
  808. for ( m = 232, gray = 8; m < 256; m++, gray += 10 )
  809. {
  810. const uint d = abs( gray - r ) + abs( gray - g ) + abs( gray - b );
  811. if ( d > prev )
  812. break;
  813. if ( d <= delta )
  814. {
  815. delta = d;
  816. m256 = m;
  817. }
  818. prev = d;
  819. }
  820. return m256;
  821. }
  822. ///////////////////////////////////////////////////////////////////////////////
  823. u8 ConvertColorRGBToM256 ( u32 rgb )
  824. {
  825. return ConvertColorRGB3ToM256( rgb >> 16, rgb >> 8, rgb );
  826. }
  827. ///////////////////////////////////////////////////////////////////////////////
  828. u32 ConvertColorM256ToRGB ( u8 m256 )
  829. {
  830. if ( m256 < 16 )
  831. return ColorTab_M0_M15[m256];
  832. if ( m256 < 232 )
  833. {
  834. m256 -= 16;
  835. const uint r = m256 / 36;
  836. const uint g = m256 / 6 % 6;
  837. const uint b = m256 % 6;
  838. u32 col = 0;
  839. if (r) col |= 0x370000 + 0x280000 * r;
  840. if (g) col |= 0x003700 + 0x002800 * g;
  841. if (b) col |= 0x000037 + 0x000028 * b;
  842. return col;
  843. }
  844. m256 -= 232;
  845. return 0x080808 + m256 * 0x0a0a0a;
  846. }
  847. //
  848. ///////////////////////////////////////////////////////////////////////////////
  849. /////////////// terminal ///////////////
  850. ///////////////////////////////////////////////////////////////////////////////
  851. // Sequence counter for output to stdout (and stderr).
  852. // Functions shall increment it on output, so that other functions
  853. // know about a destroyed screen.
  854. uint stdout_seq_count = 0;
  855. ///////////////////////////////////////////////////////////////////////////////
  856. uint opt_width = 0;
  857. uint opt_max_width = 0;
  858. uint opt_height = 0;
  859. uint opt_max_height = 0;
  860. //-----------------------------------------------------------------------------
  861. int ScanOptWidth ( ccp arg )
  862. {
  863. return ERR_OK != ScanSizeOptU32(
  864. &opt_width, // u32 * num
  865. arg, // ccp source
  866. 1, // default_factor1
  867. 0, // int force_base
  868. "width", // ccp opt_name
  869. 40, // u64 min
  870. 10000, // u64 max
  871. 1, // u32 multiple
  872. 0, // u32 pow2
  873. true // bool print_err
  874. );
  875. }
  876. int ScanOptMaxWidth ( ccp arg )
  877. {
  878. return ERR_OK != ScanSizeOptU32(
  879. &opt_max_width, // u32 * num
  880. arg, // ccp source
  881. 1, // default_factor1
  882. 0, // int force_base
  883. "max-width", // ccp opt_name
  884. 40, // u64 min
  885. 10000, // u64 max
  886. 1, // u32 multiple
  887. 0, // u32 pow2
  888. true // bool print_err
  889. );
  890. }
  891. //-----------------------------------------------------------------------------
  892. int ScanOptHeight ( ccp arg )
  893. {
  894. return ERR_OK != ScanSizeOptU32(
  895. &opt_height, // u32 * num
  896. arg, // ccp source
  897. 1, // default_factor1
  898. 0, // int force_base
  899. "height", // ccp opt_name
  900. 40, // u64 min
  901. 10000, // u64 max
  902. 1, // u32 multiple
  903. 0, // u32 pow2
  904. true // bool print_err
  905. );
  906. }
  907. int ScanOptMaxHeight ( ccp arg )
  908. {
  909. return ERR_OK != ScanSizeOptU32(
  910. &opt_max_height, // u32 * num
  911. arg, // ccp source
  912. 1, // default_factor1
  913. 0, // int force_base
  914. "max-height", // ccp opt_name
  915. 40, // u64 min
  916. 10000, // u64 max
  917. 1, // u32 multiple
  918. 0, // u32 pow2
  919. true // bool print_err
  920. );
  921. }
  922. ///////////////////////////////////////////////////////////////////////////////
  923. ///////////////////////////////////////////////////////////////////////////////
  924. term_size_t GetTermSize ( int default_width, int default_height )
  925. {
  926. PRINT0("GetTermWidth(%d,%d) opt=%d,%d, max=%d,%d\n",
  927. default_width, default_height,
  928. opt_width, opt_height, opt_max_width, opt_max_height );
  929. term_size_t ts;
  930. if ( opt_width > 0 && opt_height > 0 )
  931. {
  932. ts.width = opt_width;
  933. ts.height = opt_height;
  934. }
  935. else
  936. {
  937. ts = GetTermSizeFD(STDOUT_FILENO,default_width,default_height);
  938. if ( opt_width > 0 )
  939. ts.width = opt_width;
  940. else if ( opt_max_width > 0 && ts.width > opt_max_width )
  941. ts.width = opt_max_width;
  942. if ( opt_height > 0 )
  943. ts.height = opt_height;
  944. else if ( opt_max_height > 0 && ts.height > opt_max_height )
  945. ts.height = opt_max_height;
  946. }
  947. return ts;
  948. }
  949. ///////////////////////////////////////////////////////////////////////////////
  950. term_size_t GetTermSizeFD ( int fd, int default_width, int default_height )
  951. {
  952. PRINT("GetTermSizeFD(%d,%d,%d)\n",fd,default_width,default_height);
  953. #ifdef TIOCGSIZE
  954. TRACE(" - have TIOCGSIZE\n");
  955. #endif
  956. #ifdef TIOCGWINSZ
  957. TRACE(" - have TIOCGWINSZ\n");
  958. #endif
  959. #ifndef WIN_SZS_LIB
  960. if (isatty(fd))
  961. {
  962. TRACE(" - isatty\n");
  963. #ifdef TIOCGSIZE
  964. {
  965. struct ttysize ts;
  966. if ( !ioctl(fd,TIOCGSIZE,&ts))
  967. {
  968. PRINT(" - TIOCGSIZE = %d*%d\n",ts.ts_cols,ts.ts_lines);
  969. if ( ts.ts_cols > 0 && ts.ts_lines > 0 )
  970. {
  971. term_size_t tes = {ts.ts_cols,ts.ts_lines};
  972. return tes;
  973. }
  974. }
  975. }
  976. #endif
  977. #ifdef TIOCGWINSZ
  978. {
  979. struct winsize ws;
  980. if ( !ioctl(fd,TIOCGWINSZ,&ws))
  981. {
  982. PRINT(" - TIOCGWINSZ = %d*%d\n",ws.ws_col,ws.ws_row);
  983. if ( ws.ws_col > 0 && ws.ws_row > 0 )
  984. {
  985. term_size_t ts = {ws.ws_col,ws.ws_row};
  986. return ts;
  987. }
  988. }
  989. }
  990. #endif
  991. }
  992. #endif
  993. term_size_t ts = {default_width,default_height};
  994. return ts;
  995. }
  996. ///////////////////////////////////////////////////////////////////////////////
  997. ///////////////////////////////////////////////////////////////////////////////
  998. int GetTermWidth ( int default_value, int min_value )
  999. {
  1000. TRACE("GetTermWidth(%d,%d) opt=%d\n",default_value,min_value,opt_width);
  1001. const term_size_t ts = GetTermSize(default_value,25);
  1002. return ts.width > min_value ? ts.width : min_value;
  1003. }
  1004. ///////////////////////////////////////////////////////////////////////////////
  1005. int GetTermWidthFD ( int fd, int default_value, int min_value )
  1006. {
  1007. TRACE("GetTermWidthFD(%d,%d,%d)\n",fd,default_value,min_value);
  1008. const term_size_t ts = GetTermSizeFD(fd,default_value,25);
  1009. return ts.width > min_value ? ts.width : min_value;
  1010. }
  1011. ///////////////////////////////////////////////////////////////////////////////
  1012. ///////////////////////////////////////////////////////////////////////////////
  1013. int GetTermHeight ( int default_value, int min_value )
  1014. {
  1015. TRACE("GetTermHeight(%d,%d) opt=%d\n",default_value,min_value,opt_height);
  1016. const term_size_t ts = GetTermSize(80,default_value);
  1017. return ts.width > min_value ? ts.width : min_value;
  1018. }
  1019. ///////////////////////////////////////////////////////////////////////////////
  1020. int GetTermHeightFD ( int fd, int default_value, int min_value )
  1021. {
  1022. TRACE("GetTermHeightFD(%d,%d,%d)\n",fd,default_value,min_value);
  1023. const term_size_t ts = GetTermSizeFD(fd,80,default_value);
  1024. return ts.height > min_value ? ts.height : min_value;
  1025. }
  1026. ///////////////////////////////////////////////////////////////////////////////
  1027. ///////////////////////////////////////////////////////////////////////////////
  1028. term_size_t auto_term_size = {80,25};
  1029. uint auto_term_resized = 0; // incremented for each resize, init by 0
  1030. uint auto_term_size_dirty = 0; // >0: SIGWINCH received, auto_term_size is dirty
  1031. //-----------------------------------------------------------------------------
  1032. bool GetAutoTermSize()
  1033. {
  1034. // return true if changed
  1035. auto_term_size_dirty = 0;
  1036. int fd = isatty(1) ? 1 : isatty(0) ? 0 : -1;
  1037. if ( fd >= 0 )
  1038. {
  1039. term_size_t size
  1040. = GetTermSizeFD(fd,auto_term_size.width,auto_term_size.height);
  1041. if (memcmp(&auto_term_size,&size,sizeof(size)))
  1042. {
  1043. auto_term_size = size;
  1044. if (!++auto_term_resized)
  1045. auto_term_resized++;
  1046. return true;
  1047. }
  1048. }
  1049. return false;
  1050. }
  1051. //-----------------------------------------------------------------------------
  1052. static void Signal_SIGWINCH ( int signal )
  1053. {
  1054. if (!++auto_term_size_dirty)
  1055. auto_term_size_dirty++;
  1056. }
  1057. void EnableAutoTermSize()
  1058. {
  1059. signal(SIGWINCH,Signal_SIGWINCH);
  1060. GetAutoTermSize();
  1061. }
  1062. //
  1063. ///////////////////////////////////////////////////////////////////////////////
  1064. ///////////////////////////////////////////////////////////////////////////////
  1065. good_term_width_t good_term_width =
  1066. {
  1067. .min_width = 40,
  1068. .def_width = 100,
  1069. .max_width = 120,
  1070. .good_width = 120
  1071. };
  1072. ///////////////////////////////////////////////////////////////////////////////
  1073. int GetGoodTermWidth ( good_term_width_t *gtw, bool force )
  1074. {
  1075. if (!gtw)
  1076. gtw = &good_term_width;
  1077. if ( force || !gtw->setup_done )
  1078. {
  1079. gtw->setup_done = true;
  1080. int good_width = opt_width;
  1081. if (!good_width)
  1082. {
  1083. good_width = GetTermWidth(gtw->def_width,gtw->min_width);
  1084. const int max = opt_max_width ? opt_max_width : gtw->max_width;
  1085. if ( good_width > max )
  1086. good_width = max;
  1087. }
  1088. if ( good_width < gtw->min_width )
  1089. good_width = gtw->min_width;
  1090. gtw->good_width = good_width;
  1091. }
  1092. return gtw->good_width;
  1093. }
  1094. //
  1095. ///////////////////////////////////////////////////////////////////////////////
  1096. ///////////////////////////////////////////////////////////////////////////////
  1097. ccp TermCursorUp = TERM_CURSOR_UP; // move cursor up
  1098. ccp TermCursorDown = TERM_CURSOR_DOWN; // move cursor down
  1099. ccp TermCursorRight = TERM_CURSOR_RIGHT; // move cursor right
  1100. ccp TermCursorLeft = TERM_CURSOR_LEFT; // move cursor left
  1101. ccp TermCursorUpN = TERM_CURSOR_UP_N; // move cursor N* up (format 1 '%d')
  1102. ccp TermCursorDownN = TERM_CURSOR_DOWN_N; // move cursor N* down (format 1 '%d')
  1103. ccp TermCursorRightN = TERM_CURSOR_RIGHT_N; // move cursor N* right (format 1 '%d')
  1104. ccp TermCursorLeftN = TERM_CURSOR_LEFT_N; // move cursor N* left (format 1 '%d')
  1105. ccp TermClearEOL = TERM_CLEAR_EOL; // clear from cursor to end of line
  1106. ccp TermClearBOL = TERM_CLEAR_BOL; // clear from beginning of line to cursor
  1107. ccp TermClearLine = TERM_CLEAR_LINE; // clear entire line
  1108. ccp TermClearEOD = TERM_CLEAR_EOD; // clear from cursor to end of display
  1109. ccp TermClearBOD = TERM_CLEAR_BOD; // clear from beginning of display to cursor
  1110. ccp TermClearDisplay = TERM_CLEAR_DISPLAY; // clear Entire display
  1111. ccp TermSetWrap = TERM_SET_WRAP; // enabled line wrapping
  1112. ccp TermResetWrap = TERM_RESET_WRAP; // disable line wrapping
  1113. ccp TermTextModeBeg = TERM_TEXT_MODE_BEG; // begin of text mode sequence
  1114. ccp TermTextModeBeg0 = TERM_TEXT_MODE_BEG; // begin of text mode sequence with reset
  1115. ccp TermTextModeEnd = TERM_TEXT_MODE_END; // end of text mode sequence
  1116. ccp TermTextModeReset = TERM_TEXT_MODE_RESET; // reset text mode
  1117. static uint grayscale_tab[4] = {0,8,7,15};
  1118. #if SUPPORT_36_COLORS
  1119. const char ColorIndexName[TCI__N][16] =
  1120. {
  1121. "black",
  1122. "grey1",
  1123. "grey2",
  1124. "grey3",
  1125. "grey4",
  1126. "grey5",
  1127. "grey6",
  1128. "white",
  1129. "red",
  1130. "red_orange",
  1131. "orange",
  1132. "orange_yellow",
  1133. "yellow",
  1134. "yellow_green",
  1135. "green",
  1136. "green_cyan",
  1137. "cyan",
  1138. "cyan_blue",
  1139. "blue",
  1140. "blue_magenta",
  1141. "magenta",
  1142. "magenta_red",
  1143. "b_red",
  1144. "b_red_orange",
  1145. "b_orange",
  1146. "b_orange_yellow",
  1147. "b_yellow",
  1148. "b_yellow_green",
  1149. "b_green",
  1150. "b_green_cyan",
  1151. "b_cyan",
  1152. "b_cyan_blue",
  1153. "b_blue",
  1154. "b_blue_magenta",
  1155. "b_magenta",
  1156. "b_magenta_red",
  1157. };
  1158. #else // !SUPPORT_36_COLORS
  1159. const char ColorIndexName[TCI__N][11] =
  1160. {
  1161. "black",
  1162. "dark gray",
  1163. "light gray",
  1164. "white",
  1165. "red",
  1166. "orange",
  1167. "yellow",
  1168. "green",
  1169. "cyan",
  1170. "blue",
  1171. "magenta",
  1172. "b_red",
  1173. "b_orange",
  1174. "b_yellow",
  1175. "b_green",
  1176. "b_cyan",
  1177. "b_blue",
  1178. "b_magenta",
  1179. };
  1180. #endif // !SUPPORT_36_COLORS
  1181. const int Color18Index[18+1] = // 18 elements + -1 as terminator
  1182. {
  1183. TCI_BLACK, // gray scale
  1184. TCI_DARKGRAY,
  1185. TCI_LIGHTGRAY,
  1186. TCI_WHITE,
  1187. TCI_RED, // normal colors in rainbow order
  1188. TCI_ORANGE,
  1189. TCI_YELLOW,
  1190. TCI_GREEN,
  1191. TCI_CYAN,
  1192. TCI_BLUE,
  1193. TCI_MAGENTA,
  1194. TCI_B_RED, // bold colors in rainbow order
  1195. TCI_B_ORANGE,
  1196. TCI_B_YELLOW,
  1197. TCI_B_GREEN,
  1198. TCI_B_CYAN,
  1199. TCI_B_BLUE,
  1200. TCI_B_MAGENTA,
  1201. -1
  1202. };
  1203. ///////////////////////////////////////////////////////////////////////////////
  1204. ///////////////////////////////////////////////////////////////////////////////
  1205. static char * GetColorCircBuf ( uint len )
  1206. {
  1207. static char circ_buf[2048];
  1208. static char *circ_ptr = circ_buf;
  1209. DASSERT( circ_ptr >= circ_buf && circ_ptr <= circ_buf + sizeof(circ_buf) );
  1210. if ( len > sizeof(circ_buf)/8 )
  1211. return GetCircBuf(len);
  1212. if ( circ_buf + sizeof(circ_buf) - circ_ptr < len )
  1213. circ_ptr = circ_buf;
  1214. char *buf = circ_ptr;
  1215. circ_ptr += len;
  1216. DASSERT( circ_ptr >= circ_buf && circ_ptr <= circ_buf + sizeof(circ_buf) );
  1217. return buf;
  1218. }
  1219. //-----------------------------------------------------------------------------
  1220. ccp GetTextMode
  1221. (
  1222. // returns a pointer to an internal circulary buffer (not GetCircBuf())
  1223. ColorMode_t col_mode, // if < COLMD_ON: return an empty string
  1224. TermTextMode_t mode // mode for text generation
  1225. )
  1226. {
  1227. if ( col_mode < COLMD_ON )
  1228. return EmptyString;
  1229. if ( mode == TTM_RESET )
  1230. return TermTextModeReset;
  1231. uint len = strlen(TermTextModeBeg) + strlen(TermTextModeEnd) + 2;
  1232. if ( mode & TTM_F_COLOR )
  1233. len += 3;
  1234. else if ( mode & TTM_F_GRAYSCALE )
  1235. len += 8;
  1236. if ( mode & TTM_F_BG_COLOR )
  1237. len += 3;
  1238. else if ( mode & TTM_F_BG_GRAYSCALE )
  1239. len += 8;
  1240. if ( mode & TTM_RESET )
  1241. len += 2;
  1242. if ( mode & (TTM_BOLD|TTM_NO_BOLD) )
  1243. len += 3;
  1244. if ( mode & (TTM_UL|TTM_NO_UL) )
  1245. len += 3;
  1246. //--- use a private circulary buffer (long term valid)
  1247. char *buf = GetColorCircBuf(len);
  1248. //--- compose string
  1249. uint sep = 0;
  1250. char *end = buf + len;
  1251. char *dest = StringCopyS(buf,len,TermTextModeBeg);
  1252. if ( mode & TTM_RESET )
  1253. {
  1254. *dest++ = '0';
  1255. sep++;
  1256. }
  1257. if ( mode & TTM_BOLD )
  1258. {
  1259. if (sep++)
  1260. *dest++ = ';';
  1261. *dest++ = '1';
  1262. }
  1263. else if ( mode & TTM_NO_BOLD )
  1264. {
  1265. if (sep++)
  1266. *dest++ = ';';
  1267. *dest++ = '2';
  1268. *dest++ = '2';
  1269. }
  1270. if ( mode & TTM_UL )
  1271. {
  1272. if (sep++)
  1273. *dest++ = ';';
  1274. *dest++ = '4';
  1275. }
  1276. else if ( mode & TTM_NO_UL )
  1277. {
  1278. if (sep++)
  1279. *dest++ = ';';
  1280. *dest++ = '2';
  1281. *dest++ = '4';
  1282. }
  1283. if ( mode & TTM_F_COLOR )
  1284. {
  1285. if (sep++)
  1286. *dest++ = ';';
  1287. dest = snprintfE(dest,end,"%u",(mode&TTM_M_COLOR)+30);
  1288. }
  1289. else if ( mode & TTM_F_GRAYSCALE )
  1290. {
  1291. if (sep++)
  1292. *dest++ = ';';
  1293. dest = snprintfE(dest,end,"38;5;%u",
  1294. grayscale_tab[ mode & TTM_M_GRAYSCALE ]);
  1295. }
  1296. if ( mode & TTM_F_BG_COLOR )
  1297. {
  1298. if (sep++)
  1299. *dest++ = ';';
  1300. dest = snprintfE(dest,end,"%u",((mode&TTM_M_BG_COLOR)>>TTM_SHIFT_BG)+40);
  1301. }
  1302. else if ( mode & TTM_F_BG_GRAYSCALE )
  1303. {
  1304. if (sep++)
  1305. *dest++ = ';';
  1306. dest = snprintfE(dest,end,"48;5;%u",
  1307. grayscale_tab[ (mode & TTM_M_BG_GRAYSCALE) >> TTM_SHIFT_BG ]);
  1308. }
  1309. StringCopyE(dest,end,TermTextModeEnd);
  1310. return buf;
  1311. }
  1312. //
  1313. ///////////////////////////////////////////////////////////////////////////////
  1314. ///////////////////////////////////////////////////////////////////////////////
  1315. #if SUPPORT_36_COLORS
  1316. ccp GetColorMode // 36 colors version
  1317. (
  1318. // returns a pointer to an internal circulary buffer (not GetCircBuf())
  1319. ColorMode_t col_mode, // if < COLMD_ON: return an empty string
  1320. TermColorIndex_t font_index, // index of font color
  1321. TermColorIndex_t bg_index, // index of background color
  1322. GetColorOption_t option // execution options
  1323. )
  1324. {
  1325. col_mode = NormalizeColorMode(col_mode,8);
  1326. if ( col_mode < COLMD_ON )
  1327. return EmptyString;
  1328. //--- recommended combinations
  1329. if ( option & GCM_ALT
  1330. && (uint)font_index < TCI__IGNORE
  1331. && (uint)bg_index < TCI__IGNORE )
  1332. {
  1333. static const u8 tab[TCI__N_BG][TCI__N_FONT] =
  1334. {
  1335. //--- TCI_GRAY0 = TCI_BLACK
  1336. {
  1337. TCI_GRAY2, // TCI_GRAY0 = TCI_BLACK
  1338. TCI_GRAY2, // TCI_GRAY1
  1339. TCI_GRAY3, // TCI_GRAY2 = TCI_DARKGRAY
  1340. TCI_GRAY3, // TCI_GRAY3
  1341. TCI_GRAY4, // TCI_GRAY4
  1342. TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY
  1343. TCI_GRAY6, // TCI_GRAY6
  1344. TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE
  1345. TCI_B_RED, // TCI_RED
  1346. TCI_B_RED_ORANGE, // TCI_RED_ORANGE
  1347. TCI_B_ORANGE, // TCI_ORANGE
  1348. TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  1349. TCI_B_YELLOW, // TCI_YELLOW
  1350. TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN
  1351. TCI_B_GREEN, // TCI_GREEN
  1352. TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN
  1353. TCI_B_CYAN, // TCI_CYAN
  1354. TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE
  1355. TCI_B_BLUE, // TCI_BLUE
  1356. TCI_B_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  1357. TCI_B_MAGENTA, // TCI_MAGENTA
  1358. TCI_B_MAGENTA_RED, // TCI_MAGENTA_RED
  1359. },
  1360. //--- TCI_GRAY1
  1361. {
  1362. TCI_GRAY3, // TCI_GRAY0 = TCI_BLACK
  1363. TCI_GRAY3, // TCI_GRAY1
  1364. TCI_GRAY4, // TCI_GRAY2 = TCI_DARKGRAY
  1365. TCI_GRAY4, // TCI_GRAY3
  1366. TCI_GRAY5, // TCI_GRAY4
  1367. TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY
  1368. TCI_GRAY6, // TCI_GRAY6
  1369. TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE
  1370. TCI_B_RED, // TCI_RED
  1371. TCI_B_RED_ORANGE, // TCI_RED_ORANGE
  1372. TCI_B_ORANGE, // TCI_ORANGE
  1373. TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  1374. TCI_B_YELLOW, // TCI_YELLOW
  1375. TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN
  1376. TCI_B_GREEN, // TCI_GREEN
  1377. TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN
  1378. TCI_B_CYAN, // TCI_CYAN
  1379. TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE
  1380. TCI_B_BLUE, // TCI_BLUE
  1381. TCI_B_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  1382. TCI_B_MAGENTA, // TCI_MAGENTA
  1383. TCI_B_MAGENTA_RED, // TCI_MAGENTA_RED
  1384. },
  1385. //--- TCI_GRAY2 = TCI_DARKGRAY
  1386. {
  1387. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  1388. TCI_GRAY0, // TCI_GRAY1
  1389. TCI_GRAY0, // TCI_GRAY2 = TCI_DARKGRAY
  1390. TCI_GRAY4, // TCI_GRAY3
  1391. TCI_GRAY4, // TCI_GRAY4
  1392. TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY
  1393. TCI_GRAY6, // TCI_GRAY6
  1394. TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE
  1395. TCI_B_RED, // TCI_RED
  1396. TCI_B_RED_ORANGE, // TCI_RED_ORANGE
  1397. TCI_B_ORANGE, // TCI_ORANGE
  1398. TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  1399. TCI_B_YELLOW, // TCI_YELLOW
  1400. TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN
  1401. TCI_B_GREEN, // TCI_GREEN
  1402. TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN
  1403. TCI_B_CYAN, // TCI_CYAN
  1404. TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE
  1405. TCI_B_BLUE, // TCI_BLUE
  1406. TCI_B_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  1407. TCI_B_MAGENTA, // TCI_MAGENTA
  1408. TCI_B_MAGENTA_RED, // TCI_MAGENTA_RED
  1409. },
  1410. //--- TCI_GRAY3
  1411. {
  1412. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  1413. TCI_GRAY0, // TCI_GRAY1
  1414. TCI_GRAY1, // TCI_GRAY2 = TCI_DARKGRAY
  1415. TCI_GRAY1, // TCI_GRAY3
  1416. TCI_GRAY5, // TCI_GRAY4
  1417. TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY
  1418. TCI_GRAY6, // TCI_GRAY6
  1419. TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE
  1420. TCI_B_RED, // TCI_RED
  1421. TCI_B_RED_ORANGE, // TCI_RED_ORANGE
  1422. TCI_B_ORANGE, // TCI_ORANGE
  1423. TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  1424. TCI_B_YELLOW, // TCI_YELLOW
  1425. TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN
  1426. TCI_B_GREEN, // TCI_GREEN
  1427. TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN
  1428. TCI_B_CYAN, // TCI_CYAN
  1429. TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE
  1430. TCI_B_BLUE, // TCI_BLUE
  1431. TCI_B_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  1432. TCI_B_MAGENTA, // TCI_MAGENTA
  1433. TCI_B_MAGENTA_RED, // TCI_MAGENTA_RED
  1434. },
  1435. //--- TCI_GRAY4 = TCI_LIGHTGRAY
  1436. {
  1437. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  1438. TCI_GRAY1, // TCI_GRAY1
  1439. TCI_GRAY1, // TCI_GRAY2 = TCI_DARKGRAY
  1440. TCI_GRAY2, // TCI_GRAY3
  1441. TCI_GRAY2, // TCI_GRAY4
  1442. TCI_GRAY6, // TCI_GRAY5 = TCI_LIGHTGRAY
  1443. TCI_GRAY6, // TCI_GRAY6
  1444. TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE
  1445. TCI_RED, // TCI_RED
  1446. TCI_RED_ORANGE, // TCI_RED_ORANGE
  1447. TCI_B_ORANGE, // TCI_ORANGE
  1448. TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  1449. TCI_B_YELLOW, // TCI_YELLOW
  1450. TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN
  1451. TCI_B_GREEN, // TCI_GREEN
  1452. TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN
  1453. TCI_B_CYAN, // TCI_CYAN
  1454. TCI_CYAN_BLUE, // TCI_CYAN_BLUE
  1455. TCI_BLUE, // TCI_BLUE
  1456. TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  1457. TCI_MAGENTA, // TCI_MAGENTA
  1458. TCI_MAGENTA_RED, // TCI_MAGENTA_RED
  1459. },
  1460. //--- TCI_GRAY5 = TCI_LIGHTGRAY
  1461. {
  1462. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  1463. TCI_GRAY1, // TCI_GRAY1
  1464. TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY
  1465. TCI_GRAY2, // TCI_GRAY3
  1466. TCI_GRAY3, // TCI_GRAY4
  1467. TCI_GRAY3, // TCI_GRAY5 = TCI_LIGHTGRAY
  1468. TCI_GRAY7, // TCI_GRAY6
  1469. TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE
  1470. TCI_RED, // TCI_RED
  1471. TCI_RED_ORANGE, // TCI_RED_ORANGE
  1472. TCI_ORANGE, // TCI_ORANGE
  1473. TCI_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  1474. TCI_B_YELLOW, // TCI_YELLOW
  1475. TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN
  1476. TCI_B_GREEN, // TCI_GREEN
  1477. TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN
  1478. TCI_B_CYAN, // TCI_CYAN
  1479. TCI_CYAN_BLUE, // TCI_CYAN_BLUE
  1480. TCI_BLUE, // TCI_BLUE
  1481. TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  1482. TCI_MAGENTA, // TCI_MAGENTA
  1483. TCI_MAGENTA_RED, // TCI_MAGENTA_RED
  1484. },
  1485. //--- TCI_GRAY6
  1486. {
  1487. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  1488. TCI_GRAY1, // TCI_GRAY1
  1489. TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY
  1490. TCI_GRAY2, // TCI_GRAY3
  1491. TCI_GRAY3, // TCI_GRAY4
  1492. TCI_GRAY3, // TCI_GRAY5 = TCI_LIGHTGRAY
  1493. TCI_GRAY4, // TCI_GRAY6
  1494. TCI_GRAY4, // TCI_GRAY7 = TCI_WHITE
  1495. TCI_RED, // TCI_RED
  1496. TCI_RED_ORANGE, // TCI_RED_ORANGE
  1497. TCI_ORANGE, // TCI_ORANGE
  1498. TCI_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  1499. TCI_ORANGE_YELLOW, // TCI_YELLOW
  1500. TCI_YELLOW_GREEN, // TCI_YELLOW_GREEN
  1501. TCI_GREEN, // TCI_GREEN
  1502. TCI_GREEN_CYAN, // TCI_GREEN_CYAN
  1503. TCI_CYAN, // TCI_CYAN
  1504. TCI_CYAN_BLUE, // TCI_CYAN_BLUE
  1505. TCI_BLUE, // TCI_BLUE
  1506. TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  1507. TCI_MAGENTA, // TCI_MAGENTA
  1508. TCI_MAGENTA_RED, // TCI_MAGENTA_RED
  1509. },
  1510. //--- TCI_GRAY7 = TCI_WHITE
  1511. {
  1512. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  1513. TCI_GRAY1, // TCI_GRAY1
  1514. TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY
  1515. TCI_GRAY3, // TCI_GRAY3
  1516. TCI_GRAY4, // TCI_GRAY4
  1517. TCI_GRAY4, // TCI_GRAY5 = TCI_LIGHTGRAY
  1518. TCI_GRAY5, // TCI_GRAY6
  1519. TCI_GRAY5, // TCI_GRAY7 = TCI_WHITE
  1520. TCI_RED, // TCI_RED
  1521. TCI_RED_ORANGE, // TCI_RED_ORANGE
  1522. TCI_ORANGE, // TCI_ORANGE
  1523. TCI_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  1524. TCI_ORANGE_YELLOW, // TCI_YELLOW
  1525. TCI_YELLOW_GREEN, // TCI_YELLOW_GREEN
  1526. TCI_GREEN, // TCI_GREEN
  1527. TCI_GREEN_CYAN, // TCI_GREEN_CYAN
  1528. TCI_CYAN, // TCI_CYAN
  1529. TCI_CYAN_BLUE, // TCI_CYAN_BLUE
  1530. TCI_BLUE, // TCI_BLUE
  1531. TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  1532. TCI_MAGENTA, // TCI_MAGENTA
  1533. TCI_MAGENTA_RED, // TCI_MAGENTA_RED
  1534. },
  1535. //--- TCI_RED
  1536. {
  1537. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  1538. TCI_GRAY1, // TCI_GRAY1
  1539. TCI_GRAY1, // TCI_GRAY2 = TCI_DARKGRAY
  1540. TCI_GRAY4, // TCI_GRAY3
  1541. TCI_GRAY4, // TCI_GRAY4
  1542. TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY
  1543. TCI_GRAY6, // TCI_GRAY6
  1544. TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE
  1545. TCI_B_ORANGE, // TCI_RED
  1546. TCI_B_ORANGE, // TCI_RED_ORANGE
  1547. TCI_B_ORANGE, // TCI_ORANGE
  1548. TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  1549. TCI_B_YELLOW, // TCI_YELLOW
  1550. TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN
  1551. TCI_B_GREEN, // TCI_GREEN
  1552. TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN
  1553. TCI_B_CYAN, // TCI_CYAN
  1554. TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE
  1555. TCI_B_BLUE, // TCI_BLUE
  1556. TCI_B_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  1557. TCI_B_MAGENTA, // TCI_MAGENTA
  1558. TCI_B_MAGENTA, // TCI_MAGENTA_RED
  1559. },
  1560. //--- TCI_RED_ORANGE
  1561. {
  1562. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  1563. TCI_GRAY1, // TCI_GRAY1
  1564. TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY
  1565. TCI_GRAY2, // TCI_GRAY3
  1566. TCI_GRAY5, // TCI_GRAY4
  1567. TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY
  1568. TCI_GRAY6, // TCI_GRAY6
  1569. TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE
  1570. TCI_RED, // TCI_RED
  1571. TCI_RED, // TCI_RED_ORANGE
  1572. TCI_B_ORANGE_YELLOW, // TCI_ORANGE
  1573. TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  1574. TCI_B_YELLOW, // TCI_YELLOW
  1575. TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN
  1576. TCI_B_GREEN, // TCI_GREEN
  1577. TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN
  1578. TCI_B_CYAN, // TCI_CYAN
  1579. TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE
  1580. TCI_BLUE, // TCI_BLUE
  1581. TCI_B_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  1582. TCI_B_MAGENTA, // TCI_MAGENTA
  1583. TCI_MAGENTA_RED, // TCI_MAGENTA_RED
  1584. },
  1585. //--- TCI_ORANGE
  1586. {
  1587. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  1588. TCI_GRAY1, // TCI_GRAY1
  1589. TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY
  1590. TCI_GRAY3, // TCI_GRAY3
  1591. TCI_GRAY3, // TCI_GRAY4
  1592. TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY
  1593. TCI_GRAY6, // TCI_GRAY6
  1594. TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE
  1595. TCI_RED, // TCI_RED
  1596. TCI_RED, // TCI_RED_ORANGE
  1597. TCI_B_ORANGE_YELLOW, // TCI_ORANGE
  1598. TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  1599. TCI_B_YELLOW, // TCI_YELLOW
  1600. TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN
  1601. TCI_B_GREEN, // TCI_GREEN
  1602. TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN
  1603. TCI_B_CYAN, // TCI_CYAN
  1604. TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE
  1605. TCI_BLUE, // TCI_BLUE
  1606. TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  1607. TCI_MAGENTA, // TCI_MAGENTA
  1608. TCI_MAGENTA_RED, // TCI_MAGENTA_RED
  1609. },
  1610. //--- TCI_ORANGE_YELLOW
  1611. {
  1612. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  1613. TCI_GRAY1, // TCI_GRAY1
  1614. TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY
  1615. TCI_GRAY3, // TCI_GRAY3
  1616. TCI_GRAY3, // TCI_GRAY4
  1617. TCI_GRAY6, // TCI_GRAY5 = TCI_LIGHTGRAY
  1618. TCI_GRAY6, // TCI_GRAY6
  1619. TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE
  1620. TCI_RED, // TCI_RED
  1621. TCI_RED, // TCI_RED_ORANGE
  1622. TCI_B_ORANGE, // TCI_ORANGE
  1623. TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  1624. TCI_B_YELLOW, // TCI_YELLOW
  1625. TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN
  1626. TCI_B_GREEN, // TCI_GREEN
  1627. TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN
  1628. TCI_B_CYAN, // TCI_CYAN
  1629. TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE
  1630. TCI_BLUE, // TCI_BLUE
  1631. TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  1632. TCI_MAGENTA, // TCI_MAGENTA
  1633. TCI_MAGENTA_RED, // TCI_MAGENTA_RED
  1634. },
  1635. //--- TCI_YELLOW
  1636. {
  1637. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  1638. TCI_GRAY1, // TCI_GRAY1
  1639. TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY
  1640. TCI_GRAY2, // TCI_GRAY3
  1641. TCI_GRAY3, // TCI_GRAY4
  1642. TCI_GRAY3, // TCI_GRAY5 = TCI_LIGHTGRAY
  1643. TCI_GRAY6, // TCI_GRAY6
  1644. TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE
  1645. TCI_B_RED, // TCI_RED
  1646. TCI_B_RED_ORANGE, // TCI_RED_ORANGE
  1647. TCI_B_ORANGE, // TCI_ORANGE
  1648. TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  1649. TCI_B_YELLOW, // TCI_YELLOW
  1650. TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN
  1651. TCI_B_GREEN, // TCI_GREEN
  1652. TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN
  1653. TCI_B_CYAN, // TCI_CYAN
  1654. TCI_CYAN_BLUE, // TCI_CYAN_BLUE
  1655. TCI_BLUE, // TCI_BLUE
  1656. TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  1657. TCI_MAGENTA, // TCI_MAGENTA
  1658. TCI_MAGENTA_RED, // TCI_MAGENTA_RED
  1659. },
  1660. //--- TCI_YELLOW_GREEN
  1661. {
  1662. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  1663. TCI_GRAY1, // TCI_GRAY1
  1664. TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY
  1665. TCI_GRAY3, // TCI_GRAY3
  1666. TCI_GRAY3, // TCI_GRAY4
  1667. TCI_GRAY6, // TCI_GRAY5 = TCI_LIGHTGRAY
  1668. TCI_GRAY6, // TCI_GRAY6
  1669. TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE
  1670. TCI_RED, // TCI_RED
  1671. TCI_RED_ORANGE, // TCI_RED_ORANGE
  1672. TCI_ORANGE, // TCI_ORANGE
  1673. TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  1674. TCI_B_YELLOW, // TCI_YELLOW
  1675. TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN
  1676. TCI_B_GREEN, // TCI_GREEN
  1677. TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN
  1678. TCI_B_CYAN, // TCI_CYAN
  1679. TCI_CYAN_BLUE, // TCI_CYAN_BLUE
  1680. TCI_BLUE, // TCI_BLUE
  1681. TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  1682. TCI_MAGENTA, // TCI_MAGENTA
  1683. TCI_MAGENTA_RED, // TCI_MAGENTA_RED
  1684. },
  1685. //--- TCI_GREEN
  1686. {
  1687. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  1688. TCI_GRAY1, // TCI_GRAY1
  1689. TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY
  1690. TCI_GRAY3, // TCI_GRAY3
  1691. TCI_GRAY3, // TCI_GRAY4
  1692. TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY
  1693. TCI_GRAY6, // TCI_GRAY6
  1694. TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE
  1695. TCI_RED, // TCI_RED
  1696. TCI_RED_ORANGE, // TCI_RED_ORANGE
  1697. TCI_ORANGE, // TCI_ORANGE
  1698. TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  1699. TCI_B_YELLOW, // TCI_YELLOW
  1700. TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN
  1701. TCI_B_GREEN, // TCI_GREEN
  1702. TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN
  1703. TCI_B_CYAN, // TCI_CYAN
  1704. TCI_CYAN_BLUE, // TCI_CYAN_BLUE
  1705. TCI_BLUE, // TCI_BLUE
  1706. TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  1707. TCI_MAGENTA, // TCI_MAGENTA
  1708. TCI_MAGENTA_RED, // TCI_MAGENTA_RED
  1709. },
  1710. //--- TCI_GREEN_CYAN
  1711. {
  1712. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  1713. TCI_GRAY1, // TCI_GRAY1
  1714. TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY
  1715. TCI_GRAY3, // TCI_GRAY3
  1716. TCI_GRAY3, // TCI_GRAY4
  1717. TCI_GRAY6, // TCI_GRAY5 = TCI_LIGHTGRAY
  1718. TCI_GRAY6, // TCI_GRAY6
  1719. TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE
  1720. TCI_RED, // TCI_RED
  1721. TCI_B_RED_ORANGE, // TCI_RED_ORANGE
  1722. TCI_B_ORANGE, // TCI_ORANGE
  1723. TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  1724. TCI_B_YELLOW, // TCI_YELLOW
  1725. TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN
  1726. TCI_B_GREEN, // TCI_GREEN
  1727. TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN
  1728. TCI_B_CYAN, // TCI_CYAN
  1729. TCI_CYAN_BLUE, // TCI_CYAN_BLUE
  1730. TCI_BLUE, // TCI_BLUE
  1731. TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  1732. TCI_MAGENTA, // TCI_MAGENTA
  1733. TCI_MAGENTA_RED, // TCI_MAGENTA_RED
  1734. },
  1735. //--- TCI_CYAN
  1736. {
  1737. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  1738. TCI_GRAY1, // TCI_GRAY1
  1739. TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY
  1740. TCI_GRAY3, // TCI_GRAY3
  1741. TCI_GRAY3, // TCI_GRAY4
  1742. TCI_GRAY6, // TCI_GRAY5 = TCI_LIGHTGRAY
  1743. TCI_GRAY6, // TCI_GRAY6
  1744. TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE
  1745. TCI_RED, // TCI_RED
  1746. TCI_B_RED_ORANGE, // TCI_RED_ORANGE
  1747. TCI_B_ORANGE, // TCI_ORANGE
  1748. TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  1749. TCI_B_YELLOW, // TCI_YELLOW
  1750. TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN
  1751. TCI_B_GREEN, // TCI_GREEN
  1752. TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN
  1753. TCI_B_CYAN, // TCI_CYAN
  1754. TCI_CYAN_BLUE, // TCI_CYAN_BLUE
  1755. TCI_BLUE, // TCI_BLUE
  1756. TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  1757. TCI_MAGENTA, // TCI_MAGENTA
  1758. TCI_MAGENTA_RED, // TCI_MAGENTA_RED
  1759. },
  1760. //--- TCI_CYAN_BLUE
  1761. {
  1762. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  1763. TCI_GRAY1, // TCI_GRAY1
  1764. TCI_GRAY1, // TCI_GRAY2 = TCI_DARKGRAY
  1765. TCI_GRAY2, // TCI_GRAY3
  1766. TCI_GRAY2, // TCI_GRAY4
  1767. TCI_GRAY6, // TCI_GRAY5 = TCI_LIGHTGRAY
  1768. TCI_GRAY6, // TCI_GRAY6
  1769. TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE
  1770. TCI_B_RED, // TCI_RED
  1771. TCI_B_RED_ORANGE, // TCI_RED_ORANGE
  1772. TCI_B_ORANGE, // TCI_ORANGE
  1773. TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  1774. TCI_B_YELLOW, // TCI_YELLOW
  1775. TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN
  1776. TCI_B_GREEN, // TCI_GREEN
  1777. TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN
  1778. TCI_B_CYAN, // TCI_CYAN
  1779. TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE
  1780. TCI_BLUE, // TCI_BLUE
  1781. TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  1782. TCI_MAGENTA, // TCI_MAGENTA
  1783. TCI_MAGENTA_RED, // TCI_MAGENTA_RED
  1784. },
  1785. //--- TCI_BLUE
  1786. {
  1787. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  1788. TCI_GRAY0, // TCI_GRAY1
  1789. TCI_GRAY3, // TCI_GRAY2 = TCI_DARKGRAY
  1790. TCI_GRAY4, // TCI_GRAY3
  1791. TCI_GRAY4, // TCI_GRAY4
  1792. TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY
  1793. TCI_GRAY6, // TCI_GRAY6
  1794. TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE
  1795. TCI_B_RED, // TCI_RED
  1796. TCI_B_RED_ORANGE, // TCI_RED_ORANGE
  1797. TCI_B_ORANGE, // TCI_ORANGE
  1798. TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  1799. TCI_B_YELLOW, // TCI_YELLOW
  1800. TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN
  1801. TCI_B_GREEN, // TCI_GREEN
  1802. TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN
  1803. TCI_B_CYAN, // TCI_CYAN
  1804. TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE
  1805. TCI_B_BLUE, // TCI_BLUE
  1806. TCI_B_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  1807. TCI_B_MAGENTA, // TCI_MAGENTA
  1808. TCI_B_MAGENTA_RED, // TCI_MAGENTA_RED
  1809. },
  1810. //--- TCI_BLUE_MAGENTA
  1811. {
  1812. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  1813. TCI_GRAY0, // TCI_GRAY1
  1814. TCI_GRAY3, // TCI_GRAY2 = TCI_DARKGRAY
  1815. TCI_GRAY4, // TCI_GRAY3
  1816. TCI_GRAY4, // TCI_GRAY4
  1817. TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY
  1818. TCI_GRAY6, // TCI_GRAY6
  1819. TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE
  1820. TCI_B_RED, // TCI_RED
  1821. TCI_B_RED_ORANGE, // TCI_RED_ORANGE
  1822. TCI_B_ORANGE, // TCI_ORANGE
  1823. TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  1824. TCI_B_YELLOW, // TCI_YELLOW
  1825. TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN
  1826. TCI_B_GREEN, // TCI_GREEN
  1827. TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN
  1828. TCI_B_CYAN, // TCI_CYAN
  1829. TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE
  1830. TCI_B_BLUE, // TCI_BLUE
  1831. TCI_B_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  1832. TCI_B_MAGENTA, // TCI_MAGENTA
  1833. TCI_B_MAGENTA_RED, // TCI_MAGENTA_RED
  1834. },
  1835. //--- TCI_MAGENTA
  1836. {
  1837. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  1838. TCI_GRAY1, // TCI_GRAY1
  1839. TCI_GRAY1, // TCI_GRAY2 = TCI_DARKGRAY
  1840. TCI_GRAY4, // TCI_GRAY3
  1841. TCI_GRAY4, // TCI_GRAY4
  1842. TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY
  1843. TCI_GRAY6, // TCI_GRAY6
  1844. TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE
  1845. TCI_B_RED_ORANGE, // TCI_RED
  1846. TCI_B_RED_ORANGE, // TCI_RED_ORANGE
  1847. TCI_B_ORANGE, // TCI_ORANGE
  1848. TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  1849. TCI_B_YELLOW, // TCI_YELLOW
  1850. TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN
  1851. TCI_B_GREEN, // TCI_GREEN
  1852. TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN
  1853. TCI_B_CYAN, // TCI_CYAN
  1854. TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE
  1855. TCI_BLUE, // TCI_BLUE
  1856. TCI_B_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  1857. TCI_B_MAGENTA, // TCI_MAGENTA
  1858. TCI_B_MAGENTA_RED, // TCI_MAGENTA_RED
  1859. },
  1860. //--- TCI_MAGENTA_RED
  1861. {
  1862. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  1863. TCI_GRAY1, // TCI_GRAY1
  1864. TCI_GRAY1, // TCI_GRAY2 = TCI_DARKGRAY
  1865. TCI_GRAY4, // TCI_GRAY3
  1866. TCI_GRAY4, // TCI_GRAY4
  1867. TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY
  1868. TCI_GRAY6, // TCI_GRAY6
  1869. TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE
  1870. TCI_B_RED_ORANGE, // TCI_RED
  1871. TCI_B_RED_ORANGE, // TCI_RED_ORANGE
  1872. TCI_B_ORANGE, // TCI_ORANGE
  1873. TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  1874. TCI_B_YELLOW, // TCI_YELLOW
  1875. TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN
  1876. TCI_B_GREEN, // TCI_GREEN
  1877. TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN
  1878. TCI_B_CYAN, // TCI_CYAN
  1879. TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE
  1880. TCI_BLUE, // TCI_BLUE
  1881. TCI_B_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  1882. TCI_B_MAGENTA, // TCI_MAGENTA
  1883. TCI_B_MAGENTA_RED, // TCI_MAGENTA_RED
  1884. },
  1885. //--- TCI_B_RED
  1886. {
  1887. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  1888. TCI_GRAY1, // TCI_GRAY1
  1889. TCI_GRAY1, // TCI_GRAY2 = TCI_DARKGRAY
  1890. TCI_GRAY4, // TCI_GRAY3
  1891. TCI_GRAY4, // TCI_GRAY4
  1892. TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY
  1893. TCI_GRAY6, // TCI_GRAY6
  1894. TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE
  1895. TCI_B_ORANGE, // TCI_RED
  1896. TCI_B_ORANGE, // TCI_RED_ORANGE
  1897. TCI_B_ORANGE, // TCI_ORANGE
  1898. TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  1899. TCI_B_YELLOW, // TCI_YELLOW
  1900. TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN
  1901. TCI_B_GREEN, // TCI_GREEN
  1902. TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN
  1903. TCI_B_CYAN, // TCI_CYAN
  1904. TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE
  1905. TCI_BLUE, // TCI_BLUE
  1906. TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  1907. TCI_B_MAGENTA, // TCI_MAGENTA
  1908. TCI_B_MAGENTA, // TCI_MAGENTA_RED
  1909. },
  1910. //--- TCI_B_RED_ORANGE
  1911. {
  1912. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  1913. TCI_GRAY1, // TCI_GRAY1
  1914. TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY
  1915. TCI_GRAY2, // TCI_GRAY3
  1916. TCI_GRAY5, // TCI_GRAY4
  1917. TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY
  1918. TCI_GRAY6, // TCI_GRAY6
  1919. TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE
  1920. TCI_RED, // TCI_RED
  1921. TCI_RED, // TCI_RED_ORANGE
  1922. TCI_B_ORANGE_YELLOW, // TCI_ORANGE
  1923. TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  1924. TCI_B_YELLOW, // TCI_YELLOW
  1925. TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN
  1926. TCI_B_GREEN, // TCI_GREEN
  1927. TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN
  1928. TCI_B_CYAN, // TCI_CYAN
  1929. TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE
  1930. TCI_BLUE, // TCI_BLUE
  1931. TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  1932. TCI_MAGENTA, // TCI_MAGENTA
  1933. TCI_MAGENTA_RED, // TCI_MAGENTA_RED
  1934. },
  1935. //--- TCI_B_ORANGE
  1936. {
  1937. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  1938. TCI_GRAY1, // TCI_GRAY1
  1939. TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY
  1940. TCI_GRAY3, // TCI_GRAY3
  1941. TCI_GRAY3, // TCI_GRAY4
  1942. TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY
  1943. TCI_GRAY6, // TCI_GRAY6
  1944. TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE
  1945. TCI_RED, // TCI_RED
  1946. TCI_RED_ORANGE, // TCI_RED_ORANGE
  1947. TCI_B_ORANGE_YELLOW, // TCI_ORANGE
  1948. TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  1949. TCI_B_YELLOW, // TCI_YELLOW
  1950. TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN
  1951. TCI_B_GREEN, // TCI_GREEN
  1952. TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN
  1953. TCI_B_CYAN, // TCI_CYAN
  1954. TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE
  1955. TCI_BLUE, // TCI_BLUE
  1956. TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  1957. TCI_MAGENTA, // TCI_MAGENTA
  1958. TCI_MAGENTA_RED, // TCI_MAGENTA_RED
  1959. },
  1960. //--- TCI_B_ORANGE_YELLOW
  1961. {
  1962. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  1963. TCI_GRAY1, // TCI_GRAY1
  1964. TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY
  1965. TCI_GRAY3, // TCI_GRAY3
  1966. TCI_GRAY4, // TCI_GRAY4
  1967. TCI_GRAY4, // TCI_GRAY5 = TCI_LIGHTGRAY
  1968. TCI_GRAY6, // TCI_GRAY6
  1969. TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE
  1970. TCI_RED, // TCI_RED
  1971. TCI_RED_ORANGE, // TCI_RED_ORANGE
  1972. TCI_ORANGE, // TCI_ORANGE
  1973. TCI_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  1974. TCI_YELLOW, // TCI_YELLOW
  1975. TCI_YELLOW_GREEN, // TCI_YELLOW_GREEN
  1976. TCI_GREEN, // TCI_GREEN
  1977. TCI_GREEN_CYAN, // TCI_GREEN_CYAN
  1978. TCI_CYAN, // TCI_CYAN
  1979. TCI_CYAN_BLUE, // TCI_CYAN_BLUE
  1980. TCI_BLUE, // TCI_BLUE
  1981. TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  1982. TCI_MAGENTA, // TCI_MAGENTA
  1983. TCI_MAGENTA_RED, // TCI_MAGENTA_RED
  1984. },
  1985. //--- TCI_B_YELLOW
  1986. {
  1987. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  1988. TCI_GRAY1, // TCI_GRAY1
  1989. TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY
  1990. TCI_GRAY3, // TCI_GRAY3
  1991. TCI_GRAY4, // TCI_GRAY4
  1992. TCI_GRAY4, // TCI_GRAY5 = TCI_LIGHTGRAY
  1993. TCI_GRAY5, // TCI_GRAY6
  1994. TCI_GRAY5, // TCI_GRAY7 = TCI_WHITE
  1995. TCI_RED, // TCI_RED
  1996. TCI_RED_ORANGE, // TCI_RED_ORANGE
  1997. TCI_ORANGE, // TCI_ORANGE
  1998. TCI_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  1999. TCI_YELLOW, // TCI_YELLOW
  2000. TCI_YELLOW_GREEN, // TCI_YELLOW_GREEN
  2001. TCI_GREEN, // TCI_GREEN
  2002. TCI_GREEN_CYAN, // TCI_GREEN_CYAN
  2003. TCI_CYAN, // TCI_CYAN
  2004. TCI_CYAN_BLUE, // TCI_CYAN_BLUE
  2005. TCI_BLUE, // TCI_BLUE
  2006. TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  2007. TCI_MAGENTA, // TCI_MAGENTA
  2008. TCI_MAGENTA_RED, // TCI_MAGENTA_RED
  2009. },
  2010. //--- TCI_B_YELLOW_GREEN
  2011. {
  2012. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  2013. TCI_GRAY1, // TCI_GRAY1
  2014. TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY
  2015. TCI_GRAY3, // TCI_GRAY3
  2016. TCI_GRAY4, // TCI_GRAY4
  2017. TCI_GRAY4, // TCI_GRAY5 = TCI_LIGHTGRAY
  2018. TCI_GRAY5, // TCI_GRAY6
  2019. TCI_GRAY5, // TCI_GRAY7 = TCI_WHITE
  2020. TCI_RED, // TCI_RED
  2021. TCI_RED_ORANGE, // TCI_RED_ORANGE
  2022. TCI_ORANGE, // TCI_ORANGE
  2023. TCI_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  2024. TCI_YELLOW, // TCI_YELLOW
  2025. TCI_YELLOW_GREEN, // TCI_YELLOW_GREEN
  2026. TCI_GREEN, // TCI_GREEN
  2027. TCI_GREEN_CYAN, // TCI_GREEN_CYAN
  2028. TCI_CYAN, // TCI_CYAN
  2029. TCI_CYAN_BLUE, // TCI_CYAN_BLUE
  2030. TCI_BLUE, // TCI_BLUE
  2031. TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  2032. TCI_MAGENTA, // TCI_MAGENTA
  2033. TCI_MAGENTA_RED, // TCI_MAGENTA_RED
  2034. },
  2035. //--- TCI_B_GREEN
  2036. {
  2037. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  2038. TCI_GRAY1, // TCI_GRAY1
  2039. TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY
  2040. TCI_GRAY3, // TCI_GRAY3
  2041. TCI_GRAY4, // TCI_GRAY4
  2042. TCI_GRAY4, // TCI_GRAY5 = TCI_LIGHTGRAY
  2043. TCI_GRAY5, // TCI_GRAY6
  2044. TCI_GRAY5, // TCI_GRAY7 = TCI_WHITE
  2045. TCI_RED, // TCI_RED
  2046. TCI_RED_ORANGE, // TCI_RED_ORANGE
  2047. TCI_ORANGE, // TCI_ORANGE
  2048. TCI_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  2049. TCI_YELLOW, // TCI_YELLOW
  2050. TCI_YELLOW_GREEN, // TCI_YELLOW_GREEN
  2051. TCI_GREEN, // TCI_GREEN
  2052. TCI_GREEN_CYAN, // TCI_GREEN_CYAN
  2053. TCI_CYAN, // TCI_CYAN
  2054. TCI_CYAN_BLUE, // TCI_CYAN_BLUE
  2055. TCI_BLUE, // TCI_BLUE
  2056. TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  2057. TCI_MAGENTA, // TCI_MAGENTA
  2058. TCI_MAGENTA_RED, // TCI_MAGENTA_RED
  2059. },
  2060. //--- TCI_B_GREEN_CYAN
  2061. {
  2062. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  2063. TCI_GRAY1, // TCI_GRAY1
  2064. TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY
  2065. TCI_GRAY3, // TCI_GRAY3
  2066. TCI_GRAY4, // TCI_GRAY4
  2067. TCI_GRAY4, // TCI_GRAY5 = TCI_LIGHTGRAY
  2068. TCI_GRAY5, // TCI_GRAY6
  2069. TCI_GRAY5, // TCI_GRAY7 = TCI_WHITE
  2070. TCI_RED, // TCI_RED
  2071. TCI_RED_ORANGE, // TCI_RED_ORANGE
  2072. TCI_ORANGE, // TCI_ORANGE
  2073. TCI_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  2074. TCI_YELLOW, // TCI_YELLOW
  2075. TCI_YELLOW_GREEN, // TCI_YELLOW_GREEN
  2076. TCI_GREEN, // TCI_GREEN
  2077. TCI_GREEN_CYAN, // TCI_GREEN_CYAN
  2078. TCI_CYAN, // TCI_CYAN
  2079. TCI_CYAN_BLUE, // TCI_CYAN_BLUE
  2080. TCI_BLUE, // TCI_BLUE
  2081. TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  2082. TCI_MAGENTA, // TCI_MAGENTA
  2083. TCI_MAGENTA_RED, // TCI_MAGENTA_RED
  2084. },
  2085. //--- TCI_B_CYAN
  2086. {
  2087. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  2088. TCI_GRAY1, // TCI_GRAY1
  2089. TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY
  2090. TCI_GRAY3, // TCI_GRAY3
  2091. TCI_GRAY4, // TCI_GRAY4
  2092. TCI_GRAY4, // TCI_GRAY5 = TCI_LIGHTGRAY
  2093. TCI_GRAY5, // TCI_GRAY6
  2094. TCI_GRAY5, // TCI_GRAY7 = TCI_WHITE
  2095. TCI_RED, // TCI_RED
  2096. TCI_RED_ORANGE, // TCI_RED_ORANGE
  2097. TCI_ORANGE, // TCI_ORANGE
  2098. TCI_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  2099. TCI_YELLOW, // TCI_YELLOW
  2100. TCI_YELLOW_GREEN, // TCI_YELLOW_GREEN
  2101. TCI_GREEN, // TCI_GREEN
  2102. TCI_GREEN_CYAN, // TCI_GREEN_CYAN
  2103. TCI_CYAN, // TCI_CYAN
  2104. TCI_CYAN_BLUE, // TCI_CYAN_BLUE
  2105. TCI_BLUE, // TCI_BLUE
  2106. TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  2107. TCI_MAGENTA, // TCI_MAGENTA
  2108. TCI_MAGENTA_RED, // TCI_MAGENTA_RED
  2109. },
  2110. //--- TCI_CYAN_BLUE
  2111. {
  2112. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  2113. TCI_GRAY1, // TCI_GRAY1
  2114. TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY
  2115. TCI_GRAY3, // TCI_GRAY3
  2116. TCI_GRAY4, // TCI_GRAY4
  2117. TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY
  2118. TCI_GRAY6, // TCI_GRAY6
  2119. TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE
  2120. TCI_RED, // TCI_RED
  2121. TCI_RED_ORANGE, // TCI_RED_ORANGE
  2122. TCI_ORANGE, // TCI_ORANGE
  2123. TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  2124. TCI_B_YELLOW, // TCI_YELLOW
  2125. TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN
  2126. TCI_B_GREEN, // TCI_GREEN
  2127. TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN
  2128. TCI_B_CYAN, // TCI_CYAN
  2129. TCI_CYAN_BLUE, // TCI_CYAN_BLUE
  2130. TCI_BLUE, // TCI_BLUE
  2131. TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  2132. TCI_MAGENTA, // TCI_MAGENTA
  2133. TCI_MAGENTA_RED, // TCI_MAGENTA_RED
  2134. },
  2135. //--- TCI_B_BLUE
  2136. {
  2137. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  2138. TCI_GRAY1, // TCI_GRAY1
  2139. TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY
  2140. TCI_GRAY3, // TCI_GRAY3
  2141. TCI_GRAY4, // TCI_GRAY4
  2142. TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY
  2143. TCI_GRAY6, // TCI_GRAY6
  2144. TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE
  2145. TCI_RED, // TCI_RED
  2146. TCI_RED_ORANGE, // TCI_RED_ORANGE
  2147. TCI_ORANGE, // TCI_ORANGE
  2148. TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  2149. TCI_B_YELLOW, // TCI_YELLOW
  2150. TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN
  2151. TCI_B_GREEN, // TCI_GREEN
  2152. TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN
  2153. TCI_B_CYAN, // TCI_CYAN
  2154. TCI_CYAN_BLUE, // TCI_CYAN_BLUE
  2155. TCI_BLUE, // TCI_BLUE
  2156. TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  2157. TCI_MAGENTA, // TCI_MAGENTA
  2158. TCI_MAGENTA_RED, // TCI_MAGENTA_RED
  2159. },
  2160. //--- TCI_B_BLUE_MAGENTA
  2161. {
  2162. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  2163. TCI_GRAY1, // TCI_GRAY1
  2164. TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY
  2165. TCI_GRAY3, // TCI_GRAY3
  2166. TCI_GRAY4, // TCI_GRAY4
  2167. TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY
  2168. TCI_GRAY6, // TCI_GRAY6
  2169. TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE
  2170. TCI_RED, // TCI_RED
  2171. TCI_RED_ORANGE, // TCI_RED_ORANGE
  2172. TCI_B_ORANGE, // TCI_ORANGE
  2173. TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  2174. TCI_B_YELLOW, // TCI_YELLOW
  2175. TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN
  2176. TCI_B_GREEN, // TCI_GREEN
  2177. TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN
  2178. TCI_B_CYAN, // TCI_CYAN
  2179. TCI_B_CYAN_BLUE, // TCI_CYAN_BLUE
  2180. TCI_BLUE, // TCI_BLUE
  2181. TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  2182. TCI_MAGENTA, // TCI_MAGENTA
  2183. TCI_MAGENTA_RED, // TCI_MAGENTA_RED
  2184. },
  2185. //--- TCI_B_MAGENTA
  2186. {
  2187. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  2188. TCI_GRAY1, // TCI_GRAY1
  2189. TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY
  2190. TCI_GRAY3, // TCI_GRAY3
  2191. TCI_GRAY4, // TCI_GRAY4
  2192. TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY
  2193. TCI_GRAY6, // TCI_GRAY6
  2194. TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE
  2195. TCI_RED, // TCI_RED
  2196. TCI_RED_ORANGE, // TCI_RED_ORANGE
  2197. TCI_B_ORANGE, // TCI_ORANGE
  2198. TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  2199. TCI_B_YELLOW, // TCI_YELLOW
  2200. TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN
  2201. TCI_B_GREEN, // TCI_GREEN
  2202. TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN
  2203. TCI_B_CYAN, // TCI_CYAN
  2204. TCI_CYAN_BLUE, // TCI_CYAN_BLUE
  2205. TCI_BLUE, // TCI_BLUE
  2206. TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  2207. TCI_MAGENTA, // TCI_MAGENTA
  2208. TCI_MAGENTA_RED, // TCI_MAGENTA_RED
  2209. },
  2210. //--- TCI_B_MAGENTA_RED
  2211. {
  2212. TCI_GRAY0, // TCI_GRAY0 = TCI_BLACK
  2213. TCI_GRAY1, // TCI_GRAY1
  2214. TCI_GRAY2, // TCI_GRAY2 = TCI_DARKGRAY
  2215. TCI_GRAY3, // TCI_GRAY3
  2216. TCI_GRAY4, // TCI_GRAY4
  2217. TCI_GRAY5, // TCI_GRAY5 = TCI_LIGHTGRAY
  2218. TCI_GRAY6, // TCI_GRAY6
  2219. TCI_GRAY7, // TCI_GRAY7 = TCI_WHITE
  2220. TCI_RED, // TCI_RED
  2221. TCI_RED, // TCI_RED_ORANGE
  2222. TCI_B_ORANGE, // TCI_ORANGE
  2223. TCI_B_ORANGE_YELLOW, // TCI_ORANGE_YELLOW
  2224. TCI_B_YELLOW, // TCI_YELLOW
  2225. TCI_B_YELLOW_GREEN, // TCI_YELLOW_GREEN
  2226. TCI_B_GREEN, // TCI_GREEN
  2227. TCI_B_GREEN_CYAN, // TCI_GREEN_CYAN
  2228. TCI_B_CYAN, // TCI_CYAN
  2229. TCI_CYAN_BLUE, // TCI_CYAN_BLUE
  2230. TCI_BLUE, // TCI_BLUE
  2231. TCI_BLUE_MAGENTA, // TCI_BLUE_MAGENTA
  2232. TCI_MAGENTA, // TCI_MAGENTA
  2233. TCI_MAGENTA_RED, // TCI_MAGENTA_RED
  2234. },
  2235. };
  2236. const uint font = font_index < TCI_B_RED ? font_index
  2237. : font_index - (TCI_B_RED-TCI_RED);
  2238. font_index = tab[bg_index][font];
  2239. }
  2240. //--- color index
  2241. static const u8 color_index_8[] =
  2242. {
  2243. 0, // TCI_GRAY0 = TCI_BLACK
  2244. 0, // TCI_GRAY1
  2245. 8, // TCI_GRAY2 = TCI_DARKGRAY
  2246. 8, // TCI_GRAY3
  2247. 7, // TCI_GRAY4
  2248. 7, // TCI_GRAY5 = TCI_LIGHTGRAY
  2249. 15, // TCI_GRAY6
  2250. 15, // TCI_GRAY7 = TCI_WHITE
  2251. 1, // TCI_RED
  2252. 1, // TCI_RED_ORANGE
  2253. 1, // TCI_ORANGE
  2254. 1, // TCI_ORANGE_YELLOW
  2255. 3, // TCI_YELLOW
  2256. 3, // TCI_YELLOW_GREEN
  2257. 2, // TCI_GREEN
  2258. 2, // TCI_GREEN_CYAN
  2259. 6, // TCI_CYAN
  2260. 6, // TCI_CYAN_BLUE
  2261. 4, // TCI_BLUE
  2262. 4, // TCI_BLUE_MAGENTA
  2263. 5, // TCI_MAGENTA
  2264. 5, // TCI_MAGENTA_RED
  2265. 9, // TCI_B_RED
  2266. 9, // TCI_B_RED_ORANGE
  2267. 9, // TCI_B_ORANGE
  2268. 9, // TCI_B_ORANGE_YELLOW
  2269. 11, // TCI_B_YELLOW
  2270. 11, // TCI_B_YELLOW_GREEN
  2271. 10, // TCI_B_GREEN
  2272. 10, // TCI_B_GREEN_CYAN
  2273. 14, // TCI_B_CYAN
  2274. 14, // TCI_B_CYAN_BLUE
  2275. 12, // TCI_B_BLUE
  2276. 12, // TCI_B_BLUE_MAGENTA
  2277. 13, // TCI_B_MAGENTA
  2278. 13, // TCI_B_MAGENTA_RED
  2279. };
  2280. static const u8 color_index_256[] =
  2281. {
  2282. 232, // TCI_GRAY0 = TCI_BLACK
  2283. 236, // TCI_GRAY1
  2284. 240, // TCI_GRAY2 = TCI_DARKGRAY
  2285. 243, // TCI_GRAY3
  2286. 246, // TCI_GRAY4
  2287. 249, // TCI_GRAY5 = TCI_LIGHTGRAY
  2288. 252, // TCI_GRAY6
  2289. 255, // TCI_GRAY7 = TCI_WHITE
  2290. 160, // TCI_RED
  2291. 166, // TCI_RED_ORANGE
  2292. 172, // TCI_ORANGE
  2293. 136, // TCI_ORANGE_YELLOW
  2294. 142, // TCI_YELLOW
  2295. 106, // TCI_YELLOW_GREEN
  2296. 34, // TCI_GREEN
  2297. 36, // TCI_GREEN_CYAN
  2298. 37, // TCI_CYAN
  2299. 32, // TCI_CYAN_BLUE
  2300. 21, // TCI_BLUE
  2301. 92, // TCI_BLUE_MAGENTA
  2302. 164, // TCI_MAGENTA
  2303. 162, // TCI_MAGENTA_RED
  2304. 196, // TCI_B_RED
  2305. 202, // TCI_B_RED_ORANGE
  2306. 208, // TCI_B_ORANGE
  2307. 214, // TCI_B_ORANGE_YELLOW
  2308. 226, // TCI_B_YELLOW
  2309. 154, // TCI_B_YELLOW_GREEN
  2310. 46, // TCI_B_GREEN
  2311. 49, // TCI_B_GREEN_CYAN
  2312. 51, // TCI_B_CYAN
  2313. 75, // TCI_B_CYAN_BLUE
  2314. 105, // TCI_B_BLUE
  2315. 177, // TCI_B_BLUE_MAGENTA
  2316. 207, // TCI_B_MAGENTA
  2317. 204, // TCI_B_MAGENTA_RED
  2318. };
  2319. const u8 *color_index;
  2320. uint x_bg;
  2321. if ( col_mode == COLMD_256_COLORS )
  2322. {
  2323. color_index = color_index_256;
  2324. x_bg = 8;
  2325. }
  2326. else
  2327. {
  2328. color_index = color_index_8;
  2329. x_bg = 16;
  2330. option |= GCM_SHORT;
  2331. }
  2332. //--- output
  2333. char buf[100], *end = buf + sizeof(buf);
  2334. char *dest = StringCopyE(buf,end,TermTextModeBeg0);
  2335. const uint bg = (uint)bg_index < TCI__IGNORE ? color_index[bg_index] : ~0;
  2336. ccp sep = "";
  2337. if ( (uint)font_index < TCI__IGNORE )
  2338. {
  2339. uint idx = color_index[font_index];
  2340. if ( idx < 16 && idx == (bg&7) && option & GCM_ALT )
  2341. idx = idx ^ 8;
  2342. if ( !(option & GCM_SHORT) || idx >= 16 )
  2343. dest = snprintfE(dest,end,"38;5;%u",idx);
  2344. else if ( idx < 8 )
  2345. dest = snprintfE(dest,end,"0;%u",30+idx);
  2346. else
  2347. dest = snprintfE(dest,end,"1;%u",22+idx);
  2348. sep = ";";
  2349. }
  2350. if ( (uint)bg_index < TCI__IGNORE )
  2351. {
  2352. if ( !(option & GCM_SHORT) || bg >= x_bg )
  2353. dest = snprintfE(dest,end,"%s48;5;%u",sep,bg);
  2354. else
  2355. dest = snprintfE(dest,end,"%s%u",sep,40+(bg&7));
  2356. }
  2357. dest = StringCopyE(dest,end,TermTextModeEnd);
  2358. const int len = dest + 1 - buf;
  2359. char *res = GetColorCircBuf(len);
  2360. memcpy(res,buf,len);
  2361. return res;
  2362. }
  2363. #else // !SUPPORT_36_COLORS
  2364. ccp GetColorMode // 18 colors version
  2365. (
  2366. // returns a pointer to an internal circulary buffer (not GetCircBuf())
  2367. ColorMode_t col_mode, // if < COLMD_ON: return an empty string
  2368. TermColorIndex_t font_index, // index of font color
  2369. TermColorIndex_t bg_index, // index of background color
  2370. GetColorOption_t option // execution options
  2371. )
  2372. {
  2373. col_mode = NormalizeColorMode(col_mode,8);
  2374. if ( col_mode < COLMD_ON )
  2375. return EmptyString;
  2376. //--- recommended combinations
  2377. if ( option & GCM_ALT
  2378. && (uint)font_index < TCI__IGNORE
  2379. && (uint)bg_index < TCI__IGNORE )
  2380. {
  2381. static const u8 tab[TCI__N_BG][TCI__N_FONT] =
  2382. {
  2383. //--- TCI_BLACK
  2384. {
  2385. TCI_DARKGRAY, // TCI_BLACK
  2386. TCI_DARKGRAY, // TCI_DARKGRAY
  2387. TCI_LIGHTGRAY, // TCI_LIGHTGRAY
  2388. TCI_WHITE, // TCI_WHITE
  2389. TCI_B_RED, // TCI_RED
  2390. TCI_B_ORANGE, // TCI_ORANGE
  2391. TCI_B_YELLOW, // TCI_YELLOW
  2392. TCI_B_GREEN, // TCI_GREEN
  2393. TCI_B_CYAN, // TCI_CYAN
  2394. TCI_B_BLUE, // TCI_BLUE
  2395. TCI_B_MAGENTA, // TCI_MAGENTA
  2396. },
  2397. //--- TCI_DARKGRAY
  2398. {
  2399. TCI_BLACK, // TCI_BLACK
  2400. TCI_LIGHTGRAY, // TCI_DARKGRAY
  2401. TCI_LIGHTGRAY, // TCI_LIGHTGRAY
  2402. TCI_WHITE, // TCI_WHITE
  2403. TCI_B_RED, // TCI_RED
  2404. TCI_B_ORANGE, // TCI_ORANGE
  2405. TCI_B_YELLOW, // TCI_YELLOW
  2406. TCI_B_GREEN, // TCI_GREEN
  2407. TCI_B_CYAN, // TCI_CYAN
  2408. TCI_B_BLUE, // TCI_BLUE
  2409. TCI_B_MAGENTA, // TCI_MAGENTA
  2410. },
  2411. //--- TCI_LIGHTGRAY
  2412. {
  2413. TCI_BLACK, // TCI_BLACK
  2414. TCI_DARKGRAY, // TCI_DARKGRAY
  2415. TCI_DARKGRAY, // TCI_LIGHTGRAY
  2416. TCI_WHITE, // TCI_WHITE
  2417. TCI_RED, // TCI_RED
  2418. TCI_ORANGE, // TCI_ORANGE
  2419. TCI_B_YELLOW, // TCI_YELLOW
  2420. TCI_GREEN, // TCI_GREEN
  2421. TCI_CYAN, // TCI_CYAN
  2422. TCI_BLUE, // TCI_BLUE
  2423. TCI_MAGENTA, // TCI_MAGENTA
  2424. },
  2425. //--- TCI_WHITE
  2426. {
  2427. TCI_BLACK, // TCI_BLACK
  2428. TCI_DARKGRAY, // TCI_DARKGRAY
  2429. TCI_LIGHTGRAY, // TCI_LIGHTGRAY
  2430. TCI_LIGHTGRAY, // TCI_WHITE
  2431. TCI_RED, // TCI_RED
  2432. TCI_ORANGE, // TCI_ORANGE
  2433. TCI_ORANGE, // TCI_YELLOW
  2434. TCI_GREEN, // TCI_GREEN
  2435. TCI_CYAN, // TCI_CYAN
  2436. TCI_BLUE, // TCI_BLUE
  2437. TCI_MAGENTA, // TCI_MAGENTA
  2438. },
  2439. //--- TCI_RED
  2440. {
  2441. TCI_BLACK, // TCI_BLACK
  2442. TCI_LIGHTGRAY, // TCI_DARKGRAY
  2443. TCI_LIGHTGRAY, // TCI_LIGHTGRAY
  2444. TCI_WHITE, // TCI_WHITE
  2445. TCI_B_RED, // TCI_RED
  2446. TCI_B_ORANGE, // TCI_ORANGE
  2447. TCI_B_YELLOW, // TCI_YELLOW
  2448. TCI_B_GREEN, // TCI_GREEN
  2449. TCI_B_CYAN, // TCI_CYAN
  2450. TCI_B_BLUE, // TCI_BLUE
  2451. TCI_B_MAGENTA, // TCI_MAGENTA
  2452. },
  2453. //--- TCI_ORANGE
  2454. {
  2455. TCI_BLACK, // TCI_BLACK
  2456. TCI_DARKGRAY, // TCI_DARKGRAY
  2457. TCI_WHITE, // TCI_LIGHTGRAY
  2458. TCI_WHITE, // TCI_WHITE
  2459. TCI_RED, // TCI_RED
  2460. TCI_B_ORANGE, // TCI_ORANGE
  2461. TCI_B_YELLOW, // TCI_YELLOW
  2462. TCI_B_GREEN, // TCI_GREEN
  2463. TCI_B_CYAN, // TCI_CYAN
  2464. TCI_BLUE, // TCI_BLUE
  2465. TCI_MAGENTA, // TCI_MAGENTA
  2466. },
  2467. //--- TCI_YELLOW
  2468. {
  2469. TCI_BLACK, // TCI_BLACK
  2470. TCI_DARKGRAY, // TCI_DARKGRAY
  2471. TCI_WHITE, // TCI_LIGHTGRAY
  2472. TCI_WHITE, // TCI_WHITE
  2473. TCI_RED, // TCI_RED
  2474. TCI_ORANGE, // TCI_ORANGE
  2475. TCI_B_YELLOW, // TCI_YELLOW
  2476. TCI_B_GREEN, // TCI_GREEN
  2477. TCI_B_CYAN, // TCI_CYAN
  2478. TCI_BLUE, // TCI_BLUE
  2479. TCI_MAGENTA, // TCI_MAGENTA
  2480. },
  2481. //--- TCI_GREEN
  2482. {
  2483. TCI_BLACK, // TCI_BLACK
  2484. TCI_DARKGRAY, // TCI_DARKGRAY
  2485. TCI_LIGHTGRAY, // TCI_LIGHTGRAY
  2486. TCI_WHITE, // TCI_WHITE
  2487. TCI_RED, // TCI_RED
  2488. TCI_ORANGE, // TCI_ORANGE
  2489. TCI_B_YELLOW, // TCI_YELLOW
  2490. TCI_B_GREEN, // TCI_GREEN
  2491. TCI_B_CYAN, // TCI_CYAN
  2492. TCI_BLUE, // TCI_BLUE
  2493. TCI_MAGENTA, // TCI_MAGENTA
  2494. },
  2495. //--- TCI_CYAN
  2496. {
  2497. TCI_BLACK, // TCI_BLACK
  2498. TCI_DARKGRAY, // TCI_DARKGRAY
  2499. TCI_LIGHTGRAY, // TCI_LIGHTGRAY
  2500. TCI_WHITE, // TCI_WHITE
  2501. TCI_RED, // TCI_RED
  2502. TCI_ORANGE, // TCI_ORANGE
  2503. TCI_B_YELLOW, // TCI_YELLOW
  2504. TCI_B_GREEN, // TCI_GREEN
  2505. TCI_B_CYAN, // TCI_CYAN
  2506. TCI_BLUE, // TCI_BLUE
  2507. TCI_MAGENTA, // TCI_MAGENTA
  2508. },
  2509. //--- TCI_BLUE
  2510. {
  2511. TCI_BLACK, // TCI_BLACK
  2512. TCI_LIGHTGRAY, // TCI_DARKGRAY
  2513. TCI_LIGHTGRAY, // TCI_LIGHTGRAY
  2514. TCI_WHITE, // TCI_WHITE
  2515. TCI_RED, // TCI_RED
  2516. TCI_ORANGE, // TCI_ORANGE
  2517. TCI_B_YELLOW, // TCI_YELLOW
  2518. TCI_B_GREEN, // TCI_GREEN
  2519. TCI_B_CYAN, // TCI_CYAN
  2520. TCI_CYAN, // TCI_BLUE
  2521. TCI_B_MAGENTA, // TCI_MAGENTA
  2522. },
  2523. //--- TCI_MAGENTA
  2524. {
  2525. TCI_BLACK, // TCI_BLACK
  2526. TCI_LIGHTGRAY, // TCI_DARKGRAY
  2527. TCI_LIGHTGRAY, // TCI_LIGHTGRAY
  2528. TCI_WHITE, // TCI_WHITE
  2529. TCI_RED, // TCI_RED
  2530. TCI_ORANGE, // TCI_ORANGE
  2531. TCI_B_YELLOW, // TCI_YELLOW
  2532. TCI_B_GREEN, // TCI_GREEN
  2533. TCI_B_CYAN, // TCI_CYAN
  2534. TCI_CYAN, // TCI_BLUE
  2535. TCI_B_MAGENTA, // TCI_MAGENTA
  2536. },
  2537. //--- TCI_B_RED
  2538. {
  2539. TCI_BLACK, // TCI_BLACK
  2540. TCI_DARKGRAY, // TCI_DARKGRAY
  2541. TCI_WHITE, // TCI_LIGHTGRAY
  2542. TCI_WHITE, // TCI_WHITE
  2543. TCI_RED, // TCI_RED
  2544. TCI_ORANGE, // TCI_ORANGE
  2545. TCI_B_YELLOW, // TCI_YELLOW
  2546. TCI_B_GREEN, // TCI_GREEN
  2547. TCI_B_CYAN, // TCI_CYAN
  2548. TCI_BLUE, // TCI_BLUE
  2549. TCI_MAGENTA, // TCI_MAGENTA
  2550. },
  2551. //--- TCI_B_ORANGE
  2552. {
  2553. TCI_BLACK, // TCI_BLACK
  2554. TCI_DARKGRAY, // TCI_DARKGRAY
  2555. TCI_WHITE, // TCI_LIGHTGRAY
  2556. TCI_WHITE, // TCI_WHITE
  2557. TCI_RED, // TCI_RED
  2558. TCI_ORANGE, // TCI_ORANGE
  2559. TCI_B_YELLOW, // TCI_YELLOW
  2560. TCI_B_GREEN, // TCI_GREEN
  2561. TCI_B_CYAN, // TCI_CYAN
  2562. TCI_BLUE, // TCI_BLUE
  2563. TCI_MAGENTA, // TCI_MAGENTA
  2564. },
  2565. //--- TCI_B_YELLOW
  2566. {
  2567. TCI_BLACK, // TCI_BLACK
  2568. TCI_DARKGRAY, // TCI_DARKGRAY
  2569. TCI_DARKGRAY, // TCI_LIGHTGRAY
  2570. TCI_DARKGRAY, // TCI_WHITE
  2571. TCI_RED, // TCI_RED
  2572. TCI_ORANGE, // TCI_ORANGE
  2573. TCI_YELLOW, // TCI_YELLOW
  2574. TCI_GREEN, // TCI_GREEN
  2575. TCI_CYAN, // TCI_CYAN
  2576. TCI_BLUE, // TCI_BLUE
  2577. TCI_MAGENTA, // TCI_MAGENTA
  2578. },
  2579. //--- TCI_B_GREEN
  2580. {
  2581. TCI_BLACK, // TCI_BLACK
  2582. TCI_DARKGRAY, // TCI_DARKGRAY
  2583. TCI_DARKGRAY, // TCI_LIGHTGRAY
  2584. TCI_WHITE, // TCI_WHITE
  2585. TCI_RED, // TCI_RED
  2586. TCI_ORANGE, // TCI_ORANGE
  2587. TCI_B_YELLOW, // TCI_YELLOW
  2588. TCI_GREEN, // TCI_GREEN
  2589. TCI_CYAN, // TCI_CYAN
  2590. TCI_BLUE, // TCI_BLUE
  2591. TCI_MAGENTA, // TCI_MAGENTA
  2592. },
  2593. //--- TCI_B_CYAN
  2594. {
  2595. TCI_BLACK, // TCI_BLACK
  2596. TCI_DARKGRAY, // TCI_DARKGRAY
  2597. TCI_DARKGRAY, // TCI_LIGHTGRAY
  2598. TCI_WHITE, // TCI_WHITE
  2599. TCI_RED, // TCI_RED
  2600. TCI_ORANGE, // TCI_ORANGE
  2601. TCI_YELLOW, // TCI_YELLOW
  2602. TCI_GREEN, // TCI_GREEN
  2603. TCI_CYAN, // TCI_CYAN
  2604. TCI_BLUE, // TCI_BLUE
  2605. TCI_MAGENTA, // TCI_MAGENTA
  2606. },
  2607. //--- TCI_B_BLUE
  2608. {
  2609. TCI_BLACK, // TCI_BLACK
  2610. TCI_DARKGRAY, // TCI_DARKGRAY
  2611. TCI_DARKGRAY, // TCI_LIGHTGRAY
  2612. TCI_WHITE, // TCI_WHITE
  2613. TCI_RED, // TCI_RED
  2614. TCI_B_ORANGE, // TCI_ORANGE
  2615. TCI_B_YELLOW, // TCI_YELLOW
  2616. TCI_B_GREEN, // TCI_GREEN
  2617. TCI_B_CYAN, // TCI_CYAN
  2618. TCI_CYAN, // TCI_BLUE
  2619. TCI_MAGENTA, // TCI_MAGENTA
  2620. },
  2621. //--- TCI_B_MAGENTA
  2622. {
  2623. TCI_BLACK, // TCI_BLACK
  2624. TCI_DARKGRAY, // TCI_DARKGRAY
  2625. TCI_DARKGRAY, // TCI_LIGHTGRAY
  2626. TCI_WHITE, // TCI_WHITE
  2627. TCI_RED, // TCI_RED
  2628. TCI_B_ORANGE, // TCI_ORANGE
  2629. TCI_B_YELLOW, // TCI_YELLOW
  2630. TCI_GREEN, // TCI_GREEN
  2631. TCI_B_CYAN, // TCI_CYAN
  2632. TCI_CYAN, // TCI_BLUE
  2633. TCI_MAGENTA, // TCI_MAGENTA
  2634. },
  2635. };
  2636. const uint font = font_index < TCI_B_RED ? font_index
  2637. : font_index - (TCI_B_RED-TCI_RED);
  2638. font_index = tab[bg_index][font];
  2639. }
  2640. //--- color index
  2641. static const u8 color_index_8[] =
  2642. {
  2643. 0, // TCI_BLACK
  2644. 8, // TCI_DARKGRAY
  2645. 7, // TCI_LIGHTGRAY
  2646. 15, // TCI_WHITE
  2647. 1, // TCI_RED
  2648. 1, // TCI_ORANGE
  2649. 3, // TCI_YELLOW
  2650. 2, // TCI_GREEN
  2651. 6, // TCI_CYAN
  2652. 4, // TCI_BLUE
  2653. 5, // TCI_MAGENTA
  2654. 9, // TCI_B_RED
  2655. 9, // TCI_B_ORANGE
  2656. 11, // TCI_B_YELLOW
  2657. 10, // TCI_B_GREEN
  2658. 14, // TCI_B_CYAN
  2659. 12, // TCI_B_BLUE
  2660. 13, // TCI_B_MAGENTA
  2661. };
  2662. static const u8 color_index_256[] =
  2663. {
  2664. 0, // TCI_BLACK
  2665. 8, // TCI_DARKGRAY
  2666. 7, // TCI_LIGHTGRAY
  2667. 15, // TCI_WHITE
  2668. 160, // TCI_RED
  2669. 172, // TCI_ORANGE
  2670. 142, // TCI_YELLOW
  2671. 34, // TCI_GREEN
  2672. 37, // TCI_CYAN
  2673. 21, // TCI_BLUE
  2674. 164, // TCI_MAGENTA
  2675. 196, // TCI_B_RED
  2676. 208, // TCI_B_ORANGE
  2677. 226, // TCI_B_YELLOW
  2678. 46, // TCI_B_GREEN
  2679. 51, // TCI_B_CYAN
  2680. 105, // TCI_B_BLUE
  2681. 207, // TCI_B_MAGENTA
  2682. };
  2683. const u8 *color_index;
  2684. uint x_bg;
  2685. if ( col_mode == COLMD_256_COLORS )
  2686. {
  2687. color_index = color_index_256;
  2688. x_bg = 8;
  2689. }
  2690. else
  2691. {
  2692. color_index = color_index_8;
  2693. x_bg = 16;
  2694. option |= GCM_SHORT;
  2695. }
  2696. //--- output
  2697. char buf[100], *end = buf + sizeof(buf);
  2698. char *dest = StringCopyE(buf,end,TermTextModeBeg0);
  2699. ccp sep = "";
  2700. if ( (uint)font_index < TCI__IGNORE )
  2701. {
  2702. const uint idx = color_index[font_index];
  2703. if ( !(option & GCM_SHORT) || idx >= 16 )
  2704. dest = snprintfE(dest,end,"38;5;%u",idx);
  2705. else if ( idx < 8 )
  2706. dest = snprintfE(dest,end,"0;%u",30+idx);
  2707. else
  2708. dest = snprintfE(dest,end,"1;%u",22+idx);
  2709. sep = ";";
  2710. }
  2711. if ( (uint)bg_index < TCI__IGNORE )
  2712. {
  2713. const uint idx = color_index[bg_index];
  2714. if ( !(option & GCM_SHORT) || idx >= x_bg )
  2715. dest = snprintfE(dest,end,"%s48;5;%u",sep,idx);
  2716. else
  2717. dest = snprintfE(dest,end,"%s%u",sep,40+(idx&7));
  2718. }
  2719. dest = StringCopyE(dest,end,TermTextModeEnd);
  2720. const int len = dest + 1 - buf;
  2721. char *res = GetColorCircBuf(len);
  2722. memcpy(res,buf,len);
  2723. return res;
  2724. }
  2725. #endif // !SUPPORT_36_COLORS
  2726. //
  2727. ///////////////////////////////////////////////////////////////////////////////
  2728. /////////////// color ids ///////////////
  2729. ///////////////////////////////////////////////////////////////////////////////
  2730. // [[color_helper_tab_t]]
  2731. const TermColorId_t color8id = { .col =
  2732. {
  2733. 0x00, // TCE_GREY0,
  2734. 0x00, // TCE_GREY1,
  2735. 0x10, // TCE_GREY2,
  2736. 0x10, // TCE_GREY3,
  2737. 0x10, // TCE_GREY4,
  2738. 0x07, // TCE_GREY5,
  2739. 0x07, // TCE_GREY6,
  2740. 0x07, // TCE_GREY7,
  2741. 0x17, // TCE_GREY8,
  2742. 0x17, // TCE_GREY9,
  2743. 0x01, // TCE_RED_MAGENTA,
  2744. 0x01, // TCE_RED,
  2745. 0x01, // TCE_RED_ORANGE,
  2746. 0x01, // TCE_ORANGE_RED,
  2747. 0x01, // TCE_ORANGE,
  2748. 0x03, // TCE_ORANGE_YELLOW,
  2749. 0x03, // TCE_YELLOW_ORANGE,
  2750. 0x03, // TCE_YELLOW,
  2751. 0x03, // TCE_YELLOW_GREEN,
  2752. 0x02, // TCE_GREEN_YELLOW,
  2753. 0x02, // TCE_GREEN,
  2754. 0x02, // TCE_GREEN_CYAN,
  2755. 0x06, // TCE_CYAN_GREEN,
  2756. 0x06, // TCE_CYAN,
  2757. 0x06, // TCE_CYAN_BLUE,
  2758. 0x04, // TCE_BLUE_CYAN,
  2759. 0x04, // TCE_BLUE,
  2760. 0x04, // TCE_BLUE_MAGENTA,
  2761. 0x05, // TCE_MAGENTA_BLUE,
  2762. 0x05, // TCE_MAGENTA,
  2763. 0x05, // TCE_MAGENTA_RED,
  2764. 0x11, // TCE_B_RED_MAGENTA,
  2765. 0x11, // TCE_B_RED,
  2766. 0x11, // TCE_B_RED_ORANGE,
  2767. 0x11, // TCE_B_ORANGE_RED,
  2768. 0x11, // TCE_B_ORANGE,
  2769. 0x13, // TCE_B_ORANGE_YELLOW,
  2770. 0x13, // TCE_B_YELLOW_ORANGE,
  2771. 0x13, // TCE_B_YELLOW,
  2772. 0x13, // TCE_B_YELLOW_GREEN,
  2773. 0x12, // TCE_B_GREEN_YELLOW,
  2774. 0x12, // TCE_B_GREEN,
  2775. 0x12, // TCE_B_GREEN_CYAN,
  2776. 0x16, // TCE_B_CYAN_GREEN,
  2777. 0x16, // TCE_B_CYAN,
  2778. 0x16, // TCE_B_CYAN_BLUE,
  2779. 0x14, // TCE_B_BLUE_CYAN,
  2780. 0x14, // TCE_B_BLUE,
  2781. 0x14, // TCE_B_BLUE_MAGENTA,
  2782. 0x15, // TCE_B_MAGENTA_BLUE,
  2783. 0x15, // TCE_B_MAGENTA,
  2784. 0x15, // TCE_B_MAGENTA_RED,
  2785. }};
  2786. // values for 38;5;x or 48;5;x
  2787. const TermColorId_t color256id = { .col =
  2788. {
  2789. 232, // TCE_GREY0,
  2790. 235, // TCE_GREY1,
  2791. 237, // TCE_GREY2,
  2792. 240, // TCE_GREY3,
  2793. 242, // TCE_GREY4,
  2794. 245, // TCE_GREY5,
  2795. 247, // TCE_GREY6,
  2796. 250, // TCE_GREY7,
  2797. 252, // TCE_GREY8,
  2798. 255, // TCE_GREY9,
  2799. 161, // TCE_RED_MAGENTA,
  2800. 160, // TCE_RED,
  2801. 166, // TCE_RED_ORANGE,
  2802. 166, // TCE_ORANGE_RED,
  2803. 172, // TCE_ORANGE,
  2804. 136, // TCE_ORANGE_YELLOW,
  2805. 136, // TCE_YELLOW_ORANGE,
  2806. 142, // TCE_YELLOW,
  2807. 106, // TCE_YELLOW_GREEN,
  2808. 70, // TCE_GREEN_YELLOW,
  2809. 34, // TCE_GREEN,
  2810. 35, // TCE_GREEN_CYAN,
  2811. 36, // TCE_CYAN_GREEN,
  2812. 37, // TCE_CYAN,
  2813. 32, // TCE_CYAN_BLUE,
  2814. 27, // TCE_BLUE_CYAN,
  2815. 21, // TCE_BLUE,
  2816. 92, // TCE_BLUE_MAGENTA,
  2817. 128, // TCE_MAGENTA_BLUE,
  2818. 164, // TCE_MAGENTA,
  2819. 162, // TCE_MAGENTA_RED,
  2820. 198, // TCE_B_RED_MAGENTA,
  2821. 196, // TCE_B_RED,
  2822. 202, // TCE_B_RED_ORANGE,
  2823. 202, // TCE_B_ORANGE_RED,
  2824. 208, // TCE_B_ORANGE,
  2825. 214, // TCE_B_ORANGE_YELLOW,
  2826. 220, // TCE_B_YELLOW_ORANGE,
  2827. 226, // TCE_B_YELLOW,
  2828. 154, // TCE_B_YELLOW_GREEN,
  2829. 118, // TCE_B_GREEN_YELLOW,
  2830. 46, // TCE_B_GREEN,
  2831. 49, // TCE_B_GREEN_CYAN,
  2832. 50, // TCE_B_CYAN_GREEN,
  2833. 51, // TCE_B_CYAN,
  2834. 75, // TCE_B_CYAN_BLUE,
  2835. 111, // TCE_B_BLUE_CYAN,
  2836. 105, // TCE_B_BLUE,
  2837. 141, // TCE_B_BLUE_MAGENTA,
  2838. 177, // TCE_B_MAGENTA_BLUE,
  2839. 207, // TCE_B_MAGENTA,
  2840. 205, // TCE_B_MAGENTA_RED,
  2841. }};
  2842. //
  2843. ///////////////////////////////////////////////////////////////////////////////
  2844. /////////////// color tables ///////////////
  2845. ///////////////////////////////////////////////////////////////////////////////
  2846. // [[color_helper_tab_t]]
  2847. typedef struct color_helper_tab_t
  2848. {
  2849. ccp name;
  2850. uint offset;
  2851. bool is_alt;
  2852. }
  2853. color_helper_tab_t;
  2854. //-----------------------------------------------------------------------------
  2855. #undef JOB0
  2856. #undef JOB1
  2857. #undef JOB2
  2858. #undef SEP1
  2859. #define JOB0 {0,0,0}
  2860. #define JOB1(n) { #n, offsetof(ColorSet_t,n), 0 },
  2861. #define JOB2(t,n,a) { #t, offsetof(ColorSet_t,n), a },
  2862. #define SEP1 { EmptyString, 0, 0 },
  2863. //-----------------------------------------------------------------------------
  2864. static const color_helper_tab_t ch_tab_color[] =
  2865. {
  2866. SEP1
  2867. JOB1(red_magenta)
  2868. JOB1(red)
  2869. JOB1(red_orange)
  2870. JOB1(orange_red)
  2871. JOB1(orange)
  2872. JOB1(orange_yellow)
  2873. JOB1(yellow_orange)
  2874. JOB1(yellow)
  2875. JOB1(yellow_green)
  2876. JOB1(green_yellow)
  2877. JOB1(green)
  2878. JOB1(green_cyan)
  2879. JOB1(cyan_green)
  2880. JOB1(cyan)
  2881. JOB1(cyan_blue)
  2882. JOB1(blue_cyan)
  2883. JOB1(blue)
  2884. JOB1(blue_magenta)
  2885. JOB1(magenta_blue)
  2886. JOB1(magenta)
  2887. JOB1(magenta_red)
  2888. JOB0
  2889. };
  2890. //-----------------------------------------------------------------------------
  2891. static const color_helper_tab_t ch_tab_bcolor[] =
  2892. {
  2893. // [[new-color]]
  2894. SEP1
  2895. JOB1(b_red_magenta)
  2896. JOB1(b_red)
  2897. JOB1(b_red_orange)
  2898. JOB1(b_orange_red)
  2899. JOB1(b_orange)
  2900. JOB1(b_orange_yellow)
  2901. JOB1(b_yellow_orange)
  2902. JOB1(b_yellow)
  2903. JOB1(b_yellow_green)
  2904. JOB1(b_green_yellow)
  2905. JOB1(b_green)
  2906. JOB1(b_green_cyan)
  2907. JOB1(b_cyan_green)
  2908. JOB1(b_cyan)
  2909. JOB1(b_cyan_blue)
  2910. JOB1(b_blue_cyan)
  2911. JOB1(b_blue)
  2912. JOB1(b_blue_magenta)
  2913. JOB1(b_magenta_blue)
  2914. JOB1(b_magenta)
  2915. JOB1(b_magenta_red)
  2916. JOB0
  2917. };
  2918. //-----------------------------------------------------------------------------
  2919. _Static_assert( N_COLORSET_GREY == 10, "wrong N_COLORSET_GREY" );
  2920. static const color_helper_tab_t ch_tab_grey[] =
  2921. {
  2922. // [[new-color]]
  2923. SEP1
  2924. JOB1(black)
  2925. JOB1(b_black)
  2926. JOB1(white)
  2927. JOB1(b_white)
  2928. SEP1
  2929. JOB2(grey0,grey[0],0)
  2930. JOB2(grey1,grey[1],0)
  2931. JOB2(grey2,grey[2],0)
  2932. JOB2(grey3,grey[3],0)
  2933. JOB2(grey4,grey[4],0)
  2934. JOB2(grey5,grey[5],0)
  2935. JOB2(grey6,grey[6],0)
  2936. JOB2(grey7,grey[7],0)
  2937. JOB2(grey8,grey[8],0)
  2938. JOB2(grey9,grey[9],0)
  2939. JOB0
  2940. };
  2941. //-----------------------------------------------------------------------------
  2942. static const color_helper_tab_t ch_tab_name1[] =
  2943. {
  2944. // [[new-color]]
  2945. SEP1
  2946. JOB1(setup)
  2947. JOB1(run)
  2948. JOB1(abort)
  2949. JOB1(finish)
  2950. JOB1(script)
  2951. JOB1(open)
  2952. JOB1(close)
  2953. JOB1(file)
  2954. JOB1(job)
  2955. JOB1(debug)
  2956. JOB1(log)
  2957. JOB1(mark)
  2958. JOB1(info)
  2959. JOB1(hint)
  2960. JOB1(warn)
  2961. JOB1(err)
  2962. JOB1(bad)
  2963. JOB1(name)
  2964. JOB1(op)
  2965. JOB1(value)
  2966. JOB2(val,value,1)
  2967. JOB1(success)
  2968. JOB1(error)
  2969. JOB1(fail)
  2970. JOB1(fail2)
  2971. JOB1(fatal)
  2972. JOB1(select)
  2973. JOB1(differ)
  2974. JOB1(stat_line)
  2975. JOB1(warn_line)
  2976. JOB1(proc_line)
  2977. JOB0
  2978. };
  2979. //-----------------------------------------------------------------------------
  2980. _Static_assert( N_COLORSET_HL_LINE == 4, "wrong N_COLORSET_HL_LINE" );
  2981. _Static_assert( N_COLORSET_ORDER == 9, "wrong N_COLORSET_ORDER" );
  2982. static const color_helper_tab_t ch_tab_name2[] =
  2983. {
  2984. // [[new-color]]
  2985. SEP1
  2986. JOB2(hl_line0,hl_line[0],0)
  2987. JOB2(hl_line1,hl_line[1],0)
  2988. JOB2(hl_line2,hl_line[2],0)
  2989. JOB2(hl_line3,hl_line[3],0)
  2990. JOB2(order0,order[0],0)
  2991. JOB2(order1,order[1],0)
  2992. JOB2(order2,order[2],0)
  2993. JOB2(order3,order[3],0)
  2994. JOB2(order4,order[4],0)
  2995. JOB2(order5,order[5],0)
  2996. JOB2(order6,order[6],0)
  2997. JOB2(order7,order[7],0)
  2998. JOB2(order8,order[8],0)
  2999. JOB1(cite)
  3000. JOB1(status)
  3001. JOB1(highlight)
  3002. JOB2(hl,highlight,1)
  3003. JOB1(hide)
  3004. JOB1(heading)
  3005. JOB2(head,heading,1)
  3006. JOB1(caption)
  3007. JOB1(section)
  3008. JOB1(syntax)
  3009. JOB1(cmd)
  3010. JOB1(option)
  3011. JOB2(opt,option,1)
  3012. JOB1(param)
  3013. JOB2(par,param,1)
  3014. JOB1(off)
  3015. JOB1(on)
  3016. JOB0
  3017. };
  3018. //-----------------------------------------------------------------------------
  3019. _Static_assert( N_COLORSET_HL_LINE == 4, "wrong N_COLORSET_HL_LINE" );
  3020. _Static_assert( N_COLORSET_ORDER == 9, "wrong N_COLORSET_ORDER" );
  3021. static const color_helper_tab_t ch_tab_name[] =
  3022. {
  3023. // [[new-color]]
  3024. SEP1
  3025. JOB1(setup)
  3026. JOB1(run)
  3027. JOB1(abort)
  3028. JOB1(finish)
  3029. JOB1(script)
  3030. JOB1(open)
  3031. JOB1(close)
  3032. JOB1(file)
  3033. JOB1(job)
  3034. JOB1(debug)
  3035. JOB1(log)
  3036. JOB1(mark)
  3037. JOB1(info)
  3038. JOB1(hint)
  3039. JOB1(warn)
  3040. JOB1(err)
  3041. JOB1(bad)
  3042. JOB1(name)
  3043. JOB1(op)
  3044. JOB1(value)
  3045. JOB2(val,value,1)
  3046. JOB1(success)
  3047. JOB1(error)
  3048. JOB1(fail)
  3049. JOB1(fail2)
  3050. JOB1(fatal)
  3051. JOB1(select)
  3052. JOB1(differ)
  3053. JOB1(stat_line)
  3054. JOB1(warn_line)
  3055. JOB1(proc_line)
  3056. JOB2(hl_line0,hl_line[0],0)
  3057. JOB2(hl_line1,hl_line[1],0)
  3058. JOB2(hl_line2,hl_line[2],0)
  3059. JOB2(hl_line3,hl_line[3],0)
  3060. JOB2(order0,order[0],0)
  3061. JOB2(order1,order[1],0)
  3062. JOB2(order2,order[2],0)
  3063. JOB2(order3,order[3],0)
  3064. JOB2(order4,order[4],0)
  3065. JOB2(order5,order[5],0)
  3066. JOB2(order6,order[6],0)
  3067. JOB2(order7,order[7],0)
  3068. JOB2(order8,order[8],0)
  3069. JOB1(cite)
  3070. JOB1(status)
  3071. JOB1(highlight)
  3072. JOB2(hl,highlight,1)
  3073. JOB1(hide)
  3074. JOB1(heading)
  3075. JOB2(head,heading,1)
  3076. JOB1(caption)
  3077. JOB1(section)
  3078. JOB1(syntax)
  3079. JOB1(cmd)
  3080. JOB1(option)
  3081. JOB2(opt,option,1)
  3082. JOB1(param)
  3083. JOB2(par,param,1)
  3084. JOB1(off)
  3085. JOB1(on)
  3086. JOB0
  3087. };
  3088. //-----------------------------------------------------------------------------
  3089. #undef JOB0
  3090. #undef JOB1
  3091. #undef JOB2
  3092. #undef SEP1
  3093. //
  3094. ///////////////////////////////////////////////////////////////////////////////
  3095. /////////////// colors ///////////////
  3096. ///////////////////////////////////////////////////////////////////////////////
  3097. const ColorSet_t * GetColorSet0()
  3098. {
  3099. static ColorSet_t col = {0};
  3100. if (!col.col_mode)
  3101. {
  3102. col.col_mode = COLMD_OFF;
  3103. col.colorize = false;
  3104. col.n_colors = 0;
  3105. col.space = EmptyString;
  3106. col.tab = EmptyString;
  3107. col.lf = EmptyString;
  3108. ccp *ptr = &col.reset;
  3109. ccp *end = (ccp*)((ccp)&col + sizeof(col));
  3110. while ( ptr < end )
  3111. *ptr++ = EmptyString;
  3112. }
  3113. return &col;
  3114. }
  3115. ///////////////////////////////////////////////////////////////////////////////
  3116. const ColorSet_t * GetColorSet8()
  3117. {
  3118. // [[new-color]]
  3119. static ColorSet_t col = {0};
  3120. if (!col.col_mode)
  3121. {
  3122. col.col_mode = COLMD_8_COLORS;
  3123. col.colorize = true;
  3124. col.n_colors = 8;
  3125. col.space = Space200;
  3126. col.tab = Tabs20;
  3127. col.lf = LF20;
  3128. col.reset = TermTextModeReset;
  3129. col.setup = STRDUP(GetTextMode(1,TTM_COL_SETUP));
  3130. col.run = STRDUP(GetTextMode(1,TTM_COL_RUN));
  3131. col.abort = STRDUP(GetTextMode(1,TTM_COL_ABORT));
  3132. col.finish = STRDUP(GetTextMode(1,TTM_COL_FINISH));
  3133. col.script = STRDUP(GetTextMode(1,TTM_COL_SCRIPT));
  3134. col.open = STRDUP(GetTextMode(1,TTM_COL_OPEN));
  3135. col.close = STRDUP(GetTextMode(1,TTM_COL_CLOSE));
  3136. col.file = STRDUP(GetTextMode(1,TTM_COL_FILE));
  3137. col.job = STRDUP(GetTextMode(1,TTM_COL_JOB));
  3138. col.debug = STRDUP(GetTextMode(1,TTM_COL_DEBUG));
  3139. col.log = STRDUP(GetTextMode(1,TTM_COL_LOG));
  3140. col.mark = STRDUP(GetTextMode(1,TTM_COL_MARK));
  3141. col.info = STRDUP(GetTextMode(1,TTM_COL_INFO));
  3142. col.hint = STRDUP(GetTextMode(1,TTM_COL_HINT));
  3143. col.warn = STRDUP(GetTextMode(1,TTM_COL_WARN));
  3144. col.err = STRDUP(GetTextMode(1,TTM_COL_ERR));
  3145. col.bad = STRDUP(GetTextMode(1,TTM_COL_BAD));
  3146. col.name = STRDUP(GetTextMode(1,TTM_COL_NAME));
  3147. col.op = STRDUP(GetTextMode(1,TTM_COL_OP));
  3148. col.value = STRDUP(GetTextMode(1,TTM_COL_VALUE));
  3149. col.success = STRDUP(GetTextMode(1,TTM_COL_SUCCESS));
  3150. col.error = STRDUP(GetTextMode(1,TTM_COL_ERROR));
  3151. col.fail = STRDUP(GetTextMode(1,TTM_COL_FAIL));
  3152. col.fail2 = STRDUP(GetTextMode(1,TTM_COL_FAIL2));
  3153. col.fatal = STRDUP(GetTextMode(1,TTM_COL_FATAL));
  3154. col.select = STRDUP(GetTextMode(1,TTM_COL_SELECT));
  3155. col.differ = STRDUP(GetTextMode(1,TTM_COL_DIFFER));
  3156. col.stat_line = STRDUP(GetTextMode(1,TTM_COL_STAT_LINE));
  3157. col.warn_line = STRDUP(GetTextMode(1,TTM_COL_WARN_LINE));
  3158. col.proc_line = STRDUP(GetTextMode(1,TTM_COL_PROC_LINE));
  3159. col.cite = STRDUP(GetTextMode(1,TTM_COL_CITE));
  3160. col.status = STRDUP(GetTextMode(1,TTM_COL_STATUS));
  3161. col.highlight = STRDUP(GetTextMode(1,TTM_COL_HIGHLIGHT));
  3162. col.hide = STRDUP(GetTextMode(1,TTM_COL_HIDE));
  3163. col.heading = STRDUP(GetTextMode(1,TTM_COL_HEADING));
  3164. col.caption = STRDUP(GetTextMode(1,TTM_COL_CAPTION));
  3165. col.section = STRDUP(GetTextMode(1,TTM_COL_SECTION));
  3166. col.syntax = STRDUP(GetTextMode(1,TTM_COL_SYNTAX));
  3167. col.cmd = STRDUP(GetTextMode(1,TTM_COL_CMD));
  3168. col.option = STRDUP(GetTextMode(1,TTM_COL_OPTION));
  3169. col.param = STRDUP(GetTextMode(1,TTM_COL_PARAM));
  3170. col.on = STRDUP(GetTextMode(1,TTM_COL_ON));
  3171. col.off = STRDUP(GetTextMode(1,TTM_COL_OFF));
  3172. _Static_assert( N_COLORSET_HL_LINE == 4, "wrong N_COLORSET_HL_LINE" );
  3173. col.hl_line[0] = STRDUP(GetTextMode(1,TTM_COL_HL_LINE0));
  3174. col.hl_line[1] = STRDUP(GetTextMode(1,TTM_COL_HL_LINE1));
  3175. col.hl_line[2] = STRDUP(GetTextMode(1,TTM_COL_HL_LINE2));
  3176. col.hl_line[3] = STRDUP(GetTextMode(1,TTM_COL_HL_LINE3));
  3177. _Static_assert( N_COLORSET_ORDER == 9, "wrong N_COLORSET_ORDER" );
  3178. col.order[0] = STRDUP(GetTextMode(1,TTM_COL_ORDER0));
  3179. col.order[1] = STRDUP(GetTextMode(1,TTM_COL_ORDER1));
  3180. col.order[2] = STRDUP(GetTextMode(1,TTM_COL_ORDER2));
  3181. col.order[3] = STRDUP(GetTextMode(1,TTM_COL_ORDER3));
  3182. col.order[4] = STRDUP(GetTextMode(1,TTM_COL_ORDER4));
  3183. col.order[5] = STRDUP(GetTextMode(1,TTM_COL_ORDER5));
  3184. col.order[6] = STRDUP(GetTextMode(1,TTM_COL_ORDER6));
  3185. col.order[7] = STRDUP(GetTextMode(1,TTM_COL_ORDER7));
  3186. col.order[8] = STRDUP(GetTextMode(1,TTM_COL_ORDER8));
  3187. _Static_assert( N_COLORSET_GREY == 10, "wrong N_COLORSET_GREY" );
  3188. col.grey[0] =
  3189. col.grey[1] =
  3190. col.black = STRDUP(GetTextMode(1,TTM_NO_BOLD|TTM_BLACK));
  3191. col.grey[2] =
  3192. col.grey[3] =
  3193. col.grey[4] =
  3194. col.b_black = STRDUP(GetTextMode(1,TTM_BOLD|TTM_BLACK));
  3195. col.grey[5] =
  3196. col.grey[6] =
  3197. col.grey[7] =
  3198. col.white = STRDUP(GetTextMode(1,TTM_NO_BOLD|TTM_WHITE));
  3199. col.grey[8] =
  3200. col.grey[9] =
  3201. col.b_white = STRDUP(GetTextMode(1,TTM_BOLD|TTM_WHITE));
  3202. col.red_magenta =
  3203. col.red =
  3204. col.red_orange =
  3205. col.orange_red =
  3206. col.orange = STRDUP(GetTextMode(1,TTM_NO_BOLD|TTM_RED));
  3207. col.orange_yellow =
  3208. col.yellow_orange =
  3209. col.yellow =
  3210. col.yellow_green = STRDUP(GetTextMode(1,TTM_NO_BOLD|TTM_YELLOW));
  3211. col.green_yellow =
  3212. col.green =
  3213. col.green_cyan = STRDUP(GetTextMode(1,TTM_NO_BOLD|TTM_GREEN));
  3214. col.cyan_green =
  3215. col.cyan =
  3216. col.cyan_blue = STRDUP(GetTextMode(1,TTM_NO_BOLD|TTM_CYAN));
  3217. col.blue_cyan =
  3218. col.blue =
  3219. col.blue_magenta = STRDUP(GetTextMode(1,TTM_NO_BOLD|TTM_BLUE));
  3220. col.magenta_blue =
  3221. col.magenta =
  3222. col.magenta_red = STRDUP(GetTextMode(1,TTM_NO_BOLD|TTM_MAGENTA));
  3223. col.b_red_magenta =
  3224. col.b_red =
  3225. col.b_red_orange =
  3226. col.b_orange_red =
  3227. col.b_orange = STRDUP(GetTextMode(1,TTM_BOLD|TTM_RED));
  3228. col.b_orange_yellow =
  3229. col.b_yellow_orange =
  3230. col.b_yellow =
  3231. col.b_yellow_green = STRDUP(GetTextMode(1,TTM_BOLD|TTM_YELLOW));
  3232. col.b_green_yellow =
  3233. col.b_green =
  3234. col.b_green_cyan = STRDUP(GetTextMode(1,TTM_BOLD|TTM_GREEN));
  3235. col.b_cyan_green =
  3236. col.b_cyan =
  3237. col.b_cyan_blue = STRDUP(GetTextMode(1,TTM_BOLD|TTM_CYAN));
  3238. col.b_blue_cyan =
  3239. col.b_blue =
  3240. col.b_blue_magenta = STRDUP(GetTextMode(1,TTM_BOLD|TTM_BLUE));
  3241. col.b_magenta_blue =
  3242. col.b_magenta =
  3243. col.b_magenta_red = STRDUP(GetTextMode(1,TTM_BOLD|TTM_MAGENTA));
  3244. TermColorIndex_t font, bg;
  3245. for ( font = 0; font < TCI__N_FONT; font++ )
  3246. for ( bg = 0; bg < TCI__N_BG; bg++ )
  3247. col.matrix[font][bg]
  3248. = STRDUP(GetColorMode(COLMD_8_COLORS,font,bg,GCM_ALT|GCM_SHORT));
  3249. }
  3250. return &col;
  3251. }
  3252. ///////////////////////////////////////////////////////////////////////////////
  3253. const ColorSet_t * GetColorSet256()
  3254. {
  3255. // [[new-color]]
  3256. static ColorSet_t col = {0};
  3257. if (!col.col_mode)
  3258. {
  3259. //--- default settings (copy of 8-COLORS)
  3260. memcpy(&col,GetColorSet8(),sizeof(col));
  3261. col.col_mode = COLMD_256_COLORS;
  3262. col.n_colors = 256;
  3263. //--- special settings
  3264. col.setup = "\e[0;38;5;86m";
  3265. col.run = "\e[0;38;5;229m";
  3266. col.abort = "\e[0;38;5;198m";
  3267. col.finish = "\e[0;38;5;154m";
  3268. col.script = "\e[0;0;30;48;5;219m";
  3269. col.open = "\e[0;38;5;225m";
  3270. col.close = "\e[0;38;5;219m";
  3271. col.file = "\e[0;38;5;223m";
  3272. col.heading = "\e[0;38;5;111m";
  3273. col.cmd = "\e[0;38;5;123m";
  3274. col.info = "\e[0;38;5;49m";
  3275. col.hint = "\e[0;38;5;220m";
  3276. col.warn = "\e[0;38;5;208m";
  3277. col.err = "\e[0;38;5;198m";
  3278. col.debug = "\e[0;38;5;210m";
  3279. col.error = "\e[0;38;5;255;48;5;130m";
  3280. col.fail = "\e[0;38;5;251;48;5;88m";
  3281. col.fail2 = "\e[0;38;5;255;48;5;88m";
  3282. col.fatal = "\e[0;38;5;255;48;5;129m";
  3283. col.differ = "\e[0;38;5;226;48;5;18m";
  3284. col.stat_line = "\e[0;38;5;231;48;5;18m";
  3285. col.warn_line = "\e[0;38;5;214;48;5;18m";
  3286. col.hide = "\e[0;38;5;245m";
  3287. _Static_assert( N_COLORSET_HL_LINE == 4, "wrong N_COLORSET_HL_LINE" );
  3288. col.hl_line[0] = "\e[0;38;5;145m";
  3289. col.hl_line[1] = "\e[0;38;5;159m";
  3290. col.hl_line[2] = "\e[0;38;5;157m";
  3291. col.hl_line[3] = "\e[0;38;5;217m";
  3292. _Static_assert( N_COLORSET_ORDER == 9, "wrong N_COLORSET_ORDER" );
  3293. //col.order[0] =
  3294. col.order[1] = "\e[0;38;5;39m";
  3295. //col.order[2] =
  3296. //col.order[3] =
  3297. //col.order[4] =
  3298. col.order[5] = "\e[0;38;5;214m";
  3299. col.order[6] = "\e[0;38;5;197m";
  3300. col.order[7] = "\e[0;38;5;213m";
  3301. col.order[8] = "\e[0;38;5;141m";
  3302. //--- special settings: color names
  3303. // dark:
  3304. // ./mkw-ana testcol 400-420 420-330 330-030 030-033 033-005 005-404 404-400
  3305. // ./mkw-ana testcol 401 400 410 420 320 330 230 130 030 031 032 033 024 015 005 204 304 404 402 401
  3306. col.red_magenta = "\e[38;5;161m";
  3307. col.red = "\e[38;5;160m";
  3308. col.red_orange =
  3309. col.orange_red = "\e[38;5;166m";
  3310. col.orange = "\e[38;5;172m";
  3311. col.orange_yellow =
  3312. col.yellow_orange = "\e[38;5;136m";
  3313. col.yellow = "\e[38;5;142m";
  3314. col.yellow_green = "\e[38;5;106m";
  3315. col.green_yellow = "\e[38;5;70m";
  3316. col.green = "\e[38;5;34m";
  3317. col.green_cyan = "\e[38;5;35m";
  3318. col.cyan_green = "\e[38;5;36m";
  3319. col.cyan = "\e[38;5;37m";
  3320. col.cyan_blue = "\e[38;5;32m";
  3321. col.blue_cyan = "\e[38;5;27m";
  3322. col.blue = "\e[38;5;21m";
  3323. col.blue_magenta = "\e[38;5;92m";
  3324. col.magenta_blue = "\e[38;5;128m";
  3325. col.magenta = "\e[38;5;164m";
  3326. col.magenta_red = "\e[38;5;162m";
  3327. // bold:
  3328. // ./mkw-ana testcol 500-520 520-550 550-050 050-055 055-225 225-515 515-500
  3329. // ./mkw-ana testcol 502 500 510 520 530 540 550 350 250 050 053 054 055 135 235 225 325 425 515 513 502
  3330. col.b_red_magenta = "\e[38;5;198m";
  3331. col.b_red = "\e[38;5;196m";
  3332. col.b_red_orange =
  3333. col.b_orange_red = "\e[38;5;202m";
  3334. col.b_orange = "\e[38;5;208m";
  3335. col.b_orange_yellow = "\e[38;5;214m";
  3336. col.b_yellow_orange = "\e[38;5;220m";
  3337. col.b_yellow = "\e[38;5;226m";
  3338. col.b_yellow_green = "\e[38;5;154m";
  3339. col.b_green_yellow = "\e[38;5;118m";
  3340. col.b_green = "\e[38;5;46m";
  3341. col.b_green_cyan = "\e[38;5;49m";
  3342. col.b_cyan_green = "\e[38;5;50m";
  3343. col.b_cyan = "\e[38;5;51m";
  3344. col.b_cyan_blue = "\e[38;5;75m";
  3345. col.b_blue_cyan = "\e[38;5;111m";
  3346. col.b_blue = "\e[38;5;105m";
  3347. col.b_blue_magenta = "\e[38;5;141m";
  3348. col.b_magenta_blue = "\e[38;5;177m";
  3349. col.b_magenta = "\e[38;5;207m";
  3350. col.b_magenta_red = "\e[38;5;205m";
  3351. _Static_assert( N_COLORSET_GREY == 10, "wrong N_COLORSET_GREY" );
  3352. col.grey[0] = "\e[38;5;232m";
  3353. col.grey[1] = "\e[38;5;235m";
  3354. col.grey[2] = "\e[38;5;237m";
  3355. col.grey[3] = "\e[38;5;240m";
  3356. col.grey[4] = "\e[38;5;242m";
  3357. col.grey[5] = "\e[38;5;245m";
  3358. col.grey[6] = "\e[38;5;247m";
  3359. col.grey[7] = "\e[38;5;250m";
  3360. col.grey[8] = "\e[38;5;252m";
  3361. col.grey[9] = "\e[38;5;255m";
  3362. TermColorIndex_t font, bg;
  3363. for ( font = 0; font < TCI__N_FONT; font++ )
  3364. for ( bg = 0; bg < TCI__N_BG; bg++ )
  3365. col.matrix[font][bg]
  3366. = STRDUP(GetColorMode(COLMD_256_COLORS,font,bg,GCM_ALT|GCM_SHORT));
  3367. }
  3368. return &col;
  3369. }
  3370. ///////////////////////////////////////////////////////////////////////////////
  3371. int setupterm(char *term, int fildes, int *errret);
  3372. int tigetnum(char *capname);
  3373. const ColorSet_t * GetColorSetAuto ( bool force_on )
  3374. {
  3375. static ColorMode_t auto_mode = COLMD_AUTO;
  3376. if ( opt_colorize != COLMD_AUTO )
  3377. {
  3378. if ( opt_colorize == COLMD_ON )
  3379. force_on = true;
  3380. else
  3381. auto_mode = opt_colorize;
  3382. }
  3383. if ( auto_mode == COLMD_AUTO )
  3384. {
  3385. char *term = getenv("TERM");
  3386. #ifdef __CYGWIN__
  3387. if (!term)
  3388. term = "cygwin";
  3389. #else
  3390. if (!term)
  3391. term = "vt100";
  3392. #endif
  3393. int error;
  3394. setupterm(term,1,&error);
  3395. const int ncol = tigetnum("colors");
  3396. auto_mode = ncol >= 256 ? COLMD_256_COLORS
  3397. : ncol >= 8 ? COLMD_8_COLORS
  3398. : COLMD_OFF;
  3399. if ( auto_mode == COLMD_OFF && !strcmp(term,"cygwin") )
  3400. auto_mode = COLMD_8_COLORS;
  3401. #ifdef TEST
  3402. fprintf(stderr,">>> GetColorSetAuto(%d) => \"%s\" n=%d => %d [%s]\n",
  3403. force_on, term, ncol,
  3404. auto_mode, GetColorModeName(auto_mode,0) );
  3405. #endif
  3406. }
  3407. switch(auto_mode)
  3408. {
  3409. case COLMD_8_COLORS:
  3410. return GetColorSet8();
  3411. case COLMD_256_COLORS:
  3412. return GetColorSet256();
  3413. default:
  3414. return force_on ? GetColorSet8() : GetColorSet0();
  3415. }
  3416. }
  3417. ///////////////////////////////////////////////////////////////////////////////
  3418. const ColorSet_t * GetColorSet ( ColorMode_t col_mode )
  3419. {
  3420. switch(col_mode)
  3421. {
  3422. case COLMD_AUTO:
  3423. return GetColorSetAuto(false);
  3424. case COLMD_ON:
  3425. return GetColorSetAuto(true);
  3426. case COLMD_8_COLORS:
  3427. return GetColorSet8();
  3428. case COLMD_256_COLORS:
  3429. return GetColorSet256();
  3430. default:
  3431. return GetColorSet0();
  3432. }
  3433. }
  3434. ///////////////////////////////////////////////////////////////////////////////
  3435. const ColorSet_t * GetFileColorSet ( FILE *f )
  3436. {
  3437. return GetColorSet(GetFileColorized(f));
  3438. }
  3439. ///////////////////////////////////////////////////////////////////////////////
  3440. bool SetupColorSet ( ColorSet_t *cs, FILE *f )
  3441. {
  3442. DASSERT(cs);
  3443. memcpy(cs,GetColorSet(GetFileColorized(f)),sizeof(*cs));
  3444. return cs->colorize;
  3445. }
  3446. ///////////////////////////////////////////////////////////////////////////////
  3447. int GetColorOffsetByName ( ccp name )
  3448. {
  3449. struct cdef_t
  3450. {
  3451. u16 delta;
  3452. char name[16];
  3453. };
  3454. #undef DEF1
  3455. #undef DEF2
  3456. #define DEF1(n) { offsetof(ColorSet_t,n), #n },
  3457. #define DEF2(t,n) { offsetof(ColorSet_t,n), #t },
  3458. _Static_assert( N_COLORSET_HL_LINE == 4, "wrong N_COLORSET_HL_LINE" );
  3459. _Static_assert( N_COLORSET_ORDER == 9, "wrong N_COLORSET_ORDER" );
  3460. _Static_assert( N_COLORSET_GREY == 10, "wrong N_COLORSET_GREY" );
  3461. static const struct cdef_t tab[] =
  3462. {
  3463. // [[new-color]] order by name
  3464. DEF1(abort)
  3465. DEF1(b_black)
  3466. DEF1(b_blue)
  3467. DEF1(b_blue_cyan)
  3468. DEF1(b_blue_magenta)
  3469. DEF1(b_cyan)
  3470. DEF1(b_cyan_blue)
  3471. DEF1(b_cyan_green)
  3472. DEF1(b_green)
  3473. DEF1(b_green_cyan)
  3474. DEF1(b_green_yellow)
  3475. DEF1(b_magenta)
  3476. DEF1(b_magenta_blue)
  3477. DEF1(b_magenta_red)
  3478. DEF1(b_orange)
  3479. DEF1(b_orange_red)
  3480. DEF1(b_orange_yellow)
  3481. DEF1(b_red)
  3482. DEF1(b_red_magenta)
  3483. DEF1(b_red_orange)
  3484. DEF1(b_white)
  3485. DEF1(b_yellow)
  3486. DEF1(b_yellow_green)
  3487. DEF1(b_yellow_orange)
  3488. DEF1(bad)
  3489. DEF1(black)
  3490. DEF1(blue)
  3491. DEF1(blue_cyan)
  3492. DEF1(blue_magenta)
  3493. DEF1(caption)
  3494. DEF1(cite)
  3495. DEF1(close)
  3496. DEF1(cmd)
  3497. DEF1(cyan)
  3498. DEF1(cyan_blue)
  3499. DEF1(cyan_green)
  3500. DEF1(debug)
  3501. DEF1(differ)
  3502. DEF1(err)
  3503. DEF1(error)
  3504. DEF1(fail)
  3505. DEF1(fail2)
  3506. DEF1(fatal)
  3507. DEF1(file)
  3508. DEF1(finish)
  3509. DEF2(gray0,grey[0])
  3510. DEF2(gray1,grey[1])
  3511. DEF2(gray2,grey[2])
  3512. DEF2(gray3,grey[3])
  3513. DEF2(gray4,grey[4])
  3514. DEF2(gray5,grey[5])
  3515. DEF2(gray6,grey[6])
  3516. DEF2(gray7,grey[7])
  3517. DEF2(gray8,grey[8])
  3518. DEF2(gray9,grey[9])
  3519. DEF1(green)
  3520. DEF1(green_cyan)
  3521. DEF1(green_yellow)
  3522. DEF2(grey0,grey[0])
  3523. DEF2(grey1,grey[1])
  3524. DEF2(grey2,grey[2])
  3525. DEF2(grey3,grey[3])
  3526. DEF2(grey4,grey[4])
  3527. DEF2(grey5,grey[5])
  3528. DEF2(grey6,grey[6])
  3529. DEF2(grey7,grey[7])
  3530. DEF2(grey8,grey[8])
  3531. DEF2(grey9,grey[9])
  3532. DEF2(head,heading)
  3533. DEF1(heading)
  3534. DEF1(hide)
  3535. DEF1(highlight)
  3536. DEF1(hint)
  3537. DEF2(hl,highlight)
  3538. DEF2(hl_line0,hl_line[0])
  3539. DEF2(hl_line1,hl_line[1])
  3540. DEF2(hl_line2,hl_line[2])
  3541. DEF2(hl_line3,hl_line[3])
  3542. DEF1(info)
  3543. DEF1(job)
  3544. DEF1(log)
  3545. DEF1(magenta)
  3546. DEF1(magenta_blue)
  3547. DEF1(magenta_red)
  3548. DEF1(mark)
  3549. DEF1(name)
  3550. DEF1(off)
  3551. DEF1(on)
  3552. DEF1(op)
  3553. DEF1(open)
  3554. DEF2(opt,option)
  3555. DEF1(option)
  3556. DEF1(orange)
  3557. DEF1(orange_red)
  3558. DEF1(orange_yellow)
  3559. DEF2(order0,order[0])
  3560. DEF2(order1,order[1])
  3561. DEF2(order2,order[2])
  3562. DEF2(order3,order[3])
  3563. DEF2(order4,order[4])
  3564. DEF2(order5,order[5])
  3565. DEF2(order6,order[6])
  3566. DEF2(order7,order[7])
  3567. DEF2(order8,order[8])
  3568. DEF2(par,param)
  3569. DEF1(param)
  3570. DEF1(proc_line)
  3571. DEF1(red)
  3572. DEF1(red_magenta)
  3573. DEF1(red_orange)
  3574. DEF1(reset)
  3575. DEF1(run)
  3576. DEF1(script)
  3577. DEF1(section)
  3578. DEF1(select)
  3579. DEF1(setup)
  3580. DEF1(stat_line)
  3581. DEF1(status)
  3582. DEF1(success)
  3583. DEF1(syntax)
  3584. DEF2(val,value)
  3585. DEF1(value)
  3586. DEF1(warn)
  3587. DEF1(warn_line)
  3588. DEF1(white)
  3589. DEF1(yellow)
  3590. DEF1(yellow_green)
  3591. DEF1(yellow_orange)
  3592. };
  3593. #if HAVE_PRINT
  3594. static bool done = false;
  3595. if (!done)
  3596. {
  3597. done = true;
  3598. uint i, max_len = 0, err_count = 0;
  3599. const struct cdef_t *cd = tab;
  3600. for ( i = 0; i < sizeof(tab)/sizeof(*tab); i++, cd++ )
  3601. {
  3602. if ( max_len < strlen(cd->name) )
  3603. max_len = strlen(cd->name);
  3604. if ( i > 0 && strcmp(cd[-1].name,cd->name) >= 0 )
  3605. {
  3606. err_count++;
  3607. PRINT("\e[1;35mWRONG COL ORDER: %s > %s \e[0m\n", cd[-1].name, cd->name);
  3608. }
  3609. }
  3610. DASSERT_MSG( max_len < sizeof(cd->name),
  3611. "%s(): max name len = %d, possible = %zd\n",
  3612. __FUNCTION__, max_len, sizeof(cd->name)-1 );
  3613. DASSERT_MSG( !err_count,
  3614. "%s(): color order is %d* wrong!\n",
  3615. __FUNCTION__, err_count );
  3616. }
  3617. #endif
  3618. //--- search the name
  3619. if (name)
  3620. {
  3621. int beg = 0;
  3622. int end = sizeof(tab)/sizeof(*tab) - 1;
  3623. while ( beg <= end )
  3624. {
  3625. const uint idx = (beg+end)/2;
  3626. const int stat = strcmp(name,tab[idx].name);
  3627. if ( stat < 0 )
  3628. end = idx - 1 ;
  3629. else if ( stat > 0 )
  3630. beg = idx + 1;
  3631. else
  3632. return tab[idx].delta;
  3633. }
  3634. }
  3635. return -1;
  3636. }
  3637. ///////////////////////////////////////////////////////////////////////////////
  3638. ccp GetColorByName ( const ColorSet_t *colset, ccp name )
  3639. {
  3640. if ( colset && name )
  3641. {
  3642. const int offset = GetColorOffsetByName(name);
  3643. if ( offset > 0 )
  3644. return GetColorByValidOffset(colset,offset);
  3645. }
  3646. return EmptyString;
  3647. }
  3648. ///////////////////////////////////////////////////////////////////////////////
  3649. ccp GetColorByOffsetOrName ( const ColorSet_t *colset, int * offset, ccp name )
  3650. {
  3651. if (!offset)
  3652. return GetColorByName(colset,name);
  3653. if (!*offset)
  3654. *offset = GetColorOffsetByName(name);
  3655. return *offset > 0 ? GetColorByValidOffset(colset,*offset) : EmptyString;
  3656. }
  3657. ///////////////////////////////////////////////////////////////////////////////
  3658. ///////////////////////////////////////////////////////////////////////////////
  3659. void ResetLineColor ( const ColorSet_t *colset )
  3660. {
  3661. ColorSet_t *cs = (ColorSet_t*)colset;
  3662. cs->line_begin =
  3663. cs->line_end = EmptyString;
  3664. cs->line_reset = cs->reset;
  3665. }
  3666. //-----------------------------------------------------------------------------
  3667. void SetLineColor ( const ColorSet_t *colset, int level )
  3668. {
  3669. _Static_assert( N_COLORSET_HL_LINE == 4, "wrong N_COLORSET_HL_LINE" );
  3670. ColorSet_t *cs = (ColorSet_t*)colset;
  3671. if ( level <= 0 )
  3672. {
  3673. cs->line_begin = EmptyString;
  3674. cs->line_reset = cs->reset;
  3675. cs->line_end = EmptyString;
  3676. }
  3677. else
  3678. {
  3679. cs->line_begin =
  3680. cs->line_reset = cs->hl_line[ level < N_COLORSET_HL_LINE ? level : N_COLORSET_HL_LINE-1 ];
  3681. cs->line_end = cs->reset;
  3682. }
  3683. }
  3684. _Static_assert( N_COLORSET_ORDER == 9, "wrong N_COLORSET_ORDER" );
  3685. // [[col-order]]
  3686. ///////////////////////////////////////////////////////////////////////////////
  3687. ///////////////////////////////////////////////////////////////////////////////
  3688. // [[color_helper_t]]
  3689. typedef struct color_helper_t
  3690. {
  3691. FILE *f; // valid output file
  3692. int indent; // indention of output
  3693. const ColorSet_t *cs; // valid color set; if NULL: use std colors
  3694. PrintColorFunc func; // output function, never NULL
  3695. ColorSelect_t select; // select color groups
  3696. int multi_assign; // >0: Allow A=B="..."; >1: reorder records too
  3697. bool print_alt; // print alternative names
  3698. bool allow_sep; // allow separator lines
  3699. StringField_t sf; // collect strings hre if multi_assign>1
  3700. }
  3701. color_helper_t;
  3702. //-----------------------------------------------------------------------------
  3703. static void print_by_helper_tab
  3704. (
  3705. color_helper_t *ch, // valid param
  3706. const color_helper_tab_t *tab // valid color list
  3707. )
  3708. {
  3709. DASSERT(ch);
  3710. DASSERT(tab);
  3711. const ColorSet_t *col = ch->cs;
  3712. if ( ch->multi_assign <= 0 )
  3713. {
  3714. for ( ; tab->name; tab++ )
  3715. {
  3716. if ( !tab->is_alt || ch->print_alt )
  3717. {
  3718. if (tab->offset)
  3719. {
  3720. ch->allow_sep = true;
  3721. ch->func( ch->f, ch->indent, col,
  3722. tab->name, *(ccp*)((u8*)col+tab->offset) );
  3723. }
  3724. else if (ch->allow_sep)
  3725. {
  3726. ch->allow_sep = false;
  3727. ch->func(ch->f,ch->indent,col,0,0);
  3728. }
  3729. }
  3730. }
  3731. return;
  3732. }
  3733. //-------------------------------------------------------------------------
  3734. if ( ch->multi_assign > 1 )
  3735. {
  3736. char key[100];
  3737. for ( ; tab->name; tab++ )
  3738. {
  3739. if ( tab->offset && ( !tab->is_alt || ch->print_alt ))
  3740. {
  3741. snprintf(key,sizeof(key),"%s\1%s",*(ccp*)((u8*)col+tab->offset),tab->name);
  3742. InsertStringField(&ch->sf,key,false);
  3743. }
  3744. }
  3745. return;
  3746. }
  3747. //-------------------------------------------------------------------------
  3748. // ch->multi_assign == 1
  3749. // skip separators
  3750. while ( tab->name && ( !tab->offset || !( !tab->is_alt || ch->print_alt )))
  3751. tab++;
  3752. while (tab->name)
  3753. {
  3754. bool have_next = false;
  3755. const color_helper_tab_t *next = tab+1;
  3756. for ( ; next->name; next++ )
  3757. {
  3758. if ( next->offset && ( !next->is_alt || ch->print_alt ))
  3759. {
  3760. have_next = true;
  3761. break;
  3762. }
  3763. }
  3764. ccp val = *(ccp*)((u8*)col+tab->offset);
  3765. if ( have_next && !strcmp(val,*(ccp*)((u8*)col+next->offset)) )
  3766. val = 0;
  3767. ch->func( ch->f, ch->indent, col, tab->name, val );
  3768. if (!have_next)
  3769. break;
  3770. tab = next;
  3771. }
  3772. };
  3773. //-----------------------------------------------------------------------------
  3774. void PrintColorSetHelper2
  3775. (
  3776. color_helper_t *ch // valid params
  3777. )
  3778. {
  3779. // [[new-color]]
  3780. DASSERT(ch);
  3781. DASSERT(ch->f);
  3782. DASSERT(ch->func);
  3783. if (!ch->cs)
  3784. ch->cs = GetColorSet(COLMD_ON);
  3785. ch->indent = NormalizeIndent(ch->indent) + 15; // 15 is max name width
  3786. if ( !ch->select )
  3787. ch->select = COLSEL_M_MODE;
  3788. ch->print_alt = ( ch->select & COLSEL_F_ALT ) != 0;
  3789. ch->allow_sep = true;
  3790. if ( ch->multi_assign > 1 )
  3791. InitializeStringField(&ch->sf);
  3792. if ( ch->select & COLSEL_COLOR )
  3793. print_by_helper_tab(ch,ch_tab_color);
  3794. if ( ch->select & COLSEL_B_COLOR )
  3795. print_by_helper_tab(ch,ch_tab_bcolor);
  3796. if ( ch->select & COLSEL_GREY )
  3797. print_by_helper_tab(ch,ch_tab_grey);
  3798. if ( (ch->select & COLSEL_NAME) == COLSEL_NAME )
  3799. print_by_helper_tab(ch,ch_tab_name);
  3800. else if ( ch->select & COLSEL_NAME1 )
  3801. print_by_helper_tab(ch,ch_tab_name1);
  3802. else if ( ch->select & COLSEL_NAME2 )
  3803. print_by_helper_tab(ch,ch_tab_name2);
  3804. if ( ch->multi_assign > 1 )
  3805. {
  3806. ccp *ptr, *end = ch->sf.field + ch->sf.used;
  3807. for ( ptr = ch->sf.field; ptr < end; ptr++ )
  3808. {
  3809. ccp val = *ptr;
  3810. char *name = strchr(val,'\1');
  3811. if (!name) continue; // this may never happen!!
  3812. if ( ptr+1 < end && !memcmp(val,ptr[1],name-val+1) )
  3813. val = 0;
  3814. *name++ = 0;
  3815. ch->func( ch->f, ch->indent, ch->cs, name, val );
  3816. }
  3817. ResetStringField(&ch->sf);
  3818. }
  3819. }
  3820. ///////////////////////////////////////////////////////////////////////////////
  3821. ///////////////////////////////////////////////////////////////////////////////
  3822. void PrintColorSetHelper
  3823. (
  3824. FILE *f, // valid output file
  3825. int indent, // indention of output
  3826. const ColorSet_t *cs, // valid color set; if NULL: use std colors
  3827. PrintColorFunc func, // output function, never NULL
  3828. ColorSelect_t select, // select color groups
  3829. int multi_assign // >0: Allow A=B="..."; >1: reorder records too
  3830. )
  3831. {
  3832. color_helper_t ch =
  3833. {
  3834. .f = f,
  3835. .indent = indent,
  3836. .cs = cs,
  3837. .func = func,
  3838. .select = select,
  3839. .multi_assign = multi_assign,
  3840. };
  3841. PrintColorSetHelper2(&ch);
  3842. }
  3843. ///////////////////////////////////////////////////////////////////////////////
  3844. static void PrintColorSetCOL
  3845. (
  3846. // On start of group: col_name := NULL, col_string := NULL
  3847. FILE *f, // valid output file
  3848. int indent, // normalized indention of output
  3849. const ColorSet_t *cs, // valid color set, never NULL
  3850. ccp col_name, // name of color
  3851. ccp col_string // escape string for the color
  3852. )
  3853. {
  3854. if (!col_name)
  3855. fputc('\n',f);
  3856. else
  3857. {
  3858. DASSERT(col_string);
  3859. #ifdef TEST
  3860. fprintf(f,"%*s %s %s %s | %s %s %s\n", \
  3861. indent, col_name, col_string, col_name, cs->reset,
  3862. GetColorByName(cs,col_name), col_name, cs->reset );
  3863. #else
  3864. fprintf(f,"%*s %s %s %s\n",
  3865. indent, col_name, col_string, col_name, cs->reset );
  3866. #endif
  3867. }
  3868. }
  3869. //-----------------------------------------------------------------------------
  3870. static void PrintColorSetSH
  3871. (
  3872. // On start of group: col_name := NULL, col_string := NULL
  3873. FILE *f, // valid output file
  3874. int indent, // normalized indention of output
  3875. const ColorSet_t *cs, // valid color set, never NULL
  3876. ccp col_name, // name of color
  3877. ccp col_string // escape string for the color
  3878. )
  3879. {
  3880. if (col_name)
  3881. {
  3882. DASSERT(col_string);
  3883. char name[50], buf[50];
  3884. char *dest = name;
  3885. while ( *col_name && dest < name + sizeof(name) - 1 )
  3886. *dest++ = toupper((int)*col_name++);
  3887. *dest = 0;
  3888. PrintEscapedString(buf,sizeof(buf),col_string,-1,CHMD_ESC,0,0);
  3889. if (memcmp(buf,"\\x1B",4))
  3890. fprintf(f," COL_%s=$'%s'\n",name,buf);
  3891. else
  3892. fprintf(f," COL_%s='\\033%s'\n",name,buf+4);
  3893. }
  3894. }
  3895. //-----------------------------------------------------------------------------
  3896. static void PrintColorSetPHP
  3897. (
  3898. // On start of group: col_name := NULL, col_string := NULL
  3899. FILE *f, // valid output file
  3900. int indent, // normalized indention of output
  3901. const ColorSet_t *cs, // valid color set, never NULL
  3902. ccp col_name, // name of color
  3903. ccp col_string // escape string for the color
  3904. )
  3905. {
  3906. if ( col_name )
  3907. {
  3908. fprintf(f," $COL->%s%.*s=", col_name, (29-(int)strlen(col_name))/8, Tabs20 );
  3909. if (col_string)
  3910. {
  3911. char buf[50];
  3912. PrintEscapedString(buf,sizeof(buf),col_string,-1,CHMD_ESC,0,0);
  3913. if (memcmp(buf,"\\x1B",4))
  3914. fprintf(f," \"%s\";\n",buf);
  3915. else
  3916. fprintf(f," \"\\033%s\";\n",buf+4);
  3917. }
  3918. else
  3919. fputc('\n',f);
  3920. }
  3921. }
  3922. //-----------------------------------------------------------------------------
  3923. void PrintColorSet
  3924. (
  3925. FILE *f, // valid output file
  3926. int indent, // indention of output
  3927. const ColorSet_t *cs, // valid color set; if NULL: use std colors
  3928. ColorSelect_t select, // select color groups
  3929. uint format // output format
  3930. // 0: colored list
  3931. // 1: shell definitions
  3932. // 2: php class
  3933. )
  3934. {
  3935. DASSERT(f);
  3936. char buf[50];
  3937. switch(format)
  3938. {
  3939. case 1:
  3940. if (!cs)
  3941. cs = GetColorSet(COLMD_ON);
  3942. PrintEscapedString(buf,sizeof(buf),cs->reset,-1,CHMD_ESC,0,0);
  3943. if (memcmp(buf,"\\x1B",4))
  3944. fprintf(f," COL0=$'%s'\n",buf);
  3945. else
  3946. fprintf(f," COL0=$'\\033%s'\n",buf+4);
  3947. PrintColorSetHelper(f,indent,cs,PrintColorSetSH,select,0);
  3948. break;
  3949. case 2:
  3950. if (!cs)
  3951. cs = GetColorSet(COLMD_ON);
  3952. PrintColorSetHelper(f,indent,cs,PrintColorSetPHP,select,2);
  3953. break;
  3954. default:
  3955. PrintColorSetHelper(f,indent,cs,PrintColorSetCOL,select,0);
  3956. fputc('\n',f);
  3957. break;
  3958. }
  3959. }
  3960. //
  3961. ///////////////////////////////////////////////////////////////////////////////
  3962. /////////////// ViewColor*() ///////////////
  3963. ///////////////////////////////////////////////////////////////////////////////
  3964. void SetupColorView ( ColorView_t *cv )
  3965. {
  3966. DASSERT(cv);
  3967. if (!cv->f)
  3968. cv->f = stdout;
  3969. cv->indent = NormalizeIndent(cv->indent);
  3970. #ifdef DCLIB_TERMINAL
  3971. cv->col_mode = cv->colset
  3972. ? cv->colset->col_mode
  3973. : NormalizeColorMode(cv->col_mode,
  3974. cv->term ? cv->term->colors : 8 );
  3975. #else
  3976. cv->col_mode = cv->colset
  3977. ? cv->colset->col_mode
  3978. : NormalizeColorMode(cv->col_mode,8);
  3979. #endif
  3980. if (!cv->colset)
  3981. cv->colset = GetColorSet(cv->col_mode);
  3982. switch(cv->order)
  3983. {
  3984. case 'r': case 'R': cv->order = 0; break;
  3985. case 'g': case 'G': cv->order = 1; break;
  3986. case 'b': case 'B': cv->order = 2; break;
  3987. }
  3988. cv->allow_sep = false;
  3989. }
  3990. ///////////////////////////////////////////////////////////////////////////////
  3991. void SetupColorViewMode ( ColorView_t *cv, ColorMode_t col_mode )
  3992. {
  3993. DASSERT(cv);
  3994. cv->col_mode = col_mode;
  3995. cv->colset = 0;
  3996. SetupColorView(cv);
  3997. }
  3998. ///////////////////////////////////////////////////////////////////////////////
  3999. ///////////////////////////////////////////////////////////////////////////////
  4000. static ccp col_names[] =
  4001. {
  4002. "black:",
  4003. "red:",
  4004. "green:",
  4005. "yellow:",
  4006. "blue:",
  4007. "magenta:",
  4008. "cyan:",
  4009. "white:",
  4010. 0
  4011. };
  4012. //-----------------------------------------------------------------------------
  4013. void ViewColorsAttrib8 ( ColorView_t *cv )
  4014. {
  4015. DASSERT(cv);
  4016. SetupColorView(cv);
  4017. DASSERT(cv->colset);
  4018. #ifdef TEST
  4019. fprintf(cv->f,"%*s%s() %s, %u colors, mode %d, stdcol %d, order %d\n",
  4020. cv->indent,"", __FUNCTION__,
  4021. GetColorModeName(cv->colset->col_mode,0),
  4022. cv->colset->n_colors, cv->mode, cv->std_col, cv->order );
  4023. #endif
  4024. //--------------------------------------------------
  4025. fprintf(cv->f,
  4026. "%s\n%*sStandard font colors with attributes (ul=underline) for mode %s:\n\n",
  4027. cv->colset->reset, cv->indent, "",
  4028. GetColorModeName(cv->col_mode,0) );
  4029. uint fg = 0, bg = 0;
  4030. switch( (int)cv->std_col )
  4031. {
  4032. case TCI_BLACK:
  4033. case TCI_DARKGRAY: fg = TTM_WHITE|TTM_BOLD; bg = TTM_BG_BLACK; break;
  4034. case TCI_LIGHTGRAY:
  4035. case TCI_WHITE: fg = TTM_BLACK; bg = TTM_BG_WHITE; break;
  4036. case TCI_RED:
  4037. case TCI_B_RED:
  4038. case TCI_ORANGE:
  4039. case TCI_B_ORANGE: fg = TTM_WHITE|TTM_BOLD; bg = TTM_BG_RED; break;
  4040. case TCI_YELLOW:
  4041. case TCI_B_YELLOW: fg = TTM_BLACK; bg = TTM_BG_YELLOW; break;
  4042. case TCI_GREEN:
  4043. case TCI_B_GREEN: fg = TTM_WHITE|TTM_BOLD; bg = TTM_BG_GREEN; break;
  4044. case TCI_CYAN:
  4045. case TCI_B_CYAN: fg = TTM_BLACK; bg = TTM_BG_CYAN; break;
  4046. case TCI_BLUE:
  4047. case TCI_B_BLUE: fg = TTM_WHITE|TTM_BOLD; bg = TTM_BG_BLUE; break;
  4048. case TCI_MAGENTA:
  4049. case TCI_B_MAGENTA: fg = TTM_WHITE|TTM_BOLD; bg = TTM_BG_MAGENTA; break;
  4050. }
  4051. ccp *cname;
  4052. TermTextMode_t mode = TTM_BLACK;
  4053. for ( cname = col_names; *cname; cname++, mode += 0x01 )
  4054. {
  4055. fprintf(cv->f,"%*s%s %u %-9s %snormal %sbold %sbold+ul %sul%s reset %s\n",
  4056. cv->indent, "",
  4057. GetTextMode(cv->col_mode,fg|bg),
  4058. (int)(cname - col_names) + 30,
  4059. *cname,
  4060. GetTextMode(cv->col_mode,bg|mode),
  4061. GetTextMode(cv->col_mode,bg|TTM_BOLD),
  4062. GetTextMode(cv->col_mode,bg|TTM_UL),
  4063. GetTextMode(cv->col_mode,bg|TTM_NO_BOLD),
  4064. GetTextMode(cv->col_mode,bg|TTM_RESET),
  4065. cv->colset->reset );
  4066. }
  4067. //--------------------------------------------------
  4068. fprintf(cv->f,
  4069. "\n%*sStandard background colors with attributes (ul=underline) for mode %s:\n\n",
  4070. cv->indent, "", GetColorModeName(cv->col_mode,0) );
  4071. mode = TTM_BG_BLACK;
  4072. for ( cname = col_names; *cname; cname++, mode += 0x10 )
  4073. {
  4074. fprintf(cv->f,"%*s %u %-9s %s white %s bold %sul%s black %sbold %sul%s %s\n",
  4075. cv->indent, "",
  4076. (int)(cname - col_names) + 40,
  4077. *cname,
  4078. GetTextMode(cv->col_mode,mode|TTM_WHITE),
  4079. GetTextMode(cv->col_mode,TTM_BOLD),
  4080. GetTextMode(cv->col_mode,TTM_UL|TTM_NO_BOLD),
  4081. GetTextMode(cv->col_mode,mode|TTM_BLACK|TTM_RESET),
  4082. GetTextMode(cv->col_mode,TTM_BOLD),
  4083. GetTextMode(cv->col_mode,TTM_UL|TTM_NO_BOLD),
  4084. GetTextMode(cv->col_mode,TTM_NO_UL),
  4085. GetTextMode(cv->col_mode,TTM_RESET) );
  4086. }
  4087. }
  4088. ///////////////////////////////////////////////////////////////////////////////
  4089. ///////////////////////////////////////////////////////////////////////////////
  4090. void ViewColorsCombi8 ( ColorView_t *cv )
  4091. {
  4092. DASSERT(cv);
  4093. SetupColorView(cv);
  4094. DASSERT(cv->colset);
  4095. #ifdef TEST
  4096. fprintf(cv->f,"%*s%s() %s, %u colors, mode %d, stdcol %d, order %d\n",
  4097. cv->indent,"", __FUNCTION__,
  4098. GetColorModeName(cv->colset->col_mode,0),
  4099. cv->colset->n_colors, cv->mode, cv->std_col, cv->order );
  4100. #endif
  4101. fprintf(cv->f,
  4102. "%s\n%*sFont and background color combinations (no=normal, bo=bold) for mode %s:\n\n",
  4103. cv->colset->reset, cv->indent, "",
  4104. GetColorModeName(cv->col_mode,0) );
  4105. uint mode = TTM_BG_BLACK;
  4106. ccp *cname;
  4107. for ( cname = col_names; *cname; cname++, mode += 0x10 )
  4108. {
  4109. fprintf(cv->f,"%*s %u %-9s ",
  4110. cv->indent, "",
  4111. (int)(cname - col_names) + 40,
  4112. *cname );
  4113. TermTextMode_t mode2;
  4114. for ( mode2 = TTM_BLACK; mode2 <= TTM_WHITE; mode2++ )
  4115. fprintf(cv->f,"%s no %sbo ",
  4116. GetTextMode(cv->col_mode,mode|mode2|TTM_NO_BOLD),
  4117. GetTextMode(cv->col_mode,TTM_BOLD) );
  4118. fprintf(cv->f," %s\n",cv->colset->reset );
  4119. }
  4120. }
  4121. ///////////////////////////////////////////////////////////////////////////////
  4122. void ViewColors18 ( ColorView_t *cv )
  4123. {
  4124. DASSERT(cv);
  4125. SetupColorView(cv);
  4126. DASSERT(cv->colset);
  4127. #ifdef TEST
  4128. fprintf(cv->f,"%*s%s() %s, %u colors, mode %d, stdcol %d, order %d\n",
  4129. cv->indent,"", __FUNCTION__,
  4130. GetColorModeName(cv->colset->col_mode,0),
  4131. cv->colset->n_colors, cv->mode, cv->std_col, cv->order );
  4132. #endif
  4133. GetColorOption_t col_option = cv->col_option & ~GCM_ALT;
  4134. fprintf(cv->f,
  4135. "%s\n%*s18x18 color table ('0'=std, '1'=optimized%s) for mode %s:\n\n",
  4136. cv->colset->reset, cv->indent, "",
  4137. col_option & GCM_SHORT ? "; allow short codes" : "",
  4138. GetColorModeName(cv->col_mode,0) );
  4139. const int *pbg;
  4140. for ( pbg = Color18Index; *pbg >= 0; pbg++ )
  4141. {
  4142. uint bg = *pbg;
  4143. if ( bg == TCI_RED || bg == TCI_B_RED )
  4144. fputc('\n',cv->f);
  4145. fprintf(cv->f,"%*s %-12s ",
  4146. cv->indent, "", ColorIndexName[bg] );
  4147. const int *pfont;
  4148. for ( pfont = Color18Index; *pfont >= 0; pfont++ )
  4149. {
  4150. uint font = *pfont;
  4151. if ( font == TCI_RED || font == TCI_B_RED )
  4152. fprintf(cv->f," %s ",TERM_TEXT_MODE_RESET);
  4153. fprintf(cv->f,"%s 0%s1",
  4154. GetColorMode(cv->col_mode,font,bg,col_option),
  4155. GetColorMode(cv->col_mode,font,bg,col_option|GCM_ALT) );
  4156. }
  4157. fprintf(cv->f," %s\n",TERM_TEXT_MODE_RESET);
  4158. }
  4159. }
  4160. ///////////////////////////////////////////////////////////////////////////////
  4161. void ViewColorsDC ( ColorView_t *cv, bool optimized )
  4162. {
  4163. DASSERT(cv);
  4164. SetupColorView(cv);
  4165. DASSERT(cv->colset);
  4166. #ifdef TEST
  4167. fprintf(cv->f,"%*s%s() %s, %u colors, mode %d, stdcol %d, order %d\n",
  4168. cv->indent,"", __FUNCTION__,
  4169. GetColorModeName(cv->colset->col_mode,0),
  4170. cv->colset->n_colors, cv->mode, cv->std_col, cv->order );
  4171. #endif
  4172. GetColorOption_t col_option = cv->col_option & ~GCM_ALT;
  4173. if (optimized)
  4174. col_option |= GCM_ALT;
  4175. fprintf(cv->f,
  4176. "%s\n%*s%ux%u color table (%s%s) for mode %s:\n\n",
  4177. cv->colset->reset, cv->indent, "",
  4178. TCI__N, TCI__N,
  4179. optimized ? "optimized" : "standard",
  4180. col_option & GCM_SHORT ? "; allow short codes" : "",
  4181. GetColorModeName(cv->col_mode,0) );
  4182. uint bg;
  4183. for ( bg = 0; bg < TCI__N; bg++ )
  4184. {
  4185. if ( bg == TCI_RED || bg == TCI_B_RED )
  4186. fputc('\n',cv->f);
  4187. fprintf(cv->f,"%*s %-15s ",
  4188. cv->indent, "", ColorIndexName[bg] );
  4189. ccp fill = " ";
  4190. uint font;
  4191. for ( font = 0; font < TCI__N; font++ )
  4192. {
  4193. if ( font == TCI_RED || font == TCI_B_RED )
  4194. {
  4195. fprintf(cv->f," %s ",TERM_TEXT_MODE_RESET);
  4196. fill = " ";
  4197. }
  4198. fprintf(cv->f,"%s%sx",
  4199. GetColorMode(cv->col_mode,font,bg,col_option), fill );
  4200. fill = "";
  4201. }
  4202. fprintf(cv->f," %s\n",TERM_TEXT_MODE_RESET);
  4203. }
  4204. }
  4205. ///////////////////////////////////////////////////////////////////////////////
  4206. static void ViewColors256_helper
  4207. (
  4208. ColorView_t *cv, // basic data
  4209. uint beg, // first color printed
  4210. uint end, // first color not printed
  4211. uint step // increment
  4212. )
  4213. {
  4214. if ( cv->colset->n_colors < 8 )
  4215. {
  4216. uint i;
  4217. for ( i = beg; i < end; i += step )
  4218. fprintf(cv->f," %03u ",i);
  4219. }
  4220. #if 0 // [[2do]]
  4221. else if ( cv->colset->n_colors < 256 )
  4222. {
  4223. }
  4224. #endif
  4225. else
  4226. {
  4227. int mode;
  4228. if ( cv->mode & 1 )
  4229. {
  4230. mode = 48;
  4231. fputs("\e[38;5;0m",cv->f);
  4232. }
  4233. else
  4234. mode = 38;
  4235. for ( uint i = beg; i < end; i += step )
  4236. fprintf(cv->f,"\e[%u;5;%um %03u ",mode,i,i);
  4237. fputs("\e[0m",cv->f);
  4238. }
  4239. }
  4240. //-----------------------------------------------------------------------------
  4241. void ViewColors256 ( ColorView_t *cv )
  4242. {
  4243. DASSERT(cv);
  4244. SetupColorView(cv);
  4245. DASSERT(cv->colset);
  4246. #ifdef TEST
  4247. fprintf(cv->f,"%*s%s() %s, %u colors, mode %d, stdcol %d, order %d\n",
  4248. cv->indent,"", __FUNCTION__,
  4249. GetColorModeName(cv->colset->col_mode,0),
  4250. cv->colset->n_colors, cv->mode, cv->std_col, cv->order );
  4251. #endif
  4252. fprintf(cv->f,
  4253. "%s\n%*s256 colors = 16 std colors + 6x6x6 colors + 24 gray for mode %s:\n",
  4254. cv->colset->reset, cv->indent, "",
  4255. GetColorModeName(cv->col_mode,0) );
  4256. int step, inc_horz, inc_vert;
  4257. switch (cv->order)
  4258. {
  4259. case 1:
  4260. step = 1;
  4261. inc_horz = 6;
  4262. inc_vert = 36;
  4263. break;
  4264. case 2:
  4265. step = 6;
  4266. inc_horz = 1;
  4267. inc_vert = 36;
  4268. break;
  4269. default:
  4270. step = 1;
  4271. inc_horz = 36;
  4272. inc_vert = 6;
  4273. break;
  4274. }
  4275. //--- 16 standard colors in 2 rows
  4276. fprintf(cv->f,"\n%*s ",cv->indent,"");
  4277. ViewColors256_helper(cv,0,8,1);
  4278. fprintf(cv->f,"\n%*s ",cv->indent,"");
  4279. ViewColors256_helper(cv,8,16,1);
  4280. fputs("\e[0m\n\n",cv->f);
  4281. uint bl, num = 16;
  4282. for ( bl = 0; bl < 3; bl++ )
  4283. {
  4284. uint i, n = num;
  4285. for ( i = 0; i < 6; i++ )
  4286. {
  4287. fprintf(cv->f,"%*s ",cv->indent,"");
  4288. ViewColors256_helper(cv,n,n+6*step,step);
  4289. fputs(" ",cv->f);
  4290. ViewColors256_helper(cv,n+inc_horz,n+inc_horz+6*step,step);
  4291. fputc('\n',cv->f);
  4292. n += inc_vert;
  4293. }
  4294. fputc('\n',cv->f);
  4295. num += 2*inc_horz;
  4296. }
  4297. fprintf(cv->f,"%*s ",cv->indent,"");
  4298. ViewColors256_helper(cv,232,232+12,1);
  4299. fprintf(cv->f,"\n%*s ",cv->indent,"");
  4300. ViewColors256_helper(cv,232+12,232+24,1);
  4301. fputs("\e[0m\n",cv->f);
  4302. }
  4303. ///////////////////////////////////////////////////////////////////////////////
  4304. static void ViewColorsPredef_helper
  4305. (
  4306. ColorView_t *cv, // basic data
  4307. const color_helper_tab_t *tab // valid color list
  4308. )
  4309. {
  4310. DASSERT(cv);
  4311. DASSERT(tab);
  4312. const ColorSet_t *col = cv->colset;
  4313. const int indent = cv->indent + 15; // 15 is max name width
  4314. for ( ; tab->name; tab++ )
  4315. {
  4316. if ( !tab->is_alt || cv->print_alt )
  4317. {
  4318. if (tab->offset)
  4319. {
  4320. cv->allow_sep = true;
  4321. ccp val = *(ccp*)((u8*)col+tab->offset);
  4322. if (*val)
  4323. fprintf(cv->f,"%*s %s %-15s %s \\e%s\n",
  4324. indent, tab->name, val, tab->name, col->reset, val+1 );
  4325. else
  4326. fprintf(cv->f,"%*s %s %-15s %s\n",
  4327. indent, tab->name, val, tab->name, col->reset );
  4328. }
  4329. else if (cv->allow_sep)
  4330. {
  4331. cv->allow_sep = false;
  4332. fputc('\n',cv->f);
  4333. }
  4334. }
  4335. }
  4336. }
  4337. //-----------------------------------------------------------------------------
  4338. void ViewColorsPredef ( ColorView_t *cv, ColorSelect_t colsel )
  4339. {
  4340. // [[new-color]]
  4341. DASSERT(cv);
  4342. SetupColorView(cv);
  4343. DASSERT(cv->colset);
  4344. if ( !colsel )
  4345. colsel = COLSEL_M_MODE;
  4346. cv->print_alt = ( colsel & COLSEL_F_ALT ) != 0;
  4347. fprintf(cv->f,
  4348. "%s\n%*sPredefined%s color names for mode %s:\n\n",
  4349. cv->colset->reset, cv->indent, "",
  4350. colsel & COLSEL_NAME ? " semantic" : "",
  4351. GetColorModeName(cv->col_mode,0) );
  4352. if ( (colsel & COLSEL_NAME) == COLSEL_NAME )
  4353. ViewColorsPredef_helper(cv,ch_tab_name);
  4354. else if ( colsel & COLSEL_NAME1 )
  4355. ViewColorsPredef_helper(cv,ch_tab_name1);
  4356. else if ( colsel & COLSEL_NAME2 )
  4357. ViewColorsPredef_helper(cv,ch_tab_name2);
  4358. if ( colsel & COLSEL_COLOR )
  4359. ViewColorsPredef_helper(cv,ch_tab_color);
  4360. if ( colsel & COLSEL_B_COLOR )
  4361. ViewColorsPredef_helper(cv,ch_tab_bcolor);
  4362. if ( colsel & COLSEL_GREY )
  4363. ViewColorsPredef_helper(cv,ch_tab_grey);
  4364. }
  4365. //-----------------------------------------------------------------------------
  4366. void ViewColorsPage ( ColorView_t *cv, uint page )
  4367. {
  4368. const typeof(cv->mode) saved_mode = cv->mode;
  4369. switch(page)
  4370. {
  4371. case 0: ViewColorsAttrib8(cv); ViewColorsCombi8(cv); break;
  4372. case 1: ViewColors18(cv); break;
  4373. case 2: ViewColorsDC(cv,false); break;
  4374. case 3: ViewColorsDC(cv,true); break;
  4375. case 4: cv->mode=0; ViewColors256(cv); break;
  4376. case 5: cv->mode=1; ViewColors256(cv); break;
  4377. case 6: ViewColorsPredef(cv,COLSEL_GREY); break;
  4378. case 7: ViewColorsPredef(cv,COLSEL_M_COLOR); break;
  4379. case 8: ViewColorsPredef(cv,COLSEL_NAME1|COLSEL_F_ALT); break;
  4380. case 9: ViewColorsPredef(cv,COLSEL_NAME2|COLSEL_F_ALT); break;
  4381. }
  4382. cv->mode = saved_mode;
  4383. }
  4384. //
  4385. ///////////////////////////////////////////////////////////////////////////////
  4386. /////////////// old color views (wrapper) ///////////////
  4387. ///////////////////////////////////////////////////////////////////////////////
  4388. void PrintTextModes
  4389. (
  4390. FILE *f, // valid output file
  4391. int indent, // indention of output
  4392. ColorMode_t col_mode // color mode
  4393. )
  4394. {
  4395. ColorView_t cv;
  4396. InitializeColorView(&cv);
  4397. cv.f = f;
  4398. cv.indent = indent;
  4399. cv.col_mode = col_mode;
  4400. ViewColorsAttrib8(&cv);
  4401. ViewColorsCombi8(&cv);
  4402. }
  4403. ///////////////////////////////////////////////////////////////////////////////
  4404. void PrintColorModes
  4405. (
  4406. FILE *f, // valid output file
  4407. int indent, // indention of output
  4408. ColorMode_t col_mode, // color mode -> NormalizeColorMode()
  4409. GetColorOption_t option // execution options (GCM_ALT ignored)
  4410. )
  4411. {
  4412. ColorView_t cv;
  4413. InitializeColorView(&cv);
  4414. cv.f = f;
  4415. cv.indent = indent;
  4416. cv.col_mode = col_mode;
  4417. cv.col_option = option;
  4418. ViewColors18(&cv);
  4419. }
  4420. //
  4421. ///////////////////////////////////////////////////////////////////////////////
  4422. /////////////// stdout, stderr, stdlog and colors ///////////////
  4423. ///////////////////////////////////////////////////////////////////////////////
  4424. FILE *stdlog = 0; // NULL or logfile
  4425. bool close_stdlog = 0; // true: close file behing 'stdlog'
  4426. FILE *stdmsg = 0; // 'stdlog' or 'stdout' or 'stderr' or NULL
  4427. FILE *stdwrn = 0; // used by PrintError(), initialized with 'stderr'
  4428. ColorMode_t colorize_stdout = COLMD_AUTO;
  4429. ColorMode_t colorize_stderr = COLMD_AUTO;
  4430. ColorMode_t colorize_stdlog = COLMD_AUTO;
  4431. ColorMode_t colorize_stdmsg = COLMD_AUTO;
  4432. ColorMode_t colorize_stdwrn = COLMD_AUTO;
  4433. const ColorSet_t *colout = 0; // color set for 'stdout'
  4434. const ColorSet_t *colerr = 0; // color set for 'stderr'
  4435. const ColorSet_t *collog = 0; // color set for 'stdlog'
  4436. const ColorSet_t *colmsg = 0; // color set for 'stdmsg'
  4437. const ColorSet_t *colwrn = 0; // color set for 'stdwrn'
  4438. ///////////////////////////////////////////////////////////////////////////////
  4439. ColorMode_t GetFileColorized ( FILE *f )
  4440. {
  4441. if (!stdmsg)
  4442. SetupStdMsg();
  4443. return !f ? COLMD_OFF
  4444. : f == stdlog && colorize_stdlog != COLMD_AUTO ? colorize_stdlog
  4445. : f == stdout && colorize_stdout != COLMD_AUTO ? colorize_stdout
  4446. : f == stderr && colorize_stderr != COLMD_AUTO ? colorize_stderr
  4447. : f == stdmsg && colorize_stdmsg != COLMD_AUTO ? colorize_stdmsg
  4448. : f == stdwrn && colorize_stdwrn != COLMD_AUTO ? colorize_stdwrn
  4449. : opt_colorize >= COLMD_ON ? opt_colorize
  4450. : opt_colorize == COLMD_AUTO && isatty(fileno(f))
  4451. ? COLMD_AUTO
  4452. : COLMD_OFF;
  4453. }
  4454. ///////////////////////////////////////////////////////////////////////////////
  4455. void SetupStdMsg()
  4456. {
  4457. //--- setup
  4458. static bool active = false; // avoid loops
  4459. if (!active)
  4460. {
  4461. active = true;
  4462. stdwrn = stderr;
  4463. colwrn = colerr;
  4464. colorize_stdwrn = colorize_stderr;
  4465. if (!colout)
  4466. {
  4467. colorize_stdout = GetFileColorized(stdout);
  4468. colout = GetColorSet(colorize_stdout);
  4469. }
  4470. if (!colerr)
  4471. {
  4472. colorize_stderr = GetFileColorized(stderr);
  4473. colerr = GetColorSet(colorize_stderr);
  4474. }
  4475. if (!collog)
  4476. {
  4477. colorize_stdlog = GetFileColorized(stdlog);
  4478. collog = GetColorSet(colorize_stdlog);
  4479. }
  4480. active = false;
  4481. }
  4482. //--- assign to msg
  4483. if (stdlog)
  4484. {
  4485. stdmsg = stdlog;
  4486. colmsg = collog;
  4487. colorize_stdmsg = colorize_stdlog;
  4488. }
  4489. else if (stdout)
  4490. {
  4491. stdmsg = stdout;
  4492. colmsg = colout;
  4493. colorize_stdmsg = colorize_stdout;
  4494. }
  4495. else if (stderr)
  4496. {
  4497. stdmsg = stderr;
  4498. colmsg = colerr;
  4499. colorize_stdmsg = colorize_stderr;
  4500. }
  4501. else
  4502. {
  4503. stdmsg = 0;
  4504. colmsg = GetColorSet0();
  4505. colorize_stdmsg = 0;
  4506. }
  4507. noPRINT("SetupStdMsg() : out=%d[%zd], err=%d[%zd], log=%d[%zd], msg=%d[%zd]\n",
  4508. colorize_stdout, colout ? strlen(colout->reset) : -1,
  4509. colorize_stderr, colerr ? strlen(colerr->reset) : -1,
  4510. colorize_stdlog, collog ? strlen(collog->reset) : -1,
  4511. colorize_stdmsg, colmsg ? strlen(colmsg->reset) : -1 );
  4512. }
  4513. ///////////////////////////////////////////////////////////////////////////////
  4514. enumError OpenStdLog
  4515. (
  4516. ccp fname, // If NULL or empty: don't open and use 'fallback'
  4517. // If first char == '+': open file in append mode
  4518. FILE *fallback // Fall back to this file, if no file name given
  4519. // If NULL: just clode 'stdlog'.
  4520. )
  4521. {
  4522. CloseStdLog();
  4523. bool append = fname && *fname == '+';
  4524. if (append)
  4525. fname++;
  4526. if ( !fname || !*fname )
  4527. {
  4528. if (fallback)
  4529. {
  4530. stdlog = fallback;
  4531. colorize_stdlog = GetFileColorized(stdlog);
  4532. PRINT("COLORIZE/LOG/FALLBACK: opt=%d, out=%d, err=%d, log=%d\n",
  4533. opt_colorize, colorize_stdout, colorize_stderr, colorize_stdlog );
  4534. }
  4535. }
  4536. else
  4537. {
  4538. if (!strcmp(fname,"-"))
  4539. {
  4540. stdlog = stdout;
  4541. colorize_stdlog = colorize_stdout;
  4542. }
  4543. else
  4544. {
  4545. stdlog = fopen( fname, append ? "ab" : "wb" );
  4546. if (!stdlog)
  4547. return ERROR1(ERR_CANT_CREATE,
  4548. "Can't open log file (mode=%s): %s\n",
  4549. append ? "append" : "create", fname );
  4550. close_stdlog = true;
  4551. colorize_stdlog = GetFileColorized(stdlog);
  4552. }
  4553. PRINT("COLORIZE/LOG: opt=%d, out=%d, err=%d, log=%d\n",
  4554. opt_colorize, colorize_stdout, colorize_stderr, colorize_stdlog );
  4555. }
  4556. collog = GetColorSet(colorize_stdlog);
  4557. SetupStdMsg();
  4558. return ERR_OK;
  4559. }
  4560. ///////////////////////////////////////////////////////////////////////////////
  4561. void CloseStdLog()
  4562. {
  4563. if (stdlog)
  4564. {
  4565. if (close_stdlog)
  4566. fclose(stdlog);
  4567. else
  4568. fflush(stdlog);
  4569. stdlog = 0;
  4570. }
  4571. close_stdlog = false;
  4572. colorize_stdlog = 0;
  4573. collog = GetColorSet0();
  4574. SetupStdMsg();
  4575. }
  4576. ///////////////////////////////////////////////////////////////////////////////
  4577. ///////////////////////////////////////////////////////////////////////////////
  4578. void SaveStdFiles ( SavedStdFiles_t *ssf )
  4579. {
  4580. DASSERT(ssf);
  4581. ssf->std_out = stdout;
  4582. ssf->std_err = stderr;
  4583. ssf->std_log = stdlog;
  4584. ssf->std_msg = stdmsg;
  4585. ssf->std_wrn = stdwrn;
  4586. ssf->col_out = colout;
  4587. ssf->col_err = colerr;
  4588. ssf->col_log = collog;
  4589. ssf->col_msg = colmsg;
  4590. ssf->col_wrn = colwrn;
  4591. ssf->stdout_seq_count = stdout_seq_count;
  4592. ssf->f = 0;
  4593. ssf->data = 0;
  4594. ssf->size = 0;
  4595. ssf->marker = 0;
  4596. }
  4597. ///////////////////////////////////////////////////////////////////////////////
  4598. void RestoreStdFiles ( SavedStdFiles_t *ssf )
  4599. {
  4600. DASSERT(ssf);
  4601. stdout = ssf->std_out;
  4602. stderr = ssf->std_err;
  4603. stdlog = ssf->std_log;
  4604. stdmsg = ssf->std_msg;
  4605. stdwrn = ssf->std_wrn;
  4606. colout = ssf->col_out;
  4607. colerr = ssf->col_err;
  4608. collog = ssf->col_log;
  4609. colmsg = ssf->col_msg;
  4610. colwrn = ssf->col_wrn;
  4611. stdout_seq_count = ssf->stdout_seq_count;
  4612. }
  4613. ///////////////////////////////////////////////////////////////////////////////
  4614. void RedirectStdFiles
  4615. (
  4616. SavedStdFiles_t *ssf, // not NULL: save old output here
  4617. FILE *f, // use this as out,err,log and msg, never NULL
  4618. const ColorSet_t *colset,// new colset; if NULL: use GetFileColorSet(f)
  4619. bool err_too // true: redirect stderr too
  4620. )
  4621. {
  4622. DASSERT(f);
  4623. if (ssf)
  4624. SaveStdFiles(ssf);
  4625. stdout = stdwrn = stdmsg = f;
  4626. colout = colwrn = colmsg = colset ? colset : GetFileColorSet(f);
  4627. // special handling for stdlog
  4628. if (stdlog)
  4629. {
  4630. stdlog = stdout;
  4631. collog = colout;
  4632. }
  4633. if (err_too)
  4634. {
  4635. stderr = stdout;
  4636. colerr = colout;
  4637. }
  4638. }
  4639. ///////////////////////////////////////////////////////////////////////////////
  4640. #ifndef __APPLE__
  4641. enumError CatchStdFiles
  4642. (
  4643. SavedStdFiles_t *ssf, // save old output and data here, never NULL
  4644. const ColorSet_t *colset // new colset; if NULL: no color support
  4645. )
  4646. {
  4647. DASSERT(ssf);
  4648. SaveStdFiles(ssf);
  4649. FILE *f = open_memstream(&ssf->data,&ssf->size);
  4650. if (!f)
  4651. return ERR_CANT_CREATE;
  4652. ssf->f = f;
  4653. RedirectStdFiles(0,f,colset,false);
  4654. return ERR_OK;
  4655. }
  4656. #endif // !__APPLE__
  4657. ///////////////////////////////////////////////////////////////////////////////
  4658. void TermCatchStdFiles ( SavedStdFiles_t *ssf )
  4659. {
  4660. DASSERT(ssf);
  4661. RestoreStdFiles(ssf);
  4662. if (ssf->f)
  4663. {
  4664. fclose(ssf->f);
  4665. ssf->f = 0;
  4666. }
  4667. }
  4668. //
  4669. ///////////////////////////////////////////////////////////////////////////////
  4670. /////////////// END ///////////////
  4671. ///////////////////////////////////////////////////////////////////////////////