window.c 224 KB
Newer Older
Jim Blandy's avatar
Jim Blandy committed
1 2
/* Window creation, deletion and examination for GNU Emacs.
   Does not include redisplay.
3
   Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
4
                 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
Glenn Morris's avatar
Glenn Morris committed
5
                 Free Software Foundation, Inc.
Jim Blandy's avatar
Jim Blandy committed
6 7 8

This file is part of GNU Emacs.

9
GNU Emacs is free software: you can redistribute it and/or modify
Jim Blandy's avatar
Jim Blandy committed
10
it under the terms of the GNU General Public License as published by
11 12
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Jim Blandy's avatar
Jim Blandy committed
13 14 15 16 17 18 19

GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
20
along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
Jim Blandy's avatar
Jim Blandy committed
21

22
#include <config.h>
23
#include <stdio.h>
24
#include <setjmp.h>
25

Jim Blandy's avatar
Jim Blandy committed
26 27
#include "lisp.h"
#include "buffer.h"
28
#include "keyboard.h"
Stefan Monnier's avatar
Stefan Monnier committed
29
#include "keymap.h"
Jim Blandy's avatar
Jim Blandy committed
30
#include "frame.h"
Jim Blandy's avatar
Jim Blandy committed
31 32 33 34 35
#include "window.h"
#include "commands.h"
#include "indent.h"
#include "termchar.h"
#include "disptab.h"
Andreas Schwab's avatar
Andreas Schwab committed
36
#include "dispextern.h"
37 38
#include "blockinput.h"
#include "intervals.h"
39
#include "termhooks.h"		/* For FRAME_TERMINAL.  */
40

41
#ifdef HAVE_X_WINDOWS
Andreas Schwab's avatar
Andreas Schwab committed
42
#include "xterm.h"
43
#endif	/* HAVE_X_WINDOWS */
Andrew Innes's avatar
Andrew Innes committed
44 45 46
#ifdef WINDOWSNT
#include "w32term.h"
#endif
47 48 49
#ifdef MSDOS
#include "msdos.h"
#endif
50 51 52
#ifdef HAVE_NS
#include "nsterm.h"
#endif
53

54
Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configuration_p;
55
Lisp_Object Qdisplay_buffer;
56
Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command;
57
Lisp_Object Qwindow_size_fixed;
58

59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
static int displayed_window_lines (struct window *);
static struct window *decode_window (Lisp_Object);
static int count_windows (struct window *);
static int get_leaf_windows (struct window *, struct window **, int);
static void window_scroll (Lisp_Object, int, int, int);
static void window_scroll_pixel_based (Lisp_Object, int, int, int);
static void window_scroll_line_based (Lisp_Object, int, int, int);
static int window_min_size_1 (struct window *, int, int);
static int window_min_size_2 (struct window *, int, int);
static int window_min_size (struct window *, int, int, int, int *);
static void size_window (Lisp_Object, int, int, int, int, int);
static int freeze_window_start (struct window *, void *);
static int window_fixed_size_p (struct window *, int, int);
static void enlarge_window (Lisp_Object, int, int);
static Lisp_Object window_list (void);
static int add_window_to_list (struct window *, void *);
static int candidate_window_p (Lisp_Object, Lisp_Object, Lisp_Object,
                               Lisp_Object);
static Lisp_Object next_window (Lisp_Object, Lisp_Object,
                                Lisp_Object, int);
static void decode_next_window_args (Lisp_Object *, Lisp_Object *,
                                     Lisp_Object *);
Andreas Schwab's avatar
Andreas Schwab committed
81
static void foreach_window (struct frame *,
82
				 int (* fn) (struct window *, void *),
Andreas Schwab's avatar
Andreas Schwab committed
83
                            void *);
84 85 86 87
static int foreach_window_1 (struct window *,
                             int (* fn) (struct window *, void *),
                             void *);
static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object);
Glenn Morris's avatar
Glenn Morris committed
88
static Lisp_Object select_window (Lisp_Object, Lisp_Object, int);
89

Jim Blandy's avatar
Jim Blandy committed
90 91 92 93 94 95
/* This is the window in which the terminal's cursor should
   be left when nothing is being done with it.  This must
   always be a leaf window, and its buffer is selected by
   the top level editing loop at the end of each command.

   This value is always the same as
Jim Blandy's avatar
Jim Blandy committed
96
   FRAME_SELECTED_WINDOW (selected_frame).  */
Jim Blandy's avatar
Jim Blandy committed
97 98 99

Lisp_Object selected_window;

Gerd Moellmann's avatar
Gerd Moellmann committed
100 101 102 103 104 105
/* A list of all windows for use by next_window and Fwindow_list.
   Functions creating or deleting windows should invalidate this cache
   by setting it to nil.  */

Lisp_Object Vwindow_list;

106 107 108
/* The mini-buffer window of the selected frame.
   Note that you cannot test for mini-bufferness of an arbitrary window
   by comparing against this; but you can test for mini-bufferness of
Jim Blandy's avatar
Jim Blandy committed
109
   the selected window.  */
110

Jim Blandy's avatar
Jim Blandy committed
111 112
Lisp_Object minibuf_window;

113 114 115
/* Non-nil means it is the window whose mode line should be
   shown as the selected window when the minibuffer is selected.  */

116
Lisp_Object minibuf_selected_window;
117

118
/* Hook run at end of temp_output_buffer_show.  */
119

120 121
Lisp_Object Qtemp_buffer_show_hook;

Jim Blandy's avatar
Jim Blandy committed
122
/* Incremented for each window created.  */
123

Jim Blandy's avatar
Jim Blandy committed
124 125
static int sequence_number;

126
/* Nonzero after init_window_once has finished.  */
127

128 129
static int window_initialized;

130
/* Hook to run when window config changes.  */
131

132
static Lisp_Object Qwindow_configuration_change_hook;
133 134 135 136
/* Incremented by 1 whenever a window is deleted.  */

int window_deletion_count;

137 138
/* Used by the function window_scroll_pixel_based */

