bittyboxen

Tonight I saw xscreensaver running on a Mac with my very own eyes! I committed an unnatural act upon rzr_grl's defenseless bittybox by installing The Disaster, fink, and through that, The Tail-Light Chaser and its nine billion prerequisites. I did my hacking on it remotely, running The Sink and CVS through SSH, so it was really just like using a real computer! (Except I had to be on the console for sudo to work, for some reason I don't understand.)

I only had to make a couple of tweaks to my configure script to get it to go. First, you have to run gcc with -no-cpp-precomp (to disable Objective C support) or else the compiler dumps core. And second, it was mis-detecting Kerberos. Or rather, it was correctly detecting that both Kerberos 4 and 5 are present, but I have no idea the right way to actually link against them, since there doesn't seem to be a libcrypt. Locking seems to work with the usual getpwent method, though.

The image-manipulating modes are unable to grab screenshots, and I don't expect to ever be able to fix that ("rootless" X being the totally wacko thing it is.) They are able to load images files from disk just fine, though, via gdk_pixbuf.

The GL hacks don't work, though. They display a motionless mess of static-y color noise on the window, after printing this when they start:

    kCGErrorIllegalArgument : initCGDisplayState: cannot map display interlocks.
    unknown error code : invalid display
    unknown error code : invalid display
    unknown error code : invalid display
    unknown error code : invalid display
    gl: couldn't allocate CGLContextObj

There were compilation weirdnesses too: it found multiple definitions of various GL functions, from both /usr/X11R6/lib/ and /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/. I'm guessing that it should be using one or the other, but I can't figure out how to tell it which to use. The warning message suggested using -bind_at_load, but that didn't affect things.

But here's the strangest part: if I run GL programs on Linux, remotely-displaying to the OSX box, they run fine -- and fast. So things work when going through X+GLX, just not locally.

Also it can't find libjpeg, even though I finked it. Who knows.

Anyone have any words of wisdom about the GL thing, or about Kerberos?

Tags: , , , , ,

