quinta-feira, janeiro 18, 2007

O Caso do Bloqueio do YouTube - Uma análise técnica

Passado o frenesi do Cicablock, ou Cicagate, ou qualquer outro nome pelo qual você, leitor, tenha ouvido falar dessa aberração jurídica que foi o bloqueio do site YouTube por causa do vídeo onde Daniela Cicarelli e seu namorado aparecem transando em uma praia espanhola, decidi que era uma boa idéia escrever uma pequena (ou não tão pequena assim) análise técnica do evento e tentar com isso oferecer subsídios àqueles que tentem entender o episódio.



De forma rápida, uma vez que o vídeo de Daniela Cicarelli foi considerado "ilegal", o juiz pediu um parecer técnico sobre a possibilidade ou não desse bloqueio. Na realidade, aqui pretende-se justamente fazer isso, mas indo para um outro patamar, que é o de dissecar as possibilidades de um bloqueio a conteúdo na Internet e potenciais problemas que possam tornar esse bloqueio impraticável. Percebam que aqui não uso o termo impossível, até mesmo porque não "existe impossível" no cyber-espaço, mas sim impraticável, seja por custos operacionais ou por reações adversas.



Vamos começar então analisando as possibilidades de um bloqueio a conteúdo. Perceba que aqui não faço nenhuma distinção a textos, imagens, sons, vídeos ou qualquer multimídia. Faço isso de forma a deixar claro que a Internet é, de certa forma, feita de bits que compõem, em sua esfera mais abstrata e human-friendly conteúdo, mas que continuam sendo bits em sua esfera mais "concreta" e machine-friendly.



Sem delongas, vamos ver três tipos de bloqueio que poderiam ser implementados: isolamento de redes, bloqueio de conteúdo por keycontent, bloqueio de conteúdo por checagem de validação (checksum). Vou explicar a seguir o que cada um desses bloqueios, sua implementação e seus problemas.



1-) Bloqueio pelo isolamento de redes:



Esse primeiro bloqueio foi implementado no caso do Cicagate pela Brasil Telecom e pela Telefônica. Dele derivaremos duas novas "interpretações" para as tecnologias da Internet, mas antes partiremos para a teoria básica.



Podemos definir que uma rede de computadores na verdade apenas replica uma rede de troca de informações humana, que por sua vez é estabelecida quando nos comunicamos uns com os outros (por exemplo, no bate-papo sobre futebol). Ora, para montarmos uma comunicação, precisamos de um emissor (alguém que envia a informação, ou mensagem), um receptor (alguém que recebe a informação), um meio por onde a informação irá trafegar, e um protocolo que permita que o emissor envie a informação de maneira que o receptor a receba. Esse protocolo pode, por sua vez, também incluir traduções entre o protocolo utilizado pelos pares se estes forem diretamente incompatíveis (definindo "incompatível" aqui como "suficientemente diferente para comprometer ou invalidar a comunicação").



Desse modo, podemos definir que o alvo para invalidar uma comunicação são quatro: o emissor, o receptor, o meio e pelo menos um dos protocolos adotados. Uma vez que você iniba um deles, a comunicação deixa de existir.



Transportando essa teoria ao mundo cibernético da Internet, podemos dizer que o emissor é o site do qual o usuário solicita o conteúdo (ou seja, a mensagem), o receptor é o usuário, o meio são as várias vias de transmissão de bits, seja por cabo, fibra, ou sinais magnéticos e os protocolos são os protocolos da pilha TCP/IP. Agora que já transportamos a teoria para a parte técnica, podemos falar um pouco sobre os protocolos.



Todo protocolo de rede (e o TCP/IP não é exceção) precisa saber qual é o destinatário e o remetente da informação, da mesma forma que um carteiro precisa saber o endereço de quem vai receber a carta e, caso essa pessoa não esteja lá, o endereço para onde mandar a carta de volta, indicando que a mesma não se encontra. No caso do TCP/IP, essa parte é feita pelo endereço IP, uma seqüência de 32 bits representada em 4 números decimais chamados "octetos", que representam "pedaços" de 8 bits do endereço IP. Como exemplo, poderíamos afirmar que uma máquina qualquer pode ser representada pelo endereço IP hipotético 123.456.789.012.



Agora que sabemos que todo servidor na Internet é representado pelo endereço IP, temos que entender também sobre os backbones (espinhas dorsais) e roteadores. De maneira simples, um roteador é um equipamento que é capaz de direcionar os dados enviados para ele por uma ou mais rotas até que os dados alcancem seu destino. Podemos comparar mal-e-mal um roteador a uma agência de correio, onde as cartas são separadas para seus vários destinos. Da mesma forma que uma agência do correio, o roteador IP não precisa conhecer todos os destinos possíveis para enviar (ou, como chamamos tecnicamente, rotear) os dados: em caso de não saber para onde enviar os dados, todo roteador é programado a seguir uma "rota padrão", ou seja, um caminho para o qual ele envia os pacotes que ele não sabe para onde mandar. Podemos comparar essa situação, por exemplo, a uma agência que manda uma carta para a central dos Correios no estado por não saber para onde a mandar. A partir daí, a central dos Correios é que se torna responsável por enviar a carta adiante. No caso, chamamos a nossa "central dos Correios" de backbone.



Como todo mundo sabe, o endereço de uma carta deve ser correto (ou ao menos válido) para que a carta chegue ao seu destino. Se ele estiver incorreto, normalmente a carta retorna a seu rementente com um alerta de que a carta está endereçada errada. O mesmo vale para o IP: se um backbone não consegue entregar um pacote por algum motivo, o sistema devolve ao usuário (na verdade, ao sistema do usuário) um alerta indicando que o endereço desejado não existe, tecnicamente um "pacote ICMP Destination Unreachable" (pacote é o nome que dá-se tecnicamente a uma parcela de informação que é enviada pelo meio de rede, podendo compor de uma quantidade arbitrária de bits; ICMP significa Internet Control Message Protocol, ou Protocolo de Mensagens de Controle da Internet, que de maneira rápida pode ser entendido como um protocolo que permite que um determinado endereço IP, ou host, possa saber se suas solicitações a outro host foram atendidas e se não foram, porquê; e Destination Unreachable quer dizer que o host de destino não foi encontrado por algum motivo).



Desse modo, podemos entender que o sistema é então alertado de que o host em questão não existe. A maioria dos roteadores, para contribuir com a performance da Internet, ao receber um desses pacotes param de tentar enviar dados ao host em questão por algum tempo, normalmente uns 5 minutos. Isso também impede que um host que tenha saído do ar por alguns instantes (por manutenção, por exemplo) nunca mais seja alcançado.



Portanto, chegamos ao ponto: como bloquear um host válido. A resposta seria tornar o host inválido de alguma forma. E como fazer isso? Com o uso de um firewall.



Firewalls são programas ou equipamentos que analisam os dados de um pacote de dados IP para verificar se o mesmo contêm algum tipo de problema ou informação inválida ou perigosa através de certas informações chave. São programas muito úteis na proteção contra ataques de pessoas más-intencionadas na Internet, uma vez que vários tipos de pacotes IP inválidos e habil e maliciosamente montados podem ser usados para fazer um host sair do ar ou permitir sua invasão (não entraremos nesse detalhe pois não nos é relevante).



Além disso, muitos firewalls atuais permitem que seus administradores bloqueiem determinados IPs, sejam por estarem sendo ponto de partida de invasões (como analogia, seria o equivalente cibernético a uma ponte levadiça medieval) ou então por representar hosts de serviços que são perigosos ou inapropriados de alguma forma.



O importante aqui é que um firewall barra qualquer comunicação daquele ponto em diante para qualquer ponto "atrás dele" (ou seja, que tenha que passar por ele para chegar em seu destino). Isso é muito útil pois desonera, por exemplo, uma empresa, que pode implementar um único firewall na sua "saída" para o backbone de Internet ao qual ela se conecte (podemos pensar nesse caso no firewall como uma aduana).



Se você leu com cautela até aqui esse documento, já deve ter reparado no que aconteceu: provavelmente um firewall foi ativado no backbone da Telefônica e da Brasil Telecom, de modo que eles começaram a considerar o IP do site YouTube como "perigoso ou inapropriado". Aparentemente uma solução simples e rápida.



Mas quais são os incovenientes? Basicamente são cinco:



  1. Você está onerando todas as comunicações, mesmo aquelas válidas, uma vez que os dados têm de ser analisados quando da saída do pacote para a rede "desprotegida" e da volta dos dados (quando esse ocorre). Mesmo que o pacote seja considerado válido (por exemplo, por não estar indo ao YouTube) ainda assim ele deve ser validado, o que exige processamento, fazendo com que o pacote demore a ser enviado e atrase os demais (imagine uma aduana super-lotada por causa de fiscalizações da Receita Federal: essa seria a imagem de um firewall nessa situação);
  2. Se por um acaso (o que não ocorreu no caso YouTube), um mesmo host contiver mais de um site (isso é possível, mas não entraremos nos detalhes técnicos, uma vez que é um assunto razoavelmente complexo e fora do escopo desse documento), todos os sites estarão bloqueados. O bloqueio de IP é "burro", não conseguindo analisar todo o conteúdo dentro dele, e sim certas informações chave. Existem filtros mais "refinados", sobre os quais falaremos adiante. De certa forma, foi o que ocorreu no caso Cicagate;
  3. Derivado do problema (1), você onera todas as redes para trás, reduzindo a performance dos hosts "atrás" do firewall. O firewall tem que gastar algum tempo para analisar cada pacote de dados para definir se o mesmo é válido ou não. Embora os roteadores e firewalls sejam rápidos nisso (coisa de milisegundos ou até micro-segundos dependendo do sistema), temos que considerar que milhares, até milhões de pacotes são enviados a cada segundo pela Internet. Ou seja, o "poder de fogo" necessário é muito grande, principalmente se procurar-se não onerar o tráfego lícito;
  4. Como comentamos ao analisar o problema (2), o bloqueio de IP é "burro", não analisando realmente o conteúdo. Isso, ao mesmo tempo que passa por censura (lembre-se, todo o site está fora do ar. É como se arrancássemos o cabo que chega a um tronco de telefones dentro de uma empresa, ou derrubássemos uma torre de telefonia celular), ele não impede a divulgação do conteúdo por meio de sites similares;
  5. Também derivado do problema (2), o bloqueio de IP pode se tornar inefetivo se, fora da rede "protegida" um outro host IP fizer o redirecionamento do pacote IP para o IP bloqueado. Técnicas de redirecionamento por meio de proxies (softwares que fazem esse papel de intermediário) são conhecidas e muito baratas, além de ajudarem na própria performance da Internet. O detalhe aqui é que, para o firewall, o conteúdo não vem do IP bloqueado, mas sim do IP do proxy. Como não há uma análise do que vêm, mas sim de onde vêm, o conteúdo proibido "vaza";


Esclarecido o problema, vamos analisar duas táticas de bloqueio mais "refinadas", mas que ainda assim não são tão efetivas, que são a checagem por keycontent e a checagem por validação (checksum).



2-) Bloqueio por checagem de keycontent:



Como já vimos anteriormente, tentar bloquear conteúdo na Internet apenas por meio de bloqueio de IP não é uma coisa muito efetiva e pode acarretar, na verdade, "fogo amigo" (ou seja, eliminar conteúdo importante). Então vamos ter que "subir um nível", ou seja, passar a lidar com o conteúdo um pouco acima, apesar de ainda falarmos de bits.



