Feb 03

Web Design and Programmers

On a project at work, we’re starting into web development from being entirely desktop applications.  It’s a new thing to learn because of that.  We’re working with a contractor, who is creating the majority of the website for us.  He has suggested, and we have implemented, a REST-based service for sending data to and from the server.  Fortunately, making a REST-based web service in Java is very easy using Genson and JAX-RS.

However, this post is not about that.  It is about web technologies in general.  Originally, I spent a fair amount of time researching different web technologies that use Java as the backend, and I came up with a few such as JSP, JSF, as well as some frameworks, such as PrimeFaces.  We’re not using JSF technology at the moment, but that’s not really the point either.

There are a lot of different web technologies out there, and each has its own pros and cons.  My real question here is why do we treat web design as separate from programming the website?  While researching the advantages/disadvantages of a REST-only website, I came across this good post on programmers.SE about the pros and cons, which then led me to this interesting post about using tag libraries in web pages.  Essentially, what this boils down to is:

The benefit here is that web designers are supposed to be able to work with these tags, or at least that’s what they say. In practice, in all my years of software development and programming, I have yet to ever see this magical unicorn walk out of the shadows and into the sunlight.

My question here though is: why are we treating web development in a different light than we are treating desktop application development?

When developing a desktop application, generally the programmers are the people who create the design.  Even if somebody creates the design in a GUI designer, the programmer has to be involved in how to tie all the events together – they don’t exist in separate paradigms, which is what web technologies seem to do.

In fact, I make all of my Java GUIs by hand.  I have never made a QT gui by hand, but from the generated code that I have looked at it follows a very similar programming model(composite design pattern).  What exactly is preventing a web designer from doing code, and what is preventing a programmer from making a website?

It seems to me that this is not something where the programmer and the web designer are two different people.  What seems to be better would be to have people that can straddle both areas.  After all, we are generally not pigeon-holed into just one area.  If you work mostly on backend code, it is not unreasonable to also touch the GUI code at some point, so you must know how the GUIs are set-up.  But for web development, this seems to be just the opposite.

Perhaps what we need is a swing-like web framework that you don’t need to make any HTML files for, just create the entire website through code.  This sounds complicated, and I don’t know if it would solve the problem.

Jan 19

PIC32 and I2C

I’ve been struggling with Microchip’s plib library trying to get I2C working.  First, the example I2C code is horrible.  Second, I’m not even sure what sample hardware from Microchip actually uses it.  It’s just so confusing.

Anyway, there are a few things to note here about the I2C library and the quirks that it has:

  • Make sure that you have pull-up resistors on the I2C bus.  This was problem #1.
  • Make sure you configure all pins as digital, if they are analog pins.  This was problem #2.
  • There are two methods you need to acknowledge the I2C: I2CAcknowledgeByte and I2CByteWasAcknowledged.
  • When reading a byte from the bus when you are the master, you need to call I2CReceiverEnable for each byte that you need to get.

These functions are not very special; the problem is that they are poorly documented.  For the most part, the plib functions simply access the registers directly in memory and return an appropriate value after checking the bits that may be set as a side effect.  It’s not particularly hard, they are just oddly named often times.

Anyway, you can see more about this both here and… some other place on the Microchip forums, I can’t find it now.

Hope that helps.

Dec 22

Adventures in accidental chown

So earlier today I had to get Virtualbox up and running, and it was complaining about permissions not being set right.  For some reason, the permissions on my /usr directory were slightly messed up and not owned by root.  So, I did:

sudo chown root:root /usr

That didn’t fix the problem.  Going into the /usr directory, I also noticed that a few of the other folders weren’t owned by root.  So, let’s just go fix everything at once:

sudo chown -R root:root /usr

Okay, now let’s try starting Virtualbox!

Virtualbox now complains about not being setuid.  Okay, fine.  Let’s reinstall virtualbox, since it says that should fix it.

sudo dpkg -i virtualbox.deb
sudo: must be setuid root

Oops.

 

Turns out, doing the chroot dropped the setuid bit from all binaries in the /usr directory.

