]> git.eshelyaron.com Git - emacs.git/commitdiff
* xterm.h (x_catch_errors) Return value changed to void.
authorChong Yidong <cyd@stupidchicken.com>
Sat, 25 Feb 2006 23:20:10 +0000 (23:20 +0000)
committerChong Yidong <cyd@stupidchicken.com>
Sat, 25 Feb 2006 23:20:10 +0000 (23:20 +0000)
(x_uncatch_errors): Unused count argument deleted.

* xterm.c (x_catch_errors): Don't use record_unwind_protect, since
it can be called in a signal handler.
(x_catch_errors_unwind): Function deleted.
(x_uncatch_errors): Deallocate last x_error_message_stack struct.
(x_check_errors): Call x_uncatch_errors before signalling error.

(x_load_font, x_term_init, XTmouse_position, handle_one_xevent)
(x_connection_closed, x_list_fonts): Use new versions of
x_catch_errors and x_uncatch_errors.

* xselect.c (x_own_selection, x_decline_selection_request)
(x_reply_selection_request, x_get_foreign_selection)
(Fx_get_atom_name, Fx_send_client_event): Likewise.

* xfns.c (x_real_positions, x_set_mouse_color, Fx_focus_frame):
Likewise.

* eval.c (record_unwind_protect): Add an assertion.

src/ChangeLog
src/eval.c
src/xfns.c
src/xselect.c
src/xterm.c
src/xterm.h

index 8ea097fa118fff7a98f78234b5071f84a8050bc2..ea5f5e317b8d1e79b69a520d89a4cd87665cc122 100644 (file)
@@ -1,3 +1,27 @@
+2006-02-25  Chong Yidong  <cyd@stupidchicken.com>
+
+       * xterm.h (x_catch_errors) Return value changed to void.
+       (x_uncatch_errors): Unused count argument deleted.
+       
+       * xterm.c (x_catch_errors): Don't use record_unwind_protect, since
+       it can be called in a signal handler.
+       (x_catch_errors_unwind): Function deleted.
+       (x_uncatch_errors): Deallocate last x_error_message_stack struct.
+       (x_check_errors): Call x_uncatch_errors before signalling error.
+
+       (x_load_font, x_term_init, XTmouse_position, handle_one_xevent)
+       (x_connection_closed, x_list_fonts): Use new versions of
+       x_catch_errors and x_uncatch_errors.
+
+       * xselect.c (x_own_selection, x_decline_selection_request)
+       (x_reply_selection_request, x_get_foreign_selection)
+       (Fx_get_atom_name, Fx_send_client_event): Likewise.
+
+       * xfns.c (x_real_positions, x_set_mouse_color, Fx_focus_frame):
+       Likewise.
+
+       * eval.c (record_unwind_protect): Add an assertion.
+
 2006-02-25  Stefan Monnier  <monnier@iro.umontreal.ca>
 
        * process.c (Fmake_network_process): Init the process's mark.
index eff284820f08818ffa135e19205a5ef9b528d350..06d53c907b4a4cfe48c4b90035810b0e16c169da 100644 (file)
@@ -3199,6 +3199,8 @@ record_unwind_protect (function, arg)
      Lisp_Object (*function) P_ ((Lisp_Object));
      Lisp_Object arg;
 {
+  eassert (!handling_signal);
+
   if (specpdl_ptr == specpdl + specpdl_size)
     grow_specpdl ();
   specpdl_ptr->func = function;
index 9f221efb5dee69bfdd73119e2e20f4dd4f2c1ddc..a65cf31a3608b58b3779a740c4ee7d53325c3f86 100644 (file)
@@ -577,11 +577,9 @@ x_real_positions (f, xptr, yptr)
   int had_errors = 0;
   Window win = f->output_data.x->parent_desc;
 
-  int count;
-
   BLOCK_INPUT;
 
-  count = x_catch_errors (FRAME_X_DISPLAY (f));
+  x_catch_errors (FRAME_X_DISPLAY (f));
 
   if (win == FRAME_X_DISPLAY_INFO (f)->root_window)
     win = FRAME_OUTER_WINDOW (f);
@@ -668,7 +666,7 @@ x_real_positions (f, xptr, yptr)
       had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
     }
 
