+2019-06-25 Tom Tromey <tom@tromey.com>
+
+ * tui/tui-winsource.h (tui_update_source_window_as_is)
+ (tui_alloc_source_buffer, tui_line_is_displayed)
+ (tui_addr_is_displayed): Change type of win_info.
+ * tui/tui-winsource.c (tui_update_source_window_as_is)
+ (tui_clear_source_content, tui_show_source_line)
+ (tui_show_source_content, tui_source_window_base::refill)
+ (tui_source_window_base::set_is_exec_point_at)
+ (tui_source_window_base::set_is_exec_point_at)
+ (tui_update_breakpoint_info, tui_set_exec_info_content): Update.
+ (tui_alloc_source_buffer, tui_line_is_displayed)
+ (tui_addr_is_displayed): Change type of win_info. Update.
+ * tui/tui-win.c (tui_resize_all, tui_adjust_win_heights)
+ (tui_source_window_base::do_make_visible_with_new_height):
+ Update.
+ * tui/tui-source.c (tui_set_source_content)
+ (tui_set_source_content_nil)
+ (tui_source_window::do_scroll_vertical): Update.
+ * tui/tui-layout.c (show_layout): Update.
+ * tui/tui-disasm.c (tui_set_disassem_content)
+ (tui_disasm_window::do_scroll_vertical): Update.
+ * tui/tui-data.h (tui_win_content): Remove.
+ (struct tui_gen_win_info) <content, content_size>: Remove.
+ (struct tui_source_element): Add initializers and destructor.
+ (union tui_which_element, struct tui_win_element): Remove.
+ (struct tui_source_window_base) <content>: New field.
+ (struct tui_data_window): Remove destructor.
+ (tui_alloc_content, tui_free_win_content)
+ (tui_free_all_source_wins_content): Don't declare.
+ * tui/tui-data.c (tui_initialize_static_data): Update.
+ (init_content_element, tui_alloc_content): Remove.
+ (~tui_gen_win_info): Update.
+ (~tui_data_window, tui_free_all_source_wins_content)
+ (tui_free_win_content, free_content, free_content_elements):
+ Remove.
+
2019-06-25 Tom Tromey <tom@tromey.com>
* tui/tui-winsource.h (tui_clear_source_content)
static int win_resized = FALSE;
-/*********************************
-** Static function forward decls
-**********************************/
-static void free_content (tui_win_content,
- int,
- enum tui_win_type);
-static void free_content_elements (tui_win_content,
- int,
- enum tui_win_type);
-
-
-
/*********************************
** PUBLIC FUNCTIONS
**********************************/
win->origin.x =
win->origin.y =
win->viewport_height =
- win->content_size =
win->last_visible_line = 0;
win->handle = NULL;
- win->content = NULL;
win->content_in_use = FALSE;
win->is_visible = false;
win->title = 0;
}
-/* init_content_element().
- */
-static void
-init_content_element (struct tui_win_element *element,
- enum tui_win_type type)
-{
- gdb_assert (type != EXEC_INFO_WIN);
- gdb_assert (type != LOCATOR_WIN);
- gdb_assert (type != CMD_WIN);
- gdb_assert (type != DATA_ITEM_WIN);
- gdb_assert (type != DATA_WIN);
-
- switch (type)
- {
- case SRC_WIN:
- case DISASSEM_WIN:
- element->which_element.source.line = NULL;
- element->which_element.source.line_or_addr.loa = LOA_LINE;
- element->which_element.source.line_or_addr.u.line_no = 0;
- element->which_element.source.is_exec_point = false;
- element->which_element.source.has_break = FALSE;
- break;
- default:
- break;
- }
-}
-
tui_win_info::tui_win_info (enum tui_win_type type)
: tui_gen_win_info (type)
{
start_line_or_addr.u.addr = 0;
}
-/* Allocates the content and elements in a block. */
-tui_win_content
-tui_alloc_content (int num_elements, enum tui_win_type type)
-{
- tui_win_content content;
- struct tui_win_element *element_block_ptr;
- int i;
-
- gdb_assert (type != EXEC_INFO_WIN);
- gdb_assert (type != LOCATOR_WIN);
-
- content = XNEWVEC (struct tui_win_element *, num_elements);
-
- /*
- * All windows, except the data window, can allocate the
- * elements in a chunk. The data window cannot because items
- * can be added/removed from the data display by the user at any
- * time.
- */
- if (type != DATA_WIN)
- {
- element_block_ptr = XNEWVEC (struct tui_win_element, num_elements);
- for (i = 0; i < num_elements; i++)
- {
- content[i] = element_block_ptr;
- init_content_element (content[i], type);
- element_block_ptr++;
- }
- }
-
- return content;
-}
-
-
tui_gen_win_info::~tui_gen_win_info ()
{
if (handle != NULL)
{
tui_delete_win (handle);
handle = NULL;
- tui_free_win_content (this);
}
xfree (title);
}
delete execution_info;
}
-tui_data_window::~tui_data_window ()
-{
- if (content != NULL)
- {
- regs_column_count = 1;
- display_regs = false;
- content = NULL;
- content_size = 0;
- }
-}
-
-void
-tui_free_all_source_wins_content ()
-{
- for (tui_source_window_base *win_info : tui_source_windows ())
- {
- tui_free_win_content (win_info);
- tui_free_win_content (win_info->execution_info);
- }
-}
-
-
-void
-tui_free_win_content (struct tui_gen_win_info *win_info)
-{
- if (win_info->content != NULL)
- {
- free_content (win_info->content,
- win_info->content_size,
- win_info->type);
- win_info->content = NULL;
- }
- win_info->content_size = 0;
-}
-
-
/**********************************
** LOCAL STATIC FUNCTIONS **
**********************************/
-static void
-free_content (tui_win_content content,
- int content_size,
- enum tui_win_type win_type)
-{
- if (content != NULL)
- {
- free_content_elements (content, content_size, win_type);
- xfree (content);
- }
-}
-
-
tui_data_item_window::~tui_data_item_window ()
{
xfree (value);
xfree (content);
}
-
-/* free_content_elements().
- */
-static void
-free_content_elements (tui_win_content content,
- int content_size,
- enum tui_win_type type)
-{
- if (content != NULL)
- {
- int i;
-
- if (type == DISASSEM_WIN)
- {
- /* Free whole source block. */
- xfree (content[0]->which_element.source.line);
- }
- else
- {
- for (i = 0; i < content_size; i++)
- {
- struct tui_win_element *element;
-
- element = content[i];
- if (element != NULL)
- {
- switch (type)
- {
- case SRC_WIN:
- xfree (element->which_element.source.line);
- break;
- default:
- break;
- }
- }
- }
- }
- if (type != DATA_WIN && type != DATA_ITEM_WIN)
- xfree (content[0]); /* Free the element block. */
- }
-}
int x, y;
};
-struct tui_win_element;
-
-/* This describes the content of the window. */
-typedef struct tui_win_element **tui_win_content;
-
/* Generic window information. */
struct tui_gen_win_info
{
int height = 0;
/* Origin of window. */
struct tui_point origin = {0, 0};
- /* Content of window. */
- tui_win_content content = nullptr;
- /* Size of content (# of elements). */
- int content_size = 0;
/* Can it be used, or is it already used? */
int content_in_use = FALSE;
/* Viewport height. */
/* Elements in the Source/Disassembly Window. */
struct tui_source_element
{
- char *line;
+ tui_source_element ()
+ {
+ line_or_addr.loa = LOA_LINE;
+ line_or_addr.u.line_no = 0;
+ }
+
+ ~tui_source_element ()
+ {
+ xfree (line);
+ }
+
+ char *line = nullptr;
struct tui_line_or_address line_or_addr;
- bool is_exec_point;
- int has_break;
+ bool is_exec_point = false;
+ int has_break = 0;
};
typedef char tui_exec_info_content[TUI_EXECINFO_SIZE];
-/* An content element in a window. */
-union tui_which_element
-{
- struct tui_source_element source; /* The source elements. */
-};
-
-struct tui_win_element
-{
- union tui_which_element which_element;
-};
-
/* Execution info window class. */
struct tui_exec_info_window : public tui_gen_win_info
/* Architecture associated with code at this location. */
struct gdbarch *gdbarch = nullptr;
+
+ std::vector<tui_source_element> content;
};
/* A TUI source window. */
{
}
- ~tui_data_window () override;
DISABLE_COPY_AND_ASSIGN (tui_data_window);
void clear_detail () override;
/* Data Manipulation Functions. */
extern void tui_initialize_static_data (void);
-extern tui_win_content tui_alloc_content (int, enum tui_win_type);
-extern void tui_free_win_content (struct tui_gen_win_info *);
-extern void tui_free_all_source_wins_content (void);
extern struct tui_win_info *tui_partial_win_by_name (const char *);
extern enum tui_layout_type tui_current_layout (void);
extern void tui_set_current_layout_to (enum tui_layout_type);
line = (char*) alloca (insn_pos + insn_size + 1);
/* Now construct each line. */
+ TUI_DISASM_WIN->content.resize (max_lines);
for (i = 0; i < max_lines; i++)
{
- struct tui_win_element *element;
- struct tui_source_element *src;
int cur_len;
- element = TUI_DISASM_WIN->content[i];
- src = &element->which_element.source;
+ tui_source_element *src = &TUI_DISASM_WIN->content[i];
strcpy (line, asm_lines[i].addr_string);
cur_len = strlen (line);
memset (line + cur_len, ' ', insn_pos - cur_len);
strcpy (line + insn_pos, asm_lines[i].insn);
/* Now copy the line taking the offset into account. */
+ xfree (src->line);
if (strlen (line) > offset)
- {
- strncpy (src->line, &line[offset], line_width);
- src->line[line_width] = '\0';
- }
+ src->line = xstrndup (&line[offset], line_width);
else
- src->line[0] = '\0';
+ src->line = xstrdup ("");
src->line_or_addr.loa = LOA_ADDRESS;
src->line_or_addr.u.addr = asm_lines[i].addr;
xfree (asm_lines[i].addr_string);
xfree (asm_lines[i].insn);
}
- TUI_DISASM_WIN->content_size = i;
return TUI_SUCCESS;
}
void
tui_disasm_window::do_scroll_vertical (int num_to_scroll)
{
- if (content != NULL)
+ if (!content.empty ())
{
CORE_ADDR pc;
struct tui_line_or_address val;
- pc = content[0]->which_element.source.line_or_addr.u.addr;
+ pc = content[0].line_or_addr.u.addr;
if (num_to_scroll >= 0)
num_to_scroll++;
else
/* Since the new layout may cause changes in window size, we
should free the content and reallocate on next display of
source/asm. */
- tui_free_all_source_wins_content ();
tui_clear_source_windows ();
if (layout == SRC_DATA_COMMAND
|| layout == DISASSEM_DATA_COMMAND)
cur_line_no = src->start_line_or_addr.u.line_no = line_no;
const char *iter = srclines.c_str ();
+ TUI_SRC_WIN->content.resize (nlines);
while (cur_line < nlines)
{
- struct tui_win_element *element
- = TUI_SRC_WIN->content[cur_line];
+ struct tui_source_element *element
+ = &TUI_SRC_WIN->content[cur_line];
std::string text;
if (*iter != '\0')
/* Set whether element is the execution point
and whether there is a break point on it. */
- element->which_element.source.line_or_addr.loa =
- LOA_LINE;
- element->which_element.source.line_or_addr.u.line_no =
- cur_line_no;
- element->which_element.source.is_exec_point =
- (filename_cmp (locator->full_name,
- symtab_to_fullname (s)) == 0
- && cur_line_no == locator->line_no);
-
- xfree (TUI_SRC_WIN->content[cur_line]
- ->which_element.source.line);
- TUI_SRC_WIN->content[cur_line]
- ->which_element.source.line
+ element->line_or_addr.loa = LOA_LINE;
+ element->line_or_addr.u.line_no = cur_line_no;
+ element->is_exec_point
+ = (filename_cmp (locator->full_name,
+ symtab_to_fullname (s)) == 0
+ && cur_line_no == locator->line_no);
+
+ xfree (TUI_SRC_WIN->content[cur_line].line);
+ TUI_SRC_WIN->content[cur_line].line
= xstrdup (text.c_str ());
cur_line++;
cur_line_no++;
}
- TUI_SRC_WIN->content_size = nlines;
ret = TUI_SUCCESS;
}
}
/* Set to empty each line in the window, except for the one which
contains the message. */
- while (curr_line < win_info->content_size)
+ while (curr_line < win_info->content.size ())
{
/* Set the information related to each displayed line to null:
i.e. the line number is 0, there is no bp, it is not where
the program is stopped. */
- struct tui_win_element *element = win_info->content[curr_line];
+ struct tui_source_element *element = &win_info->content[curr_line];
- element->which_element.source.line_or_addr.loa = LOA_LINE;
- element->which_element.source.line_or_addr.u.line_no = 0;
- element->which_element.source.is_exec_point = false;
- element->which_element.source.has_break = FALSE;
+ element->line_or_addr.loa = LOA_LINE;
+ element->line_or_addr.u.line_no = 0;
+ element->is_exec_point = false;
+ element->has_break = FALSE;
/* Set the contents of the line to blank. */
- element->which_element.source.line[0] = (char) 0;
+ element->line[0] = (char) 0;
/* If the current line is in the middle of the screen, then we
want to display the 'no source available' message in it.
xpos = (line_width - 1) / 2 - warning_length;
src_line = xstrprintf ("%s%s", n_spaces (xpos), warning_string);
- xfree (element->which_element.source.line);
- element->which_element.source.line = src_line;
+ xfree (element->line);
+ element->line = src_line;
}
curr_line++;
void
tui_source_window::do_scroll_vertical (int num_to_scroll)
{
- if (content != NULL)
+ if (!content.empty ())
{
struct tui_line_or_address l;
struct symtab *s;
s = cursal.symtab;
l.loa = LOA_LINE;
- l.u.line_no = content[0]->which_element.source.line_or_addr.u.line_no
+ l.u.line_no = content[0].line_or_addr.u.line_no
+ num_to_scroll;
if (l.u.line_no > s->nlines)
/* line = s->nlines - win_info->content_size + 1; */
/* elz: fix for dts 23398. */
- l.u.line_no
- = content[0]->which_element.source.line_or_addr.u.line_no;
+ l.u.line_no = content[0].line_or_addr.u.line_no;
if (l.u.line_no <= 0)
l.u.line_no = 1;
make_invisible_and_set_new_height (TUI_CMD_WIN, new_height);
first_win->make_visible_with_new_height ();
TUI_CMD_WIN->make_visible_with_new_height ();
- if (src_win->content_size <= 0)
+ if (src_win->content.empty ())
tui_erase_source_content (src_win, EMPTY_SOURCE_PROMPT);
break;
default:
first_win->make_visible_with_new_height ();
second_win->make_visible_with_new_height ();
TUI_CMD_WIN->make_visible_with_new_height ();
- if (src_win->content_size <= 0)
+ if (src_win->content.empty ())
tui_erase_source_content (src_win, EMPTY_SOURCE_PROMPT);
break;
}
win_info->make_visible_with_new_height ();
primary_win_info->make_visible_with_new_height ();
if ((src_win_info->type == SRC_WIN
- || src_win_info->type == DISASSEM_WIN)
- && src_win_info->content_size <= 0)
- tui_erase_source_content
- ((tui_source_window_base *) src_win_info,
- EMPTY_SOURCE_PROMPT);
+ || src_win_info->type == DISASSEM_WIN))
+ {
+ tui_source_window_base *src_base
+ = (tui_source_window_base *) src_win_info;
+ if (src_base->content.empty ())
+ tui_erase_source_content (src_base,
+ EMPTY_SOURCE_PROMPT);
+ }
}
else
{
TUI_CMD_WIN->make_visible_with_new_height ();
second_win->make_visible_with_new_height ();
first_win->make_visible_with_new_height ();
- if (src1 != nullptr && src1->content_size <= 0)
+ if (src1 != nullptr && src1->content.empty ())
tui_erase_source_content (src1, EMPTY_SOURCE_PROMPT);
- if (second_win->content_size <= 0)
+ if (second_win->content.empty ())
tui_erase_source_content (second_win, EMPTY_SOURCE_PROMPT);
}
}
void
tui_source_window_base::do_make_visible_with_new_height ()
{
- tui_free_win_content (execution_info);
tui_make_visible (execution_info);
- if (content != NULL)
+ if (!content.empty ())
{
struct tui_line_or_address line_or_addr;
struct symtab_and_line cursal
= get_current_source_symtab_and_line ();
line_or_addr = start_line_or_addr;
- tui_free_win_content (this);
tui_update_source_window (this, gdbarch,
cursal.symtab, line_or_addr, TRUE);
}
symtab_and_line sal;
sal.line = line_or_addr.u.line_no +
- (win_info->content_size - 2);
+ (win_info->content.size () - 2);
sal.symtab = s;
sal.pspace = SYMTAB_PSPACE (s);
set_current_source_symtab_and_line (sal);
win_info->content_in_use = FALSE;
tui_erase_source_content (win_info, display_prompt);
- for (i = 0; i < win_info->content_size; i++)
+ for (i = 0; i < win_info->content.size (); i++)
{
- struct tui_win_element *element = win_info->content[i];
+ struct tui_source_element *element = &win_info->content[i];
- element->which_element.source.has_break = FALSE;
- element->which_element.source.is_exec_point = false;
+ element->has_break = FALSE;
+ element->is_exec_point = false;
}
}
}
/* Redraw the complete line of a source or disassembly window. */
static void
-tui_show_source_line (struct tui_win_info *win_info, int lineno)
+tui_show_source_line (struct tui_source_window_base *win_info, int lineno)
{
- struct tui_win_element *line;
+ struct tui_source_element *line;
int x;
- line = win_info->content[lineno - 1];
- if (line->which_element.source.is_exec_point)
+ line = &win_info->content[lineno - 1];
+ if (line->is_exec_point)
tui_set_reverse_mode (win_info->handle, true);
wmove (win_info->handle, lineno, 1);
- tui_puts (line->which_element.source.line,
+ tui_puts (line->line,
win_info->handle);
- if (line->which_element.source.is_exec_point)
+ if (line->is_exec_point)
tui_set_reverse_mode (win_info->handle, false);
/* Clear to end of line but stop before the border. */
void
tui_show_source_content (struct tui_source_window_base *win_info)
{
- if (win_info->content_size > 0)
+ if (!win_info->content.empty ())
{
int lineno;
- for (lineno = 1; lineno <= win_info->content_size; lineno++)
+ for (lineno = 1; lineno <= win_info->content.size (); lineno++)
tui_show_source_line (win_info, lineno);
}
else
}
tui_update_source_window_as_is (this, gdbarch, s,
- content[0]
- ->which_element.source.line_or_addr,
+ content[0].line_or_addr,
FALSE);
}
void
tui_source_window_base::do_scroll_horizontal (int num_to_scroll)
{
- if (content != NULL)
+ if (!content.empty ())
{
int offset = horizontal_offset + num_to_scroll;
if (offset < 0)
int i;
i = 0;
- while (i < content_size)
+ while (i < content.size ())
{
bool new_state;
struct tui_line_or_address content_loa =
- content[i]->which_element.source.line_or_addr;
+ content[i].line_or_addr;
gdb_assert (l.loa == LOA_ADDRESS || l.loa == LOA_LINE);
gdb_assert (content_loa.loa == LOA_LINE
new_state = true;
else
new_state = false;
- if (new_state != content[i]->which_element.source.is_exec_point)
+ if (new_state != content[i].is_exec_point)
{
changed = true;
- content[i]->which_element.source.is_exec_point = new_state;
+ content[i].is_exec_point = new_state;
tui_show_source_line (this, i + 1);
}
i++;
refreshed. */
int
-tui_update_breakpoint_info (struct tui_win_info *win,
+tui_update_breakpoint_info (struct tui_source_window_base *win,
int current_only)
{
int i;
int need_refresh = 0;
tui_source_window_base *src = (tui_source_window_base *) win;
- for (i = 0; i < win->content_size; i++)
+ for (i = 0; i < win->content.size (); i++)
{
struct breakpoint *bp;
extern struct breakpoint *breakpoint_chain;
int mode;
struct tui_source_element *line;
- line = &win->content[i]->which_element.source;
+ line = &win->content[i];
if (current_only && !line->is_exec_point)
continue;
= win_info->execution_info->maybe_allocate_content (win_info->height);
tui_update_breakpoint_info (win_info, 1);
- for (int i = 0; i < win_info->content_size; i++)
+ for (int i = 0; i < win_info->content.size (); i++)
{
tui_exec_info_content &element = content[i];
- struct tui_win_element *src_element;
+ struct tui_source_element *src_element;
int mode;
- src_element = win_info->content[i];
+ src_element = &win_info->content[i];
memset (element, ' ', sizeof (tui_exec_info_content));
element[TUI_EXECINFO_SIZE - 1] = 0;
/* Now update the exec info content based upon the state
of each line as indicated by the source content. */
- mode = src_element->which_element.source.has_break;
+ mode = src_element->has_break;
if (mode & TUI_BP_HIT)
element[TUI_BP_HIT_POS] = (mode & TUI_BP_HARDWARE) ? 'H' : 'B';
else if (mode & (TUI_BP_ENABLED | TUI_BP_DISABLED))
else if (mode & TUI_BP_DISABLED)
element[TUI_BP_BREAK_POS] = '-';
- if (src_element->which_element.source.is_exec_point)
+ if (src_element->is_exec_point)
element[TUI_EXEC_POS] = '>';
}
}
werase (exec_info->handle);
exec_info->refresh_window ();
- for (int cur_line = 1; (cur_line <= win_info->content_size); cur_line++)
+ for (int cur_line = 1; cur_line <= win_info->content.size (); cur_line++)
mvwaddstr (exec_info->handle,
cur_line,
0,
}
void
-tui_alloc_source_buffer (struct tui_win_info *win_info)
+tui_alloc_source_buffer (struct tui_source_window_base *win_info)
{
int i, line_width, max_lines;
line_width = win_info->width - 2 + 1;
/* Allocate the buffer for the source lines. */
- if (win_info->content == NULL)
+ win_info->content.resize (max_lines);
+ for (i = 0; i < max_lines; i++)
{
- /* Allocate the content list. */
- win_info->content = tui_alloc_content (max_lines, SRC_WIN);
- for (i = 0; i < max_lines; i++)
- win_info->content[i]->which_element.source.line
- = (char *) xmalloc (line_width);
+ if (win_info->content[i].line == nullptr)
+ win_info->content[i].line = (char *) xmalloc (line_width);
}
}
in the current source window. */
int
tui_line_is_displayed (int line,
- struct tui_win_info *win_info,
+ struct tui_source_window_base *win_info,
int check_threshold)
{
int is_displayed = FALSE;
else
threshold = 0;
i = 0;
- while (i < win_info->content_size - threshold
+ while (i < win_info->content.size () - threshold
&& !is_displayed)
{
is_displayed
- = win_info->content[i]
- ->which_element.source.line_or_addr.loa == LOA_LINE
- && win_info->content[i]
- ->which_element.source.line_or_addr.u.line_no == line;
+ = win_info->content[i].line_or_addr.loa == LOA_LINE
+ && win_info->content[i].line_or_addr.u.line_no == line;
i++;
}
in the current source window. */
int
tui_addr_is_displayed (CORE_ADDR addr,
- struct tui_win_info *win_info,
+ struct tui_source_window_base *win_info,
int check_threshold)
{
int is_displayed = FALSE;
else
threshold = 0;
i = 0;
- while (i < win_info->content_size - threshold
+ while (i < win_info->content.size () - threshold
&& !is_displayed)
{
is_displayed
- = win_info->content[i]
- ->which_element.source.line_or_addr.loa == LOA_ADDRESS
- && win_info->content[i]
- ->which_element.source.line_or_addr.u.addr == addr;
+ = win_info->content[i].line_or_addr.loa == LOA_ADDRESS
+ && win_info->content[i].line_or_addr.u.addr == addr;
i++;
}
/* Scan the source window and the breakpoints to update the hasBreak
information for each line. Returns 1 if something changed and the
execution window must be refreshed. */
-extern int tui_update_breakpoint_info (struct tui_win_info *win,
+extern int tui_update_breakpoint_info (struct tui_source_window_base *win,
int current_only);
/* Function to display the "main" routine. */
extern void tui_clear_exec_info_content (struct tui_source_window_base *);
extern void tui_update_exec_info (struct tui_source_window_base *);
-extern void tui_alloc_source_buffer (struct tui_win_info *);
-extern int tui_line_is_displayed (int,
- struct tui_win_info *,
+extern void tui_alloc_source_buffer (struct tui_source_window_base *);
+extern int tui_line_is_displayed (int,
+ struct tui_source_window_base *,
int);
-extern int tui_addr_is_displayed (CORE_ADDR,
- struct tui_win_info *,
+extern int tui_addr_is_displayed (CORE_ADDR,
+ struct tui_source_window_base *,
int);