To fix this, you’ll have to boot from a rescue disk/CD of some kind, and change the permissions on sudo:

chmod 4755 /path/to/mounted/filesystem/usr/bin/sudo

Other programs will also be messed up at that point, but now that you have sudo you can change the permissions to what they should be, and/or reinstall. 🙂

Oct 29

The Definition of Programming

Programming (noun): The art of putting together software that other people have written and breaking it in new and exciting ways.

 

It’s rare that you will have to create something entirely new from scratch.  So, it’s always a matter of taking things that have already been made and putting them together.

Conceptually, this a pretty simple idea.  In practice however, it’s much more complicated.  You need to know how exactly all the parts come together.  This is why good documentation of libraries is very important.  Without good documentation, it’s next to impossible to integrate a needed library.  You almost have to become an expert in how the library works, which rather defeats the purpose of using a library in the first place! This is very annoying.  Please, write good documentation!

 

Also, it seems that ‘programming’ could be both a noun and a verb, but Webster’s only defines it as a noun.  Seems like a bit of an oversight.

Aug 11

GNOME 3 Plugins: Settings

This post is going to be based partially on the source of Coverflow Alt Tab, plus some of the source files that are already included in GNOME 3.

Also, a few notes here: it appears at this time that there is no way to easily import your schema into the GSettings backend.  This may be added at a future time.  So, any settings that you make will essentially be unstructured and possibly break if somebody messes around with them.

The first thing for us to do is to create a new XML schema for us. This schema holds the keys to our values, as well as default values and descriptions.  There’s some documentation on the GNOME website, so i will only go over a small portion of what is there, given that I only understand a small portion. 🙂

For our purposes, we will define two keys: one string key which will be the text to display, and a boolean value that we will mess around with later.  For now, let’s define the XML schema:

<?xml version="1.0" encoding="UTF-8"?>
<schemalist>
  <schema id="com.rm5248.testplugin" path="/org/gnome/shell/extensions/rm5248/">
    <key type="s" name="hello-text" >
        <default>"Hello, World!"</default>
        <summary>The text to display</summary>
        <description>The text to display</description>
    </key>
    <key type="b" name="wait" >
        <default>false</default>
        <summary>Wait?</summary>
        <description>Do you wait until OK?</description>
    </key>
  </schema>
</schemalist>

This is pretty straightforward: you have a schema with a name(com.rm5248.testplugin) and two keys, a string value called ‘hello-text’ and a boolean vaue called ‘wait’.  Once we have written the XML file, we need to generate the binary version of it.  To do that, simply use the glib-compile-schemas tool:

glib-compile-schemas schemas/

Now that we have our compiled schema, it’s time to retrieve settings from the GSettings database.  In order to do that, we will need this lib.js file from CoverflowAltTab.  From the copyright, it appears to be from the GNOME sources, however I have been unable to find where it originally comes from.

Now that we have our schema compiled and in the schemas/ directory, it’s a very simple process to get the default settings(as we haven’t changed them at all.).  In fact, here’s the entire code:

const Gio = imports.gi.Gio;
const ThisExtension = imports.misc.extensionUtils.getCurrentExtension();
const Lib = ThisExtension.imports.lib;

const RM_SCHEMA = 'com.rm5248.testplugin';
const TEXT_KEY = 'hello-text';
const BOOL_KEY = 'wait';

let settings = null;

function init() {
    // Create the new settings
    settings = Lib.getSettings( RM_SCHEMA );
}

function enable() {
    log( settings.get_string( TEXT_KEY ) );
    log( settings.get_boolean( BOOL_KEY ) );
}

function disable() {
}

For now, we’re just printing out the settings to the console, which is not very useful. We’ll expand this in a bit, but before we do that let’s make a GTK widget to set the settings.  Looking at the GNOME documentation, we see that we can change settings by having a prefs.js file with a method buildPrefsWidget.

A quick note before we get started here: when constructing a C object, the parameters to the object(in the {} syntax) are properties to set on the object.  Take for example the properties on GTKLabel: if you want to set the ‘angle’ property when constructing, you would do:

new Gtk.Label( { angle: 20 } );

Do this for all the properties that you wish to set when you create the object.

Now, moving on to the actual code of the prefs.js file.  Everything here is fairly straightforward if you’ve done GTK+ programming before.  Here’s the code that will pop up a GTK+ widget:

function buildPrefsWidget(){
    let frame = new Gtk.Box( { orientation: Gtk.Orientation.VERTICAL, border_width: 10, spacing: 10 } );

    //There are two settings, so we will have one that changes the text and one that changes
    //the boolean value.
    //Create an EntryBuffer to store the text in
    let entryBuffer = new Gtk.EntryBuffer( { text: settings.get_string( TEXT_KEY ) } );
    let textBox = new Gtk.Box( { orientation: Gtk.Orientation.HORIZONTAL, spacing: 10 } );
    let textLabel = new Gtk.Label( { label: "Hello text", xalign: 0 } );
    let textEntry = new Gtk.Entry( { buffer: entryBuffer } );
    //Gtk.Entry implements GtkEditable interface, which is where the 'changed' signal comes from
    textEntry.connect( 'changed', function( widget ){
      settings.set_string( TEXT_KEY, widget.get_text() );
     } );
    textBox.pack_start( textLabel, true, true, 0 );
    textBox.add( textEntry );

    //Let's change our boolean value now
    let boolBox = new Gtk.Box( { orientation: Gtk.Orientation.HORIZONTAL, spacing: 10 } );
    let boolLabel = new Gtk.Label( { label: "Do we wait?", xalign: 0 } );
    let boolRadio = new Gtk.Switch( { active: settings.get_boolean( BOOL_KEY ) } );
    //Gtk.Switch has an 'activate' signal, but don't connect to that directly.
    //Instead, the docs say to use the 'notify::active' signal
    boolRadio.connect( 'notify::active', function( widget ){
        settings.set_boolean( BOOL_KEY, widget.get_active() );
     } );
    boolBox.pack_start( boolLabel, true, true, 0 );
    boolBox.add( boolRadio );

    frame.add( textBox );
    frame.add( boolBox );
    frame.show_all();

    return frame;
}

To test this out, re-load the shell (ALT+F2, r, enter), and open up gnome-tweak-tool.  Under ‘Extensions’, there should now be a small cog for the ‘settings example’ extension.  If you open that up, you should see the two settings that we made: one for the text, and one for the boolean value.  By changing these values, you can change what the extension will print out when the plugin is loaded.

You can also use dconf to see the values directly, once you have saved them first.  Change a value with gnome-tweak-tool, open up dconf and navigate to /org/gnome/shell/extensions/rm5248/, and you will see the settings that you have made.  Remember though, they only appear there if they are different from the defaults; this may not be true for all programs, but it is true for gnome-shell extensions.

You may find the complete source here.

Aug 08

GSettings

So I’m working on this settings stuff for GNOME 3, and I attempted to compile a new gsettings schema.  So I make my XML schema, and run glib-compile-schemas, and it comes back at me:

schemas/com.rm5248.testplugin.gschema.xml: 0-1:unknown keyword. This entire file has been ignored.

Okay… so I look at the file, and everything looks fine.  I can’t see anything wrong with it.  I go back and forth, trying different things, until I narrow it down to this key:

<key type="s" name="hello-text" >
        <default>Hello, World!</default>
        <summary>The text to display</summary>
        <description>The text to display</description>
    </key>

Commenting this out makes it work fine. So I look at the documentation for the schemas, and nothing immediately pops out at me, until I see the following:

One possible pitfall in doing schema conversion is that the default values in GSettings schemas are parsed by the GVariant parser. This means that strings need to include quotes in the XML.

So I change the XML to be the following:

<key type="s" name="hello-text" >
        <default>"Hello, World!"</default>
        <summary>The text to display</summary>
        <description>The text to display</description>
    </key>

What. The. Hell.

