X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/2889df585ae164ccf8fc57ffdbb432dfcd75e870..618db430981dbc0dfed318503808bb7b744750b7:/src/xterm.c diff --git a/src/xterm.c b/src/xterm.c index 9c2e660cff..fd09d6d481 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -1,6 +1,6 @@ /* X Communication module for terminals which understand the X protocol. Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, - 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -753,11 +753,6 @@ x_after_update_window_line (desired_row) { int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y)); - /* Internal border is drawn below the tool bar. */ - if (WINDOWP (f->tool_bar_window) - && w == XWINDOW (f->tool_bar_window)) - y -= width; - BLOCK_INPUT; x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 0, y, width, height, False); @@ -1383,19 +1378,27 @@ x_draw_composite_glyph_string_foreground (s) if (j < i) { font->driver->draw (s, j, i, x, y, 0); + if (s->face->overstrike) + font->driver->draw (s, j, i, x + 1, y, 0); x += width; } xoff = LGLYPH_XOFF (glyph); yoff = LGLYPH_YOFF (glyph); wadjust = LGLYPH_WADJUST (glyph); font->driver->draw (s, i, i + 1, x + xoff, y + yoff, 0); + if (s->face->overstrike) + font->driver->draw (s, i, i + 1, x + xoff + 1, y + yoff, 0); x += wadjust; j = i + 1; width = 0; } } if (j < i) - font->driver->draw (s, j, i, x, y, 0); + { + font->driver->draw (s, j, i, x, y, 0); + if (s->face->overstrike) + font->driver->draw (s, j, i, x + 1, y, 0); + } } } @@ -2951,6 +2954,12 @@ x_clear_frame (struct frame *f) colors or something like that, then they should be notified. */ x_scroll_bar_clear (f); +#if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS) + /* Make sure scroll bars are redrawn. As they aren't redrawn by + redisplay, do it here. */ + gtk_widget_queue_draw (FRAME_GTK_WIDGET (f)); +#endif + XFlush (FRAME_X_DISPLAY (f)); UNBLOCK_INPUT; @@ -3006,6 +3015,22 @@ XTflash (f) BLOCK_INPUT; { +#ifdef USE_GTK + /* Use Gdk routines to draw. This way, we won't draw over scroll bars + when the scroll bars and the edit widget share the same X window. */ + GdkGCValues vals; + GdkGC *gc; + vals.foreground.pixel = (FRAME_FOREGROUND_PIXEL (f) + ^ FRAME_BACKGROUND_PIXEL (f)); + vals.function = GDK_XOR; + gc = gdk_gc_new_with_values (FRAME_GTK_WIDGET (f)->window, + &vals, + GDK_GC_FUNCTION + | GDK_GC_FOREGROUND); +#define XFillRectangle(d, win, gc, x, y, w, h) \ + gdk_draw_rectangle (FRAME_GTK_WIDGET (f)->window, \ + gc, TRUE, x, y, w, h) +#else GC gc; /* Create a GC that will use the GXxor function to flip foreground @@ -3020,7 +3045,7 @@ XTflash (f) gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), GCFunction | GCForeground, &values); } - +#endif { /* Get the height not including a menu bar widget. */ int height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, FRAME_LINES (f)); @@ -3056,13 +3081,14 @@ XTflash (f) XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc, flash_left, (FRAME_INTERNAL_BORDER_WIDTH (f) - + FRAME_TOOL_BAR_LINES (f) * FRAME_LINE_HEIGHT (f)), + + FRAME_TOP_MARGIN_HEIGHT (f)), width, flash_height); XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc, flash_left, (height - flash_height - FRAME_INTERNAL_BORDER_WIDTH (f)), width, flash_height); + } else /* If it is short, flash it all. */ @@ -3110,7 +3136,7 @@ XTflash (f) XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc, flash_left, (FRAME_INTERNAL_BORDER_WIDTH (f) - + FRAME_TOOL_BAR_LINES (f) * FRAME_LINE_HEIGHT (f)), + + FRAME_TOP_MARGIN_HEIGHT (f)), width, flash_height); XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc, flash_left, @@ -3124,7 +3150,12 @@ XTflash (f) flash_left, FRAME_INTERNAL_BORDER_WIDTH (f), width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); +#ifdef USE_GTK + g_object_unref (G_OBJECT (gc)); +#undef XFillRectangle +#else XFreeGC (FRAME_X_DISPLAY (f), gc); +#endif x_flush (f); } } @@ -5788,6 +5819,7 @@ event_handler_gdk (gxev, ev, data) { XEvent *xev = (XEvent *) gxev; + BLOCK_INPUT; if (current_count >= 0) { struct x_display_info *dpyinfo; @@ -5798,23 +5830,27 @@ event_handler_gdk (gxev, ev, data) /* Filter events for the current X input method. GTK calls XFilterEvent but not for key press and release, so we do it here. */ - if (xev->type == KeyPress || xev->type == KeyRelease) - if (dpyinfo && x_filter_event (dpyinfo, xev)) - return GDK_FILTER_REMOVE; + if ((xev->type == KeyPress || xev->type == KeyRelease) + && dpyinfo + && x_filter_event (dpyinfo, xev)) + { + UNBLOCK_INPUT; + return GDK_FILTER_REMOVE; + } #endif if (! dpyinfo) current_finish = X_EVENT_NORMAL; else - { - current_count += - handle_one_xevent (dpyinfo, xev, ¤t_finish, - current_hold_quit); - } + current_count += + handle_one_xevent (dpyinfo, xev, ¤t_finish, + current_hold_quit); } else current_finish = x_dispatch_event (xev, xev->xany.display); + UNBLOCK_INPUT; + if (current_finish == X_EVENT_GOTO_OUT || current_finish == X_EVENT_DROP) return GDK_FILTER_REMOVE; @@ -7432,6 +7468,11 @@ x_clear_frame_area (f, x, y, width, height) { x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), x, y, width, height, False); +#ifdef USE_GTK + /* Must queue a redraw, because scroll bars might have been cleared. */ + if (FRAME_GTK_WIDGET (f)) + gtk_widget_queue_draw (FRAME_GTK_WIDGET (f)); +#endif } @@ -9812,7 +9853,7 @@ x_wm_set_icon_pixmap (f, pixmap_id) { Pixmap icon_pixmap, icon_mask; -#ifndef USE_X_TOOLKIT +#if !defined USE_X_TOOLKIT && !defined USE_GTK Window window = FRAME_OUTER_WINDOW (f); #endif @@ -10067,7 +10108,6 @@ x_term_init (display_name, xrm_option, resource_name) int argc; char *argv[NUM_ARGV]; char **argv2 = argv; - GdkAtom atom; guint id; #ifndef HAVE_GTK_MULTIDISPLAY if (!EQ (Vinitial_window_system, Qx)) @@ -10206,10 +10246,25 @@ x_term_init (display_name, xrm_option, resource_name) terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD)); init_kboard (terminal->kboard); terminal->kboard->Vwindow_system = Qx; + + /* Add the keyboard to the list before running Lisp code (via + Qvendor_specific_keysyms below), since these are not traced + via terminals but only through all_kboards. */ + terminal->kboard->next_kboard = all_kboards; + all_kboards = terminal->kboard; + if (!EQ (XSYMBOL (Qvendor_specific_keysyms)->function, Qunbound)) { char *vendor = ServerVendor (dpy); - /* Temporarily hide the partially initialized terminal */ + + /* Protect terminal from GC before removing it from the + list of terminals. */ + struct gcpro gcpro1; + Lisp_Object gcpro_term; + XSETTERMINAL (gcpro_term, terminal); + GCPRO1 (gcpro_term); + + /* Temporarily hide the partially initialized terminal. */ terminal_list = terminal->next_terminal; UNBLOCK_INPUT; terminal->kboard->Vsystem_key_alist @@ -10218,10 +10273,9 @@ x_term_init (display_name, xrm_option, resource_name) BLOCK_INPUT; terminal->next_terminal = terminal_list; terminal_list = terminal; + UNGCPRO; } - terminal->kboard->next_kboard = all_kboards; - all_kboards = terminal->kboard; /* Don't let the initial kboard remain current longer than necessary. That would cause problems if a file loaded on startup tries to prompt in the mini-buffer. */ @@ -10570,7 +10624,6 @@ void x_delete_display (dpyinfo) struct x_display_info *dpyinfo; { - int i; struct terminal *t; /* Close all frames and delete the generic struct terminal for this @@ -10722,7 +10775,6 @@ void x_delete_terminal (struct terminal *terminal) { struct x_display_info *dpyinfo = terminal->display_info.x; - int i; /* Protect against recursive calls. delete_frame in delete_terminal calls us back when it deletes our last frame. */