summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--navit/android/src/org/navitproject/navit/Navit.java84
-rw-r--r--navit/android/src/org/navitproject/navit/NavitGraphics.java1
-rw-r--r--navit/graphics.c86
-rw-r--r--navit/graphics.h30
-rw-r--r--navit/graphics/android/graphics_android.c61
-rw-r--r--navit/graphics/gd/graphics_gd.c2
-rw-r--r--navit/graphics/gtk_drawing_area/graphics_gtk_drawing_area.c2
-rw-r--r--navit/graphics/null/graphics_null.c2
-rw-r--r--navit/graphics/opengl/graphics_opengl.c2
-rw-r--r--navit/graphics/qt_qpainter/graphics_qt_qpainter.cpp3
-rw-r--r--navit/graphics/sdl/graphics_sdl.c2
-rw-r--r--navit/graphics/win32/graphics_win32.c2
-rw-r--r--navit/gui/internal/gui_internal.c4
-rw-r--r--navit/gui/internal/gui_internal_bookmark.c6
-rw-r--r--navit/gui/internal/gui_internal_command.c4
-rw-r--r--navit/gui/internal/gui_internal_html.c7
-rw-r--r--navit/gui/internal/gui_internal_keyboard.c103
-rw-r--r--navit/gui/internal/gui_internal_keyboard.h1
-rw-r--r--navit/gui/internal/gui_internal_poi.c6
-rw-r--r--navit/gui/internal/gui_internal_search.c5
20 files changed, 406 insertions, 7 deletions
diff --git a/navit/android/src/org/navitproject/navit/Navit.java b/navit/android/src/org/navitproject/navit/Navit.java
index 920b79a98..a0c61bd72 100644
--- a/navit/android/src/org/navitproject/navit/Navit.java
+++ b/navit/android/src/org/navitproject/navit/Navit.java
@@ -116,6 +116,20 @@ public class Navit extends Activity
public static final String NAVIT_PREFS = "NavitPrefs";
Boolean isFullscreen = false;
+
+ /**
+ * @brief A Runnable to restore soft input when the user returns to the activity.
+ *
+ * An instance of this class can be passed to the main message queue in the Activity's
+ * {@code onRestore()} method.
+ */
+ private class SoftInputRestorer implements Runnable {
+ public void run() {
+ Navit.this.showNativeKeyboard();
+ }
+ }
+
+
public void removeFileIfExists(String source) {
File file = new File(source);
@@ -445,6 +459,26 @@ public class Navit extends Activity
Log.e("Navit", "timestamp for navigate_to expired! not using data");
}
}
+ Log.d(TAG, "onResume");
+ if (show_soft_keyboard_now_showing) {
+ /* Calling showNativeKeyboard() directly won't work here, we need to use the message queue */
+ View cf = getCurrentFocus();
+ if (cf == null)
+ Log.e(TAG, "no view in focus, can't get a handler");
+ else
+ cf.getHandler().post(new SoftInputRestorer());
+ }
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ Log.d(TAG, "onPause");
+ if (show_soft_keyboard_now_showing) {
+ Log.d(TAG, "onPause:hiding soft input");
+ this.hideNativeKeyboard();
+ show_soft_keyboard_now_showing = true;
+ }
}
private void parseNavigationURI(String schemeSpecificPart) {
@@ -645,6 +679,56 @@ public class Navit extends Activity
openOptionsMenu();
}
+
+ /**
+ * @brief Shows the native keyboard or other input method.
+ *
+ * @return {@code true} if an input method is going to be displayed, {@code false} if not
+ */
+ public int showNativeKeyboard() {
+ /*
+ * Apologies for the huge mess that this function is, but Android's soft input API is a big
+ * nightmare. Its devs have mercifully given us an option to show or hide the keyboard, but
+ * there is no reliable way to figure out if it is actually showing, let alone how much of the
+ * screen it occupies, so our best bet is guesswork.
+ */
+ Configuration config = getResources().getConfiguration();
+ if ((config.keyboard == Configuration.KEYBOARD_QWERTY) && (config.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO))
+ /* physical keyboard present, exit */
+ return 0;
+
+ /* Use SHOW_FORCED here, else keyboard won't show in landscape mode */
+ mgr.showSoftInput(getCurrentFocus(), InputMethodManager.SHOW_FORCED);
+ show_soft_keyboard_now_showing = true;
+
+ /*
+ * Crude way to estimate the height occupied by the keyboard: for AOSP on KitKat and Lollipop it
+ * is about 62-63% of available screen width (in portrait mode) but no more than slightly above
+ * 46% of height (in landscape mode).
+ */
+ Display display_ = getWindowManager().getDefaultDisplay();
+ int width_ = display_.getWidth();
+ int height_ = display_.getHeight();
+ int maxHeight = height_ * 47 / 100;
+ int inputHeight = width_ * 63 / 100;
+ if (inputHeight > (maxHeight))
+ inputHeight = maxHeight;
+
+ /* the receiver isn't going to fire before the UI thread becomes idle, well after this method returns */
+ Log.d(TAG, "showNativeKeyboard:return (assuming true)");
+ return inputHeight;
+ }
+
+
+ /**
+ * @brief Hides the native keyboard or other input method.
+ */
+ public void hideNativeKeyboard() {
+ mgr.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
+ show_soft_keyboard_now_showing = false;
+ }
+
+
void setDestination(float latitude, float longitude, String address) {
Toast.makeText( getApplicationContext(),getString(R.string.address_search_set_destination) + "\n" + address, Toast.LENGTH_LONG).show(); //TRANS
diff --git a/navit/android/src/org/navitproject/navit/NavitGraphics.java b/navit/android/src/org/navitproject/navit/NavitGraphics.java
index 005f79bf2..de7c41863 100644
--- a/navit/android/src/org/navitproject/navit/NavitGraphics.java
+++ b/navit/android/src/org/navitproject/navit/NavitGraphics.java
@@ -738,6 +738,7 @@ public class NavitGraphics
frameLayout.addView(statusTintView);
activity.setContentView(frameLayout);
+
view.requestFocus();
}
else
diff --git a/navit/graphics.c b/navit/graphics.c
index abd18455c..5c6f9e5b3 100644
--- a/navit/graphics.c
+++ b/navit/graphics.c
@@ -1070,6 +1070,91 @@ graphics_background_gc(struct graphics *this_, struct graphics_gc *gc)
this_->meth.background_gc(this_->priv, gc ? gc->priv : NULL);
}
+
+/**
+ * @brief Shows the native on-screen keyboard or other input method
+ *
+ * This method is a wrapper around the respective method of the graphics plugin.
+ *
+ * The caller should populate the {@code kbd} argument with appropriate {@code mode} and {@code lang}
+ * members so the graphics plugin can determine the best matching layout.
+ *
+ * If an input method is shown, the graphics plugin should try to select the configuration which best
+ * matches the specified {@code mode}. For example, if {@code mode} specifies a numeric layout, the
+ * graphics plugin should select a numeric keyboard layout (if available), or the equivalent for another
+ * input method (such as setting stroke recognition to identify strokes as numbers). Likewise, when an
+ * alphanumeric-uppercase mode is requested, it should switch to uppercase input.
+ *
+ * Implementations should, however, consider that Navit's internal keyboard allows the user to switch
+ * modes at will (the only exception being degree mode) and thus must not "lock" the user into a limited
+ * layout with no means to switch to a general-purpose one. For example, house number entry in an
+ * address search dialog may default to numeric mode, but since some house numbers may contain
+ * non-numeric characters, a pure numeric keyboard is suitable only if the user has the option to switch
+ * to an alphanumeric layout.
+ *
+ * When multiple alphanumeric layouts are available, the graphics plugin should use the {@code lang}
+ * argument to determine the best layout.
+ *
+ * When selecting an input method, preference should always be given to the default or last selected
+ * input method and configuration if it matches the requested {@code mode} and {@code lang}.
+ *
+ * If the native input method is going to obstruct parts of Navit's UI, the graphics plugin should set
+ * {@code kbd->w} and {@code kbd->h} to the height and width to the appropriate value in pixels. A value
+ * of -1 indicates that the input method fills the entire available width or height of the space
+ * available to Navit. On windowed platforms, where the on-screen input method and Navit's window may be
+ * moved relative to each other as needed and can be displayed alongside each other, the graphics plugin
+ * should report 0 for both dimensions.
+ *
+ * @param this_ The graphics instance
+ * @param kbd The keyboard instance
+ *
+ * @return 1 if the native keyboard is going to be displayed, 0 if not, -1 if the method is not
+ * supported by the plugin
+ */
+int graphics_show_native_keyboard (struct graphics *this_, struct graphics_keyboard *kbd) {
+ int ret;
+ if (!this_->meth.show_native_keyboard)
+ ret = -1;
+ else
+ ret = this_->meth.show_native_keyboard(kbd);
+ dbg(lvl_debug, "return %d\n", ret);
+ return ret;
+}
+
+
+/**
+ * @brief Hides the native on-screen keyboard or other input method
+ *
+ * This method is a wrapper around the respective method of the graphics plugin.
+ *
+ * A call to this function indicates that Navit no longer needs the input method and is about to reclaim
+ * any screen real estate it may have previously reserved for the input method.
+ *
+ * On platforms that don't support overlapping windows this means that the on-screen input method should
+ * be hidden, as it may otherwise obstruct parts of Navit's UI.
+ *
+ * On windowed platforms, where on-screen input methods can be displayed alongside Navit or moved around
+ * as needed, the graphics driver should instead notify the on-screen method that it is no longer
+ * expecting user input, allowing the input method to take the appropriate action.
+ *
+ * The graphics plugin must free any data it has stored in {@code kbd->gra_priv} and reset the pointer
+ * to {@code NULL} to indicate it has done so.
+ *
+ * The caller may free {@code kbd} after this function returns.
+ *
+ * @param this The graphics instance
+ * @param kbd The keyboard instance
+ *
+ * @return True if the call was successfully passed to the plugin, false if the method is not supported
+ * by the plugin
+ */
+int graphics_hide_native_keyboard (struct graphics *this_, struct graphics_keyboard *kbd) {
+ if (!this_->meth.hide_native_keyboard)
+ return 0;
+ this_->meth.hide_native_keyboard(kbd);
+ return 1;
+}
+
#include "attr.h"
#include "popup.h"
#include <stdio.h>
@@ -2959,3 +3044,4 @@ graphics_process_selection(struct graphics *gra, struct displaylist *dl)
curr=g_list_next(curr);
}
}
+
diff --git a/navit/graphics.h b/navit/graphics.h
index 44bd6c919..2ffbd9ab0 100644
--- a/navit/graphics.h
+++ b/navit/graphics.h
@@ -64,6 +64,31 @@ struct graphics_image_buffer {
int len;
};
+struct graphics_keyboard_priv;
+
+/**
+ * Describes an instance of the native on-screen keyboard or other input method.
+ */
+struct graphics_keyboard {
+ int w; /**< The width of the area obscured by the keyboard (-1 for full width) */
+ int h; /**< The height of the area obscured by the keyboard (-1 for full height) */
+ /* TODO mode is currently a copy of the respective value in the internal GUI and uses the same values.
+ * This may need to be changed to something with globally available enum, possibly with revised values.
+ * The Android implementation (the first to support a native on-screen keyboard) does not use this field
+ * due to limitations of the platform. */
+ int mode; /**< Mode flags for the keyboard */
+ char *lang; /**< The preferred language for text input, may be {@code NULL}. */
+ void *gui_priv; /**< Private data determined by the GUI. The GUI may store
+ * a pointer to a data structure of its choice here. It is
+ * the responsibility of the GUI to free the data structure
+ * when it is no longer needed. The graphics plugin should
+ * not access this member. */
+ struct graphics_keyboard_priv *gra_priv; /**< Private data determined by the graphics plugin. The
+ * graphics plugin is responsible for its management. If it
+ * uses this member, it must free the associated data in
+ * its {@code hide_native_keyboard} method. */
+};
+
/** Magic value for unset/unspecified width/height. */
#define IMAGE_W_H_UNSET (-1)
@@ -124,6 +149,8 @@ struct graphics_methods {
void (*overlay_disable)(struct graphics_priv *gr, int disable);
void (*overlay_resize)(struct graphics_priv *gr, struct point *p, int w, int h, int wraparound);
int (*set_attr)(struct graphics_priv *gr, struct attr *attr);
+ int (*show_native_keyboard)(struct graphics_keyboard *kbd);
+ void (*hide_native_keyboard)(struct graphics_keyboard *kbd);
};
@@ -253,6 +280,9 @@ int graphics_displayitem_within_dist(struct displaylist *displaylist, struct dis
void graphics_add_selection(struct graphics *gra, struct item *item, enum item_type type, struct displaylist *dl);
void graphics_remove_selection(struct graphics *gra, struct item *item, enum item_type type, struct displaylist *dl);
void graphics_clear_selection(struct graphics *gra, struct displaylist *dl);
+int graphics_show_native_keyboard (struct graphics *this_, struct graphics_keyboard *kbd);
+int graphics_hide_native_keyboard (struct graphics *this_, struct graphics_keyboard *kbd);
+
/* end of prototypes */
#ifdef __cplusplus
}
diff --git a/navit/graphics/android/graphics_android.c b/navit/graphics/android/graphics_android.c
index 2bf9ed952..41f441c96 100644
--- a/navit/graphics/android/graphics_android.c
+++ b/navit/graphics/android/graphics_android.c
@@ -485,6 +485,12 @@ set_attr(struct graphics_priv *gra, struct attr *attr)
}
}
+
+int show_native_keyboard (struct graphics_keyboard *kbd);
+
+void hide_native_keyboard (struct graphics_keyboard *kbd);
+
+
static struct graphics_methods graphics_methods = {
graphics_destroy,
draw_mode,
@@ -507,6 +513,8 @@ static struct graphics_methods graphics_methods = {
overlay_disable,
overlay_resize,
set_attr,
+ show_native_keyboard,
+ hide_native_keyboard,
};
static void
@@ -737,7 +745,7 @@ graphics_android_init(struct graphics_priv *ret, struct graphics_priv *parent, s
}
static jclass NavitClass;
-static jmethodID Navit_disableSuspend, Navit_exit, Navit_fullscreen, Navit_runOptionsItem, Navit_showMenu;
+static jmethodID Navit_disableSuspend, Navit_exit, Navit_fullscreen, Navit_runOptionsItem, Navit_showMenu, Navit_showNativeKeyboard, Navit_hideNativeKeyboard;
static int
graphics_android_fullscreen(struct window *win, int on)
@@ -1128,6 +1136,8 @@ event_android_new(struct event_methods *meth)
Navit_showMenu = (*jnienv)->GetMethodID(jnienv, NavitClass, "showMenu", "()V");
if (Navit_showMenu == NULL)
return NULL;
+ Navit_showNativeKeyboard = (*jnienv)->GetMethodID(jnienv, NavitClass, "showNativeKeyboard", "()I");
+ Navit_hideNativeKeyboard = (*jnienv)->GetMethodID(jnienv, NavitClass, "hideNativeKeyboard", "()V");
dbg(lvl_debug,"ok\n");
*meth=event_android_methods;
@@ -1135,6 +1145,55 @@ event_android_new(struct event_methods *meth)
}
+/**
+ * @brief Displays the native input method.
+ *
+ * This method decides whether a native on-screen input method, such as a virtual keyboard, needs to be
+ * displayed. A typical case in which there is no need for an on-screen input method is if a hardware
+ * keyboard is present.
+ *
+ * Note that the Android platform lacks reliable means of determining whether an on-screen input method
+ * is going to be displayed or how much screen space it is going to occupy. Therefore this method tries
+ * to guess these values. They have been tested and found to work correctly with the AOSP keyboard, and
+ * are thus expected to be compatible with most on-screen keyboards found on the market, but results may
+ * be unexpected with other input methods.
+ *
+ * @param kbd A {@code struct graphics_keyboard} which describes the requirements for the input method
+ * and will be populated with the data of the input method before the function returns.
+ *
+ * @return True if the input method is going to be displayed, false if not.
+ */
+int show_native_keyboard (struct graphics_keyboard *kbd) {
+ kbd->w = -1;
+ if (Navit_showNativeKeyboard == NULL) {
+ dbg(lvl_error, "method Navit.showNativeKeyboard() not found, cannot display keyboard\n");
+ return 0;
+ }
+ kbd->h = (*jnienv)->CallIntMethod(jnienv, android_activity, Navit_showNativeKeyboard);
+ dbg(lvl_error, "keyboard size is %d x %d px\n", kbd->w, kbd->h);
+ dbg(lvl_error, "return\n");
+ /* zero height means we're not showing a keyboard, therefore normalize height to boolean */
+ return !!(kbd->h);
+}
+
+
+/**
+ * @brief Hides the native input method and frees associated private data.
+ *
+ * @param kbd The {@code struct graphics_keyboard} which was passed to the earlier call to
+ * {@link show_native_keyboard(struct graphics_keyboard *)}. The {@code gra_priv} member of the struct
+ * will be freed by this function.
+ */
+void hide_native_keyboard (struct graphics_keyboard *kbd) {
+ if (Navit_hideNativeKeyboard == NULL) {
+ dbg(lvl_error, "method Navit.hideNativeKeyboard() not found, cannot dismiss keyboard\n");
+ return;
+ }
+ (*jnienv)->CallVoidMethod(jnienv, android_activity, Navit_hideNativeKeyboard);
+ g_free(kbd->gra_priv);
+}
+
+
void
plugin_init(void)
{
diff --git a/navit/graphics/gd/graphics_gd.c b/navit/graphics/gd/graphics_gd.c
index 47868d622..908007a0e 100644
--- a/navit/graphics/gd/graphics_gd.c
+++ b/navit/graphics/gd/graphics_gd.c
@@ -813,6 +813,8 @@ static struct graphics_methods graphics_methods = {
overlay_disable,
overlay_resize,
set_attr,
+ NULL, /* show_native_keyboard */
+ NULL, /* hide_native_keyboard */
};
static struct graphics_priv *
diff --git a/navit/graphics/gtk_drawing_area/graphics_gtk_drawing_area.c b/navit/graphics/gtk_drawing_area/graphics_gtk_drawing_area.c
index 9c7bdd511..9d6dd998b 100644
--- a/navit/graphics/gtk_drawing_area/graphics_gtk_drawing_area.c
+++ b/navit/graphics/gtk_drawing_area/graphics_gtk_drawing_area.c
@@ -1073,6 +1073,8 @@ static struct graphics_methods graphics_methods = {
overlay_disable,
overlay_resize,
set_attr,
+ NULL, /* show_native_keyboard */
+ NULL, /* hide_native_keyboard */
};
static struct graphics_priv *
diff --git a/navit/graphics/null/graphics_null.c b/navit/graphics/null/graphics_null.c
index e3d617af2..ce4dc6de2 100644
--- a/navit/graphics/null/graphics_null.c
+++ b/navit/graphics/null/graphics_null.c
@@ -236,6 +236,8 @@ static struct graphics_methods graphics_methods = {
get_text_bbox,
overlay_disable,
overlay_resize,
+ NULL, /* show_native_keyboard */
+ NULL, /* hide_native_keyboard */
};
static struct graphics_priv *
diff --git a/navit/graphics/opengl/graphics_opengl.c b/navit/graphics/opengl/graphics_opengl.c
index c927299dc..da82cd107 100644
--- a/navit/graphics/opengl/graphics_opengl.c
+++ b/navit/graphics/opengl/graphics_opengl.c
@@ -1432,6 +1432,8 @@ static struct graphics_methods graphics_methods = {
NULL,
overlay_disable,
overlay_resize,
+ NULL, /* show_native_keyboard */
+ NULL, /* hide_native_keyboard */
};
static struct graphics_priv *
diff --git a/navit/graphics/qt_qpainter/graphics_qt_qpainter.cpp b/navit/graphics/qt_qpainter/graphics_qt_qpainter.cpp
index 714f0753e..3a7509b0d 100644
--- a/navit/graphics/qt_qpainter/graphics_qt_qpainter.cpp
+++ b/navit/graphics/qt_qpainter/graphics_qt_qpainter.cpp
@@ -696,7 +696,8 @@ static struct graphics_methods graphics_methods = {
overlay_disable,
NULL,
set_attr,
-
+ NULL, /* show_native_keyboard */
+ NULL, /* hide_native_keyboard */
};
//##############################################################################################################
diff --git a/navit/graphics/sdl/graphics_sdl.c b/navit/graphics/sdl/graphics_sdl.c
index 886aacd3d..b0cc66776 100644
--- a/navit/graphics/sdl/graphics_sdl.c
+++ b/navit/graphics/sdl/graphics_sdl.c
@@ -907,6 +907,8 @@ static struct graphics_methods graphics_methods = {
overlay_disable,
NULL, /* overlay_resize */
NULL, /* set_attr */
+ NULL, /* show_native_keyboard */
+ NULL, /* hide_native_keyboard */
};
static struct graphics_priv *
diff --git a/navit/graphics/win32/graphics_win32.c b/navit/graphics/win32/graphics_win32.c
index 6ccf29564..609e61ce8 100644
--- a/navit/graphics/win32/graphics_win32.c
+++ b/navit/graphics/win32/graphics_win32.c
@@ -1582,6 +1582,8 @@ static struct graphics_methods graphics_methods =
get_text_bbox,
overlay_disable,
overlay_resize,
+ NULL, /* show_native_keyboard */
+ NULL, /* hide_native_keyboard */
};
diff --git a/navit/gui/internal/gui_internal.c b/navit/gui/internal/gui_internal.c
index 08066cbc4..a3a7b2994 100644
--- a/navit/gui/internal/gui_internal.c
+++ b/navit/gui/internal/gui_internal.c
@@ -743,9 +743,7 @@ gui_internal_call_linked_on_finish(struct gui_priv *this, struct widget *wm, voi
struct widget * gui_internal_keyboard(struct gui_priv *this, int mode);
-
-
-
+struct widget * gui_internal_keyboard_show_native(struct gui_priv *this, struct widget *w, int mode, char *lang);
static void
diff --git a/navit/gui/internal/gui_internal_bookmark.c b/navit/gui/internal/gui_internal_bookmark.c
index 21102ba1a..eed0de123 100644
--- a/navit/gui/internal/gui_internal_bookmark.c
+++ b/navit/gui/internal/gui_internal_bookmark.c
@@ -104,6 +104,8 @@ gui_internal_cmd_add_bookmark2(struct gui_priv *this, struct widget *wm, void *d
gui_internal_widget_append(w, wl);
if (this->keyboard)
gui_internal_widget_append(w, gui_internal_keyboard(this, VKBD_FLAG_2 | gui_internal_keyboard_init_mode(getenv("LANG"))));
+ else
+ gui_internal_keyboard_show_native(this, w, VKBD_FLAG_2 | gui_internal_keyboard_init_mode(getenv("LANG")), getenv("LANG"));
gui_internal_menu_render(this);
}
@@ -132,6 +134,8 @@ gui_internal_cmd_add_bookmark_folder2(struct gui_priv *this, struct widget *wm,
gui_internal_widget_append(w, wl);
if (this->keyboard)
gui_internal_widget_append(w, gui_internal_keyboard(this, VKBD_FLAG_2 | gui_internal_keyboard_init_mode(getenv("LANG"))));
+ else
+ gui_internal_keyboard_show_native(this, w, VKBD_FLAG_2 | gui_internal_keyboard_init_mode(getenv("LANG")), getenv("LANG"));
gui_internal_menu_render(this);
}
@@ -161,6 +165,8 @@ gui_internal_cmd_rename_bookmark(struct gui_priv *this, struct widget *wm, void
gui_internal_widget_append(w, wl);
if (this->keyboard)
gui_internal_widget_append(w, gui_internal_keyboard(this, VKBD_FLAG_2 | gui_internal_keyboard_init_mode(getenv("LANG"))));
+ else
+ gui_internal_keyboard_show_native(this, w, VKBD_FLAG_2 | gui_internal_keyboard_init_mode(getenv("LANG")), getenv("LANG"));
gui_internal_menu_render(this);
}
diff --git a/navit/gui/internal/gui_internal_command.c b/navit/gui/internal/gui_internal_command.c
index 98a736fb8..12de558fb 100644
--- a/navit/gui/internal/gui_internal_command.c
+++ b/navit/gui/internal/gui_internal_command.c
@@ -294,6 +294,8 @@ gui_internal_cmd_enter_coord(struct gui_priv *this, char *function, struct attr
if (this->keyboard)
gui_internal_widget_append(w, gui_internal_keyboard(this, VKBD_DEGREE));
+ else
+ gui_internal_keyboard_show_native(this, w, VKBD_DEGREE, NULL);
gui_internal_menu_render(this);
}
@@ -860,6 +862,8 @@ gui_internal_cmd_log(struct gui_priv *this)
gui_internal_widget_append(w, wl);
if (this->keyboard)
gui_internal_widget_append(w, gui_internal_keyboard(this, VKBD_FLAG_2 | gui_internal_keyboard_init_mode(getenv("LANG"))));
+ else
+ gui_internal_keyboard_show_native(this, w, VKBD_FLAG_2 | gui_internal_keyboard_init_mode(getenv("LANG")), getenv("LANG"));
gui_internal_menu_render(this);
gui_internal_leave(this);
}
diff --git a/navit/gui/internal/gui_internal_html.c b/navit/gui/internal/gui_internal_html.c
index 8350dbdcc..9b42fbdec 100644
--- a/navit/gui/internal/gui_internal_html.c
+++ b/navit/gui/internal/gui_internal_html.c
@@ -491,9 +491,12 @@ gui_internal_html_menu(struct gui_priv *this, const char *document, char *anchor
callback_list_call_attr_2(this->cbl,attr_gui,anchor,&doc);
gui_internal_html_parse_text(this, doc);
g_free(doc);
- if (this->keyboard_required && this->keyboard) {
+ if (this->keyboard_required) {
this->html_container->flags=gravity_center|orientation_vertical|flags_expand|flags_fill;
- gui_internal_widget_append(this->html_container, gui_internal_keyboard(this, VKBD_FLAG_2 | gui_internal_keyboard_init_mode(getenv("LANG"))));
+ if (this->keyboard)
+ gui_internal_widget_append(this->html_container, gui_internal_keyboard(this, VKBD_FLAG_2 | gui_internal_keyboard_init_mode(getenv("LANG"))));
+ else
+ gui_internal_keyboard_show_native(this, this->html_container, VKBD_FLAG_2 | gui_internal_keyboard_init_mode(getenv("LANG")), getenv("LANG"));
}
gui_internal_menu_render(this);
graphics_draw_mode(this->gra, draw_mode_end);
diff --git a/navit/gui/internal/gui_internal_keyboard.c b/navit/gui/internal/gui_internal_keyboard.c
index ea71eb593..8d85012ad 100644
--- a/navit/gui/internal/gui_internal_keyboard.c
+++ b/navit/gui/internal/gui_internal_keyboard.c
@@ -16,6 +16,9 @@ void
gui_internal_keyboard_to_upper_case(struct gui_priv *this)
{
struct menu_data *md;
+
+ if (!this->keyboard)
+ return;
md=gui_internal_menu_data(this);
// Switch to lowercase after the first key is pressed
if (md->keyboard_mode == 10) // Latin
@@ -30,6 +33,9 @@ void
gui_internal_keyboard_to_lower_case(struct gui_priv *this)
{
struct menu_data *md;
+
+ if (!this->keyboard)
+ return;
md=gui_internal_menu_data(this);
// Switch to lowercase after the first key is pressed
if (md->keyboard_mode == (VKBD_LATIN_UPPER | VKBD_FLAG_2)) // Latin
@@ -435,3 +441,100 @@ gui_internal_keyboard_init_mode(char *lang)
g_free(lang);
return ret;
}
+
+
+/**
+ * @brief Hides the platform's native on-screen keyboard or other input method
+ *
+ * This function is called as the {@code wfree} method of the placeholder widget for the platform's
+ * native on-screen keyboard. It is a wrapper around the corresponding method of the graphics plugin,
+ * which takes care of all platform-specific actions to hide the on-screen input method it previously
+ * displayed.
+ *
+ * A call to this function indicates that Navit no longer needs the input method and is about to destroy
+ * its placeholder widget. Navit will subsequently reclaim any screen real estate it may have previously
+ * reserved for the input method.
+ *
+ * This function will free the {@code struct graphics_keyboard} pointed to by {@code w->data}
+ *
+ * @param this The internal GUI instance
+ * @param w The placeholder widget
+ */
+void gui_internal_keyboard_hide_native(struct gui_priv *this_, struct widget *w) {
+ struct graphics_keyboard *kbd = (struct graphics_keyboard *) w->data;
+
+ if (kbd) {
+ graphics_hide_native_keyboard(this_->gra, kbd);
+ g_free(kbd->lang);
+ g_free(kbd->gui_priv);
+ } else
+ dbg(lvl_warning, "no graphics_keyboard found, cleanup failed\n");
+ g_free(w);
+}
+
+
+/**
+ * @brief Shows the platform's native on-screen keyboard or other input method
+ *
+ * This method is a wrapper around the corresponding method of the graphics plugin, which takes care of
+ * all platform-specific details. In particular, it is up to the graphics plugin to determine how to
+ * handle the request: it may show its on-screen keyboard or another input method (such as stroke
+ * recognition). It may choose to simply ignore the request, which will typically occur when a hardware
+ * keyboard (or other hardware input) is available.
+ *
+ * The platform's native input method may obstruct parts of Navit's UI. To prevent parts of the UI from
+ * becoming unreachable, this method will insert an empty box widget in the appropriate size at the
+ * appropriate position, provided the graphics plugin reports the correct values. Otherwise a zero-size
+ * widget is inserted. If the graphics driver decides not to display an on-screen input method, no
+ * widget will be created and the return value will be {@code NULL}.
+ *
+ * The widget's {@code wfree} function, to be called when the widget is destroyed, will be used to hide
+ * the platform keyboard when it is no longer needed.
+ *
+ * @param this The internal GUI instance
+ * @param w The parent of the widget requiring text input
+ * @param mode The requested keyboard mode
+ * @param lang The language for text input, used to select a keyboard layout
+ *
+ * @return The placeholder widget for the on-screen keyboard, may be {@code NULL}
+ */
+struct widget * gui_internal_keyboard_show_native(struct gui_priv *this, struct widget *w, int mode, char *lang) {
+ struct widget *ret = NULL;
+ struct menu_data *md = gui_internal_menu_data(this);
+ struct graphics_keyboard *kbd = g_new0(struct graphics_keyboard, 1);
+ int res;
+
+ kbd->mode = mode;
+ if (lang)
+ kbd->lang = g_strdup(lang);
+ res = graphics_show_native_keyboard(this->gra, kbd);
+
+ switch(res) {
+ case -1:
+ dbg(lvl_error, "graphics has no show_native_keyboard method, cannot display keyboard\n");
+ /* no break */
+ case 0:
+ g_free(kbd);
+ return NULL;
+ }
+
+ ret = gui_internal_box_new(this, gravity_center|orientation_horizontal_vertical|flags_fill);
+ md->keyboard = ret;
+ md->keyboard_mode=mode;
+ ret->wfree = gui_internal_keyboard_hide_native;
+ if (kbd->h < 0) {
+ ret->h = w->h;
+ ret->hmin = w->hmin;
+ } else
+ ret->h = kbd->h;
+ if (kbd->w < 0) {
+ ret->w = w->w;
+ ret->wmin = w->wmin;
+ } else
+ ret->w = kbd->w;
+ dbg(lvl_error, "ret->w=%d, ret->h=%d\n", ret->w, ret->h);
+ ret->data = (void *) kbd;
+ gui_internal_widget_append(w, ret);
+ dbg(lvl_error, "return\n");
+ return ret;
+}
diff --git a/navit/gui/internal/gui_internal_keyboard.h b/navit/gui/internal/gui_internal_keyboard.h
index 336ba2c01..9b9039224 100644
--- a/navit/gui/internal/gui_internal_keyboard.h
+++ b/navit/gui/internal/gui_internal_keyboard.h
@@ -24,6 +24,7 @@ struct gui_priv;
struct widget;
struct widget *gui_internal_keyboard_do(struct gui_priv *this, struct widget *wkbdb, int mode);
struct widget *gui_internal_keyboard(struct gui_priv *this, int mode);
+struct widget *gui_internal_keyboard_show_native(struct gui_priv *this, struct widget *w, int mode, char *lang);
int gui_internal_keyboard_init_mode(char *lang);
void gui_internal_keyboard_to_upper_case(struct gui_priv *this);
void gui_internal_keyboard_to_lower_case(struct gui_priv *this);
diff --git a/navit/gui/internal/gui_internal_poi.c b/navit/gui/internal/gui_internal_poi.c
index c3eed5e60..68ca67650 100644
--- a/navit/gui/internal/gui_internal_poi.c
+++ b/navit/gui/internal/gui_internal_poi.c
@@ -449,6 +449,7 @@ gui_internal_cmd_pois_filter_do(struct gui_priv *this, struct widget *wm, void *
{
struct widget *w=data;
struct poi_param *param;
+ GList *l;
if(!w->text)
return;
@@ -468,6 +469,9 @@ gui_internal_cmd_pois_filter_do(struct gui_priv *this, struct widget *wm, void *
gui_internal_poi_param_set_filter(param, w->text);
+ l = g_list_previous(g_list_last(this->root.children));
+ gui_internal_prune_menu(this, l->data);
+
gui_internal_cmd_pois(this,w,param);
gui_internal_poi_param_free(param);
}
@@ -533,6 +537,8 @@ gui_internal_cmd_pois_filter(struct gui_priv *this, struct widget *wm, void *dat
if (this->keyboard)
gui_internal_widget_append(w, gui_internal_keyboard(this, keyboard_mode));
+ else
+ gui_internal_keyboard_show_native(this, w, keyboard_mode, getenv("LANG"));
gui_internal_menu_render(this);
diff --git a/navit/gui/internal/gui_internal_search.c b/navit/gui/internal/gui_internal_search.c
index a0d6a3b2e..262559c14 100644
--- a/navit/gui/internal/gui_internal_search.c
+++ b/navit/gui/internal/gui_internal_search.c
@@ -212,6 +212,9 @@ gui_internal_highlight_possible_keys(struct gui_priv *this, char *possible_keys)
{
struct menu_data *md;
+ if (!this->keyboard)
+ return;
+
md=gui_internal_menu_data(this);
if (md && md->keyboard && !(this->flags & 2048)) {
GList *lk=md->keyboard->children;
@@ -570,6 +573,8 @@ gui_internal_search(struct gui_priv *this, const char *what, const char *type, i
wk->name=g_strdup(type);
if (this->keyboard)
gui_internal_widget_append(w, gui_internal_keyboard(this, keyboard_mode));
+ else
+ gui_internal_keyboard_show_native(this, w, keyboard_mode, getenv("LANG"));
gui_internal_menu_render(this);
}