Logo Search packages:      
Sourcecode: papaya version File versions  Download package

external_app.cpp

/*
 * DO NOT EDIT THIS FILE - it is generated by Glade.
 */

#ifndef WIN32
#ifndef __CYGWIN__

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>

#include <unistd.h>

#include <stdio.h>
#include <stdlib.h>

#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>

#include <X11/Xlib.h>
#include <X11/Xmd.h>
#include <X11/Xutil.h>

#include "Message.h"
#include "Connection.h"
#include "BaseWindow.h"

extern BaseWindow * mainWindow;

GtkWidget *exec_window = NULL;
GtkWidget *exec_command_entry = NULL;
GtkWidget *exec_name_entry = NULL;
GtkWidget *exec_spinner = NULL;

GtkWidget * create_exec_window();

// Not multiple call safe...
Display * dpy;
Atom xa_wm_state;
int
is_mapped(Window window)
{
    Atom actual_type;
    int actual_format;
    unsigned long nitems;
    unsigned long bytes_after;
    unsigned char *prop;
    int retv;
    CARD32 state;

    retv = XGetWindowProperty(dpy, window, xa_wm_state, 0L, 1L, False, xa_wm_state,
                              &actual_type, &actual_format, &nitems, &bytes_after, &prop);

    if (retv != Success)            { return 0; }
    if (actual_type == None)        { return 0; }
    if (actual_type != xa_wm_state) { return 0; }
    if (nitems != 1)                { return 0; }
    if (actual_format != 32)        { return 0; }

    state = *((CARD32 *) prop);

    switch ((int) state) {
        case WithdrawnState: return 0;
        case NormalState:    return 1;
    case IconicState:    return 1;
    }

    /*
    ** We assume that the window manager knows what it is doing...
    */
    return 1;
}


struct ChildWindowInfo {

  int num_events;
  GtkWidget * socket;

};

#if 1
int exec_timeout(gpointer data) {

  XEvent event;
  bool ok = false;

  struct ChildWindowInfo * cwi = (struct ChildWindowInfo *)data;
  int num_events = cwi->num_events;
  GtkWidget * socket = cwi->socket;

  printf("Number of events to wait for: %d.\n", num_events);

  while (num_events > 0) {
    
    XNextEvent(dpy, &event);

    switch (event.type) {
    case CreateNotify:

      if (event.xcreatewindow.send_event) {
      break; // Ignore
      }
      if (event.xcreatewindow.override_redirect) {
      break; // Ignore
      }
      XSelectInput(dpy, event.xcreatewindow.window, PropertyChangeMask);

      // call is_mapped to see if the Window is mapped.
      if (is_mapped(event.xcreatewindow.window))
      ok = true;

      num_events--;
      if (num_events == 0) {
      gtk_socket_steal(GTK_SOCKET(socket), event.xcreatewindow.window);
      free(cwi);
      return 0;
      }
      break;

    case PropertyNotify:

      if (event.xproperty.send_event) {
      break; // Ignored
      }

      if (!is_mapped(event.xproperty.window))
      break; // Ignored
      // Accepted
      num_events--;
      if (num_events == 0) {
      gtk_socket_steal(GTK_SOCKET(socket), event.xproperty.window);
      free(cwi);
      return 0;
      }
      break;
    }
    
  }

  return 0;

}
#else
int exec_timeout(gpointer data) {
  int id = -1;
  FILE * fp;

  system("xwininfo -name unique_id | grep \"Window id\" | cut -d ' ' -f 4 > /tmp/mudclient.id");

  fp = fopen("/tmp/mudclient.id", "r");
  if (!fp)
    return -1;

  fscanf(fp, "%x", &id);
  fclose(fp);

  if (id < 0)
    return 1;

  // Attempt to swallow the window with id id.
  gtk_socket_steal(GTK_SOCKET(data), id);
  return 0;
}
#endif
 
void on_exec_app_button_clicked (GtkButton * button, gpointer user_data, gint i) {
   
  if (!exec_window)
    exec_window = create_exec_window();
  
  gtk_widget_show(exec_window);
}

