X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=src%2Fwindow.c;h=49936677c23dfca5f5a001507106aa7e73d548ee;hb=fed235e548376a8a2763405c4623fdf23f5c6529;hp=8922d8f3d1e116d168bf45c7ee9655878af750da;hpb=5de3ee3365d18b1dcdcf320fd0a4a77de2a6287e;p=rodin%2Fchimara.git diff --git a/src/window.c b/src/window.c index 8922d8f..4993667 100644 --- a/src/window.c +++ b/src/window.c @@ -510,37 +510,74 @@ glk_window_open(winid_t split, glui32 method, glui32 size, glui32 wintype, gtk_widget_set_parent(win->frame, GTK_WIDGET(glk_data->self)); gtk_widget_queue_resize(GTK_WIDGET(glk_data->self)); + gdk_threads_leave(); + /* For text grid windows, wait until GTK draws the window (see note in glk_window_get_size() ), calculate the size and fill the buffer with blanks. */ if(wintype == wintype_TextGrid) { - while(win->widget->allocation.width == 1 && win->widget->allocation.height == 1) - { - /* Release the GDK lock momentarily */ - gdk_threads_leave(); - gdk_threads_enter(); - while(gtk_events_pending()) - gtk_main_iteration(); - } - win->width = (glui32)(win->widget->allocation.width / win->unit_width); - win->height = (glui32)(win->widget->allocation.height / win->unit_height); + /* Force the window to be drawn and cache its size */ + glk_window_get_size(win, NULL, NULL); - /* Mark the cursor position */ + /* Create the cursor position mark */ + gdk_threads_enter(); GtkTextIter begin; GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(win->widget) ); gtk_text_buffer_get_start_iter(buffer, &begin); gtk_text_buffer_create_mark(buffer, "cursor_position", &begin, TRUE); - - /* Fill the buffer with blanks and move the cursor to the upper left */ gdk_threads_leave(); + + /* Fill the buffer with blanks and move the cursor to the upper left */ glk_window_clear(win); - gdk_threads_enter(); } - gdk_threads_leave(); - return win; } +/* Internal function: destroy this window's GTK widgets, window streams, + and those of all its children */ +static void +destroy_windows_below(winid_t win, stream_result_t *result) +{ + switch(win->type) + { + case wintype_Blank: + gdk_threads_enter(); + gtk_widget_unparent(win->widget); + gdk_threads_leave(); + break; + + case wintype_TextGrid: + case wintype_TextBuffer: + gdk_threads_enter(); + gtk_widget_unparent(win->frame); + gdk_threads_leave(); + /* TODO: Cancel all input requests */ + break; + + case wintype_Pair: + destroy_windows_below(win->window_node->children->data, NULL); + destroy_windows_below(win->window_node->children->next->data, NULL); + break; + + default: + ILLEGAL_PARAM("Unknown window type: %u", win->type); + return; + } + stream_close_common(win->window_stream, result); +} + +/* Internal function: free the winid_t structure of this window and those of all its children */ +static void +free_winids_below(winid_t win) +{ + if(win->type == wintype_Pair) { + free_winids_below(win->window_node->children->data); + free_winids_below(win->window_node->children->next->data); + } + win->magic = MAGIC_FREE; + g_free(win); +} + /** * glk_window_close: * @win: Window to close. @@ -585,97 +622,14 @@ glk_window_open(winid_t split, glui32 method, glui32 size, glui32 wintype, * Constraints. * */ - -static void -dump_window_tree(GNode *node) -{ - if(node == NULL) { - g_printerr("NULL"); - return; - } - g_printerr("["); - switch(((winid_t)node->data)->type) { - case wintype_Pair: - g_printerr("Pair "); - dump_window_tree(node->children); - dump_window_tree(node->children->next); - g_printerr("]"); - break; - case wintype_TextBuffer: - g_printerr("Buffer]"); - break; - case wintype_TextGrid: - g_printerr("Grid]"); - break; - case wintype_Blank: - g_printerr("Blank]"); - break; - default: - g_printerr("Fucked up - %d]", ((winid_t)node->data)->type); - } -} - -static void -close_window_streams_below(winid_t win, stream_result_t *result) -{ - if(win->type == wintype_Pair) { - close_window_streams_below(win->window_node->children->data, NULL); - close_window_streams_below(win->window_node->children->next->data, NULL); - } - stream_close_common(win->window_stream, result); -} - -static void -destroy_widgets_below(winid_t win) -{ - switch(win->type) - { - case wintype_Blank: - gdk_threads_enter(); - gtk_widget_unparent(win->widget); - gdk_threads_leave(); - break; - - case wintype_TextGrid: - case wintype_TextBuffer: - gdk_threads_enter(); - gtk_widget_unparent(win->frame); - gdk_threads_leave(); - /* TODO: Cancel all input requests */ - break; - - case wintype_Pair: - destroy_widgets_below(win->window_node->children->data); - destroy_widgets_below(win->window_node->children->next->data); - break; - - default: - ILLEGAL_PARAM("Unknown window type: %u", win->type); - return; - } -} - -static void -free_winids_below(winid_t win) -{ - if(win->type == wintype_Pair) { - free_winids_below(win->window_node->children->data); - free_winids_below(win->window_node->children->next->data); - } - win->magic = MAGIC_FREE; - g_free(win); -} - void glk_window_close(winid_t win, stream_result_t *result) { VALID_WINDOW(win, return); - /* First close all the window streams before trashing the window tree */ - close_window_streams_below(win, result); - - /* Then destroy the widgets of this window and below */ - destroy_widgets_below(win); + /* First close all the window streams and destroy the widgets of this window + and below, before trashing the window tree */ + destroy_windows_below(win, result); /* Then free the winid_t structures below this node, but not this one itself */ if(win->type == wintype_Pair) { @@ -725,6 +679,7 @@ glk_window_close(winid_t win, stream_result_t *result) g_free(win); /* Schedule a redraw */ + gdk_threads_enter(); gtk_widget_queue_resize( GTK_WIDGET(glk_data->self) ); gdk_threads_leave(); } @@ -941,7 +896,20 @@ glk_window_get_size(winid_t win, glui32 *widthptr, glui32 *heightptr) break; case wintype_TextGrid: - /* The text grid caches its width and height */ + gdk_threads_enter(); + /* Wait for the window to be drawn, and then cache the width and height */ + while(win->widget->allocation.width == 1 && win->widget->allocation.height == 1) + { + /* Release the GDK lock momentarily */ + gdk_threads_leave(); + gdk_threads_enter(); + while(gtk_events_pending()) + gtk_main_iteration(); + } + win->width = (glui32)(win->widget->allocation.width / win->unit_width); + win->height = (glui32)(win->widget->allocation.height / win->unit_height); + gdk_threads_leave(); + if(widthptr != NULL) *widthptr = win->width; if(heightptr != NULL)