void sn_startup(gboolean reconfig)
{
    if (reconfig) return;

    sn_display = sn_display_new(obt_display, NULL, NULL);
    sn_context = sn_monitor_context_new(sn_display, ob_screen,
                                        sn_event_func, NULL, NULL);
    sn_launcher = sn_launcher_context_new(sn_display, ob_screen);

    xqueue_add_callback(sn_handler, NULL);
}
Exemple #2
0
void sn_startup(gboolean reconfig)
{
    if (reconfig) return;

    sn_display = sn_display_new(obt_display, NULL, NULL);
    sn_context = sn_monitor_context_new(sn_display, ob_screen,
                                        sn_event_func, NULL, NULL);
    sn_launcher = sn_launcher_context_new(sn_display, ob_screen);

    obt_main_loop_x_add(ob_main_loop, sn_handler, NULL, NULL);
}
Exemple #3
0
void init_X11() {
    server.dsp = XOpenDisplay(NULL);
    if (!server.dsp) DIE("tint: could not open display.");

    server_init_atoms();
    server.screen = DefaultScreen(server.dsp);
    server.root_win = RootWindow(server.dsp, server.screen);
    server.desktop = server_get_current_desktop();
    server_init_visual();
    XSetErrorHandler((XErrorHandler)server_catch_error);

#ifdef HAVE_SN
    // Initialize startup-notification
    server.sn_dsp = sn_display_new(server.dsp, error_trap_push, error_trap_pop);
    server.pids = g_tree_new(cmp_ptr);
    // Setup a handler for child termination
    struct sigaction act;
    memset(&act, 0, sizeof(struct sigaction));
    act.sa_handler = sigchld_handler;
    if (sigaction(SIGCHLD, &act, 0)) {
        perror("sigaction");
    }
#endif  // HAVE_SN

    imlib_context_set_display(server.dsp);
    imlib_context_set_visual(server.visual);
    imlib_context_set_colormap(server.colormap);

    /* Catch events */
    XSelectInput(server.dsp, server.root_win,
                 PropertyChangeMask | StructureNotifyMask);

    setlocale(LC_ALL, "");
    // config file use '.' as decimal separator
    setlocale(LC_NUMERIC, "POSIX");

    // load default icon
    gchar* path;
    const gchar* const* data_dirs;
    data_dirs = g_get_system_data_dirs();
    int i;
    for (i = 0; data_dirs[i] != NULL; i++) {
        path = g_build_filename(data_dirs[i], "tinto", "default_icon.png", NULL);
        if (g_file_test(path, G_FILE_TEST_EXISTS))
            default_icon = imlib_load_image(path);
        g_free(path);
    }

    // get monitor and desktop config
    get_monitors();
    get_desktops();
}
Exemple #4
0
void XDesktopContainer::eventLoop()
{
    XEvent ev;
#ifdef HAVE_STARTUP_NOTIFICATION
    sn_context = NULL;
    sn_display = NULL; 
    sn_bool_t retval;
    sn_display = sn_display_new (display,
        		         error_trap_push,
				 error_trap_pop);

#endif /* HAVE_STARTUP_NOTIFICATION  */
    
    for(;;)
    {
        if( !XPending( display ) && timer){
		if(!bg->IsOneShot()){
			timer->Update();
		}
	}
	else {
	 
          XNextEvent(display, &ev);
#ifdef HAVE_STARTUP_NOTIFICATION
	  if (sn_display != NULL){
	   sn_display_process_event (sn_display, &ev);
          }
#endif /* HAVE_STARTUP_NOTIFICATION  */
          event = ev;
          parseEvent();
	}
    }
    
#ifdef HAVE_STARTUP_NOTIFICATION
    sn_launcher_context_unref (sn_context);
    if (sn_display)
    {
       sn_display_unref (sn_display);
    }
#endif /* HAVE_STARTUP_NOTIFICATION  */
}
static void
startup_notification_complete(void)
{
	Display *xdisplay;

	xdisplay = GDK_DISPLAY();
	sn_display = sn_display_new(xdisplay,
								sn_error_trap_push,
								sn_error_trap_pop);
	sn_context =
		sn_launchee_context_new_from_environment(sn_display,
												 DefaultScreen(xdisplay));

	if (sn_context != NULL)
	{
		sn_launchee_context_complete(sn_context);
		sn_launchee_context_unref(sn_context);

		sn_display_unref(sn_display);
	}
}
Exemple #6
0
StartupNotify *startup_notify_start(const char *program, const char *icon) {
#ifdef HAVE_LIBSTARTUP_NOTIFICATION
	const char *id;
	fl_open_display();

	StartupNotify *s = new StartupNotify;
	s->display = sn_display_new(fl_display, error_trap_push, error_trap_pop);
	s->context = sn_launcher_context_new(s->display, fl_screen);

	sn_launcher_context_set_binary_name(s->context, program);
	sn_launcher_context_set_icon_name(s->context, icon);
	sn_launcher_context_initiate(s->context, "ede-launch", program, CurrentTime);

	id = sn_launcher_context_get_startup_id(s->context);
	if(!id) id = "";

	edelib_setenv("DESKTOP_STARTUP_ID", id, 1);
	XSync(fl_display, False);

	return s;
#else
	return 0;
#endif
}
// Indicate that launchee has completed startup
void startup_completed(void)
{
    SnLauncheeContext* launchee;
    Display*           xdisplay;
    SnDisplay*         display;

    // Open display
    xdisplay = XOpenDisplay(NULL);
    if (xdisplay != NULL)
    {
        // Create startup notification context
        display = sn_display_new(xdisplay, NULL, NULL);
        launchee = sn_launchee_context_new_from_environment(display, DefaultScreen(xdisplay));

        // Indicate startup has completed and free resources
        if (launchee)
        {
            sn_launchee_context_complete(launchee);
            sn_launchee_context_unref(launchee);
        }
        sn_display_unref(display);
        XCloseDisplay(xdisplay);
    }
}
int 
main(int argc, char **argv)
{
  int i, x, y;

  /* Config Parameters */
  int switch_count      = 1;
  char *img_file        = NULL;
  char *dotdesktop_file = NULL;
  MBDotDesktop *dd      = NULL;
  Bool start_app        = False;
  char png_path[256]    = { 0 };

  TrayApp = mb_tray_app_new ( "mb-applet-launcher",
			      resize_callback,
			      paint_callback,
			      &argc,
			      &argv );  

  for (i = 1; i < argc; i++) {
    if (argv[i][0] == '-')
      {

	if (!strcmp ("--title", argv[i]) || !strcmp ("-n", argv[i])) {
	  if (++i>=argc) usage (argv[0]);
	  win_panel_title = argv[i];
	  switch_count += 2;
	  continue;
	}

	if (!strcmp ("--kill", argv[i]) || !strcmp ("-k", argv[i])) {
	  action = ACTION_KILL;
	  switch_count++;
	  continue;
	}

	if (!strcmp ("--start", argv[i]) || !strcmp ("-s", argv[i])) {
	  start_app = True;
	  switch_count++;
	  continue;
	}
	
	if (!strcmp ("--kill", argv[i]) || !strcmp ("-k", argv[i])) {
	  action = ACTION_KILL;
	  switch_count++;
	  continue;
	}
	
	if (!strcmp ("--relaunch", argv[i]) || !strcmp ("-l", argv[i])) {
	  action = ACTION_NONE;
	  switch_count++;
	  continue;
	}
	
	if (!strcmp ("--message", argv[i]) || !strcmp ("-m", argv[i])) {
	  action = ACTION_MESSAGE_DOCK;
	  switch_count++;
	  continue;
	}

	if (!strcmp ("--no-animation", argv[i]) || !strcmp ("-na", argv[i])) {
	  DoAnimation = False;
	  switch_count++;
	  continue;
	}

	if (!strcmp ("--desktop", argv[i])) {
	  if (++i>=argc) usage (argv[0]);
	  dotdesktop_file = argv[i];
	  switch_count += 2;
	  continue;
	}
	usage(argv[0]);
      }
    else break;
  }

  if (argc-switch_count < 2 && dotdesktop_file == NULL) usage(argv[0]);

  dpy    = mb_tray_app_xdisplay(TrayApp);
  screen = mb_tray_app_xscreen(TrayApp);

  atom_wm_state  = XInternAtom(dpy, "WM_STATE", False);
  atom_wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
  atom_wm_protos = XInternAtom(dpy, "WM_PROTOCOLS", False);

  pb = mb_pixbuf_new(dpy, mb_tray_app_xscreen(TrayApp));

  if (dotdesktop_file != NULL)
    {
      if ((dd = mb_dotdesktop_new_from_file(dotdesktop_file)) != NULL
	  && mb_dotdesktop_get(dd, "Name")
	  && mb_dotdesktop_get(dd, "Icon")
	  && mb_dotdesktop_get(dd, "Exec") )
	{

	  img_file = mb_dotdesktop_get(dd, "Icon");

	  if (img_file[0] != '/')
	    {
	      snprintf(png_path, 256, "%s/pixmaps/%s", DATADIR,  
		       mb_dotdesktop_get(dd, "Icon") );
	      img_file = strdup(png_path);
	    }

	  cmd_str  = mb_dotdesktop_get_exec(dd);
	  if (!win_panel_title) 
	    win_panel_title = mb_dotdesktop_get(dd, "Name");
#ifdef USE_LIBSN

	  if (mb_dotdesktop_get(dd, "SingleInstance")
	      && !strcasecmp(mb_dotdesktop_get(dd, "SingleInstance"), 
			     "true"))
	    {
	      action = ACTION_SI;
	    }
	  else if (mb_dotdesktop_get(dd, "StartupNotify")
		   && !strcasecmp(mb_dotdesktop_get(dd, "StartupNotify"), 
				  "true"))
	    {
	      action = ACTION_SN;
	    }
	  else   
#endif
	    if (mb_dotdesktop_get(dd, "X-MB-NoWindow")
		&& !strcasecmp(mb_dotdesktop_get(dd, "X-MB-NoWindow"), 
			       "true"))
	      {
		DoAnimation = False;
		action = ACTION_NONE;
	      }	
	}
      else
	{
	  fprintf(stderr,"%s: failed to parse %s\n", 
		  argv[0], dotdesktop_file); 
	  exit(1);
	}

    } else {
      img_file = argv[switch_count];

      if (img_file[0] != '/')
	{
	  /* FIXME: should really get from theme */
	  snprintf(png_path, 256, "%s/pixmaps/%s", DATADIR, img_file);
	  img_file = strdup(png_path);
	}

      cmd_str  = arr_to_str(&argv[switch_count+1], argc - switch_count - 1);
    }

  if (!(img_icon = mb_pixbuf_img_new_from_file(pb, img_file)))
    {
      fprintf(stderr, "%s: failed to load image %s \n", 
	      argv[0], img_file );
      exit(1);
    }

  /* make active button image */
  img_icon_active = mb_pixbuf_img_clone(pb, img_icon);

  for (x=0; x<mb_pixbuf_img_get_width(img_icon); x++)
    for (y=0; y<mb_pixbuf_img_get_height(img_icon); y++)
      {
	int aa;
	unsigned char r,g,b,a;
	mb_pixbuf_img_get_pixel (pb, img_icon_active, x, y, &r, &g, &b, &a);

	aa = (int)a;
	aa -=  0x80; if (aa < 0) aa = 0;

	mb_pixbuf_img_set_pixel_alpha(img_icon_active, x, y, aa);
      }


#ifdef USE_LIBSN
  if (action == ACTION_SN || action == ACTION_SI)
    sn_dpy = sn_display_new (dpy, NULL, NULL);
#endif

  mb_tray_app_set_xevent_callback (TrayApp, xevent_callback );

  mb_tray_app_set_button_callback (TrayApp, button_callback );


  if (win_panel_title == NULL) 	/* XXX UTF8 naming */
    {
      win_panel_title = malloc( strlen(argv[1+switch_count]) +
				strlen(" Launcher") + 1 ); 
      strcpy(win_panel_title, argv[1+switch_count]);
      strcat(win_panel_title, " Launcher");
    }
  
  mb_tray_app_set_name (TrayApp, win_panel_title);

  XSelectInput(dpy, mb_tray_app_xrootwin(TrayApp), SubstructureNotifyMask);

  signal(SIGCHLD, SIG_IGN);

  mb_tray_app_set_icon(TrayApp, pb, img_icon);

  /* make sure we always end up on the left of the panel */
  mb_tray_app_request_offset (TrayApp, -1); 

  if (start_app)
    {
      switch(action)
	{
#ifdef USE_LIBSN
	case ACTION_SN:
	  sn_activate(win_panel_title, cmd_str);
	  break;
	case ACTION_SI:
	  si_activate(win_panel_title, cmd_str);
	  break;
#endif
	case ACTION_NONE:
	  fork_exec(cmd_str);
	  break;
	case ACTION_KILL:
	case ACTION_TOGGLE_WIN_STATE:
	  fork_exec(cmd_str);
	  win_launched = get_launch_window();
	  break;
	}
    }

  mb_tray_app_main (TrayApp);

  XCloseDisplay(dpy);
  exit(0);
}
int 
main(int argc, char **argv)
{
  MBTrayApp *app = NULL;
  MBPixbufImage *img_icon = NULL;
  struct timeval tv;
  char *icon_path;
  struct timezone  tz;
  struct tm       *localTime = NULL; 
  time_t           actualTime;

#if ENABLE_NLS
  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, DATADIR "/locale");
  bind_textdomain_codeset (PACKAGE, "UTF-8"); 
  textdomain (PACKAGE);