-  x_uncatch_errors (FRAME_X_DISPLAY (f), count);
+  x_uncatch_errors (FRAME_X_DISPLAY (f));
 
   UNBLOCK_INPUT;
 
@@ -946,7 +944,6 @@ x_set_mouse_color (f, arg, oldval)
   Display *dpy = FRAME_X_DISPLAY (f);
   Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
   Cursor hourglass_cursor, horizontal_drag_cursor;
-  int count;
   unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
   unsigned long mask_color = x->background_pixel;
 
@@ -963,7 +960,7 @@ x_set_mouse_color (f, arg, oldval)
   BLOCK_INPUT;
 
   /* It's not okay to crash if the user selects a screwy cursor.  */
-  count = x_catch_errors (dpy);
+  x_catch_errors (dpy);
 
   if (!NILP (Vx_pointer_shape))
     {
@@ -1024,7 +1021,7 @@ x_set_mouse_color (f, arg, oldval)
 
   /* Check and report errors with the above calls.  */
   x_check_errors (dpy, "can't set cursor shape: %s");
-  x_uncatch_errors (dpy, count);
+  x_uncatch_errors (dpy);
 
   {
     XColor fore_color, back_color;
@@ -3441,13 +3438,12 @@ FRAME nil means use the selected frame.  */)
 {
   struct frame *f = check_x_frame (frame);
   Display *dpy = FRAME_X_DISPLAY (f);
-  int count;
 
   BLOCK_INPUT;
-  count = x_catch_errors (dpy);
+  x_catch_errors (dpy);
   XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                  RevertToParent, CurrentTime);
-  x_uncatch_errors (dpy, count);
+  x_uncatch_errors (dpy);
   UNBLOCK_INPUT;
 
   return Qnil;
index 850cb058e864d5277722e48934a93442692fa9f1..6efa625543ebf60dd0926d90573a49e7ed3794d6 100644 (file)
@@ -402,16 +402,15 @@ x_own_selection (selection_name, selection_value)
   Time time = last_event_timestamp;
   Atom selection_atom;
   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (sf);
-  int count;
 
   CHECK_SYMBOL (selection_name);
   selection_atom = symbol_to_x_atom (dpyinfo, display, selection_name);
 
   BLOCK_INPUT;
-  count = x_catch_errors (display);
+  x_catch_errors (display);
   XSetSelectionOwner (display, selection_atom, selecting_window, time);
   x_check_errors (display, "Can't set selection: %s");
-  x_uncatch_errors (display, count);
+  x_uncatch_errors (display);
   UNBLOCK_INPUT;
 
   /* Now update the local cache */
@@ -572,7 +571,6 @@ x_decline_selection_request (event)
      struct input_event *event;
 {
   XSelectionEvent reply;
-  int count;
 
   reply.type = SelectionNotify;
   reply.display = SELECTION_EVENT_DISPLAY (event);
@@ -585,10 +583,10 @@ x_decline_selection_request (event)
   /* The reason for the error may be that the receiver has
      died in the meantime.  Handle that case.  */
   BLOCK_INPUT;
-  count = x_catch_errors (reply.display);
+  x_catch_errors (reply.display);
   XSendEvent (reply.display, reply.requestor, False, 0L, (XEvent *) &reply);
   XFlush (reply.display);
-  x_uncatch_errors (reply.display, count);
+  x_uncatch_errors (reply.display);
   UNBLOCK_INPUT;
 }
 
@@ -690,7 +688,7 @@ x_reply_selection_request (event, format, data, size, type)
   int format_bytes = format/8;
   int max_bytes = SELECTION_QUANTUM (display);
   struct x_display_info *dpyinfo = x_display_info_for_display (display);
-  int count;
+  int count = SPECPDL_INDEX ();
 
   if (max_bytes > MAX_SELECTION_QUANTUM)
     max_bytes = MAX_SELECTION_QUANTUM;
@@ -707,7 +705,7 @@ x_reply_selection_request (event, format, data, size, type)
 
   /* #### XChangeProperty can generate BadAlloc, and we must handle it! */
   BLOCK_INPUT;
-  count = x_catch_errors (display);
+  x_catch_errors (display);
 
 #ifdef TRACE_SELECTION
   {
@@ -860,7 +858,9 @@ x_reply_selection_request (event, format, data, size, type)
      UNBLOCK to enter the event loop and get possible errors delivered,
      and then BLOCK again because x_uncatch_errors requires it.  */
   BLOCK_INPUT;
-  x_uncatch_errors (display, count);
+
+  unbind_to (count, Qnil);
+  x_uncatch_errors (display);
   UNBLOCK_INPUT;
 }
 \f
@@ -1392,7 +1392,7 @@ x_get_foreign_selection (selection_symbol, target_type, time_stamp)
 
   BLOCK_INPUT;
 
-  count = x_catch_errors (display);
+  x_catch_errors (display);
 
   TRACE2 ("Get selection %s, type %s",
          XGetAtomName (display, type_atom),
@@ -1409,6 +1409,8 @@ x_get_foreign_selection (selection_symbol, target_type, time_stamp)
 
   frame = some_frame_on_display (dpyinfo);
 
+  count = SPECPDL_INDEX ();
+
   /* If the display no longer has frames, we can't expect
      to get many more selection requests from it, so don't
      bother trying to queue them.  */
@@ -1430,8 +1432,9 @@ x_get_foreign_selection (selection_symbol, target_type, time_stamp)
   TRACE1 ("  Got event = %d", !NILP (XCAR (reading_selection_reply)));
 
   BLOCK_INPUT;
+  unbind_to (count, Qnil);
   x_check_errors (display, "Cannot get selection: %s");
-  x_uncatch_errors (display, count);
+  x_uncatch_errors (display);
   UNBLOCK_INPUT;
 
   if (NILP (XCAR (reading_selection_reply)))
@@ -2650,7 +2653,6 @@ If the value is 0 or the atom is not known, return the empty string.  */)
   struct frame *f = check_x_frame (frame);
   char *name = 0;
   Lisp_Object ret = Qnil;
-  int count;
   Display *dpy = FRAME_X_DISPLAY (f);
   Atom atom;
 
@@ -2664,14 +2666,14 @@ If the value is 0 or the atom is not known, return the empty string.  */)
     error ("Wrong type, value must be number or cons");
 
   BLOCK_INPUT;