void
on_exec_ok_button_clicked              (GtkButton       *button,
                                        gpointer         user_data)
{

  char * name;
  char command[16384];
  int num_events;

  if (!exec_window)
    return;

  name = (gchar *)gtk_entry_get_text(GTK_ENTRY(exec_name_entry));
  sprintf(command, "%s", (gchar *)gtk_entry_get_text(GTK_ENTRY(exec_command_entry)));

  num_events = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(exec_spinner));

  if (strlen(name) == 0 || strlen(command) == 0) {
    new Message("Command not specified", "Please specify a command, and a name for the notebook.", true);
    return;
  }

  printf("About to try and create a page for the app.\n");

  // Create a socket widget and stick it in the notebook.
  GtkWidget * socket = mainWindow->addPageForApp(name);

  printf("We added a page for the app.\n");

#if 0

  GtkWidget * socket = gtk_socket_new();
  gtk_widget_show(socket);

  GtkWidget * label = gtk_label_new(name);
  gtk_widget_show(label);

  gtk_notebook_append_page(mainWindow->notebook, socket, label);

#endif

  // Open the Display.
  dpy = XOpenDisplay(NULL);

  // Register interest in action on the root window
  XSelectInput(dpy, DefaultRootWindow(dpy), SubstructureNotifyMask);

  xa_wm_state = XInternAtom(dpy, "WM_STATE", False);

  // fork and exec to create the application
  int pid = fork();

  if (pid == 0) { // child

    int curr_arg = 0;
    char * args[20];
    char * last = command;
    char * pc;

    // Close the display on the child.
    //    XCloseDisplay(dpy);

    while (curr_arg < 19 && last) {
      pc = strchr(last, ' ');
      if (!pc) {
      args[curr_arg++] = strdup(last);
      last = NULL;
      } else {
      *pc='\0';
      args[curr_arg++] = strdup(last);
      last = pc+1;
      }
    }

    args[curr_arg] = NULL;
    execvp(command, args);

    // Should never reach this
    abort();
  } else {
    // Create a timeout to try and swallow the child

    struct ChildWindowInfo * cwi = (struct ChildWindowInfo *)malloc(sizeof(struct ChildWindowInfo));
    cwi->socket = socket;
    cwi->num_events = num_events;

    gtk_timeout_add(1000, exec_timeout, cwi);
  }

  gtk_widget_hide(exec_window);
  gtk_widget_destroy(exec_window);
  exec_window = NULL;

}


void
on_exec_cancel_button_clicked          (GtkButton       *button,
                                        gpointer         user_data)
{

  if (exec_window) {
    gtk_widget_hide(exec_window);
    gtk_widget_destroy(exec_window);
    exec_window = NULL;
  }

}



