OpenCores
URL https://opencores.org/ocsvn/connect-6/connect-6/trunk

Subversion Repositories connect-6

[/] [connect-6/] [trunk/] [CONNECTK/] [connectk-2.0/] [src/] [draw.c] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 sumanta.ch
 
2
/*
3
 
4
connectk -- a program to play the connect-k family of games
5
Copyright (C) 2007 Michael Levin
6
 
7
This program is free software; you can redistribute it and/or
8
modify it under the terms of the GNU General Public License
9
as published by the Free Software Foundation; either version 2
10
of the License, or (at your option) any later version.
11
 
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20
 
21
*/
22
 
23
#include "config.h"
24
#include <gtk/gtk.h>
25
#include <cairo.h>
26
#ifndef NO_CAIRO_SVG
27
#include <cairo-svg.h>
28
#endif
29
#include <string.h>
30
#include <math.h>
31
#include "shared.h"
32
#include "connectk.h"
33
 
34
/*
35
 *      Rendering
36
 */
37
 
38
typedef unsigned int PCOORD;
39
 
40
static GtkWidget *drawing_area = NULL;
41
static GdkPixmap *pixmap = NULL;
42
static cairo_t *cairo = NULL;
43
static PCOORD board_xo = 0, board_yo = 0;
44
static BCOORD hover_x, hover_y;
45
static int tile_size = 1;
46
static gboolean hover = FALSE, playable = TRUE, do_not_dirty = FALSE;
47
static AIMoves *marks = NULL;
48
static double marks_min, marks_max;
49
 
50
// Convert from pixel to board coordinates
51
static gboolean pcoord_to_bcoord(PCOORD px, PCOORD py, BCOORD *bx, BCOORD *by)
52
{
53
        if (px < board_xo + tile_size || py < board_yo + tile_size ||
54
            px >= drawing_area->allocation.width - board_xo - tile_size ||
55
            py >= drawing_area->allocation.height - board_yo - tile_size)
56
                return FALSE;
57
        *bx = (px - board_xo) / tile_size - 1;
58
        *by = (py - board_yo) / tile_size - 1;
59
        return TRUE;
60
}
61
 
62
// Convert from board to pixel coordinates
63
static void bcoords_to_pcoords(BCOORD bx, BCOORD by, PCOORD *px, PCOORD *py)
64
{
65
        *px = (bx + 1) * tile_size + board_xo;
66
        *py = (by + 1) * tile_size + board_yo;
67
}
68
 
69
/* Render a colored piece on the pixmap */
70
static void draw_piece(BCOORD bx, BCOORD by, PIECE type, double a)
71
{
72
        PCOORD px, py;
73
 
74
        bcoords_to_pcoords(bx, by, &px, &py);
75
 
76
        /* Render a black and white piece on the pixmap */
77
        if (opt_grayscale && type != PIECE_NONE) {
78
                cairo_arc(cairo, px + tile_size / 2, py + tile_size / 2,
79
                          tile_size / 2 - 2, 0., G_PI * 2.);
80
                if (type == PIECE_BLACK)
81
                        cairo_set_source_rgba(cairo, 0, 0, 0, a);
82
                else
83
                        cairo_set_source_rgba(cairo, 1, 1, 1, a);
84
                cairo_fill_preserve(cairo);
85
                cairo_set_source_rgba(cairo, 0, 0, 0, a);
86
                cairo_set_line_width(cairo, 2.);
87
                cairo_stroke(cairo);
88
        }
89
 
90
        /* Render a colored piece */
91
        else if (type != PIECE_NONE) {
92
                double r, g, b, hr, hg, hb;
93
 
94
                if (type == PIECE_WHITE) {
95
                        r = 0.90;
96
                        g = 0.85;
97
                        b = 0.65;
98
                } else if(type == PIECE_BLACK) {
99
                        r = 0.15;
100
                        g = 0.15;
101
                        b = 0.20;
102
                } else
103
                        return;
104
                hr = r * 2;
105
                hg = g * 2;
106
                hb = b * 2;
107
                if (hr > 1.) hr = 1.;
108
                if (hg > 1.) hg = 1.;
109
                if (hb > 1.) hb = 1.;
110
 
111
                // Draw stone body
112
                cairo_arc(cairo, px + tile_size / 2, py + tile_size / 2,
113
                          tile_size / 2 - 2, 0., G_PI * 2.);
114
                cairo_set_source_rgba(cairo, r, g, b, a);
115
                cairo_fill_preserve(cairo);
116
                cairo_set_source_rgba(cairo, r / 2, g / 2, b / 2, a);
117
                cairo_stroke(cairo);
118
 
119
                // Draw stone highlight
120
                if (a >= 1.) {
121
                        cairo_arc(cairo, px + tile_size / 3, py + tile_size / 3,
122
                                  tile_size / 6, 0., G_PI * 2.);
123
                        cairo_set_source_rgba(cairo, hr, hg, hb, a);
124
                        cairo_fill(cairo);
125
                }
126
        }
127
        if (!do_not_dirty)
128
                gtk_widget_queue_draw_area(drawing_area, px, py, tile_size,
129
                                           tile_size);
130
}
131
 