O TCP/IP na verdade não é um protocolo de dados, e sim uma pilha de protocolos (protocol stack). Em um sistema assim, os protocolos "superiores" (que lidam diretamente com o usuário) vão repassando os dados aos protocolos "inferiores", que por sua vez "envelopam" esses dados com as informações de controle específicas de sua camada, até a última, a camada física, que realmente manda os dados. Ao chegarem em seu destino, os dados vão sendo "desenvelopados" pelas camadas "inferioras" que remetem os dados às camadas "superioras", até a camada onde os dados serão tratados.



Imaginemos o seguinte exemplo: você solicita uma página Web para um servidor qualquer. Você abre seu navegador e digita o endereço da página desejada. Uma vez o endereço digitado, o navegador formata esse endereço em uma solicitação HTTP, que é o protocolo da Web. Uma vez formatada a requisição, os dados são mandados para a camada seguinte, onde o protocolo TCP (Transfer Control Protocol) "envelopa" os dados da camada HTTP com seus dados de controle. Para o TCP, não interessa a formatação da requisição HTTP. Ele apenas sabe que tem que enviar esses dados para uma porta de dados específica no servidor (porta de dados é uma porta lógica para onde os dados devem ser enviados. O uso dessas portas permite que um mesmo servidor possa administrar vários serviços conforme a conveniência), a porta 80, então ele "envelopa" essa informação junto com os dados do HTTP, no qual ele não mexe. Em seguida, o TCP manda as informações para a camada "inferior", a do protocolo IP, que novamente "envelopa" os dados: ele não precisa saber a qual porta o TCP precisa enviar os dados, só precisa saber que precisa mandar os dados para um IP qualquer. Ele então "envelopa" essa informação de controle com as informações anteriores e manda para a camada física, onde a placa de rede (ou wireless) sabe qual é o servidor para o qual os dados serão enviados. Perceba que não estamos falando de como o sistema descobre essas informações, uma vez que é informação excessivamente técnica e irrelevante na nossa análise. Basta que saibamos que os protocolos conseguem obter certas informações que permitam a ele descobrir como enviar corretamente os dados desejados.



Uma vez que os dados chegam na camada física do servidor de destino, o processo é invertido: o protocolo da camada física (seja qual for, Ethernet, WiFi, WiMax, etc...) "desenvelopa" os dados que vieram e manda-os para a camada de rede. Não é problema da camada física tratar os dados recebidos, então ele faz o que seria dito no popular de "toma que o filho é teu" com os dados recém-chegados para o protocolo de nível superior. O protocolo de rede identifica os dados como sendo direcionados para ele, então "desenvelopa" os dados recebidos e envia-os para a camada TCP. Nesse proceso de "desenvelopar" ele apenas "retira" os dados relacionados à sua camada, não mexendo em mais nada, uma vez que ele não sabe que dados estão "envelopados" e também pouco lhe interessa. Uma vez que os dados "sobem", o TCP identifica a porta desejada e envia os dados a um servidor que está "escutando" a (ou seja, será responsável pelos dados que chegarem à) porta desejada (no caso, 80). Por fim, o servidor trata essa requisição e o processo se repete, mas no sentido inverso.



Na realidade, o sistema de envio de dados em rede é um pouco mais complicado que isso, pois existem questões como checagens de se os dados enviados estão corretos e confirmações de chegada dos dados, além dos diversos mecanismos usados para que os protocolos saibam como enviar corretamente os dados, mas em sua base isso deve ser o suficiente para compreender o que estamos falando.



Perceba que uma camada está pouco interessada para como as camadas superioras e inferioras tratam os dados ao receber/enviar. Ele apenas sabe como receber e enviar dados para cada uma dessas camadas, e ainda asism para as camadas diretamente superioras e inferioras. Isso permite um rápido desenvolvimento de novos protocolos e permite que problemas em uma camada não afetem (ao menos totalmente) as demais. Além disso, evita o risco de que uma alteração em um protocolo afete os demais. Como comparação rápida, imagine um monte de blocos Lego: você pode remover pequenas partes de um objeto feito com Lego e substituí-las por outras sem maiores problemas na maioria dos casos.



Essa topologia de pilha permite que facilmente seja adicionada "camadas" extras à pilha. Uma dessas "camadas" extras já vimos anteriormente, que é o Firewall. De maneira similar, podemos imaginar uma camada que afete, por exemplo, os dados ao irem/virem para/da camada TCP. Esse firewall é conhecido como filtro de conteúdo.



A técnica de filtragem de conteúdo na Internet já é bastante popular, principalmente em empresas, para restringir o acesso a certos tipos de serviços ou conteúdos. Existem várias técnicas para isso, sendo as principais: a técnica de restrição por porta, que, de maneira bastante simples, pode ser entendida como um firewall que aproveita-se do fato de os serviços na Internet, como Email, Web e Mensagens Instantâneas utilizarem-se de portas específicas para funcionarem e bloqueiam tais portas; e aqueles que buscam conteúdos específicos (que chamaremos de conteúdos chaves - keycontents) que identificam o protocolo ou conteúdo acessado e bloqueiam o acesso a partir desse conteúdo.



Os bloqueios por keycontent baseiam-se no fato de que o protocolo sempre exige ou envia uma determinada informação para que o programa que o usuário está usando reconheça essa comunicação. Por exemplo, uma string qualquer é enviada antes do conteúdo propriamente dito ser enviado, ou então o endereço do site é enviado. Em todos os caso, para resumir, o filtro analisa o conteúdo enviado/recebido atrás de padrões que identifiquem o conteúdo (como, por exemplo, a palavra "sexo" em sites eróticos), barrando o conteúdo a partir do momento em que o conteúdo em questão se encaixa em certos critérios definidos no bloqueio. Não irei aprofundar na explicação, mas o importante é saber que, como o que trafega na Internet são bits, qualquer padrão desses bits pode ser detectado pelo filtro em questão, desde que devidamente preparado a trabalhar com o protocolo em questão.



Esse bloqueio pode aparentemente parecer muito efetivo, principalmente contra conteúdos textuais, mas ele tem alguns inconvenientes:



  1. Demanda muito mais processamento, uma vez que na realidade ele processará muito mais informação do que alguns poucos bits, podendo processar informações da ordem de milhares ou até de milhões de bits em uma única solicitação até decidir se libera ou não a comunicação. Além disso, a oneração do sistema aumenta proporcionalmente;
  2. A maioria dos filtros de conteúdo são muito específicos para um determinado tipo de informação (por exemplo, informações textuais oriundas da Web). Se o meio ou a mensagem for alterada (por exemplo, enviar uma imagem ou mandar o texto por email), ele irá "vazar" pelo filtro de conteúdo;
  3. Muitos filtros de conteúdo são "burros", ou seja, não são capazes de identificar o contexto do conteúdo. Por exemplo, um filtro especificado para bloquear conteúdos com a palavra "sexo" irá barrar sites de pornografia, mas poderá bloquear sites de educação sexual e até mesmo cadastros em sites. Basta que a palavra "sexo" apareça para que o conteúdo seja bloqueado. A isso é chamado em informática de "falso positivo", o que demanda uma contínua supervisão para a melhoria do filtro;
  4. Os filtros também podem estar sujeitos a dois problemas: poisoning e falso negativo. O segundo problema é mais "passivo", onde o conteúdo é levemente alterado de forma a "vazar" pelo filtro. Por exemplo, um site colocar "siexo" ao invés de "sexo", o que já causaria no filtro o entendimento que aquele não é um site de "sexo". O poisoning (envenenamento) é uma espécie de "tática vingativa" dos que se sentem prejudicados com o filtro de conteúdo, onde o filtro é "envenenado", principalmente se são usadas técnicas de Inteligência Artificial para que o mesmo passe a negar conteúdos. A idéia é que junto com os materiais considerados "positivos" para o bloqueio, outros tantos "negativos" sejam inseridos, de maneira que, ao analisar-se para atualizar-se com novos padrões, a IA do filtro pegue padrões falsos que batam com conteúdo bom e acabe provocado um aumento no número de "falsos positivos";
  5. Técnicas de criptografia, como o uso de redes como Tor ou FreeNet ou mesmo o uso de HTTPS ou SSH, podem permitir que o filtro seja ignorado, uma vez que o embaralhamento provocado pelos protocolos em questão faria o conteúdo não conseguir mais ser detectado pelo filtro. Nesse caso, a solução seria impedir o acesso por esses protocolos;


Como vimos, a aplicação dessa técnica não é nada viável em uma estrutura de backbone, uma vez que oneraria demais a comunicação (ele teria que abrir os pacotes, analisar e tudo o mais, o que faria com que demorasse muito a liberação dos pacotes), embora para empresas a técnica seja útil e barata (uma vez que o menor número de dados permite que o processamento não seja tão oneroso).



Mas uma coisa que muitos podem questionar é que os filtros baseados em keycontent não são bons para informação não textual. E nisso eu concordo. Existe um sistema que podemos analisar que pdoeria ser útil, tanto que existem investimentos em o torná-lo prático.



3-) Bloqueio baseado em soma de verificação (checksum):



Para um computador, não importa o conteúdo transmitido: tudo resumem-se a bits, 0s e 1s, informação matemática. E como toda informação matemática, os bits podem sofrer cálculos.



A idéia por trás do sistema de soma de verificação é essa: por meio de algoritmos, os bits em um determinado conteúdo transmitido (não importa se é um filme ou algumas poucas letras) é calculado e dele é obtido um número qualquer. Esse número, chamado de checksum, é enviado ou obtido pela outra ponta da comunicação que pega o mesmo algoritmo e o conteúdo obtido e refaz o cálculo. Uma vez que para obter-se o mesmo valor é necessário que todos os bits sejam exatamente os mesmos que foram mandados originalmente e na mesma seqüência, o fato do checksum obtido não ser o mesmo do conhecido irá determinar que o conteúdo não é o mesmo que o original, e deverá ser descartado.



O uso de checksum é muito comum quando você precisa transmitir grandes quantidades de informações pela rede. Na realidade, quase todos os protocolos conhecidos, ao menos nos níveis mais baixos, possuem soma de verificação como metodologia para correção de erros. Além disso, muitos protocolos de checksum, como SHA, GPG e MD5 são conhecidos e testados pelo tempo, além de facilmente implementáveis e com códigos conhecidos. Isso, ao menos na teoria, permitiria que um protocolo que fizesse um checksum contra conteúdo conhecido como "inapropriado" o fizesse contra qualquer conteúdo copiado via rede e o analisasse contra uma lista de checksums conhecidos como de conteúdos "inapropriados", inutilizado a cópia caso o mesmo "casasse" com um dos checksum em questão.



