Editor.c 229 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* $TOG: Editor.c /main/24 1999/10/14 16:38:25 mgreess $
  24. **********************************<+>*************************************
  25. ***************************************************************************
  26. **
  27. ** File: Editor.c
  28. **
  29. ** Project: Text Editor widget
  30. **
  31. ** Description:
  32. ** -----------
  33. ** This is the main source file for the Text Editor widget.
  34. **
  35. *******************************************************************
  36. * (c) Copyright 1996 Digital Equipment Corporation.
  37. * (c) Copyright 1993, 1994, 1996 Hewlett-Packard Company.
  38. * (c) Copyright 1993, 1994, 1996 International Business Machines Corp.
  39. * (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc.
  40. * (c) Copyright 1996 Novell, Inc.
  41. * (c) Copyright 1996 FUJITSU LIMITED.
  42. * (c) Copyright 1996 Hitachi.
  43. * (c) Copyright 1993, 1994 Unix System Labs, Inc., a subsidiary of Novell, Inc.
  44. ********************************************************************
  45. **
  46. **************************************************************************
  47. **********************************<+>*************************************/
  48. /*-------------------------------------------------------------
  49. ** Include Files
  50. */
  51. #ifndef _XOPEN_SOURCE
  52. #define _XOPEN_SOURCE 600
  53. #endif
  54. #include <ctype.h>
  55. #include <stdlib.h>
  56. #if defined(sun)
  57. # if (_XOPEN_VERSION==3)
  58. # include <wctype.h>
  59. # else
  60. # include <wchar.h>
  61. # endif
  62. # include <libintl.h>
  63. #elif defined(__linux__) || defined(CSRG_BASED)
  64. # include <wctype.h>
  65. # include <wchar.h>
  66. #endif /* linux || CSRG_BASED */
  67. #include <sys/wait.h>
  68. #include "signal.h"
  69. #include <string.h>
  70. #include <limits.h> /* For LINE_MAX definition */
  71. #include <sys/errno.h> /* For Error handling */
  72. #include "EditorP.h"
  73. #include <Dt/Dnd.h>
  74. #include "X11/Xutil.h"
  75. #include <X11/StringDefs.h>
  76. #include <X11/keysymdef.h>
  77. #include <Xm/Form.h>
  78. #include <Xm/MessageB.h>
  79. #include <Xm/MwmUtil.h>
  80. #include <Xm/TextF.h>
  81. #include <Xm/LabelG.h>
  82. #include <Xm/SeparatoG.h>
  83. #include <Xm/PushBG.h>
  84. #include <Xm/ToggleBG.h>
  85. #include <Xm/RowColumn.h>
  86. /* Need the following for _DtOkString */
  87. #include <Dt/DtP.h>
  88. #include <Dt/DtMsgsP.h>
  89. #include <Dt/HourGlass.h>
  90. #include "DtWidgetI.h"
  91. /*
  92. * Private functions borrowed from Motif.
  93. */
  94. extern XmTextLineTable _XmTextGetLineTable(Widget widget, int *total_lines);
  95. extern char * _XmStringSourceGetString(XmTextWidget tw,
  96. XmTextPosition from,
  97. XmTextPosition to,
  98. #if NeedWidePrototypes
  99. int want_wchar);
  100. #else
  101. Boolean want_wchar);
  102. #endif /* NeedWidePrototypes */
  103. /*-------------------------------------------------------------
  104. ** Public Interface
  105. **-------------------------------------------------------------
  106. */
  107. /******** Public Function Declarations ********/
  108. /******** End Public Function Declarations ********/
  109. /*-------------------------------------------------------------
  110. ** Forward Declarations
  111. **-------------------------------------------------------------
  112. */
  113. /******** Static Function Declarations ********/
  114. static void ClassInitialize(void);
  115. static void Initialize(
  116. Widget rw,
  117. Widget nw,
  118. ArgList al,
  119. Cardinal *num_args) ;
  120. static void VariableInitialize(
  121. DtEditorWidget new);
  122. static void ValidateResources(
  123. DtEditorWidget new,
  124. DtEditorWidget request);
  125. static Widget CreateText(
  126. DtEditorWidget parent);
  127. static void extractFontMetrics(
  128. DtEditorWidget w,
  129. XmFontList fontlist,
  130. int *height,
  131. int *width);
  132. static void getFontMetrics(
  133. DtEditorWidget w);
  134. static void Destroy(
  135. Widget widget);
  136. static void SetStatusLine(
  137. DtEditorWidget ew,
  138. Boolean statusLineOn);
  139. static Widget CreateStatusLine(
  140. DtEditorWidget parent);
  141. static Boolean SetValues(
  142. Widget cw,
  143. Widget rw,
  144. Widget nw);
  145. static void _DtEditorGetCenterToggleLabel(
  146. Widget wid,
  147. int resource_offset,
  148. XtArgVal *value );
  149. static void _DtEditorGetChangeAllButtonLabel(
  150. Widget wid,
  151. int resource_offset,
  152. XtArgVal *value );
  153. static void _DtEditorGetChangeButtonLabel(
  154. Widget wid,
  155. int resource_offset,
  156. XtArgVal *value );
  157. static void _DtEditorGetChangeFieldLabel(
  158. Widget wid,
  159. int resource_offset,
  160. XtArgVal *value );
  161. static void _DtEditorGetColumns(
  162. Widget wid,
  163. int resource_offset,
  164. XtArgVal *value );
  165. static void _DtEditorGetCurrentLineLabel(
  166. Widget wid,
  167. int resource_offset,
  168. XtArgVal *value );
  169. static void _DtEditorGetCursorPosition(
  170. Widget wid,
  171. int resource_offset,
  172. XtArgVal *value );
  173. static void _DtEditorGetFindButtonLabel(
  174. Widget wid,
  175. int resource_offset,
  176. XtArgVal *value );
  177. static void _DtEditorGetFindFieldLabel(
  178. Widget wid,
  179. int resource_offset,
  180. XtArgVal *value );
  181. static void _DtEditorGetFormatAllButtonLabel(
  182. Widget wid,
  183. int resource_offset,
  184. XtArgVal *value );
  185. static void _DtEditorGetFormatParagraphButtonLabel(
  186. Widget wid,
  187. int resource_offset,
  188. XtArgVal *value );
  189. static void _DtEditorGetJustifyToggleLabel(
  190. Widget wid,
  191. int resource_offset,
  192. XtArgVal *value );
  193. static void _DtEditorGetLeftAlignToggleLabel(
  194. Widget wid,
  195. int resource_offset,
  196. XtArgVal *value );
  197. static void _DtEditorGetLeftMarginFieldLabel(
  198. Widget wid,
  199. int resource_offset,
  200. XtArgVal *value );
  201. static void _DtEditorGetMaxLength(
  202. Widget wid,
  203. int resource_offset,
  204. XtArgVal *value );
  205. static void _DtEditorGetMisspelledListLabel(
  206. Widget wid,
  207. int resource_offset,
  208. XtArgVal *value );
  209. static void _DtEditorGetRightAlignToggleLabel(
  210. Widget wid,
  211. int resource_offset,
  212. XtArgVal *value );
  213. static void _DtEditorGetRightMarginFieldLabel(
  214. Widget wid,
  215. int resource_offset,
  216. XtArgVal *value );
  217. static void _DtEditorGetRows(
  218. Widget wid,
  219. int resource_offset,
  220. XtArgVal *value );
  221. static void _DtEditorGetScrollLeftSide(
  222. Widget wid,
  223. int resource_offset,
  224. XtArgVal *value );
  225. static void _DtEditorGetScrollTopSide(
  226. Widget wid,
  227. int resource_offset,
  228. XtArgVal *value );
  229. static void _DtEditorGetTextBackground(
  230. Widget wid,
  231. int resource_offset,
  232. XtArgVal *value );
  233. static void _DtEditorGetTextForeground(
  234. Widget wid,
  235. int resource_offset,
  236. XtArgVal *value );
  237. static void _DtEditorGetTopCharacter(
  238. Widget wid,
  239. int resource_offset,
  240. XtArgVal *value );
  241. static void _DtEditorGetLineCountLabel(
  242. Widget wid,
  243. int resource_offset,
  244. XtArgVal *value );
  245. static void FixWordWrap( /* XXX Word Wrap workaround */
  246. Widget w, /* XXX Word Wrap workaround */
  247. Boolean wrapOn); /* XXX Word Wrap workaround */
  248. static void BackwardChar(
  249. Widget w,
  250. XEvent *event,
  251. char **params,
  252. Cardinal *num_params);
  253. static void BackwardPara(
  254. Widget w,
  255. XEvent *event,
  256. char **params,
  257. Cardinal *num_params);
  258. static void BackwardWord(
  259. Widget w,
  260. XEvent *event,
  261. char **params,
  262. Cardinal *num_params);
  263. static void BeginningOfFile(
  264. Widget w,
  265. XEvent *event,
  266. char **params,
  267. Cardinal *num_params);
  268. static void BeginningOfLine(
  269. Widget w,
  270. XEvent *event,
  271. char **params,
  272. Cardinal *num_params);
  273. static void ClearSelection(
  274. Widget w,
  275. XEvent *event,
  276. char **params,
  277. Cardinal *num_params);
  278. static void CopyClipboard(
  279. Widget w,
  280. XEvent *event,
  281. char **params,
  282. Cardinal *num_params);
  283. static void CutClipboard(
  284. Widget w,
  285. XEvent *event,
  286. char **params,
  287. Cardinal *num_params);
  288. static void DeleteNextChar(
  289. Widget w,
  290. XEvent *event,
  291. char **params,
  292. Cardinal *num_params);
  293. static void DeleteNextWord(
  294. Widget w,
  295. XEvent *event,
  296. char **params,
  297. Cardinal *num_params);
  298. static void DeletePrevChar(
  299. Widget w,
  300. XEvent *event,
  301. char **params,
  302. Cardinal *num_params);
  303. static void DeletePrevWord(
  304. Widget w,
  305. XEvent *event,
  306. char **params,
  307. Cardinal *num_params);
  308. static void DeleteToEOL(
  309. Widget w,
  310. XEvent *event,
  311. char **params,
  312. Cardinal *num_params);
  313. static void DeleteToSOL(
  314. Widget w,
  315. XEvent *event,
  316. char **params,
  317. Cardinal *num_params);
  318. static void DeselectAll(
  319. Widget w,
  320. XEvent *event,
  321. char **params,
  322. Cardinal *num_params);
  323. static void EndOfFile(
  324. Widget w,
  325. XEvent *event,
  326. char **params,
  327. Cardinal *num_params);
  328. static void EndOfLine(
  329. Widget w,
  330. XEvent *event,
  331. char **params,
  332. Cardinal *num_params);
  333. static void ForwardChar(
  334. Widget w,
  335. XEvent *event,
  336. char **params,
  337. Cardinal *num_params);
  338. static void ForwardPara(
  339. Widget w,
  340. XEvent *event,
  341. char **params,
  342. Cardinal *num_params);
  343. static void ForwardWord(
  344. Widget w,
  345. XEvent *event,
  346. char **params,
  347. Cardinal *num_params);
  348. static void GoToLine(
  349. Widget w,
  350. XEvent *event,
  351. char **params,
  352. Cardinal *num_params);
  353. static void GoToLine_I(
  354. Widget w,
  355. XEvent *event,
  356. char **params,
  357. Cardinal *num_params);
  358. static void Help(
  359. Widget w,
  360. XEvent *event,
  361. char **params,
  362. Cardinal *num_params);
  363. static void InsertString(
  364. Widget w,
  365. XEvent *event,
  366. char **params,
  367. Cardinal *num_params);
  368. static void KeySelect(
  369. Widget w,
  370. XEvent *event,
  371. char **params,
  372. Cardinal *num_params);
  373. static void NewlineAndBackup(
  374. Widget w,
  375. XEvent *event,
  376. char **params,
  377. Cardinal *num_params);
  378. static void NewlineAndIndent(
  379. Widget w,
  380. XEvent *event,
  381. char **params,
  382. Cardinal *num_params);
  383. static void NextPage(
  384. Widget w,
  385. XEvent *event,
  386. char **params,
  387. Cardinal *num_params);
  388. static void PageLeft(
  389. Widget w,
  390. XEvent *event,
  391. char **params,
  392. Cardinal *num_params);
  393. static void PageRight(
  394. Widget w,
  395. XEvent *event,
  396. char **params,
  397. Cardinal *num_params);
  398. static void PasteClipboard(
  399. Widget w,
  400. XEvent *event,
  401. char **params,
  402. Cardinal *num_params);
  403. static void PreviousPage(
  404. Widget w,
  405. XEvent *event,
  406. char **params,
  407. Cardinal *num_params);
  408. static void ProcessCancel(
  409. Widget w,
  410. XEvent *event,
  411. char **params,
  412. Cardinal *num_params);
  413. static void ProcessDown(
  414. Widget w,
  415. XEvent *event,
  416. char **params,
  417. Cardinal *num_params);
  418. static void ProcessShiftDown(
  419. Widget w,
  420. XEvent *event,
  421. char **params,
  422. Cardinal *num_params);
  423. static void ProcessShiftUp(
  424. Widget w,
  425. XEvent *event,
  426. char **params,
  427. Cardinal *num_params);
  428. static void ProcessUp(
  429. Widget w,
  430. XEvent *event,
  431. char **params,
  432. Cardinal *num_params);
  433. static void QuoteNextChar(
  434. Widget w,
  435. XEvent *event,
  436. char **params,
  437. Cardinal *num_params);
  438. static void QuoteNextChar_I(
  439. Widget w,
  440. XEvent *event,
  441. char **params,
  442. Cardinal *num_params);
  443. static void SelectAll(
  444. Widget w,
  445. XEvent *event,
  446. char **params,
  447. Cardinal *num_params);
  448. static void ToggleInsertMode(
  449. Widget w,
  450. XEvent *event,
  451. char **params,
  452. Cardinal *num_params);
  453. static void ToggleInsertMode_I(
  454. Widget w,
  455. XEvent *event,
  456. char **params,
  457. Cardinal *num_params);
  458. static void UndoEdit(
  459. Widget w,
  460. XEvent *event,
  461. char **params,
  462. Cardinal *num_params);
  463. static void UndoEdit_I(
  464. Widget w,
  465. XEvent *event,
  466. char **params,
  467. Cardinal *num_params);
  468. static void Call_TextSelectCallback(
  469. DtEditorWidget editor);
  470. static void Call_TextDeselectCallback(
  471. DtEditorWidget editor);
  472. static void Editor_SetSelectionProc(
  473. XmTextSource source,
  474. XmTextPosition left,
  475. XmTextPosition right,
  476. Time set_time );
  477. static void CallHelpCallback(
  478. DtEditorWidget editor,
  479. int reason);
  480. static void HelpEditWindowCB(
  481. Widget w,
  482. caddr_t client_data,
  483. caddr_t call_data );
  484. static void HelpStatusCurrentLineCB(
  485. Widget w,
  486. caddr_t client_data,
  487. caddr_t call_data );
  488. static void HelpStatusTotalLinesCB(
  489. Widget w,
  490. caddr_t client_data,
  491. caddr_t call_data );
  492. static void HelpStatusMessageCB(
  493. Widget w,
  494. caddr_t client_data,
  495. caddr_t call_data );
  496. static void HelpStatusOverstrikeCB(
  497. Widget w,
  498. caddr_t client_data,
  499. caddr_t call_data );
  500. static void RegisterDropZone(
  501. DtEditorWidget w );
  502. static void UnregisterDropZone(
  503. DtEditorWidget w );
  504. static void SetInfoDialogTitle(
  505. DtEditorWidget editor );
  506. static int FormatText (
  507. AdjRecPtr pAdjRec );
  508. static void AdjustParaCB(
  509. Widget w,
  510. caddr_t client_data,
  511. caddr_t call_data );
  512. static void AdjustAllCB(
  513. Widget w,
  514. caddr_t client_data,
  515. caddr_t call_data );
  516. static DtEditorErrorCode DoAdjust(
  517. DtEditorWidget editor,
  518. int leftMargin,
  519. int rightMargin,
  520. unsigned int alignment,
  521. XmTextPosition start,
  522. XmTextPosition end);
  523. static void SetFormatDialogTitle(
  524. DtEditorWidget editor);
  525. static void ResetFormatDialog(
  526. DtEditorWidget editor);
  527. static void CreateFormatDialog(
  528. DtEditorWidget editor);
  529. static void GetAdjustSettings(
  530. DtEditorWidget pPad,
  531. DtEditorFormatSettings *formatSettings);
  532. static void UpdateOverstrikeIndicator(
  533. DtEditorWidget widget,
  534. Boolean overstrikeOn );
  535. /******** End Static Function Declarations ********/
  536. /****************************************************************
  537. *
  538. * Compatability routines
  539. *
  540. ****************************************************************/
  541. #if defined(NO_putwc)
  542. static wint_t putwc(wint_t wc, FILE *stream)
  543. {
  544. int rc = putc((int) wc, stream);
  545. return (wint_t) rc;
  546. }
  547. static wint_t getwc(FILE *stream)
  548. {
  549. int rc = getc(stream);
  550. return (wint_t) rc;
  551. }
  552. #endif /* NO_putwc */
  553. /****************************************************************
  554. *
  555. * Translations and Actions
  556. *
  557. ****************************************************************/
  558. /*
  559. * The following are the translations which DtEditor places (overrides)
  560. * on the scrolled text widget. If the DtNtextTranslations resource is
  561. * set, it will also be added (in override mode) to the text widget.
  562. */
  563. static char EditorTranslationTable[] = "\
  564. ~s ~c ~m ~a <Key>Return: newline-and-indent()\n\
  565. ~s m<Key>osfBackSpace: I-undo-edit()\n\
  566. ~s c<Key>osfBackSpace: delete-previous-word()\n\
  567. s<Key>osfBackSpace: delete-to-start-of-line()\n\
  568. ~s ~c <Key>osfInsert: I-toggle-insert-mode()\n\
  569. <Key>osfUndo: I-undo-edit()\n\
  570. c<Key>g: I-go-to-line()\n\
  571. c<Key>q: I-quote-next-character()\n\
  572. c<Key>z: I-undo-edit()";
  573. /*
  574. * The following are DtEditor's actions. A few are internal only (_I
  575. * suffix) and will be called by the default translations DtEditor places
  576. * on the text widget (see previous comment). The rest will only be called
  577. * from an application with XtCallActionProc(). The main difference is
  578. * the internal ones will be passed a text widget ID, while the public
  579. * ones will be passed a DtEditor ID.
  580. */
  581. static XtActionsRec EditorActionTable[] = {
  582. {"I-go-to-line", (XtActionProc)GoToLine_I},
  583. {"I-toggle-insert-mode", (XtActionProc)ToggleInsertMode_I},
  584. {"I-undo-edit", (XtActionProc)UndoEdit_I},
  585. {"I-quote-next-character", (XtActionProc)QuoteNextChar_I},
  586. {"backward-character", (XtActionProc)BackwardChar},
  587. {"backward-paragraph", (XtActionProc)BackwardPara},
  588. {"backward-word", (XtActionProc)BackwardWord},
  589. {"beginning-of-file", (XtActionProc)BeginningOfFile},
  590. {"beginning-of-line", (XtActionProc)BeginningOfLine},
  591. {"clear-selection", (XtActionProc)ClearSelection},
  592. {"copy-clipboard", (XtActionProc)CopyClipboard},
  593. {"cut-clipboard", (XtActionProc)CutClipboard},
  594. {"delete-next-character", (XtActionProc)DeleteNextChar},
  595. {"delete-next-word", (XtActionProc)DeleteNextWord},
  596. {"delete-previous-character", (XtActionProc)DeletePrevChar},
  597. {"delete-previous-word", (XtActionProc)DeletePrevWord},
  598. {"delete-to-end-of-line", (XtActionProc)DeleteToEOL},
  599. {"delete-to-start-of-line", (XtActionProc)DeleteToSOL},
  600. {"deselect-all", (XtActionProc)DeselectAll},
  601. {"end-of-file", (XtActionProc)EndOfFile},
  602. {"end-of-line", (XtActionProc)EndOfLine},
  603. {"forward-character", (XtActionProc)ForwardChar},
  604. {"forward-paragraph", (XtActionProc)ForwardPara},
  605. {"forward-word", (XtActionProc)ForwardWord},
  606. {"go-to-line", (XtActionProc)GoToLine},
  607. {"Help", (XtActionProc)Help},
  608. {"insert-string", (XtActionProc)InsertString},
  609. {"key-select", (XtActionProc)KeySelect},
  610. {"newline-and-backup", (XtActionProc)NewlineAndBackup},
  611. {"newline-and-indent", (XtActionProc)NewlineAndIndent},
  612. {"next-page", (XtActionProc)NextPage},
  613. {"page-left", (XtActionProc)PageLeft},
  614. {"page-right", (XtActionProc)PageRight},
  615. {"paste-clipboard", (XtActionProc)PasteClipboard},
  616. {"previous-page", (XtActionProc)PreviousPage},
  617. {"process-cancel", (XtActionProc)ProcessCancel},
  618. {"process-down", (XtActionProc)ProcessDown},
  619. {"process-shift-down", (XtActionProc)ProcessShiftDown},
  620. {"process-shift-up", (XtActionProc)ProcessShiftUp},
  621. {"process-up", (XtActionProc)ProcessUp},
  622. {"quote-next-character", (XtActionProc)QuoteNextChar},
  623. {"select-all", (XtActionProc)SelectAll},
  624. {"toggle-insert-mode", (XtActionProc)ToggleInsertMode},
  625. {"undo-edit", (XtActionProc)UndoEdit},
  626. };
  627. /****************************************************************
  628. *
  629. * Defines
  630. *
  631. ****************************************************************/
  632. #define NL_SETN 1
  633. #ifdef _AIX
  634. #define iswctype(a,b) is_wctype(a,b)
  635. #define wctype(a) get_wctype(a)
  636. #endif /* _AIX */
  637. #if !(defined(sun) && (_XOPEN_VERSION==3))
  638. #if !(defined(__FreeBSD__))
  639. # define iswblank(wc) iswctype((wc),blnkclass)
  640. # undef getwc /* Use the libc function */
  641. #endif
  642. #if defined(_AIX) /* _AIX */
  643. /* IBM defines wctype to get_wctype above - don't use const. */
  644. static char *blankString = "space";
  645. #else /* _AIX */
  646. static const char *blankString = "space";
  647. #endif /* _AIX */
  648. static wctype_t _DtEditor_blankClass;
  649. #else
  650. # define wctype_t int
  651. # define iswblank(a) iswspace(a)
  652. # define iswctype(a,b) _iswctype(a,b)
  653. # define wcwidth(a) sun_wcwidth(a)
  654. #endif /* not sun */
  655. #define MAXTABSIZE 100 /* max legal tabsize */
  656. /****************************************************************
  657. *
  658. * Define misc data structures
  659. *
  660. ****************************************************************/
  661. static wctype_t ekinclass = 0; /* Prop value for "ekinsoku" class */
  662. static wctype_t bekinclass = 0; /* Prop value for "bekinsoku" class */
  663. static wctype_t blnkclass = 0; /* Prop value for "Blank" Class */
  664. /****************************************************************
  665. *
  666. * Resource List
  667. *
  668. ****************************************************************/
  669. static XmSyntheticResource syn_resources[] =
  670. {
  671. {
  672. DtNcolumns, sizeof(short),
  673. XtOffset (DtEditorWidget, editor.editStuff.columns),
  674. _DtEditorGetColumns, NULL
  675. },
  676. {
  677. DtNcenterToggleLabel, sizeof (XmString),
  678. XtOffset (DtEditorWidget, editor.formatStuff.centerToggleLabel),
  679. _DtEditorGetCenterToggleLabel, NULL
  680. },
  681. {
  682. DtNchangeAllButtonLabel, sizeof (XmString),
  683. XtOffset (DtEditorWidget,
  684. editor.searchStuff.changeAllButtonLabel),
  685. _DtEditorGetChangeAllButtonLabel, NULL
  686. },
  687. {
  688. DtNchangeButtonLabel, sizeof (XmString),
  689. XtOffset(DtEditorWidget, editor.searchStuff.changeButtonLabel),
  690. _DtEditorGetChangeButtonLabel, NULL
  691. },
  692. {
  693. DtNchangeFieldLabel, sizeof (XmString),
  694. XtOffset(DtEditorWidget, editor.searchStuff.changeFieldLabel),
  695. _DtEditorGetChangeFieldLabel, NULL
  696. },
  697. {
  698. DtNcurrentLineLabel, sizeof (XmString),
  699. XtOffset(DtEditorWidget, editor.statusStuff.currentLineLabel),
  700. _DtEditorGetCurrentLineLabel, NULL
  701. },
  702. {
  703. DtNcursorPosition, sizeof (XmTextPosition),
  704. XtOffset(DtEditorWidget, editor.editStuff.cursorPos),
  705. _DtEditorGetCursorPosition, NULL
  706. },
  707. {
  708. DtNfindButtonLabel, sizeof (XmString),
  709. XtOffset(DtEditorWidget, editor.searchStuff.findButtonLabel),
  710. _DtEditorGetFindButtonLabel, NULL
  711. },
  712. {
  713. DtNfindFieldLabel, sizeof (XmString),
  714. XtOffset(DtEditorWidget, editor.searchStuff.findFieldLabel),
  715. _DtEditorGetFindFieldLabel, NULL
  716. },
  717. {
  718. DtNformatAllButtonLabel, sizeof (XmString),
  719. XtOffset(DtEditorWidget,
  720. editor.formatStuff.formatAllButtonLabel),
  721. _DtEditorGetFormatAllButtonLabel, NULL
  722. },
  723. {
  724. DtNformatParagraphButtonLabel, sizeof (XmString),
  725. XtOffset(DtEditorWidget,
  726. editor.formatStuff.formatParaButtonLabel),
  727. _DtEditorGetFormatParagraphButtonLabel, NULL
  728. },
  729. {
  730. DtNjustifyToggleLabel, sizeof (XmString),
  731. XtOffset (DtEditorWidget,
  732. editor.formatStuff.justifyToggleLabel),
  733. _DtEditorGetJustifyToggleLabel, NULL
  734. },
  735. {
  736. DtNleftAlignToggleLabel, sizeof (XmString),
  737. XtOffset (DtEditorWidget,
  738. editor.formatStuff.leftAlignToggleLabel),
  739. _DtEditorGetLeftAlignToggleLabel, NULL
  740. },
  741. {
  742. DtNleftMarginFieldLabel, sizeof (XmString),
  743. XtOffset (DtEditorWidget,
  744. editor.formatStuff.leftMarginFieldLabel),
  745. _DtEditorGetLeftMarginFieldLabel, NULL
  746. },
  747. {
  748. DtNmaxLength, sizeof(int),
  749. XtOffset(DtEditorWidget, editor.editStuff.maxLength),
  750. _DtEditorGetMaxLength, NULL
  751. },
  752. {
  753. DtNmisspelledListLabel, sizeof (XmString),
  754. XtOffset (DtEditorWidget,
  755. editor.searchStuff.misspelledListLabel),
  756. _DtEditorGetMisspelledListLabel, NULL
  757. },
  758. {
  759. DtNrightAlignToggleLabel, sizeof (XmString),
  760. XtOffset (DtEditorWidget,
  761. editor.formatStuff.rightAlignToggleLabel),
  762. _DtEditorGetRightAlignToggleLabel, NULL
  763. },
  764. {
  765. DtNrightMarginFieldLabel, sizeof (XmString),
  766. XtOffset (DtEditorWidget,
  767. editor.formatStuff.rightMarginFieldLabel),
  768. _DtEditorGetRightMarginFieldLabel, NULL
  769. },
  770. {
  771. DtNrows, sizeof(short),
  772. XtOffset (DtEditorWidget, editor.editStuff.rows),
  773. _DtEditorGetRows, NULL
  774. },
  775. {
  776. DtNscrollLeftSide, sizeof (Boolean),
  777. XtOffset (DtEditorWidget, editor.editStuff.scrollLeft),
  778. _DtEditorGetScrollLeftSide, NULL
  779. },
  780. {
  781. DtNscrollTopSide, sizeof (Boolean),
  782. XtOffset (DtEditorWidget, editor.editStuff.scrollTop),
  783. _DtEditorGetScrollTopSide, NULL
  784. },
  785. {
  786. DtNtextBackground, sizeof(Pixel),
  787. XtOffset (DtEditorWidget, editor.editStuff.background),
  788. _DtEditorGetTextBackground, NULL
  789. },
  790. {
  791. DtNtextForeground, sizeof(Pixel),
  792. XtOffset (DtEditorWidget, editor.editStuff.foreground),
  793. _DtEditorGetTextForeground, NULL
  794. },
  795. {
  796. DtNtopCharacter, sizeof(XmTextPosition),
  797. XtOffset (DtEditorWidget, editor.editStuff.topCharacter),
  798. _DtEditorGetTopCharacter, NULL
  799. },
  800. {
  801. DtNtotalLineCountLabel, sizeof (XmString),
  802. XtOffset (DtEditorWidget, editor.statusStuff.totalLineLabel),
  803. _DtEditorGetLineCountLabel, NULL
  804. },
  805. };
  806. static XtResource resources[] =
  807. {
  808. {
  809. DtNautoShowCursorPosition,
  810. DtCAutoShowCursorPosition, XmRBoolean, sizeof (Boolean),
  811. XtOffset(DtEditorWidget,
  812. editor.editStuff.autoShowCursorPos),
  813. XmRImmediate, (XtPointer) True
  814. },
  815. {
  816. DtNbuttonFontList, DtCFontList, XmRFontList, sizeof(XmFontList),
  817. XtOffsetOf(struct _XmBulletinBoardRec,
  818. bulletin_board.button_font_list),
  819. XmRFontList, (XtPointer) NULL
  820. },
  821. {
  822. DtNblinkRate, DtCBlinkRate, XmRInt, sizeof(int),
  823. XtOffset(DtEditorWidget, editor.editStuff.blinkRate),
  824. XmRImmediate, (XtPointer) 500
  825. },
  826. {
  827. DtNcenterToggleLabel, DtCCenterToggleLabel,
  828. XmRXmString, sizeof (XmString),
  829. XtOffset (DtEditorWidget, editor.formatStuff.centerToggleLabel),
  830. XmRImmediate, (XtPointer) DtUNSPECIFIED
  831. },
  832. {
  833. DtNchangeAllButtonLabel, DtCChangeAllButtonLabel,
  834. XmRXmString, sizeof (XmString),
  835. XtOffset (DtEditorWidget,
  836. editor.searchStuff.changeAllButtonLabel),
  837. XmRImmediate, (XtPointer) DtUNSPECIFIED
  838. },
  839. {
  840. DtNchangeButtonLabel, DtCChangeButtonLabel,
  841. XmRXmString, sizeof (XmString),
  842. XtOffset(DtEditorWidget, editor.searchStuff.changeButtonLabel),
  843. XmRImmediate, (XtPointer) DtUNSPECIFIED
  844. },
  845. {
  846. DtNchangeFieldLabel, DtCChangeFieldLabel,
  847. XmRXmString, sizeof (XmString),
  848. XtOffset(DtEditorWidget, editor.searchStuff.changeFieldLabel),
  849. XmRImmediate, (XtPointer) DtUNSPECIFIED
  850. },
  851. {
  852. DtNcolumns, DtCColumns, XmRShort, sizeof(short),
  853. XtOffset (DtEditorWidget, editor.editStuff.columns),
  854. XmRImmediate, (XtPointer) DtUNSPECIFIED
  855. },
  856. {
  857. DtNcurrentLineLabel, DtCCurrentLineLabel,
  858. XmRXmString, sizeof (XmString),
  859. XtOffset(DtEditorWidget, editor.statusStuff.currentLineLabel),
  860. XmRImmediate, (XtPointer) DtUNSPECIFIED
  861. },
  862. {
  863. DtNcursorPosition, DtCCursorPosition, XmRTextPosition,
  864. sizeof (XmTextPosition),
  865. XtOffset(DtEditorWidget, editor.editStuff.cursorPos),
  866. XmRImmediate, (XtPointer) DtUNSPECIFIED
  867. },
  868. {
  869. DtNcursorPositionVisible, DtCCursorPositionVisible,
  870. XmRBoolean, sizeof (Boolean),
  871. XtOffset(DtEditorWidget,
  872. editor.editStuff.cursorPosVisible),
  873. XmRImmediate, (XtPointer) True
  874. },
  875. {
  876. DtNdialogTitle, DtCDialogTitle, XmRXmString, sizeof (XmString),
  877. XtOffsetOf(struct _XmBulletinBoardRec,
  878. bulletin_board.dialog_title),
  879. XmRString, (XtPointer) NULL
  880. },
  881. {
  882. DtNeditable, DtCEditable, XmRBoolean, sizeof (Boolean),
  883. XtOffset (DtEditorWidget, editor.editStuff.editable),
  884. XmRImmediate, (XtPointer) True
  885. },
  886. {
  887. DtNfindButtonLabel, DtCFindButtonLabel,
  888. XmRXmString, sizeof (XmString),
  889. XtOffset(DtEditorWidget, editor.searchStuff.findButtonLabel),
  890. XmRImmediate, (XtPointer) DtUNSPECIFIED
  891. },
  892. {
  893. DtNfindChangeDialogTitle, DtCFindChangeDialogTitle,
  894. XmRXmString, sizeof (XmString),
  895. XtOffset(DtEditorWidget, editor.searchStuff.fndChngTitle),
  896. XmRString, (XtPointer) NULL
  897. },
  898. {
  899. DtNfindFieldLabel, DtCFindFieldLabel,
  900. XmRXmString, sizeof (XmString),
  901. XtOffset(DtEditorWidget, editor.searchStuff.findFieldLabel),
  902. XmRImmediate, (XtPointer) DtUNSPECIFIED
  903. },
  904. {
  905. DtNformatAllButtonLabel, DtCFormatAllButtonLabel,
  906. XmRXmString, sizeof (XmString),
  907. XtOffset(DtEditorWidget,
  908. editor.formatStuff.formatAllButtonLabel),
  909. XmRImmediate, (XtPointer) DtUNSPECIFIED
  910. },
  911. {
  912. DtNformatParagraphButtonLabel, DtCFormatParagraphButtonLabel,
  913. XmRXmString, sizeof (XmString),
  914. XtOffset(DtEditorWidget,
  915. editor.formatStuff.formatParaButtonLabel),
  916. XmRImmediate, (XtPointer) DtUNSPECIFIED
  917. },
  918. {
  919. DtNformatSettingsDialogTitle, DtCFormatSettingsDialogTitle,
  920. XmRXmString, sizeof (XmString),
  921. XtOffset(DtEditorWidget, editor.formatStuff.formatDialogTitle),
  922. XmRString, (XtPointer) NULL
  923. },
  924. {
  925. DtNinformationDialogTitle, DtCInformationDialogTitle,
  926. XmRXmString, sizeof (XmString),
  927. XtOffset(DtEditorWidget, editor.warningStuff.infoDialogTitle),
  928. XmRString, (XtPointer) NULL
  929. },
  930. {
  931. DtNinsertLabel, DtCInsertLabel, XmRXmString, sizeof (XmString),
  932. XtOffset (DtEditorWidget, editor.statusStuff.ins),
  933. XmRImmediate, (XtPointer) DtUNSPECIFIED
  934. },
  935. {
  936. DtNjustifyToggleLabel, DtCJustifyToggleLabel,
  937. XmRXmString, sizeof (XmString),
  938. XtOffset(DtEditorWidget, editor.formatStuff.justifyToggleLabel),
  939. XmRImmediate, (XtPointer) DtUNSPECIFIED
  940. },
  941. {
  942. DtNlabelFontList, DtCFontList, XmRFontList, sizeof(XmFontList),
  943. XtOffsetOf(struct _XmBulletinBoardRec,
  944. bulletin_board.label_font_list),
  945. XmRFontList, (XtPointer) NULL
  946. },
  947. {
  948. DtNleftAlignToggleLabel, DtCLeftAlignToggleLabel,
  949. XmRXmString, sizeof (XmString),
  950. XtOffset(DtEditorWidget,
  951. editor.formatStuff.leftAlignToggleLabel),
  952. XmRImmediate, (XtPointer) DtUNSPECIFIED
  953. },
  954. {
  955. DtNleftMarginFieldLabel, DtCLeftMarginFieldLabel,
  956. XmRXmString, sizeof (XmString),
  957. XtOffset(DtEditorWidget,
  958. editor.formatStuff.leftMarginFieldLabel),
  959. XmRImmediate, (XtPointer) DtUNSPECIFIED
  960. },
  961. {
  962. DtNmaxLength, DtCMaxLength, XmRInt, sizeof(int),
  963. XtOffset(DtEditorWidget, editor.editStuff.maxLength),
  964. XmRImmediate, (XtPointer) DtUNSPECIFIED
  965. },
  966. {
  967. DtNmisspelledListLabel, DtCMisspelledListLabel,
  968. XmRXmString, sizeof (XmString),
  969. XtOffset (DtEditorWidget,
  970. editor.searchStuff.misspelledListLabel),
  971. XmRImmediate, (XtPointer) DtUNSPECIFIED
  972. },
  973. {
  974. DtNoverstrike, DtCOverstrike, XmRBoolean, sizeof (Boolean),
  975. XtOffset(DtEditorWidget, editor.editStuff.overstrikeMode),
  976. XmRImmediate, (XtPointer) False
  977. },
  978. {
  979. DtNoverstrikeLabel, DtCOverstrikeLabel,
  980. XmRXmString, sizeof (XmString),
  981. XtOffset (DtEditorWidget, editor.statusStuff.ovr),
  982. XmRImmediate, (XtPointer) DtUNSPECIFIED
  983. },
  984. {
  985. DtNrightAlignToggleLabel, DtCRightAlignToggleLabel,
  986. XmRXmString, sizeof (XmString),
  987. XtOffset(DtEditorWidget,
  988. editor.formatStuff.rightAlignToggleLabel),
  989. XmRImmediate, (XtPointer) DtUNSPECIFIED
  990. },
  991. {
  992. DtNrightMarginFieldLabel, DtCRightMarginFieldLabel,
  993. XmRXmString, sizeof (XmString),
  994. XtOffset(DtEditorWidget,
  995. editor.formatStuff.rightMarginFieldLabel),
  996. XmRImmediate, (XtPointer) DtUNSPECIFIED
  997. },
  998. {
  999. DtNrows, DtCRows, XmRShort, sizeof(short),
  1000. XtOffset (DtEditorWidget, editor.editStuff.rows),
  1001. XmRImmediate, (XtPointer) DtUNSPECIFIED
  1002. },
  1003. {
  1004. DtNscrollHorizontal, DtCScroll, XmRBoolean, sizeof (Boolean),
  1005. XtOffset (DtEditorWidget, editor.editStuff.scrollHorizontal),
  1006. XmRImmediate, (XtPointer) True
  1007. },
  1008. {
  1009. DtNscrollLeftSide, DtCScrollSide, XmRBoolean, sizeof (Boolean),
  1010. XtOffset (DtEditorWidget, editor.editStuff.scrollLeft),
  1011. XmRImmediate, (XtPointer) DtUNSPECIFIED
  1012. },
  1013. {
  1014. DtNscrollTopSide, DtCScrollSide, XmRBoolean, sizeof (Boolean),
  1015. XtOffset (DtEditorWidget, editor.editStuff.scrollTop),
  1016. XmRImmediate, (XtPointer) DtUNSPECIFIED
  1017. },
  1018. {
  1019. DtNscrollVertical, DtCScroll, XmRBoolean, sizeof (Boolean),
  1020. XtOffset (DtEditorWidget, editor.editStuff.scrollVertical),
  1021. XmRImmediate, (XtPointer) True
  1022. },
  1023. {
  1024. DtNshowStatusLine,
  1025. DtCShowStatusLine, XmRBoolean, sizeof (Boolean),
  1026. XtOffset (DtEditorWidget, editor.statusStuff.showStatusLine),
  1027. XmRImmediate, (XtPointer) False
  1028. },
  1029. {
  1030. DtNspellDialogTitle, DtCSpellDialogTitle,
  1031. XmRXmString, sizeof (XmString),
  1032. XtOffset(DtEditorWidget, editor.searchStuff.spellTitle),
  1033. XmRString, (XtPointer) NULL
  1034. },
  1035. {
  1036. DtNspellFilter, DtCSpellFilter, XmRString, sizeof(XmRString),
  1037. XtOffset (DtEditorWidget, editor.searchStuff.spellFilter),
  1038. XmRString, "spell"
  1039. },
  1040. {
  1041. DtNtextBackground, DtCBackground,
  1042. XmRPixel, sizeof(Pixel),
  1043. XtOffset (DtEditorWidget, editor.editStuff.background),
  1044. XmRImmediate, (XtPointer) DtUNSPECIFIED
  1045. },
  1046. {
  1047. DtNtextDeselectCallback,
  1048. DtCCallback, XtRCallback, sizeof (XtCallbackList),
  1049. XtOffset (DtEditorWidget, editor.textDeselect),
  1050. XtRCallback, (XtPointer) NULL
  1051. },
  1052. {
  1053. DtNtextForeground, DtCForeground,
  1054. XmRPixel, sizeof(Pixel),
  1055. XtOffset (DtEditorWidget, editor.editStuff.foreground),
  1056. XmRImmediate, (XtPointer) DtUNSPECIFIED
  1057. },
  1058. {
  1059. DtNtextFontList, DtCFontList, XmRFontList, sizeof(XmFontList),
  1060. XtOffsetOf(struct _XmBulletinBoardRec,
  1061. bulletin_board.text_font_list),
  1062. XmRFontList, (XtPointer) NULL
  1063. },
  1064. {
  1065. DtNtextSelectCallback,
  1066. DtCCallback, XtRCallback, sizeof (XtCallbackList),
  1067. XtOffset (DtEditorWidget, editor.textSelect),
  1068. XtRCallback, (XtPointer) NULL
  1069. },
  1070. {
  1071. DtNtextTranslations, DtCTranslations,
  1072. XmRTranslationTable, sizeof (XtTranslations),
  1073. XtOffsetOf(struct _XmBulletinBoardRec,
  1074. bulletin_board.text_translations),
  1075. XmRImmediate, (XtPointer) NULL
  1076. },
  1077. {
  1078. DtNtopCharacter, DtCTopCharacter,
  1079. XmRTextPosition, sizeof(XmTextPosition),
  1080. XtOffset (DtEditorWidget, editor.editStuff.topCharacter),
  1081. XmRImmediate, (XtPointer) DtUNSPECIFIED
  1082. },
  1083. {
  1084. DtNtotalLineCountLabel, DtCTotalLineCountLabel,
  1085. XmRXmString, sizeof (XmString),
  1086. XtOffset (DtEditorWidget,
  1087. editor.statusStuff.totalLineLabel),
  1088. XmRImmediate, (XtPointer) DtUNSPECIFIED
  1089. },
  1090. {
  1091. DtNwordWrap,
  1092. DtCWordWrap, XmRBoolean, sizeof (Boolean),
  1093. XtOffset (DtEditorWidget, editor.editStuff.wordWrap),
  1094. XmRImmediate, (XtPointer) False
  1095. },
  1096. };
  1097. /****************************************************************
  1098. *
  1099. * Public Function Declarations
  1100. *
  1101. ****************************************************************/
  1102. /****************************************************************
  1103. *
  1104. * Class Record
  1105. *
  1106. ****************************************************************/
  1107. externaldef( dteditorclassrec ) DtEditorClassRec
  1108. dtEditorClassRec =
  1109. {
  1110. /* Core Part
  1111. */
  1112. {
  1113. (WidgetClass) &xmFormClassRec, /* superclass */
  1114. "DtEditor", /* class_name */
  1115. sizeof (DtEditorRec), /* widget_size */
  1116. ClassInitialize, /* class_initialize */
  1117. NULL, /* class_part_initialize*/
  1118. False, /* class_inited */
  1119. (XtInitProc) Initialize, /* initialize */
  1120. NULL, /* initialize_hook */
  1121. XtInheritRealize, /* realize */
  1122. (XtActionList)EditorActionTable,/* actions */
  1123. (Cardinal)XtNumber(EditorActionTable), /* num_actions */
  1124. resources, /* resources */
  1125. XtNumber (resources), /* num_resources */
  1126. NULLQUARK, /* xrm_class */
  1127. True, /* compress_motion */
  1128. XtExposeCompressMaximal, /* compress_exposure */
  1129. False, /* compress_enterleave */
  1130. False, /* visible_interest */
  1131. (XtWidgetProc) Destroy, /* destroy */
  1132. XtInheritResize, /* resize */
  1133. XtInheritExpose, /* expose */
  1134. (XtSetValuesFunc) SetValues, /* set_values */
  1135. NULL, /* set_values_hook */
  1136. XtInheritSetValuesAlmost, /* set_values_almost */
  1137. NULL, /* get_values_hook */
  1138. XtInheritAcceptFocus, /* accept_focus */
  1139. XtVersion, /* version */
  1140. NULL, /* callback private */
  1141. XtInheritTranslations, /* tm_table */
  1142. XtInheritQueryGeometry, /* query_geometry */
  1143. (XtStringProc)NULL, /* display_accelerator */
  1144. NULL, /* extension */
  1145. },
  1146. /* Composite Part
  1147. */
  1148. {
  1149. XtInheritGeometryManager, /* geometry_manager */
  1150. XtInheritChangeManaged, /* change_managed */
  1151. XtInheritInsertChild, /* insert_child */
  1152. XtInheritDeleteChild, /* delete_child */
  1153. NULL, /* extension */
  1154. },
  1155. /* Constraint Part
  1156. */
  1157. {
  1158. NULL, /* constraint_resources */
  1159. 0, /* num_constraint_resource */
  1160. sizeof(XmFormConstraintRec), /* size of constraint */
  1161. NULL, /* initialization */
  1162. NULL, /* constraint_destroy */
  1163. NULL, /* constraint_set_values */
  1164. NULL, /* extension */
  1165. },
  1166. /* XmManager Part
  1167. */
  1168. {
  1169. XmInheritTranslations, /* default_translations */
  1170. syn_resources, /* syn_resources */
  1171. XtNumber(syn_resources), /* num_syn_resources */
  1172. NULL, /* syn_cont_resources */
  1173. 0, /* num_syn_cont_resources */
  1174. XmInheritParentProcess, /* parent_process */
  1175. NULL, /* extension */
  1176. },
  1177. /* XmbulletinBoard Part
  1178. */
  1179. {
  1180. FALSE, /* always_install_accelerators */
  1181. (XmGeoCreateProc)NULL, /* geo_matrix_create */
  1182. XmInheritFocusMovedProc, /* focus_moved_proc */
  1183. NULL, /* extension */
  1184. },
  1185. /* XmForm Part
  1186. */
  1187. {
  1188. NULL, /* extension */
  1189. },
  1190. /* DtEditor Part
  1191. */
  1192. {
  1193. 0, /* extension */
  1194. }
  1195. };
  1196. WidgetClass dtEditorWidgetClass = (WidgetClass) &dtEditorClassRec;
  1197. /*-------------------------------------------------------------
  1198. ** Editor Procs
  1199. **-------------------------------------------------------------
  1200. */
  1201. /****************************************************************
  1202. *
  1203. * Private Procs
  1204. *
  1205. ****************************************************************/
  1206. /*-------------------------------------------------------------
  1207. ** Function: static void ClassInitialize (void);
  1208. **
  1209. ** Parameters:
  1210. **
  1211. ** Purpose: This is the Editor class initializzation routine.
  1212. ** It is called once, before the first instance
  1213. ** is created.
  1214. */
  1215. static void
  1216. ClassInitialize(void)
  1217. {
  1218. #if !(defined(sun) && (_XOPEN_VERSION==3))
  1219. _DtEditor_blankClass = wctype(blankString);
  1220. /*
  1221. ** These calls determine if the particular value is True for
  1222. ** the current locale. A value of -1 is returned if the locale
  1223. ** does not support the charclass. If the locale supports the
  1224. ** charclass, the return value is passed as a parameter to the
  1225. ** iswctype call.
  1226. */
  1227. ekinclass = wctype("ekinsoku");
  1228. bekinclass = wctype("bkinsoku");
  1229. blnkclass = wctype("blank");
  1230. #endif /* end not Sun */
  1231. }
  1232. /*-------------------------------------------------------------
  1233. ** Function: static void Initialize (
  1234. ** Widget rw,
  1235. ** Widget nw,
  1236. ** ArgList arg_list,
  1237. ** Cardinal *num_args)
  1238. **
  1239. ** Parameters:
  1240. **
  1241. ** Purpose: This is the Editor widget initialize routine.
  1242. ** It is responsible for the following:
  1243. ** 1) Validate all resources the user passed in,
  1244. ** 2) Override any invalid resources,
  1245. ** 3) Initialize the internal data structures,
  1246. ** 4) Create the edit area widget
  1247. ** 5) Create the status area widget, if requested
  1248. ** 6) Add any callbacks and actions
  1249. */
  1250. static void
  1251. Initialize(
  1252. Widget rw,
  1253. Widget nw,
  1254. ArgList arg_list,
  1255. Cardinal *num_args)
  1256. {
  1257. DtEditorWidget request = (DtEditorWidget) rw,
  1258. new = (DtEditorWidget) nw;
  1259. /* Initialize non-resource portion of the instance structure */
  1260. VariableInitialize (new);
  1261. /* Validate the incoming arguments to make sure they are OK */
  1262. ValidateResources (new, request);
  1263. /*
  1264. * Create & customize the scrolled text widget
  1265. */
  1266. M_text(new) = CreateText (new);
  1267. XtManageChild( M_text(new)) ;
  1268. /*
  1269. * If the widget is not "read only" then register it as a drop zone
  1270. */
  1271. if ( M_editable(new) == True )
  1272. RegisterDropZone( new );
  1273. /*
  1274. * Compute the width & height of the scrolled text's font. These values
  1275. * will be used when formatting and in calculating the window manager
  1276. * hints.
  1277. */
  1278. getFontMetrics(new);
  1279. /*
  1280. * Create the status line
  1281. */
  1282. SetStatusLine( new, M_status_showStatusLine(request) );
  1283. } /* end Initialize */
  1284. /*-------------------------------------------------------------
  1285. ** Function: static void VariableInitialize (
  1286. ** DtEditorWidget new )
  1287. **
  1288. ** Parameters: The Editor widget being created
  1289. **
  1290. ** Purpose: This routine:
  1291. ** 1) Initializes the widget's instance structure
  1292. */
  1293. static void
  1294. VariableInitialize(
  1295. DtEditorWidget new)
  1296. {
  1297. Widget thisParent;
  1298. /*
  1299. * Initialize the non-resource instance fields
  1300. */
  1301. M_display(new) = XtDisplayOfObject( (Widget)new->core.parent );
  1302. M_app_context(new) = XtDisplayToApplicationContext(M_display(new));
  1303. /*
  1304. * Empty 'for' walks up the widget tree to find a shell.
  1305. */
  1306. for (thisParent = new->core.parent;
  1307. thisParent != (Widget)NULL && XtIsShell(thisParent) == False;
  1308. thisParent = XtParent(thisParent));
  1309. M_topLevelShell(new) = thisParent;
  1310. /* Initialize edit area fields */
  1311. M_loadingAllNewData(new) = False;
  1312. M_unreadChanges(new) = False; /* There have not been any changes since */
  1313. /* the app requested the data */
  1314. M_deletionStart(new) = NO_DELETION_IN_PROGRESS;
  1315. M_deletedText(new) = (char *)NULL;
  1316. M_insertStart(new) = 0;
  1317. M_insertionLength(new) = 0;
  1318. M_textSelectCbCalled(new) = False;
  1319. M_fontWidth(new) = -1;
  1320. /* Initialize status line fields */
  1321. M_status_statusArea(new) = (Widget)NULL;
  1322. M_status_messageText(new) = (Widget)NULL;
  1323. M_status_currentLine(new) = -1;
  1324. M_status_lastLine(new) = -1;
  1325. /* Initialize search function data */
  1326. M_search_dialog(new) = (Widget) NULL;
  1327. M_search_dialogMode(new) = SPELL;
  1328. M_search_string(new) = (char *)NULL;
  1329. M_replace_string(new) = (char *)NULL;
  1330. M_misspelled_string(new) = (char *)NULL;
  1331. M_misspelled_found(new) = False;
  1332. /* Initialize format function data */
  1333. M_format_dialog(new) = (Widget)NULL;
  1334. /* Initialize warning dialogs data */
  1335. M_gen_warning(new) = (Widget)NULL;
  1336. } /* end VariableInitialize */
  1337. /*-------------------------------------------------------------
  1338. ** Function: static void ValidateResources (
  1339. ** DtEditorWidget new,
  1340. ** DtEditorWidget request )
  1341. **
  1342. ** Parameters: The Editor widget being created & its requested
  1343. ** resource values
  1344. **
  1345. ** Purpose: This routine:
  1346. ** 1) Validates the widget's requested resources
  1347. */
  1348. static void
  1349. ValidateResources(
  1350. DtEditorWidget new,
  1351. DtEditorWidget request)
  1352. {
  1353. /*
  1354. * Validate the requested values for the editor's resources
  1355. */
  1356. /*
  1357. * Make local copies of all resource strings assigned by the application.
  1358. */
  1359. if (M_spellFilter(request) != (char *) NULL)
  1360. M_spellFilter(new) = XtNewString( M_spellFilter(request) );
  1361. /*
  1362. * Copy the dialog titles if the application set them, otherwise,
  1363. * get their values from the message catalog.
  1364. */
  1365. if (M_spellTitle(request) != (XmString) NULL)
  1366. M_spellTitle(new) = XmStringCopy( M_spellTitle(request) );
  1367. else
  1368. M_spellTitle(new) = XmStringCreateLocalized(SPELL_TITLE);
  1369. if (M_fndChngTitle(request) != (XmString) NULL)
  1370. M_fndChngTitle(new) = XmStringCopy( M_fndChngTitle(request) );
  1371. else
  1372. M_fndChngTitle(new) = XmStringCreateLocalized(FIND_TITLE);
  1373. if (E_format_dialogTitle(request) != (XmString) NULL)
  1374. E_format_dialogTitle(new) = XmStringCopy( E_format_dialogTitle(request) );
  1375. else
  1376. E_format_dialogTitle(new) = XmStringCreateLocalized(FORMAT_SETTINGS);
  1377. if (E_infoDialogTitle(request) != (XmString) NULL)
  1378. E_infoDialogTitle(new) = XmStringCopy( E_infoDialogTitle(request) );
  1379. else
  1380. E_infoDialogTitle(new) = XmStringCreateLocalized(INFO_TITLE);
  1381. /*
  1382. * Copy the insert & overstrike label indicators if the appli-
  1383. * cation set them, otherwise, get their value from the message
  1384. * catalog.
  1385. * Check for DtUNSPECIFIED because NULL is a valid value.
  1386. */
  1387. if (M_status_insertLabel(request) != (XmString) DtUNSPECIFIED)
  1388. M_status_insertLabel(new) =
  1389. XmStringCopy( M_status_insertLabel(request) );
  1390. else
  1391. M_status_insertLabel(new) = XmStringCreateLocalized(INS);
  1392. if (M_status_overstrikeLabel(request) != (XmString) DtUNSPECIFIED)
  1393. M_status_overstrikeLabel(new) =
  1394. XmStringCopy( M_status_overstrikeLabel(request) );
  1395. else
  1396. M_status_overstrikeLabel(new) = XmStringCreateLocalized(OVR);
  1397. } /* end ValidateResources */
  1398. /*-------------------------------------------------------------
  1399. ** Function: static Widget CreateText (
  1400. ** DtEditorWidget parent)
  1401. **
  1402. ** Parameters: The parent of the text widget
  1403. **
  1404. ** Purpose: This routine creates the scrolled text widget which
  1405. ** lives inside the editor widget.
  1406. ** It is responsible for the following:
  1407. ** 1) Creating the scrolled text widget,
  1408. ** 2) Adding specific translations,
  1409. ** 3) Adding our own callbacks,
  1410. ** 4) Substituting our own set selection routine.
  1411. */
  1412. static Widget
  1413. CreateText(
  1414. DtEditorWidget parent)
  1415. {
  1416. int ac; /* arg count */
  1417. Arg al[21]; /* arg list */
  1418. Widget text;
  1419. /*
  1420. * First, set up the hardwired scrolled text widget resource values.
  1421. * (Change these and you die! Aha! Ha! Ha! Ha! [evil laugh])
  1422. */
  1423. ac = 0;
  1424. XtSetArg (al[ac], XmNeditMode, XmMULTI_LINE_EDIT); ac++;
  1425. XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  1426. XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  1427. XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  1428. XtSetArg(al[ac], XmNpendingDelete, True); ac++;
  1429. /*
  1430. * Now, set up the resource values which can vary (passed in from
  1431. * application or default values).
  1432. *
  1433. * If a synthetic resource is DtUNSPECIFIED don't set it, but let
  1434. * it default to the scrolled text default value.
  1435. * If it is specified, clear the data field after setting the
  1436. * resource because the value in the field will be out of sync
  1437. * with the real value.
  1438. */
  1439. XtSetArg(al[ac], XmNautoShowCursorPosition, M_autoShowCursorPos(parent));
  1440. ac++;
  1441. XtSetArg(al[ac], XmNblinkRate, M_blinkRate(parent)); ac++;
  1442. if ( M_columns(parent) != DtUNSPECIFIED) {
  1443. XtSetArg (al[ac], XmNcolumns, M_columns(parent) ); ac++;
  1444. M_columns(parent) = (short) DtUNSPECIFIED;
  1445. }
  1446. if ( M_cursorPos(parent) != DtUNSPECIFIED) {
  1447. XtSetArg (al[ac], XmNcursorPosition, M_cursorPos(parent)); ac++;
  1448. M_cursorPos(parent) = (XmTextPosition) DtUNSPECIFIED;
  1449. }
  1450. XtSetArg(al[ac], XmNcursorPositionVisible, M_cursorPosVisible(parent));
  1451. ac++;
  1452. XtSetArg(al[ac], XmNeditable, M_editable(parent)); ac++;
  1453. if ( E_textFontList(parent) != (XmFontList) NULL) {
  1454. XtSetArg (al[ac], XmNfontList, E_textFontList(parent)); ac++;
  1455. }
  1456. if ( M_maxLength(parent) != DtUNSPECIFIED) {
  1457. XtSetArg (al[ac], XmNmaxLength, M_maxLength(parent) ); ac++;
  1458. M_maxLength(parent) = (int) DtUNSPECIFIED;
  1459. }
  1460. if ( M_rows(parent) != DtUNSPECIFIED) {
  1461. XtSetArg (al[ac], XmNrows, M_rows(parent) ); ac++;
  1462. M_rows(parent) = (short) DtUNSPECIFIED;
  1463. }
  1464. XtSetArg (al[ac], XmNscrollHorizontal, M_scrollHorizontal(parent) ); ac++;
  1465. if ( M_scrollLeftSide(parent) != (Boolean)DtUNSPECIFIED) {
  1466. XtSetArg (al[ac], XmNscrollLeftSide, M_scrollLeftSide(parent) ); ac++;
  1467. M_scrollLeftSide(parent) = (Boolean)DtUNSPECIFIED;
  1468. }
  1469. if ( M_scrollTopSide(parent) != (Boolean)DtUNSPECIFIED) {
  1470. XtSetArg (al[ac], XmNscrollTopSide, M_scrollTopSide(parent) ); ac++;
  1471. M_scrollTopSide(parent) = (Boolean)DtUNSPECIFIED;
  1472. }
  1473. XtSetArg (al[ac], XmNscrollVertical, M_scrollVertical(parent) ); ac++;
  1474. if ( M_topCharacter(parent) != DtUNSPECIFIED) {
  1475. XtSetArg (al[ac], XmNtopCharacter, M_topCharacter(parent) ); ac++;
  1476. M_topCharacter(parent) = (XmTextPosition) DtUNSPECIFIED;
  1477. }
  1478. XtSetArg (al[ac], XmNwordWrap, M_wordWrap(parent) ); ac++;
  1479. /* Create text widget */
  1480. text = XmCreateScrolledText ( (Widget) parent, "text", al, ac );
  1481. /*
  1482. * Now, set the foreground & background of the text widget. Could not
  1483. * set it at create time because the scrolled window would have
  1484. * picked it up, too.
  1485. */
  1486. ac=0;
  1487. if ( M_textBackground(parent) != DtUNSPECIFIED) {
  1488. XtSetArg (al[ac], XmNbackground, M_textBackground(parent) ); ac++;
  1489. M_textBackground(parent) = (Pixel) DtUNSPECIFIED;
  1490. }
  1491. if ( M_textForeground(parent) != DtUNSPECIFIED) {
  1492. XtSetArg (al[ac], XmNforeground, M_textForeground(parent) ); ac++;
  1493. M_textForeground(parent) = (Pixel) DtUNSPECIFIED;
  1494. }
  1495. if (ac)
  1496. XtSetValues( text, al, ac);
  1497. /* XXX Word Wrap workaround. See comments for FixWordWrap() */
  1498. if ( M_scrollHorizontal(parent) ) /* XXX Word Wrap workaround */
  1499. FixWordWrap(text, M_wordWrap(parent)); /* XXX Word Wrap workaround */
  1500. /* Put the editor-specific translation routines in place. */
  1501. XtOverrideTranslations(text,
  1502. XtParseTranslationTable(EditorTranslationTable));
  1503. /* Add any translations set by the application. */
  1504. if ( E_textTranslations(parent) != (XtTranslations)NULL ) {
  1505. XtOverrideTranslations(text, E_textTranslations(parent));
  1506. }
  1507. /*
  1508. * Add modify verify callback
  1509. */
  1510. XtAddCallback(text, XmNmodifyVerifyCallback,
  1511. (XtCallbackProc) _DtEditorModifyVerifyCB,
  1512. (XtPointer) parent);
  1513. /*
  1514. * Add the Help callback
  1515. */
  1516. XtAddCallback( text, XmNhelpCallback, (XtCallbackProc) HelpEditWindowCB,
  1517. (XtPointer) parent );
  1518. /*
  1519. * Substitute our own Set Selection routine which can
  1520. * call the textSelect and textDeselect callback procs
  1521. */
  1522. if(((XmTextWidget)(text))->text.source->SetSelection !=
  1523. Editor_SetSelectionProc) {
  1524. M_setSelection(parent) =
  1525. ((XmTextWidget)(text))->text.source->SetSelection;
  1526. ((XmTextWidget)(text))->text.source->SetSelection =
  1527. Editor_SetSelectionProc;
  1528. }
  1529. XtSetSensitive (text, True);
  1530. return(text);
  1531. } /* end CreateText */
  1532. /*-------------------------------------------------------------
  1533. ** Function: static int extractFontMetrics (
  1534. ** XmFontList fontlist )
  1535. **
  1536. ** Purpose: Given a font list, determine the width & height
  1537. ** of the characters.
  1538. **
  1539. ** This routine is lifted almost straight out of
  1540. ** lib/Xm/TextOut.c (see LoadFontMetrics() ) so the editor will
  1541. ** select the same font the text widget is working with.
  1542. */
  1543. static void
  1544. extractFontMetrics(
  1545. DtEditorWidget w,
  1546. XmFontList fontlist,
  1547. int *height,
  1548. int *width)
  1549. {
  1550. XmFontContext context;
  1551. XmFontListEntry next_entry;
  1552. XmFontType type_return = XmFONT_IS_FONT;
  1553. XtPointer tmp_font;
  1554. XFontStruct *font = NULL;
  1555. Boolean have_font_struct = False;
  1556. Boolean have_font_set = False;
  1557. Boolean use_font_set = False;
  1558. XFontSetExtents *fs_extents;
  1559. unsigned long tmp_width = 0;
  1560. int font_descent, font_ascent;
  1561. char* font_tag = NULL;
  1562. *width = *height = 0;
  1563. if (XmFontListInitFontContext(&context, fontlist)) {
  1564. /*
  1565. * Look through the font list for a fontset with the default tag.
  1566. * If we do not find it, use the first font set we came to, otherwise,
  1567. * use the first font struct we came to.
  1568. */
  1569. do {
  1570. Boolean do_break = False;
  1571. next_entry = XmFontListNextEntry(context);
  1572. if (next_entry) {
  1573. tmp_font = XmFontListEntryGetFont(next_entry, &type_return);
  1574. if (type_return == XmFONT_IS_FONTSET) {
  1575. /*
  1576. * Have a font set
  1577. */
  1578. font_tag = XmFontListEntryGetTag(next_entry);
  1579. if (!have_font_set){
  1580. /*
  1581. * Save the first fontset found in case we don't find
  1582. * a default tag font set.
  1583. */
  1584. have_font_set = True; /* we have a font set. */
  1585. use_font_set = True;
  1586. font = (XFontStruct *)tmp_font;
  1587. /*
  1588. * We have a font set, so no need to consider future font
  1589. * structs
  1590. */
  1591. have_font_struct = True;
  1592. /*
  1593. * If this is the default font set break out, we've
  1594. * found the one we want.
  1595. */
  1596. if (!strcmp(XmFONTLIST_DEFAULT_TAG, font_tag))
  1597. do_break = True;
  1598. }
  1599. else if (!strcmp(XmFONTLIST_DEFAULT_TAG, font_tag)) {
  1600. /*
  1601. * If this is the default font set save it & break out,
  1602. * we've found the one we want.
  1603. */
  1604. font = (XFontStruct *)tmp_font;
  1605. have_font_set = True;
  1606. do_break = True;
  1607. }
  1608. if (NULL != font_tag)
  1609. XtFree(font_tag);
  1610. if (do_break)
  1611. break;
  1612. }
  1613. else if (!have_font_struct){
  1614. /*
  1615. * Have a font
  1616. */
  1617. use_font_set = False;
  1618. /*
  1619. * Save the first one in case no font set is found
  1620. */
  1621. font = (XFontStruct *)tmp_font;
  1622. use_font_set = False;
  1623. have_font_struct = True;
  1624. }
  1625. }
  1626. } while (next_entry != NULL);
  1627. XmFontListFreeFontContext(context);
  1628. /*
  1629. * Now, extract the font metrics from the font set or font that
  1630. * we chose.
  1631. */
  1632. if (use_font_set) {
  1633. /*
  1634. * Chose a font set
  1635. */
  1636. fs_extents = XExtentsOfFontSet((XFontSet)font);
  1637. if (XmDirectionMatch(w->manager.string_direction,
  1638. XmTOP_TO_BOTTOM_RIGHT_TO_LEFT)) {
  1639. tmp_width = (unsigned long)fs_extents->max_ink_extent.width;
  1640. } else {
  1641. tmp_width = (unsigned long)fs_extents->max_logical_extent.width;
  1642. }
  1643. /* max_logical_extent.y is number of pixels from origin to top of
  1644. * rectangle (i.e. y is negative) */
  1645. font_ascent = -fs_extents->max_logical_extent.y;
  1646. font_descent = fs_extents->max_logical_extent.height +
  1647. fs_extents->max_logical_extent.y;
  1648. }
  1649. else {
  1650. /*
  1651. * Chose a font struct
  1652. */
  1653. font_ascent = font->max_bounds.ascent;
  1654. font_descent = font->max_bounds.descent;
  1655. if ( (!XGetFontProperty(font, XA_QUAD_WIDTH, &tmp_width)) ||
  1656. tmp_width == 0 )
  1657. {
  1658. if ( font->per_char && font->min_char_or_byte2 <= '0' &&
  1659. font->max_char_or_byte2 >= '0' )
  1660. tmp_width = font->per_char['0' - font->min_char_or_byte2].width;
  1661. else
  1662. tmp_width = font->max_bounds.width;
  1663. }
  1664. }
  1665. if (tmp_width <= 0) tmp_width = 1;
  1666. *width = (int)tmp_width; /* This assumes there will be no truncation */
  1667. *height = font_descent + font_ascent;
  1668. }
  1669. } /* end extractFontMetrics */
  1670. /*-------------------------------------------------------------
  1671. ** Function: static void getFontMetrics (
  1672. ** DtEditorWidget w )
  1673. **
  1674. ** Parameters: An Editor widget
  1675. **
  1676. ** Purpose: Determine the height & width of the scrolled text
  1677. ** widget's font
  1678. **
  1679. */
  1680. static void
  1681. getFontMetrics(
  1682. DtEditorWidget w)
  1683. {
  1684. Arg al[10]; /* arg list */
  1685. XmFontList fontlist;
  1686. int width, height;
  1687. /*
  1688. * Get the text widget's font list
  1689. *
  1690. * Note, have to retrieve the fontList from the text widget rather
  1691. * than use the DtNtextFontList resource because the text widget may
  1692. * have rejected the font specified with DtNtextFontList. This way
  1693. * we will get the fontList actually used by the text widget.
  1694. */
  1695. XtSetArg(al[0], XmNfontList, &fontlist);
  1696. XtGetValues(M_text(w), al, 1);
  1697. /*
  1698. * Now, extract the height and width
  1699. */
  1700. extractFontMetrics( w, fontlist, &height, &width );
  1701. M_fontWidth(w) = width;
  1702. M_fontHeight(w) = height;
  1703. } /* end getFontMetrics */
  1704. /*-------------------------------------------------------------
  1705. ** Destroy
  1706. ** Release resources allocated for a widget instance.
  1707. */
  1708. static void
  1709. Destroy(
  1710. Widget widget )
  1711. {
  1712. DtEditorWidget editor = (DtEditorWidget) widget;
  1713. /*
  1714. * Cleanup the edit window
  1715. */
  1716. /*
  1717. * (Nothing to be done. Unregistering it as a drop site is handled
  1718. * automatically by the DnD library.)
  1719. */
  1720. /*
  1721. * Cleanup the status line
  1722. */
  1723. if (M_status_insertLabel(editor) != (XmString)DtUNSPECIFIED)
  1724. XmStringFree(M_status_insertLabel(editor));
  1725. if (M_status_overstrikeLabel(editor) != (XmString)DtUNSPECIFIED)
  1726. XmStringFree(M_status_overstrikeLabel(editor));
  1727. if (E_status_currentLineLabel(editor) != (XmString)DtUNSPECIFIED)
  1728. XmStringFree(E_status_currentLineLabel(editor));
  1729. if (E_status_totalLineCountLabel(editor) != (XmString)DtUNSPECIFIED)
  1730. XmStringFree(E_status_totalLineCountLabel(editor));
  1731. /*
  1732. * Cleanup the Find/Change & Spell dialogs
  1733. */
  1734. if (M_search_string(editor))
  1735. XtFree(M_search_string(editor));
  1736. if (M_replace_string(editor))
  1737. XtFree(M_replace_string(editor));
  1738. if (M_misspelled_string(editor))
  1739. XtFree(M_misspelled_string(editor));
  1740. if (M_spellFilter(editor))
  1741. XtFree(M_spellFilter(editor));
  1742. if (M_spellTitle(editor) != (XmString)NULL)
  1743. XmStringFree(M_spellTitle(editor));
  1744. if (E_misspelledListLabel(editor) != (XmString)DtUNSPECIFIED)
  1745. XmStringFree(E_misspelledListLabel(editor));
  1746. if (M_fndChngTitle(editor) != (XmString)NULL)
  1747. XmStringFree(M_fndChngTitle(editor));
  1748. if (E_findFieldLabel(editor) != (XmString)DtUNSPECIFIED)
  1749. XmStringFree(E_findFieldLabel(editor));
  1750. if (E_changeFieldLabel(editor) != (XmString)DtUNSPECIFIED)
  1751. XmStringFree(E_changeFieldLabel(editor));
  1752. if (E_findButtonLabel(editor) != (XmString)DtUNSPECIFIED)
  1753. XmStringFree(E_findButtonLabel(editor));
  1754. if (E_changeButtonLabel(editor) != (XmString)DtUNSPECIFIED)
  1755. XmStringFree(E_changeButtonLabel(editor));
  1756. if (E_changeAllButtonLabel(editor) != (XmString)DtUNSPECIFIED)
  1757. XmStringFree(E_changeAllButtonLabel(editor));
  1758. /*
  1759. * Cleanup the Format Settings dialog
  1760. */
  1761. if (E_format_dialogTitle(editor) != (XmString)NULL)
  1762. XmStringFree(E_format_dialogTitle(editor));
  1763. if (E_format_leftMarginFieldLabel(editor) != (XmString)DtUNSPECIFIED)
  1764. XmStringFree(E_format_leftMarginFieldLabel(editor));
  1765. if (E_format_rightMarginFieldLabel(editor) != (XmString)DtUNSPECIFIED)
  1766. XmStringFree(E_format_rightMarginFieldLabel(editor));
  1767. if (E_format_leftAlignToggleLabel(editor) != (XmString)DtUNSPECIFIED)
  1768. XmStringFree(E_format_leftAlignToggleLabel(editor));
  1769. if (E_format_rightAlignToggleLabel(editor) != (XmString)DtUNSPECIFIED)
  1770. XmStringFree(E_format_rightAlignToggleLabel(editor));
  1771. if (E_format_justifyToggleLabel(editor) != (XmString)DtUNSPECIFIED)
  1772. XmStringFree(E_format_justifyToggleLabel(editor));
  1773. if (E_format_centerToggleLabel(editor) != (XmString)DtUNSPECIFIED)
  1774. XmStringFree(E_format_centerToggleLabel(editor));
  1775. if (E_format_formatAllButtonLabel(editor) != (XmString)DtUNSPECIFIED)
  1776. XmStringFree(E_format_formatAllButtonLabel(editor));
  1777. if (E_format_formatParagraphButtonLabel(editor) != (XmString)DtUNSPECIFIED)
  1778. XmStringFree(E_format_formatParagraphButtonLabel(editor));
  1779. /*
  1780. * Cleanup the Information dialog
  1781. */
  1782. if (E_infoDialogTitle(editor) != (XmString)NULL)
  1783. XmStringFree(E_infoDialogTitle(editor));
  1784. /*
  1785. * Cleanup the Undo deletion context
  1786. */
  1787. _DtEditorResetUndo(editor);
  1788. } /* end Destroy */
  1789. /*-------------------------------------------------------------
  1790. ** SetValues
  1791. ** Handle changes in resource data.
  1792. */
  1793. static Boolean
  1794. SetValues(
  1795. Widget cw,
  1796. Widget rw,
  1797. Widget nw )
  1798. {
  1799. Boolean redisplay_flag = False;
  1800. Arg al[15]; /* arg list */
  1801. int ac; /* arg count */
  1802. Boolean resetSpellTitle = False,
  1803. resetFormatTitle = False,
  1804. resetInfoTitle = False,
  1805. newButtonFontList = False,
  1806. newLabelFontList = False,
  1807. newTextFontList = False,
  1808. NeedToFixWordWrap = False; /* XXX Word Wrap workaround*/
  1809. DtEditorWidget current = (DtEditorWidget) cw;
  1810. DtEditorWidget request = (DtEditorWidget) rw;
  1811. DtEditorWidget new = (DtEditorWidget) nw;
  1812. /*
  1813. * XXX Need to propagate changes to Core resources, like XmNbackground,
  1814. * to the children.
  1815. */
  1816. /*
  1817. * If a synthetic resource is specified, clear the data field
  1818. * after setting the resource because the value in the field
  1819. * will be out of sync with the real value (contained in the
  1820. * child widget).
  1821. */
  1822. /*
  1823. * General changes, not directly affecting a child
  1824. */
  1825. /* Check for a new spell filter */
  1826. if ( strcmp(M_spellFilter(request), M_spellFilter(current)) != 0 )
  1827. {
  1828. XtFree( M_spellFilter(current) );
  1829. M_spellFilter(new) = XtNewString( M_spellFilter(request) );
  1830. }
  1831. /* Check for new font lists */
  1832. if ( E_buttonFontList(request) != E_buttonFontList(current) )
  1833. newButtonFontList = True;
  1834. if ( E_labelFontList(request) != E_labelFontList(current) )
  1835. newLabelFontList = True;
  1836. if ( E_textFontList(request) != E_textFontList(current) )
  1837. newTextFontList = True;
  1838. /*
  1839. * Check for any changes which affect the dialog titles
  1840. */
  1841. if (XmStringCompare(E_dialogTitle(request),E_dialogTitle(current)) == False) {
  1842. resetSpellTitle = resetFormatTitle = resetInfoTitle = True;
  1843. }
  1844. if (XmStringCompare(M_spellTitle(request),M_spellTitle(current)) == False) {
  1845. XmStringFree( M_spellTitle(current) );
  1846. M_spellTitle(new) = XmStringCopy( M_spellTitle(request) );
  1847. resetSpellTitle = True;
  1848. }
  1849. if (XmStringCompare(M_fndChngTitle(request),M_fndChngTitle(current)) == False)
  1850. {
  1851. XmStringFree( M_fndChngTitle(current) );
  1852. M_fndChngTitle(new) = XmStringCopy( M_fndChngTitle(request) );
  1853. resetSpellTitle = True;
  1854. }
  1855. if (XmStringCompare(E_format_dialogTitle(request),
  1856. E_format_dialogTitle(current) ) == False)
  1857. {
  1858. XmStringFree( E_format_dialogTitle(current) );
  1859. E_format_dialogTitle(new) = XmStringCopy( E_format_dialogTitle(request) );
  1860. resetFormatTitle = True;
  1861. }
  1862. if (XmStringCompare(E_infoDialogTitle(request),
  1863. E_infoDialogTitle(current) ) == False)
  1864. {
  1865. XmStringFree( E_infoDialogTitle(current) );
  1866. E_infoDialogTitle(new) = XmStringCopy( E_infoDialogTitle(request) );
  1867. resetInfoTitle = True;
  1868. }
  1869. /*
  1870. * Calculate new titles for the dialogs depending upon which resources
  1871. * changed.
  1872. */
  1873. if ( resetSpellTitle == True ) {
  1874. /*
  1875. * No need to do anything because the Spell and Find/Change dialog
  1876. * titles are recomputed every time.
  1877. */
  1878. redisplay_flag = True;
  1879. }
  1880. if ( resetFormatTitle == True ) {
  1881. SetFormatDialogTitle( new );
  1882. redisplay_flag = True;
  1883. }
  1884. if ( resetInfoTitle == True ) {
  1885. SetInfoDialogTitle( new );
  1886. redisplay_flag = True;
  1887. }
  1888. /*
  1889. * Check for any changes which affect the status line
  1890. */
  1891. if (M_status_showStatusLine(request) != M_status_showStatusLine(current)) {
  1892. SetStatusLine( new, M_status_showStatusLine(request) );
  1893. redisplay_flag = True;
  1894. }
  1895. if ( M_overstrikeMode(request) != M_overstrikeMode(current) ) {
  1896. UpdateOverstrikeIndicator( new, M_overstrikeMode(request) );
  1897. XtCallActionProc( (Widget) M_text(current), "toggle-overstrike",
  1898. (XEvent *)NULL, (String *)NULL, 0 );
  1899. redisplay_flag = True;
  1900. }
  1901. if ( M_status_statusArea(current) != (Widget)NULL ) {
  1902. if (newLabelFontList == True) {
  1903. XtSetArg (al[0], XmNfontList, E_labelFontList(request) );
  1904. XtSetValues( (Widget) M_status_lineLabel(current), al, 1);
  1905. XtSetValues( (Widget) M_status_totalLabel(current), al, 1);
  1906. XtSetValues( (Widget) M_status_totalText(current), al, 1);
  1907. XtSetValues( (Widget) M_status_overstrikeWidget(current), al, 1);
  1908. }
  1909. ac=0;
  1910. if (newTextFontList == True) {
  1911. XtSetArg( al[ac], XmNfontList, E_textFontList(request) ); ac++;
  1912. }
  1913. if ( M_textBackground(request) != DtUNSPECIFIED) {
  1914. XtSetArg( al[ac], XmNbackground, M_textBackground(request) ); ac++;
  1915. }
  1916. if ( M_textForeground(request) != DtUNSPECIFIED) {
  1917. XtSetArg( al[ac], XmNforeground, M_textForeground(request) ); ac++;
  1918. }
  1919. if ( ac ) {
  1920. XtSetValues( (Widget) M_status_lineText(current), al, ac);
  1921. XtSetValues( (Widget) M_status_messageText(current), al, ac);
  1922. }
  1923. }
  1924. /*
  1925. * Check for any changes which affect the dialog boxes
  1926. */
  1927. /* Information dialog */
  1928. if ( M_gen_warning(current) != (Widget)NULL ) {
  1929. if ( newButtonFontList == True ) {
  1930. XtSetArg (al[0], XmNfontList, E_buttonFontList(request) );
  1931. XtSetValues(
  1932. XmMessageBoxGetChild(M_gen_warning(current), XmDIALOG_OK_BUTTON),
  1933. al, 1 );
  1934. }
  1935. if ( newLabelFontList == True ) {
  1936. XtSetArg (al[0], XmNfontList, E_labelFontList(request) );
  1937. XtSetValues(
  1938. XmMessageBoxGetChild(M_gen_warning(current), XmDIALOG_MESSAGE_LABEL),
  1939. al, 1 );
  1940. }
  1941. }
  1942. /* Find/Change dialog */
  1943. if ( M_search_dialog(current) != (Widget)NULL )
  1944. {
  1945. if ( newButtonFontList == True ) {
  1946. XtSetArg (al[0], XmNfontList, E_buttonFontList(request));
  1947. XtSetValues( (Widget)M_search_findBtn(current), al, 1 );
  1948. XtSetValues( (Widget)M_search_replaceBtn(current), al, 1 );
  1949. XtSetValues( (Widget)M_search_replaceAllBtn(current), al, 1 );
  1950. XtSetValues( (Widget)M_search_closeBtn(current), al, 1 );
  1951. XtSetValues( (Widget)M_search_helpBtn(current), al, 1 );
  1952. }
  1953. if ( newLabelFontList == True ) {
  1954. XtSetArg (al[0], XmNfontList, E_labelFontList(request) );
  1955. XtSetValues( (Widget)M_search_listLbl(current), al, 1 );
  1956. XtSetValues( (Widget)M_search_findLbl(current), al, 1 );
  1957. XtSetValues( (Widget)M_search_replaceLbl(current), al, 1);
  1958. }
  1959. if ( newTextFontList == True ) {
  1960. XtSetArg (al[0], XmNfontList, E_textFontList(request) );
  1961. XtSetValues( (Widget)M_search_spellList(current), al, 1);
  1962. XtSetValues( (Widget)M_findText(current), al, 1 );
  1963. XtSetValues( (Widget)M_replaceText(current), al, 1 );
  1964. }
  1965. ac=0;
  1966. if ( M_textBackground(request) != DtUNSPECIFIED) {
  1967. XtSetArg( al[ac], XmNbackground, M_textBackground(request) ); ac++;
  1968. }
  1969. if ( M_textForeground(request) != DtUNSPECIFIED) {
  1970. XtSetArg( al[ac], XmNforeground, M_textForeground(request) ); ac++;
  1971. }
  1972. if ( ac ) {
  1973. XtSetValues( (Widget) M_findText(current), al, ac);
  1974. XtSetValues( (Widget) M_replaceText(current), al, ac);
  1975. }
  1976. }
  1977. /* Format Settings dialog */
  1978. if ( M_format_dialog(current) != (Widget)NULL )
  1979. {
  1980. if ( newButtonFontList == True ) {
  1981. XtSetArg (al[0], XmNfontList, E_buttonFontList(request));
  1982. XtSetValues( (Widget)M_format_leftJust(current), al, 1 );
  1983. XtSetValues( (Widget)M_format_rightJust(current), al, 1);
  1984. XtSetValues( (Widget)M_format_bothJust(current), al, 1 );
  1985. XtSetValues( (Widget)M_format_center(current), al, 1 );
  1986. XtSetValues( (Widget)M_format_paragraph(current), al, 1);
  1987. XtSetValues( (Widget)M_format_all(current), al, 1 );
  1988. XtSetValues( (Widget)M_format_close(current), al, 1 );
  1989. XtSetValues( (Widget)M_format_help(current), al, 1 );
  1990. }
  1991. if ( newLabelFontList == True ) {
  1992. XtSetArg (al[0], XmNfontList, E_labelFontList(request) );
  1993. XtSetValues( (Widget)M_format_leftLabel(current), al, 1 );
  1994. XtSetValues( (Widget)M_format_rightLabel(current), al, 1);
  1995. }
  1996. if ( newTextFontList == True ) {
  1997. XtSetArg (al[0], XmNfontList, E_textFontList(request) );
  1998. XtSetValues( (Widget)M_format_leftMarginField(current), al, 1 );
  1999. XtSetValues( (Widget)M_format_rightMarginField(current), al, 1);
  2000. }
  2001. ac=0;
  2002. if ( M_textBackground(request) != DtUNSPECIFIED) {
  2003. XtSetArg( al[ac], XmNbackground, M_textBackground(request) ); ac++;
  2004. }
  2005. if ( M_textForeground(request) != DtUNSPECIFIED) {
  2006. XtSetArg( al[ac], XmNforeground, M_textForeground(request) ); ac++;
  2007. }
  2008. if ( ac ) {
  2009. XtSetValues( (Widget) M_format_leftMarginField(current), al, ac);
  2010. XtSetValues( (Widget) M_format_rightMarginField(current), al, ac);
  2011. }
  2012. }
  2013. /*
  2014. * Check for any changes which affect the edit area (scrolled text widget)
  2015. */
  2016. ac=0;
  2017. if ( M_autoShowCursorPos(request) != M_autoShowCursorPos(current) ) {
  2018. XtSetArg( al[ac], XmNautoShowCursorPosition, M_autoShowCursorPos(request));
  2019. ac++;
  2020. }
  2021. if ( M_blinkRate(request) != M_blinkRate(current) ) {
  2022. XtSetArg( al[ac], XmNblinkRate, M_blinkRate(request)); ac++;
  2023. }
  2024. if ( M_columns(request) != DtUNSPECIFIED) {
  2025. XtSetArg (al[ac], XmNcolumns, M_columns(request) ); ac++;
  2026. M_columns(new) = (short) DtUNSPECIFIED;
  2027. redisplay_flag = True;
  2028. }
  2029. /* PERF - disable redisplay for all SetValues */
  2030. if ( M_cursorPos(request) != DtUNSPECIFIED) {
  2031. XmTextSetCursorPosition( M_text(new), M_topCharacter(request) );
  2032. M_cursorPos(new) = (XmTextPosition) DtUNSPECIFIED;
  2033. }
  2034. if ( M_cursorPosVisible(request) != M_cursorPosVisible(current) ) {
  2035. XtSetArg( al[ac], XmNcursorPositionVisible, M_cursorPosVisible(request));
  2036. ac++;
  2037. }
  2038. if ( M_editable(request) != M_editable(current) ) {
  2039. XtSetArg( al[ac], XmNeditable, M_editable(request)); ac++;
  2040. if( M_editable(request) ) {
  2041. /*
  2042. * If the widget is becoming editable, register it as a
  2043. * drop site and...
  2044. */
  2045. RegisterDropZone( new );
  2046. /*
  2047. * ...turn back on the Change To field in the Find/Change dialog
  2048. */
  2049. if ( M_search_dialog(current) != (Widget)NULL ) {
  2050. XtSetSensitive(M_search_replaceLbl(current), True);
  2051. XtSetSensitive(M_replaceText(current), True);
  2052. }
  2053. }
  2054. else
  2055. /*
  2056. * It's no longer available as a drop site.
  2057. */
  2058. UnregisterDropZone( current );
  2059. }
  2060. if ( M_maxLength(request) != DtUNSPECIFIED) {
  2061. XtSetArg (al[ac], XmNmaxLength, M_maxLength(request) ); ac++;
  2062. M_maxLength(new) = (int) DtUNSPECIFIED;
  2063. }
  2064. if ( M_rows(request) != DtUNSPECIFIED) {
  2065. XtSetArg (al[ac], XmNrows, M_rows(request) ); ac++;
  2066. M_rows(new) = (short) DtUNSPECIFIED;
  2067. redisplay_flag = True;
  2068. }
  2069. if ( M_textBackground(request) != DtUNSPECIFIED) {
  2070. XtSetArg (al[ac], XmNbackground, M_textBackground(request) ); ac++;
  2071. M_textBackground(new) = (XmTextPosition) DtUNSPECIFIED;
  2072. redisplay_flag = True;
  2073. }
  2074. if ( newTextFontList == True ) {
  2075. XtSetArg (al[ac], XmNfontList, E_textFontList(request) ); ac++;
  2076. redisplay_flag = True;
  2077. }
  2078. if ( M_textForeground(request) != DtUNSPECIFIED) {
  2079. XtSetArg (al[ac], XmNforeground, M_textForeground(request) ); ac++;
  2080. M_textForeground(new) = (XmTextPosition) DtUNSPECIFIED;
  2081. redisplay_flag = True;
  2082. }
  2083. /* PERF - disable redisplay for all SetValues */
  2084. if ( M_topCharacter(request) != DtUNSPECIFIED) {
  2085. XmTextSetTopCharacter( M_text(new), M_topCharacter(request) );
  2086. M_topCharacter(new) = (XmTextPosition) DtUNSPECIFIED;
  2087. }
  2088. if ( M_wordWrap(request) != M_wordWrap(current) ) {
  2089. XtSetArg( al[ac], XmNwordWrap, M_wordWrap(request)); ac++;
  2090. NeedToFixWordWrap=M_scrollHorizontal(current);/*XXX Word Wrap workaround*/
  2091. }
  2092. if ( NeedToFixWordWrap ) /*XXX Word Wrap workaround*/
  2093. FixWordWrap(M_text(new), M_wordWrap(request));/*XXX Word Wrap workaround*/
  2094. if ( ac )
  2095. XtSetValues( (Widget) M_text(new), al, ac);
  2096. if ( E_textTranslations(request) != E_textTranslations(current) ) {
  2097. XtOverrideTranslations(M_text(new), E_textTranslations(request));
  2098. }
  2099. if ( newTextFontList == True ) {
  2100. getFontMetrics(new);
  2101. }
  2102. return (redisplay_flag);
  2103. } /* end Set values */
  2104. /**************************************************************
  2105. **
  2106. ** Get values routines for synthetic resources
  2107. **
  2108. **/
  2109. static void
  2110. _DtEditorGetCenterToggleLabel(
  2111. Widget wid,
  2112. int resource_offset,
  2113. XtArgVal *value )
  2114. {
  2115. DtEditorWidget editor = (DtEditorWidget) wid;
  2116. XmString data;
  2117. Arg al[1];
  2118. /*
  2119. * Get the value directly from the field in the instance structure.
  2120. * If it is DtUNSPECIFIED then either:
  2121. * 1) the value has been assigned to the widget (so get it from
  2122. * there), or
  2123. * 2) the value has never been set (so return the default value).
  2124. */
  2125. if (E_format_centerToggleLabel(editor) != (XmString) DtUNSPECIFIED)
  2126. data = XmStringCopy( E_format_centerToggleLabel(editor) );
  2127. else if (M_format_dialog(editor) != (Widget)NULL)
  2128. {
  2129. XtSetArg( al[0], XmNlabelString, &data) ;
  2130. XtGetValues( (Widget) M_format_center(editor), al, 1) ;
  2131. }
  2132. else
  2133. data = XmStringCreateLocalized(CENTER);
  2134. *value = (XtArgVal) data ;
  2135. return;
  2136. } /* end _DtEditorGetCenterToggleLabel */
  2137. static void
  2138. _DtEditorGetChangeAllButtonLabel(
  2139. Widget wid,
  2140. int resource_offset,
  2141. XtArgVal *value )
  2142. {
  2143. DtEditorWidget editor = (DtEditorWidget) wid;
  2144. XmString data;
  2145. Arg al[1];
  2146. /*
  2147. * Get the value directly from the field in the instance structure.
  2148. * If it is DtUNSPECIFIED then either:
  2149. * 1) the value has been assigned to the widget (so get it from
  2150. * there), or
  2151. * 2) the value has never been set (so return the default value).
  2152. */
  2153. if (E_changeAllButtonLabel(editor) != (XmString) DtUNSPECIFIED)
  2154. data = XmStringCopy( E_changeAllButtonLabel(editor) );
  2155. else if (M_search_dialog(editor) != (Widget) NULL)
  2156. {
  2157. XtSetArg( al[0], XmNlabelString, &data) ;
  2158. XtGetValues( (Widget) M_search_replaceAllBtn(editor), al, 1) ;
  2159. }
  2160. else
  2161. data = XmStringCreateLocalized(CHNG_ALL_BUTTON);
  2162. *value = (XtArgVal) data ;
  2163. return;
  2164. } /* end _DtEditorGetChangeAllButtonLabel */
  2165. static void
  2166. _DtEditorGetChangeButtonLabel(
  2167. Widget wid,
  2168. int resource_offset,
  2169. XtArgVal *value )
  2170. {
  2171. DtEditorWidget editor = (DtEditorWidget) wid;
  2172. XmString data;
  2173. Arg al[1];
  2174. /*
  2175. * Get the value directly from the field in the instance structure.
  2176. * If it is DtUNSPECIFIED then either:
  2177. * 1) the value has been assigned to the widget (so get it from
  2178. * there), or
  2179. * 2) the value has never been set (so return the default value).
  2180. */
  2181. if (E_changeButtonLabel(editor) != (XmString) DtUNSPECIFIED)
  2182. data = XmStringCopy( E_changeButtonLabel(editor) );
  2183. else if (M_search_dialog(editor) != (Widget) NULL)
  2184. {
  2185. XtSetArg( al[0], XmNlabelString, &data) ;
  2186. XtGetValues( (Widget) M_search_replaceBtn(editor), al, 1) ;
  2187. }
  2188. else
  2189. data = XmStringCreateLocalized(CHANGE_BUTTON);
  2190. *value = (XtArgVal) data ;
  2191. return;
  2192. } /* end _DtEditorGetChangeButtonLabel */
  2193. static void
  2194. _DtEditorGetChangeFieldLabel(
  2195. Widget wid,
  2196. int resource_offset,
  2197. XtArgVal *value )
  2198. {
  2199. DtEditorWidget editor = (DtEditorWidget) wid;
  2200. XmString data;
  2201. Arg al[1];
  2202. /*
  2203. * Get the value directly from the field in the instance structure.
  2204. * If it is DtUNSPECIFIED then either:
  2205. * 1) the value has been assigned to the widget (so get it from
  2206. * there), or
  2207. * 2) the value has never been set (so return the default value).
  2208. */
  2209. if (E_changeFieldLabel(editor) != (XmString) DtUNSPECIFIED)
  2210. data = XmStringCopy( E_changeFieldLabel(editor) );
  2211. else if (M_search_dialog(editor) != (Widget) NULL)
  2212. {
  2213. XtSetArg( al[0], XmNlabelString, &data) ;
  2214. XtGetValues( (Widget) M_search_replaceLbl(editor), al, 1) ;
  2215. }
  2216. else
  2217. data = XmStringCreateLocalized(CHANGE_LABEL);
  2218. *value = (XtArgVal) data ;
  2219. return;
  2220. } /* end _DtEditorGetChangeFieldLabel */
  2221. static void
  2222. _DtEditorGetColumns(
  2223. Widget wid,
  2224. int resource_offset,
  2225. XtArgVal *value )
  2226. {
  2227. DtEditorWidget editor = (DtEditorWidget) wid;
  2228. short data;
  2229. Arg al[1];
  2230. XtSetArg( al[0], XmNcolumns, &data) ;
  2231. XtGetValues( (Widget) M_text(editor), al, 1) ;
  2232. *value = (XtArgVal) data ;
  2233. return;
  2234. } /* end _DtEditorGetColumns */
  2235. static void
  2236. _DtEditorGetCurrentLineLabel(
  2237. Widget wid,
  2238. int resource_offset,
  2239. XtArgVal *value )
  2240. {
  2241. DtEditorWidget editor = (DtEditorWidget) wid;
  2242. XmString data;
  2243. Arg al[1];
  2244. /*
  2245. * Get the value directly from the field in the instance structure.
  2246. * If it is DtUNSPECIFIED then either:
  2247. * 1) the value has been assigned to the widget (so get it from
  2248. * there), or
  2249. * 2) the value has never been set (so return the default value).
  2250. */
  2251. if (E_status_currentLineLabel(editor) != (XmString) DtUNSPECIFIED)
  2252. data = XmStringCopy( E_status_currentLineLabel(editor) );
  2253. else if (M_status_statusArea(editor) != (Widget) NULL)
  2254. {
  2255. XtSetArg( al[0], XmNlabelString, &data) ;
  2256. XtGetValues( (Widget) M_status_lineLabel(editor), al, 1) ;
  2257. }
  2258. else
  2259. data = XmStringCreateLocalized(LINE);
  2260. *value = (XtArgVal) data ;
  2261. return;
  2262. } /* end _DtEditorGetCurrentLineLabel */
  2263. static void
  2264. _DtEditorGetCursorPosition(
  2265. Widget wid,
  2266. int resource_offset,
  2267. XtArgVal *value )
  2268. {
  2269. DtEditorWidget editor = (DtEditorWidget) wid;
  2270. XmTextPosition data;
  2271. Arg al[1];
  2272. XtSetArg( al[0], XmNcursorPosition, &data) ;
  2273. XtGetValues( (Widget) M_text(editor), al, 1) ;
  2274. *value = (XtArgVal) data ;
  2275. return;
  2276. } /* end _DtEditorGetCursorPosition */
  2277. static void
  2278. _DtEditorGetFindButtonLabel(
  2279. Widget wid,
  2280. int resource_offset,
  2281. XtArgVal *value )
  2282. {
  2283. DtEditorWidget editor = (DtEditorWidget) wid;
  2284. XmString data;
  2285. Arg al[1];
  2286. /*
  2287. * Get the value directly from the field in the instance structure.
  2288. * If it is DtUNSPECIFIED then either:
  2289. * 1) the value has been assigned to the widget (so get it from
  2290. * there), or
  2291. * 2) the value has never been set (so return the default value).
  2292. */
  2293. if (E_findButtonLabel(editor) != (XmString) DtUNSPECIFIED)
  2294. data = XmStringCopy( E_findButtonLabel(editor) );
  2295. else if (M_search_dialog(editor) != (Widget) NULL)
  2296. {
  2297. XtSetArg( al[0], XmNlabelString, &data) ;
  2298. XtGetValues( (Widget) M_search_findBtn(editor), al, 1) ;
  2299. }
  2300. else
  2301. data = XmStringCreateLocalized(FIND_BUTTON);
  2302. *value = (XtArgVal) data ;
  2303. return;
  2304. } /* end _DtEditorGetFindButtonLabel */
  2305. static void
  2306. _DtEditorGetFindFieldLabel(
  2307. Widget wid,
  2308. int resource_offset,
  2309. XtArgVal *value )
  2310. {
  2311. DtEditorWidget editor = (DtEditorWidget) wid;
  2312. XmString data;
  2313. Arg al[1];
  2314. /*
  2315. * Get the value directly from the field in the instance structure.
  2316. * If it is DtUNSPECIFIED then either:
  2317. * 1) the value has been assigned to the widget (so get it from
  2318. * there), or
  2319. * 2) the value has never been set (so return the default value).
  2320. */
  2321. if (E_findFieldLabel(editor) != (XmString) DtUNSPECIFIED)
  2322. data = XmStringCopy( E_findFieldLabel(editor) );
  2323. else if (M_search_dialog(editor) != (Widget) NULL)
  2324. {
  2325. XtSetArg( al[0], XmNlabelString, &data) ;
  2326. XtGetValues( (Widget) M_search_findLbl(editor), al, 1) ;
  2327. }
  2328. else
  2329. data = XmStringCreateLocalized(FIND_LABEL);
  2330. *value = (XtArgVal) data ;
  2331. return;
  2332. } /* end _DtEditorGetFindFieldLabel */
  2333. static void
  2334. _DtEditorGetFormatAllButtonLabel(
  2335. Widget wid,
  2336. int resource_offset,
  2337. XtArgVal *value )
  2338. {
  2339. DtEditorWidget editor = (DtEditorWidget) wid;
  2340. XmString data;
  2341. Arg al[1];
  2342. /*
  2343. * Get the value directly from the field in the instance structure.
  2344. * If it is DtUNSPECIFIED then either:
  2345. * 1) the value has been assigned to the widget (so get it from
  2346. * there), or
  2347. * 2) the value has never been set (so return the default value).
  2348. */
  2349. if (E_format_formatAllButtonLabel(editor) != (XmString) DtUNSPECIFIED)
  2350. data = XmStringCopy( E_format_formatAllButtonLabel(editor) );
  2351. else if (M_format_dialog(editor) != (Widget)NULL)
  2352. {
  2353. XtSetArg( al[0], XmNlabelString, &data) ;
  2354. XtGetValues( (Widget) M_format_all(editor), al, 1) ;
  2355. }
  2356. else
  2357. data = XmStringCreateLocalized(ALL);
  2358. *value = (XtArgVal) data ;
  2359. return;
  2360. } /* end _DtEditorGetFormatAllButtonLabel */
  2361. static void
  2362. _DtEditorGetFormatParagraphButtonLabel(
  2363. Widget wid,
  2364. int resource_offset,
  2365. XtArgVal *value )
  2366. {
  2367. DtEditorWidget editor = (DtEditorWidget) wid;
  2368. XmString data;
  2369. Arg al[1];
  2370. /*
  2371. * Get the value directly from the field in the instance structure.
  2372. * If it is DtUNSPECIFIED then either:
  2373. * 1) the value has been assigned to the widget (so get it from
  2374. * there), or
  2375. * 2) the value has never been set (so return the default value).
  2376. */
  2377. if(E_format_formatParagraphButtonLabel(editor) != (XmString) DtUNSPECIFIED)
  2378. data = XmStringCopy( E_format_formatParagraphButtonLabel(editor) );
  2379. else if (M_format_dialog(editor) != (Widget)NULL)
  2380. {
  2381. XtSetArg( al[0], XmNlabelString, &data) ;
  2382. XtGetValues( (Widget) M_format_paragraph(editor), al, 1) ;
  2383. }
  2384. else
  2385. data = XmStringCreateLocalized(PARAGRAPH);
  2386. *value = (XtArgVal) data ;
  2387. return;
  2388. } /* end _DtEditorGetFormatParagraphButtonLabel */
  2389. static void
  2390. _DtEditorGetJustifyToggleLabel(
  2391. Widget wid,
  2392. int resource_offset,
  2393. XtArgVal *value )
  2394. {
  2395. DtEditorWidget editor = (DtEditorWidget) wid;
  2396. XmString data;
  2397. Arg al[1];
  2398. /*
  2399. * Get the value directly from the field in the instance structure.
  2400. * If it is DtUNSPECIFIED then either:
  2401. * 1) the value has been assigned to the widget (so get it from
  2402. * there), or
  2403. * 2) the value has never been set (so return the default value).
  2404. */
  2405. if (E_format_justifyToggleLabel(editor) != (XmString) DtUNSPECIFIED)
  2406. data = XmStringCopy( E_format_justifyToggleLabel(editor) );
  2407. else if (M_format_dialog(editor) != (Widget)NULL)
  2408. {
  2409. XtSetArg( al[0], XmNlabelString, &data) ;
  2410. XtGetValues( (Widget) M_format_bothJust(editor), al, 1) ;
  2411. }
  2412. else
  2413. data = XmStringCreateLocalized(JUSTIFY);
  2414. *value = (XtArgVal) data ;
  2415. return;
  2416. } /* end _DtEditorGetJustifyToggleLabel */
  2417. static void
  2418. _DtEditorGetLeftAlignToggleLabel(
  2419. Widget wid,
  2420. int resource_offset,
  2421. XtArgVal *value )
  2422. {
  2423. DtEditorWidget editor = (DtEditorWidget) wid;
  2424. XmString data;
  2425. Arg al[1];
  2426. /*
  2427. * Get the value directly from the field in the instance structure.
  2428. * If it is DtUNSPECIFIED then either:
  2429. * 1) the value has been assigned to the widget (so get it from
  2430. * there), or
  2431. * 2) the value has never been set (so return the default value).
  2432. */
  2433. if (E_format_leftAlignToggleLabel(editor) != (XmString) DtUNSPECIFIED)
  2434. data = XmStringCopy( E_format_leftAlignToggleLabel(editor) );
  2435. else if (M_format_dialog(editor) != (Widget)NULL)
  2436. {
  2437. XtSetArg( al[0], XmNlabelString, &data) ;
  2438. XtGetValues( (Widget) M_format_leftJust(editor), al, 1) ;
  2439. }
  2440. else
  2441. data = XmStringCreateLocalized(LEFT_ALIGN);
  2442. *value = (XtArgVal) data ;
  2443. return;
  2444. } /* end _DtEditorGetLeftAlignToggleLabel */
  2445. static void
  2446. _DtEditorGetLeftMarginFieldLabel(
  2447. Widget wid,
  2448. int resource_offset,
  2449. XtArgVal *value )
  2450. {
  2451. DtEditorWidget editor = (DtEditorWidget) wid;
  2452. XmString data;
  2453. Arg al[1];
  2454. /*
  2455. * Get the value directly from the field in the instance structure.
  2456. * If it is DtUNSPECIFIED then either:
  2457. * 1) the value has been assigned to the widget (so get it from
  2458. * there), or
  2459. * 2) the value has never been set (so return the default value).
  2460. */
  2461. if (E_format_leftMarginFieldLabel(editor) != (XmString) DtUNSPECIFIED)
  2462. data = XmStringCopy( E_format_leftMarginFieldLabel(editor) );
  2463. else if (M_format_dialog(editor) != (Widget)NULL)
  2464. {
  2465. XtSetArg( al[0], XmNlabelString, &data) ;
  2466. XtGetValues( (Widget) M_format_leftLabel(editor), al, 1) ;
  2467. }
  2468. else
  2469. data = XmStringCreateLocalized(LEFT_MARGIN);
  2470. *value = (XtArgVal) data ;
  2471. return;
  2472. } /* end _DtEditorGetLeftMarginFieldLabel */
  2473. static void
  2474. _DtEditorGetMaxLength(
  2475. Widget wid,
  2476. int resource_offset,
  2477. XtArgVal *value )
  2478. {
  2479. DtEditorWidget editor = (DtEditorWidget) wid;
  2480. int data;
  2481. Arg al[1];
  2482. XtSetArg( al[0], XmNmaxLength, &data) ;
  2483. XtGetValues( (Widget) M_text(editor), al, 1) ;
  2484. *value = (XtArgVal) data ;
  2485. return;
  2486. } /* end _DtEditorGetMaxLength */
  2487. static void
  2488. _DtEditorGetMisspelledListLabel(
  2489. Widget wid,
  2490. int resource_offset,
  2491. XtArgVal *value )
  2492. {
  2493. DtEditorWidget editor = (DtEditorWidget) wid;
  2494. XmString data;
  2495. Arg al[1];
  2496. /*
  2497. * Get the value directly from the field in the instance structure.
  2498. * If it is DtUNSPECIFIED then either:
  2499. * 1) the value has been assigned to the widget (so get it from
  2500. * there), or
  2501. * 2) the value has never been set (so return the default value).
  2502. */
  2503. if (E_misspelledListLabel(editor) != (XmString) DtUNSPECIFIED)
  2504. data = XmStringCopy( E_misspelledListLabel(editor) );
  2505. else if (M_search_dialog(editor) != (Widget) NULL)
  2506. {
  2507. XtSetArg( al[0], XmNlabelString, &data) ;
  2508. XtGetValues( (Widget) M_search_listLbl(editor), al, 1) ;
  2509. }
  2510. else
  2511. data = XmStringCreateLocalized(MISSPELLED);
  2512. *value = (XtArgVal) data ;
  2513. return;
  2514. } /* end _DtEditorGetMisspelledListLabel */
  2515. static void
  2516. _DtEditorGetRightAlignToggleLabel(
  2517. Widget wid,
  2518. int resource_offset,
  2519. XtArgVal *value )
  2520. {
  2521. DtEditorWidget editor = (DtEditorWidget) wid;
  2522. XmString data;
  2523. Arg al[1];
  2524. /*
  2525. * Get the value directly from the field in the instance structure.
  2526. * If it is DtUNSPECIFIED then either:
  2527. * 1) the value has been assigned to the widget (so get it from
  2528. * there), or
  2529. * 2) the value has never been set (so return the default value).
  2530. */
  2531. if (E_format_rightAlignToggleLabel(editor) != (XmString) DtUNSPECIFIED)
  2532. data = XmStringCopy( E_format_rightAlignToggleLabel(editor) );
  2533. else if (M_format_dialog(editor) != (Widget)NULL)
  2534. {
  2535. XtSetArg( al[0], XmNlabelString, &data) ;
  2536. XtGetValues( (Widget) M_format_rightJust(editor), al, 1) ;
  2537. }
  2538. else
  2539. data = XmStringCreateLocalized(RIGHT_ALIGN);
  2540. *value = (XtArgVal) data ;
  2541. return;
  2542. } /* end _DtEditorGetRightAlignToggleLabel */
  2543. static void
  2544. _DtEditorGetRightMarginFieldLabel(
  2545. Widget wid,
  2546. int resource_offset,
  2547. XtArgVal *value )
  2548. {
  2549. DtEditorWidget editor = (DtEditorWidget) wid;
  2550. XmString data;
  2551. Arg al[1];
  2552. /*
  2553. * Get the value directly from the field in the instance structure.
  2554. * If it is DtUNSPECIFIED then either:
  2555. * 1) the value has been assigned to the widget (so get it from
  2556. * there), or
  2557. * 2) the value has never been set (so return the default value).
  2558. */
  2559. if (E_format_rightMarginFieldLabel(editor) != (XmString) DtUNSPECIFIED)
  2560. data = XmStringCopy( E_format_rightMarginFieldLabel(editor) );
  2561. else if (M_format_dialog(editor) != (Widget)NULL)
  2562. {
  2563. XtSetArg( al[0], XmNlabelString, &data) ;
  2564. XtGetValues( (Widget) M_format_rightLabel(editor), al, 1) ;
  2565. }
  2566. else
  2567. data = XmStringCreateLocalized(RIGHT_MARGIN);
  2568. *value = (XtArgVal) data ;
  2569. return;
  2570. } /* end _DtEditorGetRightMarginFieldLabel */
  2571. static void
  2572. _DtEditorGetRows(
  2573. Widget wid,
  2574. int resource_offset,
  2575. XtArgVal *value )
  2576. {
  2577. DtEditorWidget editor = (DtEditorWidget) wid;
  2578. short data;
  2579. Arg al[1];
  2580. XtSetArg( al[0], XmNrows, &data) ;
  2581. XtGetValues( (Widget) M_text(editor), al, 1) ;
  2582. *value = (XtArgVal) data ;
  2583. return;
  2584. } /* end _DtEditorGetRows */
  2585. static void
  2586. _DtEditorGetScrollLeftSide(
  2587. Widget wid,
  2588. int resource_offset,
  2589. XtArgVal *value )
  2590. {
  2591. DtEditorWidget editor = (DtEditorWidget) wid;
  2592. Boolean data;
  2593. Arg al[1];
  2594. XtSetArg( al[0], XmNscrollLeftSide, &data) ;
  2595. XtGetValues( (Widget) M_text(editor), al, 1) ;
  2596. *value = (XtArgVal) data ;
  2597. return;
  2598. } /* end _DtEditorGetScrollLeftSide */
  2599. static void
  2600. _DtEditorGetScrollTopSide(
  2601. Widget wid,
  2602. int resource_offset,
  2603. XtArgVal *value )
  2604. {
  2605. DtEditorWidget editor = (DtEditorWidget) wid;
  2606. Boolean data;
  2607. Arg al[1];
  2608. XtSetArg( al[0], XmNscrollTopSide, &data) ;
  2609. XtGetValues( (Widget) M_text(editor), al, 1) ;
  2610. *value = (XtArgVal) data ;
  2611. return;
  2612. } /* end _DtEditorGetScrollTopSide */
  2613. static void
  2614. _DtEditorGetTextBackground(
  2615. Widget wid,
  2616. int resource_offset,
  2617. XtArgVal *value )
  2618. {
  2619. DtEditorWidget editor = (DtEditorWidget) wid;
  2620. Pixel data;
  2621. Arg al[1];
  2622. XtSetArg( al[0], XmNbackground, &data) ;
  2623. XtGetValues( (Widget) M_text(editor), al, 1) ;
  2624. *value = (XtArgVal) data ;
  2625. return;
  2626. } /* end _DtEditorGetTextBackground */
  2627. static void
  2628. _DtEditorGetTextForeground(
  2629. Widget wid,
  2630. int resource_offset,
  2631. XtArgVal *value )
  2632. {
  2633. DtEditorWidget editor = (DtEditorWidget) wid;
  2634. Pixel data;
  2635. Arg al[1];
  2636. XtSetArg( al[0], XmNforeground, &data) ;
  2637. XtGetValues( (Widget) M_text(editor), al, 1) ;
  2638. *value = (XtArgVal) data ;
  2639. return;
  2640. } /* end _DtEditorGetTextForeground */
  2641. static void
  2642. _DtEditorGetTopCharacter(
  2643. Widget wid,
  2644. int resource_offset,
  2645. XtArgVal *value )
  2646. {
  2647. DtEditorWidget editor = (DtEditorWidget) wid;
  2648. XmTextPosition data;
  2649. Arg al[1];
  2650. XtSetArg( al[0], XmNtopCharacter, &data) ;
  2651. XtGetValues( (Widget) M_text(editor), al, 1) ;
  2652. *value = (XtArgVal) data ;
  2653. return;
  2654. } /* end _DtEditorGetTopCharacter */
  2655. static void
  2656. _DtEditorGetLineCountLabel(
  2657. Widget wid,
  2658. int resource_offset,
  2659. XtArgVal *value )
  2660. {
  2661. DtEditorWidget editor = (DtEditorWidget) wid;
  2662. XmString data;
  2663. Arg al[1];
  2664. /*
  2665. * Get the value directly from the field in the instance structure.
  2666. * If it is DtUNSPECIFIED then either:
  2667. * 1) the value has been assigned to the widget (so get it from
  2668. * there), or
  2669. * 2) the value has never been set (so return the default value).
  2670. */
  2671. if (E_status_totalLineCountLabel(editor) != (XmString) DtUNSPECIFIED)
  2672. data = XmStringCopy( E_status_totalLineCountLabel(editor) );
  2673. else if (M_status_statusArea(editor) != (Widget) NULL)
  2674. {
  2675. XtSetArg( al[0], XmNlabelString, &data) ;
  2676. XtGetValues( (Widget) M_status_totalLabel(editor), al, 1) ;
  2677. }
  2678. else
  2679. data = XmStringCreateLocalized(TOTAL);
  2680. *value = (XtArgVal) data ;
  2681. return;
  2682. } /* end _DtEditorGetLineCountLabel */
  2683. /**************************************************************
  2684. **
  2685. ** Action Procedures
  2686. **
  2687. **/
  2688. /*
  2689. * The following are DtEditor's actions. A few are internal only (_I
  2690. * suffix) and will be called by the default translations DtEditor places
  2691. * on the text widget. The rest will be called from an application with
  2692. * XtCallActionProc(). The main difference is the internal ones will be
  2693. * passed a text widget ID, while the public ones will be passed a DtEditor ID.
  2694. */
  2695. static void
  2696. BackwardChar(
  2697. Widget w,
  2698. XEvent *event,
  2699. char **params,
  2700. Cardinal *num_params)
  2701. {
  2702. DtEditorWidget editor = (DtEditorWidget)w;
  2703. XtCallActionProc( M_text(editor), "backward-character", event,
  2704. params, *num_params );
  2705. }
  2706. static void
  2707. BackwardPara(
  2708. Widget w,
  2709. XEvent *event,
  2710. char **params,
  2711. Cardinal *num_params)
  2712. {
  2713. DtEditorWidget editor = (DtEditorWidget)w;
  2714. XtCallActionProc( M_text(editor), "backward-paragraph", event,
  2715. params, *num_params );
  2716. }
  2717. static void
  2718. BackwardWord(
  2719. Widget w,
  2720. XEvent *event,
  2721. char **params,
  2722. Cardinal *num_params)
  2723. {
  2724. DtEditorWidget editor = (DtEditorWidget)w;
  2725. XtCallActionProc( M_text(editor), "backward-word", event,
  2726. params, *num_params );
  2727. }
  2728. static void
  2729. BeginningOfFile(
  2730. Widget w,
  2731. XEvent *event,
  2732. char **params,
  2733. Cardinal *num_params)
  2734. {
  2735. DtEditorWidget editor = (DtEditorWidget)w;
  2736. XtCallActionProc( M_text(editor), "beginning-of-file", event,
  2737. params, *num_params );
  2738. }
  2739. static void
  2740. BeginningOfLine(
  2741. Widget w,
  2742. XEvent *event,
  2743. char **params,
  2744. Cardinal *num_params)
  2745. {
  2746. DtEditorWidget editor = (DtEditorWidget)w;
  2747. XtCallActionProc( M_text(editor), "beginning-of-line", event,
  2748. params, *num_params );
  2749. }
  2750. static void
  2751. ClearSelection(
  2752. Widget w,
  2753. XEvent *event,
  2754. char **params,
  2755. Cardinal *num_params)
  2756. {
  2757. DtEditorWidget editor = (DtEditorWidget)w;
  2758. XtCallActionProc( M_text(editor), "clear-selection", event,
  2759. params, *num_params );
  2760. /*
  2761. * Clearing selected text also deselects the selection, but for some
  2762. * reason the selection proc (Editor_SetSelectionProc) does not get
  2763. * called, therefore, we need to call the DtNtextDeselectCallback
  2764. * from here.
  2765. */
  2766. Call_TextDeselectCallback(editor);
  2767. }
  2768. static void
  2769. CopyClipboard(
  2770. Widget w,
  2771. XEvent *event,
  2772. char **params,
  2773. Cardinal *num_params)
  2774. {
  2775. DtEditorWidget editor = (DtEditorWidget)w;
  2776. XtCallActionProc( M_text(editor), "copy-clipboard", event,
  2777. params, *num_params );
  2778. }
  2779. static void
  2780. CutClipboard(
  2781. Widget w,
  2782. XEvent *event,
  2783. char **params,
  2784. Cardinal *num_params)
  2785. {
  2786. DtEditorWidget editor = (DtEditorWidget)w;
  2787. XtCallActionProc( M_text(editor), "cut-clipboard", event,
  2788. params, *num_params );
  2789. }
  2790. static void
  2791. DeleteNextChar(
  2792. Widget w,
  2793. XEvent *event,
  2794. char **params,
  2795. Cardinal *num_params)
  2796. {
  2797. DtEditorWidget editor = (DtEditorWidget)w;
  2798. XtCallActionProc( M_text(editor), "delete-next-character", event,
  2799. params, *num_params );
  2800. }
  2801. static void
  2802. DeleteNextWord(
  2803. Widget w,
  2804. XEvent *event,
  2805. char **params,
  2806. Cardinal *num_params)
  2807. {
  2808. DtEditorWidget editor = (DtEditorWidget)w;
  2809. XtCallActionProc( M_text(editor), "delete-next-word", event,
  2810. params, *num_params );
  2811. }
  2812. static void
  2813. DeletePrevChar(
  2814. Widget w,
  2815. XEvent *event,
  2816. char **params,
  2817. Cardinal *num_params)
  2818. {
  2819. DtEditorWidget editor = (DtEditorWidget)w;
  2820. XtCallActionProc( M_text(editor), "delete-previous-character", event,
  2821. params, *num_params );
  2822. }
  2823. static void
  2824. DeletePrevWord(
  2825. Widget w,
  2826. XEvent *event,
  2827. char **params,
  2828. Cardinal *num_params)
  2829. {
  2830. DtEditorWidget editor = (DtEditorWidget)w;
  2831. XtCallActionProc( M_text(editor), "delete-previous-word", event,
  2832. params, *num_params );
  2833. }
  2834. static void
  2835. DeleteToEOL(
  2836. Widget w,
  2837. XEvent *event,
  2838. char **params,
  2839. Cardinal *num_params)
  2840. {
  2841. DtEditorWidget editor = (DtEditorWidget)w;
  2842. XtCallActionProc( M_text(editor), "delete-to-end-of-line", event,
  2843. params, *num_params );
  2844. }
  2845. static void
  2846. DeleteToSOL(
  2847. Widget w,
  2848. XEvent *event,
  2849. char **params,
  2850. Cardinal *num_params)
  2851. {
  2852. DtEditorWidget editor = (DtEditorWidget)w;
  2853. XtCallActionProc( M_text(editor), "delete-to-start-of-line", event,
  2854. params, *num_params );
  2855. }
  2856. static void
  2857. DeselectAll(
  2858. Widget w,
  2859. XEvent *event,
  2860. char **params,
  2861. Cardinal *num_params)
  2862. {
  2863. DtEditorWidget editor = (DtEditorWidget)w;
  2864. XtCallActionProc( M_text(editor), "deselect-all", event,
  2865. params, *num_params );
  2866. }
  2867. static void
  2868. EndOfFile(
  2869. Widget w,
  2870. XEvent *event,
  2871. char **params,
  2872. Cardinal *num_params)
  2873. {
  2874. DtEditorWidget editor = (DtEditorWidget)w;
  2875. XtCallActionProc( M_text(editor), "end-of-file", event,
  2876. params, *num_params );
  2877. }
  2878. static void
  2879. EndOfLine(
  2880. Widget w,
  2881. XEvent *event,
  2882. char **params,
  2883. Cardinal *num_params)
  2884. {
  2885. DtEditorWidget editor = (DtEditorWidget)w;
  2886. XtCallActionProc( M_text(editor), "end-of-line", event,
  2887. params, *num_params );
  2888. }
  2889. static void
  2890. ForwardChar(
  2891. Widget w,
  2892. XEvent *event,
  2893. char **params,
  2894. Cardinal *num_params)
  2895. {
  2896. DtEditorWidget editor = (DtEditorWidget)w;
  2897. XtCallActionProc( M_text(editor), "forward-character", event,
  2898. params, *num_params );
  2899. }
  2900. static void
  2901. ForwardPara(
  2902. Widget w,
  2903. XEvent *event,
  2904. char **params,
  2905. Cardinal *num_params)
  2906. {
  2907. DtEditorWidget editor = (DtEditorWidget)w;
  2908. XtCallActionProc( M_text(editor), "forward-paragraph", event,
  2909. params, *num_params );
  2910. }
  2911. static void
  2912. ForwardWord(
  2913. Widget w,
  2914. XEvent *event,
  2915. char **params,
  2916. Cardinal *num_params)
  2917. {
  2918. DtEditorWidget editor = (DtEditorWidget)w;
  2919. XtCallActionProc( M_text(editor), "forward-word", event,
  2920. params, *num_params );
  2921. }
  2922. static void
  2923. GoToLine(
  2924. Widget w,
  2925. XEvent *event,
  2926. char **params,
  2927. Cardinal *num_params)
  2928. {
  2929. DtEditorWidget editor = (DtEditorWidget)w;
  2930. if( M_status_statusArea(editor) != (Widget)NULL &&
  2931. XtIsManaged(M_status_statusArea(editor)) == True )
  2932. {
  2933. /*
  2934. * Set the input focus to the "Line" text field.
  2935. */
  2936. XmProcessTraversal(M_status_lineText(editor), XmTRAVERSE_CURRENT);
  2937. /*
  2938. * Select the current contents to allow easy modification.
  2939. */
  2940. XtCallActionProc( (Widget)M_status_lineText(editor), "select-all",
  2941. event, (String *)NULL, 0 );
  2942. }
  2943. } /* end GoToLine */
  2944. /*
  2945. * Internal action called only from the scrolled text widget
  2946. */
  2947. static void
  2948. GoToLine_I(
  2949. Widget w,
  2950. XEvent *event,
  2951. char **params,
  2952. Cardinal *num_params)
  2953. {
  2954. XmTextWidget tw = (XmTextWidget)w;
  2955. DtEditorWidget editor = (DtEditorWidget)M_editor(tw);
  2956. GoToLine( (Widget)editor, event, params, num_params );
  2957. } /* end GoToLine_I */
  2958. static void
  2959. Help(
  2960. Widget w,
  2961. XEvent *event,
  2962. char **params,
  2963. Cardinal *num_params)
  2964. {
  2965. CallHelpCallback((DtEditorWidget)w, DtEDITOR_HELP_EDIT_WINDOW);
  2966. }
  2967. static void
  2968. InsertString(
  2969. Widget w,
  2970. XEvent *event,
  2971. char **params,
  2972. Cardinal *num_params)
  2973. {
  2974. DtEditorWidget editor = (DtEditorWidget)w;
  2975. XtCallActionProc( M_text(editor), "insert-string", event,
  2976. params, *num_params );
  2977. }
  2978. static void
  2979. KeySelect(
  2980. Widget w,
  2981. XEvent *event,
  2982. char **params,
  2983. Cardinal *num_params)
  2984. {
  2985. DtEditorWidget editor = (DtEditorWidget)w;
  2986. XtCallActionProc( M_text(editor), "key-select", event,
  2987. params, *num_params );
  2988. }
  2989. static void
  2990. NewlineAndBackup(
  2991. Widget w,
  2992. XEvent *event,
  2993. char **params,
  2994. Cardinal *num_params)
  2995. {
  2996. DtEditorWidget editor = (DtEditorWidget)w;
  2997. XtCallActionProc( M_text(editor), "newline-and-backup", event,
  2998. params, *num_params );
  2999. }
  3000. static void
  3001. NewlineAndIndent(
  3002. Widget w,
  3003. XEvent *event,
  3004. char **params,
  3005. Cardinal *num_params)
  3006. {
  3007. DtEditorWidget editor = (DtEditorWidget)w;
  3008. XtCallActionProc( M_text(editor), "newline-and-indent", event,
  3009. params, *num_params );
  3010. }
  3011. static void
  3012. NextPage(
  3013. Widget w,
  3014. XEvent *event,
  3015. char **params,
  3016. Cardinal *num_params)
  3017. {
  3018. DtEditorWidget editor = (DtEditorWidget)w;
  3019. XtCallActionProc( M_text(editor), "next-page", event,
  3020. params, *num_params );
  3021. }
  3022. static void
  3023. PageLeft(
  3024. Widget w,
  3025. XEvent *event,
  3026. char **params,
  3027. Cardinal *num_params)
  3028. {
  3029. DtEditorWidget editor = (DtEditorWidget)w;
  3030. XtCallActionProc( M_text(editor), "page-left", event,
  3031. params, *num_params );
  3032. }
  3033. static void
  3034. PageRight(
  3035. Widget w,
  3036. XEvent *event,
  3037. char **params,
  3038. Cardinal *num_params)
  3039. {
  3040. DtEditorWidget editor = (DtEditorWidget)w;
  3041. XtCallActionProc( M_text(editor), "page-right", event,
  3042. params, *num_params );
  3043. }
  3044. static void
  3045. PasteClipboard(
  3046. Widget w,
  3047. XEvent *event,
  3048. char **params,
  3049. Cardinal *num_params)
  3050. {
  3051. DtEditorWidget editor = (DtEditorWidget)w;
  3052. XtCallActionProc( M_text(editor), "paste-clipboard", event,
  3053. params, *num_params );
  3054. }
  3055. static void
  3056. PreviousPage(
  3057. Widget w,
  3058. XEvent *event,
  3059. char **params,
  3060. Cardinal *num_params)
  3061. {
  3062. DtEditorWidget editor = (DtEditorWidget)w;
  3063. XtCallActionProc( M_text(editor), "previous-page", event,
  3064. params, *num_params );
  3065. }
  3066. static void
  3067. ProcessCancel(
  3068. Widget w,
  3069. XEvent *event,
  3070. char **params,
  3071. Cardinal *num_params)
  3072. {
  3073. DtEditorWidget editor = (DtEditorWidget)w;
  3074. XtCallActionProc( M_text(editor), "process-cancel", event,
  3075. params, *num_params );
  3076. }
  3077. static void
  3078. ProcessDown(
  3079. Widget w,
  3080. XEvent *event,
  3081. char **params,
  3082. Cardinal *num_params)
  3083. {
  3084. DtEditorWidget editor = (DtEditorWidget)w;
  3085. XtCallActionProc( M_text(editor), "process-down", event,
  3086. params, *num_params );
  3087. }
  3088. static void
  3089. ProcessShiftDown(
  3090. Widget w,
  3091. XEvent *event,
  3092. char **params,
  3093. Cardinal *num_params)
  3094. {
  3095. DtEditorWidget editor = (DtEditorWidget)w;
  3096. XtCallActionProc( M_text(editor), "process-shift-down", event,
  3097. params, *num_params );
  3098. }
  3099. static void
  3100. ProcessShiftUp(
  3101. Widget w,
  3102. XEvent *event,
  3103. char **params,
  3104. Cardinal *num_params)
  3105. {
  3106. DtEditorWidget editor = (DtEditorWidget)w;
  3107. XtCallActionProc( M_text(editor), "process-shift-up", event,
  3108. params, *num_params );
  3109. }
  3110. static void
  3111. ProcessUp(
  3112. Widget w,
  3113. XEvent *event,
  3114. char **params,
  3115. Cardinal *num_params)
  3116. {
  3117. DtEditorWidget editor = (DtEditorWidget)w;
  3118. XtCallActionProc( M_text(editor), "process-up", event,
  3119. params, *num_params );
  3120. }
  3121. /************************************************************************
  3122. * GetModeSwitchModifier
  3123. * Find if any Mod<n> modifier is acting as the Group modifier - you
  3124. * can't assume Mod1Mask is always it.
  3125. * Returns the mask of the modifier key to which the Mode_switch
  3126. * keysym is attached.
  3127. *
  3128. ************************************************************************/
  3129. /* ARGSUSED */
  3130. static unsigned int
  3131. GetModeSwitchModifier(
  3132. Display *dpy)
  3133. {
  3134. XModifierKeymap *pMap;
  3135. int mapIndex, keyCol, mapSize;
  3136. KeySym keySym;
  3137. unsigned int modeSwitchModMask = 0;
  3138. pMap = XGetModifierMapping(dpy);
  3139. mapSize = 8*pMap->max_keypermod;
  3140. for (mapIndex = 3*pMap->max_keypermod; mapIndex < mapSize; mapIndex++) {
  3141. /* look only at the first 4 columns of key map */
  3142. for (keyCol = 0; keyCol < 4; keyCol++) {
  3143. keySym = XKeycodeToKeysym(dpy, pMap->modifiermap[mapIndex], keyCol);
  3144. if (keySym == XK_Mode_switch)
  3145. modeSwitchModMask |= 1 << (mapIndex / pMap->max_keypermod);
  3146. }
  3147. }
  3148. XFreeModifiermap(pMap);
  3149. return modeSwitchModMask;
  3150. }
  3151. /************************************************************************
  3152. *
  3153. * DtEditorQuoteNextChar
  3154. * This action routine circumvents the normal XtDispatchEvent
  3155. * mechanism, inserting the next control or extended character
  3156. * directly into text without processed by event handlers or the
  3157. * translation manager. This means, for
  3158. * example, that the next control or extended character will be
  3159. * inserted into text without being intrepreted as a Motif menu
  3160. * or text widget accelerator.
  3161. *
  3162. ************************************************************************/
  3163. /* ARGSUSED */
  3164. static void
  3165. QuoteNextChar(
  3166. Widget widget,
  3167. XEvent *event,
  3168. char **params,
  3169. Cardinal *num_params)
  3170. {
  3171. DtEditorWidget editor = (DtEditorWidget)widget;
  3172. static unsigned int ExtendcharMask = 0;
  3173. /* NOTE: ExtendcharMask could be a global set via a MappingNotify
  3174. * event handler. But it isn't...
  3175. */
  3176. if (! ExtendcharMask)
  3177. {
  3178. _DtProcessLock();
  3179. if (! ExtendcharMask)
  3180. ExtendcharMask = GetModeSwitchModifier( M_display(editor) );
  3181. _DtProcessUnlock();
  3182. }
  3183. for (;;)
  3184. {
  3185. XEvent next;
  3186. #ifdef XTHREADS
  3187. /*
  3188. * We cannot let XtAppNextEvent bloc, because the intrinsics
  3189. * will release locks and some other thread might dispatch
  3190. * the event we want to trap.
  3191. */
  3192. XtInputMask mask;
  3193. XtAppContext app = XtWidgetToApplicationContext(widget);
  3194. while ((mask = XtAppPending(app)) == 0)
  3195. {
  3196. if (XtAppGetExitFlag(app))
  3197. return;
  3198. }
  3199. if (mask & XtIMXEvent)
  3200. {
  3201. #endif
  3202. XtAppNextEvent(M_app_context(editor), &next);
  3203. if ((next.type == KeyPress) &&
  3204. (! IsModifierKey(XLookupKeysym((XKeyEvent *) &next, 0))) )
  3205. {
  3206. if (next.xkey.state & (ControlMask|ExtendcharMask))
  3207. XtCallActionProc(M_text(editor), "self-insert", &next, NULL, 0);
  3208. else
  3209. XtDispatchEvent(&next);
  3210. break;
  3211. }
  3212. else
  3213. XtDispatchEvent(&next);
  3214. #ifdef XTHREADS
  3215. }
  3216. else
  3217. {
  3218. /* Some (non-X) event is pending, so this should not block. */
  3219. XtAppProcessEvent(app, mask);
  3220. }
  3221. #endif
  3222. }
  3223. } /* end QuoteNextChar */
  3224. /*
  3225. * Internal action called only from the scrolled text widget
  3226. */
  3227. static void
  3228. QuoteNextChar_I(
  3229. Widget w,
  3230. XEvent *event,
  3231. char **params,
  3232. Cardinal *num_params)
  3233. {
  3234. XmTextWidget tw = (XmTextWidget)w;
  3235. DtEditorWidget editor = (DtEditorWidget) M_editor(tw);
  3236. QuoteNextChar( (Widget)editor, event, params, num_params );
  3237. } /* end QuoteNextChar_I */
  3238. static void
  3239. SelectAll(
  3240. Widget w,
  3241. XEvent *event,
  3242. char **params,
  3243. Cardinal *num_params)
  3244. {
  3245. DtEditorWidget editor = (DtEditorWidget)w;
  3246. XtCallActionProc( M_text(editor), "select-all", event,
  3247. params, *num_params );
  3248. }
  3249. static void
  3250. ToggleInsertMode(
  3251. Widget w,
  3252. XEvent *event,
  3253. char **params,
  3254. Cardinal *num_params)
  3255. {
  3256. DtEditorWidget editor = (DtEditorWidget)w;
  3257. /*
  3258. * Toggle the state of the DtNoverstrike resource
  3259. */
  3260. XtVaSetValues(w, DtNoverstrike, !M_overstrikeMode(editor), NULL);
  3261. } /* end ToggleInsertMode */
  3262. static void
  3263. ToggleInsertMode_I(
  3264. Widget w,
  3265. XEvent *event,
  3266. char **params,
  3267. Cardinal *num_params)
  3268. {
  3269. XmTextWidget tw = (XmTextWidget)w;
  3270. DtEditorWidget editor = (DtEditorWidget)M_editor(tw);
  3271. ToggleInsertMode( (Widget)editor, event, params, num_params );
  3272. } /* end ToggleInsertMode_I */
  3273. static void
  3274. UndoEdit(
  3275. Widget w,
  3276. XEvent *event,
  3277. char **params,
  3278. Cardinal *num_params)
  3279. {
  3280. DtEditorUndoEdit(w);
  3281. } /* end UndoEdit */
  3282. static void
  3283. UndoEdit_I(
  3284. Widget w,
  3285. XEvent *event,
  3286. char **params,
  3287. Cardinal *num_params)
  3288. {
  3289. XmTextWidget tw = (XmTextWidget)w;
  3290. UndoEdit( (Widget)M_editor(tw), event, params, num_params );
  3291. } /* end UndoEdit_I */
  3292. /*
  3293. * XXX All lines in this file marked "XXX Word Wrap workaround"
  3294. * XXX are related to a Motif 1.2 Text widget design defect regarding
  3295. * XXX word wrap. For Motif 1.2, the Text widget was designed so word
  3296. * XXX wrap will not function if the scrolled text widget has a
  3297. * XXX horizontal scroll bar ("a hscrollbar means the paper is infinite
  3298. * XXX so there is no edge to wrap at"). This change was made in
  3299. * XXX Xm/TextOut.c RCS version 1.71 checked in July, 1991. A
  3300. * XXX CMVC report was filed 9/8/94 & assigned number 4772.
  3301. */
  3302. #include <Xm/TextOutP.h> /* XXX Word Wrap workaround */
  3303. static void /* XXX Word Wrap workaround */
  3304. FixWordWrap( /* XXX Word Wrap workaround */
  3305. Widget w, /* XXX Word Wrap workaround */
  3306. Boolean wrapOn) /* XXX Word Wrap workaround */
  3307. { /* XXX Word Wrap workaround */
  3308. XmTextWidget tw = (XmTextWidget)w; /* XXX Word Wrap workaround */
  3309. OutputData data = tw->text.output->data; /* XXX Word Wrap workaround */
  3310. data->scrollhorizontal = !wrapOn; /* XXX Word Wrap workaround */
  3311. } /* XXX Word Wrap workaround */
  3312. static void
  3313. Call_TextSelectCallback(
  3314. DtEditorWidget editor)
  3315. {
  3316. DtEditorSelectCallbackStruct select_cb;
  3317. /*
  3318. * Call the Editor widget's DtNtextSelectCallback proc
  3319. * if it hasn't been called since the last select.
  3320. */
  3321. if ( !M_textSelectCbCalled(editor) ) {
  3322. M_textSelectCbCalled(editor) = True;
  3323. select_cb.reason = DtEDITOR_TEXT_SELECT;
  3324. select_cb.event = (XEvent *)NULL;
  3325. XtCallCallbackList ((Widget)editor, M_textSelect(editor),
  3326. (XtPointer) &select_cb);
  3327. }
  3328. } /* end Call_TextSelectCallback */
  3329. static void
  3330. Call_TextDeselectCallback(
  3331. DtEditorWidget editor)
  3332. {
  3333. DtEditorSelectCallbackStruct select_cb;
  3334. /*
  3335. * Call the Editor widget's DtNtextDeselectCallback proc
  3336. * if it hasn't been called since the last deselect.
  3337. */
  3338. if ( M_textSelectCbCalled(editor) ) {
  3339. M_textSelectCbCalled(editor) = False;
  3340. select_cb.reason = DtEDITOR_TEXT_DESELECT;
  3341. select_cb.event = (XEvent *)NULL;
  3342. XtCallCallbackList ((Widget)editor, M_textDeselect(editor),
  3343. (XtPointer) &select_cb);
  3344. }
  3345. } /* end Call_TextDeselectCallback */
  3346. /*
  3347. * Editor_SetSelectionProc
  3348. * is put into the widget->text.source->SetSelection.
  3349. * Used to call the DtEditor's select/unselect callbacks
  3350. */
  3351. static void
  3352. Editor_SetSelectionProc(
  3353. XmTextSource source,
  3354. XmTextPosition left,
  3355. XmTextPosition right,
  3356. Time set_time )
  3357. {
  3358. XmSourceData data = source->data;
  3359. Widget widget;
  3360. XmTextWidget tw;
  3361. DtEditorWidget editor;
  3362. /*
  3363. * Sanity check
  3364. */
  3365. if (!XtIsRealized((Widget)data->widgets[0]) ||
  3366. data->numwidgets <= 0)
  3367. return;
  3368. if (left < 0) left = right = 0;
  3369. widget = (Widget) data->widgets[0];
  3370. tw = (XmTextWidget)widget;
  3371. editor = M_editor(tw);
  3372. if (!editor->core.being_destroyed) {
  3373. if (left < right) {
  3374. /*
  3375. * There is a selected area if left < right so call the
  3376. * DtNtextSelectCallback.
  3377. */
  3378. Call_TextSelectCallback( editor );
  3379. }
  3380. else {
  3381. /*
  3382. * Left = Right so nothing is selected; call the
  3383. * DtNtextDeselectCallback.
  3384. */
  3385. Call_TextDeselectCallback( editor );
  3386. }
  3387. }
  3388. /*
  3389. * Now, call the text widget's real Set Selection proc
  3390. */
  3391. (*M_setSelection(editor))(source, left, right, set_time);
  3392. } /* end Editor_SetSelectionProc */
  3393. /**************************************************************
  3394. **
  3395. ** Drag and drop routines
  3396. **
  3397. **/
  3398. /*
  3399. * Handles drops of a file into the text editor, after validation in the
  3400. * transfer callback. Files are handled by reading their contents.
  3401. * Text is handled by Motif.
  3402. *
  3403. * Changing the contents of the text widget occurs here, rather than in
  3404. * the transfer callback, because of the visual changes which occur when
  3405. * changing the text widget.
  3406. */
  3407. static void
  3408. AnimateCallback(
  3409. Widget w,
  3410. XtPointer client_data,
  3411. XtPointer call_data )
  3412. {
  3413. int numItems, ii;
  3414. DtEditorErrorCode error;
  3415. DtDndDropAnimateCallbackStruct *animateInfo =
  3416. (DtDndDropAnimateCallbackStruct *) call_data;
  3417. DtEditorWidget editor = (DtEditorWidget) client_data;
  3418. /*
  3419. * XXX Only really needed if # of items is > 1
  3420. */
  3421. _DtTurnOnHourGlass( M_topLevelShell(editor) );
  3422. /*
  3423. * How many items are being dropped on us?
  3424. */
  3425. numItems = animateInfo->dropData->numItems;
  3426. switch (animateInfo->dropData->protocol)
  3427. {
  3428. case DtDND_FILENAME_TRANSFER:
  3429. {
  3430. /*
  3431. * OK, insert each file we are given
  3432. */
  3433. for (ii = 0; ii < numItems; ii++)
  3434. {
  3435. error = DtEditorInsertFromFile( (Widget)editor,
  3436. animateInfo->dropData->data.files[ii] );
  3437. /*
  3438. * If the file was not inserted successfully, then quit
  3439. * (don't care if the file is read only or if it contained
  3440. * nulls that were stripped out).
  3441. */
  3442. if( error != DtEDITOR_NO_ERRORS &&
  3443. error != DtEDITOR_READ_ONLY_FILE &&
  3444. error != DtEDITOR_NULLS_REMOVED )
  3445. {
  3446. ii = numItems; /* break out of loop */
  3447. }
  3448. } /* end for */
  3449. break;
  3450. } /* end file transfer case */
  3451. case DtDND_BUFFER_TRANSFER:
  3452. {
  3453. /*
  3454. * OK, insert each buffer we are given
  3455. */
  3456. DtDndBuffer *buffers = animateInfo->dropData->data.buffers;
  3457. DtEditorContentRec cr;
  3458. cr.type = DtEDITOR_DATA;
  3459. for (ii = 0; ii < numItems; ii++)
  3460. {
  3461. cr.value.data.buf = buffers[ii].bp;
  3462. cr.value.data.length = buffers[ii].size;
  3463. error = DtEditorInsert( (Widget)editor, &cr );
  3464. /*
  3465. * If the buffer was not inserted successfully, then quit
  3466. * (don't care if the file contained nulls that were stripped out).
  3467. */
  3468. if( error != DtEDITOR_NO_ERRORS && error != DtEDITOR_NULLS_REMOVED )
  3469. {
  3470. ii = numItems; /* break out of loop */
  3471. }
  3472. } /* end for */
  3473. break;
  3474. } /* end buffer transfer case */
  3475. case DtDND_TEXT_TRANSFER:
  3476. {
  3477. /*
  3478. * Receiving a text drop.
  3479. *
  3480. * Text drag and drop is handled by Motif so this switch
  3481. * will never be called.
  3482. *
  3483. */
  3484. break;
  3485. } /* end text transfer case */
  3486. default:
  3487. {
  3488. }
  3489. } /* end switch */
  3490. /*
  3491. * XXX Only really needed if # of items is > 1
  3492. */
  3493. _DtTurnOffHourGlass( M_topLevelShell(editor) );
  3494. } /* end AnimateCallback */
  3495. /*
  3496. * Validates a drop of a file into the text widget.
  3497. *
  3498. * Changing the contents of the text widget occurs in the animate
  3499. * callback, rather than here, because of the visual changes which
  3500. * occur when changing the text widget.
  3501. */
  3502. /* ARGSUSED */
  3503. static void
  3504. TransferCallback(
  3505. Widget w,
  3506. XtPointer client_data,
  3507. XtPointer call_data)
  3508. {
  3509. int numItems, ii;
  3510. DtEditorErrorCode error;
  3511. DtDndTransferCallbackStruct *transferInfo =
  3512. (DtDndTransferCallbackStruct *) call_data;
  3513. transferInfo->status = DtDND_SUCCESS;
  3514. /*
  3515. * How many items are being dropped on us?
  3516. */
  3517. numItems = transferInfo->dropData->numItems;
  3518. switch (transferInfo->dropData->protocol)
  3519. {
  3520. case DtDND_FILENAME_TRANSFER:
  3521. {
  3522. /*
  3523. * Check to see if we can read each file we are given
  3524. */
  3525. for (ii = 0; ii < numItems; ii++)
  3526. {
  3527. error = _DtEditorValidateFileAccess(
  3528. transferInfo->dropData->data.files[ii],
  3529. READ_ACCESS);
  3530. /*
  3531. * Can't access it for reading so reject drop
  3532. */
  3533. if ( error != DtEDITOR_NO_ERRORS ) {
  3534. transferInfo->status = DtDND_FAILURE;
  3535. ii = numItems; /* break out of loop */
  3536. }
  3537. } /* end for each file */
  3538. break;
  3539. } /* end file transfer case */
  3540. case DtDND_BUFFER_TRANSFER:
  3541. {
  3542. /*
  3543. * Receiving a buffer drop.
  3544. * -- do nothing in transfer
  3545. */
  3546. break;
  3547. } /* end buffer transfer case */
  3548. case DtDND_TEXT_TRANSFER:
  3549. {
  3550. /*
  3551. * Receiving a text drop.
  3552. *
  3553. * Text drag and drop is handled by Motif so this switch
  3554. * will never be called.
  3555. *
  3556. */
  3557. break;
  3558. } /* end text transfer case */
  3559. default:
  3560. {
  3561. transferInfo->status = DtDND_FAILURE;
  3562. break;
  3563. }
  3564. } /* end switch */
  3565. } /* end TransferCallback */
  3566. /*-------------------------------------------------------------
  3567. ** Function: static void RegisterDropZone (
  3568. ** DtEditorWidget w)
  3569. **
  3570. ** Parameters: A DtEditor widget
  3571. **
  3572. ** Purpose: This routine registers the edit window's text widget
  3573. ** as a drop site for file & buffer drops. Because it
  3574. ** is a text widget it will automatically accept text
  3575. ** drops.
  3576. */
  3577. static void
  3578. RegisterDropZone(
  3579. DtEditorWidget w)
  3580. {
  3581. int ac;
  3582. Arg al[2];
  3583. XtCallbackRec transferCB[] = { {TransferCallback, NULL}, {NULL, NULL} };
  3584. XtCallbackRec animateCB[] = { {AnimateCallback, NULL}, {NULL, NULL} };
  3585. transferCB[0].closure = (XtPointer) w;
  3586. animateCB[0].closure = (XtPointer) w;
  3587. /*
  3588. * Register file & buffer transfers... let Motif handle text DnD
  3589. */
  3590. ac=0;
  3591. XtSetArg( al[ac], DtNdropAnimateCallback, animateCB ); ac++;
  3592. DtDndDropRegister( M_text(w),
  3593. DtDND_FILENAME_TRANSFER|DtDND_BUFFER_TRANSFER,
  3594. XmDROP_COPY, transferCB, al, ac );
  3595. } /* end RegisterDropZone */
  3596. /*-------------------------------------------------------------
  3597. ** Function: static void UnregisterDropZone (
  3598. ** DtEditorWidget w)
  3599. **
  3600. ** Parameters: A DtEditor widget
  3601. **
  3602. ** Purpose: This routine unregisters the edit window
  3603. */
  3604. static void
  3605. UnregisterDropZone(
  3606. DtEditorWidget w)
  3607. {
  3608. DtDndDropUnregister( M_text(w) );
  3609. } /* end UnregisterDropZone */
  3610. /************************************************************************
  3611. *
  3612. * SetInfoDialogTitle - Change the title for the Information dialog
  3613. *
  3614. ************************************************************************/
  3615. static void
  3616. SetInfoDialogTitle(
  3617. DtEditorWidget editor)
  3618. {
  3619. Arg al[2];
  3620. /*
  3621. * If the Information dialog has been created, change its title
  3622. */
  3623. if( M_gen_warning(editor) != (Widget)NULL )
  3624. {
  3625. /*
  3626. * Prepend the DialogTitle resource, if it has been set
  3627. */
  3628. if( E_dialogTitle(editor) != (XmString)NULL ) {
  3629. XmString titleStr;
  3630. /*
  3631. * Add the "functional title" to the DialogTitle
  3632. */
  3633. titleStr = XmStringConcat( E_dialogTitle(editor),
  3634. E_infoDialogTitle(editor) );
  3635. XtSetArg( al[0], XmNdialogTitle, titleStr );
  3636. XtSetValues(M_gen_warning(editor), al, 1);
  3637. XmStringFree( titleStr );
  3638. }
  3639. else {
  3640. XtSetArg( al[0], XmNdialogTitle, E_infoDialogTitle(editor) );
  3641. XtSetValues(M_gen_warning(editor), al, 1);
  3642. }
  3643. }
  3644. } /* end SetInfoDialogTitle */
  3645. /************************************************************************
  3646. *
  3647. * _DtEditorWarning - get a message to the user
  3648. *
  3649. ************************************************************************/
  3650. void
  3651. _DtEditorWarning(
  3652. DtEditorWidget editor,
  3653. char *mess,
  3654. unsigned char dialogType)
  3655. {
  3656. Arg al[10];
  3657. int ac;
  3658. char *tmpMess;
  3659. XmString tmpStr;
  3660. tmpMess = strdup(mess);
  3661. /* create the dialog if it is the first time */
  3662. if(M_gen_warning(editor) == (Widget) NULL)
  3663. {
  3664. XmString titleStr = (XmString) NULL;
  3665. XmString okStr;
  3666. ac = 0;
  3667. /*
  3668. * First, create the dialog's title, prepending the
  3669. * DtNdialogTitle resource, if it is set
  3670. */
  3671. if( E_dialogTitle(editor) != (XmString)NULL ) {
  3672. /*
  3673. * Add the "functional title" to the DialogTitle
  3674. */
  3675. titleStr = XmStringConcat( E_dialogTitle(editor),
  3676. E_infoDialogTitle(editor) );
  3677. XtSetArg (al[ac], XmNdialogTitle, titleStr ); ac++;
  3678. }
  3679. else {
  3680. XtSetArg (al[ac], XmNdialogTitle, E_infoDialogTitle(editor)); ac++;
  3681. }
  3682. okStr = XmStringCreateLocalized((char*) _DtOkString);
  3683. XtSetArg (al[ac], XmNokLabelString, okStr); ac++;
  3684. M_gen_warning(editor) = (Widget) XmCreateMessageDialog(
  3685. M_topLevelShell(editor), "Warn",
  3686. al, ac);
  3687. if (titleStr != (XmString) NULL)
  3688. XmStringFree( titleStr );
  3689. XmStringFree(okStr);
  3690. /* Set the correct font lists for the message & OK button. */
  3691. XtSetArg (al[0], XmNfontList, E_buttonFontList(editor));
  3692. XtSetValues(
  3693. XmMessageBoxGetChild(M_gen_warning(editor), XmDIALOG_OK_BUTTON),
  3694. al, 1) ;
  3695. XtSetArg (al[0], XmNfontList, E_labelFontList(editor));
  3696. XtSetValues(
  3697. XmMessageBoxGetChild(M_gen_warning(editor), XmDIALOG_MESSAGE_LABEL),
  3698. al, 1) ;
  3699. /* Unmanage unneeded children. */
  3700. XtUnmanageChild ( XmMessageBoxGetChild(M_gen_warning(editor),
  3701. XmDIALOG_CANCEL_BUTTON) );
  3702. XtUnmanageChild ( XmMessageBoxGetChild(M_gen_warning(editor),
  3703. XmDIALOG_HELP_BUTTON) );
  3704. XtRealizeWidget (M_gen_warning(editor));
  3705. ac=0;
  3706. XtSetArg(al[ac], XmNmwmInputMode,
  3707. MWM_INPUT_PRIMARY_APPLICATION_MODAL);ac++;
  3708. XtSetValues(XtParent(M_gen_warning(editor)), al, ac);
  3709. }
  3710. tmpStr = XmStringCreateLocalized(tmpMess);
  3711. ac = 0;
  3712. XtSetArg(al[ac], XmNdialogType, dialogType); ac++;
  3713. XtSetArg(al[ac], XmNmessageString, tmpStr); ac++;
  3714. XtSetValues(M_gen_warning(editor), al, ac);
  3715. XmStringFree(tmpStr);
  3716. XtFree( (char *) tmpMess );
  3717. XtManageChild (M_gen_warning(editor));
  3718. } /* end _DtEditorWarning */
  3719. /*********************************************************************
  3720. *
  3721. * The following section contains the procedures related to the staus
  3722. * line
  3723. *
  3724. *********************************************************************/
  3725. #define FORCE True
  3726. #define DONT_FORCE False
  3727. /*
  3728. * PositionActivateCB is invoked when the user presses [Return] after
  3729. * (presumably) modifying the current line text field. It retrieves
  3730. * the user specified line number and calls DtEditorGoToLine().
  3731. */
  3732. /* ARGSUSED */
  3733. static void
  3734. PositionActivateCB(
  3735. Widget w,
  3736. caddr_t client_data,
  3737. caddr_t call_data )
  3738. {
  3739. DtEditorWidget editor = (DtEditorWidget)client_data;
  3740. char *lineStr = XmTextFieldGetString(M_status_lineText(editor));
  3741. int newLineNum = atoi(lineStr);
  3742. XtFree(lineStr);
  3743. DtEditorGoToLine ((Widget)editor, newLineNum);
  3744. XmProcessTraversal(M_text(editor), XmTRAVERSE_CURRENT);
  3745. } /* PositionActivateCB */
  3746. /*
  3747. * _DtEditorUpdateLineDisplay updates the current & total line displays
  3748. * in the status line, if needed. Normally, the displays are not changed
  3749. * if the correct numbers are (supposedly) displayed. Setting forceUpdate
  3750. * will cause the numbers to be updated anyways. This is primarily used
  3751. * when the user enters a number into the current line display to force
  3752. * display of the correct number.
  3753. */
  3754. void
  3755. _DtEditorUpdateLineDisplay(
  3756. DtEditorWidget editor,
  3757. int currentLine,
  3758. Boolean forceUpdate )
  3759. {
  3760. XmTextWidget tw = (XmTextWidget) M_text(editor);
  3761. Arg al[10];
  3762. char tmpChars[8];
  3763. int lastLine;
  3764. XmString tmpXmStr;
  3765. /*
  3766. * Only change the current & total lines displays if the status
  3767. * line is visible
  3768. */
  3769. if ( M_status_showStatusLine(editor) == True )
  3770. {
  3771. /*
  3772. * Current line
  3773. */
  3774. if (M_status_currentLine(editor) != currentLine || forceUpdate)
  3775. {
  3776. sprintf(tmpChars, "%d", currentLine);
  3777. XmTextFieldSetString(M_status_lineText(editor), tmpChars);
  3778. M_status_currentLine(editor) = currentLine;
  3779. }
  3780. /*
  3781. * Total lines
  3782. */
  3783. lastLine = tw->text.total_lines;
  3784. if(M_status_lastLine(editor) != lastLine )
  3785. {
  3786. sprintf(tmpChars, "%d", lastLine);
  3787. tmpXmStr = XmStringCreateLocalized(tmpChars);
  3788. XtSetArg(al[0], XmNlabelString, tmpXmStr);
  3789. XtSetValues( M_status_totalText(editor), al, 1 );
  3790. XmStringFree(tmpXmStr);
  3791. M_status_lastLine(editor) = lastLine;
  3792. }
  3793. }
  3794. } /* end _DtEditorUpdateLineDisplay */
  3795. static void
  3796. UpdateOverstrikeIndicator(
  3797. DtEditorWidget widget,
  3798. Boolean overstrikeOn )
  3799. {
  3800. Arg al[10];
  3801. int ac;
  3802. DtEditorWidget ew = (DtEditorWidget) widget;
  3803. /*
  3804. * Only change the overstrike indicator if the status line is visible
  3805. */
  3806. if ( M_status_showStatusLine(ew) == True &&
  3807. M_status_overstrikeWidget(ew) != (Widget) NULL )
  3808. {
  3809. ac=0;
  3810. if ( overstrikeOn == True ) {
  3811. XtSetArg(al[ac], XmNlabelString, M_status_overstrikeLabel(ew)); ac++;
  3812. }
  3813. else {
  3814. XtSetArg(al[ac], XmNlabelString, M_status_insertLabel(ew)); ac++;
  3815. }
  3816. XtSetValues( M_status_overstrikeWidget(ew), al, ac );
  3817. }
  3818. } /* end UpdateOverstrikeIndicator */
  3819. int
  3820. _DtEditorGetLineIndex(
  3821. XmTextWidget tw,
  3822. XmTextPosition pos)
  3823. {
  3824. int startLine, lastLine, middleLine;
  3825. XmTextLineTable lineTab = tw->text.line_table;
  3826. startLine = 0;
  3827. lastLine = tw->text.total_lines - 1;
  3828. while(startLine != lastLine)
  3829. {
  3830. middleLine = (startLine + lastLine)/2;
  3831. if(middleLine == startLine || middleLine == lastLine)
  3832. {
  3833. /*
  3834. * We're down to 2 lines. It's gotta be on one of these
  3835. * two lines.
  3836. */
  3837. if(pos < (XmTextPosition) lineTab[lastLine].start_pos)
  3838. lastLine = startLine;
  3839. else
  3840. startLine = lastLine;
  3841. }
  3842. else
  3843. {
  3844. if (pos < (XmTextPosition) lineTab[middleLine].start_pos)
  3845. lastLine = middleLine;
  3846. else
  3847. startLine = middleLine;
  3848. }
  3849. }
  3850. return startLine;
  3851. } /* end _DtEditorGetLineIndex */
  3852. /*
  3853. * SetCursorPosStatus is called as an XmNmotionVerifyCallback on the
  3854. * text widget when the statusLine is turned on. It computes and
  3855. * displays the new line of the insert cursor.
  3856. */
  3857. static void
  3858. SetCursorPosStatus(
  3859. Widget w,
  3860. caddr_t client_data,
  3861. caddr_t call_data )
  3862. {
  3863. DtEditorWidget editor = (DtEditorWidget)client_data;
  3864. XmTextWidget tw = (XmTextWidget)w;
  3865. XmTextVerifyCallbackStruct * cb = (XmTextVerifyCallbackStruct *) call_data;
  3866. int startLine;
  3867. startLine = _DtEditorGetLineIndex(tw, cb->newInsert) + 1;
  3868. _DtEditorUpdateLineDisplay( editor, startLine, FORCE );
  3869. } /* end SetCursorPosStatus */
  3870. static void
  3871. SetStatusLine(
  3872. DtEditorWidget ew,
  3873. Boolean statusLineOn)
  3874. {
  3875. Arg al[10];
  3876. int ac;
  3877. int currentLine;
  3878. XmTextPosition cursorPos;
  3879. M_status_showStatusLine(ew) = statusLineOn;
  3880. if( statusLineOn == True )
  3881. {
  3882. if( M_status_statusArea(ew) == (Widget)NULL )
  3883. M_status_statusArea(ew) = CreateStatusLine( ew );
  3884. /*
  3885. * Update the line counts
  3886. */
  3887. cursorPos = (XmTextPosition)DtEditorGetInsertionPosition( (Widget)ew );
  3888. currentLine = _DtEditorGetLineIndex( (XmTextWidget) M_text(ew),
  3889. cursorPos ) + 1;
  3890. _DtEditorUpdateLineDisplay( ew, currentLine, DONT_FORCE );
  3891. /*
  3892. * Update the overstrike indicator
  3893. */
  3894. UpdateOverstrikeIndicator( ew, M_overstrikeMode(ew) );
  3895. /*
  3896. * Show the status line
  3897. */
  3898. XtManageChild( M_status_statusArea(ew) );
  3899. /*
  3900. * Hook the scrolled text widget to the status line
  3901. */
  3902. ac = 0;
  3903. XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_WIDGET ); ac++;
  3904. XtSetArg( al[ac], XmNbottomWidget, M_status_statusArea(ew) ); ac++;
  3905. XtSetValues( XtParent(M_text(ew)), al, ac );
  3906. XtAddCallback( M_text(ew), XmNmotionVerifyCallback,
  3907. (XtCallbackProc) SetCursorPosStatus, (XtPointer)ew);
  3908. }
  3909. else
  3910. {
  3911. /*
  3912. * Hook the scrolled text widget to the bottom of the form
  3913. */
  3914. ac = 0;
  3915. XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
  3916. XtSetValues( XtParent(M_text(ew)), al, ac );
  3917. XtRemoveCallback( M_text(ew), XmNmotionVerifyCallback,
  3918. (XtCallbackProc) SetCursorPosStatus, (XtPointer)ew);
  3919. /*
  3920. * Hide the status line
  3921. */
  3922. if( M_status_statusArea(ew) != (Widget)NULL )
  3923. XtUnmanageChild( M_status_statusArea(ew) );
  3924. }
  3925. } /* SetStatusLine */
  3926. /************************************************************************
  3927. *
  3928. * CreateStatusLine - Creates the status line
  3929. *
  3930. ************************************************************************/
  3931. static Widget
  3932. CreateStatusLine(
  3933. DtEditorWidget parent)
  3934. {
  3935. Arg al[20];
  3936. int ac;
  3937. Widget container;
  3938. XmString tmpStr;
  3939. Pixel background, foreground;
  3940. /*
  3941. * Match the background & foreground colors of the edit window
  3942. * Don't use DtNtextBackground/Foreground directly because they
  3943. * will be DtUNSPECIFIED.
  3944. */
  3945. ac = 0;
  3946. XtSetArg(al[ac], XmNforeground, &foreground); ac++;
  3947. XtSetArg(al[ac], XmNbackground, &background); ac++;
  3948. XtGetValues(M_text(parent), al, ac);
  3949. /*
  3950. * Create the status line container
  3951. */
  3952. ac = 0;
  3953. XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
  3954. XtSetArg( al[ac], XmNleftAttachment, XmATTACH_FORM ); ac++;
  3955. XtSetArg( al[ac], XmNrightAttachment, XmATTACH_FORM ); ac++;
  3956. XtSetArg( al[ac], XmNverticalSpacing, 3 ); ac++;
  3957. XtSetArg( al[ac], XmNhorizontalSpacing, 3 ); ac++;
  3958. container = (Widget) XmCreateForm( (Widget)parent, "statusLine",
  3959. al, ac );
  3960. /*
  3961. * Create the current line label and text field
  3962. */
  3963. ac = 0;
  3964. if (E_status_currentLineLabel(parent) != (XmString)DtUNSPECIFIED)
  3965. {
  3966. /*
  3967. * Use the resource value & clear it (to save space).
  3968. */
  3969. tmpStr = XmStringCopy(E_status_currentLineLabel(parent));
  3970. E_status_currentLineLabel(parent) = (XmString)DtUNSPECIFIED;
  3971. }
  3972. else {
  3973. /*
  3974. * The resource has not been set so use its default value
  3975. */
  3976. tmpStr = XmStringCreateLocalized(LINE);
  3977. }
  3978. XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
  3979. XtSetArg( al[ac], XmNtopAttachment, XmATTACH_FORM ); ac++;
  3980. XtSetArg( al[ac], XmNleftAttachment, XmATTACH_FORM ); ac++;
  3981. XtSetArg(al[ac], XmNlabelString, tmpStr); ac++;
  3982. XtSetArg(al[ac], XmNfontList, E_labelFontList(parent) ); ac++;
  3983. M_status_lineLabel(parent) = (Widget) XmCreateLabelGadget( container,
  3984. "lineLabel", al, ac);
  3985. XtManageChild(M_status_lineLabel(parent));
  3986. XtAddCallback(M_status_lineLabel(parent), XmNhelpCallback,
  3987. (XtCallbackProc)HelpStatusCurrentLineCB, parent);
  3988. XmStringFree(tmpStr);
  3989. ac = 0;
  3990. XtSetArg(al[ac], XmNcolumns, 6); ac++;
  3991. XtSetArg(al[ac], XmNforeground, foreground); ac++;
  3992. XtSetArg(al[ac], XmNbackground, background); ac++;
  3993. XtSetArg( al[ac], XmNfontList, E_textFontList(parent)); ac++;
  3994. XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
  3995. XtSetArg( al[ac], XmNtopAttachment, XmATTACH_FORM ); ac++;
  3996. XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
  3997. XtSetArg( al[ac], XmNleftWidget, M_status_lineLabel(parent) ); ac++;
  3998. M_status_lineText(parent) = XmCreateTextField( container, "lineText",
  3999. al, ac );
  4000. XtManageChild(M_status_lineText(parent));
  4001. XtAddCallback(M_status_lineText(parent), XmNactivateCallback,
  4002. (XtCallbackProc)PositionActivateCB, parent);
  4003. XtAddCallback(M_status_lineText(parent), XmNhelpCallback,
  4004. (XtCallbackProc)HelpStatusCurrentLineCB, parent);
  4005. /*
  4006. * Create the total lines labels
  4007. */
  4008. ac = 0;
  4009. if (E_status_totalLineCountLabel(parent) != (XmString)DtUNSPECIFIED)
  4010. {
  4011. /*
  4012. * Use the resource value & clear it (to save space).
  4013. */
  4014. tmpStr = XmStringCopy(E_status_totalLineCountLabel(parent));
  4015. E_status_totalLineCountLabel(parent) = (XmString)DtUNSPECIFIED;
  4016. }
  4017. else {
  4018. /*
  4019. * The resource has not been set so use its default value
  4020. */
  4021. tmpStr = XmStringCreateLocalized(TOTAL);
  4022. }
  4023. XtSetArg(al[ac], XmNlabelString, tmpStr); ac++;
  4024. XtSetArg(al[ac], XmNfontList, E_labelFontList(parent) ); ac++;
  4025. XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
  4026. XtSetArg( al[ac], XmNtopAttachment, XmATTACH_FORM ); ac++;
  4027. XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
  4028. XtSetArg( al[ac], XmNleftWidget, M_status_lineText(parent) ); ac++;
  4029. M_status_totalLabel(parent) = (Widget) XmCreateLabelGadget( container,
  4030. "totalLabel", al, ac);
  4031. XtManageChild(M_status_totalLabel(parent));
  4032. XtAddCallback(M_status_totalLabel(parent), XmNhelpCallback,
  4033. (XtCallbackProc)HelpStatusTotalLinesCB, parent);
  4034. XmStringFree(tmpStr);
  4035. ac = 0;
  4036. XtSetArg(al[ac], XmNfontList, E_labelFontList(parent) ); ac++;
  4037. XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
  4038. XtSetArg( al[ac], XmNtopAttachment, XmATTACH_FORM ); ac++;
  4039. XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
  4040. XtSetArg( al[ac], XmNleftWidget, M_status_totalLabel(parent) ); ac++;
  4041. M_status_totalText(parent) = (Widget) XmCreateLabelGadget( container,
  4042. "totalText", al, ac);
  4043. XtManageChild(M_status_totalText(parent));
  4044. XtAddCallback(M_status_totalText(parent), XmNhelpCallback,
  4045. (XtCallbackProc)HelpStatusTotalLinesCB, parent);
  4046. /*
  4047. * Create the overstrike indicator
  4048. */
  4049. ac = 0;
  4050. /*
  4051. XtSetArg(al[ac], XmNrecomputeSize, False); ac++;
  4052. */
  4053. XtSetArg(al[ac], XmNmarginLeft, 0); ac++;
  4054. XtSetArg(al[ac], XmNmarginRight, 0); ac++;
  4055. XtSetArg(al[ac], XmNmarginWidth, 0); ac++;
  4056. XtSetArg( al[ac], XmNrightOffset, 3 ); ac++;
  4057. XtSetArg(al[ac], XmNfontList, E_labelFontList(parent) ); ac++;
  4058. XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
  4059. XtSetArg( al[ac], XmNtopAttachment, XmATTACH_FORM ); ac++;
  4060. XtSetArg( al[ac], XmNrightAttachment, XmATTACH_FORM ); ac++;
  4061. M_status_overstrikeWidget(parent) =
  4062. (Widget) XmCreateLabelGadget( container, "overstrikeLabel", al, ac);
  4063. XtManageChild(M_status_overstrikeWidget(parent));
  4064. XtAddCallback(M_status_overstrikeWidget(parent), XmNhelpCallback,
  4065. (XtCallbackProc)HelpStatusOverstrikeCB, parent);
  4066. /*
  4067. * Create the application message area
  4068. */
  4069. ac = 0;
  4070. XtSetArg(al[ac], XmNbackground, parent->core.background_pixel); ac++;
  4071. XtSetArg(al[ac], XmNforeground, foreground); ac++;
  4072. XtSetArg( al[ac], XmNfontList, E_textFontList(parent)); ac++;
  4073. XtSetArg(al[ac], XmNeditable, False); ac++;
  4074. XtSetArg(al[ac], XmNcursorPositionVisible, False); ac++;
  4075. XtSetArg(al[ac], XmNtraversalOn, False); ac++;
  4076. XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
  4077. XtSetArg( al[ac], XmNtopAttachment, XmATTACH_FORM ); ac++;
  4078. XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
  4079. XtSetArg( al[ac], XmNleftWidget, M_status_totalText(parent) ); ac++;
  4080. XtSetArg( al[ac], XmNleftOffset, 17 ); ac++;
  4081. XtSetArg( al[ac], XmNrightAttachment, XmATTACH_WIDGET ); ac++;
  4082. XtSetArg(al[ac], XmNrightWidget, M_status_overstrikeWidget(parent)); ac++;
  4083. M_status_messageText(parent) =
  4084. XmCreateTextField( container, "messageText", al, ac );
  4085. XtManageChild(M_status_messageText(parent));
  4086. XtAddCallback(M_status_messageText(parent), XmNhelpCallback,
  4087. (XtCallbackProc)HelpStatusMessageCB, parent);
  4088. return( container );
  4089. } /* end CreateStatusLine */
  4090. /*********************************************************************
  4091. *
  4092. * The following section contains the procedures related to help
  4093. *
  4094. *********************************************************************/
  4095. static void
  4096. CallHelpCallback(
  4097. DtEditorWidget editor,
  4098. int reason)
  4099. {
  4100. DtEditorHelpCallbackStruct help_cb;
  4101. help_cb.reason = reason;
  4102. help_cb.event = (XEvent *) NULL;
  4103. XtCallCallbackList( (Widget)editor, M_HelpCB(editor),
  4104. (XtPointer) &help_cb );
  4105. } /* end CallHelpCallback */
  4106. /****
  4107. * Edit window help callbacks
  4108. */
  4109. /* ARGSUSED */
  4110. static void
  4111. HelpEditWindowCB(
  4112. Widget w,
  4113. caddr_t client_data,
  4114. caddr_t call_data )
  4115. {
  4116. CallHelpCallback((DtEditorWidget)client_data, DtEDITOR_HELP_EDIT_WINDOW);
  4117. }
  4118. /****
  4119. * Status Line help callbacks
  4120. */
  4121. /* XXX
  4122. * Who uses this??
  4123. */
  4124. /* ARGSUSED */
  4125. static void
  4126. HelpStatusLineCB(
  4127. Widget w,
  4128. caddr_t client_data,
  4129. caddr_t call_data )
  4130. {
  4131. CallHelpCallback((DtEditorWidget)client_data, DtEDITOR_HELP_STATUS_LINE);
  4132. }
  4133. /* ARGSUSED */
  4134. static void
  4135. HelpStatusCurrentLineCB(
  4136. Widget w,
  4137. caddr_t client_data,
  4138. caddr_t call_data )
  4139. {
  4140. CallHelpCallback( (DtEditorWidget)client_data,
  4141. DtEDITOR_HELP_STATUS_CURRENT_LINE );
  4142. }
  4143. /* ARGSUSED */
  4144. static void
  4145. HelpStatusTotalLinesCB(
  4146. Widget w,
  4147. caddr_t client_data,
  4148. caddr_t call_data )
  4149. {
  4150. CallHelpCallback( (DtEditorWidget)client_data,
  4151. DtEDITOR_HELP_STATUS_TOTAL_LINES );
  4152. }
  4153. /* ARGSUSED */
  4154. static void
  4155. HelpStatusMessageCB(
  4156. Widget w,
  4157. caddr_t client_data,
  4158. caddr_t call_data )
  4159. {
  4160. CallHelpCallback( (DtEditorWidget)client_data,
  4161. DtEDITOR_HELP_STATUS_MESSAGE );
  4162. }
  4163. /* ARGSUSED */
  4164. static void
  4165. HelpStatusOverstrikeCB(
  4166. Widget w,
  4167. caddr_t client_data,
  4168. caddr_t call_data )
  4169. {
  4170. CallHelpCallback( (DtEditorWidget)client_data,
  4171. DtEDITOR_HELP_STATUS_OVERSTRIKE );
  4172. }
  4173. /****
  4174. * Format Settings dialog help callbacks
  4175. */
  4176. /* ARGSUSED */
  4177. static void
  4178. HelpFormatDialogCB(
  4179. Widget w,
  4180. caddr_t client_data,
  4181. caddr_t call_data )
  4182. {
  4183. CallHelpCallback((DtEditorWidget)client_data, DtEDITOR_HELP_FORMAT_DIALOG);
  4184. }
  4185. /* ARGSUSED */
  4186. static void
  4187. HelpFormatRightMarginCB(
  4188. Widget w,
  4189. caddr_t client_data,
  4190. caddr_t call_data )
  4191. {
  4192. CallHelpCallback( (DtEditorWidget)client_data,
  4193. DtEDITOR_HELP_FORMAT_RIGHT_MARGIN);
  4194. }
  4195. /* ARGSUSED */
  4196. static void
  4197. HelpFormatLeftMarginCB(
  4198. Widget w,
  4199. caddr_t client_data,
  4200. caddr_t call_data )
  4201. {
  4202. CallHelpCallback( (DtEditorWidget)client_data,
  4203. DtEDITOR_HELP_FORMAT_LEFT_MARGIN);
  4204. }
  4205. /* ARGSUSED */
  4206. static void
  4207. HelpFormatJustifyButtonsCB(
  4208. Widget w,
  4209. caddr_t client_data,
  4210. caddr_t call_data )
  4211. {
  4212. CallHelpCallback( (DtEditorWidget)client_data,
  4213. DtEDITOR_HELP_FORMAT_ALIGNMENT);
  4214. }
  4215. /****
  4216. * Find/Change & Spell dialogs help callbacks
  4217. */
  4218. /* ARGSUSED */
  4219. void
  4220. _DtEditorHelpSearchCB(
  4221. Widget w,
  4222. caddr_t client_data,
  4223. caddr_t call_data )
  4224. {
  4225. DtEditorWidget editor = (DtEditorWidget)client_data;
  4226. switch (M_search_dialogMode(editor))
  4227. {
  4228. case SPELL:
  4229. CallHelpCallback( (DtEditorWidget)client_data,
  4230. DtEDITOR_HELP_SPELL_DIALOG);
  4231. break;
  4232. case REPLACE:
  4233. default:
  4234. CallHelpCallback( (DtEditorWidget)client_data,
  4235. DtEDITOR_HELP_CHANGE_DIALOG);
  4236. break;
  4237. }
  4238. } /* _DtEditorHelpSearchCB */
  4239. /* ARGSUSED */
  4240. void
  4241. _DtEditorHelpSearchFindCB(
  4242. Widget w,
  4243. caddr_t client_data,
  4244. caddr_t call_data )
  4245. {
  4246. CallHelpCallback( (DtEditorWidget)client_data,
  4247. DtEDITOR_HELP_CHANGE_FIND);
  4248. }
  4249. /* ARGSUSED */
  4250. void
  4251. _DtEditorHelpSearchChangeCB(
  4252. Widget w,
  4253. caddr_t client_data,
  4254. caddr_t call_data )
  4255. {
  4256. DtEditorWidget editor = (DtEditorWidget)client_data;
  4257. switch (M_search_dialogMode(editor))
  4258. {
  4259. case SPELL:
  4260. CallHelpCallback( (DtEditorWidget)client_data,
  4261. DtEDITOR_HELP_SPELL_CHANGE);
  4262. break;
  4263. case REPLACE:
  4264. default:
  4265. CallHelpCallback( (DtEditorWidget)client_data,
  4266. DtEDITOR_HELP_CHANGE_CHANGE);
  4267. break;
  4268. }
  4269. } /* _DtEditorHelpSearchChangeCB */
  4270. /* ARGSUSED */
  4271. void
  4272. _DtEditorHelpSearchSpellCB(
  4273. Widget w,
  4274. caddr_t client_data,
  4275. caddr_t call_data )
  4276. {
  4277. CallHelpCallback( (DtEditorWidget)client_data,
  4278. DtEDITOR_HELP_SPELL_MISSPELLED_WORDS);
  4279. }
  4280. /*********************************************************************
  4281. *
  4282. * The following section contains the procedures related to formating
  4283. * text and the Format Settings dialog.
  4284. *
  4285. *********************************************************************/
  4286. /*
  4287. * Do simple formatting of paragraphs of text.
  4288. * Designed for speed, at some cost in complexity and redundancy.
  4289. *
  4290. * There is a minor undocumented bug in Dump(). It calls Justify() in the
  4291. * case where the last word of the last line of a paragraph is an end-of-
  4292. * sentence word (typical) and ends just one blank before the margin
  4293. * (rare). This results in one blank being inserted in the line when it's
  4294. * not necessary. It happens because the two trailing blanks after the
  4295. * word cause an "ordinary" line dump before Fill() sees the next line and
  4296. * knows it has an end of paragraph. WARNING: The situation would be
  4297. * aggravated if FillWord() ever set blanks to an even larger number.
  4298. */
  4299. /*
  4300. ** This section contains changes for EUC_4B compatibility.
  4301. ** WPI interface is used.
  4302. */
  4303. /* Global Variables and extern declarations */
  4304. typedef struct _WORD{ /* describe one word */
  4305. wint_t *cp; /* word location in buffer */
  4306. int inlinenum; /* word start line in input */
  4307. int incolumn; /* word start column in input */
  4308. int length; /* size of word */
  4309. int score; /* word + next for jflag */
  4310. int blanks; /* output trailing blanks need */
  4311. int wclen; /* Length of wide character word */
  4312. } WORD;
  4313. typedef struct {
  4314. wchar_t Blank;
  4315. AdjRecPtr pAdj;
  4316. /* FORMATTING CONTROL */
  4317. int m0flag;
  4318. long fillmargin;
  4319. long centermiddle;
  4320. int tabsize; /* tab size in use */
  4321. int centerstartpara; /* expect para. start? in "Center" */
  4322. /* Global/static vars used in "Fill" */
  4323. wint_t *wordbuf; /* see comments for "Fill" for discussion */
  4324. wint_t *wordcp;
  4325. wint_t *wordcpwrap;
  4326. WORD *word;
  4327. WORD *wordbase;
  4328. WORD *wordlimit;
  4329. WORD *wordfirst;
  4330. WORD *wordat;
  4331. WORD *wordnext;
  4332. int inlinenum;
  4333. int incolumn;
  4334. int outlinenum;
  4335. int pendchars;
  4336. int indent1, indent2;
  4337. } FormatData;
  4338. #define isekinsoku(wc) iswctype((wc),ekinclass)
  4339. #define isbekinsoku(wc) iswctype((wc),bekinclass)
  4340. #define LINESIZE BUFSIZ /* how big a line can be */
  4341. #define WORDMAX LINESIZE /* see above for discussion */
  4342. #define WORDNEXT(d,at) { if (++at == d->wordlimit) at = d->wordbase; } /* statement */
  4343. #define WORDPREV(d,at) (((at == d->wordbase) ? d->wordlimit : at) - 1) /* function */
  4344. #include <locale.h>
  4345. extern int _nl_space_alt;
  4346. /*
  4347. * Forward declarations
  4348. */
  4349. static int DoLine (FormatData *data, FILE *filep);
  4350. static void Center (FormatData *data,
  4351. wint_t *in_line, wint_t *inlinelim);
  4352. static void Fill (FormatData *data, wint_t *in_line, wint_t *inlinelim);
  4353. static void FillWord (FormatData *data);
  4354. static void Dump (FormatData *data, int endpara);
  4355. static void PrintIndent (FormatData *data, int indent);
  4356. static void PrintTag (FormatData *data, WORD *wordpast);
  4357. static void PrintWords (FormatData *data, WORD *wordpast);
  4358. static void Justify (FormatData *data, int blanks, WORD *wordpast);
  4359. static int CompareWords (const void *, const void *);
  4360. static int EkinBekinProc(FormatData *data, WORD **wordpast);
  4361. static void postEkinBekinProc(FormatData *data, int *poutchars, WORD *wordpast);
  4362. #if defined(sun)
  4363. /*
  4364. * A small workaround for systems that don't have wcwidth...
  4365. */
  4366. static int
  4367. sun_wcwidth(
  4368. const wchar_t wc)
  4369. {
  4370. int status;
  4371. char mbstr[MB_LEN_MAX + 1];
  4372. status = wctomb(mbstr, wc);
  4373. if (status > 0)
  4374. return(euccol(mbstr));
  4375. else
  4376. return(status);
  4377. }
  4378. #endif /* sun */
  4379. /*
  4380. * The following utilities: lineBlank, findNonBlank, and countBlanks all
  4381. * require the lineLen parameter to specify the number of characters, not
  4382. * bytes, in the line.
  4383. */
  4384. static Boolean
  4385. lineBlank(
  4386. char *pLine,
  4387. int lineLen)
  4388. {
  4389. int byteNum, charNum;
  4390. wchar_t wc;
  4391. size_t mbCurMax = MB_CUR_MAX;
  4392. for(byteNum = charNum = 0; charNum < lineLen;
  4393. byteNum += mblen(&pLine[byteNum], mbCurMax), charNum++)
  4394. {
  4395. (void) mbtowc(&wc, &pLine[byteNum], mbCurMax);
  4396. #if !(defined(sun) && (_XOPEN_VERSION==3))
  4397. if( !iswctype(wc, _DtEditor_blankClass) )
  4398. return False;
  4399. #else
  4400. if( !iswblank(wc) )
  4401. return False;
  4402. #endif /* not sun */
  4403. }
  4404. return True;
  4405. }
  4406. static char *
  4407. findNonBlank(
  4408. char *pLine,
  4409. int lineLen)
  4410. {
  4411. int byteNum, charNum;
  4412. wchar_t wc;
  4413. size_t mbCurMax = MB_CUR_MAX;
  4414. for(byteNum = charNum = 0; charNum < lineLen;
  4415. byteNum += mblen(&pLine[byteNum], mbCurMax), charNum++)
  4416. {
  4417. (void) mbtowc(&wc, &pLine[byteNum], mbCurMax);
  4418. #if !(defined(sun) && (_XOPEN_VERSION==3))
  4419. if( !iswctype(wc, _DtEditor_blankClass) )
  4420. return &pLine[byteNum];
  4421. #else
  4422. if(! iswblank(wc) )
  4423. return &pLine[byteNum];
  4424. #endif /* not sun */
  4425. }
  4426. return &pLine[byteNum];
  4427. }
  4428. static int
  4429. countBlanks(
  4430. char *pLine,
  4431. int lineLen)
  4432. {
  4433. int byteNum, charNum, count;
  4434. wchar_t wc;
  4435. size_t mbCurMax = MB_CUR_MAX;
  4436. for(byteNum = charNum = 0, count = 0; charNum < lineLen;
  4437. byteNum += mblen(&pLine[byteNum], mbCurMax), charNum++)
  4438. {
  4439. (void) mbtowc(&wc, &pLine[byteNum], mbCurMax);
  4440. if(iswcntrl(wc))
  4441. {
  4442. if(mblen(&pLine[byteNum], mbCurMax) == 1)
  4443. {
  4444. switch((int) pLine[byteNum])
  4445. {
  4446. /*
  4447. * I don't really know what to do with weird embedded chars.
  4448. * This is just a guess. In non-ascii locales this could
  4449. * screw up, but I don't know how else to deal with
  4450. * weird embedded control characters.
  4451. */
  4452. case '\n': /* newline */
  4453. case '\f': /* form feed */
  4454. count++;
  4455. continue;
  4456. case '\t': /* horizontal tab */
  4457. count += 8;
  4458. continue;
  4459. case '\b': /* backspace */
  4460. count--;
  4461. continue;
  4462. case '\r': /* carriage return */
  4463. count = 0;
  4464. continue;
  4465. default:
  4466. return count;
  4467. }
  4468. }
  4469. else
  4470. count++; /* multibyte control chars??? */
  4471. continue;
  4472. }
  4473. #if !(defined(sun) && (_XOPEN_VERSION==3))
  4474. if(!iswctype(wc, _DtEditor_blankClass))
  4475. return count;
  4476. #else
  4477. if(! iswblank(wc) )
  4478. return count;
  4479. #endif /* not sun */
  4480. count++;
  4481. }
  4482. return count;
  4483. }
  4484. /*
  4485. * fixLeftMarginAndNewlines - writes out a substring from the text widget,
  4486. * inserting leading blanks as needed to set the left margin, and adding
  4487. * newlines at all "virtual" (i.e. word-wrapped) lines. It assumes that the
  4488. * specified substring is an integer number of lines - i.e. the substring
  4489. * cannot begin or end in the middle of a line. Non-complying substrings
  4490. * are expanded to encompass whole lines.
  4491. */
  4492. static void
  4493. fixLeftMarginAndNewlines(
  4494. DtEditorWidget editor,
  4495. FILE *fp,
  4496. int leftMargin,
  4497. int rightMargin,
  4498. int startPos,
  4499. int endPos)
  4500. {
  4501. Widget widget = M_text(editor);
  4502. XmTextLineTable lineTable;
  4503. int i;
  4504. int lineIndex, lineLen, nextLen, lineIndent, lastIndex,
  4505. lineByteLen, total_lines;
  4506. Boolean newPara = True;
  4507. char *pLine, *pNext, *pFirstNonBlank, *pLastChar;
  4508. size_t mbCurMax = MB_CUR_MAX;
  4509. lineTable = _XmTextGetLineTable(widget, &total_lines);
  4510. if (leftMargin > rightMargin || leftMargin < 0)
  4511. leftMargin = 0;
  4512. lineIndent = leftMargin;
  4513. /*
  4514. * calculate the starting line number and ending line number
  4515. * for the [sub]string we're operating upon.
  4516. */
  4517. lineIndex = _DtEditorGetLineIndex((XmTextWidget)M_text(editor), startPos);
  4518. lastIndex = _DtEditorGetLineIndex((XmTextWidget)M_text(editor), endPos);
  4519. /*
  4520. * This loop terminates with one line unwritten. This is correct
  4521. * if we're not formatting the last line of the file, as that means
  4522. * that we must be formatting a paragraph, and the paragraph adjust
  4523. * code has trouble locating the end of a paragraph (as opposed to the
  4524. * beginning of the next paragraph. If the last line of the text is
  4525. * to be formatted, it is handled after this loop terminates.
  4526. */
  4527. for(; lineIndex < lastIndex; lineIndex++)
  4528. {
  4529. /*
  4530. * if the current line was word-wrapped, put out a nl.
  4531. */
  4532. if(lineTable[lineIndex].virt_line)
  4533. fwrite("\n", sizeof(char), 1, fp);
  4534. lineLen = lineTable[lineIndex + 1].start_pos -
  4535. lineTable[lineIndex].start_pos;
  4536. pLine = _XmStringSourceGetString((XmTextWidget)M_text(editor),
  4537. lineTable[lineIndex].start_pos,
  4538. lineTable[lineIndex + 1].start_pos, False);
  4539. pLastChar = _DtEditorGetPointer(pLine, lineLen - 1);
  4540. lineByteLen = pLastChar - pLine + mblen(pLastChar, mbCurMax);
  4541. if(lineBlank(pLine, lineLen))
  4542. {
  4543. /*
  4544. * Blank lines indicate the start of a new paragraph.
  4545. * They also don't require any indent adjustment so are
  4546. * quick/easy to write out.
  4547. */
  4548. fwrite( pLine, sizeof(char),
  4549. _DtEditorGetPointer(pLine, lineLen) - pLine, fp );
  4550. newPara = True;
  4551. XtFree(pLine);
  4552. continue;
  4553. }
  4554. if(newPara == True)
  4555. {
  4556. int firstIndent;
  4557. /*
  4558. * Calc the proper indent for the first line, and
  4559. * the indent for the rest of the lines
  4560. * in the paragraph. If there's only one line in the
  4561. * paragraph, then the proper indent is adjustStuff.left_margin.
  4562. */
  4563. /*
  4564. * Get the next line.
  4565. */
  4566. if((total_lines - lineIndex) > 2)
  4567. nextLen = lineTable[lineIndex + 2].start_pos -
  4568. lineTable[lineIndex + 1].start_pos;
  4569. else
  4570. nextLen = XmTextGetLastPosition(widget) -
  4571. lineTable[lineIndex + 1].start_pos;
  4572. pNext = _XmStringSourceGetString((XmTextWidget)M_text(editor),
  4573. lineTable[lineIndex + 1].start_pos,
  4574. lineTable[lineIndex + 1].start_pos + nextLen, False);
  4575. if(lineBlank(pNext, nextLen)) /* single line paragraph */
  4576. firstIndent = lineIndent = leftMargin;
  4577. else
  4578. {
  4579. int curFirstIndent, curSecondIndent, offset;
  4580. curFirstIndent = countBlanks(pLine, lineLen);
  4581. curSecondIndent = countBlanks(pNext, nextLen);
  4582. offset = curFirstIndent - curSecondIndent;
  4583. if(offset >= 0)
  4584. {
  4585. /* second line is closer to the left margin */
  4586. /*
  4587. * Note, the first line will still be indented even
  4588. * if the remaining words in the paragraph can
  4589. * all fit on the first line. The end result is a
  4590. * one line indented paragraph. I am mentioning
  4591. * this because some may think this is a defect.
  4592. */
  4593. firstIndent = leftMargin + offset;
  4594. lineIndent = leftMargin;
  4595. }
  4596. else
  4597. {
  4598. firstIndent = leftMargin;
  4599. lineIndent = leftMargin - offset;
  4600. }
  4601. }
  4602. for(i = firstIndent; i-- > 0;)
  4603. fwrite(" ", sizeof(char), 1, fp); /* that's a _space_ */
  4604. pFirstNonBlank = findNonBlank(pLine, lineLen);
  4605. fwrite(pFirstNonBlank, sizeof(char), lineByteLen -
  4606. (pFirstNonBlank - pLine), fp);
  4607. newPara = False;
  4608. XtFree(pLine);
  4609. continue;
  4610. }
  4611. for(i = lineIndent; i-- > 0;)
  4612. fwrite(" ", sizeof(char), 1, fp); /* that's a _space_ */
  4613. pFirstNonBlank = findNonBlank(pLine, lineLen);
  4614. fwrite(pFirstNonBlank, sizeof(char), lineByteLen -
  4615. (pFirstNonBlank - pLine), fp);
  4616. XtFree(pLine);
  4617. }
  4618. if((total_lines - lineIndex) == 1)
  4619. {
  4620. /*
  4621. * Now we have to handle the last line.
  4622. */
  4623. if(lineTable[lineIndex].virt_line)
  4624. fwrite("\n", sizeof(char), 1, fp);
  4625. if((total_lines - lineIndex) > 2)
  4626. lineLen = lineTable[lineIndex + 1].start_pos -
  4627. lineTable[lineIndex].start_pos;
  4628. else
  4629. lineLen = XmTextGetLastPosition(widget) -
  4630. lineTable[lineIndex].start_pos;
  4631. if(lineLen > 0)
  4632. {
  4633. for(i = lineIndent; i-- > 0;)
  4634. fwrite(" ", sizeof(char), 1, fp); /* that's a _space_ */
  4635. pLine = _XmStringSourceGetString((XmTextWidget)M_text(editor),
  4636. lineTable[lineIndex].start_pos,
  4637. lineTable[lineIndex].start_pos + lineLen, False);
  4638. pLastChar = _DtEditorGetPointer(pLine, lineLen - 1);
  4639. lineByteLen = pLastChar - pLine + mblen(pLastChar, mbCurMax);
  4640. if(lineBlank(pLine, lineLen))
  4641. {
  4642. fwrite(pLine, sizeof(char), lineByteLen, fp);
  4643. }
  4644. else
  4645. {
  4646. pFirstNonBlank = findNonBlank(pLine, lineLen);
  4647. fwrite(pFirstNonBlank, sizeof(char), lineByteLen -
  4648. (pFirstNonBlank - pLine), fp);
  4649. }
  4650. XtFree(pLine);
  4651. }
  4652. }
  4653. XtFree((XtPointer)lineTable);
  4654. }
  4655. /************************************************************************
  4656. * FormatText -
  4657. *
  4658. * Initialize, check arguments embedded in AdjRec, open and read files,
  4659. * and pass a series of lines to lower-level routines.
  4660. */
  4661. static int
  4662. FormatText (
  4663. AdjRecPtr
  4664. pAdjRec)
  4665. {
  4666. long maxmargin; /* max allowed */
  4667. FILE *filep; /* file to read */
  4668. int retVal;
  4669. FormatData data;
  4670. /*
  4671. * INITIALIZE FOR NLS
  4672. */
  4673. mbtowc(&data.Blank," ",1);
  4674. /*
  4675. * Initialize global/statics.
  4676. */
  4677. if((data.wordbuf = malloc(sizeof(wint_t) * LINESIZE * 3)) == (wint_t *)NULL)
  4678. return 0;
  4679. if((data.word = malloc(sizeof(WORD) * WORDMAX)) == (WORD *)NULL)
  4680. {
  4681. retVal = 0;
  4682. goto CleanUp;
  4683. }
  4684. data.tabsize = 8; /* default tab size */
  4685. data.centerstartpara = True;
  4686. data.fillmargin = data.centermiddle = pAdjRec->margin;
  4687. data.m0flag = (data.fillmargin == 0L);
  4688. /*
  4689. * Initialize global/statics for "Fill".
  4690. */
  4691. data.wordcp = data.wordbuf;
  4692. data.wordcpwrap = data.wordbuf + (LINESIZE * 2);
  4693. data.wordbase = & data.word [0];
  4694. data.wordlimit = & data.word [WORDMAX];
  4695. data.wordfirst = & data.word [0];
  4696. data.wordnext = & data.word [0];
  4697. data.inlinenum = 0;
  4698. data.outlinenum = 1;
  4699. data.pendchars = 0;
  4700. /*
  4701. * CHECK ARGUMENTS:
  4702. */
  4703. if (pAdjRec->cflag + pAdjRec->jflag + pAdjRec->rflag > 1)
  4704. {
  4705. retVal = 0;
  4706. goto CleanUp;
  4707. }
  4708. maxmargin = pAdjRec->cflag? (LINESIZE / 2) : LINESIZE;
  4709. if ((data.fillmargin < 0L) || (data.fillmargin > maxmargin))
  4710. {
  4711. retVal = 0;
  4712. goto CleanUp;
  4713. }
  4714. if ((pAdjRec->tabsize > 0) && (pAdjRec->tabsize <= MAXTABSIZE))
  4715. data.tabsize = pAdjRec->tabsize;
  4716. /*
  4717. * OPEN AND READ INPUT FILE:
  4718. */
  4719. filep = pAdjRec->infp;
  4720. data.pAdj = pAdjRec; /* set (file) global var to passed in rec */
  4721. while (DoLine (&data, filep))
  4722. ;
  4723. /*
  4724. * DUMP LAST LINE AND EXIT:
  4725. */
  4726. if (! data.pAdj->cflag) /* not centering */
  4727. {
  4728. Dump (&data, True); /* force end paragraph */
  4729. }
  4730. retVal = 1;
  4731. CleanUp:
  4732. if(data.wordbuf != (wint_t *)NULL)
  4733. {
  4734. free(data.wordbuf);
  4735. }
  4736. if(data.word != (WORD *)NULL)
  4737. {
  4738. free(data.word);
  4739. }
  4740. return retVal;
  4741. }
  4742. /************************************************************************
  4743. * D O L I N E
  4744. *
  4745. * Read one input line and do generic processing (read chars from input
  4746. * to in_line, crunching backspaces). Return True if successful, else
  4747. * false at end of input file. This must be done before expanding tabs;
  4748. * pass half-processed line to Center() or Fill() for more work.
  4749. *
  4750. * Assumes getc() is efficient.
  4751. * in_line[] is static so it is only allocated once.
  4752. */
  4753. static int
  4754. DoLine (FormatData *data,
  4755. FILE *filep) /* open file to read */
  4756. {
  4757. wint_t in_line [LINESIZE]; /* after reading in */
  4758. wint_t *incp = in_line; /* place in in_line */
  4759. wint_t *incplim = in_line + LINESIZE; /* limit of in_line */
  4760. wint_t c;
  4761. /*
  4762. * READ LINE WITH BACKSPACE CRUNCHING:
  4763. */
  4764. while (incp < incplim) /* buffer not full */
  4765. {
  4766. c = getwc (filep); /* get and save wide char */
  4767. switch(c)
  4768. {
  4769. case WEOF:
  4770. if (incp == in_line) /* nothing read yet */
  4771. return (False);
  4772. case L'\0': /* fall through */
  4773. case L'\n': /* end of line */
  4774. incplim = incp; /* set limit (quit loop) */
  4775. break;
  4776. case L'\b': /* backspace */
  4777. if (incp > in_line) /* not at start */
  4778. incp--; /* just back up */
  4779. break;
  4780. default: /* any other char */
  4781. *incp++ = c;
  4782. break;
  4783. }
  4784. }
  4785. /* now incplim is correctly set to last char + 1 */
  4786. /*
  4787. * PASS LINE ON FOR MORE WORK:
  4788. */
  4789. if (data->pAdj->cflag) Center (data, in_line, incplim);
  4790. else Fill (data, in_line, incplim);
  4791. return (True); /* maybe more to read */
  4792. } /* DoLine */
  4793. /************************************************************************
  4794. * C E N T E R
  4795. *
  4796. * Center text (starting at in_line, ending before inlinelim). First copy
  4797. * chars from in_line to outline skipping nonprintables and expanding tabs.
  4798. * For efficiency (at the cost of simplicity), note and skip indentation
  4799. * at the same time. Then, print outline with indentation to center it.
  4800. *
  4801. * outline[] is static so it is only allocated once; startpara so it is
  4802. * used for successive lines.
  4803. */
  4804. static void
  4805. Center (FormatData *data,
  4806. wint_t *in_line, /* start of input line */
  4807. wint_t *inlinelim) /* end of line + 1 */
  4808. {
  4809. wint_t *incp; /* pointer in in_line */
  4810. wint_t outline [LINESIZE + MAXTABSIZE]; /* after generic work */
  4811. wint_t *outcp = outline; /* place in outline */
  4812. wint_t *outlinelim = outline + LINESIZE; /* limit of outline*/
  4813. int haveword = False; /* hit word in in_line? */
  4814. wint_t ch; /* current working char */
  4815. int needsp; /* spaces need for tab */
  4816. int indent = 0; /* size of indentation */
  4817. int textwidth; /* size of text part */
  4818. int extwidth = 0; /* additional width for MBCS */
  4819. /*
  4820. * SCAN INPUT LINE:
  4821. */
  4822. for (incp = in_line; (incp < inlinelim) && (outcp < outlinelim); incp++)
  4823. {
  4824. ch = *incp;
  4825. /*
  4826. * SKIP WHITE SPACE:
  4827. */
  4828. if (iswspace(ch))
  4829. {
  4830. needsp = ((ch != L'\t') && (iswblank(ch))) ?
  4831. 1 : data->tabsize - ((indent + outcp - outline) % data->tabsize);
  4832. if (! haveword) /* indentation */
  4833. indent += needsp;
  4834. else /* past text */
  4835. for ( ; needsp > 0; needsp--)
  4836. *outcp++ = data->Blank;
  4837. }
  4838. /*
  4839. * CARRY OVER PRINTABLE CHARS AND NOTE INDENTATION:
  4840. */
  4841. else if (iswprint (ch)) /* note: ch != ' ' */
  4842. {
  4843. *outcp++ = ch; /* just copy it over */
  4844. haveword = True;
  4845. if(MB_CUR_MAX > 1 && wcwidth(ch) > 1)
  4846. extwidth += wcwidth(ch) - 1;
  4847. }
  4848. /* else do nothing, which tosses other chars */
  4849. } /* end for */
  4850. /* Now outcp is the new outlinelim */
  4851. /*
  4852. * HANDLE BLANK LINE (no text):
  4853. */
  4854. if (! haveword)
  4855. {
  4856. putc ('\n', data->pAdj->outfp); /* "eat" any whitespace */
  4857. data->centerstartpara = True; /* expect new paragraph */
  4858. }
  4859. /*
  4860. * EAT TRAILING BLANKS, SET TEXTWIDTH:
  4861. */
  4862. else
  4863. {
  4864. /* note that outcp > outline */
  4865. while ((outcp[-1] != L'\t') && iswblank(outcp [-1]))
  4866. outcp--;
  4867. textwidth = (outcp - outline); /* thus textwidth > 0 */
  4868. /*
  4869. * SET AUTOMARGIN AND PRINT CENTERED LINE:
  4870. *
  4871. * The equations used depend on truncating division:
  4872. *
  4873. * eqn. 1 eqn. 2
  4874. * Margin Middle Width Results
  4875. * odd exact odd exact centering
  4876. * odd exact even extra char to right
  4877. * even left odd extra char to left
  4878. * even left even exact centering (due to "extra" char to right)
  4879. *
  4880. * When centermiddle is default or given by user, it is the same as the
  4881. * first two lines above (middle exactly specified).
  4882. */
  4883. if (data->centerstartpara) /* start of paragraph */
  4884. {
  4885. data->centerstartpara = False;
  4886. if (data->m0flag) /* set automargin */
  4887. /* 1 */ data->centermiddle = (indent + textwidth + extwidth + 1) / 2;
  4888. }
  4889. /* 2 */ PrintIndent (data, data->centermiddle - ((textwidth + extwidth + 1) / 2));
  4890. {
  4891. int i;
  4892. for(i = 0; i < textwidth; i++)
  4893. {
  4894. putwc(outline[i], data->pAdj->outfp);
  4895. }
  4896. putc('\n', data->pAdj->outfp);
  4897. }
  4898. } /* else */
  4899. } /* Center */
  4900. /************************************************************************
  4901. * WORD DATA STRUCTURES USED TO TRACK WORDS WHILE FILLING:
  4902. *
  4903. * This complicated scheme is used to minimize the actual data moving
  4904. * and manipulation needed to do the job.
  4905. *
  4906. * Words are kept in wordbuf[] without trailing nulls. It is large enough
  4907. * to accommodate two lines' worth of words plus wrap around to start a new
  4908. * word (which might be as big as a line) without overwriting old words
  4909. * not yet dumped. wordcp -> next free location in wordbuf[];
  4910. * wordcpwrap -> last place a new word is allowed to start.
  4911. *
  4912. * Words are pointed to and described by word[] structures. The array is
  4913. * big enough to accommodate two lines' worth of words, assuming each word
  4914. * takes at least two characters (including separator). wordbase and
  4915. * wordlimit are the bounds of the array. wordfirst remembers the first
  4916. * word in the array not yet printed. wordat is the word being worked on
  4917. * after wordnext is advanced (and maybe wrapped around). New elements
  4918. * are "allocated" using wordnext, a pointer that is wrapped around as
  4919. * needed.
  4920. *
  4921. * inlinenum and incolumn track the current input line and column per
  4922. * paragraph. outlinenum tracks the next line to print. All are base 1,
  4923. * but inlinenum is preset to zero at the start of each paragraph.
  4924. *
  4925. * pendchars tracks the number of dumpable characters accrued so far, to
  4926. * trigger dumping. indent1 and indent2 remember the indentations seen
  4927. * for the first two lines of each paragraph.
  4928. */
  4929. /************************************************************************
  4930. * F I L L
  4931. *
  4932. * Parse an input line (in_line to inlinelim) into words and trigger
  4933. * FillWord() as needed to finish each word, which in turn can call
  4934. * Dump() to dump output lines. This routine sacrifices simplicity and
  4935. * clarity for efficiency. It uses shared global word data except
  4936. * outlinenum and pendchars.
  4937. */
  4938. static void
  4939. Fill (FormatData *data,
  4940. wint_t *in_line, /* start of input line */
  4941. wint_t *inlinelim) /* end of line + 1 */
  4942. {
  4943. wint_t *incp; /* place in in_line */
  4944. wint_t ch; /* current working char */
  4945. int haveword = False; /* hit word in in_line? */
  4946. int inword = False; /* currently in a word? */
  4947. /*
  4948. * SCAN INPUT LINE:
  4949. */
  4950. data->inlinenum++;
  4951. data->incolumn = 1; /* starting a line */
  4952. for (incp = in_line; incp < inlinelim; incp++)
  4953. {
  4954. ch = *incp;
  4955. /*
  4956. * AT WHITE SPACE; FINISH PREVIOUS WORD if any, then skip white space:
  4957. */
  4958. if (iswspace(ch))
  4959. {
  4960. if (inword) /* was skipping a word */
  4961. {
  4962. inword = False;
  4963. FillWord(data);
  4964. }
  4965. data->incolumn += ((ch != L'\t') && (iswblank(ch))) ?
  4966. 1 : data->tabsize - ((data->incolumn - 1) % data->tabsize);
  4967. }
  4968. /*
  4969. * AT PART OF WORD; START NEW ONE IF NEEDED:
  4970. */
  4971. else if (iswprint (ch))
  4972. {
  4973. if (! inword) /* start new word */
  4974. {
  4975. inword = True;
  4976. if (data->wordcp > data->wordcpwrap)/* past wrap point */
  4977. data->wordcp = data->wordbuf;/* wraparound buffer */
  4978. data->wordat = data->wordnext;
  4979. WORDNEXT (data,data->wordnext);
  4980. data->wordat->cp = data->wordcp; /* note start of word */
  4981. data->wordat->inlinenum = data->inlinenum; /* note input line */
  4982. data->wordat->incolumn = data->incolumn; /* note input column */
  4983. data->wordat->wclen = 0;
  4984. if (! haveword)
  4985. {
  4986. haveword = True;
  4987. switch (data->inlinenum)/* note indentations */
  4988. {
  4989. case 1:
  4990. data->indent1 = data->incolumn - 1;
  4991. break;
  4992. case 2:
  4993. data->indent2 = data->incolumn - 1;
  4994. break;
  4995. }
  4996. }
  4997. }
  4998. /*
  4999. * SAVE ONE CHAR OF WORD:
  5000. */
  5001. *(data->wordcp++) = ch;
  5002. {
  5003. int n = wcwidth(ch);
  5004. if (n > 0)
  5005. { /* == 0 for a null char */
  5006. data->incolumn += n;
  5007. data->wordat->wclen++;
  5008. }
  5009. }
  5010. } /* else */
  5011. /* else skip other chars by doing nothing */
  5012. } /* for */
  5013. /*
  5014. * END OF LINE; HANDLE BLANK LINE, OR FINISH WORD AND AUTOMARGIN:
  5015. */
  5016. if (! haveword) /* no text on line */
  5017. {
  5018. data->inlinenum--; /* don't count empty lines */
  5019. Dump (data, True); /* force end paragraph */
  5020. fputc ('\n', data->pAdj->outfp); /* put this empty line */
  5021. data->inlinenum = 0; /* start new paragraph */
  5022. }
  5023. else /* have text on line */
  5024. {
  5025. if (inword) /* line ends in word */
  5026. FillWord(data);
  5027. if (data->pendchars > data->fillmargin)
  5028. { /* time to dump line */
  5029. Dump (data, False); /* not end of paragraph */
  5030. }
  5031. if (data->m0flag && (data->inlinenum == 1)) /* need to note right margin */
  5032. data->fillmargin = data->wordat->incolumn + data->wordat->length - 1;
  5033. }
  5034. } /* Fill */
  5035. /************************************************************************
  5036. * F I L L W O R D
  5037. *
  5038. * Save values for the word just finished and dump the output line if
  5039. * needed. Uses shared global word values, but does not touch outlinenum,
  5040. * and only increments pendchars.
  5041. *
  5042. * Trailing blanks (1 or 2) needed after a word are figured here.
  5043. * wordlen is the total length (nonzero) and wordcp points to the char
  5044. * past the end of the word. Two blanks are needed after words ending in:
  5045. *
  5046. * <terminal>[<quote>][<close>]
  5047. *
  5048. * where <terminal> is any of . : ? !
  5049. * <quote> is any of ' "
  5050. * <close> is any of ) ] }
  5051. *
  5052. * For efficiency, this routine avoids calling others to do character
  5053. * matching; it does them in line.
  5054. */
  5055. static void
  5056. FillWord (FormatData *data)
  5057. {
  5058. int wordlen; /* length of word to fill */
  5059. int blanks = 1; /* trailing blanks needed */
  5060. wint_t ch1, ch2, ch3; /* last chars of word */
  5061. data->wordat->length = (data->incolumn - data->wordat->incolumn);
  5062. wordlen = data->wordat->wclen;
  5063. /*
  5064. * CHECK FOR SPECIAL END OF WORD:
  5065. */
  5066. ch3 = data->wordcp [-1];
  5067. if ((ch3 == L'.') || (ch3 == L':') || (ch3 == L'?') || (ch3 ==L'!'))
  5068. {
  5069. blanks = 2; /* <terminal> */
  5070. }
  5071. else if (wordlen >= 2)
  5072. {
  5073. ch2 = data->wordcp [-2];
  5074. if( ((ch2 == L'.') || (ch2 == L':') || (ch2 ==L'?') || (ch2 == L'!')) &&
  5075. ((ch3 == L'\'') || (ch3 == L'"') || (ch3 ==L')') || (ch3 == L']')
  5076. || (ch3 == L'}'))
  5077. )
  5078. {
  5079. blanks = 2; /* <terminal><quote or close> */
  5080. }
  5081. else if (wordlen >= 3)
  5082. {
  5083. ch1 = data->wordcp [-3];
  5084. if( ((ch1 == L'.') || (ch1 == L':') || (ch1 == L'?') || (ch1 == L'!'))
  5085. && ((ch2 == L'\'') || (ch2 == L'"'))
  5086. && ((ch3 == L')') || (ch3 == L']') || (ch3 == L'}')) )
  5087. {
  5088. blanks = 2; /* <terminal><quote><close> */
  5089. }
  5090. }
  5091. } /* else */
  5092. /*
  5093. * SAVE VALUES
  5094. */
  5095. data->pendchars += wordlen + (data->wordat->blanks = blanks);
  5096. } /* FillWord */
  5097. /************************************************************************
  5098. * D U M P
  5099. *
  5100. * Print output line(s), with all necessary indentation and formatting,
  5101. * if required (at end of paragraph) or if permissible. If required,
  5102. * indent1 is used if indent2 is not set yet (not on second line of
  5103. * input). Otherwise, if not at end of paragraph, dumping is only
  5104. * permissible after beginning the second input line, so fillmargin and
  5105. * indent2 are known, so tagged paragraphs are done right.
  5106. *
  5107. * Whenever dumping, all "full" lines are dumped, which means more than
  5108. * just one may be printed per call. jflag or rflag formatting is
  5109. * applied to all lines, except that jflag is ignored for the last line
  5110. * of each paragraph.
  5111. *
  5112. * Uses shared global word data, but does not touch inlinenum, incolumn,
  5113. * indent1, or indent2.
  5114. */
  5115. static void
  5116. Dump (FormatData *data,
  5117. int endpara) /* end of paragraph? */
  5118. {
  5119. int haveindent2 = (data->inlinenum >= 2); /* indent2 known? */
  5120. int startpara; /* start of paragraph? */
  5121. int normal; /* non-tagged line? */
  5122. WORD *wordpast = data->wordfirst; /* past last to dump */
  5123. int wordlen; /* length of one word */
  5124. int indent; /* local value */
  5125. int outneed; /* chars need to dump */
  5126. int outchars; /* chars found to dump */
  5127. /*
  5128. * IF DUMPING NEEDED, DUMP LINES TILL DONE:
  5129. */
  5130. if (! (endpara || haveindent2)) /* not time to dump */
  5131. return;
  5132. while ( (data->pendchars > data->fillmargin) /* line is full */
  5133. || (endpara && (data->wordfirst != data->wordnext)) ) /* more to dump */
  5134. {
  5135. startpara = (data->outlinenum < 2);
  5136. indent = (startpara || (! haveindent2)) ? data->indent1 : data->indent2;
  5137. /*
  5138. * CHECK FOR TAGGED PARAGRAPH if needed:
  5139. */
  5140. normal = True; /* default == no tag */
  5141. if (startpara && haveindent2 && (data->indent1 < data->indent2))
  5142. {
  5143. int incol2 = data->indent2 + 1; /* column needed */
  5144. while ( (wordpast != data->wordnext) /* more words */
  5145. && (wordpast->inlinenum == 1)) /* from line 1 */
  5146. {
  5147. if (wordpast->incolumn == incol2) /* bingo */
  5148. {
  5149. normal = False;
  5150. break;
  5151. }
  5152. WORDNEXT (data,wordpast);
  5153. }
  5154. if (normal)
  5155. wordpast = data->wordfirst; /* reset value */
  5156. /*
  5157. * PRINT TAG PART OF TAGGED PARAGRAPH:
  5158. */
  5159. else
  5160. {
  5161. WORD *wordat = data->wordfirst; /* local value */
  5162. while (wordat != wordpast) /* decrement pendchars */
  5163. {
  5164. data->pendchars -= wordat->length + wordat->blanks;
  5165. WORDNEXT (data,wordat);
  5166. }
  5167. PrintIndent (data, indent);
  5168. PrintTag (data, wordpast); /* preceding words */
  5169. data->wordfirst = wordpast; /* do rest of line */
  5170. indent = data->indent2; /* as if second line */
  5171. }
  5172. } /* if */
  5173. /*
  5174. * FIND WORDS WHICH FIT ON [REST OF] LINE:
  5175. */
  5176. if (indent >= data->fillmargin) /* don't over indent */
  5177. indent = data->fillmargin - 1;
  5178. outneed = data->fillmargin - indent; /* always greater than zero */
  5179. outchars = 0;
  5180. wordlen = wordpast->length;
  5181. do { /* always consume one */
  5182. outchars += wordlen + wordpast->blanks;
  5183. WORDNEXT (data,wordpast);
  5184. } while ( (wordpast != data->wordnext) /* not last word */
  5185. && (outchars + (wordlen = wordpast->length) <= outneed)
  5186. );
  5187. /* next will fit */
  5188. /*
  5189. ** BEKINSOKU/EKINSOKU PROCESSING
  5190. */
  5191. if( EkinBekinProc(data, &wordpast) )
  5192. postEkinBekinProc(data, &outchars,wordpast);
  5193. data->pendchars -= outchars; /* pendchars to consume */
  5194. /* from now on, don't include trailing blanks on last word */
  5195. outchars -= (WORDPREV (data,wordpast) -> blanks);
  5196. /* now wordfirst and wordpast specify the words to dump */
  5197. /*
  5198. * PRINT INDENTATION AND PREPARE JUSTIFICATION:
  5199. */
  5200. if (data->pAdj->rflag) /* right-justify only */
  5201. {
  5202. if (normal) /* nothing printed yet */
  5203. PrintIndent (data, data->fillmargin - outchars);
  5204. else /* indent + tag printed */
  5205. {
  5206. int blanks = data->fillmargin - outchars - indent;
  5207. while (blanks-- > 0) /* can't use PrintIndent()*/
  5208. putwc(data->Blank, data->pAdj->outfp);
  5209. }
  5210. }
  5211. else
  5212. {
  5213. if (normal) /* not already done */
  5214. PrintIndent (data, indent);
  5215. if (data->pAdj->jflag && ! (endpara && (wordpast == data->wordnext)))
  5216. Justify (data, outneed - outchars, wordpast);
  5217. }
  5218. /*
  5219. * PRINT REST OF LINE:
  5220. */
  5221. PrintWords (data, wordpast);
  5222. putwc('\n', data->pAdj->outfp);
  5223. data->wordfirst = wordpast;
  5224. data->outlinenum++; /* affects startpara */
  5225. } /* while */
  5226. if (endpara)
  5227. data->outlinenum = 1;
  5228. } /* Dump */
  5229. /************************************************************************
  5230. * P R I N T I N D E N T
  5231. *
  5232. * Print line indentation (if > 0), optionally using tabs where possible.
  5233. * Does not print a newline.
  5234. */
  5235. static void
  5236. PrintIndent (FormatData *data,
  5237. int indent) /* leading indentation */
  5238. {
  5239. if (indent > 0) /* indentation needed */
  5240. {
  5241. if (! data->pAdj->bflag) /* unexpand leading blanks */
  5242. {
  5243. while (indent >= data->tabsize)
  5244. {
  5245. putc ('\t', data->pAdj->outfp);
  5246. indent -= data->tabsize;
  5247. }
  5248. }
  5249. fprintf (data->pAdj->outfp, "%*s", indent, "");/*[remaining] blanks */
  5250. }
  5251. } /* PrintIndent */
  5252. /************************************************************************
  5253. * P R I N T T A G
  5254. *
  5255. * Print paragraph tag words from word[] array beginning with (global)
  5256. * wordfirst and ending before (parameter) wordpast, using input column
  5257. * positions in each word's data. Assumes indentation of indent1 was
  5258. * already printed on the line. Assumes *wordpast is the next word on
  5259. * the line and its column position is valid, and appends spaces up to
  5260. * the start of that word. Doesn't print a newline.
  5261. *
  5262. * Line indentation must already be done, as this routine doesn't know
  5263. * how to print leading tabs, only blanks.
  5264. */
  5265. static void
  5266. PrintTag (FormatData *data,
  5267. WORD *wordpast) /* past last to print */
  5268. {
  5269. WORD *wordat = data->wordfirst; /* local value */
  5270. int outcol = data->indent1 + 1; /* next column */
  5271. int wordcol; /* desired column */
  5272. wint_t *wordcp; /* place in word */
  5273. wint_t *wordcplim; /* limit of word */
  5274. while (True) /* till break */
  5275. {
  5276. wordcol = wordat->incolumn;
  5277. while (outcol < wordcol)/* space over to word */
  5278. {
  5279. putwc(data->Blank, data->pAdj->outfp);
  5280. outcol++;
  5281. }
  5282. if (wordat == wordpast) /* past last word */
  5283. break; /* quit the loop */
  5284. wordcp = wordat->cp;
  5285. wordcplim = wordcp + wordat->wclen;
  5286. while (wordcp < wordcplim) /* print word */
  5287. putwc(*wordcp++, data->pAdj->outfp);
  5288. outcol += wordat->length;
  5289. WORDNEXT (data,wordat);
  5290. }
  5291. } /* PrintTag */
  5292. /************************************************************************
  5293. * P R I N T W O R D S
  5294. *
  5295. * Print words from word[] array beginning with (global) wordfirst and
  5296. * ending before (parameter) wordpast, using word sizes and trailing
  5297. * blanks (except for last word on line). Doesn't print a newline.
  5298. */
  5299. static void
  5300. PrintWords (FormatData *data,
  5301. WORD *wordpast) /* past last to print */
  5302. {
  5303. WORD *wordat = data->wordfirst; /* local value */
  5304. wint_t *wordcp; /* place in word */
  5305. wint_t *wordcplim; /* limit of word */
  5306. int blanks; /* after a word */
  5307. while (True) /* till break */
  5308. {
  5309. wordcp = wordat->cp;
  5310. wordcplim = wordcp + wordat->wclen;
  5311. blanks = wordat->blanks; /* set before do WORDNEXT() */
  5312. while (wordcp < wordcplim) /* print word */
  5313. {
  5314. putwc(*wordcp++, data->pAdj->outfp);
  5315. }
  5316. wordat->wclen = 0;
  5317. WORDNEXT (data,wordat);
  5318. if (wordat == wordpast) /* just did last word */
  5319. break;
  5320. while (blanks-- > 0) /* print trailing blanks */
  5321. putwc(data->Blank, data->pAdj->outfp);
  5322. }
  5323. } /* PrintWords */
  5324. /************************************************************************
  5325. * J U S T I F Y
  5326. *
  5327. * Do left/right justification of [part of] a line in the word[] array
  5328. * beginning with (global) wordfirst and ending before (parameter)
  5329. * wordpast, by figuring where to insert blanks.
  5330. *
  5331. * Gives each word (except the last on the line) a score based on its
  5332. * size plus the size of the next word. Quicksorts word indices into
  5333. * order of current trailing blanks (least first), then score (most
  5334. * first). Cycles through this list adding trailing blanks to word[]
  5335. * entries such that words will space out nicely when printed.
  5336. */
  5337. static void
  5338. Justify (FormatData *data,
  5339. int blanks, /* blanks to insert */
  5340. WORD *wordpast) /* past last to print */
  5341. {
  5342. WORD *wordat; /* local value */
  5343. int sortat; /* place in sort[] */
  5344. int wordlen; /* size of this word */
  5345. int nextlen; /* size of next word */
  5346. int level; /* current blanks level */
  5347. WORD *sort [WORDMAX]; /* sorted pointers */
  5348. int words; /* words in sort[] */
  5349. wordat = WORDPREV (data,wordpast); /* last word on line */
  5350. if ((blanks < 1) || (wordat == data->wordfirst))
  5351. return; /* can't do anything */
  5352. /*
  5353. * COMPUTE SCORES FOR WORDS AND SORT INDICES:
  5354. *
  5355. * March backwards through the words on line, starting with next to last.
  5356. */
  5357. words = 0;
  5358. nextlen = wordat->length; /* length of last word */
  5359. do { /* always at least one */
  5360. wordat = WORDPREV (data,wordat);
  5361. wordlen = wordat->length;
  5362. wordat->score = wordlen + nextlen; /* this plus next */
  5363. nextlen = wordlen;
  5364. sort [words++] = wordat; /* prepare for sorting */
  5365. } while (wordat != data->wordfirst);
  5366. qsort ((wint_t *) sort, words, sizeof (WORD *), CompareWords);
  5367. /*
  5368. * ADD TRAILING BLANKS TO PAD OUT WORDS:
  5369. *
  5370. * Each pass through the sorted list adds one trailing blank to each word
  5371. * not already past the current level. Thus all one-blank words are brought
  5372. * up to two; then all twos up to three; etc.
  5373. */
  5374. level = 0;
  5375. while (True) /* till return */
  5376. {
  5377. level++;
  5378. for (sortat = 0; sortat < words; sortat++)
  5379. {
  5380. wordat = sort [sortat];
  5381. if (wordat->blanks > level) /* end of this level */
  5382. break; /* start next level */
  5383. wordat->blanks++;
  5384. if (--blanks <= 0) /* no more needed */
  5385. return;
  5386. }
  5387. }
  5388. } /* Justify */
  5389. /************************************************************************
  5390. * C O M P A R E W O R D S
  5391. *
  5392. * Compare two word[] entries based on pointers to (WORD *), as called
  5393. * from qsort(3). Tell which entry has priority for receiving inserted
  5394. * blanks (least trailing blanks first, then highest scores), by returning
  5395. * -1 for the first entry, +1 for second entry, or 0 if no difference.
  5396. * (-1 literally means first entry < second entry, so it sorts first.)
  5397. */
  5398. static int
  5399. CompareWords (const void *p1, const void *p2)
  5400. {
  5401. WORD *word1 = *((WORD **)p1); /* (WORD *) pointers */
  5402. WORD *word2 = *((WORD **)p2);
  5403. int blanks1 = word1->blanks; /* trailing blanks */
  5404. int blanks2 = word2->blanks;
  5405. if (blanks1 == blanks2) /* commonest case */
  5406. {
  5407. int score1 = word1->score; /* word scores */
  5408. int score2 = word2->score;
  5409. if (score1 > score2) return (-1); /* word1 has priority */
  5410. else if (score1 < score2) return ( 1);
  5411. else return (0);
  5412. }
  5413. else if (blanks1 < blanks2) return (-1); /* word1 has priority */
  5414. else return ( 1);
  5415. } /* CompareWords */
  5416. /*
  5417. ** BKINSOKU and EKINSOKU processing for Japanese text
  5418. **
  5419. ** The function scans the wordlist that are ready for printing
  5420. ** and updates the "wordpast" pointer based on the rules of
  5421. ** BKINSOKU and EKINSOKU characters.
  5422. **
  5423. ** The code does not split a line just after a "gyomatu kinsoku"
  5424. ** character and just before a "gyoto kinsoku" character.
  5425. ** "Gyomatsu kinsoku" (e-kinsoku) are characters which cannot be
  5426. ** placed at the end of a line. "Gyoto kinsoku" (b-kinsoku) are
  5427. ** characters which can not be placed at the top of a line.
  5428. **
  5429. ** Global variables used:
  5430. ** wordfirst - beginning the word list (buffer of pending lines)
  5431. ** wordnext - next available spot in the pending buffer (i.e.
  5432. ** end of the buffer).
  5433. **
  5434. ** Global variables modified:
  5435. ** None.
  5436. **
  5437. ** Return Values:
  5438. ** 0 - No Post processing is required.
  5439. ** 1 - Post processing is required
  5440. */
  5441. #if !(defined(sun) && (_XOPEN_VERSION==3))
  5442. static int
  5443. EkinBekinProc(FormatData *data,
  5444. WORD **wordpast)
  5445. {
  5446. WORD *curword,*compword,*prevword;
  5447. int ekinflag = False, margin;
  5448. /*
  5449. * curword points to the last word of the first line.
  5450. * compword points to the first word of the next line or to the next
  5451. * available spot if there is no next line.
  5452. */
  5453. compword = *wordpast;
  5454. curword = WORDPREV(data,compword);
  5455. /*
  5456. * If the length of the current word is > fillmargin
  5457. * or it is the only word then return.
  5458. */
  5459. if (curword->length > data->fillmargin || (curword == data->wordfirst))
  5460. return False;
  5461. /*
  5462. * EKINSOKU processing
  5463. * If this character set supports ekinclass (can't end a line) char,
  5464. * start at the end of the line and search back until
  5465. * 1) we find a non-ekinsoku character, or
  5466. * 2) come to the beginning of the pending buffer.
  5467. */
  5468. if (ekinclass)
  5469. {
  5470. while (isekinsoku(*(curword->cp+curword->wclen-1)))
  5471. {
  5472. ekinflag = True;
  5473. if (curword == data->wordfirst) /* Boundary Condition */
  5474. break;
  5475. curword = WORDPREV(data,curword);
  5476. }
  5477. /*
  5478. * Post EKIN processing (i.e. we found an ekinsoku character in
  5479. * the line before finding an non-ekinsoku).
  5480. */
  5481. if (ekinflag) {
  5482. if (curword != data->wordfirst) {
  5483. /*
  5484. * We found a non-ekinsoku after we found the ekinsoku.
  5485. * Move the end of line to just after the non-ekinsoku.
  5486. */
  5487. WORDNEXT(data,curword);
  5488. *wordpast = curword;
  5489. return True;
  5490. }
  5491. else { /* Boundary condition */
  5492. /*
  5493. * Reached the beginning of the buffer without finding a
  5494. * non-ekinsoku. If the last word in the line can begin
  5495. * a line (i.e. non-bkinsoku) make it the first word of
  5496. * the next line.
  5497. */
  5498. curword = WORDPREV(data,compword);
  5499. if (!isbekinsoku(*curword->cp)) {
  5500. *wordpast = curword;
  5501. return True;
  5502. }
  5503. return False;
  5504. }
  5505. }
  5506. }
  5507. /*
  5508. * If we reached this point then:
  5509. * 1) the character set does not support ekinclass characters, or
  5510. * 2) the last character in the line is non-ekinsoku.
  5511. * Now, need to see if we can begin the next line with the first
  5512. * character on that line.
  5513. */
  5514. /*
  5515. * BEKINSOKU processing
  5516. * If this character set supports bekinclass (can't begin a line) char,
  5517. * search forward from the begining of the next line (curword) to the
  5518. * end of the buffer (wordnext) until:
  5519. * 1) A non-bekinsoku word is found,
  5520. * 2) if the line limit exceeds the set value, or
  5521. * 3) we reach the end of the buffer.
  5522. */
  5523. if (bekinclass)
  5524. {
  5525. /*
  5526. * compword points to the first word of the next line.
  5527. */
  5528. curword = compword;
  5529. margin = data->indent2;
  5530. while (curword != data->wordnext)
  5531. {
  5532. if (!isbekinsoku(*curword->cp))
  5533. break;
  5534. margin += (curword->length + curword->blanks);
  5535. if (margin >= data->fillmargin)
  5536. return False;
  5537. WORDNEXT(data,curword);
  5538. }
  5539. if (curword != data->wordnext && curword != compword)
  5540. {
  5541. /*
  5542. * The first word of the second line is bekinsoku so search
  5543. * backwards from end of first line until we are:
  5544. * 1) not at the first word of the buffer, and
  5545. * 2) not in between either an ekinsoku or bekinsoku character.
  5546. */
  5547. /*
  5548. * compword points to the first word of the next line.
  5549. * curword points to the last word of the first line.
  5550. */
  5551. curword = WORDPREV(data,compword);
  5552. prevword = WORDPREV(data,curword);
  5553. while ( (curword != data->wordfirst) &&
  5554. (isbekinsoku(*curword->cp) ||
  5555. isekinsoku(*(prevword->cp+prevword->wclen-1)))
  5556. )
  5557. {
  5558. margin += curword->length + curword->blanks;
  5559. if (margin >= data->fillmargin)
  5560. return False;
  5561. curword = prevword;
  5562. prevword = WORDPREV(data,curword);
  5563. }
  5564. if (curword != data->wordfirst) {
  5565. /*
  5566. * Did not reach the beginning of the buffer so we are between
  5567. * two non-ekinsoku & non-bekinsoku characters. Move the end
  5568. * of the first line here.
  5569. */
  5570. *wordpast = curword;
  5571. return True;
  5572. }
  5573. }
  5574. return False;
  5575. }
  5576. return False;
  5577. } /* end EkinBekinProc */
  5578. #else
  5579. static int
  5580. EkinBekinProc(FormatData *data,
  5581. WORD **wordpast)
  5582. {
  5583. WORD *curword,*compword,*prevword,*nextword;
  5584. int margin = data->indent2;
  5585. /*
  5586. * prevword points to the last word of the first line.
  5587. * compword & curword point to the first word of the next line or
  5588. * to the next available spot in the buffer if there is no next line.
  5589. */
  5590. compword = *wordpast;
  5591. curword = compword;
  5592. prevword = WORDPREV(data,curword);
  5593. /*
  5594. * If the length of the previous word is > fillmargin
  5595. * or it is the only word in the line then return.
  5596. * wordfirst points to the beginning of the buffer of pending lines.
  5597. */
  5598. if (prevword->length > data->fillmargin || (prevword == data->wordfirst))
  5599. return False;
  5600. /*
  5601. * Starting at the beginning of the next line, search backwards
  5602. * until:
  5603. * 1) we find two words we can split between lines, or
  5604. * 2) we reach the beginning of the buffer.
  5605. *
  5606. * If there is no next line start with the last two words of this line
  5607. * (wordnext points to the next available space in the buffer (i.e
  5608. * the end of the buffer).
  5609. */
  5610. if (curword == data->wordnext) {
  5611. curword = prevword;
  5612. prevword = WORDPREV(data,curword);
  5613. }
  5614. while ( (curword != data->wordfirst) &&
  5615. (wdbindf(*(prevword->cp+prevword->wclen-1), *curword->cp, 1) >4)
  5616. )
  5617. {
  5618. curword = prevword;
  5619. prevword = WORDPREV(data,curword);
  5620. }
  5621. if (curword != data->wordfirst) {
  5622. /*
  5623. * Did not reach the beginning of the buffer so we are between
  5624. * two non-ekinsoku & non-bekinsoku characters. Move the end
  5625. * of the first line here.
  5626. */
  5627. *wordpast = curword;
  5628. return True;
  5629. }
  5630. else {
  5631. /*
  5632. * Reached the beginning of the buffer so search forward
  5633. * from the beginning of the second line until:
  5634. * 1) we find two words we can split between lines,
  5635. * 2) we reach the end of the buffer, or
  5636. * 3) the line becomes too long.
  5637. *
  5638. * If there is no next line then just exit.
  5639. */
  5640. /*
  5641. * compword points to the first word of the next line or to the
  5642. * next available spot in the buffer if there is no next line.
  5643. * nextword points to the second word of the next line.
  5644. * wordnext points to the next available space in the buffer (i.e
  5645. * the end of the buffer)
  5646. */
  5647. curword = compword;
  5648. nextword = compword;
  5649. WORDNEXT(data,nextword);
  5650. if (curword == data->wordnext)
  5651. return False;
  5652. while (nextword != data->wordnext)
  5653. {
  5654. if (wdbindf(*(curword->cp+curword->wclen-1), *nextword->cp, 1) < 5)
  5655. break;
  5656. margin += (curword->length + curword->blanks);
  5657. if (margin >= data->fillmargin)
  5658. return False;
  5659. curword = nextword;
  5660. WORDNEXT(data,nextword);
  5661. }
  5662. if (nextword != data->wordnext) {
  5663. /*
  5664. * Did not reach the end of the buffer so we are between
  5665. * two non-ekinsoku & non-bekinsoku characters. Move the end
  5666. * of the first line here.
  5667. */
  5668. *wordpast = nextword;
  5669. return True;
  5670. }
  5671. return False;
  5672. }
  5673. } /* end EkinBekinProc */
  5674. #endif /* not sun */
  5675. static void
  5676. postEkinBekinProc(FormatData *data,
  5677. int *poutchars,
  5678. WORD *wordpast)
  5679. {
  5680. WORD *curword;
  5681. int colvalue,curlineno;
  5682. /*
  5683. * Recompute the value of *poutchars
  5684. */
  5685. (*poutchars) = 0;
  5686. curword = data->wordfirst;
  5687. while (curword != wordpast)
  5688. {
  5689. (*poutchars) += curword->length + curword->blanks;
  5690. WORDNEXT(data,curword);
  5691. }
  5692. /*
  5693. ** Adjust the word parameters -
  5694. ** inlinenum,incolumn of all the words
  5695. ** from 'curword' till 'wordnext'
  5696. */
  5697. curword = wordpast;
  5698. curlineno = curword->inlinenum+1;
  5699. colvalue = data->indent2;
  5700. while (curword != data->wordnext)
  5701. {
  5702. curword->inlinenum = curlineno;
  5703. curword->incolumn = colvalue;
  5704. colvalue += curword->length + curword->blanks;
  5705. if (colvalue > data->fillmargin)
  5706. {
  5707. colvalue = data->indent2;
  5708. curlineno++;
  5709. }
  5710. WORDNEXT(data,curword);
  5711. }
  5712. data->incolumn = colvalue;
  5713. data->inlinenum = curlineno;
  5714. }
  5715. #ifdef DEBUG
  5716. static
  5717. prnword(pword)
  5718. WORD *pword;
  5719. {
  5720. int i = 0;
  5721. if (pword == NULL)
  5722. return;
  5723. for (i=0; i < pword->wclen; i++)
  5724. fprintf(stderr,(const char *)"%c",(char)*(pword->cp+i));
  5725. fprintf(stderr,"Word Length :%d\n",pword->wclen);
  5726. }
  5727. #endif /* DEBUG */
  5728. /* ARGSUSED */
  5729. static void
  5730. AdjustParaCB(
  5731. Widget w,
  5732. caddr_t client_data,
  5733. caddr_t call_data )
  5734. {
  5735. DtEditorFormat( (Widget)client_data, (DtEditorFormatSettings *)NULL,
  5736. DtEDITOR_FORMAT_PARAGRAPH );
  5737. } /* AdjustParaCB */
  5738. /* ARGSUSED */
  5739. static void
  5740. AdjustAllCB(
  5741. Widget w,
  5742. caddr_t client_data,
  5743. caddr_t call_data )
  5744. {
  5745. DtEditorFormat( (Widget)client_data, (DtEditorFormatSettings *)NULL,
  5746. DtEDITOR_FORMAT_ALL );
  5747. } /* AdjustAllCB */
  5748. /*********
  5749. *
  5750. * DoAdjust - given left & right margin values & an alignment style, formats
  5751. * the text from one specified text position to another.
  5752. *
  5753. * Returns:
  5754. * DtEDITOR_NO_ERRORS if the text was formatted successfully.
  5755. * DtEDITOR_ILLEGAL_SIZE if the left & right margins don't make
  5756. * sense.
  5757. * DtEDITOR_NO_TMP_FILE if the 2 temporary files cannot be
  5758. * created.
  5759. * DtEDITOR_INVALID_TYPE if specified alignment is
  5760. * unrecognized
  5761. *
  5762. */
  5763. static DtEditorErrorCode
  5764. DoAdjust(
  5765. DtEditorWidget editor,
  5766. int leftMargin,
  5767. int rightMargin,
  5768. unsigned int alignment,
  5769. XmTextPosition start,
  5770. XmTextPosition end)
  5771. {
  5772. char tempName1[L_tmpnam], tempName2[L_tmpnam];
  5773. DtEditorErrorCode returnVal;
  5774. AdjRec adjRec;
  5775. /*
  5776. * Check that valid margin values were passed in
  5777. */
  5778. if( leftMargin >= 0 &&
  5779. rightMargin > 0 &&
  5780. rightMargin < 1025 &&
  5781. leftMargin <= rightMargin )
  5782. {
  5783. /*
  5784. * Set up
  5785. */
  5786. _DtTurnOnHourGlass(M_topLevelShell(editor));
  5787. if (M_format_dialog(editor) != (Widget)NULL)
  5788. _DtTurnOnHourGlass(M_format_dialog(editor));
  5789. memset(&adjRec, 0, sizeof(AdjRec));
  5790. /* The adjust text formatting code works with a data
  5791. representation to the screen of 1 byte per column for
  5792. multibyte environment. The Motif text Widget has a data
  5793. representation of 2 bytes per column in multibyte, so we must
  5794. fool the adjust code into thinking the margins are twice the
  5795. size in a multibyte environment.
  5796. */
  5797. if (MB_CUR_MAX > 1)
  5798. {
  5799. rightMargin = rightMargin * 2;
  5800. leftMargin = leftMargin * 2;
  5801. }
  5802. switch (alignment)
  5803. {
  5804. case DtEDITOR_ALIGN_CENTER:
  5805. {
  5806. adjRec.cflag = 1;
  5807. adjRec.margin = (rightMargin + leftMargin) / 2;
  5808. break;
  5809. }
  5810. case DtEDITOR_ALIGN_JUSTIFY:
  5811. {
  5812. adjRec.jflag = 1;
  5813. adjRec.margin = rightMargin;
  5814. break;
  5815. }
  5816. case DtEDITOR_ALIGN_RIGHT:
  5817. {
  5818. adjRec.rflag = 1;
  5819. adjRec.margin = rightMargin;
  5820. break;
  5821. }
  5822. case DtEDITOR_ALIGN_LEFT:
  5823. {
  5824. adjRec.margin = rightMargin;
  5825. break;
  5826. }
  5827. default:
  5828. {
  5829. returnVal = DtEDITOR_INVALID_TYPE;
  5830. }
  5831. } /* end switch */
  5832. /*
  5833. * Turn off converting leading spaces into tabs if we are
  5834. * working in a multi-byte locale. This is necessary
  5835. * because a tab may not equal (be as wide as) 8 spaces in
  5836. * a multi-byte locale.
  5837. */
  5838. adjRec.tabsize = 8;
  5839. if (MB_CUR_MAX > 1)
  5840. adjRec.bflag = True;
  5841. else
  5842. adjRec.bflag = False;
  5843. /*
  5844. * Create the two temp files
  5845. */
  5846. (void)tmpnam(tempName1);
  5847. (void)tmpnam(tempName2);
  5848. if ((adjRec.infp = fopen(tempName1, "w+")) != (FILE *)NULL) {
  5849. /*
  5850. * Successfully opened the first temporary file
  5851. */
  5852. if((adjRec.outfp = fopen(tempName2, "w")) != (FILE *)NULL) {
  5853. /*
  5854. * Successfully opened the second temporary file, so do the
  5855. * formatting.
  5856. */
  5857. returnVal = DtEDITOR_NO_ERRORS;
  5858. fixLeftMarginAndNewlines( editor, adjRec.infp, leftMargin,
  5859. rightMargin, (int)start, (int)end );
  5860. fflush(adjRec.infp);
  5861. rewind(adjRec.infp);
  5862. FormatText(&adjRec);
  5863. fclose(adjRec.infp);
  5864. unlink(tempName1);
  5865. fclose(adjRec.outfp);
  5866. returnVal =
  5867. DtEditorReplaceFromFile( (Widget)editor, start, end, tempName2 );
  5868. unlink(tempName2);
  5869. }
  5870. else {
  5871. /*
  5872. * Could not open second temporary file, so clean up first one
  5873. */
  5874. fclose(adjRec.infp);
  5875. unlink(tempName1);
  5876. returnVal = DtEDITOR_NO_TMP_FILE;
  5877. }
  5878. } /* end creating temporary files */
  5879. else
  5880. returnVal = DtEDITOR_NO_TMP_FILE;
  5881. /*
  5882. * Clean up
  5883. */
  5884. _DtTurnOffHourGlass(M_topLevelShell(editor));
  5885. if (M_format_dialog(editor) != (Widget)NULL)
  5886. _DtTurnOffHourGlass(M_format_dialog(editor));
  5887. } /* end check for valid margins */
  5888. else
  5889. returnVal = DtEDITOR_ILLEGAL_SIZE;
  5890. return (returnVal);
  5891. }
  5892. /* ARGSUSED */
  5893. static void
  5894. AdjustCloseCB(
  5895. Widget w,
  5896. caddr_t client_data,
  5897. caddr_t call_data )
  5898. {
  5899. DtEditorWidget editor = (DtEditorWidget )client_data;
  5900. XtUnmanageChild (M_format_dialog(editor));
  5901. }
  5902. /* ARGSUSED */
  5903. static int
  5904. ComputeRightMargin(
  5905. DtEditorWidget editor)
  5906. {
  5907. Dimension text_width, highlight_thickness, shadow_thickness,
  5908. margin_width;
  5909. int rightMargin;
  5910. Arg al[5]; /* arg list */
  5911. int ac; /* arg count */
  5912. ac=0;
  5913. XtSetArg(al[ac], XmNwidth, &text_width); ac++;
  5914. XtSetArg(al[ac], XmNhighlightThickness, &highlight_thickness); ac++;
  5915. XtSetArg(al[ac], XmNshadowThickness, &shadow_thickness); ac++;
  5916. XtSetArg(al[ac], XmNmarginWidth, &margin_width); ac++;
  5917. XtGetValues(M_text(editor), al, ac);
  5918. if (M_fontWidth(editor) != 0)
  5919. rightMargin = ( (int)text_width -
  5920. (2 * ((int)highlight_thickness +
  5921. (int)shadow_thickness + (int)margin_width))
  5922. ) / M_fontWidth(editor);
  5923. else
  5924. rightMargin = (int)text_width -
  5925. (2 * ((int)highlight_thickness +
  5926. (int)shadow_thickness + (int)margin_width));
  5927. return( rightMargin );
  5928. } /* end ComputeRightMargin */
  5929. /* ARGSUSED */
  5930. static void
  5931. UpdateAdjust(
  5932. Widget widget,
  5933. XtPointer *client_data,
  5934. XConfigureEvent *event )
  5935. {
  5936. Dimension width;
  5937. DtEditorWidget editor = (DtEditorWidget) client_data;
  5938. char orgnum[20]; /* original margin size string */
  5939. Arg al[2];
  5940. XtSetArg(al[0], XmNwidth, &width);
  5941. XtGetValues(M_text(editor), al, 1);
  5942. if (width == M_textWidth(editor))
  5943. return;
  5944. M_textWidth(editor) = width;
  5945. sprintf( orgnum, "%d", ComputeRightMargin(editor) );
  5946. XmTextFieldSetString(M_format_rightMarginField(editor), orgnum);
  5947. }
  5948. /************************************************************************
  5949. *
  5950. * SetFormatDialogTitle - Change the title for the Format Settings dialog
  5951. *
  5952. ************************************************************************/
  5953. static void
  5954. SetFormatDialogTitle(
  5955. DtEditorWidget editor)
  5956. {
  5957. Arg al[2];
  5958. /*
  5959. * If the Format Settings dialog has been created, change its title
  5960. */
  5961. if( M_format_dialog(editor) != (Widget)NULL )
  5962. {
  5963. /*
  5964. * Prepend the DialogTitle resource, if it has been set
  5965. */
  5966. if( E_dialogTitle(editor) != (XmString)NULL ) {
  5967. XmString titleStr;
  5968. /*
  5969. * Add the "functional title" to the DialogTitle
  5970. */
  5971. titleStr = XmStringConcat( E_dialogTitle(editor),
  5972. E_format_dialogTitle(editor) );
  5973. XtSetArg( al[0], XmNdialogTitle, titleStr );
  5974. XtSetValues(M_format_dialog(editor), al, 1);
  5975. XmStringFree( titleStr );
  5976. }
  5977. else {
  5978. XtSetArg( al[0], XmNdialogTitle, E_format_dialogTitle(editor) );
  5979. XtSetValues(M_format_dialog(editor), al, 1);
  5980. }
  5981. }
  5982. } /* end SetFormatDialogTitle */
  5983. /************************************************************************
  5984. *
  5985. * ResetFormatDialog - Reset margins & alignment of the Format Settings
  5986. * dialog
  5987. *
  5988. ************************************************************************/
  5989. static void
  5990. ResetFormatDialog(
  5991. DtEditorWidget editor)
  5992. {
  5993. char orgnum[20]; /* original margin size string */
  5994. /*
  5995. * Reset the margins to default values
  5996. */
  5997. /* Right margin default value */
  5998. sprintf( orgnum, "%d", ComputeRightMargin(editor) );
  5999. XmTextFieldSetString(M_format_rightMarginField(editor), orgnum);
  6000. /* Left margin default value */
  6001. sprintf(orgnum, "%d", 0);
  6002. XmTextFieldSetString(M_format_leftMarginField(editor), orgnum);
  6003. /*
  6004. * Reset the alignment style to default value
  6005. */
  6006. XmToggleButtonGadgetSetState(M_format_leftJust(editor), True, True);
  6007. } /* end ResetFormatDialog */
  6008. /************************************************************************
  6009. *
  6010. * CreateFormatDialog - Create & initialize the Format Settings dialog
  6011. *
  6012. ************************************************************************/
  6013. static void
  6014. CreateFormatDialog(
  6015. DtEditorWidget editor)
  6016. {
  6017. Arg al[15]; /* arg list */
  6018. int ac; /* arg count */
  6019. Pixel textBackground, textForeground;
  6020. XmString tempString = (XmString)NULL;
  6021. /*
  6022. * Match the background & foreground colors of the edit window
  6023. * Don't use DtNtextBackground/Foreground directly because they
  6024. * will be DtUNSPECIFIED.
  6025. */
  6026. ac = 0;
  6027. XtSetArg(al[ac], XmNforeground, &textForeground); ac++;
  6028. XtSetArg(al[ac], XmNbackground, &textBackground); ac++;
  6029. XtGetValues(M_text(editor), al, ac);
  6030. ac = 0;
  6031. /*
  6032. * First, create the dialog's title, prepending the
  6033. * DtNdialogTitle resource, if it is set
  6034. */
  6035. if( E_dialogTitle(editor) != (XmString)NULL ) {
  6036. /*
  6037. * Add the "functional title" to the DialogTitle
  6038. */
  6039. tempString = XmStringConcat( E_dialogTitle(editor),
  6040. E_format_dialogTitle(editor) );
  6041. XtSetArg (al[ac], XmNdialogTitle, tempString ); ac++;
  6042. }
  6043. else {
  6044. XtSetArg(al[ac], XmNdialogTitle, E_format_dialogTitle(editor)); ac++;
  6045. }
  6046. XtSetArg (al[ac], XmNautoUnmanage, False); ac++;
  6047. XtSetArg (al[ac], XmNmarginWidth, 5); ac++;
  6048. XtSetArg (al[ac], XmNmarginHeight, 5); ac++;
  6049. XtSetArg (al[ac], XmNshadowThickness, 1); ac++;
  6050. XtSetArg (al[ac], XmNshadowType, XmSHADOW_OUT); ac++;
  6051. XtSetArg (al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
  6052. M_format_dialog(editor) = XmCreateFormDialog(
  6053. M_topLevelShell(editor), "ad_dial", al, ac);
  6054. if (tempString != (XmString)NULL)
  6055. XmStringFree( tempString );
  6056. XtAddCallback(M_format_dialog(editor), XmNhelpCallback,
  6057. (XtCallbackProc)HelpFormatDialogCB, (XtPointer)editor);
  6058. /*
  6059. * When creating the fields & buttons use the appropriate label
  6060. * resource (e.g. DtNcenterToggleLabel), if it has been set, then
  6061. * clear the resource to save space. The field or button widget
  6062. * will contain the actual value & it can be gotten from there,
  6063. * if it is needed.
  6064. *
  6065. * If the appropriate resource has not been set, use its default
  6066. * value from the message catalog.
  6067. */
  6068. /*
  6069. * create the left margin label and text field
  6070. */
  6071. ac = 0;
  6072. if (E_format_leftMarginFieldLabel(editor) != (XmString) DtUNSPECIFIED) {
  6073. /*
  6074. * Use the resource value & clear it (to save space).
  6075. */
  6076. tempString = XmStringCopy(E_format_leftMarginFieldLabel(editor));
  6077. E_format_leftMarginFieldLabel(editor) = (XmString) DtUNSPECIFIED;
  6078. }
  6079. else {
  6080. /*
  6081. * The resource has not been set so use its default value
  6082. */
  6083. tempString = XmStringCreateLocalized(LEFT_MARGIN);
  6084. }
  6085. XtSetArg(al[ac], XmNlabelString, tempString); ac++;
  6086. XtSetArg (al[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
  6087. XtSetArg (al[ac], XmNleftPosition, 2); ac++;
  6088. XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  6089. XtSetArg (al[ac], XmNtopOffset, 10); ac++;
  6090. XtSetArg (al[ac], XmNfontList, E_labelFontList(editor)); ac++;
  6091. M_format_leftLabel(editor) = (Widget) XmCreateLabelGadget (
  6092. M_format_dialog(editor), "left_label", al, ac);
  6093. XtManageChild (M_format_leftLabel(editor));
  6094. XmStringFree (tempString);
  6095. XtAddCallback(M_format_leftLabel(editor), XmNhelpCallback,
  6096. (XtCallbackProc)HelpFormatLeftMarginCB, (XtPointer)editor);
  6097. ac = 0;
  6098. XtSetArg (al[ac], XmNbackground, textBackground); ac++;
  6099. XtSetArg (al[ac], XmNforeground, textForeground); ac++;
  6100. XtSetArg (al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
  6101. XtSetArg (al[ac], XmNleftWidget, M_format_leftLabel(editor)); ac++;
  6102. XtSetArg (al[ac], XmNleftOffset, 3); ac++;
  6103. XtSetArg (al[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
  6104. XtSetArg (al[ac], XmNrightPosition, 45); ac++;
  6105. XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  6106. XtSetArg (al[ac], XmNtopOffset, 5); ac++;
  6107. XtSetArg (al[ac], XmNtraversalOn, True); ac++;
  6108. XtSetArg (al[ac], XmNcolumns, 3); ac++;
  6109. XtSetArg (al[ac], XmNfontList, E_textFontList(editor)); ac++;
  6110. M_format_leftMarginField(editor) = (Widget) XmCreateTextField (
  6111. M_format_dialog(editor), "left_text", al, ac);
  6112. XtManageChild (M_format_leftMarginField(editor));
  6113. XtAddCallback(M_format_leftMarginField(editor), XmNhelpCallback,
  6114. (XtCallbackProc)HelpFormatLeftMarginCB, (XtPointer)editor);
  6115. /*
  6116. * create the right margin label and text field
  6117. */
  6118. ac = 0;
  6119. if (E_format_rightMarginFieldLabel(editor) != (XmString) DtUNSPECIFIED)
  6120. {
  6121. /*
  6122. * Use the resource value & clear it (to save space).
  6123. */
  6124. tempString = XmStringCopy(E_format_rightMarginFieldLabel(editor));
  6125. E_format_rightMarginFieldLabel(editor) = (XmString) DtUNSPECIFIED;
  6126. }
  6127. else
  6128. {
  6129. /*
  6130. * The resource has not been set so use its default value
  6131. */
  6132. tempString = XmStringCreateLocalized(RIGHT_MARGIN);
  6133. }
  6134. XtSetArg(al[ac], XmNlabelString, tempString); ac++;
  6135. XtSetArg (al[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
  6136. XtSetArg (al[ac], XmNleftPosition, 55); ac++;
  6137. XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  6138. XtSetArg (al[ac], XmNtopOffset, 10); ac++;
  6139. XtSetArg (al[ac], XmNfontList, E_labelFontList(editor)); ac++;
  6140. M_format_rightLabel(editor)= (Widget) XmCreateLabelGadget (
  6141. M_format_dialog(editor), "right_label", al, ac);
  6142. XtManageChild (M_format_rightLabel(editor));
  6143. XmStringFree (tempString);
  6144. XtAddCallback(M_format_rightLabel(editor), XmNhelpCallback,
  6145. (XtCallbackProc)HelpFormatRightMarginCB,
  6146. (XtPointer)editor);
  6147. ac = 0;
  6148. XtSetArg (al[ac], XmNbackground, textBackground); ac++;
  6149. XtSetArg (al[ac], XmNforeground, textForeground); ac++;
  6150. XtSetArg (al[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
  6151. XtSetArg (al[ac], XmNrightPosition, 98); ac++;
  6152. XtSetArg (al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
  6153. XtSetArg (al[ac], XmNleftWidget, M_format_rightLabel(editor)); ac++;
  6154. XtSetArg (al[ac], XmNleftOffset, 3); ac++;
  6155. XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  6156. XtSetArg (al[ac], XmNtopOffset, 5); ac++;
  6157. XtSetArg (al[ac], XmNtraversalOn, True); ac++;
  6158. XtSetArg (al[ac], XmNcolumns, 3); ac++;
  6159. XtSetArg (al[ac], XmNfontList, E_textFontList(editor)); ac++;
  6160. M_format_rightMarginField(editor) = (Widget) XmCreateTextField (
  6161. M_format_dialog(editor),
  6162. "right_text", al, ac);
  6163. XtManageChild (M_format_rightMarginField(editor));
  6164. XtAddCallback(M_format_rightMarginField(editor), XmNhelpCallback,
  6165. (XtCallbackProc)HelpFormatRightMarginCB,
  6166. (XtPointer)editor);
  6167. /*
  6168. * create the radio box for justification choices
  6169. */
  6170. ac = 0;
  6171. XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  6172. XtSetArg (al[ac], XmNleftOffset, 5); ac++;
  6173. XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
  6174. XtSetArg (al[ac], XmNtopWidget, M_format_leftMarginField(editor)); ac++;
  6175. XtSetArg (al[ac], XmNtopOffset, 5); ac++;
  6176. XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  6177. XtSetArg (al[ac], XmNrightOffset, 5); ac++;
  6178. XtSetArg (al[ac], XmNtraversalOn, True); ac++;
  6179. M_format_radioBox(editor) = (Widget) XmCreateRadioBox(
  6180. M_format_dialog(editor), "radioBox", al, ac);
  6181. XtAddCallback(M_format_radioBox(editor), XmNhelpCallback,
  6182. (XtCallbackProc)HelpFormatJustifyButtonsCB,
  6183. (XtPointer)editor);
  6184. XtManageChild(M_format_radioBox(editor));
  6185. /* Create Left Align toggle */
  6186. ac = 0;
  6187. if (E_format_leftAlignToggleLabel(editor) != (XmString) DtUNSPECIFIED) {
  6188. /*
  6189. * Use the resource value & clear it (to save space).
  6190. */
  6191. tempString = XmStringCopy(E_format_leftAlignToggleLabel(editor));
  6192. E_format_leftAlignToggleLabel(editor) = (XmString) DtUNSPECIFIED;
  6193. }
  6194. else {
  6195. /*
  6196. * The resource has not been set so use its default value
  6197. */
  6198. tempString = XmStringCreateLocalized(LEFT_ALIGN);
  6199. }
  6200. XtSetArg(al[ac], XmNlabelString, tempString); ac++;
  6201. XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
  6202. M_format_leftJust(editor) = (Widget) XmCreateToggleButtonGadget(
  6203. M_format_radioBox(editor), "left_just", al, ac);
  6204. XmStringFree (tempString);
  6205. XtManageChild(M_format_leftJust(editor));
  6206. /* Create Right Align toggle */
  6207. ac = 0;
  6208. if(E_format_rightAlignToggleLabel(editor) != (XmString)DtUNSPECIFIED) {
  6209. /*
  6210. * Use the resource value & clear it (to save space).
  6211. */
  6212. tempString = XmStringCopy(E_format_rightAlignToggleLabel(editor));
  6213. E_format_rightAlignToggleLabel(editor) = (XmString) DtUNSPECIFIED;
  6214. }
  6215. else {
  6216. /*
  6217. * The resource has not been set so use its default value
  6218. */
  6219. tempString = XmStringCreateLocalized(RIGHT_ALIGN);
  6220. }
  6221. XtSetArg(al[ac], XmNlabelString, tempString); ac++;
  6222. XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
  6223. M_format_rightJust(editor) = (Widget) XmCreateToggleButtonGadget(
  6224. M_format_radioBox(editor), "right_just", al, ac);
  6225. XmStringFree (tempString);
  6226. XtManageChild(M_format_rightJust(editor));
  6227. /* Create Justify toggle */
  6228. ac = 0;
  6229. if (E_format_justifyToggleLabel(editor) != (XmString) DtUNSPECIFIED) {
  6230. /*
  6231. * Use the resource value & clear it (to save space).
  6232. */
  6233. tempString = XmStringCopy(E_format_justifyToggleLabel(editor));
  6234. E_format_justifyToggleLabel(editor) = (XmString) DtUNSPECIFIED;
  6235. }
  6236. else {
  6237. /*
  6238. * The resource has not been set so use its default value
  6239. */
  6240. tempString = XmStringCreateLocalized( JUSTIFY );
  6241. }
  6242. XtSetArg(al[ac], XmNlabelString, tempString); ac++;
  6243. XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
  6244. M_format_bothJust(editor) = (Widget) XmCreateToggleButtonGadget(
  6245. M_format_radioBox(editor), "both_just", al, ac);
  6246. XmStringFree (tempString);
  6247. XtManageChild(M_format_bothJust(editor));
  6248. /* Create Center align toggle */
  6249. ac = 0;
  6250. if (E_format_centerToggleLabel(editor) != (XmString) DtUNSPECIFIED) {
  6251. /*
  6252. * Use the resource value & clear it (to save space).
  6253. */
  6254. tempString = XmStringCopy(E_format_centerToggleLabel(editor));
  6255. E_format_centerToggleLabel(editor) = (XmString) DtUNSPECIFIED;
  6256. }
  6257. else {
  6258. /*
  6259. * The resource has not been set so use its default value
  6260. */
  6261. tempString = XmStringCreateLocalized(CENTER);
  6262. }
  6263. XtSetArg(al[ac], XmNlabelString, tempString); ac++;
  6264. XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
  6265. M_format_center(editor) = (Widget) XmCreateToggleButtonGadget(
  6266. M_format_radioBox(editor), "center", al, ac);
  6267. XmStringFree(tempString);
  6268. XtManageChild(M_format_center(editor));
  6269. /* Create a separator between the radio box and buttons */
  6270. ac = 0;
  6271. XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  6272. XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  6273. XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
  6274. XtSetArg (al[ac], XmNtopWidget, M_format_radioBox(editor)); ac++;
  6275. XtSetArg (al[ac], XmNtopOffset, 15); ac++;
  6276. M_format_separator(editor) = (Widget) XmCreateSeparatorGadget (
  6277. M_format_dialog(editor), "separator", al, ac);
  6278. XtManageChild (M_format_separator(editor));
  6279. /* Create Format Paragraph button */
  6280. ac = 0;
  6281. if ( E_format_formatParagraphButtonLabel(editor) !=
  6282. (XmString) DtUNSPECIFIED ) {
  6283. /*
  6284. * Use the resource value & clear it (to save space).
  6285. */
  6286. tempString = XmStringCopy(E_format_formatParagraphButtonLabel(editor));
  6287. E_format_formatParagraphButtonLabel(editor) = (XmString) DtUNSPECIFIED;
  6288. }
  6289. else {
  6290. /*
  6291. * The resource has not been set so use its default value
  6292. */
  6293. tempString = XmStringCreateLocalized(PARAGRAPH);
  6294. }
  6295. XtSetArg(al[ac], XmNlabelString, tempString); ac++;
  6296. XtSetArg (al[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
  6297. XtSetArg (al[ac], XmNleftPosition, 2); ac++;
  6298. XtSetArg (al[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
  6299. XtSetArg (al[ac], XmNrightPosition, 25); ac++;
  6300. XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
  6301. XtSetArg (al[ac], XmNtopWidget, M_format_separator(editor)); ac++;
  6302. XtSetArg (al[ac], XmNtopOffset, 5); ac++;
  6303. XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  6304. XtSetArg (al[ac], XmNbottomOffset, 5); ac++;
  6305. XtSetArg (al[ac], XmNmarginWidth, 4); ac++;
  6306. XtSetArg (al[ac], XmNmarginHeight, 4); ac++;
  6307. XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
  6308. M_format_paragraph(editor) = (Widget) XmCreatePushButtonGadget (
  6309. M_format_dialog(editor), "para", al, ac);
  6310. XtManageChild (M_format_paragraph(editor));
  6311. XmStringFree (tempString);
  6312. XtAddCallback (M_format_paragraph(editor), XmNactivateCallback,
  6313. (XtCallbackProc) AdjustParaCB, (XtPointer) editor);
  6314. /* Create Format All button */
  6315. ac = 0;
  6316. if (E_format_formatAllButtonLabel(editor) != (XmString)DtUNSPECIFIED) {
  6317. /*
  6318. * Use the resource value & clear it (to save space).
  6319. */
  6320. tempString = XmStringCopy(E_format_formatAllButtonLabel(editor));
  6321. E_format_formatAllButtonLabel(editor) = (XmString) DtUNSPECIFIED;
  6322. }
  6323. else {
  6324. /*
  6325. * The resource has not been set so use its default value
  6326. */
  6327. tempString = XmStringCreateLocalized(ALL);
  6328. }
  6329. XtSetArg(al[ac], XmNlabelString, tempString); ac++;
  6330. XtSetArg (al[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
  6331. XtSetArg (al[ac], XmNleftPosition, 27); ac++;
  6332. XtSetArg (al[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
  6333. XtSetArg (al[ac], XmNrightPosition, 49); ac++;
  6334. XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
  6335. XtSetArg (al[ac], XmNtopWidget, M_format_separator(editor)); ac++;
  6336. XtSetArg (al[ac], XmNtopOffset, 5); ac++;
  6337. XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  6338. XtSetArg (al[ac], XmNbottomOffset, 5); ac++;
  6339. XtSetArg (al[ac], XmNmarginWidth, 4); ac++;
  6340. XtSetArg (al[ac], XmNmarginHeight, 4); ac++;
  6341. XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
  6342. M_format_all(editor) = (Widget) XmCreatePushButtonGadget(
  6343. M_format_dialog(editor), "all", al, ac);
  6344. XtManageChild (M_format_all(editor));
  6345. XmStringFree (tempString);
  6346. XtAddCallback (M_format_all(editor), XmNactivateCallback,
  6347. (XtCallbackProc) AdjustAllCB, (XtPointer) editor);
  6348. /* Create Close button */
  6349. tempString = XmStringCreateLocalized(CLOSE_BUTTON);
  6350. ac = 0;
  6351. XtSetArg (al[ac], XmNlabelString, tempString); ac++;
  6352. XtSetArg (al[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
  6353. XtSetArg (al[ac], XmNleftPosition, 51); ac++;
  6354. XtSetArg (al[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
  6355. XtSetArg (al[ac], XmNrightPosition, 73); ac++;
  6356. XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
  6357. XtSetArg (al[ac], XmNtopWidget, M_format_separator(editor)); ac++;
  6358. XtSetArg (al[ac], XmNtopOffset, 5); ac++;
  6359. XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  6360. XtSetArg (al[ac], XmNbottomOffset, 5); ac++;
  6361. XtSetArg (al[ac], XmNmarginWidth, 4); ac++;
  6362. XtSetArg (al[ac], XmNmarginHeight, 4); ac++;
  6363. XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
  6364. M_format_close(editor) = (Widget) XmCreatePushButtonGadget (
  6365. M_format_dialog(editor), "close", al, ac);
  6366. XtManageChild (M_format_close(editor));
  6367. XmStringFree (tempString);
  6368. XtAddCallback (M_format_close(editor), XmNactivateCallback,
  6369. (XtCallbackProc) AdjustCloseCB, (XtPointer) editor);
  6370. tempString = XmStringCreateLocalized(HELP_BUTTON);
  6371. ac = 0;
  6372. XtSetArg (al[ac], XmNlabelString, tempString); ac++;
  6373. XtSetArg (al[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
  6374. XtSetArg (al[ac], XmNleftPosition, 75); ac++;
  6375. XtSetArg (al[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
  6376. XtSetArg (al[ac], XmNrightPosition, 98); ac++;
  6377. XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
  6378. XtSetArg (al[ac], XmNtopWidget, M_format_separator(editor)); ac++;
  6379. XtSetArg (al[ac], XmNtopOffset, 5); ac++;
  6380. XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  6381. XtSetArg (al[ac], XmNbottomOffset, 5); ac++;
  6382. XtSetArg (al[ac], XmNmarginWidth, 4); ac++;
  6383. XtSetArg (al[ac], XmNmarginHeight, 4); ac++;
  6384. XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
  6385. M_format_help(editor) = (Widget) XmCreatePushButtonGadget(
  6386. M_format_dialog(editor), "help", al, ac);
  6387. XtManageChild (M_format_help(editor));
  6388. XmStringFree (tempString);
  6389. XtAddCallback( M_format_help(editor), XmNactivateCallback,
  6390. (XtCallbackProc) HelpFormatDialogCB, (XtPointer) editor);
  6391. /*
  6392. * set the default/activation button.
  6393. */
  6394. XtSetArg(al[0], XmNdefaultButton, M_format_close(editor));
  6395. XtSetValues(M_format_dialog(editor), al, 1);
  6396. XtRealizeWidget (M_format_dialog(editor));
  6397. /*
  6398. * Initialize the margins & alignment toggles
  6399. */
  6400. ResetFormatDialog(editor);
  6401. XtSetArg(al[0], XmNwidth, &(M_textWidth(editor)));
  6402. XtGetValues(M_text(editor), al, 1);
  6403. XtAddEventHandler(M_text(editor), StructureNotifyMask, False,
  6404. (XtEventHandler) UpdateAdjust, (XtPointer) editor);
  6405. } /* end CreateFormatDialog */
  6406. /************************************************************************
  6407. *
  6408. * GetAdjustSettings - Read the alignment settings from the Format
  6409. * Settings dialog.
  6410. *
  6411. ************************************************************************/
  6412. static void
  6413. GetAdjustSettings(
  6414. DtEditorWidget editor,
  6415. DtEditorFormatSettings *formatSettings)
  6416. {
  6417. if( M_format_dialog(editor)!= (Widget)NULL ) {
  6418. /*
  6419. * Read the current alignment settings from the Format Settings
  6420. * dialog.
  6421. */
  6422. char *num;
  6423. /*
  6424. * Get current type of alignment
  6425. */
  6426. if (XmToggleButtonGadgetGetState(M_format_leftJust(editor)))
  6427. formatSettings->alignment = DtEDITOR_ALIGN_LEFT;
  6428. else if (XmToggleButtonGadgetGetState(M_format_rightJust(editor)))
  6429. formatSettings->alignment = DtEDITOR_ALIGN_RIGHT;
  6430. else if (XmToggleButtonGadgetGetState(M_format_bothJust(editor)))
  6431. formatSettings->alignment = DtEDITOR_ALIGN_JUSTIFY;
  6432. else
  6433. formatSettings->alignment = DtEDITOR_ALIGN_CENTER;
  6434. /*
  6435. * Get current margin settings
  6436. */
  6437. num = (char *) XmTextFieldGetString(
  6438. (Widget)M_format_rightMarginField(editor) );
  6439. formatSettings->rightMargin = atoi(num);
  6440. XtFree(num);
  6441. num = (char *) XmTextFieldGetString(
  6442. (Widget)M_format_leftMarginField(editor) );
  6443. formatSettings->leftMargin = atoi(num);
  6444. XtFree(num);
  6445. }
  6446. else {
  6447. /*
  6448. * The Format Settings dialog box has not been created so use the
  6449. * default values.
  6450. */
  6451. formatSettings->leftMargin = 0;
  6452. formatSettings->rightMargin = ComputeRightMargin(editor);
  6453. formatSettings->alignment = DtEDITOR_ALIGN_LEFT;
  6454. }
  6455. }
  6456. /****************************************************************
  6457. *
  6458. * Public Procs
  6459. *
  6460. ****************************************************************/
  6461. /*********************************************************
  6462. *
  6463. * DtCreateEditor
  6464. * Create an instance of an editor and return the widget id.
  6465. */
  6466. Widget
  6467. DtCreateEditor(
  6468. Widget parent,
  6469. char *name,
  6470. ArgList arglist,
  6471. Cardinal argcount )
  6472. {
  6473. return( XtCreateWidget(name,dtEditorWidgetClass,parent,arglist,argcount) );
  6474. }
  6475. Boolean
  6476. DtEditorCheckForUnsavedChanges(
  6477. Widget widget)
  6478. {
  6479. DtEditorWidget editor = (DtEditorWidget) widget;
  6480. Boolean result;
  6481. _DtWidgetToAppContext(widget);
  6482. _DtAppLock(app);
  6483. result = M_unreadChanges( editor );
  6484. _DtAppUnlock(app);
  6485. return result;
  6486. } /* end DtEditorCheckForUnsavedChanges */
  6487. Boolean
  6488. DtEditorDeleteSelection(
  6489. Widget widget)
  6490. {
  6491. XmTextPosition first, last;
  6492. DtEditorWidget editor = (DtEditorWidget) widget;
  6493. Boolean result;
  6494. _DtWidgetToAppContext(widget);
  6495. _DtAppLock(app);
  6496. /*
  6497. * Check for a non-null selection
  6498. */
  6499. if ( XmTextGetSelectionPosition(M_text(editor), &first, &last) &&
  6500. first != last )
  6501. {
  6502. XmTextRemove(M_text(editor));
  6503. result = True;
  6504. }
  6505. else
  6506. result = False;
  6507. _DtAppUnlock(app);
  6508. return result;
  6509. } /* end DtEditorDeleteSelection */
  6510. /*
  6511. * DtEditorClearSelection replaces the currently selected text with
  6512. * spaces. It requires an event because the underlying text widget
  6513. * routines require one to look at the time stamp within.
  6514. */
  6515. Boolean
  6516. DtEditorClearSelection(
  6517. Widget widget)
  6518. {
  6519. DtEditorWidget editor = (DtEditorWidget) widget;
  6520. char *params=(char *)NULL;
  6521. Cardinal num_params = 0;
  6522. XEvent event;
  6523. _DtWidgetToAppContext(widget);
  6524. _DtAppLock(app);
  6525. /*
  6526. * Create an event with a correct timestamp
  6527. */
  6528. event.xkey.time = XtLastTimestampProcessed( M_display(editor) );
  6529. /*
  6530. * Call routine to clear primary selection
  6531. */
  6532. ClearSelection( widget, &event, &params, &num_params );
  6533. _DtAppUnlock(app);
  6534. return(True);
  6535. } /* end DtEditorClearSelection */
  6536. /*
  6537. *
  6538. * DtEditorDeselect - Unselects any selected text of an Editor widget
  6539. *
  6540. */
  6541. Boolean
  6542. DtEditorDeselect(
  6543. Widget widget)
  6544. {
  6545. DtEditorWidget editor = (DtEditorWidget) widget;
  6546. char *params=(char *)NULL;
  6547. Cardinal num_params = 0;
  6548. XEvent event;
  6549. _DtWidgetToAppContext(widget);
  6550. _DtAppLock(app);
  6551. /*
  6552. * Create an event with a correct timestamp
  6553. */
  6554. event.xkey.time = XtLastTimestampProcessed( M_display(editor) );
  6555. DeselectAll( widget, &event, &params, &num_params );
  6556. _DtAppUnlock(app);
  6557. return(True);
  6558. } /* end DtEditorDeselect */
  6559. /*
  6560. *
  6561. * DtEditorDisableRedisplay - Temporarily prevent visual update of a
  6562. * Editor widget
  6563. *
  6564. */
  6565. void
  6566. DtEditorDisableRedisplay(
  6567. Widget widget)
  6568. {
  6569. DtEditorWidget editor = (DtEditorWidget) widget;
  6570. _DtWidgetToAppContext(widget);
  6571. _DtAppLock(app);
  6572. XmTextDisableRedisplay( M_text(editor) );
  6573. _DtAppUnlock(app);
  6574. } /* end DtEditorDisableRedisplay */
  6575. /*
  6576. *
  6577. * DtEditorEnableRedisplay - Force visual update of an Editor widget
  6578. *
  6579. */
  6580. void
  6581. DtEditorEnableRedisplay(
  6582. Widget widget)
  6583. {
  6584. DtEditorWidget editor = (DtEditorWidget) widget;
  6585. _DtWidgetToAppContext(widget);
  6586. _DtAppLock(app);
  6587. XmTextEnableRedisplay( M_text(editor) );
  6588. _DtAppUnlock(app);
  6589. } /* end DtEditorEnableRedisplay */
  6590. /*********
  6591. *
  6592. * DtEditorFormat
  6593. * Given left & right margin values & an alignment style,
  6594. * formats either the current paragraph or the entire document,
  6595. * as specified. If margin values & alignment style are not
  6596. * provided, DtEditorFormat will use the current values from
  6597. * the Format Settings dialog.
  6598. *
  6599. * Returns:
  6600. * DtEDITOR_NO_ERRORS if the text was formatted successfully.
  6601. * DtEDITOR_NO_TMP_FILE if the 2 temporary files cannot be
  6602. * created.
  6603. * DtEDITOR_ILLEGAL_SIZE if the left & right margins don't make
  6604. * sense.
  6605. * DtEDITOR_INVALID_RANGE if specified amount to format is
  6606. * unrecognized
  6607. * DtEDITOR_INVALID_TYPE if specified alignment is
  6608. * unrecognized
  6609. *
  6610. */
  6611. DtEditorErrorCode
  6612. DtEditorFormat(
  6613. Widget widget,
  6614. DtEditorFormatSettings *formatSettings,
  6615. unsigned int amountToFormat )
  6616. {
  6617. DtEditorWidget editor = (DtEditorWidget) widget;
  6618. DtEditorErrorCode error;
  6619. int leftMargin, rightMargin, alignment;
  6620. _DtWidgetToAppContext(widget);
  6621. _DtAppLock(app);
  6622. /*
  6623. * Check to see if we should use the format settings from the
  6624. * Format Settings dialog.
  6625. */
  6626. if( formatSettings == (DtEditorFormatSettings *) NULL )
  6627. {
  6628. DtEditorFormatSettings tmpFormatSettings;
  6629. /*
  6630. * Get the format settings from the Format Settings dialog
  6631. */
  6632. GetAdjustSettings(editor, &tmpFormatSettings);
  6633. /*
  6634. * Set up the correct format settings
  6635. */
  6636. leftMargin = tmpFormatSettings.leftMargin;
  6637. rightMargin = tmpFormatSettings.rightMargin;
  6638. alignment = tmpFormatSettings.alignment;
  6639. }
  6640. else {
  6641. leftMargin = formatSettings->leftMargin;
  6642. rightMargin = formatSettings->rightMargin;
  6643. alignment = formatSettings->alignment;
  6644. }
  6645. /*
  6646. * Now, do the formatting
  6647. */
  6648. switch (amountToFormat)
  6649. {
  6650. case DtEDITOR_FORMAT_ALL:
  6651. {
  6652. error = DoAdjust( editor, leftMargin, rightMargin, alignment,
  6653. 0, XmTextGetLastPosition(M_text(editor)) );
  6654. break;
  6655. }
  6656. case DtEDITOR_FORMAT_PARAGRAPH:
  6657. {
  6658. XmTextPosition start, end;
  6659. char *params=(char *)NULL;
  6660. Cardinal num_params = 0;
  6661. /*
  6662. * Create an event with a correct timestamp
  6663. */
  6664. XEvent event;
  6665. event.xkey.time = XtLastTimestampProcessed( M_display(editor) );
  6666. /*
  6667. * Get the beginning & ending positions of the current paragraph
  6668. */
  6669. ForwardPara( widget, &event, &params, &num_params );
  6670. end = XmTextGetInsertionPosition(M_text(editor));
  6671. if( end != XmTextGetLastPosition(M_text(editor)) ) {
  6672. /*
  6673. * If we're not at the end, then we need to back up to the
  6674. * start of this line, otherwise we'll disturb the first line
  6675. * of the following paragraph. If we are at the end, then "end"
  6676. * must point to the end of the line, or we'll leave the last
  6677. * line along with the formatted text.
  6678. */
  6679. BeginningOfLine( widget, &event, &params, &num_params );
  6680. end = XmTextGetInsertionPosition(M_text(editor));
  6681. }
  6682. BackwardPara( widget, &event, &params, &num_params );
  6683. BeginningOfLine( widget, &event, &params, &num_params );
  6684. start = XmTextGetInsertionPosition(M_text(editor));
  6685. /*
  6686. * Pass in beginning & ending positions to adjust the current
  6687. * paragraph
  6688. */
  6689. error = DoAdjust( editor, leftMargin, rightMargin, alignment,
  6690. start, end );
  6691. break;
  6692. }
  6693. default: {
  6694. error = DtEDITOR_INVALID_RANGE;
  6695. }
  6696. } /* end switch */
  6697. _DtAppUnlock(app);
  6698. return( error );
  6699. } /* DtEditorFormat */
  6700. /*
  6701. *
  6702. * DtEditorGetMessageTextFieldID - Returns the widget ID of the Text
  6703. * Field used to display application status messages.
  6704. *
  6705. */
  6706. Widget
  6707. DtEditorGetMessageTextFieldID(
  6708. Widget widget)
  6709. {
  6710. DtEditorWidget editor = (DtEditorWidget) widget;
  6711. Widget result;
  6712. _DtWidgetToAppContext(widget);
  6713. _DtAppLock(app);
  6714. /*
  6715. * Create the status line if is does not exist
  6716. */
  6717. if( M_status_statusArea(editor) == (Widget) NULL )
  6718. M_status_statusArea(editor) = CreateStatusLine( editor );
  6719. result = M_status_messageText(editor);
  6720. _DtAppUnlock(app);
  6721. return result;
  6722. } /* end DtEditorGetMessageTextFieldID */
  6723. /*
  6724. * DtEditorGoToLine moves the insert cursor to the beginning of the
  6725. * line specified by lineNumber. It figures out the text character
  6726. * position corresponding to the specified line and sets the text
  6727. * widget's insertionPosition to that location. If this new
  6728. * insertionPosition is not currently on-screen, then the
  6729. * text widget's contents are scrolled to display the new position.
  6730. *
  6731. * The cursor can be moved to last line by specifying DtEDITOR_LAST_LINE
  6732. * as the line number.
  6733. * If lineNumber is less than one, the insert cursor will be placed
  6734. * at the beginning of the first line. If it is greater than the total
  6735. * number of lines, the cursor will be placed at the last line of text.
  6736. */
  6737. /* ARGSUSED */
  6738. void DtEditorGoToLine(
  6739. Widget widget,
  6740. int lineNumber)
  6741. {
  6742. DtEditorWidget editor = (DtEditorWidget)widget;
  6743. XmTextWidget tw;
  6744. XmTextLineTable lineTab;
  6745. XmTextPosition newPos;
  6746. _DtWidgetToAppContext(widget);
  6747. _DtAppLock(app);
  6748. tw = (XmTextWidget)M_text(editor);
  6749. lineTab = tw->text.line_table;
  6750. /*
  6751. * Validate the specified line number, check it is in range.
  6752. * If we adjust the line number, then update the current line display
  6753. * in the status line so it reflects where we are really going. This
  6754. * is only a problem if lineNumber is less/greater than the first/last
  6755. * line becausee we won't be moving the cursor so the status line will
  6756. * not be updated.
  6757. */
  6758. if (lineNumber > tw->text.total_lines || lineNumber == DtEDITOR_LAST_LINE)
  6759. {
  6760. lineNumber = tw->text.total_lines;
  6761. _DtEditorUpdateLineDisplay( editor, lineNumber, FORCE );
  6762. }
  6763. else if(lineNumber < 1)
  6764. {
  6765. lineNumber = 1;
  6766. _DtEditorUpdateLineDisplay( editor, lineNumber, FORCE );
  6767. }
  6768. /*
  6769. * Move the insertion cursor
  6770. */
  6771. newPos = lineTab[lineNumber - 1].start_pos;
  6772. XmTextSetInsertionPosition(M_text(editor), newPos);
  6773. /*
  6774. * Scroll the widget, if necessary
  6775. */
  6776. if (newPos < tw->text.top_character || newPos >= tw->text.bottom_position)
  6777. {
  6778. Arg al[5];
  6779. int ac;
  6780. Dimension height;
  6781. short rows;
  6782. Position x, y;
  6783. ac = 0;
  6784. XtSetArg(al[ac], XmNheight, &height); ac++;
  6785. XtSetArg(al[ac], XmNrows, &rows); ac++;
  6786. XtGetValues(M_text(editor), al, ac);
  6787. if(XmTextPosToXY(M_text(editor), newPos, &x, &y) == True)
  6788. {
  6789. int offset = (y - height/2) * rows;
  6790. XmTextScroll(M_text(editor), offset/(int) height);
  6791. }
  6792. }
  6793. _DtAppUnlock(app);
  6794. } /* end DtEditorGoToLine */
  6795. /*
  6796. * DtEditorGetEditorSizeHints - Set the resize increment, minimum window
  6797. * size, and base dimension properties in the supplied XSizeHints
  6798. * struct for the editor as a whole.
  6799. *
  6800. * NOTE: This routine returns data in the struct pointed to by pHints.
  6801. *
  6802. */
  6803. void
  6804. DtEditorGetSizeHints(
  6805. Widget widget,
  6806. XSizeHints *pHints) /* Return */
  6807. {
  6808. Arg al[10]; /* arg list */
  6809. int ac; /* arg count */
  6810. Dimension FormWidth, FormHeight,
  6811. Twidth, Theight, statusHeight,
  6812. highlightThickness, shadowThickness,
  6813. marginWidth, marginHeight,
  6814. textRegionWidth, textRegionHeight;
  6815. DtEditorWidget editor = (DtEditorWidget) widget;
  6816. _DtWidgetToAppContext(widget);
  6817. _DtAppLock(app);
  6818. /*
  6819. * Window manager should resize in increments of a character or line.
  6820. */
  6821. pHints->width_inc = M_fontWidth(editor);
  6822. pHints->height_inc = M_fontHeight(editor);
  6823. /*
  6824. * Size of the Editor (Form)
  6825. */
  6826. FormWidth = editor->core.width + (2 * editor->core.border_width);
  6827. FormHeight = editor->core.height + (2 * editor->core.border_width);
  6828. /*
  6829. * Size of the Edit window (text widget)
  6830. */
  6831. ac=0;
  6832. XtSetArg(al[ac], XmNwidth, &Twidth); ac++;
  6833. XtSetArg(al[ac], XmNheight, &Theight); ac++;
  6834. XtSetArg(al[ac], XmNhighlightThickness, &highlightThickness); ac++;
  6835. XtSetArg(al[ac], XmNshadowThickness, &shadowThickness); ac++;
  6836. XtSetArg(al[ac], XmNmarginWidth, &marginWidth); ac++;
  6837. XtSetArg(al[ac], XmNmarginHeight, &marginHeight); ac++;
  6838. XtGetValues(M_text(editor), al, ac);
  6839. /*
  6840. * Calculate the width & height of the area within the text widget
  6841. * which can actually display characters.
  6842. */
  6843. textRegionWidth = (int)Twidth -
  6844. (2 * ((int)highlightThickness +
  6845. (int)shadowThickness + (int)marginWidth));
  6846. textRegionHeight = (int)Theight -
  6847. (2 * ((int)highlightThickness +
  6848. (int)shadowThickness + (int)marginHeight));
  6849. /*
  6850. * Set the base width/height to the size of the area which will not
  6851. * display characters.
  6852. *
  6853. * The base width/height is used by the window manager in concert
  6854. * with the height & width increments to display the current size
  6855. * (rows & columns) of edit window (text widget) while resizing the
  6856. * editor.
  6857. */
  6858. pHints->base_width = FormWidth - textRegionWidth;
  6859. pHints->base_height = FormHeight - textRegionHeight;
  6860. /*
  6861. * Get the height of the status line, if it is turned on.
  6862. * Remember, the border width is not included in the height of the
  6863. * status line so add it in to account for the border between the
  6864. * edit window (text widget) and the status line.
  6865. */
  6866. /* XXX Actually, the statusHeight should already be included in the
  6867. * FormHeight, so it should not be necessary to add it in again.
  6868. * However, the numbers don't come out right otherwise. Hmmm? */
  6869. if( M_status_showStatusLine(editor) == True )
  6870. {
  6871. XtSetArg( al[0], XmNheight, &statusHeight );
  6872. XtGetValues( M_status_statusArea(editor), al, 1 );
  6873. statusHeight = statusHeight + editor->core.border_width;
  6874. }
  6875. else
  6876. statusHeight = 0;
  6877. /*
  6878. * What is being returned here is the minimum width & height of the
  6879. * editor. Leave room for the scrollbars, shadows, etc., plus one
  6880. * character.
  6881. */
  6882. pHints->min_width = pHints->base_width + pHints->width_inc;
  6883. pHints->min_height = pHints->base_width + pHints->height_inc +
  6884. statusHeight;
  6885. pHints->flags = PMinSize | PResizeInc | PBaseSize;
  6886. _DtAppUnlock(app);
  6887. } /* end DtEditorGetSizeHints */
  6888. void
  6889. DtEditorInvokeFormatDialog(
  6890. Widget widget)
  6891. {
  6892. DtEditorWidget editor = (DtEditorWidget) widget;
  6893. _DtWidgetToAppContext(widget);
  6894. _DtAppLock(app);
  6895. /*
  6896. * Create the dialog if it is the first time
  6897. */
  6898. if (M_format_dialog(editor) == (Widget)NULL)
  6899. CreateFormatDialog( editor );
  6900. /*
  6901. * Post the dialog
  6902. */
  6903. XtUnmanageChild (M_format_dialog(editor));
  6904. XtManageChild (M_format_dialog(editor));
  6905. XmProcessTraversal(M_format_paragraph(editor), XmTRAVERSE_CURRENT);
  6906. _DtAppUnlock(app);
  6907. } /* DtEditorInvokeFormatDialog */
  6908. void
  6909. DtEditorReset(
  6910. Widget widget)
  6911. {
  6912. DtEditorContentRec cr;
  6913. DtEditorWidget editor = (DtEditorWidget) widget;
  6914. _DtWidgetToAppContext(widget);
  6915. _DtAppLock(app);
  6916. /*
  6917. * Reset the edit window (includes the Undo context)
  6918. */
  6919. cr.type = DtEDITOR_TEXT;
  6920. cr.value.string = "";
  6921. DtEditorSetContents( widget, &cr );
  6922. /*
  6923. * Reset the status line
  6924. * Note, the current & total line displays are reset by DtEditorSetContents()
  6925. */
  6926. if( M_status_statusArea(editor) != (Widget) NULL ) {
  6927. XmTextFieldSetString( M_status_messageText(editor), "" );
  6928. }
  6929. /*
  6930. * Reset the Find/Change & Spell dialogs
  6931. */
  6932. if ( M_search_string(editor) )
  6933. XtFree(M_search_string(editor));
  6934. M_search_string(editor) = (char *)NULL;
  6935. if ( M_replace_string(editor) )
  6936. XtFree(M_replace_string(editor));
  6937. M_replace_string(editor) = (char *)NULL;
  6938. if (M_misspelled_string(editor))
  6939. XtFree(M_misspelled_string(editor));
  6940. M_misspelled_string(editor) = (char *)NULL;
  6941. /*
  6942. * Reset the Format Settings dialog
  6943. */
  6944. if (M_format_dialog(editor) != (Widget)NULL)
  6945. ResetFormatDialog(editor);
  6946. _DtAppUnlock(app);
  6947. } /* end DtEditorReset */
  6948. /*
  6949. *
  6950. * DtEditorSelectAll - Selects the contents of an Editor widget
  6951. *
  6952. */
  6953. Boolean
  6954. DtEditorSelectAll(
  6955. Widget widget)
  6956. {
  6957. DtEditorWidget editor = (DtEditorWidget) widget;
  6958. char *params=(char *)NULL;
  6959. Cardinal num_params = 0;
  6960. XEvent event;
  6961. _DtWidgetToAppContext(widget);
  6962. _DtAppLock(app);
  6963. /*
  6964. * Create an event with a correct timestamp
  6965. */
  6966. event.xkey.time = XtLastTimestampProcessed( M_display(editor) );
  6967. SelectAll( widget, &event, &params, &num_params );
  6968. _DtAppUnlock(app);
  6969. return(True);
  6970. } /* end DtEditorSelectAll */
  6971. void
  6972. DtEditorTraverseToEditor(
  6973. Widget widget)
  6974. {
  6975. DtEditorWidget editor = (DtEditorWidget) widget;
  6976. _DtWidgetToAppContext(widget);
  6977. _DtAppLock(app);
  6978. XmProcessTraversal(M_text(editor), XmTRAVERSE_CURRENT);
  6979. _DtAppUnlock(app);
  6980. } /* end DtEditorTraverseToEditor */