transparent gnome-terminal try 2




I've cleaned up the patch so that now it acts properly and you can switch it
on/off on the fly ... things that would need to be done if I wanted to hack
on it more would be ... it also doesn't impact on the speed of the normal
mode

1) separate the code into separate files
2) check desktop for desktop changes
3) work with enlightenment's desktop stuff properly (it will work now but
   moving between desktops will not work too well)
4) scrolling is done in a cheap way (I just queue a redraw on the widget
   which just sounds wrong (and it's slow):)
5) instead of using native X calls it should call gdk routines (it was
   simpler with the X calls for now)

at least this patch actually makes it usable ... so have fun and don't blame
me if it breaks

it adds gdk_imlib to libs that zvt needs though as a side effect

anyway ... apply these patches in their proper places (zvt and
gnome-terminal) .. then go to properties in the terminal and you should
see transparent and shaded options in the general section ... you can switch
"on the fly" from one mode to another ... btw .. the patches are taken
against newest cvs trees

George

-- 
------------------------------------------------------------------------------
George Lebl <jirka@5z.com> http://www.5z.com/jirka/
------------------------------------------------------------------------------
  The following implements RSA in perl and is illegal to export from the US:

          #!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj
          $/=unpack('H*',$_);$_=`echo 16dio\U$k"SK$/SM$n\EsN0p[lN*1
          lK[d2%Sa2/d0$^Ixp"|dc`;s/\W//g;$_=pack('H*',/((..)*)$/)
Index: Makefile.am
===================================================================
RCS file: /cvs/gnome/gnome-libs/zvt/Makefile.am,v
retrieving revision 1.7
diff -u -r1.7 Makefile.am
--- Makefile.am	1998/06/14 20:14:58	1.7
+++ Makefile.am	1998/10/23 03:24:58
@@ -4,6 +4,7 @@
 	-I$(includedir) 	\
 	$(SUPPORTINCS) 		\
         $(GTK_CFLAGS)  		\
+	$(GDK_IMLIB_CFLAGS)	\
 	-I$(top_srcdir)/intl -I$(top_builddir)/intl
 
 lib_LTLIBRARIES = libzvt.la
@@ -32,5 +33,6 @@
 zterm_LDADD	= 	\
 	$(top_builddir)/zvt/libzvt.la	\
 	$(GTK_LIBS) \
+	$(GDK_IMLIB_LIBS)	\
 	@LIBSUPPORT@ $(INTLLIBS)
 
Index: zvtterm.c
===================================================================
RCS file: /cvs/gnome/gnome-libs/zvt/zvtterm.c,v
retrieving revision 1.45
diff -u -r1.45 zvtterm.c
--- zvtterm.c	1998/10/18 23:04:14	1.45
+++ zvtterm.c	1998/10/23 03:24:59
@@ -22,6 +22,14 @@
 #include <gtk/gtkmain.h>
 #include <gtk/gtksignal.h>
 #include <gdk/gdk.h>
+
+#include <gdk/gdkx.h>
+#include <gdk_imlib.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <X11/Xos.h>
+
 #include <gdk/gdkkeysyms.h>
 
 #include <errno.h>
@@ -66,6 +74,130 @@
 static void zvt_term_fix_scrollbar(ZvtTerm *term);
 static void vtx_unrender_selection (struct _vtx *vx);
 
+/*kind of stolen from Eterm and needs heavy cleanup*/
+static Window desktop_window = None;
+
+static Window
+get_desktop_window(Window the_window)
+{
+    Atom prop, type, prop2;
+    int format;
+    unsigned long length, after;
+    unsigned char *data;
+    unsigned int nchildren;
+    Window w, root, *children, parent;
+    Window last_desktop_window = desktop_window;
+
+    prop = XInternAtom(GDK_DISPLAY(), "_XROOTPMAP_ID", True);
+
+    prop2 = XInternAtom(GDK_DISPLAY(), "_XROOTCOLOR_PIXEL", True);
+
+    if (prop == None && prop2 == None) {
+	return None;
+    }
+
+#ifdef WATCH_DESKTOP_OPTION
+    if (Options & Opt_watchDesktop) {
+      if (TermWin.wm_parent != None) {
+	XSelectInput(GDK_DISPLAY(), TermWin.wm_parent, None);
+      }
+      if (TermWin.wm_grandparent != None) {
+	XSelectInput(GDK_DISPLAY(), TermWin.wm_grandparent, None);
+      }
+    }
+#endif
+
+    for (w = the_window; w; w = parent) {
+	if ((XQueryTree(GDK_DISPLAY(), w, &root, &parent, &children, &nchildren)) == False) {
+	    return None;
+	}
+
+	if (nchildren) {
+	    XFree(children);
+	}
+#ifdef WATCH_DESKTOP_OPTION
+	if (Options & Opt_watchDesktop) {
+	  if (w == TermWin.parent) {
+	    TermWin.wm_parent = parent;
+	    XSelectInput(GDK_DISPLAY(), TermWin.wm_parent, StructureNotifyMask);
+	  } else if (w == TermWin.wm_parent) {
+	    TermWin.wm_grandparent = parent;
+	    XSelectInput(GDK_DISPLAY(), TermWin.wm_grandparent, StructureNotifyMask);
+	  }
+	}
+#endif
+
+	if (prop != None) {
+	    XGetWindowProperty(GDK_DISPLAY(), w, prop, 0L, 1L, False, AnyPropertyType,
+			       &type, &format, &length, &after, &data);
+	} else if (prop2 != None) {
+	    XGetWindowProperty(GDK_DISPLAY(), w, prop2, 0L, 1L, False, AnyPropertyType,
+			       &type, &format, &length, &after, &data);
+	} else {
+	    continue;
+	}
+	if (type != None) {
+	    return (desktop_window = w);
+	}
+    }
+
+  return (desktop_window = None);
+
+}
+
+static Pixmap
+get_pixmap_prop(Window the_window,char *prop_id)
+{
+	Atom prop, type;
+	int format;
+	unsigned long length, after;
+	unsigned char *data;
+	register unsigned long i=0;
+
+	/*this should be changed when desktop changes I guess*/
+	if(desktop_window == None)
+		desktop_window = get_desktop_window(the_window);
+	if(desktop_window == None)
+		desktop_window = GDK_ROOT_WINDOW();
+
+	prop = XInternAtom(GDK_DISPLAY(), prop_id, True);
+
+	if (prop == None)
+		return None;
+
+	XGetWindowProperty(GDK_DISPLAY(), desktop_window, prop, 0L, 1L, False,
+			   AnyPropertyType, &type, &format, &length, &after,
+			   &data);
+	if (type == XA_PIXMAP)
+		return *((Pixmap *)data);
+	return None;
+}
+
+static GdkPixmap *
+create_shaded_pixmap(Pixmap p, int x, int y, int w, int h)
+{
+	GdkPixmap *pix;
+	GdkImlibColorModifier mod;
+	GdkImlibImage *iim;
+	GdkWindowPrivate pw;
+
+	if(p == None)
+		return None;
+		
+	pw.xwindow = (Window)p;
+	iim = gdk_imlib_create_image_from_drawable((GdkPixmap*)&pw,NULL,
+						   x,y,w,h);
+	mod.contrast=256;
+	mod.brightness=190;
+	mod.gamma=256;
+	gdk_imlib_set_image_modifier(iim,&mod);
+	gdk_imlib_render(iim, iim->rgb_width,iim->rgb_height);
+	pix = gdk_imlib_move_image(iim);
+	gdk_imlib_destroy_image(iim);
+	
+	return pix;
+}
+
 /* Local data */
 
 enum {
@@ -101,6 +233,7 @@
   return term_type;
 }
 
+
 static void
 zvt_term_class_init (ZvtTermClass *class)
 {
@@ -161,7 +294,13 @@
   term->blink_enabled = 1;
   term->ic = NULL;
   term->in_expose = 0;
-
+  term->transparent = 0;
+  term->shaded = 0;
+  
+  term->background = None;
+  term->shaded_s.pix = NULL;
+  term->shaded_s.x = term->shaded_s.y = term->shaded_s.w = term->shaded_s.h = 0;
+  
   /* input handlers */
   term->input_id = -1;
   term->msg_id = -1;
@@ -493,6 +632,67 @@
     }
 }
 
