Ostatnio, szwendając się po kolporterze, natrafiłem na kilka pozycji tego autora, obok Serii Patroli Siergieja Łukianienki, która przypadła mi do gustu, toteż postanowiłem spróbować i zakupiłem książkę pt. "Strefa Sprawiedliwości" ("Зона справедливости") i przeczytałem. Tekst ten piszę ze względu na to, że w polskim internecie w zasadzie nie widziałem żadnych opinii na temat książek tego autora.
Strefa sprawiedliwości jest książką, której najbliżej jest do fantastyki, aczkolwiek jednocześnie bardzo ciężko zaliczyć ją do tego gatunku, gdyż jedynym elementem fantastycznym są niewyjaśnione wydarzenia, które są właściwie tłem dla opisywanych wydarzeń. Odnoszę wrażenie, że są one tylko pretekstem do pokazania pewnych cech narodu rosyjskiego.
Powieść opisuje wydarzenia związane z tajemniczą siła która bije każdego kto się znajdzie w owej strefie, zgodnie z tym ile w życiu nagrzeszył. Kilku tylko pieściło, innych porządnie pobiło, innych zmasakrowało. Te niewyjaśnione wydarzenia zaowocowały licznymi teoriami spiskowymi, większym popytem na usługi wszelkiej maści wróżek, licznymi nawróceniami i świetnym tematem dla prasy.
Głównym bohaterem i jednocześnie narratorem jest 45-letni, dość wykształcony Rosjanin, jeden z mieszkańców feralnego domu. Człowiek do bólu uczciwy, nieco zagubiony w ówczesnym społeczeństwie, nie omieszka nas poczęstować licznymi opisami niezbyt chlubnych zjawisk, jakie obserwuje w owym społeczeństwie.
Książka, choć być może bez bardzo wyszukanej fabuły, jest dość ciekawie napisana, miejscami zabawna, bardzo szybko się czyta. Pozycja jak najbardziej godna polecenia.
W przerwach od przygotowywania się do egzaminu z fizyki (a może odwrotnie? :)) gram sobie w DooMa II. Żeby było ciekawiej, gram na "High Violence" (najwyższy poza ździebko niegrywalnym nightmare ;p) i do tego bez mouselooka (tak jest ciekawiej). Ten poziom trudności ma to do siebie, że tak po 7 poziomach jest spory kłopot z amunicją. Pełno jest impów, demonów i co gorsza wszelkiego innego ustrojstwa które nie zostawia amunicji, a mało chaingunierów, a jeszcze mniej kolesi ze śrututówkami. Dlatego tak bardzo doceniłem zdolność dobrego operowania piłą. Jest to chyba najlepszy sposób oszczędzania amunicji (przede wszystkim od shotguna, który jednak jest najczęściej stosowaną przeze mnie bronią), zaraz po wykorzystywaniu agresji potworów (jako zagorzały pacyfista, jeśli mogę, lubię napuścić stwory na siebie, żeby sobie powalczyły między sobą ;p) i zaraz przed BFG9000 (o taak :)) i wyrzutnią rakiet, które jednak mają ten feler, że też wymagają amunicji. ;p
Co ciekawe, przy odrobinie wprawy można zdziałać naprawdę dużo zdziałać samą piłą. Nawet pomijając te najsłabsze potwory, które od razu się rozlatują. Gdy bawimy się z demonami (tymi różowymi i niewidzialnymi), a w około nie ma strzelców, zwykle można sobie poradzić samą piłą. Zwłaszcza przy jednoosobowym korytarzu (wówczas jest to właściwie kopanie leżącego), ale i na otwartych przestrzeniach można tak się zakręcić, żeby po kolei delikwentów wyrżnąć. Kłopot jest tylko jak cię przyprą do ściany, wtedy lepiej użyć BFG. :)
Jednakże zabijanie demonów piłą jest niezbyt wielkim wyzwaniem. Dużo ciekawiej wygląda walka z trochę silniejszymi przeciwnikami. Na ataki obłąkanego drwala są narażone przede wszystkim "głowy". Te czerwone z bazooką w gardle są chyba najłatwiejsze. Wystarczy się wbić. Problem się zaczyna gdy jest ich więcej, ale na szczęście dalsze etapy są bardzo przestronne i można je wybijać po kolei. Trochę cięższe są te co miotają małymi głowami, o których za chwilę. W tym przypadku trzeba dodatkowo zadbać o to, żeby nie zdążyła za dużo tych "łebków" naprodukować. Wbrew pozorom najbardziej upierdliwe są te małe łebki, bo tu nie wystarczy na chama wciskać "spust". Zwykle należy się uchylić i wbić się w potylicę. Biorąc pod uwagę, że pojawiają się one często hurtem, wolę już zmarnować trochę obrotówki, albo shotguna.
Co ciekawe piłą można nawet załatwić szkieletory (te wysokie z bazooką). W tym przypadku niemal konieczne jest zajście od tyłu lub od boku (chyba że się ma god mode), ale jak już się nauczysz czaić za rogiem będą twoje. Trzeba tylko uważać, bo czasami mogą uderzyć (nie wiem kiedy ale już udaje mi się temu zapobiegać) co jest trochę bolesne.
Jako ciekawostkę dodam, że da się też zaciukać piłą (parę razy mi się udało, ale jeszcze nie znam przepisu na sukces) te opasłe pokemony z z dwoma wyrzutniami rakiet zamiast dłoni i powtarzają coś na kształt "onimaru". tu oczywiście też trzeba się zaczaić, ale to niestety nie wystarcza. Boję się, że udawało mi się tylko dzięki jakiemuś ciekawemu bugowi.
W sumie taka gra w DooMa z ciągłym brakiem amunicji wymaga nie lada zdolności strategicznych. To spotkać dwie grupy potworów ze sobą. To się zaczaić, to ominąć. Bardzo fajna sprawa. :)
Nie mogę uwierzyć, że tak się rozpisałem i w końcu wyszedł tutoriial na temat oszczędzania amunicji w DooMie. Może następnym razem przejdę obie części samą piłą? :)
http://www.doomworld.com/classicdoom/info/music.php?wad=doom2.wad . Wspaniała sprawa. Trochę upierdliwy format, więc trzeba spędzić chwilkę na konwersję i otagowanie, ale myślę, że warto. :)
Jakiś czas temu zaprezentowałem mój pierwszy skrypt PHP, przygoda z tym językiem szybko się zakończyła. Przyszedł czas na perla – aż wstyd się przyznać, że dopiero teraz. Tak czy inaczej, po dość oględnym przestudiowaniu języka przyszedł czas na chrzest bojowy - napisanie skryptu, który generowałby menu na podstawie /usr/share/applications/. Być może jest już coś takiego, ale jak wszystkim dobrze wiadomo, jestem bardzo leniwy. Zadanie może nie wydające się być trudnym (choć pisanie w tego C to niezbyt kusząca perspektywa), aczkolwiek dobrze zweryfikowało to co zrozumiałem z kursu.
Zacznijmy od tego, jak ten skrypt działa. Mianowicie, parsuje on plik z szablonem (~/.fluxbox/menu.templ) i pliki *.desktop z /usr/share/applications/ i na podstawie informacji w nich zawartych buduje menu. Skrypt nie jest jeszcze doskonały i będzie wymagał dość radykalnego przerobienia, tak by elementy mogły być sortowane alfabetycznie i obsługiwały lokalizacje. Niemniej jednak działa i dość dobrze i szybko (w moim przypadku 0,03s) wypełnia swoje zadanie.
Pliki szablonowe mają bardzo prostą budowę – są to zwyczajne pliki menu fluxboksa, wzbogacone o wtrącenia w nawiasach ostrych (muszą być w oddzielnych linijkach), informujących program, jak interpretować /usr/share/applications/. Mój plik szablonu wygląda następująco i wyczerpuje opcje, które można póki co wtrącić:
<setterm urxvt -font -*-fixed-medium-r-*-*-20-*-*-*-*-*-*-2 -fg white -bg black>
<show-groups Network,Utility,AudioVideo,Game,Application,Office,Graphics,Science,System>
[begin] (Fluxbox)
[encoding] {UTF-8}
[exec] (uruchom) {fbrun}
<addterm terminal>
[exec] (WWW) {seamonkey}
[exec] (e-mail) {seamonkey --mail}
[exec] (vim) {gvim}
<insert-here>
[exec] (uaktualnij menu) {/home/bartek/fluxmenugen.pl}
[restart]
[exit]jak widać, nie jest tego dużo:
Na sam koniec natomiast gotowy skrypt, który udostępniam do dowlonego użytku.
#! /usr/bin/perl -w
$sdir = "/usr/share/applications";
$sext = ".desktop";
$favterm = "urxvt";
$destdir = $ENV{'HOME'}."/.fluxbox/";
open (TEMPLATE, $destdir."menu.templ") || die "Failed to open template file.";
if(open (DESTINATION, $destdir."menu"))
{
open (BACKUP, ">".$destdir."menu~");
while ( <DESTINATION> )
{
print BACKUP;
}
close (BACKUP);
}
close ( DESTINATION );
open (DESTINATION, ">".$destdir."menu");
opendir ( SHORTCUTS, $sdir ) || die ("failed to open $sdir.");
@shortcuts = grep { m/$sext$/ } readdir ( SHORTCUTS );
closedir ( SHORTCUTS );
%groups = ();
$ungrupped = "";
foreach $shortcut ( @shortcuts )
{
open ( SHORTCUT, $sdir."/".$shortcut);
while ( <SHORTCUT> )
{
if ( m/^Name=(.+)(\s*)$/ )
{
$name = $1;
}
elsif ( m/^Exec=(.+)(\s*)$/ )
{
$cmd = $1;
}
elsif ( m/^Terminal=(.+)(\s*)$/ )
{
$term = $1;
}
elsif ( m/^Categories=(.+)(\s*)$/ )
{
@cats = split ( /;/, $1 );
}
}
if ( !defined ( $name ) || !defined ( $cmd ) )
{
print "Failed to find essentional values for $shortcut\n";
}
else
{
if ( defined ( $term ) && $term eq "true" )
{
$cmd = $favterm." -e \"".$cmd."\"";
}
$stext = "[exec] ($name) {$cmd}\n";
if ( !defined ( @cats ) )
{
$ungrupped .= $stext;
}
else
{
foreach $cat ( @cats )
{
$groups{$cat} .= $stext;
}
}
}
}
while ( <TEMPLATE> )
{
if ( @tags = m/<(.+)>/g )
{
foreach $tag (@tags)
{
if ( $tag eq "insert-here" )
{
if ( defined ( @tagWhitelist ) )
{
foreach $group ( @tagWhitelist )
{
print DESTINATION "[submenu] ($group)\n";
print DESTINATION $groups{$group};
print DESTINATION "[end]\n"
}
}
else
{
foreach $group ( keys %groups )
{
print DESTINATION "[submenu] ($group)\n";
print DESTINATION $groups{$group};
print DESTINATION "[end]\n"
}
}
print DESTINATION $ungrupped;
}
elsif ( $tag =~ /^setterm (.+)/ )
{
$favterm = $1;
}
elsif ( $tag =~ /^addterm (.+)/ )
{
print DESTINATION "[exec] ($1) {$favterm}\n";
}
elsif ( $tag =~ /^show-groups (.+)$/ )
{
if ( defined ( @tagWhitelist ) )
{
push ( @tagWhitelist, split ( /,/, $1 ) );
}
else
{
@tagWhitelist = split ( /,/, $1 );
}
}
elsif ( $tag =~ /^show-all/ )
{
undef ( @tagWhitelist );
}
}
}
else
{
print DESTINATION;
}
}
Filmik mnie po prostu rozwalił. Zapewne, dla wielu nic nowego, bo filmik jest dość popularny na youtube, ale i tak zamieszczam: http://www.youtube.com/watch?v=U0kJHQpvgB8.
Programuję już od kilku lat, ale jakoś się złożyło, że nie pisałem jeszcze aplikacji opartych o HTTP. Postanowiłem to zmienić i odejść na trochę od programowania w Rubim(zdaję sobie sprawę, że istnieje RoR, lecz chciałem zacząć od czegoś klasycznego i chyba jednak trochę łatwiejszego, jak PHP. Dlatego też postawiłem sobie serwer Apache(swoją drogą też bardzo przydatne doświadczenie) i zacząłem próbować.
Szybko też znalazł się problem, którego rozwiązanie przez prostą aplikację PHP wydawało się całkiem rozsądne. Mianowicie w domu mam dwa komputery(jeden mój i jeden brata) i tylko jedną drukarkę. W prawdzie mógłbym udostępnić serwer CUPS, ale po pierwsze brat musiałby instalować sterowniki do drukarki(tak przynajmniej mi się wydaje ;p), a ponadto zdarza mu się używać (sic!) Windows, co jeszcze bardziej komplikuje sprawę.
Oczywiście móglibyśmy użyć Samby, ale jesteśmy zbyt leniwi, żeby konfigurować Sambę na obu komputerach tylko po to, żeby od czasu do czasu coś wydrukować. Dlatego stanęło na wysyłaniu plików do druku pocztą. To upierdliwa sprawa, stąd ten skrypt(może się komuś przyda :)):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="pl">
<head>
<title>Stronka!</title>
<META http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<?php
$uf = $_FILES['upfile'];
if(isset($uf['name']))
{
if('php' == ($wynik = substr($uf['name'],-3,3)))
{
echo '<p>Wybacz, nie odbieram plików PHP</p>';
}
else
{
rename($uf['tmp_name'], 'udload/'.$uf['name']);
}
}
if(isset($_GET['delete']))
{
unlink('udload/'.$_GET['delete']);
echo '<p>Usunięto plik "'.$_GET['delete'].'"!</p>';
}
echo '<p>Cześć! Dzięki tej stronie możesz wysyłać mi dowolne pliki,
ściągać te, które Ci udostępniam, a także wysyłać pliki do drukowania przez
moją drukarkę.</p>';
if(isset($_GET['print']))
{
if('.ps' !== ($wynik = substr($_GET['print'],-3,3)) &&
! isset($_GET['sure']))
{
echo 'Wybrany plik ma rozszerzenie inne niż *.ps. Jeśli jesteś
pewien, że zawiera dane PostScript,
<a href="index.php?print='.$_GET['print'].'&sure=1">kliknij tutaj</a>';
}
else
{
$out = array();
$ret = 0;
exec('lp /srv/http/udload/'.$_GET['print'], $out, $ret);
if($ret == 0)
{
echo '<p>Drukowanie powiodło się.</p>';
}
else
{
echo '<p>Drukowanie nie powiodło się. Zawartość stdout:
<br/>'.$out.'</p>';
}
}
}
$cdir = dir('udload');
if($cdir !== false)
{
$n = 0;
while(false !== ($file = $cdir->read()))
{
if($file != '.' && $file != '..')
{
if($n == 0)
{
echo "<h1>Pliki na serwerze:</h1><p><ol>";
$n = 1;
}
echo '<li><a href="udload/'.$file.'">'.$file.'</a>
<a href="index.php?delete='.$file.'"><sup>[usuń plik]</sup></a>
<a href="index.php?print='.$file.'"><sup>[drukuj plik]</sup></a></li>';
}
}
if($n == 1)
{
echo "</ol></p>";
}
$cdir->close();
echo '<h1>Wyślij plik</h1><p>Możesz wysłać plik o dowolnym
rozszerzeniu, oprócz *php o wielkości nie przekraczjącej 10<sup>6</sup>
bajtów:<br/><form enctype="multipart/form-data" method="post"
action="index.php"><input type="file" name="upfile" value=""/>
<input type="hidden" name="MAX_FILE_SIZE" value="1000000"/><br/>
<input type="submit" name="send"/></form>';
}
?>
</body>
</html>
Jakie wrażenia z zabaw PHP? Zdecydowanie przechodzę do RoRa, zwłaszcza po obejrzeniu filmów, które można zobaczyć na stronie projektu.
Zapewne większość miłośników edytorów tekstów takich jak Vim, czy emacs, a także wyznawcy wyższości CLI nad GUI, przyzna, że klawiatura jest znacznie szybsza, a jeśli się człowiek przyzwyczai, wygodniejsza od myszki. Ciężko jednak wyeliminować z środowiska graficznego użycie myszy. Nic bardziej mylnego, mając odpowiednie narzędzia można bez problemu używać Xów bez myszki, ani jej emulacji. Pomijając kilka dziedzin, w których raczej myszkę ciężko zastąpić(u mnie chyba tylko edytor grafiki, GIMP). W tym artykule przedstawię zarządcę okien sterowanego klawiaturą - awesome.
Już bardzo dawno mysz zadomowiła się w systemach biurkowych. Nic dziwnego, przesuwanie okien "chwytając" je kursorem myszy i wciskanie nim przycisków jest bardzo intuicyjne. Być może gdyby nie wymyślono myszy, komputery nie byłby tak powszechne. Istnieje jednak pewna grupa ludzi myśli w trochę innych kategoriach. Owocem takiego myślenia jest pomysł na zarządzanie oknami bez użycia myszy.
Pierwszą, rzeczą jaka przychodzi na myśl(przynajmniej mi przyszła;)), słysząc o zarządcy okien sterowanym klawiaturą, to "Jak to, do cholery, możliwe?". Rozwiązanie jest bardzo proste. Wystarczy, że rozmieszczeniem i zmianą rozmiarów okien zajmie się program, pozostałe rzeczy można zrobić klawiaturą, nawet w "klasycznych" środowiskach. W praktykce wygląda to mniej więcej tak:

Wbrew pozorom istnieje dość sporo takich programów: ratpoison, Ion, wmii, dwm, awesome. W tym tekście skupię się na tym ostatnim. Myślę, że każdy sobie poradzi z instalacją tego programu(jeśli nie ma go w repo twojej dystrybucji :poszukaj na freshmeat), więc przejdę od razu do rzeczy.
Podobnie jak w przypadku większości programów open source, kluczem do sukcesu jest dobra konfiguracja, którą przeprowadzamy poprzez edycję pliku ~/.awesomerc . Jego struktura jest dość prosta i można bardzo łatwo ją zrozumieć, próbując przy niej majstrować i posiłkować się manem. Jednakże, aby ułatwić Ci sprawę, przedstawię mój plik konfiguracyjny awesome i pokrótce wyjaśnię, o co chodzi. Nie będę się wdawał w zbędne szczegóły, bo o co chodzi, każdy widzi. Chyba jedyny szczegół, jaki wypada nadmienić to występujący klawisz Mod4. Jego definicja jest kwestią konfiguracji X11, w najpopularniejszych u nas klawiaturach Microsoft będzie to logo Windows. Swoją drogą, bardzo fajnie, że znajduje on wreszcie jakieś logiczne zastosowanie. :)
Mój plik konfiguracyjny składa się z trzech sekcji(jest ich więcej, jednakże nie odczułem potrzeby zgłębiania ich zastosowania :)). Pierwszą z nich jest sekcja screen:
screen 0
{
styles
{
normal
{
font = "sans 8"
fg = "#dddddd"
bg = "#444444"
border = "#555555"
}
focus
{
fg = "#000000"
bg = "#535d6c"
border = "#535d6c"
}
urgent
{
fg = "#111111"
bg = "#ff4500"
}
}
tags
{
tag one { }
tag two { }
tag three { }
tag four { }
tag five { }
tag six { }
tag seven { }
tag eight { }
tag nine { }
}
layouts
{
# layout tile { image = "/usr/share/awesome/icons/layouts/tilew.png" }
# layout tileleft { image = "/usr/share/awesome/icons/layouts/tileleftw.png" }
layout tilebottom { image = "/usr/share/awesome/icons/layouts/tilebottomw.png" }
# layout tiletop { image = "/usr/share/awesome/icons/layouts/tiletopw.png" }
# layout max { image = "/usr/share/awesome/icons/layouts/maxw.png" }
# layout spiral { image = "/usr/share/awesome/icons/layouts/spiralw.png" }
# layout dwindle { image = "/usr/share/awesome/icons/layouts/dwindlew.png" }
# layout floating { image = "/usr/share/awesome/icons/layouts/floatingw.png" }
}
statusbar mystatusbar
{
position = "top"
taglist mytaglist
{
mouse
{
button = "1"
command = "tag_view"
}
mouse
{
button = "1"
modkey = {"Mod4"}
command = "client_tag"
}
mouse
{
button = "3"
command = "tag_toggleview"
}
mouse
{
button = "3"
modkey = {"Mod4"}
command = "client_toggletag"
}
mouse
{
button = "4"
command = "tag_viewnext"
}
mouse
{
button = "5"
command = "tag_viewprev"
}
}
layoutinfo mylayoutinfo
{
mouse
{
button = "1"
command = "tag_setlayout"
arg = "+1"
}
mouse
{
button = "4"
command = "tag_setlayout"
arg = "+1"
}
mouse
{
button = "3"
command = "tag_setlayout"
arg = "-1"
}
mouse
{
button = "5"
command = "tag_setlayout"
arg = "-1"
}
}
tasklist mytasklist{}
iconbox logo
{
image = "/usr/share/awesome/icons/awesome16.png"
mouse
{
button = "1"
command = "spawn"
arg = "exec xterm -e man awesome"
}
}
}
Na samym początku mamy podsekcję styles, zostawiłem wartości domyślne. Dalej mamy podsekcję "tags". Zawiera ona listę tagów, czyli po prostu pulpitów.
Dalej, w kolejności jest podsekcja layouts. Opisuje ona sposoby rozmieszczania okien. Jak można zauważyć, owe sposoby definiuje się poprzez utworzenie odpowiedniego obrazka. Można również je przełączać(standardowo Mod4 + spacja), jednakże zakomentowałem wszystkie oprócz jednego, moim zdaniem najwygodniejszego układu, w którym główne okno(względnie okna) znajduje się u góry, a pozostałe, mniejsze są rozmieszczane poniżej. Szczerze powiedziawszy jest to nawet lepsze od tacki systemowej, bo nie zajmuje wiele miejsca, a za to przekazuje więcej informacji.
Dalej mamy sekcję "statusbar", dotyczącą cosia, w innych środowiskach zwanego panelem. Pozostawiłem wartości domyślne, bo w zasadzie nic poza listą tagów, listą layoutów i listą okien, nie jest mi na tyle potrzebne, żeby chciało mi się wystarczająco zagłębić w dokumentacji. :) Nie mam więc zegarka, jest to trochę problematyczne, ale rozwiązałem to uruchamiając na starcie xclocka, tak żeby pokazywał godzinę i datę w prawym-dolnym rogu. Dla mniej zaznajomionych w użyciu tego programu podaję wiersz polecenia dla cyfrowego zegara w formacie "dzień tygodnia, dzień.miesiąc.rok(2 cyfry) godzina:minuty", dla rozdzielczości 1280x1024:
xclock -geometry 170x30+1110+994 -d -twentyfour -strftime "%a,%d.%m.%y %H:%M"
Dalej mamy sekcję rules. Dotyczy ona wyjątkowych właściwości dla niektórych programów. W moim przypadku ogranicza się do wskazania, które okna mają "pływać", czyli nie podlegać layoutowi:
rules
{
rule { name = "Gimp" float = true }
rule { name = "MPlayer" float = true }
rule { name = "Acroread" float = true }
rule { name = "pinentry" float = true }
rule { name = "xclock" float = true }
}
Ostatnią i chyba najważniejszą sekcją, jest sekcja keys, definiująca skróty klawiszowe:
keys
{
key
{
modkey = {"Mod4"}
key = "F1"
command = "spawn"
arg = "exec xfrun4"
}
key
{
modkey = {"Mod4"}
key = "F2"
command = "spawn"
arg = "ls .menu-items | awesome-menu -e \"exec ~/.menu-items/\""
}
key
{
modkey = {"Mod4"}
key = "F3"
command = "spawn"
arg = "mpc toggle"
}
key
{
modkey = {"Mod4"}
key = "F4"
command = "spawn"
arg = "exec xterm -e \"mpc&&sleep 2\""
}
key
{
modkey = {"Mod4"}
key = "F5"
command = "spawn"
arg = "exec ario"
}
key
{
modkey = {"Mod4"}
key = "Return"
command = "spawn"
arg = "exec ~/.menu-items/Terminal"
}
key
{
modkey = {"Mod4"}
key = "space"
command = "tag_setlayout"
arg = "+1"
}
key
{
modkey = {"Mod4", "Shift"}
key = "space"
command = "tag_setlayout"
arg = "-1"
}
key
{
modkey = {"Mod4"}
key = "b"
command = "statusbar_toggle"
}
key
{
modkey = {"Mod4"}
key = "Right"
command = "client_focusnext"
}
key
{
modkey = {"Mod4"}
key = "Left"
command = "client_focusprev"
}
key
{
modkey = {"Mod4", "Shift"}
key = "Right"
command = "client_swapnext"
}
key
{
modkey = {"Mod4", "Shift"}
key = "Left"
command = "client_swapprev"
}
key
{
modkey = {"Mod4"}
key = "p"
command = "tag_setmwfact"
arg = "-0.05"
}
key
{
modkey = {"Mod4"}
key = "o"
command = "tag_setmwfact"
arg = "+0.05"
}
key
{
modkey = {"Mod4", "Control"}
key = "p"
command = "tag_setncol"
arg = "+1"
}
key
{
modkey = {"Mod4", "Control"}
key = "o"
command = "tag_setncol"
arg = "-1"
}
key
{
modkey = {"Mod4"}
key = "z"
command = "tag_viewprev"
}
key
{
modkey = {"Mod4"}
key = "x"
command = "tag_viewnext"
}
key
{
modkey = {"Mod4"}
key = "m"
command = "client_togglemax"
}
key
{
modkey = {"Mod4", "Control"}
key = "Return"
command = "client_zoom"
}
key
{
modkey = {"Mod4", "Control"}
key = "space"
command = "client_togglefloating"
}
key
{
modkey = {"Mod4", "Control"}
key = "c"
command = "client_kill"
}
key
{
modkey = {"Mod4", "Control"}
key = "q"
command = "quit"
}
key
{
modkey = {"Mod4", "Control"}
key = "r"
command = "restart"
}
key
{
modkey = {"Mod4"}
key = "0"
command = "tag_view"
}
keylist
{
modkey = {"Mod4"}
command = "tag_view"
keylist = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }
arglist = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }
}
keylist
{
modkey = {"Mod4", "Shift"}
command = "client_tag"
keylist = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }
arglist = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }
}
keylist
{
modkey = {"Mod4", "Control"}
command = "client_toggletag"
keylist = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }
arglist = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }
}
}
Myślę, że nie trudno zrozumieć zapis. Jedynie komendy mogą być nieco nie jasne, dlatego wyjaśnię kolejne skróty:
To wszystko, taki stan rzeczy mnie w pełni satysfakcjonuje i sprawia, że niechętnie sięgam po gryzonia, w związku z czym programy też obsługuję klawiaturą, co z kolei sprawia, że pracuje się szybciej. W przyszłości być może będę drążył ten temat. :)
Ostatnio sporo eksperymentowałem z różnymi środowiskami - najpierw GNOME, a potem ciut za ciężkie na mój sprzęt(Athlon XP 1700+, 512MB RAM) KDE4, którego jedyną zaletą, moim skromnym zdaniem , jest Amarok. Trochę się poinstalowało śmiecia, więc stwierdziłem, że to dobry moment, żeby spróbować czegoś nowego. Postanowiłem wybrać Zenwalka. Przede wszystkim, że bazuje na slackware i korzysta z niesprawdzonego jeszcze przeze mnie XFCE, ale też hasło "Ever tried zen computing?" nie pozostało bez znaczenia. :)
Na początek instalacja. Tu nie ma się zbytnio nad czym rozpisywać. Instalator jak instalator. Tekstowy, a jednak w ładnej oprawie(framebuffer jak sądzę). Na tym etapie zdziwił mnie fakt iż system ten, podobnie jak poprzednio przeze mnie używany Arch, traktuje wszystkie dyski jako SCSI, co objawia się się nietypowymi nazwami urządzeń(/dev/sdxn i /dev/srn). Dalej jedyną ciekawostką jest ciekawie pomyślana konfiguracja LILO, przypominająca nieco tą z PLD, ale ta jednak jest trochę bardziej rozbudowana.
Potem przyszedł czas na pierwsze bootowanie. Co ciekawe na samym wstępie poczęstował mnie porcją kilku licencji do zaakceptowania(GNU/GPL, Adobe, Intel), a następnie uruchomił alsaconf i całkiem fajny, stworzony w ncurses menedżer użytkowników. Dalej już standard - gdm.
Całkiem ładny wygląd XFCE. Po małym przekonfigurowaniu, bardzo mi odpowiada.
W oczy też się rzuca bardzo dobra szybkość(mniej więcej na równi z Archem). W standardowym zestawie programów niestety nie ma kilku ważnych programów, więc zacząłem od netpkg, menedżera pakietów Zenwalka, a właściwie jego graficznej nakładki. Program wcale przyzwoity, prosty do bólu, nic dodać nic ująć. Szybko wyszukałem seamonkeya(niestety bez polskiej lokalizacji, którą trzeba było doinstalować w klasyczny sposób), następnie mpd, mpc i z braku gmpc, ario, którego wcześniej nie znałem(a szkoda). Mpdscribble niestety musiałem zainstalować ze źródeł, jak również samodzielnie musiałem napisać skrypt startowy dla mpd/mpdscribble, a takze konfigurację. W gruncie rzeczy nic trudnego. Gdy z głośników zaczęła się sączyć muzyka mogłem przejść do konfiguracji. Najpierw XFCE. Wszystko w porządku, tylko szkoda, że nie ma edytora motywów dla GTK. No nic, nauczę się je pisać przynajmniej. :)
Dalej zaskoczył mnie zestaw konfiguratorów zenwalka. Całkiem przyjemnie się ich używa. Szkoda, że kosztem braku /etc/rc.conf. Nie można mieć wszystkiego.
Następnie przyszedł czas na sterowniki NVIDIA. Tu pozytywne zaskoczenie, bo są źródła kernela (Archu jakoś nie mogłem ich znaleźć).
Podsumowując, Zenwalk to bardzo przyjemna, szybka dystrybucja, jak najbardziej pasująca do swojego motta. Większość konfiguracji da się załatwić konfiguratorami(oprócz mpd, cupsa, konfigurowanego przez przeglądarkę; sane, sudo i nvidia). Bardzo duży plus za menedżer pakietów. W jednym zdaniu, jeśli lubisz XFCE, chcesz szybkiego i prostego, a przy okazji całkiem łatwego, systemu to Zenwalk jest zdecydowanie dobrym pomysłem.
Nagrywanie systemów plików złożonych z dużej ilości katalogów przy użyciu growisofs jest nieco kłopotliwe, bo jest dużo pisania, głównie przez ustawianie graft pointów. GNOME baker natomiast nie oferuje mi zbyt wielkiego pola do popisu, jeśli chodzi o konfigurację (jestem ślepy, czy naprawdę nie można wybrać, czy użyć Jolieta czy Rock Ridge?). Dlatego też, powodowany wrodzonym lenistwem, postanowiłem coś z tym zrobić.
Mianowicie napisałem prosty skrypt, który za nas załatwi graft pointy, a nawet sprawdzi, czy należy użyć opcji -Z czy -M. Powodowany wspomnianym lenistwem zmiana opcji odbywa się poprzez edycję skryptu (w przedstawionej wersji instaluje tylko rock-ridge). Składnia natomiast jest prosta. W argumentach wpisujemy nazwy katalogów(można spokojnie używać gwiazdki). Natomiast parametry "-f" i "-d" odpowiednio informują program, czy dane dalej parametry oznaczają pliki, czy katalogi(domyślnie katalogi). Jeśli podamy nazwę katalogu wśród plików, zostanie nagrana jego zawartość. Po wprowadzeniu polecenia program wydrukuje linię poleceń i poprosi o zatwierdzenie. Skrypt wymaga growisofsa i cdrdao, jest napisany dla archa (więc może być konieczność zmiany /dev/sr0 na odpowiednią dla twojego systemu ścieżkę). Kto chce, niech bierze:
#! /bin/bash
if [ -n "$1" ]
then
echo Burner, enter with names of wanted directories to burn on /dev/sr0 with rock-ridge, and with no joliet
else
isempty=`cdrdao disk-info --device /dev/sr0 | grep "CD-R empty" | grep "no"`
if [ "$isempty" == "" ]
then
echo -n "growisofs -Z=/dev/sr0 -R --graft-points " > .burnertmp
else
echo -n "growisofs -M=/dev/sr0 -R --graft-points " > .burnertmp
fi
isfile=0
for x in "$@"
do
case $x in
"-f") isfile=1 ;;
"-d") isfile=0 ;;
*) if [ "$isfile" == 1 ]
then
echo -n "\"`echo $x`\" " >> .burnertmp
else
echo -n "\"`echo $x`\"=\"`echo $x`\" " >> .burnertmp
fi ;;
esac
done
cat .burnertmp
echo
echo "Is that ok? If so press ENTER, CTRL+C to cancel"
read
chmod +x .burnertmp
./.burnertmp
rm .burnertmp
fi