#endif

  app = mb_tray_app_new ( _("Clock"),
			  resize_callback,
			  paint_callback,
			  &argc,
			  &argv );  

  if (app == NULL) usage();

  Pixbuf = mb_pixbuf_new(mb_tray_app_xdisplay(app), 
			 mb_tray_app_xscreen(app));

  Col  = mb_col_new_from_spec(Pixbuf, "#000000");
  Fnt = mb_font_new_from_string(mb_tray_app_xdisplay(app), "Sans bold"); 

  mb_font_set_color (Fnt, Col);

  memset(&tv,0,sizeof(struct timeval));

  /* Figure out number of seconds till next minute */
  gettimeofday(&tv, &tz);
  actualTime = tv.tv_sec;
  localTime = localtime(&actualTime);
  tv.tv_usec = 0;
  tv.tv_sec  = 60 - localTime->tm_sec;

  /* This we then get reset when first called to 60 */
  mb_tray_app_set_timeout_callback (app, timeout_callback, &tv); 

  mb_tray_app_set_button_callback (app, button_callback );

  mb_tray_app_set_theme_change_callback (app, theme_change_callback );

  if (file_exists(CONTEXT_APP))
    {
      mb_tray_app_set_context_info (app, _("Set Time")); 

      mb_tray_app_set_context_callback (app, context_callback); 
    }

  if ((icon_path = mb_dot_desktop_icon_get_full_path (NULL, 
						     16, 
						      "minitime.png"))
      != NULL)
    {
      if ((img_icon = mb_pixbuf_img_new_from_file(Pixbuf, icon_path)) != NULL)
	{
	  mb_tray_app_set_icon(app, Pixbuf, img_icon);
	  mb_pixbuf_img_free(Pixbuf, img_icon);
	}
      free(icon_path);
    }

