2015-01-17

Lenovo Fn-Ctrl Swap

Lenovo laptop keyboards have always had the Fn key as the left most key on the keyboard, like this:

If you are a full touch typist (or simply got used with an external computer keyboard) you would expect Ctrl to be the left most key on the keyboard. And this Fn and Ctrl key swap would drive you crazy.

I used to have a Lenovo W510, which had a bios option to swap Fn and Ctrl keys.

Recently I've got a Lenovo SL500, an older, consumer Lenovo model, which with an SSD drive does its job just fine :) The problem with the SL500 is that it doesn't have the Fn and Ctrl key swap in bios!

The good news is that some people have hacked the Lenovo bios files and swapped the bytes for Fn and Ctrl keys. The hacked bios files can be downloaded from here:  FN-CTRL swap on all Lenovo laptops.

The problem is that when you run WINUPTP.EXE you (might) get an error message like this:


Bummer.

Lenovo provides also an ISO image with the firmware update. Probably with a DOS update utility.

The bad news was that this ISO image was "special". If you burned it to a disk no files were present. If you tried to open it with 7-zip you would get just a Bootable_HardDisk.img file with was 512 bytes in size.

Since we know there must be a DOS firmware utility involved, the ISO file must be in an old DOS format. IsoBuster (one can download an evaluation copy) confirmed this:


The bios file is – $0a6a000.fl1, which was also present in the Windows bios update package. Also worth mentioning the PCDOS_JP label, which points to IBM PC DOS instead of MS DOS. This makes sense since Lenovo used to be part of IBM.

From the first image we can see that NERO Burning Rom was used to create the ISO file. Since I don't have access to NERO Burning Rom I needed something else.

ISO format is not compressed, which means that all the files are somewhere in the ISO file. Since I had the original $0a6a000.fl1 and the modified version all I needed was a program which would search and replace the content of the $0a6a000.fl1 file.

I googled a bit after such an utility, no luck, then decided to roll my own program.

Below is the C++ source code for my breplace program. You can get x64 binaries for Linux, macOS and Windows from GitHub. The "magic" function in this program is std::search which finds the position of the $0a6a00.fl1 fle in the ISO file.


#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <string>

size_t readFileToVector(std::istream& file, std::vector<char>& buf)
{
     file.seekg(0, std::ios_base::end);
     size_t size = file.tellg();
     file.seekg(0, std::ios_base::beg);

     buf.resize(size);
     file.read(&buf[0], size);

     return size;
}

int main(int argc, char** argv)
{
     std::vector<std::string> arguments(argv, argv + argc);
     if (arguments.size() != 5)
     {
         std::cout << "usage: breplace <file_container> <file_to_be_replaced>";
         std::cout << "<file_to_replace> <dest_file_container>" << std::endl;
         return 1;
     }

     std::vector<char> container;
     std::ifstream containerFile;
     containerFile.open(arguments[1], std::ios_base::binary | std::ios_base::in);
     size_t containerSize = readFileToVector(containerFile, container);

     std::vector<char> toBeReplaced;
     std::ifstream toBeReplacedFile;
     toBeReplacedFile.open(arguments[2], std::ios_base::binary | std::ios_base::in);
     size_t fileSize = readFileToVector(toBeReplacedFile, toBeReplaced);

     std::vector<char> toReplace;
     std::ifstream toReplaceFile;
     toReplaceFile.open(arguments[3], std::ios_base::binary | std::ios_base::in);
     readFileToVector(toReplaceFile, toReplace);

     std::vector<char> destination;
     std::ofstream destinationFile;
     destinationFile.open(arguments[4], std::ios_base::binary | std::ios_base::out);

     std::vector<char>::iterator itpos = std::search(
         container.begin(), container.end(), toBeReplaced.begin(), toBeReplaced.end());

     if (itpos == container.end())
     {
         std::cout << "File's content " << arguments[2] << " was not found" << std::endl;
         return 1;
     }

     size_t beforeFileSize = std::distance(container.begin(), itpos);
     std::cout << "File's content " << arguments[2] << " found at position: ";
     std::cout << beforeFileSize << std::endl;

     destination.resize(containerSize);
     std::copy(container.begin(), container.begin() + beforeFileSize, destination.begin());
     std::copy(toReplace.begin(), toReplace.end(), destination.begin() + beforeFileSize);
     std::copy(container.begin() + beforeFileSize + fileSize, container.end(),
               destination.begin() + beforeFileSize + fileSize);

     destinationFile.write(&destination[0], containerSize);

     return 0;
}