33 Responses:

  1. ivorjawa says:

    Right off the bat, I can tell you to not link against the Framework version of OpenGL for an X program -- that's the Objective C library.

    You can find where apt-get'd stuff goes the standard debian way, using dpkg:

    root@gorman kujawa]$ dpkg -L libjpeg
    /.
    /sw
    /sw/include
    /sw/include/jconfig.h
    /sw/include/jerror.h
    /sw/include/jmorecfg.h
    /sw/include/jpeglib.h
    /sw/lib
    /sw/lib/libjpeg.a
    /sw/lib/libjpeg.la
    /sw/share
    /sw/share/doc
    /sw/share/doc/libjpeg
    /sw/share/doc/libjpeg/README
    /sw/lib/libjpeg.dylib

    I just logged into my girlfriend's OS X box remotely and was able to use sudo. Is the account you used to remotely log into rzr_grl's machine in the admin group? If not, you should add it through the Accounts preference panel, as I don't think that editing /etc/groups will be picked up by netinfo, and OS X is NeXTStep, after all.

    I can't help you on the kerberos thing. I've never had any reason to learn it.

    • jfpoole says:

      Right off the bat, I can tell you to not link against the Framework version of OpenGL for an X program -- that's the Objective C library.

      Indeed. Linking against the OpenGL libraries that come with Apple's X11 implementation should get the GL hacks working again; I'm linking against them on my OS X machine, and the GL hacks work quite well.

      I'm sort of surprised that xscreensaver is picking up the framework libraries. When I built xscreensaver configure did the right thing and picked the X11 libraries.

      • jwz says:

        Yeah, I dunno... this is what I'm seeing:

        gcc ... -L/usr/X11R6/lib -L/sw/lib -L/usr/X11R6/lib ...
                -lGL -lGLU -lpthread -lSM -lICE -lXt -lX11 -lXmu -lXext -lm

        ld: warning multiple definitions of symbol _glGetColorTableEXT
        /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib(gll_api.o) definition of _glGetColorTableEXT
        /usr/X11R6/lib/libGL.dylib(dri_dispatch.o) definition of _glGetColorTableEXT
        ... more of the above for a couple other symbols ...

        ld: warning suggest use of -bind_at_load, as lazy binding may result in errors or different symbols being used
        symbol _glGetColorTableEXT used from dynamic library /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib(gll_api.o) not from earlier dynamic library /usr/X11R6/lib/libGL.1.dylib(dri_dispatch.o)
        ... etc ...

        • jfpoole says:

          gcc ... -L/usr/local/lib ... -L/usr/X11R6/lib -lGL -lGLU -lpthread -lSM -lICE -lXt -lX11 -lXmu -lXext -lm

          I'm not picking up anything from fink, and /usr/local/lib only contains the Motif libraries. Perhaps one of the libraries in fink linked against the Framework OpenGL, or gcc is pulling library directories out of the environment?

        • jwz says:

          One of the XDarwin developers mailed me -- those runtime errors I was getting mean "the GL program is running as a different person than the person who is logged in on the desktop." Doh! Yup, that was the problem, they work fine if I run them as the desktop user.

          So the link-time warnings seem to be ignorable.

          Now that I see the GL hacks running, I see that many of them have wrong colors because my texture loaders have endian errors, sigh...

  2. ivorjawa says:

    Oh, and as for screen captures ... you can use the screencapture utility for that.
    The caveat is that it outputs to pdf. It'd be trivial to write a small Cocoa commandline program that converts that to something more reasonable, however.
    It won't be the most efficient method of grabbing a screen, it'll fork() twice and require a temporary file or two, but it'll work.

    • jwz says:

      Do you have any idea how to do a screen capture from the command line? If I can do it from Perl, and get hold of the output file, the problem's solved...

      • ivorjawa says:

        Screencapture. :)

        [kujawa@gorman kujawa]$ which screencapture
        /usr/sbin/screencapture
        [kujawa@gorman kujawa]$ screencapture --help
        screencapture: illegal usage, file required if not going to clipboard
        usage: screencapture [-icmwsWx] [file] [cursor]
        -i capture screen interactively, by selection or window
        control key - causes screen shot to go to clipboard
        space key - toggle between mouse selection and
        window selection modes
        escape key - cancels interactive screen shot
        -c force screen capture to go to the clipboard
        -m only capture the main monitor, undefined if -i is set
        -w only allow window selection mode
        -s only allow mouse selection mode
        -W start interaction in window selection mode
        -x do not play sounds
        file where to save the screen capture
        [kujawa@gorman kujawa]$

      • ivorjawa says:

        (of course, like I said, the output of screencapture is a PDF. Cocoa has trivial methods to convert from PDF to ... just about anything you could possibly want.)

        • jwz says:

          What are these methods? Are any of them usable from the command line? The only way I know is

            gs -q -dBATCH -dNOPAUSE -dSAFER -sDEVICE=pnmraw -sOutputFile=out.ppm -- in.pdf

          and GhostScript is certainly not guaranteed (or even likely) to be installed...

          • forthdude says:

            Hmm, it's (gs) on my machine (I don't remember getting it with fink, but since it's located in '/usr/local/bin' I guess I must have.)

            Also, I think Ivorjawa was refering to method calls in Cocoa, not programs. Of course, I could be wrong...

          • ivorjawa says:

            What it involves is writing a small Cocoa program that loads the PDF and spits it out in whatever form you want. A lot more reliable than ghostscript. I'll see if I can monkey something up after I have some coffee.

  3. grahams says:

    Which X server are you using? (Apple's X Server or XDarwin)

  4. akosut says:

    They're all pretty much the same, though, at least as of Mac OS X 10.2 (earlier versions were different). Adding -lkrb4 to the link command should be sufficient, and it looks like you're already doing that. I don't think libcrypt has anything to do with Kerberos, though. It's where many Unices keep crypt(); on Mac OS X, it's in libSystem (linked by default), so you don't need -lcrypt.

    The Kerberos support in xscreensaver won't work out of the box, regardless. It looks like passwd-kerberos.c relies heavily on the Unix-style file-based Kerberos credentials cache, which Mac OS X doesn't use. Try this instead:

    <lj-raw>


    --- passwd-kerberos.c.orig Tue Feb 11 09:47:25 2003
    +++ passwd-kerberos.c Tue Feb 11 10:31:42 2003
    @@ -27,6 +27,9 @@
    #include <string.h>
    #include <sys/types.h>

    +#ifdef __APPLE__
    +# include <Kerberos/Kerberos.h>
    +#else
    #ifdef HAVE_KERBEROS5
    # include <kerberosIV/krb.h>
    # include <kerberosIV/des.h>
    @@ -34,6 +37,7 @@
    # include <krb.h>
    # include <des.h>
    #endif /* !HAVE_KERBEROS5 */
    +#endif /* ! __APPLE__ */

    #if !defined(VMS) && !defined(HAVE_ADJUNCT_PASSWD)
    # include <pwd.h>
    @@ -56,10 +60,14 @@
    #define False 0

    /* The user information we need to store */
    +#ifdef __APPLE__
    +static KLPrincipal princ;
    +#else
    static char realm[REALM_SZ];
    static char name[ANAME_SZ];
    static char inst[INST_SZ];
    static char *tk_file;
    +#endif


    /* Called at startup to grab user, instance, and realm information
    @@ -83,6 +91,11 @@
    Bool
    kerberos_lock_init (int argc, char **argv, Bool verbose_p)
    {
    +#ifdef __APPLE__
    + KLBoolean found;
    + return KLCacheHasValidTickets(NULL, kerberosVersion_Any, &found, &princ,
    + NULL) == klNoErr && found;
    +#else /* !__APPLE__ */
    int k_errno;

    memset(name, 0, sizeof(name));
    @@ -117,6 +130,7 @@
    (REALM_SZ + ANAME_SZ + INST_SZ + 3)) {
    return False;
    }
    +#endif /* !__APPLE__ */

    /* success */
    return True;
    @@ -145,6 +159,10 @@
    Bool
    kerberos_passwd_valid_p (const char *typed_passwd, Bool verbose_p)
    {
    +#ifdef __APPLE__
    + return KLAcquireNewInitialTicketsWithPassword(princ, NULL, typed_passwd,
    + NULL) == klNoErr;
    +#else /* !__APPLE */
    C_Block mitkey;
    Bool success;
    char *newtkfile;
    @@ -182,6 +200,7 @@

    /* Did we verify successfully? */
    return success;
    +#endif /* !__APPLE__ */
    }

    #endif /* NO_LOCKING -- whole file */

    </lj-raw>

    • jwz says:

      Cool, thanks, I'll give that a try.

      I did try just leaving -lcrypt out, and then I get undefined symbols _tf_close, _tf_get_pinst,_tf_get_pname, and _tf_init. I don't know what those are or where they come from...

      But I'm somewhat lost as far as finding things goes, because the "locate" database is empty and I haven't figured out where slocate or cron.daily are (it's been a long time since I've used a BSD much.)

      • eaterofhands says:

        That's because, for whatever reason, Apple chose to not use anacron. root's crontab is /etc/crontab. In it you'll see that it runs the `periodic` command daily, weekly, and monthly. Run the weekly one manually if you want to build the locatedb, or set it to run at a more appropriate time. It its the system pretty hard with disc access though. There is a '/etc/periodic' directory that controls the different types of periodic runs.

        Installing anacon through fink will get around missed cron runs. You might have to setup a second crontab specific to fink's anacron though. I haven't bothered yet.

      • akosut says:

        The tf_* symbols are krb4 library functions for directly accessing the ticket file. Since Kerberos for Macintosh uses a memory-based credentials cache instead of ticket files, it doesn't implement those functions.

      • batmite2000 says:

        Try using the command 'updatedb' from the shell and see if it updates locate's DB file... :)

        Is that included as an executable in BSD type OS's? :)

  5. m4dh4tt3r says:

    I only had to make a couple of tweaks to my configure script to get it to go. First, you have to run gcc with -no-cpp-precomp

    I also discovered this one pretty quickly when I started trying to use OS X as a regular server for a client. There are quite a few idiosyncracies, but it's still damn cool.

  6. icis_machine says:

    fetch survives because people like the cute little fetch dog. how can you say no to his ears?

  7. ch says:

    Anyone have any words of wisdom about the GL thing, or about Kerberos?

    Install Linux-PPC ?

  8. loic says:

    Weird... Native GL apps definately work. I saw the GLUT examples working for sure.

    Are you running the latest patchlevel of OS X (as updated through the Software Update control panel), I know that there was an issue that had to be resolved in a software update that was made after X11 was finished.

  9. jcurious says:

    steps taken as an "admin" user (not root):
    ./configure
    make
    (bombs as mentioned)
    edit directory makefiles add -no-cpp-precomp to the CC=
    make clean
    make
    (fails on kerb stuff as mentioned)
    patched passwd-kerberos.c from comment
    make clean
    make
    (fails again..)
    remove -Lcrypt from driver/Makefile
    make clean
    make

    everything builds fine (even lament ;) until flurry)

    RESULT:
    gcc -Wall -no-cpp-precomp -Wstrict-prototypes -Wnested-externs -std=c89 -U__STRICT_ANSI__ -c -I. -I. -I./../../utils -I./.. -I../.. -DNEED_GNOMESUPPORT_H -I/sw/include/gtk-1.2 -I/usr/X11R6/include -I/sw/include/glib-1.2 -I/sw/lib/glib/include -I/sw/include/libcapplet1 -I/sw/include/gnome-1.0 -I/sw/lib/gnome-libs/include -I/sw/include -I/sw/include/orbit-1.0 -I/sw/include/gdk-pixbuf-1.0 -I/sw/include/libxml2 -I/sw/include/gdk-pixbuf-1.0 -I/sw/include/gtk-1.2 -I/sw/include/glib-1.2 -I/sw/lib/glib/include -I/usr/X11R6/include -DSTANDALONE -DUSE_GL -DHAVE_CONFIG_H -g -O2 -I/usr/X11R6/include flurry-smoke.c
    flurry-smoke.c: In function `UpdateSmoke_ScalarFrsqrte':
    flurry-smoke.c:248: warning: implicit declaration of function `asm'
    flurry-smoke.c:248: parse error before ':' token
    flurry-smoke.c:310: parse error before ':' token
    flurry-smoke.c:320: parse error before ':' token
    make[1]: *** [flurry-smoke.o] Error 1
    make: *** [default] Error 5

    • jfpoole says:

      Try the following patch. It should fix flurry-smoke.c so flurry builds. The problem is that flurry-smoke.c contains assembler statements, which aren't allowed with the -std=c89 switch.

      --- flurry-smoke.original Wed Feb 5 23:03:21 2003
      +++ flurry-smoke.c Wed Feb 5 23:18:57 2003
      @@ -242,11 +242,13 @@
      rsquared = (dx*dx+dy*dy+dz*dz);
      f = streamSpeed * streamSpeedCoherenceFactor;

      - /* mag = f / (float) sqrt(rsquared); */
      -
      - /* reciprocal square-root estimate replaced above divide and call to system sqrt() */
      - asm("frsqrte %0, %1" : "=f" (mag) : "f" (rsquared));
      - mag *= f;
      + mag = f / (float) sqrt(rsquared);
      + /*
      + reciprocal square-root estimate replaced above divide and call to system sqrt()
      +
      + asm("frsqrte %0, %1" : "=f" (mag) : "f" (rsquared));
      + mag *= f;
      + */

      s->p[s->nextParticle].delta[0].f[s->nextSubParticle] -= (dx * mag);
      s->p[s->nextParticle].delta[1].f[s->nextSubParticle] -= (dy * mag);
      @@ -307,18 +309,19 @@
      dz = s->p[i].position[2].f[k] - flurry->spark[j]->position[2];
      rsquared = (dx*dx+dy*dy+dz*dz);

      - asm("fres %0, %1" : "=f" (f) : "f" (rsquared));
      - f *= gravity*frameRateModifier;
      -
      + /*
      + asm("fres %0, %1" : "=f" (f) : "f" (rsquared));
      + f *= gravity*frameRateModifier;
      + */
      + f = ( gravity * frameRateModifier ) / rsquared;
      +
      if((((i*4)+k) % flurry->numStreams) == j) {
      f *= 1.0f + streamBias;
      }

      - /* mag = f / (float) sqrt(rsquared); */
      + mag = f / (float) sqrt(rsquared);

      /* reciprocal square-root estimate replaced above divide and call to system sqrt() */
      - asm("frsqrte %0, %1" : "=f" (mag) : "f" (rsquared));
      - mag *= f;

      deltax -= (dx * mag);
      deltay -= (dy * mag);
      @@ -411,8 +414,11 @@
      rsquared = (dx*dx+dy*dy+dz*dz);
      f = streamSpeed * streamSpeedCoherenceFactor;

      - asm("frsqrte %0, %1" : "=f" (mag) : "f" (rsquared));
      - mag *= f;
      + mag = f / (float) sqrt(rsquared);
      + /*
      + asm("frsqrte %0, %1" : "=f" (mag) : "f" (rsquared));
      + mag *= f;
      + */

      s->p[s->nextParticle].delta[0].f[s->nextSubParticle] -= (dx * mag);
      s->p[s->nextParticle].delta[1].f[s->nextSubParticle] -= (dy * mag);
      @@ -623,8 +629,11 @@
      rsquared = (dx*dx+dy*dy+dz*dz);
      f = streamSpeed * streamSpeedCoherenceFactor;

      - asm("frsqrte %0, %1" : "=f" (mag) : "f" (rsquared));
      - mag *= f;
      + mag = f / (float) sqrt(rsquared);
      + /*
      + asm("frsqrte %0, %1" : "=f" (mag) : "f" (rsquared));
      + mag *= f;
      + */

      s->p[s->nextParticle].delta[0].f[s->nextSubParticle] -= (dx * mag);
      s->p[s->nextParticle].delta[1].f[s->nextSubParticle] -= (dy * mag);