132
// Render a marker if (x, y) is a marker tile
133
static void draw_marker(BCOORD x, BCOORD y)
134
{
135
        PCOORD px, py;
136
 
137
        if (piece_at(board, x, y) != PIECE_NONE)
138
                return;
139
        if ((board_size > 9) &&
140
            (x == 3 || x == board_size - 4 ||
141
             ((board_size & 1) && x == board_size / 2)) &&
142
            (y == 3 || y == board_size - 4 ||
143
             ((board_size & 1) && y == board_size / 2))) {
144
                bcoords_to_pcoords(x, y, &px, &py);
145
                cairo_set_source_rgba(cairo, 0., 0., 0., 1.);
146
                cairo_arc(cairo, px + tile_size / 2, py + tile_size / 2,
147
                          tile_size / 6, 0., G_PI * 2.);
148
                cairo_fill(cairo);
149
        }
150
}
151
 
152
void clear_last_moves(void)
153
/* Clear last move markers */
154
{
155
        Board *b = board;
156
        int last_moves = place_p - b->moves_left;
157
 
158
        if (!last_moves)
159
                last_moves = place_p;
160
        while (b->parent && last_moves--) {
161
                b = b->parent;
162
                draw_tile(b->move_x, b->move_y);
163
        }
164
}
165
 
166
void draw_last_moves(void)
167
/* Draw markers on the last p moves in this turn or the whole last turn */
168
{
169
        Board *b = board;
170
        int last_moves = place_p - b->moves_left;
171
 
172
        if (b->won)
173
                return;
174
        if (!last_moves)
175
                last_moves = place_p;
176
        cairo_save(cairo);
177
        while (b->parent && last_moves--) {
178
                PCOORD px, py;
179
 
180
                b = b->parent;
181
                bcoords_to_pcoords(b->move_x, b->move_y, &px, &py);
182
                if (opt_grayscale)
183
                        cairo_set_source_rgba(cairo, 1.f, 1.f, 1., 1.);
184
                else
185
                        cairo_set_source_rgba(cairo, 1.f, 1.f, 0., 1.);
186
                cairo_rectangle(cairo, px + tile_size / 3., py + tile_size / 3.,
187
                                tile_size / 3., tile_size / 3.);
188
                cairo_fill_preserve(cairo);
189
                cairo_set_source_rgba(cairo, 0.f, 0.f, 0., 1.);
190
                cairo_stroke(cairo);
191
                gtk_widget_queue_draw_area(drawing_area, px + tile_size / 3.,
192
                                           py + tile_size / 3., tile_size / 3.,
193
                                           tile_size / 3.);
194
        }
195
        cairo_restore(cairo);
196
}
197
 
198
static void draw_mark(AIMove *aim)
199
/* Draw a mark piece */
200
{
201
        PCOORD x, y;
202
        double r = 1., g = 1., b = 0., weight;
203
 
204
        /* Logarithmic scale */
205
        weight = aim->weight;
206
        if (opt_mark_log) {
207
                if (weight > 0.)
208
                        weight = log(weight);
209
                else if (weight < 0.)
210
                        weight = -log(-weight);
211
        }
212
 
213
        /* Normalized scale */
214
        if (opt_mark_norm) {
215
                weight = (weight - marks_min) / (marks_max - marks_min);
216
                r = 0.4 + 0.6 * weight;
217
                g = 0.5 - 0.2 * weight;
218
                b = 0.6 - 0.4 * weight;
219
        }
220
 
221
        /* Absolute scale */
222
        else {
223
                weight /= marks_max;
224
                if (weight > 0.)
225
                        r = 1 - weight;
226
                else if (weight < 0.)
227
                        g = 1 + weight;
228
        }
229
 
230
        /* Grayscale */
231
        if (opt_grayscale)
232
                r = g = b = 0.2 + weight * 0.6;
233
 
234
        cairo_save(cairo);
235
        cairo_set_source_rgba(cairo, r, g, b, 0.67);
236
        bcoords_to_pcoords(aim->x, aim->y, &x, &y);
237
        cairo_arc(cairo, x + tile_size / 2, y + tile_size / 2,
238
                  tile_size / 2, 0., G_PI * 2.);
239
        cairo_fill(cairo);
240
        gtk_widget_queue_draw_area(drawing_area, x, y, tile_size, tile_size);
241
        cairo_restore(cairo);
242
}
243
 