#ifdef USE_LIBSN
  sn_dpy = sn_display_new (mb_tray_app_xdisplay(app), NULL, NULL);
#endif

  mb_tray_app_main (app);

  return 1;
}
// Launch a command and initiate a startup notification
int runcmd(FXString cmd, FXString cmdname, FXString dir, FXString startdir, FXbool usesn = true, FXString snexcepts = "")
{
    int ret;

    // Change to current directory
    ret = chdir(dir.text());
    if (ret < 0)
    {
        int errcode = errno;
        if (errcode)
        {
            fprintf(stderr, _("Error: Can't enter folder %s: %s"), dir.text(), strerror(errcode));
        }
        else
        {
            fprintf(stderr, _("Error: Can't enter folder %s"), dir.text());
        }

        return(-1);
    }

    // Get rid of possible command options
    cmdname = cmdname.before(' ');

    // Check if command is in the startup notification exception list
    FXbool startup_notify = true;
    if (snexcepts != "")
    {
        FXString entry;
        for (int i = 0; ; i++)
        {
            entry = snexcepts.section(':', i);
            if (streq(entry.text(), ""))
            {
                break;
            }
            if (streq(entry.text(), cmdname.text()))
            {
                startup_notify = false;
                break;
            }
        }
    }

    // Run command with startup notification
    if (usesn && startup_notify)
    {
        Display*           xdisplay;
        SnDisplay*         display;
        SnLauncherContext* context;
        Time               timestamp;

        // Open display
        xdisplay = XOpenDisplay(NULL);
        if (xdisplay == NULL)
        {
            fprintf(stderr, _("Error: Can't open display\n"));
            ret = chdir(startdir.text());
            if (ret < 0)
            {
                int errcode = errno;
                if (errcode)
                {
                    fprintf(stderr, _("Error: Can't enter folder %s: %s"), startdir.text(), strerror(errcode));
                }
                else
                {
                    fprintf(stderr, _("Error: Can't enter folder %s"), startdir.text());
                }
            }
            return(-1);
        }

        // Message displayed in the task bar (if any)
        FXString message;
        message.format(_("Start of %s"), cmdname.text());

        // Initiate launcher context
        display = sn_display_new(xdisplay, NULL, NULL);
        context = sn_launcher_context_new(display, DefaultScreen(xdisplay));
        sn_launcher_context_set_name(context, message.text());
        sn_launcher_context_set_binary_name(context, cmdname.text());
        sn_launcher_context_set_description(context, message.text());
        sn_launcher_context_set_icon_name(context, cmdname.text());
        timestamp = gettimestamp();
        sn_launcher_context_initiate(context, "Xfe", cmd.text(), timestamp);

        // Run command in background
        cmd += " &";

        static pid_t child_pid = 0;
        switch ((child_pid = fork()))
        {
        case -1:
            fprintf(stderr, _("Error: Fork failed: %s\n"), strerror(errno));
            break;

        case 0: // Child
            sn_launcher_context_setup_child_process(context);
            execl("/bin/sh", "sh", "-c", cmd.text(), (char*)NULL);
            _exit(EXIT_SUCCESS);
            break;
        }
        sn_launcher_context_unref(context);
    }

    // Run command without startup notification
    else
    {
        // Run command in background
        cmd += " &";
        ret = system(cmd.text());
        if (ret < 0)
        {
            fprintf(stderr, _("Error: Can't execute command %s"), cmd.text());
            return(-1);
        }

        // Just display the wait cursor during a second
        sleep(1);
    }

    // Go back to startup directory
    ret = chdir(startdir.text());
    if (ret < 0)
    {
        int errcode = errno;
        if (errcode)
        {
            fprintf(stderr, _("Error: Can't enter folder %s: %s"), startdir.text(), strerror(errcode));
        }
        else
        {
            fprintf(stderr, _("Error: Can't enter folder %s"), startdir.text());
        }

        return(-1);
    }

    return(0);
}
Exemple #11
0
gboolean vfs_exec_on_screen( GdkScreen* screen,
                             const char* work_dir,
                             char** argv, char** envp,
                             const char* disp_name,
                             GSpawnFlags flags,
                             GError **err )
{
#ifdef HAVE_SN
    SnLauncherContext * ctx = NULL;
    SnDisplay* display;
#endif
    gboolean ret;
    GSpawnChildSetupFunc setup_func = NULL;
    extern char **environ;
    char** new_env = envp;
    int i, n_env = 0;
    char* display_name;
    int display_index = -1, startup_id_index = -1;

    if ( ! envp )
        envp = environ;

    n_env = g_strv_length(envp);

    new_env = g_new0( char*, n_env + 4 );
    for ( i = 0; i < n_env; ++i )
    {
        /* g_debug( "old envp[%d] = \"%s\"" , i, envp[i]); */
        if ( 0 == strncmp( envp[ i ], "DISPLAY=", 8 ) )
            display_index = i;
        else
        {
            if ( 0 == strncmp( envp[ i ], "DESKTOP_STARTUP_ID=", 19 ) )
                startup_id_index = i;
            new_env[i] = g_strdup( envp[ i ] );
        }
    }

#ifdef HAVE_SN
    display = sn_display_new ( GDK_SCREEN_XDISPLAY ( screen ),
                               ( SnDisplayErrorTrapPush ) gdk_error_trap_push,
                               ( SnDisplayErrorTrapPush ) gdk_error_trap_pop );
    if ( G_LIKELY ( display ) )
    {
        if ( !disp_name )
            disp_name = argv[ 0 ];

        ctx = sn_launcher_context_new( display, gdk_screen_get_number( screen ) );

        sn_launcher_context_set_description( ctx, disp_name );
        sn_launcher_context_set_name( ctx, g_get_prgname() );
        sn_launcher_context_set_binary_name( ctx, argv[ 0 ] );

        sn_launcher_context_set_workspace ( ctx, tvsn_get_active_workspace_number( screen ) );

        /* FIXME: I don't think this is correct, other people seem to use CurrentTime here.
                  However, using CurrentTime causes problems, so I so it like this.
                  Maybe this is incorrect, but it works, so, who cares?
        */
        /* time( &cur_time ); */
        sn_launcher_context_initiate( ctx, g_get_prgname(),
                                      argv[ 0 ], gtk_get_current_event_time() /*cur_time*/ );

        setup_func = (GSpawnChildSetupFunc) sn_launcher_context_setup_child_process;
        if( startup_id_index >= 0 )
            g_free( new_env[i] );
        else
            startup_id_index = i++;
        new_env[ startup_id_index ] = g_strconcat( "DESKTOP_STARTUP_ID=",
                                      sn_launcher_context_get_startup_id ( ctx ), NULL );
    }
#endif

    /* This is taken from gdk_spawn_on_screen */
    display_name = gdk_screen_make_display_name ( screen );
    if ( display_index >= 0 )
        new_env[ display_index ] = g_strconcat( "DISPLAY=", display_name, NULL );
    else
        new_env[ i++ ] = g_strconcat( "DISPLAY=", display_name, NULL );

    g_free( display_name );
    new_env[ i ] = NULL;

    ret = g_spawn_async( work_dir,
                         argv,  new_env,
                         flags,
                         NULL, NULL,
                         NULL, err );

    /* for debugging */
#if 0
    g_debug( "debug vfs_execute_on_screen(): flags: %d, display_index=%d", flags, display_index );
    for( i = 0; argv[i]; ++i ) {
        g_debug( "argv[%d] = \"%s\"" , i, argv[i] );
    }
    for( i = 0; i < n_env /*new_env[i]*/; ++i ) {
        g_debug( "new_env[%d] = \"%s\"" , i, new_env[i] );
    }
    if( ret )
        g_debug( "the program was executed without error" );
    else
        g_debug( "launch failed: %s", (*err)->message );
#endif

    g_strfreev( new_env );

#ifdef HAVE_SN
    if ( G_LIKELY ( ctx ) )
    {
        if ( G_LIKELY ( ret ) )
            g_timeout_add ( 20 * 1000, sn_timeout, ctx );
        else
        {
            sn_launcher_context_complete ( ctx );
            sn_launcher_context_unref ( ctx );
        }
    }

    if ( G_LIKELY ( display ) )
        sn_display_unref ( display );
#endif

    return ret;
}