Then I ran the tool as breplace.exe 6auj19uc.iso $0A6A000.FL1 $0A6A000.FL1_new 6auj19uc_fn_ctrl_swap.iso. In order to be sure that things are as they should be I did a file comparison between the two ISO files using Total Commander:


Things looked "legit" thus decided to burn the new ISO image to a disk and proceed with the bios update.

Everything worked just fine. Now the Lenovo SL500 has the Fn and Ctrl keys swapped! w00t!

Before you decide to flash your Lenovo laptop double check the bios / ISO files. This can brick your laptop!

2015-01-06

(ro) Diacriticele, internetul și Unicode

Pentru a publica texte în limba română pe internet știm că trebuie să folosim „Unicode”. Conform Wikipedia „Unicode (pronunțat în engleză /ˈjuːnɪˌkəʊd/) este un format definit de către Unicode Consortium pentru codarea, stocarea și interpretarea textelor pe suporturi informatice”.

Fiecare caracter, simbol are un număr de „ordine”. Mai jos avem numerele de ordine ale caracterelor specifice limbii române:
  • ă - litera latină mică a cu breve - U+0103
  • Ă - litera latină mare A cu breve - U+0102
  • â - litera latină mică a cu accent circumflex - U+00E2
  • Â - litera latină mare A cu accent circumflex - U+00C2
  • î - litera latină mică i cu accent circumflex - U+00EE
  • Î - litera latină mare I cu accent circumflex - U+00CE
  • ș - litera latină mică s cu virgula dedesubt - U+0219
  • Ș - litera latină mare S cu virgulă dedesubt - U+0218
  • ț - litera latină mică t cu virgulă dedesubt - U+021B
  • Ț - litera latină mare T cu virgulă dedesubt - U+021A
  • „ - ghilimele stânga jos (dublu 9 jos) - U+201E
  • ” - ghilimele dreapta sus (dublu 9 sus) - U+201D
  • « - ghilimele ascuțite stânga - U+00AB
  • » - ghilimele ascuțite dreapta - U+00BB
  • – - linia de dialog (en dash) - U+2013
În trecutul apropiat au existat sisteme de operare care au avut familii de fonturi care nu conțineau ș și ț cu virgulă. Browserele afișau pătrățele, sau literele arătau diferit deoarece alt font a fost folosit pentru afișaj.

Pentru a combate această problemă există mai multe soluții:
  • nu se folosesc diacritice. Soluție nerecomandată, dar răspândită ajutată de comoditatea celor care scriu astfel de texte. hotnews.ro WTF ?!
  • se folosesc ş și ţ cu sedilă în loc de ș și ț cu virgulă. Soluție nerecomandată, foarte răspândită ajutată de aranjamentul moștenit de la Microsoft și de soluția „Română cu Alt Dreapta” de la diacritice.ro.
  • se folosesc ș și ț cu virgulă împreună cu un cod javascript care adaptează pagina în funcție de sistemul de operare. Soluție recomandată. Wikipedia în limba română folosește această tehnică.
  • se folosesc ș și ț cu virgulă împreună cu un font specific (@font-face). Soluție recomandatăkmkz.ro folosește familiile de fonturi Futura și Frutigercatavencii.ro folosește familia de fonturi Open Sans, ș.a.m.d.
Ultima soluție mi se pare cea mai elegantă. Pagina web va arată la fel pe toate sistemele de operare și există multe familii de fonturi pe care le putem folosi de la Google Fonts (avut grijă la „Latin Extended”) sau să le avem generate de către Font Squirrel și să le avem local pe server.

kmkz.ro au ales varianta sigură și au generat fonturile cu Font Squirrel și le-au pus pe server. Dar din când în când au articole care arată bizar. Mai jos am pus capturi de ecran cu această bizarerie:

Mozilla Firefox 34
(bug #1128330)
Internet Explorer 11
(bug #1111623)
Google Chrome 39

Firefox și Internet Explorer afișează ă, ș și ț bizar, ca și cum breve-le și virgula ar fi după ă, ș și ț!

După un pic de muncă de investigație am aflat de simbolurile diacritice combinatorii din cadrul Unicode - Combining Diacritical Marks (U+0300 – U+036F).

Astfel putem avea combinațiile (literele din stânga sunt combinații):
  • ă - litera latină mică a și breve-ul - U+0061 și U+0306
  • Ă - litera latină mare A și breve-ul - U+0041 și U+0306
  • â - litera latină mică a și accentul circumflex - U+0061 și U+0302
  • Â - litera latină mare A și accentul circumflex - U+0041 și U+0302
  • î - litera latină mică i și accentul circumflex - U+0069 și U+0302
  • Î - litera latină mare I și accentul circumflex - U+0049 și U+0302
  • ș - litera latină mică s și virgula dedesubt - U+0073 și U+0326
  • Ș - litera latină mare S și virgula dedesubt - U+0053 și U+0326
  • ț - litera latină mică t și virgula dedesubt - U+0074 și U+0326
  • Ț - litera latină mare T și virgula dedesubt - U+0054 și U+0326
Literele arată ca cele necombinate, cum ne putem da seama de diferență? Simplu, copiați o literă în „notepad” și ștergeți-o cu „Backspace”, o să observați că se șterge breve-ul, accentul circumflex sau virgula prima și apoi litera de bază.

Pagina de la Kmkz se vede aiurea deoarece fonturile generate de Font Squirrel nu includ diacriticele combinatorii (U+0300 – U+036F). Putem verifica asta la Glypviewer și apoi introducând http://www.kmkz.ro/wp-content/themes/kmkz_v3/fonts/frutiger/frutigerroce-roman-webfont.woff la „Remote URL”.

Font Squirrel poate fi configurat să includă diacriticele combinatorii astfel:


Google Fonts nu exportă diacriticele combinatorii. Dacă vreți să folosiți un font de acolo, descărcați-l ca ttf/otf și apoi transformați-l cu Font Squirrel.

Google Chrome 39 ar fi trebuit să fi afișat pagina aiurea, dar dintr-un motiv sau altul afișează pagina corect.

La fileformat.info am aflat de exemplu că ț-ul a fost introdus în Unicode în versiunea 3.0.0 din Septembrie 1999, pe când virgula a fost introdusă în Unicode în versiunea 1.1.0 din Iunie 1993! Tot în versiunea 1.1.0 a fost introdus și ţ-ul cu sedilă.

Am decis să testez un Windows XP fără fonturi actualizate să văd cum afișează Internet Explorer 6.0 o pagină de test (vezi codul sursă la pastebin.com/tuavSbY4):

Familia de fonturi Arial
Familia de fonturi Tahoma


Se poate observa că problema diacriticelor lipsă nu ar fi fost rezolvată cu fonturile care nu au ș și ț cu virgulă (Tahoma fiind printre puținele familii de fonturi care vine cu ș și ț pe Windows XP). Dar avem o îmbunătățire, putem vedea caracterul de bază și nu doar un pătrățel :)

Ca fapt divers, pagina de test arată „interesant” în poza de previzualizare a serviciului de scurtare de linkuri goo.gl:



În articolul Aranjamente de tastatură românească am pus la dispoziție trei pachete de instalare pentru tastaturile românești folosite în lumea Windows.

Mai jos aveți aceleași trei pachete de instalare, dar de data aceasta literele (ăĂîÎșȘțȚ) sunt generate folosit diacriticele combinatorii:

*Aranjamentul „Română (Moștenit)” vine cu unele îmbunătățiri, pentr
u a afla mai multe vezi articolul de mai sus.

Nu știu ce software au folosit cei de la Kmkz pentru a produce textele cu diacriticele combinate, dar acum se poate face același lucru folosind Windows!

Nu recomand folosirea diacriticelor combinate, dar este bine să știm despre existența lor :)

P.S. 

Cristiana Cobliș a menționat caracterul util al diacritcelor combinate în contextul fonturilor care nu conțin diacriticele directe. Google Fonts conține multe fonturi care nu conțin diacriticele directe, mai ales ț-ul.

Am reușit să găsesc un font care îndeplinește această condiție: Righteous. Mai jos avem o captură de ecran cu Google Chrome 39 și fontul Righteous:


Din păcate doar Google Chrome randează pagina corect. Mozila Firefox 34 sau Internet Explorer 11 au probleme.

