<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Leandro A. F. Pereira &#187; c</title>
	<atom:link href="http://labs.hardinfo.org/mindcrisis/category/c/feed/" rel="self" type="application/rss+xml" />
	<link>http://labs.hardinfo.org/mindcrisis</link>
	<description>geek em treinamento</description>
	<lastBuildDate>Sat, 29 Oct 2011 11:26:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Parando o tempo</title>
		<link>http://labs.hardinfo.org/mindcrisis/2008/06/10/parando-o-tempo/</link>
		<comments>http://labs.hardinfo.org/mindcrisis/2008/06/10/parando-o-tempo/#comments</comments>
		<pubDate>Tue, 10 Jun 2008 11:45:11 +0000</pubDate>
		<dc:creator>acidx</dc:creator>
				<category><![CDATA[c]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://labs.hardinfo.org/mindcrisis/?p=337</guid>
		<description><![CDATA[Um dos problemas em usar um sistema operacional proprietário, com o Mac OS X, é a abundância de software proprietário, já empacotado e (supostamente) fácil de usar. Isso não é uma coisa ruim per se, afinal se um programa faz o que você precisa, você vai lá e compra; é claro que eu prefiro quando [...]]]></description>
			<content:encoded><![CDATA[<p>Um dos problemas em usar um sistema operacional proprietário, com o Mac OS X, é a abundância de software proprietário, já empacotado e (supostamente) fácil de usar. Isso não é uma coisa ruim <em>per se</em>, afinal se um programa faz o que você precisa, você vai lá e compra; é claro que eu <em>prefiro</em> quando tenho acesso ao código fonte. Ler código dos outros é muito instrutivo. Fora todos os quesitos de liberdade, que nem vem ao caso.</p>
<p>O problema maior, no entanto, é quando uma software house decide parar de suportar um produto. Ou simplesmente a empresa pede falência e não há meios de comprar o software. Felizmente, a maioria desses produtos (que são muito específicos), são daqueles softwares que funcionam por uma quantidade de dias e depois não abrem mais até que se compre a licença.</p>
<p>Por explorarem pequenos nichos de mercado (para uma plataforma não tão disseminada por aí), nem sempre é possível achar soluções paleativas prontas. E na falta (eu desconheço alguma coisa tão boa quanto o IDA Pro para OS X) de um disassembler ou um debugger (para software sem símbolos de debug) é que surgem as soluções mais bizarras.</p>
<p>Esses programas usam a biblioteca padrão C para obter do sistema a data e a hora atual, e fazer um cálculo para determinar se o programa deve continuar funcionando ou não. Geralmente, em UNIX, usa-se as chamadas <em>time()</em> e <em>gettimeofday()</em> para obter essa informação. Como geralmente a biblioteca C não é compilada estaticamente (isto é: soldada ao binário do programa), é possível fazer um truque legal e <strong>parar o tempo</strong>.</p>
<p>O truque é simples e consiste apenas em criar uma biblioteca compartilhada que substitua as chamadas da biblioteca C do sistema. As funções que queremos substituir são simples: apenas retornam (de alguma forma) o UNIX time, portanto podem ser escritas em pouquíssimas linhas de C. Por exemplo, a chamada <em>time()</em> pode ser escrita dessa forma (retornando o UNIX time de agora pouco):</p>
<blockquote><p>int time(void *trash) { return 1213097388; }</p></blockquote>
<p>No caso da chamada <em>gettimeofday()</em>, precisamos de uma estrutura <em>timeval</em> (copiada da página de manual, mas trocamos os tipos <em>time_t</em> e <em>suseconds_t</em> por um <em>unsigned</em>, pois não queremos fazer o #include de cabeçalhos do sistema para evitar que a estrutura e/ou a chamada seja definida e cause um erro de compilação):</p>
<blockquote><p>struct timeval {<br />
unsigned tv_sec;    /* seconds since Jan. 1, 1970 */<br />
unsigned tv_usec;  /* and microseconds */<br />
};</p></blockquote>
<p>Com essa estrutura em mãos, é fácil fazer a função substituta:</p>
<blockquote><p>int gettimeofday(struct timeval *tv, void *trash) {<br />
tv-&gt;tv_sec = 1213097388;<br />
tv-&gt;tv_usec = 0;</p>
<p>return 0;<br />
}</p></blockquote>
<p>Pronto. O artefato capaz de <strong>parar o tempo</strong> está quase construído. Basta compilar.</p>
<p>A parte de compilar uma biblioteca compartilhada depende muito do sistema operacional; consulte o manual do gcc para saber dos específicos. No caso do OS X, é só usar a flag &#8220;-dynamiclib&#8221; e gerar o binário com uma extensão &#8220;.dylib&#8221; (não é realmente necessário, mas é interessante):</p>
<blockquote><p>gcc -dynamiclib -o hiro-nakamura.dylib hiro-nakamura.c</p></blockquote>
<p>Para carregar essa biblioteca junto com o programa também é uma tarefa que depende do sistema operacional. No caso do OS X, usa-se uma combinação de variáveis de ambiente:</p>
<blockquote><p>export DYLD_FORCE_FLAT_NAMESPACE=1<br />
export DYLD_INSERT_LIBRARIES=hiro-nakamura.dylib<br />
export DYLD_BIND_AT_LAUNCH=YES</p></blockquote>
<p>Pronto. Assim que rodar qualquer programa neste shell (no caso, <em>bash</em>, adapte o export para sua concha preferida), o tempo estará congelado.</p>
<p>Yatta! <img src='http://labs.hardinfo.org/mindcrisis/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://labs.hardinfo.org/mindcrisis/2008/06/10/parando-o-tempo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Criando Módulos para o HardInfo</title>
		<link>http://labs.hardinfo.org/mindcrisis/2007/05/26/criando-modulos-para-o-hardinfo/</link>
		<comments>http://labs.hardinfo.org/mindcrisis/2007/05/26/criando-modulos-para-o-hardinfo/#comments</comments>
		<pubDate>Sat, 26 May 2007 13:00:00 +0000</pubDate>
		<dc:creator>acidx</dc:creator>
				<category><![CDATA[c]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[hardinfo]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[projects]]></category>

		<guid isPermaLink="false">http://labs.hardinfo.org/mindcrisis/2007/05/26/criando-modulos-para-o-hardinfo/</guid>
		<description><![CDATA[Com o lançamento da versão 0.4.2 do HardInfo, a API de módulos foi modificada. Ainda não tive tempo de escrever a documentação, mas esse post deve ser uma introdução breve de como se cria um módulo utilizando a nova infra-estrutura. No HardInfo, um módulo consiste em: Uma lista de entradas (cada item da lista é [...]]]></description>
			<content:encoded><![CDATA[<p>Com o lançamento da versão 0.4.2 do HardInfo, a API de módulos foi modificada. Ainda não tive tempo de escrever a documentação, mas esse post deve ser uma introdução breve de como se cria um módulo utilizando a nova infra-estrutura.</p>
<p>No HardInfo, um módulo consiste em:</p>
<ul>
<li>Uma lista de entradas (cada item da lista é mostrado como subitem da árvore na GUI; por exemplo, o módulo &#8220;Devices&#8221; tem as entradas &#8220;Processor&#8221;, &#8220;Memory&#8221;, &#8220;PCI Devices&#8221; e assim por diante)</li>
<li>Cada entrada possui uma função de obtenção de informações e uma função de callback
<ul>
<li>As funções de callback apenas retornam o que foi encontrado, como uma string (usando o formato do GKeyFile da GLib). É garantido que essas funções só serão chamadas após as funções de obtenção</li>
<li>Já as funções de obtenção são as que vasculham o ambiente procurando as informações necessárias</li>
</ul>
</li>
<li>Uma lista de métodos exportados (módulos podem chamar métodos de outros módulos)</li>
<li>Uma lista de dependências de módulos (por causa da chamada de métodos de outros módulos)</li>
<li>Informações de versão, copyright, descrição, etc.</li>
</ul>
<p>É bastante coisa, mas acredite: tudo necessário. Os módulos atuais, embora não estejam com o código mais limpo e simples de entender possíveis, são uma boa fonte de consulta para entender como essas coisas se encaixam.</p>
<p>De qualquer forma, ao incluir o cabeçalho &#8220;hardinfo.h&#8221;, algumas estruturas e funções serão prototipadas. A partir disso, pode-se começar a criar o módulo:<br />
<span id="more-278"></span></p>
<pre>#include "hardinfo.h"

void   scan_entrada(gboolean reload);
gchar *callback_entrada();

static ModuleEntry entries[] = {
 { "Entrada", "entrada.png", callback_entrada, scan_entrada },
};

static gchar *__entrada = NULL;

void
scan_entrada(gboolean reload)
{
   SCAN_START();

   if (!__entrada) {
      entrada = g_strdup("[Entrada]n"
                         "Olá Mundo=n");
   } else {
      g_free(entrada);

      entrada = g_strdup("[Entrada]n"
                         "Refresh=:)n");
   }

   SCAN_END();
}

gchar *callback_entrada()
{
   return __entrada;
}

/*
 * Retorna a lista de módulos. Não é necessário informar o tamanho, pois isso
 * é calculado em runtime.
 */
ModuleEntry *
hi_module_get_entries(void)
{
    return entries;
}

/*
 * O nome do módulo (como será mostrado na interface). O ícone não precisa ser
 * especificado, pois ele é o nome do arquivo ".so", mas com a extensão ".png".
 */
gchar *
hi_module_get_name(void)
{
    return g_strdup("Módulo Exemplo");
}

/*
 * O peso. Usado para selecionar a ordem do módulo na interface. Quanto maior o
 * seu valor (0~255), mais para baixo ficará.
 */
guchar
hi_module_get_weight(void)
{
    return 160;
}

/*
 * Se houver necessidade de inicializar alguma variável do módulo (como criar
 * tabelas hash, listas ligadas, árvores, etc), faça isso aqui.
 */
void
hi_module_init(void)
{
    g_warning("Olá mundo!");
}

/*
 * Chamado quando o usuário pede informações sobre o módulo (Help -&gt; About Modules -&gt;
 * Nome do Módulo).
 */
ModuleAbout *
hi_module_get_about(void)
{
    static ModuleAbout ma[] = {
      {
          .author       = "Foobar da Silva",
          .description  = "Exemplo de módulo para o HardInfo",
          .version      = VERSION,
          .license      = "GNU GPL version 2"
      }
    }; 

    return ma;
}</pre>
<p>Feito isso, é só compilar o módulo. A maneira mais fácil é colocar o módulo no diretório do HardInfo, editar o <tt>Makefile.in</tt> e adicionar o nome do arquivo na variável <tt>MODULES</tt>; e, após isso, rodar o <tt>configure</tt> novamente. Ao executar <tt>make</tt>, seu módulo será compilado também.</p>
<p>Agora é só instalar e executar o HardInfo. Seu módulo deve aparecer automagicamente. Tente apertar o botão &#8220;Refresh&#8221; para ver o que acontece. Monitore também a saída no console, para ver se o Warning é realmente mostrado lá (ou se foi mostrado em uma caixa de diálogo). De agora em diante, basta transformar este módulo em algo útil, obtendo informações sobre o hardware ou software básico. E, claro, não deixe de contribuí-lo: as chances dele ser distribuído em uma nova versão são bem grandes.</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.hardinfo.org/mindcrisis/2007/05/26/criando-modulos-para-o-hardinfo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HardInfo: Network Updater</title>
		<link>http://labs.hardinfo.org/mindcrisis/2007/01/19/hardinfo-network-updater/</link>
		<comments>http://labs.hardinfo.org/mindcrisis/2007/01/19/hardinfo-network-updater/#comments</comments>
		<pubDate>Fri, 19 Jan 2007 23:26:25 +0000</pubDate>
		<dc:creator>acidx</dc:creator>
				<category><![CDATA[c]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[gtk]]></category>
		<category><![CDATA[hardinfo]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[projects]]></category>

		<guid isPermaLink="false">http://labs.hardinfo.org/mindcrisis/?p=251</guid>
		<description><![CDATA[Mais um item riscado da lista de coisas a fazer para o HardInfo 0.4.2 (já disponível no SVN):]]></description>
			<content:encoded><![CDATA[<p>Mais um item riscado da lista de coisas a fazer para o HardInfo 0.4.2 (já disponível no SVN):</p>
<p align="center"><img id="image391" alt="screenshot-network-updater.png" src="http://baator.tia.mat.br:2280/wordpress/wp-content/uploads/2007/01/screenshot-network-updater.png" /></p>
<p align="center"><img alt="screenshot-network-updater-1.png" id="image392" src="http://baator.tia.mat.br:2280/wordpress/wp-content/uploads/2007/01/screenshot-network-updater-1.png" /></p>
]]></content:encoded>
			<wfw:commentRss>http://labs.hardinfo.org/mindcrisis/2007/01/19/hardinfo-network-updater/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Informação de Memória</title>
		<link>http://labs.hardinfo.org/mindcrisis/2007/01/03/informacao-de-memoria/</link>
		<comments>http://labs.hardinfo.org/mindcrisis/2007/01/03/informacao-de-memoria/#comments</comments>
		<pubDate>Wed, 03 Jan 2007 21:15:44 +0000</pubDate>
		<dc:creator>acidx</dc:creator>
				<category><![CDATA[c]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[gtk]]></category>
		<category><![CDATA[hardinfo]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[projects]]></category>

		<guid isPermaLink="false">http://labs.hardinfo.org/mindcrisis/?p=243</guid>
		<description><![CDATA[O gráfico de carga estava disponível no HardInfo desde a primeira versão, mas nunca tive coragem de implementar algo que o usasse, até hoje. Informação de memória:]]></description>
			<content:encoded><![CDATA[<p>O gráfico de carga estava disponível no HardInfo desde a primeira versão, mas nunca tive coragem de implementar algo que o usasse, até hoje. Informação de memória:</p>
<p align="center"><a href="http://baator.tia.mat.br:2280/wordpress/wp-content/uploads/2007/01/meminfo.png"><img alt="thumb-meminfo.png" id="image383" src="http://baator.tia.mat.br:2280/wordpress/wp-content/uploads/2007/01/thumb-meminfo.png" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://labs.hardinfo.org/mindcrisis/2007/01/03/informacao-de-memoria/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Usando o main loop da GLib para liberar memória temporária</title>
		<link>http://labs.hardinfo.org/mindcrisis/2007/01/02/usando-o-main-loop-da-glib-para-liberar-memoria-temporaria/</link>
		<comments>http://labs.hardinfo.org/mindcrisis/2007/01/02/usando-o-main-loop-da-glib-para-liberar-memoria-temporaria/#comments</comments>
		<pubDate>Tue, 02 Jan 2007 17:46:51 +0000</pubDate>
		<dc:creator>acidx</dc:creator>
				<category><![CDATA[c]]></category>
		<category><![CDATA[glib]]></category>
		<category><![CDATA[gtk]]></category>
		<category><![CDATA[hack]]></category>
		<category><![CDATA[idle_free]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://labs.hardinfo.org/mindcrisis/?p=240</guid>
		<description><![CDATA[(English version below.) Quando se programa com GTK+ (ou GLib) em C, muitas vezes faz-se necessário o uso de variáveis temporárias alocadas dinamicamente. O problema é ter que lembrar de liberá-las na hora correta &#8212; ou pior &#8212; ter que usar mais variávies auxiliares, como no exemplo abaixo: gchar *funcao(void) { gchar *temp = g_strdup("sou [...]]]></description>
			<content:encoded><![CDATA[<p><em>(English version below.)</em></p>
<p>Quando se programa com GTK+ (ou GLib) em C, muitas vezes faz-se necessário o uso de variáveis temporárias alocadas dinamicamente. O problema é ter que lembrar de liberá-las na hora correta &#8212; ou pior &#8212; ter que usar mais variávies auxiliares, como no exemplo abaixo:</p>
<pre><code>gchar *funcao(void) {
gchar *temp = g_strdup("sou uma string temporaria");
return g_strdup_printf("%s -> %f", temp, G_PI);
}</code></pre>
<p>Nesse exemplo, a variável temp irá vazar memória, pois ela não foi liberada após a execução do g_strdup_printf e do retorno da função. Uma maneira de resolver isso seria reescrevendo funcao como:</p>
<pre><code>gchar *funcao(void) {
gchar *temp = g_strdup("sou uma string temporaria");
gchar *temp2 = g_strdup_printf("%s -> %f", temp, G_PI);
g_free(temp);
return temp2;
}</code></pre>
<p>Agora está melhor: a variável temp não irá vazar, mas fomos obrigados a usar mais uma variável. A solução que proponho é bem simples, mas requer que seu programa rode na main loop da GLib. É para ser usado apenas em funções de callback. Não é threadsafe. Inclua essas duas pequenas funções em seu programa:</p>
<pre><code>static gboolean __idle_free_do(gpointer ptr) {
g_free(ptr);
return FALSE;
}

void gpointer idle_free(gpointer ptr) {
g_idle_add(__idle_free_do, ptr);
return ptr;
}</code></pre>
<p>Agora podemos reescrever a função teste como:</p>
<pre><code>gchar *funcao(void) {
gchar *temp = idle_free(g_strdup("sou uma string temporaria"));
return g_strdup_printf("%s -> %f", temp, G_PI);
}</code></pre>
<p>Assim a variável temp será liberada logo que o loop da GLib estiver livre para processar eventos. É uma idéia simples e prática&#8230; acho que deveria ser inclusa na GLib por padrão.</p>
<p>(façam o uso que quiser desse código, está em domínio público)</p>
<p><span id="more-240"></span><br />
<a name="english_382"></a><a href="#english_382">Using GLib main loop to free up temporary memory</a></p>
<p>When you program with GTK+ (or GLib) with C, sometimes there&#8217;s a need for temporary dynamically-allocated variables. The problem is to free them in the right time &#8212; or worse &#8212; having to use even more auxiliary variables, like in the example below:</p>
<pre><code>gchar *func(void) {
gchar *temp = g_strdup("i am a temporary string");
return g_strdup_printf("%s -> %f", temp, G_PI);
}</code></pre>
<p>In this example, the temp variable will leak memory, since it was not freed after g_strdup_printf. A way to fix this would be rewriting func as:</p>
<pre><code>gchar *func(void) {
gchar *temp = g_strdup("i am a temporary string");
gchar *temp2 = g_strdup_printf("%s -> %f", temp, G_PI);
g_free(temp);
return temp2;
}</code></pre>
<p>Much better: temp won&#8217;t leak anymore, but we had to use another variable. I propose a simpler solution, but it requires that your program runs in the GLib main loop. It should be used only on callback functions and is not threadsafe. Include these two tiny functions in your program:</p>
<pre><code>static gboolean __idle_free_do(gpointer ptr) {
g_free(ptr);
return FALSE;
}

void gpointer idle_free(gpointer ptr) {
g_idle_add(__idle_free_do, ptr);
return ptr;
}</code></pre>
<p>Now we can rewrite func as:</p>
<pre><code>gchar *func(void) {
gchar *temp = idle_free(g_strdup("i am a temporary variable"));
return g_strdup_printf("%s -> %f", temp, G_PI);
}</code></pre>
<p>This way the memory will be freed as soon as GLib gains control and the main loop is ready to process events.</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.hardinfo.org/mindcrisis/2007/01/02/usando-o-main-loop-da-glib-para-liberar-memoria-temporaria/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Novo HardInfo a caminho</title>
		<link>http://labs.hardinfo.org/mindcrisis/2007/01/02/novo-hardinfo-a-caminho/</link>
		<comments>http://labs.hardinfo.org/mindcrisis/2007/01/02/novo-hardinfo-a-caminho/#comments</comments>
		<pubDate>Tue, 02 Jan 2007 17:26:08 +0000</pubDate>
		<dc:creator>acidx</dc:creator>
				<category><![CDATA[c]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[gtk]]></category>
		<category><![CDATA[hardinfo]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[projects]]></category>

		<guid isPermaLink="false">http://labs.hardinfo.org/mindcrisis/?p=239</guid>
		<description><![CDATA[Fiz mais algumas limpezas e reorganizações no HardInfo, afim de prepará-lo para a versão 0.4.2 (que deve ser lançada em breve). As mudanças para a versão 0.4.1 são muitas, como pode-se ver na página de coisas a fazer. Dentre as novidades, destaco: Ícones do Projeto Tango Reorganização dos módulos Adição de benchmark de FPU Possibilidade [...]]]></description>
			<content:encoded><![CDATA[<p>Fiz mais algumas limpezas e reorganizações no HardInfo, afim de prepará-lo para a versão 0.4.2 (que deve ser lançada em breve). As mudanças para a versão 0.4.1 são muitas, como pode-se ver na página de <a href="http://hardinfo.berlios.de/web/Todo">coisas a fazer</a>. Dentre as novidades, destaco:</p>
<ul>
<li>Ícones do <a href="http://www.tango-project.org">Projeto Tango</a></li>
<li>Reorganização dos módulos</li>
</ul>
<div style="text-align: center"><img id="image378" alt="hardinfo-module-features.png" src="http://baator.tia.mat.br:2280/wordpress/wp-content/uploads/2007/01/hardinfo-module-features.png" /></div>
<ul>
<li>Adição de <a href="http://www.fourmilab.ch/fbench/fbench.html">benchmark de FPU</a></li>
<li>Possibilidade de salvar os resultados do benchmark como imagem (com barras de porcentagem relativa)</li>
</ul>
<div style="text-align: center"><img id="image380" alt="cpu-zlib.png" src="http://baator.tia.mat.br:2280/wordpress/wp-content/uploads/2007/01/cpu-zlib.png" /></div>
<ul>
<li>Possibilidade de copiar as informações para a área de transferência</li>
<li>Escolha do formato do relatório (texto puro ou HTML)</li>
<li>Módulos podem exportar métodos. Outros módulos podem chamá-los. Isso adicionou um pouco de complexidade no carregamento dos módulos, já que há verificação de dependências</li>
<li>Bugfixes (todos os reportados por email e pelos bugtrackers do Ubuntu e Debian)</li>
<li>Nova API de módulos (mais eficiente e madura que a anterior, embora incompatível)</li>
</ul>
<p>Todas as novidades mencionadas aqui (e na página de coisas a fazer do projeto) estão disponíveis no repositório Subversion. Quem tiver a possibilidade de testar, por favor o faça.</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.hardinfo.org/mindcrisis/2007/01/02/novo-hardinfo-a-caminho/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Abrindo o browser padrão&#8230;</title>
		<link>http://labs.hardinfo.org/mindcrisis/2006/10/27/abrindo-o-browser-padrao/</link>
		<comments>http://labs.hardinfo.org/mindcrisis/2006/10/27/abrindo-o-browser-padrao/#comments</comments>
		<pubDate>Fri, 27 Oct 2006 16:00:20 +0000</pubDate>
		<dc:creator>acidx</dc:creator>
				<category><![CDATA[c]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[glib]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://labs.hardinfo.org/mindcrisis/?p=225</guid>
		<description><![CDATA[Essa tarefa é um pouco chata em ambientes Unix: não há uma maneira padrão (salvo o Portland, que ainda não deve estar disponível na base já instalada), e perguntar para o usuário qual o browser dele não é uma opção. A rotina abaixo deve ser suficiente e funcionar bem em qualquer programa que use a [...]]]></description>
			<content:encoded><![CDATA[<p>Essa tarefa é um pouco chata em ambientes Unix: não há uma maneira padrão (salvo o Portland, que ainda não deve estar disponível na base já instalada), e perguntar para o usuário qual o browser dele não é uma opção. A rotina abaixo deve ser suficiente e funcionar bem em qualquer programa que use a GLib. Em suma, ela vai tentando abrir a URL fornecida com browsers conhecidos, tentando com o já citado Portland (xdg-open), gnome-open, kfmclient (konqueror), dentre outras opções. Se tudo for esgotado, uma mensagem é mostrada ao usuário dizendo que não foi possível encontrar um browser.</p>
<p><code /></p>
<pre>void
open_url(gchar *url)
{
const gchar *browsers[] = { "xdg-open", "gnome-open",
"kfmclient openURL", "sensible-browser",
"firefox", "epiphany", "galeon", "mozilla",
"opera", "konqueror", "links -g", NULL};
gint i;

for (i = 0; browsers[i]; i++) {
gchar *cmdline = g_strdup_printf("%s '%s'", browsers[i], url);

if (g_spawn_command_line_async(cmdline, NULL)) {
g_free(cmdline);
return;
}

g_free(cmdline);
}

g_warning("Couldn't find a Web browser to open URL %s.", url);
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://labs.hardinfo.org/mindcrisis/2006/10/27/abrindo-o-browser-padrao/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Delay em aplicações GTK+</title>
		<link>http://labs.hardinfo.org/mindcrisis/2006/10/15/delay-em-aplicacoes-gtk/</link>
		<comments>http://labs.hardinfo.org/mindcrisis/2006/10/15/delay-em-aplicacoes-gtk/#comments</comments>
		<pubDate>Sun, 15 Oct 2006 16:14:15 +0000</pubDate>
		<dc:creator>acidx</dc:creator>
				<category><![CDATA[c]]></category>
		<category><![CDATA[glib]]></category>
		<category><![CDATA[gtk]]></category>
		<category><![CDATA[hack]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://labs.hardinfo.org/mindcrisis/?p=221</guid>
		<description><![CDATA[Se desenvolve aplicações em GTK+, certamente já sentiu necessidade de colocar um pequeno delay dentro de um callback. O problema é que se o delay demorar mais que 10ms, o usuário pode perceber e a interface vai travar, o que não é nada agradável. A solução abaixo é bem simples e permite que seu código [...]]]></description>
			<content:encoded><![CDATA[<p>Se desenvolve aplicações em GTK+, certamente já sentiu necessidade de colocar um pequeno delay dentro de um callback. O problema é que se o delay demorar mais que 10ms, o usuário pode perceber e a interface vai travar, o que não é nada agradável.</p>
<p>A solução abaixo é bem simples e permite que seu código fique parado por (pelo menos) dados milisegundos, sem parar o loop principal do GTK+. Está em C, mas usar a mesma técnica em outra linguagem é trivial:</p>
<blockquote>
<pre>static gboolean __nonblock_cb(gpointer data)
{
gtk_main_quit();
return FALSE;
}

void nonblock_sleep(guint msec)
{
g_timeout_add(msec, (GSourceFunc)__nonblock_cb, NULL);
gtk_main();
}</pre>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://labs.hardinfo.org/mindcrisis/2006/10/15/delay-em-aplicacoes-gtk/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Servidor de Música (DAAP)</title>
		<link>http://labs.hardinfo.org/mindcrisis/2006/09/24/servidor-de-musica-daap/</link>
		<comments>http://labs.hardinfo.org/mindcrisis/2006/09/24/servidor-de-musica-daap/#comments</comments>
		<pubDate>Sun, 24 Sep 2006 14:08:45 +0000</pubDate>
		<dc:creator>acidx</dc:creator>
				<category><![CDATA[c]]></category>
		<category><![CDATA[daap]]></category>
		<category><![CDATA[musica]]></category>
		<category><![CDATA[patch]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://labs.hardinfo.org/mindcrisis/?p=217</guid>
		<description><![CDATA[Sábado instalei o mt-daapd, para servir música para a minha pequena LAN/WLAN. Funciona perfeitamente e acaba com o problema de &#8220;onde estão meus CDs de música?&#8221;, ou &#8220;onde coloquei aquelas MP3?&#8221;. Deu um pouco de trabalho para rodá-lo no servidor, já que não queria utilizar o howl (problemas no licenciamento) e sim o avahi, e [...]]]></description>
			<content:encoded><![CDATA[<p>Sábado instalei o <a href="http://mt-daapd.org">mt-daapd</a>, para servir música para a minha pequena LAN/WLAN. Funciona perfeitamente e acaba com o problema de &#8220;onde estão meus CDs de música?&#8221;, ou &#8220;onde coloquei aquelas MP3?&#8221;. Deu um pouco de trabalho para rodá-lo no <a href="http://tia.mat.br">servidor</a>, já que não queria utilizar o <a href="http://www.porchdogsoft.com/products/howl/">howl</a> (problemas no licenciamento) e sim o <a href="http://avahi.org">avahi</a>, e o <a href="http://willrea.be/mt-daapd/mt-daapd-stable-avahi.diff">patch disponível na web</a>¹ tinha alguns problemas; fuçando no fonte, arrumei os problemas e estou aqui, ouvindo um pouco de <a href="http://www.boaweb.co.uk">bôa</a>.</p>
<p>Se alguém interessar, mando o patch corrigido.</p>
<p>Ah, sim, estou usando o <a href="http://gnome.org/projects/rhythmbox">Rhythmbox</a> como cliente. O <a href="http://banshee-project.org">Banshee</a> também funciona com <a href="http://en.wikipedia.org/wiki/Digital_Audio_Access_Protocol">daap</a>, mas não há suporte à playlists remotas. Existem alguns clientes em Java (como o <a href="http://getittogether.sourceforge.net/">Get it Together</a>), mas chegam a ser mais pesados que o próprio iTunes. Alguma sugestão leve e multiplataforma? A máquina do meu irmão só tem 256MB de RAM&#8230;</p>
<p><strong>Update: </strong>Coloquei o patch <a href="http://tia.mat.br/~leandro/misc/mt-daapd-0.2.4-avahi-patchfix.diff">aqui</a>. Aplique primeiro (¹), depois este.</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.hardinfo.org/mindcrisis/2006/09/24/servidor-de-musica-daap/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>SDL Corruption + Audio</title>
		<link>http://labs.hardinfo.org/mindcrisis/2006/08/22/sdl-corruption-audio/</link>
		<comments>http://labs.hardinfo.org/mindcrisis/2006/08/22/sdl-corruption-audio/#comments</comments>
		<pubDate>Wed, 23 Aug 2006 00:07:59 +0000</pubDate>
		<dc:creator>acidx</dc:creator>
				<category><![CDATA[c]]></category>
		<category><![CDATA[demo]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://labs.hardinfo.org/mindcrisis/?p=215</guid>
		<description><![CDATA[Nessa altura do campeonato, todo mundo já deve ter visto o Corruption, aquele demo para o PC-XT que toca vídeo em tela cheia usando uma placa CGA. Mike Melanson, do blog &#8220;Breaking Eggs And Making Omelettes&#8221;, fez a engenharia reversa do formato e escreveu um player para o vídeo que executa em Unix com o [...]]]></description>
			<content:encoded><![CDATA[<p>Nessa altura do campeonato, todo mundo já deve ter visto o <a href="http://www.oldskool.org/pc/8088_Corruption">Corruption,</a> aquele demo para o PC-XT que toca vídeo em tela cheia usando uma placa CGA. Mike Melanson, do blog <a href="http://multimedia.cx/eggs/sdl-corruption-corrected/">&#8220;Breaking Eggs And Making Omelettes&#8221;,</a> fez a engenharia reversa do formato e escreveu um player para o vídeo que executa em Unix com o SDL.</p>
<p>Senti falta do som, então fiz um patch rápido para adicionar suporte à ele.</p>
<p>Para testar, baixe o demo no <a href="http://www.oldskool.org/pc/8088_Corruption">site dele</a>, a <a href="http://multimedia.cx/sdl-corruption/">fonte aqui</a> e o <a href="http://tia.mat.br/~leandro/misc/sdl_corruption_audio.c">sdl_corruption_audio.c</a>. Compile com <tt>gcc -o bla sdl_corruption_audio.c -lSDL</tt>. Divirta-se.</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.hardinfo.org/mindcrisis/2006/08/22/sdl-corruption-audio/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.410 seconds -->