-  count = x_catch_errors (dpy);
+  x_catch_errors (dpy);
 
   name = atom ? XGetAtomName (dpy, atom) : "";
 
   if (! x_had_errors_p (dpy))
     ret = make_string (name, strlen (name));
 
-  x_uncatch_errors (dpy, count);
+  x_uncatch_errors (dpy);
 
   if (atom && name) XFree (name);
   if (NILP (ret)) ret = make_string ("", 0);
@@ -2771,7 +2773,6 @@ are ignored.  */)
   Lisp_Object cons;
   int size;
   struct frame *f = check_x_frame (from);
-  int count;
   int to_root;
 
   CHECK_STRING (message_type);
@@ -2841,14 +2842,14 @@ are ignored.  */)
      the destination window.  But if we are sending to the root window,
      there is no such client.  Then we set the event mask to 0xffff.  The
      event then goes to clients selecting for events on the root window.  */
-  count = x_catch_errors (dpyinfo->display);
+  x_catch_errors (dpyinfo->display);
   {
     int propagate = to_root ? False : True;
     unsigned mask = to_root ? 0xffff : 0;
     XSendEvent (dpyinfo->display, wdest, propagate, mask, &event);
     XFlush (dpyinfo->display);
   }
-  x_uncatch_errors (dpyinfo->display, count);
+  x_uncatch_errors (dpyinfo->display);
   UNBLOCK_INPUT;
 
   return Qnil;
index ec5f657ab313124dc01f5140d2bed79b8de09e93..b7c1ba14caf039af82a85027fb6e434ea3ee9860 100644 (file)
@@ -324,8 +324,8 @@ static void x_update_window_end P_ ((struct window *, int, int));
 void x_delete_display P_ ((struct x_display_info *));
 
 static int x_io_error_quitter P_ ((Display *));
-int x_catch_errors P_ ((Display *));
-void x_uncatch_errors P_ ((Display *, int));
+void x_catch_errors P_ ((Display *));
+void x_uncatch_errors P_ ((Display *));
 void x_lower_frame P_ ((struct frame *));
 void x_scroll_bar_clear P_ ((struct frame *));
 int x_had_errors_p P_ ((Display *));
@@ -3719,7 +3719,6 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time)
        Window win, child;
        int win_x, win_y;
        int parent_x = 0, parent_y = 0;
-       int count;
 
        win = root;
 
@@ -3727,7 +3726,7 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time)
           structure is changing at the same time this function
           is running.  So at least we must not crash from them.  */
 
-       count = x_catch_errors (FRAME_X_DISPLAY (*fp));
+       x_catch_errors (FRAME_X_DISPLAY (*fp));
 
        if (FRAME_X_DISPLAY_INFO (*fp)->grabbed && last_mouse_frame
            && FRAME_LIVE_P (last_mouse_frame))
@@ -3796,7 +3795,7 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time)
        if (x_had_errors_p (FRAME_X_DISPLAY (*fp)))
          f1 = 0;
 
-       x_uncatch_errors (FRAME_X_DISPLAY (*fp), count);
+       x_uncatch_errors (FRAME_X_DISPLAY (*fp));
 
        /* If not, is it one of our scroll bars?  */
        if (! f1)
@@ -5713,7 +5712,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
                     Display *d = event.xclient.display;
                     /* Catch and ignore errors, in case window has been
                        iconified by a window manager such as GWM.  */
-                    int count = x_catch_errors (d);
+                    x_catch_errors (d);
                     XSetInputFocus (d, event.xclient.window,
                                     /* The ICCCM says this is
                                        the only valid choice.  */
@@ -5722,7 +5721,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
                     /* This is needed to detect the error
                        if there is an error.  */
                     XSync (d, False);
-                    x_uncatch_errors (d, count);
+                    x_uncatch_errors (d);
                   }
                 /* Not certain about handling scroll bars here */
 #endif /* 0 */
