Category Archives: programming

GSoC 2013: Red rectangle!

It turns out I’m slower with GSoC progress than anticipated. GNUstep meeting in Cambridge, which I’ll discuss in upcoming posts (and do so as soon possible, so I don’t forget all the wonderful sights and experiences, and all the wonderful people I met), was informative, but it turns out not quite supportive of my GSoC productivity. I spent a week being nervous before my first international trip, and I spent the last week (after returning) being impressed with how wonderful Germany and England are.

So, what progress did I make?

Preparations

First, before the trip, I prepared the backend. I figured out the simple things, such as where do I have to modify configure scripts in order to add support for the new backend, as well as which classes are expected by gnustep-gui. I identified the minimum set of methods that need to exist in the relevant classes (mostly OpalGState) and I added stubs.

Opal exposing X11 drawables as contexts

In Cambridge, thanks to help from Opal’s author Eric Wasylishen, we started exposing the creation of CGContext specific to X11 drawables. The function already existed in Opal; we just refactored the code a bit. (Rest of the hacking time in Cambridge was spent on other tasks.)

Drawing onscreen

Now that I finally cleared my head of amazement at how beautiful Cambridge is and how great hosts we had, I decided that it’s really long overdue that we get some content drawn on-screen. It took me a while to figure out where to draw in order to actually get the content drawn on-screen. It turns out the safest place to insert my dummy draw method is -[OpalGState DPSfill] — probably because it’s intended as the place to draw stuff, as opposed to various initialization methods such as -[OpalGState DPSinitgraphics].

The dummy draw method draws a red rectangle 1024×768, so I’m very happy to report that the test application’s NSWindow is, as of today, fully red.

Thoughts on next steps

Overall, I hope that things will roll much, much faster from here onward. There are bound to be many bugs along the way — and many assumptions by existing apps and themes. It’ll slow implementation down, but I hope that along the way I’ll figure out a way to clean up the current messy situation with gnustep-back‘s numerous classes such as GState, Context, et al.

The scariest part is that the Cairo backend looks like it handles many complex behaviors and different use situations. Let’s see how many bugs the Opal backend will have in the end and how much of Cairo backend’s behavior I’ll have to replicate to fix them. 🙂

Google killing XMPP federation with their Google Hangouts?

According to the Ars Technica article on Hangouts, we can expect Google to drop support for XMPP federation.

We should apparently be happy that Google is not dropping XMPP client-to-server connections.

The instant messaging space is apparently turning into a duopoly of Microsoft’s Skype and Google’s Hangouts with everyone else shoved to the sidelines. I’m not counting Facebook Chat as a serious alternative, and iMessage is not intended as an instant messaging service.

I hopefully don’t have to point out how much this frustrates and annoys me. Google is turning out to be worse than Microsoft ever was: they’re actively backpedaling on their past promises. They’re backstabbing the “open”. Scratch that — they’re throwing a stake through open’s heart, ripping it in pieces, then gorging on its still beating remains. Instead of reading RSS through Reader, we’re supposed to read custom posts via the closed and locked down Google+. They are killing iGoogle. They’re basically killing the open web and open Internet, while at the same time paying lip service to open.

Android, which is just-enough-Linux-but-not-really. Rich authorship markup, which requires two-way linking to Google+ instead of using the semantic web techniques.

I’ll keep on looking for ways to back out of Google ecosystem as much as possible. What’s next — Gmail that can’t send emails out?

A simple WiX template for games

Over the last few days, I’ve got some comments and emails about my old, old post about WiX in which I promised to release a functional template.

Since that work with WiX was originally done for some games, and in the meantime I began working with OS X most of the time, it took “a while” for me to grab some time and remove company branding, create a sample project, and finally prepare and release the template for my own as well as other people’s use.

You can the template from its Bitbucket repository . Have fun!

Core Data: Migrating ignores manual mapping model (or fails migration) despite mapping model's existence

Let’s say you created a somewhat complex migration model. Among other things, let’s say it includes entity migration policies (you know — subclasses of NSEntityMigrationPolicy).

However, Core Data ignores your manual migration model. Why, oh why?

You can try looking into this by clicking on schema name in Xcode 4, picking the “Run” sidebar ‘tab’, picking the “Arguments” tab, and adding -com.apple.CoreData.MigrationDebug 1. (See tech note TN2124.)

Alright, so now you see what the source persistent store’s version hashes are, and what the expected destination store’s version hashes should be. Then you see how Core Data starts migration by telling you its conclusion about what the hashes are (for the second time). Finally, it starts iterating over your manual mapping models (the .xcmappingmodel bundles).

And then you see that it finds your mapping model, picks up on it, then decides the hashes are wrong and ignores it!

“What the…?” you wonder. You compare hashes, and they are listed in different order, but essentially the same.

I can only conclude this is a bug in Core Data (or in the entity editor in Xcode4).

Luckily it’s easy to remedy! Go to the mapping model, pick another source and destination model version, then restore to the correct source and destination model versions. Definitely do make a git commit prior to making this change so you can compare what happened.

Alternatively, an answer on StackOverflow has a different solution which can be applied in case you know what is the version of the original persistent store. It involves manually setting version hashes on the NSEntityMappings inside the NSMappingModel.

Patching an unrecognized selector into a misbehaving OS X app

Let’s say you have an app that misbehaves. As in, it raises an exception mentioning an unrecognized selector.

