Commit 50bf7673 authored by Steven Tamm's avatar Steven Tamm
Browse files

Support Tooltips with the Carbon emacs port.

Some code cleanup using helper macros.
parent f2f82fa4
2004-05-29 YAMAMOTO Mitsuharu <>
* macfns.c: Don't include ccl.h.
[MAC_OSX]: Don't include QuickTime/QuickTime.h.
[!MAC_OSX]: Don't include alloca.h, Windows.h, Gestalt.h, or
(Fx_create_frame): Sync with xfns.c. Initialize cursor
(Fx_display_mm_height, Fx_display_mm_width): Calculate length from
display height/width.
(compute_tip_xy, Vx_max_tooltip_size): Declare.
(unwind_create_tip_frame, compute_tip_xy): New functions.
(x_create_tip_frame, Fx_show_tip, Fx_hide_tip): Sync with xfns.c.
(syms_of_macfns): Initialize Qcancel_timer, Vx_max_tooltip_size,
and last_show_tip_args.
* macgui.h [!MAC_OSX]: Include Gestalt.h.
(Cursor, No_Cursor): New defines.
[!TARGET_API_MAC_CARBON] (SetPortWindowPort): New compatibility
[!TARGET_API_MAC_CARBON] (arrow_cursor): Declare.
* macmenu.c (mac_menu_show, mac_dialog): Use SetPortWindowPort.
* macterm.c: Don't include Gestalt.h.
(enum mouse_tracking_type, mouse_tracking_in_progress): Remove.
(XDrawLine, XClearArea, XClearWindow, mac_draw_bitmap)
(mac_set_clip_rectangle, mac_reset_clipping, XCreatePixmap)
(XFillRectangle, mac_draw_rectangle, mac_draw_string_common)
(mac_copy_area, mac_copy_area_with_mask, x_update_end)
(construct_mouse_click, XTmouse_position)
(x_scroll_bar_report_motion, x_calc_absolute_position)
(do_mouse_moved, do_zoom_window, mac_do_receive_drag)
(XTread_socket, make_mac_frame): Use SetPortWindowPort.
(note_mouse_movement): Clear the mouse face and reset the pointer
shape when the pointer goes outside the frame without grabbing.
(mac_front_window): New function.
(mac_window_to_frame): New macro.
(XTmouse_position, x_scroll_bar_report_motion, do_window_update)
(do_window_activate, do_window_deactivate, do_app_resume)
(do_app_suspend, do_mouse_moved, do_menu_choice, do_grow_window)
(do_zoom_window, mac_do_receive_drag, XTread_socket)
(mac_check_for_quit_char): Use mac_front_window and/or
(x_scroll_bar_handle_click): Set `(PORTION . WHOLE)' part in a
scroll-bar click event.
(mac_define_frame_cursor): Change the pointer shape.
(x_free_frame_resources): Reset tip_window to NULL when it is
[!TARGET_API_MAC_CARBON] (arrow_cursor): New variable.
[!TARGET_API_MAC_CARBON] (do_init_managers): Initialize
(do_window_update): Don't do anything if the updated window is the
tooltip window.
(do_mouse_moved): Handle mouse movement events here (previously in
XTread_socket). Clear the mouse face if
dpyinfo->mouse_face_hidden is set.
(do_os_event, do_events): Remove (now in XTread_socket).
(XTread_socket): Immediately return if interrupt_input_blocked.
Loop until all the events in the queue are processed. Rearrange
codes for mouse grabbing. Add tooltip support. Include the
contents of do_os_event and do_events. Remove mouse movement
handling (now in do_mouse_moved). Add the case where
Vmouse_highlight has an integer value.
(NewMacWindow): Remove.
(make_mac_frame): Do what NewMacWindow previously did. Don't do
excess initializations.
(make_mac_terminal_frame): Previous initializations in
make_mac_frame are moved here.
(mac_initialize_display_info): Initialize
dpyinfo->mouse_face_overlay and dpyinfo->mouse_face_hidden.
* xdisp.c [MAC_OS] (No_Cursor): Remove variable.
(define_frame_cursor1): Don't treat HAVE_CARBON as a special case.
2004-05-29 Richard M. Stallman <>
* lisp.h (truncate_undo_list): Update decl.
......@@ -42,7 +42,6 @@ Boston, MA 02111-1307, USA. */
#include "epaths.h"
#include "termhooks.h"
#include "coding.h"
#include "ccl.h"
#include "systime.h"
/* #include "bitmaps/gray.xbm" */
......@@ -59,17 +58,6 @@ static unsigned char gray_bits[] = {
#include <stdlib.h>
#include <string.h>
#ifndef MAC_OSX
#include <alloca.h>
#ifdef MAC_OSX
#include <QuickTime/QuickTime.h>
#else /* not MAC_OSX */
#include <Windows.h>
#include <Gestalt.h>
#include <TextUtils.h>
#endif /* not MAC_OSX */
/*extern void free_frame_menubar ();
extern double atof ();
......@@ -2580,8 +2568,6 @@ This function is an internal primitive--use `make-frame' instead. */)
f->output_data.mac = (struct mac_output *) xmalloc (sizeof (struct mac_output));
bzero (f->output_data.mac, sizeof (struct mac_output));
f->output_data.mac->scroll_bar_foreground_pixel = -1;
f->output_data.mac->scroll_bar_background_pixel = -1;
record_unwind_protect (unwind_create_frame, frame);
......@@ -2717,25 +2703,32 @@ This function is an internal primitive--use `make-frame' instead. */)
f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
/* MAC_TODO: specify 1 below when toolbars are implemented. */
window_prompting = x_figure_window_size (f, parms, 0);
f->output_data.mac->text_cursor = kThemeIBeamCursor;
f->output_data.mac->nontext_cursor = kThemeArrowCursor;
f->output_data.mac->modeline_cursor = kThemeArrowCursor;
f->output_data.mac->hand_cursor = kThemePointingHandCursor;
f->output_data.mac->hourglass_cursor = kThemeWatchCursor;
f->output_data.mac->horizontal_drag_cursor = kThemeResizeLeftRightCursor;
f->output_data.mac->text_cursor = GetCursor (iBeamCursor);
f->output_data.mac->nontext_cursor = &arrow_cursor;
f->output_data.mac->modeline_cursor = &arrow_cursor;
f->output_data.mac->hand_cursor = &arrow_cursor;
f->output_data.mac->hourglass_cursor = GetCursor (watchCursor);
f->output_data.mac->horizontal_drag_cursor = &arrow_cursor;
/* Compute the size of the window. */
window_prompting = x_figure_window_size (f, parms, 1);
tem = mac_get_arg (parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
f->no_split = minibuffer_only || EQ (tem, Qt);
/* Create the window. Add the tool-bar height to the initial frame
height so that the user gets a text display area of the size he
specified with -g or via the registry. Later changes of the
tool-bar height don't change the frame size. This is done so that
users can create tall Emacs frames without having to guess how
tall the tool-bar will get. */
/* mac_window (f, window_prompting, minibuffer_only); */
make_mac_frame (f);
x_icon (f, parms);
x_make_gc (f);
/* Now consider the frame official. */
......@@ -2754,7 +2747,8 @@ This function is an internal primitive--use `make-frame' instead. */)
x_default_parameter (f, parms, Qcursor_type, Qbox,
"cursorType", "CursorType", RES_TYPE_SYMBOL);
x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
"scrollBarWidth", "ScrollBarWidth", RES_TYPE_NUMBER);
"scrollBarWidth", "ScrollBarWidth",
/* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
Change will not be effected unless different from the current
......@@ -2762,13 +2756,10 @@ This function is an internal primitive--use `make-frame' instead. */)
width = FRAME_COLS (f);
height = FRAME_LINES (f);
FRAME_LINES (f) = 0;
FRAME_LINES (f) = 0;
change_frame_size (f, height, width, 1, 0, 0);
/* Set up faces after all frame parameters are known. */
call1 (Qface_set_after_frame_default, frame);
#if 0 /* MAC_TODO: when we have window manager hints */
/* Tell the server what size and position, etc, we want, and how
badly we want them. This should be done after we have the menu
......@@ -3025,11 +3016,8 @@ If omitted or nil, that stands for the selected frame's display. */)
/* MAC_TODO: this is an approximation, and only of the main display */
struct mac_display_info *dpyinfo = check_x_display_info (display);
short h, v;
ScreenRes (&h, &v);
return make_number ((int) (v / 72.0 * 25.4));
return make_number ((int) (dpyinfo->height * 25.4 / dpyinfo->resy));
DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
......@@ -3043,11 +3031,8 @@ If omitted or nil, that stands for the selected frame's display. */)
/* MAC_TODO: this is an approximation, and only of the main display */
struct mac_display_info *dpyinfo = check_x_display_info (display);
short h, v;
ScreenRes (&h, &v);
return make_number ((int) (h / 72.0 * 25.4));
return make_number ((int) (dpyinfo->width * 25.4 / dpyinfo->resx));
DEFUN ("x-display-backing-store", Fx_display_backing_store,
......@@ -3595,9 +3580,11 @@ hide_hourglass ()
static Lisp_Object x_create_tip_frame P_ ((struct mac_display_info *,
Lisp_Object, Lisp_Object));
static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object,
Lisp_Object, int, int, int *, int *));
/* The frame of a currently visible tooltip, or null. */
/* The frame of a currently visible tooltip. */
Lisp_Object tip_frame;
......@@ -3612,15 +3599,42 @@ Window tip_window;
Lisp_Object last_show_tip_args;
/* Maximum size for tooltips; a cons (COLUMNS . ROWS). */
Lisp_Object Vx_max_tooltip_size;
static Lisp_Object
unwind_create_tip_frame (frame)
Lisp_Object frame;
Lisp_Object deleted;
deleted = unwind_create_frame (frame);
if (EQ (deleted, Qt))
tip_window = NULL;
tip_frame = Qnil;
return deleted;
/* Create a frame for a tooltip on the display described by DPYINFO.
PARMS is a list of frame parameters. Value is the frame. */
PARMS is a list of frame parameters. TEXT is the string to
display in the tip frame. Value is the frame.
Note that functions called here, esp. x_default_parameter can
signal errors, for instance when a specified color name is
undefined. We have to make sure that we're in a consistent state
when this happens. */
static Lisp_Object
x_create_tip_frame (dpyinfo, parms)
x_create_tip_frame (dpyinfo, parms, text)
struct mac_display_info *dpyinfo;
Lisp_Object parms;
Lisp_Object parms, text;
#if 0 /* MAC_TODO : Mac version */
struct frame *f;
Lisp_Object frame, tem;
Lisp_Object name;
......@@ -3629,8 +3643,11 @@ x_create_tip_frame (dpyinfo, parms)
int count = SPECPDL_INDEX ();
struct gcpro gcpro1, gcpro2, gcpro3;
struct kboard *kb;
int face_change_count_before = face_change_count;
Lisp_Object buffer;
struct buffer *old_buffer;
check_x ();
check_mac ();
/* Use this general default value to start with until we know if
this frame has a specified name. */
......@@ -3643,7 +3660,7 @@ x_create_tip_frame (dpyinfo, parms)
/* Get the name of the frame to use for resource lookup. */
name = w32_get_arg (parms, Qname, "name", "Name", RES_TYPE_STRING);
name = mac_get_arg (parms, Qname, "name", "Name", RES_TYPE_STRING);
if (!STRINGP (name)
&& !EQ (name, Qunbound)
&& !NILP (name))
......@@ -3652,31 +3669,50 @@ x_create_tip_frame (dpyinfo, parms)
frame = Qnil;
GCPRO3 (parms, name, frame);
tip_frame = f = make_frame (1);
f = make_frame (1);
XSETFRAME (frame, f);
buffer = Fget_buffer_create (build_string (" *tip*"));
Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer, Qnil);
old_buffer = current_buffer;
set_buffer_internal_1 (XBUFFER (buffer));
current_buffer->truncate_lines = Qnil;
specbind (Qinhibit_read_only, Qt);
specbind (Qinhibit_modification_hooks, Qt);
Ferase_buffer ();
Finsert (1, &text);
set_buffer_internal_1 (old_buffer);
record_unwind_protect (unwind_create_tip_frame, frame);
f->output_method = output_w32;
f->output_data.w32 =
(struct w32_output *) xmalloc (sizeof (struct w32_output));
bzero (f->output_data.w32, sizeof (struct w32_output));
#if 0
f->output_data.w32->icon_bitmap = -1;
/* By setting the output method, we're essentially saying that
the frame is live, as per FRAME_LIVE_P. If we get a signal
from this point on, x_destroy_window might screw up reference
counts etc. */
f->output_method = output_mac;
f->output_data.mac =
(struct mac_output *) xmalloc (sizeof (struct mac_output));
bzero (f->output_data.mac, sizeof (struct mac_output));
f->icon_name = Qnil;
#if 0 /* GLYPH_DEBUG TODO: image support. */
image_cache_refcount = FRAME_X_IMAGE_CACHE (f)->refcount;
dpyinfo_refcount = dpyinfo->reference_count;
#endif /* GLYPH_DEBUG */
FRAME_KBOARD (f) = kb;
f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window;
f->output_data.w32->explicit_parent = 0;
f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
f->output_data.mac->explicit_parent = 0;
/* Set the name; the functions to which we pass f expect the name to
be set. */
if (EQ (name, Qunbound) || NILP (name))
f->name = build_string (dpyinfo->x_id_name);
f->name = build_string (dpyinfo->mac_id_name);
f->explicit_name = 0;
......@@ -3687,12 +3723,12 @@ x_create_tip_frame (dpyinfo, parms)
specbind (Qx_resource_name, name);
/* Extract the window parameters from the supplied values
that are needed to determine window geometry. */
/* Extract the window parameters from the supplied values that are
needed to determine window geometry. */
Lisp_Object font;
font = w32_get_arg (parms, Qfont, "font", "Font", RES_TYPE_STRING);
font = mac_get_arg (parms, Qfont, "font", "Font", RES_TYPE_STRING);
/* First, try whatever font the caller has specified. */
......@@ -3706,22 +3742,16 @@ x_create_tip_frame (dpyinfo, parms)
/* Try out a font which we hope has bold and italic variations. */
if (!STRINGP (font))
font = x_new_font (f, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
if (!STRINGP (font))
font = x_new_font (f, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
if (! STRINGP (font))
font = x_new_font (f, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
if (! STRINGP (font))
/* This was formerly the first thing tried, but it finds too many fonts
and takes too long. */
font = x_new_font (f, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
font = x_new_font (f, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1");
/* If those didn't work, look for something which will at least work. */
if (! STRINGP (font))
font = x_new_font (f, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
font = x_new_font (f, "-*-monaco-*-12-*-mac-roman");
if (! STRINGP (font))
font = x_new_font (f, "-*-courier-*-10-*-mac-roman");
if (! STRINGP (font))
font = build_string ("fixed");
error ("Cannot find any usable font");
x_default_parameter (f, parms, Qfont, font,
"font", "Font", RES_TYPE_STRING);
......@@ -3737,7 +3767,7 @@ x_create_tip_frame (dpyinfo, parms)
Lisp_Object value;
value = w32_get_arg (parms, Qinternal_border_width,
value = mac_get_arg (parms, Qinternal_border_width,
"internalBorder", "internalBorder", RES_TYPE_NUMBER);
if (! EQ (value, Qunbound))
parms = Fcons (Fcons (Qinternal_border_width, value),
......@@ -3768,34 +3798,26 @@ x_create_tip_frame (dpyinfo, parms)
happen. */
init_frame_faces (f);
f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window;
f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
window_prompting = x_figure_window_size (f, parms, 0);
XSetWindowAttributes attrs;
unsigned long mask;
mask = CWBackPixel | CWOverrideRedirect | CWSaveUnder | CWEventMask;
/* Window managers looks at the override-redirect flag to
determine whether or net to give windows a decoration (Xlib
3.2.8). */
attrs.override_redirect = True;
attrs.save_under = True;
attrs.background_pixel = FRAME_BACKGROUND_PIXEL (f);
/* Arrange for getting MapNotify and UnmapNotify events. */
attrs.event_mask = StructureNotifyMask;
= XCreateWindow (FRAME_W32_DISPLAY (f),
FRAME_W32_DISPLAY_INFO (f)->root_window,
/* x, y, width, height */
0, 0, 1, 1,
/* Border. */
CopyFromParent, InputOutput, CopyFromParent,
mask, &attrs);
Rect r;
SetRect (&r, 0, 0, 1, 1);
if (CreateNewWindow (kHelpWindowClass,
| kWindowIgnoreClicksAttribute,
&r, &tip_window) == noErr)
FRAME_MAC_WINDOW (f) = tip_window;
SetWRefCon (tip_window, (long) f->output_data.mac);
/* so that update events can find this mac_output struct */
f->output_data.mac->mFP = f;
ShowWindow (tip_window);
......@@ -3813,8 +3835,8 @@ x_create_tip_frame (dpyinfo, parms)
width = FRAME_COLS (f);
height = FRAME_LINES (f);
FRAME_LINES (f) = 0;
FRAME_LINES (f) = 0;
change_frame_size (f, height, width, 1, 0, 0);
/* Add `tooltip' frame parameter's default value. */
......@@ -3822,6 +3844,26 @@ x_create_tip_frame (dpyinfo, parms)
Fmodify_frame_parameters (frame, Fcons (Fcons (intern ("tooltip"), Qt),
/* Set up faces after all frame parameters are known. This call
also merges in face attributes specified for new frames.
Frame parameters may be changed if .Xdefaults contains
specifications for the default font. For example, if there is an
`Emacs.default.attributeBackground: pink', the `background-color'
attribute of the frame get's set, which let's the internal border
of the tooltip frame appear in pink. Prevent this. */
Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
/* Set tip_frame here, so that */
tip_frame = frame;
call1 (Qface_set_after_frame_default, frame);
if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg),
f->no_split = 1;
......@@ -3833,17 +3875,80 @@ x_create_tip_frame (dpyinfo, parms)
/* Now that the frame is official, it counts as a reference to
its display. */
FRAME_W32_DISPLAY_INFO (f)->reference_count++;
FRAME_MAC_DISPLAY_INFO (f)->reference_count++;
/* Setting attributes of faces of the tooltip frame from resources
and similar will increment face_change_count, which leads to the
clearing of all current matrices. Since this isn't necessary
here, avoid it by resetting face_change_count to the value it
had before we created the tip frame. */
face_change_count = face_change_count_before;
/* Discard the unwind_protect. */
return unbind_to (count, frame);
#endif /* MAC_TODO */
return Qnil;
/* Compute where to display tip frame F. PARMS is the list of frame
parameters for F. DX and DY are specified offsets from the current
location of the mouse. WIDTH and HEIGHT are the width and height
of the tooltip. Return coordinates relative to the root window of
the display in *ROOT_X, and *ROOT_Y. */
static void
compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
struct frame *f;
Lisp_Object parms, dx, dy;
int width, height;
int *root_x, *root_y;
Lisp_Object left, top;
/* User-specified position? */
left = Fcdr (Fassq (Qleft, parms));
top = Fcdr (Fassq (Qtop, parms));
/* Move the tooltip window where the mouse pointer is. Resize and
show it. */
if (!INTEGERP (left) || !INTEGERP (top))
Point mouse_pos;
GetMouse (&mouse_pos);
LocalToGlobal (&mouse_pos);
*root_x = mouse_pos.h;
*root_y = mouse_pos.v;
if (INTEGERP (top))
*root_y = XINT (top);
else if (*root_y + XINT (dy) - height < 0)
*root_y -= XINT (dy);
*root_y -= height;
*root_y += XINT (dy);
if (INTEGERP (left))
*root_x = XINT (left);
else if (*root_x + XINT (dx) + width <= FRAME_MAC_DISPLAY_INFO (f)->width)
/* It fits to the right of the pointer. */
*root_x += XINT (dx);
else if (width + XINT (dx) <= *root_x)
/* It fits to the left of the pointer. */
*root_x -= width + XINT (dx);
/* Put it left-justified on the screen -- it ought to fit that way. */
*root_x = 0;
DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
doc : /* Show STRING in a "tooltip" window on frame FRAME.
A tooltip window is a small window displaying a string.
doc: /* Show STRING in a "tooltip" window on frame FRAME.
A tooltip window is a small X window displaying a string.
FRAME nil or omitted means use the selected frame.
......@@ -3859,19 +3964,19 @@ displayed at the mouse position, with offset DX added (default is 5 if
DX isn't specified). Likewise for the y-position; if a `top' frame
parameter is specified, it determines the y-position of the tooltip
window, otherwise it is displayed at the mouse position, with offset
DY added (default is 10). */)
(string, frame, parms, timeout, dx, dy)
DY added (default is -10).
A tooltip's maximum size is specified by `x-max-tooltip-size'.
Text larger than the specified size is clipped. */)
(string, frame, parms, timeout, dx, dy)
Lisp_Object string, frame, parms, timeout, dx, dy;
struct frame *f;
struct window *w;
Window root, child;
Lisp_Object buffer, top, left;
int root_x, root_y;
struct buffer *old_buffer;
struct text_pos pos;
int i, width, height;
int root_x, root_y, win_x, win_y;
unsigned pmask;
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
int old_windows_or_buffers_changed = windows_or_buffers_changed;
int count = SPECPDL_INDEX ();
......@@ -3920,13 +4025,11 @@ DY added (default is 10). */)
call1 (Qcancel_timer, timer);
#if 0 /* MAC_TODO : Mac specifics */
compute_tip_xy (f, parms, dx, dy, &root_x, &root_y);
root_x, root_y - FRAME_PIXEL_HEIGHT (f));
compute_tip_xy (f, parms, dx, dy, FRAME_PIXEL_WIDTH (f),
FRAME_PIXEL_HEIGHT (f), &root_x, &root_y);
MoveWindow (FRAME_MAC_WINDOW (f), root_x, root_y, false);
#endif /* MAC_TODO */
goto start_timer;
......@@ -3953,26 +4056,36 @@ DY added (default is 10). */)
/* Create a frame for the tooltip, and record it in the global
variable tip_frame. */
frame = x_create_tip_frame (FRAME_MAC_DISPLAY_INFO (f), parms);
frame = x_create_tip_frame (FRAME_MAC_DISPLAY_INFO (f), parms, string);
f = XFRAME (frame);
/* Set up the frame's root window. Currently we use a size of 80
columns x 40 lines. If someone wants to show a larger tip, he
will loose. I don't think this is a realistic case. */
/* Set up the frame's root window. */
w->left_col = w->top_line = make_number (0);
w->total_cols = make_number (80);
w->total_lines = make_number (40);
if (CONSP (Vx_max_tooltip_size)
&& INTEGERP (XCAR (Vx_max_tooltip_size))
&& XINT (XCAR (Vx_max_tooltip_size)) > 0
&& INTEGERP (XCDR (Vx_max_tooltip_size))
&& XINT (XCDR (Vx_max_tooltip_size)) > 0)
w->total_cols = XCAR (Vx_max_tooltip_size);
w->total_lines = XCDR (Vx_max_tooltip_size);
w->total_cols = make_number (80);
w->total_lines = make_number (40