Lorenz Klopfenstein.net http://www.klopfenstein.net Homepage of the swiss Klopfenstein family living in Italy. en lck@klopfenstein.net Wed, 7 Jul 2010 22:28:55 +02:00 <![CDATA[Qt on Mono with Qyoto]]> When trying to build graphical interfaces on Linux with Mono, you have lots of choice. If you want maximum portability you can use Windows Forms (which don't look so great on Mono) or Gtk# (way better for multi-platform stuff). Both have a pretty standard look, even if WinForms look native only on Windows and Gtk does so on Gnome, and both work very well for standard desktop apps.

However, when doing more advanced graphics or targeting embedded systems, both fall short: WinForms runs OK on Windows CE (even if it is very limited), while Gtk looks pretty boring and may not be the ideal choice on resource constrained systems. The next multiplatform GUI choices that come to mind are Nokia's Qt or Intel's Clutter. Clutter is still a young project, but both frameworks unfortunately lack some good .NET bindings in essence.

In my case I'm starting to use Qt, through the Qyoto bindings. The latest Ubuntu distro already includes the package, which makes getting started pretty easy — at last if it weren't for the lack of documentation.

Qyoto provides a quite complete mapping of the Qt interface, but unfortunately mantains a lot of the original C++ “smell”: many enumerations are given as simple integers, events (the signal/slot system in Qt) don't rely on .NET events but require you to bind methods to signals by their untyped name. Less of a problem, but still not very pretty: in many points Qyoto doesn't respect the common .NET naming conventions and some Qt methods should really be mapped to properties.

Anyway, these minor criticisms notwithstanding, Qyoto provides a simple and complete way to use Qt's power from C#. Let's take a look to a simple example application.

More...

]]>
Wed, 7 Jul 2010 22:28:55 +02:00
<![CDATA[Draggable glass windows with Aero]]> Aero in Windows Vista introduced the new glass windows and a nice set of APIs that allow developers to change glass and blur settings. One of the options allows to extend the glass frame from the “non-client” area to the inner parts of the window. This effect is used by many applications of Windows itself (Windows and Internet Explorer for instance, or Media Player — before they dropped the glass in Windows 7).

To understand how this works, firstly let's take a look to how a standard window is structured in Windows:

Windows areas.

A window is composed of many separate areas. The most important one in our case is the non-client area which includes many other parts (for instance the caption, i.e. the title and icon of the window). This area surrounds the central rectangular client area, which is the space where the application draws its own contents.

The whole non-client area is composed of glass in Aero: when extending the glass frame, you are effectively allowing Windows to draw its glass effect inside the client area where you too are drawing the contents of the window. Combining what you and Windows draw together can be tricky (you must draw using GDI and not GDI+ in order to handle alpha transparency and the background of your windows must be black on the glassy area), but it isn't too hard.

However, most applications that extend the glass frame allow you to drag and move the window if you click anywhere on the glass. This makes sense for the users but doesn't work out of the box: after all, even if clicking on glass, the clicks still end in your client area and must be handled by the application. To let Windows handle the clicks and enable dragging, you essentially must not only extend the glass area, but also the whole caption area inside your window (since the caption is the part of window usually in charge of handling mouse dragging). The resulting layout would look like this:

Windows areas.

How do you tell Windows that what was your client area should be considered part of the caption? Windows has a simple way of determining which parts are what: it sends WM_NCHITTEST messages asking your window directly. The message stands for “non-client hit testing” and the result you pass back to the window manager describes the area the mouse pointer is currently hovering on.

protected override void WndProc(ref Message m) {
	base.WndProc(ref m);

	if (m.Msg == WM_NCHITTEST && m.Result.ToInt32() == HTCLIENT) {
		uint lparam = (uint)m.LParam.ToInt32();
		ushort x = (ushort)lparam;
		ushort y = (ushort)(lparam >> 16);

		if(PointerOnGlass(x, y)){
			m.Result = (IntPtr)HTCAPTION;
			return;
		}
	}
}

const int WM_NCHITTEST = 0x84;
const int HTCLIENT = 1;
const int HTCAPTION = 2;

By putting this snippet of code in your WndProc method you'll tell the Window Manager to consider the pixels on glass of your client area as part of the window's caption area instead. This will automatically enable dragging, Aero Snap and so on.

