<?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>micolous.id.au</title>
	<atom:link href="http://micolous.id.au/feed/" rel="self" type="application/rss+xml" />
	<link>http://micolous.id.au</link>
	<description>the result of a blogging accident</description>
	<lastBuildDate>Tue, 02 Mar 2010 03:37:55 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Internode Radio playlist files for XBMC (and others)</title>
		<link>http://micolous.id.au/archives/2010/03/02/internode-radio-playlist-files-for-xbmc-and-others/</link>
		<comments>http://micolous.id.au/archives/2010/03/02/internode-radio-playlist-files-for-xbmc-and-others/#comments</comments>
		<pubDate>Tue, 02 Mar 2010 03:37:55 +0000</pubDate>
		<dc:creator>micolous</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://micolous.id.au/?p=230</guid>
		<description><![CDATA[I got bored and created playlist files for all the radio stations that Internode mirror.  They point to the playlist files on the page so should keep updated if the servers get changed again.

This file doesn&#8217;t update at all if a station gets added or removed from the list.

In XBMC, you just have to [...]]]></description>
			<content:encoded><![CDATA[<p>I got bored and created playlist files for all the radio stations that <a href="http://www.internode.on.net/residential/entertainment/broadband_radio/">Internode mirror</a>.  They point to the playlist files on the page so should keep updated if the servers get changed again.</p>

<p>This file doesn&#8217;t update at all if a station gets added or removed from the list.</p>

<p>In XBMC, you just have to put this ZIP file in a folder it uses as a source, and you can browse into it and play radio stations without extracting the archive.  In other players, you have to extract it yourself.</p>

<p><a href="/static/resc/InternodeRadio.zip">Download the archive</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://micolous.id.au/archives/2010/03/02/internode-radio-playlist-files-for-xbmc-and-others/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SDL VNC Server module (v2)</title>
		<link>http://micolous.id.au/archives/2010/02/17/sdl-vnc-server-module-v2/</link>
		<comments>http://micolous.id.au/archives/2010/02/17/sdl-vnc-server-module-v2/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 16:31:47 +0000</pubDate>
		<dc:creator>micolous</dc:creator>
				<category><![CDATA[Coding]]></category>

		<guid isPermaLink="false">http://micolous.id.au/?p=225</guid>
		<description><![CDATA[Time for a version two!  There&#8217;s a new version of the patch to SDL 1.2.14.  You need a clean source tree with this, so remove v1 of the patch before applying this one.

Changes:

Mouse cursors now work correctly.
You can now disable the &#8220;always shared&#8221; function of the VNC server and allow a client to [...]]]></description>
			<content:encoded><![CDATA[<p>Time for a version two!  There&#8217;s <a href="/static/projects/sdlvnc/SDL-video-vnc-v2.diff.bz2">a new version of the patch to SDL 1.2.14</a>.  You need a clean source tree with this, so remove v1 of the patch before applying this one.</p>

<p>Changes:
<ul>
<li>Mouse cursors now work correctly.</li>
<li>You can now disable the &#8220;always shared&#8221; function of the VNC server and allow a client to take exclusive control with <code>SDL<em>VNC</em>ALWAYS<em>SHARED="0"</em></code>.</li>
<li>You can change the display number manually with <code>SDLVNC<em>DISPLAY</em></code>.</li>
<li>8 bpp displays are now supported.</li>
<li>pygame applications work at 16, 24 and 32 bpp display depths. 8 doesn&#8217;t work properly.</li>
<li>This module now lies by default about the supported display depths reported by <code>SDLListModes</code>.  It defaults to 16 bpp only, in order to make pygame work properly.  You can change what it says this with <code>SDL<em>VNC</em>DEPTH</code>, or setting it to 0 to say all depths are supported.  This doesn&#8217;t limit calls to <code>SDL<em>SetVideoMode</em></code>.</li>
<li>You can tell the VNC server to ignore all client events by setting <code>SDLVNC<em>VIEW</em>ONLY="1"</code>.</li>
</ul></p>

<p>There&#8217;s also a <code>README.VNC</code> included, which documents the functionality of the library and use of it&#8217;s environment variables.</p>
]]></content:encoded>
			<wfw:commentRss>http://micolous.id.au/archives/2010/02/17/sdl-vnc-server-module-v2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SDL VNC Server module</title>
		<link>http://micolous.id.au/archives/2010/02/16/sdl-vnc-server-module/</link>
		<comments>http://micolous.id.au/archives/2010/02/16/sdl-vnc-server-module/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 19:45:32 +0000</pubDate>
		<dc:creator>micolous</dc:creator>
				<category><![CDATA[Coding]]></category>

		<guid isPermaLink="false">http://micolous.id.au/?p=218</guid>
		<description><![CDATA[I keep writing things related to VNC, and coding in C.  It&#8217;s seriously starting to worry me.

I&#8217;ve spent the last couple of days writing a new SDL video output module, which acts as a VNC server using libvncserver.  Here are the patches against SDL 1.2.14.  To use VNC support, you need to [...]]]></description>
			<content:encoded><![CDATA[<p>I keep writing things related to VNC, and coding in C.  It&#8217;s seriously starting to worry me.</p>

<p>I&#8217;ve spent the last couple of days writing a new SDL video output module, which acts as a VNC server using <a href="http://libvncserver.sourceforge.net/">libvncserver</a>.  <a href="/static/projects/sdlvnc/SDL-video-vnc-v1.diff.bz2">Here are the patches against SDL 1.2.14</a>.  To use VNC support, you need to run <code>./configure</code> with <code>--enable-video-vnc</code>, and once built and installed, run the SDL application with the environment variable <code>SDL_VIDEODRIVER="vnc"</code>.</p>

<p>What works:
<ul>
<li>16, 24 and 32-bit true-colour displays.</li>
<li>Mouse events.</li>
<li>Keyboard events.</li>
</ul></p>

<p>What&#8217;s left to do:
<ul>
<li>Fix mouse cursors so they display correctly.</li>
<li>8-bit (paletted) displays.</li>
<li>Handle surface locking properly.</li>
<li>Reduce/eliminate tearing on frequent screen updates.</li>
<li>Run the libvncserver event loop inside SDL&#8217;s event loop system.</li>
<li>Implement a password on the VNC server and some sort of simple access control.</li>
<li>Implement a view-only mode.</li>
<li>Allow setting the display number manually.</li>
<li>pygame applications.</li>
<li>Fix screen resolution change colour issues.</li>
</ul></p>

<p>What will never work:
<ul>
<li>OpenGL surfaces.</li>
<li>CDROMs, Joysticks and Sound over VNC.</li>
<li>YUV video output.</li>
</ul></p>

<p>I&#8217;ve had a lot of success with using <a href="http://www.sand-labs.org/owb/wiki">the Origyn web browser</a> (a WebKit/SDL-based web browser)  and <a href="http://www.paradroid.net/cgterm/">cgterm</a> (a SDL C64/C128 telnet client) with this output method.  Any SDL application that doesn&#8217;t use OpenGL surfaces <strong>should</strong> be able to run with this output module.</p>

<p>Some pictures:</p>

<p><a href="/static/projects/sdlvnc/sdl-video-vnc-v1-owb.png"><img src="/static/projects/sdlvnc/sdl-video-vnc-v1-owb_small.png" alt="[origyn web browser in tightvnc]" title="Origyn Web Browser (WebKit/SDL) in TightVNC"/></a> <a href="/static/projects/sdlvnc/sdl-video-vnc-v1-cgterm.png"><img src="/static/projects/sdlvnc/sdl-video-vnc-v1-cgterm_small.png" alt="[cgterm in tightvnc]" title="cgterm in TightVNC"/></a></p>
]]></content:encoded>
			<wfw:commentRss>http://micolous.id.au/archives/2010/02/16/sdl-vnc-server-module/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VNC Splitter</title>
		<link>http://micolous.id.au/archives/2010/02/05/vnc-splitter/</link>
		<comments>http://micolous.id.au/archives/2010/02/05/vnc-splitter/#comments</comments>
		<pubDate>Thu, 04 Feb 2010 15:30:19 +0000</pubDate>
		<dc:creator>micolous</dc:creator>
				<category><![CDATA[Coding]]></category>

		<guid isPermaLink="false">http://micolous.id.au/?p=199</guid>
		<description><![CDATA[More VNC clients!

This time, this one will split up a single VNC server input into smaller pieces to form a 3&#215;3 grid of smaller VNC server images.  It&#8217;ll automatically resize it to 640&#215;480.  That stuff is configurable in the defines at the top of the file.  It works best when the ratio [...]]]></description>
			<content:encoded><![CDATA[<p>More VNC clients!</p>

<p>This time, this one will split up a single VNC server input into smaller pieces to form a 3&#215;3 grid of smaller VNC server images.  It&#8217;ll automatically resize it to 640&#215;480.  That stuff is configurable in the defines at the top of the file.  It works best when the ratio between the source image and the destination image is a whole number, (ie: 4&#215;4 of 640&#215;480 images and an input of 1280&#215;960 has a 2:1 ratio), because it uses a simple &#8220;nearest neighbour&#8221; scaling algorithm.</p>

<p>The idea of this client is that you take some input into this, run a whole bunch of thin clients or low end machines connecting to each of the pieces of the screen, and align some cheap CRT monitors in a grid, creating a much bigger screen.  While there are pretty huge bezels with CRT monitors, it is a very low budget way to create a 107cm (42&#8243;) display from a 3&#215;3 array of cheap 36cm (14&#8243;) monitors, for example.</p>

<p>Be aware that some VNC servers implement JPEG compression, which looks really horrible when you scale it up (for example, Vine).  This program also requires that your VNC server has no password.</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// vnc-splitter</span>
<span style="color: #666666; font-style: italic;">// Copyright 2010 Michael Farrell &lt;http://micolous.id.au&gt;</span>
<span style="color: #666666; font-style: italic;">// build with: gcc -o vnc-splitter vnc-splitter.c -lvncserver -lvncclient</span>
<span style="color: #339933;">#include &lt;stdio.h&gt;</span>
<span style="color: #339933;">#include &lt;rfb/rfb.h&gt;</span>
<span style="color: #339933;">#include &lt;rfb/rfbclient.h&gt;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// the height and width of the screens</span>
<span style="color: #666666; font-style: italic;">// this should match the aspect ratio of the input</span>
<span style="color: #339933;">#define SCREEN_WIDTH 640</span>
<span style="color: #339933;">#define SCREEN_HEIGHT 480</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// the amount of screens is this number squared</span>
<span style="color: #339933;">#define SCREEN_SQUARE_SIZE 3</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// where to start displays counting from.</span>
<span style="color: #666666; font-style: italic;">// the first screen number is this, and subsequent screens are other positions.</span>
<span style="color: #339933;">#define DISPLAY_START 30</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// output buffers for child vnc server processes</span>
rfbScreenInfoPtr output_screens<span style="color: #009900;">&#91;</span>SCREEN_SQUARE_SIZE <span style="color: #339933;">*</span> SCREEN_SQUARE_SIZE<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #993333;">static</span> rfbBool resizeImage<span style="color: #009900;">&#40;</span>rfbClient<span style="color: #339933;">*</span> client<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  
	<span style="color: #993333;">int</span> width<span style="color: #339933;">=</span>client<span style="color: #339933;">-&gt;</span>width<span style="color: #339933;">;</span>
	<span style="color: #993333;">int</span> height<span style="color: #339933;">=</span>client<span style="color: #339933;">-&gt;</span>height<span style="color: #339933;">;</span>
	<span style="color: #993333;">int</span> depth<span style="color: #339933;">=</span>client<span style="color: #339933;">-&gt;</span>format.<span style="color: #202020;">bitsPerPixel</span><span style="color: #339933;">;</span>
	fprintf<span style="color: #009900;">&#40;</span>stderr<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;ResizeImage fired: %ix%i %ibpp<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> width<span style="color: #339933;">,</span> height<span style="color: #339933;">,</span> depth<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// change the screen resolution</span>
	<span style="color: #666666; font-style: italic;">// deallocate any existing framebuffer	</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>client<span style="color: #339933;">-&gt;</span>frameBuffer <span style="color: #339933;">!=</span> NULL<span style="color: #009900;">&#41;</span>
		free <span style="color: #009900;">&#40;</span>client<span style="color: #339933;">-&gt;</span>frameBuffer<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	client<span style="color: #339933;">-&gt;</span>frameBuffer <span style="color: #339933;">=</span> malloc<span style="color: #009900;">&#40;</span>width <span style="color: #339933;">*</span> height <span style="color: #339933;">*</span> <span style="color: #009900;">&#40;</span>depth <span style="color: #339933;">/</span> <span style="color: #0000dd;">8</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>client<span style="color: #339933;">-&gt;</span>frameBuffer <span style="color: #339933;">==</span> NULL<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		fprintf<span style="color: #009900;">&#40;</span>stderr<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;Cannot allocate memory for framebuffer!&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		exit<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// we also need to tell libvncclient how it should put pixel data in there</span>
	client<span style="color: #339933;">-&gt;</span>format.<span style="color: #202020;">redShift</span>   <span style="color: #339933;">=</span> <span style="color: #0000dd;">8</span><span style="color: #339933;">;</span>
	client<span style="color: #339933;">-&gt;</span>format.<span style="color: #202020;">greenShift</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">16</span><span style="color: #339933;">;</span>
	client<span style="color: #339933;">-&gt;</span>format.<span style="color: #202020;">blueShift</span>  <span style="color: #339933;">=</span> <span style="color: #0000dd;">24</span><span style="color: #339933;">;</span>
	client<span style="color: #339933;">-&gt;</span>format.<span style="color: #202020;">redMax</span>     <span style="color: #339933;">=</span> <span style="color: #208080;">0xFF</span><span style="color: #339933;">;</span>
	client<span style="color: #339933;">-&gt;</span>format.<span style="color: #202020;">greenMax</span>   <span style="color: #339933;">=</span> <span style="color: #208080;">0xFF</span><span style="color: #339933;">;</span>
	client<span style="color: #339933;">-&gt;</span>format.<span style="color: #202020;">blueMax</span>    <span style="color: #339933;">=</span> <span style="color: #208080;">0xFF</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// now we set the format and encoding method information back to libvncclient so it updates it's information.</span>
	SetFormatAndEncodings<span style="color: #009900;">&#40;</span>client<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// report success to libvncclient</span>
	<span style="color: #b1b100;">return</span> TRUE<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">static</span> <span style="color: #993333;">void</span> updateImage<span style="color: #009900;">&#40;</span>rfbClient<span style="color: #339933;">*</span> client<span style="color: #339933;">,</span><span style="color: #993333;">int</span> u_x<span style="color: #339933;">,</span><span style="color: #993333;">int</span> u_y<span style="color: #339933;">,</span><span style="color: #993333;">int</span> u_w<span style="color: #339933;">,</span><span style="color: #993333;">int</span> u_h<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> x<span style="color: #339933;">,</span> y<span style="color: #339933;">,</span> src_x<span style="color: #339933;">,</span> src_y<span style="color: #339933;">;</span>
	<span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> <span style="color: #339933;">*</span>dest<span style="color: #339933;">;</span>
	<span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> <span style="color: #339933;">*</span>src<span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> max_x <span style="color: #339933;">=</span> SCREEN_SQUARE_SIZE <span style="color: #339933;">*</span> SCREEN_WIDTH<span style="color: #339933;">;</span>
	<span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> max_y <span style="color: #339933;">=</span> SCREEN_SQUARE_SIZE <span style="color: #339933;">*</span> SCREEN_HEIGHT<span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// precalculate the region we actually need to update.</span>
	<span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> u_min_x <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">double</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>u_x<span style="color: #009900;">&#41;</span> <span style="color: #339933;">/</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">double</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>client<span style="color: #339933;">-&gt;</span>width<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> max_x<span style="color: #339933;">;</span>
	<span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> u_min_y <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">double</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>u_y<span style="color: #009900;">&#41;</span> <span style="color: #339933;">/</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">double</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>client<span style="color: #339933;">-&gt;</span>height<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> max_y<span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> u_max_x <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">double</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>u_x <span style="color: #339933;">+</span> u_w<span style="color: #009900;">&#41;</span> <span style="color: #339933;">/</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">double</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>client<span style="color: #339933;">-&gt;</span>width<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> max_x<span style="color: #339933;">;</span>
	<span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> u_max_y <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">double</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>u_y <span style="color: #339933;">+</span> u_h<span style="color: #009900;">&#41;</span> <span style="color: #339933;">/</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">double</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>client<span style="color: #339933;">-&gt;</span>height<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> max_y<span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #993333;">unsigned</span> <span style="color: #993333;">char</span> updated<span style="color: #009900;">&#91;</span>SCREEN_SQUARE_SIZE <span style="color: #339933;">*</span> SCREEN_SQUARE_SIZE<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
	memset<span style="color: #009900;">&#40;</span>updated<span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> SCREEN_SQUARE_SIZE <span style="color: #339933;">*</span> SCREEN_SQUARE_SIZE<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// This scaling algorithm really sucks.  It's a &quot;nearest neighbour&quot; scaling format.</span>
	<span style="color: #666666; font-style: italic;">// It's really easy to implement, really fast, but looks absolutely terrible.</span>
	<span style="color: #666666; font-style: italic;">// Try and end up with the image being blown up so that 1x1 on the original maps to 2x2</span>
	<span style="color: #666666; font-style: italic;">// on the destination.  If it maps to a fraction of pixels things look really bad.</span>
	<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>y<span style="color: #339933;">=</span>u_min_y<span style="color: #339933;">;</span> y<span style="color: #339933;">&lt;</span>u_max_y<span style="color: #339933;">;</span> y<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>x<span style="color: #339933;">=</span>u_min_x<span style="color: #339933;">;</span> x<span style="color: #339933;">&lt;</span>u_max_x<span style="color: #339933;">;</span> x<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #666666; font-style: italic;">// now find out where that maps to on the original framebuffer.</span>
			src_x <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">double</span><span style="color: #009900;">&#41;</span>x <span style="color: #339933;">/</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">double</span><span style="color: #009900;">&#41;</span>max_x<span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">double</span><span style="color: #009900;">&#41;</span>client<span style="color: #339933;">-&gt;</span>width<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			src_y <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">double</span><span style="color: #009900;">&#41;</span>y <span style="color: #339933;">/</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">double</span><span style="color: #009900;">&#41;</span>max_y<span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">double</span><span style="color: #009900;">&#41;</span>client<span style="color: #339933;">-&gt;</span>height<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #666666; font-style: italic;">// figure out where this pixel is</span>
			<span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> d <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>y <span style="color: #339933;">/</span> SCREEN_HEIGHT<span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> SCREEN_SQUARE_SIZE<span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>x <span style="color: #339933;">/</span> SCREEN_WIDTH<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #666666; font-style: italic;">// now create a pointer to where that pixel is stored</span>
			dest <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span><span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">&amp;</span>output_screens<span style="color: #009900;">&#91;</span>d<span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span>frameBuffer<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>y <span style="color: #339933;">%</span> SCREEN_HEIGHT<span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> SCREEN_WIDTH<span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>x <span style="color: #339933;">%</span> SCREEN_WIDTH<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> <span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #666666; font-style: italic;">// and fix a pointer to that</span>
			src <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span><span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">&amp;</span>client<span style="color: #339933;">-&gt;</span>frameBuffer<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>src_y <span style="color: #339933;">*</span> client<span style="color: #339933;">-&gt;</span>width<span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> src_x<span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> <span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #666666; font-style: italic;">// and copy the pixel</span>
			<span style="color: #339933;">*</span>dest <span style="color: #339933;">=</span> <span style="color: #339933;">*</span>src<span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #666666; font-style: italic;">// mark that screen as updated</span>
			updated<span style="color: #009900;">&#91;</span>d<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>x<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> x<span style="color: #339933;">&lt;</span>SCREEN_SQUARE_SIZE <span style="color: #339933;">*</span> SCREEN_SQUARE_SIZE<span style="color: #339933;">;</span> x<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>updated<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
			<span style="color: #666666; font-style: italic;">// mark the entire screen as updated for now.  this could really</span>
			<span style="color: #666666; font-style: italic;">// use some proper optimisations.</span>
			rfbMarkRectAsModified<span style="color: #009900;">&#40;</span>output_screens<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> SCREEN_WIDTH<span style="color: #339933;">,</span> SCREEN_HEIGHT<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">int</span> main <span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> argc<span style="color: #339933;">,</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>argv<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	fprintf<span style="color: #009900;">&#40;</span>stderr<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;vnc-splitter<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	fprintf<span style="color: #009900;">&#40;</span>stderr<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;Copyright 2010 Michael Farrell &lt;http://micolous.id.au&gt;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #666666; font-style: italic;">// create a 32-bpp &quot;client&quot;.</span>
	rfbClient<span style="color: #339933;">*</span> client <span style="color: #339933;">=</span> rfbGetClient<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">8</span><span style="color: #339933;">,</span><span style="color: #0000dd;">3</span><span style="color: #339933;">,</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// tell the library we can handle being resized.</span>
	client<span style="color: #339933;">-&gt;</span>canHandleNewFBSize <span style="color: #339933;">=</span> TRUE<span style="color: #339933;">;</span>
	client<span style="color: #339933;">-&gt;</span>MallocFrameBuffer <span style="color: #339933;">=</span> resizeImage<span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// handle framebuffer updates</span>
	client<span style="color: #339933;">-&gt;</span>GotFrameBufferUpdate <span style="color: #339933;">=</span> updateImage<span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// we don't care about keyboard LEDs and tightvnc chat protocol.</span>
	client<span style="color: #339933;">-&gt;</span>HandleKeyboardLedState <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
	client<span style="color: #339933;">-&gt;</span>HandleTextChat <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// make a blank cursor</span>
	rfbCursorPtr cursor <span style="color: #339933;">=</span> rfbMakeXCursor<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;<span style="color: #006699; font-weight: bold;">\0</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;<span style="color: #006699; font-weight: bold;">\0</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// create the vnc servers</span>
	<span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> id<span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>id<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> id<span style="color: #339933;">&lt;</span>SCREEN_SQUARE_SIZE <span style="color: #339933;">*</span> SCREEN_SQUARE_SIZE<span style="color: #339933;">;</span> id<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		output_screens<span style="color: #009900;">&#91;</span>id<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> rfbGetScreen<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> NULL<span style="color: #339933;">,</span> SCREEN_WIDTH<span style="color: #339933;">,</span> SCREEN_HEIGHT<span style="color: #339933;">,</span> <span style="color: #0000dd;">8</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">3</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">4</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		output_screens<span style="color: #009900;">&#91;</span>id<span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span>frameBuffer <span style="color: #339933;">=</span> malloc<span style="color: #009900;">&#40;</span>SCREEN_WIDTH <span style="color: #339933;">*</span> SCREEN_HEIGHT <span style="color: #339933;">*</span> <span style="color: #0000dd;">4</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		output_screens<span style="color: #009900;">&#91;</span>id<span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span>serverFormat.<span style="color: #202020;">redShift</span>   <span style="color: #339933;">=</span> <span style="color: #0000dd;">8</span><span style="color: #339933;">;</span>
		output_screens<span style="color: #009900;">&#91;</span>id<span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span>serverFormat.<span style="color: #202020;">greenShift</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">16</span><span style="color: #339933;">;</span>
		output_screens<span style="color: #009900;">&#91;</span>id<span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span>serverFormat.<span style="color: #202020;">blueShift</span>  <span style="color: #339933;">=</span> <span style="color: #0000dd;">24</span><span style="color: #339933;">;</span>
		output_screens<span style="color: #009900;">&#91;</span>id<span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span>serverFormat.<span style="color: #202020;">redMax</span>     <span style="color: #339933;">=</span> <span style="color: #208080;">0xFF</span><span style="color: #339933;">;</span>
		output_screens<span style="color: #009900;">&#91;</span>id<span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span>serverFormat.<span style="color: #202020;">greenMax</span>   <span style="color: #339933;">=</span> <span style="color: #208080;">0xFF</span><span style="color: #339933;">;</span>
		output_screens<span style="color: #009900;">&#91;</span>id<span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span>serverFormat.<span style="color: #202020;">blueMax</span>    <span style="color: #339933;">=</span> <span style="color: #208080;">0xFF</span><span style="color: #339933;">;</span>
&nbsp;
		output_screens<span style="color: #009900;">&#91;</span>id<span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span>autoPort <span style="color: #339933;">=</span> FALSE<span style="color: #339933;">;</span>
		output_screens<span style="color: #009900;">&#91;</span>id<span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span>port <span style="color: #339933;">=</span> SERVER_PORT_OFFSET <span style="color: #339933;">+</span> DISPLAY_START <span style="color: #339933;">+</span> id<span style="color: #339933;">;</span>
		output_screens<span style="color: #009900;">&#91;</span>id<span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span>alwaysShared <span style="color: #339933;">=</span> TRUE<span style="color: #339933;">;</span>
		rfbSetCursor<span style="color: #009900;">&#40;</span>output_screens<span style="color: #009900;">&#91;</span>id<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> cursor<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// create the server in another thread</span>
		rfbInitServer<span style="color: #009900;">&#40;</span>output_screens<span style="color: #009900;">&#91;</span>id<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		rfbRunEventLoop<span style="color: #009900;">&#40;</span>output_screens<span style="color: #009900;">&#91;</span>id<span style="color: #009900;">&#93;</span><span style="color: #339933;">,-</span><span style="color: #0000dd;">1</span><span style="color: #339933;">,</span>TRUE<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// connect to the server</span>
	fprintf<span style="color: #009900;">&#40;</span>stderr<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;Connecting to server...<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// rfbInitClient also allows us to use vncviewer-style commandline options.</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>rfbInitClient<span style="color: #009900;">&#40;</span>client<span style="color: #339933;">,&amp;</span>argc<span style="color: #339933;">,</span>argv<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
		<span style="color: #b1b100;">return</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// start pumping the loop.</span>
	fprintf<span style="color: #009900;">&#40;</span>stderr<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;Pumping...<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	clock_t last_frame <span style="color: #339933;">=</span> clock<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	clock_t this_frame <span style="color: #339933;">=</span> last_frame<span style="color: #339933;">;</span>
	<span style="color: #b1b100;">do</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #993333;">int</span> i <span style="color: #339933;">=</span> WaitForMessage<span style="color: #009900;">&#40;</span>client<span style="color: #339933;">,</span> <span style="color: #0000dd;">100</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">&lt;</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span>
			<span style="color: #666666; font-style: italic;">// there was an issue getting the message, probably our socket was closed.</span>
			<span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span>
			<span style="color: #666666; font-style: italic;">// handle message</span>
			<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>HandleRFBServerMessage<span style="color: #009900;">&#40;</span>client<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
				<span style="color: #666666; font-style: italic;">// error handling message, die.</span>
				<span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://micolous.id.au/archives/2010/02/05/vnc-splitter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A pipe-based VNC viewer</title>
		<link>http://micolous.id.au/archives/2010/02/02/a-pipe-based-vnc-viewer/</link>
		<comments>http://micolous.id.au/archives/2010/02/02/a-pipe-based-vnc-viewer/#comments</comments>
		<pubDate>Tue, 02 Feb 2010 13:34:55 +0000</pubDate>
		<dc:creator>micolous</dc:creator>
				<category><![CDATA[Coding]]></category>

		<guid isPermaLink="false">http://micolous.id.au/?p=171</guid>
		<description><![CDATA[I&#8217;ve written a simple pipe-based VNC viewer, that is, it outputs a 32 bits-per-pixel RAW ARGB image stream to stdout every tenth of a second.  The effect is you can chain this with ffmpeg to create a multicast UDP video stream:

./vnc-fifo vncserver:0 &#124; ffmpeg -f rawvideo -pix_fmt argb -s 1024x768 -i -   [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve written a simple pipe-based VNC viewer, that is, it outputs a 32 bits-per-pixel RAW ARGB image stream to <code>stdout</code> every tenth of a second.  The effect is you can chain this with ffmpeg to create a multicast UDP video stream:</p>

<p><code>./vnc-fifo vncserver:0 | ffmpeg -f rawvideo -pix_fmt argb -s 1024x768 -i -   -vsync 1 -s 512x384 -f mpegts -vcodec mpeg4 -b 1000k -threads 2 udp://239.255.2.3:1234</code></p>

<p>In this example, I assume your VNC server is running on <code>vncserver:0</code>, and it is outputting 1024&#215;768.  Other output resolutions will result in corruption, so you&#8217;ll need to change the parameter appropriately.  It&#8217;ll also resize the image to 512&#215;384.</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// vnc-fifo.c</span>
<span style="color: #339933;">#include &lt;stdio.h&gt;</span>
<span style="color: #339933;">#include &lt;rfb/rfbclient.h&gt;</span>
<span style="color: #339933;">#include &lt;time.h&gt;</span>
&nbsp;
<span style="color: #993333;">static</span> rfbBool resizeImage<span style="color: #009900;">&#40;</span>rfbClient<span style="color: #339933;">*</span> client<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  
	<span style="color: #993333;">int</span> width<span style="color: #339933;">=</span>client<span style="color: #339933;">-&gt;</span>width<span style="color: #339933;">;</span>
	<span style="color: #993333;">int</span> height<span style="color: #339933;">=</span>client<span style="color: #339933;">-&gt;</span>height<span style="color: #339933;">;</span>
	<span style="color: #993333;">int</span> depth<span style="color: #339933;">=</span>client<span style="color: #339933;">-&gt;</span>format.<span style="color: #202020;">bitsPerPixel</span><span style="color: #339933;">;</span>
	fprintf<span style="color: #009900;">&#40;</span>stderr<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;ResizeImage fired: %ix%i %ibpp<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> width<span style="color: #339933;">,</span> height<span style="color: #339933;">,</span> depth<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// change the screen resolution</span>
	<span style="color: #666666; font-style: italic;">// deallocate any existing framebuffer	</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>client<span style="color: #339933;">-&gt;</span>frameBuffer <span style="color: #339933;">!=</span> NULL<span style="color: #009900;">&#41;</span>
		free <span style="color: #009900;">&#40;</span>client<span style="color: #339933;">-&gt;</span>frameBuffer<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	client<span style="color: #339933;">-&gt;</span>frameBuffer <span style="color: #339933;">=</span> malloc<span style="color: #009900;">&#40;</span>width <span style="color: #339933;">*</span> height <span style="color: #339933;">*</span> <span style="color: #009900;">&#40;</span>depth <span style="color: #339933;">/</span> <span style="color: #0000dd;">8</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>client<span style="color: #339933;">-&gt;</span>frameBuffer <span style="color: #339933;">==</span> NULL<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		fprintf<span style="color: #009900;">&#40;</span>stderr<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;Cannot allocate memory for framebuffer!&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		exit<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// we also need to tell libvncclient how it should put pixel data in there</span>
	<span style="color: #666666; font-style: italic;">// in a format that ffmpeg will be pleased with (32bpp ARGB)</span>
	client<span style="color: #339933;">-&gt;</span>format.<span style="color: #202020;">redShift</span>   <span style="color: #339933;">=</span> <span style="color: #0000dd;">8</span><span style="color: #339933;">;</span>
	client<span style="color: #339933;">-&gt;</span>format.<span style="color: #202020;">greenShift</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">16</span><span style="color: #339933;">;</span>
	client<span style="color: #339933;">-&gt;</span>format.<span style="color: #202020;">blueShift</span>  <span style="color: #339933;">=</span> <span style="color: #0000dd;">24</span><span style="color: #339933;">;</span>
	client<span style="color: #339933;">-&gt;</span>format.<span style="color: #202020;">redMax</span>     <span style="color: #339933;">=</span> <span style="color: #208080;">0xFF</span><span style="color: #339933;">;</span>
	client<span style="color: #339933;">-&gt;</span>format.<span style="color: #202020;">greenMax</span>   <span style="color: #339933;">=</span> <span style="color: #208080;">0xFF</span><span style="color: #339933;">;</span>
	client<span style="color: #339933;">-&gt;</span>format.<span style="color: #202020;">blueMax</span>    <span style="color: #339933;">=</span> <span style="color: #208080;">0xFF</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// now we set the format and encoding method information back to libvncclient so it updates it's information.</span>
	SetFormatAndEncodings<span style="color: #009900;">&#40;</span>client<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// report success to libvncclient</span>
	<span style="color: #b1b100;">return</span> TRUE<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">int</span> main <span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> argc<span style="color: #339933;">,</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>argv<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	fprintf<span style="color: #009900;">&#40;</span>stderr<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;vnc-fifo<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #666666; font-style: italic;">// create a 32-bpp &quot;client&quot;.</span>
	rfbClient<span style="color: #339933;">*</span> client <span style="color: #339933;">=</span> rfbGetClient<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">8</span><span style="color: #339933;">,</span><span style="color: #0000dd;">3</span><span style="color: #339933;">,</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// tell the library we can handle being resized.</span>
	client<span style="color: #339933;">-&gt;</span>canHandleNewFBSize <span style="color: #339933;">=</span> TRUE<span style="color: #339933;">;</span>
	client<span style="color: #339933;">-&gt;</span>MallocFrameBuffer <span style="color: #339933;">=</span> resizeImage<span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// we don't care about keyboard LEDs and tightvnc chat protocol.</span>
	client<span style="color: #339933;">-&gt;</span>HandleKeyboardLedState <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
	client<span style="color: #339933;">-&gt;</span>HandleTextChat <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// connect to the server</span>
	fprintf<span style="color: #009900;">&#40;</span>stderr<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;Connecting to server...<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// rfbInitClient also allows us to use vncviewer-style commandline options.</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>rfbInitClient<span style="color: #009900;">&#40;</span>client<span style="color: #339933;">,&amp;</span>argc<span style="color: #339933;">,</span>argv<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
		<span style="color: #b1b100;">return</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// start pumping the loop.</span>
	fprintf<span style="color: #009900;">&#40;</span>stderr<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;Pumping...<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	clock_t last_frame <span style="color: #339933;">=</span> clock<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	clock_t this_frame <span style="color: #339933;">=</span> last_frame<span style="color: #339933;">;</span>
	<span style="color: #b1b100;">do</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #993333;">int</span> i <span style="color: #339933;">=</span> WaitForMessage<span style="color: #009900;">&#40;</span>client<span style="color: #339933;">,</span> <span style="color: #0000dd;">10</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">&lt;</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span>
			<span style="color: #666666; font-style: italic;">// there was an issue getting the message, probably our socket was closed.</span>
			<span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span>
			<span style="color: #666666; font-style: italic;">// handle message</span>
			<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>HandleRFBServerMessage<span style="color: #009900;">&#40;</span>client<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
				<span style="color: #666666; font-style: italic;">// error handling message, die.</span>
				<span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// pump out a frame only if it has been 1/10 sec since the last one.</span>
		this_frame <span style="color: #339933;">=</span> clock<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>this_frame <span style="color: #339933;">-</span> last_frame <span style="color: #339933;">&gt;=</span> <span style="color: #009900;">&#40;</span>CLOCKS_PER_SEC <span style="color: #339933;">/</span> <span style="color: #0000dd;">100</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
			<span style="color: #666666; font-style: italic;">// pump out a frame</span>
			last_frame <span style="color: #339933;">=</span> this_frame<span style="color: #339933;">;</span>
			fwrite<span style="color: #009900;">&#40;</span>client<span style="color: #339933;">-&gt;</span>frameBuffer<span style="color: #339933;">,</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">,</span> client<span style="color: #339933;">-&gt;</span>width <span style="color: #339933;">*</span> client<span style="color: #339933;">-&gt;</span>height <span style="color: #339933;">*</span> <span style="color: #009900;">&#40;</span>client<span style="color: #339933;">-&gt;</span>format.<span style="color: #202020;">bitsPerPixel</span><span style="color: #339933;">/</span><span style="color: #0000dd;">8</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> stdout<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			fflush<span style="color: #009900;">&#40;</span>stdout<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>


<p>There is an issue with using ffmpeg in this fashion, because the framerate is variable, you essentially lie in your MPEG transport stream by saying you have a much higher framerate.  The effect in ffplay is that it&#8217;ll buffer 10-45 seconds of video, play it all back to the end very fast, empty it&#8217;s buffer, then play normally.  It&#8217;ll be &#8220;hanging on your every packet&#8221; for more video data.</p>

<p>Unfortunately, I couldn&#8217;t get VLC to act in the same fashion (as a reciever), even after telling it not to drop or skip frames, playback was jerky.</p>

<p>Oh well, an experiment to see if I could get out of writing a VLC or ffmpeg source module for VNC.  Looks like if I want to go further with this, there&#8217;ll need to be a lot of changes to the code.</p>
]]></content:encoded>
			<wfw:commentRss>http://micolous.id.au/archives/2010/02/02/a-pipe-based-vnc-viewer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VNC Client as Screen Saver</title>
		<link>http://micolous.id.au/archives/2010/01/24/vnc-client-as-screen-saver/</link>
		<comments>http://micolous.id.au/archives/2010/01/24/vnc-client-as-screen-saver/#comments</comments>
		<pubDate>Sat, 23 Jan 2010 21:06:51 +0000</pubDate>
		<dc:creator>micolous</dc:creator>
				<category><![CDATA[Coding]]></category>

		<guid isPermaLink="false">http://micolous.id.au/?p=169</guid>
		<description><![CDATA[I&#8217;ve whipped up a VNC Screen Saver in .NET for Windows.  It is based on this screensaver example and VncSharp.  It&#8217;s a bit of a quick hack, but works.

To get it, download the binaries and extract it to your Windows system32 folder (typically C:\Windows\System32\).  Then open the screensaver settings, select Vncscreensaver and [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve whipped up a VNC Screen Saver in .NET for Windows.  It is based on <a href="http://www.codeproject.com/KB/cs/scrframework.aspx">this screensaver example</a> and <a href="http://cdot.senecac.on.ca/projects/vncsharp/">VncSharp</a>.  It&#8217;s a bit of a quick hack, but works.</p>

<p>To get it, <a href="/static/projects/vncscreensaver/vncscreensaver-1.0-bin.7z">download the binaries</a> and extract it to your Windows system32 folder (typically <code>C:\Windows\System32\</code>).  Then open the screensaver settings, select <code>Vncscreensaver</code> and then configure it with your VNC server details.  You can then use the screen saver!</p>

<p>Make sure the server you&#8217;re connecting to doesn&#8217;t require a password, otherwise this won&#8217;t work.  The client runs in &#8220;view only&#8221; mode.  It will quit when you either click the mouse or press a key, because hooking mouse movement seems to cause problems with the VNC client when it tries to reconnect.</p>

<p>If you&#8217;re interested, there&#8217;s also <a href="/static/projects/vncscreensaver/vncscreensaver-1.0-src.7z">source code available</a> for the program, licensed under the GPLv2 (the same license as VncSharp).</p>
]]></content:encoded>
			<wfw:commentRss>http://micolous.id.au/archives/2010/01/24/vnc-client-as-screen-saver/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux iSCSI COW Images, and Windows integration.</title>
		<link>http://micolous.id.au/archives/2010/01/23/linux-iscsi-cow-images-and-windows-integration/</link>
		<comments>http://micolous.id.au/archives/2010/01/23/linux-iscsi-cow-images-and-windows-integration/#comments</comments>
		<pubDate>Sat, 23 Jan 2010 10:38:32 +0000</pubDate>
		<dc:creator>micolous</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Computers]]></category>
		<category><![CDATA[Lanning]]></category>

		<guid isPermaLink="false">http://micolous.id.au/?p=164</guid>
		<description><![CDATA[More stuff for RetroLAN PCs, yay!

I&#8217;ve now got all the RetroLAN PCs running out of a copy-on-write image.  This means I now have a single 4GB &#8220;base&#8221; image with an installation of Windows XP, instead of having 10 of them.  It also means it is very trivial to reset the machine&#8217;s disk images, [...]]]></description>
			<content:encoded><![CDATA[<p>More stuff for RetroLAN PCs, yay!</p>

<p>I&#8217;ve now got all the RetroLAN PCs running out of a copy-on-write image.  This means I now have a single 4GB &#8220;base&#8221; image with an installation of Windows XP, instead of having 10 of them.  It also means it is very trivial to reset the machine&#8217;s disk images, which I achieved with a bit of scripting. </p>

<p>First up, I needed to setup the copy-on-write images through <code>device-mapper</code>.  This program is designed to let you setup software RAID, but it also allows snapshotting disks to provide a backup of a device at a point in time.  Unfortunately, <code>dmsetup</code> doesn&#8217;t support accessing file images, only actual devices, so I need to create some loopback devices first.</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># setup loop0 as the &quot;master&quot; image, and mark it as read-only so no changes ever get written back.</span>
losetup <span style="color: #660033;">-r</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>loop0 <span style="color: #000000; font-weight: bold;">/</span>store<span style="color: #000000; font-weight: bold;">/</span>master.img
<span style="color: #666666; font-style: italic;"># we need to get the size of the image in sectors for use later on.</span>
<span style="color: #007800;">cow_size</span>=<span style="color: #000000; font-weight: bold;">`</span>blockdev <span style="color: #660033;">--getsize</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>loop0<span style="color: #000000; font-weight: bold;">`</span></pre></td></tr></table></div>


<p>The next step is to create a blank image file and loopback device to commit changes to.  For my setup, I created 200MB images.  Be aware of things like disk-based caches and automatic defragmentation will use up the allocated space very quickly, and when you run out of space in this file further writes will not be allowed, and Windows will soon crash with a blue screen of death.  (More on dealing with this in a bit)</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># remove any existing COW image</span>
<span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #000000; font-weight: bold;">/</span>store<span style="color: #000000; font-weight: bold;">/</span>pc-1.cow
&nbsp;
<span style="color: #666666; font-style: italic;"># create a new 200MB image (it's actually comes out 5% more than stated, but it allows for overheads in the filesystem)</span>
<span style="color: #c20cb9; font-weight: bold;">dd</span> <span style="color: #007800;"><span style="color: #000000; font-weight: bold;">if</span></span>=<span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>zero <span style="color: #007800;">of</span>=<span style="color: #000000; font-weight: bold;">/</span>store<span style="color: #000000; font-weight: bold;">/</span>pc-1.cow <span style="color: #007800;">bs</span>=1M <span style="color: #007800;">count</span>=<span style="color: #000000;">200</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># now hook it to a loopback device</span>
losetup <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>loop1 <span style="color: #000000; font-weight: bold;">/</span>store<span style="color: #000000; font-weight: bold;">/</span>pc-1.cow</pre></td></tr></table></div>


<p>Now we have two devices, <code>/dev/loop0</code> which contains the master image, and <code>/dev/loop1</code> which will contain any changes made to the disk.  The next step is to use dmsetup to create a <code>device mapper</code> which will layer the COW image ontop of the original image.</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># create the cow!</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;0 <span style="color: #007800;">${cow_size}</span> snapshot /dev/loop0 /dev/loop1 p 64&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> dmsetup create pc1</pre></td></tr></table></div>


<p>This will create a device called <code>/dev/mapper/pc1</code>.  You can use it in your iSCSI setup with something like this in your <code>/etc/ietd.conf</code>:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="txt" style="font-family:monospace;">Target iqn.2010-01.lan.someplace.iscsihost:pc1
        Lun 0 Path=/dev/mapper/pc1,Type=fileio</pre></td></tr></table></div>


<p>You can then start <code>ietd</code>.</p>

<p>Now the next part is writing a script to let you reset the COW images.  <code>ietd</code> does not like you changing things while it is running, so you&#8217;ll need to make sure your script suspends all disk activity before blanking out the COW image.  Something like this:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># disconnect the COW image #1</span>
ietadm <span style="color: #660033;">--op</span> delete <span style="color: #660033;">--tid</span> <span style="color: #000000;">1</span> <span style="color: #660033;">--lun</span> <span style="color: #000000;">0</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># suspend dm activity</span>
dmsetup <span style="color: #7a0874; font-weight: bold;">suspend</span> pc1
&nbsp;
<span style="color: #666666; font-style: italic;"># clear the cow cache</span>
<span style="color: #c20cb9; font-weight: bold;">dd</span> <span style="color: #007800;"><span style="color: #000000; font-weight: bold;">if</span></span>=<span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>zero <span style="color: #007800;">of</span>=<span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>loop1
&nbsp;
<span style="color: #666666; font-style: italic;"># reload the cow table</span>
<span style="color: #007800;">master</span>=<span style="color: #ff0000;">&quot;/dev/loop0&quot;</span>
<span style="color: #007800;">cow_size</span>=<span style="color: #000000; font-weight: bold;">`</span>blockdev <span style="color: #660033;">--getsize</span> <span style="color: #800000;">${master}</span><span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;0 <span style="color: #007800;">${cow_size}</span> snapshot <span style="color: #007800;">${master}</span> /dev/loop1 p 64&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> dmsetup reload pc1
&nbsp;
<span style="color: #666666; font-style: italic;"># resume dm activity</span>
dmsetup resume pc1
&nbsp;
<span style="color: #666666; font-style: italic;"># reconnect the COW image #1</span>
ietadm <span style="color: #660033;">--op</span> new <span style="color: #660033;">--tid</span> <span style="color: #000000;">1</span> <span style="color: #660033;">--lun</span> <span style="color: #000000;">0</span> <span style="color: #660033;">--params</span> <span style="color: #007800;">Path</span>=<span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>mapper<span style="color: #000000; font-weight: bold;">/</span>pc1</pre></td></tr></table></div>


<p>You could change this script around so that it allows you to pass in a PC number as a command-line argument, and then hook in a CGI script that will call it to reset it remotely.  In my setup, I&#8217;m using gPXE to boot from iSCSI, but it can also be used to access a URL via HTTP.  So your CGI script reads in the request IP address, and if it is one of the resettable machines, it will reset it&#8217;s COW image.  Then it sends back a gPXE script instructing it to run a DOS .com file that will reboot the computer.  For this to work you need to have your CGI script execute the command as the superuser (root).</p>

<p>One of the things about the COWs is if you reset them or they become full while Windows is running, Windows will very soon crash, and refuse to boot up again.  To better inform both yourself and users about the usage levels, you can read the information from <code>dmsetup</code>:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># dmsetup status pc8</span>
<span style="color: #000000;">0</span> <span style="color: #000000;">8385930</span> snapshot <span style="color: #000000;">55296</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">409600</span></pre></td></tr></table></div>


<p>In this example, it is indicating that the full image is 8385930 sectors, and 55296 of 409600 sectors are used in the COW image.  So I wrote a Python CGI script that reports this in a parsable fashion to clients:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Content-Type: text/plain<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\r</span>&quot;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">os</span> <span style="color: #ff7700;font-weight:bold;">import</span> environ
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">subprocess</span> <span style="color: #ff7700;font-weight:bold;">import</span> Popen, PIPE
&nbsp;
ip = environ<span style="color: black;">&#91;</span><span style="color: #483d8b;">'REMOTE_ADDR'</span><span style="color: black;">&#93;</span>
d = <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>ip.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;.&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">if</span> d <span style="color: #66cc66;">&gt;</span>= <span style="color: #ff4500;">41</span> <span style="color: #ff7700;font-weight:bold;">and</span> d <span style="color: #66cc66;">&lt;</span>= <span style="color: #ff4500;">54</span>:
  machine = d - <span style="color: #ff4500;">40</span>
  <span style="color: #ff7700;font-weight:bold;">try</span>:
    p = Popen<span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/sbin/dmsetup'</span>, <span style="color: #483d8b;">'status'</span>, <span style="color: #483d8b;">'retrocow%d'</span> <span style="color: #66cc66;">%</span> machine<span style="color: black;">&#41;</span>, stdout=PIPE, stderr=PIPE<span style="color: black;">&#41;</span>
    stdout, stderr = p.<span style="color: black;">communicate</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    use, total = stdout.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">' '</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/'</span><span style="color: black;">&#41;</span>
    use, total = <span style="color: #008000;">long</span><span style="color: black;">&#40;</span>use<span style="color: black;">&#41;</span>, <span style="color: #008000;">long</span><span style="color: black;">&#40;</span>total<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;OK %d %d&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>use, total<span style="color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;">except</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;ERR Problem getting parsing information&quot;</span>
<span style="color: #ff7700;font-weight:bold;">else</span>:
  <span style="color: #808080; font-style: italic;"># return error</span>
  <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;ERR Not a RetroLAN Machine&quot;</span></pre></td></tr></table></div>


<p>For me, the RetroLAN machines have IPs ending in 41 to 54.  That corresponds to their PC number (retro-01 to retro-14).  This script outputs the following text file when requested via CGI if successful:</p>

<pre>OK 55296 409600</pre>

<p>This isn&#8217;t very usable for the end user, so I wrote a .NET 2.0 app called <code>CowBell</code> that runs in the system tray showing the percentage of COW usage, and notifies them if they&#8217;re over 75% usage (which means they will crash soon).  I&#8217;ve made <a href="/static/projects/cowbell/cowbell-1.0-src.7z">source code available for download</a>, which you&#8217;ll need to modify <code>frmMain.cs</code> line 37 to include the path to where you put the CGI script, and uncomment the line otherwise it <strong>will not compile</strong>.  If you make modifications to this program I do ask that you share your improvements with me.</p>

<p>This is the message that constantly pops up when you&#8217;re over 75% usage:</p>

<p><img src="http://micolous.id.au/static/projects/cowbell/cowbell.png" alt="" /></p>

<p>The application refreshes it&#8217;s status every 10 seconds, and if you right-click the icon it shows the COW usage in sectors.</p>
]]></content:encoded>
			<wfw:commentRss>http://micolous.id.au/archives/2010/01/23/linux-iscsi-cow-images-and-windows-integration/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dynamically changing Windows&#8217; wallpaper based on hostname</title>
		<link>http://micolous.id.au/archives/2010/01/20/dynamically-changing-windows-wallpaper-based-on-hostname/</link>
		<comments>http://micolous.id.au/archives/2010/01/20/dynamically-changing-windows-wallpaper-based-on-hostname/#comments</comments>
		<pubDate>Tue, 19 Jan 2010 18:06:12 +0000</pubDate>
		<dc:creator>micolous</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Computers]]></category>
		<category><![CDATA[Lanning]]></category>

		<guid isPermaLink="false">http://micolous.id.au/?p=159</guid>
		<description><![CDATA[I have a situation where I&#8217;ve got 14 machines booting Windows XP over iSCSI, and they&#8217;ve all got the same computer name set, and they each need to have a different wallpaper set on each machine.  This runs the &#8220;RetroLAN&#8221; machines at StreetGeek in the new setup, to make it much easier to roll [...]]]></description>
			<content:encoded><![CDATA[<p>I have a situation where I&#8217;ve got 14 machines booting Windows XP over iSCSI, and they&#8217;ve all got the same computer name set, and they each need to have a different wallpaper set on each machine.  This runs the &#8220;RetroLAN&#8221; machines at StreetGeek in the new setup, to make it much easier to roll out updates to machines.  They&#8217;re all using the same base image, and this will get restored if things get broken.  I&#8217;m using gPXE to boot the machines in the first place, and I&#8217;ve disabled NetBIOS over TCP/IP (to avoid the problem where Windows complains if two computers have the same name), and manually set the DNS search order (because when you boot Windows over iSCSI, Windows&#8217; own DHCP client doesn&#8217;t get activated).</p>

<p>So I hacked together this VBScript that does a reverse DNS lookup on the IP, and uses that to get a specific wallpaper for the machine using a bit of copy-paste from the &#8216;net.  The script requires you use <a href="http://www.jsware.net/jsware/scripts.php5#jssys">JSWare&#8217;s JSSys</a> addin for VBScript, so make sure you have that DLL installed and registered before trying to use my script.  There&#8217;s a way to do it without JSWare using the registry, but it only applies after logging out and logging in again.</p>

<p>In the code it will try to grab the wallpaper from <code>&#92;logres\wallpapers</code>.  You&#8217;ll need to change this for your setup.  To activate this, I added it to the Startup folder, so about 5 seconds after login, the wallpaper is automatically changed to be for the correct machine.</p>

<p>One minor caveat: Apparently my network card was network card #2, and there was no #1.  You can check what ID your card is in <code>HKLM\Software\Microsoft\Windows NT\CurrentVersion\NetworkCards\</code>, and change the line in the script appropriately.</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
</pre></td><td class="code"><pre class="vb" style="font-family:monospace;"><span style="color: #008000;">' Automatically setup wallpaper (autowallpaper.vbs)
</span>
<span style="color: #000080;">Function</span> GetFQDN(ipaddress)
  <span style="color: #000080;">set</span> sh = createobject(<span style="color: #800000;">&quot;wscript.shell&quot;</span>)
  <span style="color: #000080;">set</span> fso = createobject(<span style="color: #800000;">&quot;scripting.filesystemobject&quot;</span>)
  <span style="color: #000080;">Set</span> Env = sh.Environment(<span style="color: #800000;">&quot;PROCESS&quot;</span>)
&nbsp;
  workfile = fso.gettempname
  sh.run <span style="color: #800000;">&quot;%comspec% /c nslookup &quot;</span> &amp; ipaddress &amp; <span style="color: #800000;">&quot;  &gt; &quot;</span> &amp; workfile,0,<span style="color: #000080;">true</span>
  <span style="color: #000080;">set</span> sh = <span style="color: #000080;">nothing</span>
  <span style="color: #000080;">set</span> ts = fso.opentextfile(workfile)
  data = split(ts.readall,vbcr)
  ts.<span style="color: #000080;">close</span>
&nbsp;
  <span style="color: #000080;">set</span> ts = <span style="color: #000080;">nothing</span>
  fso.deletefile workfile
  <span style="color: #000080;">set</span> fso = <span style="color: #000080;">nothing</span>
  <span style="color: #000080;">for</span> n = 0 <span style="color: #000080;">to</span> <span style="color: #000080;">ubound</span>(data)
    <span style="color: #000080;">if</span> instr(data(n),<span style="color: #800000;">&quot;Name&quot;</span>) <span style="color: #000080;">then</span>
      parts = split(data(n),<span style="color: #800000;">&quot;:&quot;</span>)
      hostname= trim(<span style="color: #000080;">cstr</span>(parts(1)))
      <span style="color: #000080;">Exit</span> <span style="color: #000080;">For</span>
    <span style="color: #000080;">end</span> <span style="color: #000080;">if</span>
    hostname = <span style="color: #800000;">&quot;could not resolve IP address&quot;</span>
  <span style="color: #000080;">next</span>
&nbsp;
  GetFQDN = hostname
<span style="color: #000080;">End</span> <span style="color: #000080;">Function</span>
&nbsp;
<span style="color: #000080;">Const</span> HKCU = &amp;H80000001
<span style="color: #000080;">Const</span> HKLM = &amp;H80000002
&nbsp;
<span style="color: #000080;">Set</span> objReg = GetObject(<span style="color: #800000;">&quot;winmgmts:\\.\root\default:StdRegProv&quot;</span>)
&nbsp;
<span style="color: #008000;">' Get NIC service name
</span>objReg.GetStringValue HKLM, <span style="color: #800000;">&quot;Software\Microsoft\Windows NT\CurrentVersion\NetworkCards\2&quot;</span>, <span style="color: #800000;">&quot;ServiceName&quot;</span>, nicService
&nbsp;
<span style="color: #008000;">' Get IP address
</span>objReg.GetMultiStringValue HKLM, <span style="color: #800000;">&quot;System\CurrentControlSet\Services\TCPIP\Parameters\Interfaces\&quot;</span> &amp; nicService, <span style="color: #800000;">&quot;IPAddress&quot;</span>, addrs
&nbsp;
<span style="color: #008000;">' Resolve name
</span>fullname = GetFQDN(addrs(0))
shortname = split(fullname, <span style="color: #800000;">&quot;.&quot;</span>)(0)
&nbsp;
<span style="color: #000080;">Dim</span> objOps
<span style="color: #000080;">Set</span> objOps = CreateObject(<span style="color: #800000;">&quot;JSSys3.Ops&quot;</span>)
&nbsp;
r = objOps.SetWallpaper(<span style="color: #800000;">&quot;\\logres\wallpapers\&quot;</span> &amp; shortname &amp; <span style="color: #800000;">&quot;.bmp&quot;</span>, <span style="color: #800000;">&quot;center&quot;</span>)</pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://micolous.id.au/archives/2010/01/20/dynamically-changing-windows-wallpaper-based-on-hostname/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Night vision colour filter for Compiz</title>
		<link>http://micolous.id.au/archives/2009/11/26/night-vision-colour-filter-for-compiz/</link>
		<comments>http://micolous.id.au/archives/2009/11/26/night-vision-colour-filter-for-compiz/#comments</comments>
		<pubDate>Wed, 25 Nov 2009 15:09:10 +0000</pubDate>
		<dc:creator>micolous</dc:creator>
				<category><![CDATA[Coding]]></category>

		<guid isPermaLink="false">http://micolous.id.au/?p=157</guid>
		<description><![CDATA[I&#8217;ve hacked together a really quick colour filter for Compiz that is a &#8220;night vision mode&#8221;.  That is, it turns everything to greyscale, then drops the green and blue channels to make everything red.

Such themes are typically popular with astronomers and anyone else who works with a computer in a dark place.

Be aware that [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve hacked together a really quick colour filter for Compiz that is a &#8220;night vision mode&#8221;.  That is, it turns everything to greyscale, then drops the green and blue channels to make everything red.</p>

<p>Such themes are typically popular with astronomers and anyone else who works with a computer in a dark place.</p>

<p>Be aware that Compiz defaults to a &#8220;composite&#8221; colour filtering mode, that is, it applies <em>all</em> of your colour filters by default.  You may want to remove your other colour filters if you don&#8217;t use them after adding this one, otherwise you may come up with undesired results.  It also doesn&#8217;t apply the filter to the root window (your desktop wallpaper and icons), so you may want to change your wallpaper appropriately and remove your desktop icons.</p>

<p>The filter code:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="glsl" style="font-family:monospace;"><span style="color: #000066;">!!</span>ARBfp1<span style="color: #000066;">.</span>0
TEMP tex<span style="color: #000066;">;</span>
TEX tex<span style="color: #000066;">,</span> fragment<span style="color: #000066;">.</span><span style="color: #006600;">texcoord</span><span style="color: #000066;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">,</span> texture<span style="color: #000066;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">,</span> RECT<span style="color: #000066;">;</span>
DP3 tex<span style="color: #000066;">.</span><span style="color: #006600;">r</span><span style="color: #000066;">,</span> tex<span style="color: #000066;">,</span> <span style="color: #000066;">&#123;</span><span style="color: #0000ff;">0.33333</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">0.33333</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">0.33333</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">0</span><span style="color: #000066;">&#125;</span><span style="color: #000066;">;</span>
MUL tex<span style="color: #000066;">,</span> tex<span style="color: #000066;">,</span> <span style="color: #000066;">&#123;</span><span style="color: #0000ff;">1.0</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">0</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">0</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">1.0</span><span style="color: #000066;">&#125;</span><span style="color: #000066;">;</span>
MOV result<span style="color: #000066;">.</span><span style="color: #006600;">color</span><span style="color: #000066;">,</span> tex<span style="color: #000066;">.</span><span style="color: #006600;">rgga</span><span style="color: #000066;">;</span>
END</pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://micolous.id.au/archives/2009/11/26/night-vision-colour-filter-for-compiz/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RetroLAN fun!</title>
		<link>http://micolous.id.au/archives/2009/09/30/retrolan-fun/</link>
		<comments>http://micolous.id.au/archives/2009/09/30/retrolan-fun/#comments</comments>
		<pubDate>Wed, 30 Sep 2009 13:35:14 +0000</pubDate>
		<dc:creator>micolous</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Lanning]]></category>

		<guid isPermaLink="false">http://micolous.id.au/?p=151</guid>
		<description><![CDATA[For StreetGeek 9.08, some people may have noticed that I changed the format of the presentation software for that event.  I really should have blogged about this, say&#8230; a month ago&#8230; but I really just ran out of time to talk about it and I really didn&#8217;t want to spoil the surprise before the [...]]]></description>
			<content:encoded><![CDATA[<p>For StreetGeek 9.08, some people may have noticed that I changed the format of the presentation software for that event.  I really should have blogged about this, say&#8230; a month ago&#8230; but I really just ran out of time to talk about it and I really didn&#8217;t want to spoil the surprise before the event. <img src='http://micolous.id.au/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>

<p><img src="/static/resc/retro2.png" alt=""/></p>

<p>In SAGAPresenter (the presentation software I wrote for StreetGeek and SAGAfest), I wrote a fully functioning PETSCII telnet server.  This meant that I wasn&#8217;t just pretending to look like a Commodore 64 with downgraded graphics, but I was sending <em>actual</em> command-codes that a Commodore 64 with a network card (and telnet client) could interpret and display.  Unfortunately, we didn&#8217;t have a C64 with a network adaptor for the LAN, so I installed <a href="http://www.paradroid.net/cgterm/">Per Olofsson&#8217;s cgterm</a>, which emulated the C64 on a normal PC without the need for special hardware.  It was also much easier to hook up to a projector for the event.</p>

<p>All the while, the traditional GTK# interface was still running, and the displays all perfectly synchronised with each other.  I used <a href="http://it.toolbox.com/blogs/paytonbyrd/howto-implement-a-text-encoder-in-net-20-13243">this PETSCII .NET encoding handler</a> to do a little bit of the text conversion, however I had to write my own code to handle the text alignment and inserting control characters in the right spot.</p>

<p>All in all it was a fun hack, with not a huge amount of code additions required.  I spent most of the time converting sponsor banners by hand to PETSCII and tweaking to get them just right!</p>
]]></content:encoded>
			<wfw:commentRss>http://micolous.id.au/archives/2009/09/30/retrolan-fun/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
