Changeset 7a6e6c7


Ignore:
Timestamp:
Jun 1, 2010, 1:27:14 AM (11 years ago)
Author:
David Benjamin <davidben@mit.edu>
Branches:
master, release-1.7, release-1.8, release-1.9
Children:
05ca0d8
Parents:
7a70e26
Message:
Use signals for redraw and resize
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • global.c

    rae11191 r7a6e6c7  
    492492  g->resizepending = 0;
    493493
    494   g->lines = lines;
    495   g->cols = cols;
    496   owl_window_recompute_position(owl_window_get_screen());
     494  owl_global_get_terminal_size(&lines, &cols);
     495  if (lines) g->lines = lines;
     496  if (cols)  g->cols  = cols;
     497  owl_window_resize(owl_window_get_screen(), g->lines, g->cols);
    497498
    498499  owl_function_debugmsg("New size is %i lines, %i cols.", g->lines, g->cols);
  • owl.h

    re96b4ce r7a6e6c7  
    404404  int rightshift;
    405405  owl_window *window;
     406  gulong sig_redraw_id;
    406407  void (*onclose_hook) (struct _owl_viewwin *vwin, void *data);
    407408  void *onclose_hook_data;
     
    409410 
    410411typedef struct _owl_popwin {
     412  gulong screen_resize_id;
    411413  owl_window *border;
    412414  owl_window *content;
  • popwin.c

    r053f751 r7a6e6c7  
    1111  pw->border = owl_window_new(NULL);
    1212  pw->content = owl_window_new(pw->border);
    13   owl_window_set_redraw_cb(pw->border, owl_popwin_draw_border, pw, 0);
    14   owl_window_set_size_cb(pw->border, owl_popwin_size_border, 0, 0);
    15   owl_window_set_size_cb(pw->content, owl_popwin_size_content, 0, 0);
     13  g_signal_connect(pw->border, "redraw", G_CALLBACK(owl_popwin_draw_border), 0);
     14  pw->screen_resize_id = g_signal_connect_object(owl_window_get_screen(), "resized", G_CALLBACK(owl_popwin_size_border), pw->border, 0);
     15  g_signal_connect_object(pw->border, "resized", G_CALLBACK(owl_popwin_size_content), pw->content, 0);
     16
     17  /* bootstrap sizing */
     18  owl_popwin_size_border(owl_window_get_screen(), pw->border);
     19
    1620  owl_window_show_all(pw->border);
    1721
     
    2024}
    2125
    22 void owl_popwin_size_border(owl_window *border, void *user_data)
     26void owl_popwin_size_border(owl_window *parent, void *user_data)
    2327{
    2428  int lines, cols, startline, startcol;
    2529  int glines, gcols;
    26   owl_window *parent = owl_window_get_parent(border);
     30  owl_window *border = user_data;
    2731
    2832  owl_window_get_position(parent, &glines, &gcols, 0, 0);
     
    3640}
    3741
    38 void owl_popwin_size_content(owl_window *content, void *user_data)
     42void owl_popwin_size_content(owl_window *parent, void *user_data)
    3943{
    4044  int lines, cols;
    41   owl_window *parent = owl_window_get_parent(content);
     45  owl_window *content = user_data;
    4246  owl_window_get_position(parent, &lines, &cols, 0, 0);
    4347  owl_window_set_position(content, lines-2, cols-2, 1, 1);
     
    6872  g_object_unref(pw->border);
    6973  g_object_unref(pw->content);
     74
     75  /* See comment on g_signal_connect_object; it only prevents the closure from
     76   * being invoked. The signal handler itself still gets leaked. The other
     77   * signal is okay, since we delete both at the same time. */
     78  if (g_signal_handler_is_connected(owl_window_get_screen(), pw->screen_resize_id))
     79      g_signal_handler_disconnect(owl_window_get_screen(), pw->screen_resize_id);
     80
    7081  pw->border = 0;
    7182  pw->content = 0;
  • viewwin.c

    r5f7eadf r7a6e6c7  
    5353{
    5454  if (v->window) {
    55     owl_window_set_redraw_cb(v->window, 0, 0, 0);
     55    g_signal_handler_disconnect(v->window, v->sig_redraw_id);
    5656  }
    5757  v->window = w;
    5858  if (w) {
    59     owl_window_set_redraw_cb(w, owl_viewwin_redisplay, v, 0);
     59    v->sig_redraw_id = g_signal_connect(w, "redraw", G_CALLBACK(owl_viewwin_redisplay), v);
    6060  }
    6161}
  • window.c

    r7a70e26 r7a6e6c7  
    1919  int nlines, ncols;
    2020  int begin_y, begin_x;
    21   /* hooks */
    22   void (*redraw_cb)(owl_window *, WINDOW *, void *);
    23   void  *redraw_cbdata;
    24   void (*redraw_cbdata_destroy)(void *);
    25 
    26   void (*size_cb)(owl_window *, void *);
    27   void  *size_cbdata;
    28   void (*size_cbdata_destroy)(void *);
    2921};
     22
     23enum {
     24  REDRAW,
     25  RESIZED,
     26  LAST_SIGNAL
     27};
     28
     29static guint window_signals[LAST_SIGNAL] = { 0 };
    3030
    3131static void owl_window_dispose(GObject *gobject);
     
    4242static void _owl_window_unrealize(owl_window *w);
    4343
     44static void _owl_window_redraw_cleanup(owl_window *w, WINDOW *win);
     45
    4446G_DEFINE_TYPE (OwlWindow, owl_window, G_TYPE_OBJECT)
    4547
    4648static void owl_window_class_init (OwlWindowClass *klass)
    4749{
    48   GObjectClass *object_class = G_OBJECT_CLASS (klass);
    49 
    50   object_class->dispose = owl_window_dispose;
    51   object_class->finalize = owl_window_finalize;
     50  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
     51
     52  /* Set up the vtabl */
     53  gobject_class->dispose = owl_window_dispose;
     54  gobject_class->finalize = owl_window_finalize;
     55
     56  klass->redraw = _owl_window_redraw_cleanup;
     57  klass->resized = NULL;
     58
     59  /* Create the signals, remember IDs */
     60  window_signals[REDRAW] =
     61    g_signal_new("redraw",
     62                 G_TYPE_FROM_CLASS(gobject_class),
     63                 G_SIGNAL_RUN_CLEANUP,
     64                 G_STRUCT_OFFSET(OwlWindowClass, redraw),
     65                 NULL, NULL,
     66                 g_cclosure_marshal_VOID__POINTER,
     67                 G_TYPE_NONE,
     68                 1,
     69                 G_TYPE_POINTER, NULL);
     70
     71  /* TODO: maybe type should be VOID__INT_INT_INT_INT; will need to generate a
     72   * marshaller */
     73  window_signals[RESIZED] =
     74    g_signal_new("resized",
     75                 G_TYPE_FROM_CLASS(gobject_class),
     76                 G_SIGNAL_RUN_FIRST,
     77                 G_STRUCT_OFFSET(OwlWindowClass, resized),
     78                 NULL, NULL,
     79                 g_cclosure_marshal_VOID__VOID,
     80                 G_TYPE_NONE,
     81                 0,
     82                 NULL);
    5283}
    5384
     
    6596  }
    6697
    67   /* Clear all cbs */
    68   owl_window_set_redraw_cb (w, 0, 0, 0);
    69   owl_window_set_size_cb (w, 0, 0, 0);
    70 
    7198  /* Remove from hierarchy */
    7299  owl_window_unlink (w);
     
    100127  }
    101128  return dummy;
    102 }
    103 
    104 static void _screen_calculate_size(owl_window *screen, void *user_data)
    105 {
    106   owl_global *g = user_data;
    107   int lines, cols;
    108   owl_global_get_terminal_size(&lines, &cols);
    109   if (!g->lines) g->lines = lines;
    110   if (!g->cols) g->cols = cols;
    111   owl_window_resize(screen, g->lines, g->cols);
    112129}
    113130
     
    120137    screen = _owl_window_new(NULL, g.lines, g.cols, 0, 0);
    121138    screen->is_screen = 1;
    122     owl_window_set_size_cb(screen, _screen_calculate_size, &g, 0);
    123139    owl_window_show(screen);
    124140  }
     
    154170
    155171  return w;
    156 }
    157 
    158 /** Callbacks **/
    159 
    160 void owl_window_set_redraw_cb(owl_window *w, void (*cb)(owl_window*, WINDOW*, void*), void *cbdata, void (*cbdata_destroy)(void*))
    161 {
    162   if (w->redraw_cbdata_destroy) {
    163     w->redraw_cbdata_destroy(w->redraw_cbdata);
    164     w->redraw_cbdata = 0;
    165     w->redraw_cbdata_destroy = 0;
    166   }
    167 
    168   w->redraw_cb = cb;
    169   w->redraw_cbdata = cbdata;
    170   w->redraw_cbdata_destroy = cbdata_destroy;
    171 
    172   /* mark the window as dirty, to take new cb in account */
    173   owl_window_dirty(w);
    174 }
    175 
    176 void owl_window_set_size_cb(owl_window *w, void (*cb)(owl_window*, void*), void *cbdata, void (*cbdata_destroy)(void*))
    177 {
    178   if (w->size_cbdata_destroy) {
    179     w->size_cbdata_destroy(w->size_cbdata);
    180     w->size_cbdata = 0;
    181     w->size_cbdata_destroy = 0;
    182   }
    183 
    184   w->size_cb = cb;
    185   w->size_cbdata = cbdata;
    186   w->size_cbdata_destroy = cbdata_destroy;
    187 
    188   owl_window_recompute_position(w);
    189172}
    190173
     
    368351{
    369352  if (!w->dirty) return;
    370   if (w->win && w->redraw_cb) {
    371     w->redraw_cb(w, w->win, w->redraw_cbdata);
    372     wsyncup(w->win);
     353  if (w->win) {
     354    g_signal_emit(w, window_signals[REDRAW], 0, w->win);
    373355  }
    374356  w->dirty = 0;
     
    390372{
    391373  _owl_window_redraw_subtree(owl_window_get_screen());
     374}
     375
     376static void _owl_window_redraw_cleanup(owl_window *w, WINDOW *win)
     377{
     378  wsyncup(win);
    392379}
    393380
     
    459446    _owl_window_unrealize(w);
    460447  }
    461   /* recalculate children sizes BEFORE remapping, so that everything can resize */
    462   owl_window_children_foreach(w, (GFunc)owl_window_recompute_position, 0);
     448  g_signal_emit(w, window_signals[RESIZED], 0);
    463449  if (w->shown) {
    464450    _owl_window_realize(w);
     
    470456  owl_window_set_position(w, nlines, ncols, w->begin_y, w->begin_x);
    471457}
    472 
    473 void owl_window_recompute_position(owl_window *w)
    474 {
    475   if (w->size_cb) {
    476     /* TODO: size_cb probably wants to actually take four int*s */
    477     w->size_cb(w, w->size_cbdata);
    478   }
    479 }
    480 
    481458
    482459/** Stacking order **/
  • window.h

    r7a70e26 r7a6e6c7  
    2121{
    2222  GObjectClass parent_class;
     23  /* default implementations for signals */
     24  void (*redraw)(owl_window *, WINDOW *);
     25  void (*resized)(owl_window *);
    2326};
    2427
     
    2932owl_window *owl_window_new(owl_window *parent);
    3033void owl_window_unlink(owl_window *w);
    31 
    32 void owl_window_set_redraw_cb(owl_window *w, void (*cb)(owl_window*, WINDOW*, void*), void *cbdata, void (*cbdata_destroy)(void*));
    33 void owl_window_set_size_cb(owl_window *w, void (*cb)(owl_window*, void*), void *cbdata, void (*cbdata_destroy)(void*));
    3434
    3535void owl_window_children_foreach(owl_window *parent, GFunc func, gpointer user_data);
Note: See TracChangeset for help on using the changeset viewer.