139
static int window_scroll_pixel_based_preserve_x;
140
static int window_scroll_pixel_based_preserve_y;
141

142 143 144 145 146
/* Same for window_scroll_line_based.  */

static int window_scroll_preserve_hpos;
static int window_scroll_preserve_vpos;

147
#if 0 /* This isn't used anywhere.  */
148
/* Nonzero means we can split a frame even if it is "unsplittable".  */
149
static int inhibit_frame_unsplittable;
150
#endif
151

Jim Blandy's avatar
Jim Blandy committed
152 153

DEFUN ("windowp", Fwindowp, Swindowp, 1, 1, 0,
154
       doc: /* Return t if OBJECT is a window.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
155
  (Lisp_Object object)
Jim Blandy's avatar
Jim Blandy committed
156
{
157
  return WINDOWP (object) ? Qt : Qnil;
Jim Blandy's avatar
Jim Blandy committed
158 159
}

160
DEFUN ("window-live-p", Fwindow_live_p, Swindow_live_p, 1, 1, 0,
161
       doc: /* Return t if OBJECT is a window which is currently visible.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
162
  (Lisp_Object object)
163
{
164
  return WINDOW_LIVE_P (object) ? Qt : Qnil;
165 166
}

Jim Blandy's avatar
Jim Blandy committed
167
Lisp_Object
168
make_window (void)
Jim Blandy's avatar
Jim Blandy committed
169
{
170
  Lisp_Object val;
Jim Blandy's avatar
Jim Blandy committed
171
  register struct window *p;
172

173
  p = allocate_window ();
174 175
  ++sequence_number;
  XSETFASTINT (p->sequence_number, sequence_number);
176 177 178 179
  XSETFASTINT (p->left_col, 0);
  XSETFASTINT (p->top_line, 0);
  XSETFASTINT (p->total_lines, 0);
  XSETFASTINT (p->total_cols, 0);
180
  XSETFASTINT (p->hscroll, 0);
181
  XSETFASTINT (p->min_hscroll, 0);
182
  p->orig_top_line = p->orig_total_lines = Qnil;
Jim Blandy's avatar
Jim Blandy committed
183 184
  p->start = Fmake_marker ();
  p->pointm = Fmake_marker ();
185
  XSETFASTINT (p->use_time, 0);
Jim Blandy's avatar
Jim Blandy committed
186
  p->frame = Qnil;
Jim Blandy's avatar
Jim Blandy committed
187 188
  p->display_table = Qnil;
  p->dedicated = Qnil;
189
  p->window_parameters = Qnil;
190
  p->pseudo_window_p = 0;
191 192 193
  memset (&p->cursor, 0, sizeof (p->cursor));
  memset (&p->last_cursor, 0, sizeof (p->last_cursor));
  memset (&p->phys_cursor, 0, sizeof (p->phys_cursor));
194
  p->desired_matrix = p->current_matrix = 0;
195
  p->nrows_scale_factor = p->ncols_scale_factor = 1;
196
  p->phys_cursor_type = -1;
197
  p->phys_cursor_width = -1;
198 199 200 201 202
  p->must_be_updated_p = 0;
  XSETFASTINT (p->window_end_vpos, 0);
  XSETFASTINT (p->window_end_pos, 0);
  p->window_end_valid = Qnil;
  p->vscroll = 0;
203
  XSETWINDOW (val, p);
204
  XSETFASTINT (p->last_point, 0);
205
  p->frozen_window_start_p = 0;
206
  p->last_cursor_off_p = p->cursor_off_p = 0;
207 208 209 210 211 212 213
  p->left_margin_cols = Qnil;
  p->right_margin_cols = Qnil;
  p->left_fringe_width = Qnil;
  p->right_fringe_width = Qnil;
  p->fringes_outside_margins = Qnil;
  p->scroll_bar_width = Qnil;
  p->vertical_scroll_bar_type = Qt;
214
  p->resize_proportionally = Qnil;
Gerd Moellmann's avatar
Gerd Moellmann committed
215 216

  Vwindow_list = Qnil;
Jim Blandy's avatar
Jim Blandy committed
217 218 219 220
  return val;
}

DEFUN ("selected-window", Fselected_window, Sselected_window, 0, 0, 0,
221
       doc: /* Return the window that the cursor now appears in and commands apply to.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
222
  (void)
Jim Blandy's avatar
Jim Blandy committed
223 224 225 226
{
  return selected_window;
}

227
DEFUN ("minibuffer-window", Fminibuffer_window, Sminibuffer_window, 0, 1, 0,
228 229 230
       doc: /* Return the window used now for minibuffers.
If the optional argument FRAME is specified, return the minibuffer window
used by that frame.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
231
  (Lisp_Object frame)
Jim Blandy's avatar
Jim Blandy committed
232
{
233
  if (NILP (frame))
234
    frame = selected_frame;
235
  CHECK_LIVE_FRAME (frame);
236
  return FRAME_MINIBUF_WINDOW (XFRAME (frame));
Jim Blandy's avatar
Jim Blandy committed
237 238
}

239
DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p, Swindow_minibuffer_p, 0, 1, 0,
240
       doc: /* Return non-nil if WINDOW is a minibuffer window.
Kenichi Handa's avatar
Kenichi Handa committed
241
WINDOW defaults to the selected window.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
242
  (Lisp_Object window)
Jim Blandy's avatar
Jim Blandy committed
243 244
{
  struct window *w = decode_window (window);
245
  return MINI_WINDOW_P (w) ? Qt : Qnil;
Miles Bader's avatar
Miles Bader committed
246 247 248
}


Jim Blandy's avatar
Jim Blandy committed
249
DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p,
250
       Spos_visible_in_window_p, 0, 3, 0,
251
       doc: /* Return non-nil if position POS is currently on the frame in WINDOW.
252 253 254
Return nil if that position is scrolled vertically out of view.
If a character is only partially visible, nil is returned, unless the
optional argument PARTIALLY is non-nil.
255
If POS is only out of view because of horizontal scrolling, return non-nil.
256
If POS is t, it specifies the position of the last visible glyph in WINDOW.
257 258 259
POS defaults to point in WINDOW; WINDOW defaults to the selected window.

If POS is visible, return t if PARTIALLY is nil; if PARTIALLY is non-nil,
260 261 262 263
return value is a list of 2 or 6 elements (X Y [RTOP RBOT ROWH VPOS]),
where X and Y are the pixel coordinates relative to the top left corner
of the window.  The remaining elements are omitted if the character after
POS is fully visible; otherwise, RTOP and RBOT are the number of pixels
264
off-window at the top and bottom of the row, ROWH is the height of the
265
display row, and VPOS is the row number (0-based) containing POS.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
266
  (Lisp_Object pos, Lisp_Object window, Lisp_Object partially)
Jim Blandy's avatar
Jim Blandy committed
267 268
{
  register struct window *w;
269
  register EMACS_INT posint;
Jim Blandy's avatar
Jim Blandy committed
270
  register struct buffer *buf;
271
  struct text_pos top;
272
  Lisp_Object in_window = Qnil;
273
  int rtop, rbot, rowh, vpos, fully_p = 1;
274
  int x, y;
Jim Blandy's avatar
Jim Blandy committed
275

Miles Bader's avatar
Miles Bader committed
276 277 278 279
  w = decode_window (window);
  buf = XBUFFER (w->buffer);
  SET_TEXT_POS_FROM_MARKER (top, w->start);

280 281 282
  if (EQ (pos, Qt))
    posint = -1;
  else if (!NILP (pos))
Jim Blandy's avatar
Jim Blandy committed
283
    {
284
      CHECK_NUMBER_COERCE_MARKER (pos);
Jim Blandy's avatar
Jim Blandy committed
285 286
      posint = XINT (pos);
    }
Miles Bader's avatar
Miles Bader committed
287 288 289 290
  else if (w == XWINDOW (selected_window))
    posint = PT;
  else
    posint = XMARKER (w->pointm)->charpos;
Jim Blandy's avatar
Jim Blandy committed
291

292 293
  /* If position is above window start or outside buffer boundaries,
     or if window start is out of range, position is not visible.  */
294 295
  if ((EQ (pos, Qt)
       || (posint >= CHARPOS (top) && posint <= BUF_ZV (buf)))
296 297
      && CHARPOS (top) >= BUF_BEGV (buf)
      && CHARPOS (top) <= BUF_ZV (buf)
298
      && pos_visible_p (w, posint, &x, &y, &rtop, &rbot, &rowh, &vpos)
299
      && (fully_p = !rtop && !rbot, (!NILP (partially) || fully_p)))
300 301 302
    in_window = Qt;

  if (!NILP (in_window) && !NILP (partially))
303 304 305 306 307 308 309 310 311
    {
      Lisp_Object part = Qnil;
      if (!fully_p)
	part = list4 (make_number (rtop), make_number (rbot),
			make_number (rowh), make_number (vpos));
      in_window = Fcons (make_number (x),
			 Fcons (make_number (y), part));
    }

312
  return in_window;
Jim Blandy's avatar
Jim Blandy committed
313
}
314