+static void
+draw_back_pixmap(GtkWidget *widget, int nx,int ny,int nw,int nh)
+{
+	int x,y;
+	Window childret;
+	ZvtTerm *term = ZVT_TERM(widget);
+	GdkGC *bgc = term->back_gc;
+
+	if(term->background == None) {
+		term->background = get_pixmap_prop(GDK_WINDOW_XWINDOW(widget->window),
+				    "_XROOTPMAP_ID");
+		if(term->background == None) {
+			term->transparent = 0;
+			return;
+		}
+	}
+
+	XTranslateCoordinates(GDK_WINDOW_XDISPLAY(widget->window),
+			      GDK_WINDOW_XWINDOW(widget->window),
+			      GDK_ROOT_WINDOW(),
+			      0,0,
+			      &x,&y,
+			      &childret);
+
+	if(term->shaded) {
+		if(term->shaded_s.pix == NULL ||
+		   term->shaded_s.x != x ||
+		   term->shaded_s.y != y ||
+		   term->shaded_s.w < nw+nx ||
+		   term->shaded_s.h < nh+ny) {
+			int width,height;
+			gdk_window_get_size(widget->window,
+					    &width,&height);
+			if(term->shaded_s.pix)
+				gdk_pixmap_unref(term->shaded_s.pix);
+			term->shaded_s.pix =
+				create_shaded_pixmap(term->background,
+						     x,y,width,height);
+			term->shaded_s.x = x;
+			term->shaded_s.y = y;
+			term->shaded_s.w = width;
+			term->shaded_s.h = height;
+		}
+		gdk_draw_pixmap(widget->window,
+				bgc,
+				term->shaded_s.pix,
+				nx,ny,
+				nx,ny,
+				nw,nh);
+	} else {
+		/*non-shaded is simple*/
+		XCopyArea (GDK_WINDOW_XDISPLAY(widget->window),
+			   term->background,
+			   GDK_WINDOW_XWINDOW(widget->window),
+			   GDK_GC_XGC(bgc),
+			   x+nx,y+ny,
+			   nw,nh,
+			   nx,ny);
+	}
+}
+
 static void zvt_term_draw (GtkWidget *widget, GdkRectangle *area)
 {
   ZvtTerm *term;
@@ -502,6 +702,8 @@
 
   term = ZVT_TERM (widget);
   term->in_expose = 1;
+  if(term->transparent)
+	  draw_back_pixmap(widget,area->x,area->y,area->width,area->height);
   vt_update_rect (term->vx,
 		  area->x/term->charwidth,
 		  area->y/term->charheight,
@@ -527,6 +729,9 @@
 
   /* FIXME: may update 1 more line/char than needed */
   term->in_expose = 1;
+  if(term->transparent)
+	  draw_back_pixmap(widget,event->area.x,event->area.y,
+			   event->area.width,event->area.height);
   vt_update_rect(term->vx,
 		 event->area.x/term->charwidth,
 		 event->area.y/term->charheight,
@@ -1472,6 +1677,14 @@
   gtk_signal_emit(GTK_OBJECT(term), term_signals[CHILD_DIED]);
 }
 
+void
+zvt_term_set_transparent(ZvtTerm *terminal, int	transparent, int shaded)
+{
+	terminal->transparent = transparent;
+	terminal->shaded = shaded;
+	gtk_widget_queue_draw(GTK_WIDGET(terminal));
+}
+
 /*
   external rendering functions called by vt_update, etc
 */
@@ -1561,13 +1774,20 @@
   }
 
   /* optimise: dont 'clear' background if not in expose, and background colour == window colour */
-  /* this may look a bit weird, it really does need to be this way - so dont touch!*/
+  /* this may look a bit weird, it really does need to be this way - so dont touch! */
+  /* if the terminal is transparent we must redraw all the time as we can't optimize in that case*/
   if (term->in_expose || vx->back_match==0) {
-    gdk_draw_rectangle(widget->window,
-		       bgc,
-		       1,
-		       col*term->charwidth, row*term->charheight,
-		       len*term->charwidth, term->charheight);
+	  if(!term->transparent || back<17) {
+		  gdk_draw_rectangle(widget->window,
+				     bgc,
+				     1,
+				     col*term->charwidth, row*term->charheight,
+				     len*term->charwidth, term->charheight);
+	  } else if(!term->in_expose) {
+		  draw_back_pixmap(widget,
+				   col*term->charwidth, row*term->charheight,
+				   len*term->charwidth, term->charheight);
+	  }
   } else {
     d(printf("not clearing background in_expose = %d, back_match=%d\n", term->in_expose, vx->back_match));
     d(printf("txt = '%.*s'\n", len, text));
@@ -1596,13 +1816,20 @@
 #if 0
   GdkEvent *event;
 #endif
-
+  
   widget = user_data;
-
+  
   g_return_if_fail (widget != NULL);
   g_return_if_fail (ZVT_IS_TERM (widget));
-
+  
   term = ZVT_TERM (widget);
+
+  if(term->transparent) {
+	  /*FIXME: bad hack*/
+	  gtk_widget_queue_draw(widget);
+	  return;
+  }
+
 
   /* FIXME: check args */
 
Index: zvtterm.h
===================================================================
RCS file: /cvs/gnome/gnome-libs/zvt/zvtterm.h,v
retrieving revision 1.16
diff -u -r1.16 zvtterm.h
--- zvtterm.h	1998/10/12 10:09:15	1.16
+++ zvtterm.h	1998/10/23 03:24:59
@@ -22,10 +22,13 @@
 #define __ZVT_TERM_H__
 
 #include <gdk/gdk.h>
+#include <gdk_imlib.h>
 #include <gtk/gtkadjustment.h>
 #include <gtk/gtkwidget.h>
 #include <zvt/vtx.h>
 
+#include <X11/X.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
@@ -52,6 +55,8 @@
     unsigned int in_expose:1;	/* updating from within expose events */
     unsigned int scroll_on_keystroke:1;
     unsigned int scroll_on_output:1;
+    unsigned int transparent:1;
+    unsigned int shaded:1;
 
     int charwidth;		/* size of characters */
     int charheight;
@@ -76,6 +81,12 @@
     gulong colors [18];		/* Our colors, pixel values. */
 
     GdkIC ic;			/* input context */
+    
+    Pixmap background;
+    struct {
+	    GdkPixmap *pix;
+	    int x,y,w,h;
+    } shaded_s;
   };
 
   struct _ZvtTermClass
@@ -109,6 +120,10 @@
   void          zvt_term_set_scroll_on_output   (ZvtTerm *term, int state);
   void          zvt_term_set_color_scheme       (ZvtTerm *term, gushort *red, gushort *grn, gushort *blu);
   void          zvt_term_set_default_color_scheme (ZvtTerm *term);
+
+  void		zvt_term_set_transparent	   (ZvtTerm      *terminal,
+						    int		  transparent,
+						    int		  shaded);
 	
   /*GtkAdjustment* zvt_term_get_adjustment         (ZvtTerm      *terminal);
     void           zvk_term_set_adjustment         (ZvtTerm      *dial,
Index: gnome-terminal.c
===================================================================
RCS file: /cvs/gnome/gnome-core/gnome-terminal/gnome-terminal.c,v
retrieving revision 1.48
diff -u -r1.48 gnome-terminal.c
--- gnome-terminal.c	1998/10/19 01:35:17	1.48
+++ gnome-terminal.c	1998/10/23 03:25:40
@@ -64,6 +64,8 @@
 	GdkColor user_fore, user_back; 		/* The custom colors */
 	int menubar_hidden; 			/* Whether to show the menubar */
 	int have_user_colors;			/* Only used for command line parsing */
+	int transparent;
+	int shaded;
 } ;
 
 /* Initial command */
