| 1 #include <assert.h> |
|
| 2 #include <GL/gl.h> |
|
| 3 #include <GL/glu.h> |
|
| 4 #include "cc_interface.h" |
|
| 5 #include "crazychat.h" |
|
| 6 |
|
| 7 #include "Utilities.h" |
|
| 8 #include "QTUtilities.h" |
|
| 9 #include "camdata.h" |
|
| 10 #include "camproc.h" |
|
| 11 #include "util.h" |
|
| 12 #include <unistd.h> |
|
| 13 |
|
| 14 |
|
| 15 #ifdef __APPLE_CC__ |
|
| 16 #include <Carbon/Carbon.h> |
|
| 17 #else |
|
| 18 #include <Carbon.h> |
|
| 19 #endif |
|
| 20 |
|
| 21 /* temporarily including for development testing */ |
|
| 22 #include "cc_gtk_gl.h" |
|
| 23 |
|
| 24 /* hard coding the webcam dimensions: BAD, but we're not probing hardware yet */ |
|
| 25 |
|
| 26 #define WEBCAM_X 644 /* webcam's x dim */ |
|
| 27 #define WEBCAM_Y 480 /* webcam's y dim */ |
|
| 28 |
|
| 29 /* default webcam timer callback delay */ |
|
| 30 #define WEBCAM_CALLBACK_DELAY 40 /* in ms */ |
|
| 31 |
|
| 32 int x_click, y_click; |
|
| 33 int mode_change=0; |
|
| 34 |
|
| 35 struct input_instance input_data; |
|
| 36 |
|
| 37 /* move this to input_instance eventually */ |
|
| 38 /* |
|
| 39 UInt32 colorBuf[WEBCAM_Y][WEBCAM_X]; |
|
| 40 */ |
|
| 41 unsigned int (*colorBuf)[640]; |
|
| 42 int detection_mode=0; |
|
| 43 int draw_mode=0; //0=pixels, 1=face |
|
| 44 int easter_count; |
|
| 45 static void *kickstart(void *data); |
|
| 46 static void *facefind(void *data); |
|
| 47 |
|
| 48 /** |
|
| 49 * Resets the OpenGL viewport stuff on widget reconfiguration (resize, |
|
| 50 * reposition) |
|
| 51 * @param widget widget that got reconfigured |
|
| 52 * @param event the configuration event |
|
| 53 * @param data unused |
|
| 54 * @return TRUE ( i don't know what FALSE would do ) |
|
| 55 */ |
|
| 56 static gboolean config_wrapper(GtkWidget *widget, GdkEventConfigure *event, |
|
| 57 void *data); |
|
| 58 |
|
| 59 /** |
|
| 60 * Debug features test. Draws pixels directly to the frame buffer. |
|
| 61 * @param widget widget that we're drawing |
|
| 62 * @param event the draw event |
|
| 63 * @param data array of pixels |
|
| 64 * @return DUNNO |
|
| 65 */ |
|
| 66 static gboolean mydraw(GtkWidget *widget, GdkEventExpose *event, |
|
| 67 void *data); |
|
| 68 |
|
| 69 /** |
|
| 70 * Periodically querys the webcam for more data. |
|
| 71 * @param instance webcam input instance data |
|
| 72 * @return TRUE to stop other handler, FALSE to continue |
|
| 73 */ |
|
| 74 static gboolean webcam_cb(struct input_instance *instance); |
|
| 75 |
|
| 76 /** |
|
| 77 * Init window code, adding our click callback. |
|
| 78 * @param widget the window we clicked in |
|
| 79 * @param instance webcam input instance data |
|
| 80 */ |
|
| 81 static void init_cb(GtkWidget *widget, struct input_instance *instance); |
|
| 82 |
|
| 83 /** |
|
| 84 * Click callback |
|
| 85 * @param widget the window we clicked in |
|
| 86 * @param event the button click event structure |
|
| 87 * @param instance input instance data |
|
| 88 * @return TRUE to stop other handler, FALSE to continue |
|
| 89 */ |
|
| 90 static gboolean click_cb(GtkWidget *widget, GdkEventButton *event, |
|
| 91 struct input_instance *instance); |
|
| 92 |
|
| 93 /** |
|
| 94 * Button callback |
|
| 95 * @param button the button we clicked on |
|
| 96 * @param instance input instance data |
|
| 97 */ |
|
| 98 static void button_cb(GtkWidget *button, struct input_instance *instance); |
|
| 99 |
|
| 100 /** |
|
| 101 * Destroy callback. Called when the input processing window is destroyed. |
|
| 102 * @param widget the window we clicked in |
|
| 103 * @param cc crazychat global data structure |
|
| 104 */ |
|
| 105 static void destroy_cb(GtkWidget *widget, struct crazychat *cc); |
|
| 106 |
|
| 107 /** |
|
| 108 * Set feature material. |
|
| 109 * @param entry model selector combo box entry |
|
| 110 * @param material pointer to material we're setting |
|
| 111 */ |
|
| 112 static void material_set(GtkWidget *entry, guint8 *material); |
|
| 113 |
|
| 114 struct input_instance *init_input(struct crazychat *cc) |
|
| 115 { |
|
| 116 |
|
| 117 /*pthread_t userinput_t; // should we put this in a nicer wrapper?*/ |
|
| 118 struct draw_info *info; |
|
| 119 struct input_instance *instance; |
|
| 120 info = (struct draw_info*)malloc(sizeof(*info)); |
|
| 121 assert(info); |
|
| 122 memset(info, 0, sizeof(*info)); |
|
| 123 info->timeout = TRUE; |
|
| 124 info->delay_ms = DEFAULT_FRAME_DELAY; |
|
| 125 info->data = &input_data; |
|
| 126 instance = (struct input_instance*)info->data; |
|
| 127 memset(instance, 0, sizeof(*instance)); |
|
| 128 instance->output.features = &instance->face; |
|
| 129 EnterMovies(); |
|
| 130 filter_bank *bank; |
|
| 131 bank = Filter_Initialize(); |
|
| 132 assert(CamProc(instance, bank) == noErr); // change this prototype-> no windows |
|
| 133 instance->timer_id = g_timeout_add(WEBCAM_CALLBACK_DELAY, |
|
| 134 (GSourceFunc)webcam_cb, instance); |
|
| 135 /* THREAD_CREATE(&userinput_t, facefind, instance); // is this being created correctly?*/ |
|
| 136 struct window_box ret; |
|
| 137 cc_new_gl_window(init_cb, config_wrapper, mydraw, |
|
| 138 info, &ret); |
|
| 139 instance->widget = ret.window; |
|
| 140 gtk_window_set_title(GTK_WINDOW(ret.window), "Local User"); |
|
| 141 instance->box = ret.vbox; |
|
| 142 GtkWidget *label = gtk_label_new("Click your face"); |
|
| 143 instance->label = label; |
|
| 144 gtk_box_pack_start(GTK_BOX(ret.vbox), label, FALSE, FALSE, 0); |
|
| 145 gtk_box_reorder_child(GTK_BOX(ret.vbox), label, 0); |
|
| 146 gtk_widget_show(label); |
|
| 147 GtkWidget *button = gtk_button_new_with_label("Confirm"); |
|
| 148 gtk_box_pack_start(GTK_BOX(ret.vbox), button, FALSE, FALSE, 0); |
|
| 149 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(button_cb), |
|
| 150 instance); |
|
| 151 instance->button = button; |
|
| 152 gtk_widget_show(button); |
|
| 153 |
|
| 154 GtkWidget *hbox = gtk_hbox_new(TRUE, 0); |
|
| 155 gtk_box_pack_start(GTK_BOX(ret.vbox), hbox, FALSE, FALSE, 0); |
|
| 156 gtk_widget_show(hbox); |
|
| 157 |
|
| 158 GtkWidget *model_combo = gtk_combo_new(); |
|
| 159 GList *glist = NULL; |
|
| 160 |
|
| 161 glist = g_list_append(glist, "Dog"); |
|
| 162 glist = g_list_append(glist, "Shark"); |
|
| 163 gtk_combo_set_popdown_strings(GTK_COMBO(model_combo), glist); |
|
| 164 g_list_free(glist); |
|
| 165 //gtk_combo_box_set_column_span_column(GTK_COMBO(model_combo), |
|
| 166 // 10); |
|
| 167 gtk_box_pack_start(GTK_BOX(hbox), model_combo, TRUE, TRUE, 0); |
|
| 168 gtk_widget_show(model_combo); |
|
| 169 instance->model = model_combo; |
|
| 170 |
|
| 171 GtkWidget *head_material_combo = gtk_combo_new(); |
|
| 172 glist = NULL; |
|
| 173 glist = g_list_append(glist, "Red"); |
|
| 174 glist = g_list_append(glist, "Dark Brown"); |
|
| 175 glist = g_list_append(glist, "Light Brown"); |
|
| 176 glist = g_list_append(glist, "White"); |
|
| 177 glist = g_list_append(glist, "Green"); |
|
| 178 glist = g_list_append(glist, "Black"); |
|
| 179 gtk_combo_set_popdown_strings(GTK_COMBO(head_material_combo), glist); |
|
| 180 g_list_free(glist); |
|
| 181 //gtk_combo_box_set_column_span_column(GTK_COMBO(head_material_combo), |
|
| 182 // 10); |
|
| 183 gtk_box_pack_start(GTK_BOX(hbox), head_material_combo, TRUE, TRUE, 0); |
|
| 184 gtk_widget_show(head_material_combo); |
|
| 185 instance->head = head_material_combo; |
|
| 186 |
|
| 187 GtkWidget *appendage_material_combo = gtk_combo_new(); |
|
| 188 glist = NULL; |
|
| 189 glist = g_list_append(glist, "Red"); |
|
| 190 glist = g_list_append(glist, "Dark Brown"); |
|
| 191 glist = g_list_append(glist, "Light Brown"); |
|
| 192 glist = g_list_append(glist, "White"); |
|
| 193 glist = g_list_append(glist, "Green"); |
|
| 194 glist = g_list_append(glist, "Black"); |
|
| 195 gtk_combo_set_popdown_strings(GTK_COMBO(appendage_material_combo), |
|
| 196 glist); |
|
| 197 g_list_free(glist); |
|
| 198 //gtk_combo_box_set_column_span_column(GTK_COMBO(appendage_material_combo), 10); |
|
| 199 gtk_box_pack_start(GTK_BOX(hbox), appendage_material_combo, |
|
| 200 TRUE, TRUE, 0); |
|
| 201 gtk_widget_show(appendage_material_combo); |
|
| 202 instance->appendage = appendage_material_combo; |
|
| 203 |
|
| 204 hbox = gtk_hbox_new(TRUE, 0); |
|
| 205 gtk_box_pack_start(GTK_BOX(ret.vbox), hbox, FALSE, FALSE, 0); |
|
| 206 gtk_widget_show(hbox); |
|
| 207 |
|
| 208 GtkWidget *lids_material_combo = gtk_combo_new(); |
|
| 209 glist = NULL; |
|
| 210 glist = g_list_append(glist, "Red"); |
|
| 211 glist = g_list_append(glist, "Dark Brown"); |
|
| 212 glist = g_list_append(glist, "Light Brown"); |
|
| 213 glist = g_list_append(glist, "White"); |
|
| 214 glist = g_list_append(glist, "Green"); |
|
| 215 glist = g_list_append(glist, "Black"); |
|
| 216 gtk_combo_set_popdown_strings(GTK_COMBO(lids_material_combo), glist); |
|
| 217 g_list_free(glist); |
|
| 218 //gtk_combo_box_set_column_span_column(GTK_COMBO(lids_material_combo), 10); |
|
| 219 gtk_box_pack_start(GTK_BOX(hbox), lids_material_combo, TRUE, TRUE, 0); |
|
| 220 gtk_widget_show(lids_material_combo); |
|
| 221 instance->lid = lids_material_combo; |
|
| 222 |
|
| 223 GtkWidget *left_iris_material_combo = gtk_combo_new(); |
|
| 224 glist = NULL; |
|
| 225 glist = g_list_append(glist, "Red"); |
|
| 226 glist = g_list_append(glist, "Dark Brown"); |
|
| 227 glist = g_list_append(glist, "Light Brown"); |
|
| 228 glist = g_list_append(glist, "White"); |
|
| 229 glist = g_list_append(glist, "Green"); |
|
| 230 glist = g_list_append(glist, "Black"); |
|
| 231 gtk_combo_set_popdown_strings(GTK_COMBO(left_iris_material_combo), |
|
| 232 glist); |
|
| 233 g_list_free(glist); |
|
| 234 //gtk_combo_box_set_column_span_column(GTK_COMBO(left_iris_material_combo), 10); |
|
| 235 gtk_box_pack_start(GTK_BOX(hbox), left_iris_material_combo, |
|
| 236 TRUE, TRUE, 0); |
|
| 237 gtk_widget_show(left_iris_material_combo); |
|
| 238 instance->left_iris = left_iris_material_combo; |
|
| 239 |
|
| 240 /* |
|
| 241 GtkWidget *right_iris_material_combo = gtk_combo_new(); |
|
| 242 glist = NULL; |
|
| 243 glist = g_list_append(glist, "Red"); |
|
| 244 glist = g_list_append(glist, "Dark Brown"); |
|
| 245 glist = g_list_append(glist, "Light Brown"); |
|
| 246 glist = g_list_append(glist, "White"); |
|
| 247 glist = g_list_append(glist, "Green"); |
|
| 248 glist = g_list_append(glist, "Black"); |
|
| 249 gtk_combo_set_popdown_strings(GTK_COMBO(right_iris_material_combo), |
|
| 250 glist); |
|
| 251 g_list_free(glist); |
|
| 252 //gtk_combo_box_set_column_span_column(GTK_COMBO(right_iris_material_combo), 10); |
|
| 253 gtk_box_pack_start(GTK_BOX(hbox), right_iris_material_combo, |
|
| 254 TRUE, TRUE, 0); |
|
| 255 gtk_widget_show(right_iris_material_combo); |
|
| 256 instance->right_iris = right_iris_material_combo; |
|
| 257 */ |
|
| 258 gtk_widget_add_events(ret.draw_area, GDK_BUTTON_PRESS_MASK); |
|
| 259 g_signal_connect(G_OBJECT(ret.draw_area), "button_press_event", |
|
| 260 G_CALLBACK(click_cb), instance); |
|
| 261 g_signal_connect(G_OBJECT(ret.window), "destroy", |
|
| 262 G_CALLBACK(destroy_cb), cc); |
|
| 263 // gtk_widget_set_size_request(window, 640, 480); |
|
| 264 gtk_window_set_default_size(GTK_WINDOW(ret.window),320,300); |
|
| 265 |
|
| 266 |
|
| 267 GdkGeometry hints; |
|
| 268 hints.max_width = 640; |
|
| 269 hints.max_height = 480; |
|
| 270 |
|
| 271 gtk_window_set_geometry_hints (GTK_WINDOW(ret.window), |
|
| 272 NULL, |
|
| 273 &hints, |
|
| 274 GDK_HINT_MAX_SIZE); |
|
| 275 gtk_widget_show(ret.window); |
|
| 276 return instance; |
|
| 277 } |
|
| 278 |
|
| 279 static gboolean webcam_cb(struct input_instance *instance) |
|
| 280 { |
|
| 281 assert(instance); |
|
| 282 QueryCam(); |
|
| 283 return TRUE; |
|
| 284 } |
|
| 285 |
|
| 286 static void *facefind(void *data) |
|
| 287 { |
|
| 288 fprintf(stderr, "waiting\n"); |
|
| 289 getchar(); |
|
| 290 fprintf(stderr,"got you"); |
|
| 291 detection_mode=1; |
|
| 292 return; |
|
| 293 } |
|
| 294 |
|
| 295 void destroy_input(struct input_instance *instance) |
|
| 296 { |
|
| 297 extern filter_bank *bank; |
|
| 298 assert(instance); |
|
| 299 Filter_Destroy(bank); |
|
| 300 g_source_remove(instance->timer_id); |
|
| 301 Die(); |
|
| 302 ExitMovies(); |
|
| 303 } |
|
| 304 |
|
| 305 static gboolean config_wrapper(GtkWidget *widget, GdkEventConfigure *event, |
|
| 306 void *data) |
|
| 307 { |
|
| 308 |
|
| 309 |
|
| 310 GdkGLContext *glcontext = gtk_widget_get_gl_context(widget); |
|
| 311 GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(widget); |
|
| 312 |
|
| 313 GLfloat w = widget->allocation.width; |
|
| 314 GLfloat h = widget->allocation.height; |
|
| 315 GLfloat aspect; |
|
| 316 |
|
| 317 // fprintf(stderr,"Homicide %f %f %d\n", w,h,draw_mode); |
|
| 318 |
|
| 319 if (draw_mode==1){ |
|
| 320 // fprintf(stderr, "Bad place to be- actually not so bad\n"); |
|
| 321 return configure(widget, event, data); |
|
| 322 } |
|
| 323 |
|
| 324 /*** OpenGL BEGIN ***/ |
|
| 325 if (!gdk_gl_drawable_gl_begin(gldrawable, glcontext)) |
|
| 326 return FALSE; |
|
| 327 |
|
| 328 |
|
| 329 /* Undo all of the Model lighting here*/ |
|
| 330 |
|
| 331 // glDisable(GL_LIGHTING); |
|
| 332 glDisable(GL_DEPTH_TEST); |
|
| 333 // glDisable(GL_CULL_FACE); |
|
| 334 // glDisable(GL_LIGHT0); |
|
| 335 // glClearColor(1.0f, 1.0f, 1.0f, 1.0f); |
|
| 336 /* */ |
|
| 337 |
|
| 338 |
|
| 339 glViewport(0,-(h/14),w*2,h*2); |
|
| 340 |
|
| 341 glMatrixMode(GL_PROJECTION); |
|
| 342 glLoadIdentity(); |
|
| 343 gluOrtho2D(0,0,640,640); |
|
| 344 glRasterPos2i(0,0); |
|
| 345 glPixelZoom(-w/(1*640),(-h/(1*480))); |
|
| 346 glMatrixMode(GL_MODELVIEW); |
|
| 347 glLoadIdentity(); |
|
| 348 |
|
| 349 |
|
| 350 |
|
| 351 |
|
| 352 gdk_gl_drawable_gl_end(gldrawable); |
|
| 353 /*** OpenGL END ***/ |
|
| 354 |
|
| 355 return TRUE; |
|
| 356 } |
|
| 357 |
|
| 358 static gboolean mydraw(GtkWidget *widget, GdkEventExpose *event, |
|
| 359 void *data) |
|
| 360 { |
|
| 361 GdkGLContext *glcontext = gtk_widget_get_gl_context (widget); |
|
| 362 GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget); |
|
| 363 struct input_instance *instance = (struct input_instance*)data; |
|
| 364 unsigned int *boo; |
|
| 365 struct cc_features *features = &instance->face; |
|
| 366 |
|
| 367 char *string = gtk_entry_get_text(GTK_COMBO(instance->model)->entry); |
|
| 368 if (!strcmp(string, "Dog")) { |
|
| 369 features->kind = 0; |
|
| 370 } else if (!strcmp(string, "Shark")) { |
|
| 371 features->kind = 1; |
|
| 372 } |
|
| 373 |
|
| 374 material_set(GTK_ENTRY(GTK_COMBO(instance->head)->entry), |
|
| 375 &features->head_color); |
|
| 376 material_set(GTK_ENTRY(GTK_COMBO(instance->appendage)->entry), |
|
| 377 &features->appendage_color); |
|
| 378 material_set(GTK_ENTRY(GTK_COMBO(instance->lid)->entry), |
|
| 379 &features->lid_color); |
|
| 380 material_set(GTK_ENTRY(GTK_COMBO(instance->left_iris)->entry), |
|
| 381 &features->left_iris_color); |
|
| 382 material_set(GTK_ENTRY(GTK_COMBO(instance->left_iris)->entry), |
|
| 383 &features->right_iris_color); |
|
| 384 |
|
| 385 if (easter_count>0) { |
|
| 386 easter_count--; |
|
| 387 } else { |
|
| 388 instance->face.mode = 0; |
|
| 389 } |
|
| 390 |
|
| 391 if (mode_change>0){ |
|
| 392 mode_change--; |
|
| 393 config_wrapper(widget, event, data); |
|
| 394 } |
|
| 395 |
|
| 396 if (draw_mode==1){ |
|
| 397 instance->output.my_output=LOCAL; |
|
| 398 return draw(widget,event,&instance->output); |
|
| 399 } |
|
| 400 |
|
| 401 |
|
| 402 boo = (unsigned int*)colorBuf; |
|
| 403 |
|
| 404 assert(instance); |
|
| 405 assert(gtk_widget_is_gl_capable(widget)); |
|
| 406 |
|
| 407 /*** OpenGL BEGIN ***/ |
|
| 408 |
|
| 409 if (!gdk_gl_drawable_gl_begin(gldrawable, glcontext)) { |
|
| 410 // fprintf(stderr, "We're fucked this time.\n"); |
|
| 411 return FALSE; |
|
| 412 } |
|
| 413 |
|
| 414 glClearColor(0.0, 0.0, 0.0, 0.0); |
|
| 415 glClear(GL_COLOR_BUFFER_BIT); |
|
| 416 |
|
| 417 glDrawPixels(WEBCAM_X, WEBCAM_Y-70, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, boo); |
|
| 418 |
|
| 419 if (gdk_gl_drawable_is_double_buffered(gldrawable)) |
|
| 420 gdk_gl_drawable_swap_buffers(gldrawable); |
|
| 421 else |
|
| 422 glFlush(); |
|
| 423 |
|
| 424 gdk_gl_drawable_gl_end(gldrawable); |
|
| 425 |
|
| 426 /*** OpenGL END ***/ |
|
| 427 |
|
| 428 return TRUE; |
|
| 429 } |
|
| 430 |
|
| 431 static void init_cb(GtkWidget *widget, struct input_instance *instance) |
|
| 432 { |
|
| 433 // setupDrawlists(LOCAL); |
|
| 434 // fprintf(stderr,"init_cb\n"); |
|
| 435 } |
|
| 436 |
|
| 437 static gboolean click_cb(GtkWidget *widget, GdkEventButton *event, |
|
| 438 struct input_instance *instance) |
|
| 439 { |
|
| 440 |
|
| 441 GLfloat w = widget->allocation.width; |
|
| 442 GLfloat h = widget->allocation.height; |
|
| 443 GLfloat aspect; |
|
| 444 |
|
| 445 if (draw_mode==1) { |
|
| 446 switch (event->button) { |
|
| 447 case 1: |
|
| 448 Debug("F U!\n"); |
|
| 449 instance->face.mode = 1; |
|
| 450 easter_count = 5; |
|
| 451 break; |
|
| 452 case 3: |
|
| 453 Debug("should never get here\n"); |
|
| 454 instance->face.mode = 2; |
|
| 455 easter_count = 5; |
|
| 456 break; |
|
| 457 default: |
|
| 458 instance->face.mode = 0; |
|
| 459 break; |
|
| 460 } |
|
| 461 return FALSE; |
|
| 462 } |
|
| 463 |
|
| 464 x_click=(event->x*(640/w)); |
|
| 465 x_click=640-x_click; |
|
| 466 y_click=(event->y-(h/14))*(480/(h-(h/14))); |
|
| 467 detection_mode=1; |
|
| 468 //Debug("@@@ x:%d y:%d\n", x_click, y_click); |
|
| 469 |
|
| 470 gtk_label_set_text(instance->label, |
|
| 471 "Put on the box, then press confirm."); |
|
| 472 if (x_click <= 10) x_click=10; |
|
| 473 if (x_click >= WEBCAM_X-10) x_click=WEBCAM_X-60; |
|
| 474 if (y_click <= 10) y_click=10; |
|
| 475 if (y_click >= WEBCAM_Y-10) y_click=WEBCAM_Y-60; |
|
| 476 |
|
| 477 return FALSE; |
|
| 478 } |
|
| 479 |
|
| 480 static void button_cb(GtkWidget *button, struct input_instance *instance) |
|
| 481 { |
|
| 482 if (!draw_mode) { /* transition to face mode */ |
|
| 483 if (detection_mode == 0) { /* ignore confirm if no calibrate */ |
|
| 484 return; |
|
| 485 } |
|
| 486 setupLighting(instance->widget); |
|
| 487 mode_change = 1; |
|
| 488 gtk_button_set_label(GTK_BUTTON(button), "Calibrate"); |
|
| 489 gtk_label_set_label(instance->label, |
|
| 490 "If things get too crazy, click Calibrate."); |
|
| 491 } else { /* transition to calibration mode */ |
|
| 492 gtk_label_set_label(instance->label, "Click your face"); |
|
| 493 mode_change = 2; |
|
| 494 gtk_button_set_label(GTK_BUTTON(button), "Confirm"); |
|
| 495 } |
|
| 496 draw_mode = !draw_mode; |
|
| 497 } |
|
| 498 |
|
| 499 static void destroy_cb(GtkWidget *widget, struct crazychat *cc) |
|
| 500 { |
|
| 501 cc->features_state = 0; |
|
| 502 destroy_input(cc->input_data); |
|
| 503 cc->input_data = NULL; |
|
| 504 } |
|
| 505 |
|
| 506 static void material_set(GtkWidget *entry, guint8 *material) |
|
| 507 { |
|
| 508 char *string = gtk_entry_get_text(GTK_ENTRY(entry)); |
|
| 509 if (!strcmp(string, "Red")) { |
|
| 510 *material = 0; |
|
| 511 } else if (!strcmp(string, "Dark Brown")) { |
|
| 512 *material = 1; |
|
| 513 } else if (!strcmp(string, "Light Brown")) { |
|
| 514 *material = 2; |
|
| 515 } else if (!strcmp(string, "White")) { |
|
| 516 *material = 3; |
|
| 517 } else if (!strcmp(string, "Green")) { |
|
| 518 *material = 4; |
|
| 519 } else if (!strcmp(string, "Black")) { |
|
| 520 *material = 5; |
|
| 521 } |
|
| 522 } |
|