Jan
29
2007
16

Overdrive/1

Un recap sui progetti a cui sto lavorando al momento.

<h4>Clutter</h4>

Nei commenti al <a href="http://www.emmanuelebassi.net/archives/2007/01/the-body-says-no/">blog precendente</a> mi si chiedeva di Clutter. Per chi non seguisse Planet GNOME (o per chi lo seguisse ma non avesse comunque la più pallida idea di cosa si tratti), <a href="http://www.clutter-project.org">Clutter</a> è un toolkit che ho contribuito a realizzare più o meno da quando sono stato assunto alla OpenedHand (settimana più, settimana meno).

Clutter è un toolkit basato sulle stesse librerie usate per le GTK+ (GLib, GObject, Pango) ideato per scrivere applicazioni con un’interfaccia grafica mono-finestra – ad esempio: media box, personal video recorder, etc. – in ambienti (<em>embedded</em> e non) dotati di grafica accelerata (tramite <a href="http://en.wikipedia.org/wiki/OpenGL">OpenGL</a> oppure <a href="http://en.wikipedia.org/wiki/OpenGL_ES">OpenGL ES</a>). Clutter fornisce un <em>canvas</em>, rappresentato dal <em>singleton</em> <code>ClutterStage</code>, e alcuni <em>widget</em>, chiamati <code>ClutterActor</code>. I widget forniti sono (volutamente, al momento) pochi: non solo perché siamo alla release 0.2.0, ma soprattutto perché vogliamo vedere di cosa necessitano gli sviluppatori prima di implementare <code>ClutterActor</code> nel modo sbagliato o del tutto inutili.

<strong>Hello, World</strong> – Come funziona Clutter? Ecco un semplice <a href="http://devel.emmanuelebassi.net/software/hello-clutter.py">"hello, world"</a> che sfrutta buona parte delle nuove API. È scritto in Python – avrei preferito scriverlo in Perl, ma conoscendo la quantità di pythonisti in "ascolto" ho scelto altrimenti; la versione in Perl è disponibile a richiesta. Se volete, potete scaricarla e farci quello che volete – è nel <em>public domain</em>, come dovrebbero essere tutti gli "hello world" di questo mondo. Se cliccate dopo il link, smonto il codice in blocchi per spiegare come funziona.

<!–more–>

<pre>
<span style="color:purple">import</span> sys
<span style="color:purple">import</span> clutter
</pre>

Si parte importando i moduli, ovviamente. Il modulo <code>clutter</code> è fornito da <a href="http://www.clutter-project.org/sources/pyclutter/0.2/">pyclutter</a> e supporta tutta la <em>core library</em>; non appena riuscirò ad avere un po’ di tempo, e a domare le interazioni tra Python, GObject e GStreamer, pyclutter fornirà anche i binding per le estensioni multimediali disponibili (al momento) in C.

<pre>
<span style="color:orange">class</span> <span style="color:blue">HelloClutter</span>:
<span style="color:orange">def</span> <span style="color:blue">__init__</span> (self, message):
self.stage = clutter.stage_get_default()
self.stage.set_color(clutter.color_parse(<span style="color:red">’DarkSlateGrey’</span>))
self.stage.set_size(800, 600)
self.stage.connect(<span style="color:red">’key-press-event’</span>, clutter.main_quit)
self.stage.connect(<span style="color:red">’button-press-event’</span>,
self.on_button_press_event)
</pre>

Semplice classe per la nostra applicazione; inizializziamo tutto quando e cominciamo a creare lo <em>stage</em> principale su cui aggiungeremo i vari attori. Diamo una mano di "DarkSlateGrey" al palco, lo allarghiamo a 800 pixel per 600 e colleghiamo i due eventi che ci interessano: pressione di un tasto (a cui associamo l’uscita dal programma) e pressione di un pulsante del mouse (a cui associamo il metodo <code>on_button_press_event</code>).

<pre>
color = clutter.Color(0xff, 0xcc, 0xcc, 0xdd)
</pre>

Creiamo un colore, dandogli i valori dei quattro canali (rosso, verde, blu e alpha per l’opacità). Questo è uno dei vari modi che Clutter mette a disposizione per creare un colore. In alternativa, si può usare una stringa di testo (come sopra) che, però, non cambierà il valore dell’opacità di default; si può usare un intero senza segno da 32 bit (packed) come <code>0xffccccdd</code>; si può usare una conversione di <em>colorspace</em> da <acronym title="Hue Luminance Saturation">HLS</acronym> a <acronym title="Red, Green, Blue">RGB</acronym>.

