23 * questions.
24 */
25 #include "glass_window.h"
26 #include "glass_general.h"
27 #include "glass_key.h"
28 #include "glass_screen.h"
29 #include "glass_dnd.h"
30
31 #include <com_sun_glass_events_WindowEvent.h>
32 #include <com_sun_glass_events_ViewEvent.h>
33 #include <com_sun_glass_events_MouseEvent.h>
34 #include <com_sun_glass_events_KeyEvent.h>
35
36 #include <com_sun_glass_ui_Window_Level.h>
37
38 #include <X11/extensions/shape.h>
39 #include <cairo.h>
40 #include <cairo-xlib.h>
41 #include <gdk/gdkx.h>
42 #include <gdk/gdk.h>
43
44 #include <string.h>
45
46 #include <iostream>
47 #include <algorithm>
48
49 WindowContext * WindowContextBase::sm_grab_window = NULL;
50 WindowContext * WindowContextBase::sm_mouse_drag_window = NULL;
51
52 GdkWindow* WindowContextBase::get_gdk_window(){
53 return gdk_window;
54 }
55
56 jobject WindowContextBase::get_jview() {
57 return jview;
58 }
59
60 jobject WindowContextBase::get_jwindow() {
61 return jwindow;
62 }
334
335 if (jview) {
336 mainEnv->CallVoidMethod(jview, jViewNotifyMouse,
337 isDrag ? com_sun_glass_events_MouseEvent_DRAG : com_sun_glass_events_MouseEvent_MOVE,
338 button,
339 (jint) event->x, (jint) event->y,
340 (jint) event->x_root, (jint) event->y_root,
341 glass_modifier,
342 JNI_FALSE,
343 JNI_FALSE);
344 CHECK_JNI_EXCEPTION(mainEnv)
345 }
346 }
347
348 void WindowContextBase::process_mouse_scroll(GdkEventScroll* event) {
349 jdouble dx = 0;
350 jdouble dy = 0;
351
352 // converting direction to change in pixels
353 switch (event->direction) {
354 case GDK_SCROLL_UP:
355 dy = 1;
356 break;
357 case GDK_SCROLL_DOWN:
358 dy = -1;
359 break;
360 case GDK_SCROLL_LEFT:
361 dx = 1;
362 break;
363 case GDK_SCROLL_RIGHT:
364 dx = -1;
365 break;
366 }
367
368 if (jview) {
369 mainEnv->CallVoidMethod(jview, jViewNotifyScroll,
370 (jint) event->x, (jint) event->y,
371 (jint) event->x_root, (jint) event->y_root,
372 dx, dy,
373 gdk_modifier_mask_to_glass(event->state),
399 JNI_FALSE);
400 CHECK_JNI_EXCEPTION(mainEnv)
401 }
402 }
403 }
404
405 void WindowContextBase::process_key(GdkEventKey* event) {
406 bool press = event->type == GDK_KEY_PRESS;
407 jint glassKey = get_glass_key(event);
408 jint glassModifier = gdk_modifier_mask_to_glass(event->state);
409 if (press) {
410 glassModifier |= glass_key_to_modifier(glassKey);
411 } else {
412 glassModifier &= ~glass_key_to_modifier(glassKey);
413 }
414 jcharArray jChars = NULL;
415 jchar key = gdk_keyval_to_unicode(event->keyval);
416 if (key >= 'a' && key <= 'z' && (event->state & GDK_CONTROL_MASK)) {
417 key = key - 'a' + 1; // map 'a' to ctrl-a, and so on.
418 } else {
419 key = glass_gtk_fixup_typed_key(key, event->keyval);
420 }
421
422 if (key > 0) {
423 jChars = mainEnv->NewCharArray(1);
424 if (jChars) {
425 mainEnv->SetCharArrayRegion(jChars, 0, 1, &key);
426 CHECK_JNI_EXCEPTION(mainEnv)
427 }
428 } else {
429 jChars = mainEnv->NewCharArray(0);
430 }
431 if (jview) {
432 if (press) {
433 mainEnv->CallVoidMethod(jview, jViewNotifyKey,
434 com_sun_glass_events_KeyEvent_PRESS,
435 glassKey,
436 jChars,
437 glassModifier);
438 CHECK_JNI_EXCEPTION(mainEnv)
439
1437 WindowContextBase::process_destroy();
1438 }
1439
1440 ////////////////////////////// WindowContextPlug ////////////////////////////////
1441
1442 static gboolean plug_configure(GtkWidget *widget, GdkEvent *event, gpointer user_data) {
1443 (void)widget;
1444
1445 if (event->type == GDK_CONFIGURE) {
1446 ((WindowContextPlug*)user_data)->process_gtk_configure(&event->configure);
1447 }
1448 return FALSE;
1449 }
1450
1451 WindowContextPlug::WindowContextPlug(jobject _jwindow, void* _owner) :
1452 WindowContextBase(),
1453 parent()
1454 {
1455 jwindow = mainEnv->NewGlobalRef(_jwindow);
1456
1457 gtk_widget = gtk_plug_new((GdkNativeWindow)PTR_TO_JLONG(_owner));
1458
1459 g_signal_connect(G_OBJECT(gtk_widget), "configure-event", G_CALLBACK(plug_configure), this);
1460
1461 gtk_widget_set_size_request(gtk_widget, 0, 0);
1462 gtk_widget_set_events(gtk_widget, GDK_ALL_EVENTS_MASK);
1463 gtk_widget_set_can_focus(GTK_WIDGET(gtk_widget), TRUE);
1464 gtk_widget_set_app_paintable(gtk_widget, TRUE);
1465
1466 gtk_widget_realize(gtk_widget);
1467 gdk_window = gtk_widget_get_window(gtk_widget);
1468
1469 g_object_set_data_full(G_OBJECT(gdk_window), GDK_WINDOW_DATA_CONTEXT, this, NULL);
1470 gdk_window_register_dnd(gdk_window);
1471
1472 gtk_container = gtk_fixed_new();
1473 gtk_container_add (GTK_CONTAINER(gtk_widget), gtk_container);
1474 gtk_widget_realize(gtk_container);
1475 }
1476
1477 GtkWindow *WindowContextPlug::get_gtk_window() {
1763
1764 embedded_children.erase(pos);
1765 if (toFront) {
1766 embedded_children.push_back(this);
1767 } else {
1768 embedded_children.insert(embedded_children.begin(), this);
1769 }
1770
1771 gdk_window_restack(gdk_window, NULL, toFront ? TRUE : FALSE);
1772 }
1773
1774 void WindowContextChild::enter_fullscreen() {
1775 if (full_screen_window) {
1776 return;
1777 }
1778
1779 full_screen_window = new WindowContextTop(jwindow, NULL, 0L, UNTITLED,
1780 NORMAL, (GdkWMFunction) 0);
1781 int x, y, w, h;
1782 gdk_window_get_origin(gdk_window, &x, &y);
1783 gdk_window_get_geometry(gdk_window, NULL, NULL, &w, &h, NULL);
1784 full_screen_window->set_bounds(x, y, true, true, w, h, -1, -1);
1785
1786 if (WindowContextBase::sm_grab_window == this) {
1787 ungrab_focus();
1788 }
1789
1790 reparent_children(full_screen_window);
1791
1792 full_screen_window->set_visible(true);
1793 full_screen_window->enter_fullscreen();
1794
1795 if (jwindow) {
1796 mainEnv->CallVoidMethod(jwindow, jWindowNotifyDelegatePtr, (jlong)full_screen_window);
1797 CHECK_JNI_EXCEPTION(mainEnv)
1798 }
1799
1800 if (jview) {
1801 this->view = (GlassView*)mainEnv->GetLongField(jview, jViewPtr);
1802
1803 this->view->current_window = full_screen_window;
|
23 * questions.
24 */
25 #include "glass_window.h"
26 #include "glass_general.h"
27 #include "glass_key.h"
28 #include "glass_screen.h"
29 #include "glass_dnd.h"
30
31 #include <com_sun_glass_events_WindowEvent.h>
32 #include <com_sun_glass_events_ViewEvent.h>
33 #include <com_sun_glass_events_MouseEvent.h>
34 #include <com_sun_glass_events_KeyEvent.h>
35
36 #include <com_sun_glass_ui_Window_Level.h>
37
38 #include <X11/extensions/shape.h>
39 #include <cairo.h>
40 #include <cairo-xlib.h>
41 #include <gdk/gdkx.h>
42 #include <gdk/gdk.h>
43 #ifdef GLASS_GTK3
44 #include <gtk/gtkx.h>
45 #endif
46
47 #include <string.h>
48
49 #include <iostream>
50 #include <algorithm>
51
52 WindowContext * WindowContextBase::sm_grab_window = NULL;
53 WindowContext * WindowContextBase::sm_mouse_drag_window = NULL;
54
55 GdkWindow* WindowContextBase::get_gdk_window(){
56 return gdk_window;
57 }
58
59 jobject WindowContextBase::get_jview() {
60 return jview;
61 }
62
63 jobject WindowContextBase::get_jwindow() {
64 return jwindow;
65 }
337
338 if (jview) {
339 mainEnv->CallVoidMethod(jview, jViewNotifyMouse,
340 isDrag ? com_sun_glass_events_MouseEvent_DRAG : com_sun_glass_events_MouseEvent_MOVE,
341 button,
342 (jint) event->x, (jint) event->y,
343 (jint) event->x_root, (jint) event->y_root,
344 glass_modifier,
345 JNI_FALSE,
346 JNI_FALSE);
347 CHECK_JNI_EXCEPTION(mainEnv)
348 }
349 }
350
351 void WindowContextBase::process_mouse_scroll(GdkEventScroll* event) {
352 jdouble dx = 0;
353 jdouble dy = 0;
354
355 // converting direction to change in pixels
356 switch (event->direction) {
357 #if GTK_CHECK_VERSION(3, 4, 0)
358 case GDK_SCROLL_SMOOTH:
359 //FIXME 3.4 ???
360 break;
361 #endif
362 case GDK_SCROLL_UP:
363 dy = 1;
364 break;
365 case GDK_SCROLL_DOWN:
366 dy = -1;
367 break;
368 case GDK_SCROLL_LEFT:
369 dx = 1;
370 break;
371 case GDK_SCROLL_RIGHT:
372 dx = -1;
373 break;
374 }
375
376 if (jview) {
377 mainEnv->CallVoidMethod(jview, jViewNotifyScroll,
378 (jint) event->x, (jint) event->y,
379 (jint) event->x_root, (jint) event->y_root,
380 dx, dy,
381 gdk_modifier_mask_to_glass(event->state),
407 JNI_FALSE);
408 CHECK_JNI_EXCEPTION(mainEnv)
409 }
410 }
411 }
412
413 void WindowContextBase::process_key(GdkEventKey* event) {
414 bool press = event->type == GDK_KEY_PRESS;
415 jint glassKey = get_glass_key(event);
416 jint glassModifier = gdk_modifier_mask_to_glass(event->state);
417 if (press) {
418 glassModifier |= glass_key_to_modifier(glassKey);
419 } else {
420 glassModifier &= ~glass_key_to_modifier(glassKey);
421 }
422 jcharArray jChars = NULL;
423 jchar key = gdk_keyval_to_unicode(event->keyval);
424 if (key >= 'a' && key <= 'z' && (event->state & GDK_CONTROL_MASK)) {
425 key = key - 'a' + 1; // map 'a' to ctrl-a, and so on.
426 } else {
427 #ifdef GLASS_GTK2
428 if (key == 0) {
429 // Work around "bug" fixed in gtk-3.0:
430 // http://mail.gnome.org/archives/commits-list/2011-March/msg06832.html
431 switch (event->keyval) {
432 case 0xFF08 /* Backspace */: key = '\b';
433 case 0xFF09 /* Tab */: key = '\t';
434 case 0xFF0A /* Linefeed */: key = '\n';
435 case 0xFF0B /* Vert. Tab */: key = '\v';
436 case 0xFF0D /* Return */: key = '\r';
437 case 0xFF1B /* Escape */: key = '\033';
438 case 0xFFFF /* Delete */: key = '\177';
439 }
440 }
441 #endif
442 }
443
444 if (key > 0) {
445 jChars = mainEnv->NewCharArray(1);
446 if (jChars) {
447 mainEnv->SetCharArrayRegion(jChars, 0, 1, &key);
448 CHECK_JNI_EXCEPTION(mainEnv)
449 }
450 } else {
451 jChars = mainEnv->NewCharArray(0);
452 }
453 if (jview) {
454 if (press) {
455 mainEnv->CallVoidMethod(jview, jViewNotifyKey,
456 com_sun_glass_events_KeyEvent_PRESS,
457 glassKey,
458 jChars,
459 glassModifier);
460 CHECK_JNI_EXCEPTION(mainEnv)
461
1459 WindowContextBase::process_destroy();
1460 }
1461
1462 ////////////////////////////// WindowContextPlug ////////////////////////////////
1463
1464 static gboolean plug_configure(GtkWidget *widget, GdkEvent *event, gpointer user_data) {
1465 (void)widget;
1466
1467 if (event->type == GDK_CONFIGURE) {
1468 ((WindowContextPlug*)user_data)->process_gtk_configure(&event->configure);
1469 }
1470 return FALSE;
1471 }
1472
1473 WindowContextPlug::WindowContextPlug(jobject _jwindow, void* _owner) :
1474 WindowContextBase(),
1475 parent()
1476 {
1477 jwindow = mainEnv->NewGlobalRef(_jwindow);
1478
1479 WindowContext* parent = ((WindowContext*)JLONG_TO_PTR(_owner));
1480 Window win = GDK_WINDOW_XID(parent->get_gdk_window());
1481 gtk_widget = gtk_plug_new(win);
1482
1483 g_signal_connect(G_OBJECT(gtk_widget), "configure-event", G_CALLBACK(plug_configure), this);
1484
1485 gtk_widget_set_size_request(gtk_widget, 0, 0);
1486 gtk_widget_set_events(gtk_widget, GDK_ALL_EVENTS_MASK);
1487 gtk_widget_set_can_focus(GTK_WIDGET(gtk_widget), TRUE);
1488 gtk_widget_set_app_paintable(gtk_widget, TRUE);
1489
1490 gtk_widget_realize(gtk_widget);
1491 gdk_window = gtk_widget_get_window(gtk_widget);
1492
1493 g_object_set_data_full(G_OBJECT(gdk_window), GDK_WINDOW_DATA_CONTEXT, this, NULL);
1494 gdk_window_register_dnd(gdk_window);
1495
1496 gtk_container = gtk_fixed_new();
1497 gtk_container_add (GTK_CONTAINER(gtk_widget), gtk_container);
1498 gtk_widget_realize(gtk_container);
1499 }
1500
1501 GtkWindow *WindowContextPlug::get_gtk_window() {
1787
1788 embedded_children.erase(pos);
1789 if (toFront) {
1790 embedded_children.push_back(this);
1791 } else {
1792 embedded_children.insert(embedded_children.begin(), this);
1793 }
1794
1795 gdk_window_restack(gdk_window, NULL, toFront ? TRUE : FALSE);
1796 }
1797
1798 void WindowContextChild::enter_fullscreen() {
1799 if (full_screen_window) {
1800 return;
1801 }
1802
1803 full_screen_window = new WindowContextTop(jwindow, NULL, 0L, UNTITLED,
1804 NORMAL, (GdkWMFunction) 0);
1805 int x, y, w, h;
1806 gdk_window_get_origin(gdk_window, &x, &y);
1807 #ifdef GLASS_GTK3
1808 gdk_window_get_geometry(gdk_window, NULL, NULL, &w, &h);
1809 #else
1810 gdk_window_get_geometry(gdk_window, NULL, NULL, &w, &h, NULL);
1811 #endif
1812 full_screen_window->set_bounds(x, y, true, true, w, h, -1, -1);
1813
1814 if (WindowContextBase::sm_grab_window == this) {
1815 ungrab_focus();
1816 }
1817
1818 reparent_children(full_screen_window);
1819
1820 full_screen_window->set_visible(true);
1821 full_screen_window->enter_fullscreen();
1822
1823 if (jwindow) {
1824 mainEnv->CallVoidMethod(jwindow, jWindowNotifyDelegatePtr, (jlong)full_screen_window);
1825 CHECK_JNI_EXCEPTION(mainEnv)
1826 }
1827
1828 if (jview) {
1829 this->view = (GlassView*)mainEnv->GetLongField(jview, jViewPtr);
1830
1831 this->view->current_window = full_screen_window;
|