OSX Xboard 4.7.2 .app

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

User avatar
hgm
Posts: 27788
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: OSX Xboard 4.7.2 .app

Post by hgm »

OK, try this: directly after gtk_init(); in main() (gtk/xboard.c) we insert the following block of code:

Code: Select all

{
  GtkosxApplication *theApp = g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
  g_signal_connect(theApp, "NSApplicationOpenFile", G_CALLBACK(StartNewXBoard), NULL);
  if(argc == 1) { // called without args: OSX open-file signal might follow
    static char *fakeArgv[3] = {NULL, clickedFile, NULL};
    suppress = 1;
    usleep(10000); // wait 10 msec (and hope this is long enough).
    while(gtk_events_pending()) gtk_main_loop(); // process all events that came in upto now
    suppress = 0; // future open-file signals should start new instance
    if(clickedFile[0]) { // we were sent an open-file signal with filename!
      fakeArgv[0] = argv[0];
      argc = 2; argv = fakeArgv; // fake that we were called as "xboard filename"
    }
  }
}
The code we added in xoptions.c for StartNewXBoard must be moved to xboard.c, (e.g. to just above main()), and slightly altered, to:

Code: Select all

static char clickedFile[MSG_SIZ];
static int suppress;

static gboolean
StartNewXBoard(GtkosxApplication *app, gchar *path, gpointer user_data)
{
  if(suppress) { // we just started XBoard without arguments
    strncpy(clickedFile, path, MSG_SIZ); // remember file name 
  } else { // we are running something presumably useful
    char buf[MSG_SIZ];
    snprintf("open -n -a \"xboard\" \"%s\"", path);
    system(buf); // start new instance on this file
  }
  return TRUE;
}
The g_signal_connect line must also be removed from xoptions.c, as well as the old extern declaration of suppress in xboard.c.
JoshPettus
Posts: 730
Joined: Fri Oct 19, 2012 2:23 am

Re: OSX Xboard 4.7.2 .app

Post by JoshPettus »

Sorry I hate to ask you but I must have put it in wrong, is this correct?

Code: Select all

static char clickedFile[MSG_SIZ];
static int suppress;

static gboolean
StartNewXBoard(GtkosxApplication *app, gchar *path, gpointer user_data)
{
  if(suppress) { // we just started XBoard without arguments
    strncpy(clickedFile, path, MSG_SIZ); // remember file name
  } else { // we are running something presumably useful
    char buf[MSG_SIZ];
    snprintf("open -n -a \"xboard\" \"%s\"", path);
    system(buf); // start new instance on this file
  }
  return TRUE;
} 