Este mult mai simplu să facem browserele să afișeze corect diacriticele combinate decât să convingem toți autorii de fonturi să adauge literele lipsă, în special ț-ul :)

2014-11-14

Thank you Google!

This is my third "Thank you Google!" article. In the first two articles I've thanked Google for fixing the Droid and then the Roboto font families.

This time I'm thanking Google for adding a dictionary for the Romanian keyboard in Android thus enabling gesture typing. I remember seeing gesture typing fist on the Swype keyboard.

I've noticed this feature on my Nexus 5 with the arrival of Android 4.4.4 update.

Last week I've updated my HP TouchPad to Android 4.4 (CyanogenMod 11) and took a screen shot of "Google Keyboard". I've pointed out the elephant in the picture.


Gesture typing makes typing correct Romanian fast and enjoyable! Note that the keyboard has some quirks, which I've reported here: #35339.

Here is a recording of me gesture typing the Romanian Pangram:


Microsoft has added to Windows Phone 8.1 gesture typing and the call it shape writing or Word Flow. As it turns out, Word Flow is supported only for the following languages:
Arabic, Dutch, English (UK and US), Finnish, French, German, Italian, Polish, Portuguese (Brazil), Russian, Spanish (Mexico and Spain), Turkish, Ukrainian.
It seems Windows Phone keyboard needs more than a dictionary (it does come with a Romanian dictionary) to enable gesture typing. I've made a suggestion to Microsoft to add WordFlow support to Romanian language in Windows Phone. Vote if you want it :)

Hats off to Google! Shame on you Microsoft!

P.S. Recently I've learned that Google Keyboard is not available everywhere. For example you will not find Google Keyboard on Play Store in Germany and if you search it in the browser and then open the link you will get this nice image (Tested on a Moto X bought in Germany):


It's not only music and videos that Google blocks in Germany, it's also apps!

2014-06-20

Qt Creator - Help is on the way

Visual Studio starting from version 2002 to 2008 had a poor help experience. Hitting F1 in Visual Studio resulted soon in me cursing while looking at the help window's progress bar. Unlike Visual Studio 6 which had a very responsive help system.

I remember looking with Process Explorer to see what's going under the hood and it was very surprising to see the C# compiler running...

To overcome this waiting I would open up a web browser and search online. This habit stuck. The web search engine become my best friend.

Visual Studio 2010 has fixed the help system (some local web server technology if I remember correctly), but I haven't spent much time with it so that I would go back at pressing F1 for help.

For the past three years I've been using Qt Creator and I was happy with my work flow: code editing, debugging with Qt Creator and online web search for help.

Therefore I found myself hacking a project using Qt and Qt Creator and searching online after QBrush, QPainter documentation.

If you search online after QBrush you will most probably (at this moment in time using google) get this: qt-project.org/doc/qt-4.8/qbrush.html I would then click on the link and change it to qt-project.org/doc/qt-5.3/qbrush.html. This became annoying after a while.

Now I know that Qt Creator already comes with the most up to date Qt documentation (depending of course if you have the most up to date Qt installed).

But I would have not realized this if my work colleague Miika Järvinen wouldn't have mentioned a small project of his.

His small project involved having the awesome cppreference.com offline C++ documentation available in Qt Creator. Now cppreference has a qch file compiled, but it only shows the main index page when using F1 or searching with "?". If you navigate to the help panel you get an annoying endless "waiting" cursor.

Miika noticed that the qch file was broken due to invalid paths and he compiled a fixed version, which you can get it from here. The endless "waiting" cursor is still present though.

Below you have an example how to use the awesome Qt Creator help system with the equally awesome offline documentation from cppreference.com:

Qt Creator 3.1 on Kubuntu 14.04
Now I could be "helped" by Qt Creator and not by the online web search!

Imagine the productivity kick you can get if you have the browser window closed, or code offline for that matter :)

2014-03-02

Debugging QNX applications using Qt Creator

According to Wikipedia QNX is: "QNX is a commercial Unix-like real-time operating system, aimed primarily at the embedded systems market".

One could get an evaluation copy of QNX 6.5.0SP1 and have a virtual machine running the x86 version of QNX 6.5.0SP1. QNX comes with an Eclipse based IDE, which is nice and all but I'm interested in QtCreator :)

Ed Langley has a very nice blog entry named - Setting up a QNX image for use with Qt Creator.