@@ -81,6 +83,8 @@
 	GtkWidget *blink_checkbox;
 	GtkWidget *scroll_kbd_checkbox;
 	GtkWidget *scroll_out_checkbox;
+	GtkWidget *transparent_checkbox;
+	GtkWidget *shaded_checkbox;
 	GtkWidget *menubar_checkbox;
 	GtkWidget *font_entry;
 	GtkWidget *color_scheme;
@@ -342,6 +346,9 @@
 	cfg->scroll_key = gnome_config_get_bool ("scrollonkey=true");
 	cfg->scroll_out = gnome_config_get_bool ("scrollonoutput=false");
 
+	cfg->transparent = gnome_config_get_bool ("transparent=false");
+	cfg->shaded = gnome_config_get_bool ("shaded=false");
+
 	if (strcasecmp (fore_color, back_color) == 0)
 		/* don't let them set identical foreground and background colors */
 		cfg->color_set = 0;
@@ -372,6 +379,9 @@
 	newcfg->scroll_out = GTK_TOGGLE_BUTTON (prefs->scroll_out_checkbox)->active;
 	newcfg->scroll_key = GTK_TOGGLE_BUTTON (prefs->scroll_kbd_checkbox)->active;
 
+	newcfg->transparent = GTK_TOGGLE_BUTTON (prefs->transparent_checkbox)->active;
+	newcfg->shaded = GTK_TOGGLE_BUTTON (prefs->shaded_checkbox)->active;
+
 	(int) newcfg->scrollbar_position = gtk_object_get_user_data (GTK_OBJECT (prefs->scrollbar));
 
 	g_free (newcfg->font);