Ainda assim, essa forma em teoria perfeita de checar conteúdo possui falhas estruturais graves:



  1. Demanda ainda mais poder computacional, pois o tipo de cálculo realizado costuma ser de alto poder computacional (como exemplo, se você baixar um arquivo ISO de uma distribuição Linux, em uma máquina mais ou menos atual levará pelo menos 5 minutos até que o checksum do mesmo seja calculado) e onera excessivamente a comunicação;
  2. Assim como no caso da análise de keycontent, temos o problema da criptografia: quando um processo criptográfico é aplicado a um conteúdo, o mesmo se torna diferente do original, o que invalidaria o checksum, gerando um "falso negativo";
  3. Da mesma forma, conteúdos válidos poderiam sofrer ainda com "falso positivo". Embora os protocolos de checksum procurem evitar o caso de "falso positivo", tentando fazer com que apenas um conteúdo gere um determinado checksum, é razoável supor que, embora muito remota, a chance de um haver "falsos positivos" entre conteúdos em um checksum é algo possível;
  4. Provocar um "falso negativo" em um conteúdo desse é fácil: basta que aja uma alteração, por menor que seja, no conteúdo. Por exemplo: basta que um bit de dados seja adicionado/removido e o checksum irá "falhar", retornando o "falso negativo". Dependendo do tipo de mensagem, esse bit não irá comprometer a mensagem, podendo facilmente ser eliminado;
  5. Como uma forma de tentar reduzir-se as chances de (1) e (4), poderia-se analisar o conteúdo por "frações" do mesmo, gerando-se checksum de cada um deles em um tamanho razoável e, a partir de um deles dando "positivo" o conteúdo inteiro fosse invalidado. Porém, essa tática aumentaria por sua vez a chance de (3), principalmente porque pode ocorrer, conforme o tamanho da amostra que sofrerá a soma de verificação, que conteúdos similares possuam seqüências similares. Ou seja, quanto menor a amostra, mais rápido será a determinação do checksum e menor a chance de que um "falso negativo" seja gerado por remoção (afinal, se o cara remover um frame de um pedaço, os demais continuarão do mesmo jeito), mas maior será a chance de provocar-se um "falso positivo", pois será estatisticamente mais provavel que dois pedaços de dois conteúdos se pareçam;
  6. Esse sistema está extremamente suscetível a mudanças nos protocolos e formatos de informação. Por exemplo: uma música em MP3 é diferente de uma em WMA ou em Ogg Vorbis. Mesmo sendo a mesma música ao ouvirmos-a, o conteúdo é considerado diferente pelo checksum. Existem técnicas que utilizam watermarking, que seria algo similar ao que foi discutido em (5), mas ainda assim o sistema seria suscetível;

4-) Conclusão:



O caso Cicarelli apenas demonstrou o quão inconseqüente uma tomada de atitude judicial mal feita pode se provar e o quanto ela pode prejudicar as pessoas: milhões de vídeos educativos e de entretenimento no YouTube ficaram indisponíveis por 48 horas. Por sua vez, a filtragem mostrou-se inefetiva, pois outros sites receberam o conteúdo e ao mesmo tempo esse conteúdo era levemente alterado sempre, escapando de possíveis filtros como os teorizados aqui. Ainda leverá muito, muito tempo até que computadores sejam capazes de filtrar conteúdo da mesma forma que seres humanos o fazem. E isso caracterizaria censura.



Espero que esse documento comprove o quão difícil seria produzir filtros como os propostos, de modo que as pessoas entendam que esse tipo de filtragem (ao menos com a tecnologia atual) é impraticável para o porte que a Justiça Brasileira deseja, embora para pequeno porte possa ser viável.



Leia, reflita e tire suas conclusões...







powered by performancing firefox

Digg! | links to this post

quarta-feira, janeiro 17, 2007

Memes: Resoluções 2007 e cinco coisas que odeio na net

Desculpem todos, mas estou preparando um post mais interessante. Enquanto isso, vou me atualizando nas Memes da Net. Aqui vou em duas Memes que estão (ou estavam) rolando até bem pouco tempo:

  • Resoluções 2007:
  1. Comprar um Notebook: Sério, estou precisando urgentemente de um, agora no emprego novo meu!!
  2. Começar a pesquisar para um LPI: preciso também, e é também questão de realização profissional
  3. Pagar a faculdade: ter sido financiado pela facu foi ótimo, mas tem seu lado negativo. :-P
  4. Postar mais no blog: eu não sou um problogger e nem pretendo ser, ao menos não tão cedo, mas mesmo assim preciso postar mais no blog;
  5. (Pós virada do ano) Dar o máximo no GuBRo-SP: agora que fui gentilmente aceito como líder, preciso mostrar serviço. E isso ressalta o (1). Não sabe o que é GuBRo-SP? Dá uma olhadinha aqui.
  • Cinco coisas que odeio na Net:
  1. Miguxês: Gente que fala axim já toma um banimento na cara por mim. Tudo bem que a Net exige eficiência, mas custa escrever corretamente para a gente não ser obrigado a decifrar o que está escrito?
  2. Jogos babacas no Orkut, ao menos fora de contexto: quero dizer, é legal você entrar no "Cólera do Dragão no Chuveiro" e participar do "Pergunte ao Shiryu", mas essa praga tem que se disseminar para comunidades mais sérias?!
  3. Spam: se vocês conhecerem alguém que goste de spam, façam um favor a todos nós: internem esse cara!
  4. Fanboys de Windows que não sabem a menor diferença entre um software livre e um gratuíto. Vide site Baboo (sem link: eles não merecem). Quer ser fanboy, por mim tudo bem, mas ao menos saiba o que você está criticando!
  5. Gente mal-educada: gente, existe uma netiqueta para que, afinal de contas? A pior coisa que existe são os trolls. Trolls bons só no RPG e olhe lá!





powered by performancing firefox

Digg! | links to this post

segunda-feira, janeiro 15, 2007

5 coisas que você não sabe sobre mim



Entrando de gaiato na Meme do pessoal da Blogosfera, resolvi colocar aqui cinco coisas sobre mim:
  1. Já fiz teatro, circo e estudei alemão;
  2. Meu primeiro contato com a informática foi aos 4 anos de idade, com um pré-histório MC-1000 (uma espécie de cruza bizarra entre Apple II e TRS-80).;

  3. Sou RPGista inveterado e traduzi materiais de RPG gratuítos da Internet, entre eles o sistema Fudge (aos interessados, o site é http://www.fudgebrasil.cjb.net );



  4. Cheguei a ser mandando para a diretoria quando certa vez uma professora me tomou um livro de informática que estava lendo. Nada demais, se não tivesse míseros 10 anos na época;



  5. Entre os gêneros musicais que mais gosto estão o New Age, Celta, Música de Raiz Brasileira (Tonico e Tinoco, Pena Branca e Xavantinho), Eletrônico, Synthpop, anos 80 e românticos anos 70;

[Atualizando]: Dois fatos adicionais que senti que era relevante

  1. Jogo Xadrez e embora não me considere muito bom, já participei de torneios estaduais quando adolescente;
  2. Sou leitor voraz, sendo que meu hábito de leitura começou aos 9 anos de idade após ler "O Pequeno Príncipe". Atualmente, me acho pelado se saio de casa sem um livro na mochila. O atual é "Crime e Castigo";






powered by

performancing firefox



Digg! | links to this post

quarta-feira, dezembro 27, 2006

Criando uma classe de janela em FLTK2 usando o FLUID

Reblog de um antigo artigo meu sobre programação. Espero que aproveitem.

Criando uma classe de janela em FLTK2 usando o FLUID

Por Fábio Emilio Costa

Simples e multiplataforma, a FLTK (lê-se "fullticks") é uma interface gráfica despretenciosa e que oferece recursos básicos para o seu desenvolvedor. Ela gera programas extremamente enxutos e leves em sua interface gráfica e está disponível em várias das principais plataformas e SOs da atualidade.

Nesse artigo, veremos como desenvolver uma classe de Janela utilizando-se do FLUID, um gerador de interface simplificado que vêm com o FLTK.

Nota: Os exemplos serão apresentados para o Dev-C++ for Windows. Para outros compiladores e ambientes operacionais, leia a documentação do compilador e obtenha maiores informações em http://www.fltk.org e http://www.fltk.net. Apesar disso, os exemplos de programação são todos genéricos, podendo ser usados em qualquer platadforma e compilador.

1-) Obtendo os DevPaks:

O Dev-C++ tem como principais características ser free software (GPL) e ser muito extensível, através dos DevPaks, pacotes especiais instalados no ambiente de desenvolvimento. Se você não tiver o Dev-C++, você poderá o obter em http://www.bloodshed.net/dev.
A primeira coisa é obter o DevPak do FLTK. Ele pode ser obtido em http://www.fltk.net/files/devpak/FLTK2.DevPak. Você também precisará do DevPak de libpthreads, copiado em http://www.fltk.net/files/devpak/libpthread.DevPak. Esses dois pacotes são necessários.

Com o Dev-C++ instalado, basta clicar duas vezes nos arquivos dos DevPak. Instale primeiro o libpthread.DevPak, em seguida o FLTK2.DevPak.

2-) Preparando o Dev-C++:

Você precisará preparar o ambiente, inserindo nele o FLUID. Para isso, clique no menu Ferramentas. Você terá um menu semelhante o abaixo.

No caso, o FLUID já está inserido, mas vejamos como inserí-lo no menu. Escolha a opção "Configurar Ferramentas". Aparecerá uma janela como a abaixo.




Clique em "Adicionar" e você receberá uma nova janela, como a seguinte:

Digite "FLUID" em Título e escolha os caminhos do programa e do diretório de trabalho. Em geral o caminho do programa será C:\Dev-Cpp\bin\fluid.exe, e o diretório de trabalho, C:\Dev-Cpp\bin\. Corrija esses dados conforme sua instalação.

Clique OK. Aparecerá a entrada do FLUID na Janela "Configuração das Ferramentas". Clique OK. O FLUID já deverá estar no menu Ferramentas do Dev-C++.

Agora que o Dev-C++ já está configurado, vamos passar a ver como o FLUID funciona.

3-) Desenhando uma tela no FLUID:

Para começar, chame o FLUID no Menu Ferramentas. Você deverá receber uma janela como a seguinte.

O FLUID exige uma função para poder começar a criar os Widgets (os objetos de Janela). Para colocar uma função no fluid, vá em New | Code | Function/Method.


Você receberá uma janela como a seguinte (você pode ignorar por enquanto as opções e ir direto ao assunto clicando OK):

Com o tempo você poderá ver essas opções. De imediato, ignore-as e vamos para o assunto que é criar a janela: Vá em New | Group | fltk::Window. Isso irá lhe abrir uma janela. Clique duas vezes sobre ela e você irá receber uma janela de configurações do Widget. Sempre que precisar dessa janela para um certo Widget, clique duas vezes sobre ele:



Por enquanto vamos nos ater à aba GUI. Na aba Style você
encontrará configurações relacionadas a cores e fontes do Widget. Na aba
C++, você encontrará configurações expecíficas de C++, como visibilidade do
Widget e por aí afora.



Na aba GUI, para a Window, alteraremos apenas a propriedade Label.
Diferentemente de outras APIs de Interface Gráfica, a FLTK coloca labels em todos
os seus componentes. Na verdade, o componente raiz de todos os demais componentes, fltk::Widget, pode ser usado como um Label caso necessário. No caso,
vamos definir o Label como "Hello World!". As demais propriedades podem ficar como
estão. Clique em OK ou aperte ENTER.