Qt Creator needs SSH communication with the QNX target, in my case a virtual machine. Ed Langley's blog entry has details on how to get this up and running.

I've created a "hello world" C++ project. In order to have Qt Creator deploy this hello world application one needs to add the following lines to the pro file:

target.path = /home/sam/qnx_test
INSTALLS += target 


Debugging the application using Qt Creator 3.0.1 looked like this:


Debugging works out of the box, unfortunately the STL types are not displayed very "pretty".

QNX 6.5.0SP1 comes with "GNU gdb 6.8 qnx-nto (rev. 506)" which is copyrighted "(C) 2008 Free Software Foundation, Inc.", which is a bit dated.

Fortunately QNX has an updated version of GDB "gdb-7.5-r791". Upgrading gdb was just a matter of unpacking gdb-prereq-linux.tgz and linux-gdb-7.5-r791.tar.gz. Now GDB version is "GNU gdb (GDB) 7.5 qnx (rev. 791)" which is copyrighted "(C) 2012 Free Software Foundation, Inc.".

Unfortunately Qt Creator 3.0.1 was not able to use the debugger. In Qt Creator's "Debugger Log" I was able to find out why:

&"    import binascii\n"
&"ImportError: No module named binascii\n"
&"Error while executing Python code.\n"


Python from the "gdb-prereq-linux.tgz" file, which ended up being installed here /opt/qnx650/host/linux/x86/usr/python27/, was incomplete. Binascii module should have been available, but was not.

So I decided to compile my own version of "Python 2.7.2". This was a bit tricky because Qt Creator needs a 32bit version of Python and my Linux installation was 64bit. I've set up a schroot environment for a 32bit version of my Linux distribution and done a ./configure, make, make install build of Python 2.7.2.

I've uploaded my Python 2.7.2 build here, "installation" should be done like:

# tar xJf python-2.7.2.tar.xz  -C /opt/qnx650

After upgrading GDB and Python Qt Creator 3.0.1 debugging looked like this:


As we can see it's not necessarily better. The STL types are not just not "pretty", this time are not accessible. One could say that's even worse.

Upgrading Qt Creator to the upcoming 3.1 release improved things a bit:


As you can see std::vector was displayed correctly. I don't know why "value" was presented as . The "Debugger Log" didn't show up any errors.

Digia announced on 25th of February 2014 the debut of "Qt 5 support for latest release of QNX operating system", which means that Qt Creator 3.1 and future versions would support QNX 6.6!

I hope you will give Qt Creator a try when developing QNX applications!

2014-02-15

(ro) Tastatura românească „3 în 1”


Când vine vorba de tastaturi românești multora li se ridică părul în cap. Și asta pe bună dreptate, de vină este aranjamentul „moștenit” de la Microsoft. Conform Decât o Revistă „moștenirea” a început astfel:
„Legenda spune că pe la începutul anilor ’90, băieții de la Microsoft au venit în România să se intereseze cum să-și localizeze sistemul de operare și au ajuns la Poliție. Destul de logic, pentru că Poliția emite documentele de stare civilă și se presupune deci că sunt cunoscute nevoile limbii. Ei bine, la Poliție se pare că au găsit niște mașini de scris nemțești și așa ne-am pricopsit cu z și y inversate și ă, î, ș, ț pe tastele cu parantezele pătrate, punct și virgulă și apostrof.”
Din 2004 avem un standard ASRO de tastatură (SR-13392:2004) actualizat, bazat pe aranjamentul american. Acest standard este implementat pe sistemul de operare Windows începând cu Windows Vista, pentru drivere pentru Windows XP / 2000 vizitați această pagină.

Avem și o lege care recomandă folosirea tastaturii românești, și anume ordinul MCTI  nr. 414 din 25 septembrie 2006 cu privire la utilizarea codării standardizate a seturilor de caractere în documentele în formă electronică, conține la Art. 4: 
„Pentru scrierea și procesarea documentelor în formă electronică în limba română se recomandă a se folosi tastatura românească în conformitate cu aranjamentul 1 de caractere din standardul SR 13392:2004 sau orice versiune actualizată a acestuia ori standardul care îl înlocuiește.”
Din păcate nici acum, peste aproape zece ani, nu există pe piața românească tastaturi conforme cu standardul românesc SR-13392:2004.