315
DEFUN ("window-line-height", Fwindow_line_height,
316
       Swindow_line_height, 0, 2, 0,
317 318 319
       doc: /* Return height in pixels of text line LINE in window WINDOW.
If WINDOW is nil or omitted, use selected window.

320 321 322 323
Return height of current line if LINE is omitted or nil.  Return height of
header or mode line if LINE is `header-line' and `mode-line'.
Otherwise, LINE is a text line number starting from 0.  A negative number
counts from the end of the window.
324

325
Value is a list (HEIGHT VPOS YPOS OFFBOT), where HEIGHT is the height
326
in pixels of the visible part of the line, VPOS and YPOS are the
327
vertical position in lines and pixels of the line, relative to the top
328
of the first text line, and OFFBOT is the number of off-window pixels at
329 330
the bottom of the text line.  If there are off-window pixels at the top
of the (first) text line, YPOS is negative.
331 332 333

Return nil if window display is not up-to-date.  In that case, use
`pos-visible-in-window-p' to obtain the information.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
334
  (Lisp_Object line, Lisp_Object window)
335 336 337 338
{
  register struct window *w;
  register struct buffer *b;
  struct glyph_row *row, *end_row;
339
  int max_y, crop, i, n;
340 341 342 343 344

  w = decode_window (window);

  if (noninteractive
      || w->pseudo_window_p)
345
    return Qnil;
346 347 348 349 350 351 352 353 354 355 356 357

  CHECK_BUFFER (w->buffer);
  b = XBUFFER (w->buffer);

  /* Fail if current matrix is not up-to-date.  */
  if (NILP (w->window_end_valid)
      || current_buffer->clip_changed
      || current_buffer->prevent_redisplay_optimizations_p
      || XFASTINT (w->last_modified) < BUF_MODIFF (b)
      || XFASTINT (w->last_overlay_modified) < BUF_OVERLAY_MODIFF (b))
    return Qnil;

358 359 360 361 362 363 364 365 366 367
  if (NILP (line))
    {
      i = w->cursor.vpos;
      if (i < 0 || i >= w->current_matrix->nrows
	  || (row = MATRIX_ROW (w->current_matrix, i), !row->enabled_p))
	return Qnil;
      max_y = window_text_bottom_y (w);
      goto found_row;
    }

368
  if (EQ (line, Qheader_line))
369
    {
370 371 372
      if (!WINDOW_WANTS_HEADER_LINE_P (w))
	return Qnil;
      row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
373 374
      if (!row->enabled_p)
	return Qnil;
375 376 377
      return list4 (make_number (row->height),
		    make_number (0), make_number (0),
		    make_number (0));
378
    }
379 380

  if (EQ (line, Qmode_line))
381
    {
382 383 384 385 386 387 388 389 390
      row = MATRIX_MODE_LINE_ROW (w->current_matrix);
      if (!row->enabled_p)
	return Qnil;
      return list4 (make_number (row->height),
		    make_number (0), /* not accurate */
		    make_number (WINDOW_HEADER_LINE_HEIGHT (w)
				 + window_text_bottom_y (w)),
		    make_number (0));
    }
391

392
  CHECK_NUMBER (line);
393
  n = XINT (line);
394 395 396 397

  row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
  end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
  max_y = window_text_bottom_y (w);
398
  i = 0;
399 400 401 402 403

  while ((n < 0 || i < n)
	 && row <= end_row && row->enabled_p
	 && row->y + row->height < max_y)
    row++, i++;
404

405 406 407
  if (row > end_row || !row->enabled_p)
    return Qnil;

408
  if (++n < 0)
409 410 411
    {
      if (-n > i)
	return Qnil;
412 413
      row += n;
      i += n;
414 415
    }

416
 found_row:
417 418
  crop = max (0, (row->y + row->height) - max_y);
  return list4 (make_number (row->height + min (0, row->y) - crop),
419
		make_number (i),
420 421
		make_number (row->y),
		make_number (crop));
422 423
}