int
main (int argc, char **argv)
{
    int i, clockFontPxlSize, coordFontPxlSize, fontPxlSize;
    int boardWidth, boardHeight, w, h;
    char *p;
    int forceMono = False;

    srandom(time(0)); // [HGM] book: make random truly random

    setbuf(stdout, NULL);
    setbuf(stderr, NULL);
    debugFP = stderr;

    if(argc > 1 && (!strcmp(argv[1], "-v" ) || !strcmp(argv[1], "--version" ))) {
	printf("%s version %s\n", PACKAGE_NAME, PACKAGE_VERSION);
	exit(0);
    }

    if(argc > 1 && !strcmp(argv[1], "--help" )) {
	PrintOptions();
	exit(0);
    }

    /* set up GTK */
    gtk_init (&argc, &argv);
{
  GtkosxApplication *theApp = g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
  g_signal_connect(theApp, "NSApplicationOpenFile", G_CALLBACK(StartNewXBoard), NULL);
  if(argc == 1) { // called without args: OSX open-file signal might follow
    static char *fakeArgv[3] = {NULL, clickedFile, NULL};
    suppress = 1;
    usleep(10000); // wait 10 msec (and hope this is long enough).
    while(gtk_events_pending()) gtk_main_loop(); // process all events that came in upto now
    suppress = 0; // future open-file signals should start new instance
    if(clickedFile[0]) { // we were sent an open-file signal with filename!
      fakeArgv[0] = argv[0];
      argc = 2; argv = fakeArgv; // fake that we were called as "xboard filename"
    }
  }
} 
Also we want to put in the
#include "gtkmacintegration/gtkosxapplication.h"
in xboard.c?

I see this error

Code: Select all

gtk/xboard.c: In function 'StartNewXBoard':
gtk/xboard.c:753:5: error: expected expression before ')' token
     snprintf("open -n -a \"xboard\" \"%s\"", path);
     ^
User avatar
hgm
Posts: 27788
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: OSX Xboard 4.7.2 .app

Post by hgm »

OK, sorry. I was so fixed on getting the quotes right, that I forgot to put in the two extra arguments that snprintf needs compared to printf. The line should have been

Code: Select all

snprintf(buf, MSG_SIZ, "open -n -a \"xboard\" \"%s\"", path);
And yes, you are right: the #include must also be put in xboard.c, or it would not know what things like GtkosxApplication mean. You could for instance put it directly behind the #include of gtk/gtk.h.
JoshPettus
Posts: 730
Joined: Fri Oct 19, 2012 2:23 am

Re: OSX Xboard 4.7.2 .app

Post by JoshPettus »

Damn..

Code: Select all

Undefined symbols for architecture x86_64:
  "_gtk_main_loop", referenced from:
      _main in xboard.o
ld: symbol(s) not found for architecture x86_64
What library is that from? Sounds like an important part of gtk for me not to have..

While I'm at it,
shouldn't it be:

Code: Select all

snprintf(buf, MSG_SIZ, "open -n -a \"xboard\" --args \"%s\"", path);
? I was going to find out the hard way but then this popped up.[/code]
User avatar
hgm
Posts: 27788
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: OSX Xboard 4.7.2 .app

Post by hgm »

OK, another oops... :oops:

This had to be gtk_main_iteration().
JoshPettus wrote:While I'm at it,
shouldn't it be:

Code: Select all

snprintf(buf, MSG_SIZ, "open -n -a "xboard" --args "%s"", path);
? I was going to find out the hard way but then this popped up.[/code]
Perhaps this might be indeed better. But I think the other one would work too. Because this is the case where the %s represents a file to be opened, and the --args was mainly needed to make things like "xboard -ncp" work.

The difference would be that with the --args XBoard would get the filename passed immediately (like in Linux), while without it, it would be send to it afterwards with an OpenFile signal. The new code should be able to handle the latter, but using XBoard the old way seems less risky. So put in the --arg.
JoshPettus
Posts: 730
Joined: Fri Oct 19, 2012 2:23 am

Re: OSX Xboard 4.7.2 .app

Post by JoshPettus »

with --args
didn't load on the first instance, It then loaded again and again on the second.

without --args
didn't load on the first instance
didn't load on the second


Interesting result, but I don't think we are getting what we want

I delted all the old suppression stuff as you said so the opening again and again is understandable, but the fact it isn't loading on the first instance is what bothers me.
JoshPettus
Posts: 730
Joined: Fri Oct 19, 2012 2:23 am

Re: OSX Xboard 4.7.2 .app

Post by JoshPettus »

Yah put the the suppression line back in, it loads the pgn file just fine, in a new instance, if xboard is already open. Is there any way we can get it to launch with xboard file.pgn if it isn't?
User avatar
hgm
Posts: 27788
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: OSX Xboard 4.7.2 .app

Post by hgm »

It seems that my design to catch the OpenFile signal on the first startup is not working. That explains why you never see the first click, and also why you would not see it load on later clicks withouth --args (when "open" simulates a first-click). It should start up an XBoard instance, however.

Seems we will have to do some debugging. Problem is that we won't always have a terminal to print on. So I guess we would have to let it print stuff to a file. In main():

Code: Select all

{
  GtkosxApplication *theApp = g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
  FILE *f = fopen("temp.debug", "a");
  fprintf(f, "%6d Start XBoard: argc = %d, arg = %s\n", getpid(), argc, argc > 1 ? argv[1] : "NONE");
  fclose(f);
And in StartNewXBoard:

Code: Select all

StartNewXBoard(GtkosxApplication *app, gchar *path, gpointer user_data)
{
  FILE *f = fopen("temp.debug", "a");
  fprintf(f, "%6d Signal: suppress = %d, path = %s\n", getpid(), suppress, path);
  fclose(f);
(Perhaps for temp.debug you would have to use a path name to a directory that is convenient for you to create the file temp.debug. This file should accumulate all debug output, as it is opened in 'append mode'.)
JoshPettus
Posts: 730
Joined: Fri Oct 19, 2012 2:23 am

Re: OSX Xboard 4.7.2 .app

Post by JoshPettus »

ok so If I wanted to just put it in my home directory where would I put that?

I treid putting ~/temp.debug in both instances but it created a binary that just outright crashed.

I then tried without it hoping it would just put it there and no file was created
User avatar
hgm
Posts: 27788
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: OSX Xboard 4.7.2 .app

Post by hgm »

I don't know what the path name of your home directory is. Type "pwd" in a terminal to let it print it. (On Linux it would be something like /home/joshua .)

[Edit]
Indeed, the ~ trick does not work on the level of the OS. It is the command shell that recognizes it and replaces it.