<pre>
self.label = clutter.Label()
self.label.set_font_name(<span style="color:red">’Mono 32′</span>)
self.label.set_text(message)
self.label.set_color(color)
(label_width, label_height) = self.label.get_size()
label_x = self.stage.get_width() – label_width – 50
label_y = self.stage.get_height() – label_height
self.label.set_position(label_x, label_y)
self.stage.add(self.label)
</pre>

Dopo il palco, creiamo il primo attore: una semplice etichetta di testo. Decidiamo il font e il contenuto e posizioniamo l’attore a cinquanta pixel dall’estremo in basso a destra dello <em>stage</em>. Le dimensioni dell’etichetta vengono ricalcolate quando impostiamo il font e il testo, così da garantirci sempre dei valori aggiornati. Usando Pango, abbiamo gratis il supporto per l’internazionalizzazione delle stringhe, dei glifi, dei paragrafi, dell’ellissi dei testi, degli spazi e delle legature.

<pre>
self.cursor = clutter.Rectangle()
self.cursor.set_color(color)
self.cursor.set_size(20, label_height)
cursor_x = self.stage.get_width() – 50
cursor_y = self.stage.get_height() – label_height
self.cursor.set_position(cursor_x, cursor_y)
self.stage.add(self.cursor)
</pre>

Altro attore: il "cursore" alto quanto l’etichetta di testo, largo venti pixel e posto nell’estremo in basso a destra del nostro <em>stage</em>. Ora non ci resta che animarlo, facendolo lampeggiare.

<pre>
self.timeline = clutter.Timeline(30, 25)
self.timeline.set_loop(True)
alpha = clutter.Alpha(self.timeline, clutter.ramp_func)
self.behaviour = clutter.BehaviourOpacity(alpha, 0xdd, 0)
self.behaviour.apply(self.cursor)
</pre>

Per le animazioni ricorro ai "behaviour", i comportamenti che accennavo all’inizio del post. Per prima cosa, creo una timeline, ovvero una linea che dia il computo del tempo; la voglio di trenta frame, con 25 frame al secondo, e la voglio in <em>loop</em>.

Come seconda cosa, creo un <em>alpha</em>. Un <code>ClutterAlpha</code> è un oggetto che lega una timeline a una funzione; ad ogni "tic" della timeline, invoca la funzione e ottiene un intero senza segno che è dipendente solo dal tempo. In pratica, ingegneristicamente parlando, è un generatore di <a href="http://en.wikipedia.org/wiki/Waveform">forme d’onda</a> (mi rendo conto solo ora, cercandolo, che Wikipedia italiana non ha una pagina sui generatori di forme d’onda; gli ingeneri sono peggio degli idraulici: quando servono non ci sono mai).

Infine, creo un <em>behaviour</em>, ovvero un oggetto che controlla una o più proprietà di un set di attori usando l’oggetto alpha; in questo caso, un <code>ClutterBehaviourOpacity</code> che controlla l’opacità degli attori.

<pre>
<span style="color:orange">def</span> <span style="color:blue">on_button_press_event</span> (self, stage, event):
print <span style="color:red">"mouse button %d pressed at (%d, %d)"</span> % <span style="color:purple">\\</span>
(event.button, event.x, event.y)
</pre>

Questo è il callback del nostro evento, giusto per mostrare come ottenere i vari dettagli dall’oggetto <code>event</code>.

<pre>
<span style="color:orange">def</span> <span style="color:blue">run</span> (self):
self.stage.show_all()
self.timeline.start()
clutter.main()
</pre>

Il metodo <code>run</code> serve a:

<ul>
<li>mostrare tutti gli attori sullo <em>stage</em>;</li>
<li>avviare la timeline;</li>
<li>avviare il main loop;</li>
</ul>

In questo senso, Clutter funziona esattamente come le GTK+: il main loop gira ed esegue il dispatch degli eventi da X all’applicazione.

<pre>
<span style="color:orange">def</span> <span style="color:blue">main</span> (args):
<span style="color:orange">if</span> args:
message = args[0]
<span style="color:orange">else</span>:
message = <span style="color:red">’Hello, Clutter!’</span>