244
void draw_marks(AIMoves *m, int redraw)
245
/* Set the marks array to a new list of moves and draw it, if any, otherwise
246
   clear */
247
{
248
        AIMoves *old_marks;
249
        int i;
250
 
251
        old_marks = marks;
252
        marks = NULL;
253
        if (old_marks && old_marks != m) {
254
                if (redraw)
255
                        for (i = 0; i < old_marks->len; i++)
256
                                draw_tile(old_marks->data[i].x,
257
                                          old_marks->data[i].y);
258
                aimoves_free(old_marks);
259
        }
260
        if (m) {
261
                marks = m;
262
                marks_min = AIW_LOSE;
263
                marks_max = AIW_WIN;
264
 
265
                /* Find maximum weighted move */
266
                if (opt_mark_norm && marks->len) {
267
                        AIWEIGHT min, max;
268
 
269
                        aimoves_range(marks, &min, &max);
270
                        marks_min = min;
271
                        marks_max = max;
272
                }
273
 
274
                if (opt_mark_log) {
275
                        if (marks_min > 0)
276
                                marks_min = log(marks_min);
277
                        else if (marks_min < 0)
278
                                marks_min = -log(-marks_min);
279
                        if (marks_max > 0)
280
                                marks_max = log(marks_max);
281
                        else if (marks_max < 0)
282
                                marks_max = -log(-marks_max);
283
                }
284
                if (redraw)
285
                        for (i = 0; i < marks->len; i++)
286
                                draw_mark(marks->data + i);
287
        }
288
}
289
 
290
void sum_of_marks(void)
291
/* Test function to sum up the marked piece weights */
292
{
293
        AIWEIGHT total = 0;
294
        int i;
295
 
296
        if (!marks)
297
                return;
298
        for (i = 0; i < marks->len; i++)
299
                total += marks->data[i].weight;
300
        g_debug("marks total to %d", total);
301
}
302
 
303
// Render a tile on the pixmap
304
void draw_tile(BCOORD bx, BCOORD by)
305
{
306
        PCOORD px, py, px_mid, py_mid;
307
        PIECE piece;
308
        int i;
309
 
310
        bcoords_to_pcoords(bx, by, &px, &py);
311
        cairo_save(cairo);
312
 
313
        // Draw tile background
314
        cairo_rectangle(cairo, px, py, tile_size, tile_size);
315
        if (opt_grayscale)
316
                cairo_set_source_rgba(cairo, 1., 1., 1., 1.);
317
        else
318
                cairo_set_source_rgba(cairo, 0.9, 0.8, 0.4, 1.);
319
        cairo_fill(cairo);
320
 
321
        // Draw tile cross
322
        px_mid = px + tile_size / 2;
323
        py_mid = py + tile_size / 2;
324
        cairo_set_line_width(cairo, 1.5);
325
        cairo_move_to(cairo, px_mid, by ? py : py_mid - 1);
326
        cairo_line_to(cairo, px_mid,
327
                      by == board_size - 1 ? py_mid + 1: py + tile_size);
328
        cairo_move_to(cairo, bx? px : px_mid - 1, py_mid);
329
        cairo_line_to(cairo, bx == board_size - 1 ? px_mid + 1: px + tile_size,
330
                      py + tile_size / 2);
331
        cairo_set_source_rgba(cairo, 0., 0., 0., 1.);
332
        cairo_stroke(cairo);
333
 
334
        cairo_restore(cairo);
335
 
336
        /* Draw grid marker */
337
        draw_marker(bx, by);
338
 
339
        /* Draw piece or piece mark */
340
        piece = piece_at(board, bx, by);
341
        if (piece == PIECE_NONE && (i = aimoves_find(marks, bx, by)) >= 0)
342
                draw_mark(marks->data + i);
343
        else
344
                draw_piece(bx, by, piece, 1.);
345
}
346
 