424

Jim Blandy's avatar
Jim Blandy committed
425 426

static struct window *
427
decode_window (register Lisp_Object window)
Jim Blandy's avatar
Jim Blandy committed
428
{
Jim Blandy's avatar
Jim Blandy committed
429
  if (NILP (window))
Jim Blandy's avatar
Jim Blandy committed
430 431
    return XWINDOW (selected_window);

432
  CHECK_LIVE_WINDOW (window);
Jim Blandy's avatar
Jim Blandy committed
433 434 435
  return XWINDOW (window);
}

Kenichi Handa's avatar
Kenichi Handa committed
436
static struct window *
437
decode_any_window (register Lisp_Object window)
Kenichi Handa's avatar
Kenichi Handa committed
438 439 440 441 442 443 444 445
{
  if (NILP (window))
    return XWINDOW (selected_window);

  CHECK_WINDOW (window);
  return XWINDOW (window);
}

Jim Blandy's avatar
Jim Blandy committed
446
DEFUN ("window-buffer", Fwindow_buffer, Swindow_buffer, 0, 1, 0,
447 448
       doc: /* Return the buffer that WINDOW is displaying.
WINDOW defaults to the selected window.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
449
  (Lisp_Object window)
Jim Blandy's avatar
Jim Blandy committed
450 451 452 453 454
{
  return decode_window (window)->buffer;
}

DEFUN ("window-height", Fwindow_height, Swindow_height, 0, 1, 0,
455 456 457
       doc: /* Return the number of lines in WINDOW.
WINDOW defaults to the selected window.

458 459 460 461
The return value includes WINDOW's mode line and header line, if any.

Note: The function does not take into account the value of `line-spacing'
when calculating the number of lines in WINDOW.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
462
  (Lisp_Object window)
Jim Blandy's avatar
Jim Blandy committed
463
{
Kenichi Handa's avatar
Kenichi Handa committed
464
  return decode_any_window (window)->total_lines;
Jim Blandy's avatar
Jim Blandy committed
465 466 467
}

DEFUN ("window-width", Fwindow_width, Swindow_width, 0, 1, 0,
468
       doc: /* Return the number of display columns in WINDOW.
469 470 471 472 473
WINDOW defaults to the selected window.

Note: The return value is the number of columns available for text in
WINDOW.  If you want to find out how many columns WINDOW takes up, use
(let ((edges (window-edges))) (- (nth 2 edges) (nth 0 edges))).  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
474
  (Lisp_Object window)
Jim Blandy's avatar
Jim Blandy committed
475
{
Kenichi Handa's avatar
Kenichi Handa committed
476
  return make_number (window_box_text_cols (decode_any_window (window)));
Jim Blandy's avatar
Jim Blandy committed
477 478
}

479 480 481
DEFUN ("window-full-width-p", Fwindow_full_width_p, Swindow_full_width_p, 0, 1, 0,
       doc: /* Return t if WINDOW is as wide as its frame.
WINDOW defaults to the selected window.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
482
  (Lisp_Object window)
483 484 485 486
{
  return WINDOW_FULL_WIDTH_P (decode_any_window (window)) ? Qt : Qnil;
}

Jim Blandy's avatar
Jim Blandy committed
487
DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0,
488 489
       doc: /* Return the number of columns by which WINDOW is scrolled from left margin.
WINDOW defaults to the selected window.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
490
  (Lisp_Object window)
Jim Blandy's avatar
Jim Blandy committed
491 492 493 494 495
{
  return decode_window (window)->hscroll;
}

DEFUN ("set-window-hscroll", Fset_window_hscroll, Sset_window_hscroll, 2, 2, 0,
496
       doc: /* Set number of columns WINDOW is scrolled from left margin to NCOL.
497
Return NCOL.  NCOL should be zero or positive.
498 499

Note that if `automatic-hscrolling' is non-nil, you cannot scroll the
500
window so that the location of point moves off-window.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
501
  (Lisp_Object window, Lisp_Object ncol)
Jim Blandy's avatar
Jim Blandy committed
502
{
503 504
  struct window *w = decode_window (window);
  int hscroll;
Jim Blandy's avatar
Jim Blandy committed
505

506
  CHECK_NUMBER (ncol);
507
  hscroll = max (0, XINT (ncol));
508

509 510
  /* Prevent redisplay shortcuts when changing the hscroll.  */
  if (XINT (w->hscroll) != hscroll)
Gerd Moellmann's avatar
Gerd Moellmann committed
511
    XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
512

513
  w->hscroll = make_number (hscroll);
Jim Blandy's avatar
Jim Blandy committed
514 515 516
  return ncol;
}

517 518
DEFUN ("window-redisplay-end-trigger", Fwindow_redisplay_end_trigger,
       Swindow_redisplay_end_trigger, 0, 1, 0,
519
       doc: /* Return WINDOW's redisplay end trigger value.
520
WINDOW defaults to the selected window.
521
See `set-window-redisplay-end-trigger' for more information.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
522
  (Lisp_Object window)
523 524 525 526 527 528
{
  return decode_window (window)->redisplay_end_trigger;
}

DEFUN ("set-window-redisplay-end-trigger", Fset_window_redisplay_end_trigger,
       Sset_window_redisplay_end_trigger, 2, 2, 0,
529 530 531 532 533 534
       doc: /* Set WINDOW's redisplay end trigger value to VALUE.
VALUE should be a buffer position (typically a marker) or nil.
If it is a buffer position, then if redisplay in WINDOW reaches a position
beyond VALUE, the functions in `redisplay-end-trigger-functions' are called
with two arguments: WINDOW, and the end trigger value.
Afterwards the end-trigger value is reset to nil.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
535
  (register Lisp_Object window, Lisp_Object value)
536 537 538 539 540 541 542 543
{
  register struct window *w;

  w = decode_window (window);
  w->redisplay_end_trigger = value;
  return value;
}

Jim Blandy's avatar
Jim Blandy committed
544
DEFUN ("window-edges", Fwindow_edges, Swindow_edges, 0, 1, 0,
545
       doc: /* Return a list of the edge coordinates of WINDOW.
546 547 548 549 550 551 552 553 554
The list has the form (LEFT TOP RIGHT BOTTOM).
TOP and BOTTOM count by lines, and LEFT and RIGHT count by columns,
all relative to 0, 0 at top left corner of frame.

RIGHT is one more than the rightmost column occupied by WINDOW.
BOTTOM is one more than the bottommost row occupied by WINDOW.
The edges include the space used by WINDOW's scroll bar, display
margins, fringes, header line, and/or mode line.  For the edges of
just the text area, use `window-inside-edges'.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
555
  (Lisp_Object window)
Jim Blandy's avatar
Jim Blandy committed
556
{
Kenichi Handa's avatar
Kenichi Handa committed
557
  register struct window *w = decode_any_window (window);
Jim Blandy's avatar
Jim Blandy committed
558

559 560 561 562 563
  return Fcons (make_number (WINDOW_LEFT_EDGE_COL (w)),
	 Fcons (make_number (WINDOW_TOP_EDGE_LINE (w)),
	 Fcons (make_number (WINDOW_RIGHT_EDGE_COL (w)),
	 Fcons (make_number (WINDOW_BOTTOM_EDGE_LINE (w)),
		Qnil))));
Jim Blandy's avatar
Jim Blandy committed
564 565
}

566 567
DEFUN ("window-pixel-edges", Fwindow_pixel_edges, Swindow_pixel_edges, 0, 1, 0,
       doc: /* Return a list of the edge pixel coordinates of WINDOW.
568 569 570 571 572 573 574 575
The list has the form (LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at
the top left corner of the frame.

RIGHT is one more than the rightmost x position occupied by WINDOW.
BOTTOM is one more than the bottommost y position occupied by WINDOW.
The pixel edges include the space used by WINDOW's scroll bar, display
margins, fringes, header line, and/or mode line.  For the pixel edges
of just the text area, use `window-inside-pixel-edges'.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
576
  (Lisp_Object window)
577
{
Kenichi Handa's avatar
Kenichi Handa committed
578
  register struct window *w = decode_any_window (window);
579 580 581 582 583 584 585 586

  return Fcons (make_number (WINDOW_LEFT_EDGE_X (w)),
	 Fcons (make_number (WINDOW_TOP_EDGE_Y (w)),
	 Fcons (make_number (WINDOW_RIGHT_EDGE_X (w)),
	 Fcons (make_number (WINDOW_BOTTOM_EDGE_Y (w)),
		Qnil))));
}

587 588 589 590 591 592 593 594
static void
calc_absolute_offset(struct window *w, int *add_x, int *add_y)
{
  struct frame *f = XFRAME (w->frame);
  *add_y = f->top_pos;
#ifdef FRAME_MENUBAR_HEIGHT
  *add_y += FRAME_MENUBAR_HEIGHT (f);
#endif
595 596 597
#ifdef FRAME_TOOLBAR_TOP_HEIGHT
  *add_y += FRAME_TOOLBAR_TOP_HEIGHT (f);
#elif FRAME_TOOLBAR_HEIGHT
598 599 600 601 602 603
  *add_y += FRAME_TOOLBAR_HEIGHT (f);
#endif
#ifdef FRAME_NS_TITLEBAR_HEIGHT
  *add_y += FRAME_NS_TITLEBAR_HEIGHT (f);
#endif
  *add_x = f->left_pos;
604 605 606
#ifdef FRAME_TOOLBAR_LEFT_WIDTH
  *add_x += FRAME_TOOLBAR_LEFT_WIDTH (f);
#endif
607 608 609 610 611 612 613 614 615 616 617 618
}

DEFUN ("window-absolute-pixel-edges", Fwindow_absolute_pixel_edges,
       Swindow_absolute_pixel_edges, 0, 1, 0,
       doc: /* Return a list of the edge pixel coordinates of WINDOW.
The list has the form (LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at
the top left corner of the display.

RIGHT is one more than the rightmost x position occupied by WINDOW.
BOTTOM is one more than the bottommost y position occupied by WINDOW.
The pixel edges include the space used by WINDOW's scroll bar, display
margins, fringes, header line, and/or mode line.  For the pixel edges
619
of just the text area, use `window-inside-absolute-pixel-edges'.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
620
  (Lisp_Object window)
621 622 623
{
  register struct window *w = decode_any_window (window);
  int add_x, add_y;
624
  calc_absolute_offset (w, &add_x, &add_y);
625 626 627 628 629 630 631 632

  return Fcons (make_number (WINDOW_LEFT_EDGE_X (w) + add_x),
         Fcons (make_number (WINDOW_TOP_EDGE_Y (w) + add_y),
	 Fcons (make_number (WINDOW_RIGHT_EDGE_X (w) + add_x),
	 Fcons (make_number (WINDOW_BOTTOM_EDGE_Y (w) + add_y),
		Qnil))));
}

633 634
DEFUN ("window-inside-edges", Fwindow_inside_edges, Swindow_inside_edges, 0, 1, 0,
       doc: /* Return a list of the edge coordinates of WINDOW.
635 636 637 638 639 640 641 642
The list has the form (LEFT TOP RIGHT BOTTOM).
TOP and BOTTOM count by lines, and LEFT and RIGHT count by columns,
all relative to 0, 0 at top left corner of frame.

RIGHT is one more than the rightmost column of WINDOW's text area.
BOTTOM is one more than the bottommost row of WINDOW's text area.
The inside edges do not include the space used by the WINDOW's scroll
bar, display margins, fringes, header line, and/or mode line.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
643
  (Lisp_Object window)
644
{
Kenichi Handa's avatar
Kenichi Handa committed
645
  register struct window *w = decode_any_window (window);
646 647 648 649 650 651

  return list4 (make_number (WINDOW_BOX_LEFT_EDGE_COL (w)
			     + WINDOW_LEFT_MARGIN_COLS (w)
			     + WINDOW_LEFT_FRINGE_COLS (w)),
		make_number (WINDOW_TOP_EDGE_LINE (w)
			     + WINDOW_HEADER_LINE_LINES (w)),
652
		make_number (WINDOW_BOX_RIGHT_EDGE_COL (w)
653 654 655 656 657 658 659
			     - WINDOW_RIGHT_MARGIN_COLS (w)
			     - WINDOW_RIGHT_FRINGE_COLS (w)),
		make_number (WINDOW_BOTTOM_EDGE_LINE (w)
			     - WINDOW_MODE_LINE_LINES (w)));
}

DEFUN ("window-inside-pixel-edges", Fwindow_inside_pixel_edges, Swindow_inside_pixel_edges, 0, 1, 0,
660
       doc: /* Return a list of the edge pixel coordinates of WINDOW.
661 662 663 664 665 666
The list has the form (LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at
the top left corner of the frame.

RIGHT is one more than the rightmost x position of WINDOW's text area.
BOTTOM is one more than the bottommost y position of WINDOW's text area.
The inside edges do not include the space used by WINDOW's scroll bar,
667
display margins, fringes, header line, and/or mode line.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
668
  (Lisp_Object window)
669
{
Kenichi Handa's avatar
Kenichi Handa committed
670
  register struct window *w = decode_any_window (window);
671 672 673 674 675 676

  return list4 (make_number (WINDOW_BOX_LEFT_EDGE_X (w)
			     + WINDOW_LEFT_MARGIN_WIDTH (w)
			     + WINDOW_LEFT_FRINGE_WIDTH (w)),
		make_number (WINDOW_TOP_EDGE_Y (w)
			     + WINDOW_HEADER_LINE_HEIGHT (w)),
677
		make_number (WINDOW_BOX_RIGHT_EDGE_X (w)
678 679 680 681 682 683
			     - WINDOW_RIGHT_MARGIN_WIDTH (w)
			     - WINDOW_RIGHT_FRINGE_WIDTH (w)),
		make_number (WINDOW_BOTTOM_EDGE_Y (w)
			     - WINDOW_MODE_LINE_HEIGHT (w)));
}

684 685 686 687 688 689 690 691 692 693 694
DEFUN ("window-inside-absolute-pixel-edges",
       Fwindow_inside_absolute_pixel_edges,
       Swindow_inside_absolute_pixel_edges, 0, 1, 0,
       doc: /* Return a list of the edge pixel coordinates of WINDOW.
The list has the form (LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at
the top left corner of the display.

RIGHT is one more than the rightmost x position of WINDOW's text area.
BOTTOM is one more than the bottommost y position of WINDOW's text area.
The inside edges do not include the space used by WINDOW's scroll bar,
display margins, fringes, header line, and/or mode line.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
695
  (Lisp_Object window)
696 697 698
{
  register struct window *w = decode_any_window (window);
  int add_x, add_y;
699
  calc_absolute_offset (w, &add_x, &add_y);
700 701 702 703 704 705 706 707 708 709 710 711 712

  return list4 (make_number (WINDOW_BOX_LEFT_EDGE_X (w)
			     + WINDOW_LEFT_MARGIN_WIDTH (w)
			     + WINDOW_LEFT_FRINGE_WIDTH (w) + add_x),
		make_number (WINDOW_TOP_EDGE_Y (w)
			     + WINDOW_HEADER_LINE_HEIGHT (w) + add_y),
		make_number (WINDOW_BOX_RIGHT_EDGE_X (w)
			     - WINDOW_RIGHT_MARGIN_WIDTH (w)
			     - WINDOW_RIGHT_FRINGE_WIDTH (w) + add_x),
		make_number (WINDOW_BOTTOM_EDGE_Y (w)
			     - WINDOW_MODE_LINE_HEIGHT (w) + add_y));
}

713
/* Test if the character at column X, row Y is within window W.
714
   If it is not, return ON_NOTHING;
715
   if it is in the window's text area, return ON_TEXT;
716
   if it is on the window's modeline, return ON_MODE_LINE;
Jim Blandy's avatar
Jim Blandy committed
717
   if it is on the border between the window and its right sibling,
718
      return ON_VERTICAL_BORDER.
719
   if it is on a scroll bar, return ON_SCROLL_BAR.
720
   if it is on the window's top line, return ON_HEADER_LINE;
Kim F. Storm's avatar
Kim F. Storm committed
721
   if it is in left or right fringe of the window,
722
      return ON_LEFT_FRINGE or ON_RIGHT_FRINGE;
723
   if it is in the marginal area to the left/right of the window,
724
      return ON_LEFT_MARGIN or ON_RIGHT_MARGIN.
725 726 727

   X and Y are frame relative pixel coordinates.  */

728
static enum window_part
729
coordinates_in_window (register struct window *w, int x, int y)
Jim Blandy's avatar
Jim Blandy committed
730
{
731
  struct frame *f = XFRAME (WINDOW_FRAME (w));
732
  int left_x, right_x;
733
  enum window_part part;
734 735 736
  int ux = FRAME_COLUMN_WIDTH (f);
  int x0 = WINDOW_LEFT_EDGE_X (w);
  int x1 = WINDOW_RIGHT_EDGE_X (w);
737 738 739
  /* The width of the area where the vertical line can be dragged.
     (Between mode lines for instance.  */
  int grabbable_width = ux;
740
  int lmargin_width, rmargin_width, text_left, text_right;
741 742 743 744 745 746
  int top_y = WINDOW_TOP_EDGE_Y (w);
  int bottom_y = WINDOW_BOTTOM_EDGE_Y (w);

  /* Outside any interesting row?  */
  if (y < top_y || y >= bottom_y)
    return ON_NOTHING;
747

748 749
  /* In what's below, we subtract 1 when computing right_x because we
     want the rightmost pixel, which is given by left_pixel+width-1.  */
750 751 752
  if (w->pseudo_window_p)
    {
      left_x = 0;
753
      right_x = WINDOW_TOTAL_WIDTH (w) - 1;
754 755 756
    }
  else
    {
757 758
      left_x = WINDOW_BOX_LEFT_EDGE_X (w);
      right_x = WINDOW_BOX_RIGHT_EDGE_X (w) - 1;
759
    }
760

761 762 763 764 765
  /* On the mode line or header line?  If it's near the start of
     the mode or header line of window that's has a horizontal
     sibling, say it's on the vertical line.  That's to be able
     to resize windows horizontally in case we're using toolkit
     scroll bars.  */
766

767
  if (WINDOW_WANTS_MODELINE_P (w)
768
      && y >= bottom_y - CURRENT_MODE_LINE_HEIGHT (w))
769
    {
770 771 772
      part = ON_MODE_LINE;

    header_vertical_border_check:
773 774
      /* We're somewhere on the mode line.  We consider the place
	 between mode lines of horizontally adjacent mode lines
775
	 as the vertical border.  If scroll bars on the left,
776
	 return the right window.  */
777 778 779 780 781 782 783 784 785 786 787 788 789 790
      if ((WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
	   || WINDOW_RIGHTMOST_P (w))
	  && !WINDOW_LEFTMOST_P (w)
	  && eabs (x - x0) < grabbable_width)
	return ON_VERTICAL_BORDER;

      /* Make sure we're not at the rightmost position of a
	 mode-/header-line and there's yet another window on the
	 right.  (Bug#1372)  */
      else if ((WINDOW_RIGHTMOST_P (w) || x < x1)
	       && eabs (x - x1) < grabbable_width)
	return ON_VERTICAL_BORDER;

      if (x < x0 || x >= x1)
791 792
	return ON_NOTHING;

793
      return part;
794
    }
795 796

  if (WINDOW_WANTS_HEADER_LINE_P (w)
797
      && y < top_y + CURRENT_HEADER_LINE_HEIGHT (w))
798
    {
799 800
      part = ON_HEADER_LINE;
      goto header_vertical_border_check;
801
    }
802

803
  if (x < x0 || x >= x1) return ON_NOTHING;
804

805
  /* Outside any interesting column?  */
806 807
  if (x < left_x || x > right_x)
    return ON_SCROLL_BAR;
808 809 810

  lmargin_width = window_box_width (w, LEFT_MARGIN_AREA);
  rmargin_width = window_box_width (w, RIGHT_MARGIN_AREA);
811

812 813 814 815
  text_left = window_box_left (w, TEXT_AREA);
  text_right = text_left + window_box_width (w, TEXT_AREA);

  if (FRAME_WINDOW_P (f))
816
    {
817
      if (!w->pseudo_window_p
818
	  && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
819
	  && !WINDOW_RIGHTMOST_P (w)
820 821
	  && (eabs (x - right_x) < grabbable_width))
	return ON_VERTICAL_BORDER;
822
    }
823 824 825 826 827 828 829 830
  /* Need to say "x > right_x" rather than >=, since on character
     terminals, the vertical line's x coordinate is right_x.  */
  else if (!w->pseudo_window_p
	   && !WINDOW_RIGHTMOST_P (w)
	   && x > right_x - ux)
    return ON_VERTICAL_BORDER;

  if (x < text_left)
831 832 833
    {
      if (lmargin_width > 0
	  && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
834 835 836 837
	      ? (x >= left_x + WINDOW_LEFT_FRINGE_WIDTH (w))
	      : (x < left_x + lmargin_width)))
	return ON_LEFT_MARGIN;

838 839 840
      return ON_LEFT_FRINGE;
    }

841
  if (x >= text_right)
842 843 844
    {
      if (rmargin_width > 0
	  && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
845 846 847 848
	      ? (x < right_x - WINDOW_RIGHT_FRINGE_WIDTH (w))
	      : (x >= right_x - rmargin_width)))
	return ON_RIGHT_MARGIN;

849 850 851 852 853
      return ON_RIGHT_FRINGE;
    }

  /* Everything special ruled out - must be on text area */
  return ON_TEXT;