app = HelloClutter(message)
app.run()
return 0

<span style="color:orange">if</span> __name__ == <span style="color:red">’__main__’</span>:
sys.exit(main(sys.argv[1:]))
</pre>

Qui c’è la solita ferramenta necessaria per i programmi Python. Per avviare, basta eseguire:

<pre>
$ python hello-clutter.py "Ciao, mondo"
</pre>

<strong>Where do we go from here?</strong> – La versione 0.1 di Clutter, rilasciata l’anno passato, ha gettato le fondamenta per gli attori di base, ed è stata sufficiente per realizzare <acronym title="OpenedHand Presentation Tool">OPT</acronym>, un programma di presentazione usato da Ross Burton, da Jeff Waugh e dal sottoscritto al GUADEC di Vilanova. Per la version 0.2 abbiamo migliorato l’API, creato un renderer GL per Pango (riducendo l’utilizzo della memoria e aumentando la velocità e il supporto per l’internazionalizzazione) e aggiunto il supporto per i "comportamenti" (<code>ClutterBehaviour</code>) degli attori – ovvero un modo per animare i widget sul canvas. Purtroppo, a parte <a href="http://svn.o-hand.com/view/clutter/trunk/toys/opt/">OPT</a> non abbiamo notizia (al momento) di applicazioni che usino Clutter. Per questo ci farebbe piacere l’input della comunità, anche per sapere quali sono non solo i bug, ma anche le feature e le richieste che gli sviluppatori di applicazioni hanno; se voleste delle modifiche alle API per realizzare il prossimo rivale di MythTV (la cui interfaccia, diciamocela tutta, va bene a duemila <em>geek</em>, ma se la vedono gli utenti che hanno difficoltà a cambiare l’ora del videoregistratore abbiamo diecimila utenti che si buttano dalla finestra dall’orrore), oppure se avete dei bug da segnalare, basta aprire un ticket su <a href="http://bugzilla.o-hand.com/enter_bug.cgi?product=Clutter">Bugzilla</a>.

<em style="font-size:80%">continua…</em>

Jan
24
2007
1

Margaret vs. Pauline

Non capisco cosa stupisca <a href="http://magentaewoland.splinder.com/1169590683#10676368">woland</a> tra queste <a href="http://www.youtube.com/watch?v=cwsetvvIc-Y">normali dinamiche</a> <a href="http://en.wikipedia.org/wiki/Jack_Bauer">fratello</a>-<a href="http://en.wikipedia.org/wiki/Graham_Bauer">fratello</a>.

<em style="font-size:80%">Warning: i link di cui sopra sono spoiler – non dite che non vi avevo avvertito</em>

Written by ebassi in: Television,series |
Jan
18
2007
9

The Body Says No

È giunto il momento di rivelare al mondo, e alle anime belle che lo abitano, una verità orrenda, per troppo tempo taciuta da Chi Sa:

<div style="text-align:center"><h3>Python Fa Schifo e Chi l’Ha Scritto Va Tumulato Vivo Sotto Una Colata di Cemento a Presa Rapida</h3></div>

Certo, il linguaggio in sé è moderatamente carino, ma appena tenti di muoverti sotto l’interprete, per scrivere un modulo di interfaccia tra una libreria C e Python, l’idiozia della API Python/C e l’assenza di messaggi di errore significativi rendono il lavoro con Python una tortura – e dimostrano un’amatorialità degna di Ruby. Un’ora di questa tortura e rimpiango le macro criptiche e l’assenza di documentazione delle API del Perl. Per un linguaggio che si vanta di seguire il dogma del <em>better explicit than implicit</em>, le API C sono il trionfo della perversione mentale, della rottura all’indietro, dell’inconsistenza nelle <em>naming policy</em> e della mancanza di utilità.

Ovviamente, ognuno è libero di pensarla diversamente; sono convinto che Pythonisti arriveranno qui nel tentativo di mostrarmi la Retta Via Verso l’Illuminazione. Per me, tuttavia, e per i miei scopi non esiste differenza tra il lavorare per mezza giornata con Python e darmi delle vigorose martellate sui coglioni.

<em style="font-size:80%">Adesso mi sento molto meglio. E no, Python continua a farmi schifo.</em>

Written by ebassi in: Linux,Rants,Software |
Jan
10
2007
5

Something to Look Forward to/2

<em>Ma te come lavvedi?</em> – ovvero: l’iPhone è una stronzata o il gadget che cambierà la vita nostra e dei nostri figli in <em>secula seculorum</em>? Steve Jobs è il male incarnato, un venditore di fumo che ci propina tecnologia di cinque anni fa come se fosse nuova e <em>on the edge</em>, oppure è la seconda venuta di Cristo in terra, che ci libererà dalla schiavitù delle interfaccie grafiche vecchie di trent’anni?

Faccio il terzista moderato, e dichiaro: <em>a little bit of both</em>.

L’iPhone è uno smart phone, ovvero un <acronym title="Personal Digital Assistant">PDA</acronym> con un telefono cellulare; la Apple sa come fare i <acronym title="Personal Digital Assistant">PDA</acronym> dai tempi del Newton – solo che, all’epoca, non sapeva ancora venderli, o convincere la gente a comprarli (ché, poi, è la stessa cosa). I telefoni cellulari sono fuori dal loro campo, ma fortunatamente per loro ormai trovi circuiteria che implementa il GSM o l’EDGE al mercato del pesce. A questo punto, si aggiunge uno schermo da tre pollici e mezzo, touch screen e multi point e si elimina la tastiera – come hanno fatto la Siemens e altre telco svariate volte. Il problema con i touch screen si riassume in due parole: "feedback tattile", ovvero quella cosa che dice al vostro cervello "si, hai premuto il tasto". È qualcosa di basso livello, non coinvolge nemmeno il feedback dell’aggeggio (ovvero in quanto tempo l’aggeggio risponde al comando); è solo il modo in cui il tuo cervello funziona con gli oggetti tridimensionali. Ecco perché al giorno d’oggi non abbiamo grosse scrivanie di cristallo su cui appaiono tastiere colorate (a-la Tron); perché i laptop hanno ancora una tastiera invece di essere tutti tablet pc; perché i <acronym title="Personal Digital Assistant">PDA</acronym> hanno quasi tutti la stilo. Il nostro cervello funziona nei modi più strani: se premiamo qualcosa il cervello <strong>vuole</strong> la conferma. Se l’Apple ha sviluppato qualcosa del genere, avrà fatto anche i suoi bei studi di usabilità su qualche centinaio di cavie, quindi non discuto della scelta; la Apple, però, è nota anche per le sue belle cantonate – sebbene ne faccia di meno, negli ultimi tempi, non vuol dire che siano diventati infallibili quando Jobs parla <em>ex keynote</em>.

Andiamo oltre: interfaccia multi point. Ancora, niente di nuovo sotto il sole. Hanno fatto una demo tempo fa ai Google Labs, e l’idea ha l’indubbio pregio (dal punto di vista dell’industria dell’<acronym title="Information Technology">IT</acronym>) di scalare verso l’alto, con schemi intorno ai trenta pollici. tre pollici? <em>mmh, not so much</em>. Io faccio fatica ad usare la N800 (che pure prevede un <em>thumb mode</em>, anche se single point) con le mie dita, e lo schermo è un pollice più grande.

Tralascerò volutamente il wifi e la possibilità di usarlo come sistema di connessione verso Internet.

Il software, a questo punto. OS X in un ambiente embedded è interessante – e dati gli effetti mostrati penso abbiano un chip grafico in grado di usare GL ES; anche qui, nulla di nuovo. Sincronizzazione? Questa è interessante, e se funziona correttamente può essere il vero <em>selling point</em> dell’iPhone. Conosco anche troppa gente attaccata alla SIM del cellulare da anni, che teme di perdere tutti i contatti perché quegli aggeggi sono troppo stupidi per permettere di avere una rubrica unica di contatti tra computer e telefono. Qui, però, interviene anche la penetrazione di mercato della Apple Computer – a meno che non vendano una suite anche per Windows – come iTunes. Significa forse che un port delle utility del Mac (calendaring, foto, contatti) sotto Windows è in arrivo insieme all’iPhone?

In buona sostanza: iPhone non è la panacea per il problema "telefono cellulare intelligente". Non è nemmeno "<a href="http://www.freddynietzsche.com/2007/01/oops_we_did_it_again_1.php">solo un telefono: non è smart, non è multi, non è mega</a>", non solo perché non è stato venduto alla massa di <em>zealot</em> della casa della mela morsicata come "non solo un telefonino", ma anche perché si ripromette di essere <strong>il</strong> telefonino (smart, mega, multi) – e questo, signori miei, è un obbiettivo di mercato.