If you use the WindowsFormsAero library, you can simply use the GlassForm helper class and derive from it. The form handles all glass-related stuff automagically (you simply have to set the glass margins you want). It also allows you to hide the window's title and icon in a simple way. Check it out!

]]>
Thu, 1 Jul 2010 23:43:40 +02:00
<![CDATA[Force Hibernation with Hybrid Sleep]]> 160

Windows Vista introduced a very nice feature called “hybrid sleep” that simplifies power management and allows the PC to enter a deep sleep state (S2 or S3) while persisting the RAM contents to disk. In this case, even if the computer lost power it could always resume its state without data loss.

I like this feature quite much and it appears to have become the default “sleep” state on most operating systems (Mac OS X had it for some time and the latest Ubuntu appears to use Hybrid Sleep as well by default). In some cases however you'd perhaps want the PC to hibernate and skip the sleep state altogether (i.e. enter the S4 state directly). Unfortunately Windows hides the hibernate option: your only option is to enter sleep, wait until the RAM state has been written to disk and then power off the computer manually.

Needless to say, this is ugly and could lead you to powering off the PC before it had a chance to write all data to disk. In order to force Windows to enter hibernation directly (without having to disable Hybrid Sleep), you'll need to run the following command from the command line (no need to run as administrator):

%windir%\system32\rundll32.exe PowrProf.dll, SetSuspendState 0,1,0

This will quickly fade out the screen, save the RAM to disk and power off the computer as if you clicked on the old “hibernate” option.

]]>
Sat, 29 May 2010 23:25:12 +02:00
<![CDATA[OnTopReplica 2.9.3]]> A minor update to OnTopReplica is available since a couple of days via the ClickOnce installer or on the CodePlex repository.

This new version adds some minor tweaks (alphabetic region ordering, some minor redrawing issues, etc.) and adds a new Czech translation to the ones available (italian and english at the time). Many thanks to René Mihula for the translation!  :)

In the meantime, a portoguese translation is in the works and for the upcoming 3.0 version I'm planning to integrate some Windows 7 specific features (Vista will still be supported of course).

]]>
Fri, 14 May 2010 14:01:35 +02:00
<![CDATA[Wireless Multicast TV... after]]> The Wireless Multicast TV event has been a success, everything worked correctly (even exceeding our initial expectations in fact). We used the following setup during the presentation:

The Wireless Multicast TV setup schematic

Our objective was to get real time Web TV contents from the Internet and stream them locally to a certain number of clients using multicast over a wireless network. The incoming media resources from the Internet were handled by our proxy server (the box I worked on prevalently), re-encoded and then streamed to multicast addresses. The inner network was a wireless link, composed by one antenna linked to 10 CPEs. Each CPE was then cabled to a client computer, playing back the video streams.

The main point of the experiment being that, since multicast can be very cheap if implemented on a wireless network, it can be successfully used to deliver real time media without incurring in the typical bandwidth saturation that would be caused by using unicast streaming.

More...

]]>
Fri, 14 May 2010 00:03:23 +02:00
<![CDATA[Wireless Multicast TV... before]]> I've been working at the University of Urbino for a couple of months, trying to get a working example of a Web TV over a wireless multicast transmission channel. All of the team's efforts (me and a couple of other people) are focused on the public event of tomorrow:

Wireless Multicast TV event banner

We will try to demo a proxy server (which has been built primarily by myself using ASP.NET and GStreamer) that receives various Web TVs from the Internet (our partners for the event are StreamIt and the italian RAI) and 1080p high definition movies stored locally on the server, transcodes the A/V stream and forwards it via multicast.

The multicast stream will then cross a radio link (provided by our partners at Essentia) and get to 10 client PCs, representing 10 households that might wish to receive TV contents through their wireless connection.

Essentially the demo will try to prove that such transmission methods provide much lower impact on the available bandwidth (which can be very scarce on metropolitan wireless connections, especially if shared between many clients of the same household). Wireless multicast TV is usually limited to “traditional” media delivery similar to that of the standard TV broadcast (that is, no on-demand video), but could be integrated with some innovative commercial solutions (for instance, on-demand video that gets cheaper as more users decide to watch it).

If everything works as planned (and so far it didn't  :S), starting tomorrow I'll have more time to write about the things we worked on: lots of stuff, starting with the RTMP protocol, GStreamer, RTP multicast streaming...  :D

]]>
Tue, 4 May 2010 22:46:09 +02:00
<![CDATA[iHeresy - Win7 on MacBook Pro]]> MacBook Pro Windows 7 installation ritual.