Agora temos uma janela vazia com um título na Janela ("Hello
World!
"). Agora vamos adicionar dois componentes na janela, mais exatamente um
fltk::ReturnButton. Para
isso, clique com o botão direito sobre a Janela. Você irá receber um menu semelhante
àquele aonde você adicionou a função e a Janela. Escolha primeiro text |
fltk::Input. Dimensione-a e posicione-a aonde preferir, como em qualquer
outro ambiente RAD (como o VisualStudio ou o Delphi). Depois de posicioná-lo aonde
desejar, clique duas vezes sobre o Input para chamar a janela de propriedades. O
fltk::Input é como um componente Edit do Delphi ou um
TextBox do VisualStudio. Ele aceita dados e pode alterá-los e tudo o
mais.



Na janela de propriedades do fltk::Input, primeiro
digite em Label "Digite o seu nome:". Depois, vá até Alignment. Perceba que
há quatro setas indicando para as quatro direções básicas (para cima, para baixo, direita
e esquerda). Clique na seta para cima para marcá-la e na seta para a direita para
desmarcá-la. Clique novamente em OK ou pressione Enter. Repare que o label foi parar em
cima do Input e centralizado em relação a ele.



Vamos agora para o fltk::ReturnButton. O fltk::ReturnButton é como um botão normal de outros RAD, mas com uma
diferença fundamental: no Window aonde ele estiver, ele sempre será acionado quando a
tecla Enter for pressionada. Você deve estar pensando agora no botão OK dentro da janela
de propriedades do FLUID: ele é um fltk::ReturnButton. Para
botões normais, a FLTK oferece o componente fltk::Button, sendo
que o fltk::ReturnButton e o fltk::ReturnButton são intercambiáveis.



Clique duas vezes no fltk::ReturnButton. Na janela
de propriedades, vamos mudar apenas o Label para "Hello World!".



Se você seguiu corretamente todos os passos, você deverá ter conseguido um
Form similar a esse:





Se você conseguiu, parabéns! Você criou sua primeira janela no FLUID. Vá em
File | Save e salve a janela criada pelo FLUID.



Nota: Em Windows o FLUID tem um bug no qual não pode
salvar-se nenhuma janela em diretórios que tenham espaço no nome. Tenha sempre isso em
mente ao salvar a janela.





Depois de salvar a janela, vá em File | Write Code. O FLUID irá gerar dois
arquivos com o mesmo nome que você deu para a sua janela, mas com extensões .cxx e .h. Serão esses os arquivos que iremos
usar no projeto. Pode fechar o FLUID após isso.



4-) Criando um Projeto FLTK2:



OK... Agora que fechamos o FLUID, a primeira coisa que precisamos fazer é voltar ao
Dev-C++ e criar um projeto FLTK2 para podermos compilar o código gerado no FLTK.



Voltando ao projeto... Imaginando que tudo tenha sido feito corretamente,
você agora terá dois arquivos, .h.
E agora voltamos ao Dev-C++.



A primeira coisa é ir em Arquivo | Novo | Projeto. Vai
abrir-se uma janela como a abaixo:





Escolha, na guia FLTK2
(Static). Dê um nome qualquer ao projeto nas Opções de Projeto (Por exemplo, Teste). Vai se abrir uma janela normal, solicitando um local para
gravar o arquivo .dev do projeto. Escolha um diretório qualquer
conveniente para salvar este arquivo. Você receberá uma janela como a seguinte:






Perceba que o sistema já lhe gera um main.cpp. Não
iremos o utilizar, mas se quiser compilá-lo para fazer um teste se o FLTK está bem
instalado, pressione F9 ou vá em Executar | Compilar &
Executar. Salve o arquivo se necessário (no diretório escolhido para o projeto!),
e se tudo foi instalado corretamente (e deve ter sido para ter chegado até aqui), você
receberá a seguinte janela:






PS: Os ícones na Barra de Tarefas não são partes da FLTK, e sim de um
Plugin do WinAMP chamado WinAmpBar...



Se estiver tudo OK, voltemos ao projeto. Vamos inserir os dois arquivos gerados pelo
FLUID no projeto. Para isso, copie os arquivos gerados pelo FLUID para o diretório aonde
você salvou o seu projeto. Aproveite e renomeie o arquivo, mudando sua extensão de .cxx para .cpp. Depois, vá até o lado direito,
aonde está o teu projeto e clique com o botão direito. Um menu como o abaixo irá
aparecer. Clique em Adicionar ao Projeto e escolha os arquivos gerados pelo FLUID
(relembrando que o .cxx teve sua extensão alterada para .cpp) .





Após adicionar os arquivos, você terá três arquivos no seu projeto: main.cpp e os arquivos .cpp e .h gerados pelo FLUID. Vejamos o .h (no caso,
teste.h):



// generated by Fast Light User Interface Designer (fluid)
version 2.0002 #ifndef teste_h #define teste_h #include <fltk/Window.h> #include
<fltk/Input.h> #include <fltk/ReturnButton.h> extern "C" { fltk::Window*
make_window(); } #endif



Na verdade, não vamos aproveitar muito desse código. Vejamos agora o .cpp (no caso, teste.cpp):



// generated by Fast Light User Interface Designer (fluid)
version 2.0002 #include "teste.h" fltk::Window* make_window() {
fltk::Window* w; {fltk::Window* o = new fltk::Window(267, 99, "Hello
World!"); w = o;
o->begin(); {fltk::Input* o = new fltk::Input(30, 25,
205, 25, "Digite seu nome:");
o->align(fltk::ALIGN_TOP); }
{fltk::ReturnButton* o = new fltk::ReturnButton(70, 60,
130, 25, "Hello World!"); o->shortcut(0xff0d);
} o->end();
} return w; }



Agora podemos dizer qual será a idéia: perceba que o FLUID gerou os objetos
que fltk::Input, e fltk::ReturnButton usando comandos new, pois
eles são objetos declarados nos headers (cabeçalhos) <fltk/Window.h>, <fltk/Input.h> e
<fltk/ReturnButton.h>, que são importados no
header teste.h. No caso, a idéia será
declarar em teste.h uma classe herdando de
fltk::Window, e dentreo criar um fltk::Input*, e fltk::ReturnButton*, dessa forma usando os comandos já gerados
pelo FLUID para gerar os objetos durante à construção de nossa classe herdada. Na
destruição da mesma, deveremos também lembrar de destruir os objetos fltk::Input*, e fltk::ReturnButton*, devolvendo a memória usada por
ele.



Vamos começar:



5-) Modificando o .h:



Primeiro de tudo, vamos alterar o header teste.h. Para
isso, vamos retirar a linha:



extern "C" { fltk::Window* make_window(); }



E colocar o seguinte código para definirmos a classe:



using namespace fltk; class wHelloWorld:public Window {
private: Input *txtHelloWorld;
ReturnButton *btnHelloWorld; public:
wHelloWorld();
~wHelloWorld(); };



Se você conhece bem C++, deve ter notado que originalmente declaramos que o
header usa o namespace fltk.
Quando falavamos lá em cima em fltk::ReturnButton, queríamos
dizer um objeto ReturnButton no namespace fltk. Com o uso do comando using namespace
fltk, evitamos a necessidade de indicar o namespace toda vez.
Caso você acredite que você possa ter conflito de nomes usando esse método, utilize a
declaração explícita com o fltk::.



Logo em seguida declaramos a classe wHelloWorld,
que herda todos os métodos públicos de fltk::Window. Perceba que
aqui poderíamos fazer sobrecarga dos vários métodos que a FLTK oferece para sua classe
fltk::Window. No caso, porém, não iremos fazer isso. Continuemos,
então.



Em seguida, declaramo dois ponteiros para objetos FLTK como privativos:
ReturnButton
*btnHelloWorld. Esses ponteiros indicarão os objetos que iremos manipular.



Logo abaixo, declaramos o construtor e o destrutor da classe wHelloWorld. Será neles que iremos manipular os objetos, criando-os
antes do uso pelo software e os destruindo quando a janela for destruída.



Se você compilar o programa, você receberá o mesmo "Hello World" visto
anteriormente, já que não implementamos a classe wHelloWorld.
Então vamos fazer isso.



6-) Implementando a classe wHelloWorld:



Agora vamos passar para a implementação da classe wHelloWorld. Antes, porém, vejamos o código gerado pelo FLUID para a
janela em teste.cpp:



// generated by Fast Light User Interface Designer (fluid)
version 2.0002 #include "teste.h" fltk::Window* make_window() {
fltk::Window* w; {fltk::Window* o = new fltk::Window(267, 99, "Hello
World!"); w = o; o->begin();
{fltk::Input* o = new fltk::Input(30, 25, 205, 25, "Digite
seu nome:"); o->align(fltk::ALIGN_TOP);
} {fltk::ReturnButton* o = new
fltk::ReturnButton(70, 60, 130, 25, "Hello World!");
o->shortcut(0xff0d); } o->end();
} return w; }



Perceba que ele começa com uma função chamada make_window(), que retorna um ponteiro para uma fltk::Window. Vamos tirar isso e colocar o nosso construtor:



wHelloWorld::wHelloWorld()
:Window(267,
99, "Hello World!") { Window* w;



Perceba que aproveitamos a declaração da Janela gerada pelo FLUID, e
aproveitamos o ponteiro fltk::Window* w declarado, pois
precisaremos de um fltk::Window* dentro do construtor, e o fltk::Window* w declarado presta-se bem para isso.



Agora, vamos substituir as seguintes linhas:



{fltk::Window* o = new fltk::Window(267, 99, "Hello World!");
w = o; o->begin();



Pelo seguinte código:



w=this; w->begin(); Utilizamos aqui o ponteiro
this para auto-referenciar nosso objeto wHelloWorld específico. Em seguida, chamamos o método (ou
função-membro, se você preferir) begin() de w, lembrando que w foi
inicializado como this, ou seja, como o próprio
objeto sendo criado. Esse método begin() é herdado
por fltk::Window de fltk::Group e indica aonde o FLTK deverá começar a contar os
objetos seguintes como parte da Window. Podemos
dizer, utilizando o jargão do VB.Net, que a classe Window
é um componente coleção (ou um objeto container,
no jargão do Delphi), ou seja, pode "armazenar" dentro dele outros objetos. Tudo que
acontece com ele, acontece aos demais objetos: se ele é desativado, todos os demais
objetos o são. Se ele é destruído, todos os demais o são também (em teoria, mas não custa
nada dar uma reforçada).



Agora vamos inicializar o ponteiro para nossa caixa de texto (ou Input), substituindo o seguinte código:



{fltk::Input* o = new fltk::Input(30, 25, 205, 25, "Digite
seu nome:"); o->align(fltk::ALIGN_TOP); }



por:



txtHelloWorld = new Input(30, 25, 205, 25, "Digite seu
nome:"); txtHelloWorld->align(ALIGN_TOP);



Perceba que a sintaxe de quase todos os objetos FLTK é a mesma



<obj>(<x>,<y>,<l>,<h>,<caption>)



Aonde <obj> é o nome da classe, <x> e <y> indicam a posição aonde o
objeto será inserido dentro do conteiner (no caso, wHelloWorld) em pixels, <l> e <h> indicam respectivamente a
largura e a altura do objeto (também em pixels), e <caption> guarda um texto a ser exibido próximo (ou dentro) do
objeto. No caso, o nosso txtHelloWorld é um Input (equivalente ao TextBox do VB.Net e ao TEdit do Delphi), será
construído a 30 pixels do canto direito e a 25 pixels do topo do conteiner
dele (no caso, wHelloWorld), terá 205 pixels de largura, 25
pixels de altura e exibirá próximo a ele o texto "Digite seu
nome:
".



Você deve estar se perguntando "como o FLTK sabe aonde posicionar o
texto dos objetos?
". Todos os objetos da FLTK possuem um método align() que retorna/define o alinhamento do objeto FLTK específico. Seu
default varia de objeto para objeto, mas em geral para os objetos container
(como Group) fica no topo,
centralizado (ou de outra forma no padrão do gerenciador de janelas), em objetos de
edição (como Output ou RadioButton) à esquerda, centralizado na altura e nos demais casos
(como Label), dentro do
Widget. No caso, utilizamos o comando



txtHelloWorld->align(ALIGN_TOP);



para indicarmos que queremos alinhar o texto do nosso txtHelloWorld acima do mesmo,
centralizado em relação ao Widget.



Nota: para pessoas que vêem do background do Delphi e do VB,
deve ser difícil imaginar o texto como sendo o label do widget. Em ambos os
casos, normalmente o texto equivale ao que vai dentro do widget. Na
verdade, existe uma diferença aqui entre label e valor. O texto
(label) é o texto que indica para o usuário o widget. Já o que o VB e o
Delphi entendem como texto é chamado na FLTK de valor (método value()). Veremos mais sobre isso quando estivermos desenvolvendo o
código que interagem com a janela.



Falta pouco para convertermos a nossa janela do FLUID em classe. Mude o
seguinte código:



{fltk::ReturnButton* o = new fltk::ReturnButton(70, 60, 130,
25, "Hello World!"); o->shortcut(0xff0d); }



Para:



btnHelloWorld = new ReturnButton(70, 60, 130, 25, "Hello
World!");



Perceba que não estaremos aproveitando o código:



o->shortcut(0xff0d); }



Isso porque, como o botão escolhido já é um ReturnButton, ou seja, um Botão acionado quando a tecla Return é pressionada, não há necessidade de definir-se um atalho de
teclado para ele, que é a função do método shortcut().



Agora vamos terminar tudo, substituindo esse código:



o->end(); } return w;



Por este:



w->end();



Perceba que não aproveitamos o return, pois quando
utilizamos construtores é esperado que o mesmo receba o objeto construído ao término de
sua construção.



Com isso terminamos o construtor. O destrutor é ainda mais simples:



wHelloWorld::~wHelloWorld() { delete txtHelloWorld; delete
btnHelloWorld; }



Ou seja, apenas destrói os objetos criados pela nossa classe wHelloWorld.



No fim das contas, esse é o código que deveremos ter ao fim de tudo:



// generated by Fast Light User Interface
Designer (fluid) version 2.0002 #include "teste.h" wHelloWorld::wHelloWorld()
:Window(267, 99,
"Hello World!") { Window* w; w=this;
w->begin(); txtHelloWorld = new Input(30, 25, 205, 25, "Digite seu
nome:"); txtHelloWorld->align(ALIGN_TOP); btnHelloWorld = new ReturnButton(70, 60, 130, 25, "Hello
World!"); w->end(); }



wHelloWorld::~wHelloWorld() { delete
txtHelloWorld; delete btnHelloWorld; }



Mas se você compilar e rodar o programa ainda estaremos recebendo o bendito
HelloWorld! Como fazer para receber a nossa janela? Veremos isso agora:



7-) Chamando a Janela desenhada:



Voltemos agora para o nosso main.cpp. Se você
estiver usando o DevPak correto no Dev-C++, você deverá ter o seguinte main.cpp:



// This is just small FLTK2 application // Now you can
imediately compile&run it in Dev-C++ // Enjoy FLTK2 - Dejan Lekic, dejan@fltk.net,
http://dejan.lekic.org #include <fltk/Window.h> #include <fltk/Widget.h>
#include <fltk/run.h>



using namespace fltk; int main(int argc, char **argv) {
Window *window = new Window(300, 180); window->begin();
Widget *box = new Widget(20, 40, 260, 100, "Hello, World!");
box->box(UP_BOX); box->labelfont(HELVETICA_BOLD_ITALIC);
box->labelsize(36); box->labeltype(SHADOW_LABEL);
window->end(); window->show(argc, argv); return run();
}



Perceba que ele já tem uma janela dentro dele. Vamos modificar o
código para que ele receba nossa Janela e a abra.



Primeiro de tudo, remova todo o código de dentro da função main. Mantenha a definição da função e os parâmetros, e mantenha também
o return run(). Você provavelmente terá algo como:



// This is just small FLTK2 application // Now you can
imediately compile&run it in Dev-C++ // Enjoy FLTK2 - Dejan Lekic, dejan@fltk.net,
http://dejan.lekic.org



#include <fltk/Window.h> #include <fltk/Widget.h>
#include <fltk/run.h> using namespace fltk;



int main(int argc, char **argv) { return run();
}



OK... Agora vamos eliminar todos os #includes desnecessários:
apague as seguintes linhas:



#include <fltk/Window.h> #include
<fltk/Widget.h>



E as substitua por:



#include "teste.h"



Com isso você estará indicando ao sistema que você tem um header
teste.h, que você precisará usar. Lembre-se que é em teste.h que é aonde está a definição da nossa classe wHelloWorld.



Perceba que não removemos o header<fltk/run.h>, pois precisaremos da função run() definida nele, que retorna um int com um
código de erro caso tenha havido uma falha de execução, ou 0 se o programa executou
normalmente.



Agora falta muito, muito pouco. Dentro da função main , escreva este código antes de return
run():



wHelloWorld *frmHelloWorld=new wHelloWorld();
frmHelloWorld->show();



O que fazemos aqui é:





  1. Criar um objeto wHelloWorld chamado frmHelloWorld;





  2. Chamar o método show() do objeto frmHelloWorld, que ele herdou da classe fltk::Window;





Se tudo estiver OK, você tem o seguinte código:



// This is just small FLTK2 application // Now you can
imediately compile&run it in Dev-C++ // Enjoy FLTK2 - Dejan Lekic, dejan@fltk.net,
http://dejan.lekic.org



#include "teste.h" #include <fltk/run.h>



using namespace fltk;



int main(int argc, char **argv) {
wHelloWorld *frmHelloWorld=new wHelloWorld(); frmHelloWorld->show();
return run(); } Se estiver, rode e compile o programa, você deverá
ter uma janela como a seguinte:





8-) Implementando funcionalidades na
Janela:



Agora, porém, tente clicar no Botão "Hello World!" ou pressionar
Return dentro da caixa de texto. Você perceberá que nada acontece! Isso se deve pelo fato
de que não avisamos para o FLTK o que ele deve fazer quando o ReturnButton for clicado. No FLTK, isso é feito através de
callbacks.



Para aqueles que vêm do panorama VB.Net, podemos comparar toscamente o
callback como uma espécie de delegate ao contrário. No delegate, é o
objeto que avisa ao sistema que que algo aconteceu com ele, e é o sistema quem deve ter
uma função para tratar o evento delegado (daí o nome delegate). No
callback, é o sistema quem fornece ao objeto uma função que ele deverá chamar
quando algo acontecer com ele (o que que dizer, mal e mal, callback em
inglês).



Em FLTK, exige-se que o callback tenha a seguinte estrutura:



void <nome_func>(Widget*, void*);



Onde <nome_func> é uma função que recebe dois
parâmetros: um ponteiro para o Widget que disparou o evento (normalmente
não-usado) e um ponteiro void (em geral, é por onde vem a janela aonde está o
Widget).



Além disso, o FLTK, quando usado em classe, exige que os callbacks
não sejam funções membros não-static. Nesse caso restam três opções:





  1. usar funções membro static;





  2. deixar os Widget públicos ou;





  3. usar funções friend;





No caso, adotaremos a terceira opção: até agora não consegui utilizar a
primeira no Dev-C++ (por algum motivo de configuração, creio eu) e a segunda não é das
melhores opções.



Para quem não sabe o que são funções friend, elas são funções
não-membro (ou seja, não fazem parte do objeto) que podem acessar os dados
privativos e protegidos (private e protected). Embora elas violem os
conceitos de OOP, o uso de friend permite alguns recursos interessantes, como no
nosso caso.



Comecemos modificando o teste.h. Nas declarações de #include, adicione as seguintes linhas:



#include <fltk/ask.h> #include <iostream>



Precisaremos da função fltk::message() (declarada
no header <fltk/ask.h>) e do objeto std::string, que
pertence ao namespace std (e que está incluído no header <iostream>).



Para nos facilitar a vida com o string, logo abaixo de:



using namespace fltk;



Inclua essa linha:



using namespace std;



Descendo na definição da classe, na parte public, inclua essa
linha:



friend void HelloClick(Widget* w, void* v);



Perceba que essa função HelloClick possui
exatamente o tipo de parâmetros exigidos por padrão de um callback, como vimos
anteriormente.



Aqui acabamos com a questão da definição de classe. Voltemos para o código.
No construtor da classe wHelloWorld, logo abaixo a criação do
objeto btnHelloWorld, acrescente essa linha:



btnHelloWorld->callback(HelloClick,w);



Nesse caso, utilizamos o método callback do objeto
btnHelloWorld para definir o callback do mesmo. No caso, esse método possui o
seguinte protótipo, definido em <fltk/Widget.h>:



void callback(Callback* c, void* p);



No caso, definimos como Callback* (um ponteiro de
função interno do objeto) nossa função HelloClick (ela é passada como um ponteiro
para a função) e passamos como void* o nosso ponteiro w (lembre-se que w é um ponteiro para o objeto
criado). É importante notar que o ReturnButton herda o método
callback da classe-mãe geral fltk::Widget. Como ela é a classe-mãe de todas as demais, isso quer
dizer que todos os objetos FLTK, sem exceção, possuem métodos callback e, portanto, podem receber funções de callback conforme
a necessidade.



OK. Agora, vá até o fim do código fonte e insira o seguinte código:



void HelloClick(Widget* w, void* v) {
wHelloWorld *to=((wHelloWorld*)v);
string strHelloWorld("Olá,");
strHelloWorld+=to->txtHelloWorld->value();
strHelloWorld+="! Sou um programa em FLTK!";
message(strHelloWorld.c_str());
}



Vamos explicar agora o que isso faz:



Perceba que essa função void HelloClick(Widget* w, void*
v) é declarada de forma semelhante à nossa friend definida na classe. Na
prática, essa é a nossa friend! Ela é ligada pela assinatura da
função (ou seja, ela é uma função void, chamada HelloClick, que recebe um Widget* (um ponteiro
para um Widget)e um void* v (um ponteiro "vazio" - um
ponteiro para alguma coisa qualquer).



A primeira coisa que precisamos fazer é transformar o ponteiro void* v recebido em um ponteiro para a nossa janela.

"Mas ele já não é?", você deve se perguntar.



Sim... e não.



Esse ponteiro aponta para o endereço aonde nossa janela foi alocada,
mas ele não sabe que no caso temos um objeto da classe wHelloWorld. Por isso, precisamos trasformar o nosso void* v em um wHelloWorld* (ou seja, um
ponteiro para um objeto wHelloWorld). Para isso, utilizamos um
cast, como o mostrado na linha abaixo:



wHelloWorld *to=((wHelloWorld*)v);



Perceba a declaração do cast: ele associa ao ponteiro wHelloWorld *to o valor de v, mas alertando
para o sistema que v deve ser entendido como um ponteiro para um
objeto wHelloWorld (wHelloWorld*). Perceba que essa indicação fica em parênteses,
como no caso (wHelloWorld*).



As três próximas linhas criam um objeto std::string
e colocam nele informações:



string strHelloWorld("Olá,");
strHelloWorld+=to->txtHelloWorld->value(); strHelloWorld+="! Sou um programa em
FLTK!";



Perceba que não precisamos usar std::, pois já
declaramos o uso do namespace std no teste.h na linha using namespace std. O objeto
strHelloWorld é inicializado com o texto "Olá,
", e ao pouco vai recebendo outros textos que vão sendo contatenados ao fim do
texto. Na segunda linha está o interessante:



strHelloWorld+=to->txtHelloWorld->value();



Utilizando o método value() do nosso objeto txtHelloWorld, ele pega o texto digitado na caixa de texto no momento
em que o callback for acionado e o concatena ao objeto strHelloWorld criado. Em seguida ele adiciona o fim da saudação.



Depois utilizamos a função não-membro do FLTK message() (ou, no caso de não declarar-se o uso de namespace,
fltk::message()) para exibir o texto em uma caixa de informações
(mais ou menos como uma versão rudimentar do MsgBox() do VB.Net
ou do MessageDlg do Delphi):



message(strHelloWorld.c_str());



Essa função, como dissemos anteriormente, é declarado em <fltk/ask.h>. Ele pode receber dois tipos de parâmetros: um char* que será exibido, ou um texto formatado como na função printf() do C, com os devidos dados a serem exibidos. No caso,
precisamos oferecer uma saída do nosso objeto string strHelloWorld como um char* (ponteiro de
caracteres, o tipo de string do C). Para isso, usamos o método c_str() do objeto strHelloWorld.



Agora, compile e rode o programa. Se tudo deu certo, quando você digitar um texto na
caixa de texto, como:






E pressionar a tecla Return ou clicar no botão
?Hello World!?, você irá receber uma mensagem como a seguinte:






Bem, isso conclui nosso rápido interlúdio na FLTK. Para maiores
informações, a API da FLTK2 é divulgada em http://www.fltk.net. Nesse mesmo site podem ser
obtidos cópias para consulta offline da documentação FLTK (embora levemente
desatualizadas, são muito úteis). Outro site importante também é http://www.fltk.org. Nele você poderá encontrar
informações adicionais sobre a FLTK.



Sobre o Autor:



Fábio Emilio Costa é tecnólogo em Desenvolvimento de Software pelas
Faculdades ASMEC, em Ouro Fino/MG. Pode ser encontrado em fabiocosta0305@yahoo.com.br. Desenvolve a
dois anos em C++ e a um ano e meio em FLTK2 e SQLite, além de desenvolver em PHP e Ruby.



powered by performancing firefox

Digg! | links to this post

quinta-feira, junho 08, 2006

Inclusão digital: ferramenta para o desenvolvimento

Uma pessoa presa a uma cadeira de rodas, na Vila Curuçá. Um garoto de 17 anos, de Cidade Tiradentes. Uma catarinense de 74 anos, também moradora de Cidade Tiradentes. Um peruano refugiado, morador de Guaianases. Um advogado bem sucedido, que mora próximo à Rodovia Raposo Tavares. Um garoto de 23 anos, da Cohab Parada de Taipas. Uma família moradora do Parque do Carmo. Um senhor de 41 anos, de Vila Brasilândia. O que todos eles tem em comum, além de morarem em bairros de periferia da cidade de São Paulo (à exceção do advogado)?

A resposta é: Telecentros. Vinte computadores com acesso à Internet em banda larga, cursos de uso de computadores e possibilidade de uso livre dos mesmos sem custo.

Carlos de Macedo, da Vila Curuçá, provavelmente seria apenas mais um desses milhares de portadores de deficiência que temos no Brasil. Cléber Santos,o jovem da Cidade Tiradentes, talvez tivesse conhecido alguns traficantes, não um dos maiores programadores de todo o mundo. A senhora Mafalda Judith Dal Pozzo, a catarinense moradora de Cidade Tiradentes, muito possivelmente estaria "jogada às traças", como a maior parte dos idosos em nosso país. Alejandro Lara, o peruano de Guaianases, poderia estar totalmente alienado com relação à sua terra natal. O advogado Caio Sérgio Serroni, talvez seria mais um advogado plenamente alienado em relação ao nosso país. Cleideneide de Oliveira, o jovem de Parada de Taipas (sim, o nome é dele), talvez fosse mais um jovem enchendo as estatísticas policiais e as telas do "Cidade Alerta" e do "Brasil Urgente". A família de Dulce e Manoel Apolinário de Souza simplesmente poderia estar gastando seu tempo assistindo Ratinho e outras coisas similares. E Cláudio Vieira poderia ser apenas mais um "peão" da construção civil, apenas mais um.

Mas os Telecentros mudaram a vida de todos eles.

Carlos, depois de participar dos cursos nos Telecentros, tornou-se parte de um importante projeto para a inclusão digital de deficientes físicos. Cléber foi elogiado por Richard Stallman, ex-pesquisador do MIT e fundador do projeto GNU e do Movimento do Software Livre, por sua persistência e vontade de programar. Mafalda pode passar a se corresponder com parentes seus espalhados por lugares tão longes e tão diferentes da realidade de Cidade Tiradentes quanto o Paraná e os Estados Unidos. Alejandro pode tanto receber como enviar notícias para seu primo no Peru. Caio tornou-se um apaixonado pelo projeto dos Telecentros, passando tais valores, assim como os do escotismo (outra de suas paixões) aos seus filhos. Cliedeneide pode arrumar amigos e se socializar, mesmo com dificuldades, ao ponto de um deles lhe ajudar a conseguir um emprego. Os senhores de Parque do Carmo puderam ampliar seus conhecimentos e passar a dialogar melhor com a filha Helena. E Cláudio, de servente de pedreiro e ex-cobrador da CMTC, tornou-se auxiliar técnico do Governo Eletrônico, recuperando a auto-estima e a vontade de lutar.

Vidas mudadas por um telecentro. Destaques da importância da inclusão digital.

Quando fala-se em inclusão digital, todos imaginam que seja importante apenas pela questão do analfabetismo funcional. E, claramente, isso é importante. Castells, em sua verdadeira obra-referência "A Sociedade em Rede", mapeia mudanças nas nossas estruturas sociais para uma tendência de um mundo informacional, aonde todas as operações sócio-político-culturais passarão por redes de informações. Não necessariamente redes digitais, as com enorme participação delas. E Castells, embora quem melhor tenha feito tal análise até agora, não foi o único. Partindo da "Terceira Onda" de Toffler até a "Sociedade Pós-Capitalista" de Drucker, passando pelo "Paradoxo Global" de Naisbitt, todos eles mostram que nossa sociedade está em um processo de mudança de grande porte, no mínimo comparável às mudanças sociais que romperam o feudalismo na Revolução Industrial.

Porém, se imaginarmos que realmente há uma revolução tão grande, não podemos deixar os estratos mais pobres da sociedade de fora, incorrendo no risco de, combinando-se a globalização atual, realizada segundo um modelo que Boaventura de Souza Santos define como "globalização hegemônica", aonde há um "conjunto de trocas desiguas pelo qual um determinado artefato, condição, entidade ou identidade local estende a sua influência para além das fronteiras nacionais e, ao fazê-lo, desenvolve a capacidade de designar como local outro artefato, confição, entidade ou identidade rival." (SOUZA SANTOS APUD SILVEIRA, 2001), à exclusão digital, ela própria já proviniente, de certa maneira, da exclusão social vivida em todo o mundo, mas mais flagrantemente nos países em desenvolvimento, potencializarmos uma "constituição de uma nova classe dirigente, composta dos administradores, formuladores e executores da telemática, (...) uma sociedade partida entre info-ricos e info-pobres", como definido por Arthur Kroker e citado por Ségio Amadeu da Silveira (SILVEIRA, 2001). Essa sociedade será potencialmente mais difícil de ser rompida, já que a informação passará cada vez mais um recurso primário social, como citado por Sérgio Amadeu da Silveira, citando Anthony Smith em Geopolitics of Information (SILVEIRA, 2001).

Dessa forma, é imprencidível analisar a inclusão digital como não apenas formação de mão-de-obra para o mercado de trabalho, incorrendo no erro de outros tantos projetos de "inclusão social". Pois, embora o emprego e o trabalho sejam realmente ferramentas para a inclusão social, a partir do aumento da auto-estima e da participação da pessoa na sociedade, essa inclusão no mercado de trabalho é apenas um dos componentes para uma legítima inclusão social. A inclusão social deve também permitir a participação da pessoa em todos os seus direitos, inclusive o direito à liberdade de expressão. E, em nosso período atual, liberdade de expressão envolve o acesso e a troca de informações através dos meios digitais em geral, e via Internet em particular.

Não é possível esperar por uma ação do mercado. O mercado é regido pelo lucro e pela lei da oferta e da demanda. Principalmente em nosso mundo neoliberal, não podemos ficar esperando o mercado decidir quem pode o que e quando, o que pode acabar dando aos extratos mais pobres de nossa sociedade apenas o high trash, não o high tech, o lixo digital. É necessário realizarmos a mesma constatação definida por Silveira: "o mercado não irá incluir na era da informação os extratos pobres e desprovidos de dinheiro." Isso porque, sendo regido pela ótica capitalista, o mercado visa o lucro e a acumulação de riqueza, o que vai de encontro à necessidade "altruística" que precisa ser identificada para a verdadeira inclusão de tais populações.

Portanto, resta aos governos e ONGs realizar tal inclusão digital.

Podemos imaginar isso de várias formas, inclusive com a participação do mercado. Mas é importante que as rédeas de tal desenvolvimento estejam nas mãos dos governos e das ONGs, de modo que tais projetos não sejam usados pelo mercado como um meio de aumentar a tecno-dependência dessas populações, entendendo-se tecno-dependência como a dependência de uma pessoa ou grupo de pessoas de uma determinada peça de tecnologia para execução de suas atividades, mesmo havendo peças similares tão eficientes quanto à peça na qual o grupo é dependente.

Mas, mais importante, é necessário que tais projetos sejam enraizados nas necessidades das populações em questão, e ao mesmo tempo devendo oferecer-lhes a chance de ver os tipos de expressão que elas poderão exercer por meio da comunicação por meios digitais.

A inclusão digital é importantíssima, poderíamos dizer fundamental, para a formação de uma sociedade crítica para o século XXI. Pelos exemplos que introduziram esse texto, citados no livro digital "Toda essa Gente", do Governo Eletrônico de São Paulo, podemos ver o poder de inclusão que as mídias digitais e a Internet oferecem. Salas de vinte computadores, com acesso em banda larga, de alta velocidade, à Internet permitiram todas as mudanças de vida citadas anteriormente. Jovens tendo oportunidades de crescimento. Adultos desempregados recuperando o emprego. Senhores ganhando auto-estima. Populações normalmente esquecidas nos grotões de nosso país que ganham uma chance de exporem sua voz, normalmente esquecida pela grande mídia e pelas elites de nosso país.

É importante agir. O Brasil já ficou de fora de várias revoluções e de várias mudanças. Não podemos deixar esse bonde passar. Não podemos isolar mais ainda nossos pobres. Ou incorriremos no risco de nos tornar definitivamente uma mera "república de bananas".

BIBLIOGRAFIA:

SOUZA SANTOS, Boaventura de (org) - A Globalização e as ciências sociais APUD SILVEIRA, Sérgio Amadeu da - Inclusão Digital, Software Livre e Globalização Contra-Hegemônica IN SILVEIRA, Sérgio Amadeu da; CASSINO, João (org) - Software Livre e Inclusão Digital, São Paulo: Conrad, 2001

SILVEIRA, Sérgio Amadeu da - Inclusão Digital, Software Livre e Globalização Contra-Hegemônica IN SILVEIRA, Sérgio Amadeu da; CASSINO, João (org) - Software Livre e Inclusão Digital, São Paulo: Conrad, 2001

CASTELLS, Manoel - A Sociedade em Rede, São Paulo: Paz e Terra, 2003

TOFFLER, Alvin - A Terceira Onda, São Paulo: Record, 1986

DRUCKER, Peter - A Sociedade Pós-Capitalistas, São Paulo: Campus, 2000

CASSINO, João (Org) -- Toda Essa Gente, São Paulo: Prefeitura Municipal de São Paulo, 2003, disponível via Internet em http://www.rau-tu.unicamp.br/nou-rau/softwarelivre/document/?code=86, acessado em 15 de outubro de 2004

powered by performancing firefox



powered by performancing firefox



powered by performancing firefox



Technorati Tags: , ,

powered by performancing firefox

Digg! | links to this post

quarta-feira, maio 17, 2006

Revista Veja, Software Livre e Falácias

Como não poderia deixar de ser, a revista "Veja" continua atacando toda atitude do governo atual. No caso atingindo o Software Livre. De maneira extremamente simplista, ela afirma que o fato do governo federal ter apoiado o software livre causou queda do Brasil no ranking dos países que melhor usam TI.

OK... Vamos por partes:

O fato de apoiar o SL não implica necessariamente em queda de produção, senão não teríamos casos como o da NASA, HSBC, Carrefour, Casas Bahias, Pixar, entre outras, tendo tanto sucesso utilizando tecnologia de FLOSS. Na realidade, há pouco investimento nos profissionais nacionais. A maior parte dos profissionais nacionais são pouco preparados para lidar com tecnologias inovadoras. Na realidade, são poucos os profissionais brasileiros preparados para trabalhar com tecnologia em geral, conhecendo premissas básicas de engenharia de software e outros conceitos. Na maioria do empresariado e dos políticos brasileiros, é preferível mandar o dinheiro brasileiro para Redmond e/ou para Bangalore do que investir esse dinheiro no Brasil, na qualificação do profissional de informática do Brasil.

Além disso, a matéria, em um de seus quadros afirma categoricamente:

Ao presentear países vizinhos com programas produzidos pelo governo federal, Lula tirou mercado de empresas brasileiras.

Isso é um erro de quem não conhece Software Livre: na prática, o software produzido e "cedido" em Software Livre não é cedido. Apenas seu pagamento pode vir por outras formas: consultoria, códigos, documentação... Ou seja, tudo isso tem a ver com outras questões, e não apenas de caráter financeiro

Além disso, temos que imaginar que tem pessoas de outros países produzindo e cedendo código por esse mesmo sistema. Temos finlandeses (Linux), Americanos (GNU,OpenOffice.org,...), Alemães (KDE, MySQL), Holandeses (Python/PHP), Dinamarqueses (Rails), e pessoas de todos os cantos do mundo trabalhando nesse grande multirão de desenvolvimento de software chamado Software Livre. E o Brasil está usando software desses países e contribuindo com eles e ao mesmo tempo formando profissionais nacionais capazes de lidar com ele, o que é comprovado pelos casos de Marcelo Tosatti, Alfredo Kojima, Hélio Chissin, Alexandre Oliva, entre outros, estão para provar

O fato de empresas de outros países estarem usando o software produzido no Brasil de maneira livre não implica em que elas não irão pagar nada por ele. Muito provavelmente esses países irão acrescentar coisas ao software. De repente, Argentinos desenvolverão documentação, peruanos acrescentarão códigos, venezuelanos irão depurar. E isso tudo poderá ser acrescentado (na maior parte dos casos) ao software produzido no Brasil.

Mesmo sendo petista, tenho que admitir que SL não pode ser reduzido a um movimento puramente partidário. Existem pessoas mexendo com SL por todos os motivos: altruísmo genuino, ganhos financeiro, conhecimento, expressão artística, aprendizado, desafio, ou até mesmo a pura falta do que fazer! :P Portanto, o argumento da Veja:

A oposição aos programas comerciais – leia-se aí a Microsoft, fabricante do sistema operacional Windows e a maior empresa mundial de software – é uma bandeira do PT.

É falacioso: se chama generalização

A mesma linha contem outra falácia:

A posição está baseada, em parte, na desconfiança ideológica que o partido nutre em relação às grandes corporações capitalistas.

Essa falácia é chamada de ataque ao homem e inclui também generalização e linguagem preconceituosa. Não existe nada que impeça o governo Lula de usar Software Proprietário. No caso, foi feita uma opção pelo Governo Federal em utilizar software livre.
A matéria também desonera o fato do tratamento que é dado ao software proprietário e a tendenciosa predileção por ele. Se não pode existir predileção pelo SL, por lógica também não pode existir pelo Software Proprietário.
Perceba uma questão também, no primeiro parágrafo citado:

A oposição aos programas comerciais – leia-se aí a Microsoft, fabricante do sistema operacional Windows ... (Grifo meu)

Perceba que menciona-se de maneira estranha a Microsoft, em outra falácia lógica (regra pela exceção), que mostra que "todos os softwares comerciais" estão sendo prejudicados, mas na prática é uma questão isolada da Microsoft e de empresas que se associaram diretamente a ela. Existem casos de convivências mais ou menos saudáveis entre o Software Proprietário e Software Livre (e os xiitas vão me matar por dizer isso). IBM, Sun, Oracle, Cisco, Novell, Sybase, Informix, CA... Todas elas são grandes empresas também, tão grandes quanto a MS.

Existe muito que não se fala nesse debate e que a revista Veja, famosa pelos seus "argumentos" e conhecida como um exemplo do que não se fazer como jornalismo (pergunte no Observatório de Imprensa) simplesmente se fez de muda, o que é estranho se considerarmos que o Grupo Abril se beneficia do SL (e creio que não pagou a nenhuma consultoria por isso), como é divulgado pela própria Info Exame (revista do grupo focada em TI). Foco-me nas questões de:
  • Como foi a opção do governo pelo SL;
  • O que levou o país a cair em ranking;
Na primeira questão, gostaria de citar o blog do Fábio Luis (Falcon_Dark):

Livre Acesso por Falcon_Dark
Nenhum governo pode dar-se ao luxo de desconfiar de grandes corporações capitalistas, seja ele brasileiro ou não. Verifica-se facilmente isso buscando informar-se sobre quais são os fornecedores de suprimentos, equipamentos, insumos, software e treinamento do governo. Diversas multi-nacionais estão entre os fornecedores do governo, grandes corporações capitalistas, não só para TI, mas para várias outras áreas. Dizer que o governo opta pelo software livre porque desconfia de grandes corporações é enganoso. Os motivos pelos quais o governo decidiu-se pelo software livre estão listados e explicados publicamente, exatamente para que um debate adulto possa se desenvolver sobre o tema. Talvez o governo anterior não tenha feito esta opção pelo SL porque à época ele não estava maduro o suficiente para os padrões determinados. Talvez o governo anterior tenha decidido que, na época, o custo de implementar SL ainda fosse maior. O fato é que o governo anterior usou software proprietário em escala porque achou que era melhor assim, o atual optou pelo software livre por pensar da mesma forma, ambos agiram como empresas agem quando escolhem o que adotar. É claro que existe um manto ideológico ao redor do SL, e também um manto político. E não é assim com todo o resto, principalmente no tocante à administração pública?

O viés ideológico existe? Sim, realmente existe. Mas o que também existem é:
  1. O amadurecimento contínuo do SL. Temos diversas ferramentas poderosas desenvolvidas "de graça" por pessoas de todo o mundo, como GNU/Linux, OpenOffice.org (que roda em Windows também), as ferramentas Mozilla (Camino, Seamonkey, Thunderbird e Firefox - e que roda em Windows também), o editor GNU EMACS (que roda em Windows também), o editor de imagens GIMP (que... bem, você entendeu o recado). Perceba que "de graça" está entre aspas pois (1) o software livre é livre, mas não necessariamente de casa e (2) quem usa software livre acaba invariavelmente pagando, com tempo de estudo, documentos, apostilas, palestras, e até mesmo em dinheiro...;
  2. Experiências bem sucedidas com o uso de Software Livre para redução de custos e viabilidade tanto técnica quanto social da TI. Casos como os dos Telecentros (São Paulo e Porto Alegre) e de Rio das Ostras e do Paraná (curiosamente citado na matéria da Veja, mas sem mencionar o software livre), e de empresas como Renner, Casas Bahias, Carrefour e Pão de Açúcar comprovam que o Software Livre é viável e que vem fornecendo mercado para muitas empresas de consultoria;
Mas, então, porque cargas-d'água o Brasil caiu em ranking. Vejo isso por dois fatores:
  1. Há muito pouco investimento em educação no Brasil, e menor ainda nas TIC: nós não aprendemos a utilizar o melhor potencial do SL, que é o código, para aprendermos e melhorarmos (e contribuirmos, como é a regra do jogo). Muitas vezes, para nós, o que vale é que as coisas "custam 10 reaus" na barraquinha ching-ling (perceba que mesmo aqui não temos brasileiros :( ). Nossas faculdades não ensinam aos alunos fundamentos básicos de estudo de código ou de desenvolvimento que permitam que o mesmo explore os conhecimentos em potencial armazenado dentro de códigos que custariam milhões de dólares e que estão disponível livremente para estudo. Citando o estudo de David A. Wheeler, pesquisador norte-americano, "More than a Gigabuck: Estimating GNU/Linux's Size"
Particularmente, custaria mais de 1 bilhão de dólares desenvolver esta distribuição GNU/Linux (NT: no caso, a Red Hat 7.1, com todos os pacotes incluídos nela) pelos meios proprietários convencionais nos estados unidos. (....) Além disso o Red Hat Linux 7.1 inclui mais de 30 milhões de linhas reais de Código (Source Line of Code - no caso, descontando-se linhas de comentários e afins), enquanto o 6.2 continha 17 milhões de linhas. Usando a métrica e modelo de custo COCOMO (NT: métrica usada em engenharia de software para estimativas de custo de um software), esse sistema exigiria algo em torno de 8 mil anos-pessoa de tempo de desenvolvimento (comparando-se com os 4.500 anos-pessoa da versão 6.2) (...). Isso tudo graças a um crescente número de programas de software livre/código aberto maduros ou em amadurecimento disponíveis ao redor do mundo. (Tradução minha).
Perceba que estamos falando aqui de mais de 1 bilhão de dólares em valor econômico, pronto para qualquer um usar e, melhor ainda, aprender com ele. São 8 mil anos-pessoa em código disponível para qualquer um que possa entender esse código, o que deveria ser o caso de qualquer um com uma formação universitária em TI (ou, ao menos, qualquer um com formação técnica e dedicação). Mas isso não está acontecendo. Estamos (para variar), perdendo o trem da história.
  1. Iniciativas de inclusão digital das pessoas não vem sendo tomadas ou, quando tomadas, são de maneira pouco crítica e sem respeito a necessidades locais. Projetos como o FUST estão engavetados, por pressões provocadas por causa de decisões políticas equivocadas, muitas delas que procuravam, de maneira capciosa, favorecer a Microsoft. Claro que ela não poderia deixar barato. Citando novamente o Fábio Luis:
Se em lugar de falar de software estivéssemos falando de carros, por exemplo. Poderíamos dizer que uma licitação que busca comprar automóveis de 4 portas deve excluir veículos de 2 portas por definição. Uma empresa que só fabrica automóveis de 2 portas poderia afirmar que o governo não pode pedir carros de 4 portas apenas porque ela não os fabrica? Obviamente não. Mas a Microsoft afirma que o governo não pode querer comprar software livre porque isso a exclui da licitação. Em lugar de oferecer um produto dentro dos parâmetros técnicos que o comprador exige a Microsoft busca mudar as expectativas e necessidades do cliente para que ele compre o produto que ela fabrica.
Em meu post anterior, disse que uma das coisas que me atraiu ao GNU/Linux era justamente isso: ele se adapta a mim, não eu a ele. É ele que tem que atender minhas necessidades, não eu às suas exigências. E parece que nosso amigo Falcon_Dark está de acordo:

Livre Acesso por Falcon_Dark
Uma padaria que precisa de um sistema operacional para seus caixas compra o mesmo software que uma empresa aérea para seus balcões de atendimento. Provavelmente a empresa aérea tem mais chances de conseguir algum tipo de adaptação funcional para seus sistemas, ainda que certamente a pequena padaria pagará um preço maior por cada cópia adquirida. Ao comprar um Windows você paga um preço cobrado pelo desenvolvimento de tudo que está naquela caixinha, não importa se você vai usar aquilo ou não. Talvez você não rode aplicações legadas de Windows95, mas o código para elas está lá em algum lugar e você foi cobrado por elas. (...) O modelo do software livre é mais moderno e busca estar mais atento às reais necessidades do cliente. Em qualquer software livre você pode não só adicionar coisas que seu negócio precisa, mas também pode retirar coisas que você não precisa, o que pode tornar o software bem mais barato. Ainda que a pequena padaria não queira pagar um fornecedor para adaptar um Linux para suas necessidades, ela ainda conta com mais três alternativas. A própria padaria pode adaptar o software, se algum funcionário seu souber como fazer isso. Ela pode pagar para um profissional autônomo fazer isso, o que talvez seja mais barato que as duas alternativas anteriores. Ou ela ainda pode conseguir executar a alternativa mais barata de todas, que é encontrar por aí, na internet, um software que já esteja pronto porque uma pequena padaria de Lisboa passou por esse processo antes, e como o software é livre você pode usá-lo sem problemas.
Justamente aqui reside a oportunidade: "Ela pode pagar para um profissional autônomo fazer isso". Ajustar conforme a necessidade. Com o código, o Céu é o Limite. Existe muito mercado aí em customização de SL, e é entrando nesse mercado que está o bolo. Treinamento e suporte são muito requisitados, e aí está um filão bom e muito interessante para trabalhar-se com SL, até mesmo porque a própria MS não oferece eternamente suporte (o Win98 perdeu esse ano o suporte oficial). É uma tolice não treinar, mas o treinamento, quando visto como investimento, possui grandes compensações e permite uma fácil depreciação e diluição do custo no tempo, muito mais do que a mera compra de licenças (caixinhas). Um bom acordo do tipo SLA (Service Level Agreement - Acordo de Nivel de Serviço) pode ser uma solução que (1) ajuda o cliente a reduzir seus custos no SL, (2) permite um aumento nos lucros da empresa prestadora de suporte, através de satisfação do cliente e rápida resposta e (3) permite um grau enorme de "coopetição", aonde as empresas colaboram entre si e competem entre si, mostrando seus diferenciais mas socorrendo nos momentos de maior necessidade.
Essa é a oportunidade que o Brasil tá perdendo, por falta de capacitação de seus profissionais, não pelo uso de SL.
Espero que tenha ficado clara minha posição... Por favor, comentem e concordem, discordem, acordem ou recordem, mas enfim, não fiquemos parados!


Technorati Tags: , , , ,

powered by performancing firefox

Digg! | links to this post

domingo, maio 07, 2006

Porquê minha opção pelo Software Livre (e de onde eu blogo)...

Esse post está sendo redigido em uma semana na qual o software livre teve um ganho muito importante, mesmo que de maneira indireta: o formato OpenDocument (usado, entre outros, por OpenOffice.org/BROffice.org e KOffice), foi aprovado pela ISO/IEC, tornando-se o padrão ISO 26300 (fonte Wikipedia).
Embora isso possa não querer dizer muita coisa (o caso do padrão OSI de redes serve de exemplo), é uma conquista para os defensores do software livre e dos padrões abertos. Recebido com frieza e até com hostilidade, o OpenDocument começa a se firmar como uma alternativa ao padrão de facto, o .doc da Microsoft.
Para comemorar, a comunidade OpenOffice.org lançou a campanha Get Legal - Get OpenOffice.org, com um selo para ser inserido nos sites/blogs que apóiam o OpenOffice.org (ou chamado no Brasil de BROffice.org, por causa de uma marca registrada e de uma ameaça de processo contra a comunidade OpenOffice.org), estimulando as pessoas a baixarem o OpenOffice.org. Do site:
"De acordo com dados publicados pela Microsoft, 35% de todo software do mundo é potencialmente roubado ou de alguma outra forma ilegal."
Esses dados são verdadeiros e creditáveis, e não existe motivação que justifique a pirataria. Mas o ponto mais interessante da jogada vem a seguir:
"Após anos de tolerância velada à pirataria como uma forma de garantir uma grande fatia de mercado, agora a Microsoft passou à ofensiva para grantir que todas as cópias de seu software são legais."
Isso é fato: a Microsoft se beneficiou muito com a pirataria do seu software. A longo prazo, ela utilizou a estratégia conhecida nos meios de marketing como "fidelização": ao "oferecer" seu sistema de maneiras "facilitadas" (por que não foi adotada proteções anti-cópia desde o começo?), agora ela defende que a pirataria é ruim, chegando até mesmo, por meio de instituições de combate à pirataria, como a BSA da Inglaterra, oferecer recompensas por informações que levem a piratas, principalmente no mundo corporativo.
Mas existe uma alternativa mais honesta, mesmo que não seja boazinha (ninguém disse que a Novell ou a Red Hat estão nessa pelos lindos olhos azuis de Linus Torvalds), que é o GNU/Linux e o software livre em geral.
Cada vez mais o software livre desponta como uma alternativa viável, e não apenas como um plano de futuro ou como um brinquedo de geeks e maníacos por internet, ou como uma coisa para pequenas empresas. Na palestra que dei recentemente e sobre a qual falei nesse blog (disponível no Internet Archive para download) eu mostrei que existem grandes empresas e instituições se envolvendo com o software livre. Fico imaginando que Samuel Klein das Casas Bahias deve ter apoiado o uso de GNU/Linux na sua empresa não apenas por custos iniciais, mas pelo downsizing menor, por não estar atrelados a um fornecedor (se eles quiserem mandar a IBM às favas, sem problema... Existem outros fornecedores).
Agora, tirando tudo isso, o que me levou ao Software Livre?
  1. Aprendo conforme desejo: eu vou usando as ferramentas que quero e indo com elas até eu decidir que está bom;
  2. O computador se adapta a mim, não eu a ele: tendo muitas opções de distros, Interfaces, navegadores, editores, leitores de email... eu sempre consigo achar uma que me agrade mais e que satisfaça as minhas necessidades. Por exemplo, uso EMACS, mas não porque ele seja "o melhor", mas porque para mim, ele satisfaz minhas necessidades. Se meus amigos, por exemplo, preferirem o VI, não vou nem lamentar: free software também é free as in choice (livre como em liberdade de escolha);
  3. Programas Highlander: a verdade é que é muito difícil minar o software livre. Quem foi (como eu) no passado usuário do OS/2 da IBM sabe do que estou falando: o poder mercadológico da MS atropelou o OS/2, mais competente mas menos divulgado. As pessoas que fazem SL, e aqui não falo apenas de desenvolver os programas, mas também de criar documentação, apostilas, cursos, materiais, ferramentas, seminários, "evangelizar" novos usuários, etc... estão nesse jogo pelos mais diversos motivos: aprendizado, diletantismo, grana... cada um decide o seu motivo, mas todos colaboram;
  4. "A regra é clara!": tomo a frase do Arnaldo César Coelho emprestada, pois, mesmo as empresas mais dispostas a "vampirizar" o software livre estão nessa às claras: é uma coisa de todos conhecerem quem é quem. Alguém supunha que a Red Hat poderia permanecer para sempre distribuindo CDs Acho que não. Porém, quando ela criou o Projeto Fedora, deu um espaço. Claro que ela se oxigena em seu Red Hat Entreprise através o Fedora, da mesma forma como no caso de SuSE/OpenSuSE, StarOffice/OpenOffice.org. Mas creia, todos estão cientes do risco;
  5. Desafio: algumas vezes, os desafios de implementar uma nova característica ou recurso no nosso ambiente de uso cotidiano (como instalar uma placa de Wireless, configurar uma impressora ou detectar uma câmera fotográfica digital) torna para mim tudo muito interessante, pois eu sei que estou crescendo como profissional de informática, melhorando minhas capacidades, me tornando mais preparado para o futuro.
Bem, essas são as minhas motivações para usar Software Livre. E as suas, quais são?


PS: De onde eu blogo...

Aproveitando a campanha do pessoal, aqui vai o meu "ponto de blogagem" (existe essa palavra? :D)

Especificações "técnicas":
  • Local: Borda da Mata, MG, Brazil (Latitude: 22º 16' 27" S, Longitude: 46º 09' 55" O);
  • Quando: 07 de maio de 2006 (Domingo)
  • O que:
    • Processador: AMD Semprom 2800+ (2 GHz);
    • Memória: 1GB;
    • HD: 80 GB;
    • Vídeo: 32 MB Compartilhada (SIS 720);
    • Som: On board AC97 compatível;
    • Monitor: Samsung SyncMaster 551v;
    • Mouse: Genius NetScroll Optical (USB);
    • Wireless: DLink DWL-520+;
    • SOs: Dual-boot: Normalmente (99% do tempo) no Mandriva Linux 2006 Free;
    • Programas Úteis: OpenOffice.org, EMACS, XINE, MPD (Music Player Daemon), Mozilla Thunderbird, Mozilla Firefox, Yakuake, Superkaramba;
    • Extensões Úteis (Firefox): Performancing, Yoono toolbar, StumbleUpon, Fasterfox, Flashgot, Flashblock, AddBlock, Add Bookmark Here, CrashRecovery, DiggThis, FoxyTunes, LiveLines, MediaPlayerConectivity, SmoothWeel, TabMix Plus, Save Image in Folder, ReloadEvery;
  • "Acessórios": headset para o Skype (quando uso) ou para quando quero ouvir músicas em paz; porta-trecos com canetas de todos os tipos e outras cositas más; papéis e CDs de diversos tipos espalhados na mesa; fio para a antena de wireless;


powered by performancing firefox

Digg! | links to this post