给RDP加一个connection bar

来源:互联网 发布:下歌的软件 编辑:程序博客网 时间:2024/04/29 12:56
 

//自己写的一个简易的程序,给linux下rdp加一个connection bar......

#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <gdk/gdk.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#define WIDTH 600
#define HIGTH 30
#define IDENV "RDP_WINDOW_ID"
#define APPNAME "rdesktop"
gchar *para[50];
pid_t rdp_pid = 0;
//extern int errno;
GtkWidget *label;

void free_para()
{
    gint index = 0;
    while(para[index])
    {  
        g_free(para[index]);
        index++;
    }
}
void app_close(GtkWidget *widget, gpointer data)
{
    free_para();
    gtk_main_quit();
}

void button_mouse_clicked(GtkWidget *button, gpointer data)
{

}

void button_close_clicked(GtkWidget *button, gpointer data)
{
    if(rdp_pid != 0)
    {
        gchar temp[20];
        g_print("please wait child %d close/n", rdp_pid);
       // kill(rdp_pid, SIGKILL);
        g_sprintf(temp, "kill %d", rdp_pid);
        system(temp);
       // waitpid(rdp_pid, NULL, 0);
    }
    //app_close(NULL, NULL);
}

void button_min_clicked(GtkWidget *button, gpointer data)
{
    GtkWidget *pwindow = (GtkWidget *)data;
    GtkWidget *cwindow;
    cwindow=gtk_widget_get_parent(button);
    gtk_window_iconify(GTK_WINDOW(pwindow));
  //  gtk_window_iconify(GTK_WINDOW(cwindow));
}

gboolean enter_notify(GtkWidget *window, GdkEventCrossing *event, gpointer user_data)
{
    GtkWidget *tbutton = (GtkWidget *)user_data;
    gint x, y;

    gtk_window_get_position(GTK_WINDOW(window), &x, &y);
    if(event->type == GDK_ENTER_NOTIFY)
    {  
        gtk_window_move(GTK_WINDOW(window), x, 0);
    }
    return FALSE;
}

gboolean leave_notify(GtkWidget *window, GdkEventCrossing *event, gpointer user_data)
{
    GtkWidget *tbutton = (GtkWidget *)user_data;
    gint x, y;

    gtk_window_get_position(GTK_WINDOW(window), &x, &y);
    if((event->type == GDK_LEAVE_NOTIFY) && !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tbutton)))
    { 
         gtk_window_move(GTK_WINDOW(window), x, 2-HIGTH);
    }
    return FALSE;
}


GtkWidget * windowbar_create(GtkWidget *window)
{
    GtkWidget *windowbar;
    GtkWidget *hbox;
    GtkWidget *button_mouse, *button_close, *button_min;
    gint x, y;
   
    GdkColor color;
    color.red=65320;
    color.green=65520;
    color.blue=41668;

    windowbar=gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_transient_for(GTK_WINDOW(windowbar), GTK_WINDOW(window));
  
    gtk_widget_set_size_request(windowbar, WIDTH, HIGTH);
    gtk_window_set_decorated(GTK_WINDOW(windowbar), FALSE);
    gtk_widget_modify_bg (windowbar, GTK_STATE_NORMAL, &color);
 
    hbox=gtk_hbox_new(FALSE, 10);
    gtk_container_add(GTK_CONTAINER(windowbar), hbox);

    button_mouse=gtk_toggle_button_new_with_label("M");
    gtk_box_pack_start(GTK_BOX(hbox), button_mouse, FALSE, FALSE, 5);
    gtk_toggle_button_set_active((GtkToggleButton *)button_mouse, TRUE);


    label=gtk_label_new("connect IP");
    gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 5);
    gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);

    button_close=gtk_button_new_with_label("X");
    gtk_box_pack_end(GTK_BOX(hbox), button_close, FALSE, FALSE, 5);
   
    button_min=gtk_button_new_with_label("__");
    gtk_box_pack_end(GTK_BOX(hbox), button_min, FALSE, FALSE, 0);

    g_signal_connect(button_mouse, "toggled", G_CALLBACK(button_mouse_clicked), NULL);
    g_signal_connect(button_close, "clicked", G_CALLBACK(button_close_clicked), NULL);
    g_signal_connect(button_min, "clicked", G_CALLBACK(button_min_clicked), window);
    g_signal_connect(windowbar, "enter-notify-event", G_CALLBACK(enter_notify), button_mouse);
    g_signal_connect(windowbar, "leave-notify-event", G_CALLBACK(leave_notify), button_mouse);
 
    gtk_window_set_position(GTK_WINDOW(windowbar), GTK_WIN_POS_CENTER);
    gtk_window_get_position(GTK_WINDOW(windowbar), &x, &y);
    g_print("window bar %d,%d/n", x, y);
    gtk_window_move(GTK_WINDOW(windowbar), x, 0);
    gtk_widget_show_all(windowbar);
    g_signal_connect(windowbar, "destroy", G_CALLBACK(app_close), NULL);
    return windowbar;
}