Anul trecut am aflat de existența firmei americane WASD Keyboards. Ei fac tastaturi mecanice la comandă, tastaturi care pot fi desenate cum vrea clientul. În felul acesta mi-am comandat o tastatură conformă cu aranjamentul secundar al standardului SR 13392:2004. Am scris despre acestă poveste aici: Tastatura RO-PRO.

În timp ce lucram la șabloanele pentru tastatură mi-a venit ideea să combin cele două aranjamente, în felul acesta am obținut o tastatură „3 în 1” - americană, română standard și română programatori.
Pentru a diferenția cele două aranjamente am folosit culori. Roșu pentru caracterele specifice aranjamentului primar / standard și albastru pentru cel secundar / programatori.

Tastatura „3 în 1” ar putea satisface 100% nevoia de comunicare a utilizatorului român. Dacă nu scrie cu diacritice, poate liniștit să ignore tastele colorate și să folosească partea americană a tastaturii. Dacă scrie cu diacritice poate să-și seteze în sistemul de operare aranjamentul preferat și culorile o să-l ghideze spre diacritice, respectiv ghilimelele românești sau linia de dialog.

Am mai tratat și problema traducerii etichetelor de pe tastele de sistem și anume „Esc”, „Insert”, „Delete”, „Home”, „End”, „Page Down”, „Page Up”, „Print Screen”, „Scroll Lock”, „Pause”. Nu le-am tradus în română deoarece etichetele ar fi fost prea lungi, am folosit simboluri. Există standardul ISO/IEC 9995-7:2009 (vezi varianta „final draft”) care tratează exact această problemă (mulțumesc „Secărică” pentru document / idee). Dacă în marea majoritate a cazurilor simbolurile erau „ușor” de înțeles, pentru „Esc” și „Pause” cu greu utilizatorul de rând și-ar fi dat seama ce înseamnă acele simboluri. Așa că am decis să folosesc alte simboluri mult mai ușor de înțeles.

Pentru că „WASD Keyboards” a început să folosească culori am decis să dau comandă la o tastatură „3 în 1”. În urma sfaturilor primite pe lista de Diacritice (mulțumesc Mișu', mulțumesc „Pixel”) am schimbat și fontul folosit pentru etichete din Roboto în Fira Sans, font folosit de sistemul de operare Firefox OS.

Tastatura arată astfel:

Pentru cei dispuși să plătească pentru o asemenea tastatură, pașii pentru a o achiziționa sunt:
  1. mers la WASD Keyboards pe sait și ales varianta cu 87 sau cu 104 taste
  2. selectat tipul de contact folosit (Cherry Maro, Roșu, Verde, etc)
  3. selectat tipul de atenuator de zgomot
  4. selectat șablonul tastaturii românești „3 în 1”
  5. selectat culoarea tastelor, textul negru din șablon va fi înlocuit cu alb pe tastele negre.
Anul acesta am avut șansa să merg la CES2014, unde am discutat cu reprezentanții câtorva producători de tastaturi: Logitech, Genius și Delux. A rămas că după târg vom discuta pe email. De la Logitech nu am primit niciun răspuns. Cu cei de la Genius am avut un schimb de emailuri concluzionat cu (diacriticele le-am adăugat eu):
„Lipsa unei cereri constante din piață pentru tastaturile customizate, după cum sunt sigur că știți, nu ne permite să onorăm cereri punctuale, chiar dacă discutăm de un MOQ de 1000 buc.

Ar însemna o investiție considerabilă în capacitățile de producție, care nu poate fi susținută „a la long”
Am avut o discuție și cu partenerii noștri în acest sens, dar nici acolo nu există un interes major pentru a susține livrări constante.

În situația dată, mă tem că nu putem avea o soluție la cererea dumneavoastră.”
Din fericire cei de la Delux s-au arătat mai deschiși la idea de a produce o tastatură românească „3 în 1”. Comanda minimă ar fi de 1000 bucăți. Am înțeles că urmează să primesc o mostră și apoi voi putea da comanda :)

Pentru finanțare m-am gândit la o campanie pe Multifinanțare. Cu ajutorul unei campanii „virale” pe rețelele de socializare ar trebui să se găsească 1000 de oameni de bine, nu?

Eu sper că în viitorul apropriat vor exista tastaturi românești conforme cu standardul SR 13392:2004 în România!