@@ -7469,7 +7468,11 @@ x_text_icon (f, icon_name)
 #define X_ERROR_MESSAGE_SIZE 200
 
 /* If non-nil, this should be a string.
-   It means catch X errors  and store the error message in this string.  */
+   It means catch X errors  and store the error message in this string.
+
+   The reason we use a stack is that x_catch_error/x_uncatch_error can
+   be called from a signal handler.
+*/
 
 struct x_error_message_stack {
   char string[X_ERROR_MESSAGE_SIZE];
@@ -7506,20 +7509,12 @@ x_error_catcher (display, error)
    Calling x_uncatch_errors resumes the normal error handling.  */
 
 void x_check_errors ();
-static Lisp_Object x_catch_errors_unwind ();
 
-int
+void
 x_catch_errors (dpy)
      Display *dpy;
 {
-  int count = SPECPDL_INDEX ();
   struct x_error_message_stack *data = xmalloc (sizeof (*data));
-  Lisp_Object dummy;
-#ifdef ENABLE_CHECKING
-  dummy = make_number ((EMACS_INT)dpy + (EMACS_INT)x_error_message);
-#else
-  dummy = Qnil;
-#endif
 
   /* Make sure any errors from previous requests have been dealt with.  */
   XSync (dpy, False);
@@ -7528,21 +7523,19 @@ x_catch_errors (dpy)
   data->string[0] = 0;
   data->prev = x_error_message;
   x_error_message = data;
-
-  record_unwind_protect (x_catch_errors_unwind, dummy);
-
-  return count;
 }
 
-/* Unbind the binding that we made to check for X errors.  */
+/* Undo the last x_catch_errors call.
+   DPY should be the display that was passed to x_catch_errors.  */
 
-static Lisp_Object
-x_catch_errors_unwind (dummy)
-     Lisp_Object dummy;
+void
+x_uncatch_errors (dpy)
+     Display *dpy;
 {
-  Display *dpy = x_error_message->dpy;
   struct x_error_message_stack *tmp;
 
+  eassert (x_error_message && dpy == x_error_message->dpy);
+
   /* The display may have been closed before this function is called.
      Check if it is still open before calling XSync.  */
   if (x_display_info_for_display (dpy) != 0)
@@ -7554,12 +7547,7 @@ x_catch_errors_unwind (dummy)
 
   tmp = x_error_message;
   x_error_message = x_error_message->prev;
-  free (tmp);
-
-  eassert (EQ (dummy,
-              make_number ((EMACS_INT)dpy + (EMACS_INT)x_error_message)));
-
-  return Qnil;
+  xfree (tmp);
 }
 
 /* If any X protocol errors have arrived since the last call to
@@ -7575,7 +7563,12 @@ x_check_errors (dpy, format)
   XSync (dpy, False);
 
   if (x_error_message->string[0])
-    error (format, x_error_message->string);
+    {
+      char string[X_ERROR_MESSAGE_SIZE];
+      bcopy (x_error_message->string, string, X_ERROR_MESSAGE_SIZE);
+      x_uncatch_errors (dpy);
+      error (format, string);
+    }
 }
 
 /* Nonzero if we had any X protocol errors
@@ -7600,19 +7593,6 @@ x_clear_errors (dpy)
   x_error_message->string[0] = 0;
 }
 
-/* Stop catching X protocol errors and let them make Emacs die.
-   DPY should be the display that was passed to x_catch_errors.
-   COUNT should be the value that was returned by
-   the corresponding call to x_catch_errors.  */
-
-void
-x_uncatch_errors (dpy, count)
-     Display *dpy;
-     int count;
-{
-  unbind_to (count, Qnil);
-}
-
 #if 0
 static unsigned int x_wire_count;
 x_trace_wire ()
@@ -7669,7 +7649,6 @@ x_connection_closed (dpy, error_message)
 {
   struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
   Lisp_Object frame, tail;
-  int count;
 
   error_msg = (char *) alloca (strlen (error_message) + 1);
   strcpy (error_msg, error_message);
@@ -7679,7 +7658,7 @@ x_connection_closed (dpy, error_message)
      below.  Otherwise, we might end up with printing ``can't find per
      display information'' in the recursive call instead of printing
      the original message here.  */
-  count = x_catch_errors (dpy);
+  x_catch_errors (dpy);
 
   /* We have to close the display to inform Xt that it doesn't
      exist anymore.  If we don't, Xt will continue to wait for
@@ -7747,7 +7726,7 @@ x_connection_closed (dpy, error_message)
   if (dpyinfo)
     x_delete_display (dpyinfo);
 
-  x_uncatch_errors (dpy, count);
+  x_uncatch_errors (dpy);
 
   if (x_display_list == 0)
     {
@@ -9353,7 +9332,6 @@ x_list_fonts (f, pattern, size, maxnames)
     = f ? FRAME_X_DISPLAY_INFO (f) : x_display_list;
   Display *dpy = dpyinfo->display;
   int try_XLoadQueryFont = 0;
-  int count;
   int allow_auto_scaled_font = 0;
 
   if (size < 0)
@@ -9393,7 +9371,7 @@ x_list_fonts (f, pattern, size, maxnames)
       /* At first, put PATTERN in the cache.  */
 
       BLOCK_INPUT;
-      count = x_catch_errors (dpy);
+      x_catch_errors (dpy);
 
       if (try_XLoadQueryFont)
        {
@@ -9474,7 +9452,7 @@ x_list_fonts (f, pattern, size, maxnames)
            }
        }
 
-      x_uncatch_errors (dpy, count);
+      x_uncatch_errors (dpy);
       UNBLOCK_INPUT;
 
       if (names)
@@ -9565,7 +9543,7 @@ x_list_fonts (f, pattern, size, maxnames)
              XFontStruct *thisinfo;
 
              BLOCK_INPUT;
-             count = x_catch_errors (dpy);
+             x_catch_errors (dpy);
              thisinfo = XLoadQueryFont (dpy,
                                         SDATA (XCAR (tem)));
              if (x_had_errors_p (dpy))
@@ -9575,7 +9553,7 @@ x_list_fonts (f, pattern, size, maxnames)
                  thisinfo = NULL;
                  x_clear_errors (dpy);
                }
