41
41
/* The structure used internally to store the status. */
42
42
static TextData *text_data = (TextData *) NULL;
44
/* The structure used to configure text input. */
45
TextConfig *text_config = (TextConfig *) NULL;
45
47
/* Create the text window. */
47
create_text_window (GtkWindow *parent)
49
create_text_window (GtkWindow *parent)
49
51
GError *error = (GError *) NULL;
57
59
gtk_builder_add_from_file (text_data->text_window_gtk_builder, TEXT_UI_FILE, &error);
61
g_warning ("Failed to load builder file: %s", error->message);
63
g_warning ("Failed to load builder file: %s", error->message);
70
72
GObject *text_obj = gtk_builder_get_object (text_data->text_window_gtk_builder, "text_window");
71
73
text_data->window = GTK_WIDGET (text_obj);
73
gtk_window_set_transient_for (GTK_WINDOW (text_data->window), GTK_WINDOW (parent));
75
75
gtk_window_set_opacity (GTK_WINDOW (text_data->window), 1);
76
gtk_widget_set_usize (GTK_WIDGET (text_data->window), gdk_screen_width (), gdk_screen_height ());
76
gtk_widget_set_size_request (GTK_WIDGET (text_data->window), gdk_screen_width (), gdk_screen_height ());
82
82
/* Move the pen cursor. */
83
static void move_editor_cursor ()
83
static void move_editor_cursor ()
101
102
cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
103
104
if (text_data->blink_show)
105
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
106
cairo_set_line_width (cr, text_data->pen_width);
107
cairo_set_source_color_from_string (cr, text_data->color);
109
cairo_rectangle (cr, text_data->pos->x, text_data->pos->y - height, TEXT_CURSOR_WIDTH, height);
111
text_data->blink_show = FALSE;
106
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
107
cairo_set_line_width (cr, text_data->pen_width);
108
cairo_set_source_color_from_string (cr, text_data->color);
109
cairo_rectangle (cr, text_data->pos->x, text_data->pos->y - height, TEXT_CURSOR_WIDTH, height);
110
text_data->blink_show = FALSE;
115
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
114
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
116
115
cairo_rectangle (cr, text_data->pos->x, text_data->pos->y - height, TEXT_CURSOR_WIDTH, height);
118
117
cairo_rectangle (cr,
119
118
text_data->pos->x-1,
120
119
text_data->pos->y - height - 1,
121
TEXT_CURSOR_WIDTH + 2,
124
text_data->blink_show=TRUE;
120
TEXT_CURSOR_WIDTH + 2,
122
text_data->blink_show=TRUE;
128
126
cairo_stroke (cr);
142
141
cairo_set_operator (text_data->cr, CAIRO_OPERATOR_CLEAR);
144
143
cairo_rectangle (text_data->cr,
145
char_info->x + char_info->x_bearing -1,
146
char_info->y + char_info->y_bearing -1,
147
gdk_screen_width ()+2,
148
text_data->max_font_height + 2);
144
char_info->x + char_info->x_bearing -1,
145
char_info->y + char_info->y_bearing -1,
146
gdk_screen_width ()+2,
147
text_data->max_font_height + 2);
150
149
cairo_fill (text_data->cr);
151
150
cairo_stroke (text_data->cr);
173
172
/* Set the text cursor. */
175
set_text_cursor (GtkWidget *window)
174
set_text_cursor (GtkWidget *window)
177
176
gdouble decoration_height = 4;
178
177
gint height = text_data->max_font_height + decoration_height * 2;
179
178
gint width = TEXT_CURSOR_WIDTH * 3;
180
GdkPixmap *pixmap = gdk_pixmap_new (NULL, width, height, 1);
181
cairo_t *text_pointer_pcr = gdk_cairo_create (pixmap);
182
GdkPixmap *bitmap = gdk_pixmap_new (NULL, width, height, 1);
183
cairo_t *text_pointer_cr = gdk_cairo_create (bitmap);
179
cairo_surface_t *text_surface_t = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
180
cairo_t *text_pointer_cr = cairo_create (text_surface_t);
184
181
GdkColor *background_color_p = rgba_to_gdkcolor (BLACK);
185
182
GdkColor *foreground_color_p = rgba_to_gdkcolor (text_data->color);
186
183
GdkCursor *cursor = (GdkCursor *) NULL;
188
clear_cairo_context (text_pointer_pcr);
189
cairo_set_operator (text_pointer_pcr, CAIRO_OPERATOR_SOURCE);
190
cairo_set_source_rgb (text_pointer_pcr, 1, 1, 1);
191
cairo_paint (text_pointer_pcr);
192
cairo_stroke (text_pointer_pcr);
193
cairo_destroy (text_pointer_pcr);
184
GdkPixbuf *pixbuf = (GdkPixbuf *) NULL;
195
186
if (text_pointer_cr)
197
188
clear_cairo_context (text_pointer_cr);
198
cairo_set_source_rgb (text_pointer_cr, 1, 1, 1);
189
cairo_set_source_color_from_string (text_pointer_cr, text_data->color);
199
190
cairo_set_operator (text_pointer_cr, CAIRO_OPERATOR_SOURCE);
200
191
cairo_set_line_width (text_pointer_cr, 2);
216
207
cairo_stroke (text_pointer_cr);
217
208
cairo_destroy (text_pointer_cr);
220
cursor = gdk_cursor_new_from_pixmap (pixmap,
225
height-decoration_height);
211
pixbuf = gdk_pixbuf_get_from_surface (text_surface_t,
217
cursor = gdk_cursor_new_from_pixbuf ( gdk_display_get_default (), pixbuf, 0, 0);
227
219
gdk_window_set_cursor (gtk_widget_get_window (text_data->window), cursor);
229
gdk_cursor_unref (cursor);
231
g_object_unref (pixmap);
232
g_object_unref (bitmap);
221
g_object_unref (cursor);
222
g_object_unref (pixbuf);
223
cairo_surface_destroy (text_surface_t);
233
224
g_free (foreground_color_p);
234
225
g_free (background_color_p);
231
/* Add a save-point with the text. */
238
text_data->blink_show=FALSE;
241
if (text_data->letterlist)
243
annotate_push_context (text_data->cr);
244
g_slist_foreach (text_data->letterlist,
248
g_slist_free (text_data->letterlist);
249
text_data->letterlist = NULL;
240
256
/* Initialization routine. */
242
init_text_widget (GtkWidget *widget)
258
init_text_widget (GtkWidget *widget)
260
gtk_widget_input_shape_combine_region(text_data->window, NULL);
261
drill_window_in_bar_area (text_data->window);
244
263
if (!text_data->cr)
246
text_data->cr = gdk_cairo_create (widget->window);
265
text_data->cr = gdk_cairo_create ( gtk_widget_get_window (widget) );
247
266
cairo_set_operator (text_data->cr, CAIRO_OPERATOR_SOURCE);
248
267
cairo_set_line_width (text_data->cr, text_data->pen_width);
249
268
cairo_set_source_color_from_string (text_data->cr, text_data->color);
250
269
cairo_set_font_size (text_data->cr, text_data->pen_width * 2);
271
/* Select the font */
272
cairo_select_font_face (text_data->cr, text_config->fontfamily,
273
CAIRO_FONT_SLANT_NORMAL,
274
CAIRO_FONT_WEIGHT_NORMAL);
251
276
/* This is a trick; we must found the maximum height of the font. */
252
277
cairo_text_extents (text_data->cr, "|" , &text_data->extents);
253
278
text_data->max_font_height = text_data->extents.height;
254
279
set_text_cursor (widget);
257
drill_window_in_bar_area (text_data->window);
260
283
grab_pointer (text_data->window, TEXT_MOUSE_EVENTS);
278
/* Add a save-point with the text. */
285
text_data->blink_show=FALSE;
288
if (text_data->letterlist)
290
annotate_push_context (text_data->cr);
291
g_slist_foreach (text_data->letterlist, (GFunc)g_free, NULL);
292
g_slist_free (text_data->letterlist);
293
text_data->letterlist = NULL;
300
301
/* Destroy text window. */
302
destroy_text_window ()
303
destroy_text_window ()
304
305
if (text_data->window)
307
308
ungrab_pointer (gdk_display_get_default ());
309
310
if (text_data->window)
311
gtk_widget_destroy (text_data->window);
312
text_data->window = NULL;
312
gtk_widget_destroy (text_data->window);
313
text_data->window = NULL;
318
319
/* keyboard event snooper. */
319
320
G_MODULE_EXPORT gboolean
320
key_snooper (GtkWidget *widget,
321
key_snooper (GtkWidget *widget,
325
326
if (event->type != GDK_KEY_PRESS) {
331
332
blink_cursor (NULL);
333
334
gboolean closed_to_bar = inside_bar_window (text_data->pos->x + text_data->extents.x_advance,
334
text_data->pos->y-text_data->max_font_height/2);
335
text_data->pos->y-text_data->max_font_height/2);
336
if ( (event->keyval == GDK_BackSpace) ||
337
(event->keyval == GDK_Delete))
337
if ( (event->keyval == GDK_KEY_BackSpace) ||
338
(event->keyval == GDK_KEY_Delete))
339
340
delete_character (); // undo the last character inserted
341
342
/* It is the end of the line or the letter is closed to the window bar. */
342
343
else if ( (text_data->pos->x + text_data->extents.x_advance >= gdk_screen_width ()) ||
343
344
(closed_to_bar) ||
344
(event->keyval == GDK_Return) ||
345
(event->keyval == GDK_ISO_Enter) ||
346
(event->keyval == GDK_KP_Enter))
345
(event->keyval == GDK_KEY_Return) ||
346
(event->keyval == GDK_KEY_ISO_Enter) ||
347
(event->keyval == GDK_KEY_KP_Enter))
348
text_data->pos->x = 0;
349
/* select the x indentation */
350
text_data->pos->x = text_config->leftmargin;
349
351
text_data->pos->y += text_data->max_font_height;
353
/* Simple Tab-Implementation */
354
else if (event->keyval == GDK_KEY_Tab)
356
text_data->pos->x += text_config->tabsize;
351
358
/* Is the character printable? */
352
359
else if (isprint (event->keyval))
392
/* On configure event. */
393
G_MODULE_EXPORT gboolean
394
on_text_window_configure (GtkWidget *widget,
395
GdkEventExpose *event,
402
/* On screen changed. */
404
on_text_window_screen_changed (GtkWidget *widget,
405
GdkScreen *previous_screen,
408
GdkScreen *screen = gtk_widget_get_screen(GTK_WIDGET (widget));
409
GdkVisual *visual = gdk_screen_get_rgba_visual(screen);
412
visual = gdk_screen_get_system_visual (screen);
415
gtk_widget_set_visual (widget, visual);
385
419
/* The windows has been exposed. */
386
420
G_MODULE_EXPORT gboolean
387
on_window_text_expose_event (GtkWidget *widget,
388
GdkEventExpose *event,
421
on_text_window_expose_event (GtkWidget *widget,
391
gint is_fullscreen = gdk_window_get_state (widget->window) & GDK_WINDOW_STATE_FULLSCREEN;
425
GdkWindow *gdk_win = gtk_widget_get_window (widget);
426
gint is_fullscreen = gdk_window_get_state (gdk_win) & GDK_WINDOW_STATE_FULLSCREEN;
393
428
if (!is_fullscreen)
408
443
/* Is the point (x,y) above the virtual keyboard? */
410
is_above_virtual_keyboard (gint x,
445
is_above_virtual_keyboard (gint x,
414
449
HWND hwnd = FindWindow (VIRTUALKEYBOARD_WINDOW_NAME, NULL);
419
454
if (!GetWindowRect (hwnd, &rect))
423
458
if ( (rect.left<x)&& (x<rect.right)&& (rect.top<y)&& (y<rect.bottom))
432
467
/* This is called when the button is leased. */
433
468
G_MODULE_EXPORT gboolean
434
on_window_text_button_release (GtkWidget *win,
469
on_text_window_button_release (GtkWidget *win,
438
473
/* only button1 allowed */
439
474
if (ev->button != 1)
462
497
text_data->pos->y = ev->y_root;
463
498
move_editor_cursor ();
465
stop_virtual_keyboard ();
466
start_virtual_keyboard ();
468
500
/* This present the ardesia bar and the panels. */
469
501
gtk_window_present (GTK_WINDOW (get_bar_window ()));
471
502
gtk_window_present (GTK_WINDOW (text_data->window));
472
503
gdk_window_raise (gtk_widget_get_window (text_data->window));
505
stop_virtual_keyboard ();
506
start_virtual_keyboard ();
474
508
text_data->timer = g_timeout_add (1000, blink_cursor, NULL);
481
515
/* This shots when the text pointer is moving. */
482
516
G_MODULE_EXPORT gboolean
483
on_window_text_cursor_motion (GtkWidget *win,
517
on_text_window_cursor_motion (GtkWidget *win,
488
522
if (inside_bar_window (ev->x_root, ev->y_root))
497
531
/* Start the widget for the text insertion. */
498
void start_text_widget (GtkWindow *parent, gchar* color, gint tickness)
532
void start_text_widget (GtkWindow *parent,
500
536
text_data = g_malloc ((gsize) sizeof (TextData));
516
552
create_text_window (parent);
554
/* This trys to set an alpha channel. */
555
on_text_window_screen_changed(text_data->window, NULL, text_data);
518
557
/* In the gtk 2.16.6 the gtkbuilder property double-buffered is not parsed
519
558
* from the glade file and then I set this by hands.
521
560
gtk_widget_set_double_buffered (text_data->window, FALSE);
562
//gtk_window_set_transient_for (GTK_WINDOW (text_data->window), GTK_WINDOW (parent));
523
563
gtk_window_set_keep_above (GTK_WINDOW (text_data->window), TRUE);
564
gtk_widget_grab_focus (text_data->window);
525
566
/* Connect all the callback from gtkbuilder xml file. */
526
567
gtk_builder_connect_signals (text_data->text_window_gtk_builder, (gpointer) text_data);
542
583
/* Stop the text insertion widget. */
548
589
stop_virtual_keyboard ();
550
591
if (text_data->snooper_handler_id)
552
gtk_key_snooper_remove (text_data->snooper_handler_id);
553
text_data->snooper_handler_id = 0;
593
gtk_key_snooper_remove (text_data->snooper_handler_id);
594
text_data->snooper_handler_id = 0;
557
598
destroy_text_window ();
559
600
if (text_data->cr)
561
cairo_destroy (text_data->cr);
562
text_data->cr = NULL;
602
cairo_destroy (text_data->cr);
603
text_data->cr = NULL;
565
606
if (text_data->pos)
567
g_free (text_data->pos);
568
text_data->pos = NULL;
608
g_free (text_data->pos);
609
text_data->pos = NULL;
571
612
/* Free the gtk builder object. */
572
613
if (text_data->text_window_gtk_builder)
574
g_object_unref (text_data->text_window_gtk_builder);
615
g_object_unref (text_data->text_window_gtk_builder);
575
616
text_data->text_window_gtk_builder = NULL;
578
619
g_free (text_data);
579
620
text_data = NULL;