| 1 |
#include <gtk/gtk.h> |
| 2 |
#include <gdk-pixbuf/gdk-pixbuf.h> |
| 3 |
#include <ccss/ccss.h> |
| 4 |
|
| 5 |
GtkWidget *window, *container, *theme, *css_scroll, *css; |
| 6 |
GdkPixbuf *pixbuf; |
| 7 |
|
| 8 |
ccss_stylesheet_t *stylesheet; |
| 9 |
|
| 10 |
/* ================================================================ */ |
| 11 |
/* Our little hierarchy */ |
| 12 |
typedef enum _CopperClasses { |
| 13 |
CC_FRAME, |
| 14 |
CC_CORNER, |
| 15 |
CC_TOPLEFT, |
| 16 |
CC_TOPRIGHT, |
| 17 |
CC_BOTTOMLEFT, |
| 18 |
CC_BOTTOMRIGHT, |
| 19 |
CC_EDGE, |
| 20 |
CC_TOP, |
| 21 |
CC_RIGHT, |
| 22 |
CC_BOTTOM, |
| 23 |
CC_LEFT, |
| 24 |
CC_TITLEBAR, |
| 25 |
CC_BUTTON, |
| 26 |
CC_LEFTBUTTON, |
| 27 |
CC_MENU, |
| 28 |
CC_RIGHTBUTTON, |
| 29 |
CC_MINIMIZE, |
| 30 |
CC_MAXIMIZE, |
| 31 |
CC_CLOSE, |
| 32 |
CC_TITLE, |
| 33 |
CC_LAST |
| 34 |
} CopperClasses; |
| 35 |
|
| 36 |
char *names[] = |
| 37 |
{ |
| 38 |
"frame", |
| 39 |
"corner", "topleft", "topright", "bottomleft", "bottomright", |
| 40 |
"edge", "top", "right", "bottom", "left", |
| 41 |
"titlebar", |
| 42 |
"button", "leftbutton", "menu", |
| 43 |
"rightbutton", "minimize", "maximize", "close", |
| 44 |
"title", |
| 45 |
"last" |
| 46 |
}; |
| 47 |
|
| 48 |
CopperClasses parents[] = |
| 49 |
{ |
| 50 |
CC_LAST, |
| 51 |
CC_FRAME, CC_CORNER, CC_CORNER, CC_CORNER, CC_CORNER, |
| 52 |
CC_FRAME, CC_EDGE, CC_EDGE, CC_EDGE, CC_EDGE, |
| 53 |
CC_FRAME, |
| 54 |
CC_TITLEBAR, CC_BUTTON, CC_LEFTBUTTON, |
| 55 |
CC_BUTTON, CC_RIGHTBUTTON, CC_RIGHTBUTTON, CC_RIGHTBUTTON, |
| 56 |
CC_TITLEBAR, |
| 57 |
CC_LAST |
| 58 |
}; |
| 59 |
|
| 60 |
typedef struct |
| 61 |
{ |
| 62 |
ccss_node_t basic; |
| 63 |
CopperClasses copper_class; |
| 64 |
} CopperNode; |
| 65 |
|
| 66 |
CopperNode copper_nodes[CC_LAST]; |
| 67 |
|
| 68 |
static char const* |
| 69 |
get_type (ccss_node_t const *self) |
| 70 |
{ |
| 71 |
g_warning ("It's %s", self->type_name); |
| 72 |
return self->type_name; |
| 73 |
} |
| 74 |
|
| 75 |
static ptrdiff_t |
| 76 |
get_instance (ccss_node_t const *self) |
| 77 |
{ |
| 78 |
return self->instance; |
| 79 |
} |
| 80 |
|
| 81 |
static char const* |
| 82 |
get_style (ccss_node_t const *self) { |
| 83 |
return self->inline_style; |
| 84 |
} |
| 85 |
|
| 86 |
static ccss_node_t* |
| 87 |
get_container (ccss_node_t const *self) |
| 88 |
{ |
| 89 |
CopperClasses candidate = parents[((CopperNode*)self)->copper_class]; |
| 90 |
|
| 91 |
if (candidate==CC_LAST) |
| 92 |
return NULL; |
| 93 |
else |
| 94 |
/* or should we allocate a new one? */ |
| 95 |
return (ccss_node_t*) &(copper_nodes[candidate]); |
| 96 |
} |
| 97 |
|
| 98 |
static ccss_node_class_t copper_node_class = { |
| 99 |
.get_type = (ccss_node_get_type_f) get_type, |
| 100 |
.get_instance = (ccss_node_get_instance_f) get_instance, |
| 101 |
.get_style = (ccss_node_get_style_f) get_style, |
| 102 |
.get_container = (ccss_node_get_container_f) get_container |
| 103 |
}; |
| 104 |
|
| 105 |
static void |
| 106 |
initialise_classes (void) |
| 107 |
{ |
| 108 |
int i; |
| 109 |
|
| 110 |
for (i=0; i<CC_LAST; i++) |
| 111 |
{ |
| 112 |
ccss_node_init ((ccss_node_t*) &copper_nodes[i], &copper_node_class); |
| 113 |
copper_nodes[i].basic.type_name = names[i]; |
| 114 |
copper_nodes[i].basic.instance = 0; |
| 115 |
copper_nodes[i].basic.inline_style = NULL; |
| 116 |
copper_nodes[i].copper_class = i; |
| 117 |
} |
| 118 |
} |
| 119 |
|
| 120 |
/* ================================================================ */ |
| 121 |
|
| 122 |
static gint |
| 123 |
expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer data) |
| 124 |
{ |
| 125 |
/* |
| 126 |
int w, h; |
| 127 |
|
| 128 |
int titlebar_width=0, titlebar_height=0; |
| 129 |
|
| 130 |
ccss_style_t *style = ccss_stylesheet_query (stylesheet, |
| 131 |
(ccss_node_t*) &copper_nodes[CC_FRAME]); |
| 132 |
cairo_t *cr = gdk_cairo_create (widget->window); |
| 133 |
gtk_window_get_size (GTK_WINDOW (window), &w, &h); |
| 134 |
|
| 135 |
g_warning ("Yes.\n"); |
| 136 |
ccss_cairo_style_draw_rectangle (style, cr, 0, 0, 100, 100); |
| 137 |
|
| 138 |
cairo_destroy (cr); |
| 139 |
|
| 140 |
#if 0 |
| 141 |
gtk_layout_move (GTK_LAYOUT (container), css_scroll, 50, 50); |
| 142 |
gtk_widget_set_size_request (css_scroll, |
| 143 |
w-100, |
| 144 |
h-100); |
| 145 |
#endif |
| 146 |
|
| 147 |
*/ |
| 148 |
return TRUE; |
| 149 |
} |
| 150 |
|
| 151 |
static char * |
| 152 |
url (GSList const *args, |
| 153 |
void *user_data) |
| 154 |
{ |
| 155 |
char *cwd; |
| 156 |
char *path; |
| 157 |
char *uri; |
| 158 |
char *filename = NULL; |
| 159 |
|
| 160 |
g_return_val_if_fail (args && args->data, NULL); |
| 161 |
filename = (char*) args->data; |
| 162 |
|
| 163 |
if (strcmp (filename, "metacity:icon.png")==0) |
| 164 |
{ |
| 165 |
/* this is magic */ |
| 166 |
filename = "gtk-edit.png"; |
| 167 |
} |
| 168 |
|
| 169 |
cwd = g_get_current_dir (); |
| 170 |
path = g_build_filename (cwd, filename, NULL); |
| 171 |
g_free (cwd), cwd = NULL; |
| 172 |
uri = g_strdup_printf ("file://%s", path); |
| 173 |
g_free (path), path = NULL; |
| 174 |
|
| 175 |
return uri; |
| 176 |
} |
| 177 |
|
| 178 |
static char * |
| 179 |
named (GSList const *args, void *user_data) |
| 180 |
{ |
| 181 |
char *name = NULL; |
| 182 |
|
| 183 |
if (!name) |
| 184 |
/* fall back to black */ |
| 185 |
return g_strdup("#00000000"); |
| 186 |
|
| 187 |
name = args->data; |
| 188 |
g_warning ("Looking up named colour %s", name); |
| 189 |
|
| 190 |
/* stub: magenta for everything */ |
| 191 |
return g_strdup("#FF00FFFF"); |
| 192 |
} |
| 193 |
|
| 194 |
static ccss_function_t const _functions[] = |
| 195 |
{ |
| 196 |
{ "url", url, NULL }, |
| 197 |
{ "named", named, NULL }, |
| 198 |
{ NULL } |
| 199 |
}; |
| 200 |
|
| 201 |
int |
| 202 |
main (int argc, char **argv) |
| 203 |
{ |
| 204 |
ccss_grammar_t *grammar; |
| 205 |
ccss_style_t *style; |
| 206 |
GtkTextBuffer *buffer; |
| 207 |
GtkTextTagTable *tag_table; |
| 208 |
char *contents; |
| 209 |
GError *error = NULL; |
| 210 |
|
| 211 |
gtk_init (&argc, &argv); |
| 212 |
|
| 213 |
initialise_classes (); |
| 214 |
|
| 215 |
grammar = ccss_grammar_create_css (); |
| 216 |
ccss_grammar_add_functions (grammar, _functions); |
| 217 |
stylesheet = ccss_grammar_create_stylesheet_from_file (grammar, |
| 218 |
"colours.css", |
| 219 |
NULL); |
| 220 |
|
| 221 |
g_file_get_contents ("exampleXX.css", &contents, NULL, NULL); |
| 222 |
|
| 223 |
window = gtk_window_new (GTK_WINDOW_TOPLEVEL); |
| 224 |
gtk_window_set_title (GTK_WINDOW (window), "Copper"); |
| 225 |
gtk_widget_set_app_paintable (window, TRUE); |
| 226 |
/* |
| 227 |
container = gtk_layout_new (NULL, NULL); |
| 228 |
gtk_widget_set_app_paintable (container, TRUE); |
| 229 |
|
| 230 |
tag_table = gtk_text_tag_table_new (); |
| 231 |
buffer = gtk_text_buffer_new (tag_table); |
| 232 |
|
| 233 |
gtk_text_buffer_set_text (buffer, contents, -1); |
| 234 |
|
| 235 |
css = gtk_text_view_new_with_buffer (buffer); |
| 236 |
|
| 237 |
css_scroll = gtk_scrolled_window_new (NULL, NULL); |
| 238 |
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (css_scroll), |
| 239 |
GTK_POLICY_ALWAYS, GTK_POLICY_ALWAYS); |
| 240 |
gtk_container_add (GTK_CONTAINER (css_scroll), css); |
| 241 |
|
| 242 |
gtk_layout_put (GTK_LAYOUT (container), css_scroll, 150, 150); |
| 243 |
|
| 244 |
gtk_container_add (GTK_CONTAINER (window), container); |
| 245 |
*/ |
| 246 |
gtk_widget_show_all (window); |
| 247 |
|
| 248 |
g_signal_connect (G_OBJECT (container), "expose_event", G_CALLBACK (expose_event), NULL); |
| 249 |
g_signal_connect (G_OBJECT (window), "delete_event", G_CALLBACK (gtk_main_quit), NULL); |
| 250 |
|
| 251 |
gtk_main (); |
| 252 |
|
| 253 |
return 0; |
| 254 |
} |