-             x_uncatch_errors (dpy, count);
+             x_uncatch_errors (dpy);
              UNBLOCK_INPUT;
 
              if (thisinfo)
@@ -9731,7 +9709,6 @@ x_load_font (f, fontname, size)
 {
   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
   Lisp_Object font_names;
-  int count;
 
   /* Get a list of all the fonts that match this name.  Once we
      have a list of matching fonts, we compare them against the fonts
@@ -9770,7 +9747,7 @@ x_load_font (f, fontname, size)
       fontname = (char *) SDATA (XCAR (font_names));
 
     BLOCK_INPUT;
-    count = x_catch_errors (FRAME_X_DISPLAY (f));
+    x_catch_errors (FRAME_X_DISPLAY (f));
     font = (XFontStruct *) XLoadQueryFont (FRAME_X_DISPLAY (f), fontname);
     if (x_had_errors_p (FRAME_X_DISPLAY (f)))
       {
@@ -9779,7 +9756,7 @@ x_load_font (f, fontname, size)
        font = NULL;
        x_clear_errors (FRAME_X_DISPLAY (f));
       }
-    x_uncatch_errors (FRAME_X_DISPLAY (f), count);
+    x_uncatch_errors (FRAME_X_DISPLAY (f));
     UNBLOCK_INPUT;
     if (!font)
       return NULL;
@@ -10552,7 +10529,6 @@ x_term_init (display_name, xrm_option, resource_name)
     Display *dpy = dpyinfo->display;
     XrmValue d, fr, to;
     Font font;
-    int count;
 
     d.addr = (XPointer)&dpy;
     d.size = sizeof (Display *);
@@ -10560,12 +10536,12 @@ x_term_init (display_name, xrm_option, resource_name)
     fr.size = sizeof (XtDefaultFont);
     to.size = sizeof (Font *);
     to.addr = (XPointer)&font;
-    count = x_catch_errors (dpy);
+    x_catch_errors (dpy);
     if (!XtCallConverter (dpy, XtCvtStringToFont, &d, 1, &fr, &to, NULL))
       abort ();
     if (x_had_errors_p (dpy) || !XQueryFont (dpy, font))
       XrmPutLineResource (&xrdb, "Emacs.dialog.*.font: 9x15");
-    x_uncatch_errors (dpy, count);
+    x_uncatch_errors (dpy);
   }
 #endif
 #endif
index bc52efe379d644bb3273a5a79ee1397f9755a68d..b2fa92fa4e4a778e046c921b845c0bea9cfdf771 100644 (file)
@@ -958,9 +958,9 @@ void x_delete_display P_ ((struct x_display_info *));
 void x_make_frame_visible P_ ((struct frame *));
 void x_iconify_frame P_ ((struct frame *));
 void x_wm_set_size_hint P_ ((struct frame *, long, int));
-int x_catch_errors P_ ((Display *));
+void x_catch_errors P_ ((Display *));
 int x_had_errors_p P_ ((Display *));
-void x_uncatch_errors P_ ((Display *, int));
+void x_uncatch_errors P_ ((Display *));
 void x_check_errors P_ ((Display *, char *));
 int x_text_icon P_ ((struct frame *, char *));
 int x_bitmap_icon P_ ((struct frame *, Lisp_Object));
@@ -974,10 +974,10 @@ extern void cancel_mouse_face P_ ((struct frame *));
 extern void x_scroll_bar_clear P_ ((struct frame *));
 extern int x_text_icon P_ ((struct frame *, char *));
 extern int x_bitmap_icon P_ ((struct frame *, Lisp_Object));
-extern int x_catch_errors P_ ((Display *));
+extern void x_catch_errors P_ ((Display *));
 extern void x_check_errors P_ ((Display *, char *));
 extern int x_had_errors_p P_ ((Display *));
-extern void x_uncatch_errors P_ ((Display *, int));
+extern void x_uncatch_errors P_ ((Display *));
 extern void x_set_window_size P_ ((struct frame *, int, int, int));
 extern void x_set_mouse_position P_ ((struct frame *, int, int));
 extern void x_set_mouse_pixel_position P_ ((struct frame *, int, int));