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

<channel>
	<title>ColonelPanic &#187; tutorial</title>
	<atom:link href="http://colonelpanic.net/tag/tutorial/feed/" rel="self" type="application/rss+xml" />
	<link>http://colonelpanic.net</link>
	<description>Dumping our corps so you don&#039;t have to</description>
	<lastBuildDate>Mon, 30 Jan 2012 17:50:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>UPDATED: Terminal Nirvana with TotalTerminal (Snow Leopard, Lion)</title>
		<link>http://colonelpanic.net/2011/08/updated-terminal-nirvana-with-totalterminal-snow-leopard-lion/</link>
		<comments>http://colonelpanic.net/2011/08/updated-terminal-nirvana-with-totalterminal-snow-leopard-lion/#comments</comments>
		<pubDate>Tue, 30 Aug 2011 05:08:30 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[General Development]]></category>
		<category><![CDATA[Systems Administration]]></category>
		<category><![CDATA[terminal]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[visor]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=537</guid>
		<description><![CDATA[It&#8217;s been a while since I wrote up how I achieved Terminal Nirvana on Snow Leopard using SIMBL and Visor. Since then, some things have changed: TotalTerminal has replaced Visor Mac OS X Lion has been released TotalTerminal changes up the way it launches Terminal &#8212; instead of being automatically injected via SIMBL, it manually [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a while since I wrote up how I achieved <a title="Terminal Nirvana on Snow Leopard with SIMBL + Visor" href="http://colonelpanic.net/2010/07/terminal-nirvana-on-snow-leopard-with-simbl-visor/">Terminal Nirvana on Snow Leopard using SIMBL and Visor</a>. Since then, some things have changed:</p>
<ul>
<li><a href="http://totalterminal.binaryage.com/">TotalTerminal</a> has replaced Visor</li>
<li>Mac OS X Lion has been released</li>
</ul>
<p>TotalTerminal changes up the way it launches Terminal &#8212; instead of being automatically injected via SIMBL, it manually injects the plugin into Terminal.app. Well, I wasn&#8217;t going to let this deter me.</p>
<p>Getting back to Nirvana after installing TotalTerminal is not all that bad. Most of the steps haven&#8217;t changed from my original post so I will only go into detail about the new steps here. Briefly, here are the steps I followed.</p>
<ol>
<li>Remove TerminalColours.bundle SIMBL plugin &#8212; per the <a href="http://totalterminal.binaryage.com/#faq">TotalTerminal FAQ</a>, it injects its own version and having TerminalColours.bundle installed creates a conflict. (~/Library/Application\ Support/SIMBL/Plugins)</li>
<li>Fix the Home / End keys (see original post)</li>
<li>Copy Terminal.app to VisorTerminal.app (see original post)</li>
<li>Install TotalTerminal</li>
<li>Modify TotalTerminal to use VisorTerminal.app instead of Terminal.app</li>
</ol>
<h3>That&#8217;s right, there&#8217;s really only one thing to change, and it&#8217;s very simple</h3>
<p>TotalTerminal.app has a simple, compiled AppleScript which launches Terminal and injects itself. The compiled file is located at /Applications/TotalTerminal.app/Contents/Resources/Scripts/main.scpt. But, we don&#8217;t want the compiled binary version, we want the original so we can make it use VisorTerminal.app.</p>
<p>Fortunately the <a href="https://raw.github.com/binaryage/totalterminal-installer/master/TotalTerminal.app/Contents/Resources/Scripts/main.applescript">uncompiled source file</a> is available in the <a href="https://github.com/binaryage/totalterminal-installer">TotalTerminal repo on Github</a>.</p>
<p>Only one change is necessary.</p>
<div class="wp_syntax">
<div class="code">
<pre class="diff" style="font-family:monospace;"><span style="color: #888822;">--- TotalTerminal.app/Contents/Resources/Scripts/main.applescript</span>
<span style="color: #888822;">+++ TotalTerminal.app/Contents/Resources/Scripts/main.applescript</span>
<span style="color: #440088;">@@ -1,4 +1,4 @@</span>
<span style="color: #991111;">-tell application &quot;Terminal&quot;</span>
<span style="color: #00b000;">+tell application &quot;VisorTerminal&quot;</span>
        delay <span style="">1</span> -- this delay is important to prevent random &quot;Connection is Invalid -<span style="">609</span>&quot; AppleScript errors
        try
                event BATTinit</pre>
</div>
</div>
<p>Once that is done, you just need to compile the script and replace the one that shipped with TotalTerminal.</p>
<div class="wp_syntax">
<div class="code">
<pre class="bash" style="font-family:monospace;">$ osacompile <span style="color: #660033;">-o</span> main.scpt main.applescript
$ <span style="color: #c20cb9; font-weight: bold;">mv</span> main.scpt <span style="color: #000000; font-weight: bold;">/</span>Applications<span style="color: #000000; font-weight: bold;">/</span>TotalTerminal.app<span style="color: #000000; font-weight: bold;">/</span>Contents<span style="color: #000000; font-weight: bold;">/</span>Resources<span style="color: #000000; font-weight: bold;">/</span>Scripts</pre>
</div>
</div>
<h3>That&#8217;s it.</h3>
<p>You should be good to go. Put TotalTerminal.app into your user startup applications if you wish (I do), or launch it manually by launching TotalTerminal.app.</p>
<p>Enjoy the restoration of terminal nirvana.</p>
<h3>For the lazy&#8230;</h3>
<p>My modified and compiled main.applescript is <a href="http://colonelpanic.net/wp-content/uploads/2011/08/modified-applescript-compiled.zip">available for download</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2011/08/updated-terminal-nirvana-with-totalterminal-snow-leopard-lion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Terminal Nirvana on Snow Leopard with SIMBL + Visor</title>
		<link>http://colonelpanic.net/2010/07/terminal-nirvana-on-snow-leopard-with-simbl-visor/</link>
		<comments>http://colonelpanic.net/2010/07/terminal-nirvana-on-snow-leopard-with-simbl-visor/#comments</comments>
		<pubDate>Wed, 21 Jul 2010 15:09:24 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[General Development]]></category>
		<category><![CDATA[Systems Administration]]></category>
		<category><![CDATA[end]]></category>
		<category><![CDATA[home]]></category>
		<category><![CDATA[screen]]></category>
		<category><![CDATA[simbl]]></category>
		<category><![CDATA[terminal]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[vim]]></category>
		<category><![CDATA[visor]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=255</guid>
		<description><![CDATA[Note 1: The method described here should also work in Mac OS X Leopard or Tiger, just get the appropriate versions of SIMBL / Visor. Note 2: If you don&#8217;t want everything on my bullet list, just follow the steps appropriate for what you want to accomplish. Note 3: I have provided .patch files, etc. [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p><em><strong>Note 1</strong>: The method described here should also work in Mac OS X Leopard or Tiger, just get the appropriate versions of SIMBL / Visor.</em><br />
<em><strong>Note 2</strong>: If you don&#8217;t want everything on my bullet list, just follow the steps appropriate for what you want to accomplish.</em><br />
<em><strong>Note 3</strong>: I have provided .patch files, etc. at the bottom of the post for those who, like me, are a bit lazy.</em></p></blockquote>
<h2>What is Terminal Nirvana?</h2>
<p>As a developer, Terminal is one of my best friends. Maybe you can relate. I have constantly been in search of the ultimate Terminal configuration, and it has ever eluded me&#8230; until now.</p>
<p>But what is Terminal Nirvana? Here are my criteria:</p>
<ol>
<li><strong>I want the Home / End keys to move the cursor to the front / end of the line. </strong>I grew up on Windows, and I like the keys to function this way. To me, it just makes sense. Unfortunately, <a title="KeyFixer" href="http://www.starryhope.com/tech/apple/2006/keyfixer/">KeyFixer</a> doesn&#8217;t work in Terminal (but I highly recommend it for changing the behavior in most other apps!).</li>
<li><strong>I don&#8217;t want Home / End to behave differently when I am in a <a title="GNU Screen" href="http://en.wikipedia.org/wiki/Gnu_screen">screen</a> session.</strong> I use screen all the time, and Home / End need to behave consistently.</li>
<li><strong>I don&#8217;t want Home / End to do unexpected things in </strong><strong><a href="http://en.wikipedia.org/wiki/Vim_(text_editor)">VIM</a> &#8211; ever</strong><strong>.</strong> Pressing Home / End in VIM should, at the very least, not do weird things like delete lines, whether I am in a screen session or not.</li>
<li><strong>I want my terminal window available at all times.</strong> With as much as I use the terminal, opening Terminal.app all the time feels wasteful. There should be a better way. This is where <a title="SIMBL" href="http://www.culater.net/software/SIMBL/SIMBL.php">SIMBL</a> and <a title="Visor" href="http://visor.binaryage.com/">Visor</a> come in.</li>
<li><strong>I don&#8217;t want it to show up in the Dock, or in my Command + Tab list.</strong> As useful as Terminal is, there are a lot of other useful applications around, and I use a lot of them. Since I always want Terminal open anyway, it is annoying to constantly avoid / ignore / tab over it when I am using Command + Tab to switch to another running application. Oh, and it should stay away from my Dock, too.</li>
<li><strong>I want good, configurable colors in my shell.</strong> Fortunately, Visor takes care of this one by including <a title="Terminal Colors in Leopard / Snow Leopard" href="http://ciaranwal.sh/2007/11/01/customising-colours-in-leopard-terminal">TerminalColours</a> as part of the package, so you get this one &#8220;for free.&#8221;</li>
</ol>
<p>Sound like a tall order? It took me a few hours crawling around the web and experimenting to come up with a good solution, but I managed it in the end. Hopefully my experience can help save a few people some time in the future.</p>
<p>This is how I did it.<br />
<span id="more-255"></span></p>
<h2>First things first</h2>
<p>Before you go any further, make sure you have installed <a title="SIMBL" href="http://www.culater.net/software/SIMBL/SIMBL.php">SIMBL</a> and <a title="Visor" href="http://visor.binaryage.com/">Visor</a>. The latest versions work great in Snow Leopard with a 64-bit Terminal.app, so knock yourself out.</p>
<h2>Home / End keys</h2>
<p>To change the Home / End keys in Terminal.app, you are going to need to go to Terminal -&gt; Preferences -&gt; [Settings] -&gt; [Keyboard]. Remember, settings are profile-specific, so you will need to make the changes to any profiles you care about. (<em>Note: Visor uses the &#8220;Visor&#8221; profile, regardless of what you set as your default profile. What I do is rename the automatically-created &#8220;Visor&#8221; profile, configure my default profile, and then duplicate it with the name &#8220;Visor&#8221;.</em>)</p>
<p>The first thing I tried was changing the keybindings to &#8220;\001&#8243; and &#8220;\005&#8243; per the instructions I found on <a href="http://www.rickycampbell.com/fix-osx-terminal-pgup-pgdn-home-and-end/">Ricky Campbell&#8217;s blog</a>. This seemed to make sense; CTRL+A and CTRL+E move the cursor to the front / end of the line in Terminal. And I thought it was working perfectly, for a few glorious moments&#8230;</p>
<p>Unfortunately, CTRL+A is also the key combination to start a command in screen. So when I launched screen, suddenly my home key didn&#8217;t work anymore, and I randomly started sending screen commands when I used it.</p>
<p>I also tried using a ~/.inputrc file and the keybindings &#8220;\033[1~&#8221; and &#8220;\033[4~&#8221; as discussed on <a href="http://fplanque.com/dev/mac/mac-osx-terminal-page-up-down-home-end-of-line">two</a> <a href="http://linuxart.com/log/archives/2005/10/13/super-useful-inputrc/">blogs</a> I stumbled across while looking for an alternate solution. Now, I really thought I had the problem licked. Except, Home / End did weird things in VIM running within a screen session, and the necessity of using an additional .inputrc file was just a bit of a bummer.</p>
<p>Turns out Shift + Home and Shift + End  already did what I wanted, so the simplest solution of all is to just copy those keybindings already present in the Terminal settings. For good measure, I copied the &#8220;shift page up&#8221; and &#8220;shift page down&#8221; bindings to &#8220;page up&#8221; and &#8220;page down.&#8221; (<em>Note: you can either copy-paste the existing values, or hit ESC to get the \033 value and then type the other characters manually.</em>)</p>
<h3>Terminal key bindings:</h3>
<ul>
<li>home
<ul>
<li>Value: \033[H</li>
</ul>
</li>
<li>end
<ul>
<li>Value: \033[F</li>
</ul>
</li>
<li>page up
<ul>
<li>Value: \033[5~</li>
</ul>
</li>
<li>page down
<ul>
<li>Value: \033[6~</li>
</ul>
</li>
</ul>
<h2>Fixing VIM in screen</h2>
<p>Okay, almost there with the keybindings. If you run VIM inside a screen session, you will notice that Home deletes the current line, and using the arrow keys while in insert mode inserts A / B / C / D rather than moving the cursor. Not good.</p>
<p>A little tweak to your existing ~/.vimrc file will fix it right up (or, if you don&#8217;t have an existing ~/.vimrc, create it). (<em>Note: the easiest way to get the proper escape characters is to enter insert mode, and hit CTRL+V followed by the Home or End key. This will add the ^[ escape character, as well as the [F or [H characters. Do the same thing for CTRL + O to get the ^O escape character.</em>) By using CTRL+O on the imap lines, we make the Home / End keys work the same way in insert mode or command mode.</p>
<p>As an added bonus, this fixes the arrow keys while in insert mode. Though, to be honest, I have no idea why&#8230;</p>
<div class="wp_syntax">
<div class="code">
<pre class="vim" style="font-family:monospace;"><span style="color: #C5A22D;">&quot;&quot;</span><span style="color: #adadad; font-style: italic;">&quot; ~/.vimrc</span>
&nbsp;
<span style="color: #C5A22D;">&quot;&quot;</span><span style="color: #adadad; font-style: italic;">&quot; Fix home and end keybindings for screen</span>
<span style="color: #804040;">map</span> <span style="color: #000000;">^</span><span style="color: #000000;">&#91;</span><span style="color: #000000;">&#91;</span>F <span style="color: #000000;">$</span>
imap <span style="color: #000000;">^</span><span style="color: #000000;">&#91;</span><span style="color: #000000;">&#91;</span>F <span style="color: #000000;">^</span>O<span style="color: #000000;">$</span>
<span style="color: #804040;">map</span> <span style="color: #000000;">^</span><span style="color: #000000;">&#91;</span><span style="color: #000000;">&#91;</span>H g0
imap <span style="color: #000000;">^</span><span style="color: #000000;">&#91;</span><span style="color: #000000;">&#91;</span>H <span style="color: #000000;">^</span>Og0</pre>
</div>
</div>
<h2>Making Terminal always available</h2>
<p>This one was actually pretty simple. Using <a title="SIMBL" href="http://www.culater.net/software/SIMBL/SIMBL.php">SIMBL</a> and <a title="Visor" href="http://visor.binaryage.com/">Visor</a> (both compatible with 64-bit Terminal at the time of this writing) you can get Terminal to dock to the top / side / bottom of your screen, and configure it to open with a keystroke you can define.</p>
<p>My keystroke is Command + Esc (turn off Front Row first, if you hate it as much as I do). Once Terminal has been launched for the first time (thus creating the Visor window), this keystroke gets you in from anywhere, or hides it when you are done.</p>
<h2>Hiding the Dock icon, and removing Terminal from the Command + Tab list</h2>
<p>This is the most involved step, but it also provides one of the biggest benefits in my mind. Most of the information here comes from a <a href="http://www.metaskills.net/2009/8/18/visor-terminal-on-snow-leopard">MetaSkills blog article</a>.</p>
<p>In order to accomplish this, the LSUIElement key in Terminal&#8217;s Info.plist must be set to &#8220;1&#8243;. This disables the Dock icon and removes the application from the Command + Tab list. Don&#8217;t want to completely prevent Terminal from ever functioning like a normal application? The quick solution is to create new application &#8220;VisorTerminal.app&#8221; which is used for Visor, while leaving Terminal.app alone to function as normal. (This is actually a good thing, because another side-effect of setting LSUIElement : 1 is you no longer have anything change in the menubar when you are in your application&#8230; ie, you can&#8217;t click on VisorTerminal next to the Apple icon, and go into Preferences.)</p>
<h3>Create a new VisorTerminal.app</h3>
<p>Duplicate the existing Terminal.app.</p>
<div class="wp_syntax">
<div class="code">
<pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">cp</span> <span style="color: #660033;">-r</span> <span style="color: #000000; font-weight: bold;">/</span>Applications<span style="color: #000000; font-weight: bold;">/</span>Utilities<span style="color: #000000; font-weight: bold;">/</span>Terminal.app <span style="color: #000000; font-weight: bold;">/</span>Applications<span style="color: #000000; font-weight: bold;">/</span>Utilities<span style="color: #000000; font-weight: bold;">/</span>VisorTerminal.app</pre>
</div>
</div>
<p>Once you have duplicated Terminal.app, you need to change a few bundle identifiers in your new application so the two appear as distinct entities to Mac OS X. In other words, change &#8220;Terminal&#8221; to &#8220;VisorTerminal&#8221; in a few places. This is also when you add LSUIElements : 1.</p>
<div class="wp_syntax">
<div class="code">
<pre class="xml" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">&lt;!-- /Applications/Utilities/VisorTerminal.app/Contents/Info.plist --&gt;</span>
...
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>CFBundleDisplayName<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>VisorTerminal<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
...
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>CFBundleIdentifier<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>com.apple.VisorTerminal<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
...
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>CFBundleName<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>VisorTerminal<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
...
<span style="color: #808080; font-style: italic;">&lt;!-- Note: Put this right before the closing &lt;/dict&gt;&lt;/plist&gt;</span>
<span style="color: #808080; font-style: italic;">     at the end of the file --&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>LSUIElement<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
...</pre>
</div>
</div>
<p>At this point, rather than entering my preferences all over again, I elected to copy my Terminal.app preferences. Repeat this step any time you make preference changes that you want to copy over. (<em>Note: using a symlink does not seem to work. If you make changes while in VisorTerminal, such as changing the Visor hotkey, the modified file is saved over your symlink.</em>)</p>
<div class="wp_syntax">
<div class="code">
<pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">cp</span> ~<span style="color: #000000; font-weight: bold;">/</span>Library<span style="color: #000000; font-weight: bold;">/</span>Preferences<span style="color: #000000; font-weight: bold;">/</span>com.apple.Terminal.plist ~<span style="color: #000000; font-weight: bold;">/</span>Library<span style="color: #000000; font-weight: bold;">/</span>Preferences<span style="color: #000000; font-weight: bold;">/</span>com.apple.VisorTerminal.plist</pre>
</div>
</div>
<h3>Modify Visor to use VisorTerminal.app</h3>
<p>Once your new application is created and ready to go, you need to tell Visor to activate for that application rather than Terminal.app. Apply the following very familiar tweaks to Visor&#8217;s Info.plist:</p>
<div class="wp_syntax">
<div class="code">
<pre class="xml" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">&lt;!-- ~/Library/Application\ Support/SIMBL/Plugins/Visor.bundle/Contents/Info.plist --&gt;</span>
...
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>BundleIdentifier<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>com.apple.VisorTerminal<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
...
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>ExecPattern<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>*/VisorTerminal.app/Contents/MacOS/Terminal<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
...
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>BundleIdentifier<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>com.apple.VisorTerminal<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
...</pre>
</div>
</div>
<p>Once this last step is done, you are almost there. Make sure Terminal.app and VisorTerminal.app are both closed. Now, launch VisorTerminal.app and behold its wonder!</p>
<div class="wp_syntax">
<div class="code">
<pre class="bash" style="font-family:monospace;">open <span style="color: #000000; font-weight: bold;">/</span>Applications<span style="color: #000000; font-weight: bold;">/</span>Utilities<span style="color: #000000; font-weight: bold;">/</span>VisorTerminal.app</pre>
</div>
</div>
<h2>What? It didn&#8217;t work?</h2>
<p>Let me guess. A Terminal window opened, but Visor didn&#8217;t take effect. What gives? (You may have also noticed that you don&#8217;t have an entry in your menubar&#8230; see above.)</p>
<p>Turns out newer versions of SIMBL <a href="http://code.google.com/p/simbl/issues/detail?id=9">don&#8217;t activate in applications with LSUIElement : 1</a>. Apparently this is expected behavior due to the Cocoa event mechanism. But all is not lost!</p>
<p>You can manually inject SIMBL into an application using Apple Script.</p>
<div class="wp_syntax">
<div class="code">
<pre class="applescript" style="font-family:monospace;"><span style="color: #ff0033; font-weight: bold;">tell</span> <span style="color: #0066ff;">application</span> <span style="color: #009900;">&quot;VisorTerminal&quot;</span>
	inject SIMBL <span style="color: #0066ff;">into</span> Snow Leopard
<span style="color: #ff0033; font-weight: bold;">end</span> <span style="color: #ff0033; font-weight: bold;">tell</span></pre>
</div>
</div>
<p>Great, but I don&#8217;t want to do something manually every time I want a Visor window. I just want it to always be there, remember?</p>
<p>Use the <a href="http://www.tuaw.com/2007/12/27/applescript-the-script-editor/">AppleScript Editor</a> to save this snippet as an application, and then include that application in your user startup items. Voila! When you log in, the AppleScript helper executes, which launches VisorTerminal with SIMBL injected. Visor activates, your terminal automatically hides itself, yet is always there when you want it with the push of a button. It doesn&#8217;t clutter up your Dock, your application switching, and you can still use Terminal.app as usual whenever it makes sense to do so.</p>
<h2>Final thoughts</h2>
<p>First off, note that this tutorial was written using <em>SIMBL 0.9.7a</em>, <em>Visor 2.2</em>, and <em>Terminal 2.1.1 (273)</em> on Mac OS X <em>Snow Leopard 10.6.4</em>. YMMV.</p>
<p>Secondly, my thanks to all the people who are smarter than me and figured all this out. All I did was put things together.</p>
<p>Third, see below for patch files and my AppleScript application.</p>
<p>Finally, does anyone have the following issue, and know a way around it? After setting my key bindings, when I launch Terminal for the first time, they don&#8217;t take effect. Home does nothing special. If I open a new Terminal window, the home key starts working as expected, both in the new window as well as the original window. This happens to me whether I use \001 for the control character (and this without a ~/.inputrc file) or if I use the solution described above. Slightly bothersome, but since I almost always use my Visor terminal (which doesn&#8217;t exhibit the same problem&#8230; nor did it using Visor sans any modifications discussed here) I don&#8217;t notice it too often.</p>
<p><strong>Patch files:</strong> <a href="http://gist.github.com/484082">http://gist.github.com/484082</a><br />
<strong>AppleScript app:</strong> <a href="http://colonelpanic.net/wp-content/uploads/2010/07/HiddenVisorTerminal.zip">HiddenVisorTerminal.zip</a></p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2010/07/terminal-nirvana-on-snow-leopard-with-simbl-visor/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Building a firefox plugin – part three</title>
		<link>http://colonelpanic.net/2009/08/building-a-firefox-plugin-part-three/</link>
		<comments>http://colonelpanic.net/2009/08/building-a-firefox-plugin-part-three/#comments</comments>
		<pubDate>Wed, 05 Aug 2009 05:20:46 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Browser Plugin Development]]></category>
		<category><![CDATA[NPAPI]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[npobject]]></category>
		<category><![CDATA[npruntime]]></category>
		<category><![CDATA[npvariant]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=72</guid>
		<description><![CDATA[Note: For a better way to create a Browser Plugin (that will work on all browsers, not just NPAPI), check out the FireBreath project. Getting help: For a better place to ask NPAPI-related questions, check out the FireBreath Forums. Yes, there is a forum there for NPAPI plugins that don&#8217;t use FireBreath as well. Previous [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Note: </strong>For a better way to create a Browser Plugin (that will work on all browsers, not just NPAPI), check out the <a href="http://www.firebreath.org">FireBreath project</a>.</p>
<p><strong>Getting help: </strong>For a better place to ask NPAPI-related questions, check out the <a href="http://forum.firebreath.org">FireBreath Forums</a>. Yes, there is a forum there for NPAPI plugins that don&#8217;t use FireBreath as well.</p>
<h2>Previous posts</h2>
<p>The purpose of this post is to cover the basics of providing an interface by which javascript can interface with an NPAPI plugin in a cross platform manner.  The primary focus of this post will be on <a title="Mozilla Plugin API Reference : Scripting Plugins" href="https://developer.mozilla.org/en/Gecko_Plugin_API_Reference/Scripting_plugins" target="_blank">npruntime</a>, which is recommended by the Mozilla development team (or at least seems to be from the <a title="Mozilla Plugin API Reference" href="https://developer.mozilla.org/En/plugins">meager and confusing documentation</a> available from Mozilla).  More importantly, of course, it is the framework that I recommend, which is all-important, since I&#8217;m the one writing this post. =]</p>
<h2><span id="more-72"></span>Previous posts</h2>
<p>If you are new to NPAPI plugins, you may want to go back and read <a title="Building a firefox plugin - part one" href="http://colonelpanic.net/2009/03/building-a-firefox-plugin-part-one/" target="_blank">part one</a> and <a title="Building a firefox plugin - part two" href="http://colonelpanic.net/2009/05/building-a-firefox-plugin-part-two/">part two</a> of this series, which cover the basic architecture and lifecycle of an NPAPI plugin.</p>
<h2>What is npruntime?</h2>
<p>I&#8217;m so glad you ask.  This confused the daylights out of me when I first got into building browser plugins; there are references to XPCOM and references to LiveConnect and references to NPRuntime, which I never did quite get straightened out until I ran into <a title="Netscape Plugin Application Programming Interface" href="http://en.wikipedia.org/wiki/Netscape_Plugin_Application_Programming_Interface" target="_blank">a Wikipedia article on NPAPI</a>.  I recommend that you read it if you want further background information.</p>
<p>Beyond the simple question of &#8220;what is recommended?&#8221; is the consideration of practical needs.  For me, the primary considerations that led me to decide that NPRuntimeis the only mechanism that should be used on any new plugin are:</p>
<ul>
<li>NPRuntime allows dynamic interfaces &#8212; more on this, and why it is useful, later</li>
<li>NPRuntime is the plugin scripting standard supported by Mac Plugins, Safari (even on windows), Chrome, and Opera.  My goal is always to make things as cross-platform as possible.</li>
<li>Firefox 3.6 drops support for XPCOM plugins (e.g. xpt file scripting interfaces aren&#8217;t recognized)</li>
</ul>
<h2>Getting Started</h2>
<p>Throughout this post, I will be referring to Scriptable Objects a lot.  A Scriptable Object is simply an object that can be &#8220;scripted&#8221;, or accessed and used by javascript.  In firefox, a Scriptable Object is always a <a title="NPObject - MDC" href="https://developer.mozilla.org/en/NPObject" target="_blank">NPObject</a>:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">struct</span> NPObject <span style="color: #008000;">&#123;</span>
  NPClass <span style="color: #000040;">*</span>_class<span style="color: #008080;">;</span>
  <span style="color: #0000ff;">uint32_t</span> referenceCount<span style="color: #008080;">;</span>
  <span style="color: #ff0000; font-style: italic;">/*
   * Additional space may be allocated here by types of NPObjects
   */</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<p>As you can see, a NPObject is nothing more than a reference counted object with a pointer to a <a title="NPClass - MDC" href="https://developer.mozilla.org/en/NPClass">NPClass</a>.  As of the latest (as of this writing) Gecko SDK, 1.9, NPClass is defined as follows:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">struct</span> NPClass
<span style="color: #008000;">&#123;</span>
  <span style="color: #0000ff;">uint32_t</span> structVersion<span style="color: #008080;">;</span> <span style="color: #666666;">// Version of the structure (to determine which features may be missing)</span>
  NPAllocateFunctionPtr allocate<span style="color: #008080;">;</span> <span style="color: #666666;">// Called to create a new instance of this object</span>
  NPDeallocateFunctionPtr deallocate<span style="color: #008080;">;</span> <span style="color: #666666;">// Called to free the instance of this object</span>
  NPInvalidateFunctionPtr invalidate<span style="color: #008080;">;</span> <span style="color: #666666;">// Called on live objects that belong to a plugin instance that is being destroyed. This call is always followed by a call to the &lt;code&gt;deallocate&lt;/code&gt; function, or &lt;code&gt;free()&lt;/code&gt;. Any attempt to use an invalidated object will result in undefined behavior.</span>
  NPHasMethodFunctionPtr hasMethod<span style="color: #008080;">;</span> <span style="color: #666666;">// Called to query if a method exists on the NPObject</span>
  NPInvokeFunctionPtr invoke<span style="color: #008080;">;</span> <span style="color: #666666;">// Used to invoke a method on the NPObject</span>
  NPInvokeDefaultFunctionPtr invokeDefault<span style="color: #008080;">;</span> <span style="color: #666666;">// Used to invoke the NPObject as a function</span>
  NPHasPropertyFunctionPtr hasProperty<span style="color: #008080;">;</span> <span style="color: #666666;">// Called to query if a property exists on the NPObject</span>
  NPGetPropertyFunctionPtr getProperty<span style="color: #008080;">;</span> <span style="color: #666666;">// Called to get the value of a property on the NPObject</span>
  NPSetPropertyFunctionPtr setProperty<span style="color: #008080;">;</span> <span style="color: #666666;">// Called to set the value of a property on the NPObject</span>
  NPRemovePropertyFunctionPtr removeProperty<span style="color: #008080;">;</span> <span style="color: #666666;">// Called to remove/delete a property on the NPObject</span>
  NPEnumerationFunctionPtr enumerate<span style="color: #008080;">;</span> <span style="color: #666666;">// Used to get a list of properties and methods that exist on the NPObject (new in FF 3, Gecko SDK 1.9)</span>
  NPConstructFunctionPtr construct<span style="color: #008080;">;</span> <span style="color: #666666;">// Used when the new keyword is called in javascript to create a new instance of the NPObject (new in FF 3, Gecko SDK 1.9)</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<h2>Making it Object Oriented</h2>
<p>The Gecko SDK is intentionally written to use structs instead of objects; this allows it to work across many platforms, with many different types of compilers, and never worry about binary compatibility.  If you haven&#8217;t figured it out yet, the NPClass structure contains a list of function pointers that should be called by the browser (or anyone else) to talk to the NPObject.  These should never be called explicitly, but rather they should be called through the NPN_ functions that I briefly mentioned towards the end of <a title="Building a firefox plugin - part one" href="http://colonelpanic.net/2009/03/building-a-firefox-plugin-part-one/" target="_blank">part one</a>.  When one wishes to create a new instance of an NPObject, you call the <a title="NPN_CreateObject - MDC" href="https://developer.mozilla.org/en/NPN_CreateObject">NPN_CreateObject</a> function and give it the class that should be used.</p>
<p>Fortunately, since all the browser cares about is the NPClass, its function pointers, and the reference count, any class that inherits from NPObject can easily satisfy that requirement; that means that it is not difficult to make a smart NPObject; simply create static methods for each of the pointers in the NPClass struct, dereference the NPObject* that they pass in, and call a member function.</p>
<h2>Simple class definition and implementation:</h2>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &quot;npapi.h&quot;</span>
<span style="color: #339900;">#include &quot;npupp.h&quot;</span>
&nbsp;
<span style="color: #0000ff;">class</span> MyScriptableNPObject <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> NPObject
<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">protected</span><span style="color: #008080;">:</span>
    <span style="color: #666666;">// Class member functions that do the real work</span>
    <span style="color: #0000ff;">void</span> Deallocate<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">void</span> Invalidate<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> HasMethod<span style="color: #008000;">&#40;</span>NPIdentifier name<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> Invoke<span style="color: #008000;">&#40;</span>NPIdentifier name, <span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>args, <span style="color: #0000ff;">uint32_t</span> argCount, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> InvokeDefault<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>args, <span style="color: #0000ff;">uint32_t</span> argCount, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> HasProperty<span style="color: #008000;">&#40;</span>NPIdentifier name<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> GetProperty<span style="color: #008000;">&#40;</span>NPIdentifier name, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> SetProperty<span style="color: #008000;">&#40;</span>NPIdentifier name, <span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>value<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> RemoveProperty<span style="color: #008000;">&#40;</span>NPIdentifier name<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> Enumerate<span style="color: #008000;">&#40;</span>NPIdentifier <span style="color: #000040;">**</span>identifier, <span style="color: #0000ff;">uint32_t</span> <span style="color: #000040;">*</span>count<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> Construct<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>args, <span style="color: #0000ff;">uint32_t</span> argCount, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
    <span style="color: #666666;">// This is the method used to create the NPObject</span>
    <span style="color: #666666;">// This method should not be called explicitly</span>
    <span style="color: #666666;">// Instead, use NPN_CreateObject</span>
    <span style="color: #0000ff;">static</span> NPObject<span style="color: #000040;">*</span> Allocate<span style="color: #008000;">&#40;</span>NPP npp, NPClass <span style="color: #000040;">*</span>aClass<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">return</span> <span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span><span style="color: #0000dd;">new</span> MyScriptableNPObject<span style="color: #008000;">&#40;</span>npp<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #666666;">/////////////////////////////</span>
    <span style="color: #666666;">// Static NPObject methods //</span>
    <span style="color: #666666;">/////////////////////////////</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> _Deallocate<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> _Invalidate<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> _HasMethod<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj, NPIdentifier name<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> _Invoke<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj, NPIdentifier name, <span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>args, <span style="color: #0000ff;">uint32_t</span> argCount, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> _InvokeDefault<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj, <span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>args, <span style="color: #0000ff;">uint32_t</span> argCount, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> _HasProperty<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span> npobj, NPIdentifier name<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> _GetProperty<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj, NPIdentifier name, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> _SetProperty<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj, NPIdentifier name, <span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>value<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> _RemoveProperty<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj, NPIdentifier name<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> _Enumerate<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj, NPIdentifier <span style="color: #000040;">**</span>identifier, <span style="color: #0000ff;">uint32_t</span> <span style="color: #000040;">*</span>count<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> _Construct<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>npobj, <span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>args, <span style="color: #0000ff;">uint32_t</span> argCount, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">static</span> NPClass _npclass<span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">protected</span><span style="color: #008080;">:</span>
    NPP m_Instance<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<p>Due to code ownership issues, I&#8217;m not able to give you the actual code that I&#8217;m using, but if there are any compiler errors I&#8217;m sure they&#8217;ll be simple to straighten out.  The implementation for these static members will be pretty straightforward:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// static</span>
<span style="color: #0000ff;">void</span> MyScriptableNPObject<span style="color: #008080;">::</span>_Invalidate<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>obj<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>MyScriptableNPObject<span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>obj<span style="color: #008000;">&#41;</span><span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>Invalidate<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">void</span> MyScriptableNPObject<span style="color: #008080;">::</span><span style="color: #007788;">Invalidate</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #666666;">// Invalidate the control however you wish</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #666666;">// static</span>
<span style="color: #0000ff;">void</span> MyScriptableNPObject<span style="color: #008080;">::</span>_Deallocate<span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span>obj<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>MyScriptableNPObject<span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>obj<span style="color: #008000;">&#41;</span><span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>Deallocate<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">delete</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>MyScriptableNPObject<span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>obj<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">void</span> MyScriptableNPObject<span style="color: #008080;">::</span><span style="color: #007788;">Deallocate</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #666666;">// Do any cleanup needed</span>
<span style="color: #008000;">&#125;</span></pre>
</div>
</div>
<p>For brevity, I&#8217;m not going to include all of the methods here; I will go into more detail on them later.  For now, suffice it to say that after you have implemented the rest of these functions, all that is left is to define the NPClass itself:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">NPClass MyScriptableNPObject<span style="color: #008080;">::</span>_npclass <span style="color: #000080;">=</span> <span style="color: #008000;">&#123;</span>
    NP_CLASS_STRUCT_VERSION,
    MyScriptableNPObject<span style="color: #008080;">::</span><span style="color: #007788;">Allocate</span>,
    MyScriptableNPObject<span style="color: #008080;">::</span>_Deallocate,
    MyScriptableNPObject<span style="color: #008080;">::</span>_Invalidate,
    MyScriptableNPObject<span style="color: #008080;">::</span>_HasMethod,
    MyScriptableNPObject<span style="color: #008080;">::</span>_Invoke,
    MyScriptableNPObject<span style="color: #008080;">::</span>_InvokeDefault,
    MyScriptableNPObject<span style="color: #008080;">::</span>_HasProperty,
    MyScriptableNPObject<span style="color: #008080;">::</span>_GetProperty,
    MyScriptableNPObject<span style="color: #008080;">::</span>_SetProperty,
    MyScriptableNPObject<span style="color: #008080;">::</span>_RemoveProperty,
    MyScriptableNPObject<span style="color: #008080;">::</span>_Enumerate,
    MyScriptableNPObject<span style="color: #008080;">::</span>_Construct
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<h2>Creating the NPObject</h2>
<p>Once you have your custom NPObject created and your NPClass defined, we can cover the basics of the NPObject lifecycle.  Creating an NPObject is pretty straightforward:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">NPObject <span style="color: #000040;">*</span>newObj <span style="color: #000080;">=</span> NPN_CreateObject<span style="color: #008000;">&#40;</span>m_Instance, <span style="color: #000040;">&amp;</span>amp<span style="color: #008080;">;</span>MyScriptableNPObject<span style="color: #008080;">::</span>_npclass<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
NPN_RetainObject<span style="color: #008000;">&#40;</span>newObj<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<p>As you can see, all that is needed is the NPP instance handler (see <a title="Building a firefox plugin - part two" href="http://colonelpanic.net/2009/05/building-a-firefox-plugin-part-two/">part two</a>) and a pointer to the class.  Since the class is very specific to a specific NPObject, I like to create a static function to instantiate the object, like so:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">static</span> MyScriptableNPObject<span style="color: #000040;">*</span> NewObject<span style="color: #008000;">&#40;</span>NPP npp<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    MyScriptableNPObject<span style="color: #000040;">*</span> newObj <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>MyScriptableNPObject<span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>NPN_CreateObject<span style="color: #008000;">&#40;</span>npp, <span style="color: #000040;">&amp;</span>amp<span style="color: #008080;">;</span>_npclass<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> newObj<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre>
</div>
</div>
<p>This is completely voluntary, of course, but it also allows you some additional control of the creation process; for example, you may want to pass in additional parameters and have them set on the object as soon as it is created.</p>
<h2>NPObject lifecycle</h2>
<p>As you might guess, <a title="NPN_RetainObject - MDC" href="https://developer.mozilla.org/En/NPN_RetainObject">NPN_RetainObject </a>increments the reference count on a given NPObject.  Similarly, <a title="NPN_ReleaseObject - MDC" href="https://developer.mozilla.org/En/NPN_ReleaseObject" target="_blank">NPN_ReleaseObject </a>decrements the reference count.  When the reference count hits zero, the object will be destroyed by calling the specified Deallocate function, just like the Allocate function is called by NPN_CreateObject to create the object.</p>
<p>When code in one DLL allocates something and it is deallocated by a different DLL, heap corruption can (and often does) occur.  For this reason, all things that belong to you will ultimately get created and destroyed in your code.  All things that belong to the browser will get created and freed in browser code.  This way everyone stays happy =]  Make sure you keep track of your Retains and Releases; just like any reference counting, this can cause you a lot of hard to track problems.</p>
<p>Another important thing to keep in mind about the lifecycle of a NPObject is that you don&#8217;t know exactly when it will go away; the browser will release it whenever it chooses to do so.  Therefore, you need to be able to handle things gracefully even if things are destroyed in a different order than you expect.</p>
<h2>Giving the correct NPObject to the browser</h2>
<p>Now that you know what an NPObject is and rougly what it does, you need to know how the browser finds out about it.  If you&#8217;ll refer back to <a title="Building a firefox plugin - part two" href="../2009/05/building-a-firefox-plugin-part-two/">part two</a> and look at the plugin lifecycle, you&#8217;ll see on entry #5 that &#8220;Plugin creates a scriptable NPObject and returns a pointer to it (after calling <a title="NPN_RetainObject SDK docs" href="https://developer.mozilla.org/En/NPN_RetainObject" target="_blank">NPN_RetainObject</a> on it.)&#8221;  Simply put, at that point in the initialization sequence (or somewhere in there; the spec is ambiguous about the order), the Browser will call GetValue on the plugin and ask for a NPObject.  If our plugin supports NPObjects, it simply needs to create one, call <a title="NPN_RetainObject SDK docs" href="https://developer.mozilla.org/En/NPN_RetainObject" target="_blank">NPN_RetainObject</a> on it, and return it as a void pointer.  <strong>*NOTE: Make sure that you typecast it as a NPObject* before assigning it to the void pointer; I made that mistake once and spent a week trying to figure out why the wrong functions were getting called.</strong></p>
<p>Here is an example implementation of GetValue:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">NPError PluginInstance<span style="color: #008080;">::</span><span style="color: #007788;">NpapiGetValue</span><span style="color: #008000;">&#40;</span>NPPVariable variable, <span style="color: #0000ff;">void</span> <span style="color: #000040;">*</span>value<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
   NPError rv <span style="color: #000080;">=</span> NPERR_NO_ERROR<span style="color: #008080;">;</span>
   <span style="color: #0000ff;">switch</span><span style="color: #008000;">&#40;</span>variable<span style="color: #008000;">&#41;</span>
   <span style="color: #008000;">&#123;</span>
      <span style="color: #0000ff;">case</span> NPPVpluginNameString<span style="color: #008080;">:</span>
          value <span style="color: #000080;">=</span> <span style="color: #000040;">*</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">char</span> <span style="color: #000040;">**</span><span style="color: #008000;">&#41;</span>value<span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> STRINGS_PRODUCTNAME<span style="color: #008080;">;</span>
          <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
      <span style="color: #0000ff;">case</span> NPPVpluginDescriptionString<span style="color: #008080;">:</span>    <span style="color: #666666;">// Plugin description</span>
          <span style="color: #000040;">*</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">char</span> <span style="color: #000040;">**</span><span style="color: #008000;">&#41;</span>value<span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> STRINGS_FILEDESCRIPTION<span style="color: #008080;">;</span>
          <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
      <span style="color: #0000ff;">case</span> NPPVpluginScriptableNPObject<span style="color: #008080;">:</span><span style="color: #666666;">// Scriptable plugin interface (for accessing from javascript)</span>
          <span style="color: #000040;">*</span><span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">**</span><span style="color: #008000;">&#41;</span>value <span style="color: #000080;">=</span> this<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>getScriptableObject<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
          <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
      <span style="color: #0000ff;">case</span> NPPVpluginWindowBool<span style="color: #008080;">:</span>
          <span style="color: #000040;">*</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>PRBool <span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>value<span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> this<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>isWindowed<span style="color: #008080;">;</span>
          <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
      <span style="color: #0000ff;">default</span><span style="color: #008080;">:</span>
          rv <span style="color: #000080;">=</span> NPERR_GENERIC_ERROR<span style="color: #008080;">;</span>
  <span style="color: #008000;">&#125;</span>
  <span style="color: #0000ff;">return</span> rv<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
NPObject <span style="color: #000040;">*</span>PluginInstance<span style="color: #008080;">::</span><span style="color: #007788;">getScriptableObject</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
   NPObject <span style="color: #000040;">*</span>retval<span style="color: #008080;">;</span>
   <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>this<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>npobj <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span>
      retval <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>this<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>npobj<span style="color: #008080;">;</span>
   <span style="color: #0000ff;">else</span>
      retval <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>NPObject <span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>MyScriptableNPObject<span style="color: #008080;">::</span><span style="color: #007788;">NewObject</span><span style="color: #008000;">&#40;</span>this<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>npp<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
   NPN_RetainObject<span style="color: #008000;">&#40;</span>retval<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
   <span style="color: #0000ff;">return</span> retval<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre>
</div>
</div>
<h2>HasMethod and HasProperty</h2>
<p>On to the meat of the article: Say you have a javascript function like so:</p>
<pre>var objTag = document.getElementById("myObjectTag");
alert(objTag.doSomeCoolFunction);</pre>
<p>You may think that this looks a little strange, since &#8220;doSomeCoolFunction&#8221; sounds like a function call, but it is clearly accessed like a parameter here.  In Javascript, this is legal even if that is a function, because it can be used to determine if a function exists without calling it.  Therefore, you cannot have a method and a property on the same object with the same name.</p>
<p>When this call is made, the browser will call two functions on the NPObject:</p>
<ol>
<li><a title="NPN_HasMethod - MDC" href="https://developer.mozilla.org/en/NPN_HasMethod" target="_blank">HasMethod</a>(NPIdentifier name);</li>
<li><a title="NPN_HasProperty - MDC" href="https://developer.mozilla.org/en/NPN_HasProperty" target="_blank">HasProperty</a>(NPIdentifier name);</li>
</ol>
<p>The purpose of these two calls is to ascertain whether or not a property or method exists on the NPObject (as you might have guessed).  So, what is with this <a title="NPIdentifier - MDC" href="https://developer.mozilla.org/en/NPIdentifier" target="_blank">NPIdentifier </a>thing?  Well, a NPIdentifier can map to either an integer or a string.  a NPIdentifier can be converted to a string (if it is a string identifier) with <a title="NPN_UTF8FromIdentifier - MDC" href="https://developer.mozilla.org/en/NPN_UTF8FromIdentifier" target="_blank">NPN_UTF8FromIdentifier</a>.  To find out if it is a string identifier, use <a href="https://developer.mozilla.org/en/NPN_IdentifierIsString" target="_blank href=">NPN_IdentifierIsString</a>.  If it is an integer, you can use <a href="https://developer.mozilla.org/en/NPN_IntFromIdentifier" rel="custom nofollow" target="_blank">NPN_IntFromIdentifier</a>.</p>
<p>Now, the purpose of integer identifiers may not be immediately apparent to everyone; it wasn&#8217;t to me at first.  Once I figured it out, however, I was thrilled.  If you are familiar with javascript, you are doubtlessly familiar with the concept that everything in javascript is an object; arrays are actually just objects with integer keys.  So, to allow array-style access, simply handle integer identifiers!</p>
<p>Once you have converted the identifier into something you can deal with, decide if your object has that property or method (I&#8217;ll let you figure out which goes in which function) and return true or false.</p>
<p>Oh, and after you get a string wtih NPN_UTF8FromIdentifier, don&#8217;t forget to release the memory with <a href="https://developer.mozilla.org/en/NPN_MemFree" rel="internal">NPN_MemFree()</a>.</p>
<h2>NPVariant</h2>
<p>Before I go any further, I need to spend a brief paragraph or two on the <a title="NPVariant structure documentation" href="https://developer.mozilla.org/en/NPVariant" target="_blank">NPVariant structure</a>.</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">typedef</span> <span style="color: #0000ff;">struct</span> _NPVariant <span style="color: #008000;">&#123;</span>
  NPVariantType type<span style="color: #008080;">;</span>
  <span style="color: #0000ff;">union</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">bool</span> boolValue<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">int32_t</span> intValue<span style="color: #008080;">;</span>
    double_t doubleValue<span style="color: #008080;">;</span>
    NPString stringValue<span style="color: #008080;">;</span>
    NPObject <span style="color: #000040;">*</span>objectValue<span style="color: #008080;">;</span>
  <span style="color: #008000;">&#125;</span> value<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span> NPVariant<span style="color: #008080;">;</span></pre>
</div>
</div>
<p>NPVariant is the datatype used by the browser to pass variables into and out of NPObjects.  From the MDC docs, the following types are valid:</p>
<table border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<th>JavaScript type</th>
<th><code>NPVariantType</code></th>
</tr>
<tr>
<td><code>undefined</code></td>
<td><code>NPVariantType_Void</code></td>
</tr>
<tr>
<td><code>null</code></td>
<td><code>NPVariantType_Null</code></td>
</tr>
<tr>
<td><code>boolean</code></td>
<td><code>NPVariantType_Bool</code></td>
</tr>
<tr>
<td><code>number</code></td>
<td><code>NPVariantType_Int32</code> or <code>NPVariantType_Double</code></td>
</tr>
<tr>
<td><code>string</code></td>
<td><code>NPVariantType_String</code></td>
</tr>
<tr>
<td>All other types</td>
<td><code>NPVariantType_Object</code></td>
</tr>
</tbody>
</table>
<p>Since it&#8217;s getting late and I&#8217;ve already put too much in this post (I&#8217;m over 2000 words), I&#8217;ll leave it as an excercise to the reader to <a title="NPVariant docs" href="https://developer.mozilla.org/en/NPVariant" target="_blank">read up on the macros and such for using this structure</a>.</p>
<h2>Properties</h2>
<p>At this point, you should be getting a pretty good idea of how everything works.  Getting and setting properties is fairly straightforward:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">    <span style="color: #0000ff;">bool</span> GetProperty<span style="color: #008000;">&#40;</span>NPIdentifier name, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> SetProperty<span style="color: #008000;">&#40;</span>NPIdentifier name, <span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>value<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<p>To get a property, simply check the name to see what you&#8217;re going to be doing and store the value to return in *result.  If the operation succeeds, you should return true.  If not, false.</p>
<p>To set a property, again check the name to see which property you&#8217;re working with and save the value of the NPVariant parameter however you wish.  Again, return true if success, false if failure.</p>
<h2>Methods</h2>
<p>Methods aren&#8217;t much more difficult.  The only real difference is that now you have parameters to worry about.  No problem!  Parameters are passed in as an array of NPVariants:</p>
<div class="wp_syntax">
<div class="code">
<pre class="cpp" style="font-family:monospace;">    <span style="color: #0000ff;">bool</span> Invoke<span style="color: #008000;">&#40;</span>NPIdentifier name, <span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>args, <span style="color: #0000ff;">uint32_t</span> argCount, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> InvokeDefault<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> NPVariant <span style="color: #000040;">*</span>args, <span style="color: #0000ff;">uint32_t</span> argCount, NPVariant <span style="color: #000040;">*</span>result<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre>
</div>
</div>
<p>The difference between Invoke and InvokeDefault is that InvokeDefault does not ever have an identifier.  If you call &#8220;objTag.funcName()&#8221; Invoke gets called; if you call &#8220;objTag()&#8221;, then InvokeDefault gets called.</p>
<p>As with properties, store the return value in the pointer given in the last argument and handle the other arguments however you wish.</p>
<h2>Wrapping it up</h2>
<p>Alright, I know I haven&#8217;t covered everything, but this is already too long.  If you have specific questions, ask them in the comments and I&#8217;ll do my best to answer; the comments may determine the direction of my next post.</p>
<p>Since dealing with the NPIdentifiers can get to be such a pain, I recommend using a map or hashtable to store structures with function pointers to map a string name to functions to handle it; that way you don&#8217;t end up with giant if/then or case statements, and everything ends up being much cleaner.</p>
<p>Another idea for the adventuresome: abstract the actual logic (properties and methods) into another object that can be wrapped with your NPObject class, and then make another wrapper class that implements <a title="MSDN: IDispatch" href="http://msdn.microsoft.com/en-us/library/ms221608.aspx" target="_blank">IDispatch </a>so that your scriptable objects are cross platform (IDispatch objects are scriptable on Internet Explorer).</p>
<p>Good luck!</p>
<p><a title="Building a firefox plugin - part one" href="http://colonelpanic.net/2009/03/building-a-firefox-plugin-part-one/">Building a firefox plugin &#8211; part one</a></p>
<p><a title="Building a firefox plugin - part two" href="http://colonelpanic.net/2009/05/building-a-firefox-plugin-part-two/">Building a firefox plugin &#8211; part two</a></p>
<p><a title="Building a firefox plugin - part three" href="http://colonelpanic.net/2009/08/building-a-firefox-plugin-part-three/">Building a firefox plugin &#8211; part three</a></p>
<p><a title="Building a firefox plugin - part four" href="http://colonelpanic.net/2011/07/building-a-firefox-plugin-part-four/">Building a firefox plugin &#8211; part four</a></p>
<h2>Getting more help</h2>
<p><strong>Update May 14, 2011:</strong> Many people have been asking questions in the comments; while I don&#8217;t mind that, it would probably be more useful if you ask your question on <a href="http://forum.firebreath.org">the FireBreath forums</a>. There is a forum there for those just using NPAPI as well!</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2009/08/building-a-firefox-plugin-part-three/feed/</wfw:commentRss>
		<slash:comments>199</slash:comments>
		</item>
	</channel>
</rss>