@@ -439,6 +449,7 @@
 	zvt_term_set_scroll_on_keystroke (term, cfg->scroll_key);
 	zvt_term_set_scroll_on_output (term, cfg->scroll_out);
 	zvt_term_set_scrollback (term, cfg->scrollback);
+	zvt_term_set_transparent (term, cfg->transparent, cfg->shaded);
 	if (cfg->scrollbar_position == SCROLLBAR_HIDDEN)
 		gtk_widget_hide (scrollbar);
 	else {
@@ -696,6 +707,8 @@
 	FONT_ROW      = 2,
 	BLINK_ROW     = 3,
 	MENUBAR_ROW    = 4,
+	TRANSPARENT_ROW = 5,
+	SHADED_ROW    = 6,
 	SCROLL_ROW    = 1,
 	SCROLLBACK_ROW = 2,
 	KBDSCROLL_ROW = 3,
@@ -801,6 +814,25 @@
 	gtk_table_attach (GTK_TABLE (table), prefs->menubar_checkbox,
 			  2, 3, MENUBAR_ROW, MENUBAR_ROW+1, GTK_FILL, 0, GNOME_PAD, GNOME_PAD);
 
+	/* Transparency */
+	prefs->transparent_checkbox = gtk_check_button_new_with_label (_("Transparent"));
+	gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (prefs->transparent_checkbox),
+				     term->transparent ? 1 : 0);
+	gtk_signal_connect (GTK_OBJECT (prefs->transparent_checkbox), "toggled",
+			    GTK_SIGNAL_FUNC (prop_changed), prefs);
+	gtk_table_attach (GTK_TABLE (table), prefs->transparent_checkbox,
+			  2, 3, TRANSPARENT_ROW, TRANSPARENT_ROW+1, GTK_FILL, 0, GNOME_PAD, GNOME_PAD);
+
+	/* Shaded */
+	prefs->shaded_checkbox = gtk_check_button_new_with_label (_("Transparent window should be shaded"));
+	gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (prefs->shaded_checkbox),
+				     term->shaded ? 1 : 0);
+	gtk_signal_connect (GTK_OBJECT (prefs->shaded_checkbox), "toggled",
+			    GTK_SIGNAL_FUNC (prop_changed), prefs);
+	gtk_table_attach (GTK_TABLE (table), prefs->shaded_checkbox,
+			  2, 3, SHADED_ROW, SHADED_ROW+1, GTK_FILL, 0, GNOME_PAD, GNOME_PAD);
+
+
 	/* Color page */
 	table = gtk_table_new (4, 4, FALSE);
 	gnome_property_box_append_page (GNOME_PROPERTY_BOX (prefs->prop_win), table, gtk_label_new (_("Colors")));
@@ -952,6 +984,8 @@
 	gnome_config_set_bool   ("menubar", !cfg->menubar_hidden);
 	gnome_config_set_bool   ("scrollonkey", cfg->scroll_key);
 	gnome_config_set_bool   ("scrollonoutput", cfg->scroll_out);
+	gnome_config_set_bool   ("transparent", cfg->transparent);
+	gnome_config_set_bool   ("shaded", cfg->shaded);
 	gnome_config_sync ();
 
 	gnome_config_pop_prefix ();
@@ -1208,6 +1242,23 @@
 }
 
 static void
+term_change_pos(GtkWidget *widget)
+{
+	static int x=-999;
+	static int y=-999;
+	int nx,ny;
+	
+	if(!widget->window ||
+	   !ZVT_TERM(widget)->transparent)
+		return;
+	
+	gdk_window_get_position(widget->window,&nx,&ny);
+	
+	if(nx!=x || ny!=y)
+		gtk_widget_queue_draw(widget);
+}
+
+static void
 new_terminal_cmd (char **cmd, struct terminal_config *cfg_in)
 {
 	GtkWidget *app, *hbox, *scrollbar;
@@ -1255,7 +1306,6 @@
 
 	app = gnome_app_new ("Terminal", "Terminal");
 	gtk_window_set_wmclass (GTK_WINDOW (app), "GnomeTerminal", "GnomeTerminal");
-
 	if (cmd != NULL)
 		initial_term = app;
 #ifdef ZVT_USES_MINIMAL_ALLOC
@@ -1269,6 +1319,9 @@
 	/* Setup the Zvt widget */
 	term = ZVT_TERM (zvt_term_new ());
 	gtk_widget_show (GTK_WIDGET (term));
+	gtk_signal_connect_object(GTK_OBJECT(app),"configure_event",
+				  GTK_SIGNAL_FUNC(term_change_pos),
+				  GTK_OBJECT(term));
 #if ZVT_USES_MINIMAL_ALLOC
 	gtk_widget_set_usize (GTK_WIDGET (term),
 			      80 * term->charwidth,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]