Written by ebassi in: Hardware,apple |
Jan
10
2007
9

Something to Look Forward to

Apple iPhone, <a href="http://www.engadget.com/2007/01/09/live-from-macworld-2007-steve-jobs-keynote/">quindi</a>.

Il Sofri giovane <a href="http://www.wittgenstein.it/post/20070110_41354.html">riporta</a> il commento di un lettore che si aggiudica la palma del vincitore per l’asserzione più stupida in un altrimenti ragionevole discorso sul fatto che l’iPhone avrà anche un’UI interessante, ma l’hardware è ben lungi dall’essere rivoluzionario:

<blockquote>
Non c’è nessuna compatibilità con Office.
</blockquote>

Voglio conoscere il fesso che userebbe Excel su uno schermo da 3.5 pollici senza stilo e con manipolazione via dita; vorrei conoscerlo per potergli stritolare la mano in una pressa idraulica, <em>that is</em>. Un po’ come le pubblicità della Microsoft che infestano le stazioni dei treni e della <em>tube</em> da queste parti: "vai avanti, fai le modifiche a quel foglio di Excel" – sullo schermo di uno <em>smartphone</em> con una tastiera ridicola. Devi essere un decerebrato per pensare di farlo – neanche di riuscirci.

Comunque, l’iPhone e AppleTV segnano lo spostamento definitivo della Apple (non-più-Computer) Inc. nel magico mondo delle <em>appliance</em> e della elettronica di consumo; staremo a vedere che succederà nei prossimi mesi.

Prima che me lo dimentichi: su X ci sono sviluppatori che lavorano da tempo al multi-point input su touchscreen; dato che l’Apple ha brevettato l’universo, spero non ci saranno ripercussioni sull’utilizzo di questa tecnologia nelle interfacce. Ad esempio, al momento non possiamo implementare alcune funzioni del Finder in Nautilus (come le "cartelle a molla" durante il drag and drop) perché brevettate dalla casa di Cupertino.

Jan
09
2007
--

Cast no Shadow

<em style="font-size:80%">Questo è ancora il blog di un geek che sviluppa su GNOME, quindi ogni tanto vi tocca. ;-) </em>

Con un grassissimo anticipo di trentacinque (si, 35) secondi sull’ora della <em>deadline</em> per effettuare una <em>release</em>, ieri notte ho impacchettato la version 2.17.1 delle GNOME Utilities, nome in codice <em>Cast no Shadow</em>. Dalle undici di sera fino al momento in cui <code>make distcheck</code> ha completato il suo lavoro, ho implementato una delle due <em>feature</em> richieste per questo ciclo di sviluppo per l’utility che prende screenshot del desktop (l’altra, ovvero la nuova finestra di dialogo per il salvataggio dell’immagine, ahimé, dovrà attendere GNOME 2.20, dato che non l’ho completata in tempo – penso che finirà in una <em>branch</em>, dato che è quasi finita e manca solo il codice per il drag and drop):

<div style="text-align:center">
<a id="p1030" rel="attachment" class="imagelink" href="http://www.emmanuelebassi.net/archives/2007/01/cast-no-shadow/gnome-screenshot/" title="GNOME Screenshot"><img id="image1030" src="http://www.emmanuelebassi.net/wp-content/gnome-screenshot-interactive-2.png" alt="GNOME Screenshot" /></a>
</div>

<div style="text-align:center;font-size:80%;"><em>La cosa buffa è che ho catturato l’immagine di gnome-screenshot usando gnome-screenshot.</em></div>

Questa finestra di dialogo apparirà solamente se <code>gnome-screenshot</code> verrà invocato dal meno oppure usando lo switch <code>–interactive</code> da linea di comando; ovviamente, la finestra di dialogo terrà conto delle opzioni da linea di comando, quindi:

<pre>
$ gnome-screenshot –window –delay=5 –interactive
</pre>

modificherà il <code>RadioButton</code> selezionato e il valore nello <code>SpinButton</code>. Purtroppo non sono riuscito ad infilare dentro una <code>ComboBox</code> per l’effetto (bordo o ombreggiatura), e dato che siamo in <em><acronym title="User Interface">UI</acronym> freeze</em> dovrò chiedere il permesso prima di inserirlo. <del datetime="2007-01-10T10:18:03+00:00">In più, c’è un bug: non appare l’icona dell’applicazione nella parte sinistra della finestra – probabilmente, l’icona non è installata correttamente</del> grazie a Dennis Cranston, il bug è stato rimosso.

