Commit 067a69a2 authored by Paul Eggert's avatar Paul Eggert
Browse files

Merge: user-interface timestamps and other int overflow patches.

parents 5e9e35cd 9fbd6841
2011-05-15 Paul Eggert <eggert@cs.ucla.edu>
Fixups, following up to the user-interface timestamp change.
* nsterm.m (last_mouse_movement_time, ns_mouse_position): Use Time
for UI timestamps, instead of unsigned long.
* msdos.c (mouse_get_pos): Likewise.
* w32inevt.c (movement_time, w32_console_mouse_position): Likewise.
* w32gui.h (Time): Define by including "systime.h" rather than by
declaring it ourselves. (Bug#8664)
* dispextern.h (struct image): Don't assume time_t <= unsigned long.
* image.c (clear_image_cache): Likewise.
* term.c (term_mouse_position): Don't assume time_t wraparound.
Be more systematic about user-interface timestamps.
Before, the code sometimes used 'Time', sometimes 'unsigned long',
and sometimes 'EMACS_UINT', to represent these timestamps. This
change causes it to use 'Time' uniformly, as that's what X uses.
This makes the code easier to follow, and makes it easier to catch
integer overflow bugs such as Bug#8664.
* frame.c (Fmouse_position, Fmouse_pixel_position):
Use Time, not unsigned long, for user-interface timestamps.
* keyboard.c (last_event_timestamp, kbd_buffer_get_event): Likewise.
(button_down_time, make_lispy_position, make_lispy_movement): Likewise.
* keyboard.h (last_event_timestamp): Likewise.
* menu.c (Fx_popup_menu) [!HAVE_X_WINDOWS]: Likewise.
* menu.h (xmenu_show): Likewise.
* term.c (term_mouse_position): Likewise.
* termhooks.h (struct input_event.timestamp): Likewise.
(struct terminal.mouse_position_hook): Likewise.
* xmenu.c (create_and_show_popup_menu, xmenu_show): Likewise.
* xterm.c (XTmouse_position, x_scroll_bar_report_motion): Likewise.
* systime.h (Time): New decl. Pull it in from <X11/X.h> if
HAVE_X_WINDOWS, otherwise define it as unsigned long, which is
what it was before.
* menu.h, termhooks.h: Include "systime.h", for Time.
* keyboard.c (make_lispy_event): Fix problem in integer overflow.
Don't assume that the difference between two unsigned long values
can fit into an integer. At this point, we know button_down_time
<= event->timestamp, so the difference must be nonnegative, so
there's no need to cast the result if double-click-time is
nonnegative, as it should be; check that it's nonnegative, just in
case. This bug is triggered when events are more than 2**31 ms
apart (about 25 days). (Bug#8664)
* xselect.c (last_event_timestamp): Remove duplicate decl.
(x_own_selection): Remove needless cast to unsigned long.
* xmenu.c (set_frame_menubar): Use int, not EMACS_UINT, for indexes
that always fit in int. Use a sentinel instead of a counter, to
avoid a temp and to allay GCC's concerns about possible int overflow.
* frame.h (struct frame): Use int for menu_bar_items_used
instead of EMACS_INT, since it always fits in int.
* menu.c (grow_menu_items): Check for int overflow.
* xmenu.c (set_frame_menubar): Don't mishandle vectors with no nils.
* xterm.c: Use EMACS_INT for Emacs modifiers, and int for X modifiers.
Before, the code was not consistent. These values cannot exceed
2**31 - 1 so there's no need to make them unsigned.
(x_x_to_emacs_modifiers): Accept int and return EMACS_INT.
(x_emacs_to_x_modifiers): Accept EMACS_INT and return int.
(x_x_to_emacs_modifiers, x_emacs_to_x_modifiers): Reject non-integers
as modifiers.
* xterm.h (x_x_to_emacs_modifiers): Adjust to signature change.
* lisp.h (XINT) [USE_LISP_UNION_TYPE]: Cast to EMACS_INT.
(XUINT) [USE_LISP_UNION_TYPE]: Cast to EMACS_UINT.
Otherwise, GCC 4.6.0 warns about printf (pI, XINT (...)),
presumably because the widths might not match.
* window.c (size_window): Avoid needless test at loop start.
2011-05-12 Drew Adams <drew.adams@oracle.com>
* textprop.c (Fprevious_single_char_property_change): Doc fix (bug#8655).
......
......@@ -2709,7 +2709,7 @@ struct image
{
/* The time in seconds at which the image was last displayed. Set
in prepare_image_for_display. */
unsigned long timestamp;
time_t timestamp;
/* Pixmaps of the image. */
Pixmap pixmap, mask;
......
......@@ -457,10 +457,10 @@ concat (size_t nargs, Lisp_Object *args,
Lisp_Object prev;
int some_multibyte;
/* When we make a multibyte string, we can't copy text properties
while concatinating each string because the length of resulting
string can't be decided until we finish the whole concatination.
while concatenating each string because the length of resulting
string can't be decided until we finish the whole concatenation.
So, we record strings that have text properties to be copied
here, and copy the text properties after the concatination. */
here, and copy the text properties after the concatenation. */
struct textprop_rec *textprops = NULL;
/* Number of elements in textprops. */
int num_textprops = 0;
......@@ -704,7 +704,7 @@ concat (size_t nargs, Lisp_Object *args,
make_number (0),
make_number (SCHARS (this)),
Qnil);
/* If successive arguments have properites, be sure that the
/* If successive arguments have properties, be sure that the
value of `composition' property be the copy. */
if (last_to_end == textprops[argnum].to)
make_composition_value_copy (props);
......@@ -2076,7 +2076,7 @@ internal_equal (register Lisp_Object o1, register Lisp_Object o2, int depth, int
return compare_window_configurations (o1, o2, 0);
/* Aside from them, only true vectors, char-tables, compiled
functions, and fonts (font-spec, font-entity, font-ojbect)
functions, and fonts (font-spec, font-entity, font-object)
are sensible to compare, so eliminate the others now. */
if (size & PSEUDOVECTOR_FLAG)
{
......@@ -2782,7 +2782,7 @@ ITEM should be one of the following:
`months', returning a 12-element vector of month names (locale items MON_n);
`paper', returning a list (WIDTH HEIGHT) for the default paper size,
both measured in milimeters (locale items PAPER_WIDTH, PAPER_HEIGHT).
both measured in millimeters (locale items PAPER_WIDTH, PAPER_HEIGHT).
If the system can't provide such information through a call to
`nl_langinfo', or if ITEM isn't from the list above, return nil.
......
......@@ -1631,7 +1631,7 @@ and returns whatever that function returns. */)
enum scroll_bar_part party_dummy;
Lisp_Object x, y, retval;
int col, row;
unsigned long long_dummy;
Time long_dummy;
struct gcpro gcpro1;
f = SELECTED_FRAME ();
......@@ -1676,7 +1676,7 @@ and nil for X and Y. */)
Lisp_Object lispy_dummy;
enum scroll_bar_part party_dummy;
Lisp_Object x, y;
unsigned long long_dummy;
Time long_dummy;
f = SELECTED_FRAME ();
x = y = Qnil;
......
......@@ -192,7 +192,7 @@ struct frame
struct face_cache *face_cache;
/* Number of elements in `menu_bar_vector' that have meaningful data. */
EMACS_INT menu_bar_items_used;
int menu_bar_items_used;
/* A buffer to hold the frame's name. We can't use the Lisp
string's pointer (`name', above) because it might get relocated. */
......
......@@ -1523,7 +1523,7 @@ clear_image_cache (struct frame *f, Lisp_Object filter)
{
/* Free cache based on timestamp. */
EMACS_TIME t;
unsigned long old;
time_t old;
int delay, nimages = 0;
for (i = 0; i < c->used; ++i)
......
......@@ -238,7 +238,7 @@ Lisp_Object internal_last_event_frame;
/* The timestamp of the last input event we received from the X server.
X Windows wants this for selection ownership. */
unsigned long last_event_timestamp;
Time last_event_timestamp;
static Lisp_Object Qx_set_selection, Qhandle_switch_frame;
Lisp_Object QPRIMARY;
......@@ -4085,7 +4085,7 @@ kbd_buffer_get_event (KBOARD **kbp,
Lisp_Object bar_window;
enum scroll_bar_part part;
Lisp_Object x, y;
unsigned long t;
Time t;
*kbp = current_kboard;
/* Note that this uses F to determine which terminal to look at.
......@@ -5088,7 +5088,7 @@ static Lisp_Object button_down_location;
static int last_mouse_button;
static int last_mouse_x;
static int last_mouse_y;
static unsigned long button_down_time;
static Time button_down_time;
/* The number of clicks in this multiple-click. */
......@@ -5099,7 +5099,7 @@ static int double_click_count;
static Lisp_Object
make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y,
unsigned long t)
Time t)
{
enum window_part part;
Lisp_Object posn = Qnil;
......@@ -5556,9 +5556,9 @@ make_lispy_event (struct input_event *event)
&& (eabs (XINT (event->y) - last_mouse_y) <= fuzz)
&& button_down_time != 0
&& (EQ (Vdouble_click_time, Qt)
|| (INTEGERP (Vdouble_click_time)
&& ((int)(event->timestamp - button_down_time)
< XINT (Vdouble_click_time)))));
|| (NATNUMP (Vdouble_click_time)
&& (event->timestamp - button_down_time
< XFASTINT (Vdouble_click_time)))));
}
last_mouse_button = button;
......@@ -5742,9 +5742,9 @@ make_lispy_event (struct input_event *event)
&& (eabs (XINT (event->y) - last_mouse_y) <= fuzz)
&& button_down_time != 0
&& (EQ (Vdouble_click_time, Qt)
|| (INTEGERP (Vdouble_click_time)
&& ((int)(event->timestamp - button_down_time)
< XINT (Vdouble_click_time)))));
|| (NATNUMP (Vdouble_click_time)
&& (event->timestamp - button_down_time
< XFASTINT (Vdouble_click_time)))));
if (is_double)
{
double_click_count++;
......@@ -5987,7 +5987,7 @@ make_lispy_event (struct input_event *event)
static Lisp_Object
make_lispy_movement (FRAME_PTR frame, Lisp_Object bar_window, enum scroll_bar_part part,
Lisp_Object x, Lisp_Object y, unsigned long t)
Lisp_Object x, Lisp_Object y, Time t)
{
/* Is it a scroll bar movement? */
if (frame && ! NILP (bar_window))
......
......@@ -16,7 +16,7 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "systime.h" /* for EMACS_TIME */
#include "systime.h" /* for EMACS_TIME, Time */
#include "coding.h" /* for ENCODE_UTF_8 and ENCODE_SYSTEM */
/* Lisp fields in struct keyboard are hidden from most code and accessed
......@@ -459,7 +459,7 @@ extern Lisp_Object Qevent_symbol_element_mask;
/* The timestamp of the last input event we received from the X server.
X Windows wants this for selection ownership. */
extern unsigned long last_event_timestamp;
extern Time last_event_timestamp;
extern int quit_char;
......
......@@ -470,8 +470,8 @@ enum pvec_type
#define XHASH(a) ((a).i)
#define XTYPE(a) ((enum Lisp_Type) (a).u.type)
#define XINT(a) ((a).s.val)
#define XUINT(a) ((a).u.val)
#define XINT(a) ((EMACS_INT) (a).s.val)
#define XUINT(a) ((EMACS_UINT) (a).u.val)
#ifdef USE_LSB_TAG
......
......@@ -176,6 +176,8 @@ save_menu_items (void)
static void
grow_menu_items (void)
{
if ((INT_MAX - MENU_ITEMS_PANE_LENGTH) / 2 < menu_items_allocated)
memory_full ();
menu_items_allocated *= 2;
menu_items = larger_vector (menu_items, menu_items_allocated, Qnil);
}
......@@ -1145,13 +1147,13 @@ no quit occurs and `x-popup-menu' returns nil. */)
#else /* not HAVE_X_WINDOWS */
Lisp_Object bar_window;
enum scroll_bar_part part;
unsigned long time;
Time time;
void (*mouse_position_hook) (struct frame **, int,
Lisp_Object *,
enum scroll_bar_part *,
Lisp_Object *,
Lisp_Object *,
unsigned long *) =
Time *) =
FRAME_TERMINAL (new_f)->mouse_position_hook;
if (mouse_position_hook)
......
......@@ -19,6 +19,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#ifndef MENU_H
#define MENU_H
#include "systime.h" /* for Time */
extern void x_set_menu_bar_lines (struct frame *f,
Lisp_Object value,
Lisp_Object oldval);
......@@ -48,6 +50,5 @@ extern Lisp_Object w32_menu_show (FRAME_PTR, int, int, int, int,
extern Lisp_Object ns_menu_show (FRAME_PTR, int, int, int, int,
Lisp_Object, const char **);
extern Lisp_Object xmenu_show (FRAME_PTR, int, int, int, int,
Lisp_Object, const char **, EMACS_UINT);
Lisp_Object, const char **, Time);
#endif /* MENU_H */
......@@ -287,7 +287,7 @@ mouse_button_depressed (int b, int *xp, int *yp)
void
mouse_get_pos (FRAME_PTR *f, int insist, Lisp_Object *bar_window,
enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y,
unsigned long *time)
Time *time)
{
int ix, iy;
Lisp_Object frame, tail;
......
......@@ -158,7 +158,7 @@ Updated by Christian Limpach (chris@nice.ch)
/* display update */
NSPoint last_mouse_motion_position;
static NSRect last_mouse_glyph;
static unsigned long last_mouse_movement_time = 0;
static Time last_mouse_movement_time = 0;
static Lisp_Object last_mouse_motion_frame;
static EmacsScroller *last_mouse_scroll_bar = nil;
static struct frame *ns_updating_frame;
......@@ -1789,7 +1789,7 @@ Free a pool and temporary objects it refers to (callable from C)
static void
ns_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y,
unsigned long *time)
Time *time)
/* --------------------------------------------------------------------------
External (hook): inform emacs about mouse position and hit parts.
If a scrollbar is being dragged, set bar_window, part, x, y, time.
......@@ -6531,5 +6531,3 @@ Convert an X font name (XLFD) to an NS font name.
/* Tell emacs about this window system. */
Fprovide (intern ("ns"), Qnil);
}
......@@ -30,6 +30,12 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#endif
#endif
#ifdef HAVE_X_WINDOWS
# include <X11/X.h>
#else
typedef unsigned long Time;
#endif
#ifdef HAVE_TZNAME
#ifndef tzname /* For SGI. */
extern char *tzname[]; /* RS6000 and others want it this way. */
......
......@@ -2698,9 +2698,10 @@ term_mouse_movement (FRAME_PTR frame, Gpm_Event *event)
static void
term_mouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window,
enum scroll_bar_part *part, Lisp_Object *x,
Lisp_Object *y, unsigned long *timeptr)
Lisp_Object *y, Time *timeptr)
{
struct timeval now;
Time sec, usec;
*fp = SELECTED_FRAME ();
(*fp)->mouse_moved = 0;
......@@ -2711,7 +2712,9 @@ term_mouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window,
XSETINT (*x, last_mouse_x);
XSETINT (*y, last_mouse_y);
gettimeofday(&now, 0);
*timeptr = (now.tv_sec * 1000) + (now.tv_usec / 1000);
sec = now.tv_sec;
usec = now.tv_usec;
*timeptr = (sec * 1000) + (usec / 1000);
}
/* Prepare a mouse-event in *RESULT for placement in the input queue.
......
......@@ -20,6 +20,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
/* Miscellanea. */
#include "systime.h" /* for Time */
struct glyph;
struct frame;
......@@ -233,7 +235,7 @@ struct input_event
int modifiers; /* See enum below for interpretation. */
Lisp_Object x, y;
unsigned long timestamp;
Time timestamp;
/* This is padding just to put the frame_or_window field
past the size of struct selection_input_event. */
......@@ -463,7 +465,7 @@ struct terminal
enum scroll_bar_part *part,
Lisp_Object *x,
Lisp_Object *y,
unsigned long *);
Time *);
/* The window system handling code should set this if the mouse has
moved since the last call to the mouse_position_hook. Calling that
......
......@@ -20,6 +20,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#define EMACS_W32GUI_H
#include <windows.h>
#include "systime.h" /* for Time */
/* Local memory management for menus. */
#define local_heap (GetProcessHeap ())
#define local_alloc(n) (HeapAlloc (local_heap, HEAP_ZERO_MEMORY, (n)))
......@@ -47,7 +49,6 @@ typedef char * XrmDatabase;
typedef XGCValues * GC;
typedef COLORREF Color;
typedef DWORD Time;
typedef HWND Window;
typedef HDC Display; /* HDC so it doesn't conflict with xpm lib. */
typedef HCURSOR Cursor;
......@@ -147,4 +148,3 @@ typedef struct {
#endif /* EMACS_W32GUI_H */
......@@ -45,7 +45,7 @@ extern HANDLE keyboard_handle;
/* Info for last mouse motion */
static COORD movement_pos;
static DWORD movement_time;
static Time movement_time;
/* from w32fns.c */
extern unsigned int map_keypad_keys (unsigned int, unsigned int);
......@@ -544,7 +544,7 @@ w32_console_mouse_position (FRAME_PTR *f,
enum scroll_bar_part *part,
Lisp_Object *x,
Lisp_Object *y,
unsigned long *time)
Time *time)
{
BLOCK_INPUT;
......@@ -756,4 +756,3 @@ w32_console_read_socket (struct terminal *terminal,
UNBLOCK_INPUT;
return ret;
}
......@@ -3094,11 +3094,14 @@ size_window (Lisp_Object window, int size, int width_p, int nodelete_p, int firs
Lisp_Object last_child;
int child_size;
for (child = *forward; !NILP (child); child = c->next)
child = *forward;
do
{
c = XWINDOW (child);
last_child = child;
child = c->next;
}
while (!NILP (child));
child_size = WINDOW_TOTAL_SIZE (c, width_p);
size_window (last_child, size - old_size + child_size,
......
......@@ -240,7 +240,7 @@ for instance using the window manager, then this produces a quit and
FRAME_PTR new_f = SELECTED_FRAME ();
Lisp_Object bar_window;
enum scroll_bar_part part;
unsigned long time;
Time time;
Lisp_Object x, y;
(*mouse_position_hook) (&new_f, 1, &bar_window, &part, &x, &y, &time);
......@@ -922,7 +922,7 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p)
#endif
Lisp_Object items;
widget_value *wv, *first_wv, *prev_wv = 0;
EMACS_UINT i, last_i = 0;
int i;
int *submenu_start, *submenu_end;
int *submenu_top_level_items, *submenu_n_panes;
......@@ -966,7 +966,7 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p)
Lisp_Object *previous_items
= (Lisp_Object *) alloca (previous_menu_items_used
* sizeof (Lisp_Object));
EMACS_UINT subitems;
int subitems;
/* If we are making a new widget, its contents are empty,
do always reinitialize them. */
......@@ -1012,7 +1012,7 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p)
menu_items = f->menu_bar_vector;
menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
subitems = ASIZE (items) / 4;
submenu_start = (int *) alloca (subitems * sizeof (int));
submenu_start = (int *) alloca ((subitems + 1) * sizeof (int));
submenu_end = (int *) alloca (subitems * sizeof (int));
submenu_n_panes = (int *) alloca (subitems * sizeof (int));
submenu_top_level_items = (int *) alloca (subitems * sizeof (int));
......@@ -1021,8 +1021,6 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p)
{
Lisp_Object key, string, maps;
last_i = i;
key = XVECTOR (items)->contents[4 * i];
string = XVECTOR (items)->contents[4 * i + 1];
maps = XVECTOR (items)->contents[4 * i + 2];
......@@ -1039,6 +1037,7 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p)
submenu_end[i] = menu_items_used;
}
submenu_start[i] = -1;
finish_menu_items ();
/* Convert menu_items into widget_value trees
......@@ -1052,7 +1051,7 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p)
wv->help = Qnil;
first_wv = wv;
for (i = 0; i < last_i; i++)
for (i = 0; 0 <= submenu_start[i]; i++)
{
menu_items_n_panes = submenu_n_panes[i];
wv = digest_single_submenu (submenu_start[i], submenu_end[i],
......@@ -1421,7 +1420,8 @@ pop_down_menu (Lisp_Object arg)
menu pops down.
menu_item_selection will be set to the selection. */
static void
create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv, int x, int y, int for_click, EMACS_UINT timestamp)
create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv, int x, int y,
int for_click, Time timestamp)
{
int i;
GtkWidget *menu;
......@@ -1465,7 +1465,7 @@ create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv, int x, int y, i
gtk_widget_show_all (menu);
gtk_menu_popup (GTK_MENU (menu), 0, 0, pos_func, &popup_x_y, i,
timestamp > 0 ? timestamp : gtk_get_current_event_time());
timestamp ? timestamp : gtk_get_current_event_time ());
record_unwind_protect (pop_down_menu, make_save_value (menu, 0));
......@@ -1525,7 +1525,7 @@ pop_down_menu (Lisp_Object arg)
menu_item_selection will be set to the selection. */
static void
create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv,
int x, int y, int for_click, EMACS_UINT timestamp)
int x, int y, int for_click, Time timestamp)
{
int i;
Arg av[2];
......@@ -1599,7 +1599,7 @@ create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv,
Lisp_Object
xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
Lisp_Object title, const char **error_name, EMACS_UINT timestamp)
Lisp_Object title, const char **error_name, Time timestamp)
{
int i;
widget_value *wv, *save_wv = 0, *first_wv = 0, *prev_wv = 0;
......@@ -2242,7 +2242,7 @@ pop_down_menu (Lisp_Object arg)
Lisp_Object
xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
Lisp_Object title, const char **error_name, EMACS_UINT timestamp)
Lisp_Object title, const char **error_name, Time timestamp)
{
Window root;
XMenu *menu;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment