gui.h 7.63 KB
Newer Older
Colin D Bennett's avatar
Colin D Bennett committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/* gui.h - GUI components header file. */
/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
 *
 *  GRUB is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  GRUB is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <grub/types.h>
#include <grub/err.h>
#include <grub/video.h>
#include <grub/bitmap.h>
24
#include <grub/gfxmenu_view.h>
25
#include <grub/mm.h>
Colin D Bennett's avatar
Colin D Bennett committed
26 27 28 29

#ifndef GRUB_GUI_H
#define GRUB_GUI_H 1

30 31 32 33
/* The component ID identifying GUI components to be updated as the timeout
   status changes.  */
#define GRUB_GFXMENU_TIMEOUT_COMPONENT_ID "__timeout__"

Colin D Bennett's avatar
Colin D Bennett committed
34 35 36 37 38 39 40 41 42 43 44 45 46 47
typedef struct grub_gui_component *grub_gui_component_t;
typedef struct grub_gui_container *grub_gui_container_t;
typedef struct grub_gui_list *grub_gui_list_t;

typedef void (*grub_gui_component_callback) (grub_gui_component_t component,
                                             void *userdata);

/* Component interface.  */

struct grub_gui_component_ops
{
  void (*destroy) (void *self);
  const char * (*get_id) (void *self);
  int (*is_instance) (void *self, const char *type);
48
  void (*paint) (void *self, const grub_video_rect_t *bounds);
Colin D Bennett's avatar
Colin D Bennett committed
49 50 51 52
  void (*set_parent) (void *self, grub_gui_container_t parent);
  grub_gui_container_t (*get_parent) (void *self);
  void (*set_bounds) (void *self, const grub_video_rect_t *bounds);
  void (*get_bounds) (void *self, grub_video_rect_t *bounds);
53
  void (*get_minimal_size) (void *self, unsigned *width, unsigned *height);
Colin D Bennett's avatar
Colin D Bennett committed
54
  grub_err_t (*set_property) (void *self, const char *name, const char *value);
55
  void (*repaint) (void *self, int second_pass);
Colin D Bennett's avatar
Colin D Bennett committed
56 57 58 59 60 61 62 63 64 65 66 67 68
};

struct grub_gui_container_ops
{
  void (*add) (void *self, grub_gui_component_t comp);
  void (*remove) (void *self, grub_gui_component_t comp);
  void (*iterate_children) (void *self,
                            grub_gui_component_callback cb, void *userdata);
};

struct grub_gui_list_ops
{
  void (*set_view_info) (void *self,
69
                         grub_gfxmenu_view_t view);
70 71
  void (*refresh_list) (void *self,
                        grub_gfxmenu_view_t view);
Colin D Bennett's avatar
Colin D Bennett committed
72 73
};

74 75 76 77 78
struct grub_gui_progress_ops
{
  void (*set_state) (void *self, int visible, int start, int current, int end);
};

79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
typedef void (*grub_gfxmenu_set_state_t) (void *self, int visible, int start,
					  int current, int end);

struct grub_gfxmenu_timeout_notify
{
  struct grub_gfxmenu_timeout_notify *next;
  grub_gfxmenu_set_state_t set_state;
  grub_gui_component_t self;
};

extern struct grub_gfxmenu_timeout_notify *grub_gfxmenu_timeout_notifications;

static inline grub_err_t
grub_gfxmenu_timeout_register (grub_gui_component_t self,
			       grub_gfxmenu_set_state_t set_state)
{
  struct grub_gfxmenu_timeout_notify *ne = grub_malloc (sizeof (*ne));
  if (!ne)
    return grub_errno;
  ne->set_state = set_state;
  ne->self = self;
  ne->next = grub_gfxmenu_timeout_notifications;
  grub_gfxmenu_timeout_notifications = ne;
  return GRUB_ERR_NONE;
}

static inline void
grub_gfxmenu_timeout_unregister (grub_gui_component_t self)
{
  struct grub_gfxmenu_timeout_notify **p, *q;

  for (p = &grub_gfxmenu_timeout_notifications, q = *p;
       q; p = &(q->next), q = q->next)
    if (q->self == self)
      {
	*p = q->next;
115
	grub_free (q);
116 117 118 119
	break;
      }
}

120
typedef signed grub_fixed_signed_t;
121 122
#define GRUB_FIXED_1 0x10000

123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
/* Special care is taken to round to nearest integer and not just truncate.  */
static inline signed
grub_divide_round (signed a, signed b)
{
  int neg = 0;
  signed ret;
  if (b < 0)
    {
      b = -b;
      neg = !neg;
    }
  if (a < 0)
    {
      a = -a;
      neg = !neg;
    }
  ret = (unsigned) (a + b / 2) / (unsigned) b;
  return neg ? -ret : ret;
}

143 144
static inline signed
grub_fixed_sfs_divide (signed a, grub_fixed_signed_t b)
145
{
146
  return grub_divide_round (a * GRUB_FIXED_1, b);
147 148
}

149 150
static inline grub_fixed_signed_t
grub_fixed_fsf_divide (grub_fixed_signed_t a, signed b)
151
{
152
  return grub_divide_round (a, b);
153 154
}

155 156
static inline signed
grub_fixed_sfs_multiply (signed a, grub_fixed_signed_t b)
157
{
158
  return (a * b) / GRUB_FIXED_1;
159 160
}

161 162
static inline signed
grub_fixed_to_signed (grub_fixed_signed_t in)
163
{
164
  return in / GRUB_FIXED_1;
165 166
}

167 168
static inline grub_fixed_signed_t
grub_signed_to_fixed (signed in)
169
{
170
  return in * GRUB_FIXED_1;
171 172
}

Colin D Bennett's avatar
Colin D Bennett committed
173 174 175
struct grub_gui_component
{
  struct grub_gui_component_ops *ops;
176 177 178 179 180 181 182 183
  signed x;
  grub_fixed_signed_t xfrac;
  signed y;
  grub_fixed_signed_t yfrac;
  signed w;
  grub_fixed_signed_t wfrac;
  signed h;
  grub_fixed_signed_t hfrac;
Colin D Bennett's avatar
Colin D Bennett committed
184 185
};

186 187 188 189 190 191
struct grub_gui_progress
{
  struct grub_gui_component component;
  struct grub_gui_progress_ops *ops;
};

Colin D Bennett's avatar
Colin D Bennett committed
192 193
struct grub_gui_container
{
194
  struct grub_gui_component component;
Colin D Bennett's avatar
Colin D Bennett committed
195 196 197 198 199
  struct grub_gui_container_ops *ops;
};

struct grub_gui_list
{
200
  struct grub_gui_component component;
Colin D Bennett's avatar
Colin D Bennett committed
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
  struct grub_gui_list_ops *ops;
};


/* Interfaces to concrete component classes.  */

grub_gui_container_t grub_gui_canvas_new (void);
grub_gui_container_t grub_gui_vbox_new (void);
grub_gui_container_t grub_gui_hbox_new (void);
grub_gui_component_t grub_gui_label_new (void);
grub_gui_component_t grub_gui_image_new (void);
grub_gui_component_t grub_gui_progress_bar_new (void);
grub_gui_component_t grub_gui_list_new (void);
grub_gui_component_t grub_gui_circular_progress_new (void);

/* Manipulation functions.  */

/* Visit all components with the specified ID.  */
void grub_gui_find_by_id (grub_gui_component_t root,
                          const char *id,
                          grub_gui_component_callback cb,
                          void *userdata);

/* Visit all components.  */
void grub_gui_iterate_recursively (grub_gui_component_t root,
                                   grub_gui_component_callback cb,
                                   void *userdata);

/* Helper functions.  */

static __inline void
grub_gui_save_viewport (grub_video_rect_t *r)
{
  grub_video_get_viewport ((unsigned *) &r->x,
                           (unsigned *) &r->y,
                           (unsigned *) &r->width,
                           (unsigned *) &r->height);
}

static __inline void
grub_gui_restore_viewport (const grub_video_rect_t *r)
{
  grub_video_set_viewport (r->x, r->y, r->width, r->height);
}

/* Set a new viewport relative the the current one, saving the current
   viewport in OLD so it can be later restored.  */
static __inline void
grub_gui_set_viewport (const grub_video_rect_t *r, grub_video_rect_t *old)
{
  grub_gui_save_viewport (old);
  grub_video_set_viewport (old->x + r->x,
                           old->y + r->y,
                           r->width,
                           r->height);
}

258 259 260 261 262 263 264 265 266 267 268 269 270
static inline int
grub_video_have_common_points (const grub_video_rect_t *a,
			       const grub_video_rect_t *b)
{
  if (!((a->x <= b->x && b->x <= a->x + a->width)
	|| (b->x <= a->x && a->x <= b->x + b->width)))
    return 0;
  if (!((a->y <= b->y && b->y <= a->y + a->height)
	|| (b->y <= a->y && a->y <= b->y + b->height)))
    return 0;
  return 1;
}

271 272 273 274 275 276 277 278 279 280 281
static inline int
grub_video_bounds_inside_region (const grub_video_rect_t *b,
                                 const grub_video_rect_t *r)
{
  if (r->x > b->x || r->x + r->width < b->x + b->width)
    return 0;
  if (r->y > b->y || r->y + r->height < b->y + b->height)
    return 0;
  return 1;
}

Colin D Bennett's avatar
Colin D Bennett committed
282
#endif /* ! GRUB_GUI_H */