Riassumendo, le <em>feature</em> mancanti in questo ciclo di gnome-utils sono:

<ul>
<li>usare GtkPrint nel dizionario [da fare];</li>
<li>supporto per dizionari locali [includere il parser e il backend];</li>
<li>speller nell’applet del dizionario – o rimozione dell’applet in toto, in favore di deskbar-applet; [da fare]
</li><li>plug-in nel visualizzatore di log – e, in generale, pulizia del codice [quasi completo, da pulire];</li>
<li>nuova finestra di dialogo per il salvataggio degli screenshot [quasi completo];</li>
</ul>

Adesso che GNOME è passato a SVN potrei finalmente sfruttare l’occasione e aprire qualche <em>branch</em> per gli esperimenti.

Written by ebassi in: Linux,OpenSource,Software,gnome |
Jan
09
2007
13

Return to Oz

Via <a href="http://www.neropercaso.it/dal-canada-con-furore/">Lawrence</a> arrivo a <a href="http://effettofarfalla.com/articles/2006/12/25/italia-non-ci-resta-che-piangere">questo blog</a> di Antonio Cangiano.

Come transfuga posso solo riconoscermi in buona parte di quanto scritto; l’unica differenza sta nel fatto che non mi manca in alcun modo l’Italia – solo un po’ di persone che ci vivono – perché l’Italia non mi è <strong>mai</strong> piaciuta. La sfortuna di essere nato in un posto e non riconoscerlo come <em>casa</em> fin da subito, fin da quando ne esci per le vacanze e ti trovi a Parigi a nove anni e fai commenti su quanto siano maleducati gli italiani – ad alta voce, nell’imbarazzo dei tuoi; oppure quando ti trovi a Londra a sedici anni e pensi <em>questa è casa mia</em>; oppure quando ti trovi a Berlino a venticinque anni e pensi seriamente <em>se trovassi un lavoro, qui potrei viverci senza problemi</em> (e non sai mezza parola di tedesco). In generale, rifiuto (con un certo imbarazzo) un’eredità alla quale non aspiro e non tengo.

Quindi, alla domanda <em>ti manca l’Italia</em> rispondo con un secco "no". Alla domanda <em>torneresti in Italia</em> posso, quindi, rispondere: solo se mi ci ammazzano.

Written by ebassi in: Blogback,Diary,italians |
Jan
09
2007
--

The Needle has Landed

Pare che la <a href="http://europe.nokia.com/link?cid=PLAIN_TEXT_81177">N800</a> sia di <a href="http://www.ossblog.it/post/1771/n800-il-nuovo-tablet-nokia-powered-by-linux">pubblico dominio</a> oggi. Per motivi di lavoro, ho potuto vederla (e sviluppare software per la piattaforma) da qualche tempo – e, all’alba dell’agosto scorso, ho potuto <a href="http://www.emmanuelebassi.net/archives/2006/08/santas-coming-to-town/">metter le mani sopra</a> a un prototipo.

Non avendo usato una 770 per molto tempo, fare un confronto tra le due mi è eticamente impossibile; posso solo dire che il nuovo hardware è sicuramente più interessante da un punto di vista multimediale (doppio del clock, doppio della memoria volatile, supporto per memory card da 2GB), e che usare la N800 come piattaforma mobile per audio e video in <em>streaming</em> ha sicuramente molto più senso della (comunque adatta, anche se al limite) 770.

L’unica cosa che manca è una tastiera integrata – ma dato che io comunque non sopporto le tastiere microscopiche dei cellulare e dei palmari <em>a là</em> Treo, e dato che le tastiere Bluetooth funzionano benissimo, direi che la mancanza non si fa molto sentire. Altra nota dolente è la porta USB non alimentata – quindi niente chiavette USB – ma anche questo ha senso, se si pensa che una porta alimentata comporterebbe una <em>battery life</em> ridotta drasticamente.

Modestia m’impone di non parlare del lato <a href="http://o-hand.com/blog/?p=13">software</a>.

Powered by WordPress | Theme: Aeros 2.0 by TheBuckmaker.com