Well, it's far longer than what you might think.
The Damascus steel (http://en.wikipedia.org/wiki/Damascus_steel) already contains nano structures in it. The steel making process to make the Damascus steel started as early as the 3rd century.
You can read details of the nano structure here: http://www.crystalresearch.com/crt/ab40/905_a.pdf
Until now, the process of making Damascus steel has not been rediscovered. The process itself was lost probably due to various reasons. Read the Wikipedia entry above for that.
What is interesting from this, is that we are not as advanced as we thought compared to older civilization. Are we starting to rediscover what ancient human did thousands of years ago?
Wednesday, October 30, 2013
Thursday, September 5, 2013
Mediterranean Missile Test Detected by Voronezh-DM Radar?
This news: http://en.rian.ru/military_news/20130904/183151257/Russia-Defense-Ministry-Israel-Playing-With-Arms-After-Israel-Launch.html
mentions that the missile launch (which was described as a test launch by both Israel and USA) was detected in Armavir region of Russia. This is the relevant news quote:
Now, if you look at what radar installation is in Armavir, you would find this: http://en.wikipedia.org/wiki/Voronezh_radar. This means that the Voronezh-DM radar is working as "advertised". It's powerful enough to detect ballistic object(s) thousands of miles away. Feel free to disagree in the comment section :-)
mentions that the missile launch (which was described as a test launch by both Israel and USA) was detected in Armavir region of Russia. This is the relevant news quote:
The launch was detected at 10:16 a.m. Moscow time (6:16 a.m. GMT) by radar in the southern Russian city of Armavir
Now, if you look at what radar installation is in Armavir, you would find this: http://en.wikipedia.org/wiki/Voronezh_radar. This means that the Voronezh-DM radar is working as "advertised". It's powerful enough to detect ballistic object(s) thousands of miles away. Feel free to disagree in the comment section :-)
Friday, August 9, 2013
[New Article over at Infosec Institute] Introduction to Automated Captcha Solving
My article on (introduction to) solving captcha automatically is online just now over at: http://resources.infosecinstitute.com/introduction-to-automated-captcha-solving/
I hope it adds into your repertoire if you haven't know it yet :-).
I hope it adds into your repertoire if you haven't know it yet :-).
Friday, July 19, 2013
Stack Imbalance on .NET P/Invoke
The stack imbalance warning when debugging .NET code which used P/Invoke to call DLL function is mostly caused by wrong parameter calling convention. This post explains in more detail. The default parameter calling convention when using the dllimport attribute is stdcall calling convention, as you can see in this link: http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute.callingconvention(v=vs.100).aspx. This is the relevant excerpt:
This is the DLL function declaration in C:
set_log_filename() function calling convention to "cdecl" in the C# code above. After this, there is no more stack imbalance warning during debugging.
The default value for the CallingConvention field is Winapi, which in turn defaults to StdCall convention.This caused the stack handling becomes incorrect if you don't set the calling convention in your P/Invoke function declaration. Below is an example on how to do it right.
This is the DLL function declaration in C:
#ifdef __cplusplus extern "C" { #endif __declspec(dllexport) void set_log_filename(char* log_file_path); #ifdef __cplusplus } #endifand this is the P/Invoke function declaration in C#:
DllImport("captcha_solver_dll.dll", CallingConvention = CallingConvention.Cdecl)] public static extern void set_log_filename(string log_file_path);As you can see, I set the
Tuesday, June 11, 2013
Thinking of PlayStation 4 (PS4) Cluster
PS4 is finally unveiled along with its hardware specification. It would probably be a very nice system for HPC cluster, despite not officially. But there are several matters that I'm going to evaluate:
- The problem set that I'm planning to tackle involves Computational Fluid Dynamics that would be "enriched" with lot's of chemical equations as constraints in the not so distant future. Is this kind of workload suit the architecture? Moreover, the connectivity speed (max at GbE) between nodes of PS4 must be taken into account. Therefore, as Jack Dongarra, et.al put it (http://www.netlib.org/lapack/lawnspdf/lawn185.pdf), only compute intensive algorithm is best suited to game console HPC cluster. Because, only on problem types where you can keep the node busy and don't communicate intensively with each other--read within the GbE bandwidth--the game console HPC cluster would make sense. This means applications that inherently have a lot of "chatter" are best kept out of this kind of system.
- Installing Linux on the PS4 nodes. Is this going to be supported? or will it require some hacks? Well, probably Sony puts TPM hardware in the motherboard to prevent tampering with the (UEFI???) firmware. But, yeah, maybe I could do something about it?
This is just a food for thought at the moment but I think I'm going to go for it once PS4 is available. It would be worth trying. Another added "bonus" is the hUMA support in the machine (http://www.gamasutra.com/view/feature/191007/inside_the_playstation_4_with_mark_.php) is very intriguing for me. Despite AMD Kaveri CPUs would have them as well, it's much more interesting in PS4, given that the latter has 8GB GDDR5 main memory :D
Update:
----------
Well, I ended up buying four Gigabyte Brix with Celeron 2955U CPUs (see: http://www.gigabyte.com/products/product-page.aspx?pid=4743#sp). It costs me around $1K along with 4GB RAM per-node at todays exchange rate. The unit itself supports up-to 16 GB RAM per-node. Therefore, I would be able to upgrade the units RAM once I'm playing around with "big data". Anyway, what's interesting is because Celeron 2955 CPU is actually a Haswell CPU, despite its meager 1.4GHz frequency.
Update:
----------
Well, I ended up buying four Gigabyte Brix with Celeron 2955U CPUs (see: http://www.gigabyte.com/products/product-page.aspx?pid=4743#sp). It costs me around $1K along with 4GB RAM per-node at todays exchange rate. The unit itself supports up-to 16 GB RAM per-node. Therefore, I would be able to upgrade the units RAM once I'm playing around with "big data". Anyway, what's interesting is because Celeron 2955 CPU is actually a Haswell CPU, despite its meager 1.4GHz frequency.
Saturday, May 25, 2013
"Process Identifier" Support in x86-64/x64 CPUs TLB
Recent x86-64 CPUs--at least from Intel--supports a sort of process identifier in the Translation Look-aside Buffer (TLB). This is important for multiprocessing in user mode, i.e. supporting more than one process running in user mode and switching between them without invalidating and flushing the TLB.
In ARMv6 architecture and above, there is an Application Space IDentifier (ASID) hardware that identifies the process which owns an entry in the TLB. This kind of support in x86/x86-64 CPUs is long overdue. Very probably because of the need to preserve compatibility with older OS running on the platform.
However, in newer x86-64 CPUs, there is a new "field" in the CR4 control register called Process-Context IDentifier Enable (PCIDE). This field controls whether Process-Context IDentifier (PCID) is enabled in the TLB or not. The value of the PCID for the "current" process is stored in CR3 register, in bits 0 to 11 (12-bits in total). This implies that the TLB can store up-to 4KB unique PCIDs.
You can read Intel64 Software Developer Manual Volume 3, section 4.10.1 Process-Context Identifiers (PCIDs) for the details. These two articles are also helpful:
http://linuxeco.com/?p=488
http://linuxeco.com/?page_id=2
PS: Thanks to Johan over at linkedin for the links ;-)
In ARMv6 architecture and above, there is an Application Space IDentifier (ASID) hardware that identifies the process which owns an entry in the TLB. This kind of support in x86/x86-64 CPUs is long overdue. Very probably because of the need to preserve compatibility with older OS running on the platform.
However, in newer x86-64 CPUs, there is a new "field" in the CR4 control register called Process-Context IDentifier Enable (PCIDE). This field controls whether Process-Context IDentifier (PCID) is enabled in the TLB or not. The value of the PCID for the "current" process is stored in CR3 register, in bits 0 to 11 (12-bits in total). This implies that the TLB can store up-to 4KB unique PCIDs.
You can read Intel64 Software Developer Manual Volume 3, section 4.10.1 Process-Context Identifiers (PCIDs) for the details. These two articles are also helpful:
http://linuxeco.com/?p=488
http://linuxeco.com/?page_id=2
PS: Thanks to Johan over at linkedin for the links ;-)
Monday, May 6, 2013
Dr. Dobbs Article on Buffer Overflow Prevention with GCC
This article: http://www.drdobbs.com/security/anatomy-of-a-stack-smashing-attack-and-h/240001832 is very helpful for *NIX developer working with GCC compiler(s), especially those targeting x86_64 CPU architecture.
The article goes to great length explaining how the buffer overflow protection is built into GCC. The protection is known as GCC Stack Smashing Protector (SSP).
The article goes to great length explaining how the buffer overflow protection is built into GCC. The protection is known as GCC Stack Smashing Protector (SSP).
Saturday, May 4, 2013
Alternative Way to Store Information -- Quipu
Chinese, Japanese or Korean "writings" are exotic but all of them are still writings as we know it.
How about this: http://en.wikipedia.org/wiki/Quipu.
Quipu is entirely different. What makes me really amazed is that it proved that you don't need the "writing system as we know it" to store information. Thus, to build complex stuffs or develop complex system. Well, Quipu is a "sort of" writing but it's far more different than what other cultures have developed over the last several millenia. It's an original idea, an out-of-the box solution to store and presumably transmit information.
How about this: http://en.wikipedia.org/wiki/Quipu.
Quipu is entirely different. What makes me really amazed is that it proved that you don't need the "writing system as we know it" to store information. Thus, to build complex stuffs or develop complex system. Well, Quipu is a "sort of" writing but it's far more different than what other cultures have developed over the last several millenia. It's an original idea, an out-of-the box solution to store and presumably transmit information.
Monday, April 29, 2013
ARM Assembly Language Tutorial
For some reason, I really keen on using assembly language in Raspberry Pi because it's an entirely new machine architecture for me--despite my past effort on GameBoy Advance (GBA) which results only on HelloWorl application ;). So, interest on ARM is back.
I've been reading a couple of ARM assembly language tutorials so far, but I think the best for complete newbie is this one: http://www.coranac.com/tonc/text/asm.htm. It centered around "guess what?" GBA. It's one of the best that describes GNU assembler on ARM architecture I think.
Another great ARM assembly tutorial was made by the late Fravia: http://www.woodmann.com/fravia/The%20ARM%20Processor.htm. The images links are broken in that link, so just download the ZIP file and view the article locally. That way, the images links would be fine.
I've been reading a couple of ARM assembly language tutorials so far, but I think the best for complete newbie is this one: http://www.coranac.com/tonc/text/asm.htm. It centered around "guess what?" GBA. It's one of the best that describes GNU assembler on ARM architecture I think.
Another great ARM assembly tutorial was made by the late Fravia: http://www.woodmann.com/fravia/The%20ARM%20Processor.htm. The images links are broken in that link, so just download the ZIP file and view the article locally. That way, the images links would be fine.
Friday, April 26, 2013
Driver Signing for Windows Vista/7/Server 2008/8 (x86 and x64)
Details about driver signing and signing mechanism for other code running in kernel mode privilege in Windows Vista or newer (both x86 and x64) is in this link: http://msdn.microsoft.com/en-us/library/windows/hardware/gg487317.aspx
I observed that x64 versions on Windows have a better kernel mode code authentication enforcement via driver signing compared to the x86 version.
I observed that x64 versions on Windows have a better kernel mode code authentication enforcement via driver signing compared to the x86 version.
Friday, March 15, 2013
GTK+ Development for Raspberry Pi
After developing GTK+ applications (to run on Raspberry Pi) for more than 2 months, I found that it's much more productive to do most of the development and preliminary testing on my laptop. Once I'm done with the preliminary tests, I transfer the code to Raspberry Pi for native compilation. Most of the time the code runs without a hitch but in several rare occasions, I did find some minor bugs on my code once the code runs on Raspberry Pi. This is one BUG example:
The reason I'm doing this kind of development is simply time. It takes too much time to compile and test the application on Raspberry Pi. The code-test cycle on my Laptop is far faster and more productive. I hope this is also a consideration for those developing GTK+ application for Raspberry Pi.
... GError *error; // Function that uses "error" variable here ...The code above runs just fine on my laptop (x64 Linux), but it terminated the program execution in Raspberry Pi complaining that the error variable is not initialized properly. This is the fix:
... GError *error = NULL; // Function that uses "error" variable here ...Simply initializing the variable to NULL makes everything works as expected :-). There are other minor differences, but from what I have code, I can say that even multithread and multiprocess (running child process) code works just fine in Raspberry Pi when using GTK+v3.X (with the accompanying GLib, etc.). Testing the application on the laptop, most of the time mirrors the behavior of the code on Raspberry Pi.
The reason I'm doing this kind of development is simply time. It takes too much time to compile and test the application on Raspberry Pi. The code-test cycle on my Laptop is far faster and more productive. I hope this is also a consideration for those developing GTK+ application for Raspberry Pi.
Labels:
C/C++,
GTK,
Raspberry Pi,
Software Development
Wednesday, March 13, 2013
Raspberry Pi Hardware Support for Thread Synchronization
Hardware support for synchronization in multithreaded application could improve its execution time and responsiveness. The synchronization primitives mostly available in the form of atomic Compare-and-Swap instruction. On x86/x64 architecture, the instruction is called CMPXCHGXX which stands for compare-and-exchange (the XX is only a placeholder because there are several variants of the instruction). On ARM architecture, the support is in the form of the SWP (swap) instruction.
Raspberry Pi CPU supports the SWP instruction. You can see this when you "cat /proc/cpuinfo" as follows:
Raspberry Pi CPU supports the SWP instruction. You can see this when you "cat /proc/cpuinfo" as follows:
pi@raspberrypi ~ $ cat /proc/cpuinfo Processor : ARMv6-compatible processor rev 7 (v6l) BogoMIPS : 697.95 Features : swp half thumb fastmult vfp edsp java tls CPU implementer : 0x41 CPU architecture: 7 CPU variant : 0x0 CPU part : 0xb76 CPU revision : 7 Hardware : BCM2708 Revision : 000f Serial : 00000000231c08f2As you can see, the swp instruction exist in the BCM2708, the CPU on the Raspberry Pi SoC. Therefore, we could expect that multithreaded application ported from the PC (x86/x64) could seamlessly ported to Raspberry Pi with expectation that the synchronization primitives would work with the help of the hardware (via swp instruction). I have yet to do some tests on this. It should be on the next post on the Raspberry Pi subject.
Friday, March 1, 2013
Autostart (Single) Fullscreen X Application in Raspberry Pi
This post is a continuation of my previous post (http://darmawan-salihun.blogspot.com/2013/01/autostart-x-application-in-raspberry-pi.html). Here I talk about making the previous setting into a system-wide setting, i.e. an X application that would be started regardless of the X login used.
The related details are in this link. Assuming you're using Raspbian, you should edit [/etc/xdg/lxsession/LXDE/autostart] file to add the application that you want to be started right when X starts. The contents of the autostart file should look similar to this:
If you are in the final stage of customizing your Raspbian system, probably you want to get rid of everything running in X except for your own X application. In that case, you can remove the "@lxpanel --profile LXDE" line to remove the panel(s) altogether, because in default setting, the panel would be shown in the lower part of the screen (display). This is probably something you want to get rid of if your X application is a fullscreen X application.
The related details are in this link. Assuming you're using Raspbian, you should edit [/etc/xdg/lxsession/LXDE/autostart] file to add the application that you want to be started right when X starts. The contents of the autostart file should look similar to this:
@lxpanel --profile LXDE @pcmanfm --desktop --profile LXDE @xscreensaver -no-splash @[your_x_application_absolute_path_here]As you can see above, replace the place-holder (your_x_application_absolute_path_here) with the absolute path of your application (minus the brackets of course).
If you are in the final stage of customizing your Raspbian system, probably you want to get rid of everything running in X except for your own X application. In that case, you can remove the "@lxpanel --profile LXDE" line to remove the panel(s) altogether, because in default setting, the panel would be shown in the lower part of the screen (display). This is probably something you want to get rid of if your X application is a fullscreen X application.
Monday, February 4, 2013
Mathematical Analysis of Concurrent System
When you created a multithreaded application(s) or other forms of parallel code, it must be rather scary to think about the possibility of deadlock, livelock, race condition or other bad things which could not be debugged "deterministically" like in serial code.
Well, actually there's a "formal" way to verify your code by using a mathematical analysis known as Communicating Sequential Process (CSP) [http://en.wikipedia.org/wiki/Communicating_sequential_processes]. This field is a relatively new field and still very much an active research at the moment.
Another approach is using Petri-Net to help analyzing the parallel code. But, at the moment, I'm trying to learn CSP as it seems to be better suited for embedded development.
Wednesday, January 30, 2013
Disabling Raspberry Pi Cursor (Inside X11/Xorg)
In several Raspberry Pi configuration (usage scenario), the presence of cursor is not wanted. Therefore, removing the cursor from the X server is desired. This link explains various ways to disable the cursor (not merely showing a transparent cursor but disabling it altogether).
I'm using the default Raspbian distribution. Therefore, the default window manager is LXDE, managed through lightdm. Lightdm configuration file which dictates how the X server starts is /etc/lightdm/lightdm.conf. In order to disable the cursor, you have to invoke/starts the X server with the -nocursor argument, or other means as explained in the link above. I decided to go with X -nocursor command to start the X server. This is accomplished through editing the /etc/lightdm/lightdm.conf file. Find the line which starts with xserver-command and edit it to start the X server without cursor. In my particular case, the line is located right below the [SeatDefaults] group of "options". This is how it looks like when I'm done (the ellipses means lines in the file which are ignored):
Hopefully this helps those who need this kind of Raspberry/Raspbian setup.
I'm using the default Raspbian distribution. Therefore, the default window manager is LXDE, managed through lightdm. Lightdm configuration file which dictates how the X server starts is /etc/lightdm/lightdm.conf. In order to disable the cursor, you have to invoke/starts the X server with the -nocursor argument, or other means as explained in the link above. I decided to go with X -nocursor command to start the X server. This is accomplished through editing the /etc/lightdm/lightdm.conf file. Find the line which starts with xserver-command and edit it to start the X server without cursor. In my particular case, the line is located right below the [SeatDefaults] group of "options". This is how it looks like when I'm done (the ellipses means lines in the file which are ignored):
... [SeatDefaults] xserver-command=X -nocursor ...With the modification above, the cursor is gone, once I restarted the X session.
Hopefully this helps those who need this kind of Raspberry/Raspbian setup.
Moving Raspberry Pi logs and temp files to RAM
This link explains how to move your temporary files from secondary storage device (HDD, SDCard, SSD, etc.) to RAM in general--seems to be the link no longer working. I did a similar thing with my Raspberry Pi because the temporary files are not of interest in my particular setup. The difference lays in the details because of limited RAM space in Raspberry Pi, I decided to limit the amount of RAM for the temporary files to 5MB at most. This is how my Raspberry Pi /etc/fstab looks like (the snippet below only shows relevant lines for the temporary files setup):
I have tested my Raspberry Pi with several reboots and cold start and everything works without a hitch.
Update:
---------
I need to increase the amount of RAM dedicated to /tmp to 5MB after zeromq and nanomsg build (compilation) failure happened when /tmp was still 1 MB. This is due to gcc places the intermediate compilation result (i.e. the expanded asm code + macros) in /tmp before linking takes place. It seems some of the code expands to > 1MB of size. After changing /tmp to use 5MB of RAM, everything worked without a hitch.
tmpfs /tmp tmpfs defaults,noatime,mode=1777,size=5m 0 0 tmpfs /var/log tmpfs defaults,noatime,mode=1777,size=5m 0 0 tmpfs /var/tmp tmpfs defaults,noatime,mode=1777,size=1m 0 0The "size=5m" and similar parameters force the RAM size used for the corresponding temporary file to certain megabytes. The "m" suffix corresponds to "mega bytes". The details are explained in this link.
I have tested my Raspberry Pi with several reboots and cold start and everything works without a hitch.
Update:
---------
I need to increase the amount of RAM dedicated to /tmp to 5MB after zeromq and nanomsg build (compilation) failure happened when /tmp was still 1 MB. This is due to gcc places the intermediate compilation result (i.e. the expanded asm code + macros) in /tmp before linking takes place. It seems some of the code expands to > 1MB of size. After changing /tmp to use 5MB of RAM, everything worked without a hitch.
Monday, January 28, 2013
Analyzing Multithreaded Code Mathematically
Multithreaded code is hard to debug. Therefore, it helps a lot if one can analyze it mathematically to see whether the code is sound or not.
There are at least 3 approaches to do that:
There are at least 3 approaches to do that:
- With Petri-Net (http://en.wikipedia.org/wiki/Petri_net)
- With CSP (http://en.wikipedia.org/wiki/Communicating_sequential_processes)
- With Pi-Calculus (http://en.wikipedia.org/wiki/%CE%A0-calculus).
Labels:
Algorithm,
Math,
Parallel Processing,
Software Development
Math Link(s) for Programmers
I found this page by Ken Ward really interesting and useful for programmers trying to analyze the algorithm in their code or other people's code.
Particularly the pages on treatment of series. I found some of the proofs for sum of squares and other series to be particularly eye opening. Take the explanation on sum of squares using infinite calculus for example. I didn't know that it's possible to do that before :P.
Particularly the pages on treatment of series. I found some of the proofs for sum of squares and other series to be particularly eye opening. Take the explanation on sum of squares using infinite calculus for example. I didn't know that it's possible to do that before :P.
Labels:
Math,
Reverse engineering,
Software Development
GTK3 Image Scaling on Raspberry Pi Hiccups
If you read my previous post on GTK3 image scaling, you'll notice that GTK3 uses Cairo for the task. I compiled and tested the code on Raspberry Pi (B revision) but unfortunately the lag is noticeable, on the order of 1 second or more on 1366x768 LCD display. This is quite unacceptable for some "display-intensive" applications.
Anyway, this is without using any acceleration on the Pi's GPU because I have yet to make that works. I noticed a sort of GPU accelerated sample codes in the /opt directory on Raspbian but unfortunately, I have yet to be able to run the sample code successfully. Compiling the code runs just fine without problems but running the result always failed.
Anyway, this is without using any acceleration on the Pi's GPU because I have yet to make that works. I noticed a sort of GPU accelerated sample codes in the /opt directory on Raspbian but unfortunately, I have yet to be able to run the sample code successfully. Compiling the code runs just fine without problems but running the result always failed.
Thursday, January 17, 2013
Image Scaling in GTK 3 (with Cairo)
GTK 3 differs significantly to GTK 2 in the image rendering department. In GTK 2, image rendering is handled by GDK via GdkPixbuf. On the other hand, GTK 3 moves almost all of the burden to Cairo. This could be rather confusing to GTK newbies.
This post explains how to carry out image scaling with Cairo via a GTK 3 sample application. In GTK 2, this is a relatively simpler task via GDK. You should consult this, if you want to do image scaling in GTK 2.
Now, let me go straight to the sample code. The makefile for the code as follows:
You should pay attention to call cairo_paint() right after setting the cairo surface to draw into. In this case, the code calls cairo_set_source_surface() to do that in do_drawing() function. The code above is based on a modified code from this tutorial. The code displayed above, reads a PNG input file and then scale the image to the dimension of the screen before displaying it. The code also superimpose a "watermark" on the image by using the draw_mark() function.
Testing on Raspberry Pi with 1366x768 pixel display shows that Raspberry Pi is not quite up to the task when the image on the screen is repeatedly redrawn (for example when juggling between windows with Alt+Tab). In this particular case, the lag is noticeable before the scaled image is shown, could be up to 1 second.
I'm still evaluating whether or not 2D acceleration is enabled or not. Because I think Raspberry Pi have enough horsepower for the task (without the 1 second delay) of 2D acceleration is active.
This post explains how to carry out image scaling with Cairo via a GTK 3 sample application. In GTK 2, this is a relatively simpler task via GDK. You should consult this, if you want to do image scaling in GTK 2.
Now, let me go straight to the sample code. The makefile for the code as follows:
all: gcc $(shell pkg-config --cflags --libs gtk+-3.0) cairo_test.c -o cairo_test clean: rm -vf *~ cairo_testThe makefile assumes that the (single) source code file is named cairo_test.c. Now, let's proceed to cairo_test.c.
#include <cairo.h> #include <gtk/gtk.h> static void do_drawing (cairo_t *, GtkWidget * widget); struct { cairo_surface_t *image; } glob; static gboolean on_draw_event (GtkWidget * widget, cairo_t * cr, gpointer user_data) { cr = gdk_cairo_create (gtk_widget_get_window (widget)); do_drawing (cr, widget); cairo_destroy (cr); return FALSE; } static void do_drawing (cairo_t * cr, GtkWidget * widget) { gfloat screen_width; gfloat screen_height; gfloat image_width; gfloat image_height; gfloat x_scaling; gfloat y_scaling; /* Display screen dimension in console */ screen_width = gdk_screen_get_width (gdk_screen_get_default ()); screen_height = gdk_screen_get_height (gdk_screen_get_default ()); g_message ("Screen width %f", screen_width); g_message ("Screen height %f", screen_height); /* Scale the loaded image to occupy the entire screen */ image_width = cairo_image_surface_get_width (glob.image); image_height = cairo_image_surface_get_height (glob.image); g_message ("Image width %f", image_width); g_message ("Image height %f", image_height); x_scaling = screen_width / image_width; y_scaling = screen_height / image_height; g_message ("x_scaling %f", x_scaling); g_message ("y_scaling %f", y_scaling); cairo_scale (cr, x_scaling, y_scaling); cairo_set_source_surface (cr, glob.image, 0, 0); cairo_paint (cr); } static void load_image () { glob.image = cairo_image_surface_create_from_png ("resources/quake_3_arena.png"); } static void draw_mark () { cairo_t *ic; ic = cairo_create (glob.image); cairo_set_font_size (ic, 11); cairo_set_source_rgb (ic, 0.9, 0.9, 0.9); cairo_move_to (ic, 100, 100); cairo_show_text (ic, " 343 Industries 2013 , (c) Pinczakko "); cairo_stroke (ic); } int main (int argc, char *argv[]) { GtkWidget *window; GtkWidget *darea; cairo_t *cr; load_image (); draw_mark (); gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); darea = gtk_drawing_area_new (); gtk_container_add (GTK_CONTAINER (window), darea); g_signal_connect (G_OBJECT (darea), "draw", G_CALLBACK (on_draw_event), NULL); g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL); gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER); gtk_window_set_title (GTK_WINDOW (window), "Cairo Test"); gtk_window_set_decorated (GTK_WINDOW (window), FALSE); gtk_window_fullscreen (GTK_WINDOW (window)); gtk_widget_show_all (window); gtk_main (); cairo_surface_destroy (glob.image); return 0; }In the code above you can see I'm using a file in the resources directory, with name quake_3_arena.png as the image to be loaded and scaled to the dimension of the entire screen (full screen). The image scaling and drawing happens in the "draw" event handler function.
You should pay attention to call cairo_paint() right after setting the cairo surface to draw into. In this case, the code calls cairo_set_source_surface() to do that in do_drawing() function. The code above is based on a modified code from this tutorial. The code displayed above, reads a PNG input file and then scale the image to the dimension of the screen before displaying it. The code also superimpose a "watermark" on the image by using the draw_mark() function.
Testing on Raspberry Pi with 1366x768 pixel display shows that Raspberry Pi is not quite up to the task when the image on the screen is repeatedly redrawn (for example when juggling between windows with Alt+Tab). In this particular case, the lag is noticeable before the scaled image is shown, could be up to 1 second.
I'm still evaluating whether or not 2D acceleration is enabled or not. Because I think Raspberry Pi have enough horsepower for the task (without the 1 second delay) of 2D acceleration is active.
Labels:
C/C++,
GTK,
Raspberry Pi,
Software Development
Wednesday, January 16, 2013
Autostart X Application in Raspberry Pi
Assuming that you're using the official Raspbian (mine is "wheezy") image, the default Window Manager is LXDE. Therefore, to enable an X application to start automatically once X started, you would consult LXDE documentation. This is the direct link: http://wiki.lxde.org/en/Autostart.
What basically you should do is create a directory named autostart inside ~/.config. Here, the ~ means the home directory of the account that log-in directly to X. Then, in the autostart directory, create a *.desktop file and make it executable (chmod +x [your_file].desktop). The format of the *.desktop file as follows:
That's it.
Anyway, some other useful links:
https://wiki.archlinux.org/index.php/LXDE#Autostart_Programs
http://blog.flowbuzz.com/2012/07/raspberry-pi-and-autostart.html
http://wicd.sourceforge.net/moinmoin/FAQ
What basically you should do is create a directory named autostart inside ~/.config. Here, the ~ means the home directory of the account that log-in directly to X. Then, in the autostart directory, create a *.desktop file and make it executable (chmod +x [your_file].desktop). The format of the *.desktop file as follows:
[Desktop Entry] Type=Application Exec=your_application_path_here
That's it.
Anyway, some other useful links:
https://wiki.archlinux.org/index.php/LXDE#Autostart_Programs
http://blog.flowbuzz.com/2012/07/raspberry-pi-and-autostart.html
http://wicd.sourceforge.net/moinmoin/FAQ
Labels:
GTK,
Linux Tips Hacks and Guides,
Raspberry Pi
What Happened in Mali?
I was quite surprised to read the news on France involvement on the "internal" Mali troubles with "rebels" and "supposedly terrorists". Common sense would of course ruled that action as probably "useless" and waste of taxpayer money. But, well, not exactly if you dig deeper though.
The first hint comes from "the conflict" happens in the North of Mali (http://blogs.defensenews.com/intercepts/2013/01/photo-of-the-day-jan-15-2013/). What the hell is there in the "North"? Call me conspiracy theorists. But, if you look at this: http://www.oklouranium.com/, you'll notice that there is an uranium ore mine to the northeast of Mali. Are these guys fighting for Uranium? Well, that link shows that the company mining the uranium is from Australia, instead of France. But, if that
mine falls to the "rebels" hand, that would be a VERY big trouble. I'm quite sure there is black market for uranium and also there's demand of course. Another interesting fact is Mali has a quite big gold deposit (12th) in the world and 3rd in Africa. The fact is mentioned in the previous link. This is interesting nonetheless. If the rebels could control access to the gold deposit, they could probably fund themselves adequately.
Another issue in Africa lately is the feeling of unease in the West as China encroach into Africa and making big inroads, trying to secure raw materials in an area traditionally "controlled" by European countries. Well, maybe I'm thinking too much into this. But, I think it's just common sense. Any industrialized/semi-industrialized Nation or let's groups of people would have demands for raw materials. The problem is, if the material is as dangerous as uranium, that would be troublesome.
The first hint comes from "the conflict" happens in the North of Mali (http://blogs.defensenews.com/intercepts/2013/01/photo-of-the-day-jan-15-2013/). What the hell is there in the "North"? Call me conspiracy theorists. But, if you look at this: http://www.oklouranium.com/, you'll notice that there is an uranium ore mine to the northeast of Mali. Are these guys fighting for Uranium? Well, that link shows that the company mining the uranium is from Australia, instead of France. But, if that
mine falls to the "rebels" hand, that would be a VERY big trouble. I'm quite sure there is black market for uranium and also there's demand of course. Another interesting fact is Mali has a quite big gold deposit (12th) in the world and 3rd in Africa. The fact is mentioned in the previous link. This is interesting nonetheless. If the rebels could control access to the gold deposit, they could probably fund themselves adequately.
Another issue in Africa lately is the feeling of unease in the West as China encroach into Africa and making big inroads, trying to secure raw materials in an area traditionally "controlled" by European countries. Well, maybe I'm thinking too much into this. But, I think it's just common sense. Any industrialized/semi-industrialized Nation or let's groups of people would have demands for raw materials. The problem is, if the material is as dangerous as uranium, that would be troublesome.
Tuesday, January 15, 2013
Tutorial on Writing GTK+ Mutithreaded Application
I've been looking for some nice tutorials on GTK+ Multithreaded Applications for a while. I think these are the most representative on the web at the moment (at least for newbies like me):
http://blog.borovsak.si/2009/06/multi-threaded-gtk-applications.html
http://blogs.operationaldynamics.com/andrew/software/gnome-desktop/gtk-thread-awareness
and also this thread on gnome mailing list:
https://mail.gnome.org/archives/gtk-devel-list/2007-January/msg00137.html
http://blog.borovsak.si/2009/06/multi-threaded-gtk-applications.html
http://blogs.operationaldynamics.com/andrew/software/gnome-desktop/gtk-thread-awareness
and also this thread on gnome mailing list:
https://mail.gnome.org/archives/gtk-devel-list/2007-January/msg00137.html
Monday, January 7, 2013
Interprocess Communication with DBus in GTK Applications (for Beginners)
This post is meant to provide pointers to where to start developing with GTK application that use DBus as its inter-process communication platform.
Beginners starting to program DBus in GTK applications surely rather frustrated by the lack of up to date tutorials out there. Fear not, there's actually a lot of sample codes and tutorials in the glib2 source code distribution! Albeit not exactly for real beginners. You should still read the DBus tutorial over at http://dbus.freedesktop.org/doc/dbus-tutorial.html to understand the concepts. It's impossible to understand the glib wrapper (in the GIO part of glib) unless you understand the DBus concepts.
I'm using Slackware 14 at the moment. So, naturally, glib2 source code is in the second DVD in the l (library) package series. Mine is glib-2.32.4. The documentation related to DBus in Glib is under the GIO section because GIO is the part of Glib which implements the DBus bindings. If you have download glib-2.X source code, the documentation for the Glib DBus binding (GDBus) starts in the glib-[glib_version]/docs/reference/gio/html/index.html file. You'll be able to browse through all of the GDBus info from there, such as GDBusConnection, GDBusMessage and so on.
Now, for beginner, having a sample dbus server and client that actually works is of utmost importance. No problem, head over to glib GIO documentation over at http://developer.gnome.org/gio/2.29/GDBusConnection.html (Note: This is the online version of the GDBus binding documentation I mentioned in the previous paragraph). Scroll down to Example 2 (D-Bus server example), this is the DBus server source code. Now, for the DBus client, scroll down to Example 4 (D-Bus UNIX File Descriptor example), this is the DBus client source code.
Now, let's name the DBus server source code dbus_server.c and the client dbus_client.c. This is the Makefile I used to build both sample code:
Screenshot time.. This is how it looks like when I run the DBus server and then the DBus client shortly thereafter. The screenshot is taken on the shell that runs the DBus server.
Mind you that this is Glib 2.0 used in GTK+3.0 or above, not GTK+2.0! Also, you should run the applications under X11, otherwise they will not be able to connect to DBus because the required glib2 library call failed. This is because in most Linux distribution, the GDK library--which GTK depends on--is built with X11 back-end. You can check this dependency with the following command:
Anyway, you could actually watch the DBus "messages" in real time as the exchange from the server and client application happens with dbus-monitor. Just run dbus-monitor in another shell before you run the client. You could filter out unwanted messages from showing-up with dbus-monitor options.
Well, hopefully this is enough to help those poor souls looking for DBus and GTK beginner's guide out there.
Beginners starting to program DBus in GTK applications surely rather frustrated by the lack of up to date tutorials out there. Fear not, there's actually a lot of sample codes and tutorials in the glib2 source code distribution! Albeit not exactly for real beginners. You should still read the DBus tutorial over at http://dbus.freedesktop.org/doc/dbus-tutorial.html to understand the concepts. It's impossible to understand the glib wrapper (in the GIO part of glib) unless you understand the DBus concepts.
I'm using Slackware 14 at the moment. So, naturally, glib2 source code is in the second DVD in the l (library) package series. Mine is glib-2.32.4. The documentation related to DBus in Glib is under the GIO section because GIO is the part of Glib which implements the DBus bindings. If you have download glib-2.X source code, the documentation for the Glib DBus binding (GDBus) starts in the glib-[glib_version]/docs/reference/gio/html/index.html file. You'll be able to browse through all of the GDBus info from there, such as GDBusConnection, GDBusMessage and so on.
Now, for beginner, having a sample dbus server and client that actually works is of utmost importance. No problem, head over to glib GIO documentation over at http://developer.gnome.org/gio/2.29/GDBusConnection.html (Note: This is the online version of the GDBus binding documentation I mentioned in the previous paragraph). Scroll down to Example 2 (D-Bus server example), this is the DBus server source code. Now, for the DBus client, scroll down to Example 4 (D-Bus UNIX File Descriptor example), this is the DBus client source code.
Now, let's name the DBus server source code dbus_server.c and the client dbus_client.c. This is the Makefile I used to build both sample code:
all: gcc $(shell pkg-config --cflags --libs gtk+-3.0) dbus_server.c -o dbus_server gcc $(shell pkg-config --cflags --libs gtk+-3.0) dbus_client.c -o dbus_client clean: rm -vf *~ dbus_server dbus_clientJust invoke make to build them all in your shell. I made some changes to the DBus server code to display verbose logging in the shell. These are the changes:
77,78c77,78 < "As requested, here's a GError not registered " < "(G_IO_ERROR_FAILED_HANDLED)"); --- > "As requested, here's a GError not registered > (G_IO_ERROR_FAILED_HANDLED)"); 85,86c85,86 < "As requested, here's a GError that is registered " < "(G_DBUS_ERROR_MATCH_RULE_NOT_FOUND)"); --- > "As requested, here's a GError that is registered > (G_DBUS_ERROR_MATCH_RULE_NOT_FOUND)"); 160,161c160,161 < "Your message bus daemon does not support " < "file descriptor passing (need D-Bus >= 1.3.0)"); --- > "Your message bus daemon does not support file > descriptor passing (need D-Bus >= 1.3.0)"); 298,299d297 < g_printf("Timeout reached! \n"); < 339,340d336 < g_printf("DBus \"bus\" acquired! \n"); < 361d356 < g_printf("DBus \"name\" acquired! \n"); 369,370d363 < g_printf("Connection to DBus lost!\n"); < 398,399d390 < g_printf("Entering g_main_loop_new() ..\n"); < 403,404d393 < g_printf("Leaving g_main_loop_new() ..\n"); < 411,413d399 < <They're not major changes, just to log where the execution is in the server code at runtime.
Screenshot time.. This is how it looks like when I run the DBus server and then the DBus client shortly thereafter. The screenshot is taken on the shell that runs the DBus server.
Mind you that this is Glib 2.0 used in GTK+3.0 or above, not GTK+2.0! Also, you should run the applications under X11, otherwise they will not be able to connect to DBus because the required glib2 library call failed. This is because in most Linux distribution, the GDK library--which GTK depends on--is built with X11 back-end. You can check this dependency with the following command:
me@my_machine:~/$ pkg-config --cflags --libs gdk -I/usr/include/gtk-1.2 -I/usr/include/glib-1.2 -I/usr/lib/glib/include -lgdk -lXext -lX11 -lm -lglibAs you can see, the output of the command in my machine shows dependency to X11, namely in the -lXext -lX11 linker parameters.
Anyway, you could actually watch the DBus "messages" in real time as the exchange from the server and client application happens with dbus-monitor. Just run dbus-monitor in another shell before you run the client. You could filter out unwanted messages from showing-up with dbus-monitor options.
Well, hopefully this is enough to help those poor souls looking for DBus and GTK beginner's guide out there.
Subscribe to:
Posts (Atom)