Index: src/gpsdrive_config.c =================================================================== --- src/gpsdrive_config.c (revision 1855) +++ src/gpsdrive_config.c (working copy) @@ -643,4 +643,7 @@ /* kismet default values */ g_strlcpy(local_config.kismet_servername, "localhost", sizeof(local_config.kismet_servername)); local_config.kismet_serverport = 2501; + + /* run a normal GUI by default */ + local_config.embedded_gui_mode = NOT_EMBEDDED; } Index: src/gpsdrive_config.h =================================================================== --- src/gpsdrive_config.h (revision 1855) +++ src/gpsdrive_config.h (working copy) @@ -45,6 +45,13 @@ void writeconfig (); void readconfig (); void config_init (); + +typedef enum _embedded_gui_mode { + NOT_EMBEDDED = 0, + EMBEDDED_WITH_QUIT_ALLOWED = 1, + EMBEDDED_NO_QUIT_ALLOWED = 2, +} EmbeddedGuiMode; + typedef struct { gchar config_file[500]; @@ -111,6 +118,9 @@ gchar kismet_servername[500]; gint kismet_serverport; gchar screenshot_dir[1000]; + EmbeddedGuiMode embedded_gui_mode; /**< uses GTK Plug instead of Window; + * expects to be embedded in a separate + * GTK app */ } local_gpsdrive_config; Index: src/main_gui.c =================================================================== --- src/main_gui.c (revision 1855) +++ src/main_gui.c (working copy) @@ -213,7 +213,17 @@ gint quit_program_cb (GtkWidget *widget, gpointer datum) { - gtk_main_quit (); + /* This is called when the top-level GpsDrive window is closed OR + * the user selects "Quit" from the menu. + * In the case that the GUI is embedded into a separate application, + * that may not be desirable behavior, so we can disallow it by + * using '-m 2' on the command line (thus setting + * local_config.embedded_gui_mode=EMBEDDED_NO_QUIT_ALLOWED). + * (Note that GpsDrive can still be killed by sending it a + * SIGTERM.) */ + if (local_config.embedded_gui_mode != EMBEDDED_NO_QUIT_ALLOWED) { + gtk_main_quit (); + } return TRUE; } @@ -2292,7 +2302,28 @@ if ( mydebug > 11 ) fprintf(stderr,"create_main_window\n"); +#ifndef _WIN32 + if (NOT_EMBEDDED == local_config.embedded_gui_mode) { + /* the default */ + main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + } + else { + /* embeddable-GUI mode means no GUI appears until it is + * hooked into a GTK Socket widget in a separate application. + * Thus, we print out the window ID here so that the other + * app can pass that to the GTK Socket's add_id() method. */ + main_window = gtk_plug_new(0); + /* gtk_plug_get_id() returns a GdkNativeWindow, which is + * really a guint32 on all platforms according to: + * https://www.linux-foundation.org/dbadmin/browse/type_single.php?cmd=list-by-id&Tid=12788 + */ + fprintf(stdout, "Main Window ID is 0x%08x\n", + gtk_plug_get_id(GTK_PLUG(main_window))); + } +#else /* _WIN32 */ main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); +#endif /* !_WIN32 */ + g_snprintf (main_title, sizeof (main_title), "%s v%s", "GpsDrive", VERSION); Index: src/gpsdrive.c =================================================================== --- src/gpsdrive.c (revision 1855) +++ src/gpsdrive.c (working copy) @@ -2656,6 +2656,10 @@ _("-b server servername for NMEA server (if gpsd runs on another host)\n"), _("-c WP set start position in simulation mode to this waypoint (WP)\n"), _("-M mode set GUI mode; mode may be 'desktop' (default), 'pda' or 'car'\n"), + _("-m X embeddable GUI mode; no GUI appears; for use in external GTK apps\n"), + _(" 0 = not embedded (default)\n"), + _(" 1 = embedded, Quit allowed, closes GpsDrive when window closed\n"), + _(" 2 = embedded, no Quit allowed (quit by sending SIGTERM/KILL)\n"), _("-i ignore NMEA checksum (risky, only for broken GPS receivers\n"), _("-q disable SQL support\n"), _("-F force display of position even it is invalid\n"), @@ -2700,7 +2704,7 @@ { /* long options plus --geometry and -g */ i = getopt_long (argc, argv, - "W:ES:A:ab:c:X1qivPdD:TFepC:H:hnf:l:t:so:g:M:?", + "W:ES:A:ab:c:X1qivPdD:TFepC:H:hnf:l:t:so:g:M:m:?", long_options, &option_index); #else do @@ -2763,6 +2767,24 @@ exit(-1); } break; + case 'm': + switch (strtol (optarg, NULL, 0)) + { + case 0: + local_config.embedded_gui_mode = NOT_EMBEDDED; + break; + case 1: + local_config.embedded_gui_mode = EMBEDDED_WITH_QUIT_ALLOWED; + break; + case 2: + local_config.embedded_gui_mode = EMBEDDED_NO_QUIT_ALLOWED; + break; + default: + (void) fprintf(stderr, "Unknown embedded GUI ('-m') option" + "value\n"); + break; + } + break; case '1': onemousebutton = TRUE; break;