I never thought I'd ever own an Apple computer. Now I do, but still the Apple OS doesn't really cut it for what I have to do for work. Hence, shortly after it's arrival, I went looking for some chicken blood, scented candles and a mysterious black robe: ready to perform the iHeresy and install Windows 7 on the brand new MacBook Pro!

Thanks to Apple, the heretical procedure is quite easy: the Snow Leopard installation disc you get with your Mac contains all Windows drivers you'll need and Mac OSX itself can do the partitioning work for you and setup the EFI bootloader correctly. In most cases the official installation guide will be perfectly fine to install Windows on a Mac PC.

However, if you'd like to setup a triple boot with Mac OSX, Windows and Linux, you'll need a more advanced solution: rEFIt, a toolkit that lets you customize the bootloader and boot from almost everything. Just download the latest package and install it in Mac OSX (it's a simple .dmg package). Refit won't show up as an installed application, but at the next reboot it should already show up instead of the gray Apple logo.

Now you're ready to partition your Apple's hard disk and install any other operating system. To do so, I suggest this great guide (which is slightly outdated, but nonetheless valid and very detailed). Essentially you'll have to follow this three steps...

More...

]]>
Mon, 3 May 2010 22:16:20 +02:00
<![CDATA[iBetrayal]]> In the last months there has been a silent and progressive change in my family. A slow revolution that has overruled every rational economic decision and forced us to buy Apple computers (I refuse to cite the usual “PC vs. Mac” thingie since it's just not true: Macs are overpriced PCs!).

So, after my brother bought a Mac Book Pro when he left for his school, my mother followed with another Apple laptop. Still justifiable, since both of them do computer design and after all every self-respectable designer wouldn't suit for nothing less than a Mac. But then... we inexcusably also bought a 27 inch iMac!

Unpacking our new 27' iMac.
Unpacking our new 27' iMac.

We started using it in the kitchen to watch movies most of all — a rather underutilized piece of hardware until now. Still, the screen is absolutely gorgeous and watching movies on it is a pleasure.

Anyway, I was “keeping it real” and was standing by my PC-only principles... that is, until the finishing blow struck. For the last months I have been working at some new project for the University of Urbino. The professor I'm working with went on a “we got money, we gotta spend it” buying spree (not really, but quite) and bought some new hardware for the lab I work in. One of those machines was indeed a Mac Book Pro 13, which has then been assigned to me.  :) Yuppie.
An offer I couldn't refuse of course.

More...

]]>
Fri, 23 Apr 2010 02:06:28 +02:00
<![CDATA[URL generation in ASP.NET MVC without a HttpContext]]> A peculiarity of URL generation in ASP.NET MVC that often bugged me is that you cannot generate URLs outside of an ASP.NET HttpContext. All built in URL generation classes (HtmlHelper, UrlHelper, LinkBuilder etc.) will throw an exception if called without the right parameters or when HttpContext.Current is null.

ASP.NET MVC

This is only because these classes need to know the path of the ASP.NET application they are running in, in order to generate correct relative URLs. For example, a typical website URL can have this form:

http://www.example.com/path/to/application/route/page?parameter=value

In this case our ASP.NET application is hosted under the /path/to/application path. All requests to paths under that application will be forwarded to our app instance and then handled by the ASP.NET routing module. In order to generate links to another page, you can use the full absolute path:

http://www.example.com/path/to/application/route2

or a relative one:

../route2

or, as MVC always does, links that start at the root folder of the host:

/path/to/application/route2

Thus the problem lies in the fact that the host name and the application path can only be found in the current HttpRequest instance. As long as MVC continues to generate URLs in that form, we'll have to manually supply the correct application path in some way when we try to use the URL builders outside of a HttpContext (this is mostly the case when you generate e-mails on a background thread or similar scenarios).

More...

]]>
Mon, 5 Apr 2010 17:39:26 +02:00
<![CDATA[Mono loves ASP.NET]]> In these days I have been working on a multicast streaming server that will run on a Linux box and needs some kind of web frontend. Being a seasoned ASP.NET MVC supporter I naturally picked Mono to run an ASP.NET website on Apache. A combination that — unbelievable, I know — works remarkably well!

Mono on Apache

More...

]]>
Thu, 25 Mar 2010 17:12:31 +01:00