347
/* Print centered text */
348
static void center_print(double x, double y, const char *str)
349
{
350
        cairo_text_extents_t te;
351
        size_t len;
352
 
353
        len = strlen(str);
354
        cairo_text_extents(cairo, str, &te);
355
        cairo_move_to(cairo, x - te.width / 2, y + te.width / len / 2);
356
        cairo_show_text(cairo, str);
357
}
358
 
359
void draw_win(void)
360
/* Draw a line to indicate the winning line on the current board */
361
{
362
        PCOORD x1, y1, x2, y2, tmp;
363
 
364
        if (!board->won)
365
                return;
366
 
367
        bcoords_to_pcoords(board->win_x1, board->win_y1, &x1, &y1);
368
        bcoords_to_pcoords(board->win_x2, board->win_y2, &x2, &y2);
369
        cairo_save(cairo);
370
        cairo_set_source_rgba(cairo, 1., 0., 0., 0.67);
371
        cairo_set_line_width(cairo, tile_size / 3);
372
        cairo_set_line_cap(cairo, CAIRO_LINE_CAP_ROUND);
373
        cairo_move_to(cairo, x1 + tile_size / 2, y1 + tile_size / 2);
374
        cairo_line_to(cairo, x2 + tile_size / 2, y2 + tile_size / 2);
375
        cairo_stroke(cairo);
376
        cairo_restore(cairo);
377
        if (x2 < x1) {
378
                tmp = x1;
379
                x1 = x2;
380
                x2 = tmp;
381
        }
382
        if (y2 < y1) {
383
                tmp = y1;
384
                y1 = y2;
385
                y2 = tmp;
386
        }
387
        gtk_widget_queue_draw_area(drawing_area, x1, y1, x2 + tile_size - x1,
388
                                   y2 + tile_size - y1);
389
}
390
 
391
void draw_board_sized(int size)
392
/* Render the backing board pixmap; if size is not set then the board is drawn
393
   to fit the drawing area */