void waitchild(int sig)
{
    gint result = waitpid(rdp_pid, (int *)0, WNOHANG);
    g_print("waitpid %d return %d/n", rdp_pid, result);
    if(rdp_pid == result || result == -1)
    {
        g_print("Child closed/n");
        app_close(NULL, NULL);
    }
    else if(result == 0)
    {
        g_print("Child %d is killed/n", rdp_pid);
        app_close(NULL, NULL);
    }
    else if(rdp_pid == 0)
    { 
       free_para();
       g_print("error: at least one parameter error/n");
       exit(-1);
    }
}

gboolean set_env(gint win_id)
{
    gchar *env;
    env = g_strdup_printf("%s=%d", IDENV, win_id);
    if(env)
    {
        if(putenv(env) == -1)
        {
            g_free(env);
            return FALSE;
        }
        else
        {
            gchar *get = getenv(IDENV);
            g_print("set %s=0x%x, get %s/n", IDENV, win_id, get);
            return TRUE;
        }
    }
    else
        return FALSE;
}

GtkWidget *windowrdp_create()
{
    GtkWidget *windowrdp;
    Window xwin;
    GdkScreen *screen;
    gint height, width;
 
    GdkColor color;
 
    color.red=80;
    color.green=65520;
    color.blue=120;
 
    windowrdp=gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(windowrdp), "rdpwindow");
 //   gtk_widget_modify_bg (windowrdp, GTK_STATE_NORMAL, &color);

    screen=gdk_screen_get_default();  
    height=gdk_screen_get_height(screen );    
    width=gdk_screen_get_width(screen); 
    gtk_window_set_default_size(GTK_WINDOW(windowrdp), width, height);
    g_print("default screen width=%d,height=%d/n",width, height);
//    gtk_window_maximize(GTK_WINDOW(windowrdp));
//    gtk_window_fullscreen(GTK_WINDOW(windowrdp));
    gtk_window_set_decorated(GTK_WINDOW(windowrdp), FALSE);

    gtk_widget_show(windowrdp);
    xwin = GDK_WINDOW_XWINDOW(GTK_WIDGET(windowrdp)->window);
//    g_print("window id is 0x%x/n", xwin);
    if(!set_env(xwin))
    {
       g_print("Set window ID fail/n");
       return NULL;
    }
    g_signal_connect(windowrdp, "destroy", G_CALLBACK(app_close), NULL);
    return windowrdp;
}

pid_t connect_rdp(int argc, char *argv[])
{
    if(argc < 3)
    {
        g_print("error: command parameter error!/n");
  return 0;
    }
    int i;
    if(0!=g_ascii_strncasecmp(argv[1], APPNAME, strlen(APPNAME)))
    {  
        g_print("error: Application name is %s, must be %s/n", argv[1], APPNAME);
 return 0;
    }
    else
    {
  gint index = 0;
  for(index = 0; index < argc -1; index++)
  { 
      if((argv[index+1][0] == '-') && (argv[index+1][1] == 'X'))
    continue;
      para[index] = (char*)malloc((strlen(argv[index+1]) + 1) * sizeof(char));
      memset(para[index], 0, (strlen(argv[index+1]) + 1) * sizeof(char));
             strcpy(para[index], argv[index+1]);
  }
 
        para[index] = g_strdup_printf("-X0x%x", atoi(getenv(IDENV)));
  
        g_print("*********connect RDP***********/n");
        for(index = 0; para[index]; index++)
        {
            g_print("%s ", para[index]);
        }
        g_print("/n");
 struct sigaction act;
 act.sa_handler = waitchild;
 sigemptyset(&act.sa_mask);
 act.sa_flags = 0;
 
        sigaction(SIGCHLD, &act, 0);
        pid_t pid;
        pid = fork();
        if (0 != pid)
 {
  //          g_print("pid fork = %d/n", pid);
     return pid;
 }
        else
        {
//            usleep(500*1000);
            execvp(APPNAME, para);
            exit(-1);
        }
   }
}

int main(int argc, char *argv[])
{
    GtkWidget *windowrdp;
    GtkWidget *windowbar; 
   
    gtk_init(&argc, &argv);

    if(!(windowrdp = windowrdp_create()))
    {
        app_close(NULL, NULL);
    }
    if(!(windowbar = windowbar_create(windowrdp)))
    {
        app_close(NULL, NULL);
    }
    if((rdp_pid = connect_rdp(argc, argv)) == 0)
    {
        if(waitpid(-1, (int *)0, WNOHANG) == -1)
           exit(-1); 
    }
    gtk_main();
    return 0;
}

原创粉丝点击