Why do string values have to be highlighted?  That doesn’t make a lot of sense.  There shouldn’t be any reason for that.  It is still valid XML, but who does it that way? Moreover, WHY DOESN’T THE ERROR MESSAGE GIVE ME ANY USEFUL INFORMATION? That is possibly the worst error message ever. Okay, it’s been ignored, BUT WHY THE HELL HAS IT BEEN IGNORED?! Is it really that hard to provide good error messages? Also, what the hell is the “0-1”? Is it some sort of bizzare error code or what? There’s nothing to imply that the reason it failed was because it was missing a quote – at least if it gave a line number that would let me clue in to what is going on, but apparently they can’t be bothered to do that.

Aug 07

GNOME 3 Plugins: DBus

I’m currently messing around with GNOME 3 plugins, and there’s not a whole lot of information out there.  Like, almost nothing.  So, as I’m working on this stuff I will be posting up some information and some small plugins that demonstrate a certain feature.  Whenever possible, I will also link to the relevant code or library function(or at least what I think the proper library/function is).

Now, before we get started, note that this information is for GNOME shell 3.8.4, which is what Debian 8 ships with, as well as Red Hat Enterprise Linux(RHEL) 7.  Also, a note to the GNOME devs: WRITE SOME DOCUMENTATION.  Seriously.  Even a generated API document that shows what methods are on each object in JavaScript would be better than what currently is available(re: nothing).

Note that this is also going to be a bit of a crash course in JavaScript for me, so I may say some completely incorrect things about JavaScript.  If I make any errors, please feel free to leave a comment to correct me.  If you could also put a source with that, that would be very helpful so that we can all learn.

Alright, now let’s get onto the examples!

Create a new Extension

This is covered in most of the tutorials already, but we of course need an extension to edit!  So, let’s create a new one with:

gnome-shell-extension-tool --create-extension

Now give it a name, description and UUID. You can see an example here.  The new extension will be in

~/.local/share/gnome-shell/extensions/<your-extension-id>

Once you have edited an extension, you will have to reload the gnome-shell in order for the changes to take effect.  To do this, do ALT+F2, type ‘r’, and hit enter.

To view the output of the console, you will have to use systemd’s journalctl(for Debian 8, and probably RHEL 7).  The command is:

journalctl /usr/bin/gnome-session -f -o cat

Source here.

Also, you can enable-disable extensions using gnome-tweak-tool.

Example 1: DBus Connections

If you’re unfamiliar with DBus concepts, I recommend that you take a look at my DBus tutorial.  The first thing that we are going to have to do is to define an XML interface(essentially, what the DBus Introspection method gives back).

So, using our old friend the DBus tutorial, we will create an interface that looks suspiciously similar to our first DBus example of simply echoing a string out to the console. Here’s the interface XML:

<interface name="com.rm5248.ReceiveInterface">
<method name="echoMessage">
    <arg type="s" direction="in" name="message"/>
</method>
</interface>

For each method that we put on the bus, we must have a method on our javascript object that has the same name.  If we don’t, we will get an error about there not being a method to call.

Here’s the important part that actually connects to the bus(DBusIface refers to the XML that we defined above):

    this._dbusImpl = Gio.DBusExportedObject.wrapJSObject( DBusIface, this );
    this._dbusImpl.export( Gio.DBus.session, '/' );

You can check to see that this method works using qdbus:

qdbus org.gnome.Shell / com.rm5248.ReceiveInterface.echoMessage hithere

You should now see the log printed out with your message.

This is all well and good, but what if we want to have our own DBus address?  We don’t want everything to be under the org.gnome.Shell address. To do that, we simple need to acquire the well-known name on the bus that we want to use:

this._dbusId = Gio.DBus.session.own_name( 'com.rm5248', Gio.BusNameOwnerFlags.NONE, this._nameAcquired, this._nameLost );

A note on this though: your object will still be accessible from the well-known bus names of ‘com.rm5248’ and ‘org.gnome.Shell’.  Essentially, ‘com.rm5248’ becomes an alias for ‘org.gnome.Shell’, so any path that you can access using ‘org.gnome.Shell’ you can also use ‘com.rm5248’.  This perhaps not a bug, but it is contrary to how most bindings work.