394
{
395
        int x, y, width, height;
396
 
397
        if (!drawing_area && !size)
398
                return;
399
 
400
        cairo_save(cairo);
401
 
402
        // Calculate visible board range
403
        if (size)
404
                width = height = tile_size = size;
405
        else {
406
                width = drawing_area->allocation.width;
407
                height = drawing_area->allocation.height;
408
        }
409
        tile_size = width;
410
        if (tile_size > height)
411
                tile_size = drawing_area->allocation.height;
412
        tile_size /= board_size + 2;
413
        board_xo = (width - tile_size * (board_size + 2)) / 2;
414
        board_yo = (height - tile_size * (board_size + 2)) / 2;
415
 
416
        // Fill gray boundaries
417
        cairo_set_source_rgba(cairo, 0.4, 0.4, 0.4, 1.);
418
        cairo_rectangle(cairo, 0, 0, width, board_yo);
419
        cairo_fill(cairo);
420
        cairo_rectangle(cairo, 0, board_yo, board_xo, height - board_yo * 2);
421
        cairo_fill(cairo);
422
        cairo_rectangle(cairo, width - board_xo - 1, board_yo, board_xo + 1,
423
                        height - board_yo * 2);
424
        cairo_fill(cairo);
425
        cairo_rectangle(cairo, 0, height - board_yo - 1, width, board_yo + 1);
426
        cairo_fill(cairo);
427
 
428
        /* Fill label boundaries */
429
        if (opt_grayscale)
430
                cairo_set_source_rgba(cairo, 1., 1., 1., 1.);
431
        else
432
                cairo_set_source_rgba(cairo, 0.9, 0.8, 0.4, 1.);
433
        cairo_rectangle(cairo, board_xo, board_yo, width - board_xo * 2,
434
                        tile_size);
435
        cairo_fill(cairo);
436
        cairo_rectangle(cairo, board_xo, board_yo + tile_size, tile_size,
437
                        height - tile_size * 2 - board_yo * 2);
438
        cairo_fill(cairo);
439
        cairo_rectangle(cairo, width - board_xo - tile_size - 1, tile_size,
440
                        tile_size + 1, height - tile_size - board_yo * 2);
441
        cairo_fill(cairo);
442
        cairo_rectangle(cairo, board_xo, height - board_yo - tile_size - 1,
443
                        width - board_xo * 2, tile_size + 1);
444
        cairo_fill(cairo);
445
 
446
        /* Set cairo font */
447
        cairo_select_font_face(cairo, "monospace", CAIRO_FONT_SLANT_NORMAL,
448
                               CAIRO_FONT_WEIGHT_BOLD);
449
        cairo_set_font_size(cairo, tile_size / 2);
450
        cairo_set_source_rgba(cairo, 0., 0., 0., 1.);
451
 
452
        /* Draw horizontal labels */
453
        for (x = 0; x < board_size; x++)
454
                center_print(board_xo + (x + 1.5) * tile_size, board_yo +
455
                             tile_size / 2, bcoord_to_alpha(x));
456
        for (x = 0; x < board_size; x++)
457
                center_print(board_xo + (x + 1.5) * tile_size,
458
                             height - board_yo - tile_size / 2,
459
                             bcoord_to_alpha(x));
460
 
461
        /* Draw vertical labels */
462
        for (y = 0; y < board_size; y++)
463
                center_print(board_xo + tile_size / 2, board_yo + (y + 1.5) *
464
                             tile_size, va("%d", board_size - y));
465
        for (y = 0; y < board_size; y++)
466
                center_print(width - board_xo - tile_size / 2,
467
                             board_yo + (y + 1.5) * tile_size,
468
                             va("%d", board_size - y));
469
 
470
        cairo_restore(cairo);
471
        do_not_dirty = TRUE;
472
 
473
        /* Refresh the marks */
474
        draw_marks(marks, FALSE);
475
 
476
        // Render board tiles and pieces
477
        for (y = 0; y < board_size; y++)
478
                for (x = 0; x < board_size; x++)
479
                        draw_tile(x, y);
480
 
481
        draw_last_moves();
482
        draw_win();
483
 
484
        // Draw hover piece
485
        if (hover)
486
                draw_piece(hover_x, hover_y, board->turn, 0.5);
487
 
488
        do_not_dirty = FALSE;
489
        if (!size)
490
                gtk_widget_queue_draw(drawing_area);
491
}
492
 
493
static void check_hover(void)
494
{
495
        hover = (piece_at(board, hover_x, hover_y) == PIECE_NONE)
496
                && hover_x < board_size && hover_y < board_size;
497
}
498
 
499
#ifndef NO_CAIRO_SVG
500
void draw_screenshot(const char *filename)
501
/* Save a screenshot file */
502
{
503
        cairo_t *old_cairo = cairo;
504
        cairo_surface_t *surface;
505
        int size = 512 - 512 % (board_size + 2);
506
 
507
        /* FIXME: 0.5 pixel wide hair lines appear at most sizes */
508
 
509
        surface = cairo_svg_surface_create(filename, size, size);
510
        cairo = cairo_create(surface);
511
        draw_board_sized(size);
512
        cairo_show_page(cairo);
513
        cairo_destroy(cairo);
514
        cairo_surface_finish(surface);
515
        cairo = old_cairo;
516
        draw_board();
517
}
518
#endif
519
 
520
/*
521
 *      Events
522
 */
523
 
524
// Create a new backing pixmap of the appropriate size
525
static gboolean configure_event(GtkWidget *widget, GdkEventConfigure *event)
526
{
527
        if (pixmap) {
528
                g_object_unref(pixmap);
529
                pixmap = NULL;
530
        }
531
        pixmap = gdk_pixmap_new(widget->window, widget->allocation.width,
532
                                widget->allocation.height, -1);
533
        if (cairo) {
534
                cairo_destroy(cairo);
535
                cairo = NULL;
536
        }
537
        cairo = gdk_cairo_create(GDK_DRAWABLE(pixmap));
538
        cairo_set_line_width(cairo, 1.);
539
        draw_board();
540
        return TRUE;
541
}
542
 
543
// Redraw the drawing area from the backing pixmap
544
static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event)
545
{
546
        gdk_draw_drawable(widget->window,
547
                          widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
548
                          pixmap, event->area.x, event->area.y, event->area.x,
549
                          event->area.y, event->area.width, event->area.height);
550
        return FALSE;
551
}
552
 
