<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3034230779454603134</id><updated>2024-09-10T08:26:50.985-07:00</updated><category term="Linux"/><category term="Ubuntu"/><category term="Pericles"/><category term="Operating Systems"/><category term="Desktop"/><category term="Google"/><category term="Server"/><category term="Standards"/><category term="open source"/><category term="software"/><category term="Apache"/><category term="Games"/><category term="Gnome"/><category term="MySQL"/><category term="UVOG"/><category term="bloat"/><category term="review"/><category term="tutorial"/><category term="Cookies"/><category term="DNS"/><category term="Firefox"/><category term="Kitten-Fu"/><category term="Philosophy"/><category term="Windows"/><category term="blogs"/><category term="FTP"/><category term="Food"/><category term="Microsoft"/><category term="PHP"/><category term="Web Apps"/><category term="Wine"/><category term="apt-cacher-ng"/><category term="freedom"/><category term="humor"/><category term="vnc"/><category term="ATtiny2313"/><category term="Arcade"/><category term="Chrome"/><category term="Chromium"/><category term="Databases"/><category term="Eben Moglen"/><category term="File Management"/><category term="Firewall"/><category term="Free Software"/><category term="Free Software Foundation"/><category term="Mercury"/><category term="Networking"/><category term="Office"/><category term="OpenOffice"/><category term="Opera"/><category term="Photos"/><category term="Religion"/><category term="Sounds"/><category term="Television"/><category term="Terminal"/><category term="Themes"/><category term="Thunderbird"/><category term="bing"/><category term="chroot"/><category term="compiz"/><category term="data"/><category term="electronics"/><category term="keyboard"/><category term="law"/><category term="metacity"/><category term="oregon"/><category term="patents"/><category term="perl"/><category term="python"/><category term="recycling"/><category term="robots"/><category term="sad"/><category term="script"/><category term="search engine"/><category term="sudo"/><title type='text'>Open Computing</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://opencomputing.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default'/><link rel='alternate' type='text/html' href='http://opencomputing.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default?start-index=26&amp;max-results=25'/><author><name>Jeff Day</name><uri>http://www.blogger.com/profile/11675035864869123800</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>68</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3034230779454603134.post-7949347207492420177</id><published>2017-05-19T20:06:00.002-07:00</published><updated>2017-05-19T20:06:22.266-07:00</updated><title type='text'>RSA SecurID on ChromeBook (Command Line)</title><content type='html'>I needed to be able to use my token generator on my new ChromeBook. &amp;nbsp;This particular model doesn&#39;t seem to have Google Play enabled at the moment, so the Android app wasn&#39;t an option.&lt;br /&gt;
&lt;br /&gt;
I&#39;ve used &quot;stoken&quot; for command line SecurID tokens in the past on macOS Sierra. &amp;nbsp;So, I decided I&#39;d compile by hand.&lt;br /&gt;
&lt;br /&gt;
This requires a ChromeBook already in Developer Mode, with a root password and a chronos password established so it is not left insecure!&lt;br /&gt;
&lt;br /&gt;
Open crosh, then run shell.&lt;br /&gt;
&lt;br /&gt;
First, install chromebrew (google it!)&lt;br /&gt;
&lt;br /&gt;
Update it.&lt;br /&gt;
&lt;br /&gt;
Install some prerequisites:&lt;br /&gt;
&lt;br /&gt;
crew install autoconf&lt;br /&gt;
crew install automake&lt;br /&gt;
crew install nettle&lt;br /&gt;
&lt;br /&gt;
Remount your user partition to allow execute privs:&lt;br /&gt;
&lt;br /&gt;
sudo mount -o remount,exec /home/chronos/user -i&lt;br /&gt;
&lt;br /&gt;
Clone the source for libxml2, you&#39;ll need to compile it first:&lt;br /&gt;
&lt;br /&gt;
git clone git://git.gnome.org/libxml2&lt;br /&gt;
cd libxml2&lt;br /&gt;
./autogen.sh&lt;br /&gt;
make&lt;br /&gt;
make install&lt;br /&gt;
cd ..&lt;br /&gt;
&lt;br /&gt;
Clone the source for stoken:&lt;br /&gt;
&lt;br /&gt;
git clone https://github.com/cernekee/stoken.git&lt;br /&gt;
cd stoken&lt;br /&gt;
./configure&lt;br /&gt;
make&lt;br /&gt;
make install&lt;br /&gt;
cd ..&lt;br /&gt;
&lt;br /&gt;
Get your sdtid file onto the machine (sd card or Dropbox or something. &amp;nbsp;Don&#39;t leave it there when you&#39;re done!)&lt;br /&gt;
&lt;br /&gt;
stoken import --file=my.sdtid&lt;br /&gt;
&lt;br /&gt;
It will prompt you for a passphrase if the file has one, then for a new password and to confirm the password. &amp;nbsp;You will enter this password every time you want to generate the token code.&lt;br /&gt;
&lt;br /&gt;
After this, to generate a token, just run stoken and enter your password.&lt;br /&gt;
&lt;br /&gt;
I hope I didn&#39;t leave out any crucial steps. &amp;nbsp;This is my summary after a lot of hit-and-miss effort to accomplish this.</content><link rel='replies' type='application/atom+xml' href='http://opencomputing.blogspot.com/feeds/7949347207492420177/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3034230779454603134/7949347207492420177' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/7949347207492420177'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/7949347207492420177'/><link rel='alternate' type='text/html' href='http://opencomputing.blogspot.com/2017/05/rsa-securid-on-chromebook-command-line.html' title='RSA SecurID on ChromeBook (Command Line)'/><author><name>Jeff Day</name><uri>http://www.blogger.com/profile/11675035864869123800</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3034230779454603134.post-6728756447259581414</id><published>2014-03-19T03:20:00.000-07:00</published><updated>2014-03-19T04:26:24.079-07:00</updated><title type='text'>New Exception Handling Model</title><content type='html'>My friend Derek and I are working on ideas for a new (or revised) programming language. Tonight we discussed exception handling. We&#39;re replacing try/catch/finally with something else, which I will demonstrate below as if it were part of PHP (it isn&#39;t!)

&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: php&quot;&gt;  function MyFunction!($x) {

    except ($E) {
      if (is_a($E, &#39;FileIOException&#39;)) {
        return false;
      } else {
        throw($E); // throw to the calling function
      }
    }

    except Special($E) {
      // this is a special exception handler
      resume;
    }


    $f = fopen!(&#39;myfile.dat&#39;);

    error_log!Special(&quot;Ignore this exception\n&quot;, 3, &#39;/no_perms.txt&#39;);
    
  }
&lt;/pre&gt;
Ok, so what is this?  Just a couple simple concepts:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Only functions declared with a ! after their name are allowed to throw exceptions up to their caller.

&lt;/li&gt;
&lt;li&gt;Exceptions thrown by calls made within the current function hit the unnamed (default) except{} handler, unless the function was invoked with a specific handler given after the ! in its name, in which case that handler is called instead.&lt;/li&gt;
&lt;li&gt;Handlers share local scope with the function they belong to, so they can set flags, manipulate local variables, etc.&lt;/li&gt;
&lt;li&gt;You can use return from inside of a handler to end the entire function.&lt;/li&gt;
&lt;li&gt;If an exception handler ends without a return or throw being encountered, execution continues with the statement after the one which triggered the exception.&lt;/li&gt;
&lt;li&gt;You are guaranteed that a function without a ! will never throw an exception when called.&lt;/li&gt;
&lt;li&gt;On the flip side, you are forced to implement an exception handler (even if it is bare minimal) if you want to use a function with the potential of an exception. &amp;nbsp;(This handler could be as simple as throwing the exception to your own caller.)&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
Is this better? &amp;nbsp;Our goal was to make it easier to know when exceptions are possible (instead of them being surprises), and to make it impossible to accidentally ignore exceptions which could be important.&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://opencomputing.blogspot.com/feeds/6728756447259581414/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3034230779454603134/6728756447259581414' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/6728756447259581414'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/6728756447259581414'/><link rel='alternate' type='text/html' href='http://opencomputing.blogspot.com/2014/03/new-exception-handling-model.html' title='New Exception Handling Model'/><author><name>Jeff Day</name><uri>http://www.blogger.com/profile/11675035864869123800</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3034230779454603134.post-8956779623253104487</id><published>2013-06-30T13:38:00.003-07:00</published><updated>2013-06-30T13:38:53.222-07:00</updated><title type='text'>My Experiences with iPhone 4.  Part 1.</title><content type='html'>I have been a long-time Android user. &amp;nbsp;But, for reasons too complex to elaborate right here, I&#39;ve just decided to take the plunge and give the iPhone 4 a try. &amp;nbsp;Yeah, it isn&#39;t the newest iPhone, but neither is my Android the newest (it&#39;s an LG Optimus Slider with the Ginger kernel installed.)&lt;br /&gt;
&lt;br /&gt;
So far, I love the iPhone, but as with most of my past loves, this relationship is complex.&lt;br /&gt;
&lt;br /&gt;
My initial conclusion is that the iPhone is not designed for humans. &amp;nbsp;This is funny considering &quot;I&quot; sound a lot more personal than a device whose mascot is a robot. &amp;nbsp;I&#39;ll attempt to break down specific areas of comparison here:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Behind-the-Scenes Multitasking and Process Management&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;iPhone: &amp;nbsp;&lt;/b&gt;There are many elegant and great things about the iPhone and iOS. &amp;nbsp;Foremost, I am impressed with the speed and stability of the device, and the (hopefully correct) assumption that it will remain just as fast and functional as long as I have it.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Android: &amp;nbsp;&lt;/b&gt;I haven&#39;t run the newest Android versions, but Android has long had problems due to the way it manages tasks in memory. &amp;nbsp;Background tasks getting stuck, eating up CPU, and taking my device to a crawl have plagued me. &amp;nbsp;I&#39;ve gone through iterations of different techniques, fixes, and monitors to try to take care of the issue, even multiple firmware versions, but the problem is fundamental. &amp;nbsp;I should never have to worry about this. &amp;nbsp;Effective multi-tasking has been a basic task in personal computing for over a decade now. &amp;nbsp;Android, you are unacceptable in this way. &amp;nbsp;Whatever goal you were trying to solve by auto-loading tasks in the background has been thwarted by the flaws.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The winner in this section is:&lt;/b&gt; &amp;nbsp;iPhone!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Music&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;iPhone:&lt;/b&gt; &amp;nbsp;I had very high hopes for the iPhone as a music device. &amp;nbsp;Apple products have been long known for their media-centric nature. &amp;nbsp;The phone even came with a set of earbuds as if to say &quot;I dare you not to use me as a music player, too.&quot; &amp;nbsp;Now that I had legitimately bought a piece of Apple tech, I figured I could be part of the club, play that game. &amp;nbsp;I eagerly prepared to copy my mp3&#39;s of my 90&#39;s music onto it so I could plug it into my car audio system and hit shuffle. &amp;nbsp;Lets try USB. &amp;nbsp;Plugged it in. &amp;nbsp;A filesystem came up! &amp;nbsp;Nice. &amp;nbsp;I don&#39;t see a Music folder. &amp;nbsp;That&#39;s weird. &amp;nbsp;So I made one. &amp;nbsp;Dropped the mp3 files in. &amp;nbsp;Unmounted, and investigated. &amp;nbsp;The phone sees no music. &amp;nbsp;I do a little Googling on the subject and find out that the only way to add music is through iTunes. &amp;nbsp;I don&#39;t run Windows. &amp;nbsp;I run Linux. &amp;nbsp;iTunes and Linux aren&#39;t the best of mates. &amp;nbsp;There are a few iTunes substitutes available, and some of them offer promising iPhone detection and look like they&#39;ll work, but apparently Apple broke compatibility in one of the iOS updates and it hasn&#39;t been able to be fixed since. &amp;nbsp;As a last ditch effort, I tried emailing a song to myself. &amp;nbsp;I can play it from the email, which is better than nothing, but there is no option to save the song or do anything with it except play it. &amp;nbsp;I am very pissed off about this. &amp;nbsp;I am a legit Apple product owner, why must I be treated like a criminal? &amp;nbsp;What arbitrary security does requiring a file to pass through iTunes on Windows or Mac actually provide? &amp;nbsp;If I had one of those platforms, I could still put my music in from mp3 files, so I just don&#39;t get it.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Android: &lt;/b&gt;&amp;nbsp;Drag and drop your music in. &amp;nbsp;It just works. &amp;nbsp;This is beyond obvious.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The winner in this section is: &amp;nbsp;&lt;/b&gt;Android&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Texting&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;iPhone:&lt;/b&gt; &amp;nbsp;I use my phone for texting more than anything else. &amp;nbsp;I knew this would be a problem area for me, going into it, but I decided particularly due to the CPU/performance issues that it would be a worthwhile change. &amp;nbsp; I have two major gripes so far. &amp;nbsp;1) &amp;nbsp;My contact&#39;s profile icons aren&#39;t used as part of the texting user interface. &amp;nbsp;I miss seeing the faces of my friends as a reminder of who I am talking with at a given moment. &amp;nbsp; 2) There is no reasonable way to input text. &amp;nbsp;I was told by some people, ridiculously, in my opinion, to use Siri to transcribe the text, but alas, I only have an iPhone not an iPhone 4. &amp;nbsp;I feel very crippled in my ability to communicate. &amp;nbsp;It is way faster than it would be if I were a slower typist, but it is a painful process to endure when I know how much simpler it could be.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Android:&lt;/b&gt; &amp;nbsp;By allowing third-party keyboards, Android has become home to Swype. &amp;nbsp;With Swype, I can text rapidly (i.e., 30wpm) with one thumb, while barely needing to look at the screen (i.e., while walking or carrying something or working on a project or playing a game.) &amp;nbsp; Without Swype, texting is a two handed ordeal (or a very slow one handed ordeal) that involves a lot of looking at the screen and a lot of correcting typos.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The winner in this section is:&lt;/b&gt; &amp;nbsp;Android&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Interface Navigation&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;iPhone: &lt;/b&gt;&amp;nbsp;I was prepared to be disappointed here. &amp;nbsp;Of the hard buttons, three of them are devoted to audio. (Vol+, Vol-, and a physical mute switch.) &amp;nbsp; The remaining two buttons are lock/power and home. &amp;nbsp;After some experimentation and being shown a few tricks by friends, the home button (the round one below the screen) is actually three buttons in one:&lt;br /&gt;
First usage: &amp;nbsp; A normal press equals &quot;home&quot;... sort of. &amp;nbsp;From any app, this sends you back to the launcher screen you were last on. &amp;nbsp;From any secondary launcher screen, pressing it again takes you to the home screen in the launcher. &amp;nbsp; From the home screen, pressing it again takes you to the search screen.&lt;br /&gt;
Second usage: &amp;nbsp;Double tapping takes you to the task manager. &amp;nbsp;After this, another double tap returns you to where you were.&lt;br /&gt;
Third usage:&amp;nbsp;&amp;nbsp;A long press invokes Voice Control (Predecessor to Siri?)&lt;br /&gt;
&lt;br /&gt;While inside Apps, navigation seems mostly acceptable. &amp;nbsp;The back arrow is usually in the upper left corner of a task. &amp;nbsp;I am glad that it is strictly hierarchical, and only present when needed. &amp;nbsp; Some apps break this and instead put a small &quot;Done&quot; button in the upper left which effectively does the same thing while not looking like an arrow. &amp;nbsp;But Facebook, in particular, breaks this by putting done in the upper-right. &amp;nbsp;Why right instead of left? &amp;nbsp;I don&#39;t know, but that&#39;s probably Facebook&#39;s fault more than Apple.&lt;br /&gt;
&lt;br /&gt;
Menus/settings are a much more difficult problem. &amp;nbsp;There just really doesn&#39;t seem to be a standard. &amp;nbsp;You have to look aroudn in each app for an icon with three horizontal lines, or a gear, or three dots, or nothing at all perhaps. &amp;nbsp;Going into the &quot;Settings&quot; app gives me Settings areas for a lot of the builtin apps, as well. &amp;nbsp;I&#39;m not sure if this will expand to include third party apps as I add more or not. &amp;nbsp;I hope so, otherwise it seems horribly inconsistent.&lt;br /&gt;
&lt;br /&gt;
(Side Note: &amp;nbsp;I just learned that Home+Power = Screenshot.)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Android: &lt;/b&gt;&amp;nbsp;Android navigation was a great idea... when it was still just an idea. &amp;nbsp;Four hard buttons: &amp;nbsp;Home, Menu, Back, and Search. &amp;nbsp;Search is practically never used, but is approximately equivalent to the long-press &quot;Voice Control&quot; on iPhone. &amp;nbsp;Home always goes home, as it should. &amp;nbsp;Menu brings up a menu for the current screen, allowing full screens apps to take up the entire screen real estate while still providing a mechanism to escape into the user interface when needed. &amp;nbsp;When in a Menu, back closes the menu. &amp;nbsp; Here&#39;s where it starts to fall apart. &amp;nbsp;Back isn&#39;t hierarchical. &amp;nbsp;It&#39;s... a mixture. &amp;nbsp;When you&#39;re in an app popped up from another app, back takes you back to the app that popped you there to begin with. &amp;nbsp;When you&#39;re at the top page in an app, back takes you out of the app to the home screen. &amp;nbsp;Back stores some sort of a stack of locations, and goes back to the previous one, but at the same time, Apps have some limited ability to manage this stack within their own context and override the behavior. &amp;nbsp; Because of this, Back often results in an App looking like it&#39;s frozen up, or taking you not back but forward because that was &quot;the last place you were&quot; and having to press it repeatedly to get to the real place you want to go. &amp;nbsp;Android&#39;s back button is a messy mess. &amp;nbsp; I know Android has taken steps to fix this in newer releases of the OS, but I haven&#39;t had a chance to review those in action yet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The winner in this section is:&lt;/b&gt;&amp;nbsp;&amp;nbsp; Neither.&lt;br /&gt;
&lt;br /&gt;
I am tempted to compare the iPhone to my Android as an actual device. &amp;nbsp;But, that&#39;s not fair, because iPhone is both device and operating system, while my particular Android phone is LG&#39;s product and and not Google&#39;s... &amp;nbsp; If I were comparing devices, however, the iPhone would win in a lot of areas.&lt;br /&gt;
&lt;br /&gt;
I will write more once I&#39;ve used the iPhone longer. &amp;nbsp;This write-up is after almost 24 hours, and I&#39;m sure I will discover some great new things in the next few days.&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://opencomputing.blogspot.com/feeds/8956779623253104487/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3034230779454603134/8956779623253104487' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/8956779623253104487'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/8956779623253104487'/><link rel='alternate' type='text/html' href='http://opencomputing.blogspot.com/2013/06/my-experiences-with-iphone-4-part-1.html' title='My Experiences with iPhone 4.  Part 1.'/><author><name>Jeff Day</name><uri>http://www.blogger.com/profile/11675035864869123800</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3034230779454603134.post-42612667141294261</id><published>2013-05-12T04:28:00.004-07:00</published><updated>2013-05-12T10:13:11.526-07:00</updated><title type='text'>Removing Unity Global Menus, Scroll Bars, Dock and returning to GNOME 2-esque Ambiance or Radiance</title><content type='html'>I&#39;m back from the dead, after a couple years of not posting, and I&#39;m here today to give you my current script to &quot;fix&quot; Ubuntu 12.10 Quantal Quetzal and 13.04 Raring Ringtail. &amp;nbsp;This script removes Unity&#39;s Global Menus, Overlay Scroll Bars, and Dock, and returns to a more GNOME 2-style look while still supporting the Ambiance or Radiance theme.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;font-size: large;&quot;&gt;Download&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
This is provided AS-IS, without any guarantees of any particular outcome. Please read &quot;what does it do&quot; so you know what you&#39;re getting into before you run this:&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://855nerdfix.com/userfiles/fixunity.sh&quot;&gt;http://855nerdfix.com/userfiles/fixunity.sh&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;font-size: large;&quot;&gt;What does it do?&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbGuHUNuC7EbfcHem7r9YRlksUk-TG8UNEn1jxqsign2XA82gRIyn0MEqYePrVSupeeg7o2DsorTEDuP5dDLQsU0VbHprm8iq1aZ1yfnPhA36S82FYs6vOmvPEgkqjRWVFpZhdmFEsCw/s1600/Screenshot+from+2013-05-12+04:21:06.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;512&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbGuHUNuC7EbfcHem7r9YRlksUk-TG8UNEn1jxqsign2XA82gRIyn0MEqYePrVSupeeg7o2DsorTEDuP5dDLQsU0VbHprm8iq1aZ1yfnPhA36S82FYs6vOmvPEgkqjRWVFpZhdmFEsCw/s640/Screenshot+from+2013-05-12+04:21:06.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Adds a new session type called &quot;Discord&quot;&lt;/li&gt;
&lt;li&gt;Replaces Unity&#39;s top panel with GNOME Panel 3. &amp;nbsp;This is not a reversion to GNOME 2&#39;s Panel, but the much better version 3 panel which goes mostly unused from what I see. You will notice one major difference from version 2 - you have to hold in Ctrl+Super in order to right click and edit the panel&#39;s composition or arrangement.&lt;/li&gt;
&lt;li&gt;Replaces Unity&#39;s left panel with Docky as a bottom panel.&lt;/li&gt;
&lt;li&gt;Removes Global Menus.&lt;/li&gt;
&lt;li&gt;Removes Overlay Scrollbars.&lt;/li&gt;
&lt;li&gt;Steals ALT+F1 and ALT+F2 back from Unity and gives them to the Applications menu and the Run Application dialog box.&lt;/li&gt;
&lt;li&gt;Installs Pidgin (because why not?)&lt;/li&gt;
&lt;li&gt;Configures some sane defaults for Compiz.&lt;/li&gt;
&lt;li&gt;Installs Applet Indicator Complete plugin on the top panel. This gives the Panel the ability to use Ubuntu&#39;s sexy Mac-like indicators and clock area and system menu.&lt;/li&gt;
&lt;li&gt;Please be aware that this script will turn off the Global Menu and Overlay Scrollbars even for your Unity session type.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;font-size: large;&quot;&gt;How to Use FixUnity&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Download the script from the link above.&lt;/li&gt;
&lt;li&gt;Set execute permissions on the script.&lt;/li&gt;
&lt;li&gt;Run it.&lt;/li&gt;
&lt;li&gt;After it completes, log out of your session, and before logging back in, choose &quot;Discord&quot; as your session type.&lt;/li&gt;
&lt;li&gt;Log in, and wait while the initial login reconfiguration happens.&lt;/li&gt;
&lt;li&gt;Enjoy Ubuntu the way it should have been.&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
Good luck!&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;Help Me!&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
If the script completes and you log into the new session type, and the outcome isn&#39;t very similar to the screenshot pictures above, let me know what happened and let&#39;s figure out how to fix it. &amp;nbsp;I am open to suggestions on how to improve this.&lt;br /&gt;
&lt;br /&gt;
&lt;b style=&quot;font-size: x-large;&quot;&gt;Recent Changes&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
0.82 - Renamed session type from &quot;Docky&quot; to &quot;Discord&quot; to more represent what I&#39;m trying to accomplish. (This tool is still useful even if you remove Docky from auto start-up and run Gnome Panel only!)&lt;br /&gt;
&lt;br /&gt;
0.81 - Fixed some Compiz settings that weren&#39;t applying properly due to the migration to dconf since I first wrote the script.&lt;br /&gt;
&lt;br /&gt;
0.8 - First public release for Ubuntu 12.10 or 13.04.</content><link rel='replies' type='application/atom+xml' href='http://opencomputing.blogspot.com/feeds/42612667141294261/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3034230779454603134/42612667141294261' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/42612667141294261'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/42612667141294261'/><link rel='alternate' type='text/html' href='http://opencomputing.blogspot.com/2013/05/removing-unity-global-menus-scroll-bars.html' title='Removing Unity Global Menus, Scroll Bars, Dock and returning to GNOME 2-esque Ambiance or Radiance'/><author><name>Jeff Day</name><uri>http://www.blogger.com/profile/11675035864869123800</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbGuHUNuC7EbfcHem7r9YRlksUk-TG8UNEn1jxqsign2XA82gRIyn0MEqYePrVSupeeg7o2DsorTEDuP5dDLQsU0VbHprm8iq1aZ1yfnPhA36S82FYs6vOmvPEgkqjRWVFpZhdmFEsCw/s72-c/Screenshot+from+2013-05-12+04:21:06.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3034230779454603134.post-5076077426021013608</id><published>2011-02-23T13:15:00.000-08:00</published><updated>2011-02-23T13:20:57.864-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="bing"/><category scheme="http://www.blogger.com/atom/ns#" term="Google"/><category scheme="http://www.blogger.com/atom/ns#" term="humor"/><category scheme="http://www.blogger.com/atom/ns#" term="search engine"/><title type='text'>Google vs Bing</title><content type='html'>As a computer instructor, I am often asked why I prefer Google over Yahoo or Microsoft&#39;s search engine (whatever they are calling it this year). &amp;nbsp;80% of the world uses Google, which can be a little scary to think about. &amp;nbsp;It would be so easy for them to abuse their power. &amp;nbsp;I will be the first to admit that they have gotten a little less cool in the last five years, and I wish they had an advanced version that had less hand-holding and would let me just get on with my searches, but even with all that, Google is miles above their competition in a few key areas. &amp;nbsp;(I&#39;m not going to really talk about Yahoo here, they have about the same market share as Microsoft, but they have too many ads and they don&#39;t try very hard to make their search better than any one else&#39;s)&lt;br /&gt;
&lt;br /&gt;
No matter how &quot;evil&quot; Google gets, rest assured that Microsoft has done worse. &amp;nbsp;I should give some of Microsoft&#39;s history on here sometime, that would be fun. &amp;nbsp;Let&#39;s just say that you don&#39;t get to the top of the Business software game by being nice.&lt;br /&gt;
&lt;br /&gt;
Google still has a sense of humor, although it&#39;s been getting dimmer over the years, and their April fools jokes are more about highlighting their newest product than having fun, and the Google Doodles are more about public relations than about celebration. &amp;nbsp;But, compared to any of the older corporations, Google is as playful as a puppy.&lt;br /&gt;
&lt;br /&gt;
Google is a friend to Linux and Mac. &amp;nbsp;Because of the other markets that Microsoft is in, they cannot afford to be nice to Linux or Mac, and the more &quot;features&quot; they have that are incompatible the more people who will be unhappy with a move away from windows. &amp;nbsp;Enter Silverlight, .Net, ActiveX and all of their other web products. &amp;nbsp;Try using IE9 on anything but the newest Windows. &amp;nbsp;And, I&#39;m using Google Chrome on my Ubuntu box to write this post.&lt;br /&gt;
&lt;br /&gt;
Lastly, Google&#39;s results are better. &amp;nbsp;I have a fun example for you all, and I know it&#39;s nothing but one example, but it shows what each company thinks of getting relevant search results to the user, and really, at the end of the day, that&#39;s what we are all looking for.&lt;br /&gt;
&lt;br /&gt;
I did a straight image search for the word rose, and then added the color filter of green, and here are the results:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQHFinXGWesIWzGFfCtwI3QcQGLj616Ucg1yj9kc5-sYIroV8gOz3DBmBzJG9A4XXoDK69E0LO-n52i5v5MWvsztXar3jdTF9Lmucr66XY5CxiDfRoMxSzD3I44s8fFqbtHKQY1yI3K50/s1600/bing.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;219&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQHFinXGWesIWzGFfCtwI3QcQGLj616Ucg1yj9kc5-sYIroV8gOz3DBmBzJG9A4XXoDK69E0LO-n52i5v5MWvsztXar3jdTF9Lmucr66XY5CxiDfRoMxSzD3I44s8fFqbtHKQY1yI3K50/s320/bing.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;Bing has ONE green rose out of fifteen results. &amp;nbsp;You get better results searching for green rose in the first place and ignoring the color filter.&lt;/div&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqP3yyOC231WCKRtw8YNdFsPmlVtdMGfod6jRHvxFg3FwrI5nfy0ZIePNg3XVy7cm8vjp7-Wke15CV7zlLxJCoUPGJfK4S9uCR435WyjynLLZ0YlREwfSwvtEhNlx1a7HzsNdKEN6XtFc/s1600/google.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;224&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqP3yyOC231WCKRtw8YNdFsPmlVtdMGfod6jRHvxFg3FwrI5nfy0ZIePNg3XVy7cm8vjp7-Wke15CV7zlLxJCoUPGJfK4S9uCR435WyjynLLZ0YlREwfSwvtEhNlx1a7HzsNdKEN6XtFc/s320/google.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;Google has twelve green roses, two pictures from the movie Green Rose, and ONE rose that is not green.&lt;/div&gt;&lt;br /&gt;
Like I said, this isn&#39;t a rigid test, just one example I stumbled on while working on a lesson plan.</content><link rel='replies' type='application/atom+xml' href='http://opencomputing.blogspot.com/feeds/5076077426021013608/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3034230779454603134/5076077426021013608' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/5076077426021013608'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/5076077426021013608'/><link rel='alternate' type='text/html' href='http://opencomputing.blogspot.com/2011/02/google-vs-bing.html' title='Google vs Bing'/><author><name>communitycomputercenter</name><uri>http://www.blogger.com/profile/12516899405069258544</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQHFinXGWesIWzGFfCtwI3QcQGLj616Ucg1yj9kc5-sYIroV8gOz3DBmBzJG9A4XXoDK69E0LO-n52i5v5MWvsztXar3jdTF9Lmucr66XY5CxiDfRoMxSzD3I44s8fFqbtHKQY1yI3K50/s72-c/bing.png" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3034230779454603134.post-1413292011643116050</id><published>2011-01-08T02:51:00.000-08:00</published><updated>2011-01-10T04:05:30.209-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Games"/><category scheme="http://www.blogger.com/atom/ns#" term="Kitten-Fu"/><category scheme="http://www.blogger.com/atom/ns#" term="software"/><category scheme="http://www.blogger.com/atom/ns#" term="tutorial"/><category scheme="http://www.blogger.com/atom/ns#" term="UVOG"/><title type='text'>2D Games with Kitten-Fu, Part Three</title><content type='html'>Alright, so &lt;a href=&quot;http://opencomputing.blogspot.com/2010/12/2d-games-with-kitten-fu-part-two.html&quot;&gt;last time&lt;/a&gt; I promised you a second cat and some grass for them to walk on.  When I originally got this far in my program I just copied and pasted and created a few if statements in order to take care of the second cat, but instead I&#39;m going to use objects because they are going to be more efficient in this case (where the cats aren&#39;t significantly different in how they behave.)&lt;br /&gt;Kitten-Fu is at version alpha 17 now, which is what i will be using for this tutorial.  The earlier and later versions should be 100% compatible with what we have done so far.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Sprites&lt;/h3&gt;&lt;br /&gt;We have two sprites to create before we work on the next bit of programing.  The first is a copy of our first cat with some coloring changes.  I also changed the head shape and the way the tail waves-this way they will both have a little different character without needing to re-do all that animation work from earlier.&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHqu4gAV7xtuGu75qWqn5s_zelYYfGSxR3T2SRMtJ1aW7PVRopMtMgs-GacP24LZpcEh9TZEMCFAnZ8zcjmcKvuUt0kzABIGXaNnbq1ZZbakCzzglr36i861Ib55rZ7mmjxSrnHO_6YzA/s1600/spottedtail-big.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 80px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHqu4gAV7xtuGu75qWqn5s_zelYYfGSxR3T2SRMtJ1aW7PVRopMtMgs-GacP24LZpcEh9TZEMCFAnZ8zcjmcKvuUt0kzABIGXaNnbq1ZZbakCzzglr36i861Ib55rZ7mmjxSrnHO_6YzA/s320/spottedtail-big.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5559772340166559074&quot; /&gt;&lt;/a&gt;&lt;br /&gt;Next, I&#39;ll make a ground sprite.  I&#39;m not really happy with the way this turned out.  I&#39;m thinking of making a new sprite that is just grass and will be placed higher on the screen along with a second sprite of just dirt at the bottom to give it that street fighter pseudo 3D feel.  Remember, I am sticking to 4 colors per 16x16 block to help keep the 8bit retro style.  Also remember that transparent counts as a color.&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpjoQIfmMaUe1QGyOlAX-DOvFcJEtr_XBgQcY2mCgqnMDKR6et3W9lx1petf7SAxG1_7HfdXX1FmPJJYe6Z7XqPYsT52qio-qjCcjoISChhRrpe1YFzUmu-CaHV_rt1xM-ReMmVXOOAyI/s1600/ground-big.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 80px; height: 80px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpjoQIfmMaUe1QGyOlAX-DOvFcJEtr_XBgQcY2mCgqnMDKR6et3W9lx1petf7SAxG1_7HfdXX1FmPJJYe6Z7XqPYsT52qio-qjCcjoISChhRrpe1YFzUmu-CaHV_rt1xM-ReMmVXOOAyI/s320/ground-big.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5559772810614835698&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3&gt;The Code&lt;/h3&gt;&lt;br /&gt;Let&#39;s start with adding the ground tile, since that&#39;s pretty simple.  First create the ground stamp:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0 -210px;&quot;&gt;stamp ground(&quot;ground.png&quot;);&lt;/pre&gt;No need to worry about slicing it at this point.  When we have more variety then we can convert it, but for now a stamp will work just fine.&lt;br /&gt;&lt;br /&gt;Next, let&#39;s add a for loop that utilizes the stamp we just created and place it at the beginning of our painting section (after we clear the screen, of course)&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0 77px;&quot;&gt;  for (int i = 0; i &lt; 8; i++) {&lt;br /&gt;    ground.put(i*16, 104);&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;If you compile your program now, it should display the ground tiles across the bottom of the screen.&lt;br /&gt;&lt;br /&gt;So far we have just been using structured programing, meaning the code just goes through in order what we told it to do without employing any fancy code.  We&#39;re going to get a whole lot fancier in just a bit.  The next thing we are going to do is add a second cat.  We COULD just copy our code and rename all of our variables with a 1 and 2 after them, but what if we need to add a third or fourth cat? (for example if we were making a kitteny RPG)  That would get old really fast as we duplicated all of our code four times.  So, to solve that we are going to employ classes.&lt;br /&gt;&lt;br /&gt;I&#39;m going to move all of the code having to do with the cat logic and painting into a kitten class.  Since I am still fairly new to object oriented programing, I don&#39;t really feel like I can explain what I&#39;m doing in very high detail, so I&#39;m just going to show you what I ended up with.&lt;br /&gt;&lt;br /&gt;If you don&#39;t know what a class is, you can think of it as a cookie cutter that you create with its own variables and functions (these have different names when they are a part of a class ... whatever)  Once we have the class/cookie cutter set up, we can use it to create instances of our class (the actual cookies).  This way, we can tell the program what a cat should look like and then make as many as we need with minimal needless duplication of code.&lt;br /&gt;&lt;br /&gt;If you know HTML at all, this has the same function as CSS does, it&#39;s f*ing amazing and lets you do all sorts of cool things to control all your similar processes all at once.&lt;br /&gt;&lt;br /&gt;Without further ado, let&#39;s look at the kitten class code (this goes right after we include KFu on line 5.)  Actually, I take that back, I&#39;m going to be converting the code into object orientedness in two passes.  This first will be the game logic, the second will be the painting portion which I will cover in more depth than the game logic.  okay, for real this time:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0 -60px&quot;&gt;int framecount = 0;&lt;br /&gt;&lt;br /&gt;class kitten {&lt;br /&gt;  public:&lt;br /&gt;  int kx;&lt;br /&gt;  int ky;&lt;br /&gt;  int walkleft;&lt;br /&gt;  int walkright;&lt;br /&gt;  int facing;&lt;br /&gt;  kitten();&lt;br /&gt;  void step();&lt;br /&gt;  private:&lt;br /&gt;};&lt;/pre&gt;&lt;br /&gt;I made framecount into a global variable for now and changed the k1x and k1y variables into just kx and ky (make sure they get changed in all the places you were using them!)&lt;br /&gt;&lt;br /&gt;Next, let&#39;s make the constructor:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0 -270px&quot;&gt;kitten::kitten() {&lt;br /&gt;  kx = 110;&lt;br /&gt;  ky = 88;&lt;br /&gt;  walkleft = 0;&lt;br /&gt;  walkright = 0;&lt;br /&gt;  facing = 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You&#39;ll notice that the above code was basically used to declare and initialize the variables that we&#39;re using in this class.  Go ahead and delete the duplicate variables at the top of main().&lt;br /&gt;&lt;br /&gt;At this point we need to create an instance of our kitten class in main().  I&#39;m going to call it kitten1, but you can name it anything you like.  Since we are going to add the paint routine to the class, we will need to call it after we create the screen, so go ahead and add this:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0 71px&quot;&gt;  kitten kitten1;&lt;/pre&gt;&lt;br /&gt;And now let&#39;s make a method (it&#39;s basically a function) which will take our actual game logic code that we reference the kitten in and make it available to use with the class:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0 -390px&quot;&gt;void kitten::step() {&lt;br /&gt;  if (framecount%2 == 0) {&lt;br /&gt;    if (walkleft == 1) {&lt;br /&gt;      kx = (kx - 1);&lt;br /&gt;      if (kx &lt; -16) { kx = 128; }&lt;br /&gt;    }&lt;br /&gt;    if (walkright == 1) {&lt;br /&gt;      kx = (kx + 1);&lt;br /&gt;      if (kx &gt; 128) { kx = -16; }&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Again, you&#39;ll want to delete the code that we have now duplicated and replace it with the following:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0 105px&quot;&gt;  kitten1.step();&lt;/pre&gt;&lt;br /&gt;Before we&#39;re done, take a look at the SDL input handling.  We use walkleft, walkright and facing there ... we&#39;ll need to point these to our kitten1 instance of the kitten class by adding kitten1. in front of each variable.&lt;br /&gt;&lt;br /&gt;Okay!  Go ahead and compile your code and make sure it still runs at this point before you continue.  If you get an error, read it and take a good look at the line number it gives (if it gives one).  Make double sure that you didn&#39;t leave anything important out like a semi-colon or a brace.  If you still can&#39;t get it to compile, take a look at the sample code at the end of this post - we are doing some major revisions to the structure of the code and that can be a little confusing at times.&lt;br /&gt;&lt;br /&gt;Once you have your code compiling and running again, let&#39;s break it again!  we&#39;re going to turn the painting routine into another method in our class.&lt;br /&gt;&lt;br /&gt;Before we start, we need to change the way we declare our slices and stamps again so that we can separate them into variable declarations and variable values just like we did with the other variables.&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0 942px;&quot;&gt;  stamp* sprites;&lt;br /&gt;  sprites = new stamp(&quot;kitten1.png&quot;, KFU_LOAD_FLIPH | KFU_LOAD_NORMAL);&lt;br /&gt;  slice* stand;&lt;br /&gt;  stand   = new slice(*sprites, 0, 0, 16, 16);&lt;br /&gt;  slice* walk[4];&lt;br /&gt;  walk[0] = new slice(*sprites, 16, 0, 16, 16);&lt;br /&gt;  walk[1] = new slice(*sprites, 32, 0, 16, 16);&lt;br /&gt;  walk[2] = new slice(*sprites, 48, 0, 16, 16);&lt;br /&gt;  walk[3] = new slice(*sprites, 32, 0, 16, 16);&lt;br /&gt;&lt;/pre&gt;I also got rid of the kitt1 from the name of the variables since that won&#39;t make a lot of sense when it is part of a generic class.&lt;br /&gt;&lt;br /&gt;So, what are those asterisks that we added to our code for?  &lt;!-- Usually when we create a variable the compiler knows how much space to allot it determined by its type, so an int will get 4 bytes of memory to store its value.  Well, when we create our own types, such as step or when we use a type that has been created for us such as slice, stamp etc from KFu, then how does the compiler know how much space to allow?  The asterisk is used to denote that the variable in question is not going to be created yet, so just save a spot in memory large enough to keep a pointer to the REAL data that will have space allocated for it when it is created.  --&gt; They are memory pointers that we are using to separate the variables.  Jeff is possibly changing kfu to make this easier, so I&#39;m not going to try and explain it :-) If you want to know more, read a good introduction to pointers in c++.&lt;br /&gt;&lt;br /&gt;Next, we should add the following to the private section of our class:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0 942px;&quot;&gt;  stamp* sprites;&lt;br /&gt;  slice* stand;&lt;br /&gt;  slice* walk[4];&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And the following to our constructor:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0 942px;&quot;&gt;  sprites = new stamp(&quot;kitten1.png&quot;, KFU_LOAD_FLIPH | KFU_LOAD_NORMAL);&lt;br /&gt;  stand   = new slice(*sprites, 0, 0, 16, 16);&lt;br /&gt;  walk[0] = new slice(*sprites, 16, 0, 16, 16);&lt;br /&gt;  walk[1] = new slice(*sprites, 32, 0, 16, 16);&lt;br /&gt;  walk[2] = new slice(*sprites, 48, 0, 16, 16);&lt;br /&gt;  walk[3] = new slice(*sprites, 32, 0, 16, 16);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now, we need to make a method that replaces the painting code:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0 942px;&quot;&gt;void kitten::paint() {&lt;br /&gt;  if (walkleft == 1) {&lt;br /&gt;    walk[anim4]-&gt;put(kx, ky);&lt;br /&gt;  } else if (walkright == 1) {&lt;br /&gt;    walk[anim4]-&gt;put(kx, ky, KFU_PUT_FLIPH);&lt;br /&gt;  } else {&lt;br /&gt;    if (facing == 0) {&lt;br /&gt;      stand-&gt;put(kx, ky);&lt;br /&gt;    } else {&lt;br /&gt;      stand-&gt;put(kx, ky, KFU_PUT_FLIPH);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Since we use the variable anim4 in our class method, let&#39;s make it a global variable next to framerate for now.  And then of course delete the original painting code and point to the class method with the following:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0 942px;&quot;&gt;  kitten1.paint();&lt;/pre&gt;&lt;br /&gt;Pretty cool, huh?  Make sure your code still runs and debug as necessary.&lt;br /&gt;&lt;br /&gt;wooo .. let&#39;s take a deep breath and take a look over all the code.  Clean up any extra spaces and comment as necessary.  Make sure you understand and recognize all of the various parts of the program still.&lt;br /&gt;&lt;br /&gt;Now for the fun part, let&#39;s add that second kitten!</content><link rel='replies' type='application/atom+xml' href='http://opencomputing.blogspot.com/feeds/1413292011643116050/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3034230779454603134/1413292011643116050' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/1413292011643116050'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/1413292011643116050'/><link rel='alternate' type='text/html' href='http://opencomputing.blogspot.com/2011/01/2d-games-with-kitten-fu-part-three.html' title='2D Games with Kitten-Fu, Part Three'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHqu4gAV7xtuGu75qWqn5s_zelYYfGSxR3T2SRMtJ1aW7PVRopMtMgs-GacP24LZpcEh9TZEMCFAnZ8zcjmcKvuUt0kzABIGXaNnbq1ZZbakCzzglr36i861Ib55rZ7mmjxSrnHO_6YzA/s72-c/spottedtail-big.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3034230779454603134.post-3059511337442112180</id><published>2010-12-07T23:15:00.000-08:00</published><updated>2010-12-09T17:59:15.839-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Games"/><category scheme="http://www.blogger.com/atom/ns#" term="Kitten-Fu"/><category scheme="http://www.blogger.com/atom/ns#" term="software"/><category scheme="http://www.blogger.com/atom/ns#" term="tutorial"/><category scheme="http://www.blogger.com/atom/ns#" term="UVOG"/><title type='text'>2D Games with Kitten-Fu, Part Two</title><content type='html'>When we left off in &lt;a href=&quot;http://opencomputing.blogspot.com/2010/12/2d-games-with-kitten-fu-part-one.html&quot;&gt;part one&lt;/a&gt;, you should have had a kitten that skated across the screen forward and backward.  This would be awesome for a hover ship, but let&#39;s animate our little cat so that its legs move while it is walking.  (oh, I&#39;m also using the KFu alpha 13 library now)&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Sprites&lt;/h3&gt;&lt;br /&gt;We&#39;re going to use a sprite sheet for our cat, so that means adding all of our cat&#39;s various poses to a single .png file.  I&#39;m going to limit myself to 16x16 for each of the kitten&#39;s poses, that way I don&#39;t have to keep track of what size I made what, and it helps with the retro look too.  Kitten-Fu allows you to specify any size you choose, just make sure you keep good track of your sprites if you make them irregular.&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuUMMLMfWQExdR3YzyoAn7N0p0LRyh9cANV8NbK8xWKWPENokxn2MEWb12QlQrzhRo_z6BcHQlfdkU4UoDaS-zTSKMeoIVrbKyQFNK90zzufs2vWQw8OjGeOIUM6Pq1Kco70c5boSW1Es/s1600/kitty1v.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 319px; height: 80px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuUMMLMfWQExdR3YzyoAn7N0p0LRyh9cANV8NbK8xWKWPENokxn2MEWb12QlQrzhRo_z6BcHQlfdkU4UoDaS-zTSKMeoIVrbKyQFNK90zzufs2vWQw8OjGeOIUM6Pq1Kco70c5boSW1Es/s320/kitty1v.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5548236550308006194&quot; /&gt;&lt;/a&gt;&lt;br /&gt;You can see four poses of my cat here.  The first is the original position from part one, the second is with the right legs extended, the third is with all four legs in the middle.  I was purposely vague on which leg was in front for this middle pose so that I didn&#39;t need to draw a second center pose.  The last position is with the left legs extended.  It took me quite a while to get the animation correct.  If you are drawing your own sprites, I would recommend that you get the basic shape you want, then code the animation sequence, and then fine tune it when you can see the changes in action.  I used a couple of YouTube videos to help me get the leg shapes correct.&lt;br /&gt;&lt;br /&gt;My first attempt at animating my cat was in the middle of the night while I was almost asleep.  I&#39;m including it here as an example of what &lt;b&gt;not&lt;/b&gt; to do!&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiw-bTvdlXDjXEL3iDLp_T5iZEITMMhFimMD4njhitu1Vf8qxdWVLKKyLYpuqZX0S1niVYOePwSzMhEccqkX9zLRkFhIEX-fmwlTuoGvuzmER3osDx3WlVmsKEq1J6UfRwroCy8vOl-tjQ/s1600/kitty0animated.gif&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 80px; height: 80px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiw-bTvdlXDjXEL3iDLp_T5iZEITMMhFimMD4njhitu1Vf8qxdWVLKKyLYpuqZX0S1niVYOePwSzMhEccqkX9zLRkFhIEX-fmwlTuoGvuzmER3osDx3WlVmsKEq1J6UfRwroCy8vOl-tjQ/s320/kitty0animated.gif&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5548236844203889090&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3&gt;The Code&lt;/h3&gt;&lt;br /&gt;So far we&#39;ve only been working with a KFu stamp, and we really haven&#39;t tapped its full potential at all.  One of the cooler things a stamp is good for is making &quot;slices&quot;.  A slice is a piece of a stamp that is cut out and used as a sprite the same way we used the stamp in part one.  What makes a slice special is that it doesn&#39;t take up more space in memory to use it.  We can load one sprite sheet, and then cut multiple slices from it, creating a veritable cornucopia of sprites on the actual screen!&lt;br /&gt;&lt;br /&gt;After we add the new kitten poses, we can leave our stamp code the same, but we&#39;re going to add our slice code underneath:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0 -195px&quot;&gt;  slice kitt1stand(kitt1, 0, 0, 16, 16);&lt;/pre&gt;&lt;br /&gt;We&#39;ll also want to change where we put the kitt1 stamp to refer to the slice instead:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0 -780px&quot;&gt;  kitt1stand.put(k1x, k1y);&lt;/pre&gt;&lt;br /&gt;Now we&#39;re going to use an array of slices for our animated kitten.  An array is a way to give a list of items numbers rather than names--this can be quite handy as we will see in a moment.  In this case, we&#39;re going to pre-load all four frames of our animation, and save them as slices.&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0 -240px&quot;&gt;  slice* kitt1walk[4];&lt;br /&gt;  kitt1walk[0] = new slice(kitt1, 16, 0, 16, 16);&lt;br /&gt;  kitt1walk[1] = new slice(kitt1, 32, 0, 16, 16);&lt;br /&gt;  kitt1walk[2] = new slice(kitt1, 48, 0, 16, 16);&lt;br /&gt;  kitt1walk[3] = new slice(kitt1, 32, 0, 16, 16);&lt;/pre&gt;&lt;br /&gt;You can see that for each slice above (for the animation and the first pose in kitt1stand) there are a couple different parts:&lt;br /&gt;&lt;br /&gt;kitt1stand or kitt1walk[x] are both slice names that we use later to call them into use, and after that are our options in the parentheses.  kitt1 refers to the stamp that we set up earlier on line 12 of part one.  The series of numbers refer to the x-position and y-position (the top left corner of the slice), and the height and width of the slice.  Of course the slices could overlap if we wanted them to, but for now that would make our cat look like a mutant.&lt;br /&gt;&lt;br /&gt;We can&#39;t just replace kitt1stand with kitt1walk, otherwise our kitten would be animated even while it was standing still, so we need a way to tell if the cat is moving, and only show the animated slice array while that is true.&lt;br /&gt;&lt;br /&gt;We already have a walkleft and a walkright variable that is set to true while the cat is moving, so we can just multi-purpose them!  The way we&#39;re going to solve our animation problem for now is to set a counter that will rotate through the numbers 0-3 every x frames.  We&#39;ll feed this number into the kitt1walk array and this will flip between all of the slices of the array in order.  Add the following code right before you clear the display and begin painting. (and, don&#39;t forget to add any relevant variable declarations at the top of the program!)&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0 -825px&quot;&gt;  // ANIMATION //&lt;br /&gt;  if (framecount%8 == 0) {&lt;br /&gt;    ++anim4;&lt;br /&gt;    if (anim4 &gt;= 4) {&lt;br /&gt;      anim4 = 0;&lt;br /&gt;    }&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;Then, to make the counter tick, add the following to increment the frame counter every time through the game loop (I added it directly underneath the GAME LOGIC heading.)&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0 -705px&quot;&gt;  ++framecount;&lt;/pre&gt;&lt;br /&gt;We can re-use this counter for anything that we want to also run with four frames, as long as we don&#39;t mind that it is running in tandem with our cat.&lt;br /&gt;&lt;br /&gt;Now that we&#39;ve set up our animation, let&#39;s get it painted to the screen.  Add a ///&amp;nbsp;PAINTING&amp;nbsp;/// heading underneath the animation code, and let&#39;s add some if statements around where we put kitt1stand.  Basically, if walkleft or walkright equal 1, then we display kitt1walk, otherwise we display kitt1stand.  I could write out the code for this a little more compactly than I have it below, but since we are about to add flipping, this sets up our statement nicely for that:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0 -1050px&quot;&gt;  if (walkleft == 1) {&lt;br /&gt;    kitt1walk[anim4]-&gt;put(k1x, k1y);&lt;br /&gt;  } else if (walkright == 1) {&lt;br /&gt;    kitt1walk[anim4]-&gt;put(k1x, k1y);&lt;br /&gt;  } else {&lt;br /&gt;    kitt1stand.put(k1x, k1y);&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;If you make your program at this point, you&#39;ll notice that the cat, although animated, moves way too fast (even for a ninja cat.)  We need a way to slow that kitten down.  How about a throttle on the game process?  every x frames, we will register a movement.  If we were working with smaller pixels, this would be less of a problem, but when your cat moves at 30 pixels per second, and your screen is only 128 pixels across ...&lt;br /&gt;&lt;br /&gt;In the GAME LOGIC section, underneath the frame counter, let&#39;s stick our movement controls into a throttle of sorts:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0 -735px&quot;&gt;  if (framecount%2 == 0) {&lt;/pre&gt;&lt;br /&gt;Now when you make the file, the cat walks slower but, especially if you&#39;re on an older / slower computer, you&#39;ll notice that the cat fluctuates in speed depending on your CPU usage.  That&#39;s because I forgot that we need to use KFu&#39;s FPS thingy.  To set it up, we need to add the following lines to the top of our actual game code, right after we finish declaring our variables and slices.&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0 -330px&quot;&gt;  fps framerate(1000/30);&lt;br /&gt;  framerate.start();&lt;/pre&gt;&lt;br /&gt;Then, at the bottom, right before we flip to the screen, add the following:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0 -1245px&quot;&gt;  framerate.delay();&lt;/pre&gt;&lt;br /&gt;we could have named framerate anything, and set the speed to anything we wanted.  I can imagine that you could change this number for underwater scenes, or something like that.&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXUxC_RyqBOZmb1KK7ZcdGY5FtjwwtVLC6TjMKeodR2wuwdcHxs1AH958ckWa0uDKNIqu6cz7Tpg1VeyduzDW6F6F_KXOUxXwcrvffVNMgsJaAap3AygFiT01UpoLD3JKf9aBZg3tXz-Q/s1600/kitty1animated.gif&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 80px; height: 80px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXUxC_RyqBOZmb1KK7ZcdGY5FtjwwtVLC6TjMKeodR2wuwdcHxs1AH958ckWa0uDKNIqu6cz7Tpg1VeyduzDW6F6F_KXOUxXwcrvffVNMgsJaAap3AygFiT01UpoLD3JKf9aBZg3tXz-Q/s320/kitty1animated.gif&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5548257949936403586&quot; /&gt;&lt;/a&gt;&lt;br /&gt;Everything should work now except for the fact that your cat can only face one direction!  Let&#39;s fix that (although, the moonwalking kitten is pretty cool.)&lt;br /&gt;&lt;br /&gt;KFu already has options set up to allow for flipping, all we need to do is activate them.  First, we need to create a flipped &quot;instance&quot; of our stamp.  This creates a complete copy of the stamp in the memory, so don&#39;t flip or rotate more than you&#39;ll actually need for your program.&lt;br /&gt;&lt;br /&gt;Your new stamp declaration should look like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0 -210px&quot;&gt;  stamp kitt1(&quot;kitten1.png&quot;, KFU_LOAD_FLIPH | KFU_LOAD_NORMAL);&lt;/pre&gt;&lt;br /&gt;FLIPH is for flip horizontal, and then NORMAL is so you can load the regular file.  If you don&#39;t declare any positional variations, KFu assumes you only wanted NORMAL, but as soon as you start declaring variations, you have to tell it exactly what you want.&lt;br /&gt;&lt;br /&gt;Do you remember where we made our if statement a bit long winded for our cat animation?  Change your slice code to the following for when the cat is walking right:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0 -1170px&quot;&gt;    kitt1walk[anim4]-&gt;put(k1x, k1y, KFU_PUT_FLIPH);&lt;/pre&gt;&lt;br /&gt;Now, the only remaining &#39;error&#39; is when your cat stops walking, it always faces left ...  Using a variable on the key presses, see if you can flip kitt1stand to face the correct direction after he finishes walking.  I have a solution in the code included at the bottom of the post--see if you can figure it out without looking.&lt;br /&gt;&lt;br /&gt;So, I lied about showing you how to add another cat, that will have to wait until part three.  We&#39;ll create a kitten object, and work on the logic that will make kitten-2 follow kitten-1, as well as some grass for them to walk on.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Files&lt;/h3&gt;&lt;br /&gt;You can download everything from part 2 here: &lt;a href=&quot;http://communitycomputercenter.com/userfiles/kittens-02.tar.gz&quot;&gt;kittens-02.tar.gz&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;* * *</content><link rel='replies' type='application/atom+xml' href='http://opencomputing.blogspot.com/feeds/3059511337442112180/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3034230779454603134/3059511337442112180' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/3059511337442112180'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/3059511337442112180'/><link rel='alternate' type='text/html' href='http://opencomputing.blogspot.com/2010/12/2d-games-with-kitten-fu-part-two.html' title='2D Games with Kitten-Fu, Part Two'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuUMMLMfWQExdR3YzyoAn7N0p0LRyh9cANV8NbK8xWKWPENokxn2MEWb12QlQrzhRo_z6BcHQlfdkU4UoDaS-zTSKMeoIVrbKyQFNK90zzufs2vWQw8OjGeOIUM6Pq1Kco70c5boSW1Es/s72-c/kitty1v.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3034230779454603134.post-3421080180180551753</id><published>2010-12-03T15:28:00.000-08:00</published><updated>2010-12-16T18:16:22.391-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Games"/><category scheme="http://www.blogger.com/atom/ns#" term="Kitten-Fu"/><category scheme="http://www.blogger.com/atom/ns#" term="software"/><category scheme="http://www.blogger.com/atom/ns#" term="tutorial"/><category scheme="http://www.blogger.com/atom/ns#" term="UVOG"/><title type='text'>2D Games with Kitten-Fu, Part One</title><content type='html'>As part of the UVOG arcade project, Jeff has been working on a 2d graphics library for C++ called Kitten-Fu.  It&#39;s cute and fuzzy like a kitten but powerful like a ninja ...&lt;br /&gt;&lt;br /&gt;I&#39;m going to be using Kitten-Fu (KFu) and other open software to create a retro, side-scrolling game about ... what else, ninja cats.&lt;br /&gt;&lt;br /&gt;As a way of introduction, I am a novice programmer who has dabbled in PHP and AVR Assembler.  I&#39;m going to be blogging my very first C++ program during this series.&lt;br /&gt;&lt;br /&gt;First, we need to install the KFu library.  KFu has a couple of dependencies, so make sure you install them first:&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;term&quot;&gt;&lt;em&gt;$&lt;/em&gt; sudo apt-get install build-essential libsdl1.2debian libsdl1.2-dev libsdl-image1.2 libsdl-image1.2-dev&lt;/div&gt;&lt;br /&gt;Once you have that, go to the &lt;a href=&quot;http://uvog.org/uvogwiki/index.php/Kitten-Fu&quot;&gt;Kitten-Fu wiki page&lt;/a&gt; and download the latest version of the library.  I&#39;m going to be using KFu alpha 10 to start with.  After you have the file downloaded, extract it and in a terminal, navigate to the extracted files and type:&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;term&quot;&gt;&lt;em&gt;$&lt;/em&gt; sudo make install&lt;/div&gt;&lt;br /&gt;Now we have access to the KFu C++ libraries and can use them in our program.&lt;br /&gt;&lt;br /&gt;Now, let&#39;s create a folder for our program to live in, for example: /home/yourName/Programing/kittens&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Sprites&lt;/h3&gt;&lt;br /&gt;I already know that I want my program to involve cats, and since I&#39;m better at drawing than coding at this point, I&#39;m going to start by drawing a sprite and then worry about getting it to the screen.  For sprite creation, I use a program called &lt;a href=&quot;http://mtpaint.sourceforge.net/&quot;&gt;MTPaint&lt;/a&gt; which is a great pixel editor.  You can use any graphics program you like.&lt;br /&gt;&lt;br /&gt;I drew my first cat at 16 by 16 pixels and in 4 colors, one of which (black) will end up transparent.  I saved my sprite as an 8bit .png, which is an indexed file format - perfect for making a retro game.  You could also use a 24bit .png which has alpha transparency (various shades of transparent) which lets you have pretty, smooth and curvy edges all at once!  Make sure to let the file know that you want the first color to be transparent.  In MTPaint this is through the save dialog.  Here&#39;s a screenshot of my final kitty:&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoE1dphxmoa1jzWbZfjN_DE2otwBQO4Uv5GUsgCsQEOnI0YPYjjyxL9FSl4MyUF00w-y6wx3bUwdGTd2krTK8SMHj3egPnCKE2nmfw4QNEqjX2-lfPeXQIjGsZvjG7xAMIeKs3bq-tje0/s1600/kitten1-disp.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoE1dphxmoa1jzWbZfjN_DE2otwBQO4Uv5GUsgCsQEOnI0YPYjjyxL9FSl4MyUF00w-y6wx3bUwdGTd2krTK8SMHj3egPnCKE2nmfw4QNEqjX2-lfPeXQIjGsZvjG7xAMIeKs3bq-tje0/s1600/kitten1-disp.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Code&lt;/h3&gt;&lt;br /&gt;Okay now let&#39;s create our program files.  I like to work with Nano, a command line text editor.  You should use whichever program you are comfortable with as long as it&#39;s a text editor and not a word processor.  (ie, not Open Office Writer or AbiWord, but using Kate or Gedit is fine)&lt;br /&gt;&lt;br /&gt;In my kittens folder, I create a new file titled kittens.cc with the following contents:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot;&gt;// kittens&lt;br /&gt;#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;#include &quot;KFu/KFu.h&quot;&lt;br /&gt;using namespace kfu;&lt;br /&gt;&lt;/unistd.&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This tells me the name of my new program, and that I want to use the KFu library.  Save the file and then create another empty file named Makefile.  A makefile is a type of script file so that you don&#39;t have to type out the compile instructions every time:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot;&gt;all: kittens_norun&lt;br /&gt;&lt;br /&gt;kittens_norun: kittens.cc&lt;br /&gt;&lt;tab&gt;&amp;nbsp;&lt;/tab&gt;g++ -o kittens kittens.cc -lKFu -Wall --pedantic&lt;br /&gt;&lt;br /&gt;kittens: kittens_norun&lt;br /&gt;&lt;tab&gt;&amp;nbsp;&lt;/tab&gt;./kittens&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;IMPORTANT: The spaces on lines 4 and 7 are really tabs, make sure you replace them in your code.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Okay, save that, and now let&#39;s get that sprite to the screen!  Open kittens.cc and add this to your file:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0px -75px&quot;&gt;int main(int argc, char* argv[]) {&lt;br /&gt;  screen display(128, 120, 640, 480);&lt;br /&gt;  stamp kitt1(&quot;kitten1.png&quot;);&lt;br /&gt;&lt;br /&gt;  kitt1.put(100, 100);&lt;br /&gt;  display.flip();&lt;br /&gt;&lt;br /&gt;  sleep(5);&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Before we talk about what everything does, let&#39;s make sure it works:&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;term&quot;&gt;&lt;em&gt;$&lt;/em&gt; &lt;kbd&gt;make kittens&lt;/kbd&gt;&lt;/div&gt;&lt;br /&gt;A smallish black screen should pop up and have a little cat standing in the middle of it, and then it should close after 5 seconds.  If this didn&#39;t happen, look back over all your code, and double check that everything is correct.  I do have the project files included at the bottom of this post if you need them.&lt;br /&gt;&lt;br /&gt;So, let&#39;s take a look at the code we just added.  &lt;tt&gt;int main(...) { ... }&lt;/tt&gt; is the wrapper for our actual program.  Pretty much everything we do will be included inside of it.&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;screen display(128, 120, 640, 480);&lt;/tt&gt;  This sets up the parameters of our game screen.  The first two numbers are the width and height of the game window.  The next two numbers are the width and height of the screen.  The game space will expand and center in the available screen space.  This lets you change the size of the pixels on the screen.  With the setup that we&#39;re using, we&#39;ll have a fairly small screen, and the pixels will be magnified x4.&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;stamp kitt1(&quot;kitten1.png&quot;);&lt;/tt&gt;  This line sets up our stamp, giving it a name (kitt1) and telling it which file to use.&lt;br /&gt;&lt;br /&gt;That&#39;s it for the setup, now we get to actually place the kitten on the screen.&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;kitt1.put(100, 100);&lt;/tt&gt;  Here, we name our stamp, tell it to &quot;put&quot; it to the screen, and tell it the x and y coordinates.&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;display.flip()&lt;/tt&gt; is what actually paints the sprites to the screen.  Very important, don&#39;t leave this out!&lt;br /&gt;&lt;br /&gt;The last thing we do is tell it to do nothing for 5 seconds (&lt;tt&gt;sleep(5);&lt;/tt&gt;) and then it gets the the final } and closes our program.&lt;br /&gt;&lt;br /&gt;There are two things we need to add to our &quot;game&quot; to make it a bit more functional: movement, and a way to close it when we want rather than only letting it last for 5 seconds.  Both of these are going to involve key presses, so let&#39;s add those in!&lt;br /&gt;&lt;br /&gt;In between the screen set up and where we actually paint the cat, let&#39;s add a section:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0px -135px&quot;&gt;/// HANDLE EVENTS ///&lt;br /&gt;  while (SDL_PollEvent(&amp;event)) {&lt;br /&gt;    switch (event.type) {&lt;br /&gt;      case SDL_KEYDOWN:&lt;br /&gt;        switch (event.key.keysym.sym) {&lt;br /&gt;          case SDLK_ESCAPE: done = 1; break;&lt;br /&gt;          default: break;&lt;br /&gt;        }&lt;br /&gt;      break;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This basically says, look at all the keys that are down, if you see the escape key get pressed, then done equals 1 and then skip to the end of this section.&lt;br /&gt;&lt;br /&gt;You will also need to add the following line to the top of your program, right after &lt;tt&gt;int main() {&lt;/tt&gt; in order to access the SDL event handling.&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0px -90px&quot;&gt;SDL_Event event;&lt;/pre&gt;&lt;br /&gt;Now, we need to tell the program that it should should skip on down to the end of the entire program when we press escape.&lt;br /&gt;&lt;br /&gt;So, surrounding everything but the first few lines of setup, add a while statement:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0px -75px&quot;&gt;int main(int argc, char* argv[]) {&lt;br /&gt;  SDL_Event event;&lt;br /&gt;  screen display(128, 120, 640, 480);&lt;br /&gt;  stamp kitt1(&quot;kitten1.png&quot;);&lt;br /&gt;&lt;br /&gt;  while (!done) {&lt;br /&gt;    ... your code ...&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We&#39;re going to have to set up the variable at the very top of our program, in between main() and the SDL_Event line:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0px -90px&quot;&gt;int done = 0;&lt;/pre&gt;&lt;br /&gt;Now, we can clean up our code by removing &lt;tt&gt;sleep(5);&lt;/tt&gt; as well as &lt;tt&gt;#include &amp;lt;unistd.h&amp;gt;&lt;/tt&gt; since we aren&#39;t using them any more.&lt;br /&gt;&lt;br /&gt;I guess I should mention that you should be compiling and running your program in between each set of changes so that you see the progression as we go along.&lt;br /&gt;&lt;br /&gt;So, let&#39;s make that kitten move!  Add the following line underneath the escape key press:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0px -270px&quot;&gt;case SDLK_LEFT: walkleft = 1; break;&lt;/pre&gt;&lt;br /&gt;This sets the walkleft variable to 1.  Add the walkleft variable underneath the done variable:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0px -90px&quot;&gt;int walkleft = 0;&lt;/pre&gt;&lt;br /&gt;All by itself, that doesn&#39;t do anything--we need to use that variable in an if statement in order to change the coordinates of our cat.&lt;br /&gt;&lt;br /&gt;First, change &lt;tt&gt;kitt1.put(100, 100);&lt;/tt&gt; to:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0px -405px&quot;&gt;kitt1.put(k1x, k1y);&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;now, let&#39;s preset our kitten&#39;s coordinates to the bottom right of the screen by setting our variables:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0px -105px&quot;&gt;int k1x = 110, k1y = 88;&lt;/pre&gt;&lt;br /&gt;Now all we have to do is create our if statement and place it right before we put the cat to the screen:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0px -420px&quot;&gt;/// GAME LOGIC ///&lt;br /&gt;  if (walkleft == 1) {&lt;br /&gt;    k1x = (k1x - 1);&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;If you run the file now, you&#39;ll notice that the cat smears itself across the screen, we need a way to clear the screen each time we paint.  So let&#39;s add the following right before we &quot;put&quot; our cat to the screen:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0px -495px&quot;&gt;display.clearSurface();&lt;/pre&gt;&lt;br /&gt;Next, we need to get the kitten to stop moving after you let go of the left arrow.  We need to add a whole section to our Handle Events section right after the &lt;tt&gt;break;&lt;/tt&gt; for &lt;tt&gt;case SDL_KEYDOWN:&lt;/tt&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0px -390px&quot;&gt;case SDL_KEYUP:&lt;br /&gt;        switch (event.key.keysym.sym) {&lt;br /&gt;          case SDLK_LEFT: walkleft = 0; break;&lt;br /&gt;          default: break;&lt;br /&gt;        }&lt;br /&gt;      break;&lt;/pre&gt;&lt;br /&gt;To get the kitten to wrap around to the other side, add the following tight after we decrement our x position:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; style=&quot;background-position: 0px -645px&quot;&gt;if (k1x &lt; -16) { k1x = 128; }&lt;/pre&gt;&lt;br /&gt;The numbers I chose here make sure that the kitten disappears off the screen before it re-appears on the other side.&lt;br /&gt;&lt;br /&gt;You should be able to add all of the code to move the kitten to the right rather than just the left.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://opencomputing.blogspot.com/2010/12/2d-games-with-kitten-fu-part-two.html&quot;&gt;Next time&lt;/a&gt; we&#39;ll flip the kitten, animate it and add another kitten to follow it around!&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Files&lt;/h3&gt;&lt;br /&gt;You can download everything from part 1 here: &lt;a href=&quot;http://www.communitycomputercenter.com/userfiles/kittens-01.tar.gz&quot;&gt;kittens-01.tar.gz&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;* * *</content><link rel='replies' type='application/atom+xml' href='http://opencomputing.blogspot.com/feeds/3421080180180551753/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3034230779454603134/3421080180180551753' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/3421080180180551753'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/3421080180180551753'/><link rel='alternate' type='text/html' href='http://opencomputing.blogspot.com/2010/12/2d-games-with-kitten-fu-part-one.html' title='2D Games with Kitten-Fu, Part One'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoE1dphxmoa1jzWbZfjN_DE2otwBQO4Uv5GUsgCsQEOnI0YPYjjyxL9FSl4MyUF00w-y6wx3bUwdGTd2krTK8SMHj3egPnCKE2nmfw4QNEqjX2-lfPeXQIjGsZvjG7xAMIeKs3bq-tje0/s72-c/kitten1-disp.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3034230779454603134.post-1907723983027994010</id><published>2010-09-20T15:19:00.001-07:00</published><updated>2010-09-20T15:20:48.480-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Arcade"/><category scheme="http://www.blogger.com/atom/ns#" term="Games"/><category scheme="http://www.blogger.com/atom/ns#" term="open source"/><category scheme="http://www.blogger.com/atom/ns#" term="UVOG"/><title type='text'>UVOG Arcade Machine</title><content type='html'>Umpqua Valley Opensource Group is building a classic-style Arcade machine (with a few innovations.)  I am in charge of drawing the sprites for one of the games, so I spent the weekend studying 8-bit video game palettes.&lt;br /&gt;&lt;br /&gt;I settled on using limitations similar to the 8-bit NES.  The NES itself only had around 54 possible colors on the system palette (technically there were 64 color indexes, but 10 of them were black and two were white!) There were also many additional limitations on how many colors could be used at a time on the screen as well as how many could be used per tile or sprite.&lt;br /&gt;&lt;br /&gt;I am using the same basic ideas to restrict the artwork for this game, but I have created an expanded palette using a full range of 64 different colors.  I also hand-tuned the choice of colors, and re-ordered the palette in a more sensible way.&lt;br /&gt;&lt;br /&gt;Because the Arcade Machine is an Open Source Project, my palette is Open Source as well. I am calling it the UVPALETTE.  It is available as a GPL (GIMP PaLette; which is usable in mtPaint also, and is basically a text file with a list of RGB values) at the following address:&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://communitycomputercenter.com/userfiles/UVPALETTE.GPL&quot;&gt;http://communitycomputercenter.com/userfiles/UVPALETTE.GPL&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I also have a demo of the palette here is a PNG file:&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEit0aFza5e3Bi1308QUY3CdeDPIsYGc18sm1h6T69EPimuVRu6Dqy_HPw59olbP-hbj0eRmVyF-UveIgdGEo1r_xh2YXM2D-LIg9rEGMPRy0_aKbDrWaUlMsW0tjJIujkELdfc72CJ5coMy/s1600/uvpalette-demo.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEit0aFza5e3Bi1308QUY3CdeDPIsYGc18sm1h6T69EPimuVRu6Dqy_HPw59olbP-hbj0eRmVyF-UveIgdGEo1r_xh2YXM2D-LIg9rEGMPRy0_aKbDrWaUlMsW0tjJIujkELdfc72CJ5coMy/s1600/uvpalette-demo.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;In order to make discussing and working with the palette easier, I have prescribed a canonical name for each color:&lt;br /&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;br /&gt;Names of colors on the first row (0x00 - 0x0F) Black, Dark Blue, Dark Cerulean, Dark Mint, Dark Green, Dark Lime, Dark Yellow, Dark Tan, Dark Orange, Dark Red, Dark Rose, Dark Orchid, Dark Violet, Dark Indigo, Forest, Charcoal.&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;br /&gt;Names of colors on the second row (0x10 - 0x1F) Gray, Blue, Cerulean, Mint, Green, Lime, Yellow, Tan, Orange, Red, Rose, Orchid, Violet, Indigo, Brown, Slate.&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;br /&gt;Names of colors on the third row (0x20 - 0x2F) Silver, Light Blue, Light Cerulean, Light Mint, Light Green, Light Lime, Light Yellow, Light Tan, Light Orange, Light Red, Light Rose, Light Orchid, Light Violet, Light Indigo, Jade, Chalk.&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;br /&gt;Names of colors on the fourth row (0x30 - 0x3F) Pale White, Pale Blue, Pale Cerulean, Pale Mint, Pale Green, Pale Lime, Pale Yellow, Pale Tan, Pale Orange, Pale Red, Pale Rose, Pale Orchid, Pale Violet, Pale Indigo, Gold, White.&lt;/div&gt;&lt;br /&gt;Here is another version of the palette demo with the prescribed color names listed for quick reference:&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNv5_nE5I8XyE3_HYwo6m6UKfOiCCoBzs6OVb5CIgfKo7jkGRUaGAgEw9BL-JLqPOyMmYWaH3eAt1uCFcY92cRA2SmE2TKeDLySs4sXcpAuaUwVR287HXChfaFfhcnx1qrAU7J2I3puKkd/s1600/uvpalette-named.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNv5_nE5I8XyE3_HYwo6m6UKfOiCCoBzs6OVb5CIgfKo7jkGRUaGAgEw9BL-JLqPOyMmYWaH3eAt1uCFcY92cRA2SmE2TKeDLySs4sXcpAuaUwVR287HXChfaFfhcnx1qrAU7J2I3puKkd/s1600/uvpalette-named.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Enjoy!</content><link rel='replies' type='application/atom+xml' href='http://opencomputing.blogspot.com/feeds/1907723983027994010/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3034230779454603134/1907723983027994010' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/1907723983027994010'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/1907723983027994010'/><link rel='alternate' type='text/html' href='http://opencomputing.blogspot.com/2010/09/uvog-arcade-machine.html' title='UVOG Arcade Machine'/><author><name>Jeff Day</name><uri>http://www.blogger.com/profile/11675035864869123800</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEit0aFza5e3Bi1308QUY3CdeDPIsYGc18sm1h6T69EPimuVRu6Dqy_HPw59olbP-hbj0eRmVyF-UveIgdGEo1r_xh2YXM2D-LIg9rEGMPRy0_aKbDrWaUlMsW0tjJIujkELdfc72CJ5coMy/s72-c/uvpalette-demo.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3034230779454603134.post-2014672387665251228</id><published>2010-09-03T15:23:00.000-07:00</published><updated>2010-09-05T14:55:17.907-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ATtiny2313"/><category scheme="http://www.blogger.com/atom/ns#" term="electronics"/><category scheme="http://www.blogger.com/atom/ns#" term="robots"/><title type='text'>Robot Logic, Part 1</title><content type='html'>&lt;div&gt;UVOG has decided to make a robot as a club project.  It will consist of Open Hardware and Open Software, and be easy for people to make at home on the cheap by repeating our steps.&lt;/div&gt;&lt;div&gt;My specialty is the software.  So far, we have decided to use a handful of ATtiny2313 chips to control the various appendages and modules of the robot.  The ATtiny2313&#39;s will be hooked up to a root controller of a type that is yet to be determined.  So, I&#39;m going to be learning AVR assembler to program the ATtiny2313 chip, but for now, I&#39;ve been doing my experimenting with C.  Assembler actually looks easier to use in this case, since I am so interested in direct pin manipulations and our memory space is so limited (2k program memory plus 256 bytes of SRAM and 256 bytes of EEPROM.)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One of my eventual goals is to learn the self-programming functions of the AVR instruction set so that I can reprogram any chip in the robot in place without any additional wiring other than that which we are using to send instructions from the root controller to the sub-controllers, but for now (until I have taught the chip how to do this), I have to use an external programmer.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Programming the Microcontroller&lt;/b&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I&#39;ve used three different programming boards for the 2313 so far.  The first one was a hand-made parallel port programmer, which pulled its current from a USB connector.  The second one is a board from Evil Mad Scientist which connects to the PC entirely with USB, through an adapter.  Both of these were ok, except I kept having to pull the IC from the programming board, and put it on my breadboard for testing, then after failing (it is inevitable), pulling it again and returning it to the programming board.  The third programmer is also a hand-made one, but this time it has two female headers running the length of the chip that I can plug test wires into.  It also has a six-pin connector to attach or detach the parallel cable, which is a lot easier than running around behind the computer every time.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;My debugging process now looks like this:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Plug the IC into the programming board.  Plug the USB and Parallel into the PC, and plug the other end of the Parallel into the programming board.  I will leave the IC , the USB and the Parallel (on the PC side) plugged in the entire time I&#39;m working.  The only cable I will unplug during the debug process is the programming board side of the parallel cable.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So far, I have not been using the UCSK, MISO, MOSI, or RESET pins (a.k.a., pins 1, 17, 18, or 19) in my actual experiment, so I can leave the IC on the test board, and hook up my other components by jumping a wire from the headers to the breadboard.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I unplug the single wire going from GND (pin 10) to the breadboard&#39;s ground bus, and I plug in the six-pin parallel connector, then run &quot;make&quot;, and my toolchain compiles and automatically uploads the compiled code into the chip.  Next, I plug the wire from pin the breadboard&#39;s ground bus back into pin 10 (GND) on the header, and I unplug the six pin connector, which releases the RESET pin causing the chip to boot up and run my code.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;When I want to test again, I simply unplug GND and plug the six pins back in.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If I simply need to reset the chip to test the boot sequence again without reprogramming it, I can either apply a GND lead to the reset pin, or plug the 6-pin parallel connector in momentarily to accomplish the same thing.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;How I Plan to Use the Chip&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The 2313 has a nice amount of general purpose input/output pins.  They have given names to the pins to indicate how they are treated internally as &quot;ports.&quot;  Along the &quot;left side&quot; of the chip, we have RESET (which doubles as PA2),  then we have PD0, PD1, PA1, PA0, PD2, PD3, PD4, PD5, and GND.  And going up the right side of the chip we have PD6, PB0 through 7, and VCC (our voltage source.)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For most of the chips in this project, I plan to use them in the following way:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Pin 1, 10, and 20 are keeping their purposes as RESET, GND, and VCC. Although repurposing RESET is possible, it is dangerous because it disables the programmability of the chip (RESET is normally held low while the chip is flashed.)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;All the other pins down the left side are going to be used as inputs, in addition to pin 11 (the bottom pin on the right side.)  This gives us a total of nine input pins which are known internally as PORTA and PORTD (with the exception of PORTA bit 2, which is reset.)  When used as inputs, the values are actually read from the ports called PINA and PIND.  All of the remaining pins on the right side will be used for outputs, which is known internally as PORTB.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Quick Review:&lt;/div&gt;&lt;div&gt;&lt;b&gt;Input: &lt;/b&gt; 2 bits of PORTA and all 7 bits of PORTD. (actually PINA and PIND)&lt;/div&gt;&lt;div&gt;&lt;b&gt;Output: &lt;/b&gt; All 8 bits of PORTB.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Some of our inputs have special functionality that we will be interested in, so we need to be careful to reserve those for the purposes we intend to use.  Specifically, pin 6 and 7, a.k.a., PORTD2 and PORTD3 are the lines used to raise INT0 and INT1.   INT0 is interesting to us, because it is the only regular user-definable interrupt that can raise the micro-controller out of its power-saver or sleep condition. (I don&#39;t remember exactly the term used for this particular sleep mode at the moment.)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I plan to use INT0 and INT1 to &quot;talk to the chip&quot; from the root controller.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This leaves us with the following general purpose inputs, which I would tend to utilize in the following manner:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Most Significant - - - - - Least Significant&lt;/div&gt;&lt;div&gt;PD6, PD5, PD4, PA1, PA0, PD1, PD0&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If I care to get this into a single byte (sans the high bit), I think I can do so by performing the following bitwise operation:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;MyInput = ((PIND &amp;amp; 0x73) | ((PINA &amp;amp; 0x03) &lt;&lt;&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Because the ATtiny2313 uses internal pull-up resistors, the default state of all the pins will read as high values (1).  To toggle a pin, we must apply ground to it, which will lower it to zero.  In other words, when we are dealing with inputs, &quot;low means active.&quot;  We might, therefore, want to inverse the value of all bits of input, so that we can logically use 1 to indicate active and 0 to indicate inactive.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Gotta run, I will post more on this later.&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://opencomputing.blogspot.com/feeds/2014672387665251228/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3034230779454603134/2014672387665251228' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/2014672387665251228'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/2014672387665251228'/><link rel='alternate' type='text/html' href='http://opencomputing.blogspot.com/2010/09/robot-logic-part-1.html' title='Robot Logic, Part 1'/><author><name>Jeff Day</name><uri>http://www.blogger.com/profile/11675035864869123800</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3034230779454603134.post-9116025769439572493</id><published>2010-08-19T12:46:00.000-07:00</published><updated>2010-08-19T13:24:17.632-07:00</updated><title type='text'>Support for older Intel Graphics Chipsets in Lucid Lynx</title><content type='html'>For those having trouble getting Intel Brookdale G [82845G/GL] and similar chipsets to work on Ubuntu 10.04, I have good news.  The Ubuntu Wiki has &lt;a href=&quot;https://wiki.ubuntu.com/X/Bugs/Lucidi8xxFreezes&quot;&gt;a page containing workarounds and fixes for the issue&lt;/a&gt;.  My preferred choice right now is to install the backported Maverick kernel. This is also good news, because Ubuntu 10.10 should be expected to work on these machines without adjustment.  Of course, if you just want the system to work with basic office-style functionality, VESA mode is a good alternative, but it will disable accelerated video.</content><link rel='replies' type='application/atom+xml' href='http://opencomputing.blogspot.com/feeds/9116025769439572493/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3034230779454603134/9116025769439572493' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/9116025769439572493'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/9116025769439572493'/><link rel='alternate' type='text/html' href='http://opencomputing.blogspot.com/2010/08/support-for-older-intel-graphics.html' title='Support for older Intel Graphics Chipsets in Lucid Lynx'/><author><name>Jeff Day</name><uri>http://www.blogger.com/profile/11675035864869123800</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3034230779454603134.post-5388122982586686454</id><published>2010-08-12T15:15:00.000-07:00</published><updated>2010-08-12T15:16:12.266-07:00</updated><title type='text'>Linux can do this</title><content type='html'>Nuff said. &lt;object width=&quot;480&quot; height=&quot;385&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://www.youtube.com/v/c1TOAXAbOAI?fs=1&amp;amp;hl=en_US&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot;&gt;&lt;/param&gt;&lt;embed src=&quot;http://www.youtube.com/v/c1TOAXAbOAI?fs=1&amp;amp;hl=en_US&quot; type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; width=&quot;480&quot; height=&quot;385&quot;&gt;&lt;/embed&gt;&lt;/object&gt;</content><link rel='replies' type='application/atom+xml' href='http://opencomputing.blogspot.com/feeds/5388122982586686454/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3034230779454603134/5388122982586686454' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/5388122982586686454'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/5388122982586686454'/><link rel='alternate' type='text/html' href='http://opencomputing.blogspot.com/2010/08/linux-can-do-this.html' title='Linux can do this'/><author><name>robots_unix</name><uri>http://www.blogger.com/profile/16991921542825149149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3034230779454603134.post-569789616113798805</id><published>2010-08-03T17:02:00.000-07:00</published><updated>2010-08-09T22:03:30.093-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="data"/><category scheme="http://www.blogger.com/atom/ns#" term="python"/><category scheme="http://www.blogger.com/atom/ns#" term="tutorial"/><title type='text'>Tutorial on making colored maps</title><content type='html'>This Tutorial uses a Python script and free SVG maps to make maps based on csv data files!  I know what I&#39;m going to be doing tonight when I get off work!&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://flowingdata.com/2009/11/12/how-to-make-a-us-county-thematic-map-using-free-tools/&quot;&gt;How to make a US county thematic map using free tools&lt;/a&gt; [flowingdata.com]&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4C0FMGLxsTTM3raBodENUMXg3fvGDeUo6KAKfvVLAW-HtnCZs4wrO41pfm9z09o2kVoPVdJbDnCKfo0X3nBmXMtxHJxasPndO0OOsCtrJPFt5gn9VbrPU5vWZN3ZXakvUC1GT_C-ek6c/s1600/unemployment.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 210px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4C0FMGLxsTTM3raBodENUMXg3fvGDeUo6KAKfvVLAW-HtnCZs4wrO41pfm9z09o2kVoPVdJbDnCKfo0X3nBmXMtxHJxasPndO0OOsCtrJPFt5gn9VbrPU5vWZN3ZXakvUC1GT_C-ek6c/s320/unemployment.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5501339004820044466&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Edit:&lt;/b&gt;&lt;br /&gt;Michael made his own version of the same map following the tutorial!  Here it is:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSTe7xXUYdD1LL-eUrCAf8xoCKI9O0PrNoP9blPJu5aJJ8GaU74LjrrPYtMCePxCmoyOYxAmwmfYpxz9TOLOSuTHCFrxrh1QV36X3VL1gbTQbHOLr9gRbVQo0EWpBEDnV3n1M9ZM1oK1o/s1600/newmap.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 208px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSTe7xXUYdD1LL-eUrCAf8xoCKI9O0PrNoP9blPJu5aJJ8GaU74LjrrPYtMCePxCmoyOYxAmwmfYpxz9TOLOSuTHCFrxrh1QV36X3VL1gbTQbHOLr9gRbVQo0EWpBEDnV3n1M9ZM1oK1o/s320/newmap.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5503642271477273266&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;!-- &lt;br /&gt;&lt;br /&gt;Sites I used along the way:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href=&quot;http://johnbokma.com/mexit/2009/09/26/python-downgrading-beatifulsoup.html&quot;&gt;http://johnbokma.com/mexit/2009/09/26/python-downgrading-beatifulsoup.html&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2&quot;&gt;http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href=&quot;http://gs.statcounter.com&quot;&gt;http://gs.statcounter.com&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Move Beautiful Soup to the /lib/Python folder&lt;br /&gt;--&gt;</content><link rel='replies' type='application/atom+xml' href='http://opencomputing.blogspot.com/feeds/569789616113798805/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3034230779454603134/569789616113798805' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/569789616113798805'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/569789616113798805'/><link rel='alternate' type='text/html' href='http://opencomputing.blogspot.com/2010/08/tutorial-on-making-colored-maps.html' title='Tutorial on making colored maps'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4C0FMGLxsTTM3raBodENUMXg3fvGDeUo6KAKfvVLAW-HtnCZs4wrO41pfm9z09o2kVoPVdJbDnCKfo0X3nBmXMtxHJxasPndO0OOsCtrJPFt5gn9VbrPU5vWZN3ZXakvUC1GT_C-ek6c/s72-c/unemployment.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3034230779454603134.post-7977832677994314470</id><published>2010-08-03T13:16:00.000-07:00</published><updated>2010-08-03T13:19:11.395-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Eben Moglen"/><category scheme="http://www.blogger.com/atom/ns#" term="Free Software"/><category scheme="http://www.blogger.com/atom/ns#" term="Free Software Foundation"/><category scheme="http://www.blogger.com/atom/ns#" term="freedom"/><category scheme="http://www.blogger.com/atom/ns#" term="MySQL"/><category scheme="http://www.blogger.com/atom/ns#" term="patents"/><title type='text'>Video, State of Free Software</title><content type='html'>Listen to &lt;a href=&quot;http://www.fsf.org/blogs/community/lp2010-moglen-state-of-free-sw&quot;&gt;this video&lt;/a&gt; of Eben Moglen&#39;s presentation on the State of Free Software.</content><link rel='replies' type='application/atom+xml' href='http://opencomputing.blogspot.com/feeds/7977832677994314470/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3034230779454603134/7977832677994314470' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/7977832677994314470'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/7977832677994314470'/><link rel='alternate' type='text/html' href='http://opencomputing.blogspot.com/2010/08/video-state-of-free-software.html' title='Video, State of Free Software'/><author><name>Jeff Day</name><uri>http://www.blogger.com/profile/11675035864869123800</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3034230779454603134.post-1682521769897624395</id><published>2010-08-02T23:41:00.000-07:00</published><updated>2010-08-03T00:35:30.569-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="freedom"/><category scheme="http://www.blogger.com/atom/ns#" term="law"/><category scheme="http://www.blogger.com/atom/ns#" term="oregon"/><category scheme="http://www.blogger.com/atom/ns#" term="recycling"/><title type='text'>Oregon&#39;s E-Cycle program flawed</title><content type='html'>We are required by law to print the following three lines on receipts for purchases of new computers or monitors, or to distribute one of several graphical alternatives:&lt;br /&gt;&lt;br /&gt;Oregon E-Cycles: Free Recycling&lt;br /&gt;for Computers, Monitors and TVs&lt;br /&gt;www.oregonecycles.org 1-888-5-ECYCLE&lt;br /&gt;&lt;br /&gt;Unfortunately, the Oregon E-Cycles program is seriously flawed and could hurt the freedom of the economy and the freedom of choice of consumers. Don&#39;t get me wrong. I support and encourage recycling and care for the environment, but this law over-reaches its purpose. The e-cycle website states: &quot;Only those brands listed as pending or compliant may be sold in or into Oregon. If a brand is not listed, it may not be sold. Sales restrictions apply to all types of sales including retail, catalog, phone and Internet sales.&quot;&lt;br /&gt;&lt;br /&gt;The DEQ decides the fee that a particular manufacturer must pay to register. If they don&#39;t pay up, they aren&#39;t allowed to sell their product [legally] in Oregon. DEQ determines the fee based on statistical information which they acquire in order to determine the market share held by the brand in question. They start with national statistics and adjust it based on a limited amount of local statistics. The minimum fee right now is $40. If a brand has more than 0.01% market share based upon DEQ&#39;s manipulated statistics, the fee goes up to $200. For brands with more than 1%, the fee is $15,000, which is the amount they are apparently collecting from prominent national manufacturers such as Dell and HP-Compaq.&lt;br /&gt;&lt;br /&gt;Imagine if every state implemented an identical program. Dell would have to pay three quarters of a million dollars every year just to be an authorized manufacturer, and that money does not go towards recycling. The manufacturers pay for the recycling fees themselves. A little shop that assembles generic computers would have to pay a combined $2000 to all fifty states, which might be more than they make in computer sales during the year, especially if new computer sales is not their main line of business.&lt;br /&gt;&lt;br /&gt;This is, of course, a bad scenario. It is unlikely that all fifty states would demand payment from a vendor. The states would have to become aware of that brand being imported into their state before they would likely make such a demand, and even so, is it enforceable if another state demands that you pay them a fee just because someone carried your product across state lines?&lt;br /&gt;&lt;br /&gt;Also, what&#39;s to say that a particular state can&#39;t raise the rates or file you in a higher market-share tier in order to pressure you out of the business. If I was a vendor in another state, and Oregon DEQ contacted me, I would be tempted to simply disable shipping to Oregon on my website, and place a warning label on my packaging saying that the product may not be imported into Oregon by the original owner--that&#39;s right! Used and refurbished equipment is exempt from the program.&lt;br /&gt;&lt;br /&gt;Here&#39;s the bad part of the law: Oregon is shooting itself in the foot because it is trying to force manufacturers around the world to comply with its fees, which could reduce the choice that customers living in Oregon have on what they may purchase. Someone will have to set up a company just across the border that will purchase a new computer for you from a non-compliant manufacturer, then resell it to you as used equipment.&lt;br /&gt;&lt;br /&gt;Frankly, I shouldn&#39;t have to pay fees to any other states, and other companies shouldn&#39;t have to pay fees to my state. &lt;b&gt;No taxation without representation! &lt;/b&gt;If the states want to have purchasers pay fees because they purchased a computer or monitor, then the state should include this on the tax forms for their own residents.&lt;br /&gt;&lt;br /&gt;Now, from the retailer point of view. Other than my purchasing options being limited by a list of brands put out by DEQ, which is quite disturbing, I also notice that I had the choice of using the three lines shown above on my receipts, or including one of the other printed materials of which there is a wide variety. The problem? All the materials are in color, and the section on logos specifically says that if you need alternate format logos including B&amp;amp;W that you must contact DEQ manually to request it. Why would a recycle program require me to print in color? They must want me to recycle my cyan and yellow toner cartridges on my laser printer more often. Well, I opted for the three lines instead to conserve toner, and to avoid showing the logo of this program which I detest.&lt;br /&gt;&lt;br /&gt;Think about how much time and money is wasted handling all the extra paperwork, calculating annual market share reports, and certifying manufacturers. This process needs to stop.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;If you too find this law to be over-reaching and limiting of your freedom, or believe that it does not serve the interests of recycling or caring for the environment, please contact your state senators and let them know that the flaws of this program need to be exposed so that action may begin to correct it and implement proper recycling legislation in its place.&lt;/b&gt;</content><link rel='replies' type='application/atom+xml' href='http://opencomputing.blogspot.com/feeds/1682521769897624395/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3034230779454603134/1682521769897624395' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/1682521769897624395'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/1682521769897624395'/><link rel='alternate' type='text/html' href='http://opencomputing.blogspot.com/2010/08/oregons-e-cycle-program-flawed.html' title='Oregon&#39;s E-Cycle program flawed'/><author><name>Jeff Day</name><uri>http://www.blogger.com/profile/11675035864869123800</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3034230779454603134.post-8056964136360675303</id><published>2010-07-27T11:59:00.000-07:00</published><updated>2010-07-27T12:09:17.837-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="bloat"/><category scheme="http://www.blogger.com/atom/ns#" term="Microsoft"/><category scheme="http://www.blogger.com/atom/ns#" term="Office"/><category scheme="http://www.blogger.com/atom/ns#" term="OpenOffice"/><category scheme="http://www.blogger.com/atom/ns#" term="Operating Systems"/><category scheme="http://www.blogger.com/atom/ns#" term="software"/><category scheme="http://www.blogger.com/atom/ns#" term="Standards"/><title type='text'>Response to .DOC Attachment</title><content type='html'>&lt;div&gt;What do you do when you receive an email file attachment in Microsoft&#39;s .DOC format?  Sure, we could open it in OpenOffice.org and go about our business, but there&#39;s no guarantee that this will remain true for future versions of .DOC.  Use of proprietary formats are a danger to interoperability and to future innovation.  One good thing to do is to reply to the email and explain why they should send the attachment in a standard format.  I&#39;ve seen several canned email responses in the past, but most are too brief to explain the issue, or too harsh in their wording to satisfy my tastes.  I was prompted to write a response after receiving such an email attachment today, and I have combined some of the best ideas from elsewhere and added some of my own.  Here is what I would recommend:&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;/i&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;The document you have sent was not saved in an accepted format for Internet mail.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It was saved in a proprietary format that is unreadable on several types of computers because the method for decoding the document is kept secret by Microsoft and is purposefully changed with each new release of Microsoft Word so that existing users of Microsoft Word will be forced to pay for expensive upgrades in order to continue to read Word Documents sent by others. For example, in 2010, Microsoft Office Home &amp;amp; Business 2010 was priced at $279.99, and Microsoft Office Professional 2010 was priced at $499.99.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Recent versions of Word have started using a newer, patented OOXML format. In many countries, it is actually illegal for other products to decipher this format. This is a lock-in technique used by Microsoft to maintain their monopoly on Office software, and by extension, their monopoly on the operating system market, since they have not released a cross-platform version of Microsoft Office compatible with other operating systems.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In most cases, the size of the file saved in Microsoft&#39;s secret, proprietary format is also substantially larger than a standards compliant file containing the same information and the same formatting.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It is also important to note that Microsoft Word documents are often infected with viruses. Excel, Access, and Power Point files are also vulnerable to infection. This potential for infection is largely due to the Macro language and the &quot;Visual Basic for Applications&quot; language which are built into the format to provide powerful programming capabilities. While powerful, these features were not protected with proper security precautions, and the majority of users do not actually use these features or even know that they exist.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What to do instead:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you continue to use Microsoft Word, please have the courtesy to “Save As” one of the following formats: ODT (if available), DOS Text, HTML, or Portable Document Format (PDF) and after saving, send the resulting file as an attachment.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Alternatively, you could use a product such as AbiWord, KOffice, Google Docs, NeoOffice, or OpenOffice.org that allows you to save your document in the Open Document Text Format (ODT), which is an ISO/IEC International Standard, and is supported by such notable companies as Apple, Adobe, Google, IBM, Intel, Nokia, Novell, and Sun Microsystems. If you don&#39;t have one of these programs, I would recommend OpenOffice.org, which may be downloaded free of charge and used for any purpose, personal or commercial.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A third option is to simply type your message directly into mail (instead of typing into Microsoft Outlook or Microsoft Word) so that you won&#39;t need to use an attachment at all.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In the highly unlikely event that your document cannot be converted to an open, non-proprietary format, consider printing it and mailing it by post, or scanning it, and sending it in a standard graphic format such as PNG or JPG.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Thank you.&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;i&gt;&lt;/i&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://opencomputing.blogspot.com/feeds/8056964136360675303/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3034230779454603134/8056964136360675303' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/8056964136360675303'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/8056964136360675303'/><link rel='alternate' type='text/html' href='http://opencomputing.blogspot.com/2010/07/response-to-doc-attachment.html' title='Response to .DOC Attachment'/><author><name>Jeff Day</name><uri>http://www.blogger.com/profile/11675035864869123800</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3034230779454603134.post-3433712857155927328</id><published>2010-07-13T22:39:00.000-07:00</published><updated>2010-07-14T00:24:05.623-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Databases"/><category scheme="http://www.blogger.com/atom/ns#" term="MySQL"/><category scheme="http://www.blogger.com/atom/ns#" term="open source"/><category scheme="http://www.blogger.com/atom/ns#" term="Standards"/><title type='text'>Open Database Conventions</title><content type='html'>I&#39;ve been using a set of database table and field naming conventions and related standards that have been gradually adopted and refined over the last 10 years.  I decided today that it would be a good idea to share these with others, particularly because I decided to bring Jim from UVOG in on a database project I&#39;m starting on.  I realized that sharing them with others on an even wider scale might be a good thing on the off-chance that, if someone else out there adopts them, and if our code ever ends up crossing paths, we will gain greater interoperability and understanding on account of using the same techniques.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Feel free to take some or all of these ideas and implement them in your own projects.  I am willing to hear feedback and incorporate it back into the standard if you think there&#39;s a better way to do something that I&#39;ve mentioned.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Some of these conventions will apply specifically to MySQL, while others will apply to the greater spectrum of databases.   My experience spans MS Access, MS SQL Server, dBase, FoxPro, the Apollo Database Engine, and MySQL, with some very light experience in SQLite and PostgreSQL, but the bulk of my work today happens in MySQL.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Naming the Database&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The name of the database itself is the least of my concerns.  I would just recommend that in code that operates with or upon the database, this value should be easily configurable along with the hostname, port, and authentication credentials, so that any database could be selected.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Naming Tables&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The name of a table should be a succinct name descriptive of what is to be represented by a single record in the table.  If each record in the table represents an account, for example, name the table &quot;account&quot; (in the singular, all lowercase.)  The reason we use singular forms is so that dot notation naming of fields makes sense when read out loud, for example, account.balance. There are many reasons we use all lowercase.  Most production Database servers are case sensitive, and by using all lowercase we can eliminate the possibility of an error relating to case.  It also improves code readability when SQL statements are written out with keywords and function names capitalized and with table and field names in lowercase.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There is a special case of naming in the event of a junction table.  (A junction table is used to create a many-to-many relationship between two tables, and consists of nothing more than an id field, and foreign keys for the two tables whose records it is tying together.)  The name of a junction table should be the name of the other two tables mashed together, with the name of the greater entity first.  For example, if I have a company table and an customer table, and customers are potentially associated with multiple companies, I would name the junction table companyemployee, and it would contain id, kcompany, and kemployee, in that order.  If there is a toss-up in determining which entity is &quot;greater,&quot; place the two table names in alphabetical order.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Naming Fields&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Always name your fields as though they are going to be used in dot notation.  We want account.balance, not account.accountbalance, so do not redundantly repeat the table name within the field name. Avoid abbreviations that seem like a hack.  For example, number is better than &quot;no&quot; or &quot;num.&quot;  Widely used abbreviations like ipaddress, ssn, or id are ok--be particularly careful to avoid expanding acronyms that are not expanded in common speech.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;The Primary Key&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In order to be properly maintained, every record needs to be addressable by a unique identifier.  This identifier should not be meaningful in any real-world way for reasons that are explained in depth elsewhere, but I will give one brief example.  If you were making an employee database, you might be tempted to use a person&#39;s SSN as the primary key for the employee table.  Three years after the program is written, your company might hire someone who is in the country on a work visa, and therefore does not have an SSN, and now your system is broken.  One will follow this line of thinking out and conclude that the key should be completely arbitrary and meaningless so that no such conflicting situation may ever occur.  Additionally, for the sake of consistency, the primary key field in each table you make should be of the same name and type.  I recommend naming the first field of each table &quot;id&quot;, setting it to &quot;auto_increment,&quot; and setting it to become the PRIMARY KEY index.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The value of this id field should be used internally for programming purposes and for describing relations between tables, but it should never be shown prominently to the user.  If it is shown, it is merely for debugging or reference purposes.  The number in this field, once generated, should not be changeable by the user, is not guaranteed to be sequential with the records around it, and is not guaranteed to fall into any range of values more specific than those allowed by an int (11) field.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Foreign Keys&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A foreign key can be thought of as a &quot;pointer&quot; referring from the current record out to another record in another table (or possibly another record in the same table.)  All foreign keys should be prefixed with the letter &quot;k&quot; (meaning key), and should either be named &quot;parent&quot; if the key is referring back to the same table for the purpose of producing a hierarchical system, or if referring to another table, it should be given the name of the table into which it points.  If more than one key in a record must point to the same table for different purposes, the purpose should be appended to the name followed by an underscore.  For example, kaddress_from and kaddress_to would be pointers to two records in the table named &quot;address.&quot;  The relation to one of them is described as &quot;from&quot; and the other as &quot;to.&quot;  This is the only time an underscore is permitted to be used in a field name, and the purpose of the underscore is to make the table name unambiguous.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;When possible, try to put keys to parent records or records which are considered to &quot;own&quot; the current record near the top of the field listing, following just after id.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If these standards are followed for the primary key and foreign key fields, I could look up any reference using the following technique:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Given a field whose name begins with &quot;k&quot;:  Take everything in the field name following the &quot;k&quot; up to the end of the name, or up to (but not including) the first encountered underscore &quot;_&quot; character, and consider this to be the &quot;lookup table name,&quot; if such a table exists.  Retrieve the data by issuing a query in the form of:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;SELECT * FROM [lookup table name] WHERE id = [value of the field]&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Choosing Appropriate Data Types for Fields&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Always choose the most restrictive type that can safely store the data, including valid values that you might not anticipate.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;KEY FIELDS&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;For id fields or foreign key fields, use INT (11)&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For boolean (yes/no or true/false) fields, use TINYINT (1)   A value of zero means false, and any nonzero value means true.  You can distinguish between individual nonzero values for record housekeeping if you wish, as long as others reading the data as merely true or false will not be under a misconception from not making such a distinction.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;CURRENCY&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;For currency values less than a million dollars, use DECIMAL (8, 2) --- increase the first size by a sufficient number of digits if you need larger currency values.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;NUMERIC DATA&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For numeric data involving whole numbers or integers only, use INT (11) --- unless the size is astronomical, in which case, you will need to upgrade to a larger type.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For weights or non-integer quantities less than ten thousand, use DECIMAL (8, 4) --- increase the first size if values beyond ten thousand are needed, or both sizes if more precision than four decimal positions is needed.  Four decimal places was chosen so that a number like 12.05% could be fully represented as 0.1205.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;DATES AND TIMES&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For date or time values or stamps where the &quot;time part&quot; has meaning (particularly in sorting), use the DATETIME type.   A value of &quot;0000-00-00 00:00:00&quot; means not entered or unknown.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For date values where the time is irrelevant, use the DATE type.  A value of &quot;0000-00-00&quot; means not entered or unknown.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;MULTIPLE CHOICE&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For multiple choice values:  If there are a discrete number of choices presently and in the near future, few choices (about 8 or less), and little or no benefit would be had by allowing the user to customize the set of choices, an enumerated value may be used.  Example:  alignment ENUM (&#39;left&#39;, &#39;right&#39;, &#39;center&#39;) DEFAULT &#39;left&#39;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For multiple choice values where the choices are numerous or user defined or potentially user managed, a foreign key and a lookup table should be used instead of an enum.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;STRINGS OF TEXT (NO MULTI-LINE VALUES)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For any string data:  If the options are very well established, choose the smallest size category from the table below that can hold all possible values, or for data that is free-form, choose one category larger than you think is really necessary.  I will give some example with each size category:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;VARCHAR (4) -- A standard name suffix like Jr., Sr., II., III.&lt;/div&gt;&lt;div&gt;VARCHAR (8) -- Data known for certain to be less than or equal to 8 characters.&lt;/div&gt;&lt;div&gt;VARCHAR (16) --  A zip code.  (Minimum to store a US zip code is presently 9 digits plus one hyphen.)&lt;/div&gt;&lt;div&gt;VARCHAR (24) -- A phone number, with decorations. The following number is 23 characters long, including spaces:  +1 (541) 375-0448 x8888&lt;/div&gt;&lt;div&gt;VARCHAR (32) -- Product codes, SKU numbers, or generated numbers that are guaranteed to be less than or equal to 32 characters.&lt;/div&gt;&lt;div&gt;VARCHAR (48) -- A first(given) name by itself, or a last name(surname) by itself.&lt;/div&gt;&lt;div&gt;VARCHAR (64) -- A full name field (first and last name together.)&lt;/div&gt;&lt;div&gt;VARCHAR (128) -- An email address.&lt;/div&gt;&lt;div&gt;VARCHAR (248) -- A web address.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;PARAGRAPHS OF TEXT, NOTES, MESSAGE CONTENT, CODE SNIPPETS&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For anything multi-line, or potentially longer than 248 characters, use the TEXT type.  If the data or text will be more than a couple of kilobytes, investigate the LONGTEXT type.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;IMAGES OR BINARY FILES&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I don&#39;t like big files taking up space in my InnoDB tables and slowing down my replication server.  Instead, I store the original filename only (and only as a convenience) in a VARCHAR field, and then save the file separately named based upon the table name and record number the file is associated with.  If I need to replicate these files, I let rsync take care of that.  If the &quot;attached&quot; files MUST be synchronized with the other data in the record at any given moment, then it might be acceptable to resort to BLOB fields.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Order of Fields&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;When creating tables, the order of the fields really doesn&#39;t matter to the database engine. The sequence, therefore, should be chosen for purposes of clarity in documentation.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Well, that&#39;s all I have for now.  Have at it, tear it up, and send me suggestions.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://opencomputing.blogspot.com/feeds/3433712857155927328/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3034230779454603134/3433712857155927328' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/3433712857155927328'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/3433712857155927328'/><link rel='alternate' type='text/html' href='http://opencomputing.blogspot.com/2010/07/open-database-conventions.html' title='Open Database Conventions'/><author><name>Jeff Day</name><uri>http://www.blogger.com/profile/11675035864869123800</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3034230779454603134.post-6962573817211557202</id><published>2010-07-13T08:25:00.001-07:00</published><updated>2010-07-13T13:51:27.650-07:00</updated><title type='text'>ACNG Client side perl script part two</title><content type='html'>Please refer to these previous articles :&lt;a href=&quot;http://opencomputing.blogspot.com/2010/07/speeding-up-your-updates-with-ubuntu.html&quot;&gt; Setting up ACNG&lt;/a&gt; &lt;a href=&quot;http://opencomputing.blogspot.com/2010/07/apt-cacher-ng-client-side-perl-script.html&quot;&gt;ACNG client side perl script&lt;/a&gt; for set up and scripting Apt-Cacher-NG.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I have made some modifications to the perl script to allow for simple gui integration.&lt;br /&gt;Props to @gpled for showing me zenity a couple of months ago.&lt;br /&gt;&lt;br /&gt;Change this:&lt;br /&gt;#!usr/bin/perl -w&lt;br /&gt;#script by @robots_unix&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;print &quot;Are you at CCC?&quot;;&lt;br /&gt;$name = ;&lt;br /&gt;chomp ($name);&lt;br /&gt;if ($name eq &quot;yes&quot;){ &lt;br /&gt;&lt;br /&gt;To this:&lt;br /&gt;&lt;br /&gt;#!usr/bin/perl -w&lt;br /&gt;#script by @robots_unix&lt;br /&gt;system(&#39;zenity --title &quot;Apt-Cacher-NG&quot; --text &quot;Are you at CCC?&quot; --list --radiolist --column &quot;ACNG&quot; --column &quot;Toggle&quot; False no True yes&gt; aptyesno&#39;);&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;open(APT, &quot;Location of aptyesno&quot;);&lt;br /&gt;$name = &lt;APT&gt;;&lt;br /&gt;if ($name eq &quot;yes\n&quot;){&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Then right-click on gnome-panel, click add to panel, click create custom application launcher, then for the command  type: sudo perl location of your perl script.&lt;br /&gt;&lt;br /&gt;Now you can change the hosts file by just clicking an icon on your gnome-panel.&lt;br /&gt;&lt;br /&gt;Have fun.</content><link rel='replies' type='application/atom+xml' href='http://opencomputing.blogspot.com/feeds/6962573817211557202/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3034230779454603134/6962573817211557202' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/6962573817211557202'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/6962573817211557202'/><link rel='alternate' type='text/html' href='http://opencomputing.blogspot.com/2010/07/acng-client-side-perl-script-part-two.html' title='ACNG Client side perl script part two'/><author><name>robots_unix</name><uri>http://www.blogger.com/profile/16991921542825149149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3034230779454603134.post-8371265120516814551</id><published>2010-07-12T12:40:00.000-07:00</published><updated>2010-07-12T12:52:44.919-07:00</updated><title type='text'>Moving the close, minimize and maximize to the right side again</title><content type='html'>I just installed Wubi and Ubuntu 10.04 and love it!!&lt;div&gt;But I was used to the close buttons being on the right&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;type in the terminal&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Lucida Grande&#39;; &quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: medium;&quot;&gt;gconftool-2 --set /apps/metacity/general/button_layout --type string menu:minimize,maximize,close&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Lucida Grande&#39;; &quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: medium;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Lucida Grande&#39;; &quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: medium;&quot;&gt;you can also change it manually:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Lucida Grande&#39;; &quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: medium;&quot;&gt;&lt;a href=&quot;http://www.howtogeek.com/howto/ubuntu/put-closemaximizeminimize-buttons-on-the-left-in-ubuntu/&quot;&gt;http://www.howtogeek.com/howto/ubuntu/put-closemaximizeminimize-buttons-on-the-left-in-ubuntu/&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Lucida Grande&#39;; &quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Lucida Grande&#39;; &quot;&gt;just type in terminal:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Lucida Grande&#39;; &quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Verdana; font-size: 14px; line-height: 17px; &quot;&gt;&lt;em style=&quot;font-style: italic; font-weight: normal; &quot;&gt;gconf-editor&lt;/em&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Lucida Grande&#39;; &quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Verdana; font-size: 14px; line-height: 17px; &quot;&gt;&lt;em style=&quot;font-style: italic; font-weight: normal; &quot;&gt;&lt;br /&gt;&lt;/em&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Lucida Grande&#39;; &quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Verdana; font-size: 14px; line-height: 17px; &quot;&gt;&lt;span style=&quot;font-weight: normal; &quot;&gt;then open apps -&gt; metacity -&gt; general&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Lucida Grande&#39;; &quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Verdana; font-size: 14px; line-height: 17px; &quot;&gt;&lt;span style=&quot;font-weight: normal; &quot;&gt;and change button layout on the right side to:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;   style=&quot;font-family:Verdana;font-size:130%;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 14px; line-height: 17px;&quot;&gt;menu:minimize,maximize,close&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;   style=&quot;font-family:Verdana;font-size:130%;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 14px; line-height: 17px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;   style=&quot;font-family:Verdana;font-size:130%;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 14px; line-height: 17px;&quot;&gt;I hope that is helpful&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:&#39;Lucida Grande&#39;;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: medium; &quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://opencomputing.blogspot.com/feeds/8371265120516814551/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3034230779454603134/8371265120516814551' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/8371265120516814551'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/8371265120516814551'/><link rel='alternate' type='text/html' href='http://opencomputing.blogspot.com/2010/07/moving-close-minimize-and-maximize-to.html' title='Moving the close, minimize and maximize to the right side again'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/15703804696957522260</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3034230779454603134.post-3435410201511844461</id><published>2010-07-12T12:38:00.000-07:00</published><updated>2010-07-12T12:40:43.058-07:00</updated><title type='text'>Linux Chrome fix backspace as back button</title><content type='html'>I like to be able to go back when browsing without using my mouse. I have found an extension which fixes the backspace so that it now goes back.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Install the extension:&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;http://www.chromeextensions.org/appearance-functioning/backspace-as-back-for-linux-2/&quot;&gt;http://www.chromeextensions.org/appearance-functioning/backspace-as-back-for-linux-2/&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Then click the radio button:&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif; font-size: medium; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; &quot;&gt;Activate Backspace for navigation in history object&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif; font-size: medium; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; &quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif; font-size: medium; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; &quot;&gt;And hit save. That is all.&lt;/span&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://opencomputing.blogspot.com/feeds/3435410201511844461/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3034230779454603134/3435410201511844461' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/3435410201511844461'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/3435410201511844461'/><link rel='alternate' type='text/html' href='http://opencomputing.blogspot.com/2010/07/linux-chrome-fix-backspace-as-back.html' title='Linux Chrome fix backspace as back button'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/15703804696957522260</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3034230779454603134.post-8081650366489284138</id><published>2010-07-12T10:59:00.001-07:00</published><updated>2010-07-12T12:07:22.718-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="apt-cacher-ng"/><category scheme="http://www.blogger.com/atom/ns#" term="Linux"/><category scheme="http://www.blogger.com/atom/ns#" term="Server"/><category scheme="http://www.blogger.com/atom/ns#" term="Ubuntu"/><title type='text'>Speeding up your Updates with Ubuntu and APT Cacher NG</title><content type='html'>If you are in a building with more than one computer running Ubuntu, you may have wondered why everyone has to download updates separately.  The answer is, they don&#39;t.  Here&#39;s how to accomplish it with a tool called apt-cacher-ng.&lt;div&gt;&lt;br /&gt;&lt;div&gt;apt-cacher-ng is a fork of a project called apt-cacher, which in turn is an alternative to apt-proxy which is poorly maintained and upon my testing, was unreliable.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Setting up the APT Cacher Server&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Begin by installing apt-cacher-ng from Synaptic Package Manager, or from the Terminal with the following command:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;sudo apt-get install apt-cacher-ng&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;By default, the version of apt-cacher included with Ubuntu does not currently include security updates.  We can easily add the security updates in, however, by following these steps:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As root, create a new file called /etc/apt-cacher-ng/ubuntu_security&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;sudo nano /etc/apt-cacher-ng/ubuntu-security&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This file will be a list of mirrors from which the updates may be downloaded.  We only want to insert a single line, the location of Ubuntu&#39;s official security updates server:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;blockquote&gt;http://security.ubuntu.com/ubuntu&lt;/blockquote&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Save and close the file.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Next, edit the file /etc/apt-cacher-ng/acng.conf&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;sudo nano /etc/apt-cacher-ng/acng.conf&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;While we&#39;re here, you will see a couple of lines like this:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;# Set to 9999 to emulate apt-proxy&lt;/div&gt;&lt;div&gt;Port:3142&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I recommend that you follow the instructions and set the port to 9999 to emulate apt-proxy. Not only will this make your server compatible with systems expecting an apt-proxy server, but it will also make the port number easier for you to remember.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Next, look for this section:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;# Repository remapping. See manual for details.&lt;/div&gt;&lt;div&gt;# In this example, backends file is generated during package installation.&lt;/div&gt;&lt;div&gt;Remap-debrep: file:deb_mirror*.gz /debian ; file:backends_debian&lt;/div&gt;&lt;div&gt;Remap-uburep: file:ubuntu_mirrors /ubuntu ; file:backends_ubuntu&lt;/div&gt;&lt;div&gt;Remap-debvol: file:debvol_mirror*.gz /debian-volatile ; file:backends_debvol&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We&#39;re going to add one more line at the end of this section to describe the Ubuntu Security repository that we are adding (make sure the following all goes on one line):&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;blockquote&gt;Remap-ubusec: file:ubuntu_security /ubuntu-security ; http://security.ubuntu.com/ubuntu&lt;/blockquote&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now, save changes to this file and restart the apt-cacher-ng service.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;sudo service apt-cacher-ng restart&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If all went well, the server is now working.  No you may proceed to setting up the clients.  &lt;i&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;color:#CC6600;&quot;&gt;I strongly recommend making the server into a client of its own apt-cacher, as there is no reason for that system to download the updates from the Internet twice.&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: normal; &quot;&gt;&lt;b&gt;Setting up an APT Cacher Client&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: normal; &quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;The basic idea of how to set up a client is to change all the lines in /etc/apt/sources.list to point at the local apt-cacher-ng server instead of at the internet servers.  I recommend taking an additional step first so that you can easily flex between different servers.  We will create a hostname alias called &quot;apt-cacher&quot; that points at your apt-cacher-ng server so you can simply re-point the hostname whenever you want to switch servers.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;sudo nano /etc/hosts&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We will add our own entry just after these two lines:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;127.0.0.1    localhost&lt;/div&gt;&lt;div&gt;127.0.1.1     your-computer-name&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If the apt-cacher-ng server is running on the same computer which you are setting up as a client, its IP address will be 127.0.0.1, otherwise, you need to find (or set) the static LAN IP address for your server.  I will assume it is 192.168.1.10 in this example because that&#39;s what it is in our building here at CCC.  The line you will add will look like this:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;192.168.1.10    apt-cacher&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Save and close the hosts file.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now we will replace the entries in the sources.list to point at the cacher:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;sudo nano /etc/apt/sources.list&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The easiest way to handle this will be a search and replace.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;First, replace every instance of &quot;us.archive.ubuntu.com&quot; with &quot;apt-cacher:9999&quot; (no quotes on either)  If you are using nano, this is accomplished by pressing Ctrl+W, Ctrl+R, then entering the search string and pressing enter, then entering the string to replace it with, and pressing enter again, then when prompted, press &quot;A&quot; for all.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Next, replace every instance of &quot;security.ubuntu.com/ubuntu&quot; with &quot;apt-cacher:9999/ubuntu-security&quot; (no quotes on these, either.)  If you are using nano, use the same steps as given above.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(In this example, we won&#39;t be handling the partner repository or any third party repositories which you might have installed.)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Save and close your sources.list.   Your final sources.list if you are running Ubuntu 10.04 Lucid Lynx will look something like this:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;# deb cdrom:[Ubuntu 10.04 LTS _Lucid Lynx_ - Release i386 (20100429)]/ lucid main restricted&lt;/div&gt;&lt;div&gt;# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to&lt;/div&gt;&lt;div&gt;# newer versions of the distribution.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;deb http://apt-cacher:9999/ubuntu/ lucid main restricted&lt;/div&gt;&lt;div&gt;deb-src http://apt-cacher:9999/ubuntu/ lucid main restricted&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;## Major bug fix updates produced after the final release of the&lt;/div&gt;&lt;div&gt;## distribution.&lt;/div&gt;&lt;div&gt;deb http://apt-cacher:9999/ubuntu/ lucid-updates main restricted&lt;/div&gt;&lt;div&gt;deb-src http://apt-cacher:9999/ubuntu/ lucid-updates main restricted&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu&lt;/div&gt;&lt;div&gt;## team. Also, please note that software in universe WILL NOT receive any&lt;/div&gt;&lt;div&gt;## review or updates from the Ubuntu security team.&lt;/div&gt;&lt;div&gt;deb http://apt-cacher:9999/ubuntu/ lucid universe&lt;/div&gt;&lt;div&gt;deb-src http://apt-cacher:9999/ubuntu/ lucid universe&lt;/div&gt;&lt;div&gt;deb http://apt-cacher:9999/ubuntu/ lucid-updates universe&lt;/div&gt;&lt;div&gt;deb-src http://apt-cacher:9999/ubuntu/ lucid-updates universe&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu &lt;/div&gt;&lt;div&gt;## team, and may not be under a free licence. Please satisfy yourself as to &lt;/div&gt;&lt;div&gt;## your rights to use the software. Also, please note that software in &lt;/div&gt;&lt;div&gt;## multiverse WILL NOT receive any review or updates from the Ubuntu&lt;/div&gt;&lt;div&gt;## security team.&lt;/div&gt;&lt;div&gt;deb http://apt-cacher:9999/ubuntu/ lucid multiverse&lt;/div&gt;&lt;div&gt;deb-src http://apt-cacher:9999/ubuntu/ lucid multiverse&lt;/div&gt;&lt;div&gt;deb http://apt-cacher:9999/ubuntu/ lucid-updates multiverse&lt;/div&gt;&lt;div&gt;deb-src http://apt-cacher:9999/ubuntu/ lucid-updates multiverse&lt;/div&gt;&lt;div&gt;&lt;div&gt;## Uncomment the following two lines to add software from Canonical&#39;s&lt;/div&gt;&lt;div&gt;## &#39;partner&#39; repository.&lt;/div&gt;&lt;div&gt;## This software is not part of Ubuntu, but is offered by Canonical and the&lt;/div&gt;&lt;div&gt;## respective vendors as a service to Ubuntu users.&lt;/div&gt;&lt;div&gt;# deb http://archive.canonical.com/ubuntu lucid partner&lt;/div&gt;&lt;div&gt;# deb-src http://archive.canonical.com/ubuntu lucid partner&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;deb http://apt-cacher:9999/ubuntu-security lucid-security main restricted&lt;/div&gt;&lt;div&gt;deb-src http://apt-cacher:9999/ubuntu-security lucid-security main restricted&lt;/div&gt;&lt;div&gt;deb http://apt-cacher:9999/ubuntu-security lucid-security universe&lt;/div&gt;&lt;div&gt;deb-src http://apt-cacher:9999/ubuntu-security lucid-security universe&lt;/div&gt;&lt;div&gt;deb http://apt-cacher:9999/ubuntu-security lucid-security multiverse&lt;/div&gt;&lt;div&gt;deb-src http://apt-cacher:9999/ubuntu-security lucid-security multiverse&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;After you have have saved your sources.list, run the following command:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;sudo apt-get update&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This will download the package index from the apt-cacher server.  You should see lots of &quot;Get&quot; &quot;Hit&quot; and &quot;Ign&quot; lines coming from http://apt-cacher (and other lines for partner and 3rd party servers) if everything is working right.  Remember that the update command will still be running at the normal speed because it has to fetch the indexes from the Internet every time to determine if the cache needs to download any new files.  Also, the first time a given package is downloaded will still be at normal speed, as well.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To try it out, run sudo apt-get upgrade to download any available updated packages, or just install a new package of your choice.   The apt-cacher should be functioning from the command line tools, from Update Manager, and from Synaptic Package Manager.  Just remember not to adjust your repository checkboxes under the &quot;Ubunto Software&quot; tab in Synaptic&#39;s Settings:Repositories menu, because it no longer knows which repositories we&#39;ve enabled (they are visible, however, on the &quot;Other Software&quot; tab, and you may adjust them there.)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;How To Switch Locations&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you are using a laptop or netbook, you may appreciate the ability to quickly switch from one loication to another, and even to be able to download updates when you are not near your regular apt-cacher-ng server at all.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I have come up with a strategy to accomplish this.  All you need to do (and you must do this while your current apt-cacher-ng server is accessible), is repeat the above steps for &quot;&lt;b&gt;Setting up the APT Cacher Server&lt;/b&gt;&quot; on your local machine, then you can simply edit your /etc/hosts file and change the entry for apt-cacher to point at 127.0.0.1 when you&#39;re on the run, or back to your server&#39;s IP when you are at home or work.  Making that one line change will allow you to continue using all of the APT tools smoothly.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There is one disadvantage, especially for netbooks or devices with smaller hard drives, and that is that you will be storing two different caches on your hard drive for files which were downloaded while &quot;on the go&quot;, one in the apt-cacher folder, and the other in the system&#39;s regular apt system cache under /var/cache/apt&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Because of this, you may want to occasionally issue the command:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;sudo apt-get clean&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This will clean the system cache of installed packages out of /var/cache/apt, saving some disk space.  This is generally a good idea to do on any Ubuntu system with disk space limitations, whether or not you are running apt-cacher-ng.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Also, if you ever need to delete the files under /var/cache/apt-cacher-ng, you may safely do so, and apt-cacher will download them again the next time they are needed.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Congratulations on successfully setting up apt-cacher-ng -- I hope!  It has saved hours and hours of downloading here in our classroom.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://opencomputing.blogspot.com/feeds/8081650366489284138/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3034230779454603134/8081650366489284138' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/8081650366489284138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/8081650366489284138'/><link rel='alternate' type='text/html' href='http://opencomputing.blogspot.com/2010/07/speeding-up-your-updates-with-ubuntu.html' title='Speeding up your Updates with Ubuntu and APT Cacher NG'/><author><name>Jeff Day</name><uri>http://www.blogger.com/profile/11675035864869123800</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3034230779454603134.post-253729807304692196</id><published>2010-07-12T08:37:00.000-07:00</published><updated>2010-07-12T12:15:41.465-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="apt-cacher-ng"/><category scheme="http://www.blogger.com/atom/ns#" term="perl"/><category scheme="http://www.blogger.com/atom/ns#" term="script"/><title type='text'>Apt-Cacher-NG Client side perl script</title><content type='html'>First off a short explanation of Apt-Cacher-NG (acng) is in order. Based on a similar project simply called Apt-Cacher, acng is a download proxy for software packages, primarily for Debian/Ubuntu clients. (http://freshmeat.net/projects/acng/)&lt;br /&gt; The way it works is the server at Community Computer Center, goes out to the official package and release servers and downloads the latest updates, that way when I, or anyone else wants to download updates, our computers simply have to download from the CCC server over the lan, which makes the download about ten times faster.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;(Editorial Note:  If you haven&#39;t set up apt-cacher-ng yet, &lt;a href=&quot;http://opencomputing.blogspot.com/2010/07/speeding-up-your-updates-with-ubuntu.html&quot;&gt;follow this post first&lt;/a&gt;.)&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The only downside is whenever I want to download the updates and I&#39;m not at CCC, I have to go and edit the hosts file in /etc, so I wrote a perl script to cut down on the steps.&lt;br /&gt;&lt;br /&gt;Copy the code into a text file and save it as a .pl, then to use, type sudo perl yourfile.pl.&lt;br /&gt;While this is not the most elegant solution, it was my first attempt at using perl, enjoy.&lt;br /&gt;&lt;br /&gt;#!usr/bin/perl -w&lt;br /&gt;#script by @robots_unix&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;print &quot;Are you at CCC?&quot;;&lt;br /&gt;$name = &lt;stdin&gt;;&lt;br /&gt;chomp ($name);&lt;br /&gt;if ($name eq &quot;yes&quot;){        #When I&#39;m at CCC&lt;br /&gt;open(INFILE, &#39;&gt;/etc/hosts&#39;);&lt;br /&gt;print INFILE &quot;127.0.0.1 localhost&lt;br /&gt;127.0.1.1 uname&lt;br /&gt;apt-cacher_ip apt-cacher&lt;br /&gt;#127.0.0.1 apt-cacher&lt;br /&gt;apt-cacher_ip server name&lt;br /&gt;# The following lines are desirable for IPv6 capable hosts&lt;br /&gt;::1     localhost ip6-localhost ip6-loopback&lt;br /&gt;fe00::0 ip6-localnet&lt;br /&gt;ff00::0 ip6-mcastprefix&lt;br /&gt;ff02::1 ip6-allnodes&lt;br /&gt;ff02::2 ip6-allrouters&lt;br /&gt;ff02::3 ip6-allhosts\n&quot;;&lt;br /&gt;close(INFILE);&lt;br /&gt;}else{            #When I&#39;m not at CCC&lt;br /&gt;open(INFILE, &#39;&gt;/etc/hosts&#39;);&lt;br /&gt;print INFILE &quot;127.0.0.1 localhost&lt;br /&gt;127.0.1.1 uname&lt;br /&gt;#apt-cacher_ip apt-cacher&lt;br /&gt;127.0.0.1 apt-cacher&lt;br /&gt;apt-cacher_ip    servername&lt;br /&gt;# The following lines are desirable for IPv6 capable hosts&lt;br /&gt;::1     localhost ip6-localhost ip6-loopback&lt;br /&gt;fe00::0 ip6-localnet&lt;br /&gt;ff00::0 ip6-mcastprefix&lt;br /&gt;ff02::1 ip6-allnodes&lt;br /&gt;ff02::2 ip6-allrouters&lt;br /&gt;ff02::3 ip6-allhosts\n&quot;;&lt;br /&gt;close(INFILE);&lt;br /&gt;}&lt;br /&gt;}&lt;/stdin&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://opencomputing.blogspot.com/feeds/253729807304692196/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3034230779454603134/253729807304692196' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/253729807304692196'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/253729807304692196'/><link rel='alternate' type='text/html' href='http://opencomputing.blogspot.com/2010/07/apt-cacher-ng-client-side-perl-script.html' title='Apt-Cacher-NG Client side perl script'/><author><name>robots_unix</name><uri>http://www.blogger.com/profile/16991921542825149149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3034230779454603134.post-4509527988334153885</id><published>2010-07-10T17:38:00.000-07:00</published><updated>2010-07-10T17:52:23.698-07:00</updated><title type='text'>Mutt and gmail</title><content type='html'>I think gmail is cool but it could be quicker to use. Right now it is slow and if you use the html version it lacks shortcuts. I think the cool way to go is to install mutt and use it to read your mail from the terminal. This article talks about some of the reasons why it is nicer and some methods to use to make mutt notify you about new mail. And how you might be able to use gmail contacts inside mutt. I think it would be cool to use googlecl to grab a contact while in mutt.&lt;div&gt;install mutt with gmail through IMAP&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;http://crunchbanglinux.org/wiki/howto/howto_setup_mutt_with_gmail_imap&quot;&gt;http://crunchbanglinux.org/wiki/howto/howto_setup_mutt_with_gmail_imap&lt;/a&gt;&lt;/div&gt;&lt;div&gt;I like the fact you can make your own shortcuts in mutt that go to certain folders that you have set up like gmail has.&lt;/div&gt;&lt;div&gt;the following will make it so you go to the inbox when typeing gi and others.&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; font-size: 12px; white-space: pre; &quot;&gt;bind editor &lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; font-size: 12px; white-space: pre; &quot;&gt;&lt;space&gt; noop &lt;/space&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; font-size: 12px; white-space: pre; &quot;&gt;&lt;space&gt;macro index gi &quot;&lt;change-folder&gt;=INBOX&lt;enter&gt;&quot; &quot;Go to inbox&quot; &lt;/enter&gt;&lt;/change-folder&gt;&lt;/space&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; font-size: 12px; white-space: pre; &quot;&gt;&lt;space&gt;&lt;change-folder&gt;&lt;enter&gt;macro index ga &quot;&lt;change-folder&gt;=[&lt;span class=&quot;search_hit&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; color: rgb(51, 51, 51); background-color: rgb(255, 255, 153); &quot;&gt;Gmail&lt;/span&gt;]/All Mail&lt;enter&gt;&quot; &quot;Go to all mail&quot; &lt;/enter&gt;&lt;/change-folder&gt;&lt;/enter&gt;&lt;/change-folder&gt;&lt;/space&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; font-size: 12px; white-space: pre; &quot;&gt;&lt;space&gt;&lt;change-folder&gt;&lt;enter&gt;&lt;change-folder&gt;&lt;enter&gt;macro index gs &quot;&lt;change-folder&gt;=[&lt;span class=&quot;search_hit&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; color: rgb(51, 51, 51); background-color: rgb(255, 255, 153); &quot;&gt;Gmail&lt;/span&gt;]/Sent Mail&lt;enter&gt;&quot; &quot;Go to Sent Mail&quot; &lt;/enter&gt;&lt;/change-folder&gt;&lt;/enter&gt;&lt;/change-folder&gt;&lt;/enter&gt;&lt;/change-folder&gt;&lt;/space&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; font-size: 12px; white-space: pre; &quot;&gt;&lt;space&gt;&lt;change-folder&gt;&lt;enter&gt;&lt;change-folder&gt;&lt;enter&gt;&lt;change-folder&gt;&lt;enter&gt;macro index gd &quot;&lt;change-folder&gt;=[&lt;span class=&quot;search_hit&quot; style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; color: rgb(51, 51, 51); background-color: rgb(255, 255, 153); &quot;&gt;Gmail&lt;/span&gt;]/Drafts&lt;enter&gt;&quot; &quot;Go to drafts&quot;&lt;/enter&gt;&lt;/change-folder&gt;&lt;/enter&gt;&lt;/change-folder&gt;&lt;/enter&gt;&lt;/change-folder&gt;&lt;/enter&gt;&lt;/change-folder&gt;&lt;/space&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; font-size: 12px; white-space: pre; &quot;&gt;&lt;space&gt;&lt;change-folder&gt;&lt;enter&gt;&lt;change-folder&gt;&lt;enter&gt;&lt;change-folder&gt;&lt;enter&gt;&lt;change-folder&gt;&lt;enter&gt;&lt;br /&gt;&lt;/enter&gt;&lt;/change-folder&gt;&lt;/enter&gt;&lt;/change-folder&gt;&lt;/enter&gt;&lt;/change-folder&gt;&lt;/enter&gt;&lt;/change-folder&gt;&lt;/space&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; font-size: 12px; white-space: pre; &quot;&gt;&lt;space&gt;&lt;change-folder&gt;&lt;enter&gt;&lt;change-folder&gt;&lt;enter&gt;&lt;change-folder&gt;&lt;enter&gt;&lt;change-folder&gt;&lt;enter&gt;all the rest of the options are listed in the link above. I like the fact that you can change the editor for mutt too.&lt;/enter&gt;&lt;/change-folder&gt;&lt;/enter&gt;&lt;/change-folder&gt;&lt;/enter&gt;&lt;/change-folder&gt;&lt;/enter&gt;&lt;/change-folder&gt;&lt;/space&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; font-size: 12px; white-space: pre; &quot;&gt;&lt;space&gt;&lt;change-folder&gt;&lt;enter&gt;&lt;change-folder&gt;&lt;enter&gt;&lt;change-folder&gt;&lt;enter&gt;&lt;change-folder&gt;&lt;enter&gt;and the wiki might be helpful&lt;/enter&gt;&lt;/change-folder&gt;&lt;/enter&gt;&lt;/change-folder&gt;&lt;/enter&gt;&lt;/change-folder&gt;&lt;/enter&gt;&lt;/change-folder&gt;&lt;/space&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; font-size: 12px; white-space: pre; &quot;&gt;&lt;space&gt;&lt;change-folder&gt;&lt;enter&gt;&lt;change-folder&gt;&lt;enter&gt;&lt;change-folder&gt;&lt;enter&gt;&lt;change-folder&gt;&lt;enter&gt;&lt;a href=&quot;http://wiki.mutt.org/index.cgi?MuttGuide&quot;&gt;http://wiki.mutt.org/index.cgi?MuttGuide&lt;/a&gt;&lt;/enter&gt;&lt;/change-folder&gt;&lt;/enter&gt;&lt;/change-folder&gt;&lt;/enter&gt;&lt;/change-folder&gt;&lt;/enter&gt;&lt;/change-folder&gt;&lt;/space&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; font-size: 12px; white-space: pre; &quot;&gt;&lt;space&gt;&lt;change-folder&gt;&lt;enter&gt;&lt;change-folder&gt;&lt;enter&gt;&lt;change-folder&gt;&lt;enter&gt;&lt;change-folder&gt;if anyone tries to install gmail or another client with mutt then post here and let us know how it went.&lt;/change-folder&gt;&lt;/enter&gt;&lt;/change-folder&gt;&lt;/enter&gt;&lt;/change-folder&gt;&lt;/enter&gt;&lt;/change-folder&gt;&lt;/space&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; font-size: 12px; white-space: pre; &quot;&gt;&lt;space&gt;&lt;change-folder&gt;&lt;enter&gt;&lt;change-folder&gt;&lt;enter&gt;&lt;change-folder&gt;&lt;enter&gt;&lt;change-folder&gt;&lt;enter&gt;&lt;br /&gt;&lt;/enter&gt;&lt;/change-folder&gt;&lt;/enter&gt;&lt;/change-folder&gt;&lt;/enter&gt;&lt;/change-folder&gt;&lt;/enter&gt;&lt;/change-folder&gt;&lt;/space&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://opencomputing.blogspot.com/feeds/4509527988334153885/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3034230779454603134/4509527988334153885' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/4509527988334153885'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/4509527988334153885'/><link rel='alternate' type='text/html' href='http://opencomputing.blogspot.com/2010/07/mutt-and-gmail.html' title='Mutt and gmail'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/15703804696957522260</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3034230779454603134.post-2669376339712292185</id><published>2010-07-09T22:13:00.000-07:00</published><updated>2010-07-09T22:23:42.854-07:00</updated><title type='text'>Too many messages in mutt</title><content type='html'>I have learned something useful for anyone that uses mutt to mail from the terminal. I can be used to get messages from cron that runs periodically. Cron can run as much as once a minute. My cron has been sending me the message &quot;don&#39;t update&quot; for 6 months. It has caused about 40MB or 29000 messages to pile up in mutt. Now I have fixed the problem so it won&#39;t echo out for success. It should only tell me about failures not successes since they don&#39;t happen very often.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Usually you can delete hundreds of messages by holding down the delete button but since I had so many messages I had to learn how to delete bult amounts of mutt mail all at once. Here is how to do it:&lt;/div&gt;&lt;div&gt;type D&lt;/div&gt;&lt;div&gt;This will tell mutt to delete using a certain pattern. I tried using &quot;update&quot; but it didn&#39;t work so I figured out what will tag all of the messages at once.&lt;/div&gt;&lt;div&gt;type .&lt;/div&gt;&lt;div&gt;Thats right, a period.&lt;/div&gt;&lt;div&gt;Then type $ to have mutt ask if you want to purge 29000 messages. It takes a second and its done.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://opencomputing.blogspot.com/feeds/2669376339712292185/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3034230779454603134/2669376339712292185' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/2669376339712292185'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/2669376339712292185'/><link rel='alternate' type='text/html' href='http://opencomputing.blogspot.com/2010/07/too-many-messages-in-mutt.html' title='Too many messages in mutt'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/15703804696957522260</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3034230779454603134.post-2279789255424543885</id><published>2010-06-20T14:15:00.001-07:00</published><updated>2010-06-22T18:29:16.064-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Google"/><category scheme="http://www.blogger.com/atom/ns#" term="Linux"/><category scheme="http://www.blogger.com/atom/ns#" term="Terminal"/><title type='text'>Using Exclamation marks in Google Command Line</title><content type='html'>As I found out in my previous post, you can&#39;t just add an ! into your post without getting a bash error.  You can sort of escape them with a /, but then they both show up (like this: /!), which is silly.  You can get around this by first, making sure that you use single quotes around your post and then adding a $ right before the quote that begins your post:&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: monospace; padding: 2px 3px; background: #beb;&quot;&gt;google blogger --title &#39;this is a blog post&#39; $&#39;this is an exciting blog!&#39;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://opencomputing.blogspot.com/feeds/2279789255424543885/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3034230779454603134/2279789255424543885' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/2279789255424543885'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3034230779454603134/posts/default/2279789255424543885'/><link rel='alternate' type='text/html' href='http://opencomputing.blogspot.com/2010/06/using-exclamation-marks-in-google_8138.html' title='Using Exclamation marks in Google Command Line'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>