Jim Blandy's avatar
Jim Blandy committed
854 855
}

856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892
/* Take X is the frame-relative pixel x-coordinate, and return the
   x-coordinate relative to part PART of window W. */
int
window_relative_x_coord (struct window *w, enum window_part part, int x)
{
  int left_x = (w->pseudo_window_p) ? 0 : WINDOW_BOX_LEFT_EDGE_X (w);

  switch (part)
    {
    case ON_TEXT:
      return x - window_box_left (w, TEXT_AREA);

    case ON_LEFT_FRINGE:
      return x - left_x;

    case ON_RIGHT_FRINGE:
      return x - left_x - WINDOW_LEFT_FRINGE_WIDTH (w);

    case ON_LEFT_MARGIN:
      return (x - left_x
	      - ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
		 ? WINDOW_LEFT_FRINGE_WIDTH (w) : 0));

    case ON_RIGHT_MARGIN:
      return (x + 1
	      - ((w->pseudo_window_p)
		 ? WINDOW_TOTAL_WIDTH (w)
		 : WINDOW_BOX_RIGHT_EDGE_X (w))
	      + window_box_width (w, RIGHT_MARGIN_AREA)
	      + ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
		 ? WINDOW_RIGHT_FRINGE_WIDTH (w) : 0));
    }

  /* ON_SCROLL_BAR, ON_NOTHING, and ON_VERTICAL_BORDER:  */
  return 0;
}

