summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin@src.gnome.org>2002-03-17 05:46:00 +0000
committerNalin Dahyabhai <nalin@src.gnome.org>2002-03-17 05:46:00 +0000
commit0d351fd6824f1b081a6dc559573ced5e0d20c5f2 (patch)
tree63edc4bfb188cc82b159a7be11286d35ceaae55e
parent2e09448fcfa06e92e8b7c272c8fde4fe277a58aa (diff)
Rework tiling of background images, and implement a blinking cursor. Set
* src/vte.c src/vte.h: Rework tiling of background images, and implement a blinking cursor. * src/vteapp.c: Set blinking cursor by default.
-rw-r--r--src/vte.c214
-rw-r--r--src/vte.h4
-rw-r--r--src/vteapp.c1
3 files changed, 109 insertions, 110 deletions
diff --git a/src/vte.c b/src/vte.c
index 43e9656..48a0fab 100644
--- a/src/vte.c
+++ b/src/vte.c
@@ -21,6 +21,7 @@
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/param.h>
+#include <sys/time.h>
#include <errno.h>
#include <fcntl.h>
#include <iconv.h>
@@ -177,9 +178,11 @@ struct _VteTerminalPrivate {
gboolean scroll_on_keystroke;
gboolean alt_sends_escape;
gboolean audible_bell;
+ gboolean cursor_blinks;
+ guint blink_period;
GdkPixbuf *bg_image_full;
GdkPixbuf *bg_image;
- float bg_saturation;
+ double bg_saturation;
};
/* A function which can handle a terminal control sequence. */
@@ -267,6 +270,29 @@ vte_invalidate_cells(VteTerminal *terminal,
gdk_window_invalidate_rect(widget->window, &rect, TRUE);
}
+/* Cause the cursor to be redrawn. */
+static gboolean
+vte_invalidate_cursor(gpointer data)
+{
+ VteTerminal *terminal;
+ if (!VTE_IS_TERMINAL(data)) {
+ return FALSE;
+ }
+ if (GTK_WIDGET_REALIZED(GTK_WIDGET(data))) {
+ terminal = VTE_TERMINAL(data);
+ vte_invalidate_cells(terminal,
+ terminal->pvt->screen->cursor_current.col,
+ 1,
+ terminal->pvt->screen->cursor_current.row,
+ 1);
+ }
+ g_timeout_add(terminal->pvt->blink_period / 2,
+ vte_invalidate_cursor,
+ terminal);
+ return FALSE;
+}
+
+/* Emit a "selection_changed" signal. */
static void
vte_terminal_emit_selection_changed(VteTerminal *terminal)
{
@@ -4469,6 +4495,10 @@ vte_terminal_init(VteTerminal *terminal)
pvt->bg_image = NULL;
pvt->bg_saturation = 0.4;
+ pvt->cursor_blinks = FALSE;
+ pvt->blink_period = 1000;
+ g_timeout_add(pvt->blink_period / 2, vte_invalidate_cursor, terminal);
+
pvt->selection = FALSE;
pvt->selection_start.x = 0;
pvt->selection_start.y = 0;
@@ -5174,8 +5204,11 @@ vte_terminal_paint(GtkWidget *widget, GdkRectangle *area)
GC gc;
struct vte_charcell *cell;
int row, drow, col, row_stop, col_stop, x_offs = 0, y_offs = 0;
- int width, height, ascent, descent;
- long delta;
+ long width, height, ascent, descent, delta;
+ struct timezone tz;
+ struct timeval tv;
+ guint daytime;
+ gboolean blink;
#ifdef HAVE_XFT
XftDraw *ftdraw = NULL;
#endif
@@ -5190,6 +5223,19 @@ vte_terminal_paint(GtkWidget *widget, GdkRectangle *area)
}
screen = terminal->pvt->screen;
+ /* Determine if blinking text should be shown. */
+ if (terminal->pvt->cursor_blinks) {
+ if (gettimeofday(&tv, &tz) == 0) {
+ daytime = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
+ daytime = daytime % terminal->pvt->blink_period;
+ blink = daytime < (terminal->pvt->blink_period / 2);
+ } else {
+ blink = TRUE;
+ }
+ } else {
+ blink = TRUE;
+ }
+
/* Set up the default palette. */
vte_terminal_set_default_colors(terminal);
@@ -5217,48 +5263,36 @@ vte_terminal_paint(GtkWidget *widget, GdkRectangle *area)
}
#endif
- /* Keep local copies of rendering information. */
- width = terminal->char_width;
- height = terminal->char_height;
- ascent = terminal->char_ascent;
- descent = terminal->char_descent;
- delta = screen->scroll_delta;
-
/* Paint the background for this area, using a filled rectangle. We
* have to do this even when the GDK background matches, otherwise
* we may miss character removals before an area is re-exposed. */
if (terminal->pvt->bg_image != NULL) {
-#ifdef VTE_DEBUG
-#ifdef VTE_DEBUG_DRAW
- fprintf(stderr, "Background dimensions are %dx%d.\n",
- gdk_pixbuf_get_width(terminal->pvt->bg_image),
- gdk_pixbuf_get_height(terminal->pvt->bg_image));
-#endif
-#endif
- /* If the image isn't big enough, cause it to be resized. */
- if ((gdk_pixbuf_get_width(terminal->pvt->bg_image) <
- area->x - x_offs + area->width) ||
- (gdk_pixbuf_get_height(terminal->pvt->bg_image) <
- area->y - y_offs + area->height)) {
- vte_terminal_set_background_image(terminal,
- terminal->pvt->bg_image_full);
-#ifdef VTE_DEBUG
-#ifdef VTE_DEBUG_DRAW
- fprintf(stderr, "Background resized to %dx%d.\n",
- gdk_pixbuf_get_width(terminal->pvt->bg_image),
- gdk_pixbuf_get_height(terminal->pvt->bg_image));
-#endif
-#endif
+ long x, y, w, h;
+ width = gdk_pixbuf_get_width(terminal->pvt->bg_image);
+ height = gdk_pixbuf_get_height(terminal->pvt->bg_image);
+
+ y = area->y;
+ while (y < area->y + area->height) {
+ h = MIN(area->y + area->height - y, height - (y % height));
+
+ x = area->x;
+ while (x < area->x + area->width) {
+ w = MIN(area->x + area->width - x, width - (x % width));
+
+ gdk_pixbuf_render_to_drawable(terminal->pvt->bg_image,
+ gdrawable, ggc,
+ x % width,
+ y % height,
+ x - x_offs,
+ y - y_offs,
+ w,
+ h,
+ GDK_RGB_DITHER_NONE,
+ 0, 0);
+ x += w;
+ }
+ y += h;
}
- gdk_pixbuf_render_to_drawable(terminal->pvt->bg_image,
- gdrawable, ggc,
- (area->x) % gdk_pixbuf_get_width(terminal->pvt->bg_image),
- (area->y) % gdk_pixbuf_get_height(terminal->pvt->bg_image),
- area->x - x_offs,
- area->y - y_offs,
- area->width,
- area->height,
- GDK_RGB_DITHER_NONE, 0, 0);
} else {
XSetForeground(display, gc,
terminal->pvt->palette[VTE_DEF_BG].pixel);
@@ -5269,6 +5303,13 @@ vte_terminal_paint(GtkWidget *widget, GdkRectangle *area)
area->height);
}
+ /* Keep local copies of rendering information. */
+ width = terminal->char_width;
+ height = terminal->char_height;
+ ascent = terminal->char_ascent;
+ descent = terminal->char_descent;
+ delta = screen->scroll_delta;
+
/* Now we're ready to draw the text. Iterate over the rows we
* need to draw. */
row = area->y / height;
@@ -5349,7 +5390,7 @@ vte_terminal_paint(GtkWidget *widget, GdkRectangle *area)
#ifdef HAVE_XFT
ftdraw,
#endif
- TRUE);
+ blink);
}
/* Done with various structures. */
@@ -5512,7 +5553,7 @@ vte_terminal_paste_clipboard(VteTerminal *terminal)
}
void
-vte_terminal_set_background_saturation(VteTerminal *terminal, float saturation)
+vte_terminal_set_background_saturation(VteTerminal *terminal, double saturation)
{
long i;
guchar *pixels, *oldpixels;
@@ -5528,6 +5569,7 @@ vte_terminal_set_background_saturation(VteTerminal *terminal, float saturation)
pixels[i] = oldpixels[i] * terminal->pvt->bg_saturation;
i--;
}
+ /* Force a redraw for everything. */
if (GTK_WIDGET_REALIZED(GTK_WIDGET(terminal))) {
vte_invalidate_cells(terminal,
0,
@@ -5541,90 +5583,32 @@ vte_terminal_set_background_saturation(VteTerminal *terminal, float saturation)
void
vte_terminal_set_background_image(VteTerminal *terminal, GdkPixbuf *image)
{
- long bits, width, oldwidth, height, oldheight, stride, oldstride, i, j;
- GdkColorspace colorspace;
- gboolean alpha;
- guchar *pixels, *oldpixels;
-
g_return_if_fail(VTE_IS_TERMINAL(terminal));
/* Get a ref to the new image if there is one. Do it here just in
- * case we're actually using the same one we're already using. */
+ * case we're actually given the same one we're already using. */
if (image != NULL) {
g_object_ref(G_OBJECT(image));
}
/* Free the previous background images. */
- if (terminal->pvt->bg_image != NULL) {
- g_object_unref(G_OBJECT(terminal->pvt->bg_image));
- terminal->pvt->bg_image = NULL;
- }
if (terminal->pvt->bg_image_full != NULL) {
g_object_unref(G_OBJECT(terminal->pvt->bg_image_full));
terminal->pvt->bg_image_full = NULL;
}
+ if (terminal->pvt->bg_image != NULL) {
+ g_object_unref(G_OBJECT(terminal->pvt->bg_image));
+ terminal->pvt->bg_image = NULL;
+ }
if (image != NULL) {
- /* Get information about the image. */
- colorspace = gdk_pixbuf_get_colorspace(image);
- alpha = gdk_pixbuf_get_has_alpha(image);
- bits = gdk_pixbuf_get_bits_per_sample(image),
- oldwidth = gdk_pixbuf_get_width(image),
- oldheight = gdk_pixbuf_get_height(image);
-
/* Set our image fields. */
terminal->pvt->bg_image_full = image;
- if (GTK_WIDGET_REALIZED(GTK_WIDGET(terminal))) {
- /* Realized, so make sure the new image is big
- * enough to cover the entire widget. */
- width = (GTK_WIDGET(terminal))->allocation.width;
- height = (GTK_WIDGET(terminal))->allocation.height;
- terminal->pvt->bg_image = gdk_pixbuf_new(colorspace,
- alpha,
- bits,
- width,
- height);
- } else {
- /* Not realized yet, just make a copy of the
- * background. */
- width = oldwidth;
- height = oldheight;
- terminal->pvt->bg_image = gdk_pixbuf_copy(image);
- }
-
- /* Get image information. */
- oldpixels = gdk_pixbuf_get_pixels(terminal->pvt->bg_image_full);
- pixels = gdk_pixbuf_get_pixels(terminal->pvt->bg_image);
- oldstride = gdk_pixbuf_get_rowstride(terminal->pvt->bg_image_full);
- stride = gdk_pixbuf_get_rowstride(terminal->pvt->bg_image);
- /* Tile the old image into the new one. */
- j = 0;
- while (j < height) {
- i = 0;
- while (i < width) {
- gdk_pixbuf_copy_area(terminal->pvt->bg_image_full,
- 0, 0,
- MIN(oldwidth, width - i),
- MIN(oldheight, height - j),
- terminal->pvt->bg_image,
- i, j);
- i += oldwidth;
- }
- j += oldheight;
- }
- /* Desaturate the new image. */
- for (i = 0; i < stride * height; i++) {
- pixels[i] = pixels[i] * terminal->pvt->bg_saturation;
- }
- }
+ terminal->pvt->bg_image = gdk_pixbuf_copy(image);
- /* Repaint everyting. */
- if (GTK_WIDGET_REALIZED(GTK_WIDGET(terminal))) {
- vte_invalidate_cells(terminal,
- 0,
- terminal->column_count,
- terminal->pvt->screen->scroll_delta,
- terminal->row_count);
+ /* Desaturate the copy. */
+ vte_terminal_set_background_saturation(terminal,
+ terminal->pvt->bg_saturation);
}
}
@@ -5667,3 +5651,15 @@ vte_terminal_get_has_selection(VteTerminal *terminal)
{
return (terminal->pvt->selection != FALSE);
}
+
+void
+vte_terminal_set_cursor_blinks(VteTerminal *terminal, gboolean blink)
+{
+ terminal->pvt->cursor_blinks = blink;
+}
+
+void
+vte_terminal_set_blink_period(VteTerminal *terminal, guint period)
+{
+ terminal->pvt->blink_period = period;
+}
diff --git a/src/vte.h b/src/vte.h
index 3a36a27..703e69d 100644
--- a/src/vte.h
+++ b/src/vte.h
@@ -112,8 +112,10 @@ void vte_terminal_set_background_image(VteTerminal *terminal, GdkPixbuf *image);
void vte_terminal_set_background_image_file(VteTerminal *terminal,
const char *path);
void vte_terminal_set_background_saturation(VteTerminal *terminal,
- float saturation);
+ double saturation);
void vte_terminal_set_background_transparent(VteTerminal *terminal);
+void vte_terminal_set_cursor_blinks(VteTerminal *terminal, gboolean blink);
+void vte_terminal_set_blink_period(VteTerminal *terminal, guint period);
gboolean vte_terminal_get_has_selection(VteTerminal *terminal);
G_END_DECLS
diff --git a/src/vteapp.c b/src/vteapp.c
index 59741c0..a994481 100644
--- a/src/vteapp.c
+++ b/src/vteapp.c
@@ -115,6 +115,7 @@ main(int argc, char **argv)
/* Set some defaults. */
vte_terminal_set_audible_bell(VTE_TERMINAL(widget), TRUE);
+ vte_terminal_set_cursor_blinks(VTE_TERMINAL(widget), TRUE);
vte_terminal_set_scroll_on_output(VTE_TERMINAL(widget), TRUE);
vte_terminal_set_scroll_on_keystroke(VTE_TERMINAL(widget), TRUE);
vte_terminal_set_background_image_file(VTE_TERMINAL(widget),