|
From: <ka...@us...> - 2009-11-13 11:53:14
|
Revision: 2938
http://ede.svn.sourceforge.net/ede/?rev=2938&view=rev
Author: karijes
Date: 2009-11-13 11:53:02 +0000 (Fri, 13 Nov 2009)
Log Message:
-----------
Call ede-keyboard-conf when clicked on applet.
Let ede-keyboard-conf uses setxkbmap for setting changes.
ede-desktop foreign callback addopted for latest modification in edelib.
ede-conf will display keyboard configuration.
Modified Paths:
--------------
trunk/ede2/ede-conf/ede-conf.conf
trunk/ede2/ede-desktop/ede-desktop.cpp
trunk/ede2/ede-keyboard-conf/ede-keyboard-conf.cpp
trunk/ede2/ede-panel/applets/keyboard-layout/KeyLayout.cpp
Modified: trunk/ede2/ede-conf/ede-conf.conf
===================================================================
--- trunk/ede2/ede-conf/ede-conf.conf 2009-11-13 11:47:30 UTC (rev 2937)
+++ trunk/ede2/ede-conf/ede-conf.conf 2009-11-13 11:53:02 UTC (rev 2938)
@@ -1,26 +1,32 @@
[EdeConf]
- items = ede-desktop-conf,ede-screensaver-conf,ede-timedate, ede-bell-conf
+ items = ede-desktop-conf,ede-screensaver-conf,ede-timedate,ede-bell-conf,ede-keyboard-conf
[ede-desktop-conf]
- name = Configure background and icons
- tip = This item will configure desktop background and icons
+ name = Background and icons
+ tip = This item will configure desktop background and icons
exec = ede-desktop-conf
icon = preferences-desktop-wallpaper
[ede-screensaver-conf]
- name = Configure screensaver
- tip = This item will setup screensaver settings
+ name = Screensaver
+ tip = This item will setup screensaver settings
exec = ede-screensaver-conf
icon = preferences-desktop-screensaver
[ede-timedate]
- name = Configure time and date
- tip = This item will configure system date and time
+ name = Time and date
+ tip = This item will configure system date and time
exec = ede-timedate
icon = preferences-date-time
[ede-bell-conf]
- name = Configure system bell
- tip = This item will configure system bell
+ name = System bell
+ tip = This item will configure system bell
exec = ede-bell-conf
icon = audio-volume-zero
+
+[ede-keyboard-conf]
+ name = Keyboard
+ tip = This item will configure keyboard preferences
+ exec = ede-keyboard-conf
+ icon = input-keyboard
Modified: trunk/ede2/ede-desktop/ede-desktop.cpp
===================================================================
--- trunk/ede2/ede-desktop/ede-desktop.cpp 2009-11-13 11:47:30 UTC (rev 2937)
+++ trunk/ede2/ede-desktop/ede-desktop.cpp 2009-11-13 11:53:02 UTC (rev 2938)
@@ -107,7 +107,7 @@
Desktop::instance()->dir_watch(dir, changed, flags);
}
-static void settings_changed_cb(Fl_Window* win) {
+static void settings_changed_cb(Fl_Window *win, void *data) {
Desktop::instance()->read_config();
Desktop::instance()->redraw();
}
@@ -142,7 +142,7 @@
do_dirwatch = true;
#ifdef USE_EDELIB_WINDOW
- edelib::foreign_callback_add(this, settings_changed_cb, "ede-desktop");
+ edelib::foreign_callback_add(this, "ede-desktop", settings_changed_cb);
/* DESKTOP_WINDOW::single_bufer(true); */
#endif
Modified: trunk/ede2/ede-keyboard-conf/ede-keyboard-conf.cpp
===================================================================
--- trunk/ede2/ede-keyboard-conf/ede-keyboard-conf.cpp 2009-11-13 11:47:30 UTC (rev 2937)
+++ trunk/ede2/ede-keyboard-conf/ede-keyboard-conf.cpp 2009-11-13 11:53:02 UTC (rev 2938)
@@ -33,12 +33,22 @@
#include <edelib/Debug.h>
#include <edelib/String.h>
#include <edelib/Resource.h>
+#include <edelib/File.h>
+#include <edelib/Run.h>
+#include <edelib/MessageBox.h>
+#include <edelib/ForeignCallback.h>
-#define CONFIG_NAME "ede-keyboard"
+#define CONFIG_NAME "ede-keyboard"
+#define PANEL_APPLET_ID "ede-keyboard"
+#define DEFAULT_X_LAYOUT "us"
EDELIB_NS_USING_AS(Window, AppWindow)
EDELIB_NS_USING(String)
EDELIB_NS_USING(Resource)
+EDELIB_NS_USING(file_path)
+EDELIB_NS_USING(run_sync)
+EDELIB_NS_USING(alert)
+EDELIB_NS_USING(foreign_callback_call)
static AppWindow *win;
static Fl_Hold_Browser *layout_browser;
@@ -79,23 +89,20 @@
dialog_canceled = false;
}
-static void fetch_current_layout(String &ret, String &rules_file_ret) {
- char *tmp = NULL;
- XkbRF_VarDefsRec vd;
+static void fetch_current_layout(String ¤t) {
+ char *rules_file;
+ XkbRF_VarDefsRec vd;
- E_ASSERT(fl_display != NULL);
-
/* get the layout straight from X since the layout can be changed during X session */
- if(!XkbRF_GetNamesProp(fl_display, &tmp, &vd) || !vd.layout)
- return;
+ if(!XkbRF_GetNamesProp(fl_display, &rules_file, &vd)) {
+ /* use some values */
+ current = DEFAULT_X_LAYOUT;
+ } else {
+ current = vd.layout;
+ }
- ret = vd.layout;
-
- /* remember rules filename too (on X.org is 'xorg')*/
- rules_file_ret = tmp;
-
- /* manually free each member */
- XFree(tmp);
+ /* free everything */
+ XFree(rules_file);
XFree(vd.layout);
XFree(vd.model);
XFree(vd.options);
@@ -164,31 +171,63 @@
r.save(CONFIG_NAME);
}
-static void apply_layout_on_x(const String &layout, const String &rules_filename) {
- XkbRF_VarDefsRec vd;
- vd.layout = (char*)layout.c_str();
-
+static void apply_changes_on_x(const char *current) {
/*
- * rest fields must be zero-fied to prevent crash
- * FIXME: will this change other fields???
+ * believe me, it is easier to call this command than to reimplmement a mess for
+ * uploading keyboard layout on X server!
*/
- vd.model = NULL;
- vd.options = NULL;
- vd.variant = NULL;
+ String setxkbmap = file_path("setxkbmap");
+ if(setxkbmap.empty()) {
+ alert(_("Unable to find 'setxkbmap' tool.\n\nThis tool is used as helper tool for "
+ "easier keyboard setup and is standard tool shipped with every X package. "
+ "Please install it first and run this program again."));
+ } else {
+ int ret = run_sync("%s %s", setxkbmap.c_str(), current);
+ /* do not show dialog since we can fail if config has bad entry when called from apply_chages_from_config() */
+ if(ret != 0)
+ E_WARNING(E_STRLOC ": 'setxkbmap %s' failed with %i\n", current, ret);
+ }
- if(XkbRF_SetNamesProp(fl_display, (char*)rules_filename.c_str(), &vd) != True)
- E_WARNING(E_STRLOC ": Failed to update XKB rules\n");
+ if(repeat_press->value())
+ XAutoRepeatOn(fl_display);
else
- XSync(fl_display, False);
+ XAutoRepeatOff(fl_display);
+
+ /* force panel applet to re-read config file to see if flag should be displayed or not*/
+ foreign_callback_call(PANEL_APPLET_ID);
+ XFlush(fl_display);
}
+static void apply_chages_from_config(void) {
+ Resource r;
+ if(!r.load(CONFIG_NAME))
+ return;
+
+ char buf[32];
+ if(!r.get("Keyboard", "layout", buf, sizeof(buf)))
+ return;
+
+ /* TODO: this should be validated somehow */
+ apply_changes_on_x(buf);
+}
+
int main(int argc, char **argv) {
- String cl, rules_filename;
+ /* must be opened first */
+ fl_open_display();
- /* needed for fetch_current_layout() and '--apply' */
- fl_open_display();
+ /* only apply what was written in config */
+ if(argc > 1 && strcmp(argv[1], "--apply") == 0) {
+ apply_chages_from_config();
+ return 0;
+ }
+
+ String cl;
dialog_canceled = false;
+ /* get layout X holds */
+ fetch_current_layout(cl);
+
+ /* construct GUI */
win = new AppWindow(340, 320, _("Keyboard configuration tool"));
win->begin();
Fl_Tabs *tabs = new Fl_Tabs(10, 10, 320, 265);
@@ -230,12 +269,9 @@
cancel_button->callback(cancel_cb);
win->end();
- /* read layouts */
- XkbRF_RulesPtr xkb_rules;
+ /* read all XKB layouts */
+ XkbRF_RulesPtr xkb_rules = fetch_all_layouts(cl);
- fetch_current_layout(cl, rules_filename);
- xkb_rules = fetch_all_layouts(cl);
-
/* read configuration */
read_config();
@@ -249,7 +285,7 @@
char *n = xkb_rules->layouts.desc[i - 1].name;
save_config(n);
- apply_layout_on_x(n, rules_filename);
+ apply_changes_on_x(n);
}
if(xkb_rules)
Modified: trunk/ede2/ede-panel/applets/keyboard-layout/KeyLayout.cpp
===================================================================
--- trunk/ede2/ede-panel/applets/keyboard-layout/KeyLayout.cpp 2009-11-13 11:47:30 UTC (rev 2937)
+++ trunk/ede2/ede-panel/applets/keyboard-layout/KeyLayout.cpp 2009-11-13 11:53:02 UTC (rev 2938)
@@ -16,20 +16,34 @@
#include <edelib/List.h>
#include <edelib/Directory.h>
#include <edelib/Nls.h>
+#include <edelib/Run.h>
+#include <edelib/ForeignCallback.h>
+/* they should match names in ede-keyboard-conf */
+#define PANEL_APPLET_ID "ede-keyboard"
+#define CONFIG_NAME "ede-keyboard"
+
EDELIB_NS_USING(Resource)
EDELIB_NS_USING(String)
EDELIB_NS_USING(list)
+EDELIB_NS_USING(run_async)
+EDELIB_NS_USING(foreign_callback_add)
+EDELIB_NS_USING(foreign_callback_remove)
EDELIB_NS_USING(RES_SYS_ONLY)
static Atom _XA_XKB_RF_NAMES_PROP_ATOM = 0;
class KeyLayout : public Fl_Button {
private:
- String path, curr_layout;
+ bool should_show_flag;
+ String path, curr_layout;
+ Fl_Image *img;
+
public:
KeyLayout();
- void do_key_layout(void);
+ ~KeyLayout();
+ void update_flag(bool read_config);
+ void do_key_layout();
int handle(int e);
};
@@ -47,29 +61,53 @@
XFree(vd.variant);
}
+/*
+ * any layout changes on X will be reported here, executed either via ede-keyboard-conf or
+ * another tool, so there are no needs to read layout from configuration file
+ */
static int xkb_events(int e) {
if(fl_xevent->xproperty.atom == _XA_XKB_RF_NAMES_PROP_ATOM) {
/* TODO: lock this */
KeyLayoutListIt it = keylayout_objects.begin(), it_end = keylayout_objects.end();
- for(; it != it_end; ++it)
+ for(; it != it_end; ++it) {
(*it)->do_key_layout();
+ (*it)->update_flag(false);
+ }
}
return 0;
}
+static void click_cb(Fl_Widget*, void*) {
+ run_async("ede-keyboard-conf");
+}
+
+static void update_flag_cb(Fl_Window*, void *data) {
+ KeyLayout *k = (KeyLayout*)data;
+ k->update_flag(true);
+ k->redraw();
+}
+
KeyLayout::KeyLayout() : Fl_Button(0, 0, 30, 25) {
+ should_show_flag = true;
+ curr_layout = "us"; /* default layout */
+ img = NULL;
+
box(FL_FLAT_BOX);
labelfont(FL_HELVETICA_BOLD);
labelsize(10);
label("??");
+ align(FL_ALIGN_CLIP);
tooltip(_("Current keyboard layout"));
+ callback(click_cb);
+ foreign_callback_add(window(), PANEL_APPLET_ID, update_flag_cb, this);
path = Resource::find_data("icons/kbflags/21x14", RES_SYS_ONLY, NULL);
do_key_layout();
+ update_flag(true);
/* TODO: lock this */
keylayout_objects.push_back(this);
@@ -81,6 +119,42 @@
Fl::add_handler(xkb_events);
}
+KeyLayout::~KeyLayout() {
+ foreign_callback_remove(update_flag_cb);
+}
+
+void KeyLayout::update_flag(bool read_config) {
+ if(read_config) {
+ Resource r;
+
+ if(r.load(CONFIG_NAME))
+ r.get("Keyboard", "show_country_flag", should_show_flag, true);
+ }
+
+ /* remove previous image if we aren't going to show it */
+ if(!should_show_flag)
+ img = NULL;
+
+ if(should_show_flag && !path.empty()) {
+ /* construct image path that has the same name as layout */
+ String full_path = path;
+
+ full_path += E_DIR_SEPARATOR_STR;
+ full_path += curr_layout;
+ full_path += ".png";
+
+ img = Fl_Shared_Image::get(full_path.c_str());
+ }
+
+ image(img);
+
+ if(img)
+ label(NULL);
+ else
+ label(curr_layout.c_str());
+ redraw();
+}
+
void KeyLayout::do_key_layout(void) {
char *tmp = NULL;
XkbRF_VarDefsRec vd;
@@ -92,31 +166,10 @@
if(!vd.layout || (curr_layout == vd.layout))
return;
+ /* just store it, so update_flag() can do the rest */
curr_layout = vd.layout;
-
- if(!path.empty()) {
- /* construct image path that has the same name as layout */
- String full_path = path;
-
- full_path += E_DIR_SEPARATOR_STR;
- full_path += curr_layout;
- full_path += ".png";
-
- img = Fl_Shared_Image::get(full_path.c_str());
- }
-
- if(img) {
- image(img);
- label(NULL);
- } else {
- image(NULL);
- label(curr_layout.c_str());
- }
-
xkbrf_names_prop_free(vd, tmp);
}
-
- redraw();
}
int KeyLayout::handle(int e) {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|