893

Jim Blandy's avatar
Jim Blandy committed
894
DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p,
895 896 897 898
       Scoordinates_in_window_p, 2, 2, 0,
       doc: /* Return non-nil if COORDINATES are in WINDOW.
COORDINATES is a cons of the form (X . Y), X and Y being distances
measured in characters from the upper-left corner of the frame.
899
\(0 . 0) denotes the character in the upper left corner of the
900 901 902 903 904
frame.
If COORDINATES are in the text portion of WINDOW,
   the coordinates relative to the window are returned.
If they are in the mode line of WINDOW, `mode-line' is returned.
If they are in the top mode line of WINDOW, `header-line' is returned.
Kim F. Storm's avatar
Kim F. Storm committed
905 906
If they are in the left fringe of WINDOW, `left-fringe' is returned.
If they are in the right fringe of WINDOW, `right-fringe' is returned.
907
If they are on the border between WINDOW and its right sibling,
908 909 910
  `vertical-line' is returned.
If they are in the windows's left or right marginal areas, `left-margin'\n\
  or `right-margin' is returned.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
911
  (register Lisp_Object coordinates, Lisp_Object window)
Jim Blandy's avatar
Jim Blandy committed
912
{
913 914
  struct window *w;
  struct frame *f;
Jim Blandy's avatar
Jim Blandy committed
915
  int x, y;
916
  Lisp_Object lx, ly;
Jim Blandy's avatar
Jim Blandy committed
917

Kenichi Handa's avatar
Kenichi Handa committed
918
  CHECK_WINDOW (window);
919 920
  w = XWINDOW (window);
  f = XFRAME (w->frame);
921
  CHECK_CONS (coordinates);
922 923
  lx = Fcar (coordinates);
  ly = Fcdr (coordinates);
924 925
  CHECK_NUMBER_OR_FLOAT (lx);
  CHECK_NUMBER_OR_FLOAT (ly);
926 927
  x = FRAME_PIXEL_X_FROM_CANON_X (f, lx) + FRAME_INTERNAL_BORDER_WIDTH (f);
  y = FRAME_PIXEL_Y_FROM_CANON_Y (f, ly) + FRAME_INTERNAL_BORDER_WIDTH (f);
928

929
  switch (coordinates_in_window (w, x, y))
Jim Blandy's avatar
Jim Blandy committed
930
    {
931
    case ON_NOTHING:
Jim Blandy's avatar
Jim Blandy committed
932 933
      return Qnil;

934
    case ON_TEXT:
935 936 937 938
      /* Convert X and Y to window relative pixel coordinates, and
	 return the canonical char units.  */
      x -= window_box_left (w, TEXT_AREA);
      y -= WINDOW_TOP_EDGE_Y (w);