The source that I used for testing can be found here. I’ve commented as much as I can, given my knowledge of how it works.

Example 2: Sending Messages

Now that we have our connection on the bus, and we can receive messages, how do we send messages out?  Well, we need to do two things: Create a proxy, and then create an instance of that proxy.  Once we have the proxy, we can call the methods asynchronously or synchronously.  Here’s the important part of the code(note that DBusIface is the same XML that we defined earlier):

   
    const ReceiveInterface = Gio.DBusProxy.makeProxyWrapper( DBusIface );
    var prox = new ReceiveInterface( Gio.DBus.session, 'com.rm5248', '/', 
        // I don't know what this Lang.bind does, but it's very important(the
        // plugin will load very slowly if it isn't here)
        Lang.bind( this, function( proxy, error ){
            if( error ) {
                log('error: ' + error );
                return;
            }
        })
    );

    try{
        // There are two methods that are made on the javascript object: <name>Sync and <name>Remote.
        // <name>Sync calls the method synchronously, <name>Remote calls it async.  
        //  I don't know where the error message goes when you call it async; a message is printed
        // out in the console that the exception was ignored.
        prox.echoMessageSync( "hithere" );
    }catch( e ){
        // This could fail if the well-known bus name does not exist
        log( 'Error calling method: ' + e );
    }

So, now we can call methods on other objects.  You can get the source code for this example here.  Also, a note on calling methods: there appears to be a bug when calling with the ‘sync’ method, in that it will take a long time to return.  I will do some more investigation.

Coming up in our next tutorial: settings.

Aug 03

Israel and Palestine in 2014

As of today, Operation Protective Edge has been going on for almost four weeks.  There doesn’t seem to be a clear end in sight at the moment.  Here’s some thoughts on what it looks like to me.

While Israel is probably justified in responding to attacks from Hamas, the entire thing is completely stupid.

Why?

Well, you can’t bomb Hamas out of existence.  It’s just not going to happen.

Why does Hamas exist in the first place?  Well, I don’t claim to be an expert on the Middle East.  But there are several problems here.  First, unemployment is around 30%.  That is not to say that unemployment is the root of all the problems; and in fact may not be, as crime does not necessarily go up when unemployment goes up.  In addition to just the unemployment, the population in Gaza is very young.  If the Freakonomics guys are to believed, that is the root of the problem here.  Essentially, people have no future, so they turn to the one organization that can give them something: Hamas.

Now, back to the central question: Why can’t we just bomb Hamas out of existence?  Well a few reasons.

  1. Hamas does have a legitimate grief against Israel, to the extent that Israel takes up much more land now then they originally were supposed to in 1947, and is currently occupying the West Bank.
  2. Bombing people will, in general, make them resentful.
  3. The danger of Hamas isn’t in guns and bombs.

The dangerous man is the one who has only one idea, because then he’ll fight and die for it.

-Francis Crick

I don’t know if the above quote is actually from Crick, but I have seen it attributed to him.  This is the main problem with Hamas – they have an idea, and people turn to them because they feel that there’s no hope(my thoughts, I don’t know if that’s actually true).

So, what has to happen?

If you want to defeat Hamas, you need to weaken them(duh).  To do that, you need to reform them.  That simply isn’t going to happen while bombs are still dropping; it creates a lot of resentment.  A large investment in Gaza and the West Bank is what has to happen in order for people to have jobs and turn against Hamas.  After all, Hamas was first elected because the people in Gaza thought that they would be able to give them a better life – since that hasn’t happened, people have begun to turn against Hamas.  Since the sentiment is generally against Hamas, now is the time to come in and invest properly.

I don’t have a magic pill that will solve everything.  But there are things that should be done to make this a better world.  Even if there aren’t any formal peace negotiations, both sides should still talk to each other.  After all, what my uncle says is true:

You’re not going to solve any problems if you don’t talk to each other.

Not talking to other people means that you don’t go anywhere.  If you’re talking, you can at least get somewhere.