Of course, it’s third party and closed-source.

But you are an enterprising young developer and you really want to patch this app.

I will not identify the app that I patched, to avoid any impression that I’m cracking the app. (It’s a popular app and I’ve run into pretty nice anti piracy protection blocking gdb on multiple layers. Since I’m not familiar with cracking and was not even attempting that, I’ve decided that it’s best to simply avoid mentioning the app name.)

Makefile

all: misbehavingappfixer.dylib

misbehavingappfixer.dylib: misbehavingappfixer.o
        gcc \
                -dynamiclib \
                -undefined suppress -flat_namespace \
                misbehavingappfixer.o \
                -framework Cocoa -o misbehavingappfixer.dylib
run:
        DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES=`pwd`/misbehavingappfixer.dylib /Applications/Misbehaving\ App.app/Contents/MacOS/Misbehaving\ App

misbehavingappfixer.c

#include 
#include 
static CFStringRef nameImp(id self, SEL _cmd)
{
        return CFSTR("IVFlawedClass");
}

void inject_init(void) __attribute__((constructor));
void inject_init(void)
{
        Class _IVFlawedClass = objc_getClass("IVFlawedClass");
        if(!_IVFlawedClass)
        {
                printf("Could not find IVFlawedClass");
                return;
        }

        SEL nameSel = sel_registerName("name");
        class_addMethod(_IVFlawedClass, nameSel, (IMP)nameImp, "@@:");
}

I avoided using Objective-C because I had some issues when I tried going that route. It should work, but I didn’t want to spend any more time on this than I already have.

Now, to use this:

make
make run

This will compile the fix dylib, and then launch the Misbehaving App while first preloading our fix dylib.

For more information, see these:

Note: from comments on Mike Ash’s post, it seems that since I’m not overwriting symbols, I don’t need to (and, more importantly, *should* not) be using flat namespace. That means, I should not be using DYLD_FORCE_FLAT_NAMESPACE and -flat_namespace.

But, it works for me, so what the hell. 🙂

Little tips on writing portable plugins (and rant on MSVC)

Having written a smallish plugin for a cross-platform database program FileMaker using a template that included projects for Xcode and VC, here’s a few tips on what you should think about when you start writing a plugin that should work on multiple platforms.

  1. Work on the Windows version first. If you’re at home on non-Windows platforms, MSVC will surprise you in numerous ways with its oddities and weird, outdated support for C.
  2. Write as much code in C for portability.
  3. Write in C90. Microsoft Visual Studio will barf a lot at you otherwise.
  4. If you disregarded #3 and wrote the code in C99 (for example, you declared variables during the function body instead of on the top of the function), you’ll have to switch to C++ to avoid changes to your code.
  5. Don’t write smart code. For example, MSVC barfs at the following:

    typedef struct _IVRect
    {
      int x, y, w, h;
    } IVRect;
    
    IVRect r = { .x = 5, .y = 6, .w = 7, .h = 8 };
    
    // but the following is ok. just don't change the order of
    // struct members. if you do -- woe upon you:
    IVRect s = { 5, 6, 7, 8 };
    

    and it especially barfs at the following:

    // given int IVRectSurfaceSum(const int rectCount, Rect * r):
    int surface = IVRectSurface(2, (IVRect[]) 
      {
        { .x = 5, .y = 6, .w = 7, .h = 8 },
        { .x = 1, .y = 2, .w = 3, .h = 4 } 
      });
    
  6. Use as many open source libraries available for majority of your platforms.
  7. …but always check what MSVC can swallow and what your target app uses. I have used version of libxml2 that depended on the newer zlib1.dll than has shipped with FileMaker. The only solution I found is — replacing FileMaker’s zlib1.dll. That’s nasty.
  8. Always write a small test C program that uses the same functions as your plugin. Port that to every platform first. On Windows, I couldn’t get stdout from my plugin once it ran under FileMaker. If I could’ve, I would’ve saved about a day of frustration why signing with xmlsec didn’t work. (xmlsec’s debug output wasn’t displayed anywhere, either).
  9. Get used to #ifdef _MSC_VER. Get really, really, really used to it.
  10. Since I’m not sure you could figure that out… I have a very low opinion about Visual C++. I did hear it produces nice, fast code. But that doesn’t change the fact that it’s terrible to use with low coverage of modern C. Actually, scratch that: nonexistent coverage of modern C.

    I mean, it’s so nasty that I’m wondering if I should have built a helper static library (or a DLL) which contained the C code using MinGW, and then used this helper library in the plugin itself.

    Visual C++ was — for me — slow, had little conformance with modern standards, and every time I had to copypaste something somewhere using GUI, a little part of me died. A slightly larger part if I had to overwrite something else, as was the case with zlib1.dll.

    I don’t know. Sure, it’s mostly familiarity-with-other-IDEs speaking out of me. Sure, tons and tons of people prefer and absolutely love Visual C++. Good for them.

    But, I apparently love modern language features far, far more. So, if you are like me, and if you are forced to build something with MSVC (an example might be — the SDK you’re writing the plugin with chose to use C++, hence the ABI is locked into MSVC), you really, really, really should constantly doublecheck if MSVC will eat up what you try to serve to it.

    Because if you used to work with Windows, and if you are nowadays mostly targeting another platform (or at least another compiler), and if you think you’re writing portable code — you may be in for a nasty surprise.

    Especially if you use third-party libraries!