939 940
      return Fcons (FRAME_CANON_X_FROM_PIXEL_X (f, x),
		    FRAME_CANON_Y_FROM_PIXEL_Y (f, y));
Jim Blandy's avatar
Jim Blandy committed
941

942
    case ON_MODE_LINE:
Jim Blandy's avatar
Jim Blandy committed
943
      return Qmode_line;
944

945
    case ON_VERTICAL_BORDER:
Jim Blandy's avatar
Jim Blandy committed
946
      return Qvertical_line;
Jim Blandy's avatar
Jim Blandy committed
947

948
    case ON_HEADER_LINE:
Gerd Moellmann's avatar
Change  
Gerd Moellmann committed
949
      return Qheader_line;
950

951 952
    case ON_LEFT_FRINGE:
      return Qleft_fringe;
953

954 955
    case ON_RIGHT_FRINGE:
      return Qright_fringe;
956

957 958
    case ON_LEFT_MARGIN:
      return Qleft_margin;
959

960 961 962
    case ON_RIGHT_MARGIN:
      return Qright_margin;

963 964 965 966
    case ON_SCROLL_BAR:
      /* Historically we are supposed to return nil in this case.  */
      return Qnil;

Jim Blandy's avatar
Jim Blandy committed
967 968 969 970 971
    default:
      abort ();
    }
}

Gerd Moellmann's avatar
Gerd Moellmann committed
972 973

/* Callback for foreach_window, used in window_from_coordinates.
974 975 976 977 978
   Check if window W contains coordinates specified by USER_DATA which
   is actually a pointer to a struct check_window_data CW.

   Check if window W contains coordinates *CW->x and *CW->y.  If it
   does, return W in *CW->window, as Lisp_Object, and return in
Dave Love's avatar
Dave Love committed
979
   *CW->part the part of the window under coordinates *X,*Y.  Return
980 981 982 983 984
   zero from this function to stop iterating over windows.  */

struct check_window_data
{
  Lisp_Object *window;
985
  int x, y;
986
  enum window_part *part;
987
};
Gerd Moellmann's avatar
Gerd Moellmann committed
988 989

static int
990
check_window_containing (struct window *w, void *user_data)
Gerd Moellmann's avatar
Gerd Moellmann committed
991
{
992
  struct check_window_data *cw = (struct check_window_data *) user_data;
993 994
  enum window_part found;
  int continue_p = 1;
Gerd Moellmann's avatar
Gerd Moellmann committed
995

996
  found = coordinates_in_window (w, cw->x, cw->y);
997
  if (found != ON_NOTHING)
Gerd Moellmann's avatar
Gerd Moellmann committed
998
    {
999
      *cw->part = found;
1000
      XSETWINDOW (*cw->window, w);
1001
      continue_p = 0;
Gerd Moellmann's avatar
Gerd Moellmann committed
1002
    }
1003

1004
  return continue_p;
Gerd Moellmann's avatar
Gerd Moellmann committed
1005 1006 1007
}


1008
/* Find the window containing frame-relative pixel position X/Y and
1009 1010 1011
   return it as a Lisp_Object.

   If X, Y is on one of the window's special `window_part' elements,
1012
   set *PART to the id of that element.
1013

Kim F. Storm's avatar