//自己写的一个简易的程序,给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;
}