553
// Mouse button is pressed over drawing area
554
static gboolean button_press_event(GtkWidget *widget, GdkEventButton *event)
555
{
556
        check_hover();
557
        if (players[board->turn].ai == PLAYER_HUMAN && hover) {
558
                make_move(hover_x, hover_y);
559
                hover = FALSE;
560
        }
561
        return TRUE;
562
}
563
 
564
// Mouse leaves drawing area
565
static gboolean leave_notify_event(GtkWidget *widget, GdkEventCrossing *event,
566
                                   gpointer user_data)
567
{
568
        if (hover) {
569
                draw_tile(hover_x, hover_y);
570
                hover = FALSE;
571
        }
572
        window_status("");
573
        return FALSE;
574
}
575
 
576
// Mouse is moved over drawing area
577
static gboolean motion_notify_event(GtkWidget *widget, GdkEventMotion *event)
578
{
579
        gint x, y;
580
        GdkModifierType state;
581
        BCOORD hover_x2, hover_y2;
582
 
583
        if (players[board->turn].ai != PLAYER_HUMAN)
584
                return FALSE;
585
 
586
        if (event->is_hint)
587
                gdk_window_get_pointer(event->window, &x, &y, &state);
588
        else {
589
                x = event->x;
590
                y = event->y;
591
                state = (GdkModifierType)event->state;
592
        }
593
        if (!pcoord_to_bcoord(x, y, &hover_x2, &hover_y2)) {
594
                if (hover) {
595
                        hover = FALSE;
596
                        draw_tile(hover_x, hover_y);
597
                }
598
                return FALSE;
599
        }
600
        if (playable &&
601
            (!hover || hover_x2 != hover_x || hover_y2 != hover_y)) {
602
                int i;
603
                char *mark_str = "";
604
 
605
                if (hover)
606
                        draw_tile(hover_x, hover_y);
607
                hover_x = hover_x2;
608
                hover_y = hover_y2;
609
                check_hover();
610
                if (!hover)
611
                        return TRUE;
612
                if ((i = aimoves_find(marks, hover_x, hover_y)) >= 0)
613
                        mark_str = va(" marked as %s",
614
                                      aiw_to_string(marks->data[i].weight));
615
                draw_piece(hover_x, hover_y, board->turn, 0.5);
616
                window_status(va("%s: play at %s/%d,%d (%d move%s left)%s",
617
                                 piece_to_string(board->turn),
618
                                 bcoords_to_string(hover_x, hover_y),
619
                                 hover_x, hover_y, board->moves_left,
620
                                 board->moves_left == 1 ? "" : "s",
621
                                 mark_str));
622
        }
623
 
624
        return TRUE;
625
}
626
 
627
/*
628
 *      Initilization and settings
629
 */
630
 
631
// Enable/disable hover and move reporting
632
void draw_playable(int yes)
633
{
634
        playable = yes;
635
        if (!yes)
636
                hover = FALSE;
637
}
638
 
639
// Create the drawing area control
640
GtkWidget *draw_init(void)
641
{
642
        if (drawing_area)
643
                return drawing_area;
644
 
645
        drawing_area = gtk_drawing_area_new();
646
        g_signal_connect(G_OBJECT(drawing_area), "expose-event",
647
                         G_CALLBACK(expose_event), NULL);
648
        g_signal_connect(G_OBJECT(drawing_area), "configure-event",
649
                         G_CALLBACK(configure_event), NULL);
650
        g_signal_connect(G_OBJECT(drawing_area), "button-press-event",
651
                         G_CALLBACK(button_press_event), NULL);
652
        g_signal_connect(G_OBJECT(drawing_area), "motion-notify-event",
653
                         G_CALLBACK(motion_notify_event), NULL);
654
        g_signal_connect(G_OBJECT(drawing_area), "leave-notify-event",
655
                         G_CALLBACK(leave_notify_event), NULL);
656
        gtk_widget_set_events(drawing_area,
657
                              GDK_EXPOSURE_MASK |
658
                              GDK_BUTTON_PRESS_MASK |
659
                              GDK_BUTTON_RELEASE_MASK |
660
                              GDK_POINTER_MOTION_MASK |
661
                              GDK_POINTER_MOTION_HINT_MASK |
662
                              GDK_LEAVE_NOTIFY_MASK);
663
        gtk_widget_set_extension_events(drawing_area,
664
                                        GDK_EXTENSION_EVENTS_CURSOR);
665
        return drawing_area;
666
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.