VYSOK ´
E U ˇ
CEN´I TECHNICK ´
E V BRN ˇ
E
BRNO UNIVERSITY OF TECHNOLOGYFAKULTA INFORMA ˇ
CN´ICH TECHNOLOGI´I
´
USTAV INFORMA ˇ
CN´ICH SYST ´
EM ˚
U
FACULTY OF INFORMATION TECHNOLOGY DEPARTMENT OF INFORMATION SYSTEMSVYLEP ˇ
SEN´I IMPLEMENTACE KONZOLY VE FREEBSD
BAKAL ´
A ˇ
RSK ´
A PR ´
ACE
BACHELOR’S THESISAUTOR PR ´
ACE
PETR JUR ´
ASEK
AUTHOR
VYSOK ´
E U ˇ
CEN´I TECHNICK ´
E V BRN ˇ
E
BRNO UNIVERSITY OF TECHNOLOGY
FAKULTA INFORMA ˇ
CN´ICH TECHNOLOGI´I
´
USTAV INFORMA ˇ
CN´ICH SYST ´
EM ˚
U
FACULTY OF INFORMATION TECHNOLOGY DEPARTMENT OF INFORMATION SYSTEMSVYLEP ˇ
SEN´I IMPLEMENTACE KONZOLY VE FREEBSD
IMPROVING CONSOLE IMPLEMENTATION IN FREEBSD
BAKAL ´
A ˇ
RSK ´
A PR ´
ACE
BACHELOR’S THESISAUTOR PR ´
ACE
PETR JUR ´
ASEK
AUTHOR
VEDOUC´I PR ´
ACE
Ing. RUDOLF ˇ
CEJKA
SUPERVISOR
Vysok´e uˇcen´ı technick´e v Brnˇe - Fakulta informaˇcn´ıch technologi´ı
´
Ustav informaˇcn´ıch syst´em˚u Akademick´y rok 2006/2007
Zad´
an´ı bakal´
aˇ
rsk´
e pr´
ace
ˇ
Reˇsitel: Petr Jur´asek
Obor: Informaˇcn´ı technologie
T´ema: Vylepˇsen´ı implementace konzoly ve FreeBSD
Kategorie: Operaˇcn´ı syst´emy
Pokyny:
1. Seznamte se se zdrojov´ym k´odem operaˇcn´ıho syst´emu FreeBSD.
2. Vytvoˇrte testovac´ı skript, kter´y umoˇzn´ı testovat nedostatky zjiˇstˇen´e u souˇcasn´e im-plementace konzoly ve FreeBSD.
Licenˇ
cn´ı smlouva
Licenˇcn´ı smlouva je uloˇzena v archivu Fakulty informaˇcn´ıch technologi´ı Vysok´eho uˇcen´ı technick´eho v Brnˇe.
Abstrakt
Tato bakal´aˇrsk´a pr´ace se zamˇeˇruje na implementaci konzoly v j´adˇre FreeBSD. Snaˇz´ı se odstranit jej´ı nedostatky. Zamˇeˇruje se zejm´ena pak na pr´aci s vyznaˇcen´ymi bloky dat myˇs´ı, kdy pˇri vˇetˇs´ıch zmˇen´ach na obrazovce nezmiz´ı, d˚uslekem toho oznaˇcuje ´uplnˇe jin´y text, neˇz se kter´ym se pracovalo p˚uvodnˇe.
Kl´ıˇcov´
a slova
FreeBSD, j´adro, konzole, oprava, implementace konzoly, C
Abstract
This bachelor’s thesis consider problems of console implementation in FreeBSD. Study the implementation console in FreeBSD from sources code. Aspire solving deficiencies of console implementation. This bachelor’s thesis focus on work with a marked section by mouse.
Keywords
FreeBSD, kernel, syscons, patch, C, console implementation
Citace
Petr Jur´asek: Vylepˇsen´ı implementace konzoly ve FreeBSD, bakal´aˇrsk´a pr´ace, Brno, FIT VUT v Brnˇe, 2007
Vylepˇsen´ı implementace konzoly ve FreeBSD
Prohl´
aˇsen´ı
Prohlaˇsuji, ˇze jsem tuto bakal´aˇrskou pr´aci vypracoval samostatnˇe pod veden´ım pana Ing. Rudolfa ˇCejky. Uvedl jsem vˇsechny liter´arn´ı prameny a publikace, ze kter´ych jsem ˇcerpal.
. . . . Petr Jur´asek 15. kvˇetna 2007
Podˇekov´
an´ı
Dˇekuji sv´emu vedouc´ımu pr´ace panu Ing. Rudolfovi ˇCejkovi za poskytnut´ı odborn´e pomoci.
c
Petr Jur´asek, 2007.
Tato pr´ace vznikla jako ˇskoln´ı d´ılo na Vysok´em uˇcen´ı technick´em v Brnˇe, Fakultˇe in-formaˇcn´ıch technologi´ı. Pr´ace je chr´anˇena autorsk´ym z´akonem a jej´ı uˇzit´ı bez udˇelen´ı opr´avnˇen´ı autorem je nez´akonn´e, s v´yjimkou z´akonem definovan´ych pˇr´ıpad˚u.
Obsah
1 Uvod´ 2
2 Teoretick´a ˇc´ast 3
2.1 Instalace operaˇcn´ıho syst´emu FreeBSD . . . 3
2.2 Po instalaˇcn´ı nastaven´ı. . . 4
2.3 Zdrojov´y k´od . . . 4
3 Anal´yza 6
3.1 ESC sekvence . . . 6
3.2 Testovac´ı skript . . . 9
3.3 V´ysledek anal´yzy . . . 9
4 Implementace opravn´e zmˇeny 11
4.1 Urˇcen´ı podm´ınek . . . 11
4.2 Implementace . . . 15
4.3 Pˇreklad j´adra . . . 20
5 Z´avˇer 22
Kapitola 1
´
Uvod
Hlavn´ım c´ılem t´eto bakal´aˇrsk´e pr´ace je anal´yza implementace konzoly ve FreeBSD a imple-mentace oprav pro pr´aci s vyznaˇcen´ym blokem myˇs´ı.
Kapitola2se zab´yv´a popisem instalace operaˇcn´ıho syst´emu FreeBSD, nastaven´ım operaˇcn´ıho syst´emu a sezn´amen´ım se se zdrojov´ymi k´ody. Kapitola3se zab´yv´a anal´yzou ESC sekvenc´ı, testovac´ım skriptem a v´ysledky testov´an´ı. Kapitola 4 se zab´yv´a popisem podm´ınek, d´ale popisuje implementaˇcn´ı zmˇeny v p˚uvodn´ım k´odu a popisuje pˇreklad j´adra. Kapitola 5
shrnuje dosaˇzen´e ´uspˇechy pˇri implementaci opravy chyb pˇri pr´aci s vyznaˇcen´ymi bloky. V dodatkuA uv´ad´ım kompletn´ı testovac´ı skript pro otestov´an´ı ESC sekvenc´ı na konzoly.
Kapitola 2
Teoretick´
a ˇ
c´
ast
Tuto bakal´aˇrskou pr´aci jsem si zvolil proto, abych se hloubˇeji sezn´amil s operaˇcn´ım syst´emem FreeBSD.
Pr´ace se zamˇeˇruje na implementaci konzoly v j´adˇre operaˇcn´ıho syst´emu FreeBSD. Jedn´a se hlavnˇe o odstranˇen´ı nedostatk˚u pˇri pr´aci s vyznaˇcen´ymi bloky dat myˇs´ı, kdy pˇri vˇetˇs´ıch zmˇen´ach na obrazovce nezmiz´ı, d˚uslekem toho oznaˇcuje ´uplnˇe jin´y text, neˇz se kter´ym se pracovalo p˚uvodnˇe.
Historie BSD syst´emu zaˇc´ın´a v poˇc´atc´ıch AT&T unixu, pokraˇcuje v´yvojem na kali-fornsk´e univerzitˇe v Berkley, kde vznik´a prvn´ı operaˇcn´ı syst´em BSD. FreeBSD projekt odstartoval roku 1993 po pˇrevzet´ı zdrojov´ych k´od˚u z projektu 386BSD, kter´y nebyl dlouho vyv´ıjen. V´ıce o historii BSD syst´emu si m˚uˇzete pˇreˇc´ıst napˇr. v [1].
M´ym prvn´ım krokem, kter´y jsem podnikl bylo sezn´amen´ı se na str´ank´ach projektu FreeBSD (http://www.freebsd.org) s pˇr´ıruˇckou k operaˇcn´ımu syst´emu FreeBSD [2].
Pokraˇcoval jsem staˇzen´ım instalaˇcn´ıch CD z veˇrejnˇe pˇr´ıstupn´eho FTP, abych se mohl zaˇc´ıt vˇenovat instalaci syst´emu. Pro z´ajemce uv´ad´ım adresu odkud si m˚uˇzete st´ahnout ISO obraz instalaˇcn´ıch CD operaˇcn´ıho syst´emu FreeBSD ftp://ftp.freebsd.org.
2.1
Instalace operaˇ
cn´ıho syst´
emu FreeBSD
Pˇred instalac´ı je vhodn´e m´ıt rozdˇelen´y disk na v´ıce ˇc´ast´ı, abyste nepˇriˇsli o jiˇz zabˇehnut´y syst´em, pokud ovˇsem nem´ate v ´umyslu na sv´em poˇc´ıtaˇci provozovat jen operaˇcn´ı syst´em FreeBSD.
Doporuˇcuji instalovat operaˇcn´ı syst´em FreeBSD za odd´ıly s operaˇcn´ım syst´emem Linux, aby nedoˇslo ke ztr´atˇe dat, d´ıky logick´ym odd´ıl˚um disku v operaˇcn´ım syst´emu FreeBSD. Pokud tak neuˇcin´ıte zavadeˇc m´a probl´em zav´est operaˇcn´ı syst´em Linux, d´ıky chybn´ym pˇrepoˇct˚um, kde se nach´az´ı bootovac´ı odd´ıl.
Pˇred zah´ajen´ım samotn´e instalace je dobr´e vˇedˇet, jak´y hardware v´aˇs poˇc´ıtaˇc pouˇz´ıv´a, abyste mohli zadat spr´avnou konfiguraci. Pokud to nev´ıte je dobr´e si to zjistit a ps´at si pozn´amky, aby jste si vˇse nemuseli pamatovat. Je pravdˇepodobn´e ˇze se v´am zjiˇstˇen´e informace o vaˇsem stroji budou hodit, a proto je dobr´e si pap´ırek s poznaˇcen´ym hardwarem poˇc´ıtaˇce pˇr´ıpevnit ke stroji, aby jste je opˇetovnˇe nemuseli vyhled´avat.
Samotn´a instalace je velmi jednoduch´a. Po vloˇzen´ı instalaˇcn´ıho CD se naˇcte zavadˇeˇc syst´emu. Po nabˇehnut´ı zavadˇeˇce syst´emu se zobraz´ı volba pro v´ybˇer zemˇe. Zvol´ıme poloˇzku Czech Republic. Pokraˇcujeme v´ybˇerem mapov´an´ı kl´avesnice, m˚uˇzeme zvolit americkou ˇ
in-stalaci syst´emu. Pomoc´ı programu fdisk vybereme voln´e m´ısto na disku pro instalaci. N´asleduje volba instalace zavadˇeˇce syst´emu, m˚uˇzeme si vybrat z moˇznost´ı nainstalovat zavadˇeˇc syst´emu, z´asah do MBR bez zavadˇeˇce syst´emu, nebo ˇz´adnou. V´ybˇer distribuce, zvolil jsem moˇznost kern-developer, protoˇze budu upravovat zdrojov´e k´ody j´adra, sp´ıˇse zdro-jov´e k´ody syst´emov´e konzoli. N´asleduje v´ybˇer instalaˇcn´ıho m´edia, vol´ım moˇznost CD/DVD. Prob´ıh´a instalace, chv´ıli to trv´a. M˚uˇzete si zat´ım odskoˇcit na svaˇcinu, neˇz se to stihne nain-stalovat. N´asleduje nastaven´ı s´ıtov´e karty a myˇsi. D´ale se zobraz´ı moˇznost vybrat si bal´ıky kter´e chceme m´ı nainstalovan´e. Zaj´ıˇzd´ım do nab´ıdky editor˚u a vyb´ır´am vim, abych mohl editovat zdrojov´e k´ody. Zobraz´ı se v´yzva ke vloˇzen´ı druh´eho CD. Pokraˇcuji vytvoˇren´ım uˇzivatelsk´eho ´uˇctu a zad´an´ım hesla spr´avce. T´ım instalace konˇc´ı.
2.2
Po instalaˇ
cn´ı nastaven´ı
Po instalaˇcn´ı nastaven´ı m˚uˇzeme prov´est v programu sysinstall.
# sysinstall
Zde zvol´ıme volbu configure a m˚uˇzeme nastavovat chov´an´ı syst´emu po startu, pˇriinstalovat softwarov´e bal´ıˇcky, spustit fdisk, apod. Pro dalˇs´ı pr´aci je vhodn´e nastavit myˇs. Myˇs zapneme volbouMouse→Enable.
Po nainstalov´an´ı FreeBSD, se mi operaˇcn´ı syst´em spouˇstˇel velmi dlouhou dobu. Bylo to t´ım, ˇze jsem mˇel zapnut´y sendmail, i kdyˇz jsem na sv´em poˇc´ıtaˇci poˇstovn´ı server ne-provozoval. Po vypnut´ı sendmailu, jsem poc´ıtil rychlejˇs´ı n´abˇeh operaˇcn´ıho syst´emu. Send-mail vypneme pˇrips´an´ım n´asleduj´ıc´ıch ˇr´adk˚u do konfiguraˇcn´ıho souboru /etc/rc.conf, z´apis prov´ad´ıme s opr´avnˇen´ım uˇzivatele root:
sendmail_enable=’NONE’ sendmail_flags=’’
sendmail_outbound_enable=’NO’ sendmail_submit_enable=’NO’ sendmail_msp_queue_enable=’NO’
Po znovu nabˇehnut´ı operaˇcn´ıho syst´emu, by se nemˇelo na obrazovce objevovat sm-mta d´emon, kter´y funguje jako MTA a sm-msp-queue d´emon, kter´y odes´ıl´a maily z fronty /var/spool/clientmqueue
2.3
Zdrojov´
y k´
od
Zdrojov´e k´ody operaˇcn´ıho syst´emu FreeBSD jsou dostupn´e v adres´aˇri /usr/src, pokud je tento adres´aˇr pr´azdn´y, nebyly zdrojov´e k´ody vybr´any pˇri instalaci. V tom pˇr´ıpadˇe je moˇzn´e ze zkop´ırovat z instalaˇcn´ıho cd, nebo st´ahnout z internetu z ftp serveru.
Na instalaˇcn´ım cd nalezneme zdrojov´e k´ody v adres´aˇri /mnt/cdrom/verze/src. N´as bude zaj´ımat vˇetev /usr/src/sys, kde se nach´az´ı zdrojov´e k´ody pro pˇreklad j´adra operaˇcn´ıho syst´emu a z´aroveˇn i pro syst´emovou konzoli. Potˇrebn´e zdrojov´e k´ody vˇetvˇe sys z cd nain-stalujeme n´asledovnˇe:
# mount /dev/cd0 /mnt/cdrom # cd /mnt/cdrom/verze/src # sh install.sh sys
Po nainstalov´an´ı zdrojov´ych k´odu j´adra, m˚uˇzeme pod´ıvat kde se nach´az´ı zdrojov´e k´ody pro syst´emovou konzoli. Zjist´ıme, ˇze zdrojov´e k´ody pro konzoli se nach´az´ı v adres´aˇri /usr/src/sys/dev/syscons.
Pokud si nech´ame pomoc´ı pˇr´ıkazulsvypsat obsah adres´aˇre, zjist´ıme, ˇze nach´az´ı nˇekolik dalˇs´ıch adres´aˇr˚u a soubor˚u. V jednotliv´ych adres´aˇr´ıch se nach´azej´ı zdrojov´e k´ody pro spoˇriˇce obrazovky.
# ls -F /usr/src/sys/dev/syscons
apm/ fade/ rain/ scterm-dumb.c scvesactl.c snake/ syscons.h blank/ fire/ scgfbrndr.c scterm-sc.c scvgarndr.c soubor sysmouse.c daemon/ green/ schistory.c scterm.c scvidctl.c star/ warp/ dragon/ logo/ scmouse.c sctermvar.h scvtb.c syscons.c
Zdrojov´e soubory jsou logicky pojmenov´any jak vid´ıme ve v´ypisu. Zdrojov´e soubory jsou v jazyce C, coˇz m˚uˇzeme odhadnout podle pˇr´ıpony c v n´azvech soubor˚u. M˚uˇzeme se pokusit tak´e odhadnout, co se ve kter´em souboru nach´az´ı. Pro bliˇzˇs´ı zkoum´an´ı si soubory m˚uˇzeme otevˇr´ıt ve vimu, a bl´ıˇze se sezn´amit s jejich obsahem.
# cd /usr/src/sys/dev/syscons # vim *.c *.h
Pro bliˇzˇs´ım prohl´ednut´ı soubor˚u, se m˚uˇzeme zamˇeˇrit na soubor scterm-sc.c, kde se nach´azej´ı ESC sekvence, kter´e budeme n´aslednˇe analyzovat. Po chvilce ˇcten´ı zdrojov´eho k´odu zjist´ıme, ˇze je velmi dobˇre ˇciteln´y. Nejsou v nˇem pouˇzity ˇz´adn´e podivn´e konstrukce jen jednoduch´y jazyk C.
Kapitola 3
Anal´
yza
3.1
ESC sekvence
Znak ESC (escape, 27, 033, 0x1b) se pouˇz´ıv´a pro definici tzv. ESC sekvenc´ı pouˇz´ıvan´ych pro rozˇs´ıˇren´ı ASCII k´odu pro r˚uzn´e ´uˇcely. Jeden nebo nˇekolik znak˚u n´asleduj´ıc´ıch znak ESC nejsou interpretov´any jako ASCII k´ody, ale mohou m´ıt speci´aln´ı v´yznam, mohou definovat pozici kurzoru na obrazovce termin´alu, definovat velikost fontu pouˇz´ıvan´eho tisk´arnou. Or-ganizace ANSI definovala sekvence urˇcen´e pro ovl´ad´an´ı znakov´ych termin´al˚u. Tyto sekvence zahrnuj´ı napˇr. posun kurzoru na urˇcit´y sloupec a ˇr´adek obrazovky.
Pˇr´ıklad:
$ printf ’\033[32m’
V´yˇse uveden´a ESC sekvence zmˇen´ı barvu textu termin´alu na zelenou, kde je znak ESC zaps´an osmiˇckovˇe 033.
Ve zdrojov´em souboru scterm-sc.c um´ıstˇen´em v adres´aˇri /usr/src/sys/dev/syscons/ jsem naˇsel tyto escape sekvence ve funkciscterm_scan_esc() pro naˇc´ıt´an´ı ESC sekvenc´ı:
1. Byl zaregistrov´an znak ESC, a d´ale n´asleduje jeden ze znak˚u viz tabulka3.1:
Tabulka 3.1: Znaky n´asleduj´ıc´ı po znaku ESC Znak Popis ˇcinnosti
7 uloˇz pozici kurzoru
8 obnov uloˇzenou pozici kurzoru [ zaˇc´atek sekvence znak˚u
M pˇresun kurzor v´yˇs o jeden ˇr´adek, roluj obrazovku pokud je na vrcholu c vymaz´an´ı obrazovky
Q nen´ı implemetov´ano
( ISO-2022: k´odov´an´ı pro japonˇstinu, ˇc´ınˇstinu, korejˇstinu
2. Byl zaregistrov´an znak [, d´ale n´asleduje viz tabulka 3.2
3. Byla znamen´ana sekvence znak˚u ESC [0 - 9]+ = viz tabulka 3.3
4. Zaznamenan´a sekvence ESC Q 5. Zaznamenan´a sekvence ESC (
Tabulka 3.2: Znaky n´asleduj´ıc´ı po znaku ESC [
Znak Popis ˇcinnosti Znak Popis ˇcinnosti 0-9 ˇc´ısla P smaˇz n znak˚u ; oddˇelovaˇc @ vloˇz n znak˚u
= jdi na sekci 3 S scroluj n ˇr´adk˚u nahoru A nahoru n ˇr´adk˚u T scroluj n ˇr´adk˚u dol˚u B dol˚u n ˇr´adk˚u X vymaˇz n znak˚u v ˇr´adku C vpravo n sloupc˚u Z pˇresuˇn se n tabul´ator˚u zpˇet D vlevo n sloupc˚u ‘ pˇresuˇn kurzor na sloupec n E kurzor na zaˇc´atku ˇr´adku o n ˇr´adk˚u dole a pˇresuˇn kurzor n sloupc˚u vpravo F kurzor zaˇc´ın´a o n ˇr´adk˚u nahoˇre d pˇresuˇn kurzor na ˇr´adek n
f pohyb kurzoru e pˇresuˇn kurzor n ˇr´adk˚u dol˚u H pohyb kurzoru m zmˇen atributy viz tabulka3.4
J vyˇcisti celou nebo ˇc´ast obrazovky s uloˇz pozici kurzoru
K vyˇcisti cel´y nebo ˇc´ast ˇr´adku u obnov uloˇzen´e souˇradnice kurzoru L vloˇz n ˇr´adk˚u x nastaveni barev viz tabulka3.5
M smaˇz n ˇr´adk˚u z zmˇen virtu´aln´ı konzoli
Tabulka 3.3: Znaky n´asleduj´ıc´ı po znaku ESC [0 - 9]+ = Znak Popis ˇcinnosti
0-9 ˇc´ısla ; oddˇelovaˇc
A nastav barvu hranic´ım obrazovky B nastav
C nastav obecn´y typ a tvar kurzoru F nastav popˇred´ı adapt´eru
G nastav pozad´ı adapt´eru
H nastav reverzn´ı popˇred´ı adapt´eru I nastav reverzn´ı pozad´ı adapt´eru S nastav doˇcasn´y typ a tvar kurzoru
Tabulka 3.4: Atributy Znak Popis ˇcinnosti
0 vr´atit se k v´ychoz´ımu nastaven´ı 1 tuˇcn´y text
4 podtrˇzen´y text 5 blik´an´ı
7 pˇrehozen´ı
22 odstranˇn tuˇcnost 24 odstraˇn podtrˇzen´ı 25 odstraˇn blik´an´ı 27 odstraˇn pˇrehozen´ı
30-37 nastav barvu ansi popˇred´ı
39 obnov v´ychoz´ı barevn´e ansi popˇred´ı 40-47 nastav ansi barvu pozad´ı
49 obnov v´ychoz´ı barevn´e ansi pozad´ı
Tabulka 3.5: Nastaven´ı barev Znak Popis ˇcinnosti
0 obnoven´ı v´ychoz´ıho nastaven´ı 1 nastaven´ı ansi pozad´ı
2 nastaven´ı ansi popˇred´ı 3 nastaven´ı adapt´eru
5 nastaven´ı reverzn´ıho pozad´ı 6 nastaven´ı reverzn´ıho popˇred´ı 7 nastaven´ı reverzn´ıho adapt´eru
3.2
Testovac´ı skript
Testovac´ı skript jsem vytv´aˇrel ve skriptovac´ım jazyce pˇr´ıkazov´eho ˇr´adku. Pouˇzil jsem jednoduch´e konstrukce jakotput, for, read, printf, exit. Do skriptu jsem nepsal vˇsechny sekvence, ale jen ty, kter´e byly vhodn´e k otestov´an´ı. Testov´an´ı se zamˇeˇrilo hlavnˇe na pr´aci s blokem vyznaˇcen´ym myˇs´ı, kter´y z˚ust´av´a na obrazovce a neodpov´ıd´a vyznaˇcen´emu textu. Uk´azka testovac´ıho skriptu pro ˇr´ıd´ıc´ı sekvenci ESC [4T – skrolov´an´ı dol˚u o 4 ˇr´adky:
#!/bin/sh tput clear for i in 0 1 2 3 4 5 6 7 8 9 a b c d e f do for j in 1 2 3 4 5 6 7 8 9 10 do printf ’$i’ done printf ’\n’ done
read Q # nacti vstup z klavesnice tput cm 0 8 # umisteni kurzoru x y read Q # nacti vstup z klavesnice
printf ’\033[4T’ # skroluj n radku dolu read Q # nacti vstup z klavesnice
exit 0
Testovac´ı skript m˚uˇzeme spustit pomoc´ı pˇr´ıkazush n´asledovnˇe:
$ sh skript-term.sh
Testovac´ı skript se spust´ı v shellu. Pokud budeme cht´ıt prov´est testovac´ı skript v bashi provedeme to n´asledovnˇe:
$ ./skript-term.sh
Testov´an´ı prob´ıhalo spuˇstˇen´ım skriptu, vybr´an´ım volby ESC sekvence k testov´an´ı. Vyp-sal se zkuˇsebn´ı text na obrazovku. Myˇs´ı jsem vybral n´ahodn´y blok. Zadal jsem vstup z kl´avesnice a ˇcekal jestli na proveden´ı sekvence a sledoval jsem jestli to bude m´ıt vliv na chov´an´ı konzoly.
3.3
V´
ysledek anal´
yzy
Po otestov´an´ı ESC sekvenc´ı, jsem dospˇel k z´avˇeru, ˇze pˇri maz´an´ı, vkl´ad´an´ı nebo skrolov´an´ı, kdy se vˇetˇsinou mˇen´ı text na obrazovce, z˚ust´av´a oznaˇcen jiˇz neplatn´y blok dat. Pˇri pohybu kurzoru se text nemˇen´ı a nepovaˇzuji za chybu, pokud z˚ustane blok dat vyznaˇcen. Z˚ust´av´a ˇspatnˇe vyznaˇcen´y blok po proveden´ı zadan´e sekvence znak˚u u tˇechto ESC sekvenc´ı:
1. Vyˇciˇstˇen´ı ˇc´asti nebo cel´eho ˇr´adku
3. Smaz´an´ı n ˇr´adk˚u
4. Smaz´an´ı n znak˚u
5. Vloˇzen´ı n znak˚u
6. Skrolov´an´ı nahoru
7. Skrolov´an´ı dol˚u
8. Vymaz´an´ı n znak˚u v ˇr´adku
N´avrhy pro odstranˇen´ı zjiˇstˇen´ych nedostatk˚u:
• Prvn´ım n´avrhem pro odstranˇen´ı zjiˇstˇen´ych nedostatk˚u bylo navrhnuto odstranˇen´ı vyznaˇcen´ı.
• Dalˇs´ım ˇreˇsen´ım bylo navrhnuto, aby se vyznaˇcen´ı posouvalo spolu s textem, dokud by nezmizel z obrazovky, oznaˇcen´ı by se zruˇsilo, ale jen v pˇr´ıpadˇe, ˇze nebyl ovlivnˇen pˇri maz´an´ı ˇci vkl´ad´an´ı vyznaˇcen´y blok dat.
Zkusil jsem se pod´ıvat bl´ıˇze na tyto sekvence a pod´ıvat se jak jsou implementov´any. Zjistil jsem ˇze volaj´ı n´asleduj´ıc´ı funkce ze souborusctermvar.h:
sc term clr eol() funkce je vol´ana pro vyˇciˇstˇen´ı ˇc´asti nebo cel´eho ˇr´adku
sc term ins line() funkce je vol´ana sekvenc´ı pro vloˇzen´ı n ˇr´adk˚u, nebo sekvenc´ı pro skrolov´an´ı nahoru, kdy je pozice y nula.
sc term del line() funkce je vol´ana pro sekvenci smaz´an´ı n ˇr´adk˚u, nebo skrolov´an´ı na-horu, kdy je pozice y nula.
sc term del char() funkce je vol´ana pro sekvenci smaz´an´ı n znak˚u
sc term ins char() funkce je vol´ana pro sekvenci vloˇzen´ı n znak˚u
Je zaj´ımav´e, ˇze funkcesc_term_ins_line()asc_term_del_line()jsou vol´any dvakr´at jednou pro vloˇzen´ı ˇc´ı smaz´an´ı ˇr´adk˚u a podruh´e pro skrolov´an´ı.
Vˇsiml jsem si, ˇze sekvence pro vymaz´an´ı n znak˚u v ˇr´adku nevol´a ˇz´adnou funkci ze souborusctermvar.h, ale nˇekolik jin´ych funkc´ıch kter´e byly vol´any ze souborusctermvar.h. Rozhold jsem se toto vol´an´ı funkc´ı pro lepˇs´ı pˇrehlednost upravit a pˇridat novou in line funkci
Kapitola 4
Implementace opravn´
e zmˇ
eny
4.1
Urˇ
cen´ı podm´ınek
Pˇri prvn´ım pohledu na probl´em m˚uˇze doj´ıt k n´asleduj´ıc´ım situac´ım s vyznaˇcen´ym blokem dat pomoc´ı myˇsi pˇri vkl´ad´an´ı/maz´an´ı:
• Prvn´ı situace nastane kdy vyznaˇcen´y blok dat myˇs´ı se nach´az´ı pˇred kurzorem. Chov´an´ı v t´eto situaci je, ˇze vyznaˇcen´y blok dat nen´ı ovlivnˇen maz´an´ım ˇci vkl´ad´an´ım, vyznaˇcen´y blok dat z˚ust´av´a i nad´ale vyznaˇcen. Nedoch´az´ı k ˇz´adn´e zmˇenˇe viz obr´azek 4.1.
Obr´azek 4.1: Kurzor se nach´az´ı za vyznaˇcen´ym blokem
• Dalˇs´ı situace nastane pokud vyznaˇcen´y blok myˇs´ı zasahuje ovlivnˇenou oblast. Oˇcek´avan´e chov´an´ı v tomto pˇr´ıpadˇe je, ˇze vyznaˇcen´y blok dat zmiz´ı. Text, kter´y byl vyznaˇcen, se zmˇenil viz obr´azek 4.2.
• Posledn´ı situace nastane, ˇze vyznaˇcen´y blok dat myˇs´ı leˇz´ı za kurzorem. Vyznaˇcen´y text nen´ı ovlivnˇen zmˇenou vyznaˇcen´eho bloku textu, ale posunem viz obr´azek 4.3. Vyznaˇcen´y blok dat se posune spoleˇcnˇe s vyznaˇcen´ym textem, pokud ˇc´ast textu, kter´a byla vyznaˇcena, zmiz´ı z obrazovky, zmiz´ı i vyznaˇcen´ı bloku.
Obr´azek 4.3: Kurzor se nach´az´ı pˇred vyznaˇcen´ym blokem
Pˇri skrolov´an´ı m˚uˇze doj´ıt k n´asleduj´ıc´ım situac´ım:
• Pˇri skorolov´an´ı se vyznaˇcen´y blok myˇs´ı posouv´a po obrazovce spolu s textem. Pokud pˇres´ahne vyznaˇcen´a oblast hranice monitoru, vyznaˇcen´ı zmiz´ı.
Uveden´e podm´ınky nepokr´yvaj´ı vˇsechny situace, ke kter´ym m˚uˇze doj´ıt, jen nastiˇnuj´ı nejobvyklejˇs´ı situace. Pro lepˇs´ı urˇcen´ı podm´ınek je nutn´e se pod´ıvat na kaˇzdou funkci zvl´aˇst’ a urˇcit pro ni podm´ınky.
Zamˇeˇrme se nyn´ı na podm´ınky pro vkl´ad´an´ı ˇr´adk˚u. Pod´ıvejme se za jak´ych situac´ı m˚uˇze doj´ıt k posunu ˇr´adk˚u. Prvn´ı situace nastane, kdy se kurzor nach´az´ı pˇred vyznaˇcenou oblast´ı viz obr´azek4.3. Dalˇs´ı pˇr´ıpad nastane, kdy se kurzor nach´az´ı na prvn´ım ˇr´adku uvnitˇr vyznaˇcen´eho bloku viz obr´azek 4.4. Nov´y ˇr´adek se vkl´ad´a na ˇr´adek na nˇemˇz se nach´az´ı kurzor, proto si posun m˚uˇzeme dovolit i kdyˇz se kurzor nach´az´ı ve vyznaˇcen´em bloku.
Obr´azek 4.4: Kurzor se nach´az´ı na prvn´ım ˇr´adku uvnitˇr vyznaˇcen´eho bloku
Z uveden´ych obr´azk˚u m˚uˇzeme urˇcit podm´ınky pro posun ˇr´adku. K posunu doch´az´ı v pˇr´ıpadˇe, pokud se kurzor nach´az´ı na stejn´em ˇr´adku jako poˇc´atek vyznaˇcen´eho bloku nebo v´yˇse neˇz poˇc´atek vyznaˇcen´eho bloku. Z toho vypl´yv´a, ˇze se u t´eto funkce zamˇeˇr´ıme na kontrolu ˇr´adk˚u tzn. y hodnot. Matematicky tuto podm´ınku m˚uˇzeme zapsat:
ycursor ≤ymouse start
Zb´yv´a urˇcit podm´ınky, za kter´ych se vyznaˇcen´y blok zruˇs´ı. Vyznaˇcen´y blok se zruˇs´ı pokud kurzor leˇz´ı ve vyznaˇcen´em bloku, ale pˇresto neleˇz´ı na prvn´ım ˇr´adku vyznaˇcen´eho
bloku jak je zn´azornˇeno na obr´azku4.2. M˚uˇze nastat situace na obr´azku4.5, kdy se kurzor nach´az´ı na ˇr´adku za koncem vyznaˇcen´eho bloku. Nov´y ˇr´adek se vloˇz´ı pˇred tento ˇr´adek a dojde k poruˇsen´ı vyznaˇcen´eho bloku.
Obr´azek 4.5: Kurzor se nach´az´ı na ˇr´adku za koncem vyznaˇcen´eho bloku
Z uveden´ych situac´ı urˇc´ıme podm´ınku pro zruˇsen´ı vyznaˇcen´eho bloku. Blok zruˇs´ıme v pˇr´ıpadˇe, ˇze konec vyznaˇcen´eho bloku leˇz´ı na stejn´em ˇr´adku jako kurzor, nebo se kurzor nach´az´ı uvnitˇr bloku, ale neleˇz´ı na prvn´ım ˇr´adku vyznaˇcen´eho bloku. Matematicky tuto podm´ınku m˚uˇzeme zapsat:
(ycursor=ymouse end)∨((ycursor < ymouse end)∧(ycursor> ymouse start))
Nyn´ı urˇc´ıme podm´ınky pro maz´an´ı ˇr´adk˚u. Urˇceme za jak´ych podm´ınek m˚uˇze doj´ıt k posunu ˇr´adk˚u pˇri maz´an´ı. K posunu ˇr´adk˚u m˚uˇze doj´ıt v pˇr´ıpadˇe, ˇze konec mazan´e oblasti se nach´az´ı pˇred zaˇc´atkem vyznaˇcen´eho bloku viz obr´azek4.6. Nejsou dalˇs´ı situace, pˇri kter´ych by mohlo doj´ıt k posunu bloku.
Obr´azek 4.6: Konec mazan´e oblasti se nach´az´ı pˇred zaˇc´atkem vyznaˇcen´eho bloku
Matematicky tuto podm´ınku vyj´adˇr´ıme:
ycursor+n−1< ymouse start
D´ale urˇc´ıme podm´ınky pro zruˇsen´ı vyznaˇcen´eho bloku. U maz´an´ı si mus´ıme d´at pozor, ˇ
ze kromˇe pozice kurzoru, mus´ıme kontrolovat konec mazan´e oblasti. Zruˇsen´ı vyznaˇcen´eho bloku nastane v pˇr´ıpadˇe, ˇze mazan´a oblast obsahuje cel´y vyznaˇcen´y blok viz obr´azek 4.7.
Tuto podm´ınku m˚uˇzeme zapsat n´asledovnˇe:
(ycursor < ymouse start)∧(ycursor+n > ymouse end)
Obr´azek 4.7: Cel´y vyznaˇcen´y blok leˇz´ı v mazan´e oblasti
podm´ınku m˚uˇzeme vyj´adˇrit:
(ycursor =ymouse start)∨(ycursor =ymouse end)
V dalˇs´ı situaci se m˚uˇze kurzor, nebo konec mazan´e oblasti nach´azet uvnitˇr vyznaˇcen´eho bloku. Podm´ınku vyj´adˇr´ıme:
((ycursor> ymouse start)∧(ycursor< ymouse end))∨((ycursor+n > ymouse start)∧(ycursor+n < ymouse end))
Urˇceme podm´ınky pro vkl´ad´an´ı znak˚u. Pˇri vkl´ad´an´ı znak˚u dojde ke zruˇsen´ı vyznaˇcen´eho bloku pokud se kurzor nach´az´ı uvnitˇr vyznaˇcen´eho bloku. K posunu bloku doch´az´ı pˇri vkl´ad´an´ı, kdy se kurzor leˇz´ı na stejn´em ˇr´adku pˇred zaˇc´atkem vyznaˇcen´eho bloku a z´aroveˇn konec vyznaˇcen´eho bloku se nach´az´ı na stejn´em ˇr´adku jako zaˇc´atek. Pokud se kurzor nach´az´ı v´yˇse o ˇr´adek neˇz zaˇc´atek vyznaˇcen´eho bloku k posunu nedoch´az´ı.
Urˇceme podm´ınky pro maz´ani znak˚u. Pˇri maz´an´ı znak˚u mus´ı br´at i v ´uvahu konec mazan´e oblasti. Pokud se konec mazan´e oblasti nebo kurzor nach´az´ı ve vyznaˇcen´em bloku dojde k odstranˇen´ı vyznaˇcen´eho bloku. Speci´aln´ı pˇr´ıpad nast´av´a kdy, vyznaˇcen´y blok je menˇs´ı neˇz poˇcet mazan´ych znak˚u a leˇz´ı uvnitˇr mazan´e oblasti, dojde opˇet k odstranˇen´ı vyznaˇcen´eho bloku. K posunu vyznaˇcen´eho bloku doch´az´ı pokud leˇz´ı na stejn´em ˇr´adku za koncem mazan´e oblasti a z´aroveˇn se konec vyznaˇcen´eho blok se nach´az´ı na tomto ˇr´adku.
Podm´ınky pro maz´an´ı znak˚u v ˇr´adku. Pˇri maz´an´ı znak˚u v ˇr´adku staˇc´ı urˇcit podm´ınky pro odznaˇcen´ı bloku. K posunu znak˚u nedoch´az´ı. Pˇri maz´an´ı bereme v ´uvahu i konec mazan´e oblasti. Pokud se konec mazan´e oblasti nebo kurzor nach´az´ı ve vyznaˇcen´em bloku dojde k odstranˇen´ı vyznaˇcen´eho bloku. Speci´aln´ı pˇr´ıpad nast´av´a kdy, vyznaˇcen´y blok je menˇs´ı neˇz poˇcet mazan´ych znak˚u a leˇz´ı uvnitˇr mazan´e oblasti, dojde opˇet k odstranˇen´ı vyznaˇcen´eho bloku.
Podm´ınky pro vyˇciˇstˇen´ı ˇc´asti nebo cel´eho ˇr´adku. Zde opˇet bereme v ´uvahu dvˇe hodnoty. Z´aleˇz´ı na pˇr´ıpadˇe kterou ˇc´ast ˇr´adku maˇzeme. V tomto pˇr´ıpadˇe nedoch´az´ı k posunu textu. Urˇcujeme podm´ınky jen pro odstranˇen´ı vyznaˇcen´eho bloku. Podm´ınky jsou podobn´e jako pro maz´an´ı znak˚u v ˇr´adku, jen se liˇs´ı hodnoty, kter´e budeme kontrolovat v jednotliv´ych pˇr´ıpadech:
Maˇzeme od kurzoru po konec ˇr´adku V tomto pˇr´ıpadˇe bereme v ´uvahu hodnoty kur-zor a konec ˇr´adku
Maˇzeme od zaˇc´atku ˇr´adku po kurzor V tomto pˇr´ıpadˇe bereme v ´uvahu hodnoty zaˇc´atek ˇr´adku a kurzor
Maˇzeme cel´y ˇr´adek V tomto pˇr´ıpade bereme v ´uvahu cel´y ˇr´adek, tedy hodnoty zaˇc´atek a konec ˇr´adku.
4.2
Implementace
Prvn´ım krokem implementace bylo pˇrid´an´ı nov´e in line funkce sc_term_del_xchar() do souboru sctermvar.h s pˇridan´ym vol´an´ım funkce sc_remove_cutmaking pro odstranˇen´ı vyznaˇcen´eho bloku:
static __inline void sc_term_del_xchar(scr_stat *scp, int n, int ch, int attr); static __inline void
sc_term_del_xchar(scr_stat *scp, int n, int ch, int attr) {
if (n < 1) n = 1;
if (n > scp->xsize - scp->xpos) n = scp->xsize - scp->xpos;
sc_vtb_erase(&scp->vtb, scp->cursor_pos, n, ch, attr); mark_for_update(scp, scp->cursor_pos);
mark_for_update(scp, scp->cursor_pos + n - 1); }
Tˇelo funkce jsem pˇrevzal se souboruscterm-sc.ca upravil jsem vol´an´ı na:
case ’X’: /* erase n characters in line */
sc_term_del_xchar(scp, tcp->param[0], sc->scr_map[0x20], tcp->cur_attr); break;
Dalˇs´ı zmˇenˇe ke kter´e doˇslo ve zdrojov´ych souborech bylo dops´an´ı vol´an´ı funkce pro
odstranˇen´ı vyznaˇcen´eho bloku v souborusctermvar.hdo funkc´ısc term ins line, sc term del line, sc term del char, sc term ins char, sc term clr eol:
...
sc_remove_cutmakring(scp); ...
Funkce by mˇela zabr´anit, aby na obrazovce z˚ust´aval vyznaˇcen´y blok myˇs´ı, kter´y by mohl ˇ
casem oznaˇcovat neplatn´y blok textu.
V dalˇs´ım kroku jsem urˇcil jak se budou v dan´e funkci implementovat podm´ınky. Podle podm´ınek jsem si urˇcil funkce, kter´e by vraceli polohu kurzoru. Jednalo by se o funkce, kter´e by vracely typ int, kter´y byl reprezentoval logickou pravdu ˇci nepravdu. Po lepˇs´ım prostudov´an´ı zdrojov´eho k´odu, jsem objevil funkcisc inside cutmark(), kter´a urˇcuje zda kurzor, leˇz´ı v oblasti bloku dat vyznaˇcen´ych myˇs´ı. Pro urˇcen´ı polohy kurzoru jsem si stanovil n´avrh n´asleduj´ıc´ıch funkc´ı:
sc inside cutmark() jiˇz implementovan´a funkce v souboruscmouse.c. Funke zjiˇst’uje zda zadan´a poloha kurzoru se nach´az´ı uvnitˇr vyznaˇcen´eho bloku myˇs´ı.
sc after cutmark() funkce vrac´ı hodnotutrue, reprezentovanou typem int, pokud kurzor leˇz´ı za vyznaˇcenou oblast´ı myˇs´ı.
sc before cutmark() funkce vrac´ı hodnotutrue, reprezentovanou typem int, pokud kurzor leˇz´ı pˇred vyznaˇcenou oblast´ı myˇs´ı.
Zd´alo se mi zbyteˇcn´e kontrolovat jestli m´a vyznaˇcen´y blok z˚ustat v poˇr´adku. N´aslednˇe jsem implementoval funkcisc before cutmark(), pro zjiˇstˇen´ı zda kurzor leˇz´ı pˇred vyznaˇcenou oblast´ı myˇs´ı:
int
sc_before_cutmark(scr_stat *scp, int pos) { int start; if (scp->mouse_cut_end < 0) return FALSE; if (scp->mouse_cut_start <= scp->mouse_cut_end) { start = scp->mouse_cut_start; } else { start = scp->mouse_cut_end; }
return (start > pos); }
D´ale jsem si na implementoval funkci sc after cutmark(), pro zjiˇstˇen´ı zda zadan´a pozice leˇz´ı za vyznaˇcenou oblast´ı myˇs´ı:
int
sc_after_cutmark(scr_stat *scp, int pos) { int end; if (scp->mouse_cut_end < 0) return FALSE; if (scp->mouse_cut_start <= scp->mouse_cut_end) { end = scp->mouse_cut_end; } else { end = scp->mouse_cut_start - 1; }
return (end < pos); }
Proch´azel jsem souborscmouse.cjestli n´ahodou neobjev´ım funkci pro posun bloku. Po dlouh´em hled´an´ı jsem ˇz´adnou funkci nenaˇsel. Rozhodl jsem se na implementovat vlastn´ı funkci pro posun bloku nazvanou sc move cutmarking():
void sc_move_cutmarking(scr_stat *scp, int n) { if (scp->mouse_cut_end >= 0) { mark_for_update(scp, scp->mouse_cut_start); mark_for_update(scp, scp->mouse_cut_end); scp->mouse_cut_start = scp->mouse_cut_start + n; scp->mouse_cut_end = scp->mouse_cut_end + n;
mark_for_update(scp, scp->mouse_cut_start); mark_for_update(scp, scp->mouse_cut_end); }
}
Pro funkci sc term ins line() vkl´ad´an´ı ˇr´adk˚u kontroluji jestli se kurzor nach´az´ı za koncem oblasti vyznaˇcen´ym blokem myˇs´ı, n´aslednˇe dojde k posunu textu nebo kurzor leˇz´ı v dan´e oblasti vyznaˇcen´ym blokem myˇs´ı, kdy dojde k odznaˇcen´ı bloku.
static __inline void
sc_term_ins_line(scr_stat *scp, int y, int n, int ch, int attr, int tail) {
...
int y_start, y_end;
if (scp->mouse_cut_start < scp->mouse_cut_end) { y_start = scp->mouse_cut_start/scp->xsize; y_end = scp->mouse_cut_end/scp->xsize; } else { y_start = scp->mouse_cut_end/scp->xsize; y_end = scp->mouse_cut_start/scp->xsize; } if ( y == 0 ) { if(y_end + n > scp->ysize) sc_remove_cutmarking(scp); else
sc_move_cutmarking(scp, n*scp->xsize); /* move cutmarking */ } else {
if ((scp->ypos <= y_start)) { if(y_end + n > scp->ysize)
sc_remove_cutmarking(scp); else
sc_move_cutmarking(scp, n*scp->xsize); /* move cutmarking */ }
if ((scp->ypos <= y_end && scp->ypos > y_start)) sc_remove_cutmarking(scp);
} ... }
Pro funkci sc term del line()maz´an´ı ˇr´adk˚u kontroluji jestli se kurzor nach´az´ı uvnitˇr vyznaˇcen´eho bloku nebo konec mazan´e oblasti, nebo jestli kurzor leˇz´ı pˇred vyznaˇcen´ym blokem a z´aroveˇn konec mazan´e oblasti leˇz´ı za vyznaˇcen´ym blokem myˇs´ı, kdy dojde k odznaˇcen´ı bloku, nebo konec mazan´e oblasti leˇz´ı pˇred vyznaˇcen´ym blokem myˇs´ı, dojde k posunu vyznaˇcen´eho bloku.
{ ...
int y_start, y_end;
if (scp->mouse_cut_start < scp->mouse_cut_end) { y_start = scp->mouse_cut_start/scp->xsize; y_end = scp->mouse_cut_end/scp->xsize; } else { y_start = scp->mouse_cut_end/scp->xsize; y_end = scp->mouse_cut_start/scp->xsize; } if ( y == 0 ) { if (y_start - n < 0) sc_remove_cutmarking(scp); else
sc_move_cutmarking(scp, n*scp->xsize*-1); /* move cutmarking */ } else { if ((scp->ypos + n <= y_start)) if (y_start - n < 0) sc_remove_cutmarking(scp); else sc_move_cutmarkig(scp, n*scp->xsize*-1);
if ((scp->ypos <= y_end && scp->ypos >= y_start) ||
(scp->ypos + n - 1 <= y_end && scp->ypos + n - 1 >= y_start) || (scp->ypos < y_start && scp->ypos + n - 1 >= y_end))
sc_remove_cutmarking(scp); }
... }
Pro funkcisc term ins char()vkl´ad´an´ı znak˚u kontroluji jestli se kurzor nach´az´ı uvnitˇr vyznaˇcen´eho bloku myˇs´ı, kdy se vyznaˇcen´ı bloku zruˇs´ı, nebo zda leˇz´ı kurzor pˇred vyznaˇcen´ym blokem a dojde k posunu.
static __inline void
sc_term_ins_char(scr_stat *scp, int n, int ch, int attr) {
...
int y_start, y_end;
if (scp->mouse_cut_start < scp->mouse_cut_end) { y_start = scp->mouse_cut_start/scp->xsize; y_end = scp->mouse_cut_end/scp->xsize; } else { y_start = scp->mouse_cut_end/scp->xsize; y_end = scp->mouse_cut_start/scp->xsize; }
if (sc_inside_cutmark(scp, scp->cursor_pos - 1)) sc_remove_cutmarking(scp);
if (sc_before_cutmark(scp, scp->cursor_pos - 1) && (scp->ypos == y_start) && (scp->ypos == y_end)) sc_move_cutmarkig(scp, n);
... }
Pro funkci sc term del char() maz´an´ı znak˚u kontroluji zda se kurzor nach´az´ı uvnitˇr vyznaˇcen´eho bloku, nebo jestli se uvnitˇr vyznaˇcen´eho bloku nach´az´ı konec mazan´e oblasti. Jeˇstˇe je tu moˇznost, ˇze mazan´a oblast je vetˇs´ı neˇz vyznaˇcen´y blok a proto kontroluji jestli mazan´a oblast neobsahuje vyznaˇcen´y blok, kdy doch´az´ı ke zruˇsen´ı vyznaˇcen´eho bloku. Kontroluji jestli nedoch´az´ı k posunu vyznaˇcen´eho bloku, kdy vyznaˇcen´y blok leˇz´ı za koncem mazan´e oblasti.
static __inline void
sc_term_del_char(scr_stat *scp, int n, int ch, int attr) {
...
int y_start, y_end;
if (scp->mouse_cut_start < scp->mouse_cut_end) { y_start = scp->mouse_cut_start/scp->xsize; y_end = scp->mouse_cut_end/scp->xsize; } else { y_start = scp->mouse_cut_end/scp->xsize; y_end = scp->mouse_cut_start/scp->xsize; } if ((sc_inside_cutmark(scp, scp->cursor_pos) || sc_inside_cutmark(scp, scp->cursor_pos + n)) || (sc_before_cutmark(scp, scp->cursor_pos + n - 1) &&
y_start != y_end) ||
(sc_before_cutmark(scp, scp->cursor_pos) && sc_after_cutmark(scp, scp->cursor_pos + n))) sc_remove_cutmarking(scp);
if (sc_before_cutmark(scp, scp->cursor_pos + n) && (scp->ypos == y_start) && (scp->ypos == y_end)) sc_move_cutmarkig(scp, n*-1);
... }
Pro funkci sc term del xchar() smaz´an´ı znak˚u v ˇr´adku kontroluji jestli leˇz´ı kurzor nebo konec mazan´e oblasti uvnitˇr vyznaˇcen´eho bloku, ˇci mazan´a oblast v sobe obsahuje vyznaˇcen´y blok. Zde nekontroluji jestli mazan´a oblast leˇz´ı pˇred vyznaˇcen´ym blokem, pˇri maz´an´ı se text neposouv´a.
sc_term_del_xchar(scr_stat *scp, int n, int ch, int attr) {
...
if ((sc_inside_cutmark(scp, scp->cursor_pos) ||
sc_inside_cutmark(scp, scp->cursor_pos + n - 1)) || (sc_before_cutmark(scp, scp->cursor_pos) &&
sc_after_cutmark(scp, scp->cursor_pos + n - 1))) sc_remove_cutmarking(scp);
... }
Pro funkci sc term clr eol()ˇciˇstˇen´ı ˇc´asti nebo cel´eho ˇr´adku je to jeˇstˇe trochu komp-likovanˇejˇs´ı z´aleˇz´ı zda maˇzu cel´y ˇr´adek nebo jen od kurzoru ke konci ˇr´adku, ˇci od kurzoru k zaˇc´atku ˇr´adku. Potˇrebuji si zde urˇcit poˇc´atek a konec ˇr´adku. Pˇri prov´adˇen´ı t´eto funkce nedoch´az´ı k posunu. Definuji jen podm´ınku za kter´e se m´a vyznaˇcen´y blok smazat.
static __inline void
sc_term_clr_eol(scr_stat *scp, int n, int ch, int attr) {
switch (n) {
case 0: /* clear form cursor to end of line */ if (sc_inside_cutmark(scp, scp->cursor_pos) ||
sc_inside_cutmark(scp, scp->cursor_pos + scp->xsize - 1 - scp->xpos)|| (sc_before_cutmark(scp, scp->cursor_pos) &&
sc_after_cutmark(scp, scp->cursor_pos + scp->xsize - 1 - scp->xpos))) sc_remove_cutmarking(scp);
break;
case 1: /* clear from beginning of line to cursor */ if (sc_inside_cutmark(scp, scp->cursor_pos) ||
sc_inside_cutmark(scp, scp->cursor_pos - scp->xpos) || (sc_before_cutmark(scp, scp->cursor_pos - scp->xpos) &&
sc_after_cutmark(scp, scp->cursor_pos))) sc_remove_cutmarking(scp);
break;
case 2: /* clear entire line */
if (sc_inside_cutmark(scp, scp->cursor_pos - scp->xpos ) || sc_inside_cutmark(scp, scp->cursor_pos +
scp->xsize - 1 - scp->xpos) ||
(sc_before_cutmark(scp, scp->cursor_pos - scp->xpos) &&
sc_after_cutmark(scp, scp->cursor_pos + scp->xsize - 1 - scp->xpos))) sc_remove_cutmarking(scp);
break; }
}
4.3
Pˇ
reklad j´
adra
Pro otestov´an´ı proveden´ych zmˇen ve zdrojov´ych souborech je nutn´e prov´est pˇreklad j´adra, aby se zmˇeny projevily pˇri testov´an´ı proveden´ych zmˇen. Pˇri pˇrekladu j´adra je vhodn´e si
vytvoˇrit vlastn´ı konfiguraˇcn´ı soubor. Konfiguraˇcn´ı soubor nalezneme v adres´aˇri /usr/src/sys/arch/conf, kde arch znaˇc´ı naˇsi architekturu napˇr. i386. Dobr´ym zvykem je pojmenovat konfiguraˇcn´ı
soubor podle n´azvu poˇc´ıtaˇce. Je vhodn´e si konfiguraˇcn´ı soubory ukl´adat do domovsk´eho adres´aˇre superuˇzivatele root, aby pˇri aktualizaci zdrojov´ych k´odu nedoˇslo k jejich pˇreps´an´ı. Vˇse potˇrebn´e zaˇr´ıd´ıme podle n´asleduj´ıc´ı skupiny pˇr´ıkaz˚u, pˇr´ıklad je pro architekturu i386, mus´ıte b´yt pˇrihl´aˇsen jako root:
cd /usr/src/sys/i386/conf mkdir /root/kernels
cp GENERIC /root/kernels/HB01-223A ln -s /root/kernels/HB01-223A
Nyn´ı m˚uˇzeme editovat konfiguraˇcn´ı soubor HB01-223A
vim HB01-223A
Po ´uprav´ach konfiguraˇcn´ıho souboru pokraˇcujeme pˇrekladem j´adra. Zmˇen´ıme adres´aˇr na /usr/src.
cd /usr/src
make buildkernel KERNCONF=HB01-223A make installkernel KERNCONF=HB01-223A
Varianta pro inkrement´aln´ı pˇreklad j´adra:
make buildkernel -DNO_KERNELCLEAN=yes KERNCONF=HB01-223A
Nov´e j´adro se zkop´ıruje do adres´aˇre /boot/kernel jako /boot/kernel/kernel a star´e j´adro se pˇresune do /boot/kernel.old/kernel. Pˇred pˇrekladem j´adra je vhodn´e si udˇelat z´alohu a v pˇr´ıpadˇe pot´ıˇz´ı zav´est zn´am´e funkˇcn´ı j´adro.
cp -r /boot/kernel /boot/kernel.save
V zavadˇeˇci je potom moˇzn´e zav´est toto j´adro pomoc´ı naps´an´ım tˇechto ˇr´adk˚u:
unload all
load /boot/kernel.save/kernel boot
Zde uv´ad´ım pro pˇrehled jak dlouho trv´a pˇreklad j´adra viz tabulka4.1. Ke srovn´an´ı jsem mˇel k dispozici dva poˇc´ıtaˇce.
Tabulka 4.1: Doba pˇrekladu j´adra Procesor Frekvence Pamˇet Casˇ Intel Celron 366 MHz 64 MB 1 h 58 m AMD Turion64 X2 1,6 GHz 1 GB 15 m 28 s
Kapitola 5
Z´
avˇ
er
Pr´ace se zab´yvala anal´yzou implementace konzoly ve FreeBSD a odstranˇen´ım jej´ıch ne-dostatk˚u. Hlavn´ım c´ılem se staly anal´yza ESC sekvence pro ˇr´ızen´ı konzoly a implementace pˇr´ıpadn´e opravy pro pr´aci s vyznaˇcen´ym blokem myˇs´ı. M˚uˇzeme v souˇcasn´e verzi implemen-tace konzoly naj´ıt chyby, napˇr. ˇspatn´a pr´ace s vyznaˇcen´ym blokem myˇs´ı.
Pˇri implementaci opravy pro pr´aci s vyznaˇcen´ym blokem myˇs´ı byly pouˇzity jednoduch´e konstrukce programovac´ıho jazyka C. Implementace opravy funguje, avˇsak v nˇekter´ych situac´ıch selh´av´a. Nebyly poˇr´ad promyˇsleny vˇsechny sc´en´aˇre, ke kter´ym by mohlo doj´ıt pˇri pr´aci na konzoly. D´ıky testov´an´ı byly odhaleny slabiny implementace opravy.
Bˇehem implementace opravy se objevily r˚uzn´e probl´emy, napˇr. pˇreklepy v k´odu, kdy nebylo snadn´e odhalit proˇc funkce nepracuje, jakby se od n´ı oˇcek´avalo a d´av´a nesmysln´e v´ysledky.
Dodatek A
Skript
Zde uv´ad´ım testovac´ı skript, kter´y byl pouˇzit pˇri testov´an´ı ESC sekvenc´ı na konzole.
#!/usr/local/bin/bash #nabidka printf ’1) Scroll up 2) Scroll down 3) Reset 4) Move cursor up 5) Up n rows 6) Down n rows 7) Right n columns 8) Left n columns 9) Cursor n lines down a) Cursor n lines up b) Cursor move
c) Cursor move
d) Clear all or part of display e) Clear all or part of line f) Insert n lines
g) Delete n lines h) Delete n chars i) Insert n chars
j) Erase n chraters in line k) Move n tabs to backwards l) Move cursor to column n
m) Move cursor to n columns to the right n) Move cursor to row n
o) Move cursor n rows down p) Switch to virtual console n’ read Volba #nacti volbu
# zaplneni obrazovky tput clear
for i in 0 1 2 3 4 5 6 7 8 9 a b c d e f do for j in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 do printf ’$i’ done printf ’\n’ done
# konec zaplneni obrazovky
tput cm 0 8 # nastav kurzor na tuto pozici read -n1 #cti jakykoliv znak, ne jen ’enter’ #proved zvolenou volbu
case ’$Volba’ in ’1’) # Scroll up printf ’\033[3S’ ;; ’2’) # Scroll down printf ’\033[3T’ ;; ’3’) # Reset printf ’\033c’ ;; ’4’) # Move cursor up printf ’\033M’ ;; ’5’) # Up n rows printf ’\033[3A’ ;; ’6’) # Down n rows printf ’\033[3B’ ;; ’7’) # Right n columns printf ’\033[3C’ ;; ’8’) # Left n columns printf ’\033[3D’ ;;
’9’) # Cursor n lines down printf ’\033[3E’
;;
’a’) # Cursor n lines up printf ’\033[3F’ ;; ’b’) # Cursor move printf ’\033[3f’ ;; ’c’) # Cursor move printf ’\033[3H’
;;
’d’) # Clear all or part of display printf ’\033[J’
;;
’e’) # Clear all or part of line printf ’\033[K’ ;; ’f’) # Insert n lines printf ’\033[3L’ ;; ’g’) # Delete n lines printf ’\033[3M’ ;; ’h’) # Delete n chars printf ’\033[3P’ ;;
’i’) # Insert n chars printf ’\033[3@’ ;;
’j’) # Erase n chraters in line printf ’\033[3X’
;;
’k’) # Move n tabs to backwards printf ’\033[3Z’
;;
’l’) # Move cursor to column n printf ’\033[4’’
;;
’m’) # Move cursor to n columns to the right printf ’\033[3a’
;;
’n’) # Move cursor to row n printf ’\033[3d’
;;
’o’) # Move cursor n rows down printf ’\033[3e’
;;
’p’) # Switch to virtual console n printf ’\033[3z’
;; esac read Q exit 0
Literatura
[1] George V. Neville-Neil Marshall Kirk McKusick. Design and Implementation of the FreeBSD Operating System. Addison-Wesley Publishing Company, 2004.
ISBN 0-201-70245-2.
[2] WWW str´anky. Freebsd handbook.