GtkWidget*
create_exec_window (void)
{
  GtkWidget *vbox1;
  GtkWidget *table1;
  GtkWidget *label1;
  GtkWidget *label2;
  GtkWidget *label3;
  GtkWidget *hbuttonbox1;
  GtkWidget *exec_ok_button;
  GtkWidget *exec_cancel_button;

  exec_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_object_set_data (GTK_OBJECT (exec_window), "exec_window", exec_window);
  gtk_window_set_title (GTK_WINDOW (exec_window), "Execute and Swallow Application");
  gtk_window_set_policy (GTK_WINDOW (exec_window), TRUE, TRUE, TRUE);

  vbox1 = gtk_vbox_new (FALSE, 0);
  gtk_widget_ref (vbox1);
  gtk_object_set_data_full (GTK_OBJECT (exec_window), "vbox1", vbox1,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (vbox1);
  gtk_container_add (GTK_CONTAINER (exec_window), vbox1);
  gtk_container_set_border_width (GTK_CONTAINER (vbox1), 3);

  table1 = gtk_table_new (2, 3, FALSE);
  gtk_widget_ref (table1);
  gtk_object_set_data_full (GTK_OBJECT (exec_window), "table1", table1,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (table1);
  gtk_box_pack_start (GTK_BOX (vbox1), table1, TRUE, TRUE, 0);
  gtk_table_set_col_spacings (GTK_TABLE (table1), 2);

  label1 = gtk_label_new ("Name");
  gtk_widget_ref (label1);
  gtk_object_set_data_full (GTK_OBJECT (exec_window), "label1", label1,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (label1);
  gtk_table_attach (GTK_TABLE (table1), label1, 0, 1, 0, 1,
                    (GtkAttachOptions) (0),
                    (GtkAttachOptions) (0), 0, 0);
  gtk_misc_set_alignment (GTK_MISC (label1), 7.45058e-09, 0.5);

  label2 = gtk_label_new ("Command");
  gtk_widget_ref (label2);
  gtk_object_set_data_full (GTK_OBJECT (exec_window), "label2", label2,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (label2);
  gtk_table_attach (GTK_TABLE (table1), label2, 0, 1, 1, 2,
                    (GtkAttachOptions) (0),
                    (GtkAttachOptions) (0), 0, 0);
  gtk_misc_set_alignment (GTK_MISC (label2), 7.45058e-09, 0.5);

  exec_command_entry = gtk_entry_new ();
  gtk_widget_ref (exec_command_entry);
  gtk_object_set_data_full (GTK_OBJECT (exec_window), "exec_command_entry", exec_command_entry,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (exec_command_entry);
  gtk_table_attach (GTK_TABLE (table1), exec_command_entry, 1, 2, 1, 2,
                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);

  exec_name_entry = gtk_entry_new ();
  gtk_widget_ref (exec_name_entry);
  gtk_object_set_data_full (GTK_OBJECT (exec_window), "exec_name_entry", exec_name_entry,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (exec_name_entry);
  gtk_table_attach (GTK_TABLE (table1), exec_name_entry, 1, 2, 0, 1,
                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);


  GtkAdjustment *spinner_adj;
  
  spinner_adj = (GtkAdjustment *) gtk_adjustment_new(1.0, 1.0, 100.0, 1.0, 1.0, 1.0);
  
  /* creates the spinner, with no decimal places */
  exec_spinner = gtk_spin_button_new (spinner_adj, 1.0, 0);
  gtk_widget_show(exec_spinner);

  // Attach the spinner to the table
  gtk_table_attach(GTK_TABLE(table1), exec_spinner, 1, 2, 2, 3,
               (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
               (GtkAttachOptions) (0), 0, 0);

  label3 = gtk_label_new("Grab window #");
  gtk_widget_ref (label3);
  gtk_object_set_data_full (GTK_OBJECT (exec_window), "label3", label3,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (label3);
  gtk_table_attach (GTK_TABLE (table1), label3, 0, 1, 2, 3,
                    (GtkAttachOptions) (0),
                    (GtkAttachOptions) (0), 0, 0);

  gtk_misc_set_alignment (GTK_MISC (label3), 7.45058e-09, 0.5);

  hbuttonbox1 = gtk_hbutton_box_new ();
  gtk_widget_ref (hbuttonbox1);
  gtk_object_set_data_full (GTK_OBJECT (exec_window), "hbuttonbox1", hbuttonbox1,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (hbuttonbox1);
  gtk_box_pack_start (GTK_BOX (vbox1), hbuttonbox1, FALSE, FALSE, 0);
  gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox1), GTK_BUTTONBOX_SPREAD);

  exec_ok_button = gtk_button_new_with_label ("Ok");
  gtk_widget_ref (exec_ok_button);
  gtk_object_set_data_full (GTK_OBJECT (exec_window), "exec_ok_button", exec_ok_button,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (exec_ok_button);
  gtk_container_add (GTK_CONTAINER (hbuttonbox1), exec_ok_button);
  GTK_WIDGET_SET_FLAGS (exec_ok_button, GTK_CAN_DEFAULT);

  exec_cancel_button = gtk_button_new_with_label ("Cancel");
  gtk_widget_ref (exec_cancel_button);
  gtk_object_set_data_full (GTK_OBJECT (exec_window), "exec_cancel_button", exec_cancel_button,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (exec_cancel_button);
  gtk_container_add (GTK_CONTAINER (hbuttonbox1), exec_cancel_button);
  GTK_WIDGET_SET_FLAGS (exec_cancel_button, GTK_CAN_DEFAULT);

  gtk_signal_connect (GTK_OBJECT (exec_ok_button), "clicked",
                      GTK_SIGNAL_FUNC (on_exec_ok_button_clicked),
                      NULL);
  gtk_signal_connect (GTK_OBJECT (exec_cancel_button), "clicked",
                      GTK_SIGNAL_FUNC (on_exec_cancel_button_clicked),
                      NULL);

  return exec_window;
}


#endif
#endif

Generated by  Doxygen 1.6.0   Back to index