Index: trunk/doc/TODO =================================================================== --- trunk/doc/TODO (revision 34601) +++ trunk/doc/TODO (revision 34602) @@ -10,7 +10,8 @@ - get() should return an allocated string - there should be a free() to be used by the caller after get() - DEL?: rethink hid api beep() - sounds like a real bad idea - gabor's idea: configurable external command - - split hid.so and core.so? + - split hid.so and core.so! + - test message log export - both action-with-filename-fmt and gui - *FEATURE: sch-rnd critical: more flexilble unit system where apps can register new units - remove k from librnd, revise sch-rnd grid menu - split the unit table in two, one librnd, one app - families should be registered Index: trunk/src/Makefile.dep =================================================================== --- trunk/src/Makefile.dep (revision 34601) +++ trunk/src/Makefile.dep (revision 34602) @@ -32,9 +32,9 @@ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/safe_fs.h \ ../src/librnd/core/safe_fs_dir.h ../src/librnd/core/compat_inc.h ../src/librnd/core/hidlib.h \ - ../src/librnd/core/event.h ../src/librnd/core/paths.h ../src/librnd/core/hid.h \ + ../src/librnd/core/event.h ../src/librnd/core/paths.h ../src/librnd/hid/hid.h \ ../src/librnd/core/box.h ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h \ - ../src/librnd/core/hid_init.h ../src_3rd/puplug/puplug.h \ + ../src/librnd/hid/hid_init.h ../src_3rd/puplug/puplug.h \ ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ ../src/librnd/core/hidlib_conf.h ../src/librnd/core/color.h \ @@ -69,10 +69,10 @@ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/genvector/vtp0.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ - ../src_3rd/genlist/gendlist.h ../src/librnd/core/hid_init.h \ + ../src_3rd/genlist/gendlist.h ../src/librnd/hid/hid_init.h \ ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ - ../src_3rd/puplug/libs.h ../src/librnd/core/hid.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/puplug/libs.h ../src/librnd/hid/hid.h ../src_3rd/libfungw/fungw.h \ ../src_3rd/genht/htpp.h ../src/librnd/core/error.h ../src/librnd/core/box.h \ ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/compat_lrealpath.o: \ @@ -99,9 +99,9 @@ ../src/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ ../src/librnd/core/globalconst.h ../src/librnd/core/color.h ../src/librnd/core/conf_hid.h \ - ../src/librnd/core/error.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid.h \ + ../src/librnd/core/error.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/box.h \ - ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/hid/hid_menu.h \ ../src/librnd/core/paths.h ../src/librnd/core/compat_fs.h ../src/librnd/core/compat_misc.h \ ../src/librnd/core/safe_fs.h ../src/librnd/core/file_loaded.h ../src/librnd/core/hidlib.h \ ../src/librnd/core/fptr_cast.h ../src/librnd/core/safe_fs_dir.h \ @@ -123,8 +123,8 @@ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h \ ../src/librnd/core/funchash_core.h ../src/librnd/core/funchash.h \ - ../src/librnd/core/funchash_core_list.h ../src/librnd/core/tool.h ../src/librnd/core/hidlib.h \ - ../src/librnd/core/grid.h ../src/librnd/core/compat_misc.h ../src/librnd/core/misc_util.h + ../src/librnd/core/funchash_core_list.h ../src/librnd/hid/tool.h ../src/librnd/core/hidlib.h \ + ../src/librnd/hid/grid.h ../src/librnd/core/compat_misc.h ../src/librnd/core/misc_util.h ../src/librnd/core/conf_hid.o: ../src/librnd/core/conf_hid.c \ ../src/librnd/rnd_config.h ../src/librnd/config.h ../src/librnd/core/conf_hid.h \ ../src/librnd/core/conf.h ../src/librnd/config.h ../src/librnd/core/global_typedefs.h \ @@ -144,17 +144,17 @@ ../src/librnd/core/global_typedefs.h ../src/librnd/config.h ../src/librnd/core/rnd_bool.h \ ../src/librnd/core/error.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src_3rd/genht/htpp.h ../src/librnd/core/event.h \ - ../src/librnd/core/unit.h ../src/librnd/core/hidlib.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_attrib.h \ - ../src_3rd/genlist/gendlist.h ../src/librnd/core/hid.h \ + ../src/librnd/core/unit.h ../src/librnd/core/hidlib.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/hid/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src/librnd/core/box.h \ ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/color.h \ ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h ../src/librnd/core/hid_cfg.h \ - ../src/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src/librnd/hid/hid_menu.h ../src_3rd/genvector/vtp0.h \ ../src/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ - ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/safe_fs.h ../src/librnd/core/conf.h \ + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/safe_fs.h ../src/librnd/core/conf.h \ ../src_3rd/liblihata/lihata.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/hidlib_conf.h @@ -181,7 +181,7 @@ ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h ../src/librnd/core/unit.h \ ../src/librnd/core/global_typedefs.h ../src/librnd/config.h ../src/librnd/core/rnd_bool.h \ - ../src/librnd/core/grid.h ../src/librnd/core/conf.h ../src/librnd/core/rnd_printf.h \ + ../src/librnd/hid/grid.h ../src/librnd/core/conf.h ../src/librnd/core/rnd_printf.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ @@ -193,20 +193,20 @@ ../src/librnd/core/heap.o: ../src/librnd/core/heap.c ../src/librnd/rnd_config.h \ ../src/librnd/config.h ../src/librnd/core/heap.h ../src/librnd/config.h ../src/librnd/core/hid.o: ../src/librnd/core/hid.c ../src/librnd/rnd_config.h \ - ../src/librnd/config.h ../src/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/config.h ../src/librnd/hid/hid.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/config.h \ ../src/librnd/core/error.h ../src/librnd/core/global_typedefs.h ../src/librnd/core/rnd_bool.h \ ../src/librnd/core/box.h ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h \ - ../src/librnd/core/unit.h ../src/librnd/core/hid_menu.h ../src/librnd/core/hid_cfg.h \ - ../src/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src/librnd/core/unit.h ../src/librnd/hid/hid_menu.h ../src/librnd/core/hid_cfg.h \ + ../src/librnd/hid/hid_menu.h ../src_3rd/genvector/vtp0.h \ ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h ../src/librnd/core/event.h \ ../src/librnd/core/hidlib.h ../src/librnd/core/hid_attrib.o: ../src/librnd/core/hid_attrib.c \ - ../src/librnd/rnd_config.h ../src/librnd/config.h ../src/librnd/core/hid_attrib.h \ - ../src_3rd/genlist/gendlist.h ../src/librnd/core/hid.h \ + ../src/librnd/rnd_config.h ../src/librnd/config.h ../src/librnd/hid/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src_3rd/libfungw/fungw.h \ @@ -221,11 +221,11 @@ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src/librnd/rnd_config.h ../src/librnd/config.h \ - ../src/librnd/core/hid.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + ../src/librnd/hid/hid.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ ../src/librnd/config.h ../src/librnd/core/error.h ../src/librnd/core/global_typedefs.h \ ../src/librnd/core/rnd_bool.h ../src/librnd/core/box.h ../src/librnd/core/math_helper.h \ ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h ../src/librnd/core/hid_cfg.h \ - ../src/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src/librnd/hid/hid_menu.h ../src_3rd/genvector/vtp0.h \ ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h ../src/librnd/core/safe_fs.h \ ../src/librnd/core/conf.h ../src/librnd/core/rnd_printf.h \ @@ -239,9 +239,9 @@ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src/librnd/core/global_typedefs.h ../src/librnd/config.h ../src/librnd/core/rnd_bool.h \ - ../src/librnd/core/hid.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + ../src/librnd/hid/hid.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ ../src/librnd/core/error.h ../src/librnd/core/box.h ../src/librnd/core/math_helper.h \ - ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h ../src/librnd/hid/hid_menu.h \ ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h ../src/librnd/core/actions.h \ ../src_3rd/liblihata/tree.h @@ -253,12 +253,12 @@ ../src_3rd/genht/ht_utils.h ../src_3rd/genvector/gds_char.h \ ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h ../src/librnd/rnd_config.h \ - ../src/librnd/config.h ../src/librnd/core/hid_cfg_input.h ../src_3rd/genht/htip.h \ + ../src/librnd/config.h ../src/librnd/hid/hid_cfg_input.h ../src_3rd/genht/htip.h \ ../src_3rd/genht/htpp.h ../src/librnd/core/hid_cfg.h \ ../src/librnd/core/global_typedefs.h ../src/librnd/config.h ../src/librnd/core/rnd_bool.h \ - ../src/librnd/core/hid.h ../src_3rd/libfungw/fungw.h ../src/librnd/core/error.h \ + ../src/librnd/hid/hid.h ../src_3rd/libfungw/fungw.h ../src/librnd/core/error.h \ ../src/librnd/core/box.h ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h \ - ../src/librnd/core/unit.h ../src/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src/librnd/core/unit.h ../src/librnd/hid/hid_menu.h ../src_3rd/genvector/vtp0.h \ ../src/librnd/core/hid_cfg_action.h ../src/librnd/core/hidlib_conf.h \ ../src/librnd/core/conf.h ../src/librnd/core/rnd_printf.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ @@ -265,9 +265,9 @@ ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h \ ../src/librnd/core/compat_misc.h ../src/librnd/core/event.h ../src/librnd/core/hidlib.h ../src/librnd/core/hid_dad.o: ../src/librnd/core/hid_dad.c \ - ../src/librnd/rnd_config.h ../src/librnd/config.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/config.h ../src/librnd/core/hid_attrib.h \ - ../src_3rd/genlist/gendlist.h ../src/librnd/core/hid.h \ + ../src/librnd/rnd_config.h ../src/librnd/config.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/config.h ../src/librnd/hid/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src_3rd/libfungw/fungw.h \ @@ -276,12 +276,12 @@ ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h \ ../src/librnd/core/color.h ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h ../src/librnd/core/hid_cfg.h \ - ../src/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src/librnd/hid/hid_menu.h ../src_3rd/genvector/vtp0.h \ ../src/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ - ../src/librnd/core/hid_dad_spin.h + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/hid_dad_spin.o: ../src/librnd/core/hid_dad_spin.c \ - ../src/librnd/rnd_config.h ../src/librnd/config.h ../src/librnd/core/hid_attrib.h \ - ../src_3rd/genlist/gendlist.h ../src/librnd/core/hid.h \ + ../src/librnd/rnd_config.h ../src/librnd/config.h ../src/librnd/hid/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src_3rd/libfungw/fungw.h \ @@ -289,17 +289,17 @@ ../src/librnd/core/global_typedefs.h ../src/librnd/core/rnd_bool.h ../src/librnd/core/box.h \ ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h \ ../src/librnd/core/color.h ../src_3rd/genvector/genvector_impl.h \ - ../src_3rd/genvector/genvector_undef.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h \ + ../src_3rd/genvector/genvector_undef.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h \ ../src_3rd/genvector/vtp0.h ../src/librnd/core/rnd_printf.h \ - ../src_3rd/genvector/gds_char.h ../src/librnd/core/hid_dad_spin.h \ - ../src/librnd/core/hid_dad_unit.h ../src/librnd/core/hidlib_conf.h ../src/librnd/core/conf.h \ + ../src_3rd/genvector/gds_char.h ../src/librnd/hid/hid_dad_spin.h \ + ../src/librnd/hid/hid_dad_unit.h ../src/librnd/core/hidlib_conf.h ../src/librnd/core/conf.h \ ../src_3rd/liblihata/lihata.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/hid_dad_tree.o: ../src/librnd/core/hid_dad_tree.c \ - ../src/librnd/rnd_config.h ../src/librnd/config.h ../src/librnd/core/hid_dad_tree.h \ - ../src/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h ../src/librnd/core/hid.h \ + ../src/librnd/rnd_config.h ../src/librnd/config.h ../src/librnd/hid/hid_dad_tree.h \ + ../src/librnd/hid/hid_attrib.h ../src_3rd/genlist/gendlist.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src_3rd/libfungw/fungw.h \ @@ -307,14 +307,14 @@ ../src/librnd/core/global_typedefs.h ../src/librnd/core/rnd_bool.h ../src/librnd/core/box.h \ ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h \ ../src/librnd/core/color.h ../src_3rd/genvector/genvector_impl.h \ - ../src_3rd/genvector/genvector_undef.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h \ + ../src_3rd/genvector/genvector_undef.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h \ ../src_3rd/genvector/vtp0.h ../src/librnd/core/rnd_printf.h \ - ../src_3rd/genvector/gds_char.h ../src/librnd/core/hid_dad_spin.h \ + ../src_3rd/genvector/gds_char.h ../src/librnd/hid/hid_dad_spin.h \ ../src_3rd/genht/hash.h ../src/librnd/core/hid_dad_unit.o: ../src/librnd/core/hid_dad_unit.c \ - ../src/librnd/rnd_config.h ../src/librnd/config.h ../src/librnd/core/hid_attrib.h \ - ../src_3rd/genlist/gendlist.h ../src/librnd/core/hid.h \ + ../src/librnd/rnd_config.h ../src/librnd/config.h ../src/librnd/hid/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src_3rd/libfungw/fungw.h \ @@ -322,54 +322,54 @@ ../src/librnd/core/global_typedefs.h ../src/librnd/core/rnd_bool.h ../src/librnd/core/box.h \ ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h \ ../src/librnd/core/color.h ../src_3rd/genvector/genvector_impl.h \ - ../src_3rd/genvector/genvector_undef.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h \ + ../src_3rd/genvector/genvector_undef.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h \ ../src_3rd/genvector/vtp0.h ../src/librnd/core/rnd_printf.h \ - ../src_3rd/genvector/gds_char.h ../src/librnd/core/hid_dad_spin.h \ - ../src/librnd/core/hid_dad_unit.h + ../src_3rd/genvector/gds_char.h ../src/librnd/hid/hid_dad_spin.h \ + ../src/librnd/hid/hid_dad_unit.h ../src/librnd/core/hid_dlg.o: ../src/librnd/core/hid_dlg.c \ ../src/librnd/rnd_config.h ../src/librnd/config.h ../src/librnd/core/actions.h \ ../src/librnd/core/global_typedefs.h ../src/librnd/config.h ../src/librnd/core/rnd_bool.h \ ../src/librnd/core/error.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src_3rd/genht/htpp.h ../src/librnd/core/event.h \ - ../src/librnd/core/unit.h ../src/librnd/core/hidlib.h ../src/librnd/core/hid.h \ + ../src/librnd/core/unit.h ../src/librnd/core/hidlib.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src/librnd/core/box.h \ - ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_attrib.h \ + ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/hid/hid_attrib.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h \ ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h ../src/librnd/core/hid_cfg.h \ - ../src/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src/librnd/hid/hid_menu.h ../src_3rd/genvector/vtp0.h \ ../src/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ - ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/hid_nogui.h + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/hid/hid_nogui.h ../src/librnd/core/hid_init.o: ../src/librnd/core/hid_init.c \ ../src/librnd/rnd_config.h ../src/librnd/config.h ../src_3rd/genvector/vts0.h \ ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h ../src_3rd/puplug/os_dep_fs.h \ - ../src/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/hid/hid.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/config.h \ ../src/librnd/core/error.h ../src/librnd/core/global_typedefs.h ../src/librnd/core/rnd_bool.h \ ../src/librnd/core/box.h ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h \ - ../src/librnd/core/unit.h ../src/librnd/core/hid_nogui.h ../src/librnd/core/event.h \ + ../src/librnd/core/unit.h ../src/librnd/hid/hid_nogui.h ../src/librnd/core/event.h \ ../src/librnd/core/hidlib.h ../src/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ - ../src_3rd/puplug/error.h ../src/librnd/core/actions.h ../src/librnd/core/hid_attrib.h \ - ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h ../src/librnd/core/hid_init.h \ - ../src_3rd/genvector/vtp0.h ../src/librnd/core/hid_dad_unit.h \ - ../src/librnd/core/hid_dad.h ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_cfg.h \ - ../src/librnd/core/hid_menu.h ../src/librnd/core/rnd_printf.h \ - ../src_3rd/genvector/gds_char.h ../src/librnd/core/hid_dad_spin.h \ + ../src_3rd/puplug/error.h ../src/librnd/core/actions.h ../src/librnd/hid/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h ../src/librnd/hid/hid_init.h \ + ../src_3rd/genvector/vtp0.h ../src/librnd/hid/hid_dad_unit.h \ + ../src/librnd/hid/hid_dad.h ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_cfg.h \ + ../src/librnd/hid/hid_menu.h ../src/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src/librnd/hid/hid_dad_spin.h \ ../src/librnd/core/compat_inc.h ../src/librnd/core/compat_fs.h \ ../src/librnd/core/file_loaded.h ../src/librnd/core/hidlib_conf.h ../src/librnd/core/conf.h \ ../src_3rd/liblihata/lihata.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ - ../src_3rd/genlist/gendlist.h ../src/librnd/core/grid.h ../src/librnd/core/funchash.h \ - ../src/librnd/core/hid_menu.h ../src/librnd/core/compat_lrealpath.h \ - ../src/librnd/core/safe_fs.h ../src/librnd/core/buildin.hidlib.h ../src/librnd/core/tool.h \ + ../src_3rd/genlist/gendlist.h ../src/librnd/hid/grid.h ../src/librnd/core/funchash.h \ + ../src/librnd/hid/hid_menu.h ../src/librnd/core/compat_lrealpath.h \ + ../src/librnd/core/safe_fs.h ../src/librnd/core/buildin.hidlib.h ../src/librnd/hid/tool.h \ ../src/librnd/core/../../../config.h ../src/librnd/core/hid_menu.o: ../src/librnd/core/hid_menu.c \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/tree.h \ @@ -392,14 +392,14 @@ ../src/librnd/core/funchash_core_list.h ../src/librnd/core/compat_misc.h \ ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ ../src/librnd/core/conf_hid.h ../src/librnd/core/safe_fs.h \ - ../src/librnd/core/hid_menu.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid.h \ + ../src/librnd/hid/hid_menu.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid.h \ ../src/librnd/core/box.h ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h \ - ../src/librnd/core/hid_menu.h + ../src/librnd/hid/hid_menu.h ../src/librnd/core/hid_nogui.o: ../src/librnd/core/hid_nogui.c \ ../src/librnd/rnd_config.h ../src/librnd/config.h ../src/librnd/core/actions.h \ ../src/librnd/core/global_typedefs.h ../src/librnd/config.h ../src/librnd/core/rnd_bool.h \ ../src/librnd/core/error.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htsp.h \ - ../src_3rd/genht/ht.h ../src_3rd/genht/htpp.h ../src/librnd/core/hid.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/htpp.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src/librnd/core/box.h \ ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h \ @@ -421,7 +421,7 @@ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/genvector/vtp0.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ - ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h ../src/librnd/core/tool.h \ + ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h ../src/librnd/hid/tool.h \ ../src/librnd/core/event.h ../src/librnd/core/hidlib.h ../src/librnd/core/error.h ../src/librnd/core/hidlib_conf.o: ../src/librnd/core/hidlib_conf.c \ ../src/librnd/rnd_config.h ../src/librnd/config.h ../src/librnd/core/conf.h ../src/librnd/config.h \ @@ -435,7 +435,7 @@ ../src_3rd/genvector/vtp0.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/error.h ../src/librnd/core/color.h \ - ../src/librnd/core/hidlib.h ../src/librnd/core/hid.h ../src_3rd/libfungw/fungw.h \ + ../src/librnd/core/hidlib.h ../src/librnd/hid/hid.h ../src_3rd/libfungw/fungw.h \ ../src_3rd/genht/htpp.h ../src/librnd/core/box.h ../src/librnd/core/math_helper.h \ ../src/librnd/core/misc_util.h ../src/librnd/core/hidlib_conf.h \ ../src/librnd/core/hidlib_conf_fields.h @@ -455,12 +455,12 @@ ../src/librnd/core/compat_misc.h ../src/librnd/core/actions.h \ ../src/librnd/core/global_typedefs.h ../src/librnd/core/rnd_bool.h ../src/librnd/core/error.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htsp.h \ - ../src_3rd/genht/ht.h ../src_3rd/genht/htpp.h ../src/librnd/core/hid_init.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/htpp.h ../src/librnd/hid/hid_init.h \ ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ ../src_3rd/puplug/libs.h ../src_3rd/genvector/vtp0.h \ ../src_3rd/genvector/genvector_impl.h \ - ../src_3rd/genvector/genvector_undef.h ../src/librnd/core/hid.h \ + ../src_3rd/genvector/genvector_undef.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src/librnd/core/box.h \ ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h \ @@ -481,10 +481,10 @@ ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h ../src/librnd/core/global_typedefs.h \ ../src/librnd/config.h ../src/librnd/core/rnd_bool.h ../src/librnd/core/error.h \ - ../src/librnd/core/hidlib.h ../src/librnd/core/hid_init.h ../src_3rd/puplug/puplug.h \ + ../src/librnd/core/hidlib.h ../src/librnd/hid/hid_init.h ../src_3rd/puplug/puplug.h \ ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ - ../src_3rd/genvector/vtp0.h ../src/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/genvector/vtp0.h ../src/librnd/hid/hid.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/box.h \ @@ -495,8 +495,8 @@ ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h ../src/librnd/core/pixmap.o: ../src/librnd/core/pixmap.c \ ../src/librnd/rnd_config.h ../src/librnd/config.h ../src_3rd/genht/hash.h \ - ../src/librnd/core/pixmap.h ../src/librnd/core/global_typedefs.h ../src/librnd/config.h \ - ../src/librnd/core/rnd_bool.h ../src/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/hid/pixmap.h ../src/librnd/core/global_typedefs.h ../src/librnd/config.h \ + ../src/librnd/core/rnd_bool.h ../src/librnd/hid/hid.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/error.h \ @@ -539,7 +539,7 @@ ../src/librnd/core/compat_fs.h ../src/librnd/core/compat_misc.h \ ../src/librnd/core/globalconst.h ../src/librnd/core/paths.h ../src/librnd/core/hidlib.h ../src/librnd/core/tool.o: ../src/librnd/core/tool.c ../src/librnd/rnd_config.h \ - ../src/librnd/config.h ../src/librnd/core/tool.h ../src_3rd/genvector/vtp0.h \ + ../src/librnd/config.h ../src/librnd/hid/tool.h ../src_3rd/genvector/vtp0.h \ ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h ../src/librnd/core/global_typedefs.h \ ../src/librnd/config.h ../src/librnd/core/rnd_bool.h ../src/librnd/core/hidlib_conf.h \ @@ -550,7 +550,7 @@ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h ../src/librnd/core/event.h \ - ../src/librnd/core/hidlib.h ../src/librnd/core/hid.h ../src_3rd/libfungw/fungw.h \ + ../src/librnd/core/hidlib.h ../src/librnd/hid/hid.h ../src_3rd/libfungw/fungw.h \ ../src_3rd/genht/htpp.h ../src/librnd/core/error.h ../src/librnd/core/box.h \ ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/actions.h \ ../src/librnd/core/compat_misc.h @@ -562,7 +562,7 @@ ../src_3rd/genvector/genvector_undef.h \ ../src_3rd/genvector/genvector_impl.c ../src/librnd/font/font.o: ../src/librnd/font/font.c ../config.h \ - ../src/librnd/config.h ../src/librnd/core/compat_misc.h ../src/librnd/core/hid.h \ + ../src/librnd/config.h ../src/librnd/core/compat_misc.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src_3rd/libfungw/fungw.h \ @@ -638,7 +638,7 @@ ../src_3rd/genlist/gendlist.h ../src/librnd/core/compat_misc.h ../src/librnd/plugins/hid_batch/batch.o: \ ../src/librnd/plugins/hid_batch/batch.c ../src/librnd/rnd_config.h \ - ../src/librnd/config.h ../src/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/config.h ../src/librnd/hid/hid.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/config.h \ @@ -655,8 +655,8 @@ ../src_3rd/liblihata/lihata.h ../src_3rd/genvector/vtp0.h \ ../src/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ - ../src/librnd/core/color.h ../src/librnd/core/hid_nogui.h ../src/librnd/core/actions.h \ - ../src/librnd/core/hid_init.h ../src/librnd/core/hid_attrib.h \ + ../src/librnd/core/color.h ../src/librnd/hid/hid_nogui.h ../src/librnd/core/actions.h \ + ../src/librnd/hid/hid_init.h ../src/librnd/hid/hid_attrib.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/plugins/hid_gtk2_gdk/gtkhid-gdk.o: \ ../src/librnd/plugins/hid_gtk2_gdk/gtkhid-gdk.c ../config.h \ @@ -670,24 +670,24 @@ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/genvector/vtp0.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ - ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h ../src/librnd/core/grid.h \ + ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h ../src/librnd/hid/grid.h \ ../src/librnd/core/color_cache.h ../src_3rd/genht/htip.h \ - ../src_3rd/genht/hash.h ../src/librnd/core/hid_attrib.h \ - ../src_3rd/genlist/gendlist.h ../src/librnd/core/hid.h \ + ../src_3rd/genht/hash.h ../src/librnd/hid/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src/librnd/hid/hid.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/error.h \ ../src/librnd/core/box.h ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h \ - ../src/librnd/core/pixmap.h ../src/librnd/core/globalconst.h \ + ../src/librnd/hid/pixmap.h ../src/librnd/core/globalconst.h \ ../src/librnd/plugins/lib_gtk2_common/compat.h \ ../src/librnd/plugins/lib_gtk2_common/compat_priv.h \ ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h \ ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ - ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ + ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h \ ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h \ ../src/librnd/plugins/lib_gtk2_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/event.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/event.h \ ../src/librnd/core/hidlib.h ../src/librnd/plugins/lib_gtk_common/glue_common.h \ ../src/librnd/plugins/lib_gtk_common/coord_conv.h \ ../src/librnd/plugins/lib_gtk_common/hid_gtk_conf.h \ @@ -698,9 +698,9 @@ ../src/librnd/config.h ../src/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ - ../src_3rd/puplug/error.h ../src/librnd/core/hid_init.h \ + ../src_3rd/puplug/error.h ../src/librnd/hid/hid_init.h \ ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ - ../src_3rd/genvector/genvector_undef.h ../src/librnd/core/hid.h \ + ../src_3rd/genvector/genvector_undef.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src_3rd/libfungw/fungw.h \ @@ -715,14 +715,14 @@ ../src_3rd/liblihata/lihata.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ - ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ + ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h \ ../src/librnd/plugins/lib_gtk2_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_attrib.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/hid/hid_attrib.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h \ - ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ ../src/librnd/plugins/lib_gtk_common/glue_hid.h ../src/librnd/plugins/hid_gtk2_gl/gtkhid-gl.o: \ ../src/librnd/plugins/hid_gtk2_gl/gtkhid-gl.c ../config.h \ @@ -730,8 +730,8 @@ ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h \ ../src/librnd/core/global_typedefs.h ../src/librnd/core/rnd_bool.h ../src/librnd/core/color.h \ ../src_3rd/genvector/genvector_impl.h \ - ../src_3rd/genvector/genvector_undef.h ../src/librnd/core/hid_attrib.h \ - ../src_3rd/genlist/gendlist.h ../src/librnd/core/hid.h \ + ../src_3rd/genvector/genvector_undef.h ../src/librnd/hid/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/error.h \ @@ -741,7 +741,7 @@ ../src_3rd/liblihata/lihata.h ../src_3rd/genvector/vtp0.h \ ../src/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ - ../src/librnd/core/pixmap.h ../src/librnd/core/globalconst.h \ + ../src/librnd/hid/pixmap.h ../src/librnd/core/globalconst.h \ ../src/librnd/plugins/lib_hid_common/clip.h \ ../src/librnd/plugins/lib_gtk_common/hid_gtk_conf.h \ ../src/librnd/plugins/lib_gtk_common/lib_gtk_config.h ../src/librnd/core/event.h \ @@ -750,14 +750,14 @@ ../src/librnd/plugins/lib_gtk2_common/compat_priv.h \ ../src/librnd/plugins/lib_gtk_common/wt_preview.h \ ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ - ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ + ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h \ ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h \ ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ ../src/librnd/plugins/lib_gtk2_common/bu_menu.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_dad_spin.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/hid/hid_dad_spin.h \ ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h \ ../src/librnd/plugins/lib_gtk_common/coord_conv.h \ ../src/librnd/plugins/lib_gtk_common/glue_common.h \ @@ -768,9 +768,9 @@ ../src/librnd/config.h ../src/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ - ../src_3rd/puplug/error.h ../src/librnd/core/hid_init.h \ + ../src_3rd/puplug/error.h ../src/librnd/hid/hid_init.h \ ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ - ../src_3rd/genvector/genvector_undef.h ../src/librnd/core/hid.h \ + ../src_3rd/genvector/genvector_undef.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src_3rd/libfungw/fungw.h \ @@ -787,19 +787,19 @@ ../src/librnd/plugins/lib_gtk_common/glue_common.h \ ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h \ ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ - ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ + ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h \ ../src/librnd/plugins/lib_gtk2_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_attrib.h \ - ../src_3rd/genlist/gendlist.h ../src/librnd/core/hid_dad_spin.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/hid/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src/librnd/hid/hid_dad_spin.h \ ../src/librnd/core/event.h ../src/librnd/plugins/lib_gtk_common/glue_hid.h ../src/librnd/plugins/hid_gtk4_gl/gtkhid-gl.o: \ ../src/librnd/plugins/hid_gtk4_gl/gtkhid-gl.c \ ../src/librnd/plugins/lib_gtk4_common/compat.h ../src/librnd/core/compat_misc.h \ ../src/librnd/config.h ../src/librnd/plugins/lib_gtk4_common/compat_priv.h \ - ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h ../src/librnd/core/hid.h \ + ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src_3rd/libfungw/fungw.h \ @@ -812,19 +812,19 @@ ../src_3rd/genvector/vtp0.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ - ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ + ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h \ ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h \ ../src/librnd/plugins/lib_gtk4_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ - ../src/librnd/core/color.h ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/event.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/hid/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src/librnd/core/color.h ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/event.h \ ../src/librnd/core/hidlib.h ../src/librnd/plugins/lib_gtk_common/wt_preview.h \ ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ ../src/librnd/plugins/lib_gtk_common/gtk_gl_common.c ../config.h \ ../src/librnd/core/color_cache.h ../src_3rd/genht/hash.h \ - ../src/librnd/core/hidlib_conf.h ../src/librnd/core/pixmap.h ../src/librnd/core/globalconst.h \ + ../src/librnd/core/hidlib_conf.h ../src/librnd/hid/pixmap.h ../src/librnd/core/globalconst.h \ ../src/librnd/plugins/lib_hid_common/clip.h \ ../src/librnd/plugins/lib_gtk_common/hid_gtk_conf.h \ ../src/librnd/plugins/lib_gtk_common/lib_gtk_config.h \ @@ -836,9 +836,9 @@ ../src/librnd/config.h ../src/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ - ../src_3rd/puplug/error.h ../src/librnd/core/hid_init.h \ + ../src_3rd/puplug/error.h ../src/librnd/hid/hid_init.h \ ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ - ../src_3rd/genvector/genvector_undef.h ../src/librnd/core/hid.h \ + ../src_3rd/genvector/genvector_undef.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src_3rd/libfungw/fungw.h \ @@ -855,13 +855,13 @@ ../src/librnd/plugins/lib_gtk_common/glue_common.h \ ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h \ ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ - ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ + ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h \ ../src/librnd/plugins/lib_gtk4_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ - ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/event.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/hid/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/event.h \ ../src/librnd/plugins/lib_gtk_common/glue_hid.h ../src/librnd/plugins/hid_lesstif/FillBox.o: \ ../src/librnd/plugins/hid_lesstif/FillBox.c ../config.h ../src/librnd/config.h \ @@ -889,12 +889,12 @@ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h \ ../src/librnd/plugins/hid_lesstif/FillBox.h ../src/librnd/core/compat_misc.h \ - ../src/librnd/core/event.h ../src/librnd/core/hidlib.h ../src/librnd/core/hid.h \ + ../src/librnd/core/event.h ../src/librnd/core/hidlib.h ../src/librnd/hid/hid.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/error.h \ ../src/librnd/core/box.h ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h \ - ../src/librnd/plugins/hid_lesstif/lesstif.h ../src/librnd/core/hid_cfg_input.h \ - ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h \ - ../src/librnd/core/hid_attrib.h ../src/librnd/core/actions.h ../src/librnd/core/hid_init.h \ + ../src/librnd/plugins/hid_lesstif/lesstif.h ../src/librnd/hid/hid_cfg_input.h \ + ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h \ + ../src/librnd/hid/hid_attrib.h ../src/librnd/core/actions.h ../src/librnd/hid/hid_init.h \ ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ ../src_3rd/puplug/libs.h ../src/librnd/plugins/hid_lesstif/ltf_stdarg.h \ @@ -901,14 +901,14 @@ ../src/librnd/plugins/hid_lesstif/dialogs.h \ ../src/librnd/plugins/hid_lesstif/dlg_attr_misc.c \ ../src/librnd/plugins/hid_lesstif/wt_xpm.h \ - ../src/librnd/plugins/hid_lesstif/wt_colorbtn.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/hid_dad_spin.h ../src/librnd/plugins/lib_hid_common/dad_markup.h \ + ../src/librnd/plugins/hid_lesstif/wt_colorbtn.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/plugins/lib_hid_common/dad_markup.h \ ../src/librnd/plugins/hid_lesstif/wt_preview.h \ ../src/librnd/plugins/hid_lesstif/dlg_attr_box.c \ ../src/librnd/plugins/hid_lesstif/Pages.h \ ../src/librnd/plugins/hid_lesstif/dlg_attr_tree.c \ ../src/librnd/plugins/hid_lesstif/xm_tree_table_widget.h \ - ../src/librnd/core/hid_dad_tree.h ../src_3rd/genht/hash.h + ../src/librnd/hid/hid_dad_tree.h ../src_3rd/genht/hash.h ../src/librnd/plugins/hid_lesstif/ltf_stdarg.o: \ ../src/librnd/plugins/hid_lesstif/ltf_stdarg.c \ ../src/librnd/plugins/hid_lesstif/ltf_stdarg.h \ @@ -930,21 +930,21 @@ ../src_3rd/genvector/vtp0.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h ../src/librnd/core/hidlib.h \ - ../src/librnd/core/pixmap.h ../src/librnd/core/color_cache.h ../src_3rd/genht/htip.h \ + ../src/librnd/hid/pixmap.h ../src/librnd/core/color_cache.h ../src_3rd/genht/htip.h \ ../src_3rd/genht/hash.h ../src/librnd/core/conf_hid.h ../src/librnd/core/error.h \ ../src/librnd/core/event.h ../src/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ - ../src_3rd/puplug/error.h ../src/librnd/core/safe_fs.h ../src/librnd/core/hid.h \ + ../src_3rd/puplug/error.h ../src/librnd/core/safe_fs.h ../src/librnd/hid/hid.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/box.h \ - ../src/librnd/core/misc_util.h ../src/librnd/core/hid_nogui.h ../src/librnd/core/hid_cfg.h \ - ../src/librnd/core/hid_menu.h ../src/librnd/plugins/hid_lesstif/lesstif.h \ - ../src/librnd/core/hid_cfg_input.h ../src/librnd/core/hid_attrib.h \ - ../src_3rd/genlist/gendlist.h ../src/librnd/core/hid_init.h \ - ../src/librnd/core/hid_dad.h ../src/librnd/core/compat_misc.h \ - ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/actions.h \ - ../src/librnd/plugins/hid_lesstif/ltf_stdarg.h ../src/librnd/core/grid.h \ - ../src/librnd/core/tool.h ../src/librnd/core/globalconst.h \ + ../src/librnd/core/misc_util.h ../src/librnd/hid/hid_nogui.h ../src/librnd/core/hid_cfg.h \ + ../src/librnd/hid/hid_menu.h ../src/librnd/plugins/hid_lesstif/lesstif.h \ + ../src/librnd/hid/hid_cfg_input.h ../src/librnd/hid/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src/librnd/hid/hid_init.h \ + ../src/librnd/hid/hid_dad.h ../src/librnd/core/compat_misc.h \ + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/actions.h \ + ../src/librnd/plugins/hid_lesstif/ltf_stdarg.h ../src/librnd/hid/grid.h \ + ../src/librnd/hid/tool.h ../src/librnd/core/globalconst.h \ ../src/librnd/plugins/hid_lesstif/wt_preview.h \ ../src/librnd/plugins/hid_lesstif/FillBox.h \ ../src/librnd/plugins/lib_hid_common/lib_hid_common.h \ @@ -962,13 +962,13 @@ ../src/librnd/config.h ../src/librnd/core/rnd_bool.h ../src/librnd/core/rnd_printf.h \ ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h ../src/librnd/core/unit.h \ - ../src/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/hid/hid.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/box.h \ ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/hid_cfg.h \ - ../src/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ - ../src/librnd/core/hid_cfg_action.h ../src/librnd/core/hid_cfg_input.h \ + ../src/librnd/hid/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src/librnd/core/hid_cfg_action.h ../src/librnd/hid/hid_cfg_input.h \ ../src_3rd/genht/htip.h ../src/librnd/core/conf_hid.h ../src/librnd/core/conf.h \ ../src_3rd/liblihata/lihata.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ @@ -1010,9 +1010,9 @@ ../src/librnd/config.h ../src/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ - ../src_3rd/puplug/error.h ../src/librnd/core/hid_init.h \ + ../src_3rd/puplug/error.h ../src/librnd/hid/hid_init.h \ ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ - ../src_3rd/genvector/genvector_undef.h ../src/librnd/core/hid.h \ + ../src_3rd/genvector/genvector_undef.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src_3rd/libfungw/fungw.h \ @@ -1031,7 +1031,7 @@ ../src/librnd/plugins/hid_remote/proto_lowparse.h ../src/librnd/plugins/hid_remote/remote.o: \ ../src/librnd/plugins/hid_remote/remote.c ../src/librnd/rnd_config.h \ - ../src/librnd/config.h ../src/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/config.h ../src/librnd/hid/hid.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/config.h \ @@ -1045,23 +1045,23 @@ ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ ../src/librnd/core/compat_misc.h ../src/librnd/core/color.h ../src/librnd/core/event.h \ ../src/librnd/core/hidlib.h ../src/librnd/plugins/hid_remote/proto.h \ - ../src/librnd/core/hid_nogui.h ../src/librnd/core/actions.h ../src/librnd/core/hid_init.h \ + ../src/librnd/hid/hid_nogui.h ../src/librnd/core/actions.h ../src/librnd/hid/hid_init.h \ ../src_3rd/genvector/vtp0.h ../src/librnd/plugins/irc/irc.o: ../src/librnd/plugins/irc/irc.c \ ../src/librnd/rnd_config.h ../src/librnd/config.h ../config.h ../src/librnd/config.h \ - ../src/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/hid/hid.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/error.h \ ../src/librnd/core/global_typedefs.h ../src/librnd/core/rnd_bool.h ../src/librnd/core/box.h \ ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h \ - ../src/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src/librnd/hid/hid_attrib.h ../src_3rd/genlist/gendlist.h \ ../src/librnd/core/color.h ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h ../src/librnd/core/actions.h \ - ../src/librnd/core/hid_dad.h ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_cfg.h \ - ../src/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src/librnd/hid/hid_dad.h ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_cfg.h \ + ../src/librnd/hid/hid_menu.h ../src_3rd/genvector/vtp0.h \ ../src/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ - ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/plugins.h \ + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/plugins.h \ ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h ../src/librnd/core/safe_fs.h \ @@ -1083,11 +1083,11 @@ ../src/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ - ../src_3rd/puplug/error.h ../src/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/puplug/error.h ../src/librnd/hid/hid.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/libfungw/fungw.h ../src/librnd/core/box.h \ ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/pixmap.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/hid/pixmap.h \ ../src/librnd/plugins/lib_exp_pixmap/draw_pixmap.h ../src/librnd/plugins/lib_exp_pixmap/lib_exp_pixmap.o: \ ../src/librnd/plugins/lib_exp_pixmap/lib_exp_pixmap.c ../config.h \ @@ -1101,16 +1101,16 @@ ../src/librnd/core/global_typedefs.h ../src/librnd/core/rnd_bool.h \ ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h ../src/librnd/core/rnd_printf.h \ - ../src_3rd/genvector/gds_char.h ../src/librnd/core/unit.h ../src/librnd/core/hid.h \ + ../src_3rd/genvector/gds_char.h ../src/librnd/core/unit.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src_3rd/libfungw/fungw.h \ ../src_3rd/genht/htpp.h ../src/librnd/core/error.h ../src/librnd/core/box.h \ - ../src/librnd/core/misc_util.h ../src/librnd/core/hid_nogui.h ../src/librnd/core/hid_init.h \ + ../src/librnd/core/misc_util.h ../src/librnd/hid/hid_nogui.h ../src/librnd/hid/hid_init.h \ ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ ../src_3rd/puplug/libs.h ../src_3rd/genvector/vtp0.h \ - ../src/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src/librnd/hid/hid_attrib.h ../src_3rd/genlist/gendlist.h \ ../src/librnd/plugins/lib_exp_text/draw_eps.h ../src/librnd/plugins/lib_exp_text/draw_hpgl.o: \ ../src/librnd/plugins/lib_exp_text/draw_hpgl.c ../src/librnd/config.h \ @@ -1130,12 +1130,12 @@ ../src/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ - ../src_3rd/puplug/error.h ../src/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/puplug/error.h ../src/librnd/hid/hid.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/box.h \ - ../src/librnd/core/misc_util.h ../src/librnd/core/hid_init.h \ - ../src_3rd/genvector/vtp0.h ../src/librnd/core/hid_attrib.h \ + ../src/librnd/core/misc_util.h ../src/librnd/hid/hid_init.h \ + ../src_3rd/genvector/vtp0.h ../src/librnd/hid/hid_attrib.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h \ ../src/librnd/plugins/lib_exp_text/media.h \ ../src/librnd/plugins/lib_exp_text/draw_ps.h ../src/librnd/core/hidlib.h @@ -1156,8 +1156,8 @@ ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h ../src/librnd/core/safe_fs.h \ - ../src/librnd/core/hid.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ - ../src/librnd/core/box.h ../src/librnd/core/hid_init.h ../src/librnd/core/hid_attrib.h \ + ../src/librnd/hid/hid.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + ../src/librnd/core/box.h ../src/librnd/hid/hid_init.h ../src/librnd/hid/hid_attrib.h \ ../src_3rd/genlist/gendlist.h \ ../src/librnd/plugins/lib_exp_text/draw_svg.h ../src/librnd/core/hidlib.h ../src/librnd/plugins/lib_exp_text/lib_exp_text.o: \ @@ -1181,10 +1181,10 @@ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/genvector/vtp0.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ - ../src_3rd/genlist/gendlist.h ../src/librnd/core/hid.h \ + ../src_3rd/genlist/gendlist.h ../src/librnd/hid/hid.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/error.h \ ../src/librnd/core/box.h ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h \ - ../src/librnd/core/hid_nogui.h ../src/librnd/core/hid_init.h ../src/librnd/core/hid_attrib.h \ + ../src/librnd/hid/hid_nogui.h ../src/librnd/hid/hid_init.h ../src/librnd/hid/hid_attrib.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h \ ../src/librnd/plugins/lib_exp_text/lpr_hid.h ../src/librnd/plugins/lib_exp_text/media.o: \ @@ -1203,7 +1203,7 @@ ../src/librnd/plugins/lib_gtk2_common/compat_priv.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.c ../src/librnd/rnd_config.h \ ../src/librnd/config.h ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h ../src/librnd/config.h \ - ../src/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/hid/hid.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/error.h \ @@ -1215,14 +1215,14 @@ ../src_3rd/genvector/vtp0.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ - ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ + ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h \ ../src/librnd/plugins/lib_gtk2_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_attrib.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/hid/hid_attrib.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h \ - ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ ../src/librnd/core/hidlib_conf.h ../src/librnd/core/actions.h \ ../src/librnd/plugins/lib_gtk_common/hid_gtk_conf.h \ ../src/librnd/plugins/lib_hid_common/cli_history.h @@ -1248,20 +1248,20 @@ ../src_3rd/liblihata/lihata.h ../src_3rd/genvector/vtp0.h \ ../src/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ - ../src/librnd/core/hidlib.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid.h \ + ../src/librnd/core/hidlib.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/box.h \ - ../src/librnd/core/math_helper.h ../src/librnd/core/hid_menu.h \ - ../src/librnd/core/hid_cfg_action.h ../src/librnd/core/tool.h \ + ../src/librnd/core/math_helper.h ../src/librnd/hid/hid_menu.h \ + ../src/librnd/core/hid_cfg_action.h ../src/librnd/hid/tool.h \ ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h \ ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ ../src_3rd/genht/htip.h ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h \ ../src/librnd/plugins/lib_gtk2_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_attrib.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/hid/hid_attrib.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h \ - ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/event.h \ + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/event.h \ ../src/librnd/plugins/lib_gtk2_common/bu_menu.h \ ../src/librnd/plugins/lib_gtk_common/in_keyboard.h \ ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ @@ -1271,7 +1271,7 @@ ../src/librnd/plugins/lib_gtk2_common/compat.h \ ../src/librnd/plugins/lib_gtk2_common/compat_priv.h \ ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h ../src/librnd/config.h \ - ../src/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/hid/hid.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/error.h \ @@ -1283,15 +1283,15 @@ ../src_3rd/genvector/vtp0.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ - ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ + ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h \ ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h \ ../src/librnd/plugins/lib_gtk2_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_attrib.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/hid/hid_attrib.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h \ - ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ ../src/librnd/plugins/lib_gtk_common/in_keyboard.h \ ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h ../src/librnd/plugins/lib_gtk2_common/dlg_attribute.o: \ @@ -1298,8 +1298,8 @@ ../src/librnd/plugins/lib_gtk2_common/dlg_attribute.c \ ../src/librnd/plugins/lib_gtk2_common/compat.h \ ../src/librnd/plugins/lib_gtk2_common/compat_priv.h \ - ../src/librnd/core/hid_dad.h ../src/librnd/core/compat_misc.h ../src/librnd/config.h \ - ../src/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h ../src/librnd/core/hid.h \ + ../src/librnd/hid/hid_dad.h ../src/librnd/core/compat_misc.h ../src/librnd/config.h \ + ../src/librnd/hid/hid_attrib.h ../src_3rd/genlist/gendlist.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src_3rd/libfungw/fungw.h \ @@ -1308,9 +1308,9 @@ ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h \ ../src/librnd/core/color.h ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h ../src/librnd/core/hid_cfg.h \ - ../src/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src/librnd/hid/hid_menu.h ../src_3rd/genvector/vtp0.h \ ../src/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ - ../src/librnd/core/hid_dad_spin.h ../src/librnd/plugins/lib_gtk_common/dlg_attribute.c \ + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/plugins/lib_gtk_common/dlg_attribute.c \ ../config.h ../src/librnd/core/hidlib_conf.h ../src/librnd/core/conf.h \ ../src_3rd/liblihata/lihata.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ @@ -1318,12 +1318,12 @@ ../src/librnd/plugins/lib_gtk_common/dlg_attribute.h \ ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h \ ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ ../src_3rd/genht/htip.h ../src/librnd/plugins/lib_gtk2_common/bu_menu.h \ ../src/librnd/core/conf_hid.h ../src/librnd/plugins/lib_gtk_common/bu_command.h \ ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/event.h \ - ../src/librnd/core/hidlib.h ../src/librnd/core/hid_dad_tree.h ../src_3rd/genht/hash.h \ - ../src/librnd/core/hid_init.h ../src_3rd/puplug/puplug.h \ + ../src/librnd/core/hidlib.h ../src/librnd/hid/hid_dad_tree.h ../src_3rd/genht/hash.h \ + ../src/librnd/hid/hid_init.h ../src_3rd/puplug/puplug.h \ ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ ../src/librnd/plugins/lib_gtk_common/hid_gtk_conf.h \ @@ -1357,14 +1357,14 @@ ../src/librnd/plugins/lib_gtk2_common/compat.h \ ../src/librnd/plugins/lib_gtk2_common/compat_priv.h \ ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_cfg.h \ - ../src/librnd/core/hid.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + ../src/librnd/hid/hid.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ ../src/librnd/core/error.h ../src/librnd/core/box.h ../src/librnd/core/math_helper.h \ - ../src/librnd/core/misc_util.h ../src/librnd/core/hid_menu.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_attrib.h \ + ../src/librnd/core/misc_util.h ../src/librnd/hid/hid_menu.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/hid/hid_attrib.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h \ - ../src/librnd/core/hid_dad_spin.h ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h \ + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h \ ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ ../src_3rd/genht/htip.h ../src/librnd/plugins/lib_gtk2_common/bu_menu.h \ ../src/librnd/core/conf_hid.h ../src/librnd/plugins/lib_gtk_common/bu_command.h \ ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ @@ -1371,7 +1371,7 @@ ../src/librnd/plugins/lib_gtk_common/dlg_topwin.c ../src/librnd/rnd_config.h \ ../src/librnd/config.h ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h \ ../src_3rd/genht/hash.h ../src/librnd/core/hidlib_conf.h ../src/librnd/core/actions.h \ - ../src/librnd/core/tool.h ../src/librnd/plugins/lib_gtk_common/bu_pixbuf.h \ + ../src/librnd/hid/tool.h ../src/librnd/plugins/lib_gtk_common/bu_pixbuf.h \ ../src/librnd/plugins/lib_gtk_common/dlg_attribute.h \ ../src/librnd/plugins/lib_gtk_common/util_listener.h \ ../src/librnd/plugins/lib_gtk_common/in_keyboard.h \ @@ -1384,8 +1384,8 @@ ../src/librnd/plugins/lib_gtk2_common/compat.h \ ../src/librnd/plugins/lib_gtk2_common/compat_priv.h \ ../src/librnd/plugins/lib_gtk_common/glue_common.c ../config.h \ - ../src/librnd/core/pixmap.h ../src/librnd/plugins/lib_gtk_common/glue_common.h \ - ../src/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/hid/pixmap.h ../src/librnd/plugins/lib_gtk_common/glue_common.h \ + ../src/librnd/hid/hid.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/error.h \ @@ -1397,14 +1397,14 @@ ../src_3rd/genvector/vtp0.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ - ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ + ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h \ ../src/librnd/plugins/lib_gtk2_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_attrib.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/hid/hid_attrib.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h \ - ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h \ ../src/librnd/plugins/lib_gtk_common/hid_gtk_conf.h \ ../src/librnd/plugins/lib_gtk_common/in_keyboard.h \ @@ -1418,7 +1418,7 @@ ../src/librnd/plugins/lib_gtk2_common/compat_priv.h \ ../src/librnd/plugins/lib_gtk_common/glue_hid.c ../src/librnd/rnd_config.h \ ../src/librnd/config.h ../src/librnd/plugins/lib_gtk_common/glue_hid.h \ - ../src/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/hid/hid.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/config.h \ @@ -1431,15 +1431,15 @@ ../src_3rd/genvector/vtp0.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ - ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ + ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h \ ../src/librnd/plugins/lib_gtk2_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_attrib.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/hid/hid_attrib.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h \ - ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ - ../src/librnd/core/actions.h ../src/librnd/core/hid_nogui.h ../src/librnd/core/pixmap.h \ + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ + ../src/librnd/core/actions.h ../src/librnd/hid/hid_nogui.h ../src/librnd/hid/pixmap.h \ ../src/librnd/plugins/lib_gtk_common/coord_conv.h ../src/librnd/core/hidlib_conf.h \ ../src/librnd/plugins/lib_gtk_common/in_keyboard.h \ ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ @@ -1460,14 +1460,14 @@ ../src/librnd/plugins/lib_gtk2_common/compat.h \ ../src/librnd/plugins/lib_gtk2_common/compat_priv.h \ ../src/librnd/plugins/lib_gtk_common/in_keyboard.c ../config.h ../src/librnd/config.h \ - ../src/librnd/plugins/lib_gtk_common/in_keyboard.h ../src/librnd/core/hid_cfg_input.h \ + ../src/librnd/plugins/lib_gtk_common/in_keyboard.h ../src/librnd/hid/hid_cfg_input.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src_3rd/genht/htip.h ../src_3rd/genht/htpp.h \ ../src/librnd/core/hid_cfg.h ../src/librnd/core/global_typedefs.h \ - ../src/librnd/core/rnd_bool.h ../src/librnd/core/hid.h ../src_3rd/libfungw/fungw.h \ + ../src/librnd/core/rnd_bool.h ../src/librnd/hid/hid.h ../src_3rd/libfungw/fungw.h \ ../src/librnd/core/error.h ../src/librnd/core/box.h ../src/librnd/core/math_helper.h \ - ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h ../src/librnd/hid/hid_menu.h \ ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h \ ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ @@ -1479,10 +1479,10 @@ ../src_3rd/genlist/gendlist.h ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ ../src/librnd/plugins/lib_gtk2_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_attrib.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/hid/hid_attrib.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h \ - ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ ../src/librnd/plugins/lib_gtk_common/glue_common.h ../src/librnd/plugins/lib_gtk2_common/in_mouse.o: \ ../src/librnd/plugins/lib_gtk2_common/in_mouse.c \ @@ -1500,17 +1500,17 @@ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genvector/vtp0.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ - ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h ../src/librnd/core/tool.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ - ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid.h \ + ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h ../src/librnd/hid/tool.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ + ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid.h \ ../src/librnd/core/box.h ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h \ - ../src/librnd/core/hid_menu.h ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h \ + ../src/librnd/hid/hid_menu.h ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h \ ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ ../src/librnd/plugins/lib_gtk2_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_attrib.h \ - ../src_3rd/genlist/gendlist.h ../src/librnd/core/hid_dad_spin.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/hid/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src/librnd/hid/hid_dad_spin.h \ ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ ../src_3rd/genvector/genvector_impl.c \ ../src/librnd/plugins/lib_gtk_common/in_keyboard.h \ @@ -1522,7 +1522,7 @@ ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ ../src_3rd/puplug/error.h ../src/librnd/plugins/lib_gtk_common/lib_gtk_config.h \ - ../src/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/hid/hid.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/error.h \ @@ -1539,7 +1539,7 @@ ../src/librnd/plugins/lib_gtk2_common/lib_gtk_config.c \ ../src/librnd/plugins/lib_gtk_common/lib_gtk_config.c ../config.h \ ../src/librnd/config.h ../src/librnd/plugins/lib_gtk_common/lib_gtk_config.h \ - ../src/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/hid/hid.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/error.h \ @@ -1566,13 +1566,13 @@ ../src/librnd/plugins/lib_gtk_common/ui_crosshair.h \ ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h ../src/librnd/core/rnd_bool.h \ ../src/librnd/core/global_typedefs.h ../src/librnd/plugins/lib_gtk_common/in_mouse.h \ - ../src/librnd/core/hid_cfg_input.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/hid/hid_cfg_input.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h ../src_3rd/genht/htip.h \ - ../src_3rd/genht/htpp.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid.h \ + ../src_3rd/genht/htpp.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid.h \ ../src_3rd/libfungw/fungw.h ../src/librnd/core/error.h ../src/librnd/core/box.h \ ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h \ - ../src/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src/librnd/hid/hid_menu.h ../src_3rd/genvector/vtp0.h \ ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h \ ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h ../src/librnd/core/conf.h \ @@ -1582,10 +1582,10 @@ ../src_3rd/genlist/gendlist.h ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ ../src/librnd/plugins/lib_gtk2_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_attrib.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/hid/hid_attrib.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h \ - ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ ../src/librnd/plugins/lib_gtk_common/hid_gtk_conf.h ../src/librnd/plugins/lib_gtk2_common/ui_zoompan.o: \ ../src/librnd/plugins/lib_gtk2_common/ui_zoompan.c \ @@ -1594,13 +1594,13 @@ ../src/librnd/plugins/lib_gtk_common/ui_zoompan.c ../config.h ../src/librnd/config.h \ ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h ../src/librnd/core/rnd_bool.h \ ../src/librnd/core/global_typedefs.h ../src/librnd/plugins/lib_gtk_common/in_mouse.h \ - ../src/librnd/core/hid_cfg_input.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/hid/hid_cfg_input.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h ../src_3rd/genht/htip.h \ - ../src_3rd/genht/htpp.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid.h \ + ../src_3rd/genht/htpp.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid.h \ ../src_3rd/libfungw/fungw.h ../src/librnd/core/error.h ../src/librnd/core/box.h \ ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h \ - ../src/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src/librnd/hid/hid_menu.h ../src_3rd/genvector/vtp0.h \ ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h \ ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h ../src/librnd/core/conf.h \ @@ -1610,10 +1610,10 @@ ../src_3rd/genlist/gendlist.h ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ ../src/librnd/plugins/lib_gtk2_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_attrib.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/hid/hid_attrib.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h \ - ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ ../src/librnd/core/hidlib_conf.h ../src/librnd/plugins/lib_hid_common/lib_hid_common.h \ ../src/librnd/plugins/lib_hid_common/dialogs_conf.h \ ../src/librnd/plugins/lib_gtk_common/glue_common.h @@ -1622,7 +1622,7 @@ ../src/librnd/plugins/lib_gtk2_common/compat.h \ ../src/librnd/plugins/lib_gtk2_common/compat_priv.h \ ../src/librnd/plugins/lib_gtk_common/util_listener.c ../src/librnd/rnd_config.h \ - ../src/librnd/config.h ../src/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/config.h ../src/librnd/hid/hid.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/config.h \ @@ -1637,13 +1637,13 @@ ../src_3rd/genvector/vtp0.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ - ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ + ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h \ ../src/librnd/plugins/lib_gtk2_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ - ../src/librnd/core/color.h ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/event.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/hid/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src/librnd/core/color.h ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/event.h \ ../src/librnd/core/hidlib.h ../src/librnd/plugins/lib_gtk2_common/util_timer.o: \ ../src/librnd/plugins/lib_gtk2_common/util_timer.c \ @@ -1650,7 +1650,7 @@ ../src/librnd/plugins/lib_gtk2_common/compat.h \ ../src/librnd/plugins/lib_gtk2_common/compat_priv.h \ ../src/librnd/plugins/lib_gtk_common/util_timer.c ../config.h ../src/librnd/config.h \ - ../src/librnd/plugins/lib_gtk_common/util_timer.h ../src/librnd/core/hid.h \ + ../src/librnd/plugins/lib_gtk_common/util_timer.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src_3rd/libfungw/fungw.h \ @@ -1664,14 +1664,14 @@ ../src_3rd/genvector/vtp0.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ - ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ + ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h \ ../src/librnd/plugins/lib_gtk2_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_attrib.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/hid/hid_attrib.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h \ - ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ ../src/librnd/plugins/lib_gtk_common/glue_common.h ../src/librnd/plugins/lib_gtk2_common/util_watch.o: \ ../src/librnd/plugins/lib_gtk2_common/util_watch.c \ @@ -1678,7 +1678,7 @@ ../src/librnd/plugins/lib_gtk2_common/compat.h \ ../src/librnd/plugins/lib_gtk2_common/compat_priv.h \ ../src/librnd/plugins/lib_gtk_common/util_watch.c ../config.h ../src/librnd/config.h \ - ../src/librnd/plugins/lib_gtk_common/util_watch.h ../src/librnd/core/hid.h \ + ../src/librnd/plugins/lib_gtk_common/util_watch.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src_3rd/libfungw/fungw.h \ @@ -1692,14 +1692,14 @@ ../src_3rd/genvector/vtp0.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ - ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ + ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h \ ../src/librnd/plugins/lib_gtk2_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_attrib.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/hid/hid_attrib.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h \ - ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ ../src/librnd/plugins/lib_gtk_common/glue_common.h ../src/librnd/plugins/lib_gtk2_common/wt_preview.o: \ ../src/librnd/plugins/lib_gtk2_common/wt_preview.c \ @@ -1706,7 +1706,7 @@ ../src/librnd/plugins/lib_gtk2_common/compat.h \ ../src/librnd/plugins/lib_gtk2_common/compat_priv.h \ ../src/librnd/plugins/lib_gtk_common/wt_preview.h ../src_3rd/genlist/gendlist.h \ - ../src/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/hid/hid.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/config.h \ @@ -1713,8 +1713,8 @@ ../src/librnd/core/error.h ../src/librnd/core/global_typedefs.h ../src/librnd/core/rnd_bool.h \ ../src/librnd/core/box.h ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h \ ../src/librnd/core/unit.h ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ - ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ + ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h \ ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h \ ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h ../src/librnd/core/conf.h \ @@ -1724,9 +1724,9 @@ ../src_3rd/genlist/gendlist.h ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ ../src/librnd/plugins/lib_gtk2_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_attrib.h ../src/librnd/core/color.h \ - ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/hid/hid_attrib.h ../src/librnd/core/color.h \ + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ ../src/librnd/plugins/lib_gtk_common/wt_preview.c ../config.h \ ../src/librnd/core/hidlib_conf.h ../src/librnd/plugins/lib_gtk_common/in_keyboard.h \ ../src/librnd/plugins/lib_gtk_common/wt_preview.h ../src/librnd/core/globalconst.h @@ -1736,7 +1736,7 @@ ../src/librnd/config.h ../src/librnd/plugins/lib_gtk4_common/compat_priv.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.c ../src/librnd/rnd_config.h \ ../src/librnd/config.h ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h \ - ../src/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/hid/hid.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/error.h \ @@ -1748,13 +1748,13 @@ ../src_3rd/genvector/vtp0.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ - ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ + ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h \ ../src/librnd/plugins/lib_gtk4_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ - ../src/librnd/core/color.h ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/event.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/hid/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src/librnd/core/color.h ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/event.h \ ../src/librnd/core/hidlib.h ../src/librnd/core/hidlib_conf.h ../src/librnd/core/actions.h \ ../src/librnd/plugins/lib_gtk_common/hid_gtk_conf.h \ ../src/librnd/plugins/lib_hid_common/cli_history.h @@ -1776,22 +1776,22 @@ ../src/librnd/core/hid_cfg_action.h ../src/librnd/core/hid_cfg.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ - ../src_3rd/genht/ht.h ../src/librnd/core/hid.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/ht.h ../src/librnd/hid/hid.h ../src_3rd/libfungw/fungw.h \ ../src_3rd/genht/htpp.h ../src/librnd/core/error.h ../src/librnd/core/box.h \ ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h \ - ../src/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src/librnd/hid/hid_menu.h ../src_3rd/genvector/vtp0.h \ ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h ../src/librnd/core/conf.h \ ../src/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ ../src_3rd/liblihata/lihata.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ ../src_3rd/genht/htip.h ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h \ ../src/librnd/plugins/lib_gtk4_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ - ../src/librnd/core/color.h ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/event.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/hid/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src/librnd/core/color.h ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/event.h \ ../src/librnd/plugins/lib_gtk_common/in_keyboard.h \ ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ ../src/librnd/plugins/lib_hid_common/menu_helper.h \ @@ -1801,7 +1801,7 @@ ../src/librnd/plugins/lib_gtk4_common/compat.c \ ../src/librnd/plugins/lib_gtk4_common/compat.h ../src/librnd/core/compat_misc.h \ ../src/librnd/config.h ../src/librnd/plugins/lib_gtk4_common/compat_priv.h \ - ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h ../src/librnd/core/hid.h \ + ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src_3rd/libfungw/fungw.h \ @@ -1814,14 +1814,14 @@ ../src_3rd/genvector/vtp0.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ - ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ + ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h \ ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h \ ../src/librnd/plugins/lib_gtk4_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ - ../src/librnd/core/color.h ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/event.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/hid/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src/librnd/core/color.h ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/event.h \ ../src/librnd/core/hidlib.h ../src/librnd/plugins/lib_gtk_common/in_keyboard.h \ ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ ../src/librnd/plugins/lib_gtk4_common/compat_clipboard.c @@ -1829,8 +1829,8 @@ ../src/librnd/plugins/lib_gtk4_common/dlg_attribute.c \ ../src/librnd/plugins/lib_gtk4_common/compat.h ../src/librnd/core/compat_misc.h \ ../src/librnd/config.h ../src/librnd/plugins/lib_gtk4_common/compat_priv.h \ - ../src/librnd/core/hid_dad.h ../src/librnd/core/hid_attrib.h \ - ../src_3rd/genlist/gendlist.h ../src/librnd/core/hid.h \ + ../src/librnd/hid/hid_dad.h ../src/librnd/hid/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src_3rd/libfungw/fungw.h \ @@ -1839,9 +1839,9 @@ ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h \ ../src/librnd/core/color.h ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h ../src/librnd/core/hid_cfg.h \ - ../src/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src/librnd/hid/hid_menu.h ../src_3rd/genvector/vtp0.h \ ../src/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ - ../src/librnd/core/hid_dad_spin.h \ + ../src/librnd/hid/hid_dad_spin.h \ ../src/librnd/plugins/lib_gtk4_common/gtkc_trunc_label.h \ ../src/librnd/plugins/lib_gtk_common/dlg_attribute.c ../config.h \ ../src/librnd/core/hidlib_conf.h ../src/librnd/core/conf.h \ @@ -1851,12 +1851,12 @@ ../src/librnd/plugins/lib_gtk_common/dlg_attribute.h \ ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h \ ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ ../src_3rd/genht/htip.h ../src/librnd/plugins/lib_gtk4_common/bu_menu.h \ ../src/librnd/core/conf_hid.h ../src/librnd/plugins/lib_gtk_common/bu_command.h \ ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/event.h \ - ../src/librnd/core/hidlib.h ../src/librnd/core/hid_dad_tree.h ../src_3rd/genht/hash.h \ - ../src/librnd/core/hid_init.h ../src_3rd/puplug/puplug.h \ + ../src/librnd/core/hidlib.h ../src/librnd/hid/hid_dad_tree.h ../src_3rd/genht/hash.h \ + ../src/librnd/hid/hid_init.h ../src_3rd/puplug/puplug.h \ ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ ../src/librnd/plugins/lib_gtk_common/hid_gtk_conf.h \ @@ -1884,25 +1884,25 @@ ../src/librnd/core/hid_cfg.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ - ../src/librnd/core/global_typedefs.h ../src/librnd/core/rnd_bool.h ../src/librnd/core/hid.h \ + ../src/librnd/core/global_typedefs.h ../src/librnd/core/rnd_bool.h ../src/librnd/hid/hid.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/error.h \ ../src/librnd/core/box.h ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h \ - ../src/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src/librnd/hid/hid_menu.h ../src_3rd/genvector/vtp0.h \ ../src_3rd/genvector/genvector_impl.h \ - ../src_3rd/genvector/genvector_undef.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genvector/genvector_undef.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/hid/hid_attrib.h ../src_3rd/genlist/gendlist.h \ ../src/librnd/core/color.h ../src/librnd/core/rnd_printf.h \ - ../src_3rd/genvector/gds_char.h ../src/librnd/core/hid_dad_spin.h \ + ../src_3rd/genvector/gds_char.h ../src/librnd/hid/hid_dad_spin.h \ ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h ../src/librnd/core/conf.h \ ../src_3rd/liblihata/lihata.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ ../src_3rd/genht/htip.h ../src/librnd/plugins/lib_gtk4_common/bu_menu.h \ ../src/librnd/core/conf_hid.h ../src/librnd/plugins/lib_gtk_common/bu_command.h \ ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/event.h \ ../src/librnd/core/hidlib.h ../src_3rd/genht/hash.h ../src/librnd/core/hidlib_conf.h \ - ../src/librnd/core/actions.h ../src/librnd/core/tool.h \ + ../src/librnd/core/actions.h ../src/librnd/hid/tool.h \ ../src/librnd/plugins/lib_gtk_common/bu_pixbuf.h \ ../src/librnd/plugins/lib_gtk_common/hid_gtk_conf.h \ ../src/librnd/plugins/lib_gtk_common/dlg_attribute.h \ @@ -1918,8 +1918,8 @@ ../src/librnd/plugins/lib_gtk4_common/compat_priv.h \ ../src/librnd/plugins/lib_gtk4_common/gtkc_scrollbar.h \ ../src/librnd/plugins/lib_gtk_common/glue_common.c ../config.h \ - ../src/librnd/core/pixmap.h ../src/librnd/plugins/lib_gtk_common/glue_common.h \ - ../src/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/hid/pixmap.h ../src/librnd/plugins/lib_gtk_common/glue_common.h \ + ../src/librnd/hid/hid.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/error.h \ @@ -1931,13 +1931,13 @@ ../src_3rd/genvector/vtp0.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ - ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ + ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h \ ../src/librnd/plugins/lib_gtk4_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ - ../src/librnd/core/color.h ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/event.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/hid/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src/librnd/core/color.h ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/event.h \ ../src/librnd/core/hidlib.h ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h \ ../src/librnd/plugins/lib_gtk_common/hid_gtk_conf.h \ ../src/librnd/plugins/lib_gtk_common/in_keyboard.h \ @@ -1951,7 +1951,7 @@ ../src/librnd/config.h ../src/librnd/plugins/lib_gtk4_common/compat_priv.h \ ../src/librnd/plugins/lib_gtk_common/glue_hid.c ../src/librnd/rnd_config.h \ ../src/librnd/config.h ../src/librnd/plugins/lib_gtk_common/glue_hid.h \ - ../src/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/hid/hid.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/error.h \ @@ -1964,15 +1964,15 @@ ../src_3rd/genvector/vtp0.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ - ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ + ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h \ ../src/librnd/plugins/lib_gtk4_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ - ../src/librnd/core/color.h ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/event.h \ - ../src/librnd/core/hidlib.h ../src/librnd/core/actions.h ../src/librnd/core/hid_nogui.h \ - ../src/librnd/core/pixmap.h ../src/librnd/plugins/lib_gtk_common/coord_conv.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/hid/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src/librnd/core/color.h ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/event.h \ + ../src/librnd/core/hidlib.h ../src/librnd/core/actions.h ../src/librnd/hid/hid_nogui.h \ + ../src/librnd/hid/pixmap.h ../src/librnd/plugins/lib_gtk_common/coord_conv.h \ ../src/librnd/core/hidlib_conf.h ../src/librnd/plugins/lib_gtk_common/in_keyboard.h \ ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ ../src/librnd/plugins/lib_gtk_common/bu_dwg_tooltip.h \ @@ -1999,14 +1999,14 @@ ../src/librnd/plugins/lib_gtk4_common/compat.h ../src/librnd/core/compat_misc.h \ ../src/librnd/config.h ../src/librnd/plugins/lib_gtk4_common/compat_priv.h \ ../src/librnd/plugins/lib_gtk_common/in_keyboard.c ../config.h \ - ../src/librnd/plugins/lib_gtk_common/in_keyboard.h ../src/librnd/core/hid_cfg_input.h \ + ../src/librnd/plugins/lib_gtk_common/in_keyboard.h ../src/librnd/hid/hid_cfg_input.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src_3rd/genht/htip.h ../src_3rd/genht/htpp.h \ ../src/librnd/core/hid_cfg.h ../src/librnd/core/global_typedefs.h \ - ../src/librnd/core/rnd_bool.h ../src/librnd/core/hid.h ../src_3rd/libfungw/fungw.h \ + ../src/librnd/core/rnd_bool.h ../src/librnd/hid/hid.h ../src_3rd/libfungw/fungw.h \ ../src/librnd/core/error.h ../src/librnd/core/box.h ../src/librnd/core/math_helper.h \ - ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h ../src/librnd/hid/hid_menu.h \ ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h \ ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ @@ -2018,9 +2018,9 @@ ../src_3rd/genlist/gendlist.h ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ ../src/librnd/plugins/lib_gtk4_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ - ../src/librnd/core/color.h ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/event.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/hid/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src/librnd/core/color.h ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/event.h \ ../src/librnd/core/hidlib.h ../src/librnd/plugins/lib_gtk_common/glue_common.h ../src/librnd/plugins/lib_gtk4_common/in_mouse.o: \ ../src/librnd/plugins/lib_gtk4_common/in_mouse.c \ @@ -2037,17 +2037,17 @@ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genvector/vtp0.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ - ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h ../src/librnd/core/tool.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ - ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid.h \ + ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h ../src/librnd/hid/tool.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ + ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid.h \ ../src/librnd/core/box.h ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h \ - ../src/librnd/core/hid_menu.h ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h \ + ../src/librnd/hid/hid_menu.h ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h \ ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ ../src/librnd/plugins/lib_gtk4_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ - ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/hid/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ ../src_3rd/genvector/genvector_impl.c \ ../src/librnd/plugins/lib_gtk_common/in_keyboard.h \ ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ @@ -2058,7 +2058,7 @@ ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ ../src_3rd/puplug/error.h ../src/librnd/plugins/lib_gtk_common/lib_gtk_config.h \ - ../src/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/hid/hid.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/error.h \ @@ -2075,7 +2075,7 @@ ../src/librnd/plugins/lib_gtk4_common/lib_gtk_config.c \ ../src/librnd/plugins/lib_gtk_common/lib_gtk_config.c ../config.h \ ../src/librnd/config.h ../src/librnd/plugins/lib_gtk_common/lib_gtk_config.h \ - ../src/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/hid/hid.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/error.h \ @@ -2102,13 +2102,13 @@ ../src/librnd/plugins/lib_gtk_common/ui_crosshair.h \ ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h ../src/librnd/core/rnd_bool.h \ ../src/librnd/core/global_typedefs.h ../src/librnd/plugins/lib_gtk_common/in_mouse.h \ - ../src/librnd/core/hid_cfg_input.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/hid/hid_cfg_input.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h ../src_3rd/genht/htip.h \ - ../src_3rd/genht/htpp.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid.h \ + ../src_3rd/genht/htpp.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid.h \ ../src_3rd/libfungw/fungw.h ../src/librnd/core/error.h ../src/librnd/core/box.h \ ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h \ - ../src/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src/librnd/hid/hid_menu.h ../src_3rd/genvector/vtp0.h \ ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h \ ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h ../src/librnd/core/conf.h \ @@ -2118,9 +2118,9 @@ ../src_3rd/genlist/gendlist.h ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ ../src/librnd/plugins/lib_gtk4_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ - ../src/librnd/core/color.h ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/event.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/hid/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src/librnd/core/color.h ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/event.h \ ../src/librnd/core/hidlib.h ../src/librnd/plugins/lib_gtk_common/hid_gtk_conf.h ../src/librnd/plugins/lib_gtk4_common/ui_zoompan.o: \ ../src/librnd/plugins/lib_gtk4_common/ui_zoompan.c \ @@ -2129,13 +2129,13 @@ ../src/librnd/plugins/lib_gtk_common/ui_zoompan.c ../config.h \ ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h ../src/librnd/core/rnd_bool.h \ ../src/librnd/core/global_typedefs.h ../src/librnd/plugins/lib_gtk_common/in_mouse.h \ - ../src/librnd/core/hid_cfg_input.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/hid/hid_cfg_input.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h ../src_3rd/genht/htip.h \ - ../src_3rd/genht/htpp.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid.h \ + ../src_3rd/genht/htpp.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid.h \ ../src_3rd/libfungw/fungw.h ../src/librnd/core/error.h ../src/librnd/core/box.h \ ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h \ - ../src/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src/librnd/hid/hid_menu.h ../src_3rd/genvector/vtp0.h \ ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h \ ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h ../src/librnd/core/conf.h \ @@ -2145,9 +2145,9 @@ ../src_3rd/genlist/gendlist.h ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ ../src/librnd/plugins/lib_gtk4_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ - ../src/librnd/core/color.h ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/event.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/hid/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src/librnd/core/color.h ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/event.h \ ../src/librnd/core/hidlib.h ../src/librnd/core/hidlib_conf.h \ ../src/librnd/plugins/lib_hid_common/lib_hid_common.h \ ../src/librnd/plugins/lib_hid_common/dialogs_conf.h \ @@ -2157,7 +2157,7 @@ ../src/librnd/plugins/lib_gtk4_common/compat.h ../src/librnd/core/compat_misc.h \ ../src/librnd/config.h ../src/librnd/plugins/lib_gtk4_common/compat_priv.h \ ../src/librnd/plugins/lib_gtk_common/util_listener.c ../src/librnd/rnd_config.h \ - ../src/librnd/config.h ../src/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/config.h ../src/librnd/hid/hid.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/error.h \ @@ -2171,13 +2171,13 @@ ../src_3rd/genvector/vtp0.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ - ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ + ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h \ ../src/librnd/plugins/lib_gtk4_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ - ../src/librnd/core/color.h ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/event.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/hid/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src/librnd/core/color.h ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/event.h \ ../src/librnd/core/hidlib.h ../src/librnd/plugins/lib_gtk4_common/util_timer.o: \ ../src/librnd/plugins/lib_gtk4_common/util_timer.c \ @@ -2184,7 +2184,7 @@ ../src/librnd/plugins/lib_gtk4_common/compat.h ../src/librnd/core/compat_misc.h \ ../src/librnd/config.h ../src/librnd/plugins/lib_gtk4_common/compat_priv.h \ ../src/librnd/plugins/lib_gtk_common/util_timer.c ../config.h \ - ../src/librnd/plugins/lib_gtk_common/util_timer.h ../src/librnd/core/hid.h \ + ../src/librnd/plugins/lib_gtk_common/util_timer.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src_3rd/libfungw/fungw.h \ @@ -2198,13 +2198,13 @@ ../src_3rd/genvector/vtp0.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ - ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ + ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h \ ../src/librnd/plugins/lib_gtk4_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ - ../src/librnd/core/color.h ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/event.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/hid/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src/librnd/core/color.h ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/event.h \ ../src/librnd/core/hidlib.h ../src/librnd/plugins/lib_gtk_common/glue_common.h ../src/librnd/plugins/lib_gtk4_common/util_watch.o: \ ../src/librnd/plugins/lib_gtk4_common/util_watch.c \ @@ -2211,7 +2211,7 @@ ../src/librnd/plugins/lib_gtk4_common/compat.h ../src/librnd/core/compat_misc.h \ ../src/librnd/config.h ../src/librnd/plugins/lib_gtk4_common/compat_priv.h \ ../src/librnd/plugins/lib_gtk_common/util_watch.c ../config.h \ - ../src/librnd/plugins/lib_gtk_common/util_watch.h ../src/librnd/core/hid.h \ + ../src/librnd/plugins/lib_gtk_common/util_watch.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src_3rd/libfungw/fungw.h \ @@ -2225,13 +2225,13 @@ ../src_3rd/genvector/vtp0.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ - ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ + ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h \ ../src/librnd/plugins/lib_gtk4_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ - ../src/librnd/core/color.h ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/event.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/hid/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src/librnd/core/color.h ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/event.h \ ../src/librnd/core/hidlib.h ../src/librnd/plugins/lib_gtk_common/glue_common.h ../src/librnd/plugins/lib_gtk4_common/wt_preview.o: \ ../src/librnd/plugins/lib_gtk4_common/wt_preview.c \ @@ -2238,7 +2238,7 @@ ../src/librnd/plugins/lib_gtk4_common/compat.h ../src/librnd/core/compat_misc.h \ ../src/librnd/config.h ../src/librnd/plugins/lib_gtk4_common/compat_priv.h \ ../src/librnd/plugins/lib_gtk_common/wt_preview.h ../src_3rd/genlist/gendlist.h \ - ../src/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/hid/hid.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/error.h \ @@ -2245,8 +2245,8 @@ ../src/librnd/core/global_typedefs.h ../src/librnd/core/rnd_bool.h ../src/librnd/core/box.h \ ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h \ ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ - ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/core/hid_cfg_input.h \ - ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/plugins/lib_gtk_common/in_mouse.h ../src/librnd/hid/hid_cfg_input.h \ + ../src_3rd/genht/htip.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h \ ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h \ ../src/librnd/plugins/lib_gtk_common/rnd_gtk.h ../src/librnd/core/conf.h \ @@ -2256,8 +2256,8 @@ ../src_3rd/genlist/gendlist.h ../src/librnd/plugins/lib_gtk_common/ui_zoompan.h \ ../src/librnd/plugins/lib_gtk4_common/bu_menu.h ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_gtk_common/bu_command.h \ - ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/hid_attrib.h ../src/librnd/core/color.h ../src/librnd/core/hid_dad_spin.h \ + ../src/librnd/plugins/lib_gtk_common/dlg_topwin.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/hid/hid_attrib.h ../src/librnd/core/color.h ../src/librnd/hid/hid_dad_spin.h \ ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ ../src/librnd/plugins/lib_gtk_common/wt_preview.c ../config.h \ ../src/librnd/core/hidlib_conf.h ../src/librnd/plugins/lib_gtk_common/in_keyboard.h \ @@ -2270,15 +2270,15 @@ ../src_3rd/genvector/genvector_undef.h ../src/librnd/core/actions.h \ ../src/librnd/core/global_typedefs.h ../src/librnd/config.h ../src/librnd/core/rnd_bool.h \ ../src/librnd/core/error.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_dad.h ../src/librnd/core/hid_attrib.h \ - ../src_3rd/genlist/gendlist.h ../src/librnd/core/hid.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/hid/hid_dad.h ../src/librnd/hid/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src/librnd/core/box.h \ ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h \ - ../src/librnd/core/color.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/core/color.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h \ ../src_3rd/genvector/vtp0.h ../src/librnd/core/rnd_printf.h \ - ../src_3rd/genvector/gds_char.h ../src/librnd/core/hid_dad_spin.h \ - ../src/librnd/core/hid_dad_tree.h \ + ../src_3rd/genvector/gds_char.h ../src/librnd/hid/hid_dad_spin.h \ + ../src/librnd/hid/hid_dad_tree.h \ ../src/librnd/plugins/lib_hid_common/act_dad.h ../src/librnd/plugins/lib_hid_common/cli_history.o: \ ../src/librnd/plugins/lib_hid_common/cli_history.c ../src/librnd/rnd_config.h \ @@ -2301,17 +2301,17 @@ ../src/librnd/config.h ../src/librnd/core/actions.h ../src/librnd/core/global_typedefs.h \ ../src/librnd/config.h ../src/librnd/core/rnd_bool.h ../src/librnd/core/error.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htsp.h \ - ../src_3rd/genht/ht.h ../src_3rd/genht/htpp.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_attrib.h \ - ../src_3rd/genlist/gendlist.h ../src/librnd/core/hid.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/htpp.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/hid/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src/librnd/core/box.h \ ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h \ ../src/librnd/core/color.h ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h ../src/librnd/core/hid_cfg.h \ - ../src/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src/librnd/hid/hid_menu.h ../src_3rd/genvector/vtp0.h \ ../src/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ - ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/hidlib.h \ + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/core/hidlib.h \ ../src/librnd/plugins/lib_hid_common/xpm.h \ ../src/librnd/plugins/lib_hid_common/dlg_comm_m.h \ ../src/librnd/plugins/lib_hid_common/lib_hid_common.h \ @@ -2325,18 +2325,18 @@ ../src/librnd/config.h ../src/librnd/core/rnd_bool.h ../src/librnd/core/error.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src_3rd/genht/htpp.h ../src/librnd/core/event.h \ - ../src/librnd/core/unit.h ../src/librnd/core/hidlib.h ../src/librnd/core/hid.h \ + ../src/librnd/core/unit.h ../src/librnd/core/hidlib.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src/librnd/core/box.h \ - ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_attrib.h \ + ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/hid/hid_attrib.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h \ ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h ../src/librnd/core/hid_cfg.h \ - ../src/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src/librnd/hid/hid_menu.h ../src_3rd/genvector/vtp0.h \ ../src/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ - ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/hid_dad_unit.h \ - ../src/librnd/core/hid_init.h ../src_3rd/puplug/puplug.h \ + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/hid/hid_dad_unit.h \ + ../src/librnd/hid/hid_init.h ../src_3rd/puplug/puplug.h \ ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ ../src/librnd/plugins/lib_hid_common/dlg_export.h @@ -2347,16 +2347,16 @@ ../src_3rd/genvector/genvector_undef.h ../src_3rd/genregex/regex_se.h \ ../src_3rd/genregex/regex_templ.h ../src_3rd/genregex/regex.h \ ../src/librnd/core/error.h ../src/librnd/core/global_typedefs.h ../src/librnd/core/rnd_bool.h \ - ../src/librnd/core/hid_dad.h ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_attrib.h \ - ../src_3rd/genlist/gendlist.h ../src/librnd/core/hid.h \ + ../src/librnd/hid/hid_dad.h ../src/librnd/core/compat_misc.h ../src/librnd/hid/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src_3rd/libfungw/fungw.h \ ../src_3rd/genht/htpp.h ../src/librnd/core/box.h ../src/librnd/core/math_helper.h \ ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h ../src/librnd/core/color.h \ - ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h ../src_3rd/genvector/vtp0.h \ ../src/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ - ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/hid_dad_tree.h \ + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/hid/hid_dad_tree.h \ ../src/librnd/core/globalconst.h ../src/librnd/core/compat_fs.h ../src/librnd/core/safe_fs.h \ ../src/librnd/core/conf.h ../src_3rd/liblihata/lihata.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ @@ -2383,11 +2383,11 @@ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genvector/vtp0.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ - ../src_3rd/genlist/gendlist.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_attrib.h \ - ../src_3rd/genlist/gendlist.h ../src/librnd/core/hid.h ../src/librnd/core/box.h \ + ../src_3rd/genlist/gendlist.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/hid/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src/librnd/hid/hid.h ../src/librnd/core/box.h \ ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/color.h \ - ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h ../src/librnd/core/hid_dad_spin.h \ + ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h ../src/librnd/hid/hid_dad_spin.h \ ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ ../src/librnd/plugins/lib_hid_common/dlg_log.h ../src/librnd/plugins/lib_hid_common/dlg_plugins.o: \ @@ -2395,17 +2395,17 @@ ../src/librnd/config.h ../src/librnd/core/actions.h ../src/librnd/core/global_typedefs.h \ ../src/librnd/config.h ../src/librnd/core/rnd_bool.h ../src/librnd/core/error.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htsp.h \ - ../src_3rd/genht/ht.h ../src_3rd/genht/htpp.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_attrib.h \ - ../src_3rd/genlist/gendlist.h ../src/librnd/core/hid.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/htpp.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/hid/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src/librnd/core/box.h \ ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h \ ../src/librnd/core/color.h ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h ../src/librnd/core/hid_cfg.h \ - ../src/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src/librnd/hid/hid_menu.h ../src_3rd/genvector/vtp0.h \ ../src/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ - ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/hid_dad_tree.h \ + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/hid/hid_dad_tree.h \ ../src_3rd/genht/hash.h ../src/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ @@ -2425,23 +2425,23 @@ ../src_3rd/liblihata/parser.h ../src_3rd/genvector/vtp0.h \ ../src/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ - ../src/librnd/core/conf_hid.h ../src/librnd/core/hid_dad.h ../src/librnd/core/compat_misc.h \ - ../src/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h ../src/librnd/core/hid.h \ + ../src/librnd/core/conf_hid.h ../src/librnd/hid/hid_dad.h ../src/librnd/core/compat_misc.h \ + ../src/librnd/hid/hid_attrib.h ../src_3rd/genlist/gendlist.h ../src/librnd/hid/hid.h \ ../src/librnd/core/box.h ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h \ - ../src/librnd/core/color.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h \ - ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/hid_dad_tree.h \ + ../src/librnd/core/color.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h \ + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/hid/hid_dad_tree.h \ ../src_3rd/genht/hash.h ../src/librnd/plugins/lib_hid_common/dlg_pref.h \ ../src/librnd/plugins/lib_hid_common/dlg_pref_win.c \ ../src/librnd/core/hidlib_conf.h ../src/librnd/plugins/lib_hid_common/dialogs_conf.h \ ../src/librnd/plugins/lib_hid_common/place.h \ ../src/librnd/plugins/lib_hid_common/dlg_pref_key.c \ - ../src/librnd/core/hid_cfg_input.h ../src_3rd/genht/htip.h \ + ../src/librnd/hid/hid_cfg_input.h ../src_3rd/genht/htip.h \ ../src_3rd/liblihata/tree.h \ ../src/librnd/plugins/lib_hid_common/dlg_pref_menu.c \ - ../src/librnd/core/hid_menu.h ../src/librnd/core/safe_fs.h \ + ../src/librnd/hid/hid_menu.h ../src/librnd/core/safe_fs.h \ ../src/librnd/plugins/lib_hid_common/dlg_pref_conf.c \ ../src/librnd/plugins/lib_hid_common/dlg_pref_confedit.c \ - ../src/librnd/core/hid_dad_unit.h + ../src/librnd/hid/hid_dad_unit.h ../src/librnd/plugins/lib_hid_common/grid_menu.o: \ ../src/librnd/plugins/lib_hid_common/grid_menu.c ../src/librnd/rnd_config.h \ ../src/librnd/config.h ../src/librnd/core/conf.h ../src/librnd/config.h \ @@ -2455,11 +2455,11 @@ ../src_3rd/genvector/vtp0.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/hidlib_conf.h \ - ../src/librnd/core/color.h ../src/librnd/core/grid.h ../src/librnd/core/event.h \ - ../src/librnd/core/hidlib.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid.h \ + ../src/librnd/core/color.h ../src/librnd/hid/grid.h ../src/librnd/core/event.h \ + ../src/librnd/core/hidlib.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/error.h \ ../src/librnd/core/box.h ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h \ - ../src/librnd/core/hid_menu.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/hid/hid_menu.h ../src/librnd/hid/hid_menu.h \ ../src/librnd/plugins/lib_hid_common/grid_menu.h ../src/librnd/plugins/lib_hid_common/gui_act.o: \ ../src/librnd/plugins/lib_hid_common/gui_act.c ../src/librnd/rnd_config.h \ @@ -2473,22 +2473,22 @@ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/genvector/vtp0.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ - ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h ../src/librnd/core/tool.h \ - ../src/librnd/core/grid.h ../src/librnd/core/error.h ../src/librnd/core/actions.h \ + ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h ../src/librnd/hid/tool.h \ + ../src/librnd/hid/grid.h ../src/librnd/core/error.h ../src/librnd/core/actions.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ - ../src/librnd/core/hid_init.h ../src_3rd/puplug/puplug.h \ + ../src/librnd/hid/hid_init.h ../src_3rd/puplug/puplug.h \ ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ - ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h ../src/librnd/core/hid.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h ../src/librnd/hid/hid.h \ ../src/librnd/core/box.h ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h \ ../src/librnd/core/compat_misc.h ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ - ../src/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ - ../src/librnd/core/hid_dad.h ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h \ - ../src/librnd/core/hid_dad_spin.h + ../src/librnd/hid/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src/librnd/hid/hid_dad.h ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h \ + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/plugins/lib_hid_common/lead_user.o: \ ../src/librnd/plugins/lib_hid_common/lead_user.c ../src/librnd/rnd_config.h \ ../src/librnd/config.h ../src/librnd/core/unit.h ../src/librnd/core/global_typedefs.h \ ../src/librnd/config.h ../src/librnd/core/rnd_bool.h ../src/librnd/core/event.h \ - ../src/librnd/core/hidlib.h ../src/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/core/hidlib.h ../src/librnd/hid/hid.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/error.h \ @@ -2510,10 +2510,10 @@ ../src_3rd/genvector/vtp0.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/error.h ../src/librnd/core/event.h \ - ../src/librnd/core/hidlib.h ../src/librnd/core/hid_menu.h ../src/librnd/core/hid_cfg.h \ - ../src/librnd/core/hid.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + ../src/librnd/core/hidlib.h ../src/librnd/hid/hid_menu.h ../src/librnd/core/hid_cfg.h \ + ../src/librnd/hid/hid.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ ../src/librnd/core/box.h ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h \ - ../src/librnd/core/hid_menu.h ../src/librnd/core/actions.h \ + ../src/librnd/hid/hid_menu.h ../src/librnd/core/actions.h \ ../src/librnd/plugins/lib_hid_common/grid_menu.h \ ../src/librnd/plugins/lib_hid_common/cli_history.h \ ../src/librnd/plugins/lib_hid_common/lead_user.h \ @@ -2525,10 +2525,10 @@ ../src/librnd/plugins/lib_hid_common/dlg_log.h \ ../src/librnd/plugins/lib_hid_common/dlg_fileselect.h \ ../src/librnd/plugins/lib_hid_common/dlg_plugins.h \ - ../src/librnd/plugins/lib_hid_common/dlg_pref.h ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_attrib.h \ + ../src/librnd/plugins/lib_hid_common/dlg_pref.h ../src/librnd/hid/hid_dad.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/hid/hid_attrib.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h \ - ../src/librnd/core/hid_dad_spin.h \ + ../src/librnd/hid/hid_dad_spin.h \ ../src/librnd/plugins/lib_hid_common/act_dad.h \ ../src/librnd/plugins/lib_hid_common/toolbar.h \ ../src/librnd/plugins/lib_hid_common/zoompan.h \ @@ -2549,8 +2549,8 @@ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/error.h ../src/librnd/core/actions.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ - ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid.h ../src/librnd/core/box.h \ - ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid.h ../src/librnd/core/box.h \ + ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/hid/hid_menu.h \ ../src/librnd/core/compat_misc.h \ ../src/librnd/plugins/lib_hid_common/menu_helper.h ../src/librnd/plugins/lib_hid_common/place.o: \ @@ -2578,15 +2578,15 @@ ../src_3rd/genvector/genvector_undef.h ../src_3rd/liblihata/tree.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ - ../src_3rd/genht/ht.h ../src/librnd/core/hid.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/ht.h ../src/librnd/hid/hid.h ../src_3rd/libfungw/fungw.h \ ../src_3rd/genht/htpp.h ../src/librnd/config.h ../src/librnd/core/error.h \ ../src/librnd/core/global_typedefs.h ../src/librnd/core/rnd_bool.h ../src/librnd/core/box.h \ ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h \ - ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ - ../src/librnd/core/hid_dad.h ../src/librnd/core/compat_misc.h ../src/librnd/core/hid_attrib.h \ + ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src/librnd/hid/hid_dad.h ../src/librnd/core/compat_misc.h ../src/librnd/hid/hid_attrib.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h \ ../src/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ - ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/tool.h ../src/librnd/core/hidlib_conf.h \ + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/hid/tool.h ../src/librnd/core/hidlib_conf.h \ ../src/librnd/core/conf.h ../src_3rd/liblihata/lihata.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/conf_hid.h \ @@ -2610,7 +2610,7 @@ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src_3rd/genht/htpp.h ../src/librnd/core/compat_misc.h \ ../src/librnd/core/hidlib.h ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h \ - ../src/librnd/plugins/lib_hid_common/zoompan.h ../src/librnd/core/hid.h \ + ../src/librnd/plugins/lib_hid_common/zoompan.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src/librnd/core/box.h \ ../src/librnd/core/math_helper.h @@ -2622,7 +2622,7 @@ ../src/librnd/plugins/lib_hid_gl/opengl_debug.h \ ../src/librnd/plugins/lib_hid_gl/opengl.h \ ../src/librnd/plugins/lib_hid_gl/hidgl.h ../src/librnd/core/hidlib.h \ - ../src/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/hid/hid.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/error.h \ @@ -2650,7 +2650,7 @@ ../src/librnd/plugins/lib_hid_gl/opengl_debug.h \ ../src/librnd/plugins/lib_hid_gl/opengl.h \ ../src/librnd/plugins/lib_hid_gl/hidgl.h ../src/librnd/core/hidlib.h \ - ../src/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/hid/hid.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/error.h \ @@ -2677,8 +2677,8 @@ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/genvector/vtp0.h ../src/librnd/core/list_conf.h \ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ - ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h ../src/librnd/core/grid.h \ - ../src/librnd/core/hid.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + ../src_3rd/genlist/gendlist.h ../src/librnd/core/color.h ../src/librnd/hid/grid.h \ + ../src/librnd/hid/hid.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ ../src/librnd/core/error.h ../src/librnd/core/box.h ../src/librnd/core/math_helper.h \ ../src/librnd/core/misc_util.h ../src/librnd/poly/rtree.h \ ../src_3rd/genrtree/genrtree_api.h ../src/librnd/core/hidlib.h \ @@ -2760,7 +2760,7 @@ ../src/librnd/config.h ../src/librnd/plugins/lib_mbtk_common/mbtk_common.h \ ../src/librnd/core/rnd_bool.h ../src/librnd/core/hidlib.h \ ../src/librnd/core/global_typedefs.h ../src/librnd/config.h \ - ../src/librnd/plugins/lib_mbtk_common/attr_dlg.h ../src/librnd/core/hid.h \ + ../src/librnd/plugins/lib_mbtk_common/attr_dlg.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src_3rd/libfungw/fungw.h \ @@ -2769,7 +2769,7 @@ ../src/librnd/plugins/lib_mbtk_common/glue_hid.o: \ ../src/librnd/plugins/lib_mbtk_common/glue_hid.c ../src/librnd/rnd_config.h \ ../src/librnd/config.h ../src/librnd/plugins/lib_mbtk_common/glue_hid.h \ - ../src/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src/librnd/hid/hid.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/config.h \ @@ -2778,11 +2778,11 @@ ../src/librnd/core/unit.h ../src/librnd/plugins/lib_mbtk_common/mbtk_common.h \ ../src/librnd/core/hidlib.h ../src/librnd/plugins/lib_mbtk_common/mbtk_common.h \ ../src/librnd/plugins/lib_mbtk_common/attr_dlg.h ../src/librnd/core/actions.h \ - ../src/librnd/core/hid_nogui.h ../src/librnd/core/hid_menu.h ../src/librnd/core/hid_cfg.h \ - ../src/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ - ../src/librnd/core/hid_cfg_input.h ../src_3rd/genht/htip.h \ - ../src/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ - ../src/librnd/core/color.h ../src/librnd/core/pixmap.h ../src/librnd/core/event.h \ + ../src/librnd/hid/hid_nogui.h ../src/librnd/hid/hid_menu.h ../src/librnd/core/hid_cfg.h \ + ../src/librnd/hid/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src/librnd/hid/hid_cfg_input.h ../src_3rd/genht/htip.h \ + ../src/librnd/hid/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src/librnd/core/color.h ../src/librnd/hid/pixmap.h ../src/librnd/core/event.h \ ../src/librnd/core/hidlib_conf.h ../src/librnd/core/conf.h ../src/librnd/core/rnd_printf.h \ ../src_3rd/genvector/gds_char.h ../src_3rd/liblihata/lihata.h \ ../src/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ @@ -2792,7 +2792,7 @@ ../src/librnd/plugins/lib_hid_common/menu_helper.h \ ../src/librnd/plugins/lib_mbtk_common/todo.c \ ../src/librnd/plugins/lib_mbtk_common/keyboard.c \ - ../src/librnd/core/compat_misc.h ../src/librnd/core/tool.h \ + ../src/librnd/core/compat_misc.h ../src/librnd/hid/tool.h \ ../src/librnd/plugins/lib_mbtk_common/mouse.c \ ../src/librnd/plugins/lib_mbtk_common/menu.c ../src/librnd/core/conf_hid.h \ ../src/librnd/plugins/lib_mbtk_common/topwin.h \ @@ -2803,9 +2803,9 @@ ../src/librnd/config.h ../src/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ - ../src_3rd/puplug/error.h ../src/librnd/core/hid_init.h \ + ../src_3rd/puplug/error.h ../src/librnd/hid/hid_init.h \ ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ - ../src_3rd/genvector/genvector_undef.h ../src/librnd/core/hid.h \ + ../src_3rd/genvector/genvector_undef.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src_3rd/libfungw/fungw.h \ @@ -2836,7 +2836,7 @@ ../src_3rd/genlist/gendlist.h ../src/librnd/plugins/lib_wget/lib_wget.h ../src/librnd/plugins/loghid/hid-logger.o: \ ../src/librnd/plugins/loghid/hid-logger.c ../config.h ../src/librnd/config.h \ - ../src/librnd/plugins/loghid/hid-logger.h ../src/librnd/core/hid.h \ + ../src/librnd/plugins/loghid/hid-logger.h ../src/librnd/hid/hid.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ ../src_3rd/genht/ht.h ../src_3rd/libfungw/fungw.h \ @@ -2861,11 +2861,11 @@ ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ - ../src/librnd/plugins/loghid/hid-logger.h ../src/librnd/core/hid.h \ + ../src/librnd/plugins/loghid/hid-logger.h ../src/librnd/hid/hid.h \ ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h ../src/librnd/core/box.h \ - ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/hid_init.h \ - ../src/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ - ../src/librnd/core/color.h ../src/librnd/core/hid_nogui.h + ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/hid/hid_init.h \ + ../src/librnd/hid/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src/librnd/core/color.h ../src/librnd/hid/hid_nogui.h ../src/librnd/plugins/stroke/stroke.o: \ ../src/librnd/plugins/stroke/stroke.c ../src/librnd/rnd_config.h \ ../src/librnd/config.h ../src/librnd/core/hidlib_conf.h ../src/librnd/core/conf.h \ @@ -2884,7 +2884,7 @@ ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ ../src_3rd/puplug/error.h ../src/librnd/core/compat_misc.h ../src/librnd/core/event.h \ - ../src/librnd/core/hidlib.h ../src/librnd/core/tool.h \ + ../src/librnd/core/hidlib.h ../src/librnd/hid/tool.h \ ../src/librnd/plugins/stroke/conf_internal.c \ ../src/librnd/plugins/stroke/stroke_conf.h \ ../src/librnd/plugins/stroke/stroke_conf_fields.h @@ -2893,7 +2893,7 @@ ../src/librnd/config.h ../src/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ - ../src_3rd/puplug/error.h ../src/librnd/core/pixmap.h \ + ../src_3rd/puplug/error.h ../src/librnd/hid/pixmap.h \ ../src/librnd/core/global_typedefs.h ../src/librnd/core/rnd_bool.h \ ../src/librnd/core/safe_fs.h ../src/librnd/core/conf.h ../src/librnd/core/rnd_printf.h \ ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ @@ -2909,7 +2909,7 @@ ../src/librnd/config.h ../src/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ - ../src_3rd/puplug/error.h ../src/librnd/core/pixmap.h \ + ../src_3rd/puplug/error.h ../src/librnd/hid/pixmap.h \ ../src/librnd/core/global_typedefs.h ../src/librnd/core/rnd_bool.h \ ../src/librnd/core/safe_fs.h ../src/librnd/core/conf.h ../src/librnd/core/rnd_printf.h \ ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ @@ -2934,18 +2934,18 @@ ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ ../src_3rd/puplug/error.h ../src/librnd/core/hid_cfg.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ - ../src_3rd/liblihata/parser.h ../src/librnd/core/hid.h ../src/librnd/core/box.h \ + ../src_3rd/liblihata/parser.h ../src/librnd/hid/hid.h ../src/librnd/core/box.h \ ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/unit.h \ - ../src/librnd/core/hid_menu.h ../src/librnd/core/hid_dad.h ../src/librnd/core/compat_misc.h \ - ../src/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src/librnd/hid/hid_menu.h ../src/librnd/hid/hid_dad.h ../src/librnd/core/compat_misc.h \ + ../src/librnd/hid/hid_attrib.h ../src_3rd/genlist/gendlist.h \ ../src/librnd/core/color.h ../src/librnd/core/rnd_printf.h \ - ../src_3rd/genvector/gds_char.h ../src/librnd/core/hid_dad_spin.h \ + ../src_3rd/genvector/gds_char.h ../src/librnd/hid/hid_dad_spin.h \ ../src/librnd/core/safe_fs.h ../src/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ ../src/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ ../src/librnd/core/safe_fs_dir.h ../src/librnd/core/compat_inc.h \ ../src/librnd/core/compat_fs.h ../src/librnd/core/event.h ../src/librnd/core/hidlib.h \ - ../src/librnd/core/hid_menu.h ../src/librnd/plugins/script/script.h \ + ../src/librnd/hid/hid_menu.h ../src/librnd/plugins/script/script.h \ ../src/librnd/plugins/script/live_script.h \ ../src/librnd/plugins/script/menu_internal.c \ ../src/librnd/plugins/script/glue_undo.c @@ -2968,11 +2968,11 @@ ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ ../src_3rd/genlist/gendlist.h ../src/librnd/core/plugins.h \ ../src_3rd/puplug/error.h ../src/librnd/core/compat_misc.h \ - ../src/librnd/core/compat_fs.h ../src/librnd/core/safe_fs.h ../src/librnd/core/hid_menu.h \ - ../src/librnd/core/hid_cfg.h ../src/librnd/core/hid.h ../src/librnd/core/box.h \ - ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/core/hid_menu.h \ + ../src/librnd/core/compat_fs.h ../src/librnd/core/safe_fs.h ../src/librnd/hid/hid_menu.h \ + ../src/librnd/core/hid_cfg.h ../src/librnd/hid/hid.h ../src/librnd/core/box.h \ + ../src/librnd/core/math_helper.h ../src/librnd/core/misc_util.h ../src/librnd/hid/hid_menu.h \ ../src/librnd/core/event.h ../src/librnd/core/hidlib.h ../src/librnd/core/globalconst.h \ - ../src/librnd/core/hid_init.h ../src/librnd/plugins/script/script.h \ + ../src/librnd/hid/hid_init.h ../src/librnd/plugins/script/script.h \ ../src/librnd/plugins/script/guess_lang.c ../src_3rd/genht/htss.h \ ../src_3rd/genht/ht_utils.h ../src_3rd/puplug/util.h \ ../src/librnd/plugins/script/c_script.c ../src/librnd/core/fptr_cast.h \ @@ -2979,9 +2979,9 @@ ../src/librnd/core/hidlib_conf.h ../src/librnd/core/color.h \ ../src/librnd/plugins/script/timer.c \ ../src/librnd/plugins/script/perma.c ../config.h \ - ../src/librnd/plugins/script/script_act.c ../src/librnd/core/hid_dad.h \ - ../src/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ - ../src/librnd/core/hid_dad_spin.h ../src/librnd/core/hid_dad_tree.h \ + ../src/librnd/plugins/script/script_act.c ../src/librnd/hid/hid_dad.h \ + ../src/librnd/hid/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src/librnd/hid/hid_dad_spin.h ../src/librnd/hid/hid_dad_tree.h \ ../src/librnd/plugins/script/live_script.h ../src_3rd/gensexpr/gsx_parse.o: ../src_3rd/gensexpr/gsx_parse.c \ ../src_3rd/gensexpr/gsx_parse.h Index: trunk/src/Makefile.in =================================================================== --- trunk/src/Makefile.in (revision 34601) +++ trunk/src/Makefile.in (revision 34602) @@ -4,7 +4,7 @@ append /local/pcb/LDFLAGS ?/local/librnd/cflags_profile put /local/pcb/DEPCFLAGS {} put /local/librnd/OBJS_3RDLIB {} -put /local/librnd/OBJS_HIDLIB {} +put /local/librnd/OBJS_CORELIB {} put /local/librnd/OBJS_C99_HIDLIB_PLG {} put /local/librnd/OBJS_HIDLIB_PLG {} @@ -84,14 +84,13 @@ # These have constructs that are not c89 strictly speaking but are # effectively c89; typical example is casting a function pointer to a # data pointer for dlsym(). -put /local/librnd/OBJS_C99_HIDLIB [@ +put /local/librnd/OBJS_C99_CORELIB [@ $(LIBRND)/core/fptr_cast.o @] -append /local/librnd/OBJS_HIDLIB [@ +append /local/librnd/OBJS_CORELIB [@ $(LIBRND)/core/actions.o $(LIBRND)/core/anyload.o - $(LIBRND)/core/anyload_act.o $(LIBRND)/core/base64.o $(LIBRND)/core/box.o $(LIBRND)/core/box_isc.o @@ -106,22 +105,9 @@ $(LIBRND)/core/event.o $(LIBRND)/core/file_loaded.o $(LIBRND)/core/funchash.o - $(LIBRND)/core/grid.o $(LIBRND)/core/heap.o - $(LIBRND)/core/hid.o - $(LIBRND)/core/hid_act.o - $(LIBRND)/core/hid_attrib.o $(LIBRND)/core/hid_cfg.o $(LIBRND)/core/hid_cfg_action.o - $(LIBRND)/core/hid_cfg_input.o - $(LIBRND)/core/hid_dlg.o - $(LIBRND)/core/hid_dad.o - $(LIBRND)/core/hid_dad_tree.o - $(LIBRND)/core/hid_dad_spin.o - $(LIBRND)/core/hid_dad_unit.o - $(LIBRND)/core/hid_init.o - $(LIBRND)/core/hid_menu.o - $(LIBRND)/core/hid_nogui.o $(LIBRND)/core/hidlib.o $(LIBRND)/core/hidlib_conf.o $(LIBRND)/core/list_conf.o @@ -131,12 +117,9 @@ $(LIBRND)/core/rnd_bool.o $(LIBRND)/core/rnd_printf.o $(LIBRND)/core/plugins.o - $(LIBRND)/core/pixmap.o $(LIBRND)/core/safe_fs.o - $(LIBRND)/core/tool.o $(LIBRND)/core/unit.o $(LIBRND)/core/vtc0.o - buildin.hidlib.o @] put /local/librnd/OBJS_POLYLIB [@ @@ -153,6 +136,26 @@ $(LIBRND)/font/xform_mx.o @] +put /local/librnd/OBJS_HIDLIB [@ + $(LIBRND)/hid/anyload_act.o + $(LIBRND)/hid/grid.o + $(LIBRND)/hid/hid.o + $(LIBRND)/hid/hid_act.o + $(LIBRND)/hid/hid_attrib.o + $(LIBRND)/hid/hid_cfg_input.o + $(LIBRND)/hid/hid_dlg.o + $(LIBRND)/hid/hid_dad.o + $(LIBRND)/hid/hid_dad_tree.o + $(LIBRND)/hid/hid_dad_spin.o + $(LIBRND)/hid/hid_dad_unit.o + $(LIBRND)/hid/hid_init.o + $(LIBRND)/hid/hid_menu.o + $(LIBRND)/hid/hid_nogui.o + $(LIBRND)/hid/pixmap.o + $(LIBRND)/hid/tool.o + buildin.hidlib.o +@] + append /local/librnd/OBJS_3RDLIB [@ ../src_3rd/liblihata/parser.o ../src_3rd/liblihata/dom.o @@ -200,11 +203,12 @@ ../src_3rd/puplug/libpuplug.a @] -put /local/librnd/OBJS_C99 /local/librnd/OBJS_C99_HIDLIB -put /local/librnd/OBJS /local/librnd/OBJS_HIDLIB +put /local/librnd/OBJS_C99 /local/librnd/OBJS_C99_CORELIB +put /local/librnd/OBJS /local/librnd/OBJS_CORELIB append /local/librnd/OBJS /local/librnd/OBJS_3RDLIB append /local/librnd/OBJS /local/librnd/OBJS_POLYLIB append /local/librnd/OBJS /local/librnd/OBJS_FONTLIB +append /local/librnd/OBJS /local/librnd/OBJS_HIDLIB #---- modules ----# @@ -252,8 +256,9 @@ uniq /local/librnd/OBJS_3RDLIB_NOAUTO uniq /local/librnd/OBJS_POLYLIB uniq /local/librnd/OBJS_FONTLIB +uniq /local/librnd/OBJS_CORELIB uniq /local/librnd/OBJS_HIDLIB -uniq /local/librnd/OBJS_C99_HIDLIB +uniq /local/librnd/OBJS_C99_CORELIB uniq /local/librnd/OBJS_HIDLIB_PLG uniq /local/librnd/OBJS_C99_HIDLIB_PLG uniq /local/librnd/OBJS_UTIL @@ -271,6 +276,7 @@ append /local/librnd/SRCS ?/local/librnd/OBJS_3RDLIB append /local/librnd/SRCS ?/local/librnd/OBJS_POLYLIB append /local/librnd/SRCS ?/local/librnd/OBJS_FONTLIB +append /local/librnd/SRCS ?/local/librnd/OBJS_CORELIB append /local/librnd/SRCS ?/local/librnd/OBJS_HIDLIB gsub /local/librnd/SRCS {.o } {.c } @@ -318,8 +324,9 @@ OBJS_POLYLIB=@/local/librnd/OBJS_POLYLIB@ OBJS_FONTLIB=@/local/librnd/OBJS_FONTLIB@ OBJS_3RDLIB=@/local/librnd/OBJS_3RDLIB@ ../src_3rd/puplug/*.o +OBJS_CORELIB=@/local/librnd/OBJS_CORELIB@ OBJS_HIDLIB=@/local/librnd/OBJS_HIDLIB@ -OBJS_C99_HIDLIB=@/local/librnd/OBJS_C99_HIDLIB@ +OBJS_C99_CORELIB=@/local/librnd/OBJS_C99_CORELIB@ OBJS_HIDLIB_PLG=@/local/librnd/OBJS_HIDLIB_PLG@ OBJS_C99_HIDLIB_PLG=@/local/librnd/OBJS_C99_HIDLIB_PLG@ OBJS_UTIL=@/local/librnd/OBJS_UTIL@ @@ -358,7 +365,7 @@ all_exe: $(SPHASH) test-rnd$(EXE) @/local/librnd/all@ -test-rnd.o: $(LIBRND)/core/buildin.hidlib.h +test-rnd.o: $(LIBRND)/hid/buildin.hidlib.h test-rnd$(EXE): $(OBJS) test-rnd.o $(OBJS_C99) $(LIBS_3RD) $(CC) test-rnd.o $(OBJS) $(OBJS_C99) -o test-rnd$(EXE) $(LIBS_PRE) $(LDFLAGS) $(LIBS) @@ -365,8 +372,9 @@ ### librnd, hidlib #### -OBJS_HIDLIB_ALL = $(OBJS_HIDLIB_PLG) $(OBJS_C99_HIDLIB_PLG) $(OBJS_HIDLIB) $(OBJS_C99_HIDLIB) -DEPS_HIDLIB_ALL = $(OBJS_HIDLIB_ALL) $(LIBS_3RD) $(LIBRND)/core/buildin.hidlib.h +OBJS_CORELIB_ALL = $(OBJS_CORELIB) $(OBJS_C99_CORELIB) +DEPS_CORELIB_ALL = $(OBJS_CORELIB_ALL) $(LIBS_3RD) $(LIBRND)/hid/buildin.hidlib.h +OBJS_HIDLIB_ALL = $(OBJS_HIDLIB) $(OBJS_HIDLIB_PLG) $(OBJS_C99_HIDLIB_PLG) @] switch cc/soname @@ -378,10 +386,11 @@ @] end; default print [@ -SONAME_HID=@cc/soname@librnd-hid.so.$(PCB_RND_VER_MAJOR) +SONAME_CORE=@cc/soname@librnd-core.so.$(PCB_RND_VER_MAJOR) SONAME_3RD=@cc/soname@librnd-3rd.so.$(PCB_RND_VER_MAJOR) SONAME_POLY=@cc/soname@librnd-poly.so.$(PCB_RND_VER_MAJOR) SONAME_FONT=@cc/soname@librnd-font.so.$(PCB_RND_VER_MAJOR) +SONAME_HID=@cc/soname@librnd-hid.so.$(PCB_RND_VER_MAJOR) @] end; end @@ -388,9 +397,9 @@ print [@ -librnd-hid.a: $(DEPS_HIDLIB_ALL) - $(ARU) $(AR) rvu librnd-hid.a $(OBJS_HIDLIB_ALL) - $(RANLIB) librnd-hid.a +librnd-core.a: $(DEPS_CORELIB_ALL) + $(ARU) $(AR) rvu librnd-core.a $(OBJS_CORELIB_ALL) + $(RANLIB) librnd-core.a librnd-3rd.a: $(OBJS_3RDLIB) $(ARU) $(AR) rvu librnd-3rd.a $(OBJS_3RDLIB) @@ -404,11 +413,15 @@ $(ARU) $(AR) rvu librnd-font.a $(OBJS_FONTLIB) $(RANLIB) librnd-font.a +librnd-hid.a: $(OBJS_HIDLIB_ALL) + $(ARU) $(AR) rvu librnd-hid.a $(OBJS_HIDLIB_ALL) + $(RANLIB) librnd-hid.a + # Note: .so depends on .a because $(ARU) renames some object files temporarily # so building the .so and the .a shouldn't be done in parallel -librnd-hid.so.$(PCB_RND_VER): $(DEPS_HIDLIB_ALL) librnd-hid.a - $(CC) @?cc/ldflags_dynlib@ @?cc/so_undefined@ $(SONAME_HID) -o librnd-hid.so.$(PCB_RND_VER) $(OBJS_HIDLIB_ALL) $(LDFLAGS) +librnd-core.so.$(PCB_RND_VER): $(DEPS_CORELIB_ALL) librnd-core.a + $(CC) @?cc/ldflags_dynlib@ @?cc/so_undefined@ $(SONAME_CORE) -o librnd-core.so.$(PCB_RND_VER) $(OBJS_CORELIB_ALL) $(LDFLAGS) librnd-3rd.so.$(PCB_RND_VER): $(OBJS_3RDLIB) librnd-3rd.a $(CC) @?cc/ldflags_dynlib@ @?cc/so_undefined@ $(SONAME_3RD) -o librnd-3rd.so.$(PCB_RND_VER) $(OBJS_3RDLIB) $(LDFLAGS) @/local/librnd/LIBRND_3RD_LDFLAGS@ @?libs/ldl@ -lm @@ -419,13 +432,16 @@ librnd-font.so.$(PCB_RND_VER): $(OBJS_FONTLIB) librnd-font.a $(CC) @?cc/ldflags_dynlib@ @?cc/so_undefined@ $(SONAME_FONT) -o librnd-font.so.$(PCB_RND_VER) $(OBJS_FONTLIB) $(LDFLAGS) -lm +librnd-hid.so.$(PCB_RND_VER): $(OBJS_HIDLIB_ALL) librnd-hid.a + $(CC) @?cc/ldflags_dynlib@ @?cc/so_undefined@ $(SONAME_HID) -o librnd-hid.so.$(PCB_RND_VER) $(OBJS_HIDLIB_ALL) $(LDFLAGS) -lm + # these are required in case librnd is used from source checkout in dynamic # lib mode -librnd-hid.so: librnd-hid.so.$(PCB_RND_VER) - $(SCCBOX) ln -f librnd-hid.so.$(PCB_RND_VER) librnd-hid.so - $(SCCBOX) ln -f librnd-hid.so.$(PCB_RND_VER) librnd-hid.so.$(PCB_RND_VER_MAJOR) +librnd-core.so: librnd-core.so.$(PCB_RND_VER) + $(SCCBOX) ln -f librnd-core.so.$(PCB_RND_VER) librnd-core.so + $(SCCBOX) ln -f librnd-core.so.$(PCB_RND_VER) librnd-core.so.$(PCB_RND_VER_MAJOR) librnd-3rd.so: librnd-3rd.so.$(PCB_RND_VER) $(SCCBOX) ln -f librnd-3rd.so.$(PCB_RND_VER) librnd-3rd.so @@ -439,6 +455,10 @@ $(SCCBOX) ln -f librnd-font.so.$(PCB_RND_VER) librnd-font.so $(SCCBOX) ln -f librnd-font.so.$(PCB_RND_VER) librnd-font.so.$(PCB_RND_VER_MAJOR) +librnd-hid.so: librnd-hid.so.$(PCB_RND_VER) + $(SCCBOX) ln -f librnd-hid.so.$(PCB_RND_VER) librnd-hid.so + $(SCCBOX) ln -f librnd-hid.so.$(PCB_RND_VER) librnd-hid.so.$(PCB_RND_VER_MAJOR) + @] @@ -451,25 +471,28 @@ else print [@ HIDLIB_CLEAN_FILES_SO=\ - librnd-hid.so.$(PCB_RND_VER) \ + librnd-core.so.$(PCB_RND_VER) \ librnd-3rd.so.$(PCB_RND_VER) \ librnd-poly.so.$(PCB_RND_VER) \ - librnd-font.so.$(PCB_RND_VER) + librnd-font.so.$(PCB_RND_VER) \ + librnd-hid.so.$(PCB_RND_VER) HIDLIB_CLEAN_FILES_SO_SY=\ - librnd-hid.so \ + librnd-core.so \ librnd-3rd.so \ librnd-poly.so \ - librnd-font.so + librnd-font.so \ + librnd-hid.so @] end print [@ HIDLIB_CLEAN_FILES_A=\ - librnd-hid.a \ + librnd-core.a \ librnd-3rd.a \ librnd-poly.a \ - librnd-font.a + librnd-font.a \ + librnd-hid.a HIDLIB_CLEAN_FILES=$(HIDLIB_CLEAN_FILES_A) $(HIDLIB_CLEAN_FILES_SO) $(HIDLIB_CLEAN_FILES_SO_SY) @@ -494,8 +517,8 @@ buildin.hidlib.c: $(LIBRND_PLUGDIR)/.builtin.hidlib.pups $(PUPLUG) cd $(LIBRND_PLUGDIR) && ../../$(PUPLUG) buildin.c "-" < .builtin.hidlib.pups > ../../buildin.hidlib.c -$(LIBRND)/core/buildin.hidlib.h: $(LIBRND_PLUGDIR)/.builtin.hidlib.pups $(PUPLUG) - $(PUPLUG) buildin.h > $(LIBRND)/core/buildin.hidlib.h +$(LIBRND)/hid/buildin.hidlib.h: $(LIBRND_PLUGDIR)/.builtin.hidlib.pups $(PUPLUG) + $(PUPLUG) buildin.h > $(LIBRND)/hid/buildin.hidlib.h @] @@ -531,7 +554,7 @@ FORCE: -DISTCLEANFILES = librnd/config.h Makefile.depgen buildin.hidlib.c $(LIBRND)/core/buildin.hidlib.h $(LIBRND)/core/compat_inc.h $(LIBRND)/core/hidlib_conf_fields.h ../src/librnd/plugins/.builtin.pups ../src/librnd/plugins/.builtin.hidlib.pups $(LIBRND)/core/librnd.mak $(LIBRND)/plugin.state @/local/pcb/DISTCLEANFILES@ +DISTCLEANFILES = librnd/config.h Makefile.depgen buildin.hidlib.c $(LIBRND)/hid/buildin.hidlib.h $(LIBRND)/core/compat_inc.h $(LIBRND)/core/hidlib_conf_fields.h ../src/librnd/plugins/.builtin.pups ../src/librnd/plugins/.builtin.hidlib.pups $(LIBRND)/core/librnd.mak $(LIBRND)/plugin.state @/local/pcb/DISTCLEANFILES@ clean: $(CLEANRULES) $(SCCBOX) rm -f -q pcb-rnd $(HIDLIB_CLEAN_FILES) $(OBJS) $(OBJS_C99) $(CLEANFILES) @@ -543,11 +566,12 @@ $(MAKE) install_librnd_ LIBDIR=$(HL_LIBDIR)/librnd4 install_librnd_: - $(SCCBOX) mkdir -p "$(HL_LIBDIR)/librnd4/plugins" "$(HL_LIBDIR)/librnd4/scconfig/template" "$(HL_INCDIR)/core" "$(HL_INCDIR)/poly" "$(HL_INCDIR)/font" "$(HL_INCDIR)/scconfig" "$(HL_INCDIR)/src_3rd/liblihata" "$(HL_INCDIR)/src_3rd/libualloc" "$(HL_INCDIR)/src_3rd/liblhtpers" "$(HL_INCDIR)/src_3rd/puplug" "$(HL_INCDIR)/src_3rd/libfungw" "$(HL_INCDIR)/src_3rd/genvector" "$(HL_INCDIR)/src_3rd/genregex" "$(HL_INCDIR)/src_3rd/ureglex" "$(HL_INCDIR)/src_3rd/genrtree" "$(HL_INCDIR)/src_3rd/libulzw" "$(HL_INCDIR)/src_3rd/genht" "$(HL_INCDIR)/src_3rd/libfungwbind/c" "$(HL_SHAREDIR)" "$(HL_INCDIR)/plugins/lib_hid_common" "$(HL_INCDIR)/plugins/lib_wget" "$(HL_INCDIR)/plugins/lib_exp_text" "$(HL_INCDIR)/plugins/lib_exp_pixmap" - $(SCCBOX) $(HOW) "librnd-hid.a" "$(HL_LIBDIR)/librnd-hid.a" + $(SCCBOX) mkdir -p "$(HL_LIBDIR)/librnd4/plugins" "$(HL_LIBDIR)/librnd4/scconfig/template" "$(HL_INCDIR)/core" "$(HL_INCDIR)/poly" "$(HL_INCDIR)/hid" "$(HL_INCDIR)/font" "$(HL_INCDIR)/scconfig" "$(HL_INCDIR)/src_3rd/liblihata" "$(HL_INCDIR)/src_3rd/libualloc" "$(HL_INCDIR)/src_3rd/liblhtpers" "$(HL_INCDIR)/src_3rd/puplug" "$(HL_INCDIR)/src_3rd/libfungw" "$(HL_INCDIR)/src_3rd/genvector" "$(HL_INCDIR)/src_3rd/genregex" "$(HL_INCDIR)/src_3rd/ureglex" "$(HL_INCDIR)/src_3rd/genrtree" "$(HL_INCDIR)/src_3rd/libulzw" "$(HL_INCDIR)/src_3rd/genht" "$(HL_INCDIR)/src_3rd/libfungwbind/c" "$(HL_SHAREDIR)" "$(HL_INCDIR)/plugins/lib_hid_common" "$(HL_INCDIR)/plugins/lib_wget" "$(HL_INCDIR)/plugins/lib_exp_text" "$(HL_INCDIR)/plugins/lib_exp_pixmap" + $(SCCBOX) $(HOW) "librnd-core.a" "$(HL_LIBDIR)/librnd-core.a" $(SCCBOX) $(HOW) "librnd-3rd.a" "$(HL_LIBDIR)/librnd-3rd.a" $(SCCBOX) $(HOW) "librnd-poly.a" "$(HL_LIBDIR)/librnd-poly.a" $(SCCBOX) $(HOW) "librnd-font.a" "$(HL_LIBDIR)/librnd-font.a" + $(SCCBOX) $(HOW) "librnd-hid.a" "$(HL_LIBDIR)/librnd-hid.a" $(SCCBOX) $(HOW) "$(LIBRND)/core/librnd.mak" "$(HL_SHAREDIR)/librnd.mak" $(SCCBOX) $(HOW) "$(LIBRND)/plugin.state" "$(HL_SHAREDIR)/plugin.state" $(SCCBOX) $(HOW) "../config.h" "$(HL_INCDIR)/core/config.h" @@ -567,7 +591,7 @@ $(SCCBOX) $(HOW) "librnd/scconfig/hooks_common.h" "$(HL_INCDIR)/scconfig/hooks_common.h" $(SCCBOX) $(HOW) "librnd/scconfig/rnd_hook_detect.h" "$(HL_INCDIR)/scconfig/rnd_hook_detect.h" $(SCCBOX) $(HOW) "librnd/scconfig/plugin_3state.h" "$(HL_INCDIR)/scconfig/plugin_3state.h" - $(SCCBOX) $(HOW) "$(LIBRND)/core/buildin.hidlib.h" "$(HL_INCDIR)/core/buildin.hidlib.h" + $(SCCBOX) $(HOW) "$(LIBRND)/hid/buildin.hidlib.h" "$(HL_INCDIR)/hid/buildin.hidlib.h" $(SCCBOX) $(HOW) "librnd/plugins/map_plugins.sh" "$(HL_LIBDIR)/librnd4/plugins/map_plugins.sh" cd ../src_3rd/puplug && $(MAKE) install_hdr_ MKDR="../$(SCCBOX) mkdir -p" INST="../$(SCCBOX) $(HOW)" INCDIR="$(HL_INCDIR)/src_3rd/puplug"@/local/pcb/rules/install_@@] @@ -577,47 +601,48 @@ @] else print [@ - $(SCCBOX) $(HOW) "librnd-hid.so.$(PCB_RND_VER)" "$(HL_LIBDIR)/librnd-hid.so.$(PCB_RND_VER)" + $(SCCBOX) $(HOW) "librnd-core.so.$(PCB_RND_VER)" "$(HL_LIBDIR)/librnd-core.so.$(PCB_RND_VER)" $(SCCBOX) $(HOW) "librnd-3rd.so.$(PCB_RND_VER)" "$(HL_LIBDIR)/librnd-3rd.so.$(PCB_RND_VER)" $(SCCBOX) $(HOW) "librnd-poly.so.$(PCB_RND_VER)" "$(HL_LIBDIR)/librnd-poly.so.$(PCB_RND_VER)" $(SCCBOX) $(HOW) "librnd-font.so.$(PCB_RND_VER)" "$(HL_LIBDIR)/librnd-font.so.$(PCB_RND_VER)" + $(SCCBOX) $(HOW) "librnd-hid.so.$(PCB_RND_VER)" "$(HL_LIBDIR)/librnd-hid.so.$(PCB_RND_VER)" @] end # rndlib: build a list of header files to be installed with the hidlib put /local/librnd/HDRS_3RDLIB /local/librnd/OBJS_3RDLIB -put /local/librnd/HDRS_HIDLIB /local/librnd/OBJS_HIDLIB -append /local/librnd/HDRS_HIDLIB /local/librnd/OBJS_POLYLIB -append /local/librnd/HDRS_HIDLIB /local/librnd/OBJS_FONTLIB +put /local/librnd/HDRS_CORELIB /local/librnd/OBJS_CORELIB +append /local/librnd/HDRS_CORELIB /local/librnd/OBJS_POLYLIB +append /local/librnd/HDRS_CORELIB /local/librnd/OBJS_FONTLIB +append /local/librnd/HDRS_CORELIB /local/librnd/OBJS_HIDLIB uniq /local/librnd/HDRS_3RDLIB -uniq /local/librnd/HDRS_HIDLIB -gsub /local/librnd/HDRS_HIDLIB {.o } {.h } +uniq /local/librnd/HDRS_CORELIB +gsub /local/librnd/HDRS_CORELIB {.o } {.h } gsub /local/librnd/HDRS_3RDLIB {.o } {.h } append /local/librnd/HDRS_3RDLIB /local/librnd/HDRS_GENHT # rndlib: corner case: some headers are not derived from the objects -sub /local/librnd/HDRS_HIDLIB {$(LIBRND)/core/hid_dlg.h } {} -sub /local/librnd/HDRS_HIDLIB {$(LIBRND)/core/conf_act.h } {} -sub /local/librnd/HDRS_HIDLIB {$(LIBRND)/core/anyload_act.h } {} -sub /local/librnd/HDRS_HIDLIB {$(LIBRND)/core/hid_act.h } {} -sub /local/librnd/HDRS_HIDLIB {$(LIBRND)/core/gui_act.h } {} -sub /local/librnd/HDRS_HIDLIB {$(LIBRND)/core/main_act.h } {} -append /local/librnd/HDRS_HIDLIB {$(LIBRND)/config.h $(LIBRND)/core/global_typedefs.h $(LIBRND)/core/globalconst.h $(LIBRND)/core/math_helper.h $(LIBRND)/core/buildin.hidlib.h $(LIBRND)/core/hid_inlines.h $(LIBRND)/core/rotate.h $(LIBRND)/core/fptr_cast.h $(LIBRND)/core/safe_fs_dir.h $(LIBRND)/core/compat_inc.h $(LIBRND)/poly/rtree2_compat.h $(LIBRND)/core/color_cache.h } -append /local/librnd/HDRS_HIDLIB {$(LIBRND)/font/font_lht.h $(LIBRND)/font/glyph.h } -append /local/librnd/HDRS_HIDLIB {$(LIBRND)/plugins/lib_hid_common/dialogs_conf.h $(LIBRND)/plugins/lib_hid_common/xpm.h $(LIBRND)/plugins/lib_hid_common/dlg_comm_m.h $(LIBRND)/plugins/lib_hid_common/place.h $(LIBRND)/plugins/lib_hid_common/toolbar.h $(LIBRND)/plugins/lib_hid_common/dlg_pref.h $(LIBRND)/plugins/lib_hid_common/zoompan.h $(LIBRND)/plugins/lib_hid_common/dlg_export.h } -append /local/librnd/HDRS_HIDLIB {$(LIBRND)/plugins/lib_wget/lib_wget.h } -append /local/librnd/HDRS_HIDLIB {$(LIBRND)/plugins/lib_exp_text/draw_eps.h } -append /local/librnd/HDRS_HIDLIB {$(LIBRND)/plugins/lib_exp_text/draw_ps.h } -append /local/librnd/HDRS_HIDLIB {$(LIBRND)/plugins/lib_exp_text/draw_svg.h } -append /local/librnd/HDRS_HIDLIB {$(LIBRND)/plugins/lib_exp_text/media.h } -append /local/librnd/HDRS_HIDLIB {$(LIBRND)/plugins/lib_exp_text/lpr_hid.h } -append /local/librnd/HDRS_HIDLIB {$(LIBRND)/plugins/lib_exp_pixmap/draw_pixmap.h } +sub /local/librnd/HDRS_CORELIB {$(LIBRND)/core/conf_act.h } {} +sub /local/librnd/HDRS_CORELIB {$(LIBRND)/core/main_act.h } {} +sub /local/librnd/HDRS_CORELIB {$(LIBRND)/hid/anyload_act.h } {} +sub /local/librnd/HDRS_CORELIB {$(LIBRND)/hid/hid_act.h } {} +sub /local/librnd/HDRS_CORELIB {$(LIBRND)/hid/hid_dlg.h } {} +append /local/librnd/HDRS_CORELIB {$(LIBRND)/config.h $(LIBRND)/core/global_typedefs.h $(LIBRND)/core/globalconst.h $(LIBRND)/core/math_helper.h $(LIBRND)/hid/buildin.hidlib.h $(LIBRND)/hid/hid_inlines.h $(LIBRND)/core/rotate.h $(LIBRND)/core/fptr_cast.h $(LIBRND)/core/safe_fs_dir.h $(LIBRND)/core/compat_inc.h $(LIBRND)/poly/rtree2_compat.h $(LIBRND)/core/color_cache.h } +append /local/librnd/HDRS_CORELIB {$(LIBRND)/font/font_lht.h $(LIBRND)/font/glyph.h } +append /local/librnd/HDRS_CORELIB {$(LIBRND)/plugins/lib_hid_common/dialogs_conf.h $(LIBRND)/plugins/lib_hid_common/xpm.h $(LIBRND)/plugins/lib_hid_common/dlg_comm_m.h $(LIBRND)/plugins/lib_hid_common/place.h $(LIBRND)/plugins/lib_hid_common/toolbar.h $(LIBRND)/plugins/lib_hid_common/dlg_pref.h $(LIBRND)/plugins/lib_hid_common/zoompan.h $(LIBRND)/plugins/lib_hid_common/dlg_export.h } +append /local/librnd/HDRS_CORELIB {$(LIBRND)/plugins/lib_wget/lib_wget.h } +append /local/librnd/HDRS_CORELIB {$(LIBRND)/plugins/lib_exp_text/draw_eps.h } +append /local/librnd/HDRS_CORELIB {$(LIBRND)/plugins/lib_exp_text/draw_ps.h } +append /local/librnd/HDRS_CORELIB {$(LIBRND)/plugins/lib_exp_text/draw_svg.h } +append /local/librnd/HDRS_CORELIB {$(LIBRND)/plugins/lib_exp_text/media.h } +append /local/librnd/HDRS_CORELIB {$(LIBRND)/plugins/lib_exp_text/lpr_hid.h } +append /local/librnd/HDRS_CORELIB {$(LIBRND)/plugins/lib_exp_pixmap/draw_pixmap.h } # TODO: remove this in 4.0.0 -append /local/librnd/HDRS_HIDLIB {$(LIBRND)/core/conf_multi_temp.h } +append /local/librnd/HDRS_CORELIB {$(LIBRND)/core/conf_multi_temp.h } # extra core headers to install -append /local/librnd/HDRS_HIDLIB { $(LIBRND)/core/funchash_core.h $(LIBRND)/core/funchash_core_list.h } +append /local/librnd/HDRS_CORELIB { $(LIBRND)/core/funchash_core.h $(LIBRND)/core/funchash_core_list.h } gsub /local/librnd/HDRS_3RDLIB {../src_3rd/liblihata/dom_[^ ]*.h } {} gsub /local/librnd/HDRS_3RDLIB {../src_3rd/liblihata/tree_[^ ]*.h } {} @@ -631,11 +656,11 @@ append /local/librnd/HDRS_3RDLIB {../src_3rd/genregex/regex_templ.h } append /local/librnd/HDRS_3RDLIB {../src_3rd/genlist/ } -sub /local/librnd/HDRS_HIDLIB {$(LIBRND)/core/buildin.hidlib.h } {} -sub /local/librnd/HDRS_HIDLIB {buildin.hidlib.h } {} +sub /local/librnd/HDRS_CORELIB {$(LIBRND)/hid/buildin.hidlib.h } {} +sub /local/librnd/HDRS_CORELIB {buildin.hidlib.h } {} # dynamic part of install_pcbrnd: hidlib headers -foreach /local/h in /local/librnd/HDRS_HIDLIB +foreach /local/h in /local/librnd/HDRS_CORELIB put /local/hd /local/h switch /local/h case {^$(LIBRND)/} @@ -679,8 +704,8 @@ else print [@ install_librnd_sy: - $(SCCBOX) $(HOW) "$(HL_LIBDIR)/librnd-hid.so.$(PCB_RND_VER)" "$(HL_LIBDIR)/librnd-hid.so.$(PCB_RND_VER_MAJOR)" - $(SCCBOX) $(HOW) "$(HL_LIBDIR)/librnd-hid.so.$(PCB_RND_VER)" "$(HL_LIBDIR)/librnd-hid.so" + $(SCCBOX) $(HOW) "$(HL_LIBDIR)/librnd-core.so.$(PCB_RND_VER)" "$(HL_LIBDIR)/librnd-core.so.$(PCB_RND_VER_MAJOR)" + $(SCCBOX) $(HOW) "$(HL_LIBDIR)/librnd-core.so.$(PCB_RND_VER)" "$(HL_LIBDIR)/librnd-core.so" $(SCCBOX) $(HOW) "$(HL_LIBDIR)/librnd-3rd.so.$(PCB_RND_VER)" "$(HL_LIBDIR)/librnd-3rd.so.$(PCB_RND_VER_MAJOR)" $(SCCBOX) $(HOW) "$(HL_LIBDIR)/librnd-3rd.so.$(PCB_RND_VER)" "$(HL_LIBDIR)/librnd-3rd.so" $(SCCBOX) $(HOW) "$(HL_LIBDIR)/librnd-poly.so.$(PCB_RND_VER)" "$(HL_LIBDIR)/librnd-poly.so.$(PCB_RND_VER_MAJOR)" @@ -687,6 +712,8 @@ $(SCCBOX) $(HOW) "$(HL_LIBDIR)/librnd-poly.so.$(PCB_RND_VER)" "$(HL_LIBDIR)/librnd-poly.so" $(SCCBOX) $(HOW) "$(HL_LIBDIR)/librnd-font.so.$(PCB_RND_VER)" "$(HL_LIBDIR)/librnd-font.so.$(PCB_RND_VER_MAJOR)" $(SCCBOX) $(HOW) "$(HL_LIBDIR)/librnd-font.so.$(PCB_RND_VER)" "$(HL_LIBDIR)/librnd-font.so" + $(SCCBOX) $(HOW) "$(HL_LIBDIR)/librnd-hid.so.$(PCB_RND_VER)" "$(HL_LIBDIR)/librnd-hid.so.$(PCB_RND_VER_MAJOR)" + $(SCCBOX) $(HOW) "$(HL_LIBDIR)/librnd-hid.so.$(PCB_RND_VER)" "$(HL_LIBDIR)/librnd-hid.so" @] end Index: trunk/src/librnd/core/hid_menu.c =================================================================== --- trunk/src/librnd/core/hid_menu.c (revision 34601) +++ trunk/src/librnd/core/hid_menu.c (nonexistent) @@ -1,1477 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * Copyright (C) 2016,2020,2021 Tibor 'Igor2' Palinkas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact: - * Project page: http://repo.hu/projects/pcb-rnd - * lead developer: http://repo.hu/projects/pcb-rnd/contact.html - * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") - */ - -/* menu file loading, menu merging: all files are loaded into the memory - where the final lihata document that represents the menu is merged; - then the new version is compared to the old version and differneces - applied to the menu system */ - -#include -#include -#include -#include -#include -#include - -#include -#include "anyload.h" -#include "hidlib.h" -#include "actions.h" -#include "file_loaded.h" -#include "hidlib_conf.h" -#include "paths.h" -#include "funchash_core.h" -#include "compat_misc.h" -#include "event.h" -#include "conf_hid.h" -#include "safe_fs.h" - -#include "hid_menu.h" - -lht_node_t ins_as_first, *rnd_hid_menu_ins_as_first = &ins_as_first; - -static const char menu_cookie[] = "librnd/hid_menu"; -static const char menu_cookie_al[] = "librnd/hid_menu/anyload"; -static rnd_conf_hid_id_t menu_conf_id; - - -/*** load & merge ***/ - -rnd_menu_sys_t rnd_menu_sys; -static long next_menu_uid; - -void rnd_menu_sys_init(rnd_menu_sys_t *msys) -{ - memset(msys, 0, sizeof(rnd_menu_sys_t)); -} - -static void rnd_menu_sys_insert(rnd_menu_sys_t *msys, rnd_menu_patch_t *menu) -{ - int n; - rnd_menu_patch_t *m; - - menu->uid = next_menu_uid++; - - /* assume only a dozen of patch files -> linear search is good enough for now */ - for(n = 0; n < msys->patches.used; n++) { - m = msys->patches.array[n]; - if (m->prio > menu->prio) { - vtp0_insert_len(&msys->patches, n, (void **)&menu, 1); - msys->changes++; - return; - } - } - vtp0_append(&msys->patches, menu); - msys->changes++; -} - -static void menu_sys_remove(rnd_menu_sys_t *msys, int n, rnd_menu_patch_t *m) -{ - vtp0_remove(&msys->patches, n, 1); - lht_dom_uninit(m->cfg.doc); - free(m->cookie); - free(m->desc); - free(m); - msys->changes++; -} - -static void rnd_menu_sys_remove(rnd_menu_sys_t *msys, rnd_menu_patch_t *mp) -{ - int n; - - /* assume only a dozen of patch files -> linear search is good enough for now */ - for(n = 0; n < msys->patches.used; n++) { - rnd_menu_patch_t *m = msys->patches.array[n]; - if (mp == m) { - menu_sys_remove(msys, n, m); - n--; - } - } -} - -static void rnd_menu_sys_remove_cookie(rnd_menu_sys_t *msys, const char *cookie) -{ - int n; - - /* assume only a dozen of patch files -> linear search is good enough for now */ - for(n = 0; n < msys->patches.used; n++) { - rnd_menu_patch_t *m = msys->patches.array[n]; - if (strcmp(m->cookie, cookie) == 0) { - menu_sys_remove(msys, n, m); - n--; - } - } -} - -static rnd_menu_patch_t *rnd_menu_sys_find_cookie(rnd_menu_sys_t *msys, const char *cookie) -{ - int n; - - for(n = 0; n < msys->patches.used; n++) { - rnd_menu_patch_t *m = msys->patches.array[n]; - if (strcmp(m->cookie, cookie) == 0) - return m; - } - - return NULL; -} - -static lht_node_t *search_list_for_node(lht_node_t *list, lht_node_t *target) -{ - lht_node_t *n; - lht_dom_iterator_t it; - - for(n = lht_dom_first(&it, list); n != NULL; n = lht_dom_next(&it)) - if (strcmp(n->name, target->name) == 0) { - if ((n->type == LHT_TEXT) && (target->type == LHT_TEXT)) { /* text nodes are normally anonymous and the have to be compared by value */ - if (strcmp(n->data.text.value, target->data.text.value) == 0) - return n; - } - else - return n; - } - return NULL; -} - -#define submenu(node) ((node->type == LHT_HASH) ? (lht_dom_hash_get((node), "submenu")) : NULL) - -static void lht_tree_merge_list_submenu(lht_node_t *dst, lht_node_t *src, lht_err_t recurse(lht_node_t *, lht_node_t *)) -{ - lht_dom_iterator_t it; - lht_node_t *s, *a; - - for(s = lht_dom_first(&it, src); s != NULL; s = lht_dom_next(&it)) { - a = search_list_for_node(dst, s); - if (a == NULL) { /* append new items at the end */ - lht_tree_detach(s); /* removing an item from the list from the iterator is a special case that works since r584 */ - lht_dom_list_append(dst, s); - } - else { - lht_tree_detach(s); /* removing an item from the list from the iterator is a special case that works since r584 */ - recurse(a, s); - } - } -} - -static lht_err_t lht_tree_merge_list_submenu_prop(lht_node_t *dst, lht_node_t *src) -{ - lht_node_t *parent = dst->parent; - assert(parent->type == LHT_HASH); - lht_tree_del(dst); - lht_tree_detach(src); - lht_dom_hash_put(parent, src); - return LHTE_SUCCESS; -} - -static lht_err_t menu_tree_merge_hash(lht_node_t *dst, lht_node_t *src, lht_err_t recurse(lht_node_t *, lht_node_t *)) -{ - lht_dom_iterator_t it; - lht_node_t *d, *ssub, *dsub; - - /* menu special casing: submenus don't mix with plain menus */ - ssub = lht_dom_hash_get(src, "submenu"); - dsub = lht_dom_hash_get(dst, "submenu"); - if ((dsub == NULL) && (ssub != NULL)) { - /* overwrite plain menu with submenu */ - for(d = lht_dom_first(&it, dst); d != NULL; d = lht_dom_next(&it)) - lht_tree_del(d); - } - else if ((dsub != NULL) && (ssub == NULL)) - lht_tree_del(dsub); /* overwrite submenu with plain menu */ - - /* after sorting that out, do the default lihata merge: */ - return lht_tree_merge_hash(dst, src, recurse); -} - -static lht_err_t lht_tree_merge_menu(lht_node_t *dst, lht_node_t *src) -{ - lht_err_t e; - - switch(dst->type) { - case LHT_INVALID_TYPE: return LHTE_BROKEN_DOC; - case LHT_TEXT: lht_tree_merge_text(dst, src); break; - case LHT_TABLE: e = lht_tree_merge_table(dst, src); if (e != LHTE_SUCCESS) return e; break; - case LHT_HASH: e = menu_tree_merge_hash(dst, src, lht_tree_merge_menu); if (e != LHTE_SUCCESS) return e; break; - case LHT_LIST: - if ((strcmp(dst->name, "submenu") == 0) || (strcmp(dst->name, "main_menu") == 0) || (strcmp(dst->name, "popups") == 0)) - lht_tree_merge_list_submenu(dst, src, lht_tree_merge_menu); - else if (strcmp(dst->name, "anchored") == 0) - lht_tree_merge_list(dst, src); - else - return lht_tree_merge_list_submenu_prop(dst, src); - break; - case LHT_SYMLINK: - /* symlink text match */ - break; - } - lht_dom_node_free(src); - return LHTE_SUCCESS; -} - -#define GET_PATH_TEXT(instname, n, path) \ -do { \ - if (inst->type != LHT_HASH) { \ - rnd_message(RND_MSG_ERROR, "Menu merging error: " instname " patch instruction must be a hash node\n"); \ - return; \ - } \ - path = lht_dom_hash_get(inst, "path"); \ - if (path == NULL) { \ - rnd_message(RND_MSG_ERROR, "Menu merging error: " instname " patch instruction without a menu path\n"); \ - return; \ - } \ - if (path->type != LHT_TEXT) { \ - rnd_message(RND_MSG_ERROR, "Menu merging error: " instname " patch instruction menu path must be text\n"); \ - return; \ - } \ - n = rnd_hid_cfg_get_menu_at_node(dst, path->data.text.value, NULL, NULL); \ - if (n == NULL) \ - return; \ -} while(0) - -static void menu_patch_apply_remove_menu(lht_node_t *dst, lht_node_t *inst) -{ - lht_node_t *n, *path; - - GET_PATH_TEXT("remove_menu", n, path); - - if ((strcmp(n->name, "main_menu") == 0) || (strcmp(n->name, "popups") == 0) || (strcmp(n->name, "anchored") == 0)) { - if (submenu(n->parent) == NULL) { - rnd_message(RND_MSG_ERROR, "Menu merging error: remove_menu patch attempted to remove a menu root\n"); - return; - } - } - - lht_tree_del(n); -} - -static void menu_patch_apply_append_menu(lht_node_t *dst, lht_node_t *inst) -{ - lht_node_t *dn, *path, *isub, *tmp, *dsub; - - GET_PATH_TEXT("append_menu", dn, path); - - isub = lht_dom_hash_get(inst, "submenu"); \ - if ((isub == NULL) || (isub->type != LHT_LIST)) { - rnd_message(RND_MSG_ERROR, "Menu merging error: append_menu patch instruction submenu must a list\n"); - return; - } - dsub = submenu(dn); - if (dsub == NULL) { - rnd_message(RND_MSG_ERROR, "Menu merging error: append_menu patch instruction attempted to append to a non-submenu %s\n", dn->name); - return; - } - - tmp = lht_dom_duptree(isub); - lht_tree_merge_using(dsub, tmp, lht_tree_merge_menu); -} - - -static void menu_patch_apply_overwrite_menu_props(lht_node_t *dst, lht_node_t *inst) -{ - lht_node_t *dn, *sn, *path, *n, *tmp; - lht_dom_iterator_t it; - - GET_PATH_TEXT("overwrite_menu_props", dn, path); - - if (submenu(dn) != NULL) { - rnd_message(RND_MSG_ERROR, "Menu merging error: overwrite_menu_props patch instruction path refers to a menu that has submenus (not properties)\n"); - return; - } - - sn = lht_dom_hash_get(inst, "props"); - if ((sn == NULL) || (sn->type != LHT_HASH)) { - rnd_message(RND_MSG_ERROR, "Menu merging error: overwrite_menu_props patch instruction needs a ha:props child\n"); - return; - } - - /* replace each named child of dn enumerating src/props */ - for(n = lht_dom_first(&it, sn); n != NULL; n = lht_dom_next(&it)) { - tmp = lht_dom_hash_get(dn, n->name); - if (tmp != NULL) - lht_tree_del(tmp); - tmp = lht_dom_duptree(n); - lht_dom_hash_put(dn, tmp); - } -} - -/* check if node is a menu file root (not menu patch root!); for backward - compatibility: accept anonymous node as menu file if it has a main_menu child */ -#define is_menu_file_root(node) \ - (((node)->type == LHT_HASH) && ((strcmp((node)->name, "rnd-menu-v1") == 0) || ((((node)->name[0] == '\0')) && (lht_dom_hash_get(node, "main_menu") != NULL)))) - -static void menu_patch_apply(lht_node_t *dst, lht_node_t *src) -{ - lht_node_t *tmp; - - /* merging a complete menu file is easy: use lihata's default merge algorithm, - except for submenu lists where by-name merging is required */ - if (is_menu_file_root(src)) { - tmp = lht_dom_duptree(src); - lht_tree_merge_using(dst, tmp, lht_tree_merge_menu); - return; - } - - /* execute patching instructions */ - if ((src->type == LHT_HASH) && (strcmp(src->name, "rnd-menu-patch-v1") == 0)) { - lht_node_t *p, *patch = lht_dom_hash_get(src, "patch"); - if ((patch == NULL) || (patch->type != LHT_LIST)) { - rnd_message(RND_MSG_ERROR, "Menu merging error: patch instructions must be in a li:patch\n"); - return; - } - for(p = patch->data.list.first; p != NULL; p = p->next) { - if (p->type != LHT_HASH) { - rnd_message(RND_MSG_ERROR, "Menu merging error: invalid patch instruction %s (not a hash)\n", p->name); - continue; - } - if (strcmp(p->name, "remove_menu") == 0) - menu_patch_apply_remove_menu(dst, p); - else if (strcmp(p->name, "append_menu") == 0) - menu_patch_apply_append_menu(dst, p); - else if (strcmp(p->name, "overwrite_menu_props") == 0) - menu_patch_apply_overwrite_menu_props(dst, p); - else { - rnd_message(RND_MSG_ERROR, "Menu merging error: unknown patch instruction %s\n", p->name); - continue; - } - } - return; - } - - rnd_message(RND_MSG_ERROR, "Menu merging error: invalid menu file root: %s\n", src->name); -} - -static void create_menu_by_node(lht_node_t *dst, lht_node_t *ins_after, int is_popup) -{ - lht_node_t *parent; - int is_main; - - if (rnd_menu_sys.gui_nomod) - return; - - parent = dst->parent; - is_main = (strcmp(parent->name, "submenu") != 0); - if (!is_main) - parent = parent->parent; - - rnd_gui->create_menu_by_node(rnd_gui, is_popup, dst->name, is_main, parent, ins_after, dst); -} - -static void menu_merge_remove_recursive(lht_node_t *node) -{ - lht_node_t *n, *sub = submenu(node); - if (sub != NULL) { - lht_dom_iterator_t it; - for(n = lht_dom_first(&it, sub); n != NULL; n = lht_dom_next(&it)) - menu_merge_remove_recursive(n); - } - rnd_gui->remove_menu_node(rnd_gui, node); - lht_tree_del(node); -} - -/* replace menu subtree at dst with the one at src */ -static void menu_merge_replace(lht_node_t *dst, lht_node_t *src, int is_popup) -{ - lht_node_t *tmp, *n, *after = rnd_hid_menu_ins_as_first; - - assert(dst->parent->type = LHT_LIST); - - /* figure where the previous node at dst on the list so we can insert at the - same position after the removal */ - for(n = dst->parent->data.list.first; (n != NULL) && (n != dst); n = n->next) - after = n; - - tmp = lht_dom_duptree(src); - lht_dom_list_insert_after(dst, tmp); - - menu_merge_remove_recursive(dst); - create_menu_by_node(tmp, after, is_popup); -} - -static rnd_bool menu_plain_submenus_differ(lht_node_t *a, lht_node_t *b) -{ - lht_node_t *n, *m; - lht_dom_iterator_t it; - - if (a->type != b->type) - return 1; - - /* assume names match - the caller should have checked that in case of list */ - - switch(a->type) { - case LHT_TEXT: - case LHT_SYMLINK: - return (strcmp(a->data.text.value, b->data.text.value) != 0); - case LHT_HASH: - if (a->data.hash.tbl->used != b->data.hash.tbl->used) - return 1; - for(n = lht_dom_first(&it, a); n != NULL; n = lht_dom_next(&it)) { - m = lht_dom_hash_get(b, n->name); - if (m == NULL) - return 1; - if (menu_plain_submenus_differ(n, m)) - return 1; - } - return 0; - case LHT_LIST: - for(n = a->data.list.first, m = b->data.list.first;; n = n->next, m = m->next) { - if ((n == NULL) && (m == NULL)) - return 0; - if ((n == NULL) || (m == NULL)) /* list length mismatch */ - return 1; - if (menu_plain_submenus_differ(n, m)) - return 1; - } - break; - default: - return 1; /* unhandled type - shouldn't be in a menu, but when it is, it surely differs */ - } - return 1; /* can't get here anyway */ -} - -static void menu_merge_submenu(lht_node_t *dst, lht_node_t *src, int is_popup) -{ - lht_node_t *dn, *sn, *ssub, *dsub, *tmp; - lht_dom_iterator_t it; - - /* find nodes that are present in dst but not in src -> remove */ - for(dn = lht_dom_first(&it, dst); dn != NULL; dn = lht_dom_next(&it)) { - sn = search_list_for_node(src, dn); - if (sn == NULL) - menu_merge_remove_recursive(dn); - } - - /* find nodes that are present in both -> either recurse or modify */ - for(dn = lht_dom_first(&it, dst); dn != NULL; dn = lht_dom_next(&it)) { - sn = search_list_for_node(src, dn); - if (sn != NULL) { - ssub = submenu(sn); - dsub = submenu(dn); - if ((dsub == NULL) && (ssub == NULL)) { - /* modify: plain node is replaced by a plain node */ - if (menu_plain_submenus_differ(dn, sn)) - menu_merge_replace(dn, sn, is_popup); /* if they are not the same, have to replace */ - } - else if ((dsub != NULL) && (ssub != NULL)) - menu_merge_submenu(dsub, ssub, is_popup); /* same submenu -> recurse */ - else if ((dsub != NULL) && (ssub == NULL)) - menu_merge_replace(dn, sn, is_popup); /* modify: a submenu is replaced by a plain node */ - else if ((dsub == NULL) && (ssub != NULL)) - menu_merge_replace(dn, sn, is_popup); /* modify: a plain node is replaced by a submenu */ - } - } - - /* find nodes that are present in src but not in dst -> add */ - for(sn = lht_dom_first(&it, src); sn != NULL; sn = lht_dom_next(&it)) { - dn = search_list_for_node(dst, sn); - if (dn == NULL) { - tmp = lht_dom_duptree(sn); - lht_dom_list_append(dst, tmp); - - dn = search_list_for_node(dst, sn); - if (dn != NULL) - create_menu_by_node(dn, NULL, is_popup); - } - } -} - -typedef struct { - char *name; /* points into path*/ - char path[1]; /* extends longer */ -} anchor_t; - -static void append_anchor(vtp0_t *anch, gds_t *path, lht_node_t *n) -{ - anchor_t *a; - int save = path->used; - gds_append(path, '/'); - gds_append_str(path, n->data.text.value); - a = malloc(sizeof(anchor_t) + path->used+1); - memcpy(a->path, path->array, path->used+1); - a->name = a->path + save + 1; -/* printf(">anchor: '%s': %s\n", a->name, a->path);*/ - gds_truncate(path, save); - vtp0_append(anch, a); -} - -static void map_anchors_submenu(vtp0_t *anch, gds_t *path, lht_node_t *root) -{ - lht_node_t *n, *sm; - assert(root->type == LHT_LIST); - for(n = root->data.list.first; n != NULL; n = n->next) { - if ((n->type == LHT_TEXT) && (n->data.text.value != NULL) && (n->data.text.value[0] == '@')) - append_anchor(anch, path, n); - sm = submenu(n); - if (sm != NULL) { - int save = path->used; - gds_append(path, '/'); - gds_append_str(path, n->name); - map_anchors_submenu(anch, path, sm); - gds_truncate(path, save); - } - } -} - -/* Insert all items from a submenu list (src_lst) after the anchor node anode; - picks up new anchors inserted by the operation */ -static void menu_merge_anchored_at(vtp0_t *anch, lht_node_t *anode, lht_node_t *src_lst, anchor_t *a) -{ - lht_node_t *n, *after = anode, *nsub; - lht_dom_iterator_t it; - gds_t path = {0}; - long init_len; - int is_popup = (strncmp(a->path, "popups", 6) == 0); - - gds_append_str(&path, a->path); - init_len = path.used - strlen(a->name) - 1; - - for(n = lht_dom_first(&it, src_lst); n != NULL; n = lht_dom_next(&it)) { - lht_tree_detach(n); - lht_dom_list_insert_after(after, n); - - if ((n->type == LHT_TEXT) && (n->data.text.value != NULL) && (n->data.text.value[0] == '@')) { - /* we may have added an anchor */ - gds_truncate(&path, init_len); - append_anchor(anch, &path, n); - } - else { - /* if a whole submenu is appended, there might be new anchors in it */ - nsub = submenu(n); - if (nsub != NULL) { - gds_truncate(&path, init_len); - map_anchors_submenu(anch, &path, nsub); - } - } - create_menu_by_node(n, after, is_popup); - after = n; - } - - - gds_uninit(&path); -} - -/* Merge the li:anchored subtree: each item must be a ha:@anchor reference with - a li:submenu; look up the @anchor in the existing tree and insert each child - of the li_submenu after that @anchor in dst. */ -static void menu_merge_anchored(vtp0_t *anch, lht_node_t *dst, lht_node_t *src) -{ - if (src->type != LHT_LIST) { - rnd_message(RND_MSG_ERROR, "Menu merging error: /anchored must be a list\n"); - return; - } - - for(src = src->data.list.first; src != NULL; src = src->next) { - long n, found = 0; - lht_node_t *src_sub; - - if ((src->name == NULL) || (src->name[0] != '@')) { - rnd_message(RND_MSG_ERROR, "Menu merging error: /anchored subtree names must started with a '@' (ignoring offending node: %s)\n", src->name); - continue; - } - - src_sub = submenu(src); - if (src_sub == NULL) { - rnd_message(RND_MSG_ERROR, "Menu merging error: /anchored node without submenu (ignoring offending node: %s)\n", src->name); - continue; - } - - for(n = 0; n < anch->used; n++) { - anchor_t *a = anch->array[n]; - if (strcmp(src->name, a->name) == 0) { - lht_node_t *anode = rnd_hid_cfg_get_menu_at_node(dst, a->path, NULL, NULL); - if (anode != NULL) { -/* printf(" anchored! '%s' at %s: %p\n", src->name, a->path, anode);*/ - menu_merge_anchored_at(anch, anode, src_sub, a); - found++; - } - } - } - if (found == 0) { - rnd_message(RND_MSG_ERROR, "Menu merging error: anchor %s not found\n", src->name); - } - } -} - - /* recursive merge of the final trees starting from the root */ -static void menu_merge_root(lht_node_t *dst, lht_node_t *src) -{ - lht_node_t *dn, *sn; - vtp0_t anch = {0}; - gds_t path = {0}; - long n; - - assert(dst->type == LHT_HASH); - assert(src->type == LHT_HASH); - - dn = lht_dom_hash_get(dst, "main_menu"); - sn = lht_dom_hash_get(src, "main_menu"); - menu_merge_submenu(dn, sn, 0); - path.used = 0; - gds_append_str(&path, "main_menu"); - map_anchors_submenu(&anch, &path, dn); - - - dn = lht_dom_hash_get(dst, "popups"); - sn = lht_dom_hash_get(src, "popups"); - menu_merge_submenu(dn, sn, 1); - path.used = 0; - gds_append_str(&path, "popups"); - map_anchors_submenu(&anch, &path, dn); - - sn = lht_dom_hash_get(src, "anchored"); - if (sn != NULL) - menu_merge_anchored(&anch, dst, sn); - - for(n = 0; n < anch.used; n++) - free(anch.array[n]); - vtp0_uninit(&anch); - TODO("mouse, toolbar_static, scripts"); -} - -static lht_doc_t *new_menu_file() -{ - lht_doc_t *new = lht_dom_init(); - - new->root = lht_dom_node_alloc(LHT_HASH, "rnd-menu-v1"); - new->root->doc = new; - lht_dom_hash_put(new->root, lht_dom_node_alloc(LHT_LIST, "main_menu")); - lht_dom_hash_put(new->root, lht_dom_node_alloc(LHT_LIST, "popups")); - lht_dom_hash_put(new->root, lht_dom_node_alloc(LHT_LIST, "anchored")); - return new; -} - -static lht_doc_t *dup_base(rnd_menu_patch_t *base) -{ - lht_node_t *tmp; - lht_doc_t *new; - - if ((base == NULL) || (base->cfg.doc == NULL) || (base->cfg.doc->root == NULL)) - return new_menu_file(); - - new = lht_dom_init(); - new->root = lht_dom_node_alloc(LHT_HASH, "rnd-menu-v1"); - new->root->doc = new; - tmp = lht_dom_duptree(base->cfg.doc->root); - lht_tree_merge(new->root, tmp); - return new; -} - -static void lht_set_doc(lht_node_t *node, lht_doc_t *doc) -{ - lht_node_t *n; - lht_dom_iterator_t it; - - node->doc = doc; - for(n = lht_dom_first(&it, node); n != NULL; n = lht_dom_next(&it)) - lht_set_doc(n, doc); -} - -static void menu_merge(rnd_hid_t *hid) -{ - rnd_menu_patch_t *base = NULL; - int just_created = 0; - - if (!rnd_menu_sys.gui_ready || (rnd_menu_sys.inhibit > 0)) - return; - - if (rnd_menu_sys.patches.used > 0) - base = rnd_menu_sys.patches.array[0]; - - if (base != NULL) { - if (base->cfg.doc->root == NULL) { - rnd_message(RND_MSG_ERROR, "Failed to load base menu file\n"); - base = NULL; - } - else if (!is_menu_file_root(base->cfg.doc->root)) { - rnd_message(RND_MSG_ERROR, "Base menu file %s has invalid root (should be: ha:rnd-menu-v1)\n", base->cfg.doc->root->name); - base = NULL; - } - } - else { - rnd_message(RND_MSG_ERROR, "Menu merging error: no menu file\n"); - return; - } - - if (hid->menu == NULL) { - hid->menu = calloc(sizeof(rnd_hid_cfg_t), 1); /* make sure the cache is cleared */ - hid->menu->doc = dup_base(base); - just_created = 1; - } - - if ((just_created == 0) || (rnd_menu_sys.patches.used > 1)) { - int n; - lht_doc_t *new; - - if ((base != NULL) && (base->cfg.doc != NULL) && (base->cfg.doc->root != NULL)) { - new = lht_dom_init(); - new->root = lht_dom_duptree(base->cfg.doc->root); - lht_set_doc(new->root, new); - } - else - new = new_menu_file(); - - /* apply all patches */ - for(n = 1; n < rnd_menu_sys.patches.used; n++) { - rnd_menu_patch_t *m = rnd_menu_sys.patches.array[n]; - menu_patch_apply(new->root, m->cfg.doc->root); - } - - /* perform the final tree merge */ - menu_merge_root(hid->menu->doc->root, new->root); - -#if 0 - { -#undef fopen - FILE *f = fopen("A_merged.lht", "w"); - lht_dom_export(hid->menu->doc->root, f, ""); - fclose(f); - } -#endif - - lht_dom_uninit(new); - - } - - rnd_menu_sys.last_merged = rnd_menu_sys.changes; - rnd_event(NULL, RND_EVENT_MENU_CHANGED, NULL); -} - -void rnd_hid_menu_gui_ready_to_create(rnd_hid_t *hid) -{ - rnd_menu_sys.gui_ready = 1; - rnd_menu_sys.gui_nomod = 1; - menu_merge(hid); -} - -void rnd_hid_menu_gui_ready_to_modify(rnd_hid_t *hid) -{ - rnd_menu_sys.gui_nomod = 0; -} - -static int determine_prio(lht_node_t *node, int default_prio) -{ - long l; - char *end; - - if ((node == NULL) || (node->type != LHT_HASH) || (strcmp(node->name, "rnd-menu-patch-v1") != 0)) - return default_prio; - node = lht_dom_hash_get(node, "prio"); - if (node == NULL) - return default_prio; - if (node->type != LHT_TEXT) { - rnd_message(RND_MSG_ERROR, "Menu merging error: ignoring prio (must be a text node)\n"); - return default_prio; - } - - l = strtol(node->data.text.value, &end, 10); - if ((*end != '\0') || (l < 1) || (l > 32767)) { - rnd_message(RND_MSG_ERROR, "Menu merging error: ignoring prio (must be an integer between 1 and 32k)\n"); - return default_prio; - } - - return l; -} - -void rnd_hid_menu_unload(rnd_hid_t *hid, const char *cookie) -{ - rnd_menu_sys_remove_cookie(&rnd_menu_sys, cookie); - menu_merge(rnd_gui); -} - -void rnd_hid_menu_unload_patch(rnd_hid_t *hid, rnd_menu_patch_t *mp) -{ - rnd_menu_sys_remove(&rnd_menu_sys, mp); - menu_merge(rnd_gui); -} - -static rnd_menu_patch_t *rnd_hid_menu_store_doc(rnd_hid_t *hid, lht_doc_t *doc, const char *cookie, int prio, const char *desc, rnd_bool has_file) -{ - rnd_menu_patch_t *menu = calloc(sizeof(rnd_menu_patch_t), 1); /* make sure the cache is cleared */ - - menu->cfg.doc = doc; - menu->prio = determine_prio(doc->root, prio); - menu->cookie = rnd_strdup(cookie); - menu->desc = rnd_strdup(desc); - menu->has_file = has_file; - - rnd_menu_sys_insert(&rnd_menu_sys, menu); - - menu_merge(hid); - - return menu; -} - -rnd_menu_patch_t *rnd_hid_menu_load(rnd_hid_t *hid, rnd_hidlib_t *hidlib, const char *cookie, int prio, const char *fn, int exact_fn, const char *embedded_fallback, const char *desc) -{ - lht_doc_t *doc = NULL; - int has_file = 0; - - if (fn != NULL) { - if (!exact_fn) { - /* try different paths to find the menu file inventing its exact name */ - char **paths = NULL, **p; - int fn_len = strlen(fn); - - if (rnd_app.menu_file_paths != NULL) { - rnd_paths_resolve_all(hidlib, rnd_app.menu_file_paths, paths, fn_len+4, rnd_false); - for(p = paths; *p != NULL; p++) { - if (doc == NULL) { - strcpy((*p)+strlen(*p), fn); - doc = rnd_hid_cfg_load_lht(hidlib, *p); - if (doc != NULL) { - rnd_file_loaded_set_at("menu", cookie, *p, desc); - has_file = 1; - } - } - free(*p); - } - free(paths); - } - } - else { - doc = rnd_hid_cfg_load_lht(hidlib, fn); - if (doc != NULL) { - rnd_file_loaded_set_at("menu", cookie, fn, desc); - has_file = 1; - } - } - } - - if ((doc == NULL) && (embedded_fallback != NULL)) { - doc = rnd_hid_cfg_load_str(embedded_fallback); - if (doc != NULL) - rnd_file_loaded_set_at("menu", cookie, "", desc); - } - if (doc == NULL) - return NULL; - - return rnd_hid_menu_store_doc(hid, doc, cookie, prio, desc, has_file); -} - -void rnd_hid_menu_merge_inhibit_inc(void) -{ - if (rnd_menu_sys.inhibit < 32767) - rnd_menu_sys.inhibit++; - else - rnd_message(RND_MSG_ERROR, "rnd_hid_menu_merge_inhibit_inc(): overflow\n"); -} - -void rnd_hid_menu_merge_inhibit_dec(void) -{ - if (rnd_menu_sys.inhibit > 0) { - rnd_menu_sys.inhibit--; - if (rnd_menu_sys.inhibit == 0) { - menu_merge(rnd_gui); - if ((rnd_gui != NULL) && (rnd_gui->update_menu_checkbox != NULL)) - rnd_gui->update_menu_checkbox(rnd_gui, NULL); - } - } - else - rnd_message(RND_MSG_ERROR, "rnd_hid_menu_merge_inhibit_dec(): underflow\n"); -} - -/*** utility ***/ - -lht_node_t *rnd_hid_cfg_get_menu_at_node(lht_node_t *at, const char *menu_path, lht_node_t *(*cb)(void *ctx, lht_node_t *node, const char *path, int rel_level), void *ctx) -{ - lht_err_t err; - lht_node_t *curr; - int level = 0, len = strlen(menu_path), iafter = 0; - char *next_seg, *path; - - path = malloc(len+4); /* need a few bytes after the end for the ':' */ - strcpy(path, menu_path); - - next_seg = path; - curr = at; - - /* Have to descend manually because of the submenu nodes */ - for(;;) { - char *next, *end; - lht_dom_iterator_t it; - - while(*next_seg == '/') next_seg++; - - if (curr != at->doc->root) { - if (level > 1) { - curr = lht_tree_path_(at->doc, curr, "submenu", 1, 0, &err); - if (curr == NULL) - break; - } - } - next = end = strchr(next_seg, '/'); - if (end == NULL) - end = next_seg + strlen(next_seg); - - *end = '\0'; - - /* find next_seg in the current level */ - for(curr = lht_dom_first(&it, curr); curr != NULL; curr = lht_dom_next(&it)) { - if (*next_seg == '@') { - /* looking for an anon text node with the value matching the anchor name */ - if ((curr->type == LHT_TEXT) && (strcmp(curr->data.text.value, next_seg) == 0)) { - iafter = 1; - break; - } - } - else { - /* looking for a hash node */ - if (strcmp(curr->name, next_seg) == 0) - break; - } - } - - if (cb != NULL) - curr = cb(ctx, curr, path, level); - - if (next != NULL) /* restore previous / so that path is a full path */ - *next = '/'; - next_seg = next; - if ((curr == NULL) || (next_seg == NULL)) - break; - next_seg++; - level++; - if (iafter) { - /* special case: insert after an @anchor and exit */ - if (cb != NULL) - curr = cb(ctx, NULL, path, level); - break; - } - } - - free(path); - return curr; -} - -lht_node_t *rnd_hid_cfg_get_menu_at(rnd_hid_cfg_t *hr, lht_node_t *at, const char *menu_path, lht_node_t *(*cb)(void *ctx, lht_node_t *node, const char *path, int rel_level), void *ctx) -{ - if (hr == NULL) - return NULL; - - return rnd_hid_cfg_get_menu_at_node(((at == NULL) ? hr->doc->root : at), menu_path, cb, ctx); -} - -lht_node_t *rnd_hid_cfg_get_menu(rnd_hid_cfg_t *hr, const char *menu_path) -{ - return rnd_hid_cfg_get_menu_at(hr, NULL, menu_path, NULL, NULL); -} - -lht_node_t *rnd_hid_cfg_menu_field(const lht_node_t *submenu, rnd_hid_cfg_menufield_t field, const char **field_name) -{ - lht_err_t err; - const char *fieldstr = NULL; - - switch(field) { - case RND_MF_ACCELERATOR: fieldstr = "a"; break; - case RND_MF_SUBMENU: fieldstr = "submenu"; break; - case RND_MF_CHECKED: fieldstr = "checked"; break; - case RND_MF_UPDATE_ON: fieldstr = "update_on"; break; - case RND_MF_SENSITIVE: fieldstr = "sensitive"; break; - case RND_MF_TIP: fieldstr = "tip"; break; - case RND_MF_ACTION: fieldstr = "action"; break; - } - if (field_name != NULL) - *field_name = fieldstr; - - if (fieldstr == NULL) - return NULL; - - return lht_tree_path_(submenu->doc, submenu, fieldstr, 1, 0, &err); -} - -typedef struct { - rnd_hid_cfg_t *hr; - lht_node_t *parent; - rnd_menu_prop_t props; - int target_level; - int err; - lht_node_t *after; -} create_menu_ctx_t; - -static lht_node_t *menu_create_sep(lht_node_t *parent, lht_node_t *ins_after) -{ - lht_node_t *n; - - if ((parent != NULL) && (parent->type != LHT_LIST)) - return NULL; - - /* ignore ins_after if we are already deeper in the tree */ - if ((ins_after != NULL) && (ins_after->parent != parent)) - ins_after = NULL; - - n = lht_dom_node_alloc(LHT_TEXT, NULL); - n->data.text.value = rnd_strdup("-"); - if (ins_after != NULL) - lht_dom_list_insert_after(ins_after, n); - else if (parent != NULL) - lht_dom_list_append(parent, n); - - return n; -} - -static const char *colorstr(const rnd_color_t *c) -{ - if (c == NULL) return NULL; - return c->str; -} - -static lht_node_t *create_menu_cb(void *ctx, lht_node_t *node, const char *path, int rel_level) -{ - int is_sep; - create_menu_ctx_t *cmc = ctx; - lht_node_t *psub; - - if (node == NULL) { /* level does not exist, create it */ - const char *name; - name = strrchr(path, '/'); - if (name != NULL) - name++; - else - name = path; - - if (rel_level <= 1) { - /* creating a main menu */ - char *end, *name = rnd_strdup(path); - for(end = name; *end == '/'; end++) ; - end = strchr(end, '/'); - *end = '\0'; - psub = cmc->parent = rnd_hid_cfg_get_menu(cmc->hr, name); - free(name); - } - else - psub = rnd_hid_cfg_menu_field(cmc->parent, RND_MF_SUBMENU, NULL); - - is_sep = (name[0] == '-') && (name[1] == '\0'); - if (rel_level == cmc->target_level) { - if (is_sep) - node = menu_create_sep(psub, cmc->after); - else - node = rnd_hid_cfg_create_hash_node(psub, cmc->after, name, "dyn", "1", "cookie", cmc->props.cookie, "a", cmc->props.accel, "tip", cmc->props.tip, "action", cmc->props.action, "checked", cmc->props.checked, "update_on", cmc->props.update_on, "foreground", colorstr(cmc->props.foreground), "background", colorstr(cmc->props.background), NULL); - if (node != NULL) - cmc->err = 0; - } - else { - if (is_sep) - node = menu_create_sep(psub, cmc->after); - else - node = rnd_hid_cfg_create_hash_node(psub, cmc->after, name, "dyn", "1", "cookie", cmc->props.cookie, NULL); - } - - if (node == NULL) - return NULL; - - if ((rel_level != cmc->target_level) || (cmc->props.action == NULL)) - lht_dom_hash_put(node, lht_dom_node_alloc(LHT_LIST, "submenu")); - - if (node->parent == NULL) { - lht_dom_list_append(psub, node); - } - else { - assert(node->parent == psub); - } - } - else { - /* existing level */ - if ((node->type == LHT_TEXT) && (node->data.text.value[0] == '@')) { - cmc->after = node; - goto skip_parent; - } - } - cmc->parent = node; - - skip_parent:; - return node; -} - -static int create_menu_manual_prop(rnd_menu_sys_t *msys, const char *path, const rnd_menu_prop_t *props) -{ - const char *name; - rnd_menu_patch_t *mp; - create_menu_ctx_t cmc; - - if (props->cookie == NULL) - return -1; - - mp = rnd_menu_sys_find_cookie(msys, props->cookie); - if (mp == NULL) { - mp = calloc(sizeof(rnd_menu_patch_t), 1); /* make sure the cache is cleared */ - mp->cfg.doc = new_menu_file(); - mp->prio = 500; - mp->cookie = rnd_strdup(props->cookie); - rnd_menu_sys_insert(msys, mp); - } - - memset(&cmc, 0, sizeof(cmc)); - cmc.hr = &mp->cfg; - cmc.err = -1; - cmc.props = *props; - - /* Allow creating new nodes only under certain main paths that correspond to menus */ - if (strncmp(path, "rnd-menu-v1/", 12) == 0) - path += 11; /* but keep the / */ - - name = path; - while(*name == '/') name++; - - if ((strncmp(name, "main_menu/", 10) == 0) || (strncmp(name, "popups/", 7) == 0) || (strncmp(name, "anchored/", 9) == 0)) { - /* calculate target level */ - for(cmc.target_level = 0; *name != '\0'; name++) { - if (*name == '/') { - cmc.target_level++; - while(*name == '/') name++; - name--; - } - } - - /* descend and visit each level, create missing levels */ - rnd_hid_cfg_get_menu_at(cmc.hr, NULL, path, create_menu_cb, &cmc); - } - - if (cmc.err == 0) { - msys->changes++; - menu_merge(rnd_gui); - } - - return cmc.err; -} - -static int create_menu_manual(rnd_menu_sys_t *msys, const char *path, const char *action, const char *tip, const char *cookie, const char *accel) -{ - rnd_menu_prop_t props = {0}; - - props.action = action; - props.tip = tip; - props.cookie = cookie; - props.accel = accel; - return create_menu_manual_prop(msys, path, &props); -} - -int rnd_hid_menu_create(const char *path, const rnd_menu_prop_t *props) -{ - return create_menu_manual_prop(&rnd_menu_sys, path, props); -} - -static int remove_menu_manual(rnd_menu_sys_t *msys, const char *path, const char *cookie) -{ - rnd_menu_patch_t *mp = rnd_menu_sys_find_cookie(msys, cookie); - lht_node_t *nd; - - if (mp == NULL) - return -1; - - nd = rnd_hid_cfg_get_menu_at(&mp->cfg, NULL, path, NULL, NULL); - if (nd == NULL) - return -1; - lht_tree_del(nd); - msys->changes++; - menu_merge(rnd_gui); - return 0; -} - -/*** actions ***/ - -static const char rnd_acts_CreateMenu[] = "CreateMenu(path)\nCreateMenu(path, action, tooltip, cookie, [accel])"; -static const char rnd_acth_CreateMenu[] = "Creates a new menu, popup (only path specified) or submenu (at least path and action are specified)"; -static fgw_error_t rnd_act_CreateMenu(fgw_arg_t *res, int argc, fgw_arg_t *argv) -{ - if (rnd_gui == NULL) { - rnd_message(RND_MSG_ERROR, "Error: can't create menu, there's no GUI hid loaded\n"); - RND_ACT_IRES(-1); - return 0; - } - - RND_ACT_CONVARG(1, FGW_STR, CreateMenu, ;); - RND_ACT_MAY_CONVARG(2, FGW_STR, CreateMenu, ;); - RND_ACT_MAY_CONVARG(3, FGW_STR, CreateMenu, ;); - RND_ACT_MAY_CONVARG(4, FGW_STR, CreateMenu, ;); - RND_ACT_MAY_CONVARG(5, FGW_STR, CreateMenu, ;); - - if (argc > 1) { - int r = create_menu_manual(&rnd_menu_sys, argv[1].val.str, (argc > 2) ? argv[2].val.str : NULL, (argc > 3) ? argv[3].val.str : NULL, (argc > 4) ? argv[4].val.str : NULL, (argc > 5) ? argv[5].val.str : NULL); - if (r != 0) - rnd_message(RND_MSG_ERROR, "Error: failed to create the menu\n"); - RND_ACT_IRES(r); - return 0; - } - - RND_ACT_FAIL(CreateMenu); -} - -static const char rnd_acts_RemoveMenu[] = "RemoveMenu(path, cookie)"; -static const char rnd_acth_RemoveMenu[] = "Recursively removes a new menu, popup (only path specified) or submenu. "; -static fgw_error_t rnd_act_RemoveMenu(fgw_arg_t *res, int argc, fgw_arg_t *argv) -{ - if (rnd_gui == NULL) { - rnd_message(RND_MSG_ERROR, "can't remove menu, there's no GUI hid loaded\n"); - RND_ACT_IRES(-1); - return 0; - } - - if (rnd_gui->remove_menu_node == NULL) { - rnd_message(RND_MSG_ERROR, "can't remove menu, the GUI doesn't support it\n"); - RND_ACT_IRES(-1); - return 0; - } - - RND_ACT_CONVARG(1, FGW_STR, RemoveMenu, ;); - RND_ACT_CONVARG(2, FGW_STR, RemoveMenu, ;); - if (remove_menu_manual(&rnd_menu_sys, argv[1].val.str, argv[2].val.str) != 0) { - rnd_message(RND_MSG_ERROR, "failed to remove some of the menu items\n"); - RND_ACT_IRES(-1); - } - else - RND_ACT_IRES(0); - return 0; -} - -static const char rnd_acts_MenuPatch[] = - "MenuPatch(load, cookie, path, desc)\n" - "MenuPatch(unload, cookie)\n" - "MenuPatch(list)\n" - "MenuPatch(InhibitInc|InhibitDec)"; -static const char rnd_acth_MenuPatch[] = "Manage menu patches"; -fgw_error_t rnd_act_MenuPatch(fgw_arg_t *res, int argc, fgw_arg_t *argv) -{ - int op; - const char *cookie = NULL, *path = NULL, *desc = ""; - - RND_ACT_CONVARG(1, FGW_KEYWORD, MenuPatch, op = fgw_keyword(&argv[1])); - RND_ACT_MAY_CONVARG(2, FGW_STR, MenuPatch, cookie = argv[2].val.str); - RND_ACT_MAY_CONVARG(3, FGW_STR, MenuPatch, path = argv[3].val.str); - RND_ACT_MAY_CONVARG(4, FGW_STR, MenuPatch, desc = argv[4].val.str); - - switch(op) { - case F_Load: - if ((cookie == NULL) || (path == NULL)) - RND_ACT_FAIL(MenuPatch); - if (rnd_hid_menu_load(rnd_gui, NULL, cookie, 500, path, 1, NULL, desc) == NULL) - rnd_message(RND_MSG_ERROR, "Failed to load menu patch %s\n", path); - RND_ACT_IRES(0); - return 0; - case F_Unload: - if (cookie == NULL) - RND_ACT_FAIL(MenuPatch); - rnd_menu_sys_remove_cookie(&rnd_menu_sys, cookie); - menu_merge(rnd_gui); - RND_ACT_IRES(0); - return 0; - case F_List: - { - int n; - rnd_message(RND_MSG_INFO, "Menu system:\n"); - for(n = 0; n < rnd_menu_sys.patches.used; n++) { - rnd_menu_patch_t *m = rnd_menu_sys.patches.array[n]; - rnd_message(RND_MSG_INFO, " [%ld] %s prio=%d %s: %s\n", m->uid, (n == 0 ? "base " : "addon"), m->prio, m->cookie, m->cfg.doc->root->file_name); - } - } - RND_ACT_IRES(0); - return 0; - case F_InhibitInc: rnd_hid_menu_merge_inhibit_inc(); break; - case F_InhibitDec: rnd_hid_menu_merge_inhibit_dec(); break; - default: - RND_ACT_FAIL(MenuPatch); - } - - RND_ACT_IRES(0); - return 0; -} - - -static int create_menu_by_node_debug(rnd_hid_t *hid, int is_popup, const char *name, int is_main, lht_node_t *parent, lht_node_t *ins_after, lht_node_t *menu_item) -{ - printf("menu debug: create: %s\n", name); - return 0; -} - - -static int remove_menu_node_debug(rnd_hid_t *hid, lht_node_t *nd) -{ - printf("menu debug: remove\n"); - return 0; -} - -static const char rnd_acts_MenuDebug[] = - "MenuDebug(save, path)\n"; -static const char rnd_acth_MenuDebug[] = "Menu debug helpers: save the merged menu in a file"; -fgw_error_t rnd_act_MenuDebug(fgw_arg_t *res, int argc, fgw_arg_t *argv) -{ - const char *op, *path; - FILE *f; - - - RND_ACT_CONVARG(1, FGW_STR, MenuDebug, op = argv[1].val.str); - - RND_ACT_IRES(1); - - if (rnd_strcasecmp(op, "save") == 0) { - RND_ACT_CONVARG(2, FGW_STR, MenuDebug, path = argv[2].val.str); - f = rnd_fopen(RND_ACT_HIDLIB, path, "w"); - if (f != NULL) { - lht_dom_export(rnd_gui->menu->doc->root, f, ""); - fclose(f); - RND_ACT_IRES(0); - } - else - rnd_message(RND_MSG_ERROR, "Failed to open '%s' for write\n", path); - } - else if (rnd_strcasecmp(op, "force-enable") == 0) { - if (rnd_gui->create_menu_by_node == NULL) - rnd_gui->create_menu_by_node = create_menu_by_node_debug; - if (rnd_gui->remove_menu_node == NULL) - rnd_gui->remove_menu_node = remove_menu_node_debug; - rnd_menu_sys.gui_ready = 1; - menu_merge(rnd_gui); - } - else - RND_ACT_FAIL(MenuDebug); - - - return 0; -} - -static rnd_action_t rnd_menu_action_list[] = { - {"CreateMenu", rnd_act_CreateMenu, rnd_acth_CreateMenu, rnd_acts_CreateMenu}, - {"RemoveMenu", rnd_act_RemoveMenu, rnd_acth_RemoveMenu, rnd_acts_RemoveMenu}, - {"MenuPatch", rnd_act_MenuPatch, rnd_acth_MenuPatch, rnd_acts_MenuPatch}, - {"MenuDebug", rnd_act_MenuDebug, rnd_acth_MenuDebug, rnd_acts_MenuDebug} -}; - -static void menu_conf_chg(rnd_conf_native_t *cfg, int arr_idx) -{ - int n; - rnd_conf_listitem_t *i; - const char *mfn; - - rnd_hid_menu_merge_inhibit_inc(); - - /* figure which menu files have conf patch associated (which are already loaded) */ - for(n = 0; n < rnd_menu_sys.patches.used; n++) { - rnd_menu_patch_t *m = rnd_menu_sys.patches.array[n]; - if (!m->has_file) continue; - mfn = m->cfg.doc->root->file_name; - m->cfg_found = 0; - if (mfn == NULL) - continue; - for(i = rnd_conflist_first((rnd_conflist_t *)&rnd_conf.rc.menu_patches); i != NULL; i = rnd_conflist_next(i)) { - const char **cfn = i->val.string; - if (strcmp(*cfn, mfn) == 0) { - m->cfg_found = 1; - break; - } - } - } - - /* remove anything we loaded for the config and we don't need anymore */ - for(n = 0; n < rnd_menu_sys.patches.used; n++) { - rnd_menu_patch_t *m = rnd_menu_sys.patches.array[n]; - if (!m->has_file) continue; - if (m->loaded_for_conf && !m->cfg_found) { - mfn = m->cfg.doc->root->file_name; -/* rnd_trace("cfg unload %s\n", mfn); */ - rnd_hid_menu_unload_patch(rnd_gui, m); - } - } - - /* load all files that are in the config but not in the menu system */ - for(i = rnd_conflist_first((rnd_conflist_t *)&rnd_conf.rc.menu_patches); i != NULL; i = rnd_conflist_next(i)) { - const char **cfn = i->val.string; - int found = 0; - - for(n = 0; n < rnd_menu_sys.patches.used; n++) { - rnd_menu_patch_t *m = rnd_menu_sys.patches.array[n]; - if (!m->has_file) continue; - mfn = m->cfg.doc->root->file_name; - if ((mfn != NULL) && (strcmp(*cfn, mfn) == 0)) { - found = 1; - break; - } - } - - if (!found) { -/* rnd_trace("cfg load %s\n", *cfn);*/ - rnd_menu_patch_t *m = rnd_hid_menu_load(rnd_gui, NULL, "cfg", 250, *cfn, 1, NULL, "Loaded from config node rc/menu_patches"); - if (m != NULL) - m->loaded_for_conf = 1; - } - } - - rnd_hid_menu_merge_inhibit_dec(); -} - -static int menu_anyload_subtree(const rnd_anyload_t *al, rnd_hidlib_t *hl, lht_node_t *root) -{ - lht_doc_t *doc; - rnd_menu_patch_t *menu; - - if (rnd_gui == NULL) - return 0; - - /* copy the root to a new doc, keep file name for at least the root node */ - doc = lht_dom_init(); - doc->root = lht_dom_duptree(root); - lht_dom_loc_newfile(doc, root->file_name); - doc->root->file_name = doc->active_file; - - menu = rnd_hid_menu_store_doc(rnd_gui, doc, menu_cookie_al, 500, "anyload", 1); - - if (menu == NULL) { - rnd_message(RND_MSG_ERROR, "menu anyload: failed to load menu patch from %s\n", doc->root->file_name); - lht_dom_uninit(doc); - return -1; - } - return 0; -} - -static rnd_anyload_t menu_anyload = {0}; - -void rnd_menu_init1(void) -{ - rnd_conf_native_t *n = rnd_conf_get_field("rc/menu_patches"); - menu_conf_id = rnd_conf_hid_reg(menu_cookie, NULL); - - rnd_menu_sys_init(&rnd_menu_sys); - - if (n != NULL) { - static rnd_conf_hid_callbacks_t cbs; - memset(&cbs, 0, sizeof(rnd_conf_hid_callbacks_t)); - cbs.val_change_post = menu_conf_chg; - rnd_conf_hid_set_cb(n, menu_conf_id, &cbs); - } - - menu_anyload.load_subtree = menu_anyload_subtree; - menu_anyload.cookie = menu_cookie_al; - rnd_anyload_reg("^rnd-menu-v[0-9]*$", &menu_anyload); -} - -void rnd_menu_act_init2(void) -{ - RND_REGISTER_ACTIONS(rnd_menu_action_list, NULL); -} - -void rnd_menu_uninit(void) -{ - rnd_anyload_unreg_by_cookie(menu_cookie_al); - rnd_conf_hid_unreg(menu_cookie); -} Index: trunk/src/librnd/core/hid_dad.c =================================================================== --- trunk/src/librnd/core/hid_dad.c (revision 34601) +++ trunk/src/librnd/core/hid_dad.c (nonexistent) @@ -1,157 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * Copyright (C) 2019 Tibor 'Igor2' Palinkas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact: - * Project page: http://repo.hu/projects/pcb-rnd - * lead developer: http://repo.hu/projects/pcb-rnd/contact.html - * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") - */ - -/* widget-type-independent DAD functions */ - -#include -#include - -int rnd_dock_is_vert[RND_HID_DOCK_max] = {0, 0, 0, 1, 0, 1}; /* Update this if rnd_hid_dock_t changes */ -int rnd_dock_has_frame[RND_HID_DOCK_max] = {0, 0, 0, 1, 0, 0}; /* Update this if rnd_hid_dock_t changes */ - -typedef struct { - rnd_hatt_compflags_t flag; - const char *name; -} comflag_name_t; - -static comflag_name_t compflag_names[] = { - {RND_HATF_FRAME, "frame"}, - {RND_HATF_SCROLL, "scroll"}, - {RND_HATF_HIDE_TABLAB, "hide_tablab"}, - {RND_HATF_LEFT_TAB, "left_tab"}, - {RND_HATF_TREE_COL, "tree_col"}, - {RND_HATF_EXPFILL, "expfill"}, - {RND_HATF_TIGHT, "tight"}, - {0, NULL} -}; - -const char *rnd_hid_compflag_bit2name(rnd_hatt_compflags_t bit) -{ - comflag_name_t *n; - for(n = compflag_names; n->flag != 0; n++) - if (n->flag == bit) - return n->name; - return NULL; -} - -rnd_hatt_compflags_t rnd_hid_compflag_name2bit(const char *name) -{ - comflag_name_t *n; - for(n = compflag_names; n->flag != 0; n++) - if (strcmp(n->name, name) == 0) - return n->flag; - return 0; -} - -void rnd_hid_dad_close(void *hid_ctx, rnd_dad_retovr_t *retovr, int retval) -{ - retovr->valid = 1; - retovr->value = retval; - rnd_gui->attr_dlg_close(hid_ctx); -} - -void rnd_hid_dad_close_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) -{ - rnd_dad_retovr_t **retovr = attr->wdata; - rnd_hid_dad_close(hid_ctx, *retovr, attr->val.lng); -} - -int rnd_hid_dad_run(void *hid_ctx, rnd_dad_retovr_t *retovr) -{ - int ret; - - retovr->valid = 0; - retovr->dont_free++; - ret = rnd_gui->attr_dlg_run(hid_ctx); - if (retovr->valid) - ret = retovr->value; - retovr->dont_free--; - return ret; -} - -int rnd_hid_attrdlg_num_children(rnd_hid_attribute_t *attrs, int start_from, int n_attrs) -{ - int n, level = 1, cnt = 0; - - for(n = start_from; n < n_attrs; n++) { - if ((level == 1) && (attrs[n].type != RND_HATT_END)) - cnt++; - switch(attrs[n].type) { - case RND_HATT_END: - level--; - if (level == 0) - return cnt; - break; - case RND_HATT_BEGIN_TABLE: - case RND_HATT_BEGIN_HBOX: - case RND_HATT_BEGIN_VBOX: - case RND_HATT_BEGIN_COMPOUND: - level++; - break; - default: - break; - } - } - return cnt; -} - -int rnd_attribute_dialog_(const char *id, rnd_hid_attribute_t *attrs, int n_attrs, const char *title, void *caller_data, void **retovr, int defx, int defy, int minx, int miny, void **hid_ctx_out) -{ - int rv; - void *hid_ctx; - - if ((rnd_gui == NULL) || (rnd_gui->attr_dlg_new == NULL)) - return -1; - - hid_ctx = rnd_gui->attr_dlg_new(rnd_gui, id, attrs, n_attrs, title, caller_data, rnd_true, NULL, defx, defy, minx, miny); - if (hid_ctx_out != NULL) - *hid_ctx_out = hid_ctx; - rv = rnd_gui->attr_dlg_run(hid_ctx); - if ((retovr == NULL) || (*retovr != 0)) - rnd_gui->attr_dlg_close(hid_ctx); - - return rv ? 0 : 1; -} - -int rnd_attribute_dialog(const char *id, rnd_hid_attribute_t *attrs, int n_attrs, const char *title, void *caller_data) -{ - return rnd_attribute_dialog_(id, attrs, n_attrs, title, caller_data, NULL, 0, 0, 0, 0, NULL); -} - -int rnd_hid_dock_enter(rnd_hid_dad_subdialog_t *sub, rnd_hid_dock_t where, const char *id) -{ - if ((rnd_gui == NULL) || (rnd_gui->dock_enter == NULL)) - return -1; - return rnd_gui->dock_enter(rnd_gui, sub, where, id); -} - -void rnd_hid_dock_leave(rnd_hid_dad_subdialog_t *sub) -{ - if ((rnd_gui == NULL) || (rnd_gui->dock_leave == NULL)) - return; - rnd_gui->dock_leave(rnd_gui, sub); -} - Index: trunk/src/librnd/core/hid_menu.h =================================================================== --- trunk/src/librnd/core/hid_menu.h (revision 34601) +++ trunk/src/librnd/core/hid_menu.h (nonexistent) @@ -1,86 +0,0 @@ -#ifndef RND_HID_MENU_H -#define RND_HID_MENU_H - -#include -#include - -typedef struct { - char *cookie, *desc; - rnd_hid_cfg_t cfg; - int prio; - long uid; - unsigned has_file:1; /* loaded from a file, can be reloaded any time */ - unsigned loaded_for_conf:1; /* loaded for rc.menu_patches */ - - /* internal/cache */ - unsigned cfg_found:1; -} rnd_menu_patch_t; - -typedef struct { - vtp0_t patches; /* list of (rnd_menu_patch_t *), ordered by priority, ascending */ - rnd_hid_cfg_t *merged; - long changes, last_merged; /* if changes > last_merged, we need to merge */ - int inhibit; - unsigned gui_ready:1; /* ready for the first merge */ - unsigned gui_nomod:1; /* do the merge but do not send any modification request - useful for the initial menu setup */ - unsigned alloced:1; /* whether ->merged is alloced (it is not, for the special case of patches->used <= 1 at the time of merging) */ -} rnd_menu_sys_t; - - -/* Search and load the menu file called from fn, using the menu search - path (from the conf system) if not given by an absolute path; if NULL or - not found, parse embedded_fallback instead (if it is not NULL). - Prio is ignored when loading a menu patch file with priority specified in the file. - Returns NULL on error. */ -rnd_menu_patch_t *rnd_hid_menu_load(rnd_hid_t *hid, rnd_hidlib_t *hidlib, const char *cookie, int prio, const char *fn, int exact_fn, const char *embedded_fallback, const char *desc); - -/* Unload a menu patch by cookie */ -void rnd_hid_menu_unload(rnd_hid_t *hid, const char *cookie); -void rnd_hid_menu_unload_patch(rnd_hid_t *hid, rnd_menu_patch_t *mp); - -/* inhibit menu merging: optimization for batch loading/unloading so only - one merge happens at the end */ -void rnd_hid_menu_merge_inhibit_inc(void); -void rnd_hid_menu_merge_inhibit_dec(void); - - -/* The GUI announces that it is ready for creating the menu; the initial - merge should happen, but no modification callbacks are done */ -void rnd_hid_menu_gui_ready_to_create(rnd_hid_t *hid); - -/* The GUI announces that it is ready for executing menu modification callbacks */ -void rnd_hid_menu_gui_ready_to_modify(rnd_hid_t *hid); - - -lht_node_t *rnd_hid_cfg_get_menu(rnd_hid_cfg_t *hr, const char *menu_path); -lht_node_t *rnd_hid_cfg_get_menu_at(rnd_hid_cfg_t *hr, lht_node_t *at, const char *menu_path, lht_node_t *(*cb)(void *ctx, lht_node_t *node, const char *path, int rel_level), void *ctx); -lht_node_t *rnd_hid_cfg_get_menu_at_node(lht_node_t *at, const char *menu_path, lht_node_t *(*cb)(void *ctx, lht_node_t *node, const char *path, int rel_level), void *ctx); - -/* plugins can manually create dynamic menus using this call; props->cookie - must be set, the menu patch is identified by that cookie */ -int rnd_hid_menu_create(const char *path, const rnd_menu_prop_t *props); - -/* Fields are retrieved using this enum so that HIDs don't need to hardwire - lihata node names */ -typedef enum { - RND_MF_ACCELERATOR, - RND_MF_SUBMENU, - RND_MF_CHECKED, - RND_MF_UPDATE_ON, - RND_MF_SENSITIVE, - RND_MF_TIP, - RND_MF_ACTION -} rnd_hid_cfg_menufield_t; - -/* Return a field of a submenu and optionally fill in field_name with the - field name expected in the lihata document (useful for error messages) */ -lht_node_t *rnd_hid_cfg_menu_field(const lht_node_t *submenu, rnd_hid_cfg_menufield_t field, const char **field_name); - -/* special value for indicating that the new menu node should be inserted on - top, as the first item (when passed in the ins_after argument */ -extern lht_node_t *rnd_hid_menu_ins_as_first; - -/* expose the menu system for the preferences dialog */ -extern rnd_menu_sys_t rnd_menu_sys; - -#endif Index: trunk/src/librnd/core/hid_dad.h =================================================================== --- trunk/src/librnd/core/hid_dad.h (revision 34601) +++ trunk/src/librnd/core/hid_dad.h (nonexistent) @@ -1,880 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * Copyright (C) 2017..2020 Tibor 'Igor2' Palinkas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact: - * Project page: http://repo.hu/projects/pcb-rnd - * lead developer: http://repo.hu/projects/pcb-rnd/contact.html - * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") - */ - -#ifndef RND_HID_DAD_H -#define RND_HID_DAD_H - -#include -#include -#include -#include -#include -#include -#include - -#include - -typedef enum { - RND_HID_TEXT_INSERT, /* insert at cursor or replace selection */ - RND_HID_TEXT_REPLACE, /* replace the entire text */ - RND_HID_TEXT_APPEND, /* append to the end of the text */ - - /* modifiers (bitfield) */ - RND_HID_TEXT_MARKUP = 0x0010 /* interpret minimal html-like markup - some HIDs may ignore these */ -} rnd_hid_text_set_t; - -typedef struct { - /* cursor manipulation callbacks */ - void (*hid_get_xy)(rnd_hid_attribute_t *attrib, void *hid_ctx, long *x, long *y); /* can be very slow */ - long (*hid_get_offs)(rnd_hid_attribute_t *attrib, void *hid_ctx); - void (*hid_set_xy)(rnd_hid_attribute_t *attrib, void *hid_ctx, long x, long y); /* can be very slow */ - void (*hid_set_offs)(rnd_hid_attribute_t *attrib, void *hid_ctx, long offs); - void (*hid_scroll_to_bottom)(rnd_hid_attribute_t *attrib, void *hid_ctx); - void (*hid_set_text)(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_text_set_t how, const char *txt); - char *(*hid_get_text)(rnd_hid_attribute_t *attrib, void *hid_ctx); /* caller needs to free the result */ - void (*hid_set_readonly)(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_bool readonly); /* by default text views are not read-only */ - - /* optional callbacks the user set after widget creation */ - void *user_ctx; - void (*user_free_cb)(rnd_hid_attribute_t *attrib, void *user_ctx, void *hid_ctx); - - /* optional callbacks HIDs may set after widget creation */ - void *hid_wdata; - void (*hid_free_cb)(rnd_hid_attribute_t *attrib, void *hid_wdata); -} rnd_hid_text_t; - - -typedef struct { - int cols; /* number of columns used by this node (allocation size) */ - void *hid_data; /* the hid running the widget can use this field to store a custom pointer per row */ - gdl_list_t children; - gdl_elem_t link; - char *path; /* full path of the node; allocated/free'd by DAD (/ is the root, every entry is specified from the root, but the leading / is omitted; in non-tree case, this only points to the first col data) */ - unsigned hide:1; /* if non-zero, the row is not visible (e.g. filtered out) */ - - /* caller/user data */ - void *user_data; - union { - void *ptr; - long lng; - double dbl; - } user_data2; - char *cell[1]; /* each cell is a char *; the true length of the array is the value of the len field; the array is allocated together with the struct */ -} rnd_hid_row_t; - -typedef struct { - gdl_list_t rows; /* ordered list of first level rows (tree root) */ - htsp_t paths; /* translate first column paths iinto (rnd_hid_row_t *) */ - rnd_hid_attribute_t *attrib; - const char **hdr; /* optional column headers (NULL means disable header) */ - - /* optional callbacks the user set after widget creation */ - void *user_ctx; - void (*user_free_cb)(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row); - void (*user_selected_cb)(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row); - int (*user_browse_activate_cb)(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row); /* returns non-zero if the row should auto-activate while browsing (e.g. stepping with arrow keys) */ - const char *(*user_copy_to_clip_cb)(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row); /* returns the string to copy to clipboard for the given row (if unset, first column text is used) */ - - /* optional callbacks HIDs may set after widget creation */ - void *hid_wdata; - void (*hid_insert_cb)(rnd_hid_attribute_t *attrib, void *hid_wdata, rnd_hid_row_t *new_row); - void (*hid_modify_cb)(rnd_hid_attribute_t *attrib, void *hid_wdata, rnd_hid_row_t *row, int col); /* if col is negative, all columns have changed */ - void (*hid_remove_cb)(rnd_hid_attribute_t *attrib, void *hid_wdata, rnd_hid_row_t *row); - void (*hid_free_cb)(rnd_hid_attribute_t *attrib, void *hid_wdata, rnd_hid_row_t *row); - rnd_hid_row_t *(*hid_get_selected_cb)(rnd_hid_attribute_t *attrib, void *hid_wdata); - void (*hid_jumpto_cb)(rnd_hid_attribute_t *attrib, void *hid_wdata, rnd_hid_row_t *row); /* row = NULL means deselect all */ - void (*hid_expcoll_cb)(rnd_hid_attribute_t *attrib, void *hid_wdata, rnd_hid_row_t *row, int expanded); /* sets whether a row is expanded or collapsed */ - void (*hid_update_hide_cb)(rnd_hid_attribute_t *attrib, void *hid_wdata); -} rnd_hid_tree_t; - -typedef struct rnd_hid_preview_s rnd_hid_preview_t; -struct rnd_hid_preview_s { - rnd_hid_attribute_t *attrib; - - rnd_box_t initial_view; - unsigned initial_view_valid:1; - - int min_sizex_px, min_sizey_px; /* hint: widget minimum size in pixels */ - - /* optional callbacks the user set after widget creation */ - void *user_ctx; - void (*user_free_cb)(rnd_hid_attribute_t *attrib, void *user_ctx, void *hid_ctx); - void (*user_expose_cb)(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e); - rnd_bool (*user_mouse_cb)(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_mouse_ev_t kind, rnd_coord_t x, rnd_coord_t y); /* returns true if redraw is needed */ - rnd_bool (*user_key_cb)(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_bool release, rnd_hid_cfg_mod_t mods, unsigned short int key_raw, unsigned short int key_tr); /* returns true if redraw is needed */ - - /* optional callbacks HIDs may set after widget creation */ - void *hid_wdata; - void (*hid_zoomto_cb)(rnd_hid_attribute_t *attrib, void *hid_wdata, const rnd_box_t *view); /* redraw only if view == NULL */ - void (*hid_free_cb)(rnd_hid_attribute_t *attrib, void *hid_wdata); -}; - -typedef struct { - int wbegin, wend; /* widget index to the correspoding RND_HATT_BEGIN_COMPOUND and RND_HATT_END */ - - /* compound implementation callbacks */ - int (*widget_state)(rnd_hid_attribute_t *end, void *hid_ctx, int idx, rnd_bool enabled); - int (*widget_hide)(rnd_hid_attribute_t *end, void *hid_ctx, int idx, rnd_bool hide); - int (*set_value)(rnd_hid_attribute_t *end, void *hid_ctx, int idx, const rnd_hid_attr_val_t *val); /* set value runtime */ - void (*set_val_num)(rnd_hid_attribute_t *attr, long l, double d, rnd_coord_t c); /* set value during creation; attr is the END */ - void (*set_val_ptr)(rnd_hid_attribute_t *attr, void *ptr); /* set value during creation; attr is the END */ - void (*set_help)(rnd_hid_attribute_t *attr, const char *text); /* set the tooltip help; attr is the END */ - void (*set_field_num)(rnd_hid_attribute_t *attr, const char *fieldname, long l, double d, rnd_coord_t c); /* set value during creation; attr is the END */ - void (*set_field_ptr)(rnd_hid_attribute_t *attr, const char *fieldname, void *ptr); /* set value during creation; attr is the END */ - void (*set_geo)(rnd_hid_attribute_t *attr, rnd_hatt_compflags_t flg, int geo); /* set geometry during creation; attr is the END */ - void (*free)(rnd_hid_attribute_t *attrib); /* called by DAD on free'ing the RND_HATT_BEGIN_COMPOUND and RND_HATT_END_COMPOUND widget */ -} rnd_hid_compound_t; - -#include - -/*** Helpers for building dynamic attribute dialogs (DAD) ***/ -#define RND_DAD_DECL(table) \ - rnd_hid_attribute_t *table = NULL; \ - int table ## _append_lock = 0; \ - int table ## _len = 0; \ - int table ## _alloced = 0; \ - void *table ## _hid_ctx = NULL; \ - int table ## _defx = 0, table ## _defy = 0; \ - int table ## _minx = 0, table ## _miny = 0; \ - rnd_dad_retovr_t *table ## _ret_override; - -#define RND_DAD_DECL_NOINIT(table) \ - rnd_hid_attribute_t *table; \ - int table ## _append_lock; \ - int table ## _len; \ - int table ## _alloced; \ - void *table ## _hid_ctx; \ - int table ## _defx, table ## _defy; \ - int table ## _minx, table ## _miny; \ - rnd_dad_retovr_t *table ## _ret_override; - -/* Free all resources allocated by DAD macros for table */ -#define RND_DAD_FREE(table) \ -do { \ - int __n__; \ - if ((table ## _hid_ctx != NULL) && (table ## _ret_override != NULL)) \ - rnd_gui->attr_dlg_free(table ## _hid_ctx); \ - for(__n__ = 0; __n__ < table ## _len; __n__++) { \ - RND_DAD_FREE_FIELD(table, __n__); \ - } \ - free(table); \ - table = NULL; \ - table ## _hid_ctx = NULL; \ - table ## _len = 0; \ - table ## _alloced = 0; \ - table ## _append_lock = 0; \ - if ((table ## _ret_override != NULL) && (table ## _ret_override->dont_free == 0)) {\ - free(table ## _ret_override); \ - table ## _ret_override = NULL; \ - } \ -} while(0) - -#define RND_DAD_NEW(id, table, title, caller_data, modal, ev_cb) \ -do { \ - table ## _ret_override = calloc(sizeof(rnd_dad_retovr_t), 1); \ - table ## _append_lock = 1; \ - table ## _hid_ctx = rnd_gui->attr_dlg_new(rnd_gui, id, table, table ## _len, title, caller_data, modal, ev_cb, table ## _defx, table ## _defy, table ## _minx, table ## _miny); \ -} while(0) - -/* Sets the default window size (that is only a hint) - NOTE: must be called - before RND_DAD_NEW() */ -#define RND_DAD_DEFSIZE(table, width, height) \ -do { \ - table ## _defx = width; \ - table ## _defy = height; \ -} while(0) - -/* Sets the minimum window size (that is only a hint) - NOTE: must be called - before RND_DAD_NEW() */ -#define RND_DAD_MINSIZE(table, width, height) \ -do { \ - table ## _minx = width; \ - table ## _miny = height; \ -} while(0) - -#define RND_DAD_RUN(table) rnd_hid_dad_run(table ## _hid_ctx, table ## _ret_override) - -/* failed is zero on success and -1 on error (e.g. cancel) or an arbitrary - value set by ret_override (e.g. on close buttons) */ -#define RND_DAD_AUTORUN(id, table, title, caller_data, failed) \ -do { \ - int __ok__; \ - table ## _ret_override = calloc(sizeof(rnd_dad_retovr_t), 1); \ - table ## _ret_override->dont_free++; \ - table ## _ret_override->valid = 0; \ - table ## _append_lock = 1; \ - __ok__ = rnd_attribute_dialog_(id,table, table ## _len, title, caller_data, (void **)&(table ## _ret_override), table ## _defx, table ## _defy, table ## _minx, table ## _miny, &table ## _hid_ctx); \ - failed = (__ok__ == 0) ? -1 : 0; \ - if (table ## _ret_override->valid) \ - failed = table ## _ret_override->value; \ - table ## _ret_override->dont_free--; \ -} while(0) - -/* Return the index of the item currenty being edited */ -#define RND_DAD_CURRENT(table) (table ## _len - 1) - -/* Begin a new box or table */ -#define RND_DAD_BEGIN(table, item_type) \ - RND_DAD_ALLOC(table, item_type); - -#define RND_DAD_BEGIN_TABLE(table, cols) \ -do { \ - RND_DAD_BEGIN(table, RND_HATT_BEGIN_TABLE); \ - RND_DAD_SET_ATTR_FIELD(table, rnd_hatt_table_cols, cols); \ -} while(0) - -#define RND_DAD_BEGIN_TABBED(table, tabs) \ -do { \ - RND_DAD_BEGIN(table, RND_HATT_BEGIN_TABBED); \ - RND_DAD_SET_ATTR_FIELD(table, wdata, tabs); \ -} while(0) - -#define RND_DAD_BEGIN_HBOX(table) RND_DAD_BEGIN(table, RND_HATT_BEGIN_HBOX) -#define RND_DAD_BEGIN_VBOX(table) RND_DAD_BEGIN(table, RND_HATT_BEGIN_VBOX) -#define RND_DAD_END(table) RND_DAD_BEGIN(table, RND_HATT_END) -#define RND_DAD_COMPFLAG(table, val) RND_DAD_SET_ATTR_FIELD(table, rnd_hatt_flags, val | (table[table ## _len-1].rnd_hatt_flags & RND_HATF_TREE_COL)) - -#define RND_DAD_LABEL(table, text) \ -do { \ - RND_DAD_ALLOC(table, RND_HATT_LABEL); \ - RND_DAD_SET_ATTR_FIELD(table, name, rnd_strdup(text)); \ -} while(0) - -/* Add label usign printf formatting syntax: RND_DAD_LABELF(tbl, ("a=%d", 12)); */ -#define RND_DAD_LABELF(table, printf_args) \ -do { \ - RND_DAD_ALLOC(table, RND_HATT_LABEL); \ - RND_DAD_SET_ATTR_FIELD(table, name, rnd_strdup_printf printf_args); \ -} while(0) - -#define RND_DAD_STRING_SELECT_REGION(table, idx, first_char_offs, len) \ -do { \ - if (rnd_gui->attr_dlg_widget_poke != NULL) { \ - fgw_arg_t __args__[3]; \ - __args__[0].type = FGW_STR; __args__[0].val.cstr = "select"; \ - __args__[1].type = FGW_INT; __args__[1].val.nat_int = first_char_offs; \ - __args__[2].type = FGW_INT; __args__[2].val.nat_int = len; \ - rnd_gui->attr_dlg_widget_poke(table, idx, 3, __args__); \ - } \ -} while(0) - -#define RND_DAD_ENUM(table, choices) \ -do { \ - RND_DAD_ALLOC(table, RND_HATT_ENUM); \ - RND_DAD_SET_ATTR_FIELD(table, wdata, choices); \ -} while(0) - -#define RND_DAD_BOOL(table) RND_DAD_ALLOC(table, RND_HATT_BOOL); -#define RND_DAD_STRING(table) RND_DAD_ALLOC(table, RND_HATT_STRING); -#define RND_DAD_INTEGER(table) RND_DAD_SPIN_INT(table); -#define RND_DAD_REAL(table) RND_DAD_SPIN_DOUBLE(table); -#define RND_DAD_COORD(table) RND_DAD_SPIN_COORD(table); - -#define RND_DAD_TEXT(table, user_ctx_) \ -do { \ - rnd_hid_text_t *txt = calloc(sizeof(rnd_hid_text_t), 1); \ - txt->user_ctx = user_ctx_; \ - RND_DAD_ALLOC(table, RND_HATT_TEXT); \ - RND_DAD_SET_ATTR_FIELD(table, wdata, txt); \ -} while(0) - -#define RND_DAD_BUTTON(table, text) \ -do { \ - RND_DAD_ALLOC(table, RND_HATT_BUTTON); \ - table[table ## _len - 1].val.str = text; \ -} while(0) - -#define RND_DAD_BUTTON_CLOSE(table, text, retval) \ -do { \ - RND_DAD_ALLOC(table, RND_HATT_BUTTON); \ - table[table ## _len - 1].val.str = text; \ - table[table ## _len - 1].val.lng = retval; \ - table[table ## _len - 1].wdata = (&table ## _ret_override); \ - RND_DAD_CHANGE_CB(table, rnd_hid_dad_close_cb); \ -} while(0) - -/* Draw a set of close buttons without trying to fill a while hbox row */ -#define RND_DAD_BUTTON_CLOSES_NAKED(table, buttons) \ -do { \ - rnd_hid_dad_buttons_t *__n__; \ - RND_DAD_BEGIN_HBOX(table); \ - RND_DAD_COMPFLAG(table, RND_HATF_EXPFILL); \ - RND_DAD_END(table); \ - for(__n__ = buttons; __n__->label != NULL; __n__++) { \ - RND_DAD_BUTTON_CLOSE(table, __n__->label, __n__->retval); \ - } \ -} while(0) - -/* Draw a set of close buttons, adding a new hbox that tries to fill a whole row */ -#define RND_DAD_BUTTON_CLOSES(table, buttons) \ -do { \ - RND_DAD_BEGIN_HBOX(table); \ - RND_DAD_BUTTON_CLOSES_NAKED(table, buttons); \ - RND_DAD_END(table); \ -} while(0) - - -#define RND_DAD_PROGRESS(table) \ -do { \ - RND_DAD_ALLOC(table, RND_HATT_PROGRESS); \ -} while(0) - -#define RND_DAD_PREVIEW(table, expose_cb, mouse_cb, key_cb, free_cb, initial_view_box, min_sizex_px_, min_sizey_px_, user_ctx_) \ -do { \ - rnd_hid_preview_t *prv = calloc(sizeof(rnd_hid_preview_t), 1); \ - prv->user_ctx = user_ctx_; \ - prv->user_expose_cb = expose_cb; \ - prv->user_mouse_cb = mouse_cb; \ - prv->user_key_cb = key_cb; \ - prv->user_free_cb = free_cb; \ - prv->min_sizex_px = min_sizex_px_; \ - prv->min_sizey_px = min_sizey_px_; \ - if ((initial_view_box) != NULL) { \ - prv->initial_view.X1 = ((rnd_box_t *)(initial_view_box))->X1; \ - prv->initial_view.Y1 = ((rnd_box_t *)(initial_view_box))->Y1; \ - prv->initial_view.X2 = ((rnd_box_t *)(initial_view_box))->X2; \ - prv->initial_view.Y2 = ((rnd_box_t *)(initial_view_box))->Y2; \ - prv->initial_view_valid = 1; \ - } \ - RND_DAD_ALLOC(table, RND_HATT_PREVIEW); \ - prv->attrib = &table[table ## _len-1]; \ - RND_DAD_SET_ATTR_FIELD(table, wdata, prv); \ -} while(0) - -#define rnd_dad_preview_zoomto(attr, view) \ -do { \ - rnd_hid_preview_t *prv = ((attr)->wdata); \ - if (prv->hid_zoomto_cb != NULL) \ - prv->hid_zoomto_cb((attr), prv->hid_wdata, view); \ -} while(0) - - -#define RND_DAD_PICTURE(table, xpm) \ -do { \ - RND_DAD_ALLOC(table, RND_HATT_PICTURE); \ - table[table ## _len - 1].wdata = xpm; \ -} while(0) - -#define RND_DAD_PICBUTTON(table, xpm) \ -do { \ - RND_DAD_ALLOC(table, RND_HATT_PICBUTTON); \ - table[table ## _len - 1].wdata = xpm; \ -} while(0) - - -#define RND_DAD_COLOR(table) \ -do { \ - RND_DAD_ALLOC(table, RND_HATT_COLOR); \ -} while(0) - - -/* Create a horizontal or vertical pane. - pane_name is used when saving pane position in window geometry; - name is a const char *, not strdup'd or free'd (should be constant in the - caller). Name must contain only alphanumerical characters, dashes and - underscores */ - -#define RND_DAD_BEGIN_HPANE(table, pane_name) \ -do { \ - RND_DAD_BEGIN(table, RND_HATT_BEGIN_HPANE); \ - table[table ## _len - 1].val.dbl = 0.5; \ - table[table ## _len - 1].name = pane_name; \ -} while(0) - -#define RND_DAD_BEGIN_VPANE(table, pane_name) \ -do { \ - RND_DAD_BEGIN(table, RND_HATT_BEGIN_VPANE); \ - table[table ## _len - 1].val.dbl = 0.5; \ - table[table ## _len - 1].name = pane_name; \ -} while(0) - - -#define RND_DAD_TREE(table, cols, first_col_is_tree, opt_header) \ -do { \ - rnd_hid_tree_t *tree = calloc(sizeof(rnd_hid_tree_t), 1); \ - htsp_init(&tree->paths, strhash, strkeyeq); \ - RND_DAD_ALLOC(table, RND_HATT_TREE); \ - tree->attrib = &table[table ## _len-1]; \ - tree->hdr = opt_header; \ - RND_DAD_SET_ATTR_FIELD(table, rnd_hatt_table_cols, cols); \ - RND_DAD_SET_ATTR_FIELD(table, rnd_hatt_flags, first_col_is_tree ? RND_HATF_TREE_COL : 0); \ - RND_DAD_SET_ATTR_FIELD(table, wdata, tree); \ -} while(0) - -#define RND_DAD_TREE_APPEND(table, row_after, cells) \ - rnd_dad_tree_append(&table[table ## _len-1], row_after, cells) - -#define RND_DAD_TREE_APPEND_UNDER(table, parent_row, cells) \ - rnd_dad_tree_append_under(&table[table ## _len-1], parent_row, cells) - -#define RND_DAD_TREE_INSERT(table, row_before, cells) \ - rnd_dad_tree_insert(&table[table ## _len-1], row_before, cells) - -/* set the named tree user callback to func_or_data; name is automatically - appended with user_, any field prefixed with user_ in rnd_hid_tree_t - can be set */ -#define RND_DAD_TREE_SET_CB(table, name, func_or_data) \ -do { \ - rnd_hid_tree_t *__tree__ = table[table ## _len-1].wdata; \ - __tree__->user_ ## name = func_or_data; \ -} while(0) - - -#define RND_DAD_SUBDIALOG(table, sub) \ -do { \ - RND_DAD_ALLOC(table, RND_HATT_SUBDIALOG); \ - RND_DAD_SET_ATTR_FIELD(table, wdata, sub); \ -} while(0) - - -#define RND_DAD_DUP_ATTR(table, attr) \ -do { \ - RND_DAD_ALLOC(table, 0); \ - memcpy(&table[table ## _len-1], (attr), sizeof(rnd_hid_attribute_t)); \ - RND_DAD_UPDATE_INTERNAL(table, table ## _len-1); \ -} while(0) - -#define RND_DAD_DUP_EXPOPT_VAL(table, opt, val_attr) \ -do { \ - const rnd_export_opt_t *__opt__ = (opt); \ - RND_DAD_ALLOC(table, 0); \ - table[table ## _len-1].name = __opt__->name; \ - table[table ## _len-1].help_text = __opt__->help_text; \ - table[table ## _len-1].type = __opt__->type; \ - table[table ## _len-1].min_val = __opt__->min_val; \ - table[table ## _len-1].max_val = __opt__->max_val; \ - table[table ## _len-1].wdata = __opt__->enumerations; \ - table[table ## _len-1].val = (val_attr); \ - RND_DAD_UPDATE_INTERNAL(table, table ## _len-1); \ -} while(0) - - -/* Set properties of the current item */ -#define RND_DAD_MINVAL(table, val) RND_DAD_SET_ATTR_FIELD_SE(table, min_val, val) -#define RND_DAD_MAXVAL(table, val) RND_DAD_SET_ATTR_FIELD_SE(table, max_val, val) -#define RND_DAD_MINMAX(table, min, max) do { RND_DAD_SET_ATTR_FIELD_SE(table, min_val, min); RND_DAD_SET_ATTR_FIELD_SE(table, max_val, max); } while(0) -#define RND_DAD_CHANGE_CB(table, cb) RND_DAD_SET_ATTR_FIELD(table, change_cb, cb) -#define RND_DAD_RIGHT_CB(table, cb) RND_DAD_SET_ATTR_FIELD(table, right_cb, cb) -#define RND_DAD_ENTER_CB(table, cb) RND_DAD_SET_ATTR_FIELD(table, enter_cb, cb) - -#define RND_DAD_HELP(table, val) \ - do { \ - switch(table[table ## _len - 1].type) { \ - case RND_HATT_END: \ - { \ - rnd_hid_compound_t *cmp = table[table ## _len - 1].wdata; \ - if ((cmp != NULL) && (cmp->set_help != NULL)) \ - cmp->set_help(&table[table ## _len - 1], (val)); \ - } \ - break; \ - default: \ - RND_DAD_SET_ATTR_FIELD(table, help_text, val); \ - } \ - } while(0) - -#define RND_DAD_DEFAULT_PTR(table, val_) \ - do {\ - switch(table[table ## _len - 1].type) { \ - case RND_HATT_BEGIN_COMPOUND: \ - case RND_HATT_END: \ - { \ - rnd_hid_compound_t *cmp = table[table ## _len - 1].wdata; \ - if ((cmp != NULL) && (cmp->set_val_ptr != NULL)) \ - cmp->set_val_ptr(&table[table ## _len - 1], (void *)(val_)); \ - else \ - assert(0); \ - } \ - break; \ - default: \ - RND_DAD_SET_ATTR_FIELD_PTR(table, val, val_); \ - } \ - } while(0) - -#define RND_DAD_DEFAULT_NUM(table, val_) \ - do {\ - switch(table[table ## _len - 1].type) { \ - case RND_HATT_BEGIN_COMPOUND: \ - case RND_HATT_END: \ - { \ - rnd_hid_compound_t *cmp = table[table ## _len - 1].wdata; \ - if ((cmp != NULL) && (cmp->set_val_num != NULL)) \ - cmp->set_val_num(&table[table ## _len - 1], (long)(val_), (double)(val_), (rnd_coord_t)(val_)); \ - else \ - assert(0); \ - } \ - break; \ - default: \ - RND_DAD_SET_ATTR_FIELD_NUM(table, val, val_); \ - } \ - } while(0); - -/* safe way to call gui->attr_dlg_set_value() - resets the unused fields */ -#define RND_DAD_SET_VALUE(hid_ctx, wid, field, val_) \ - do { \ - rnd_hid_attr_val_t __val__; \ - memset(&__val__, 0, sizeof(__val__)); \ - __val__.field = val_; \ - rnd_gui->attr_dlg_set_value(hid_ctx, wid, &__val__); \ - } while(0) - -/*** DAD internals (do not use directly) ***/ - -/* Update widget internals after a potential attr pointer change */ -#define RND_DAD_UPDATE_INTERNAL(table, widx) \ - do { \ - rnd_hid_preview_t *__prv__; \ - rnd_hid_tree_t *__tree__; \ - switch(table[(widx)].type) { \ - case RND_HATT_PREVIEW: \ - __prv__ = table[(widx)].wdata; \ - __prv__->attrib = &table[(widx)]; \ - break; \ - case RND_HATT_TREE: \ - __tree__ = table[(widx)].wdata; \ - __tree__->attrib = &table[(widx)]; \ - break; \ - default: break; \ - } \ - } while(0) - -/* Allocate a new item at the end of the attribute table; updates stored - attribute pointers of existing items (e.g. previews, trees) as the base - address of the table may have changed. */ -#define RND_DAD_ALLOC(table, item_type) \ - do { \ - assert(table ## _append_lock == 0); \ - if (table ## _len >= table ## _alloced) { \ - int __n__; \ - table ## _alloced += 16; \ - table = realloc(table, sizeof(table[0]) * table ## _alloced); \ - for(__n__ = 0; __n__ < table ## _len; __n__++) { \ - RND_DAD_UPDATE_INTERNAL(table, __n__); \ - } \ - } \ - memset(&table[table ## _len], 0, sizeof(table[0])); \ - table[table ## _len].type = item_type; \ - table ## _len++; \ - } while(0) - -#define RND_DAD_SET_ATTR_FIELD(table, field, value) \ - table[table ## _len - 1].field = (value) - -#define RND_DAD_SET_ATTR_FIELD_SE(table, field, value) \ - do { \ - table[table ## _len - 1].field = (value); \ - RND_DAD_SET_ATTR_FIELD_SIDE_EFFECT(table, field, value); \ - } while(0) - -#define RND_DAD_OR_ATTR_FIELD(table, field, value) \ - table[table ## _len - 1].field |= (value) - -#define RND_DAD_SET_ATTR_FIELD_VAL(table, field, val) \ -do { \ - switch(table[table ## _len - 1].type) { \ - case RND_HATT_LABEL: \ - assert(0); \ - break; \ - case RND_HATT_INTEGER: \ - case RND_HATT_BOOL: \ - case RND_HATT_ENUM: \ - case RND_HATT_UNIT: \ - case RND_HATT_BEGIN_TABBED: \ - table[table ## _len - 1].field.lng = (int)val; \ - break; \ - case RND_HATT_COORD: \ - table[table ## _len - 1].field.crd = (rnd_coord_t)val; \ - break; \ - case RND_HATT_REAL: \ - case RND_HATT_PROGRESS: \ - case RND_HATT_BEGIN_HPANE: \ - case RND_HATT_BEGIN_VPANE: \ - table[table ## _len - 1].field.dbl = (double)val; \ - break; \ - case RND_HATT_STRING: \ - case RND_HATT_TEXT: \ - case RND_HATT_BUTTON: \ - case RND_HATT_TREE: \ - table[table ## _len - 1].field.str = (char *)val; \ - break; \ - case RND_HATT_COLOR: \ - table[table ## _len - 1].field.clr = *(rnd_color_t *)val; \ - break; \ - case RND_HATT_BEGIN_HBOX: \ - case RND_HATT_BEGIN_VBOX: \ - case RND_HATT_BEGIN_TABLE: \ - case RND_HATT_BEGIN_COMPOUND: \ - case RND_HATT_END: \ - case RND_HATT_PREVIEW: \ - case RND_HATT_PICTURE: \ - case RND_HATT_PICBUTTON: \ - assert(0); \ - } \ -} while(0) - -/* call compount set field */ -#define RND_DAD_SET_ATTR_FIELD_SIDE_EFFECT(table, field, val_) \ -do { \ - switch(table[table ## _len - 1].type) { \ - case RND_HATT_BEGIN_COMPOUND: \ - case RND_HATT_END: \ - { \ - rnd_hid_compound_t *cmp = table[table ## _len - 1].wdata; \ - if ((cmp != NULL) && (cmp->set_field_num != NULL)) \ - cmp->set_field_num(&table[table ## _len - 1], #field, (long)(val_), (double)(val_), (rnd_coord_t)(val_)); \ - else \ - assert(0); \ - } \ - break; \ - default:; \ - } \ -} while(0) - - -#define RND_DAD_SET_ATTR_FIELD_NUM(table, field, val_) \ -do { \ - switch(table[table ## _len - 1].type) { \ - case RND_HATT_LABEL: \ - case RND_HATT_SUBDIALOG: \ - assert(0); \ - break; \ - case RND_HATT_INTEGER: \ - case RND_HATT_BOOL: \ - case RND_HATT_ENUM: \ - case RND_HATT_BEGIN_TABBED: \ - table[table ## _len - 1].field.lng = (int)val_; \ - break; \ - case RND_HATT_COORD: \ - table[table ## _len - 1].field.crd = (rnd_coord_t)val_; \ - break; \ - case RND_HATT_REAL: \ - case RND_HATT_PROGRESS: \ - case RND_HATT_BEGIN_HPANE: \ - case RND_HATT_BEGIN_VPANE: \ - table[table ## _len - 1].field.dbl = (double)val_; \ - break; \ - case RND_HATT_STRING: \ - case RND_HATT_TEXT: \ - case RND_HATT_BUTTON: \ - case RND_HATT_TREE: \ - case RND_HATT_COLOR: \ - case RND_HATT_UNIT: \ - assert(!"please use the _PTR() variant instead of the _NUM() variant"); \ - break; \ - case RND_HATT_BEGIN_HBOX: \ - case RND_HATT_BEGIN_VBOX: \ - case RND_HATT_BEGIN_TABLE: \ - case RND_HATT_PREVIEW: \ - case RND_HATT_PICTURE: \ - case RND_HATT_PICBUTTON: \ - assert(0); \ - case RND_HATT_BEGIN_COMPOUND: \ - case RND_HATT_END: \ - RND_DAD_SET_ATTR_FIELD_SIDE_EFFECT(table, field, val_); \ - break; \ - } \ -} while(0) - -#define RND_DAD_SET_ATTR_FIELD_PTR(table, field, val_) \ -do { \ - switch(table[table ## _len - 1].type) { \ - case RND_HATT_LABEL: \ - assert(0); \ - break; \ - case RND_HATT_INTEGER: \ - case RND_HATT_BOOL: \ - case RND_HATT_ENUM: \ - case RND_HATT_BEGIN_TABBED: \ - case RND_HATT_COORD: \ - case RND_HATT_REAL: \ - case RND_HATT_PROGRESS: \ - case RND_HATT_BEGIN_HPANE: \ - case RND_HATT_BEGIN_VPANE: \ - assert(!"please use the _NUM() variant instead of the _PTR() variant"); \ - break; \ - case RND_HATT_UNIT: \ - { \ - int __n__, __v__ = rnd_get_n_units(0); \ - if (val_ != NULL) { \ - for(__n__ = 0; __n__ < __v__; __n__++) { \ - if (&rnd_units[__n__] == (rnd_unit_t *)(val_)) { \ - table[table ## _len - 1].field.lng = __n__; \ - break; \ - } \ - } \ - } \ - } \ - break; \ - case RND_HATT_STRING: \ - case RND_HATT_TEXT: \ - case RND_HATT_BUTTON: \ - case RND_HATT_TREE: \ - table[table ## _len - 1].field.str = (char *)val_; \ - break; \ - case RND_HATT_COLOR: \ - table[table ## _len - 1].field.clr = *((rnd_color_t *)val_); \ - break; \ - case RND_HATT_BEGIN_HBOX: \ - case RND_HATT_BEGIN_VBOX: \ - case RND_HATT_BEGIN_TABLE: \ - case RND_HATT_PREVIEW: \ - case RND_HATT_PICTURE: \ - case RND_HATT_PICBUTTON: \ - case RND_HATT_SUBDIALOG: \ - assert(0); \ - case RND_HATT_BEGIN_COMPOUND: \ - case RND_HATT_END: \ - { \ - rnd_hid_compound_t *cmp = table[table ## _len - 1].wdata; \ - if ((cmp != NULL) && (cmp->set_field_ptr != NULL)) \ - cmp->set_field_ptr(&table[table ## _len - 1], #field, (void *)(val_)); \ - else \ - assert(0); \ - } \ - break; \ - } \ -} while(0) - -#define RND_DAD_FREE_FIELD(table, field) \ -do { \ - switch(table[field].type) { \ - case RND_HATT_LABEL: \ - free((char *)table[field].name); \ - break; \ - case RND_HATT_INTEGER: \ - case RND_HATT_BOOL: \ - case RND_HATT_ENUM: \ - case RND_HATT_COORD: \ - case RND_HATT_UNIT: \ - case RND_HATT_REAL: \ - case RND_HATT_PROGRESS: \ - case RND_HATT_STRING: \ - case RND_HATT_BUTTON: \ - case RND_HATT_PICTURE: \ - case RND_HATT_PICBUTTON: \ - case RND_HATT_COLOR: \ - case RND_HATT_SUBDIALOG: \ - break; \ - case RND_HATT_TREE: \ - rnd_dad_tree_free(&table[field]); \ - break; \ - case RND_HATT_PREVIEW: \ - { \ - rnd_hid_preview_t *prv = table[field].wdata; \ - if (prv->user_free_cb != NULL) \ - prv->user_free_cb(&table[field], prv->user_ctx, prv->hid_wdata); \ - if (prv->hid_free_cb != NULL) \ - prv->hid_free_cb(&table[field], prv->hid_wdata); \ - free(prv); \ - } \ - break; \ - case RND_HATT_TEXT: \ - { \ - rnd_hid_text_t *txt = table[field].wdata; \ - if (txt->user_free_cb != NULL) \ - txt->user_free_cb(&table[field], txt->user_ctx, txt->hid_wdata); \ - if (txt->hid_free_cb != NULL) \ - txt->hid_free_cb(&table[field], txt->hid_wdata); \ - free(txt); \ - } \ - break; \ - case RND_HATT_BEGIN_COMPOUND: \ - case RND_HATT_END: \ - { \ - rnd_hid_compound_t *cmp = table[field].wdata; \ - if ((cmp != NULL) && (cmp->free != NULL)) \ - cmp->free(&table[field]); \ - } \ - case RND_HATT_BEGIN_HBOX: \ - case RND_HATT_BEGIN_VBOX: \ - case RND_HATT_BEGIN_HPANE: \ - case RND_HATT_BEGIN_VPANE: \ - case RND_HATT_BEGIN_TABLE: \ - case RND_HATT_BEGIN_TABBED: \ - break; \ - } \ -} while(0) - -#define RND_DAD_WIDTH_CHR(table, width) \ -do { \ - if ((table[table ## _len - 1].type) == RND_HATT_END) { \ - rnd_hid_compound_t *cmp = table[table ## _len - 1].wdata; \ - if (cmp->set_geo != NULL) \ - cmp->set_geo(&table[table ## _len - 1], RND_HATF_HEIGHT_CHR, (width)); \ - } \ - else { \ - RND_DAD_OR_ATTR_FIELD(table, hatt_flags, RND_HATF_HEIGHT_CHR); \ - RND_DAD_SET_ATTR_FIELD(table, geo_width, (width)); \ - } \ -} while(0) - -/* Internal: free all rows and caches and the tree itself */ -void rnd_dad_tree_free(rnd_hid_attribute_t *attr); - -/* internal: retval override for the auto-close buttons */ -typedef struct { - int dont_free; - int valid; - int value; -} rnd_dad_retovr_t; - -typedef struct { - const char *label; - int retval; -} rnd_hid_dad_buttons_t; - -void rnd_hid_dad_close(void *hid_ctx, rnd_dad_retovr_t *retovr, int retval); -void rnd_hid_dad_close_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); -int rnd_hid_dad_run(void *hid_ctx, rnd_dad_retovr_t *retovr); -void rnd_hid_iterate(rnd_hid_t *hid); - -/* sub-dialogs e.g. for the file selector dialog */ -struct rnd_hid_dad_subdialog_s { - /* filled in by the sub-dialog's creator */ - RND_DAD_DECL_NOINIT(dlg) - - /* filled in by the parent dialog's code, the subdialog's code should - call this to query/change properties of the parent dialog. cmd and - argc/argv are all specific to the given dialog. Returns 0 on success, - return payload may be placed in res (if it is not NULL). Parent poke: - close() - cancel/close the dialog */ - int (*parent_poke)(rnd_hid_dad_subdialog_t *sub, const char *cmd, rnd_event_arg_t *res, int argc, rnd_event_arg_t *argv); - - /* OPTIONAL: filled in by the sub-dialog's creator: called by the - sub-dialog's parent while the parent dialog is being closed. If - ok is false, the dialog was cancelled */ - void (*on_close)(rnd_hid_dad_subdialog_t *sub, rnd_bool ok); - - void *parent_ctx; /* used by the parent dialog code */ - void *sub_ctx; /* used by the sub-dialog's creator */ - - gdl_elem_t link; /* list of subdialogs: e.g. dock */ -}; - -typedef struct rnd_hid_export_opt_func_dad_s { - RND_DAD_DECL_NOINIT(dlg) -} rnd_hid_export_opt_func_dad_t; - -#endif Index: trunk/src/librnd/core/pixmap.c =================================================================== --- trunk/src/librnd/core/pixmap.c (revision 34601) +++ trunk/src/librnd/core/pixmap.c (nonexistent) @@ -1,205 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * Copyright (C) 2019 Tibor 'Igor2' Palinkas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact: - * Project page: http://repo.hu/projects/pcb-rnd - * lead developer: http://repo.hu/projects/pcb-rnd/contact.html - * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") - */ - -#include - -#include -#include -#include - -#include -#include -#include - -static unsigned int pixmap_hash_(const void *key_, int pixels) -{ - rnd_pixmap_t *key = (rnd_pixmap_t *)key_; - unsigned int i; - - if (pixels && key->hash_valid) - return key->hash; - - i = longhash(key->sx); - i ^= longhash(key->sy); - i ^= longhash((long)(key->tr_rot * 1000.0) + (((long)key->tr_xmirror) << 3) + (((long)key->tr_ymirror) << 4)); - i ^= longhash((long)(key->tr_xscale * 1000.0) + (long)(key->tr_yscale * 1000.0)); - if (key->transp_valid) { - i ^= 0x900; - i ^= ((unsigned int)key->tr) << 6; - i ^= ((unsigned int)key->tg) << 14; - i ^= ((unsigned int)key->tb) << 22; - } - if (pixels) { - i ^= jenhash(key->p, key->size); - key->hash = i; - key->hash_valid = 1; - } - else - i ^= longhash(key->neutral_oid); - return i; -} - -unsigned int rnd_pixmap_hash_meta(const void *key) -{ - return pixmap_hash_(key, 0); -} - -unsigned int rnd_pixmap_hash_pixels(const void *key) -{ - return pixmap_hash_(key, 1); -} - - -static int pixmap_eq_(const void *keya_, const void *keyb_, int pixels) -{ - const rnd_pixmap_t *keya = keya_, *keyb = keyb_; - if ((keya->transp_valid) || (keyb->transp_valid)) { - if (keya->transp_valid != keyb->transp_valid) - return 0; - if ((keya->tr != keyb->tr) || (keya->tg != keyb->tg) || (keya->tb != keyb->tb)) - return 0; - } - if ((keya->tr_xmirror != keyb->tr_xmirror) || (keya->tr_ymirror != keyb->tr_ymirror)) - return 0; - if ((keya->tr_rot != keyb->tr_rot) || (keya->tr_xscale != keyb->tr_xscale) || (keya->tr_yscale != keyb->tr_yscale)) - return 0; - if ((keya->sx != keyb->sx) || (keya->sy != keyb->sy)) - return 0; - if (pixels) - return (memcmp(keya->p, keyb->p, keya->size) == 0); - else - return (keya->neutral_oid == keyb->neutral_oid); -} - -int rnd_pixmap_eq_meta(const void *keya, const void *keyb) -{ - return pixmap_eq_(keya, keyb, 0); -} - -int rnd_pixmap_eq_pixels(const void *keya, const void *keyb) -{ - return pixmap_eq_(keya, keyb, 1); -} - - -static rnd_pixmap_import_t *rnd_pixmap_chain; - -void rnd_pixmap_reg_import(const rnd_pixmap_import_t *imp, const char *cookie) -{ - rnd_pixmap_import_t *i = malloc(sizeof(rnd_pixmap_import_t)); - memcpy(i, imp, sizeof(rnd_pixmap_import_t)); - i->cookie = cookie; - i->next = rnd_pixmap_chain; - rnd_pixmap_chain = i; -} - -static void rnd_pixmap_unreg_(rnd_pixmap_import_t *i, rnd_pixmap_import_t *prev) -{ - if (prev == NULL) - rnd_pixmap_chain = i->next; - else - prev->next = i->next; - free(i); -} - -void rnd_pixmap_unreg_import_all(const char *cookie) -{ - rnd_pixmap_import_t *i, *prev = NULL, *next; - for(i = rnd_pixmap_chain; i != NULL; i = next) { - next = i->next; - if (i->cookie == cookie) - rnd_pixmap_unreg_(i, prev); - else - prev = i; - } -} - -void rnd_pixmap_uninit(void) -{ - rnd_pixmap_import_t *i; - for(i = rnd_pixmap_chain; i != NULL; i = i->next) - rnd_message(RND_MSG_ERROR, "rnd_pixmap_chain is not empty: %s. Fix your plugins!\n", i->cookie); -} - -int rnd_old_pixmap_load(rnd_hidlib_t *hidlib, rnd_pixmap_t *pxm, const char *fn) -{ - rnd_pixmap_import_t *i; - for(i = rnd_pixmap_chain; i != NULL; i = i->next) - if (i->load(hidlib, pxm, fn) == 0) - return 0; - return -1; -} - -rnd_pixmap_t *rnd_pixmap_load(rnd_hidlib_t *hidlib, const char *fn) -{ - rnd_pixmap_t *p = calloc(sizeof(rnd_pixmap_t), 1); - if (rnd_old_pixmap_load(hidlib, p, fn) == 0) - return p; - free(p); - return NULL; -} - -rnd_pixmap_t *rnd_pixmap_alloc(rnd_hidlib_t *hidlib, long sx, long sy) -{ - rnd_pixmap_t *p = calloc(sizeof(rnd_pixmap_t), 1); - p->sx = sx; - p->sy = sy; - p->size = sx * sy * 3; - p->p = malloc(p->size); - return p; -} - -rnd_pixmap_t *rnd_pixmap_dup(rnd_hidlib_t *hidlib, const rnd_pixmap_t *pxm) -{ - rnd_pixmap_t *r = malloc(sizeof(rnd_pixmap_t)); - memcpy(r, pxm, sizeof(rnd_pixmap_t)); - r->p = malloc(pxm->size); - memcpy(r->p, pxm->p, pxm->size); - r->hid_data = NULL; - r->hid_data_valid = 0; - r->refco = 0; - return r; -} - -void rnd_pixmap_free_hid_data(rnd_pixmap_t *pxm) -{ - if ((rnd_render != NULL) && (rnd_render->uninit_pixmap != NULL)) - rnd_render->uninit_pixmap(rnd_render, pxm); - pxm->hid_data_valid = 0; - pxm->hid_data = NULL; -} - -void rnd_pixmap_free_fields(rnd_pixmap_t *pxm) -{ - rnd_pixmap_free_hid_data(pxm); - free(pxm->p); -} - -void rnd_pixmap_free(rnd_pixmap_t *pxm) -{ - rnd_pixmap_free_fields(pxm); - free(pxm); -} Index: trunk/src/librnd/core/pixmap.h =================================================================== --- trunk/src/librnd/core/pixmap.h (revision 34601) +++ trunk/src/librnd/core/pixmap.h (nonexistent) @@ -1,103 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * Copyright (C) 2019 Tibor 'Igor2' Palinkas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact: - * Project page: http://repo.hu/projects/pcb-rnd - * lead developer: http://repo.hu/projects/pcb-rnd/contact.html - * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") - */ - -/* generic pixmap (low level, part of the hidlib): draw, calculate hash, compare */ - -#ifndef RND_PIXMAP_H -#define RND_PIXMAP_H - -#include - -typedef struct rnd_pixmap_import_s rnd_pixmap_import_t; - -struct rnd_pixmap_import_s { - /* configured by the caller at registration */ - const char *name; - int (*load)(rnd_hidlib_t *hidlib, rnd_pixmap_t *pxm, const char *fn); - - /* filled in by code */ - rnd_pixmap_import_t *next; - const char *cookie; - - /* Spare: see doc/developer/spare.txt */ - void (*spare_f1)(void), (*spare_f2)(void); - long spare_l1, spare_l2, spare_l3, spare_l4; - void *spare_p1, *spare_p2, *spare_p3, *spare_p4; - double spare_d1, spare_d2, spare_d3, spare_d4; - rnd_coord_t spare_c1, spare_c2, spare_c3, spare_c4; -}; - -struct rnd_pixmap_s { - long size; /* total size of the array in memory (sx*sy*3) */ - long sx, sy; /* x and y dimensions */ - unsigned char tr, tg, tb; /* color of the transparent pixel if has_transp is 1 */ - unsigned int hash; /* precalculated hash value */ - unsigned char *p; /* pixel array in r,g,b rows of sx long each */ - unsigned long neutral_oid; /* UID of the pixmap in neutral position */ - unsigned long refco; /* optional reference counting */ - - void *hid_data; /* HID's version of the pixmap */ - - /* transformation info */ - rnd_angle_t tr_rot; /* rotation angle (0 if not transformed) */ - double tr_xscale; - double tr_yscale; - unsigned tr_xmirror:1; /* whether the pixmap is mirrored along the x axis (vertical mirror) */ - unsigned tr_ymirror:1; /* whether the pixmap is mirrored along the y axis (horizontal mirror) */ - - unsigned has_transp:1; /* 1 if the pixmap has any transparent pixels */ - unsigned transp_valid:1; /* 1 if transparent pixel is available */ - unsigned hash_valid:1; /* 1 if the has value has been calculated */ - unsigned hid_data_valid:1; /* 1 if hid_data is already generated and no data changed since - maintained by core, HIDs don't need to check */ - - /* Spare: see doc/developer/spare.txt */ - void (*spare_f1)(void), (*spare_f2)(void); - long spare_l1, spare_l2, spare_l3, spare_l4; - void *spare_p1, *spare_p2, *spare_p3, *spare_p4; - double spare_d1, spare_d2, spare_d3, spare_d4; - rnd_coord_t spare_c1, spare_c2, spare_c3, spare_c4; -}; - -void rnd_pixmap_reg_import(const rnd_pixmap_import_t *imp, const char *cookie); -void rnd_pixmap_unreg_import_all(const char *cookie); -void rnd_pixmap_uninit(void); - -int rnd_old_pixmap_load(rnd_hidlib_t *hidlib, rnd_pixmap_t *pxm, const char *fn); /* legacy API, should be removed */ -rnd_pixmap_t *rnd_pixmap_load(rnd_hidlib_t *hidlib, const char *fn); -rnd_pixmap_t *rnd_pixmap_alloc(rnd_hidlib_t *hidlib, long sx, long sy); -rnd_pixmap_t *rnd_pixmap_dup(rnd_hidlib_t *hidlib, const rnd_pixmap_t *pxm); - -unsigned int rnd_pixmap_hash_meta(const void *key); -unsigned int rnd_pixmap_hash_pixels(const void *key); -int rnd_pixmap_eq_meta(const void *keya, const void *keyb); -int rnd_pixmap_eq_pixels(const void *keya, const void *keyb); - - -void rnd_pixmap_free_hid_data(rnd_pixmap_t *pxm); -void rnd_pixmap_free_fields(rnd_pixmap_t *pxm); -void rnd_pixmap_free(rnd_pixmap_t *pxm); - -#endif Index: trunk/src/librnd/core/hid_dad_tree.c =================================================================== --- trunk/src/librnd/core/hid_dad_tree.c (revision 34601) +++ trunk/src/librnd/core/hid_dad_tree.c (nonexistent) @@ -1,122 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * Copyright (C) 2018,2019 Tibor 'Igor2' Palinkas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact: - * Project page: http://repo.hu/projects/pcb-rnd - * lead developer: http://repo.hu/projects/pcb-rnd/contact.html - * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") - */ - -/* Non-inline utility functions for the DAD tree widget */ - -#include -#include - -/* recursively free a row list subtree */ -static void rnd_dad_tree_free_rowlist(rnd_hid_attribute_t *attr, gdl_list_t *list) -{ - rnd_hid_tree_t *tree = attr->wdata; - rnd_hid_row_t *r; - - while((r = gdl_first(list)) != NULL) { - gdl_remove(list, r, link); - rnd_dad_tree_free_rowlist(attr, &r->children); - - if (tree->hid_free_cb != NULL) - tree->hid_free_cb(tree->attrib, tree->hid_wdata, r); - - if (tree->user_free_cb != NULL) - tree->user_free_cb(tree->attrib, tree->hid_wdata, r); - - if (attr->rnd_hatt_flags & RND_HATF_TREE_COL) - free(r->path); - - free(r); - } -} - -/* Internal: free all rows and caches and the tree itself */ -void rnd_dad_tree_free(rnd_hid_attribute_t *attr) -{ - rnd_hid_tree_t *tree = attr->wdata; - htsp_uninit(&tree->paths); - rnd_dad_tree_free_rowlist(attr, &tree->rows); - free(tree); -} - -void rnd_dad_tree_hide_all(rnd_hid_tree_t *tree, gdl_list_t *rowlist, int val) -{ - rnd_hid_row_t *r; - for(r = gdl_first(rowlist); r != NULL; r = gdl_next(rowlist, r)) { - r->hide = val; - rnd_dad_tree_hide_all(tree, &r->children, val); - } -} - -void rnd_dad_tree_unhide_filter(rnd_hid_tree_t *tree, gdl_list_t *rowlist, int col, const char *text) -{ - rnd_hid_row_t *r, *pr; - - for(r = gdl_first(rowlist); r != NULL; r = gdl_next(rowlist, r)) { - if (strstr(r->cell[col], text) != NULL) { - rnd_dad_tree_hide_all(tree, &r->children, 0); /* if this is a node with children, show all children */ - for(pr = r; pr != NULL; pr = rnd_dad_tree_parent_row(tree, pr)) /* also show all parents so it is visible */ - pr->hide = 0; - } - rnd_dad_tree_unhide_filter(tree, &r->children, col, text); - } -} - -rnd_hid_row_t *rnd_dad_tree_mkdirp(rnd_hid_tree_t *tree, char *path, char **cells) -{ - char *cell[2] = {NULL}; - rnd_hid_row_t *parent; - char *last, *old; - - parent = htsp_get(&tree->paths, path); - if (parent != NULL) - return parent; - - last = strrchr(path, '/'); - - if (last == NULL) { - /* root dir */ - parent = htsp_get(&tree->paths, path); - if (parent != NULL) - return parent; - cell[0] = rnd_strdup(path); - return rnd_dad_tree_append(tree->attrib, NULL, cell); - } - -/* non-root-dir: get or create parent */ - *last = '\0'; - last++; - parent = rnd_dad_tree_mkdirp(tree, path, NULL); - - if (cells == NULL) { - cell[0] = rnd_strdup(last); - return rnd_dad_tree_append_under(tree->attrib, parent, cell); - } - - old = cell[0]; - cells[0] = rnd_strdup(last); - free(old); - return rnd_dad_tree_append_under(tree->attrib, parent, cells); -} Index: trunk/src/librnd/core/grid.c =================================================================== --- trunk/src/librnd/core/grid.c (revision 34601) +++ trunk/src/librnd/core/grid.c (nonexistent) @@ -1,283 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * (this file is based on PCB, interactive printed circuit board design) - * Copyright (C) 1994,1995,1996 Thomas Nau - * Copyright (C) 2018 Tibor 'Igor2' Palinkas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Contact: - * Project page: http://repo.hu/projects/pcb-rnd - * lead developer: http://repo.hu/projects/pcb-rnd/contact.html - * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") - * - */ - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static const char grid_cookie[] = "librnd grid"; -static int grid_idx_lock; - -rnd_coord_t rnd_grid_fit(rnd_coord_t x, rnd_coord_t grid_spacing, rnd_coord_t grid_offset) -{ - x -= grid_offset; - x = grid_spacing * rnd_round((double) x / grid_spacing); - x += grid_offset; - return x; -} - -rnd_bool_t rnd_grid_parse(rnd_grid_t *dst, const char *src) -{ - const char *nsep; - char *sep3, *sep2, *sep, *tmp, *size, *ox = NULL, *oy = NULL, *unit = NULL; - rnd_bool succ; - - nsep = strchr(src, ':'); - if (nsep != NULL) - src = nsep+1; - else - dst->name = NULL; - - /* remember where size starts */ - while(isspace(*src)) src++; - sep = size = tmp = rnd_strdup(src); - - /* find optional offs */ - sep2 = strchr(sep, '@'); - if (sep2 != NULL) { - sep = sep2; - *sep = '\0'; - sep++; - ox = sep; - sep3 = strchr(sep, ','); - if (sep3 != NULL) { - *sep3 = '\0'; - sep3++; - oy = sep; - } - } - - /* find optional unit switch */ - sep2 = strchr(sep, '!'); - if (sep2 != NULL) { - sep = sep2; - *sep = '\0'; - sep++; - unit = sep; - } - - /* convert */ - dst->size = rnd_get_value(size, NULL, NULL, &succ); - if ((!succ) || (dst->size < 0)) - goto error; - - if (ox != NULL) { - dst->ox = rnd_get_value(ox, NULL, NULL, &succ); - if (!succ) - goto error; - } - else - dst->ox = 0; - - if (oy != NULL) { - dst->oy = rnd_get_value(oy, NULL, NULL, &succ); - if (!succ) - goto error; - } - else - dst->oy = 0; - - if (unit != NULL) { - dst->unit = rnd_get_unit_struct(unit); - if (dst->unit == NULL) - goto error; - } - else - dst->unit = NULL; - - /* success */ - free(tmp); - - if (nsep != NULL) - dst->name = rnd_strndup(src, nsep-src-1); - else - dst->name = NULL; - return rnd_true; - - error:; - free(tmp); - return rnd_false; -} - -rnd_bool_t rnd_grid_append_print(gds_t *dst, const rnd_grid_t *src) -{ - if (src->size <= 0) - return rnd_false; - if (src->name != NULL) { - gds_append_str(dst, src->name); - gds_append(dst, ':'); - } - rnd_append_printf(dst, "%$.08mH", src->size); - if ((src->ox != 0) || (src->oy != 0)) - rnd_append_printf(dst, "@%$.08mH,%$.08mH", src->ox, src->oy); - if (src->unit != NULL) { - gds_append(dst, '!'); - gds_append_str(dst, src->unit->suffix); - } - return rnd_true; -} - -char *rnd_grid_print(const rnd_grid_t *src) -{ - gds_t tmp; - gds_init(&tmp); - if (!rnd_grid_append_print(&tmp, src)) { - gds_uninit(&tmp); - return NULL; - } - return tmp.array; /* do not uninit tmp */ -} - -void rnd_grid_set(rnd_hidlib_t *hidlib, const rnd_grid_t *src) -{ - rnd_hidlib_set_grid(hidlib, src->size, rnd_true, src->ox, src->oy); - if (src->unit != NULL) - rnd_hidlib_set_unit(hidlib, src->unit); -} - -void rnd_grid_free(rnd_grid_t *dst) -{ - free(dst->name); - dst->name = NULL; -} - -rnd_bool_t rnd_grid_list_jump(rnd_hidlib_t *hidlib, int dst) -{ - const rnd_conf_listitem_t *li; - rnd_grid_t g; - int max = rnd_conflist_length((rnd_conflist_t *)&rnd_conf.editor.grids); - - if (dst < 0) - dst = 0; - if (dst >= max) - dst = max - 1; - if (dst < 0) - return rnd_false; - - grid_idx_lock++; - - rnd_conf_setf(RND_CFR_DESIGN, "editor/grids_idx", -1, "%d", dst); - - li = rnd_conflist_nth((rnd_conflist_t *)&rnd_conf.editor.grids, dst); - /* clamp */ - if (li == NULL) { - grid_idx_lock--; - return rnd_false; - } - - if (!rnd_grid_parse(&g, li->payload)) { - grid_idx_lock--; - return rnd_false; - } - rnd_grid_set(hidlib, &g); - rnd_grid_free(&g); - - grid_idx_lock--; - return rnd_true; -} - -rnd_bool_t rnd_grid_list_step(rnd_hidlib_t *hidlib, int stp) -{ - int dst = rnd_conf.editor.grids_idx; - if (dst < 0) - dst = -dst-1; - return rnd_grid_list_jump(hidlib, dst + stp); -} - -void rnd_grid_inval(void) -{ - if (rnd_conf.editor.grids_idx > 0) - rnd_conf_setf(RND_CFR_DESIGN, "editor/grids_idx", -1, "%d", -1 - rnd_conf.editor.grids_idx); -} - -/*** catch editor/grid changes to update editor/grids_idx */ - -static void grid_conf_chg(rnd_conf_native_t *cfg, int arr_idx) -{ - gdl_iterator_t it; - rnd_conf_listitem_t *ge; - int idx = 0, found = -1; - - if (grid_idx_lock) - return; - - grid_idx_lock++; - rnd_conflist_foreach((rnd_conflist_t *)&rnd_conf.editor.grids, &it, ge) { - rnd_grid_t g; -/* g.ox = hidlib->grid_ox; g.oy = hidlib->grid_oy; */ - if (rnd_grid_parse(&g, ge->payload)) { - if ((g.size == rnd_conf.editor.grid) /*&& (g.ox == hidlib->grid_ox) && (g.oy == hidlib->grid_oy)*/) { - found = idx; - rnd_grid_free(&g); - break; - } - rnd_grid_free(&g); - } - idx++; - } - - if (rnd_conf.editor.grids_idx != found) - rnd_conf_setf(RND_CFR_DESIGN, "editor/grids_idx", -1, "%d", found); - grid_idx_lock--; -} - -void rnd_grid_init(void) -{ - rnd_conf_native_t *n = rnd_conf_get_field("editor/grid"); - static rnd_conf_hid_id_t grid_conf_id; - - if (n != NULL) { - static rnd_conf_hid_callbacks_t cbs; - grid_conf_id = rnd_conf_hid_reg(grid_cookie, NULL); - memset(&cbs, 0, sizeof(rnd_conf_hid_callbacks_t)); - cbs.val_change_post = grid_conf_chg; - rnd_conf_hid_set_cb(n, grid_conf_id, &cbs); - } - -} - -void rnd_grid_uninit(void) -{ - rnd_conf_hid_unreg(grid_cookie); -} - Index: trunk/src/librnd/core/hid_dad_tree.h =================================================================== --- trunk/src/librnd/core/hid_dad_tree.h (revision 34601) +++ trunk/src/librnd/core/hid_dad_tree.h (nonexistent) @@ -1,322 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * Copyright (C) 2018,2019 Tibor 'Igor2' Palinkas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact: - * Project page: http://repo.hu/projects/pcb-rnd - * lead developer: http://repo.hu/projects/pcb-rnd/contact.html - * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") - */ - -/* Inline helpers called by the DAD macros for the tree-table widget */ - -#ifndef RND_HID_DAD_TREE_H -#define RND_HID_DAD_TREE_H - -#include -#include -#include -#include -#include -#include - -/* recursively sets the hide flag on all nodes to val */ -void rnd_dad_tree_hide_all(rnd_hid_tree_t *tree, gdl_list_t *rowlist, int val); - -/* recursively unhide items that match text in the given column; parents are unhidden too */ -void rnd_dad_tree_unhide_filter(rnd_hid_tree_t *tree, gdl_list_t *rowlist, int col, const char *text); - -/* Recursively create the node and all parents in a tree. If cells is not NULL, - the target path row is created with these cells, else only the first col - is filled in. Temporarily modifies path (but changes it back) */ -rnd_hid_row_t *rnd_dad_tree_mkdirp(rnd_hid_tree_t *tree, char *path, char **cells); - -/* Internal: Allocate a new row and load the cells (but do not insert it anywhere) */ -RND_INLINE rnd_hid_row_t *rnd_dad_tree_new_row(char **cols) -{ - int num_cols; - rnd_hid_row_t *nrow; - char **s, **o; - for(s = cols, num_cols = 0; *s != NULL; s++, num_cols++); - - nrow = calloc(sizeof(rnd_hid_row_t) + sizeof(char *) * num_cols, 1); - nrow->cols = num_cols; - for(s = cols, o = nrow->cell; *s != NULL; s++, o++) - *o = *s; - - return nrow; -} - -RND_INLINE void rnd_dad_tree_free_row(rnd_hid_tree_t *tree, rnd_hid_row_t *row) -{ - int do_free_path = 0; - /* do this before the user callback just in case row->path == row->cell[0] - and the user callback free's it */ - if (row->path != NULL) { - htsp_pop(&tree->paths, row->path); - do_free_path = (row->path != row->cell[0]); /* user_free_cb may set row->cell[0] to NULL */ - } - - if (tree->user_free_cb != NULL) - tree->user_free_cb(tree->attrib, tree->hid_wdata, row); - - if (do_free_path) - free(row->path); - - free(row); -} - - -RND_INLINE rnd_hid_row_t *rnd_dad_tree_parent_row(rnd_hid_tree_t *tree, rnd_hid_row_t *row) -{ - char *ptr = (char *)row->link.parent; - if ((ptr == NULL) || ((gdl_list_t *)ptr == &tree->rows)) - return NULL; - - ptr -= offsetof(gdl_elem_t, parent); - ptr -= offsetof(rnd_hid_row_t, children); - return (rnd_hid_row_t *)ptr; -} - -RND_INLINE rnd_hid_row_t *rnd_dad_tree_prev_row(rnd_hid_tree_t *tree, rnd_hid_row_t *row) -{ - return row->link.prev; -} - -RND_INLINE rnd_hid_row_t *rnd_dad_tree_next_row(rnd_hid_tree_t *tree, rnd_hid_row_t *row) -{ - return row->link.next; -} - -/* recursively build a full path of a tree node in path */ -RND_INLINE void rnd_dad_tree_build_path(rnd_hid_tree_t *tree, gds_t *path, rnd_hid_row_t *row) -{ - rnd_hid_row_t *par = rnd_dad_tree_parent_row(tree, row); - if (par != NULL) - rnd_dad_tree_build_path(tree, path, par); - if (path->used > 0) - gds_append(path, '/'); - gds_append_str(path, row->cell[0]); -} - -/* calculate path of a row and insert it in the tree hash */ -RND_INLINE void rnd_dad_tree_set_hash(rnd_hid_attribute_t *attr, rnd_hid_row_t *row) -{ - rnd_hid_tree_t *tree = attr->wdata; - if (attr->rnd_hatt_flags & RND_HATF_TREE_COL) { - gds_t path; - gds_init(&path); - rnd_dad_tree_build_path(tree, &path, row); - row->path = path.array; - } - else - row->path = row->cell[0]; - htsp_set(&tree->paths, row->path, row); -} - -/* allocate a new row and append it after aft; if aft is NULL, the new row is appended at the - end of the list of entries in the root (== at the bottom of the list) */ -RND_INLINE rnd_hid_row_t *rnd_dad_tree_append(rnd_hid_attribute_t *attr, rnd_hid_row_t *aft, char **cols) -{ - rnd_hid_tree_t *tree = attr->wdata; - rnd_hid_row_t *nrow = rnd_dad_tree_new_row(cols); - gdl_list_t *par; /* the list that is the common parent of aft and the new row */ - - assert(attr == tree->attrib); - - if (aft == NULL) { - par = &tree->rows; - aft = gdl_last(par); - } - else - par = aft->link.parent; - - gdl_insert_after(par, aft, nrow, link); - rnd_dad_tree_set_hash(attr, nrow); - if (tree->hid_insert_cb != NULL) - tree->hid_insert_cb(tree->attrib, tree->hid_wdata, nrow); - return nrow; -} - -/* allocate a new row and inert it before bfr; if bfr is NULL, the new row is inserted at the - beginning of the list of entries in the root (== at the top of the list) */ -RND_INLINE rnd_hid_row_t *rnd_dad_tree_insert(rnd_hid_attribute_t *attr, rnd_hid_row_t *bfr, char **cols) -{ - rnd_hid_tree_t *tree = attr->wdata; - rnd_hid_row_t *nrow = rnd_dad_tree_new_row(cols); - gdl_list_t *par; /* the list that is the common parent of bfr and the new row */ - - assert(attr == tree->attrib); - - if (bfr == NULL) { - par = &tree->rows; - bfr = gdl_first(par); - } - else - par = bfr->link.parent; - - gdl_insert_before(par, bfr, nrow, link); - rnd_dad_tree_set_hash(attr, nrow); - if (tree->hid_insert_cb != NULL) - tree->hid_insert_cb(tree->attrib, tree->hid_wdata, nrow); - return nrow; -} - -/* allocate a new row and append it under prn; if prn is NULL, the new row is appended at the - end of the list of entries in the root (== at the bottom of the list) */ -RND_INLINE rnd_hid_row_t *rnd_dad_tree_append_under(rnd_hid_attribute_t *attr, rnd_hid_row_t *prn, char **cols) -{ - rnd_hid_tree_t *tree = attr->wdata; - rnd_hid_row_t *nrow = rnd_dad_tree_new_row(cols); - gdl_list_t *par; /* the list that is the common parent of aft and the new row */ - - assert(attr == tree->attrib); - - if (prn == NULL) - par = &tree->rows; - else - par = &prn->children; - - gdl_append(par, nrow, link); - rnd_dad_tree_set_hash(attr, nrow); - if (tree->hid_insert_cb != NULL) - tree->hid_insert_cb(tree->attrib, tree->hid_wdata, nrow); - return nrow; -} - -RND_INLINE int rnd_dad_tree_remove(rnd_hid_attribute_t *attr, rnd_hid_row_t *row) -{ - rnd_hid_tree_t *tree = attr->wdata; - rnd_hid_row_t *r, *rn, *par = rnd_dad_tree_parent_row(tree, row); - gdl_list_t *lst = (par == NULL) ? &tree->rows : &par->children; - int res = 0; - - assert(attr == tree->attrib); - - /* recursively remove all children */ - for(r = gdl_first(&row->children); r != NULL; r = rn) { - rn = gdl_next(&row->children, r); - res |= rnd_dad_tree_remove(attr, r); - } - - /* remove from gui */ - if (tree->hid_remove_cb != NULL) - tree->hid_remove_cb(tree->attrib, tree->hid_wdata, row); - else - res = -1; - - /* remove from dad */ - gdl_remove(lst, row, link); - rnd_dad_tree_free_row(tree, row); - return res; -} - -RND_INLINE void rnd_dad_tree_clear(rnd_hid_tree_t *tree) -{ - rnd_hid_row_t *r; - for(r = gdl_first(&tree->rows); r != NULL; r = gdl_first(&tree->rows)) - rnd_dad_tree_remove(tree->attrib, r); -} - -RND_INLINE rnd_hid_row_t *rnd_dad_tree_get_selected(rnd_hid_attribute_t *attr) -{ - rnd_hid_tree_t *tree = attr->wdata; - - assert(attr == tree->attrib); - - if (tree->hid_get_selected_cb == NULL) - return NULL; - - return tree->hid_get_selected_cb(tree->attrib, tree->hid_wdata); -} - -RND_INLINE void rnd_dad_tree_update_hide(rnd_hid_attribute_t *attr) -{ - rnd_hid_tree_t *tree = attr->wdata; - - assert(attr == tree->attrib); - - if (tree->hid_update_hide_cb != NULL) - tree->hid_update_hide_cb(tree->attrib, tree->hid_wdata); -} - -RND_INLINE int rnd_dad_tree_modify_cell(rnd_hid_attribute_t *attr, rnd_hid_row_t *row, int col, char *new_val) -{ - rnd_hid_tree_t *tree = attr->wdata; - - assert(attr == tree->attrib); - - if ((col < 0) || (col >= row->cols)) - return 0; - - if (col == 0) { - htsp_pop(&tree->paths, row->path); - free(row->path); - row->path = NULL; - } - - row->cell[col] = new_val; - - if (col == 0) - rnd_dad_tree_set_hash(attr, row); - - if (tree->hid_modify_cb != NULL) - tree->hid_modify_cb(tree->attrib, tree->hid_wdata, row, col); - - return 0; -} - -RND_INLINE void rnd_dad_tree_jumpto(rnd_hid_attribute_t *attr, rnd_hid_row_t *row) -{ - rnd_hid_tree_t *tree = attr->wdata; - - assert(attr == tree->attrib); - - if (tree->hid_jumpto_cb != NULL) - tree->hid_jumpto_cb(tree->attrib, tree->hid_wdata, row); -} - -RND_INLINE void rnd_dad_tree_expcoll_(rnd_hid_tree_t *tree, rnd_hid_row_t *row, rnd_bool expanded, rnd_bool recursive) -{ - if (recursive) { - rnd_hid_row_t *r; - for(r = gdl_first(&row->children); r != NULL; r = gdl_next(&row->children, r)) - rnd_dad_tree_expcoll_(tree, r, expanded, recursive); - } - if (gdl_first(&row->children) != NULL) - tree->hid_expcoll_cb(tree->attrib, tree->hid_wdata, row, expanded); -} - -RND_INLINE void rnd_dad_tree_expcoll(rnd_hid_attribute_t *attr, rnd_hid_row_t *row, rnd_bool expanded, rnd_bool recursive) -{ - rnd_hid_tree_t *tree = attr->wdata; - - assert(attr == tree->attrib); - - if (tree->hid_expcoll_cb != NULL) { - if (row == NULL) { - for(row = gdl_first(&tree->rows); row != NULL; row = gdl_next(&tree->rows, row)) - rnd_dad_tree_expcoll_(tree, row, expanded, recursive); - } - else - rnd_dad_tree_expcoll_(tree, row, expanded, recursive); - } -} - -#endif Index: trunk/src/librnd/core/grid.h =================================================================== --- trunk/src/librnd/core/grid.h (revision 34601) +++ trunk/src/librnd/core/grid.h (nonexistent) @@ -1,81 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * (this file is based on PCB, interactive printed circuit board design) - * Copyright (C) 1994,1995,1996 Thomas Nau - * Copyright (C) 2018 Tibor 'Igor2' Palinkas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Contact: - * Project page: http://repo.hu/projects/pcb-rnd - * lead developer: http://repo.hu/projects/pcb-rnd/contact.html - * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") - * - */ - -#ifndef RND_GRID_H -#define RND_GRID_H - -#include -#include -#include -#include - -/* String packed syntax (bracket means optional): - - [name:]size[@offs][!unit] - - "!" means to switch the UI to the unit specified. */ -typedef struct { - char *name; - rnd_coord_t size; - rnd_coord_t ox, oy; - const rnd_unit_t *unit; /* force switching to unit if not NULL */ -} rnd_grid_t; - -/* Returns the nearest grid-point to the given coord x */ -rnd_coord_t rnd_grid_fit(rnd_coord_t x, rnd_coord_t grid_spacing, rnd_coord_t grid_offset); - -/* Parse packed string format src into dst; allocat dst->name on success */ -rnd_bool_t rnd_grid_parse(rnd_grid_t *dst, const char *src); - -/* Free all allocated fields of a grid struct */ -void rnd_grid_free(rnd_grid_t *dst); - -/* Convert src into packed string format */ -rnd_bool_t rnd_grid_append_print(gds_t *dst, const rnd_grid_t *src); -char *rnd_grid_print(const rnd_grid_t *src); - -/* Apply grid settings from src to the pcb */ -void rnd_grid_set(rnd_hidlib_t *hidlib, const rnd_grid_t *src); - -/* Jump to grid index dst (clamped); absolute set */ -rnd_bool_t rnd_grid_list_jump(rnd_hidlib_t *hidlib, int dst); - -/* Step stp steps (can be 0) on the grids list and set the resulting grid; relative set */ -rnd_bool_t rnd_grid_list_step(rnd_hidlib_t *hidlib, int stp); - -/* invalidate the grid index; call this when changing the grid settings */ -void rnd_grid_inval(void); - -/* Reinstall grid menus */ -void rnd_grid_install_menu(void); - -void rnd_grid_init(void); -void rnd_grid_uninit(void); - -#endif Index: trunk/src/librnd/core/hid_dlg.c =================================================================== --- trunk/src/librnd/core/hid_dlg.c (revision 34601) +++ trunk/src/librnd/core/hid_dlg.c (nonexistent) @@ -1,295 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * (this file is based on PCB, interactive printed circuit board design) - * Copyright (C) 1994,1995,1996 Thomas Nau - * Copyright (C) 2004 harry eaton - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact: - * Project page: http://repo.hu/projects/pcb-rnd - * lead developer: http://repo.hu/projects/pcb-rnd/contact.html - * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") - * - */ - -#include - -#include -#include -#include -#include -#include - -static int hid_dlg_gui_inited = 0; - -/* Action and wrapper implementation for dialogs. If GUI is available, the - gui_ prefixed action is executed, else the cli_ prefixed one is used. If - nothing is available, the effect is equivalent to cancel. */ - -/* Call the gui_ or the cli_ action; act_name must be all lowercase! */ -static fgw_error_t call_dialog(const char *act_name, fgw_arg_t *res, int argc, fgw_arg_t *argv) -{ - char tmp[128]; - - strcpy(tmp, "gui_"); - strncpy(tmp+4, act_name, sizeof(tmp)-5); - if (RND_HAVE_GUI_ATTR_DLG && (fgw_func_lookup(&rnd_fgw, tmp) != NULL)) - return rnd_actionv_bin(RND_ACT_HIDLIB, tmp, res, argc, argv); - - tmp[0] = 'c'; tmp[1] = 'l'; - if (fgw_func_lookup(&rnd_fgw, tmp) != NULL) - return rnd_actionv_bin(RND_ACT_HIDLIB, tmp, res, argc, argv); - - return FGW_ERR_NOT_FOUND; -} - -static const char rnd_acts_PromptFor[] = "PromptFor([message[,default[,title]]])"; -static const char rnd_acth_PromptFor[] = "Prompt for a string. Returns the string (or NULL on cancel)"; -/* DOC: promptfor.html */ -static fgw_error_t rnd_act_PromptFor(fgw_arg_t *res, int argc, fgw_arg_t *argv) -{ - return call_dialog("promptfor", res, argc, argv); -} - -char *rnd_hid_prompt_for(rnd_hidlib_t *hl, const char *msg, const char *default_string, const char *title) -{ - fgw_arg_t res, argv[4]; - - argv[1].type = FGW_STR; argv[1].val.cstr = msg; - argv[2].type = FGW_STR; argv[2].val.cstr = default_string; - argv[3].type = FGW_STR; argv[3].val.cstr = title; - - if (rnd_actionv_bin(hl, "PromptFor", &res, 4, argv) != 0) - return NULL; - - if (res.type == (FGW_STR | FGW_DYN)) - return res.val.str; - - fgw_arg_free(&rnd_fgw, &res); - return NULL; -} - -static const char rnd_acts_MessageBox[] = "MessageBox(icon, title, label, button_txt, button_retval, ...)"; -static const char rnd_acth_MessageBox[] = "Open a modal message dialog box with title and label. If icon string is not empty, display the named icon on the left. Present one or more window close buttons with different text and return value."; -static fgw_error_t rnd_act_MessageBox(fgw_arg_t *res, int argc, fgw_arg_t *argv) -{ - return call_dialog("messagebox", res, argc, argv); -} - -int rnd_hid_message_box(rnd_hidlib_t *hl, const char *icon, const char *title, const char *label, ...) -{ - fgw_arg_t res, argv[128]; - int argc; - va_list ap; - - argv[1].type = FGW_STR; argv[1].val.cstr = icon; - argv[2].type = FGW_STR; argv[2].val.cstr = title; - argv[3].type = FGW_STR; argv[3].val.cstr = label; - argc = 4; - - va_start(ap, label); - for(;argc < 126;) { - argv[argc].type = FGW_STR; - argv[argc].val.cstr = va_arg(ap, const char *); - if (argv[argc].val.cstr == NULL) - break; - argc++; - argv[argc].type = FGW_INT; - argv[argc].val.nat_int = va_arg(ap, int); - argc++; - } - va_end(ap); - - if (rnd_actionv_bin(hl, "MessageBox", &res, argc, argv) != 0) - return -1; - - if (fgw_arg_conv(&rnd_fgw, &res, FGW_INT) == 0) - return res.val.nat_int; - - fgw_arg_free(&rnd_fgw, &res); - return -1; -} - -void rnd_hid_iterate(rnd_hid_t *hid) -{ - if (hid->iterate != NULL) - hid->iterate(hid); -} - -static const char *refresh = "progress refresh"; -static const char *cancel = "progress cancel"; -#define REFRESH_RATE 100 - -static void progress_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) -{ - rnd_hid_progress(0, 0, NULL); -} - -static void progress_close_btn_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) -{ - rnd_hid_progress(0, 0, cancel); -} - -static void progress_refresh_cb(rnd_hidval_t user_data) -{ - rnd_hid_progress(0, 0, refresh); -} - -static int rnd_gui_progress(long so_far, long total, const char *message) -{ - double now; - static rnd_hidval_t timer; - static int active = 0, cancelled = 0; - static int wp, have_timer = 0; - static rnd_hid_attr_val_t val; - static double last = 0; - static int closing = 0; - static struct { - RND_DAD_DECL_NOINIT(dlg) - } ctx; - - if (message == refresh) { - if (active) - last = rnd_dtime(); - have_timer = 0; - refresh_now:; - if (active) { - rnd_gui->attr_dlg_set_value(ctx.dlg_hid_ctx, wp, &val); - if (!have_timer) { - timer = rnd_gui->add_timer(rnd_gui, progress_refresh_cb, REFRESH_RATE, timer); - have_timer = 1; - } - rnd_hid_iterate(rnd_gui); - } - return 0; - } - - - if (message == cancel) { - cancelled = 1; - message = NULL; - } - - - /* If we are finished, destroy any dialog */ - if (so_far == 0 && total == 0 && message == NULL) { - if (active) { - if (have_timer) { - rnd_gui->stop_timer(rnd_gui, timer); - have_timer = 0; - } - if (!closing) { - closing = 1; - RND_DAD_FREE(ctx.dlg); - } - active = 0; - } - return 1; - } - - if (cancelled) { - cancelled = 0; - return 1; - } - - if (!active) { - RND_DAD_BEGIN_VBOX(ctx.dlg); - RND_DAD_LABEL(ctx.dlg, message); - RND_DAD_PROGRESS(ctx.dlg); - wp = RND_DAD_CURRENT(ctx.dlg); - - /* need to have a manual cancel button as it needs to call the close cb before really closing the window */ - RND_DAD_BEGIN_HBOX(ctx.dlg); - RND_DAD_BEGIN_HBOX(ctx.dlg); - RND_DAD_COMPFLAG(ctx.dlg, RND_HATF_EXPFILL); - RND_DAD_END(ctx.dlg); - RND_DAD_BUTTON(ctx.dlg, "cancel"); - RND_DAD_CHANGE_CB(ctx.dlg, progress_close_btn_cb); - RND_DAD_END(ctx.dlg); - RND_DAD_END(ctx.dlg); - - RND_DAD_NEW("progress", ctx.dlg, "Ringdove progress", &ctx, rnd_false, progress_close_cb); - active = 1; - cancelled = 0; - - timer = rnd_gui->add_timer(rnd_gui, progress_refresh_cb, REFRESH_RATE, timer); - have_timer = 1; - closing = 0; - } - - val.dbl = (double)so_far / (double)total; - - now = rnd_dtime(); - if (now >= (last + (REFRESH_RATE / 1000.0))) { - last = now; - goto refresh_now; - } - return 0; -} - - -int rnd_hid_progress(long so_far, long total, const char *message) -{ - if (rnd_gui == NULL) - return 0; - if ((rnd_gui->gui) && (RND_HAVE_GUI_ATTR_DLG) && (hid_dlg_gui_inited || rnd_gui->allow_dad_before_init)) - return rnd_gui_progress(so_far, total, message); - - return rnd_nogui_progress(so_far, total, message); -} - -static const char rnd_acts_Print[] = "Print()"; -static const char rnd_acth_Print[] = "Present the print export dialog for printing the layout from the GUI."; -/* DOC: print.html */ -static fgw_error_t rnd_act_Print(fgw_arg_t *res, int argc, fgw_arg_t *argv) -{ - if (RND_HAVE_GUI_ATTR_DLG && (fgw_func_lookup(&rnd_fgw, "printgui") != NULL)) - return rnd_actionv_bin(RND_ACT_HIDLIB, "printgui", res, argc, argv); - rnd_message(RND_MSG_ERROR, "action Print() is available only under a GUI HID. Please use the lpr exporter instead.\n"); - return FGW_ERR_NOT_FOUND; -} - - -static rnd_action_t hid_dlg_action_list[] = { - {"PromptFor", rnd_act_PromptFor, rnd_acth_PromptFor, rnd_acts_PromptFor}, - {"MessageBox", rnd_act_MessageBox, rnd_acth_MessageBox, rnd_acts_MessageBox}, - {"Print", rnd_act_Print, rnd_acth_Print, rnd_acts_Print} -}; - -static const char *event_dlg_cookie = "hid_dlg"; - -static void hid_dlg_log_gui_init_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) -{ - hid_dlg_gui_inited = 1; -} - -void rnd_hid_dlg_uninit(void) -{ - rnd_event_unbind_allcookie(event_dlg_cookie); -} - -void rnd_hid_dlg_init(void) -{ - rnd_event_bind(RND_EVENT_GUI_INIT, hid_dlg_log_gui_init_ev, NULL, event_dlg_cookie); -} - -void rnd_hid_dlg_init2(void) -{ - RND_REGISTER_ACTIONS(hid_dlg_action_list, NULL); -} - Index: trunk/src/librnd/core/hid_attrib.h =================================================================== --- trunk/src/librnd/core/hid_attrib.h (revision 34601) +++ trunk/src/librnd/core/hid_attrib.h (nonexistent) @@ -1,187 +0,0 @@ -#ifndef RND_HID_ATTRIB_H -#define RND_HID_ATTRIB_H - -#include -#include -#include - -/* Used for HID attributes (exporting and printing, mostly). - HA_boolean uses lng, HA_enum sets lng to the index and - str to the enumeration string. RND_HATT_LABEL just shows the - default str. */ -struct rnd_hid_attr_val_s { - long lng; - const char *str; - double dbl; - rnd_coord_t crd; - rnd_color_t clr; - void (*func)(); -}; - -typedef enum rnd_hatt_compflags_e { - RND_HATF_FRAME = 1, /* box/table has a visible frame around it */ - RND_HATF_TIGHT = 2, /* box/table/button has minimal padding and spacing */ - RND_HATF_SCROLL = 4, /* box/table is scrollable */ - RND_HATF_HIDE_TABLAB = 8, /* hide tab labes of a TABBED - the tab mechanism works, but tab names are not displayed and are not clickable */ - RND_HATF_CLR_STATIC = 8, /* color that can not be changed */ - RND_HATF_LEFT_TAB = 16, /* display tab labels of TABBED on the left instead of on top (default) */ - RND_HATF_TREE_COL = 32, /* first column of a RND_HATT_TREE is a tree */ - RND_HATF_EXPFILL = 64, /* for hbox and vbox: expand and fill */ - RND_HATF_HIDE = 128,/* widget is initially hidden */ - RND_HATF_TOGGLE = 256,/* for buttons and picbuttons: use a toggle button instead of a push button */ - RND_HATF_TEXT_TRUNCATED = 512, /* label: do not set widget size for text, truncate text if widget is smaller */ - RND_HATF_TEXT_VERTICAL = 1024,/* label: rotate text 90 degrees so it can be read from the right */ - RND_HATF_PRV_DESIGN = 2048, /* indicates that a preview widget is showing a section of the design so it needs to be redrawn when the (top window) design is redrawn */ - RND_HATF_WIDTH_CHR = 4096, /* ->geo_width is specified in charactes */ - RND_HATF_HEIGHT_CHR = 8192, /* ->geo_width is specified in charactes */ - RND_HATF_INIT_FOCUS = 16384, /* this widget has (keyboard) focus on widget creation */ - RND_HATF_PRV_GFLIP = 32768, /* global design flip determines preview flip */ - RND_HATF_PRV_LFLIP = 65536, /* local flip determines preview flip; when set RND_HATF_PRV_GFLIP is ignored */ - RND_HATF_PRG_SMALL = 131072, /* allow progress bar to be as small as possible */ - RND_HATF_TREE_NO_AUTOEXP = 262144 /* do not auto-expand or auto-colleps on tree row activation */ -} rnd_hatt_compflags_t; - -typedef enum rnd_hid_attr_type_e { - /* atomic entry types */ - RND_HATT_LABEL, - RND_HATT_INTEGER, - RND_HATT_REAL, - RND_HATT_STRING, /* WARNING: string, must be malloc()'d, can't be a (const char *) */ - RND_HATT_BOOL, - RND_HATT_ENUM, - RND_HATT_UNIT, - RND_HATT_COORD, - RND_HATT_BUTTON, /* push button; default value is the label */ - RND_HATT_TREE, /* tree/list/table view; number of columns: rnd_hatt_table_cols; data is in field 'wdata' */ - RND_HATT_PROGRESS, /* progress bar; displays dbl between 0 and 1 */ - RND_HATT_PREVIEW, /* preview/render widget; callbacks in 'wdata' */ - RND_HATT_PICTURE, /* static picture from xpm - picture data in wdata */ - RND_HATT_PICBUTTON, /* button with static picture from xpm - picture data in wdata */ - RND_HATT_COLOR, /* color pick (user input: select a color) */ - RND_HATT_TEXT, /* plain text editor; data is in 'wdata' as rnd_hid_text_t */ - RND_HATT_SUBDIALOG, /* caller operated subdialog (docked dialog); available from librnd 3.1.0 */ - - /* groups (e.g. boxes) */ - RND_HATT_BEGIN_HBOX = 100, /* NOTE: RND_HATT_IS_COMPOSITE() depends on it */ - RND_HATT_BEGIN_VBOX, - RND_HATT_BEGIN_HPANE, /* horizontal split and offer two vboxes; the split ratio is dbl between 0 and 1, that describes the left side's size */ - RND_HATT_BEGIN_VPANE, /* vertical split and offer two vboxes; the split ratio is dbl between 0 and 1, that describes the left side's size */ - RND_HATT_BEGIN_TABLE, /* wdata_aux1 is the number of columns */ - RND_HATT_BEGIN_TABBED, /* tabbed view (e.g. notebook); ->wdata stores the tab names and a NULL; default_val's integer value is the index of the current tab */ - RND_HATT_BEGIN_COMPOUND, /* subtree emulating a single widget; (rnd_hid_compound_t *) stored in END's wdata */ - - RND_HATT_END = 200 /* close one level of RND_HATT_* */ -} rnd_hid_attr_type_t; - -#define RND_HATT_IS_COMPOSITE(type) \ - (((type) >= RND_HATT_BEGIN_HBOX) && ((type) < RND_HATT_END)) - -#define RND_HAT_IS_STR(type) (type == RND_HATT_STRING) - -/* alternative field names in struct rnd_hid_attribute_s */ -#define rnd_hatt_flags hatt_flags -#define rnd_hatt_table_cols wdata_aux1 - -struct rnd_hid_attribute_s { - const char *name; - const char *help_text; - rnd_hid_attr_type_t type; - double min_val, max_val; /* for integer and real */ - rnd_hid_attr_val_t val; /* Also actual value for global attributes. */ - - /* RND_HATT_ENUM: const char ** (NULL terminated list of values) - RND_HATT_PICTURE & RND_HATT_PICBUTTON: const char **xpm - RND_HATT_TREE and others: (rnd_hid_*_t *) */ - void *wdata; /* main widget data */ - int wdata_aux1; /* auixiliary widget data - should phase out long term */ - - /* dynamic API */ - unsigned changed:1; /* 0 for initial values, 1 on user change */ - unsigned empty:1; /* set to 1 by the widget implementation if the textual value is empty, where applicable */ - void (*change_cb)(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); /* called upon value change by the user */ - void (*right_cb)(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); /* called upon right click by the user */ - void (*enter_cb)(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); /* called upon the user pressed enter in a widget that handles keys */ - void *user_data; /* ignored; the caller is free to use it */ - rnd_hatt_compflags_t hatt_flags; - - /* geometry */ - int geo_width; /* when RND_HATF_WIDTH_CHR is set, width of the widget in characters, on creation-time */ - int geo_height; - - /* Spare: see doc/developer/spare.txt */ - void (*spare_f1)(void), (*spare_f2)(void); - long spare_l1, spare_l2, spare_l3, spare_l4; - void *spare_p1, *spare_p2, *spare_p3, *spare_p4; - double spare_d1, spare_d2; - rnd_coord_t spare_c1, spare_c2; -}; - -struct rnd_export_opt_s { - const char *name; - const char *help_text; - rnd_hid_attr_type_t type; - double min_val, max_val; /* for integer and real */ - rnd_hid_attr_val_t default_val; - const char **enumerations; /* NULL terminated list of values for a RND_HATT_ENUM */ - - - /* This used to be an alternative value target but as a void * it did - no work on all platforms - it was not clear what different HATT types - should write, especially for an enum: int *, long *... */ - /* void *value; */ -}; - -/* Load export plugin's read-write hid->attribute_array with defaults from - read-only opts; do this once, at init. */ -void rnd_hid_load_defaults(rnd_hid_t *hid, const rnd_export_opt_t *opts, int len); - -/* The selected HID or export plugin (and potentially - dependent exporter plugins) register their options and command line - options will be looked up in these. Plugins not participating in the - current session won't register and the registration is lost immediately - after the export because the application exits. Cam or dialog box direct - exporting won't go through this. */ -void rnd_export_register_opts2(rnd_hid_t *hid, const rnd_export_opt_t *a, int n, const char *cookie, int copy); - -/* Remove all attributes registered with the given cookie */ -void rnd_export_remove_opts_by_cookie(const char *cookie); - -/* remove all attributes and free the list */ -void rnd_export_uninit(void); - -typedef struct rnd_hid_attr_node_s { - struct rnd_hid_attr_node_s *next; - rnd_hid_t *hid; - const rnd_export_opt_t *opts; - int n; - const char *cookie; -} rnd_hid_attr_node_t; - -extern rnd_hid_attr_node_t *rnd_hid_attr_nodes; - -void rnd_hid_usage(const rnd_export_opt_t *a, int numa); -void rnd_hid_usage_option(const char *name, const char *help); - -/* Count the number of direct children, start_from the first children */ -int rnd_hid_attrdlg_num_children(rnd_hid_attribute_t *attrs, int start_from, int n_attrs); - -/* Invoke a simple modal attribute dialog if GUI is available */ -int rnd_attribute_dialog_(const char *id, rnd_hid_attribute_t *attrs, int n_attrs, const char *title, void *caller_data, void **retovr, int defx, int defy, int minx, int miny, void **hid_ctx_out); -int rnd_attribute_dialog(const char *id, rnd_hid_attribute_t *attrs, int n_attrs, const char *title, void *caller_data); - - -/* Convert between compflag bit value and name */ -const char *rnd_hid_compflag_bit2name(rnd_hatt_compflags_t bit); -rnd_hatt_compflags_t rnd_hid_compflag_name2bit(const char *name); - -/*** When an rnd_export_opt_t item is a box, the following function is called - from its ->func ***/ - -typedef enum rnd_hid_export_opt_func_action_e { - RND_HIDEOF_USAGE, /* call_ctx is a FILE * */ - RND_HIDEOF_DAD /* call_ctx is a rnd_hid_export_opt_func_dad_t */ -} rnd_hid_export_opt_func_action_t; - -typedef void (*rnd_hid_export_opt_func_t)(rnd_hid_export_opt_func_action_t act, void *call_ctx, const rnd_export_opt_t *opt, rnd_hid_attr_val_t *val); - -#endif Index: trunk/src/librnd/core/hid_attrib.c =================================================================== --- trunk/src/librnd/core/hid_attrib.c (revision 34601) +++ trunk/src/librnd/core/hid_attrib.c (nonexistent) @@ -1,309 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * (this file is based on PCB, interactive printed circuit board design) - * Copyright (C) 1994,1995,1996 Thomas Nau - * Copyright (C) 2004 harry eaton - * Copyright (C) 2016..2019 Tibor 'Igor2' Palinkas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact: - * Project page: http://repo.hu/projects/pcb-rnd - * lead developer: http://repo.hu/projects/pcb-rnd/contact.html - * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") - * - */ - -#include -#include -#include -#include -#include - -rnd_hid_attr_node_t *rnd_hid_attr_nodes = 0; - -void rnd_export_register_opts2(rnd_hid_t *hid, const rnd_export_opt_t *a, int n, const char *cookie, int copy) -{ - rnd_hid_attr_node_t *ha; - - /* printf("%d attributes registered\n", n); */ - ha = malloc(sizeof(rnd_hid_attr_node_t)); - ha->next = rnd_hid_attr_nodes; - rnd_hid_attr_nodes = ha; - ha->opts = a; - ha->n = n; - ha->cookie = cookie; - ha->hid = hid; -} - -void rnd_export_uninit(void) -{ - rnd_hid_attr_node_t *ha, *next; - for (ha = rnd_hid_attr_nodes; ha; ha = next) { - next = ha->next; - if (ha->cookie != NULL) - fprintf(stderr, "WARNING: attribute %s by %s is not uninited, check your plugins' uninit!\n", ha->opts->name, ha->cookie); - free(ha); - } - rnd_hid_attr_nodes = NULL; -} - -void rnd_export_remove_opts_by_cookie(const char *cookie) -{ - rnd_hid_attr_node_t *ha, *next, *prev = NULL; - for (ha = rnd_hid_attr_nodes; ha; ha = next) { - next = ha->next; - if (ha->cookie == cookie) { - if (prev == NULL) - rnd_hid_attr_nodes = next; - else - prev->next = next; - free(ha); - } - else - prev = ha; - } -} - -static void opt2attr(rnd_hid_attr_val_t *dst, const rnd_export_opt_t *src) -{ - switch (src->type) { - case RND_HATT_LABEL: - case RND_HATT_INTEGER: - case RND_HATT_COORD: - case RND_HATT_BOOL: - case RND_HATT_REAL: - case RND_HATT_ENUM: - case RND_HATT_UNIT: - *dst = src->default_val; - break; - case RND_HATT_STRING: - free((char *)dst->str); - dst->str = src->default_val.str == NULL ? NULL : rnd_strdup(src->default_val.str); - break; - default: - if (RND_HATT_IS_COMPOSITE(src->type)) /* function callback */ - break; - rnd_message(RND_MSG_ERROR, "Invalid attribute type %d for attribute %s\n", src->type, src->name); - abort(); - } -} - -void rnd_hid_load_defaults(rnd_hid_t *hid, const rnd_export_opt_t *opts, int len) -{ - int n; - rnd_hid_attr_val_t *values = hid->argument_array; - - for(n = 0; n < len; n++) - opt2attr(&values[n], opts + n); -} - - -#define MAX_FILENAMES 1024 -int rnd_hid_parse_command_line(int *argc, char ***argv) -{ - rnd_hid_attr_node_t *ha; - int i, e, ok, filenames = 0; - char *filename[MAX_FILENAMES+2], *end; - rnd_bool succ; - - /* set defaults */ - for (ha = rnd_hid_attr_nodes; ha; ha = ha->next) { - rnd_hid_attr_val_t *backup = NULL; - if (ha->hid != NULL) - backup = ha->hid->argument_array; - - if (backup == NULL) { - rnd_message(RND_MSG_ERROR, "rnd_hid_parse_command_line(): no backup storage. Direct ->value field is not supported anymore. Your hid/export plugin (%s, %s) needs to be fixed.\n", ha->hid->name, ha->cookie); - return -1; - } - rnd_hid_load_defaults(ha->hid, ha->opts, ha->n); - } - - /* parse the command line and overwrite with values read from argc/argv */ - while(*argc > 0) - if (*argc && (*argv)[0][0] == '-' && (*argv)[0][1] == '-') { - int bool_val; - int arg_ofs; - - bool_val = 1; - arg_ofs = 2; - try_no_arg:; - for (ha = rnd_hid_attr_nodes; ha; ha = ha->next) { - rnd_hid_attr_val_t *backup = ha->hid->argument_array; - - for (i = 0; i < ha->n; i++) - if (strcmp((*argv)[0] + arg_ofs, ha->opts[i].name) == 0) { - const rnd_export_opt_t *a = ha->opts + i; - char *ep; - const rnd_unit_t *unit; - switch (ha->opts[i].type) { - case RND_HATT_LABEL: - break; - case RND_HATT_INTEGER: - if ((*argv)[1] == NULL) { - rnd_message(RND_MSG_ERROR, "export parameter error: %s requires a parameter\n", (*argv)[0]); - return -1; - } - else - backup[i].lng = strtol((*argv)[1], &end, 0); - if (*end != '\0') { - rnd_message(RND_MSG_ERROR, "export parameter error: %s requires an integer but got '%s'\n", (*argv)[0], (*argv)[1]); - return -1; - } - (*argc)--; - (*argv)++; - break; - case RND_HATT_COORD: - if ((*argv)[1] == NULL) { - rnd_message(RND_MSG_ERROR, "export parameter error: %s requires a parameter\n", (*argv)[0]); - return -1; - } - else - backup[i].crd = rnd_get_value((*argv)[1], NULL, NULL, &succ); - if (!succ) { - rnd_message(RND_MSG_ERROR, "export parameter error: %s requires a coord value but got '%s'\n", (*argv)[0], (*argv)[1]); - return -1; - } - (*argc)--; - (*argv)++; - break; - case RND_HATT_REAL: - if ((*argv)[1] == NULL) { - rnd_message(RND_MSG_ERROR, "export parameter error: %s requires a parameter\n", (*argv)[0]); - return -1; - } - else - backup[i].dbl = strtod((*argv)[1], &end); - if (*end != '\0') { - rnd_message(RND_MSG_ERROR, "export parameter error: %s requires a number but got '%s'\n", (*argv)[0], (*argv)[1]); - return -1; - } - (*argc)--; - (*argv)++; - break; - case RND_HATT_STRING: - backup[i].str = rnd_strdup(RND_EMPTY((*argv)[1])); - (*argc)--; - (*argv)++; - break; - case RND_HATT_BOOL: - backup[i].lng = bool_val; - break; - case RND_HATT_ENUM: - if ((*argv)[1] == NULL) { - rnd_message(RND_MSG_ERROR, "export parameter error: %s requires a parameter\n", (*argv)[0]); - return -1; - } - else - ep = (*argv)[1]; - ok = 0; - for (e = 0; a->enumerations[e]; e++) - if (strcmp(a->enumerations[e], ep) == 0) { - ok = 1; - backup[i].lng = e; - backup[i].str = ep; - break; - } - if (!ok) { - rnd_message(RND_MSG_ERROR, "ERROR: \"%s\" is an unknown value for the --%s option\n", (*argv)[1], a->name); - return -1; - } - (*argc)--; - (*argv)++; - break; - case RND_HATT_UNIT: - if ((*argv)[1] == NULL) { - rnd_message(RND_MSG_ERROR, "export parameter error: %s requires a parameter\n", (*argv)[0]); - return -1; - } - else - unit = rnd_get_unit_struct((*argv)[1]); - if (unit == NULL) { - rnd_message(RND_MSG_ERROR, "ERROR: unit \"%s\" is unknown to pcb (option --%s)\n", (*argv)[1], a->name); - return -1; - } - backup[i].lng = unit->index; - backup[i].str = unit->suffix; - (*argc)--; - (*argv)++; - break; - default: - break; - } - (*argc)--; - (*argv)++; - ha = 0; - goto got_match; - } - } - if (bool_val == 1 && strncmp((*argv)[0], "--no-", 5) == 0) { - bool_val = 0; - arg_ofs = 5; - goto try_no_arg; - } - rnd_message(RND_MSG_ERROR, "unrecognized option: %s\n", (*argv)[0]); - return -1; - got_match:; - } - else { - /* Any argument without the "--" is considered a filename. Take only - one filename for now */ - - if (filenames > MAX_FILENAMES) { - rnd_message(RND_MSG_ERROR, "Too manu filenames specified. Overflow at filename: %s\n", (*argv)[0]); - return -1; - } - if (!rnd_app.multi_design && (filenames > 0)) { - rnd_message(RND_MSG_ERROR, "Multiple filenames not supported. First filename was: %s; offending second filename: %s\n", filename[0], (*argv)[0]); - return -1; - } - - filename[filenames++] = (*argv)[0]; - (*argc)--; - (*argv)++; - } - - /* restore filename to the first argument */ - for(i = 0; i < filenames; i++) - (*argv)[i] = filename[i]; - (*argc) = filenames; - - return 0; -} - -void rnd_hid_usage_option(const char *name, const char *help) -{ - fprintf(stderr, "--%-20s %s\n", name, help); -} - -void rnd_hid_usage(const rnd_export_opt_t *a, int numa) -{ - for (; numa > 0; numa--,a++) { - const char *help; - if (a->help_text == NULL) help = ""; - else help = a->help_text; - if (RND_HATT_IS_COMPOSITE(a->type)) { - rnd_hid_export_opt_func_t fnc = a->default_val.func; - if (fnc != NULL) - fnc(RND_HIDEOF_USAGE, stderr, a, NULL); - } - else - rnd_hid_usage_option(a->name, help); - } -} - Index: trunk/src/librnd/core/hid_act.c =================================================================== --- trunk/src/librnd/core/hid_act.c (revision 34601) +++ trunk/src/librnd/core/hid_act.c (nonexistent) @@ -1,184 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * Copyright (C) 2016,2020,2021 Tibor 'Igor2' Palinkas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact: - * Project page: http://repo.hu/projects/pcb-rnd - * lead developer: http://repo.hu/projects/pcb-rnd/contact.html - * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -static const char rnd_acts_ChkMode[] = "ChkMode(expected_mode)" ; -static const char rnd_acth_ChkMode[] = "Return 1 if the currently selected mode is the expected_mode"; -static fgw_error_t rnd_act_ChkMode(fgw_arg_t *res, int argc, fgw_arg_t *argv) -{ - const char *dst; - rnd_toolid_t id; - - RND_ACT_CONVARG(1, FGW_STR, ChkMode, dst = argv[1].val.str); - - id = rnd_tool_lookup(dst); - if (id >= 0) { - RND_ACT_IRES(rnd_conf.editor.mode == id); - return 0; - } - RND_ACT_IRES(-1); - return 0; -} - - -static const char rnd_acts_ChkGridSize[] = - "ChkGridSize(expected_size)\n" - "ChkGridSize(none)\n" - ; -static const char rnd_acth_ChkGridSize[] = "Return 1 if the currently selected grid matches the expected_size. If argument is \"none\" return 1 if there is no grid."; -static fgw_error_t rnd_act_ChkGridSize(fgw_arg_t *res, int argc, fgw_arg_t *argv) -{ - const char *dst; - - RND_ACT_CONVARG(1, FGW_STR, ChkGridSize, dst = argv[1].val.str); - - if (strcmp(dst, "none") == 0) { - RND_ACT_IRES(RND_ACT_HIDLIB->grid <= 300); - return 0; - } - - RND_ACT_IRES(RND_ACT_HIDLIB->grid == rnd_get_value_ex(dst, NULL, NULL, NULL, NULL, NULL)); - return 0; -} - - -static const char rnd_acts_ChkGridUnits[] = "ChkGridUnits(expected)"; -static const char rnd_acth_ChkGridUnits[] = "Return 1 if currently selected grid unit matches the expected (normally mm or mil)"; -static fgw_error_t rnd_act_ChkGridUnits(fgw_arg_t *res, int argc, fgw_arg_t *argv) -{ - const char *expected; - RND_ACT_CONVARG(1, FGW_STR, ChkGridUnits, expected = argv[1].val.str); - RND_ACT_IRES(strcmp(rnd_conf.editor.grid_unit->suffix, expected) == 0); - return 0; -} - -static const char rnd_acts_SetGrid[] = "SetGrid(delta|*mult|/div, [unit])"; -static const char rnd_acth_SetGrid[] = "Change grid size."; -/* for doc: copy from SetValue(grid,...) */ -static fgw_error_t rnd_act_SetGrid(fgw_arg_t *res, int argc, fgw_arg_t *argv) -{ - const char *val, *units = NULL; - rnd_bool absolute; - double value; - - RND_ACT_CONVARG(1, FGW_STR, SetGrid, val = argv[1].val.str); - RND_ACT_MAY_CONVARG(2, FGW_STR, SetGrid, units = argv[2].val.str); - - RND_ACT_IRES(0); - - /* special case: can't convert with rnd_get_value() */ - if ((val[0] == '*') || (val[0] == '/')) { - double d; - char *end; - - d = strtod(val+1, &end); - if ((*end != '\0') || (d <= 0)) { - rnd_message(RND_MSG_ERROR, "SetGrid: Invalid multiplier/divider for grid set: needs to be a positive number\n"); - return 1; - } - rnd_grid_inval(); - if (val[0] == '*') - rnd_hidlib_set_grid(RND_ACT_HIDLIB, rnd_round(RND_ACT_HIDLIB->grid * d), rnd_false, 0, 0); - else - rnd_hidlib_set_grid(RND_ACT_HIDLIB, rnd_round(RND_ACT_HIDLIB->grid / d), rnd_false, 0, 0); - return 0; - } - - value = rnd_get_value(val, units, &absolute, NULL); - - rnd_grid_inval(); - if (absolute) - rnd_hidlib_set_grid(RND_ACT_HIDLIB, value, rnd_false, 0, 0); - else { - /* On the way down, until the minimum unit (1) */ - if ((value + RND_ACT_HIDLIB->grid) < 1) - rnd_hidlib_set_grid(RND_ACT_HIDLIB, 1, rnd_false, 0, 0); - else if (RND_ACT_HIDLIB->grid == 1) - rnd_hidlib_set_grid(RND_ACT_HIDLIB, value, rnd_false, 0, 0); - else - rnd_hidlib_set_grid(RND_ACT_HIDLIB, value + RND_ACT_HIDLIB->grid, rnd_false, 0, 0); - } - return 0; -} - -static const char rnd_acts_SetGridOffs[] = "SetGridOffs(x_offs, y_offs)"; -static const char rnd_acth_SetGridOffs[] = "Change grid offset (alignment) to x_offs and y_offs. Offsets should be specified with units."; -/* DOC: setgridoffs.html */ -static fgw_error_t rnd_act_SetGridOffs(fgw_arg_t *res, int argc, fgw_arg_t *argv) -{ - const char *xs, *ys; - rnd_bool xa, ya, xv, yv; - rnd_coord_t x, y; - - RND_ACT_CONVARG(1, FGW_STR, SetGridOffs, xs = argv[1].val.str); - RND_ACT_CONVARG(2, FGW_STR, SetGridOffs, ys = argv[2].val.str); - - RND_ACT_IRES(0); - - x = rnd_get_value(xs, NULL, &xa, &xv); - y = rnd_get_value(ys, NULL, &ya, &yv); - - if (!xv || !yv) { - rnd_message(RND_MSG_ERROR, "SetGrid: Invalid%s%s offset value\n", (xv ? "" : " x"), (yv ? "" : " x")); - return 1; - } - - if (!xa) x += RND_ACT_HIDLIB->grid_ox; - if (!ya) y += RND_ACT_HIDLIB->grid_oy; - - - rnd_grid_inval(); - rnd_hidlib_set_grid(RND_ACT_HIDLIB, RND_ACT_HIDLIB->grid, rnd_true, x, y); - - return 0; -} - -static rnd_action_t rnd_hid_action_list[] = { - {"ChkMode", rnd_act_ChkMode, rnd_acth_ChkMode, rnd_acts_ChkMode}, - {"ChkGridSize", rnd_act_ChkGridSize, rnd_acth_ChkGridSize, rnd_acts_ChkGridSize}, - {"ChkGridUnits", rnd_act_ChkGridUnits, rnd_acth_ChkGridUnits, rnd_acts_ChkGridUnits}, - {"SetGrid", rnd_act_SetGrid, rnd_acth_SetGrid, rnd_acts_SetGrid}, - {"SetGridOffs", rnd_act_SetGridOffs, rnd_acth_SetGridOffs, rnd_acts_SetGridOffs}, -}; - -void rnd_hid_act_init2(void) -{ - RND_REGISTER_ACTIONS(rnd_hid_action_list, NULL); -} - - - Index: trunk/src/librnd/core/tool.c =================================================================== --- trunk/src/librnd/core/tool.c (revision 34601) +++ trunk/src/librnd/core/tool.c (nonexistent) @@ -1,370 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * Copyright (C) 1994,1995,1996 Thomas Nau - * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton - * Copyright (C) 2017,2019,2020 Tibor 'Igor2' Palinkas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact: - * Project page: http://repo.hu/projects/pcb-rnd - * lead developer: http://repo.hu/projects/pcb-rnd/contact.html - * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") - */ - -#include - -#include - -#include -#include -#include -#include -#include - -#define RND_MAX_MODESTACK_DEPTH 16 /* maximum depth of mode stack */ - -rnd_bool rnd_tool_is_saved = rnd_false; - -vtp0_t rnd_tools; - -rnd_toolid_t rnd_tool_prev_id; -rnd_toolid_t rnd_tool_next_id; -static int save_position = 0; -static int save_stack[RND_MAX_MODESTACK_DEPTH]; - -static void init_current_tool(void); -static void uninit_current_tool(void); - -static int tool_select_lock = 0; - -void rnd_tool_init(void) -{ - vtp0_init(&rnd_tools); -} - -void rnd_tool_uninit(void) -{ - while(vtp0_len(&rnd_tools) != 0) { - const rnd_tool_t *tool = rnd_tool_get(0); - rnd_message(RND_MSG_WARNING, "Unregistered tool: %s of %s; check your plugins, fix them to unregister their tools!\n", tool->name, tool->cookie); - rnd_tool_unreg_by_cookie(tool->cookie); - } - vtp0_uninit(&rnd_tools); -} - -void rnd_tool_chg_mode(rnd_hidlib_t *hl) -{ - if ((hl != NULL) && (!tool_select_lock)) - rnd_tool_select_by_id(hl, rnd_conf.editor.mode); -} - -rnd_toolid_t rnd_tool_reg(rnd_tool_t *tool, const char *cookie) -{ - rnd_toolid_t id; - if (rnd_tool_lookup(tool->name) != RND_TOOLID_INVALID) /* don't register two tools with the same name */ - return -1; - tool->cookie = cookie; - id = rnd_tools.used; - vtp0_append(&rnd_tools, (void *)tool); - if (rnd_gui != NULL) - rnd_gui->reg_mouse_cursor(rnd_gui, id, tool->cursor.name, tool->cursor.pixel, tool->cursor.mask); - rnd_event(NULL, RND_EVENT_TOOL_REG, "p", tool); - return id; -} - -void rnd_tool_unreg_by_cookie(const char *cookie) -{ - rnd_toolid_t n; - for(n = 0; n < vtp0_len(&rnd_tools); n++) { - const rnd_tool_t *tool = (const rnd_tool_t *)rnd_tools.array[n]; - if (tool->cookie == cookie) { - vtp0_remove(&rnd_tools, n, 1); - n--; - } - } -} - -rnd_toolid_t rnd_tool_lookup(const char *name) -{ - rnd_toolid_t n; - for(n = 0; n < vtp0_len(&rnd_tools); n++) { - const rnd_tool_t *tool = (const rnd_tool_t *)rnd_tools.array[n]; - if (strcmp(tool->name, name) == 0) - return n; - } - return RND_TOOLID_INVALID; -} - -int rnd_tool_select_by_name(rnd_hidlib_t *hidlib, const char *name) -{ - rnd_toolid_t id = rnd_tool_lookup(name); - if (id == RND_TOOLID_INVALID) - return -1; - return rnd_tool_select_by_id(hidlib, id); -} - -int rnd_tool_select_by_id(rnd_hidlib_t *hidlib, rnd_toolid_t id) -{ - char id_s[32]; - static rnd_bool recursing = rnd_false; - int ok = 1; - - if ((id < 0) || (id > vtp0_len(&rnd_tools))) - return -1; - - /* protect the cursor while changing the mode - * perform some additional stuff depending on the new mode - * reset 'state' of attached objects - */ - if (recursing) - return -1; - - /* check if the UI logic allows picking that tool */ - rnd_event(hidlib, RND_EVENT_TOOL_SELECT_PRE, "pi", &ok, id); - if (ok == 0) - id = rnd_conf.editor.mode; - - recursing = rnd_true; - - rnd_tool_prev_id = rnd_conf.editor.mode; - rnd_tool_next_id = id; - uninit_current_tool(); - sprintf(id_s, "%d", id); - tool_select_lock = 1; - rnd_conf_set(RND_CFR_DESIGN, "editor/mode", -1, id_s, RND_POL_OVERWRITE); - tool_select_lock = 0; - init_current_tool(); - - recursing = rnd_false; - - if (rnd_gui != NULL) - rnd_gui->set_mouse_cursor(rnd_gui, id); - return 0; -} - -int rnd_tool_select_highest(rnd_hidlib_t *hidlib) -{ - rnd_toolid_t n, bestn = RND_TOOLID_INVALID; - unsigned int bestp = -1; - for(n = 0; n < vtp0_len(&rnd_tools) && (bestp > 0); n++) { - const rnd_tool_t *tool = (const rnd_tool_t *)rnd_tools.array[n]; - if (tool->priority < bestp) { - bestp = tool->priority; - bestn = n; - } - } - if (bestn == RND_TOOLID_INVALID) - return -1; - return rnd_tool_select_by_id(hidlib, bestn); -} - -int rnd_tool_save(rnd_hidlib_t *hidlib) -{ - save_stack[save_position] = rnd_conf.editor.mode; - if (save_position < RND_MAX_MODESTACK_DEPTH - 1) - save_position++; - else - return -1; - return 0; -} - -int rnd_tool_restore(rnd_hidlib_t *hidlib) -{ - if (save_position == 0) { - rnd_message(RND_MSG_ERROR, "hace: underflow of restore mode\n"); - return -1; - } - return rnd_tool_select_by_id(hidlib, save_stack[--save_position]); -} - -void rnd_tool_gui_init(void) -{ - rnd_toolid_t n; - rnd_tool_t **tool; - - if (rnd_gui == NULL) - return; - - for(n = 0, tool = (rnd_tool_t **)rnd_tools.array; n < rnd_tools.used; n++,tool++) - if (*tool != NULL) - rnd_gui->reg_mouse_cursor(rnd_gui, n, (*tool)->cursor.name, (*tool)->cursor.pixel, (*tool)->cursor.mask); -} - -/**** current tool function wrappers ****/ -#define wrap(func, err_ret, prefix, args) \ - do { \ - const rnd_tool_t *tool; \ - if ((rnd_conf.editor.mode < 0) || (rnd_conf.editor.mode >= vtp0_len(&rnd_tools))) \ - { err_ret; } \ - tool = (const rnd_tool_t *)rnd_tools.array[rnd_conf.editor.mode]; \ - if (tool->func == NULL) \ - { err_ret; } \ - prefix tool->func args; \ - } while(0) - -#define wrap_void(func, args) wrap(func, return, ;, args) -#define wrap_retv(func, err_ret, args) wrap(func, err_ret, return, args) - -static void init_current_tool(void) -{ - wrap_void(init, ()); -} - -static void uninit_current_tool(void) -{ - wrap_void(uninit, ()); -} - -void rnd_tool_press(rnd_hidlib_t *hidlib) -{ - wrap_void(press, (hidlib)); -} - -void rnd_tool_release(rnd_hidlib_t *hidlib) -{ - wrap_void(release, (hidlib)); -} - -void rnd_tool_adjust_attached(rnd_hidlib_t *hl) -{ - wrap_void(adjust_attached, (hl)); -} - -void rnd_tool_draw_attached(rnd_hidlib_t *hl) -{ - wrap_void(draw_attached, (hl)); -} - -rnd_bool rnd_tool_undo_act(rnd_hidlib_t *hl) -{ - wrap_retv(undo_act, return rnd_true, (hl)); -} - -rnd_bool rnd_tool_redo_act(rnd_hidlib_t *hl) -{ - wrap_retv(redo_act, return rnd_true, (hl)); -} - -static void do_release(rnd_hidlib_t *hidlib) -{ - if (rnd_conf.temp.click_cmd_entry_active && (rnd_cli_mouse(hidlib, 0) == 0)) - return; - - hidlib->tool_grabbed.status = rnd_false; - - rnd_tool_release(hidlib); - - if (rnd_tool_is_saved) - rnd_tool_restore(hidlib); - rnd_tool_is_saved = rnd_false; - rnd_event(hidlib, RND_EVENT_TOOL_RELEASE, NULL); -} - -void rnd_tool_do_press(rnd_hidlib_t *hidlib) -{ - if (rnd_conf.temp.click_cmd_entry_active && (rnd_cli_mouse(hidlib, 1) == 0)) - return; - - hidlib->tool_grabbed.X = hidlib->tool_x; - hidlib->tool_grabbed.Y = hidlib->tool_y; - - rnd_tool_press(hidlib); - rnd_event(hidlib, RND_EVENT_TOOL_PRESS, NULL); -} - - -static const char rnd_acts_Tool[] = - "Tool(Arc|Arrow|Copy|InsertPoint|Line|Lock|Move|None|PasteBuffer)\n" - "Tool(Poly|Rectangle|Remove|Rotate|Text|Thermal|Via)\n" "Tool(Press|Release|Cancel|Stroke)\n" "Tool(Save|Restore)"; - -static const char rnd_acth_Tool[] = "Change or use the tool mode."; -/* DOC: tool.html */ -static fgw_error_t rnd_act_Tool(fgw_arg_t *res, int argc, fgw_arg_t *argv) -{ - rnd_hidlib_t *hidlib = RND_ACT_HIDLIB; - const char *cmd; - RND_ACT_IRES(0); - RND_ACT_CONVARG(1, FGW_STR, Tool, cmd = argv[1].val.str); - - /* it is okay to use crosshair directly here, the mode command is called from a click when it needs coords */ - hidlib->tool_x = hidlib->ch_x; - hidlib->tool_y = hidlib->ch_y; - rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_false); - if (rnd_strcasecmp(cmd, "Cancel") == 0) { - rnd_tool_select_by_id(RND_ACT_HIDLIB, rnd_conf.editor.mode); - } - else if (rnd_strcasecmp(cmd, "Escape") == 0) { - const rnd_tool_t *t; - escape:; - t = rnd_tool_get(rnd_conf.editor.mode); - if ((t == NULL) || (t->escape == NULL)) { - rnd_tool_select_by_name(RND_ACT_HIDLIB, "arrow"); - hidlib->tool_hit = hidlib->tool_click = 0; /* if the mouse button is still pressed, don't start selecting a box */ - } - else - t->escape(RND_ACT_HIDLIB); - } - else if ((rnd_strcasecmp(cmd, "Press") == 0) || (rnd_strcasecmp(cmd, "Notify") == 0)) { - rnd_tool_do_press(RND_ACT_HIDLIB); - } - else if (rnd_strcasecmp(cmd, "Release") == 0) { - if (rnd_conf.editor.enable_stroke) { - int handled = 0; - rnd_event(RND_ACT_HIDLIB, RND_EVENT_STROKE_FINISH, "p", &handled); - if (handled) { - /* Ugly hack: returning 1 here will break execution of the - action script, so actions after this one could do things - that would be executed only after non-recognized gestures */ - do_release(RND_ACT_HIDLIB); - rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); - return 1; - } - } - do_release(RND_ACT_HIDLIB); - } - else if (rnd_strcasecmp(cmd, "Stroke") == 0) { - if (rnd_conf.editor.enable_stroke) - rnd_event(RND_ACT_HIDLIB, RND_EVENT_STROKE_START, "cc", hidlib->tool_x, hidlib->tool_y); - else - goto escape; /* Right mouse button restarts drawing mode. */ - } - else if (rnd_strcasecmp(cmd, "Restore") == 0) { /* restore the last saved tool */ - rnd_tool_restore(RND_ACT_HIDLIB); - } - else if (rnd_strcasecmp(cmd, "Save") == 0) { /* save currently selected tool */ - rnd_tool_save(RND_ACT_HIDLIB); - } - else { - if (rnd_tool_select_by_name(RND_ACT_HIDLIB, cmd) != 0) - rnd_message(RND_MSG_ERROR, "No such tool: '%s'\n", cmd); - } - rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); - return 0; -} - -static rnd_action_t tool_action_list[] = { - {"Tool", rnd_act_Tool, rnd_acth_Tool, rnd_acts_Tool}, - {"Mode", rnd_act_Tool, rnd_acth_Tool, rnd_acts_Tool} -}; - -void rnd_tool_act_init2(void) -{ - RND_REGISTER_ACTIONS(tool_action_list, NULL); -} - - Index: trunk/src/librnd/core/hid.c =================================================================== --- trunk/src/librnd/core/hid.c (revision 34601) +++ trunk/src/librnd/core/hid.c (nonexistent) @@ -1,99 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * (this file is based on PCB, interactive printed circuit board design) - * Copyright (C) 1994,1995,1996 Thomas Nau - * Copyright (C) 2020 Tibor 'Igor2' Palinkas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Contact: - * Project page: http://repo.hu/projects/pcb-rnd - * lead developer: http://repo.hu/projects/pcb-rnd/contact.html - * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") - * - */ - -#include -#include -#include -#include - -int rnd_hid_enable_per_dialog_hidlib = 0; - -void rnd_hid_notify_crosshair_change(rnd_hidlib_t *hl, rnd_bool changes_complete) -{ - if (rnd_gui->notify_crosshair_change) - rnd_gui->notify_crosshair_change(rnd_gui, changes_complete); - rnd_event(hl, RND_EVENT_CROSSHAIR_MOVE, "i", (int)changes_complete, NULL); -} - -char *(*rnd_hid_fileselect_imp)(rnd_hid_t *hid, const char *title, const char *descr, const char *default_file, const char *default_ext, const rnd_hid_fsd_filter_t *flt, const char *history_tag, rnd_hid_fsd_flags_t flags, rnd_hid_dad_subdialog_t *sub) = NULL; - -char *rnd_hid_fileselect(rnd_hid_t *hid, const char *title, const char *descr, const char *default_file, const char *default_ext, const rnd_hid_fsd_filter_t *flt, const char *history_tag, rnd_hid_fsd_flags_t flags, rnd_hid_dad_subdialog_t *sub) -{ - if ((hid == NULL) || (rnd_hid_fileselect_imp == NULL)) - return NULL; - - return rnd_hid_fileselect_imp(hid, title, descr, default_file, default_ext, flt, history_tag, flags, sub); -} - - -/*** GUI batch timer ***/ - -#define BTMR_REFRESH_TIME_MS 300 - -static int btmr_timer_active = 0; -static rnd_hidval_t btmr_timer; -static rnd_hidlib_t *btmr_hidlib; - -static void btmr_cb(rnd_hidval_t user_data) -{ - btmr_timer_active = 0; - rnd_hid_menu_merge_inhibit_inc(); - rnd_event(btmr_hidlib, RND_EVENT_GUI_BATCH_TIMER, NULL); - rnd_hid_menu_merge_inhibit_dec(); -} - -void rnd_hid_gui_batch_timer(rnd_hidlib_t *hidlib) -{ - rnd_hidval_t timerdata; - - if ((rnd_gui == NULL) || (!rnd_gui->gui)) - return; - - if (btmr_timer_active) { - rnd_gui->stop_timer(rnd_gui, btmr_timer); - btmr_timer_active = 0; - } - - timerdata.ptr = NULL; - btmr_timer = rnd_gui->add_timer(rnd_gui, btmr_cb, BTMR_REFRESH_TIME_MS, timerdata); - btmr_timer_active = 1; - btmr_hidlib = hidlib; -} - -int rnd_hid_get_coords(const char *msg, rnd_coord_t *x, rnd_coord_t *y, int force) -{ - if (rnd_gui == NULL) { - fprintf(stderr, "rnd_hid_get_coords: can not get coordinates (no gui) for '%s'\n", msg); - *x = 0; - *y = 0; - return -1; - } - else - return rnd_gui->get_coords(rnd_gui, msg, x, y, force); -} Index: trunk/src/librnd/core/tool.h =================================================================== --- trunk/src/librnd/core/tool.h (revision 34601) +++ trunk/src/librnd/core/tool.h (nonexistent) @@ -1,139 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * Copyright (C) 2017,2020 Tibor 'Igor2' Palinkas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact: - * Project page: http://repo.hu/projects/pcb-rnd - * lead developer: http://repo.hu/projects/pcb-rnd/contact.html - * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") - */ - -#ifndef RND_TOOL_H -#define RND_TOOL_H - -#include - -#include -#include - -typedef int rnd_toolid_t; -#define RND_TOOLID_INVALID (-1) - -typedef struct rnd_tool_cursor_s { - const char *name; /* if no custom graphics is provided, use a stock cursor by name */ - const unsigned char *pixel; /* 32 bytes: 16*16 bitmap */ - const unsigned char *mask; /* 32 bytes: 16*16 mask (1 means draw pixel) */ -} rnd_tool_cursor_t; - -#define RND_TOOL_CURSOR_NAMED(name) { name, NULL, NULL } -#define RND_TOOL_CURSOR_XBM(pixel, mask) { NULL, pixel, mask } - -typedef enum rnd_tool_flags_e { - RND_TLF_AUTO_TOOLBAR = 1 /* automatically insert in the toolbar if the menu file didn't do it */ -} rnd_tool_flags_t; - -typedef struct rnd_tool_s { - const char *name; /* textual name of the tool */ - const char *help; /* help/tooltip that explains the feature */ - const char *cookie; /* plugin cookie _pointer_ of the registrar (comparision is pointer based, not strcmp) */ - unsigned int priority; /* lower values are higher priorities; escaping mode will try to select the highest prio tool */ - const char **icon; /* XPM for the tool buttons */ - rnd_tool_cursor_t cursor; /* name of the mouse cursor to switch to when the tool is activated */ - rnd_tool_flags_t flags; - - /* tool implementation */ - void (*init)(void); - void (*uninit)(void); - void (*press)(rnd_hidlib_t *hl); - void (*release)(rnd_hidlib_t *hl); - void (*adjust_attached)(rnd_hidlib_t *hl); - void (*draw_attached)(rnd_hidlib_t *hl); - rnd_bool (*undo_act)(rnd_hidlib_t *hl); - rnd_bool (*redo_act)(rnd_hidlib_t *hl); - void (*escape)(rnd_hidlib_t *hl); - - unsigned long user_flags; - - /* Spare: see doc/developer/spare.txt */ - void (*spare_f1)(void), (*spare_f2)(void); - long spare_l1, spare_l2, spare_l3, spare_l4; - void *spare_p1, *spare_p2, *spare_p3, *spare_p4; - double spare_d1, spare_d2, spare_d3, spare_d4; - rnd_coord_t spare_c1, spare_c2, spare_c3, spare_c4; -} rnd_tool_t; - -extern vtp0_t rnd_tools; -extern rnd_toolid_t rnd_tool_prev_id; -extern rnd_toolid_t rnd_tool_next_id; -extern rnd_bool rnd_tool_is_saved; - -/* (un)initialize the tool subsystem */ -void rnd_tool_init(void); -void rnd_tool_uninit(void); - -/* call this when the mode (tool) config node changes */ -void rnd_tool_chg_mode(rnd_hidlib_t *hl); - -/* Insert a new tool in rnd_tools; returns -1 on failure */ -rnd_toolid_t rnd_tool_reg(rnd_tool_t *tool, const char *cookie); - -/* Unregister all tools that has matching cookie */ -void rnd_tool_unreg_by_cookie(const char *cookie); - -/* Return the ID of a tool by name; returns -1 on error */ -rnd_toolid_t rnd_tool_lookup(const char *name); - - -/* Select a tool by name, id or pick the highest prio tool; return 0 on success */ -int rnd_tool_select_by_name(rnd_hidlib_t *hidlib, const char *name); -int rnd_tool_select_by_id(rnd_hidlib_t *hidlib, rnd_toolid_t id); -int rnd_tool_select_highest(rnd_hidlib_t *hidlib); - -int rnd_tool_save(rnd_hidlib_t *hidlib); -int rnd_tool_restore(rnd_hidlib_t *hidlib); - -/* Called after GUI_INIT; registers all mouse cursors in the GUI */ -void rnd_tool_gui_init(void); - - -/**** Tool function wrappers; calling these will operate on the current tool - as defined in rnd_conf.editor.mode ****/ - -void rnd_tool_press(rnd_hidlib_t *hidlib); -void rnd_tool_release(rnd_hidlib_t *hidlib); -void rnd_tool_adjust_attached(rnd_hidlib_t *hl); -void rnd_tool_draw_attached(rnd_hidlib_t *hl); -rnd_bool rnd_tool_undo_act(rnd_hidlib_t *hl); -rnd_bool rnd_tool_redo_act(rnd_hidlib_t *hl); - - -/* fake a click */ -void rnd_tool_do_press(rnd_hidlib_t *hidlib); - -/**** Low level, for internal use ****/ - -/* Get the tool pointer of a tool by id */ -RND_INLINE const rnd_tool_t *rnd_tool_get(long id) -{ - rnd_tool_t **tp = (rnd_tool_t **)vtp0_get(&rnd_tools, id, 0); - if (tp == NULL) return NULL; - return *tp; -} - -#endif Index: trunk/src/librnd/core/hid.h =================================================================== --- trunk/src/librnd/core/hid.h (revision 34601) +++ trunk/src/librnd/core/hid.h (nonexistent) @@ -1,696 +0,0 @@ -#ifndef RND_HID_H -#define RND_HID_H - -#include -#include -#include - -#include -#include -#include -#include - -/* attribute dialog properties */ -typedef enum rnd_hat_property_e { - RND_HATP_GLOBAL_CALLBACK, - RND_HATP_max -} rnd_hat_property_t; - - -typedef enum { - RND_HID_MOUSE_PRESS, - RND_HID_MOUSE_RELEASE, - RND_HID_MOUSE_MOTION, - RND_HID_MOUSE_POPUP /* "right click", open context-specific popup */ -} rnd_hid_mouse_ev_t; - -/* Human Interface Device */ - -/* - -The way the HID layer works is that you instantiate a HID device -structure, and invoke functions through its members. Code in the -pcb-rnd core may *not* rely on HID internals (*anything* other than what's -defined in this file). Code in the HID layers *may* rely on data and -functions in hidlib (like, design size and such), but not on anything -in application core. - -Coordinates are ALWAYS in pcb's internal units rnd_coord_t. Positive X is -right, positive Y is down, unless flip is activated. Angles are -degrees, with 0 being right (positive X) and 90 being up (negative Y) - unless -flip is activated. All zoom, scaling, panning, and conversions are hidden -inside the HIDs. - -The main structure is rnd_hid_t. -*/ - -/* Line end cap styles. The cap *always* extends beyond the - coordinates given, by half the width of the line. */ -typedef enum { - rnd_cap_invalid = -1, - rnd_cap_square, /* square pins or pads when drawn using a line */ - rnd_cap_round /* for normal traces, round pins */ -} rnd_cap_style_t; - -/* The HID may need something more than an "int" for colors, timers, - etc. So it passes/returns one of these, which is castable to a - variety of things. */ -typedef union { - long lval; - void *ptr; -} rnd_hidval_t; - -typedef struct { - rnd_coord_t width; /* as set by set_line_width */ - rnd_cap_style_t cap; /* as set by set_line_cap */ - int xor; /* as set by set_draw_xor */ - int faded; /* as set by set_draw_faded */ - rnd_hid_t *hid; /* the HID that owns this gc */ - - - /* Spare: see doc/developer/spare.txt */ - void (*spare_f1)(void), (*spare_f2)(void); - long spare_l1, spare_l2, spare_l3, spare_l4; - void *spare_p1, *spare_p2, *spare_p3, *spare_p4; - double spare_d1, spare_d2, spare_d3, spare_d4; - rnd_coord_t spare_c1, spare_c2, spare_c3, spare_c4; -} rnd_core_gc_t; - - -#define RND_HIDCONCAT(a,b) a##b - -/* File Watch flags */ -/* Based upon those in dbus/dbus-connection.h */ -typedef enum { - RND_WATCH_READABLE = 1 << 0, /* As in POLLIN */ - RND_WATCH_WRITABLE = 1 << 1, /* As in POLLOUT */ - RND_WATCH_ERROR = 1 << 2, /* As in POLLERR */ - RND_WATCH_HANGUP = 1 << 3 /* As in POLLHUP */ -} rnd_watch_flags_t; - -typedef enum rnd_composite_op_s { - RND_HID_COMP_RESET, /* reset (allocate and clear) the sketch canvas */ - RND_HID_COMP_POSITIVE, /* draw subsequent objects in positive, with color, no XOR allowed */ - RND_HID_COMP_POSITIVE_XOR, /* draw subsequent objects in positive, with color, XOR allowed */ - RND_HID_COMP_NEGATIVE, /* draw subsequent objects in negative, ignore color */ - RND_HID_COMP_FLUSH /* combine the sketch canvas onto the output buffer and discard the sketch canvas */ -} rnd_composite_op_t; - -typedef enum rnd_burst_op_s { - RND_HID_BURST_START, - RND_HID_BURST_END -} rnd_burst_op_t; - -typedef enum rnd_hid_attr_ev_e { - RND_HID_ATTR_EV_WINCLOSE = 2, /* window closed (window manager close) */ - RND_HID_ATTR_EV_CODECLOSE /* closed by the code, including standard close buttons */ -} rnd_hid_attr_ev_t; - -typedef enum rnd_hid_fsd_flags_e { /* bitwise OR, used by file selection dialog (fsd) */ - RND_HID_FSD_READ = 1 /* when set let the user pick existing files only ("load"); if unset, both esiting and non-existing files are accepted */ -} rnd_hid_fsd_flags_t; - -typedef struct { - const char *name; - const char *mime; - const char **pat; /* NULL terminated array of file name patterns */ - - /* Spare: see doc/developer/spare.txt */ - void (*spare_f1)(void), (*spare_f2)(void); - long spare_l1, spare_l2, spare_l3, spare_l4; - void *spare_p1, *spare_p2; - double spare_d1, spare_d2; - rnd_coord_t spare_c1, spare_c2; -} rnd_hid_fsd_filter_t; - -extern const rnd_hid_fsd_filter_t rnd_hid_fsd_filter_any[]; - -/* Optional fields of a menu item; all non-NULL fields are strdup'd in the HID. */ -typedef struct rnd_menu_prop_s { - const char *action; - const char *accel; - const char *tip; /* tooltip */ - const char *checked; - const char *update_on; - const rnd_color_t *foreground; - const rnd_color_t *background; - const char *cookie; /* used for cookie based removal */ - - /* Spare: see doc/developer/spare.txt */ - long spare_l1, spare_l2, spare_l3, spare_l4; - void *spare_p1, *spare_p2, *spare_p3, *spare_p4; -} rnd_menu_prop_t; - -typedef enum rnd_hid_clipfmt_e { - RND_HID_CLIPFMT_TEXT /* plain text (c string with the \0 included) */ -} rnd_hid_clipfmt_t; - -typedef enum { - RND_HID_DOCK_TOP_LEFT, /* hbox on the top, below the menubar */ - RND_HID_DOCK_TOP_RIGHT, /* hbox on the top, next to the menubar */ - RND_HID_DOCK_TOP_INFOBAR, /* vbox for horizontally aligned important messages, above ("on top of") the drawing area for critical warnings - may have bright background color */ - RND_HID_DOCK_LEFT, - RND_HID_DOCK_BOTTOM, - RND_HID_DOCK_FLOAT, /* separate window */ - - RND_HID_DOCK_max -} rnd_hid_dock_t; - -extern int rnd_dock_is_vert[RND_HID_DOCK_max]; /* 1 if a new dock box (parent of a new sub-DAD) should be a vbox, 0 if hbox */ -extern int rnd_dock_has_frame[RND_HID_DOCK_max]; /* 1 if a new dock box (parent of a new sub-DAD) should be framed */ - -typedef enum rnd_set_crosshair_e { - RND_SC_DO_NOTHING = 0, - RND_SC_WARP_POINTER, - RND_SC_PAN_VIEWPORT -} rnd_set_crosshair_t; - -/* This is the main HID structure. */ -struct rnd_hid_s { - /* The size of this structure. We use this as a compatibility - check; a HID built with a different hid.h than we're expecting - should have a different size here. */ - int struct_size; - - /* The name of this HID. This should be suitable for - command line options, multi-selection menus, file names, - etc. */ - const char *name; - - /* Likewise, but allowed to be longer and more descriptive. */ - const char *description; - - /* If set, this is the GUI HID. Exactly one of these three flags - must be set; setting "gui" lets the expose callback optimize and - coordinate itself. */ - unsigned gui:1; - - /* If set, this is the printer-class HID. The application - may use this to do command-line printing, without having - instantiated any GUI HIDs. Only one printer HID is normally - defined at a time. */ - unsigned printer:1; - - /* If set, this HID provides an export option, and should be used as - part of the File->Export menu option. Examples are PNG, Gerber, - and EPS exporters. */ - unsigned exporter:1; - - /* Export plugin should not be listed in the export dialog; GUI plugin - should not be auto-selected */ - unsigned hide_from_gui:1; - - /* If set, draw the mask layer inverted. Normally the mask is a filled - rectangle over the design with cutouts at pins/pads. The HIDs - use render in normal mode, gerber renders in inverse mode. */ - unsigned mask_invert:1; - - /* Always draw layers in compositing mode - no base layer */ - unsigned force_compositing:1; - - /* When enabled, indicate layer of heavy terminals graphically */ - unsigned heavy_term_layer_ind:1; - - /* When 1, HID supports markup (e.g. color) in DAD text widgets */ - unsigned supports_dad_text_markup:1; - - /* it is possible to create DAD dialogs before the GUI_INIT event is emitted - (e.g. draw progress bar while loading a command line file) */ - unsigned allow_dad_before_init:1; - - /* when 1 and this hid is rnd_render, do not change rnd_render even if an export plugin or GUI is calling the render code */ - unsigned override_render:1; - - /* called by core when the global hidlib context changes (e.g. design changed) - The HID should store the hidlib pointer for knowing drawing area dimensions */ - void (*set_hidlib)(rnd_hid_t *hid, rnd_hidlib_t *hidlib); - - /* Return the hidlib the given GUI HID is currently showing - (not implemented in export HIDs) */ - rnd_hidlib_t *(*get_hidlib)(rnd_hid_t *hid); - - /* Returns a set of resources describing options the export or print - HID supports. In GUI mode, the print/export dialogs use this to - set up the selectable options. In command line mode, these are - used to interpret command line options. If n_ret_ is non-NULL, - the number of attributes is stored there. Note: the table is read-only - and persistent. */ - const rnd_export_opt_t *(*get_export_options)(rnd_hid_t *hid, int *n_ret); - - /* Exports (or print) the current design. The options given represent - the choices made from the options returned from - get_export_options. Call with options_ == NULL to start the - primary GUI (create a main window, print, export, etc) */ - void (*do_export)(rnd_hid_t *hid, rnd_hid_attr_val_t *options); - - /* Export plugins: if not NULL, rnd_hid_parse_command_line() sets up opt - value backing memory from this array */ - rnd_hid_attr_val_t *argument_array; - - /* uninit a GUI hid */ - void (*uninit)(rnd_hid_t *hid); - - /* uninit a GUI hid */ - void (*do_exit)(rnd_hid_t *hid); - - /* Process pending events, flush output, but never block. Called from busy - loops from time to time. */ - void (*iterate)(rnd_hid_t *hid); - - /* Parses the command line. Call this early for whatever HID will be - the primary HID, as it will set all the registered attributes. - The HID should remove all arguments, leaving any possible file - names behind. Returns 0 on success, positive for recoverable errors - (no change in argc or argv) and negative for unrecoverable errors. */ - int (*parse_arguments)(rnd_hid_t *hid, int *argc, char ***argv); - - /* This may be called to ask the GUI to force a redraw of a given area */ - void (*invalidate_lr)(rnd_hid_t *hid, rnd_coord_t left, rnd_coord_t right, rnd_coord_t top, rnd_coord_t bottom); - void (*invalidate_all)(rnd_hid_t *hid); - void (*notify_crosshair_change)(rnd_hid_t *hid, rnd_bool changes_complete); - void (*notify_mark_change)(rnd_hid_t *hid, rnd_bool changes_complete); - - /* During redraw or print/export cycles, this is called once per layer group - (physical layer); pusrpose/purpi are the extracted purpose field and its - keyword/function version; layer is the first layer in the group. - TODO: The group may be -1 until the layer rewrite is finished. - If it returns false (zero), the HID does not want that layer, and none of - the drawing functions should be called. If it returns rnd_true (nonzero), - the items in that layer [group] should be drawn using the various drawing - functions. In addition to the copper layer groups, you may select virtual - layers. The is_empty argument is a hint - if set, the layer is empty, if - zero it may be non-empty. */ - int (*set_layer_group)(rnd_hid_t *hid, rnd_layergrp_id_t group, const char *purpose, int purpi, rnd_layer_id_t layer, unsigned int flags, int is_empty, rnd_xform_t **xform); - - /* Tell the GUI the layer last selected has been finished with. */ - void (*end_layer)(rnd_hid_t *hid); - - /*** Drawing Functions. ***/ - - /* Make an empty gc (graphics context, which is like a pen). */ - rnd_hid_gc_t (*make_gc)(rnd_hid_t *hid); - void (*destroy_gc)(rnd_hid_gc_t gc); - - /* Composite layer drawing: manipulate the sketch canvas and set - positive or negative drawing mode. The canvas covers the screen box. */ - void (*set_drawing_mode)(rnd_hid_t *hid, rnd_composite_op_t op, rnd_bool direct, const rnd_box_t *screen); - - /* Announce start/end of a render burst for a specific screen screen box; - A GUI hid should set the coord_per_pix value here for proper optimization. */ - void (*render_burst)(rnd_hid_t *hid, rnd_burst_op_t op, const rnd_box_t *screen); - - /*** gc vs. rnd_hid_t *: rnd_core_gc_t contains ->hid, so these calls don't - need to get it as first arg. ***/ - - /* Sets a color. Can be one of the special colors like rnd_color_drill. - (Always use the drill color to draw holes and slots). - You may assume this is cheap enough to call inside the redraw - callback, but not cheap enough to call for each item drawn. */ - void (*set_color)(rnd_hid_gc_t gc, const rnd_color_t *color); - - /* Sets the line style. While calling this is cheap, calling it with - different values each time may be expensive, so grouping items by - line style is helpful. */ - void (*set_line_cap)(rnd_hid_gc_t gc, rnd_cap_style_t style); - void (*set_line_width)(rnd_hid_gc_t gc, rnd_coord_t width); - void (*set_draw_xor)(rnd_hid_gc_t gc, int xor); - /* Blends 20% or so color with 80% background. Only used for - assembly drawings so far. */ - void (*set_draw_faded)(rnd_hid_gc_t gc, int faded); - - /* The usual drawing functions. "draw" means to use segments of the - given width, whereas "fill" means to fill to a zero-width - outline. */ - void (*draw_line)(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2); - void (*draw_arc)(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t xradius, rnd_coord_t yradius, rnd_angle_t start_angle, rnd_angle_t delta_angle); - void (*draw_rect)(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2); - void (*fill_circle)(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius); - void (*fill_polygon)(rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y); - void (*fill_polygon_offs)(rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y, rnd_coord_t dx, rnd_coord_t dy); - void (*fill_rect)(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2); - - void (*draw_pixmap)(rnd_hid_t *hid, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t sx, rnd_coord_t sy, rnd_pixmap_t *pixmap); - void (*uninit_pixmap)(rnd_hid_t *hid, rnd_pixmap_t *pixmap); - - /*** GUI layout functions. Not used or defined for print/export HIDs. ***/ - - /* Temporary */ - int (*shift_is_pressed)(rnd_hid_t *hid); - int (*control_is_pressed)(rnd_hid_t *hid); - int (*mod1_is_pressed)(rnd_hid_t *hid); - - /* Returns 0 on success, -1 on esc pressed */ - int (*get_coords)(rnd_hid_t *hid, const char *msg, rnd_coord_t *x, rnd_coord_t *y, int force); - - /* Sets the crosshair, which may differ from the pointer depending - on grid and pad snap. Note that the HID is responsible for - hiding, showing, redrawing, etc. The core just tells it what - coordinates it's actually using. Note that this routine may - need to know what "pcb units" are so it can display them in mm - or mils accordingly. If cursor_action_ is set, the cursor or - screen may be adjusted so that the cursor and the crosshair are - at the same point on the screen. */ - void (*set_crosshair)(rnd_hid_t *hid, rnd_coord_t x, rnd_coord_t y, rnd_set_crosshair_t cursor_action); - - /* Causes func to be called at some point in the future. Timers are - only good for *one* call; if you want it to repeat, add another - timer during the callback for the first. user_data_ can be - anything, it's just passed to func. Times are not guaranteed to - be accurate. */ - rnd_hidval_t (*add_timer)(rnd_hid_t *hid, void (*func)(rnd_hidval_t user_data), unsigned long milliseconds, rnd_hidval_t user_data); - /* Use this to stop a timer that hasn't triggered yet. */ - void (*stop_timer)(rnd_hid_t *hid, rnd_hidval_t timer); - - /* Causes func_ to be called when some condition occurs on the file - descriptor passed. Conditions include data for reading, writing, - hangup, and errors. user_data_ can be anything, it's just passed - to func. If the watch function returns rnd_true, the watch is kept, else - it is removed. */ - rnd_hidval_t (*watch_file)(rnd_hid_t *hid, int fd, unsigned int condition, rnd_bool (*func)(rnd_hidval_t watch, int fd, unsigned int condition, rnd_hidval_t user_data), rnd_hidval_t user_data); - - /* Use this to stop a file watch; must not be called from within a GUI callback! */ - void (*unwatch_file)(rnd_hid_t *hid, rnd_hidval_t watch); - - - - /* A generic dialog to ask for a set of attributes. If n_attrs_ is - zero, attrs_(.name) must be NULL terminated. attr_dlg_run returns - non-zero if an error occurred (usually, this means the user cancelled - the dialog or something). title is the title of the dialog box - The HID may choose to ignore it or it may use it for a tooltip or - text in a dialog box, or a help string. Id is used in some events (e.g. - for window placement) and is strdup'd. If defx and defy are larger than 0, - they are hints for the default (starting) window size - can be overridden - by window placement. Returns opaque hid_ctx. - (Hid_ctx shall save rnd_hid_t so subsequent attr_dlg_*() calls don't have - it as an argument) */ - void *(*attr_dlg_new)(rnd_hid_t *hid, const char *id, rnd_hid_attribute_t *attrs, int n_attrs, const char *title, void *caller_data, rnd_bool modal, void (*button_cb)(void *caller_data, rnd_hid_attr_ev_t ev), int defx, int defy, int minx, int miny); - int (*attr_dlg_run)(void *hid_ctx); - void (*attr_dlg_raise)(void *hid_ctx); /* raise the window to top */ - void (*attr_dlg_close)(void *hid_ctx); /* close the GUI but do not yet free hid_ctx (results should be available) */ - void (*attr_dlg_free)(void *hid_ctx); - - /* Set a property of an attribute dialog (typical call is between - attr_dlg_new() and attr_dlg_run()) */ - void (*attr_dlg_property)(void *hid_ctx, rnd_hat_property_t prop, const rnd_hid_attr_val_t *val); - - - /* Disable or enable a widget of an active attribute dialog; if enabled is - 2, the widget is put to its second enabled mode (pressed state for buttons, highlight on label) */ - int (*attr_dlg_widget_state)(void *hid_ctx, int idx, int enabled); - - /* hide or show a widget of an active attribute dialog */ - int (*attr_dlg_widget_hide)(void *hid_ctx, int idx, rnd_bool hide); - - /* Changes state of widget at idx. Returns 0 on success. Meaning of - arguments is widgets-specific. */ - int (*attr_dlg_widget_poke)(void *hid_ctx, int idx, int argc, fgw_arg_t argv[]); - - /* Change the current value of a widget; same as if the user chaged it, - except the value-changed callback is inhibited */ - int (*attr_dlg_set_value)(void *hid_ctx, int idx, const rnd_hid_attr_val_t *val); - - /* Change the help text (tooltip) string of a widget; NULL means remove it. - NOTE: does _not_ change the help_text field of the attribute. */ - void (*attr_dlg_set_help)(void *hid_ctx, int idx, const char *val); - - /* top window docking: enter a new docked part by registering a - new subdialog or leave (remove a docked part) from a subdialog. Return 0 - on success. */ - int (*dock_enter)(rnd_hid_t *hid, rnd_hid_dad_subdialog_t *sub, rnd_hid_dock_t where, const char *id); - void (*dock_leave)(rnd_hid_t *hid, rnd_hid_dad_subdialog_t *sub); - - /* Something to alert the user. */ - void (*beep)(rnd_hid_t *hid); - - /* Removes a menu recursively */ - int (*remove_menu_node)(rnd_hid_t *hid, lht_node_t *nd); - - /* At the moment HIDs load the menu file. Some plugin code, like the toolbar - code needs to traverse the menu tree too. This call exposes the - HID-internal menu struct */ - rnd_hid_cfg_t *(*get_menu_cfg)(rnd_hid_t *hid); - - /* Update the state of all checkboxed menus whose lihata - node cookie matches cookie (or all checkboxed menus globally if cookie - is NULL) */ - void (*update_menu_checkbox)(rnd_hid_t *hid, const char *cookie); - - /* Creates a new menu or submenu from an existing (already merged) lihata node */ - int (*create_menu_by_node)(rnd_hid_t *hid, int is_popup, const char *name, int is_main, lht_node_t *parent, lht_node_t *ins_after, lht_node_t *menu_item); - - /* Pointer to the hid's configuration - useful for plugins and core wanting to install menus at anchors */ - rnd_hid_cfg_t *menu; - - - /* Optional: print usage string (if accepts command line arguments) - Subtopic: - NULL print generic help - string print summary for the topic in string - Return 0 on success. - */ - int (*usage)(rnd_hid_t *hid, const char *subtopic); - - - /* Optional: change cursor to indicate if an object is grabbed (or not) */ - void (*point_cursor)(rnd_hid_t *hid, rnd_bool grabbed); - - /* Optional: when non-zero, the core renderer may decide to draw cheaper - (simplified) approximation of some objects that would end up being too - small. For a GUI, this should depend on the zoom level */ - rnd_coord_t coord_per_pix; - - /* If ovr is not NULL: - - overwrite the command etry with ovr - - if cursor is not NULL, set the cursor after the overwrite - If ovr is NULL: - - if cursor is not NULL, load the value with the cursor (or -1 if not supported) - Return the current command entry content in a read-only string */ - const char *(*command_entry)(rnd_hid_t *hid, const char *ovr, int *cursor); - - /*** clipboard handling for GUI HIDs ***/ - /* Place format/data/len on the clipboard; return 0 on success */ - int (*clip_set)(rnd_hid_t *hid, rnd_hid_clipfmt_t format, const void *data, size_t len); - - /* retrieve format/data/len from the clipboard; return 0 on success; - data is a copy of the data, modifiable by the caller */ - int (*clip_get)(rnd_hid_t *hid, rnd_hid_clipfmt_t *format, void **data, size_t *len); - - /* release the data from the last clip_get(); clip_get() and clip_free() should - be called in pair */ - void (*clip_free)(rnd_hid_t *hid, rnd_hid_clipfmt_t format, void *data, size_t len); - - /* run redraw-benchmark and return an FPS value (optional) */ - double (*benchmark)(rnd_hid_t *hid); - - /* (rnd_hid_cfg_keys_t *): key state */ - void *key_state; - - /*** zoom/pan calls ***/ - - /* side-correct zoom to show a window of the design. If set_crosshair - is true, also update the crosshair to be on the center of the window */ - void (*zoom_win)(rnd_hid_t *hid, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2, rnd_bool set_crosshair); - - /* Zoom relative or absolute by factor; relative means current zoom is - multiplied by factor */ - void (*zoom)(rnd_hid_t *hid, rnd_coord_t center_x, rnd_coord_t center_y, double factor, int relative); - - /* Pan relative/absolute by x and y; relative means x and y are added to - the current pan */ - void (*pan)(rnd_hid_t *hid, rnd_coord_t x, rnd_coord_t y, int relative); - - /* Start or stop panning at x;y - stop is mode=0, start is mode=1 */ - void (*pan_mode)(rnd_hid_t *hid, rnd_coord_t x, rnd_coord_t y, rnd_bool mode); - - /* Load viewbox with the extents of visible pixels translated to design coords */ - void (*view_get)(rnd_hid_t *hid, rnd_box_t *viewbox); - - /*** misc GUI ***/ - /* Open the command line */ - void (*open_command)(rnd_hid_t *hid); - - /* Open a popup menu addressed by full menu path (starting with "/popups/"). - Return 0 on success. */ - int (*open_popup)(rnd_hid_t *hid, const char *menupath); - - - /* Change the mouse cursor to a named cursor e.g. after the tool has changed. - The list of cursors names available may depend on the HID. */ - void (*reg_mouse_cursor)(rnd_hid_t *hid, int idx, const char *name, const unsigned char *pixel, const unsigned char *mask); - void (*set_mouse_cursor)(rnd_hid_t *hid, int idx); - - /* change top window title any time the after the GUI_INIT event */ - void (*set_top_title)(rnd_hid_t *hid, const char *title); - - /* OPTIONAL: override the mouse cursor to indicate busy state */ - void (*busy)(rnd_hid_t *hid, rnd_bool busy); - - /* this field is used by that HID implementation to store its data */ - void *hid_data; - - /* convert hid_ctx into hidlib ptr; only valid within a DAD callback. This - is different from ->get_hidlib because this returns the hidlib associated - with the dialog, which (for multi-instance local dialogs) may be different - from the hidlib what's currently show by the GUI */ - rnd_hidlib_t *(*get_dad_hidlib)(void *hid_ctx); - - /*** (these should be upper, but the struct has to be extended at spares - for binary compatibility) ***/ - - /* Spare: see doc/developer/spare.txt */ - void (*spare_f1)(void), (*spare_f2)(void), (*spare_f3)(void), (*spare_f4)(void), (*spare_f5)(void), (*spare_f6)(void); - long spare_l1, spare_l2, spare_l3, spare_l4, spare_l5, spare_l6, spare_l7, spare_l8; - void *spare_p1, *spare_p2, *spare_p3, *spare_p4, *spare_p5, *spare_p6; - double spare_d1, spare_d2, spare_d3, spare_d4, spare_d5, spare_d6; - rnd_coord_t spare_c1, spare_c2, spare_c3, spare_c4; -}; - -typedef void (*rnd_hid_expose_cb_t)(rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e); - -struct rnd_hid_expose_ctx_s { - rnd_box_t view; - rnd_hid_expose_cb_t expose_cb; /* function that is called on expose to get things drawn */ - void *draw_data; /* user data for the expose function */ - - /* Spare: see doc/developer/spare.txt */ - void (*spare_f1)(void), (*spare_f2)(void); - long spare_l1, spare_l2, spare_l3, spare_l4; - void *spare_p1, *spare_p2, *spare_p3, *spare_p4; - double spare_d1, spare_d2, spare_d3, spare_d4; - rnd_coord_t spare_c1, spare_c2, spare_c3, spare_c4; -}; - -typedef void (*rnd_hid_expose_t)(rnd_hid_t *hid, const rnd_hid_expose_ctx_t *ctx); - -/* This is initially set to a "no-gui" GUI, and later reset by - main. It is used for on-screen GUI calls, such as dialog boxes */ -extern rnd_hid_t *rnd_gui; - -/* This is initially set to a "no-gui" GUI, and later reset by - main. hid_expose_callback also temporarily set it for drawing. Normally - matches rnd_gui, but is temporarily changed while exporting. It is used - for drawing calls, mainly by draw*.c */ -extern rnd_hid_t *rnd_render; - -/* This is either NULL or points to the current HID that is being called to - do the exporting. The GUI HIDs set and unset this var.*/ -extern rnd_hid_t *rnd_exporter; - -/* This is either NULL or points to the current rnd_action_t that is being - called. The action launcher sets and unsets this variable. */ -extern const rnd_action_t *rnd_current_action; - -/* The GUI may set this to be approximately the physical size of a pixel, - to allow for near-misses in selection and changes in drawing items - smaller than a screen pixel. */ -extern int rnd_pixel_slop; - -/*** Glue for GUI/CLI dialogs: wrappers around actions */ - -/* Prompts the user to enter a string, returns the string. If - default_string isn't NULL, the form is pre-filled with this - value. "msg" is printed above the query. The optional title - is the window title. - Returns NULL on cancel. The caller needs to free the returned string */ -char *rnd_hid_prompt_for(rnd_hidlib_t *hl, const char *msg, const char *default_string, const char *title); - -/* Present a dialog box with a message and variable number of buttons. If icon - is not NULL, attempt to draw the named icon on the left. The vararg part is - one or more buttons, as a list of "char *label, int retval", terminated with - NULL. */ -int rnd_hid_message_box(rnd_hidlib_t *hl, const char *icon, const char *title, const char *label, ...); - -/* Show modal progressbar to the user, offering cancel long running processes. - Pass all zeros to flush display and remove the dialog. - Returns nonzero if the user wishes to cancel the operation. */ -int rnd_hid_progress(long so_far, long total, const char *message); - -/* non-zero if DAD dialogs are available currently */ -#define RND_HAVE_GUI_ATTR_DLG \ - ((rnd_gui != NULL) && (rnd_gui->gui) && (rnd_gui->attr_dlg_new != NULL) && (rnd_gui->attr_dlg_new != rnd_nogui_attr_dlg_new)) -void *rnd_nogui_attr_dlg_new(rnd_hid_t *hid, const char *id, rnd_hid_attribute_t *attrs_, int n_attrs_, const char *title_, void *caller_data, rnd_bool modal, void (*button_cb)(void *caller_data, rnd_hid_attr_ev_t ev), int defx, int defy, int minx, int miny); - -int rnd_hid_dock_enter(rnd_hid_dad_subdialog_t *sub, rnd_hid_dock_t where, const char *id); -void rnd_hid_dock_leave(rnd_hid_dad_subdialog_t *sub); - -#define rnd_hid_redraw(pcb) rnd_gui->invalidate_all(rnd_gui) - -#define rnd_hid_busy(pcb, is_busy) \ -do { \ - rnd_event(&pcb->hidlib, RND_EVENT_BUSY, "i", is_busy, NULL); \ - if ((rnd_gui != NULL) && (rnd_gui->busy != NULL)) \ - rnd_gui->busy(rnd_gui, is_busy); \ -} while(0) - - -/* Notify the GUI that data relating to the crosshair is being changed. - * - * The argument passed is rnd_false to notify "changes are about to happen", - * and rnd_true to notify "changes have finished". - * - * Each call with a 'rnd_false' parameter must be matched with a following one - * with a 'rnd_true' parameter. Unmatched 'rnd_true' calls are currently not permitted, - * but might be allowed in the future. - * - * GUIs should not complain if they receive extra calls with 'rnd_true' as parameter. - * They should initiate a redraw of the crosshair attached objects - which may - * (if necessary) mean repainting the whole screen if the GUI hasn't tracked the - * location of existing attached drawing. */ -void rnd_hid_notify_crosshair_change(rnd_hidlib_t *hl, rnd_bool changes_complete); - -/* Plugin helper: timed batch updates; any plugin may trigger the update, multiple - triggers are batched and only a single RND_EVENT_GUI_BATCH_TIMER is emitted - after a certain time passed since the last trigger. The event is emitted - with the last hidlib argument passed. If there's no GUI available, no event - is emitted. */ -void rnd_hid_gui_batch_timer(rnd_hidlib_t *hidlib); - - /* Run the file selection dialog. Return a string the caller needs to free(). - * title may be used as a dialog box title. Ignored if NULL. - * - * descr is a longer help string. Not used at the moment. Ignored if NULL. - * - * default_file is the default file name. Ignored if NULL. - * - * default_ext is the default file extension, like ".pdf". - * Ignored if NULL. - * - * flt is a {NULL} terminated array of file filters; HID support is optional. - * Ignored if NULL. If NULL and default_ext is not NULL, the HID may make - * up a minimalistic filter from the default_ext also allowing *.*. - * - * history_tag may be used by the GUI to keep track of file - * history. Examples would be "board", "vendor", "renumber", - * etc. If NULL, no specific history is kept. - * - * flags_ are the bitwise OR - * - * sub is an optional DAD sub-dialog, can be NULL; its parent_poke commands: - * close close the dialog - * get_path returns the current full path in res as an strdup'd string (caller needs to free it) - * set_file_name replaces the file name portion of the current path from arg[0].d.s - */ -char *rnd_hid_fileselect(rnd_hid_t *hid, const char *title, const char *descr, const char *default_file, const char *default_ext, const rnd_hid_fsd_filter_t *flt, const char *history_tag, rnd_hid_fsd_flags_t flags, rnd_hid_dad_subdialog_t *sub); - - -/* temporary, will be removed in 4.0.0 where it will become hardwired 1: - if set to 1, enable each DAD dialog remembering their own hid; when 0, - ->get_dad_hidlib() returns the same hid-global "currently displayed" - value as ->get_hidlib(); 0 is the default, old, pre-4.0.0 behavior */ -extern int rnd_hid_enable_per_dialog_hidlib; - -/* Actual implementation of rnd_hid_fileselect(); registered by the plugin - that implements file selection (typically lib_hid_common). The reason - for this abstraction is that we do not need to compile the code for - the file select dialog into core, useful in non-GUI cases. */ -extern char *(*rnd_hid_fileselect_imp)(rnd_hid_t *hid, const char *title, const char *descr, const char *default_file, const char *default_ext, const rnd_hid_fsd_filter_t *flt, const char *history_tag, rnd_hid_fsd_flags_t flags, rnd_hid_dad_subdialog_t *sub); - -/* If the mouse cursor is in the drawin area, set x;y silently and return; - else show msg and let the user click in the drawing area. If force is - non-zero and msg is non-NULL, discard the cache and force querying a - new coord. This mode must NOT be used unless action arguments explictly - requested it. Returns 0 on success, -1 on esc pressed */ -int rnd_hid_get_coords(const char *msg, rnd_coord_t *x, rnd_coord_t *y, int force); - -#endif Index: trunk/src/librnd/core/hid_init.c =================================================================== --- trunk/src/librnd/core/hid_init.c (revision 34601) +++ trunk/src/librnd/core/hid_init.c (nonexistent) @@ -1,1097 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * (this file is based on PCB, interactive printed circuit board design) - * Copyright (C) 1994,1995,1996 Thomas Nau - * Copyright (C) 2004 harry eaton - * Copyright (C) 2016..2021 Tibor 'Igor2' Palinkas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact: - * Project page: http://repo.hu/projects/pcb-rnd - * lead developer: http://repo.hu/projects/pcb-rnd/contact.html - * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") - * - */ - -#include - -#include -#include -#include - -#ifdef __WIN32__ -#include -#endif - -#include - -#include - -#include -#include -#include - -/* for dlopen() and friends; will also solve all system-dependent includes - and provides a dl-compat layer on windows. Also solves the opendir related - includes. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../../../config.h" - -static const char *hid_init_cookie = "hidlib"; - - -int rnd_coord_t_size = sizeof(rnd_coord_t); - -const char *rnd_ver_str = RND_VER_STR; - -static const char *flt_any[] = {"*", "*.*", NULL}; - -const rnd_hid_fsd_filter_t rnd_hid_fsd_filter_any[] = { - { "all", NULL, flt_any }, - { NULL, NULL, NULL } -}; - -rnd_hid_t **rnd_hid_list = 0; -int rnd_hid_num_hids = 0; - -rnd_hid_t *rnd_gui = NULL; -rnd_hid_t *rnd_render = NULL; -rnd_hid_t *rnd_exporter = NULL; - -int rnd_pixel_slop = 1; - -rnd_plugin_dir_t *rnd_plugin_dir_first = NULL, *rnd_plugin_dir_last = NULL; - -void rnd_hid_init() -{ - char *tmp; - - /* Setup a "nogui" default HID */ - rnd_render = rnd_gui = rnd_hid_nogui_get_hid(); - -#ifdef LIBRNDLIBDIR - /* librnd's own */ - tmp = LIBRNDLIBDIR RND_DIR_SEPARATOR_S "plugins" RND_DIR_SEPARATOR_S HOST; - rnd_plugin_add_dir(tmp); - - tmp = LIBRNDLIBDIR RND_DIR_SEPARATOR_S "plugins"; - rnd_plugin_add_dir(tmp); -#endif - - /* host app's */ -TODO("make this configurable - add to conf_prj_dsg_ignores avoid plugin injection") - tmp = rnd_concat(rnd_conf.rc.path.exec_prefix, RND_DIR_SEPARATOR_S, "lib", RND_DIR_SEPARATOR_S, rnd_app.package, RND_DIR_SEPARATOR_S, "plugins", RND_DIR_SEPARATOR_S, HOST, NULL); - rnd_plugin_add_dir(tmp); - free(tmp); - - tmp = rnd_concat(rnd_conf.rc.path.exec_prefix, RND_DIR_SEPARATOR_S, "lib", RND_DIR_SEPARATOR_S, rnd_app.package, RND_DIR_SEPARATOR_S, "plugins", NULL); - rnd_plugin_add_dir(tmp); - free(tmp); - - /* hardwired libdir, just in case exec-prefix goes wrong (e.g. linstall) */ - if (rnd_app.lib_dir != NULL) { - tmp = rnd_concat(rnd_app.lib_dir, RND_DIR_SEPARATOR_S, "plugins", RND_DIR_SEPARATOR_S, HOST, NULL); - rnd_plugin_add_dir(tmp); - free(tmp); - tmp = rnd_concat(rnd_app.lib_dir, RND_DIR_SEPARATOR_S, "plugins", NULL); - rnd_plugin_add_dir(tmp); - free(tmp); - } - - /* rnd_conf.rc.path.home is set by the conf_core immediately on startup */ - if ((rnd_conf.rc.path.home != NULL) && (rnd_app.dot_dir != NULL)) { - tmp = rnd_concat(rnd_conf.rc.path.home, RND_DIR_SEPARATOR_S, rnd_app.dot_dir, RND_DIR_SEPARATOR_S, "plugins", RND_DIR_SEPARATOR_S, HOST, NULL); - rnd_plugin_add_dir(tmp); - free(tmp); - - tmp = rnd_concat(rnd_conf.rc.path.home, RND_DIR_SEPARATOR_S, rnd_app.dot_dir, RND_DIR_SEPARATOR_S, "plugins", NULL); - rnd_plugin_add_dir(tmp); - free(tmp); - } - - tmp = rnd_concat("plugins", RND_DIR_SEPARATOR_S, HOST, NULL); - rnd_plugin_add_dir(tmp); - free(tmp); - - rnd_plugin_add_dir("plugins"); -} - -void rnd_hid_uninit(void) -{ - rnd_plugin_dir_t *pd, *next; - - if (rnd_hid_num_hids > 0) { - int i; - for (i = rnd_hid_num_hids-1; i >= 0; i--) { - if (rnd_hid_list[i]->uninit != NULL) - rnd_hid_list[i]->uninit(rnd_hid_list[i]); - } - } - - pup_uninit(&rnd_pup); - - rnd_export_uninit(); - - free(rnd_hid_list); - - for(pd = rnd_plugin_dir_first; pd != NULL; pd = next) { - next = pd->next; - free(pd->path); - free(pd); - } - rnd_plugin_dir_first = rnd_plugin_dir_last = NULL; -} - -void rnd_hid_register_hid(rnd_hid_t *hid) -{ - int i; - int sz = (rnd_hid_num_hids + 2) * sizeof(rnd_hid_t *); - - if (hid->struct_size != sizeof(rnd_hid_t)) { - fprintf(stderr, "Warning: hid \"%s\" has an incompatible ABI.\n", hid->name); - return; - } - - for (i = 0; i < rnd_hid_num_hids; i++) - if (hid == rnd_hid_list[i]) - return; - - rnd_hid_num_hids++; - if (rnd_hid_list) - rnd_hid_list = (rnd_hid_t **) realloc(rnd_hid_list, sz); - else - rnd_hid_list = (rnd_hid_t **) malloc(sz); - - rnd_hid_list[rnd_hid_num_hids - 1] = hid; - rnd_hid_list[rnd_hid_num_hids] = 0; -} - -void rnd_hid_remove_hid(rnd_hid_t *hid) -{ - int i; - - for (i = 0; i < rnd_hid_num_hids; i++) { - if (hid == rnd_hid_list[i]) { - rnd_hid_list[i] = rnd_hid_list[rnd_hid_num_hids - 1]; - rnd_hid_list[rnd_hid_num_hids - 1] = 0; - rnd_hid_num_hids--; - return; - } - } -} - -static void rnd_hid_load_gui_plugin(const char *plugname); - -void rnd_hid_do_all_gui_plugins(void *ctx, int (*cb)(void *ctx, const char *name, const char *dir, const char *fn)) -{ - char **dir; - gds_t tmp = {0}; - - if (rnd_conf.rc.verbose >= RND_MSG_INFO) - fprintf(stderr, " no HID preference; auto-loading all HID plugins available...\n"); - - for(dir = rnd_pup_paths; *dir != NULL; dir++) { - void *d = pup_open_dir(*dir); - const char *fn; - - if (d == NULL) continue; - - while((fn = pup_read_dir(d)) != NULL) { - if (strncmp(fn, "hid_", 4) == 0) { - char *s; - tmp.used = 0; - gds_append_str(&tmp, fn); - if (tmp.used < 4) - continue; - - /* accept *.pup only and truncate .pup from the end */ - s = tmp.array + tmp.used - 4; - if (strcmp(s, ".pup") != 0) - continue; - *s = '\0'; - if (cb(ctx, tmp.array, *dir, fn) != 0) - break; - } - } - - pup_close_dir(d); - } - gds_uninit(&tmp); -} - -static int load_all_gui_plugins_cb(void *ctx, const char *name, const char *dir, const char *fn) -{ - if (rnd_conf.rc.verbose >= RND_MSG_INFO) - fprintf(stderr, "-- all-hid-load: '%s' ('%s' from %s)\n", name, fn, dir); - rnd_hid_load_gui_plugin(name); - return 0; -} - -/* Load all hid_* plugins from all puplug search paths */ -static void rnd_hid_load_all_gui_plugins(void) -{ - rnd_hid_do_all_gui_plugins(NULL, load_all_gui_plugins_cb); -} - -static int list_gui_cb(void *ctx, const char *name, const char *dir, const char *fn) -{ - gds_t *tmp = ctx; - char *end, *line, buff[1024], *desc = ""; - FILE *f; - - tmp->used = 0; - gds_append_str(tmp, dir); - gds_append(tmp, RND_DIR_SEPARATOR_C); - gds_append_str(tmp, fn); - - f = rnd_fopen(NULL, tmp->array, "r"); - if (f != NULL) { - while((line = fgets(buff, sizeof(buff), f)) != NULL) { - while(isspace(*line)) line++; - if (strncmp(line, "$short", 6) == 0) { - desc = line + 6; - while(isspace(*desc)) desc++; - end = strpbrk(desc, "\r\n"); - if (end != NULL) - *end = '\0'; - break; - } - } - fclose(f); - } - - fprintf(stderr, "\t%-16s %s\n", name, desc); - return 0; -} - -void rnd_hid_print_all_gui_plugins(void) -{ - gds_t tmp = {0}; - const pup_buildin_t *b; - - rnd_hid_do_all_gui_plugins(&tmp, list_gui_cb); - - /* print buildins */ - for(b = pup_buildins; b->name != NULL; b++) - if (strncmp(b->name, "hid_", 4) == 0) - fprintf(stderr, "\t%-16s\n", b->name); - - gds_uninit(&tmp); -} - - -/* low level (pup) load a plugin if it is not already loaded; if plugname is - NULL, try to load all plugins */ -static void rnd_hid_load_gui_plugin(const char *plugname) -{ - int st; - - if (rnd_conf.rc.verbose >= RND_MSG_INFO) - fprintf(stderr, "GUI: want '%s'\n", plugname); - if (plugname == NULL) { - /* load all available GUI plugins; with a workaround: lesstif needs to be - loaded first because it is sensitive to link order of -lXm and -lXt; - if gtk or other X related GUI is loaded before, lesstif yields error */ - rnd_hid_load_gui_plugin("hid_lesstif"); - rnd_hid_load_all_gui_plugins(); - } - else { - char tmp[256]; - - /* prefix plugin name with hid_ */ - if ((plugname[0] != 'h') || strncmp(plugname, "hid_", 4) != 0) { - int l = strlen(plugname); - if (l > sizeof(tmp) - 8) { - fprintf(stderr, "rnd_hid_load_gui_plugin: plugin name too long: '%s'\n", plugname); - return; - } - strcpy(tmp, "hid_"); - memcpy(tmp+4, plugname, l+1); - plugname = tmp; - } - - /* do not load if already loaded */ - if (pup_lookup(&rnd_pup, plugname) != NULL) { - if (rnd_conf.rc.verbose >= RND_MSG_INFO) - fprintf(stderr, " already loaded %s\n", plugname); - return; - } - - /* load the plugin */ - if (rnd_conf.rc.verbose >= RND_MSG_INFO) - fprintf(stderr, " loading %s\n", plugname); - if (pup_load(&rnd_pup, (const char **)rnd_pup_paths, plugname, 0, &st) == NULL) { - if (rnd_conf.rc.verbose >= RND_MSG_INFO) - fprintf(stderr, " failed.\n"); - } - } -} - -rnd_hid_t *rnd_hid_find_gui(rnd_hidlib_t *hidlib, const char *preference) -{ - rnd_hid_t *gui; - int i; - - if (strncmp(preference, "hid_", 4) == 0) - preference += 4; - - /* ugly hack for historical reasons: some old configs and veteran users are used to the --gui gtk option */ - if ((preference != NULL) && (strcmp(preference, "gtk") == 0)) { - gui = rnd_hid_find_gui(hidlib, "gtk2_gl"); - if (gui != NULL) - return gui; - - gui = rnd_hid_find_gui(hidlib, "gtk2_gdk"); - if (gui != NULL) - return gui; - - gui = rnd_hid_find_gui(hidlib, "gtk4_gl"); - if (gui != NULL) - return gui; - - return NULL; - } - - rnd_hid_load_gui_plugin(preference); - - /* normal search */ - if (preference != NULL) { - for (i = 0; i < rnd_hid_num_hids; i++) { - if (!rnd_hid_list[i]->printer && !rnd_hid_list[i]->exporter && !strcmp(rnd_hid_list[i]->name, preference)) { - gui = rnd_hid_list[i]; - goto found; - } - } - return NULL; - } - - for (i = 0; i < rnd_hid_num_hids; i++) { - if (!rnd_hid_list[i]->printer && !rnd_hid_list[i]->exporter && !rnd_hid_list[i]->hide_from_gui) { - gui = rnd_hid_list[i]; - goto found; - } - } - - fprintf(stderr, "Error: No GUI available.\n"); - exit(1); - - found:; - if (gui->gui) { - char *fn = NULL; - int exact_fn = 0; - rnd_menu_patch_t *mp; - - if ((rnd_conf.rc.menu_file != NULL) && (*rnd_conf.rc.menu_file != '\0')) { - fn = rnd_strdup_printf(rnd_app.menu_name_fmt, rnd_conf.rc.menu_file); - exact_fn = (strchr(rnd_conf.rc.menu_file, '/') != NULL); - } - - mp = rnd_hid_menu_load(gui, hidlib, "librnd", 0, fn, exact_fn, rnd_app.default_embedded_menu, "base menu file"); - free(fn); - if (mp == NULL) { - fprintf(stderr, "Failed to load the menu file - can not start a GUI HID.\n"); - exit(1); - } - } - return gui; -} - -rnd_hid_t *rnd_hid_find_printer() -{ - int i; - - for (i = 0; i < rnd_hid_num_hids; i++) - if (rnd_hid_list[i]->printer) - return rnd_hid_list[i]; - - return 0; -} - -void rnd_hid_print_exporter_list(FILE *f, const char *prefix, const char *suffix) -{ - int i; - for (i = 0; i < rnd_hid_num_hids; i++) - if (rnd_hid_list[i]->exporter) - fprintf(f, "%s%s%s", prefix, rnd_hid_list[i]->name, suffix); -} - -rnd_hid_t *rnd_hid_find_exporter(const char *which) -{ - int i; - - if (which == NULL) { - fprintf(stderr, "Invalid exporter: need an exporter name, one of:"); - goto list; - } - - if (strcmp(which, "-list-") == 0) { - rnd_hid_print_exporter_list(stdout, "", "\n"); - return 0; - } - - for (i = 0; i < rnd_hid_num_hids; i++) - if (rnd_hid_list[i]->exporter && strcmp(which, rnd_hid_list[i]->name) == 0) - return rnd_hid_list[i]; - - fprintf(stderr, "Invalid exporter %s, available ones:", which); - - list:; - rnd_hid_print_exporter_list(stderr, " ", ""); - fprintf(stderr, "\n"); - - return 0; -} - -rnd_hid_t **rnd_hid_enumerate() -{ - return rnd_hid_list; -} - -const char *rnd_hid_export_fn(const char *filename) -{ - if (rnd_conf.rc.export_basename) { - const char *outfn = strrchr(filename, RND_DIR_SEPARATOR_C); - if (outfn == NULL) - return filename; - return outfn + 1; - } - else - return filename; -} - -extern void rnd_hid_dlg_uninit(void); -extern void rnd_hid_dlg_init(void); - -static char *get_homedir(void) -{ - char *homedir = getenv("HOME"); - if (homedir == NULL) - homedir = getenv("USERPROFILE"); - return homedir; -} - -void rnd_pcbhl_conf_postproc(void) -{ - rnd_conf_force_set_str(rnd_conf.rc.path.home, get_homedir()); rnd_conf_ro("rc/path/home"); -} - -char *rnd_exec_prefix(char *argv0, const char *bin_dir, const char *bin_dir_to_execprefix) -{ - size_t l; - int haspath; - char *t1, *t2; - int found_bindir = 0; - char *exec_prefix = NULL; - char *bindir = NULL; - - - /* see if argv0 has enough of a path to let lrealpath give the - real path. This should be the case if you invoke pcb with - something like /usr/local/bin/pcb or ./pcb or ./foo/pcb - but if you just use pcb and it exists in your path, you'll - just get back pcb again. */ - haspath = (strchr(argv0, RND_DIR_SEPARATOR_C) != NULL); - -#ifdef DEBUG - printf("rnd_exec_prefix (%s): haspath = %d\n", argv0, haspath); -#endif - - if (haspath) { - bindir = rnd_lrealpath(argv0); - if (bindir == NULL) - bindir = rnd_strdup(argv0); - found_bindir = 1; - } - else { - char *path, *p, *tmps; - struct stat sb; - int r; - - tmps = getenv("PATH"); - - if (tmps != NULL) { - path = rnd_strdup(tmps); - - /* search through the font path for a font file */ - for (p = strtok(path, RND_PATH_DELIMETER); p && *p; p = strtok(NULL, RND_PATH_DELIMETER)) { -#ifdef DEBUG - printf("Looking for %s in %s\n", argv0, p); -#endif - if ((tmps = (char *) malloc((strlen(argv0) + strlen(p) + 2) * sizeof(char))) == NULL) { - fprintf(stderr, "rnd_exec_prefix(): malloc failed\n"); - exit(1); - } - sprintf(tmps, "%s%s%s", p, RND_DIR_SEPARATOR_S, argv0); - r = stat(tmps, &sb); - if (r == 0) { -#ifdef DEBUG - printf("Found it: \"%s\"\n", tmps); -#endif - bindir = rnd_lrealpath(tmps); - if (bindir == NULL) - bindir = rnd_strdup(tmps); - found_bindir = 1; - free(tmps); - break; - } - free(tmps); - } - free(path); - } - } - - if (found_bindir) { - /* strip off the executable name leaving only the path */ - t2 = NULL; - t1 = strchr(bindir, RND_DIR_SEPARATOR_C); - while (t1 != NULL && *t1 != '\0') { - t2 = t1; - t1 = strchr(t2 + 1, RND_DIR_SEPARATOR_C); - } - if (t2 != NULL) - *t2 = '\0'; - } - else { - /* we have failed to find out anything from argv[0] so fall back to the original install prefix */ - bindir = rnd_strdup(bin_dir); - } - - /* now find the path to exec_prefix */ - l = strlen(bindir) + 1 + strlen(bin_dir_to_execprefix) + 1; - if ((exec_prefix = (char *) malloc(l * sizeof(char))) == NULL) { - fprintf(stderr, "rnd_exec_prefix(): malloc failed\n"); - exit(1); - } - sprintf(exec_prefix, "%s%s%s", bindir, RND_DIR_SEPARATOR_S, bin_dir_to_execprefix); - free(bindir); - return exec_prefix; -} - -static void hidlib_gui_init_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) -{ - rnd_tool_gui_init(); - rnd_gui->set_mouse_cursor(rnd_gui, rnd_conf.editor.mode); /* make sure the mouse cursor is set up now that it is registered */ -} - -static void rnd_hid_init_init(void) -{ - rnd_event_bind(RND_EVENT_GUI_INIT, hidlib_gui_init_ev, NULL, hid_init_cookie); -} - -static void rnd_hid_init_uninit(void) -{ - rnd_event_unbind_allcookie(hid_init_cookie); -} - - -extern void rnd_menu_init1(void); - -void rnd_hidlib_init1(void (*conf_core_init)(void)) -{ - rnd_events_init(); - rnd_file_loaded_init(); - rnd_conf_init(); - conf_core_init(); - rnd_pcbhl_conf_postproc(); - rnd_hidlib_conf_init(); - rnd_hid_init_init(); - rnd_hid_dlg_init(); - rnd_hid_init(); - rnd_grid_init(); - rnd_color_init(); - rnd_menu_init1(); -} - -static vts0_t hidlib_conffile; - -extern void rnd_hidlib_error_init2(void); -extern void rnd_hid_dlg_init2(void); -extern void rnd_hid_nogui_init2(void); -extern void rnd_conf_act_init2(void); -extern void rnd_hid_act_init2(void); -extern void rnd_tool_act_init2(void); -extern void rnd_gui_act_init2(void); -extern void rnd_main_act_init2(void); -extern void rnd_menu_act_init2(void); -extern void rnd_anyload_init2(void); -extern void rnd_anyload_act_init2(void); -extern void rnd_conf_init2(void); - -void rnd_hidlib_init2(const pup_buildin_t *buildins, const pup_buildin_t *local_buildins) -{ - rnd_actions_init(); - - /* load custom config files in the order they were specified */ - if (hidlib_conffile.used > 0) { - int n; - for(n = 0; n < hidlib_conffile.used; n++) { - rnd_conf_role_t role = RND_CFR_CLI; - char *srole, *sep, *fn = hidlib_conffile.array[n]; - sep = strchr(fn, ';'); - if (sep != NULL) { - srole = fn; - *sep = '\0'; - fn = sep+1; - role = rnd_conf_role_parse(srole); - if (role == RND_CFR_invalid) { - fprintf(stderr, "Can't load -C config file '%s': invalid role '%s'\n", fn, srole); - free(hidlib_conffile.array[n]); - continue; - } - } - rnd_conf_load_as(role, fn, 0); - free(hidlib_conffile.array[n]); - } - vts0_uninit(&hidlib_conffile); - } - - rnd_conf_load_all(NULL, NULL); - - pup_init(&rnd_pup); - rnd_pup.error_stack_enable = 1; - - /* core actions */ - rnd_hidlib_error_init2(); - rnd_hid_dlg_init2(); - rnd_hid_nogui_init2(); - rnd_conf_act_init2(); - rnd_hid_act_init2(); - rnd_tool_act_init2(); - rnd_gui_act_init2(); - rnd_main_act_init2(); - rnd_menu_act_init2(); - rnd_conf_init2(); - - /* plugins: buildins */ - pup_buildin_load(&rnd_pup, buildins); - if (local_buildins != NULL) - pup_buildin_load(&rnd_pup, local_buildins); - pup_autoload_dir(&rnd_pup, NULL, NULL); - - rnd_conf_load_extra(NULL, NULL); - rnd_units_init(); - rnd_funchash_init(); - rnd_anyload_act_init2(); - - rnd_anyload_init2(); /* must be at the end because any init2() may register an anyload */ -} - -static void print_pup_err(pup_err_stack_t *entry, char *string) -{ - rnd_message(RND_MSG_ERROR, "puplug: %s\n", string); -} - -void rnd_hidlib_init3_auto(void) -{ - char **sp; - - if (rnd_pup.err_stack != NULL) { - rnd_message(RND_MSG_ERROR, "Some of the static linked buildins could not be loaded:\n"); - pup_err_stack_process_str(&rnd_pup, print_pup_err); - } - - for(sp = rnd_pup_paths; *sp != NULL; sp++) { - rnd_message(RND_MSG_DEBUG, "Loading plugins from '%s'\n", *sp); - pup_autoload_dir(&rnd_pup, *sp, (const char **)rnd_pup_paths); - } - - if (rnd_pup.err_stack != NULL) { - rnd_message(RND_MSG_ERROR, "Some of the dynamic linked plugins could not be loaded:\n"); - pup_err_stack_process_str(&rnd_pup, print_pup_err); - } -} - - -extern void rnd_menu_uninit(void); -extern void rnd_anyload_uninit(void); -extern void rnd_hid_cfg_keys_uninit_module(void); - - -void rnd_hidlib_uninit(void) -{ - rnd_hid_menu_merge_inhibit_inc(); /* make sure no menu merging happens during the uninitialization */ - rnd_grid_uninit(); - rnd_menu_uninit(); - rnd_hid_init_uninit(); - rnd_hid_dlg_uninit(); - - if (rnd_conf_isdirty(RND_CFR_USER)) - rnd_conf_save_file(NULL, NULL, NULL, RND_CFR_USER, NULL); - - rnd_hid_uninit(); - rnd_conf_uninit(); - rnd_plugin_uninit(); - rnd_actions_uninit(); - rnd_dad_unit_uninit(); - rnd_hid_cfg_keys_uninit_module(); - rnd_anyload_uninit(); - rnd_events_uninit(); -} - -/* parse arguments using the gui; if fails and fallback is enabled, try the next gui */ -int rnd_gui_parse_arguments(int autopick_gui, int *hid_argc, char **hid_argv[]) -{ - rnd_conf_listitem_t *apg = NULL; - - if ((autopick_gui >= 0) && (rnd_conf.rc.hid_fallback)) { /* start from the GUI we are initializing first */ - int n; - const char *g; - - rnd_conf_loop_list_str(&rnd_conf.rc.preferred_gui, apg, g, n) { - if (n == autopick_gui) - break; - } - } - - for(;;) { - int res; - if (rnd_gui->get_export_options != NULL) - rnd_gui->get_export_options(rnd_gui, NULL); - res = rnd_gui->parse_arguments(rnd_gui, hid_argc, hid_argv); - if (res == 0) - break; /* HID accepted, don't try anything else */ - if (res < 0) { - rnd_message(RND_MSG_ERROR, "Failed to initialize HID %s (unrecoverable, have to give up)\n", rnd_gui->name); - return -1; - } - fprintf(stderr, "Failed to initialize HID %s (recoverable)\n", rnd_gui->name); - if (apg == NULL) { - if (rnd_conf.rc.hid_fallback) { - ran_out_of_hids:; - rnd_message(RND_MSG_ERROR, "Tried all available HIDs, all failed, giving up.\n"); - } - else - rnd_message(RND_MSG_ERROR, "Not trying any other hid as fallback because rc/hid_fallback is disabled.\n"); - return -1; - } - - /* falling back to the next HID */ - do { - int n; - const char *g; - - apg = rnd_conf_list_next_str(apg, &g, &n); - if (apg == NULL) - goto ran_out_of_hids; - rnd_render = rnd_gui = rnd_hid_find_gui(NULL, g); - } while(rnd_gui == NULL); - } - return 0; -} - -#ifdef __WIN32__ -/* truncate the last dir segment; returns remaining length or 0 on failure */ -static int truncdir(char *dir) -{ - char *s; - - for(s = dir + strlen(dir) - 1; s >= dir; s--) { - if ((*s == '/') || (*s == '\\')) { - *s = '\0'; - return s - dir; - } - } - *dir = '\0'; - return 0; -} -extern int rnd_mkdir_(const char *path, int mode); -char *rnd_w32_root; -char *rnd_w32_libdir, *rnd_w32_bindir, *rnd_w32_sharedir, *rnd_w32_cachedir; -#endif - -void rnd_fix_locale_and_env_() -{ - static const char *lcs[] = { "LANG", "LC_NUMERIC", "LC_ALL", NULL }; - const char **lc; - - /* some Xlib calls tend ot hardwire setenv() to "" or NULL so a simple - setlocale() won't do the trick on GUI. Also set all related env var - to "C" so a setlocale(LC_ALL, "") will also do the right thing. */ - for(lc = lcs; *lc != NULL; lc++) - rnd_setenv(*lc, "C", 1); - - setlocale(LC_ALL, "C"); - - -#ifdef __WIN32__ - { - char *s, exedir[MAX_PATH]; - wchar_t *w, wexedir[MAX_PATH]; - - if (!GetModuleFileNameW(NULL, wexedir, MAX_PATH)) { - fprintf(stderr, "%s: GetModuleFileNameW(): failed to determine executable full path\n", rnd_app.package); - exit(1); - } - - for(w = wexedir, s = exedir; *w != 0; w++) - s += wctomb(s, *w); - *s = '\0'; - - truncdir(exedir); - - for(s = exedir; *s != '\0'; s++) - if (*s == '\\') - *s = '/'; - - rnd_w32_bindir = rnd_strdup(exedir); - truncdir(exedir); - rnd_w32_root = rnd_strdup(exedir); - rnd_w32_libdir = rnd_concat(exedir, "/lib/pcb-rnd", NULL); - rnd_w32_sharedir = rnd_concat(exedir, "/share/pcb-rnd", NULL); - - rnd_w32_cachedir = rnd_concat(rnd_w32_root, "/cache", NULL); - rnd_mkdir_(rnd_w32_cachedir, 0755); - -/* printf("WIN32 root='%s' libdir='%s' sharedir='%s'\n", rnd_w32_root, rnd_w32_libdir, rnd_w32_sharedir);*/ - } -#endif -} - -static int rnd_pcbhl_main_arg_match(const char *in, const char *shrt, const char *lng) -{ - return ((shrt != NULL) && (strcmp(in, shrt) == 0)) || ((lng != NULL) && (strcmp(in, lng) == 0)); -} - -void rnd_main_args_init(rnd_main_args_t *ga, int argc, const char **action_args) -{ - memset(ga, 0, sizeof(rnd_main_args_t)); - ga->hid_argv_orig = ga->hid_argv = calloc(sizeof(char *), argc); - vtp0_init(&ga->plugin_cli_conf); - ga->action_args = action_args; - ga->autopick_gui = -1; -} - -void rnd_main_args_uninit(rnd_main_args_t *ga) -{ - vtp0_uninit(&ga->plugin_cli_conf); - free(ga->hid_argv_orig); -} - -int rnd_main_args_add(rnd_main_args_t *ga, char *cmd, char *arg) -{ - const char **cs; - char *orig_cmd = cmd; - - if (*cmd == '-') { - cmd++; - if ((strcmp(cmd, "?") == 0) || (strcmp(cmd, "h") == 0) || (strcmp(cmd, "-help") == 0)) { - if (arg != NULL) { - /* memory leak, but who cares for --help? */ - ga->main_action = rnd_strdup_printf("PrintUsage(%s)", arg); - return 1; - } - ga->main_action = "PrintUsage()"; - return 0; - } - - if ((strcmp(cmd, "g") == 0) || (strcmp(cmd, "-gui") == 0) || (strcmp(cmd, "-hid") == 0)) { - ga->do_what = RND_DO_GUI; - ga->hid_name = arg; - return 1; - } - if ((strcmp(cmd, "x") == 0) || (strcmp(cmd, "-export") == 0)) { - ga->do_what = RND_DO_EXPORT; - ga->hid_name = arg; - return 1; - } - if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "-print") == 0)) { - ga->do_what = RND_DO_PRINT; - return 0; - } - - for(cs = ga->action_args; cs[2] != NULL; cs += RND_ACTION_ARGS_WIDTH) { - if (rnd_pcbhl_main_arg_match(cmd, cs[0], cs[1])) { - if (ga->main_action == NULL) { - ga->main_action = cs[2]; - ga->main_action_hint = cs[4]; - } - else - fprintf(stderr, "Warning: can't execute multiple command line actions, ignoring %s\n", orig_cmd); - return 0; - } - } - if (rnd_pcbhl_main_arg_match(cmd, "c", "-conf")) { - const char *why; - if (strncmp(arg, "plugins/", 8) == 0) { - /* plugins are not yet loaded or initialized so their configs are - unavailable. Store these settings until plugins are up. This - should not happen to non-plugin config items as those might - affect how plugins are searched/loaded. */ - const void **a = (const void **)vtp0_alloc_append(&ga->plugin_cli_conf, 1); - *a = arg; - } - else { - if (rnd_conf_set_from_cli(NULL, arg, NULL, &why) != 0) { - fprintf(stderr, "Error: failed to set config %s: %s\n", arg, why); - exit(1); - } - } - return 1; - } - if (rnd_pcbhl_main_arg_match(cmd, "C", "-conffile")) { - vts0_append(&hidlib_conffile, rnd_strdup(arg)); - return 1; - } - } - /* didn't handle argument, save it for the HID */ - ga->hid_argv[ga->hid_argc++] = orig_cmd; - return 0; -} - -static int apply_plugin_cli_conf(rnd_main_args_t *ga, int relax) -{ - int n; - for(n = 0; n < vtp0_len(&ga->plugin_cli_conf); n++) { - const char *why, *arg = ga->plugin_cli_conf.array[n]; - - if (ga->plugin_cli_conf.array[n] == NULL) continue; - - if (rnd_conf_set_from_cli(NULL, arg, NULL, &why) != 0) { - if (!relax) { - fprintf(stderr, "Error: failed to set config %s: %s\n", arg, why); - return 1; - } - } - else - ga->plugin_cli_conf.array[n] = NULL; /* remove if succesfully set so it won't be set again on multiple calls at different stages */ - } - return 0; -} - -int rnd_main_args_setup1(rnd_main_args_t *ga) -{ - /* Now that plugins are already initialized, apply plugin config items; - non-existing ones are not fatal as the GUI plugin is not yet loaded */ - apply_plugin_cli_conf(ga, 1); - - /* Export pcb from command line if requested. */ - switch(ga->do_what) { - case RND_DO_PRINT: rnd_render = rnd_exporter = rnd_gui = rnd_hid_find_printer(); break; - case RND_DO_EXPORT: rnd_render = rnd_exporter = rnd_gui = rnd_hid_find_exporter(ga->hid_name); break; - case RND_DO_GUI: - rnd_render = rnd_gui = rnd_hid_find_gui(NULL, ga->hid_name); - if (rnd_gui == NULL) { - rnd_message(RND_MSG_ERROR, "Can't find the gui (%s) requested.\n", ga->hid_name); - return 1; - } - break; - default: { - const char *g; - rnd_conf_listitem_t *i; - - rnd_render = rnd_gui = NULL; - rnd_conf_loop_list_str(&rnd_conf.rc.preferred_gui, i, g, ga->autopick_gui) { - rnd_render = rnd_gui = rnd_hid_find_gui(NULL, g); - if (rnd_gui != NULL) - break; - } - - /* try anything */ - if (rnd_gui == NULL) { - rnd_message(RND_MSG_WARNING, "Warning: can't find any of the preferred GUIs, falling back to anything available...\nYou may want to check if the plugin is loaded, try --dump-plugins and --dump-plugindirs\n"); - rnd_render = rnd_gui = rnd_hid_find_gui(NULL, NULL); - } - } - } - - /* Exit with error if GUI failed to start. */ - if (!rnd_gui) - return 1; - - /* Now that even the GUI plugin is initialized, apply remaining plugin config - items; non-existing ones are fatal */ - if (apply_plugin_cli_conf(ga, 0) != 0) - return 1; - - vtp0_uninit(&ga->plugin_cli_conf); - - return 0; -} - -int rnd_main_args_setup2(rnd_main_args_t *ga, int *exitval) -{ - *exitval = 0; - - /* plugins may have installed their new fields, reinterpret the config - (memory lht -> memory bin) to get the new fields */ - rnd_conf_update(NULL, -1); - - if (ga->main_action != NULL) { - int res = rnd_parse_command(NULL, ga->main_action, rnd_true); /* hidlib is NULL because there is no context yet */ - if ((res != 0) && (ga->main_action_hint != NULL)) - rnd_message(RND_MSG_ERROR, "\nHint: %s\n", ga->main_action_hint); - rnd_log_print_uninit_errs("main_action parse error"); - *exitval = res; - return 1; - } - - - if (rnd_gui_parse_arguments(ga->autopick_gui, &ga->hid_argc, &ga->hid_argv) != 0) { - rnd_log_print_uninit_errs("Export plugin argument parse error"); - return 1; - } - - return 0; -} - -int rnd_main_exported(rnd_main_args_t *ga, rnd_hidlib_t *hidlib, rnd_bool is_empty) -{ - if (!rnd_main_exporting) - return 0; - - if (is_empty) - rnd_message(RND_MSG_WARNING, "Exporting empty design (nothing loaded or drawn).\n"); - if (rnd_gui->set_hidlib != NULL) - rnd_gui->set_hidlib(rnd_gui, hidlib); - rnd_event(hidlib, RND_EVENT_EXPORT_SESSION_BEGIN, NULL); - rnd_gui->do_export(rnd_gui, 0); - rnd_event(hidlib, RND_EVENT_EXPORT_SESSION_END, NULL); - rnd_log_print_uninit_errs("Exporting"); - return 1; -} - -void rnd_mainloop_interactive(rnd_main_args_t *ga, rnd_hidlib_t *hidlib) -{ - rnd_hid_in_main_loop = 1; - rnd_event(hidlib, RND_EVENT_MAINLOOP_CHANGE, "i", rnd_hid_in_main_loop); - if (rnd_gui->set_hidlib != NULL) - rnd_gui->set_hidlib(rnd_gui, hidlib); - rnd_gui->do_export(rnd_gui, 0); - rnd_hid_in_main_loop = 0; - rnd_event(hidlib, RND_EVENT_MAINLOOP_CHANGE, "i", rnd_hid_in_main_loop); -} - Index: trunk/src/librnd/core/hid_inlines.h =================================================================== --- trunk/src/librnd/core/hid_inlines.h (revision 34601) +++ trunk/src/librnd/core/hid_inlines.h (nonexistent) @@ -1,99 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * Copyright (C) 2018 Tibor 'Igor2' Palinkas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact: - * Project page: http://repo.hu/projects/pcb-rnd - * lead developer: http://repo.hu/projects/pcb-rnd/contact.html - * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") - */ - -#ifndef RND_HID_INLINES -#define RND_HID_INLINES - -#include -#include - -RND_INLINE rnd_hid_gc_t rnd_hid_make_gc(void) -{ - rnd_hid_gc_t res; - rnd_core_gc_t *hc; - res = rnd_render->make_gc(rnd_gui); - hc = (rnd_core_gc_t *)res; /* assumes first field is rnd_core_gc_t */ - hc->width = RND_MAX_COORD; - hc->cap = rnd_cap_invalid; - hc->xor = 0; - hc->faded = 0; - hc->hid = rnd_gui; - return res; -} - -RND_INLINE void rnd_hid_destroy_gc(rnd_hid_gc_t gc) -{ - rnd_render->destroy_gc(gc); -} - -RND_INLINE void rnd_hid_set_line_cap(rnd_hid_gc_t gc, rnd_cap_style_t style) -{ - rnd_core_gc_t *hc = (rnd_core_gc_t *)gc; - if (hc->cap != style) { - hc->cap = style; - rnd_render->set_line_cap(gc, style); - } -} - -RND_INLINE void rnd_hid_set_line_width(rnd_hid_gc_t gc, rnd_coord_t width) -{ - rnd_core_gc_t *hc = (rnd_core_gc_t *)gc; - if (hc->width != width) { - hc->width = width; - rnd_render->set_line_width(gc, width); - } -} - -RND_INLINE void rnd_hid_set_draw_xor(rnd_hid_gc_t gc, int xor) -{ - rnd_core_gc_t *hc = (rnd_core_gc_t *)gc; - if (hc->xor != xor) { - hc->xor = xor; - rnd_render->set_draw_xor(gc, xor); - } -} - -RND_INLINE void rnd_hid_set_draw_faded(rnd_hid_gc_t gc, int faded) -{ - rnd_core_gc_t *hc = (rnd_core_gc_t *)gc; - if (hc->faded != faded) { - hc->faded = faded; - rnd_render->set_draw_faded(gc, faded); - } -} - -RND_INLINE const char *rnd_hid_command_entry(const char *ovr, int *cursor) -{ - if ((rnd_gui == NULL) || (rnd_gui->command_entry == NULL)) { - if (cursor != NULL) - *cursor = -1; - return NULL; - } - return rnd_gui->command_entry(rnd_gui, ovr, cursor); -} - - -#endif Index: trunk/src/librnd/core/hid_init.h =================================================================== --- trunk/src/librnd/core/hid_init.h (revision 34601) +++ trunk/src/librnd/core/hid_init.h (nonexistent) @@ -1,202 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * (this file is based on PCB, interactive printed circuit board design) - * Copyright (C) 1994,1995,1996 Thomas Nau - * Copyright (C) 2004 harry eaton - * Copyright (C) 2016..2019 Tibor 'Igor2' Palinkas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact: - * Project page: http://repo.hu/projects/pcb-rnd - * lead developer: http://repo.hu/projects/pcb-rnd/contact.html - * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") - * - */ - -#ifndef RND_HID_INIT_H -#define RND_HID_INIT_H - -#include -#include -#include -#include - -#define RND_ACTION_ARGS_WIDTH 5 - -/* NULL terminated list of all static HID structures. Built by - hid_register_hid, used by hid_find_*() and rnd_hid_enumerate(). The - order in this list is the same as the order of hid_register_hid - calls. */ -extern rnd_hid_t **rnd_hid_list; - -/* Count of entries in the above. */ -extern int rnd_hid_num_hids; - -/* RND_VER_STR compiled into the binary so apps can print it */ -extern const char *rnd_ver_str; - -/* Call this as soon as possible from main(). No other HID calls are - valid until this is called. */ -void rnd_hid_init(void); - -/* Call this at exit */ -void rnd_hid_uninit(void); - -/* When the application runs in interactive mode, this is called to instantiate - one GUI HID which happens to be the GUI. This HID is the one that - interacts with the mouse and keyboard. */ -rnd_hid_t *rnd_hid_find_gui(rnd_hidlib_t *hidlib, const char *preference); - -/* Finds the one printer HID and instantiates it. */ -rnd_hid_t *rnd_hid_find_printer(void); - -/* Finds the indicated exporter HID and instantiates it. */ -rnd_hid_t *rnd_hid_find_exporter(const char *); - -/* This returns a NULL-terminated array of available HIDs. The only - real reason to use this is to locate all the export-style HIDs. */ -rnd_hid_t **rnd_hid_enumerate(void); - -/* HID internal interfaces. These may ONLY be called from the HID - modules, not from the common application code. */ - -/* A HID may use this if it does not need command line arguments in - any special format; for example, the Lesstif HID needs to use the - Xt parser, but the Postscript HID can use this function. */ -int rnd_hid_parse_command_line(int *argc, char ***argv); - -/* Called by the init funcs, used to set up rnd_hid_list. */ -extern void rnd_hid_register_hid(rnd_hid_t *hid); -void rnd_hid_remove_hid(rnd_hid_t *hid); - -typedef struct rnd_plugin_dir_s rnd_plugin_dir_t; -struct rnd_plugin_dir_s { - char *path; - int num_plugins; - rnd_plugin_dir_t *next; -}; - -extern rnd_plugin_dir_t *rnd_plugin_dir_first, *rnd_plugin_dir_last; - -/* Safe file name for inclusion in export file comments/headers; if the - user requested in the config, this becomes the basename of filename, - else it is the full file name */ -const char *rnd_hid_export_fn(const char *filename); - - -/*** main(), initialize ***/ - -typedef struct { - enum { - RND_DO_SOMETHING, - RND_DO_PRINT, - RND_DO_EXPORT, - RND_DO_GUI - } do_what; - int hid_argc; - const char *main_action, *main_action_hint; - vtp0_t plugin_cli_conf; - char **hid_argv_orig, **hid_argv; - const char *hid_name; - const char **action_args; - int autopick_gui; - - /* Spare: see doc/developer/spare.txt */ - void (*spare_f1)(void), (*spare_f2)(void); - long spare_l1, spare_l2, spare_l3, spare_l4; - void *spare_p1, *spare_p2, *spare_p3, *spare_p4; - double spare_d1, spare_d2, spare_d3, spare_d4; - rnd_coord_t spare_c1, spare_c2, spare_c3, spare_c4; -} rnd_main_args_t; - -/* call this before anything, to switch locale to "C" permanently; - also sets up the environment on win32. */ -#define rnd_fix_locale_and_env() do { rnd_init_macro_checks(); rnd_fix_locale_and_env_(); } while(0) - -/* This is called by the macro, do not call this directly */ -void rnd_fix_locale_and_env_(); - -/* Figure out the canonical name of the executed program - and return malloc'ed exec prefix that should be saved in the config - bin_dir is the full installation path of the bin dir, e.g. "/usr/local/bin" - bin_dir_to_execprefix is relative path between the two, typically ".." - */ -char *rnd_exec_prefix(char *argv0, const char *bin_dir, const char *bin_dir_to_execprefix); - -void rnd_hidlib_init1(void (*conf_core_init)(void)); /* before CLI argument parsing; conf_core_init should conf_reg() at least the hidlib related nodes */ -void rnd_hidlib_init2(const pup_buildin_t *buildins, const pup_buildin_t *local_buildins); /* after CLI argument parsing */ -void rnd_hidlib_init3_auto(void); -void rnd_hidlib_uninit(void); - -/* optional: hidlib aspects of main() */ -void rnd_main_args_init(rnd_main_args_t *ga, int argc, const char **action_args); -void rnd_main_args_uninit(rnd_main_args_t *ga); - -/* Parse the next argument using the next two argv[]s. Returns 0 if arg is - not consumed, 1 if consimed. */ -int rnd_main_args_add(rnd_main_args_t *ga, char *cmd, char *arg); - -/* returns non-zero on error (the application should exit); exitval is the - desired exit value of the executable when setup2 fails. */ -int rnd_main_args_setup1(rnd_main_args_t *ga); -int rnd_main_args_setup2(rnd_main_args_t *ga, int *exitval); - -/* if -x was specified, do the export and return 1 (the caller should - exit); else return 0 */ -int rnd_main_exported(rnd_main_args_t *ga, rnd_hidlib_t *hidlib, rnd_bool is_empty); - -/* launches the GUI or CLI; after it returns, if rnd_gui is not NULL, the user - has selected another GUI to switch to. */ -void rnd_mainloop_interactive(rnd_main_args_t *ga, rnd_hidlib_t *hidlib); - -/* parse arguments using the gui; if fails and fallback is enabled, try the next gui */ -int rnd_gui_parse_arguments(int autopick_gui, int *hid_argc, char **hid_argv[]); - -/* true if main() is called for printing or exporting (no interactive HID - shall be invoked) */ -#define rnd_main_exporting (rnd_gui->printer || rnd_gui->exporter) - -#ifdef __WIN32__ -extern char *rnd_w32_root; /* installation prefix; what would be $PREFIX on FHS, e.g. /usr/local */ -extern char *rnd_w32_libdir; /* on FHS this would be $PREFIX/lib*/ -extern char *rnd_w32_bindir; /* on FHS this would be $PREFIX/bin - on win32 this also hosts the dlls */ -extern char *rnd_w32_sharedir; /* on FHS this would be $PREFIX/share */ -extern char *rnd_w32_cachedir; /* where to store cache files, e.g. gdk pixbuf loader cache; persistent, but not part of the distribution */ -#endif - -/* Runtime checks that need to be compiled into the host application. Do not - use this directly. Invoked by rnd_fix_locale_and_env(). */ -#define rnd_init_macro_checks() \ - if (sizeof(rnd_coord_t) != rnd_coord_t_size) { \ - fprintf(stderr, "rnd_init_macro_checks: rnd_coord_t size mismatch between librnd and the host app; please recompile the host app\n"); \ - exit(1); \ - } - -extern int rnd_coord_t_size; - -void rnd_pcbhl_conf_postproc(void); - -/* Search all GUI plugins (even if they are not loaded) and call cb() - on them. If cb returns non-zero, cancel the search. */ -void rnd_hid_do_all_gui_plugins(void *ctx, int (*cb)(void *ctx, const char *name, const char *dir, const char *fn)); - -/* Print all GUI plugins available (not necessarily loaded) to stderr */ -void rnd_hid_print_all_gui_plugins(void); - - -#endif Index: trunk/src/librnd/core/hid_nogui.c =================================================================== --- trunk/src/librnd/core/hid_nogui.c (revision 34601) +++ trunk/src/librnd/core/hid_nogui.c (nonexistent) @@ -1,522 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * (this file is based on PCB, interactive printed circuit board design) - * Copyright (C) 1994,1995,1996 Thomas Nau - * Copyright (C) 2004 harry eaton - * Copyright (C) 2016..2018 Tibor 'Igor2' Palinkas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact: - * Project page: http://repo.hu/projects/pcb-rnd - * lead developer: http://repo.hu/projects/pcb-rnd/contact.html - * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") - * - */ - -#include - -#include -#include -#include - -#include -#include -#include -#include - -/* This is the "gui" that is installed at startup, and is used when - there is no other real GUI to use. For the most part, it just - stops the application from (1) crashing randomly, and (2) doing - gui-specific things when it shouldn't. */ - -#define CRASH(func) fprintf(stderr, "HID error: pcb called GUI function %s without having a GUI available.\n", func); abort() - -static const char rnd_acth_cli[] = "Intenal: CLI frontend action. Do not use directly."; - -static rnd_hid_t nogui_hid; - -typedef struct rnd_hid_gc_s { - int nothing_interesting_here; -} rnd_hid_gc_s; - -static const rnd_export_opt_t *nogui_get_export_options(rnd_hid_t *hid, int *n_ret) -{ - if (n_ret != NULL) - *n_ret = 0; - return NULL; -} - -static void nogui_do_export(rnd_hid_t *hid, rnd_hid_attr_val_t *options) -{ - CRASH("do_export"); -} - -static int nogui_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) -{ - CRASH("parse_arguments"); -} - -static void nogui_invalidate_lr(rnd_hid_t *hid, rnd_coord_t l, rnd_coord_t r, rnd_coord_t t, rnd_coord_t b) -{ - CRASH("invalidate_lr"); -} - -static void nogui_invalidate_all(rnd_hid_t *hid) -{ - CRASH("invalidate_all"); -} - -static int nogui_set_layer_group(rnd_hid_t *hid, rnd_layergrp_id_t group, const char *purpose, int purpi, rnd_layer_id_t layer, unsigned int flags, int is_empty, rnd_xform_t **xform) -{ - CRASH("set_layer_group"); - return 0; -} - -static void nogui_end_layer(rnd_hid_t *hid) -{ -} - -static rnd_hid_gc_t nogui_make_gc(rnd_hid_t *hid) -{ - return 0; -} - -static void nogui_destroy_gc(rnd_hid_gc_t gc) -{ -} - -static void nogui_set_drawing_mode(rnd_hid_t *hid, rnd_composite_op_t op, rnd_bool direct, const rnd_box_t *screen) -{ - CRASH("set_drawing_mode"); -} - -static void nogui_render_burst(rnd_hid_t *hid, rnd_burst_op_t op, const rnd_box_t *screen) -{ - /* the HID may decide to ignore this hook */ -} - -static void nogui_set_color(rnd_hid_gc_t gc, const rnd_color_t *name) -{ - CRASH("set_color"); -} - -static void nogui_set_line_cap(rnd_hid_gc_t gc, rnd_cap_style_t style) -{ - CRASH("set_line_cap"); -} - -static void nogui_set_line_width(rnd_hid_gc_t gc, rnd_coord_t width) -{ - CRASH("set_line_width"); -} - -static void nogui_set_draw_xor(rnd_hid_gc_t gc, int xor_) -{ - CRASH("set_draw_xor"); -} - -static void nogui_set_draw_faded(rnd_hid_gc_t gc, int faded) -{ -} - -static void nogui_draw_line(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) -{ - CRASH("draw_line"); -} - -static void nogui_draw_arc(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t width, rnd_coord_t height, rnd_angle_t start_angle, rnd_angle_t end_angle) -{ - CRASH("draw_arc"); -} - -static void nogui_draw_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) -{ - CRASH("draw_rect"); -} - -static void nogui_fill_circle(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius) -{ - CRASH("fill_circle"); -} - -static void nogui_fill_polygon(rnd_hid_gc_t gc, int n_coords, rnd_coord_t * x, rnd_coord_t * y) -{ - CRASH("fill_polygon"); -} - -static void nogui_fill_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) -{ - CRASH("fill_rect"); -} - -static int nogui_shift_is_pressed(rnd_hid_t *hid) -{ - /* This is called from rnd_crosshair_grid_fit() when the design is loaded. */ - return 0; -} - -static int nogui_control_is_pressed(rnd_hid_t *hid) -{ - CRASH("control_is_pressed"); - return 0; -} - -static int nogui_mod1_is_pressed(rnd_hid_t *hid) -{ - CRASH("mod1_is_pressed"); - return 0; -} - -static int nogui_get_coords(rnd_hid_t *hid, const char *msg, rnd_coord_t *x, rnd_coord_t *y, int force) -{ - CRASH("get_coords"); -} - -static void nogui_set_crosshair(rnd_hid_t *hid, rnd_coord_t x, rnd_coord_t y, rnd_set_crosshair_t action) -{ -} - -static rnd_hidval_t nogui_add_timer(rnd_hid_t *hid, void (*func)(rnd_hidval_t user_data), unsigned long milliseconds, rnd_hidval_t user_data) -{ - rnd_hidval_t rv; - CRASH("add_timer"); - rv.lval = 0; - return rv; -} - -static void nogui_stop_timer(rnd_hid_t *hid, rnd_hidval_t timer) -{ - CRASH("stop_timer"); -} - -static rnd_hidval_t nogui_watch_file(rnd_hid_t *hid, int fd, unsigned int condition, rnd_bool (*func) (rnd_hidval_t watch, int fd, unsigned int condition, rnd_hidval_t user_data), rnd_hidval_t user_data) -{ - rnd_hidval_t rv; - CRASH("watch_file"); - rv.lval = 0; - return rv; -} - -static void nogui_unwatch_file(rnd_hid_t *hid, rnd_hidval_t watch) -{ - CRASH("unwatch_file"); -} - -#define MAX_LINE_LENGTH 1024 -static const char *CANCEL = "CANCEL"; -char *rnd_nogui_read_stdin_line(void) -{ - static char buf[MAX_LINE_LENGTH]; - char *s; - int i; - - s = fgets(buf, MAX_LINE_LENGTH, stdin); - if (s == NULL) { - printf("\n"); - return rnd_strdup(CANCEL); - } - - /* Strip any trailing newline characters */ - for (i = strlen(s) - 1; i >= 0; i--) - if (s[i] == '\r' || s[i] == '\n') - s[i] = '\0'; - - if (s[0] == '\0') - return NULL; - - return rnd_strdup(s); -} - -#undef MAX_LINE_LENGTH - -static fgw_error_t rnd_act_cli_PromptFor(fgw_arg_t *res, int argc, fgw_arg_t *argv) -{ - char *answer; - const char *label, *default_str = "", *title = NULL; - const char *rnd_acts_cli_PromptFor = rnd_acth_cli; - - RND_ACT_CONVARG(1, FGW_STR, cli_PromptFor, label = argv[1].val.str); - RND_ACT_MAY_CONVARG(2, FGW_STR, cli_PromptFor, default_str = argv[2].val.str); - RND_ACT_MAY_CONVARG(3, FGW_STR, cli_PromptFor, title = argv[3].val.str); - - if (!rnd_conf.rc.quiet) { - char *tmp; - if (title != NULL) - printf("*** %s ***\n", title); - if (default_str) - printf("%s [%s] : ", label, default_str); - else - printf("%s : ", label); - - tmp = rnd_nogui_read_stdin_line(); - if (tmp == NULL) - answer = rnd_strdup((default_str != NULL) ? default_str : ""); - else - answer = tmp; /* always allocated */ - } - else - answer = rnd_strdup(""); - - res->type = FGW_STR | FGW_DYN; - res->val.str = answer; - return 0; -} - -static fgw_error_t rnd_act_cli_MessageBox(fgw_arg_t *res, int argc, fgw_arg_t *argv) -{ - const char *rnd_acts_cli_MessageBox = rnd_acth_cli; - const char *icon, *title, *label, *txt, *answer; - char *end; - int n, ret; - - res->type = FGW_INT; - if (rnd_conf.rc.quiet) { - cancel:; - res->val.nat_int = -1; - return 0; - } - - RND_ACT_CONVARG(1, FGW_STR, cli_MessageBox, icon = argv[1].val.str); - RND_ACT_CONVARG(2, FGW_STR, cli_MessageBox, title = argv[2].val.str); - RND_ACT_CONVARG(3, FGW_STR, cli_MessageBox, label = argv[3].val.str); - - printf("[%s] *** %s ***\n", icon, title); - - retry:; - printf("%s:\n", label); - for(n = 4; n < argc; n+=2) { - RND_ACT_CONVARG(n+0, FGW_STR, cli_MessageBox, txt = argv[n+0].val.str); - printf(" %d = %s\n", (n - 4)/2+1, txt); - } - printf("\nChose a number from above: "); - fflush(stdout); - answer = rnd_nogui_read_stdin_line(); - if ((answer == CANCEL) || (strcmp(answer, "cancel") == 0)) - goto cancel; - if (answer == NULL) - goto retry; - ret = strtol(answer, &end, 10); - if (((*end != '\0') && (*end != '\n') && (*end != '\r')) || (ret < 1) || (ret > (argc - 3) / 2)) { - printf("\nERROR: please type a number between 1 and %d\n", (argc - 4)/2+1); - goto retry; - } - n = (ret-1)*2+5; - RND_ACT_CONVARG(n, FGW_INT, cli_MessageBox, res->val.nat_int = argv[n].val.nat_int); - return 0; -} - -void *rnd_nogui_attr_dlg_new(rnd_hid_t *hid, const char *id, rnd_hid_attribute_t *attrs_, int n_attrs_, const char *title_, void *caller_data, rnd_bool modal, void (*button_cb)(void *caller_data, rnd_hid_attr_ev_t ev), int defx, int defy, int minx, int miny) -{ - CRASH("attr_dlg_new"); -} - -static int nogui_attr_dlg_run(void *hid_ctx) -{ - CRASH("attr_dlg_run"); -} - -static void nogui_attr_dlg_raise(void *hid_ctx) -{ - CRASH("attr_dlg_raise"); -} - -static void nogui_attr_dlg_close(void *hid_ctx) -{ - CRASH("attr_dlg_close"); -} - -static void nogui_attr_dlg_free(void *hid_ctx) -{ - CRASH("attr_dlg_free"); -} - -static void nogui_attr_dlg_property(void *hid_ctx, rnd_hat_property_t prop, const rnd_hid_attr_val_t *val) -{ - CRASH("attr_dlg_dlg_property"); -} - -static void nogui_beep(rnd_hid_t *hid) -{ - putchar(7); - fflush(stdout); -} - -int rnd_nogui_progress(long so_far, long total, const char *message) -{ - static int on = 0; - static double nextt; - double now; - - if (rnd_conf.rc.quiet) - return 0; - if (message == NULL) { - if ((on) && (rnd_conf.rc.verbose >= RND_MSG_INFO)) - fprintf(stderr, "progress: finished\n"); - on = 0; - } - else { - if ((rnd_conf.rc.verbose >= RND_MSG_INFO) || (rnd_gui != &nogui_hid)) { - now = rnd_dtime(); - if (now >= nextt) { - fprintf(stderr, "progress: %ld/%ld %s\n", so_far, total, message); - nextt = now + 0.2; - } - } - on = 1; - } - return 0; -} - -static int clip_warn(void) -{ - static int warned = 0; - if (!warned) { - rnd_message(RND_MSG_ERROR, "The current GUI HID does not support clipboard.\nClipboard is emulated, not shared withother programs\n"); - warned = 1; - } - return 0; -} - -static void *clip_data = NULL; -static size_t clip_len; -static rnd_hid_clipfmt_t clip_format; - -static int nogui_clip_set(rnd_hid_t *hid, rnd_hid_clipfmt_t format, const void *data, size_t len) -{ - free(clip_data); - clip_data = malloc(len); - if (clip_data != NULL) { - memcpy(clip_data, data, len); - clip_len = len; - clip_format = format; - } - else - clip_data = NULL; - return clip_warn(); -} - -static int nogui_clip_get(rnd_hid_t *hid, rnd_hid_clipfmt_t *format, void **data, size_t *len) -{ - if (clip_data == NULL) { - *data = NULL; - clip_warn(); - return -1; - } - *data = malloc(clip_len); - if (*data == NULL) { - *data = NULL; - return -1; - } - - memcpy(*data, clip_data, clip_len); - *format = clip_format; - *len = clip_len; - return clip_warn(); -} - -static void nogui_clip_free(rnd_hid_t *hid, rnd_hid_clipfmt_t format, void *data, size_t len) -{ - free(data); -} - -static void nogui_reg_mouse_cursor(rnd_hid_t *hid, int idx, const char *name, const unsigned char *pixel, const unsigned char *mask) -{ -} - -static void nogui_set_mouse_cursor(rnd_hid_t *hid, int idx) -{ -} - -static void nogui_set_top_title(rnd_hid_t *hid, const char *title) -{ -} - -void rnd_hid_nogui_init(rnd_hid_t * hid) -{ - hid->get_export_options = nogui_get_export_options; - hid->do_export = nogui_do_export; - hid->parse_arguments = nogui_parse_arguments; - hid->invalidate_lr = nogui_invalidate_lr; - hid->invalidate_all = nogui_invalidate_all; - hid->set_layer_group = nogui_set_layer_group; - hid->end_layer = nogui_end_layer; - hid->make_gc = nogui_make_gc; - hid->destroy_gc = nogui_destroy_gc; - hid->set_drawing_mode = nogui_set_drawing_mode; - hid->render_burst = nogui_render_burst; - hid->set_color = nogui_set_color; - hid->set_line_cap = nogui_set_line_cap; - hid->set_line_width = nogui_set_line_width; - hid->set_draw_xor = nogui_set_draw_xor; - hid->set_draw_faded = nogui_set_draw_faded; - hid->draw_line = nogui_draw_line; - hid->draw_arc = nogui_draw_arc; - hid->draw_rect = nogui_draw_rect; - hid->fill_circle = nogui_fill_circle; - hid->fill_polygon = nogui_fill_polygon; - hid->fill_rect = nogui_fill_rect; - hid->shift_is_pressed = nogui_shift_is_pressed; - hid->control_is_pressed = nogui_control_is_pressed; - hid->mod1_is_pressed = nogui_mod1_is_pressed; - hid->get_coords = nogui_get_coords; - hid->set_crosshair = nogui_set_crosshair; - hid->add_timer = nogui_add_timer; - hid->stop_timer = nogui_stop_timer; - hid->watch_file = nogui_watch_file; - hid->unwatch_file = nogui_unwatch_file; - hid->attr_dlg_new = rnd_nogui_attr_dlg_new; - hid->attr_dlg_run = nogui_attr_dlg_run; - hid->attr_dlg_raise = nogui_attr_dlg_raise; - hid->attr_dlg_close = nogui_attr_dlg_close; - hid->attr_dlg_free = nogui_attr_dlg_free; - hid->attr_dlg_property = nogui_attr_dlg_property; - hid->beep = nogui_beep; - hid->clip_set = nogui_clip_set; - hid->clip_get = nogui_clip_get; - hid->clip_free = nogui_clip_free; - hid->set_mouse_cursor = nogui_set_mouse_cursor; - hid->reg_mouse_cursor = nogui_reg_mouse_cursor; - hid->set_top_title = nogui_set_top_title; -} - - -rnd_hid_t *rnd_hid_nogui_get_hid(void) -{ - memset(&nogui_hid, 0, sizeof(rnd_hid_t)); - - nogui_hid.struct_size = sizeof(rnd_hid_t); - nogui_hid.name = "nogui"; - nogui_hid.description = "Default GUI when no other GUI is present. " "Does nothing."; - - rnd_hid_nogui_init(&nogui_hid); - - return &nogui_hid; -} - - -static rnd_action_t cli_dlg_action_list[] = { - {"cli_PromptFor", rnd_act_cli_PromptFor, rnd_acth_cli, NULL}, - {"cli_MessageBox", rnd_act_cli_MessageBox, rnd_acth_cli, NULL} -}; - - -void rnd_hid_nogui_init2(void) -{ - RND_REGISTER_ACTIONS(cli_dlg_action_list, NULL); -} - Index: trunk/src/librnd/core/hid_nogui.h =================================================================== --- trunk/src/librnd/core/hid_nogui.h (revision 34601) +++ trunk/src/librnd/core/hid_nogui.h (nonexistent) @@ -1,16 +0,0 @@ -#ifndef RND_HID_COMMON_HIDNOGUI_H -#define RND_HID_COMMON_HIDNOGUI_H - -void rnd_hid_nogui_init(rnd_hid_t * hid); -rnd_hid_t *rnd_hid_nogui_get_hid(void); - -/* For checking if attr dialogs are not available: */ -void *rnd_nogui_attr_dlg_new(rnd_hid_t *hid, const char *id, rnd_hid_attribute_t *attrs_, int n_attrs_, const char *title_, void *caller_data, rnd_bool modal, void (*button_cb)(void *caller_data, rnd_hid_attr_ev_t ev), int defx, int defy, int minx, int miny); - -int rnd_nogui_progress(long so_far, long total, const char *message); - -/* Return a line of user input text, stripped of any newline characters. - Returns NULL if the user simply presses enter, or otherwise gives no input. */ -char *rnd_nogui_read_stdin_line(void); - -#endif Index: trunk/src/librnd/core/anyload_act.c =================================================================== --- trunk/src/librnd/core/anyload_act.c (revision 34601) +++ trunk/src/librnd/core/anyload_act.c (nonexistent) @@ -1,65 +0,0 @@ -/* - * COPYRIGHT - * - * librnd, modular 2D CAD framework - * (file imported from: pcb-rnd, interactive printed circuit board design) - * Copyright (C) 2021 Tibor 'Igor2' Palinkas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact: - * Project page: http://repo.hu/projects/librnd - * lead developer: http://repo.hu/projects/librnd/contact.html - * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") - */ - -#include - -#include -#include -#include - -static const char rnd_acts_AnyLoad[] = "AnyLoad([path])"; -static const char rnd_acth_AnyLoad[] = "Load \"anything\" from path (or offer a file selectio dialog if no path specified)\n"; -/* DOC: anyload.html */ -fgw_error_t rnd_act_AnyLoad(fgw_arg_t *res, int argc, fgw_arg_t *argv) -{ - const char *path = NULL; - char *path_free = NULL; - - RND_ACT_MAY_CONVARG(1, FGW_STR, AnyLoad, path = argv[1].val.str); - - if (path == NULL) - path = path_free = rnd_hid_fileselect(rnd_gui, "Import an anyload", NULL, "anyload.lht", NULL, NULL, "anyload", RND_HID_FSD_READ, NULL); - - if (path != NULL) - RND_ACT_IRES(rnd_anyload(RND_ACT_HIDLIB, path)); - else - RND_ACT_IRES(-1); - - free(path_free); - - return 0; -} - - -static rnd_action_t anyload_action_list[] = { - {"AnyLoad", rnd_act_AnyLoad, rnd_acth_AnyLoad, rnd_acts_AnyLoad}, -}; - -void rnd_anyload_act_init2(void) -{ - RND_REGISTER_ACTIONS(anyload_action_list, NULL); -} Index: trunk/src/librnd/core/hid_dad_spin.c =================================================================== --- trunk/src/librnd/core/hid_dad_spin.c (revision 34601) +++ trunk/src/librnd/core/hid_dad_spin.c (nonexistent) @@ -1,672 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * Copyright (C) 2019..2021 Tibor 'Igor2' Palinkas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact: - * Project page: http://repo.hu/projects/pcb-rnd - * lead developer: http://repo.hu/projects/pcb-rnd/contact.html - * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") - */ - -/* Compound DAD widget for numeric value entry, creating a spinbox */ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -gdl_list_t rnd_dad_coord_spins; - -const char *rnd_hid_dad_spin_up[] = { -"5 3 2 1", -" c None", -"+ c #000000", -" + ", -" +++ ", -"+++++", -}; - -const char *rnd_hid_dad_spin_down[] = { -"5 3 2 1", -" c None", -"+ c #000000", -"+++++", -" +++ ", -" + ", -}; - -const char *rnd_hid_dad_spin_unit[] = { -"4 4 2 1", -" c None", -"+ c #000000", -"+ +", -"+ +", -"+ +", -" ++ ", -}; - -const char *rnd_hid_dad_spin_warn[] = { -"9 9 3 1", -" c None", -"+ c #000000", -"* c #FF0000", -" ******* ", -"** **", -"* + + *", -"* + + *", -"* + + + *", -"* + + + *", -"* +++++ *", -"** **", -" ******* ", -}; - -static void spin_changed(void *hid_ctx, void *caller_data, rnd_hid_dad_spin_t *spin, rnd_hid_attribute_t *end) -{ - const char *s; - rnd_hid_attribute_t *str = end - spin->cmp.wend + spin->wstr; - - end->changed = 1; - - /* determine whether textual input is empty and indicate that in the compound end widget */ - s = str->val.str; - if (s == NULL) s = ""; - while(isspace(*s)) s++; - end->empty = (*s == '\0'); - - if (end->change_cb != NULL) - end->change_cb(hid_ctx, caller_data, end); -} - -static void spin_warn(void *hid_ctx, rnd_hid_dad_spin_t *spin, rnd_hid_attribute_t *end, const char *msg) -{ - rnd_gui->attr_dlg_widget_hide(hid_ctx, spin->wwarn, (msg == NULL)); - if (rnd_gui->attr_dlg_set_help != NULL) - rnd_gui->attr_dlg_set_help(hid_ctx, spin->wwarn, msg); -} - -static char *gen_str_coord(rnd_hid_dad_spin_t *spin, rnd_coord_t c, char *buf, int buflen) -{ - const rnd_unit_t *unit; - if (spin->unit != NULL) - unit = spin->unit; - else - unit = rnd_conf.editor.grid_unit; - if (buf != NULL) { - rnd_snprintf(buf, buflen, "%.06$m*", unit->suffix, c); - return buf; - } - return rnd_strdup_printf("%.06$m*", unit->suffix, c); -} - -typedef struct { - RND_DAD_DECL_NOINIT(dlg) - rnd_hid_attribute_t *end; - int wout, wunit, wstick, wglob, valid; - char buf[128]; -} spin_unit_t; - -static void spin_unit_chg_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) -{ - rnd_hid_attr_val_t hv; - spin_unit_t *su = (spin_unit_t *)caller_data; - const rnd_unit_t *unit; - int unum = su->dlg[su->wunit].val.lng; - int can_glob = su->wglob > 0; - int is_globbing = &su->dlg[su->wglob] == attr; - - if (!can_glob) - unit = &rnd_units[unum]; - else if ((!is_globbing) && (unum >= 0) && (unum < rnd_get_n_units(0))) - unit = &rnd_units[unum]; - else - unit = rnd_conf.editor.grid_unit; - - if (is_globbing && su->dlg[su->wglob].val.lng) { - /* global ticked in: also set the unit by force */ - unum = rnd_conf.editor.grid_unit - rnd_units; - hv.lng = unum; - rnd_gui->attr_dlg_set_value(hid_ctx, su->wunit, &hv); - } - - rnd_snprintf(su->buf, sizeof(su->buf), "%$m*", unit->suffix, su->end->val.crd); - hv.str = su->buf; - rnd_gui->attr_dlg_set_value(hid_ctx, su->wout, &hv); - if (!is_globbing && can_glob) { - /* unit changed: disable global, accept the user wants to use this unit */ - hv.lng = 0; - rnd_gui->attr_dlg_set_value(hid_ctx, su->wglob, &hv); - } - su->valid = 1; -} - -static void spin_unit_dialog(void *spin_hid_ctx, rnd_hid_dad_spin_t *spin, rnd_hid_attribute_t *end, rnd_hid_attribute_t *str) -{ - rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", -1}, {"ok", 0}, {NULL, 0}}; - spin_unit_t ctx; - const rnd_unit_t *def_unit; - int dlgfail; - - memset(&ctx, 0, sizeof(ctx)); - ctx.end = end; - - def_unit = spin->unit == NULL ? rnd_conf.editor.grid_unit : spin->unit; - - RND_DAD_BEGIN_VBOX(ctx.dlg); - RND_DAD_COMPFLAG(ctx.dlg, RND_HATF_EXPFILL); - RND_DAD_BEGIN_TABLE(ctx.dlg, 2); - RND_DAD_COMPFLAG(ctx.dlg, RND_HATF_FRAME); - RND_DAD_LABEL(ctx.dlg, "Original:"); - RND_DAD_LABEL(ctx.dlg, str->val.str); - RND_DAD_LABEL(ctx.dlg, "With new unit:"); - RND_DAD_LABEL(ctx.dlg, ""); - ctx.wout = RND_DAD_CURRENT(ctx.dlg); - RND_DAD_END(ctx.dlg); - - - RND_DAD_BEGIN_TABLE(ctx.dlg, 2); - RND_DAD_LABEL(ctx.dlg, "Preferred unit"); - RND_DAD_UNIT(ctx.dlg, spin->unit_family); - ctx.wunit = RND_DAD_CURRENT(ctx.dlg); - RND_DAD_HELP(ctx.dlg, "Convert value to this unit and rewrite\nthe text entry field with the converted value."); - RND_DAD_DEFAULT_PTR(ctx.dlg, def_unit); - RND_DAD_CHANGE_CB(ctx.dlg, spin_unit_chg_cb); - - if (spin->unit_family == (RND_UNIT_METRIC | RND_UNIT_IMPERIAL)) { - RND_DAD_LABEL(ctx.dlg, "Use the global"); - RND_DAD_BOOL(ctx.dlg); - RND_DAD_HELP(ctx.dlg, "Ignore the above unit selection,\nuse the global unit (grid unit) in this spinbox,\nfollow changes of the global unit"); - ctx.wglob = RND_DAD_CURRENT(ctx.dlg); - RND_DAD_DEFAULT_NUM(ctx.dlg, (spin->unit == NULL)); - RND_DAD_CHANGE_CB(ctx.dlg, spin_unit_chg_cb); - - RND_DAD_LABEL(ctx.dlg, "Stick to unit"); - RND_DAD_BOOL(ctx.dlg); - RND_DAD_HELP(ctx.dlg, "Upon any update from software, switch back to\the selected unit even if the user specified\na different unit in the text field."); - ctx.wstick = RND_DAD_CURRENT(ctx.dlg); - RND_DAD_DEFAULT_NUM(ctx.dlg, spin->no_unit_chg); - RND_DAD_CHANGE_CB(ctx.dlg, spin_unit_chg_cb); - } - else { - ctx.wglob = -1; - ctx.wstick = -1; - } - - RND_DAD_END(ctx.dlg); - - RND_DAD_BEGIN_HBOX(ctx.dlg); - RND_DAD_COMPFLAG(ctx.dlg, RND_HATF_EXPFILL); - RND_DAD_BEGIN_HBOX(ctx.dlg); - RND_DAD_COMPFLAG(ctx.dlg, RND_HATF_EXPFILL); - RND_DAD_END(ctx.dlg); - RND_DAD_BUTTON_CLOSES(ctx.dlg, clbtn); - RND_DAD_END(ctx.dlg); - RND_DAD_END(ctx.dlg); - - RND_DAD_AUTORUN("unit", ctx.dlg, "spinbox coord unit change", &ctx, dlgfail); - if ((dlgfail == 0) && (ctx.valid)) { - rnd_hid_attr_val_t hv; - int unum = ctx.dlg[ctx.wunit].val.lng; - int can_glob = (spin->unit_family == (RND_UNIT_METRIC | RND_UNIT_IMPERIAL)); - - if (!can_glob) - spin->unit = &rnd_units[unum]; - else if ((!ctx.dlg[ctx.wglob].val.lng) && (unum >= 0) && (unum < rnd_get_n_units(0))) - spin->unit = &rnd_units[unum]; - else - spin->unit = NULL; - - if (can_glob) - spin->no_unit_chg = ctx.dlg[ctx.wstick].val.lng; - else - spin->no_unit_chg = 1; - - hv.str = rnd_strdup(ctx.buf); - rnd_gui->attr_dlg_set_value(spin_hid_ctx, spin->wstr, &hv); - } - - RND_DAD_FREE(ctx.dlg); -} - -static double get_step(rnd_hid_dad_spin_t *spin, rnd_hid_attribute_t *end, rnd_hid_attribute_t *str) -{ - double v, step; - const rnd_unit_t *unit; - - if (spin->step > 0) - return spin->step; - - switch(spin->type) { - case RND_DAD_SPIN_INT: - step = pow(10, floor(log10(fabs((double)end->val.lng)) - 1.0)); - if (step < 1) - step = 1; - break; - case RND_DAD_SPIN_DOUBLE: - case RND_DAD_SPIN_FREQ: - v = end->val.dbl; - if (v == 0) - v = spin->vmax / 10; - if (v == 0) - step = 1; - else - step = pow(10, floor(log10(fabs(v)) - 1.0)); - break; - case RND_DAD_SPIN_COORD: - if (spin->unit == NULL) { - rnd_bool succ = 0; - if (str->val.str != NULL) - succ = rnd_get_value_unit(str->val.str, NULL, 0, &v, &unit); - if (!succ) { - v = end->val.crd; - unit = rnd_conf.editor.grid_unit; - } - } - else - unit = spin->unit; - v = rnd_coord_to_unit(unit, end->val.crd); - step = pow(10, floor(log10(fabs(v)) - 1.0)); - if (step <= 0.0) - step = 1; - step = rnd_unit_to_coord(unit, step); - break; - } - return step; -} - -#define SPIN_CLAMP(dst) \ - do { \ - if ((spin->vmin_valid) && (dst < spin->vmin)) { \ - dst = spin->vmin; \ - warn = "Value already at the minimum"; \ - } \ - if ((spin->vmax_valid) && (dst > spin->vmax)) { \ - dst = spin->vmax; \ - warn = "Value already at the maximum"; \ - } \ - } while(0) - -static void do_step(void *hid_ctx, rnd_hid_dad_spin_t *spin, rnd_hid_attribute_t *str, rnd_hid_attribute_t *end, double step) -{ - rnd_hid_attr_val_t hv; - const char *warn = NULL; - char buf[128]; - - switch(spin->type) { - case RND_DAD_SPIN_INT: - end->val.lng += step; - SPIN_CLAMP(end->val.lng); - sprintf(buf, "%ld", end->val.lng); - break; - case RND_DAD_SPIN_DOUBLE: - case RND_DAD_SPIN_FREQ: - end->val.dbl += step; - SPIN_CLAMP(end->val.dbl); - sprintf(buf, "%f", end->val.dbl); - break; - case RND_DAD_SPIN_COORD: - end->val.crd += step; - SPIN_CLAMP(end->val.crd); - spin->last_good_crd = end->val.crd; - gen_str_coord(spin, end->val.crd, buf, sizeof(buf)); - break; - } - - spin_warn(hid_ctx, spin, end, warn); - hv.str = rnd_strdup(buf); - spin->set_writeback_lock++; - rnd_gui->attr_dlg_set_value(hid_ctx, spin->wstr, &hv); - spin->set_writeback_lock--; -} - -void rnd_dad_spin_up_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) -{ - rnd_hid_dad_spin_t *spin = (rnd_hid_dad_spin_t *)attr->user_data; - rnd_hid_attribute_t *str = attr - spin->wup + spin->wstr; - rnd_hid_attribute_t *end = attr - spin->wup + spin->cmp.wend; - - rnd_dad_spin_txt_enter_cb_dry(hid_ctx, caller_data, str); /* fix up missing unit */ - - do_step(hid_ctx, spin, str, end, get_step(spin, end, str)); - spin_changed(hid_ctx, caller_data, spin, end); - rnd_dad_spin_txt_enter_call_users(hid_ctx, end); -} - -void rnd_dad_spin_down_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) -{ - rnd_hid_dad_spin_t *spin = (rnd_hid_dad_spin_t *)attr->user_data; - rnd_hid_attribute_t *str = attr - spin->wdown + spin->wstr; - rnd_hid_attribute_t *end = attr - spin->wdown + spin->cmp.wend; - - rnd_dad_spin_txt_enter_cb_dry(hid_ctx, caller_data, str); /* fix up missing unit */ - - do_step(hid_ctx, spin, str, end, -get_step(spin, end, str)); - spin_changed(hid_ctx, caller_data, spin, end); - rnd_dad_spin_txt_enter_call_users(hid_ctx, end); -} - -static int is_str_zero(const char *s) -{ - if (s == NULL) return 0; - - /* leading whitepsace */ - while(isspace(*s)) s++; - - /* 00.000 */ - while(*s == '0') s++; - if (*s == '.') { - s++; - while(*s == '0') s++; - } - - /* trailing whitepsace */ - while(isspace(*s)) s++; - - return *s == '\0'; -} - -void rnd_dad_spin_txt_change_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) -{ - rnd_hid_dad_spin_t *spin = (rnd_hid_dad_spin_t *)attr->user_data; - rnd_hid_attribute_t *str = attr; - rnd_hid_attribute_t *end = attr - spin->wstr + spin->cmp.wend; - char *ends, *warn = NULL; - long l; - double d; - rnd_bool succ, absolute; - const rnd_unit_t *unit; - - if (spin->set_writeback_lock) - return; - - switch(spin->type) { - case RND_DAD_SPIN_INT: - l = strtol(str->val.str, &ends, 10); - SPIN_CLAMP(l); - if (*ends != '\0') - warn = "Invalid integer - result is truncated"; - end->val.lng = l; - break; - case RND_DAD_SPIN_DOUBLE: - d = strtod(str->val.str, &ends); - SPIN_CLAMP(d); - if (*ends != '\0') - warn = "Invalid numeric - result is truncated"; - end->val.dbl = d; - break; - case RND_DAD_SPIN_COORD: - /* special case: 0 is okay without unit */ - if (is_str_zero(str->val.str)) { - end->val.crd = 0; - spin->last_good_crd = 0; - break; - } - succ = rnd_get_value_unit(str->val.str, &absolute, 0, &d, &unit); - if (succ) { - SPIN_CLAMP(d); - end->val.crd = d; - spin->last_good_crd = d; - } - else { - warn = "Invalid coord value or unit - result is truncated"; - end->val.crd = spin->last_good_crd; - } - if (!spin->no_unit_chg) - spin->unit = unit; - break; - default: rnd_trace("INTERNAL ERROR: spin_set_num\n"); - } - - spin_warn(hid_ctx, spin, end, warn); - spin_changed(hid_ctx, caller_data, spin, end); -} - -void rnd_dad_spin_txt_enter_cb_dry(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) -{ - rnd_hid_dad_spin_t *spin = (rnd_hid_dad_spin_t *)attr->user_data; - rnd_hid_attribute_t *str = attr; - rnd_hid_attribute_t *end = attr - spin->wstr + spin->cmp.wend; - const char *inval; - char *ends, *warn = NULL; - int changed = 0; - double d; - rnd_bool succ, absolute; - const rnd_unit_t *unit; - - if (spin->set_writeback_lock) - return; - - switch(spin->type) { - case RND_DAD_SPIN_COORD: - inval = str->val.str; - while(isspace(*inval)) inval++; - if (*inval == '\0') - inval = "0"; - succ = rnd_get_value_unit(inval, &absolute, 0, &d, &unit); - if (succ) - break; - strtod(inval, &ends); - while(isspace(*ends)) ends++; - if (*ends == '\0') { - rnd_hid_attr_val_t hv; - char *tmp = rnd_concat(inval, " ", rnd_conf.editor.grid_unit->suffix, NULL); - - changed = 1; - hv.str = tmp; - spin->set_writeback_lock++; - rnd_gui->attr_dlg_set_value(hid_ctx, spin->wstr, &hv); - spin->set_writeback_lock--; - succ = rnd_get_value_unit(str->val.str, &absolute, 0, &d, &unit); - if (succ) { - end->val.crd = d; - spin->last_good_crd = d; - } - free(tmp); - } - break; - default: - /* don't do anything extra for the rest */ - break; - } - - if (changed) { - spin_warn(hid_ctx, spin, end, warn); - spin_changed(hid_ctx, caller_data, spin, end); - } -} - -void rnd_dad_spin_txt_enter_call_users(void *hid_ctx, rnd_hid_attribute_t *end) -{ - struct { - void *caller_data; - } *hc = hid_ctx; - - if (end->enter_cb != NULL) - end->enter_cb(hid_ctx, hc->caller_data, end); -} - -void rnd_dad_spin_txt_enter_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) -{ - rnd_hid_dad_spin_t *spin = (rnd_hid_dad_spin_t *)attr->user_data; - rnd_hid_attribute_t *end = attr - spin->wstr + spin->cmp.wend; - - rnd_dad_spin_txt_enter_cb_dry(hid_ctx, caller_data, attr); - rnd_dad_spin_txt_enter_call_users(hid_ctx, end); -} - - -void rnd_dad_spin_unit_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) -{ - rnd_hid_dad_spin_t *spin = (rnd_hid_dad_spin_t *)attr->user_data; - rnd_hid_attribute_t *str = attr - spin->wunit + spin->wstr; - rnd_hid_attribute_t *end = attr - spin->wunit + spin->cmp.wend; - spin_unit_dialog(hid_ctx, spin, end, str); -} - -void rnd_dad_spin_set_num(rnd_hid_attribute_t *attr, long l, double d, rnd_coord_t c) -{ - rnd_hid_dad_spin_t *spin = attr->wdata; - rnd_hid_attribute_t *str = attr - spin->cmp.wend + spin->wstr; - - switch(spin->type) { - case RND_DAD_SPIN_INT: - attr->val.lng = l; - free((char *)str->val.str); - str->val.str = rnd_strdup_printf("%ld", l); - break; - case RND_DAD_SPIN_DOUBLE: - attr->val.dbl = d; - free((char *)str->val.str); - str->val.str = rnd_strdup_printf("%f", d); - break; - case RND_DAD_SPIN_COORD: - attr->val.crd = c; - spin->last_good_crd = c; - spin->unit = NULL; - free((char *)str->val.str); - str->val.str = gen_str_coord(spin, c, NULL, 0); - break; - default: rnd_trace("INTERNAL ERROR: spin_set_num\n"); - } -} - -void rnd_dad_spin_free(rnd_hid_attribute_t *attr) -{ - if (attr->type == RND_HATT_END) { - rnd_hid_dad_spin_t *spin = attr->wdata; - if (spin->type == RND_DAD_SPIN_COORD) - gdl_remove(&rnd_dad_coord_spins, spin, link); - free(spin); - } -} - -int rnd_dad_spin_widget_state(rnd_hid_attribute_t *end, void *hid_ctx, int idx, rnd_bool enabled) -{ - rnd_hid_dad_spin_t *spin = end->wdata; - return rnd_gui->attr_dlg_widget_state(hid_ctx, spin->wall, enabled); -} - -int rnd_dad_spin_widget_hide(rnd_hid_attribute_t *end, void *hid_ctx, int idx, rnd_bool hide) -{ - rnd_hid_dad_spin_t *spin = end->wdata; - return rnd_gui->attr_dlg_widget_hide(hid_ctx, spin->wall, hide); -} - -int rnd_dad_spin_set_value(rnd_hid_attribute_t *end, void *hid_ctx, int idx, const rnd_hid_attr_val_t *val) -{ - rnd_hid_dad_spin_t *spin = end->wdata; - rnd_hid_attribute_t *str = end - spin->cmp.wend + spin->wstr; - - /* do not modify the text field if the value is the same */ - switch(spin->type) { - case RND_DAD_SPIN_INT: - if (val->lng == end->val.lng) - return 0; - end->val.lng = val->lng; - break; - case RND_DAD_SPIN_DOUBLE: - case RND_DAD_SPIN_FREQ: - if (val->dbl == end->val.dbl) - return 0; - end->val.dbl = val->dbl; - break; - case RND_DAD_SPIN_COORD: - if (val->crd == end->val.crd) - return 0; - end->val.crd = val->crd; - spin->last_good_crd = val->crd; - break; - } - do_step(hid_ctx, spin, str, end, 0); /* cheap conversion + error checks */ - return 0; -} - -void rnd_dad_spin_set_help(rnd_hid_attribute_t *end, const char *help) -{ - rnd_hid_dad_spin_t *spin = end->wdata; - rnd_hid_attribute_t *str = end - spin->cmp.wend + spin->wstr; - - if ((spin->hid_ctx == NULL) || (*spin->hid_ctx == NULL)) /* while building */ - str->help_text = help; - else if (rnd_gui->attr_dlg_set_help != NULL) /* when the dialog is already running */ - rnd_gui->attr_dlg_set_help(*spin->hid_ctx, spin->wstr, help); -} - -void rnd_dad_spin_update_global_coords(void) -{ - rnd_hid_dad_spin_t *spin; - - - for(spin = gdl_first(&rnd_dad_coord_spins); spin != NULL; spin = gdl_next(&rnd_dad_coord_spins, spin)) { - rnd_hid_attribute_t *dlg; - void *hid_ctx; - - if ((spin->unit != NULL) || (spin->attrs == NULL) || (*spin->attrs == NULL) || (spin->hid_ctx == NULL) || (*spin->hid_ctx == NULL)) - continue; - - dlg = *spin->attrs; - hid_ctx = *spin->hid_ctx; - do_step(hid_ctx, spin, &dlg[spin->wstr], &dlg[spin->cmp.wend], 0); /* cheap conversion*/ - } -} - -void rnd_dad_spin_update_internal(rnd_hid_dad_spin_t *spin) -{ - rnd_hid_attribute_t *dlg = *spin->attrs, *end = dlg+spin->cmp.wend; - rnd_hid_attribute_t *str = dlg + spin->wstr; - void *hid_ctx = *spin->hid_ctx; - char buf[128]; - - if (hid_ctx == NULL) /* before run() */ - str->val.str = rnd_strdup(gen_str_coord(spin, end->val.crd, buf, sizeof(buf))); - else - do_step(hid_ctx, spin, &dlg[spin->wstr], &dlg[spin->cmp.wend], 0); /* cheap conversion*/ -} - -void rnd_dad_spin_set_geo(rnd_hid_attribute_t *end, rnd_hatt_compflags_t flg, int geo) -{ - rnd_hid_dad_spin_t *spin = end->wdata; - rnd_hid_attribute_t *str = end - spin->cmp.wend + spin->wstr; - - if (flg == RND_HATF_HEIGHT_CHR) { - str->hatt_flags |= RND_HATF_HEIGHT_CHR; - str->geo_width = geo; - } -} - -void rnd_dad_spin_set_field_num(rnd_hid_attribute_t *end, const char *fieldname, long l, double d, rnd_coord_t c) -{ - rnd_hid_dad_spin_t *spin = end->wdata; - if (strcmp(fieldname, "max_val") == 0) { - spin->vmax_valid = 1; - spin->vmax = d; - } - else if (strcmp(fieldname, "min_val") == 0) { - spin->vmin_valid = 1; - spin->vmin = d; - } -} - Index: trunk/src/librnd/core/hid_dad_unit.c =================================================================== --- trunk/src/librnd/core/hid_dad_unit.c (revision 34601) +++ trunk/src/librnd/core/hid_dad_unit.c (nonexistent) @@ -1,135 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * Copyright (C) 2019 Tibor 'Igor2' Palinkas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact: - * Project page: http://repo.hu/projects/pcb-rnd - * lead developer: http://repo.hu/projects/pcb-rnd/contact.html - * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") - */ - -/* Compound DAD widget for numeric value entry, creating a spinbox */ - -#include - -#include -#include -#include -#include - -void rnd_dad_unit_change_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) -{ - rnd_hid_dad_unit_t *unit = (rnd_hid_dad_unit_t *)attr->user_data; - rnd_hid_attribute_t *enu = attr; - rnd_hid_attribute_t *end = attr - unit->wenum + unit->cmp.wend; - const char **vals = enu->wdata; - const rnd_unit_t *u = get_unit_by_suffix(vals[enu->val.lng]); - int unit_id = u == NULL ? -1 : u - rnd_units; - - end->val.lng = unit_id; - end->changed = 1; - if (end->change_cb != NULL) - end->change_cb(hid_ctx, caller_data, end); -} - -void rnd_dad_unit_set_num(rnd_hid_attribute_t *attr, long unit_id, double unused1, rnd_coord_t unused2) -{ - int l; - rnd_hid_dad_unit_t *unit = attr->wdata; - rnd_hid_attribute_t *enu = attr - unit->cmp.wend + unit->wenum; - const char *target = rnd_units[unit_id].suffix; - const char **vals = enu->wdata; - - for(l = 0; vals[l] != NULL; l++) { - if (strcmp(target, vals[l]) == 0) { - enu->val.lng = l; - attr->val.lng = l; - } - } -} - -void rnd_dad_unit_set_val_ptr(rnd_hid_attribute_t *end, void *val_) -{ - const rnd_unit_t *val = val_; - int __n__, __v__ = rnd_get_n_units(1); - if (val != NULL) { - for(__n__ = 0; __n__ < __v__; __n__++) { - if (&rnd_units[__n__] == val) { - rnd_dad_unit_set_num(end, __n__, 0, 0); - return; - } - } - } -} - -int rnd_dad_unit_widget_state(rnd_hid_attribute_t *end, void *hid_ctx, int idx, rnd_bool enabled) -{ - rnd_hid_dad_unit_t *unit = end->wdata; - return rnd_gui->attr_dlg_widget_state(hid_ctx, unit->wenum, enabled); -} - -int rnd_dad_unit_widget_hide(rnd_hid_attribute_t *end, void *hid_ctx, int idx, rnd_bool hide) -{ - rnd_hid_dad_unit_t *unit = end->wdata; - return rnd_gui->attr_dlg_widget_hide(hid_ctx, unit->wenum, hide); -} - -int rnd_dad_unit_set_value(rnd_hid_attribute_t *end, void *hid_ctx, int idx, const rnd_hid_attr_val_t *val) -{ - rnd_hid_dad_unit_t *unit = end->wdata; - if (rnd_gui->attr_dlg_set_value(hid_ctx, unit->wenum, val) != 0) - return -1; - end->val.lng = val->lng; - return 0; -} - -void rnd_dad_unit_set_help(rnd_hid_attribute_t *end, const char *help) -{ - rnd_hid_dad_unit_t *unit = end->wdata; - rnd_hid_attribute_t *enu = end - unit->cmp.wend + unit->wenum; - - if ((unit->hid_ctx == NULL) || (*unit->hid_ctx == NULL)) /* while building */ - enu->help_text = help; - else if (rnd_gui->attr_dlg_set_help != NULL) /* when the dialog is already running */ - rnd_gui->attr_dlg_set_help(*unit->hid_ctx, unit->wenum, help); -} - -const char **rnd_dad_unit_enum = NULL; - -void rnd_dad_unit_init(enum rnd_family_e family) -{ - int len, n, i; - - if (rnd_dad_unit_enum != NULL) - return; - - len = rnd_get_n_units(0); - rnd_dad_unit_enum = malloc(sizeof(char *) * (len+1)); - for(n = i = 0; i < len; i++) { - if (rnd_units[i].family & family) - rnd_dad_unit_enum[n++] = rnd_units[i].suffix; - } - rnd_dad_unit_enum[n] = NULL; -} - -void rnd_dad_unit_uninit(void) -{ - free(rnd_dad_unit_enum); - rnd_dad_unit_enum = NULL; -} Index: trunk/src/librnd/core/hid_dad_spin.h =================================================================== --- trunk/src/librnd/core/hid_dad_spin.h (revision 34601) +++ trunk/src/librnd/core/hid_dad_spin.h (nonexistent) @@ -1,166 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * Copyright (C) 2019 Tibor 'Igor2' Palinkas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact: - * Project page: http://repo.hu/projects/pcb-rnd - * lead developer: http://repo.hu/projects/pcb-rnd/contact.html - * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") - */ - -/* Compound DAD widget for numeric value entry, creating a spinbox */ - -#ifndef RND_HID_DAD_SPIN_H -#define RND_HID_DAD_SPIN_H - -#include - -typedef struct { - rnd_hid_compound_t cmp; - double step; /* how much an up/down step modifies; 0 means automatic */ - double vmin, vmax; - unsigned vmin_valid:1; - unsigned vmax_valid:1; - unsigned no_unit_chg:1; - int wall, wstr, wup, wdown, wunit, wwarn; - const rnd_unit_t *unit; /* for RND_DAD_SPIN_COORD and RND_DAD_SPIN_FREQ only: current unit */ - rnd_family_t unit_family; - rnd_hid_attribute_t **attrs; - void **hid_ctx; - int set_writeback_lock; - rnd_coord_t last_good_crd; - enum { - RND_DAD_SPIN_INT, - RND_DAD_SPIN_DOUBLE, - RND_DAD_SPIN_COORD, - RND_DAD_SPIN_FREQ - } type; - rnd_hid_attr_type_t wtype; - gdl_elem_t link; - - /* Spare: see doc/developer/spare.txt */ - void (*spare_f1)(void), (*spare_f2)(void); - long spare_l1, spare_l2, spare_l3, spare_l4; - void *spare_p1, *spare_p2, *spare_p3, *spare_p4; - double spare_d1, spare_d2, spare_d3, spare_d4; - rnd_coord_t spare_c1, spare_c2, spare_c3, spare_c4; -} rnd_hid_dad_spin_t; - -#define RND_DAD_SPIN_INT(table) RND_DAD_SPIN_ANY(table, RND_DAD_SPIN_INT, RND_HATT_INTEGER, 0, 0) -#define RND_DAD_SPIN_DOUBLE(table) RND_DAD_SPIN_ANY(table, RND_DAD_SPIN_DOUBLE, RND_HATT_REAL, 0, 0) -#define RND_DAD_SPIN_COORD(table) RND_DAD_SPIN_ANY(table, RND_DAD_SPIN_COORD, RND_HATT_COORD, 1, RND_UNIT_METRIC | RND_UNIT_IMPERIAL) -#define RND_DAD_SPIN_FREQ(table) RND_DAD_SPIN_ANY(table, RND_DAD_SPIN_FREQ, RND_HATT_REAL, 1, RND_UNIT_FREQ) - -/* Return the widget-type (RND_DAD_HATT) of a spinbox at the RND_HATT_END widget; - useful for dispatching what value set to use */ -#define RND_DAD_SPIN_GET_TYPE(attr) \ - ((((attr)->type == RND_HATT_END) && (((rnd_hid_dad_spin_t *)((attr)->wdata))->cmp.free == rnd_dad_spin_free)) ? ((rnd_hid_dad_spin_t *)((attr)->wdata))->wtype : RND_HATT_END) - -/*** implementation ***/ - -#define RND_DAD_SPIN_ANY(table, typ, wtyp, has_unit, unit_family_) \ -do { \ - rnd_hid_dad_spin_t *spin = calloc(sizeof(rnd_hid_dad_spin_t), 1); \ - RND_DAD_BEGIN(table, RND_HATT_BEGIN_COMPOUND); \ - spin->cmp.wbegin = RND_DAD_CURRENT(table); \ - RND_DAD_SET_ATTR_FIELD(table, wdata, spin); \ - RND_DAD_BEGIN_HBOX(table); \ - spin->wall = RND_DAD_CURRENT(table); \ - RND_DAD_COMPFLAG(table, RND_HATF_TIGHT); \ - RND_DAD_STRING(table); \ - RND_DAD_DEFAULT_PTR(table, rnd_strdup("")); \ - RND_DAD_ENTER_CB(table, rnd_dad_spin_txt_enter_cb); \ - RND_DAD_CHANGE_CB(table, rnd_dad_spin_txt_change_cb); \ - RND_DAD_SET_ATTR_FIELD(table, user_data, (const char **)spin); \ - spin->wstr = RND_DAD_CURRENT(table); \ - RND_DAD_BEGIN_VBOX(table); \ - RND_DAD_COMPFLAG(table, RND_HATF_TIGHT); \ - RND_DAD_PICBUTTON(table, rnd_hid_dad_spin_up); \ - RND_DAD_CHANGE_CB(table, rnd_dad_spin_up_cb); \ - RND_DAD_SET_ATTR_FIELD(table, user_data, (const char **)spin); \ - spin->wup = RND_DAD_CURRENT(table); \ - RND_DAD_PICBUTTON(table, rnd_hid_dad_spin_down); \ - RND_DAD_CHANGE_CB(table, rnd_dad_spin_down_cb); \ - RND_DAD_SET_ATTR_FIELD(table, user_data, (const char **)spin); \ - spin->wdown = RND_DAD_CURRENT(table); \ - RND_DAD_END(table); \ - RND_DAD_BEGIN_VBOX(table); \ - RND_DAD_COMPFLAG(table, RND_HATF_TIGHT); \ - if (has_unit) { \ - RND_DAD_PICBUTTON(table, rnd_hid_dad_spin_unit); \ - RND_DAD_CHANGE_CB(table, rnd_dad_spin_unit_cb); \ - RND_DAD_SET_ATTR_FIELD(table, user_data, (const char **)spin); \ - spin->wunit = RND_DAD_CURRENT(table); \ - } \ - RND_DAD_PICTURE(table, rnd_hid_dad_spin_warn); \ - RND_DAD_COMPFLAG(table, RND_HATF_HIDE); \ - RND_DAD_SET_ATTR_FIELD(table, user_data, (const char **)spin); \ - spin->wwarn = RND_DAD_CURRENT(table); \ - RND_DAD_END(table); \ - RND_DAD_END(table); \ - RND_DAD_END(table); \ - RND_DAD_SET_ATTR_FIELD(table, wdata, spin); \ - spin->cmp.wend = RND_DAD_CURRENT(table); \ - \ - spin->cmp.free = rnd_dad_spin_free; \ - spin->cmp.set_val_num = rnd_dad_spin_set_num; \ - spin->cmp.widget_state = rnd_dad_spin_widget_state; \ - spin->cmp.widget_hide = rnd_dad_spin_widget_hide; \ - spin->cmp.set_value = rnd_dad_spin_set_value; \ - spin->cmp.set_help = rnd_dad_spin_set_help; \ - spin->cmp.set_geo = rnd_dad_spin_set_geo; \ - spin->cmp.set_field_num = rnd_dad_spin_set_field_num; \ - spin->type = typ; \ - spin->wtype = wtyp; \ - spin->attrs = &table; \ - spin->hid_ctx = &table ## _hid_ctx; \ - spin->unit_family = unit_family_; \ - \ - if (typ == RND_DAD_SPIN_COORD) \ - gdl_append(&rnd_dad_coord_spins, spin, link); \ -} while(0) - -extern const char *rnd_hid_dad_spin_up[]; -extern const char *rnd_hid_dad_spin_down[]; -extern const char *rnd_hid_dad_spin_unit[]; -extern const char *rnd_hid_dad_spin_unit[]; -extern const char *rnd_hid_dad_spin_warn[]; - -void rnd_dad_spin_up_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); -void rnd_dad_spin_down_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); -void rnd_dad_spin_txt_enter_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); -void rnd_dad_spin_txt_enter_cb_dry(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); -void rnd_dad_spin_txt_enter_call_users(void *hid_ctx, rnd_hid_attribute_t *end); /* call the user's enter_cb on end */ -void rnd_dad_spin_txt_change_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); -void rnd_dad_spin_unit_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); - -void rnd_dad_spin_free(rnd_hid_attribute_t *attrib); -void rnd_dad_spin_set_num(rnd_hid_attribute_t *attr, long l, double d, rnd_coord_t c); -int rnd_dad_spin_widget_state(rnd_hid_attribute_t *end, void *hid_ctx, int idx, rnd_bool enabled); -int rnd_dad_spin_widget_hide(rnd_hid_attribute_t *end, void *hid_ctx, int idx, rnd_bool hide); -int rnd_dad_spin_set_value(rnd_hid_attribute_t *end, void *hid_ctx, int idx, const rnd_hid_attr_val_t *val); -void rnd_dad_spin_set_help(rnd_hid_attribute_t *end, const char *help); -void rnd_dad_spin_set_geo(rnd_hid_attribute_t *end, rnd_hatt_compflags_t flg, int geo); -void rnd_dad_spin_set_field_num(rnd_hid_attribute_t *attr, const char *fieldname, long l, double d, rnd_coord_t c); - -void rnd_dad_spin_update_internal(rnd_hid_dad_spin_t *spin); /* update the widget from spin, before or after the dialog is realized */ - -extern gdl_list_t rnd_dad_coord_spins; /* list of all active coord spinboxes */ - -#endif Index: trunk/src/librnd/core/hid_dad_unit.h =================================================================== --- trunk/src/librnd/core/hid_dad_unit.h (revision 34601) +++ trunk/src/librnd/core/hid_dad_unit.h (nonexistent) @@ -1,83 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * Copyright (C) 2019 Tibor 'Igor2' Palinkas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact: - * Project page: http://repo.hu/projects/pcb-rnd - * lead developer: http://repo.hu/projects/pcb-rnd/contact.html - * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") - */ - -/* Compound DAD widget for creating a unit change combo box */ - -#ifndef RND_HID_DAD_UNIT_H -#define RND_HID_DAD_UNIT_H - -#include - -#include - -typedef struct { - rnd_hid_compound_t cmp; - void **hid_ctx; - rnd_family_t family; /* which families of units are allowed in this spinbox */ - int wenum; -} rnd_hid_dad_unit_t; - -/*** implementation ***/ - - -#define RND_DAD_UNIT(table, family_) \ -do { \ - rnd_hid_dad_unit_t *unit = calloc(sizeof(rnd_hid_dad_unit_t), 1); \ - RND_DAD_BEGIN(table, RND_HATT_BEGIN_COMPOUND); \ - unit->cmp.wbegin = RND_DAD_CURRENT(table); \ - rnd_dad_unit_init(family_); \ - RND_DAD_ENUM(table, rnd_dad_unit_enum); \ - RND_DAD_CHANGE_CB(table, rnd_dad_unit_change_cb); \ - RND_DAD_SET_ATTR_FIELD(table, user_data, (const char **)unit); \ - unit->wenum = RND_DAD_CURRENT(table); \ - RND_DAD_END(table); \ - RND_DAD_SET_ATTR_FIELD(table, wdata, unit); \ - unit->cmp.wend = RND_DAD_CURRENT(table); \ - \ - unit->cmp.set_val_num = rnd_dad_unit_set_num; \ - unit->cmp.widget_state = rnd_dad_unit_widget_state; \ - unit->cmp.widget_hide = rnd_dad_unit_widget_hide; \ - unit->cmp.set_value = rnd_dad_unit_set_value; \ - unit->cmp.set_val_ptr = rnd_dad_unit_set_val_ptr; \ - unit->cmp.set_help = rnd_dad_unit_set_help; \ - unit->family = family_; \ - unit->hid_ctx = &table ## _hid_ctx; \ -} while(0) - -extern const char **rnd_dad_unit_enum; - -void rnd_dad_unit_set_num(rnd_hid_attribute_t *attr, long l, double unused1, rnd_coord_t unused2); -int rnd_dad_unit_widget_state(rnd_hid_attribute_t *end, void *hid_ctx, int idx, rnd_bool enabled); -int rnd_dad_unit_widget_hide(rnd_hid_attribute_t *end, void *hid_ctx, int idx, rnd_bool hide); -int rnd_dad_unit_set_value(rnd_hid_attribute_t *end, void *hid_ctx, int idx, const rnd_hid_attr_val_t *val); -void rnd_dad_unit_set_val_ptr(rnd_hid_attribute_t *end, void *val); -void rnd_dad_unit_set_help(rnd_hid_attribute_t *end, const char *help); -void rnd_dad_unit_change_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); - -void rnd_dad_unit_init(enum rnd_family_e family); -void rnd_dad_unit_uninit(void); - -#endif Index: trunk/src/librnd/core/hid_cfg_input.c =================================================================== --- trunk/src/librnd/core/hid_cfg_input.c (revision 34601) +++ trunk/src/librnd/core/hid_cfg_input.c (nonexistent) @@ -1,835 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * Copyright (C) 2016 Tibor 'Igor2' Palinkas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Contact: - * Project page: http://repo.hu/projects/pcb-rnd - * lead developer: http://repo.hu/projects/pcb-rnd/contact.html - * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* split value into a list of '-' separated words; examine each word - and set the bitmask of modifiers */ -static rnd_hid_cfg_mod_t parse_mods(const char *value, const char **last, unsigned int vlen) -{ - rnd_hid_cfg_mod_t m = 0; - int press = 0; - const char *next; - - while(isspace(*value)) value++; - - if (*value != '<') { - for(;;) { - if ((vlen >= 5) && (rnd_strncasecmp(value, "shift", 5) == 0)) m |= RND_M_Shift; - else if ((vlen >= 4) && (rnd_strncasecmp(value, "ctrl", 4) == 0)) m |= RND_M_Ctrl; - else if ((vlen >= 3) && (rnd_strncasecmp(value, "alt", 3) == 0)) m |= RND_M_Alt; - else if ((vlen >= 7) && (rnd_strncasecmp(value, "release", 7) == 0)) m |= RND_M_Release; - else if ((vlen >= 5) && (rnd_strncasecmp(value, "press", 5) == 0)) press = 1; - else - rnd_message(RND_MSG_ERROR, "Unknown modifier: %s\n", value); - /* skip to next word */ - next = strpbrk(value, "<- \t"); - if (next == NULL) - break; - if (*next == '<') - break; - vlen -= (next - value); - value = next+1; - } - } - - if (last != NULL) - *last = value; - - if (press && (m & RND_M_Release)) - rnd_message(RND_MSG_ERROR, "Bogus modifier: both press and release\n"); - - return m; -} - -static rnd_hid_cfg_mod_t button_name2mask(const char *name) -{ - /* All mouse-related resources must be named. The name is the - mouse button number. */ - if (!name) - return 0; - else if (rnd_strcasecmp(name, "left") == 0) return RND_MB_LEFT; - else if (rnd_strcasecmp(name, "middle") == 0) return RND_MB_MIDDLE; - else if (rnd_strcasecmp(name, "right") == 0) return RND_MB_RIGHT; - - else if (rnd_strcasecmp(name, "scroll-up") == 0) return RND_MB_SCROLL_UP; - else if (rnd_strcasecmp(name, "scroll-down") == 0) return RND_MB_SCROLL_DOWN; - else if (rnd_strcasecmp(name, "scroll-left") == 0) return RND_MB_SCROLL_UP; - else if (rnd_strcasecmp(name, "scroll-right") == 0) return RND_MB_SCROLL_DOWN; - else { - rnd_message(RND_MSG_ERROR, "Error: unknown mouse button: %s\n", name); - return 0; - } -} - -static unsigned int keyhash_int(htip_key_t a) { return murmurhash32(a & 0xFFFF); } - -static unsigned int keyb_hash(const void *key_) -{ - const rnd_hid_cfg_keyhash_t *key = key_; - unsigned int i = 0; - i += key->key_raw; i <<= 8; - i += ((unsigned int)key->key_tr) << 4; - i += key->mods; - return murmurhash32(i); -} - -static int keyb_eq(const void *keya_, const void *keyb_) -{ - const rnd_hid_cfg_keyhash_t *keya = keya_, *keyb = keyb_; - return (keya->key_raw == keyb->key_raw) && (keya->key_tr == keyb->key_tr) && (keya->mods == keyb->mods); -} - -/************************** MOUSE ***************************/ - -int rnd_hid_cfg_mouse_init(rnd_hid_cfg_t *hr, rnd_hid_cfg_mouse_t *mouse) -{ - lht_node_t *btn, *m; - - mouse->mouse = rnd_hid_cfg_get_menu(hr, "/mouse"); - - if (mouse->mouse == NULL) { - rnd_message(RND_MSG_ERROR, "Warning: no /mouse section in the resource file - mouse is disabled\n"); - return -1; - } - - if (mouse->mouse->type != LHT_LIST) { - rnd_hid_cfg_error(mouse->mouse, "Warning: should be a list - mouse is disabled\n"); - return -1; - } - - if (mouse->mouse_mask == NULL) - mouse->mouse_mask = htip_alloc(keyhash_int, htip_keyeq); - else - htip_clear(mouse->mouse_mask); - - for(btn = mouse->mouse->data.list.first; btn != NULL; btn = btn->next) { - rnd_hid_cfg_mod_t btn_mask = button_name2mask(btn->name); - if (btn_mask == 0) { - rnd_hid_cfg_error(btn, "unknown mouse button"); - continue; - } - if (btn->type != LHT_LIST) { - rnd_hid_cfg_error(btn, "needs to be a list"); - continue; - } - for(m = btn->data.list.first; m != NULL; m = m->next) { - rnd_hid_cfg_mod_t mod_mask = parse_mods(m->name, NULL, -1); - htip_set(mouse->mouse_mask, btn_mask|mod_mask, m); - } - } - return 0; -} - -static lht_node_t *find_best_action(rnd_hid_cfg_mouse_t *mouse, rnd_hid_cfg_mod_t button_and_mask) -{ - lht_node_t *n; - - if (mouse->mouse_mask == NULL) - return NULL; - - /* look for exact mod match */ - n = htip_get(mouse->mouse_mask, button_and_mask); - if (n != NULL) - return n; - - if (button_and_mask & RND_M_Release) { - /* look for plain release for the given button */ - n = htip_get(mouse->mouse_mask, (button_and_mask & RND_M_ANY) | RND_M_Release); - if (n != NULL) - return n; - } - - return NULL; -} - -void rnd_hid_cfg_mouse_action(rnd_hidlib_t *hl, rnd_hid_cfg_mouse_t *mouse, rnd_hid_cfg_mod_t button_and_mask, rnd_bool cmd_entry_active) -{ - rnd_conf.temp.click_cmd_entry_active = cmd_entry_active; - rnd_hid_cfg_action(hl, find_best_action(mouse, button_and_mask)); - rnd_event(hl, RND_EVENT_USER_INPUT_POST, NULL); - rnd_conf.temp.click_cmd_entry_active = 0; -} - - -/************************** KEYBOARD ***************************/ -int rnd_hid_cfg_keys_init(rnd_hid_cfg_keys_t *km) -{ - htpp_init(&km->keys, keyb_hash, keyb_eq); - return 0; -} - -static void rnd_hid_cfg_keys_free(htpp_t *ht); - -static void rnd_hid_cfg_key_free(rnd_hid_cfg_keyseq_t *ns) -{ - rnd_hid_cfg_keys_free(&ns->seq_next); - htpp_uninit(&ns->seq_next); - free(ns); -} - -static void rnd_hid_cfg_keys_free(htpp_t *ht) -{ - htpp_entry_t *e; - for(e = htpp_first(ht); e != NULL; e = htpp_next(ht, e)) - rnd_hid_cfg_key_free(e->value); -} - -int rnd_hid_cfg_keys_uninit(rnd_hid_cfg_keys_t *km) -{ - rnd_hid_cfg_keys_free(&km->keys); - htpp_uninit(&km->keys); - return 0; -} - -rnd_hid_cfg_keyseq_t *rnd_hid_cfg_keys_add_under(rnd_hid_cfg_keys_t *km, rnd_hid_cfg_keyseq_t *parent, rnd_hid_cfg_mod_t mods, unsigned short int key_raw, unsigned short int key_tr, int terminal, const char **errmsg) -{ - rnd_hid_cfg_keyseq_t *ns; - rnd_hid_cfg_keyhash_t addr; - htpp_t *phash = (parent == NULL) ? &km->keys : &parent->seq_next; - - /* do not grow the tree under actions */ - if ((parent != NULL) && (parent->action_node != NULL)) { - if (*errmsg != NULL) - *errmsg = "unreachable multikey combo: prefix of the multikey stroke already has an action"; - return NULL; - } - - addr.mods = mods; - addr.key_raw = key_raw; - addr.key_tr = key_tr; - - /* already in the tree */ - ns = htpp_get(phash, &addr); - if (ns != NULL) { - if (terminal) { - if (*errmsg != NULL) - *errmsg = "duplicate: already registered"; - return NULL; /* full-path-match is collision */ - } - return ns; - } - - /* new node on this level */ - ns = calloc(sizeof(rnd_hid_cfg_keyseq_t), 1); - if (!terminal) - htpp_init(&ns->seq_next, keyb_hash, keyb_eq); - - ns->addr.mods = mods; - ns->addr.key_raw = key_raw; - ns->addr.key_tr = key_tr; - - htpp_set(phash, &ns->addr, ns); - return ns; -} - -const rnd_hid_cfg_keytrans_t rnd_hid_cfg_key_default_trans[] = { - { "semicolon", ';' }, - { NULL, 0 }, -}; - -static unsigned short int translate_key(rnd_hid_cfg_keys_t *km, const char *desc, int len) -{ - char tmp[256]; - - if ((km->auto_chr) && (len == 1)) - return *desc; - - if (len > sizeof(tmp)-1) { - rnd_message(RND_MSG_ERROR, "key sym name too long\n"); - return 0; - } - strncpy(tmp, desc, len); - tmp[len] = '\0'; - - if (km->auto_tr != NULL) { - const rnd_hid_cfg_keytrans_t *t; - for(t = km->auto_tr; t->name != NULL; t++) { - if (rnd_strcasecmp(tmp, t->name) == 0) { - tmp[0] = t->sym; - tmp[1] = '\0'; - len = 1; - break; - } - } - } - - return km->translate_key(tmp, len); -} - -static int parse_keydesc(rnd_hid_cfg_keys_t *km, const char *keydesc, rnd_hid_cfg_mod_t *mods, unsigned short int *key_raws, unsigned short int *key_trs, int arr_len, const lht_node_t *loc) -{ - const char *curr, *next, *last, *k; - int slen, len; - - slen = 0; - curr = keydesc; - do { - if (slen >= arr_len) - return -1; - while(isspace(*curr)) curr++; - if (*curr == '\0') - break; - next = strchr(curr, ';'); - if (next != NULL) { - len = next - curr; - while(*next == ';') next++; - } - else - len = strlen(curr); - - mods[slen] = parse_mods(curr, &last, len); - - k = strchr(last, '<'); - if (k == NULL) { - rnd_message(RND_MSG_ERROR, "Missing in the key description: '%s' at %s:%ld\n", keydesc, loc->file_name, loc->line+1); - return -1; - } - len -= k-last; - k++; len--; - if (rnd_strncasecmp(k, "key>", 4) == 0) { - k+=4; len-=4; - key_raws[slen] = translate_key(km, k, len); - key_trs[slen] = 0; - } - else if (rnd_strncasecmp(k, "char>", 5) == 0) { - k+=5; len-=5; - key_raws[slen] = 0; - if (!isalnum(*k)) - key_trs[slen] = *k; - else - key_trs[slen] = 0; - k++; len--; - } - else { - rnd_message(RND_MSG_ERROR, "Missing or in the key description starting at %s at %s:%ld\n", k-1, loc->file_name, loc->line+1); - return -1; - } - - if ((key_raws[slen] == 0) && (key_trs[slen] == 0)) { - char *s; - s = malloc(len+1); - memcpy(s, k, len); - s[len] = '\0'; - rnd_message(RND_MSG_ERROR, "Unrecognised key symbol in key description: %s at %s:%ld\n", s, loc->file_name, loc->line+1); - free(s); - return -1; - } - - slen++; - curr = next; - } while(curr != NULL); - return slen; -} - -int rnd_hid_cfg_keys_add_by_strdesc_(rnd_hid_cfg_keys_t *km, const char *keydesc, const lht_node_t *action_node, rnd_hid_cfg_keyseq_t **out_seq, int out_seq_len) -{ - rnd_hid_cfg_mod_t mods[RND_HIDCFG_MAX_KEYSEQ_LEN]; - unsigned short int key_raws[RND_HIDCFG_MAX_KEYSEQ_LEN]; - unsigned short int key_trs[RND_HIDCFG_MAX_KEYSEQ_LEN]; - rnd_hid_cfg_keyseq_t *lasts; - int slen, n; - const char *errmsg; - - slen = parse_keydesc(km, keydesc, mods, key_raws, key_trs, RND_HIDCFG_MAX_KEYSEQ_LEN, action_node); - if (slen <= 0) - return slen; - - if ((out_seq != NULL) && (slen >= out_seq_len)) - return -1; - -/* printf("KEY insert\n");*/ - - lasts = NULL; - for(n = 0; n < slen; n++) { - rnd_hid_cfg_keyseq_t *s; - int terminal = (n == slen-1); - -/* printf(" mods=%x sym=%x\n", mods[n], key_chars[n]);*/ - - s = rnd_hid_cfg_keys_add_under(km, lasts, mods[n], key_raws[n], key_trs[n], terminal, &errmsg); - if (s == NULL) { - rnd_message(RND_MSG_ERROR, "Failed to add hotkey binding: %s: %s\n", keydesc, errmsg); - return -1; /* no need to free anything, uninit will recursively free the leftover at exit */ - } - if (terminal) - s->action_node = action_node; - - if (out_seq != NULL) - out_seq[n] = s; - lasts = s; - } - - return slen; -} - -int rnd_hid_cfg_keys_add_by_strdesc(rnd_hid_cfg_keys_t *km, const char *keydesc, const lht_node_t *action_node) -{ - return rnd_hid_cfg_keys_add_by_strdesc_(km, keydesc, action_node, NULL, 0); -} - -int rnd_hid_cfg_keys_add_by_desc_(rnd_hid_cfg_keys_t *km, const lht_node_t *keydescn, const lht_node_t *action_node, rnd_hid_cfg_keyseq_t **out_seq, int out_seq_len) -{ - switch(keydescn->type) { - case LHT_TEXT: return rnd_hid_cfg_keys_add_by_strdesc_(km, keydescn->data.text.value, action_node, out_seq, out_seq_len); - case LHT_LIST: - { - int ret = -1, cnt; - lht_node_t *n; - for(n = keydescn->data.list.first, cnt = 0; n != NULL; n = n->next, cnt++) { - if (n->type != LHT_TEXT) - break; - if (cnt == 0) - ret = rnd_hid_cfg_keys_add_by_strdesc_(km, n->data.text.value, action_node, out_seq, out_seq_len); - else - rnd_hid_cfg_keys_add_by_strdesc_(km, n->data.text.value, action_node, NULL, 0); - } - return ret; - } - default:; - } - return -1; -} - -int rnd_hid_cfg_keys_add_by_desc(rnd_hid_cfg_keys_t *km, const lht_node_t *keydescn, const lht_node_t *action_node) -{ - return rnd_hid_cfg_keys_add_by_desc_(km, keydescn, action_node, NULL, 0); -} - -int rnd_hid_cfg_keys_del_by_strdesc(rnd_hid_cfg_keys_t *km, const char *keydesc) -{ - rnd_hid_cfg_mod_t mods[RND_HIDCFG_MAX_KEYSEQ_LEN]; - unsigned short int key_raws[RND_HIDCFG_MAX_KEYSEQ_LEN]; - unsigned short int key_trs[RND_HIDCFG_MAX_KEYSEQ_LEN]; - int slen, n; - htpp_t *phash = &km->keys; - rnd_hid_cfg_keyseq_t *ns; - rnd_hid_cfg_keyhash_t addr; - htpp_entry_t *e; - - slen = parse_keydesc(km, keydesc, mods, key_raws, key_trs, RND_HIDCFG_MAX_KEYSEQ_LEN, NULL); - if (slen <= 0) - return slen; - - for(n = 0; n < slen; n++) { - int terminal = (n == slen-1); - - addr.mods = mods[n]; - addr.key_raw = key_raws[n]; - addr.key_tr = key_trs[n]; - - ns = htpp_get(phash, &addr); - if (ns == NULL) - return -1; - - if (!terminal) - phash = &ns->seq_next; - } - - e = htpp_popentry(phash, &addr); - if (e != NULL) - rnd_hid_cfg_key_free(e->value); - - return 0; -} - -int rnd_hid_cfg_keys_del_by_desc(rnd_hid_cfg_keys_t *km, const lht_node_t *keydescn) -{ - switch(keydescn->type) { - case LHT_TEXT: return rnd_hid_cfg_keys_del_by_strdesc(km, keydescn->data.text.value); - case LHT_LIST: - { - int ret = 0; - lht_node_t *n; - for(n = keydescn->data.list.first; n != NULL; n = n->next) { - if (n->type != LHT_TEXT) - break; - ret |= rnd_hid_cfg_keys_del_by_strdesc(km, n->data.text.value); - } - return ret; - } - default:; - } - return -1; -} - - -static void gen_accel(gds_t *s, rnd_hid_cfg_keys_t *km, const char *keydesc, int *cnt, const char *sep, const lht_node_t *loc) -{ - rnd_hid_cfg_mod_t mods[RND_HIDCFG_MAX_KEYSEQ_LEN]; - unsigned short int key_raws[RND_HIDCFG_MAX_KEYSEQ_LEN]; - unsigned short int key_trs[RND_HIDCFG_MAX_KEYSEQ_LEN]; - int slen, n; - - slen = parse_keydesc(km, keydesc, mods, key_raws, key_trs, RND_HIDCFG_MAX_KEYSEQ_LEN, loc); - if (slen <= 0) - return; - - if (*cnt > 0) - gds_append_str(s, sep); - - for(n = 0; n < slen; n++) { - char buff[64]; - - if (n > 0) - gds_append(s, ' '); - - - if (key_raws[n]) { - if (km->key_name(key_raws[n], buff, sizeof(buff)) != 0) - strcpy(buff, ""); - } - else if (key_trs[n] != 0) { - buff[0] = key_trs[n]; - buff[1] ='\0'; - } - else - strcpy(buff, ""); - - if (mods[n] & RND_M_Alt) gds_append_str(s, "Alt-"); - if (mods[n] & RND_M_Ctrl) gds_append_str(s, "Ctrl-"); - if (mods[n] & RND_M_Shift) gds_append_str(s, "Shift-"); - gds_append_str(s, buff); - } -} - -char *rnd_hid_cfg_keys_gen_accel(rnd_hid_cfg_keys_t *km, const lht_node_t *keydescn, unsigned long mask, const char *sep) -{ - gds_t s; - int cnt = 0; - - memset(&s, 0, sizeof(s)); - - switch(keydescn->type) { - case LHT_TEXT: - if (mask & 1) - gen_accel(&s, km, keydescn->data.text.value, &cnt, sep, keydescn); - break; - case LHT_LIST: - { - int cnt; - lht_node_t *n; - for(n = keydescn->data.list.first, cnt = 0; n != NULL; n = n->next, cnt++, mask >>= 1) { - if (n->type != LHT_TEXT) - break; - if (!(mask & 1)) - continue; - gen_accel(&s, km, n->data.text.value, &cnt, sep, keydescn); - } - } - default:; - } - return s.array; -} - -char *rnd_hid_cfg_keys_gen_desc(rnd_hid_cfg_mod_t mods, unsigned short int key_raw, unsigned short int key_tr) -{ - gds_t s = {0}; - - if (key_tr != 0) { - if ((key_tr <= 32) || (key_tr >= 127)) - return NULL; - gds_append_str(&s, ""); - gds_append(&s, key_tr); - return s.array; - } - - - TODO("We should call km->key_name, but where this call is coming from, km is not available"); - if ((key_raw <= 32) || (key_raw >= 127)) - return NULL; - - if (mods & RND_M_Alt) gds_append_str(&s, "Alt-"); - if (mods & RND_M_Ctrl) gds_append_str(&s, "Ctrl-"); - if (mods & RND_M_Shift) gds_append_str(&s, "Shift-"); - if (s.used > 0) s.used--; /* remove the trailing '-' */ - gds_append_str(&s, ""); - gds_append(&s, key_raw); - return s.array; -} - - -int rnd_hid_cfg_keys_input_(rnd_hidlib_t *hl, rnd_hid_cfg_keys_t *km, rnd_hid_cfg_mod_t mods, unsigned short int key_raw, unsigned short int key_tr, rnd_hid_cfg_keyseq_t **seq, int *seq_len) -{ - rnd_hid_cfg_keyseq_t *ns; - rnd_hid_cfg_keyhash_t addr; - htpp_t *phash = (*seq_len == 0) ? &km->keys : &((seq[(*seq_len)-1])->seq_next); - - if (key_raw == 0) { - static int warned = 0; - if (!warned) { - rnd_message(RND_MSG_ERROR, "Keyboard translation error: probably the US layout is not enabled. Some hotkeys may not work properly\n"); - warned = 1; - } - /* happens if only the translated version is available. Try to reverse - engineer it as good as we can. */ - if (isalpha(key_tr)) { - if (isupper(key_tr)) { - key_raw = tolower(key_tr); - mods |= RND_M_Shift; - } - else - key_raw = key_tr; - } - else if (isdigit(key_tr)) - key_raw = key_tr; - /* the rest: punctuations should be handled by key_tr; special keys: well... */ - } - - /* first check for base key + mods */ - addr.mods = mods; - addr.key_raw = key_raw; - addr.key_tr = 0; - - ns = htpp_get(phash, &addr); - - /* if not found, try with translated key + limited mods */ - if (ns == NULL) { - addr.mods = mods & RND_M_Ctrl; - addr.key_raw = 0; - addr.key_tr = key_tr; - ns = htpp_get(phash, &addr); - } - - /* already in the tree */ - if (ns == NULL) { - (*seq_len) = 0; - return -1; - } - - seq[*seq_len] = ns; - (*seq_len)++; - - /* found a terminal node with an action */ - if (ns->action_node != NULL) { - km->seq_len_action = *seq_len; - (*seq_len) = 0; - rnd_event(hl, RND_EVENT_USER_INPUT_KEY, NULL); - return km->seq_len_action; - } - - rnd_event(hl, RND_EVENT_USER_INPUT_KEY, NULL); - return 0; -} - - -/*** key translation hash ***/ -static int xlate_conf_rev = -1; /* last conf rev the translation table got checked on */ -static int xlate_avail = 0; -static htpp_t xlate_hash; - -static void xlate_uninit(void) -{ - genht_uninit_deep(htpp, &xlate_hash, { - free(htent->key); - free(htent->value); - }); -} - -static void xlate_reload(rnd_hid_cfg_keys_t *km, rnd_conf_native_t *nat) -{ - gdl_iterator_t it; - rnd_conf_listitem_t *kt; - - if (xlate_avail) { - xlate_uninit(); - xlate_avail = 0; - } - - if (rnd_conflist_length(nat->val.list) < 1) - return; - - htpp_init(&xlate_hash, keyb_hash, keyb_eq); - rnd_conflist_foreach(nat->val.list, &it, kt) { - rnd_hid_cfg_keyhash_t k, v, *hk, *hv; - rnd_hid_cfg_mod_t m; - - /* parse key and value to temporary k & v */ - if (parse_keydesc(km, kt->name, &m, &k.key_raw, &k.key_tr, 1, kt->prop.src) != 1) { - rnd_message(RND_MSG_ERROR, "Invalid key translation left side: '%s'\n (config problem, check your editor/translate_key)\n", kt->name); - continue; - } - k.mods = m; - if (parse_keydesc(km, kt->payload, &m, &v.key_raw, &v.key_tr, 1, kt->prop.src) != 1) { - rnd_message(RND_MSG_ERROR, "Invalid key translation left side: '%s'\n (config problem, check your editor/translate_key)\n", kt->payload); - continue; - } - v.mods = m; - hv = htpp_get(&xlate_hash, &k); - if (hv != NULL) { - rnd_message(RND_MSG_ERROR, "Ignoring redundant key translation: '%s'\n (config problem, check your editor/translate_key)\n", kt->payload); - continue; - } - else { - /* new key-val pair, add */ - hk = malloc(sizeof(rnd_hid_cfg_keyhash_t)); memcpy(hk, &k, sizeof(k)); - hv = malloc(sizeof(rnd_hid_cfg_keyhash_t)); memcpy(hv, &v, sizeof(v)); - htpp_insert(&xlate_hash, hk, hv); - } - } - xlate_avail = 1; -} - -int rnd_hid_cfg_keys_input(rnd_hidlib_t *hl, rnd_hid_cfg_keys_t *km, rnd_hid_cfg_mod_t mods, unsigned short int key_raw, unsigned short int key_tr) -{ - rnd_hid_cfg_keyhash_t ck, *cv; - - if (rnd_conf_rev > xlate_conf_rev) { - rnd_conf_native_t *nat = rnd_conf_get_field("editor/translate_key"); - if ((nat != NULL) && (nat->rnd_conf_rev > xlate_conf_rev)) - xlate_reload(km, nat); - xlate_conf_rev = rnd_conf_rev; - } - - if (xlate_avail) { - /* apply the key translation table from our config */ - ck.mods = mods; - ck.key_raw = key_raw; - ck.key_tr = 0; - - /* check by raw... */ - cv = htpp_get(&xlate_hash, &ck); - if (cv == NULL) { - /* if not found also check by translated */ - ck.key_raw = 0; - ck.key_tr = key_tr; - cv = htpp_get(&xlate_hash, &ck); - } - - /* hit: replace input key from the xlate table */ - if (cv != NULL) { - mods = cv->mods; - if (cv->key_raw != 0) - key_tr = key_raw = cv->key_raw; - if (cv->key_tr != 0) - key_tr = key_raw = cv->key_tr; - } - } - - return rnd_hid_cfg_keys_input_(hl, km, mods, key_raw, key_tr, km->seq, &km->seq_len); -} - - -/*** key translation hash ends **/ - -int rnd_hid_cfg_keys_action_(rnd_hidlib_t *hl, rnd_hid_cfg_keyseq_t **seq, int seq_len) -{ - int res; - - if (seq_len < 1) - return -1; - - res = rnd_hid_cfg_action(hl, seq[seq_len-1]->action_node); - rnd_event(hl, RND_EVENT_USER_INPUT_POST, NULL); - return res; -} - -int rnd_hid_cfg_keys_action(rnd_hidlib_t *hl, rnd_hid_cfg_keys_t *km) -{ - int ret = rnd_hid_cfg_keys_action_(hl, km->seq, km->seq_len_action); - km->seq_len_action = 0; - return ret; -} - -int rnd_hid_cfg_keys_seq_(rnd_hid_cfg_keys_t *km, rnd_hid_cfg_keyseq_t **seq, int seq_len, char *dst, int dst_len) -{ - int n, sum = 0; - char *end = dst; - - dst_len -= 25; /* make room for a full key with modifiers, the \0 and the potential ellipsis */ - - for(n = 0; n < seq_len; n++) { - int k = seq[n]->addr.key_raw, mods = seq[n]->addr.mods, ll = 0, l; - - if (n != 0) { - *end = ' '; - end++; - ll = 1; - } - - if (mods & RND_M_Alt) { strncpy(end, "Alt-", dst_len); end += 4; ll += 4; } - if (mods & RND_M_Ctrl) { strncpy(end, "Ctrl-", dst_len); end += 5; ll += 5; } - if (mods & RND_M_Shift) { strncpy(end, "Shift-", dst_len); end += 6; ll += 6; } - - if (k == 0) - k = seq[n]->addr.key_tr; - - if (km->key_name(k, end, dst_len) == 0) { - l = strlen(end); - } - else { - strncpy(end, "", dst_len); - l = 9; - } - - ll += l; - - sum += ll; - dst_len -= ll; - end += l; - - if (dst_len <= 1) { - strcpy(dst, " ..."); - sum += 4; - dst_len -= 4; - end += 4; - break; - } - } - *end = '\0'; - return sum; -} - -int rnd_hid_cfg_keys_seq(rnd_hid_cfg_keys_t *km, char *dst, int dst_len) -{ - if (km->seq_len_action > 0) - return rnd_hid_cfg_keys_seq_(km, km->seq, km->seq_len_action, dst, dst_len); - else - return rnd_hid_cfg_keys_seq_(km, km->seq, km->seq_len, dst, dst_len); -} - -void rnd_hid_cfg_keys_uninit_module(void) -{ - if (xlate_avail) - xlate_uninit(); -} - Index: trunk/src/librnd/core/hid_cfg_input.h =================================================================== --- trunk/src/librnd/core/hid_cfg_input.h (revision 34601) +++ trunk/src/librnd/core/hid_cfg_input.h (nonexistent) @@ -1,142 +0,0 @@ -#ifndef RND_HID_CFG_INPUT_H -#define RND_HID_CFG_INPUT_H - -#include -#include -#include -#include - -/************************** MOUSE ***************************/ - -typedef struct { - lht_node_t *mouse; - htip_t *mouse_mask; -} rnd_hid_cfg_mouse_t; - -int rnd_hid_cfg_mouse_init(rnd_hid_cfg_t *hr, rnd_hid_cfg_mouse_t *mouse); -void rnd_hid_cfg_mouse_action(rnd_hidlib_t *hl, rnd_hid_cfg_mouse_t *mouse, rnd_hid_cfg_mod_t button_and_mask, rnd_bool cmd_entry_active); - - -/************************** KEYBOARD ***************************/ -#define RND_HIDCFG_MAX_KEYSEQ_LEN 32 -typedef struct hid_cfg_keyhash_s { - unsigned short int mods; /* of rnd_hid_cfg_mod_t */ - unsigned short int key_raw; /* raw keyboard code (0 means use ->key_tr instead); this is in the config; e.g. on US keyboard shift+3 this is Shift3 */ - unsigned short int key_tr; /* rendered: gui-translated keyboard code (0 means use ->key_raw instead); this is in the config; e.g. on US keyboard shift+3 this is # */ -} rnd_hid_cfg_keyhash_t; - - -typedef struct rnd_hid_cfg_keyseq_s rnd_hid_cfg_keyseq_t; -struct rnd_hid_cfg_keyseq_s { - rnd_hid_cfg_keyhash_t addr; - - unsigned long int keysym; /* optional 32 bit long storage the GUI hid should cast to whatever the GUI backend supports */ - - const lht_node_t *action_node; /* terminal node: end of sequence, run actions */ - - htpp_t seq_next; /* ... or if node is NULL, a hash for each key that may follow the current one */ - rnd_hid_cfg_keyseq_t *parent; -}; - -/* Translate symbolic name to single-char keysym before processing; useful - for shortcuts like "Return -> '\r'" which are otherwise hard to describe - in text format */ -typedef struct rnd_hid_cfg_keytrans_s { - const char *name; - char sym; -} rnd_hid_cfg_keytrans_t; - -extern const rnd_hid_cfg_keytrans_t rnd_hid_cfg_key_default_trans[]; - -/* A complete tree of keyboard shortcuts/hotkeys */ -typedef struct rnd_hid_cfg_keys_s { - htpp_t keys; - - /* translate key sym description (the portion after ) to key_char; - desc is a \0 terminated string, len is only a hint. Should return 0 - on error. */ - unsigned short int (*translate_key)(const char *desc, int len); - - /* convert a key_char to human readable name, copy the string to out/out_len. - Return 0 on success. */ - int (*key_name)(unsigned short int key_char, char *out, int out_len); - - - int auto_chr; /* if non-zero: don't call translate_key() for 1-char symbols, handle the default way */ - const rnd_hid_cfg_keytrans_t *auto_tr; /* apply this table before calling translate_key() */ - - /* current sequence state */ - rnd_hid_cfg_keyseq_t *seq[RND_HIDCFG_MAX_KEYSEQ_LEN]; - int seq_len; - int seq_len_action; /* when an action node is hit, save sequence length for executing the action while seq_len is reset */ -} rnd_hid_cfg_keys_t; - - -/* Initialize a new keyboard context - Returns 0 on success. -*/ -int rnd_hid_cfg_keys_init(rnd_hid_cfg_keys_t *km); - -/* Free km's fields recursively */ -int rnd_hid_cfg_keys_uninit(rnd_hid_cfg_keys_t *km); - -/* Add the next key of a key sequence; key sequences form a tree. A key starting - a new key sequence should have parent set NULL, subsequent calls should have - parent set to the previously returned keyseq value. Terminal is non-zero if - this is the last key of the sequence. - Raw vs. translated keys are desribed at rnd_hid_cfg_keys_input(). - Returns NULL on error and loads errmsg if not NULL */ -rnd_hid_cfg_keyseq_t *rnd_hid_cfg_keys_add_under(rnd_hid_cfg_keys_t *km, rnd_hid_cfg_keyseq_t *parent, rnd_hid_cfg_mod_t mods, unsigned short int key_raw, unsigned short int key_tr, int terminal, const char **errmsg); - -/* Add a new key using a description (read from a lihata file usually) - If out_seq is not NULL, load the array with pointers pointing to each - key in the sequence, up to out_seq_len. - When key desc is a lihata node, it may be a list (multiple keys for the - same action). In this case return value and seq are set using the first key. - Returns -1 on failure or the length of the sequence. -*/ -int rnd_hid_cfg_keys_add_by_desc(rnd_hid_cfg_keys_t *km, const lht_node_t *keydesc, const lht_node_t *action_node); -int rnd_hid_cfg_keys_add_by_desc_(rnd_hid_cfg_keys_t *km, const lht_node_t *keydesc, const lht_node_t *action_node, rnd_hid_cfg_keyseq_t **out_seq, int out_seq_len); -int rnd_hid_cfg_keys_add_by_strdesc(rnd_hid_cfg_keys_t *km, const char *keydesc, const lht_node_t *action_node); -int rnd_hid_cfg_keys_add_by_strdesc_(rnd_hid_cfg_keys_t *km, const char *keydesc, const lht_node_t *action_node, rnd_hid_cfg_keyseq_t **out_seq, int out_seq_len); - - -int rnd_hid_cfg_keys_del_by_desc(rnd_hid_cfg_keys_t *km, const lht_node_t *keydesc); - -/* Allocate a new string and generate a human readable accel-text; mask determines - which keys on the list are generated (when multiple key sequences are - specified for the same action; from LSB to MSB, at most 32 keys) - Caller needs to free the string; returns NULL on error. - */ -char *rnd_hid_cfg_keys_gen_accel(rnd_hid_cfg_keys_t *km, const lht_node_t *keydescn, unsigned long mask, const char *sep); - -/* Allocate a new string and generate a key-desc; returns NULL on error */ -char *rnd_hid_cfg_keys_gen_desc(rnd_hid_cfg_mod_t mods, unsigned short int key_raw, unsigned short int key_tr); - - -/* Process next input key stroke. - Seq and seq_len must not be NULL as they are the internal state of multi-key - processing. Load seq array with pointers pointing to each key in the - sequence, up to seq_len. - Key_raw is the raw key code for base keys, without any translation, key_tr - is the translated character; e.g. shift+1 is always reported as key_raw=1 - and on US keyboard reported as key_tr=! - Returns: - -1 if the key stroke or sequence is invalid - 0 if more characters needed to complete the sequence - + a positive integer means the lookup succeeded and the return value - is the length of the resulting sequence. -*/ -int rnd_hid_cfg_keys_input(rnd_hidlib_t *hl, rnd_hid_cfg_keys_t *km, rnd_hid_cfg_mod_t mods, unsigned short int key_raw, unsigned short int key_tr); -int rnd_hid_cfg_keys_input_(rnd_hidlib_t *hl, rnd_hid_cfg_keys_t *km, rnd_hid_cfg_mod_t mods, unsigned short int key_raw, unsigned short int key_tr, rnd_hid_cfg_keyseq_t **seq, int *seq_len); - -/* Run the action for a key sequence looked up by rnd_hid_cfg_keys_input(). - Returns: the result of the action or -1 on error */ -int rnd_hid_cfg_keys_action(rnd_hidlib_t *hl, rnd_hid_cfg_keys_t *km); -int rnd_hid_cfg_keys_action_(rnd_hidlib_t *hl, rnd_hid_cfg_keyseq_t **seq, int seq_len); - -/* Print a squence into dst in human readable form; returns strlen(dst) */ -int rnd_hid_cfg_keys_seq(rnd_hid_cfg_keys_t *km, char *dst, int dst_len); -int rnd_hid_cfg_keys_seq_(rnd_hid_cfg_keys_t *km, rnd_hid_cfg_keyseq_t **seq, int seq_len, char *dst, int dst_len); - -#endif Index: trunk/src/librnd/core/conf.c =================================================================== --- trunk/src/librnd/core/conf.c (revision 34601) +++ trunk/src/librnd/core/conf.c (revision 34602) @@ -49,6 +49,7 @@ #include #include #include +#include static const char *flcat = "conf"; @@ -1092,6 +1093,19 @@ f->rnd_conf_rev = rnd_conf_rev; } +static char *get_homedir(void) +{ + char *homedir = getenv("HOME"); + if (homedir == NULL) + homedir = getenv("USERPROFILE"); + return homedir; +} + +void rnd_pcbhl_conf_postproc(void) +{ + rnd_conf_force_set_str(rnd_conf.rc.path.home, get_homedir()); rnd_conf_ro("rc/path/home"); +} + int rnd_conf_rev = 0; void rnd_conf_update(const char *path, int arr_idx) { Index: trunk/src/librnd/core/conf.h =================================================================== --- trunk/src/librnd/core/conf.h (revision 34601) +++ trunk/src/librnd/core/conf.h (revision 34602) @@ -460,4 +460,7 @@ int rnd_conf_resolve_all(rnd_conf_resolve_t *res); +/*** misc ***/ +void rnd_pcbhl_conf_postproc(void); + #endif Index: trunk/src/librnd/core/conf_act.c =================================================================== --- trunk/src/librnd/core/conf_act.c (revision 34601) +++ trunk/src/librnd/core/conf_act.c (revision 34602) @@ -230,27 +230,8 @@ return 0; } -static const char rnd_acts_setunits[] = "SetUnits(mm|mil)"; -static const char rnd_acth_setunits[] = "Set the default measurement units."; -/* DOC: setunits.html */ -static fgw_error_t rnd_act_SetUnits(fgw_arg_t *res, int argc, fgw_arg_t *argv) -{ - const rnd_unit_t *new_unit; - const char *name; - - RND_ACT_CONVARG(1, FGW_STR, setunits, name = argv[1].val.str); - RND_ACT_IRES(0); - - new_unit = rnd_get_unit_struct(name); - rnd_hidlib_set_unit(RND_ACT_HIDLIB, new_unit); - - return 0; -} - - static rnd_action_t rnd_conf_action_list[] = { - {"conf", rnd_act_Conf, rnd_acth_Conf, rnd_acts_Conf}, - {"SetUnits", rnd_act_SetUnits, rnd_acth_setunits, rnd_acts_setunits} + {"conf", rnd_act_Conf, rnd_acth_Conf, rnd_acts_Conf} }; void rnd_conf_act_init2(void) Index: trunk/src/librnd/core/error.c =================================================================== --- trunk/src/librnd/core/error.c (revision 34601) +++ trunk/src/librnd/core/error.c (revision 34602) @@ -32,11 +32,13 @@ #include #include #include -#include +#include #include #include #include +rnd_hid_t *rnd_gui = NULL; + void rnd_trace(const char *Format, ...) { #ifndef NDEBUG @@ -249,29 +251,27 @@ if (rnd_strcasecmp(op, "Clear") == 0) { unsigned long from = -1, to = -1; RND_ACT_MAY_CONVARG(2, FGW_ULONG, Log, from = fgw_keyword(&argv[2])); - RND_ACT_MAY_CONVARG(3, FGW_ULONG, Log, from = fgw_keyword(&argv[3])); + RND_ACT_MAY_CONVARG(3, FGW_ULONG, Log, to = fgw_keyword(&argv[3])); rnd_log_del_range(from, to); rnd_event(NULL, RND_EVENT_LOG_CLEAR, "pp", &from, &to); ret = 0; } else if (rnd_strcasecmp(op, "Export") == 0) { - const char *fmts[] = { "text", "lihata", NULL }; - rnd_hid_dad_subdialog_t fmtsub; - char *fn; - int wfmt; + const char *fn, *fmt; - memset(&fmtsub, 0, sizeof(fmtsub)); - RND_DAD_ENUM(fmtsub.dlg, fmts); - wfmt = RND_DAD_CURRENT(fmtsub.dlg); - fn = rnd_hid_fileselect(rnd_gui, "Export log", NULL, "log.txt", NULL, NULL, "log", 0, &fmtsub); + RND_ACT_MAY_CONVARG(2, FGW_STR, Log, fn = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, Log, fmt = argv[3].val.str); + if (fn != NULL) { - ret = rnd_log_export(NULL, fn, (fmtsub.dlg[wfmt].val.lng == 1)); + int fmt_lihata = (fmt != NULL) && (strcmp(fmt, "lihata") == 0); + ret = rnd_log_export(NULL, fn, fmt_lihata); if (ret != 0) rnd_message(RND_MSG_ERROR, "Failed to export log to '%s'\n", fn); - free(fn); } - else - ret = 0; + else { + /* call through to the dialog box version */ + return rnd_actionv_bin(RND_ACT_HIDLIB, "LogGui", res, argc, argv); + } } else { RND_ACT_FAIL(Log); Index: trunk/src/librnd/core/error.h =================================================================== --- trunk/src/librnd/core/error.h (revision 34601) +++ trunk/src/librnd/core/error.h (revision 34602) @@ -37,6 +37,10 @@ disabled in non-debug compilation */ void rnd_trace(const char *Format, ...); +/* This is initially set to a "no-gui" GUI, and later reset by + main. It is used for on-screen GUI calls, such as dialog boxes */ +extern rnd_hid_t *rnd_gui; + typedef enum rnd_message_level_s { RND_MSG_DEBUG = 0, /* Debug message. Should probably not be shown in regular operation. */ RND_MSG_INFO, /* Info message. FYI for the user, no action needed. */ Index: trunk/src/librnd/core/hid_cfg.h =================================================================== --- trunk/src/librnd/core/hid_cfg.h (revision 34601) +++ trunk/src/librnd/core/hid_cfg.h (revision 34602) @@ -32,7 +32,6 @@ #include #include #include -#include #define RND_M_Mod0(n) (1u<<(n)) typedef enum { @@ -90,8 +89,4 @@ /* Report an error about a node */ void rnd_hid_cfg_error(const lht_node_t *node, const char *fmt, ...); - -/* for backward compatibility: */ -#include "hid_menu.h" - #endif Index: trunk/src/librnd/core/hidlib.c =================================================================== --- trunk/src/librnd/core/hidlib.c (revision 34601) +++ trunk/src/librnd/core/hidlib.c (revision 34602) @@ -27,7 +27,6 @@ #include #include -#include #include #include Index: trunk/src/librnd/core/hidlib_conf.c =================================================================== --- trunk/src/librnd/core/hidlib_conf.c (revision 34601) +++ trunk/src/librnd/core/hidlib_conf.c (revision 34602) @@ -30,12 +30,9 @@ #include #include #include -#include #include -#define RND_MAX_GRID RND_MIL_TO_COORD(1000) - rnd_conf_t rnd_conf; int rnd_hidlib_conf_init() @@ -49,23 +46,3 @@ return cnt; } -/* sets cursor grid with respect to grid offset values */ -void rnd_hidlib_set_grid(rnd_hidlib_t *hidlib, rnd_coord_t Grid, rnd_bool align, rnd_coord_t ox, rnd_coord_t oy) -{ - if (Grid >= 1 && Grid <= RND_MAX_GRID) { - if (align) { - hidlib->grid_ox = ox % Grid; - hidlib->grid_oy = oy % Grid; - } - hidlib->grid = Grid; - rnd_conf_set_design("editor/grid", "%$mS", Grid); - if (rnd_conf.editor.draw_grid) - rnd_gui->invalidate_all(rnd_gui); - } -} - -void rnd_hidlib_set_unit(rnd_hidlib_t *hidlib, const rnd_unit_t *new_unit) -{ - if (new_unit != NULL && new_unit->allow != RND_UNIT_NO_PRINT) - rnd_conf_set(RND_CFR_DESIGN, "editor/grid_unit", -1, new_unit->suffix, RND_POL_OVERWRITE); -} Index: trunk/src/librnd/core/hidlib_conf.h =================================================================== --- trunk/src/librnd/core/hidlib_conf.h (revision 34601) +++ trunk/src/librnd/core/hidlib_conf.h (revision 34602) @@ -107,9 +107,5 @@ int rnd_hidlib_conf_init(); -/* sets cursor grid with respect to grid spacing, offset and unit values */ -void rnd_hidlib_set_grid(rnd_hidlib_t *hidlib, rnd_coord_t Grid, rnd_bool align, rnd_coord_t ox, rnd_coord_t oy); -void rnd_hidlib_set_unit(rnd_hidlib_t *hidlib, const rnd_unit_t *new_unit); - #endif Index: trunk/src/librnd/font/font.c =================================================================== --- trunk/src/librnd/font/font.c (revision 34601) +++ trunk/src/librnd/font/font.c (revision 34602) @@ -28,7 +28,7 @@ #include #include "config.h" #include -#include +#include #include #include #include Index: trunk/src/librnd/hid/Makefile =================================================================== --- trunk/src/librnd/hid/Makefile (nonexistent) +++ trunk/src/librnd/hid/Makefile (revision 34602) @@ -0,0 +1,2 @@ +all: + cd ../.. && make Index: trunk/src/librnd/hid/anyload_act.c =================================================================== --- trunk/src/librnd/hid/anyload_act.c (nonexistent) +++ trunk/src/librnd/hid/anyload_act.c (revision 34602) @@ -0,0 +1,65 @@ +/* + * COPYRIGHT + * + * librnd, modular 2D CAD framework + * (file imported from: pcb-rnd, interactive printed circuit board design) + * Copyright (C) 2021 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/librnd + * lead developer: http://repo.hu/projects/librnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include +#include +#include + +static const char rnd_acts_AnyLoad[] = "AnyLoad([path])"; +static const char rnd_acth_AnyLoad[] = "Load \"anything\" from path (or offer a file selectio dialog if no path specified)\n"; +/* DOC: anyload.html */ +fgw_error_t rnd_act_AnyLoad(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *path = NULL; + char *path_free = NULL; + + RND_ACT_MAY_CONVARG(1, FGW_STR, AnyLoad, path = argv[1].val.str); + + if (path == NULL) + path = path_free = rnd_hid_fileselect(rnd_gui, "Import an anyload", NULL, "anyload.lht", NULL, NULL, "anyload", RND_HID_FSD_READ, NULL); + + if (path != NULL) + RND_ACT_IRES(rnd_anyload(RND_ACT_HIDLIB, path)); + else + RND_ACT_IRES(-1); + + free(path_free); + + return 0; +} + + +static rnd_action_t anyload_action_list[] = { + {"AnyLoad", rnd_act_AnyLoad, rnd_acth_AnyLoad, rnd_acts_AnyLoad}, +}; + +void rnd_anyload_act_init2(void) +{ + RND_REGISTER_ACTIONS(anyload_action_list, NULL); +} Index: trunk/src/librnd/hid/grid.c =================================================================== --- trunk/src/librnd/hid/grid.c (nonexistent) +++ trunk/src/librnd/hid/grid.c (revision 34602) @@ -0,0 +1,305 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 2018 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const char grid_cookie[] = "librnd grid"; +static int grid_idx_lock; + +rnd_coord_t rnd_grid_fit(rnd_coord_t x, rnd_coord_t grid_spacing, rnd_coord_t grid_offset) +{ + x -= grid_offset; + x = grid_spacing * rnd_round((double) x / grid_spacing); + x += grid_offset; + return x; +} + +rnd_bool_t rnd_grid_parse(rnd_grid_t *dst, const char *src) +{ + const char *nsep; + char *sep3, *sep2, *sep, *tmp, *size, *ox = NULL, *oy = NULL, *unit = NULL; + rnd_bool succ; + + nsep = strchr(src, ':'); + if (nsep != NULL) + src = nsep+1; + else + dst->name = NULL; + + /* remember where size starts */ + while(isspace(*src)) src++; + sep = size = tmp = rnd_strdup(src); + + /* find optional offs */ + sep2 = strchr(sep, '@'); + if (sep2 != NULL) { + sep = sep2; + *sep = '\0'; + sep++; + ox = sep; + sep3 = strchr(sep, ','); + if (sep3 != NULL) { + *sep3 = '\0'; + sep3++; + oy = sep; + } + } + + /* find optional unit switch */ + sep2 = strchr(sep, '!'); + if (sep2 != NULL) { + sep = sep2; + *sep = '\0'; + sep++; + unit = sep; + } + + /* convert */ + dst->size = rnd_get_value(size, NULL, NULL, &succ); + if ((!succ) || (dst->size < 0)) + goto error; + + if (ox != NULL) { + dst->ox = rnd_get_value(ox, NULL, NULL, &succ); + if (!succ) + goto error; + } + else + dst->ox = 0; + + if (oy != NULL) { + dst->oy = rnd_get_value(oy, NULL, NULL, &succ); + if (!succ) + goto error; + } + else + dst->oy = 0; + + if (unit != NULL) { + dst->unit = rnd_get_unit_struct(unit); + if (dst->unit == NULL) + goto error; + } + else + dst->unit = NULL; + + /* success */ + free(tmp); + + if (nsep != NULL) + dst->name = rnd_strndup(src, nsep-src-1); + else + dst->name = NULL; + return rnd_true; + + error:; + free(tmp); + return rnd_false; +} + +rnd_bool_t rnd_grid_append_print(gds_t *dst, const rnd_grid_t *src) +{ + if (src->size <= 0) + return rnd_false; + if (src->name != NULL) { + gds_append_str(dst, src->name); + gds_append(dst, ':'); + } + rnd_append_printf(dst, "%$.08mH", src->size); + if ((src->ox != 0) || (src->oy != 0)) + rnd_append_printf(dst, "@%$.08mH,%$.08mH", src->ox, src->oy); + if (src->unit != NULL) { + gds_append(dst, '!'); + gds_append_str(dst, src->unit->suffix); + } + return rnd_true; +} + +char *rnd_grid_print(const rnd_grid_t *src) +{ + gds_t tmp; + gds_init(&tmp); + if (!rnd_grid_append_print(&tmp, src)) { + gds_uninit(&tmp); + return NULL; + } + return tmp.array; /* do not uninit tmp */ +} + +void rnd_grid_set(rnd_hidlib_t *hidlib, const rnd_grid_t *src) +{ + rnd_hidlib_set_grid(hidlib, src->size, rnd_true, src->ox, src->oy); + if (src->unit != NULL) + rnd_hidlib_set_unit(hidlib, src->unit); +} + +void rnd_grid_free(rnd_grid_t *dst) +{ + free(dst->name); + dst->name = NULL; +} + +rnd_bool_t rnd_grid_list_jump(rnd_hidlib_t *hidlib, int dst) +{ + const rnd_conf_listitem_t *li; + rnd_grid_t g; + int max = rnd_conflist_length((rnd_conflist_t *)&rnd_conf.editor.grids); + + if (dst < 0) + dst = 0; + if (dst >= max) + dst = max - 1; + if (dst < 0) + return rnd_false; + + grid_idx_lock++; + + rnd_conf_setf(RND_CFR_DESIGN, "editor/grids_idx", -1, "%d", dst); + + li = rnd_conflist_nth((rnd_conflist_t *)&rnd_conf.editor.grids, dst); + /* clamp */ + if (li == NULL) { + grid_idx_lock--; + return rnd_false; + } + + if (!rnd_grid_parse(&g, li->payload)) { + grid_idx_lock--; + return rnd_false; + } + rnd_grid_set(hidlib, &g); + rnd_grid_free(&g); + + grid_idx_lock--; + return rnd_true; +} + +rnd_bool_t rnd_grid_list_step(rnd_hidlib_t *hidlib, int stp) +{ + int dst = rnd_conf.editor.grids_idx; + if (dst < 0) + dst = -dst-1; + return rnd_grid_list_jump(hidlib, dst + stp); +} + +void rnd_grid_inval(void) +{ + if (rnd_conf.editor.grids_idx > 0) + rnd_conf_setf(RND_CFR_DESIGN, "editor/grids_idx", -1, "%d", -1 - rnd_conf.editor.grids_idx); +} + +/*** catch editor/grid changes to update editor/grids_idx */ + +static void grid_conf_chg(rnd_conf_native_t *cfg, int arr_idx) +{ + gdl_iterator_t it; + rnd_conf_listitem_t *ge; + int idx = 0, found = -1; + + if (grid_idx_lock) + return; + + grid_idx_lock++; + rnd_conflist_foreach((rnd_conflist_t *)&rnd_conf.editor.grids, &it, ge) { + rnd_grid_t g; +/* g.ox = hidlib->grid_ox; g.oy = hidlib->grid_oy; */ + if (rnd_grid_parse(&g, ge->payload)) { + if ((g.size == rnd_conf.editor.grid) /*&& (g.ox == hidlib->grid_ox) && (g.oy == hidlib->grid_oy)*/) { + found = idx; + rnd_grid_free(&g); + break; + } + rnd_grid_free(&g); + } + idx++; + } + + if (rnd_conf.editor.grids_idx != found) + rnd_conf_setf(RND_CFR_DESIGN, "editor/grids_idx", -1, "%d", found); + grid_idx_lock--; +} + +void rnd_grid_init(void) +{ + rnd_conf_native_t *n = rnd_conf_get_field("editor/grid"); + static rnd_conf_hid_id_t grid_conf_id; + + if (n != NULL) { + static rnd_conf_hid_callbacks_t cbs; + grid_conf_id = rnd_conf_hid_reg(grid_cookie, NULL); + memset(&cbs, 0, sizeof(rnd_conf_hid_callbacks_t)); + cbs.val_change_post = grid_conf_chg; + rnd_conf_hid_set_cb(n, grid_conf_id, &cbs); + } + +} + +void rnd_grid_uninit(void) +{ + rnd_conf_hid_unreg(grid_cookie); +} + +/* sets cursor grid with respect to grid offset values */ +void rnd_hidlib_set_grid(rnd_hidlib_t *hidlib, rnd_coord_t Grid, rnd_bool align, rnd_coord_t ox, rnd_coord_t oy) +{ + if (Grid >= 1 && Grid <= RND_MAX_GRID) { + if (align) { + hidlib->grid_ox = ox % Grid; + hidlib->grid_oy = oy % Grid; + } + hidlib->grid = Grid; + rnd_conf_set_design("editor/grid", "%$mS", Grid); + if (rnd_conf.editor.draw_grid) + rnd_gui->invalidate_all(rnd_gui); + } +} + +void rnd_hidlib_set_unit(rnd_hidlib_t *hidlib, const rnd_unit_t *new_unit) +{ + if (new_unit != NULL && new_unit->allow != RND_UNIT_NO_PRINT) + rnd_conf_set(RND_CFR_DESIGN, "editor/grid_unit", -1, new_unit->suffix, RND_POL_OVERWRITE); +} Index: trunk/src/librnd/hid/grid.h =================================================================== --- trunk/src/librnd/hid/grid.h (nonexistent) +++ trunk/src/librnd/hid/grid.h (revision 34602) @@ -0,0 +1,87 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 2018 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#ifndef RND_GRID_H +#define RND_GRID_H + +#define RND_MAX_GRID RND_MIL_TO_COORD(1000) + +#include +#include +#include +#include + +/* String packed syntax (bracket means optional): + + [name:]size[@offs][!unit] + + "!" means to switch the UI to the unit specified. */ +typedef struct { + char *name; + rnd_coord_t size; + rnd_coord_t ox, oy; + const rnd_unit_t *unit; /* force switching to unit if not NULL */ +} rnd_grid_t; + +/* Returns the nearest grid-point to the given coord x */ +rnd_coord_t rnd_grid_fit(rnd_coord_t x, rnd_coord_t grid_spacing, rnd_coord_t grid_offset); + +/* Parse packed string format src into dst; allocat dst->name on success */ +rnd_bool_t rnd_grid_parse(rnd_grid_t *dst, const char *src); + +/* Free all allocated fields of a grid struct */ +void rnd_grid_free(rnd_grid_t *dst); + +/* Convert src into packed string format */ +rnd_bool_t rnd_grid_append_print(gds_t *dst, const rnd_grid_t *src); +char *rnd_grid_print(const rnd_grid_t *src); + +/* Apply grid settings from src to the pcb */ +void rnd_grid_set(rnd_hidlib_t *hidlib, const rnd_grid_t *src); + +/* Jump to grid index dst (clamped); absolute set */ +rnd_bool_t rnd_grid_list_jump(rnd_hidlib_t *hidlib, int dst); + +/* Step stp steps (can be 0) on the grids list and set the resulting grid; relative set */ +rnd_bool_t rnd_grid_list_step(rnd_hidlib_t *hidlib, int stp); + +/* invalidate the grid index; call this when changing the grid settings */ +void rnd_grid_inval(void); + +/* Reinstall grid menus */ +void rnd_grid_install_menu(void); + +void rnd_grid_init(void); +void rnd_grid_uninit(void); + +/* sets cursor grid with respect to grid spacing, offset and unit values */ +void rnd_hidlib_set_grid(rnd_hidlib_t *hidlib, rnd_coord_t Grid, rnd_bool align, rnd_coord_t ox, rnd_coord_t oy); +void rnd_hidlib_set_unit(rnd_hidlib_t *hidlib, const rnd_unit_t *new_unit); + +#endif Index: trunk/src/librnd/hid/hid.c =================================================================== --- trunk/src/librnd/hid/hid.c (nonexistent) +++ trunk/src/librnd/hid/hid.c (revision 34602) @@ -0,0 +1,99 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 2020 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include +#include +#include +#include + +int rnd_hid_enable_per_dialog_hidlib = 0; + +void rnd_hid_notify_crosshair_change(rnd_hidlib_t *hl, rnd_bool changes_complete) +{ + if (rnd_gui->notify_crosshair_change) + rnd_gui->notify_crosshair_change(rnd_gui, changes_complete); + rnd_event(hl, RND_EVENT_CROSSHAIR_MOVE, "i", (int)changes_complete, NULL); +} + +char *(*rnd_hid_fileselect_imp)(rnd_hid_t *hid, const char *title, const char *descr, const char *default_file, const char *default_ext, const rnd_hid_fsd_filter_t *flt, const char *history_tag, rnd_hid_fsd_flags_t flags, rnd_hid_dad_subdialog_t *sub) = NULL; + +char *rnd_hid_fileselect(rnd_hid_t *hid, const char *title, const char *descr, const char *default_file, const char *default_ext, const rnd_hid_fsd_filter_t *flt, const char *history_tag, rnd_hid_fsd_flags_t flags, rnd_hid_dad_subdialog_t *sub) +{ + if ((hid == NULL) || (rnd_hid_fileselect_imp == NULL)) + return NULL; + + return rnd_hid_fileselect_imp(hid, title, descr, default_file, default_ext, flt, history_tag, flags, sub); +} + + +/*** GUI batch timer ***/ + +#define BTMR_REFRESH_TIME_MS 300 + +static int btmr_timer_active = 0; +static rnd_hidval_t btmr_timer; +static rnd_hidlib_t *btmr_hidlib; + +static void btmr_cb(rnd_hidval_t user_data) +{ + btmr_timer_active = 0; + rnd_hid_menu_merge_inhibit_inc(); + rnd_event(btmr_hidlib, RND_EVENT_GUI_BATCH_TIMER, NULL); + rnd_hid_menu_merge_inhibit_dec(); +} + +void rnd_hid_gui_batch_timer(rnd_hidlib_t *hidlib) +{ + rnd_hidval_t timerdata; + + if ((rnd_gui == NULL) || (!rnd_gui->gui)) + return; + + if (btmr_timer_active) { + rnd_gui->stop_timer(rnd_gui, btmr_timer); + btmr_timer_active = 0; + } + + timerdata.ptr = NULL; + btmr_timer = rnd_gui->add_timer(rnd_gui, btmr_cb, BTMR_REFRESH_TIME_MS, timerdata); + btmr_timer_active = 1; + btmr_hidlib = hidlib; +} + +int rnd_hid_get_coords(const char *msg, rnd_coord_t *x, rnd_coord_t *y, int force) +{ + if (rnd_gui == NULL) { + fprintf(stderr, "rnd_hid_get_coords: can not get coordinates (no gui) for '%s'\n", msg); + *x = 0; + *y = 0; + return -1; + } + else + return rnd_gui->get_coords(rnd_gui, msg, x, y, force); +} Index: trunk/src/librnd/hid/hid.h =================================================================== --- trunk/src/librnd/hid/hid.h (nonexistent) +++ trunk/src/librnd/hid/hid.h (revision 34602) @@ -0,0 +1,696 @@ +#ifndef RND_HID_H +#define RND_HID_H + +#include +#include +#include + +#include +#include +#include +#include + +/* attribute dialog properties */ +typedef enum rnd_hat_property_e { + RND_HATP_GLOBAL_CALLBACK, + RND_HATP_max +} rnd_hat_property_t; + + +typedef enum { + RND_HID_MOUSE_PRESS, + RND_HID_MOUSE_RELEASE, + RND_HID_MOUSE_MOTION, + RND_HID_MOUSE_POPUP /* "right click", open context-specific popup */ +} rnd_hid_mouse_ev_t; + +/* Human Interface Device */ + +/* + +The way the HID layer works is that you instantiate a HID device +structure, and invoke functions through its members. Code in the +pcb-rnd core may *not* rely on HID internals (*anything* other than what's +defined in this file). Code in the HID layers *may* rely on data and +functions in hidlib (like, design size and such), but not on anything +in application core. + +Coordinates are ALWAYS in pcb's internal units rnd_coord_t. Positive X is +right, positive Y is down, unless flip is activated. Angles are +degrees, with 0 being right (positive X) and 90 being up (negative Y) - unless +flip is activated. All zoom, scaling, panning, and conversions are hidden +inside the HIDs. + +The main structure is rnd_hid_t. +*/ + +/* Line end cap styles. The cap *always* extends beyond the + coordinates given, by half the width of the line. */ +typedef enum { + rnd_cap_invalid = -1, + rnd_cap_square, /* square pins or pads when drawn using a line */ + rnd_cap_round /* for normal traces, round pins */ +} rnd_cap_style_t; + +/* The HID may need something more than an "int" for colors, timers, + etc. So it passes/returns one of these, which is castable to a + variety of things. */ +typedef union { + long lval; + void *ptr; +} rnd_hidval_t; + +typedef struct { + rnd_coord_t width; /* as set by set_line_width */ + rnd_cap_style_t cap; /* as set by set_line_cap */ + int xor; /* as set by set_draw_xor */ + int faded; /* as set by set_draw_faded */ + rnd_hid_t *hid; /* the HID that owns this gc */ + + + /* Spare: see doc/developer/spare.txt */ + void (*spare_f1)(void), (*spare_f2)(void); + long spare_l1, spare_l2, spare_l3, spare_l4; + void *spare_p1, *spare_p2, *spare_p3, *spare_p4; + double spare_d1, spare_d2, spare_d3, spare_d4; + rnd_coord_t spare_c1, spare_c2, spare_c3, spare_c4; +} rnd_core_gc_t; + + +#define RND_HIDCONCAT(a,b) a##b + +/* File Watch flags */ +/* Based upon those in dbus/dbus-connection.h */ +typedef enum { + RND_WATCH_READABLE = 1 << 0, /* As in POLLIN */ + RND_WATCH_WRITABLE = 1 << 1, /* As in POLLOUT */ + RND_WATCH_ERROR = 1 << 2, /* As in POLLERR */ + RND_WATCH_HANGUP = 1 << 3 /* As in POLLHUP */ +} rnd_watch_flags_t; + +typedef enum rnd_composite_op_s { + RND_HID_COMP_RESET, /* reset (allocate and clear) the sketch canvas */ + RND_HID_COMP_POSITIVE, /* draw subsequent objects in positive, with color, no XOR allowed */ + RND_HID_COMP_POSITIVE_XOR, /* draw subsequent objects in positive, with color, XOR allowed */ + RND_HID_COMP_NEGATIVE, /* draw subsequent objects in negative, ignore color */ + RND_HID_COMP_FLUSH /* combine the sketch canvas onto the output buffer and discard the sketch canvas */ +} rnd_composite_op_t; + +typedef enum rnd_burst_op_s { + RND_HID_BURST_START, + RND_HID_BURST_END +} rnd_burst_op_t; + +typedef enum rnd_hid_attr_ev_e { + RND_HID_ATTR_EV_WINCLOSE = 2, /* window closed (window manager close) */ + RND_HID_ATTR_EV_CODECLOSE /* closed by the code, including standard close buttons */ +} rnd_hid_attr_ev_t; + +typedef enum rnd_hid_fsd_flags_e { /* bitwise OR, used by file selection dialog (fsd) */ + RND_HID_FSD_READ = 1 /* when set let the user pick existing files only ("load"); if unset, both esiting and non-existing files are accepted */ +} rnd_hid_fsd_flags_t; + +typedef struct { + const char *name; + const char *mime; + const char **pat; /* NULL terminated array of file name patterns */ + + /* Spare: see doc/developer/spare.txt */ + void (*spare_f1)(void), (*spare_f2)(void); + long spare_l1, spare_l2, spare_l3, spare_l4; + void *spare_p1, *spare_p2; + double spare_d1, spare_d2; + rnd_coord_t spare_c1, spare_c2; +} rnd_hid_fsd_filter_t; + +extern const rnd_hid_fsd_filter_t rnd_hid_fsd_filter_any[]; + +/* Optional fields of a menu item; all non-NULL fields are strdup'd in the HID. */ +typedef struct rnd_menu_prop_s { + const char *action; + const char *accel; + const char *tip; /* tooltip */ + const char *checked; + const char *update_on; + const rnd_color_t *foreground; + const rnd_color_t *background; + const char *cookie; /* used for cookie based removal */ + + /* Spare: see doc/developer/spare.txt */ + long spare_l1, spare_l2, spare_l3, spare_l4; + void *spare_p1, *spare_p2, *spare_p3, *spare_p4; +} rnd_menu_prop_t; + +typedef enum rnd_hid_clipfmt_e { + RND_HID_CLIPFMT_TEXT /* plain text (c string with the \0 included) */ +} rnd_hid_clipfmt_t; + +typedef enum { + RND_HID_DOCK_TOP_LEFT, /* hbox on the top, below the menubar */ + RND_HID_DOCK_TOP_RIGHT, /* hbox on the top, next to the menubar */ + RND_HID_DOCK_TOP_INFOBAR, /* vbox for horizontally aligned important messages, above ("on top of") the drawing area for critical warnings - may have bright background color */ + RND_HID_DOCK_LEFT, + RND_HID_DOCK_BOTTOM, + RND_HID_DOCK_FLOAT, /* separate window */ + + RND_HID_DOCK_max +} rnd_hid_dock_t; + +extern int rnd_dock_is_vert[RND_HID_DOCK_max]; /* 1 if a new dock box (parent of a new sub-DAD) should be a vbox, 0 if hbox */ +extern int rnd_dock_has_frame[RND_HID_DOCK_max]; /* 1 if a new dock box (parent of a new sub-DAD) should be framed */ + +typedef enum rnd_set_crosshair_e { + RND_SC_DO_NOTHING = 0, + RND_SC_WARP_POINTER, + RND_SC_PAN_VIEWPORT +} rnd_set_crosshair_t; + +/* This is the main HID structure. */ +struct rnd_hid_s { + /* The size of this structure. We use this as a compatibility + check; a HID built with a different hid.h than we're expecting + should have a different size here. */ + int struct_size; + + /* The name of this HID. This should be suitable for + command line options, multi-selection menus, file names, + etc. */ + const char *name; + + /* Likewise, but allowed to be longer and more descriptive. */ + const char *description; + + /* If set, this is the GUI HID. Exactly one of these three flags + must be set; setting "gui" lets the expose callback optimize and + coordinate itself. */ + unsigned gui:1; + + /* If set, this is the printer-class HID. The application + may use this to do command-line printing, without having + instantiated any GUI HIDs. Only one printer HID is normally + defined at a time. */ + unsigned printer:1; + + /* If set, this HID provides an export option, and should be used as + part of the File->Export menu option. Examples are PNG, Gerber, + and EPS exporters. */ + unsigned exporter:1; + + /* Export plugin should not be listed in the export dialog; GUI plugin + should not be auto-selected */ + unsigned hide_from_gui:1; + + /* If set, draw the mask layer inverted. Normally the mask is a filled + rectangle over the design with cutouts at pins/pads. The HIDs + use render in normal mode, gerber renders in inverse mode. */ + unsigned mask_invert:1; + + /* Always draw layers in compositing mode - no base layer */ + unsigned force_compositing:1; + + /* When enabled, indicate layer of heavy terminals graphically */ + unsigned heavy_term_layer_ind:1; + + /* When 1, HID supports markup (e.g. color) in DAD text widgets */ + unsigned supports_dad_text_markup:1; + + /* it is possible to create DAD dialogs before the GUI_INIT event is emitted + (e.g. draw progress bar while loading a command line file) */ + unsigned allow_dad_before_init:1; + + /* when 1 and this hid is rnd_render, do not change rnd_render even if an export plugin or GUI is calling the render code */ + unsigned override_render:1; + + /* called by core when the global hidlib context changes (e.g. design changed) + The HID should store the hidlib pointer for knowing drawing area dimensions */ + void (*set_hidlib)(rnd_hid_t *hid, rnd_hidlib_t *hidlib); + + /* Return the hidlib the given GUI HID is currently showing + (not implemented in export HIDs) */ + rnd_hidlib_t *(*get_hidlib)(rnd_hid_t *hid); + + /* Returns a set of resources describing options the export or print + HID supports. In GUI mode, the print/export dialogs use this to + set up the selectable options. In command line mode, these are + used to interpret command line options. If n_ret_ is non-NULL, + the number of attributes is stored there. Note: the table is read-only + and persistent. */ + const rnd_export_opt_t *(*get_export_options)(rnd_hid_t *hid, int *n_ret); + + /* Exports (or print) the current design. The options given represent + the choices made from the options returned from + get_export_options. Call with options_ == NULL to start the + primary GUI (create a main window, print, export, etc) */ + void (*do_export)(rnd_hid_t *hid, rnd_hid_attr_val_t *options); + + /* Export plugins: if not NULL, rnd_hid_parse_command_line() sets up opt + value backing memory from this array */ + rnd_hid_attr_val_t *argument_array; + + /* uninit a GUI hid */ + void (*uninit)(rnd_hid_t *hid); + + /* uninit a GUI hid */ + void (*do_exit)(rnd_hid_t *hid); + + /* Process pending events, flush output, but never block. Called from busy + loops from time to time. */ + void (*iterate)(rnd_hid_t *hid); + + /* Parses the command line. Call this early for whatever HID will be + the primary HID, as it will set all the registered attributes. + The HID should remove all arguments, leaving any possible file + names behind. Returns 0 on success, positive for recoverable errors + (no change in argc or argv) and negative for unrecoverable errors. */ + int (*parse_arguments)(rnd_hid_t *hid, int *argc, char ***argv); + + /* This may be called to ask the GUI to force a redraw of a given area */ + void (*invalidate_lr)(rnd_hid_t *hid, rnd_coord_t left, rnd_coord_t right, rnd_coord_t top, rnd_coord_t bottom); + void (*invalidate_all)(rnd_hid_t *hid); + void (*notify_crosshair_change)(rnd_hid_t *hid, rnd_bool changes_complete); + void (*notify_mark_change)(rnd_hid_t *hid, rnd_bool changes_complete); + + /* During redraw or print/export cycles, this is called once per layer group + (physical layer); pusrpose/purpi are the extracted purpose field and its + keyword/function version; layer is the first layer in the group. + TODO: The group may be -1 until the layer rewrite is finished. + If it returns false (zero), the HID does not want that layer, and none of + the drawing functions should be called. If it returns rnd_true (nonzero), + the items in that layer [group] should be drawn using the various drawing + functions. In addition to the copper layer groups, you may select virtual + layers. The is_empty argument is a hint - if set, the layer is empty, if + zero it may be non-empty. */ + int (*set_layer_group)(rnd_hid_t *hid, rnd_layergrp_id_t group, const char *purpose, int purpi, rnd_layer_id_t layer, unsigned int flags, int is_empty, rnd_xform_t **xform); + + /* Tell the GUI the layer last selected has been finished with. */ + void (*end_layer)(rnd_hid_t *hid); + + /*** Drawing Functions. ***/ + + /* Make an empty gc (graphics context, which is like a pen). */ + rnd_hid_gc_t (*make_gc)(rnd_hid_t *hid); + void (*destroy_gc)(rnd_hid_gc_t gc); + + /* Composite layer drawing: manipulate the sketch canvas and set + positive or negative drawing mode. The canvas covers the screen box. */ + void (*set_drawing_mode)(rnd_hid_t *hid, rnd_composite_op_t op, rnd_bool direct, const rnd_box_t *screen); + + /* Announce start/end of a render burst for a specific screen screen box; + A GUI hid should set the coord_per_pix value here for proper optimization. */ + void (*render_burst)(rnd_hid_t *hid, rnd_burst_op_t op, const rnd_box_t *screen); + + /*** gc vs. rnd_hid_t *: rnd_core_gc_t contains ->hid, so these calls don't + need to get it as first arg. ***/ + + /* Sets a color. Can be one of the special colors like rnd_color_drill. + (Always use the drill color to draw holes and slots). + You may assume this is cheap enough to call inside the redraw + callback, but not cheap enough to call for each item drawn. */ + void (*set_color)(rnd_hid_gc_t gc, const rnd_color_t *color); + + /* Sets the line style. While calling this is cheap, calling it with + different values each time may be expensive, so grouping items by + line style is helpful. */ + void (*set_line_cap)(rnd_hid_gc_t gc, rnd_cap_style_t style); + void (*set_line_width)(rnd_hid_gc_t gc, rnd_coord_t width); + void (*set_draw_xor)(rnd_hid_gc_t gc, int xor); + /* Blends 20% or so color with 80% background. Only used for + assembly drawings so far. */ + void (*set_draw_faded)(rnd_hid_gc_t gc, int faded); + + /* The usual drawing functions. "draw" means to use segments of the + given width, whereas "fill" means to fill to a zero-width + outline. */ + void (*draw_line)(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2); + void (*draw_arc)(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t xradius, rnd_coord_t yradius, rnd_angle_t start_angle, rnd_angle_t delta_angle); + void (*draw_rect)(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2); + void (*fill_circle)(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius); + void (*fill_polygon)(rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y); + void (*fill_polygon_offs)(rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y, rnd_coord_t dx, rnd_coord_t dy); + void (*fill_rect)(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2); + + void (*draw_pixmap)(rnd_hid_t *hid, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t sx, rnd_coord_t sy, rnd_pixmap_t *pixmap); + void (*uninit_pixmap)(rnd_hid_t *hid, rnd_pixmap_t *pixmap); + + /*** GUI layout functions. Not used or defined for print/export HIDs. ***/ + + /* Temporary */ + int (*shift_is_pressed)(rnd_hid_t *hid); + int (*control_is_pressed)(rnd_hid_t *hid); + int (*mod1_is_pressed)(rnd_hid_t *hid); + + /* Returns 0 on success, -1 on esc pressed */ + int (*get_coords)(rnd_hid_t *hid, const char *msg, rnd_coord_t *x, rnd_coord_t *y, int force); + + /* Sets the crosshair, which may differ from the pointer depending + on grid and pad snap. Note that the HID is responsible for + hiding, showing, redrawing, etc. The core just tells it what + coordinates it's actually using. Note that this routine may + need to know what "pcb units" are so it can display them in mm + or mils accordingly. If cursor_action_ is set, the cursor or + screen may be adjusted so that the cursor and the crosshair are + at the same point on the screen. */ + void (*set_crosshair)(rnd_hid_t *hid, rnd_coord_t x, rnd_coord_t y, rnd_set_crosshair_t cursor_action); + + /* Causes func to be called at some point in the future. Timers are + only good for *one* call; if you want it to repeat, add another + timer during the callback for the first. user_data_ can be + anything, it's just passed to func. Times are not guaranteed to + be accurate. */ + rnd_hidval_t (*add_timer)(rnd_hid_t *hid, void (*func)(rnd_hidval_t user_data), unsigned long milliseconds, rnd_hidval_t user_data); + /* Use this to stop a timer that hasn't triggered yet. */ + void (*stop_timer)(rnd_hid_t *hid, rnd_hidval_t timer); + + /* Causes func_ to be called when some condition occurs on the file + descriptor passed. Conditions include data for reading, writing, + hangup, and errors. user_data_ can be anything, it's just passed + to func. If the watch function returns rnd_true, the watch is kept, else + it is removed. */ + rnd_hidval_t (*watch_file)(rnd_hid_t *hid, int fd, unsigned int condition, rnd_bool (*func)(rnd_hidval_t watch, int fd, unsigned int condition, rnd_hidval_t user_data), rnd_hidval_t user_data); + + /* Use this to stop a file watch; must not be called from within a GUI callback! */ + void (*unwatch_file)(rnd_hid_t *hid, rnd_hidval_t watch); + + + + /* A generic dialog to ask for a set of attributes. If n_attrs_ is + zero, attrs_(.name) must be NULL terminated. attr_dlg_run returns + non-zero if an error occurred (usually, this means the user cancelled + the dialog or something). title is the title of the dialog box + The HID may choose to ignore it or it may use it for a tooltip or + text in a dialog box, or a help string. Id is used in some events (e.g. + for window placement) and is strdup'd. If defx and defy are larger than 0, + they are hints for the default (starting) window size - can be overridden + by window placement. Returns opaque hid_ctx. + (Hid_ctx shall save rnd_hid_t so subsequent attr_dlg_*() calls don't have + it as an argument) */ + void *(*attr_dlg_new)(rnd_hid_t *hid, const char *id, rnd_hid_attribute_t *attrs, int n_attrs, const char *title, void *caller_data, rnd_bool modal, void (*button_cb)(void *caller_data, rnd_hid_attr_ev_t ev), int defx, int defy, int minx, int miny); + int (*attr_dlg_run)(void *hid_ctx); + void (*attr_dlg_raise)(void *hid_ctx); /* raise the window to top */ + void (*attr_dlg_close)(void *hid_ctx); /* close the GUI but do not yet free hid_ctx (results should be available) */ + void (*attr_dlg_free)(void *hid_ctx); + + /* Set a property of an attribute dialog (typical call is between + attr_dlg_new() and attr_dlg_run()) */ + void (*attr_dlg_property)(void *hid_ctx, rnd_hat_property_t prop, const rnd_hid_attr_val_t *val); + + + /* Disable or enable a widget of an active attribute dialog; if enabled is + 2, the widget is put to its second enabled mode (pressed state for buttons, highlight on label) */ + int (*attr_dlg_widget_state)(void *hid_ctx, int idx, int enabled); + + /* hide or show a widget of an active attribute dialog */ + int (*attr_dlg_widget_hide)(void *hid_ctx, int idx, rnd_bool hide); + + /* Changes state of widget at idx. Returns 0 on success. Meaning of + arguments is widgets-specific. */ + int (*attr_dlg_widget_poke)(void *hid_ctx, int idx, int argc, fgw_arg_t argv[]); + + /* Change the current value of a widget; same as if the user chaged it, + except the value-changed callback is inhibited */ + int (*attr_dlg_set_value)(void *hid_ctx, int idx, const rnd_hid_attr_val_t *val); + + /* Change the help text (tooltip) string of a widget; NULL means remove it. + NOTE: does _not_ change the help_text field of the attribute. */ + void (*attr_dlg_set_help)(void *hid_ctx, int idx, const char *val); + + /* top window docking: enter a new docked part by registering a + new subdialog or leave (remove a docked part) from a subdialog. Return 0 + on success. */ + int (*dock_enter)(rnd_hid_t *hid, rnd_hid_dad_subdialog_t *sub, rnd_hid_dock_t where, const char *id); + void (*dock_leave)(rnd_hid_t *hid, rnd_hid_dad_subdialog_t *sub); + + /* Something to alert the user. */ + void (*beep)(rnd_hid_t *hid); + + /* Removes a menu recursively */ + int (*remove_menu_node)(rnd_hid_t *hid, lht_node_t *nd); + + /* At the moment HIDs load the menu file. Some plugin code, like the toolbar + code needs to traverse the menu tree too. This call exposes the + HID-internal menu struct */ + rnd_hid_cfg_t *(*get_menu_cfg)(rnd_hid_t *hid); + + /* Update the state of all checkboxed menus whose lihata + node cookie matches cookie (or all checkboxed menus globally if cookie + is NULL) */ + void (*update_menu_checkbox)(rnd_hid_t *hid, const char *cookie); + + /* Creates a new menu or submenu from an existing (already merged) lihata node */ + int (*create_menu_by_node)(rnd_hid_t *hid, int is_popup, const char *name, int is_main, lht_node_t *parent, lht_node_t *ins_after, lht_node_t *menu_item); + + /* Pointer to the hid's configuration - useful for plugins and core wanting to install menus at anchors */ + rnd_hid_cfg_t *menu; + + + /* Optional: print usage string (if accepts command line arguments) + Subtopic: + NULL print generic help + string print summary for the topic in string + Return 0 on success. + */ + int (*usage)(rnd_hid_t *hid, const char *subtopic); + + + /* Optional: change cursor to indicate if an object is grabbed (or not) */ + void (*point_cursor)(rnd_hid_t *hid, rnd_bool grabbed); + + /* Optional: when non-zero, the core renderer may decide to draw cheaper + (simplified) approximation of some objects that would end up being too + small. For a GUI, this should depend on the zoom level */ + rnd_coord_t coord_per_pix; + + /* If ovr is not NULL: + - overwrite the command etry with ovr + - if cursor is not NULL, set the cursor after the overwrite + If ovr is NULL: + - if cursor is not NULL, load the value with the cursor (or -1 if not supported) + Return the current command entry content in a read-only string */ + const char *(*command_entry)(rnd_hid_t *hid, const char *ovr, int *cursor); + + /*** clipboard handling for GUI HIDs ***/ + /* Place format/data/len on the clipboard; return 0 on success */ + int (*clip_set)(rnd_hid_t *hid, rnd_hid_clipfmt_t format, const void *data, size_t len); + + /* retrieve format/data/len from the clipboard; return 0 on success; + data is a copy of the data, modifiable by the caller */ + int (*clip_get)(rnd_hid_t *hid, rnd_hid_clipfmt_t *format, void **data, size_t *len); + + /* release the data from the last clip_get(); clip_get() and clip_free() should + be called in pair */ + void (*clip_free)(rnd_hid_t *hid, rnd_hid_clipfmt_t format, void *data, size_t len); + + /* run redraw-benchmark and return an FPS value (optional) */ + double (*benchmark)(rnd_hid_t *hid); + + /* (rnd_hid_cfg_keys_t *): key state */ + void *key_state; + + /*** zoom/pan calls ***/ + + /* side-correct zoom to show a window of the design. If set_crosshair + is true, also update the crosshair to be on the center of the window */ + void (*zoom_win)(rnd_hid_t *hid, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2, rnd_bool set_crosshair); + + /* Zoom relative or absolute by factor; relative means current zoom is + multiplied by factor */ + void (*zoom)(rnd_hid_t *hid, rnd_coord_t center_x, rnd_coord_t center_y, double factor, int relative); + + /* Pan relative/absolute by x and y; relative means x and y are added to + the current pan */ + void (*pan)(rnd_hid_t *hid, rnd_coord_t x, rnd_coord_t y, int relative); + + /* Start or stop panning at x;y - stop is mode=0, start is mode=1 */ + void (*pan_mode)(rnd_hid_t *hid, rnd_coord_t x, rnd_coord_t y, rnd_bool mode); + + /* Load viewbox with the extents of visible pixels translated to design coords */ + void (*view_get)(rnd_hid_t *hid, rnd_box_t *viewbox); + + /*** misc GUI ***/ + /* Open the command line */ + void (*open_command)(rnd_hid_t *hid); + + /* Open a popup menu addressed by full menu path (starting with "/popups/"). + Return 0 on success. */ + int (*open_popup)(rnd_hid_t *hid, const char *menupath); + + + /* Change the mouse cursor to a named cursor e.g. after the tool has changed. + The list of cursors names available may depend on the HID. */ + void (*reg_mouse_cursor)(rnd_hid_t *hid, int idx, const char *name, const unsigned char *pixel, const unsigned char *mask); + void (*set_mouse_cursor)(rnd_hid_t *hid, int idx); + + /* change top window title any time the after the GUI_INIT event */ + void (*set_top_title)(rnd_hid_t *hid, const char *title); + + /* OPTIONAL: override the mouse cursor to indicate busy state */ + void (*busy)(rnd_hid_t *hid, rnd_bool busy); + + /* this field is used by that HID implementation to store its data */ + void *hid_data; + + /* convert hid_ctx into hidlib ptr; only valid within a DAD callback. This + is different from ->get_hidlib because this returns the hidlib associated + with the dialog, which (for multi-instance local dialogs) may be different + from the hidlib what's currently show by the GUI */ + rnd_hidlib_t *(*get_dad_hidlib)(void *hid_ctx); + + /*** (these should be upper, but the struct has to be extended at spares + for binary compatibility) ***/ + + /* Spare: see doc/developer/spare.txt */ + void (*spare_f1)(void), (*spare_f2)(void), (*spare_f3)(void), (*spare_f4)(void), (*spare_f5)(void), (*spare_f6)(void); + long spare_l1, spare_l2, spare_l3, spare_l4, spare_l5, spare_l6, spare_l7, spare_l8; + void *spare_p1, *spare_p2, *spare_p3, *spare_p4, *spare_p5, *spare_p6; + double spare_d1, spare_d2, spare_d3, spare_d4, spare_d5, spare_d6; + rnd_coord_t spare_c1, spare_c2, spare_c3, spare_c4; +}; + +typedef void (*rnd_hid_expose_cb_t)(rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e); + +struct rnd_hid_expose_ctx_s { + rnd_box_t view; + rnd_hid_expose_cb_t expose_cb; /* function that is called on expose to get things drawn */ + void *draw_data; /* user data for the expose function */ + + /* Spare: see doc/developer/spare.txt */ + void (*spare_f1)(void), (*spare_f2)(void); + long spare_l1, spare_l2, spare_l3, spare_l4; + void *spare_p1, *spare_p2, *spare_p3, *spare_p4; + double spare_d1, spare_d2, spare_d3, spare_d4; + rnd_coord_t spare_c1, spare_c2, spare_c3, spare_c4; +}; + +typedef void (*rnd_hid_expose_t)(rnd_hid_t *hid, const rnd_hid_expose_ctx_t *ctx); + +/* This is initially set to a "no-gui" GUI, and later reset by + main. It is used for on-screen GUI calls, such as dialog boxes */ +/*extern rnd_hid_t *rnd_gui; - declared in core/error.h */ + +/* This is initially set to a "no-gui" GUI, and later reset by + main. hid_expose_callback also temporarily set it for drawing. Normally + matches rnd_gui, but is temporarily changed while exporting. It is used + for drawing calls, mainly by draw*.c */ +extern rnd_hid_t *rnd_render; + +/* This is either NULL or points to the current HID that is being called to + do the exporting. The GUI HIDs set and unset this var.*/ +extern rnd_hid_t *rnd_exporter; + +/* This is either NULL or points to the current rnd_action_t that is being + called. The action launcher sets and unsets this variable. */ +extern const rnd_action_t *rnd_current_action; + +/* The GUI may set this to be approximately the physical size of a pixel, + to allow for near-misses in selection and changes in drawing items + smaller than a screen pixel. */ +extern int rnd_pixel_slop; + +/*** Glue for GUI/CLI dialogs: wrappers around actions */ + +/* Prompts the user to enter a string, returns the string. If + default_string isn't NULL, the form is pre-filled with this + value. "msg" is printed above the query. The optional title + is the window title. + Returns NULL on cancel. The caller needs to free the returned string */ +char *rnd_hid_prompt_for(rnd_hidlib_t *hl, const char *msg, const char *default_string, const char *title); + +/* Present a dialog box with a message and variable number of buttons. If icon + is not NULL, attempt to draw the named icon on the left. The vararg part is + one or more buttons, as a list of "char *label, int retval", terminated with + NULL. */ +int rnd_hid_message_box(rnd_hidlib_t *hl, const char *icon, const char *title, const char *label, ...); + +/* Show modal progressbar to the user, offering cancel long running processes. + Pass all zeros to flush display and remove the dialog. + Returns nonzero if the user wishes to cancel the operation. */ +int rnd_hid_progress(long so_far, long total, const char *message); + +/* non-zero if DAD dialogs are available currently */ +#define RND_HAVE_GUI_ATTR_DLG \ + ((rnd_gui != NULL) && (rnd_gui->gui) && (rnd_gui->attr_dlg_new != NULL) && (rnd_gui->attr_dlg_new != rnd_nogui_attr_dlg_new)) +void *rnd_nogui_attr_dlg_new(rnd_hid_t *hid, const char *id, rnd_hid_attribute_t *attrs_, int n_attrs_, const char *title_, void *caller_data, rnd_bool modal, void (*button_cb)(void *caller_data, rnd_hid_attr_ev_t ev), int defx, int defy, int minx, int miny); + +int rnd_hid_dock_enter(rnd_hid_dad_subdialog_t *sub, rnd_hid_dock_t where, const char *id); +void rnd_hid_dock_leave(rnd_hid_dad_subdialog_t *sub); + +#define rnd_hid_redraw(pcb) rnd_gui->invalidate_all(rnd_gui) + +#define rnd_hid_busy(pcb, is_busy) \ +do { \ + rnd_event(&pcb->hidlib, RND_EVENT_BUSY, "i", is_busy, NULL); \ + if ((rnd_gui != NULL) && (rnd_gui->busy != NULL)) \ + rnd_gui->busy(rnd_gui, is_busy); \ +} while(0) + + +/* Notify the GUI that data relating to the crosshair is being changed. + * + * The argument passed is rnd_false to notify "changes are about to happen", + * and rnd_true to notify "changes have finished". + * + * Each call with a 'rnd_false' parameter must be matched with a following one + * with a 'rnd_true' parameter. Unmatched 'rnd_true' calls are currently not permitted, + * but might be allowed in the future. + * + * GUIs should not complain if they receive extra calls with 'rnd_true' as parameter. + * They should initiate a redraw of the crosshair attached objects - which may + * (if necessary) mean repainting the whole screen if the GUI hasn't tracked the + * location of existing attached drawing. */ +void rnd_hid_notify_crosshair_change(rnd_hidlib_t *hl, rnd_bool changes_complete); + +/* Plugin helper: timed batch updates; any plugin may trigger the update, multiple + triggers are batched and only a single RND_EVENT_GUI_BATCH_TIMER is emitted + after a certain time passed since the last trigger. The event is emitted + with the last hidlib argument passed. If there's no GUI available, no event + is emitted. */ +void rnd_hid_gui_batch_timer(rnd_hidlib_t *hidlib); + + /* Run the file selection dialog. Return a string the caller needs to free(). + * title may be used as a dialog box title. Ignored if NULL. + * + * descr is a longer help string. Not used at the moment. Ignored if NULL. + * + * default_file is the default file name. Ignored if NULL. + * + * default_ext is the default file extension, like ".pdf". + * Ignored if NULL. + * + * flt is a {NULL} terminated array of file filters; HID support is optional. + * Ignored if NULL. If NULL and default_ext is not NULL, the HID may make + * up a minimalistic filter from the default_ext also allowing *.*. + * + * history_tag may be used by the GUI to keep track of file + * history. Examples would be "board", "vendor", "renumber", + * etc. If NULL, no specific history is kept. + * + * flags_ are the bitwise OR + * + * sub is an optional DAD sub-dialog, can be NULL; its parent_poke commands: + * close close the dialog + * get_path returns the current full path in res as an strdup'd string (caller needs to free it) + * set_file_name replaces the file name portion of the current path from arg[0].d.s + */ +char *rnd_hid_fileselect(rnd_hid_t *hid, const char *title, const char *descr, const char *default_file, const char *default_ext, const rnd_hid_fsd_filter_t *flt, const char *history_tag, rnd_hid_fsd_flags_t flags, rnd_hid_dad_subdialog_t *sub); + + +/* temporary, will be removed in 4.0.0 where it will become hardwired 1: + if set to 1, enable each DAD dialog remembering their own hid; when 0, + ->get_dad_hidlib() returns the same hid-global "currently displayed" + value as ->get_hidlib(); 0 is the default, old, pre-4.0.0 behavior */ +extern int rnd_hid_enable_per_dialog_hidlib; + +/* Actual implementation of rnd_hid_fileselect(); registered by the plugin + that implements file selection (typically lib_hid_common). The reason + for this abstraction is that we do not need to compile the code for + the file select dialog into core, useful in non-GUI cases. */ +extern char *(*rnd_hid_fileselect_imp)(rnd_hid_t *hid, const char *title, const char *descr, const char *default_file, const char *default_ext, const rnd_hid_fsd_filter_t *flt, const char *history_tag, rnd_hid_fsd_flags_t flags, rnd_hid_dad_subdialog_t *sub); + +/* If the mouse cursor is in the drawin area, set x;y silently and return; + else show msg and let the user click in the drawing area. If force is + non-zero and msg is non-NULL, discard the cache and force querying a + new coord. This mode must NOT be used unless action arguments explictly + requested it. Returns 0 on success, -1 on esc pressed */ +int rnd_hid_get_coords(const char *msg, rnd_coord_t *x, rnd_coord_t *y, int force); + +#endif Index: trunk/src/librnd/hid/hid_act.c =================================================================== --- trunk/src/librnd/hid/hid_act.c (nonexistent) +++ trunk/src/librnd/hid/hid_act.c (revision 34602) @@ -0,0 +1,202 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,2020,2021 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static const char rnd_acts_ChkMode[] = "ChkMode(expected_mode)" ; +static const char rnd_acth_ChkMode[] = "Return 1 if the currently selected mode is the expected_mode"; +static fgw_error_t rnd_act_ChkMode(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *dst; + rnd_toolid_t id; + + RND_ACT_CONVARG(1, FGW_STR, ChkMode, dst = argv[1].val.str); + + id = rnd_tool_lookup(dst); + if (id >= 0) { + RND_ACT_IRES(rnd_conf.editor.mode == id); + return 0; + } + RND_ACT_IRES(-1); + return 0; +} + + +static const char rnd_acts_ChkGridSize[] = + "ChkGridSize(expected_size)\n" + "ChkGridSize(none)\n" + ; +static const char rnd_acth_ChkGridSize[] = "Return 1 if the currently selected grid matches the expected_size. If argument is \"none\" return 1 if there is no grid."; +static fgw_error_t rnd_act_ChkGridSize(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *dst; + + RND_ACT_CONVARG(1, FGW_STR, ChkGridSize, dst = argv[1].val.str); + + if (strcmp(dst, "none") == 0) { + RND_ACT_IRES(RND_ACT_HIDLIB->grid <= 300); + return 0; + } + + RND_ACT_IRES(RND_ACT_HIDLIB->grid == rnd_get_value_ex(dst, NULL, NULL, NULL, NULL, NULL)); + return 0; +} + + +static const char rnd_acts_ChkGridUnits[] = "ChkGridUnits(expected)"; +static const char rnd_acth_ChkGridUnits[] = "Return 1 if currently selected grid unit matches the expected (normally mm or mil)"; +static fgw_error_t rnd_act_ChkGridUnits(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *expected; + RND_ACT_CONVARG(1, FGW_STR, ChkGridUnits, expected = argv[1].val.str); + RND_ACT_IRES(strcmp(rnd_conf.editor.grid_unit->suffix, expected) == 0); + return 0; +} + +static const char rnd_acts_SetGrid[] = "SetGrid(delta|*mult|/div, [unit])"; +static const char rnd_acth_SetGrid[] = "Change grid size."; +/* for doc: copy from SetValue(grid,...) */ +static fgw_error_t rnd_act_SetGrid(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *val, *units = NULL; + rnd_bool absolute; + double value; + + RND_ACT_CONVARG(1, FGW_STR, SetGrid, val = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, SetGrid, units = argv[2].val.str); + + RND_ACT_IRES(0); + + /* special case: can't convert with rnd_get_value() */ + if ((val[0] == '*') || (val[0] == '/')) { + double d; + char *end; + + d = strtod(val+1, &end); + if ((*end != '\0') || (d <= 0)) { + rnd_message(RND_MSG_ERROR, "SetGrid: Invalid multiplier/divider for grid set: needs to be a positive number\n"); + return 1; + } + rnd_grid_inval(); + if (val[0] == '*') + rnd_hidlib_set_grid(RND_ACT_HIDLIB, rnd_round(RND_ACT_HIDLIB->grid * d), rnd_false, 0, 0); + else + rnd_hidlib_set_grid(RND_ACT_HIDLIB, rnd_round(RND_ACT_HIDLIB->grid / d), rnd_false, 0, 0); + return 0; + } + + value = rnd_get_value(val, units, &absolute, NULL); + + rnd_grid_inval(); + if (absolute) + rnd_hidlib_set_grid(RND_ACT_HIDLIB, value, rnd_false, 0, 0); + else { + /* On the way down, until the minimum unit (1) */ + if ((value + RND_ACT_HIDLIB->grid) < 1) + rnd_hidlib_set_grid(RND_ACT_HIDLIB, 1, rnd_false, 0, 0); + else if (RND_ACT_HIDLIB->grid == 1) + rnd_hidlib_set_grid(RND_ACT_HIDLIB, value, rnd_false, 0, 0); + else + rnd_hidlib_set_grid(RND_ACT_HIDLIB, value + RND_ACT_HIDLIB->grid, rnd_false, 0, 0); + } + return 0; +} + +static const char rnd_acts_SetGridOffs[] = "SetGridOffs(x_offs, y_offs)"; +static const char rnd_acth_SetGridOffs[] = "Change grid offset (alignment) to x_offs and y_offs. Offsets should be specified with units."; +/* DOC: setgridoffs.html */ +static fgw_error_t rnd_act_SetGridOffs(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *xs, *ys; + rnd_bool xa, ya, xv, yv; + rnd_coord_t x, y; + + RND_ACT_CONVARG(1, FGW_STR, SetGridOffs, xs = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, SetGridOffs, ys = argv[2].val.str); + + RND_ACT_IRES(0); + + x = rnd_get_value(xs, NULL, &xa, &xv); + y = rnd_get_value(ys, NULL, &ya, &yv); + + if (!xv || !yv) { + rnd_message(RND_MSG_ERROR, "SetGrid: Invalid%s%s offset value\n", (xv ? "" : " x"), (yv ? "" : " x")); + return 1; + } + + if (!xa) x += RND_ACT_HIDLIB->grid_ox; + if (!ya) y += RND_ACT_HIDLIB->grid_oy; + + + rnd_grid_inval(); + rnd_hidlib_set_grid(RND_ACT_HIDLIB, RND_ACT_HIDLIB->grid, rnd_true, x, y); + + return 0; +} + +static const char rnd_acts_setunits[] = "SetUnits(mm|mil)"; +static const char rnd_acth_setunits[] = "Set the default measurement units."; +/* DOC: setunits.html */ +static fgw_error_t rnd_act_SetUnits(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const rnd_unit_t *new_unit; + const char *name; + + RND_ACT_CONVARG(1, FGW_STR, setunits, name = argv[1].val.str); + RND_ACT_IRES(0); + + new_unit = rnd_get_unit_struct(name); + rnd_hidlib_set_unit(RND_ACT_HIDLIB, new_unit); + + return 0; +} + +static rnd_action_t rnd_hid_action_list[] = { + {"ChkMode", rnd_act_ChkMode, rnd_acth_ChkMode, rnd_acts_ChkMode}, + {"ChkGridSize", rnd_act_ChkGridSize, rnd_acth_ChkGridSize, rnd_acts_ChkGridSize}, + {"ChkGridUnits", rnd_act_ChkGridUnits, rnd_acth_ChkGridUnits, rnd_acts_ChkGridUnits}, + {"SetGrid", rnd_act_SetGrid, rnd_acth_SetGrid, rnd_acts_SetGrid}, + {"SetGridOffs", rnd_act_SetGridOffs, rnd_acth_SetGridOffs, rnd_acts_SetGridOffs}, + {"SetUnits", rnd_act_SetUnits, rnd_acth_setunits, rnd_acts_setunits} +}; + +void rnd_hid_act_init2(void) +{ + RND_REGISTER_ACTIONS(rnd_hid_action_list, NULL); +} + + + Index: trunk/src/librnd/hid/hid_attrib.c =================================================================== --- trunk/src/librnd/hid/hid_attrib.c (nonexistent) +++ trunk/src/librnd/hid/hid_attrib.c (revision 34602) @@ -0,0 +1,309 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 2004 harry eaton + * Copyright (C) 2016..2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include +#include +#include +#include +#include + +rnd_hid_attr_node_t *rnd_hid_attr_nodes = 0; + +void rnd_export_register_opts2(rnd_hid_t *hid, const rnd_export_opt_t *a, int n, const char *cookie, int copy) +{ + rnd_hid_attr_node_t *ha; + + /* printf("%d attributes registered\n", n); */ + ha = malloc(sizeof(rnd_hid_attr_node_t)); + ha->next = rnd_hid_attr_nodes; + rnd_hid_attr_nodes = ha; + ha->opts = a; + ha->n = n; + ha->cookie = cookie; + ha->hid = hid; +} + +void rnd_export_uninit(void) +{ + rnd_hid_attr_node_t *ha, *next; + for (ha = rnd_hid_attr_nodes; ha; ha = next) { + next = ha->next; + if (ha->cookie != NULL) + fprintf(stderr, "WARNING: attribute %s by %s is not uninited, check your plugins' uninit!\n", ha->opts->name, ha->cookie); + free(ha); + } + rnd_hid_attr_nodes = NULL; +} + +void rnd_export_remove_opts_by_cookie(const char *cookie) +{ + rnd_hid_attr_node_t *ha, *next, *prev = NULL; + for (ha = rnd_hid_attr_nodes; ha; ha = next) { + next = ha->next; + if (ha->cookie == cookie) { + if (prev == NULL) + rnd_hid_attr_nodes = next; + else + prev->next = next; + free(ha); + } + else + prev = ha; + } +} + +static void opt2attr(rnd_hid_attr_val_t *dst, const rnd_export_opt_t *src) +{ + switch (src->type) { + case RND_HATT_LABEL: + case RND_HATT_INTEGER: + case RND_HATT_COORD: + case RND_HATT_BOOL: + case RND_HATT_REAL: + case RND_HATT_ENUM: + case RND_HATT_UNIT: + *dst = src->default_val; + break; + case RND_HATT_STRING: + free((char *)dst->str); + dst->str = src->default_val.str == NULL ? NULL : rnd_strdup(src->default_val.str); + break; + default: + if (RND_HATT_IS_COMPOSITE(src->type)) /* function callback */ + break; + rnd_message(RND_MSG_ERROR, "Invalid attribute type %d for attribute %s\n", src->type, src->name); + abort(); + } +} + +void rnd_hid_load_defaults(rnd_hid_t *hid, const rnd_export_opt_t *opts, int len) +{ + int n; + rnd_hid_attr_val_t *values = hid->argument_array; + + for(n = 0; n < len; n++) + opt2attr(&values[n], opts + n); +} + + +#define MAX_FILENAMES 1024 +int rnd_hid_parse_command_line(int *argc, char ***argv) +{ + rnd_hid_attr_node_t *ha; + int i, e, ok, filenames = 0; + char *filename[MAX_FILENAMES+2], *end; + rnd_bool succ; + + /* set defaults */ + for (ha = rnd_hid_attr_nodes; ha; ha = ha->next) { + rnd_hid_attr_val_t *backup = NULL; + if (ha->hid != NULL) + backup = ha->hid->argument_array; + + if (backup == NULL) { + rnd_message(RND_MSG_ERROR, "rnd_hid_parse_command_line(): no backup storage. Direct ->value field is not supported anymore. Your hid/export plugin (%s, %s) needs to be fixed.\n", ha->hid->name, ha->cookie); + return -1; + } + rnd_hid_load_defaults(ha->hid, ha->opts, ha->n); + } + + /* parse the command line and overwrite with values read from argc/argv */ + while(*argc > 0) + if (*argc && (*argv)[0][0] == '-' && (*argv)[0][1] == '-') { + int bool_val; + int arg_ofs; + + bool_val = 1; + arg_ofs = 2; + try_no_arg:; + for (ha = rnd_hid_attr_nodes; ha; ha = ha->next) { + rnd_hid_attr_val_t *backup = ha->hid->argument_array; + + for (i = 0; i < ha->n; i++) + if (strcmp((*argv)[0] + arg_ofs, ha->opts[i].name) == 0) { + const rnd_export_opt_t *a = ha->opts + i; + char *ep; + const rnd_unit_t *unit; + switch (ha->opts[i].type) { + case RND_HATT_LABEL: + break; + case RND_HATT_INTEGER: + if ((*argv)[1] == NULL) { + rnd_message(RND_MSG_ERROR, "export parameter error: %s requires a parameter\n", (*argv)[0]); + return -1; + } + else + backup[i].lng = strtol((*argv)[1], &end, 0); + if (*end != '\0') { + rnd_message(RND_MSG_ERROR, "export parameter error: %s requires an integer but got '%s'\n", (*argv)[0], (*argv)[1]); + return -1; + } + (*argc)--; + (*argv)++; + break; + case RND_HATT_COORD: + if ((*argv)[1] == NULL) { + rnd_message(RND_MSG_ERROR, "export parameter error: %s requires a parameter\n", (*argv)[0]); + return -1; + } + else + backup[i].crd = rnd_get_value((*argv)[1], NULL, NULL, &succ); + if (!succ) { + rnd_message(RND_MSG_ERROR, "export parameter error: %s requires a coord value but got '%s'\n", (*argv)[0], (*argv)[1]); + return -1; + } + (*argc)--; + (*argv)++; + break; + case RND_HATT_REAL: + if ((*argv)[1] == NULL) { + rnd_message(RND_MSG_ERROR, "export parameter error: %s requires a parameter\n", (*argv)[0]); + return -1; + } + else + backup[i].dbl = strtod((*argv)[1], &end); + if (*end != '\0') { + rnd_message(RND_MSG_ERROR, "export parameter error: %s requires a number but got '%s'\n", (*argv)[0], (*argv)[1]); + return -1; + } + (*argc)--; + (*argv)++; + break; + case RND_HATT_STRING: + backup[i].str = rnd_strdup(RND_EMPTY((*argv)[1])); + (*argc)--; + (*argv)++; + break; + case RND_HATT_BOOL: + backup[i].lng = bool_val; + break; + case RND_HATT_ENUM: + if ((*argv)[1] == NULL) { + rnd_message(RND_MSG_ERROR, "export parameter error: %s requires a parameter\n", (*argv)[0]); + return -1; + } + else + ep = (*argv)[1]; + ok = 0; + for (e = 0; a->enumerations[e]; e++) + if (strcmp(a->enumerations[e], ep) == 0) { + ok = 1; + backup[i].lng = e; + backup[i].str = ep; + break; + } + if (!ok) { + rnd_message(RND_MSG_ERROR, "ERROR: \"%s\" is an unknown value for the --%s option\n", (*argv)[1], a->name); + return -1; + } + (*argc)--; + (*argv)++; + break; + case RND_HATT_UNIT: + if ((*argv)[1] == NULL) { + rnd_message(RND_MSG_ERROR, "export parameter error: %s requires a parameter\n", (*argv)[0]); + return -1; + } + else + unit = rnd_get_unit_struct((*argv)[1]); + if (unit == NULL) { + rnd_message(RND_MSG_ERROR, "ERROR: unit \"%s\" is unknown to pcb (option --%s)\n", (*argv)[1], a->name); + return -1; + } + backup[i].lng = unit->index; + backup[i].str = unit->suffix; + (*argc)--; + (*argv)++; + break; + default: + break; + } + (*argc)--; + (*argv)++; + ha = 0; + goto got_match; + } + } + if (bool_val == 1 && strncmp((*argv)[0], "--no-", 5) == 0) { + bool_val = 0; + arg_ofs = 5; + goto try_no_arg; + } + rnd_message(RND_MSG_ERROR, "unrecognized option: %s\n", (*argv)[0]); + return -1; + got_match:; + } + else { + /* Any argument without the "--" is considered a filename. Take only + one filename for now */ + + if (filenames > MAX_FILENAMES) { + rnd_message(RND_MSG_ERROR, "Too manu filenames specified. Overflow at filename: %s\n", (*argv)[0]); + return -1; + } + if (!rnd_app.multi_design && (filenames > 0)) { + rnd_message(RND_MSG_ERROR, "Multiple filenames not supported. First filename was: %s; offending second filename: %s\n", filename[0], (*argv)[0]); + return -1; + } + + filename[filenames++] = (*argv)[0]; + (*argc)--; + (*argv)++; + } + + /* restore filename to the first argument */ + for(i = 0; i < filenames; i++) + (*argv)[i] = filename[i]; + (*argc) = filenames; + + return 0; +} + +void rnd_hid_usage_option(const char *name, const char *help) +{ + fprintf(stderr, "--%-20s %s\n", name, help); +} + +void rnd_hid_usage(const rnd_export_opt_t *a, int numa) +{ + for (; numa > 0; numa--,a++) { + const char *help; + if (a->help_text == NULL) help = ""; + else help = a->help_text; + if (RND_HATT_IS_COMPOSITE(a->type)) { + rnd_hid_export_opt_func_t fnc = a->default_val.func; + if (fnc != NULL) + fnc(RND_HIDEOF_USAGE, stderr, a, NULL); + } + else + rnd_hid_usage_option(a->name, help); + } +} + Index: trunk/src/librnd/hid/hid_attrib.h =================================================================== --- trunk/src/librnd/hid/hid_attrib.h (nonexistent) +++ trunk/src/librnd/hid/hid_attrib.h (revision 34602) @@ -0,0 +1,187 @@ +#ifndef RND_HID_ATTRIB_H +#define RND_HID_ATTRIB_H + +#include +#include +#include + +/* Used for HID attributes (exporting and printing, mostly). + HA_boolean uses lng, HA_enum sets lng to the index and + str to the enumeration string. RND_HATT_LABEL just shows the + default str. */ +struct rnd_hid_attr_val_s { + long lng; + const char *str; + double dbl; + rnd_coord_t crd; + rnd_color_t clr; + void (*func)(); +}; + +typedef enum rnd_hatt_compflags_e { + RND_HATF_FRAME = 1, /* box/table has a visible frame around it */ + RND_HATF_TIGHT = 2, /* box/table/button has minimal padding and spacing */ + RND_HATF_SCROLL = 4, /* box/table is scrollable */ + RND_HATF_HIDE_TABLAB = 8, /* hide tab labes of a TABBED - the tab mechanism works, but tab names are not displayed and are not clickable */ + RND_HATF_CLR_STATIC = 8, /* color that can not be changed */ + RND_HATF_LEFT_TAB = 16, /* display tab labels of TABBED on the left instead of on top (default) */ + RND_HATF_TREE_COL = 32, /* first column of a RND_HATT_TREE is a tree */ + RND_HATF_EXPFILL = 64, /* for hbox and vbox: expand and fill */ + RND_HATF_HIDE = 128,/* widget is initially hidden */ + RND_HATF_TOGGLE = 256,/* for buttons and picbuttons: use a toggle button instead of a push button */ + RND_HATF_TEXT_TRUNCATED = 512, /* label: do not set widget size for text, truncate text if widget is smaller */ + RND_HATF_TEXT_VERTICAL = 1024,/* label: rotate text 90 degrees so it can be read from the right */ + RND_HATF_PRV_DESIGN = 2048, /* indicates that a preview widget is showing a section of the design so it needs to be redrawn when the (top window) design is redrawn */ + RND_HATF_WIDTH_CHR = 4096, /* ->geo_width is specified in charactes */ + RND_HATF_HEIGHT_CHR = 8192, /* ->geo_width is specified in charactes */ + RND_HATF_INIT_FOCUS = 16384, /* this widget has (keyboard) focus on widget creation */ + RND_HATF_PRV_GFLIP = 32768, /* global design flip determines preview flip */ + RND_HATF_PRV_LFLIP = 65536, /* local flip determines preview flip; when set RND_HATF_PRV_GFLIP is ignored */ + RND_HATF_PRG_SMALL = 131072, /* allow progress bar to be as small as possible */ + RND_HATF_TREE_NO_AUTOEXP = 262144 /* do not auto-expand or auto-colleps on tree row activation */ +} rnd_hatt_compflags_t; + +typedef enum rnd_hid_attr_type_e { + /* atomic entry types */ + RND_HATT_LABEL, + RND_HATT_INTEGER, + RND_HATT_REAL, + RND_HATT_STRING, /* WARNING: string, must be malloc()'d, can't be a (const char *) */ + RND_HATT_BOOL, + RND_HATT_ENUM, + RND_HATT_UNIT, + RND_HATT_COORD, + RND_HATT_BUTTON, /* push button; default value is the label */ + RND_HATT_TREE, /* tree/list/table view; number of columns: rnd_hatt_table_cols; data is in field 'wdata' */ + RND_HATT_PROGRESS, /* progress bar; displays dbl between 0 and 1 */ + RND_HATT_PREVIEW, /* preview/render widget; callbacks in 'wdata' */ + RND_HATT_PICTURE, /* static picture from xpm - picture data in wdata */ + RND_HATT_PICBUTTON, /* button with static picture from xpm - picture data in wdata */ + RND_HATT_COLOR, /* color pick (user input: select a color) */ + RND_HATT_TEXT, /* plain text editor; data is in 'wdata' as rnd_hid_text_t */ + RND_HATT_SUBDIALOG, /* caller operated subdialog (docked dialog); available from librnd 3.1.0 */ + + /* groups (e.g. boxes) */ + RND_HATT_BEGIN_HBOX = 100, /* NOTE: RND_HATT_IS_COMPOSITE() depends on it */ + RND_HATT_BEGIN_VBOX, + RND_HATT_BEGIN_HPANE, /* horizontal split and offer two vboxes; the split ratio is dbl between 0 and 1, that describes the left side's size */ + RND_HATT_BEGIN_VPANE, /* vertical split and offer two vboxes; the split ratio is dbl between 0 and 1, that describes the left side's size */ + RND_HATT_BEGIN_TABLE, /* wdata_aux1 is the number of columns */ + RND_HATT_BEGIN_TABBED, /* tabbed view (e.g. notebook); ->wdata stores the tab names and a NULL; default_val's integer value is the index of the current tab */ + RND_HATT_BEGIN_COMPOUND, /* subtree emulating a single widget; (rnd_hid_compound_t *) stored in END's wdata */ + + RND_HATT_END = 200 /* close one level of RND_HATT_* */ +} rnd_hid_attr_type_t; + +#define RND_HATT_IS_COMPOSITE(type) \ + (((type) >= RND_HATT_BEGIN_HBOX) && ((type) < RND_HATT_END)) + +#define RND_HAT_IS_STR(type) (type == RND_HATT_STRING) + +/* alternative field names in struct rnd_hid_attribute_s */ +#define rnd_hatt_flags hatt_flags +#define rnd_hatt_table_cols wdata_aux1 + +struct rnd_hid_attribute_s { + const char *name; + const char *help_text; + rnd_hid_attr_type_t type; + double min_val, max_val; /* for integer and real */ + rnd_hid_attr_val_t val; /* Also actual value for global attributes. */ + + /* RND_HATT_ENUM: const char ** (NULL terminated list of values) + RND_HATT_PICTURE & RND_HATT_PICBUTTON: const char **xpm + RND_HATT_TREE and others: (rnd_hid_*_t *) */ + void *wdata; /* main widget data */ + int wdata_aux1; /* auixiliary widget data - should phase out long term */ + + /* dynamic API */ + unsigned changed:1; /* 0 for initial values, 1 on user change */ + unsigned empty:1; /* set to 1 by the widget implementation if the textual value is empty, where applicable */ + void (*change_cb)(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); /* called upon value change by the user */ + void (*right_cb)(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); /* called upon right click by the user */ + void (*enter_cb)(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); /* called upon the user pressed enter in a widget that handles keys */ + void *user_data; /* ignored; the caller is free to use it */ + rnd_hatt_compflags_t hatt_flags; + + /* geometry */ + int geo_width; /* when RND_HATF_WIDTH_CHR is set, width of the widget in characters, on creation-time */ + int geo_height; + + /* Spare: see doc/developer/spare.txt */ + void (*spare_f1)(void), (*spare_f2)(void); + long spare_l1, spare_l2, spare_l3, spare_l4; + void *spare_p1, *spare_p2, *spare_p3, *spare_p4; + double spare_d1, spare_d2; + rnd_coord_t spare_c1, spare_c2; +}; + +struct rnd_export_opt_s { + const char *name; + const char *help_text; + rnd_hid_attr_type_t type; + double min_val, max_val; /* for integer and real */ + rnd_hid_attr_val_t default_val; + const char **enumerations; /* NULL terminated list of values for a RND_HATT_ENUM */ + + + /* This used to be an alternative value target but as a void * it did + no work on all platforms - it was not clear what different HATT types + should write, especially for an enum: int *, long *... */ + /* void *value; */ +}; + +/* Load export plugin's read-write hid->attribute_array with defaults from + read-only opts; do this once, at init. */ +void rnd_hid_load_defaults(rnd_hid_t *hid, const rnd_export_opt_t *opts, int len); + +/* The selected HID or export plugin (and potentially + dependent exporter plugins) register their options and command line + options will be looked up in these. Plugins not participating in the + current session won't register and the registration is lost immediately + after the export because the application exits. Cam or dialog box direct + exporting won't go through this. */ +void rnd_export_register_opts2(rnd_hid_t *hid, const rnd_export_opt_t *a, int n, const char *cookie, int copy); + +/* Remove all attributes registered with the given cookie */ +void rnd_export_remove_opts_by_cookie(const char *cookie); + +/* remove all attributes and free the list */ +void rnd_export_uninit(void); + +typedef struct rnd_hid_attr_node_s { + struct rnd_hid_attr_node_s *next; + rnd_hid_t *hid; + const rnd_export_opt_t *opts; + int n; + const char *cookie; +} rnd_hid_attr_node_t; + +extern rnd_hid_attr_node_t *rnd_hid_attr_nodes; + +void rnd_hid_usage(const rnd_export_opt_t *a, int numa); +void rnd_hid_usage_option(const char *name, const char *help); + +/* Count the number of direct children, start_from the first children */ +int rnd_hid_attrdlg_num_children(rnd_hid_attribute_t *attrs, int start_from, int n_attrs); + +/* Invoke a simple modal attribute dialog if GUI is available */ +int rnd_attribute_dialog_(const char *id, rnd_hid_attribute_t *attrs, int n_attrs, const char *title, void *caller_data, void **retovr, int defx, int defy, int minx, int miny, void **hid_ctx_out); +int rnd_attribute_dialog(const char *id, rnd_hid_attribute_t *attrs, int n_attrs, const char *title, void *caller_data); + + +/* Convert between compflag bit value and name */ +const char *rnd_hid_compflag_bit2name(rnd_hatt_compflags_t bit); +rnd_hatt_compflags_t rnd_hid_compflag_name2bit(const char *name); + +/*** When an rnd_export_opt_t item is a box, the following function is called + from its ->func ***/ + +typedef enum rnd_hid_export_opt_func_action_e { + RND_HIDEOF_USAGE, /* call_ctx is a FILE * */ + RND_HIDEOF_DAD /* call_ctx is a rnd_hid_export_opt_func_dad_t */ +} rnd_hid_export_opt_func_action_t; + +typedef void (*rnd_hid_export_opt_func_t)(rnd_hid_export_opt_func_action_t act, void *call_ctx, const rnd_export_opt_t *opt, rnd_hid_attr_val_t *val); + +#endif Index: trunk/src/librnd/hid/hid_cfg_input.c =================================================================== --- trunk/src/librnd/hid/hid_cfg_input.c (nonexistent) +++ trunk/src/librnd/hid/hid_cfg_input.c (revision 34602) @@ -0,0 +1,836 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* split value into a list of '-' separated words; examine each word + and set the bitmask of modifiers */ +static rnd_hid_cfg_mod_t parse_mods(const char *value, const char **last, unsigned int vlen) +{ + rnd_hid_cfg_mod_t m = 0; + int press = 0; + const char *next; + + while(isspace(*value)) value++; + + if (*value != '<') { + for(;;) { + if ((vlen >= 5) && (rnd_strncasecmp(value, "shift", 5) == 0)) m |= RND_M_Shift; + else if ((vlen >= 4) && (rnd_strncasecmp(value, "ctrl", 4) == 0)) m |= RND_M_Ctrl; + else if ((vlen >= 3) && (rnd_strncasecmp(value, "alt", 3) == 0)) m |= RND_M_Alt; + else if ((vlen >= 7) && (rnd_strncasecmp(value, "release", 7) == 0)) m |= RND_M_Release; + else if ((vlen >= 5) && (rnd_strncasecmp(value, "press", 5) == 0)) press = 1; + else + rnd_message(RND_MSG_ERROR, "Unknown modifier: %s\n", value); + /* skip to next word */ + next = strpbrk(value, "<- \t"); + if (next == NULL) + break; + if (*next == '<') + break; + vlen -= (next - value); + value = next+1; + } + } + + if (last != NULL) + *last = value; + + if (press && (m & RND_M_Release)) + rnd_message(RND_MSG_ERROR, "Bogus modifier: both press and release\n"); + + return m; +} + +static rnd_hid_cfg_mod_t button_name2mask(const char *name) +{ + /* All mouse-related resources must be named. The name is the + mouse button number. */ + if (!name) + return 0; + else if (rnd_strcasecmp(name, "left") == 0) return RND_MB_LEFT; + else if (rnd_strcasecmp(name, "middle") == 0) return RND_MB_MIDDLE; + else if (rnd_strcasecmp(name, "right") == 0) return RND_MB_RIGHT; + + else if (rnd_strcasecmp(name, "scroll-up") == 0) return RND_MB_SCROLL_UP; + else if (rnd_strcasecmp(name, "scroll-down") == 0) return RND_MB_SCROLL_DOWN; + else if (rnd_strcasecmp(name, "scroll-left") == 0) return RND_MB_SCROLL_UP; + else if (rnd_strcasecmp(name, "scroll-right") == 0) return RND_MB_SCROLL_DOWN; + else { + rnd_message(RND_MSG_ERROR, "Error: unknown mouse button: %s\n", name); + return 0; + } +} + +static unsigned int keyhash_int(htip_key_t a) { return murmurhash32(a & 0xFFFF); } + +static unsigned int keyb_hash(const void *key_) +{ + const rnd_hid_cfg_keyhash_t *key = key_; + unsigned int i = 0; + i += key->key_raw; i <<= 8; + i += ((unsigned int)key->key_tr) << 4; + i += key->mods; + return murmurhash32(i); +} + +static int keyb_eq(const void *keya_, const void *keyb_) +{ + const rnd_hid_cfg_keyhash_t *keya = keya_, *keyb = keyb_; + return (keya->key_raw == keyb->key_raw) && (keya->key_tr == keyb->key_tr) && (keya->mods == keyb->mods); +} + +/************************** MOUSE ***************************/ + +int rnd_hid_cfg_mouse_init(rnd_hid_cfg_t *hr, rnd_hid_cfg_mouse_t *mouse) +{ + lht_node_t *btn, *m; + + mouse->mouse = rnd_hid_cfg_get_menu(hr, "/mouse"); + + if (mouse->mouse == NULL) { + rnd_message(RND_MSG_ERROR, "Warning: no /mouse section in the resource file - mouse is disabled\n"); + return -1; + } + + if (mouse->mouse->type != LHT_LIST) { + rnd_hid_cfg_error(mouse->mouse, "Warning: should be a list - mouse is disabled\n"); + return -1; + } + + if (mouse->mouse_mask == NULL) + mouse->mouse_mask = htip_alloc(keyhash_int, htip_keyeq); + else + htip_clear(mouse->mouse_mask); + + for(btn = mouse->mouse->data.list.first; btn != NULL; btn = btn->next) { + rnd_hid_cfg_mod_t btn_mask = button_name2mask(btn->name); + if (btn_mask == 0) { + rnd_hid_cfg_error(btn, "unknown mouse button"); + continue; + } + if (btn->type != LHT_LIST) { + rnd_hid_cfg_error(btn, "needs to be a list"); + continue; + } + for(m = btn->data.list.first; m != NULL; m = m->next) { + rnd_hid_cfg_mod_t mod_mask = parse_mods(m->name, NULL, -1); + htip_set(mouse->mouse_mask, btn_mask|mod_mask, m); + } + } + return 0; +} + +static lht_node_t *find_best_action(rnd_hid_cfg_mouse_t *mouse, rnd_hid_cfg_mod_t button_and_mask) +{ + lht_node_t *n; + + if (mouse->mouse_mask == NULL) + return NULL; + + /* look for exact mod match */ + n = htip_get(mouse->mouse_mask, button_and_mask); + if (n != NULL) + return n; + + if (button_and_mask & RND_M_Release) { + /* look for plain release for the given button */ + n = htip_get(mouse->mouse_mask, (button_and_mask & RND_M_ANY) | RND_M_Release); + if (n != NULL) + return n; + } + + return NULL; +} + +void rnd_hid_cfg_mouse_action(rnd_hidlib_t *hl, rnd_hid_cfg_mouse_t *mouse, rnd_hid_cfg_mod_t button_and_mask, rnd_bool cmd_entry_active) +{ + rnd_conf.temp.click_cmd_entry_active = cmd_entry_active; + rnd_hid_cfg_action(hl, find_best_action(mouse, button_and_mask)); + rnd_event(hl, RND_EVENT_USER_INPUT_POST, NULL); + rnd_conf.temp.click_cmd_entry_active = 0; +} + + +/************************** KEYBOARD ***************************/ +int rnd_hid_cfg_keys_init(rnd_hid_cfg_keys_t *km) +{ + htpp_init(&km->keys, keyb_hash, keyb_eq); + return 0; +} + +static void rnd_hid_cfg_keys_free(htpp_t *ht); + +static void rnd_hid_cfg_key_free(rnd_hid_cfg_keyseq_t *ns) +{ + rnd_hid_cfg_keys_free(&ns->seq_next); + htpp_uninit(&ns->seq_next); + free(ns); +} + +static void rnd_hid_cfg_keys_free(htpp_t *ht) +{ + htpp_entry_t *e; + for(e = htpp_first(ht); e != NULL; e = htpp_next(ht, e)) + rnd_hid_cfg_key_free(e->value); +} + +int rnd_hid_cfg_keys_uninit(rnd_hid_cfg_keys_t *km) +{ + rnd_hid_cfg_keys_free(&km->keys); + htpp_uninit(&km->keys); + return 0; +} + +rnd_hid_cfg_keyseq_t *rnd_hid_cfg_keys_add_under(rnd_hid_cfg_keys_t *km, rnd_hid_cfg_keyseq_t *parent, rnd_hid_cfg_mod_t mods, unsigned short int key_raw, unsigned short int key_tr, int terminal, const char **errmsg) +{ + rnd_hid_cfg_keyseq_t *ns; + rnd_hid_cfg_keyhash_t addr; + htpp_t *phash = (parent == NULL) ? &km->keys : &parent->seq_next; + + /* do not grow the tree under actions */ + if ((parent != NULL) && (parent->action_node != NULL)) { + if (*errmsg != NULL) + *errmsg = "unreachable multikey combo: prefix of the multikey stroke already has an action"; + return NULL; + } + + addr.mods = mods; + addr.key_raw = key_raw; + addr.key_tr = key_tr; + + /* already in the tree */ + ns = htpp_get(phash, &addr); + if (ns != NULL) { + if (terminal) { + if (*errmsg != NULL) + *errmsg = "duplicate: already registered"; + return NULL; /* full-path-match is collision */ + } + return ns; + } + + /* new node on this level */ + ns = calloc(sizeof(rnd_hid_cfg_keyseq_t), 1); + if (!terminal) + htpp_init(&ns->seq_next, keyb_hash, keyb_eq); + + ns->addr.mods = mods; + ns->addr.key_raw = key_raw; + ns->addr.key_tr = key_tr; + + htpp_set(phash, &ns->addr, ns); + return ns; +} + +const rnd_hid_cfg_keytrans_t rnd_hid_cfg_key_default_trans[] = { + { "semicolon", ';' }, + { NULL, 0 }, +}; + +static unsigned short int translate_key(rnd_hid_cfg_keys_t *km, const char *desc, int len) +{ + char tmp[256]; + + if ((km->auto_chr) && (len == 1)) + return *desc; + + if (len > sizeof(tmp)-1) { + rnd_message(RND_MSG_ERROR, "key sym name too long\n"); + return 0; + } + strncpy(tmp, desc, len); + tmp[len] = '\0'; + + if (km->auto_tr != NULL) { + const rnd_hid_cfg_keytrans_t *t; + for(t = km->auto_tr; t->name != NULL; t++) { + if (rnd_strcasecmp(tmp, t->name) == 0) { + tmp[0] = t->sym; + tmp[1] = '\0'; + len = 1; + break; + } + } + } + + return km->translate_key(tmp, len); +} + +static int parse_keydesc(rnd_hid_cfg_keys_t *km, const char *keydesc, rnd_hid_cfg_mod_t *mods, unsigned short int *key_raws, unsigned short int *key_trs, int arr_len, const lht_node_t *loc) +{ + const char *curr, *next, *last, *k; + int slen, len; + + slen = 0; + curr = keydesc; + do { + if (slen >= arr_len) + return -1; + while(isspace(*curr)) curr++; + if (*curr == '\0') + break; + next = strchr(curr, ';'); + if (next != NULL) { + len = next - curr; + while(*next == ';') next++; + } + else + len = strlen(curr); + + mods[slen] = parse_mods(curr, &last, len); + + k = strchr(last, '<'); + if (k == NULL) { + rnd_message(RND_MSG_ERROR, "Missing in the key description: '%s' at %s:%ld\n", keydesc, loc->file_name, loc->line+1); + return -1; + } + len -= k-last; + k++; len--; + if (rnd_strncasecmp(k, "key>", 4) == 0) { + k+=4; len-=4; + key_raws[slen] = translate_key(km, k, len); + key_trs[slen] = 0; + } + else if (rnd_strncasecmp(k, "char>", 5) == 0) { + k+=5; len-=5; + key_raws[slen] = 0; + if (!isalnum(*k)) + key_trs[slen] = *k; + else + key_trs[slen] = 0; + k++; len--; + } + else { + rnd_message(RND_MSG_ERROR, "Missing or in the key description starting at %s at %s:%ld\n", k-1, loc->file_name, loc->line+1); + return -1; + } + + if ((key_raws[slen] == 0) && (key_trs[slen] == 0)) { + char *s; + s = malloc(len+1); + memcpy(s, k, len); + s[len] = '\0'; + rnd_message(RND_MSG_ERROR, "Unrecognised key symbol in key description: %s at %s:%ld\n", s, loc->file_name, loc->line+1); + free(s); + return -1; + } + + slen++; + curr = next; + } while(curr != NULL); + return slen; +} + +int rnd_hid_cfg_keys_add_by_strdesc_(rnd_hid_cfg_keys_t *km, const char *keydesc, const lht_node_t *action_node, rnd_hid_cfg_keyseq_t **out_seq, int out_seq_len) +{ + rnd_hid_cfg_mod_t mods[RND_HIDCFG_MAX_KEYSEQ_LEN]; + unsigned short int key_raws[RND_HIDCFG_MAX_KEYSEQ_LEN]; + unsigned short int key_trs[RND_HIDCFG_MAX_KEYSEQ_LEN]; + rnd_hid_cfg_keyseq_t *lasts; + int slen, n; + const char *errmsg; + + slen = parse_keydesc(km, keydesc, mods, key_raws, key_trs, RND_HIDCFG_MAX_KEYSEQ_LEN, action_node); + if (slen <= 0) + return slen; + + if ((out_seq != NULL) && (slen >= out_seq_len)) + return -1; + +/* printf("KEY insert\n");*/ + + lasts = NULL; + for(n = 0; n < slen; n++) { + rnd_hid_cfg_keyseq_t *s; + int terminal = (n == slen-1); + +/* printf(" mods=%x sym=%x\n", mods[n], key_chars[n]);*/ + + s = rnd_hid_cfg_keys_add_under(km, lasts, mods[n], key_raws[n], key_trs[n], terminal, &errmsg); + if (s == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to add hotkey binding: %s: %s\n", keydesc, errmsg); + return -1; /* no need to free anything, uninit will recursively free the leftover at exit */ + } + if (terminal) + s->action_node = action_node; + + if (out_seq != NULL) + out_seq[n] = s; + lasts = s; + } + + return slen; +} + +int rnd_hid_cfg_keys_add_by_strdesc(rnd_hid_cfg_keys_t *km, const char *keydesc, const lht_node_t *action_node) +{ + return rnd_hid_cfg_keys_add_by_strdesc_(km, keydesc, action_node, NULL, 0); +} + +int rnd_hid_cfg_keys_add_by_desc_(rnd_hid_cfg_keys_t *km, const lht_node_t *keydescn, const lht_node_t *action_node, rnd_hid_cfg_keyseq_t **out_seq, int out_seq_len) +{ + switch(keydescn->type) { + case LHT_TEXT: return rnd_hid_cfg_keys_add_by_strdesc_(km, keydescn->data.text.value, action_node, out_seq, out_seq_len); + case LHT_LIST: + { + int ret = -1, cnt; + lht_node_t *n; + for(n = keydescn->data.list.first, cnt = 0; n != NULL; n = n->next, cnt++) { + if (n->type != LHT_TEXT) + break; + if (cnt == 0) + ret = rnd_hid_cfg_keys_add_by_strdesc_(km, n->data.text.value, action_node, out_seq, out_seq_len); + else + rnd_hid_cfg_keys_add_by_strdesc_(km, n->data.text.value, action_node, NULL, 0); + } + return ret; + } + default:; + } + return -1; +} + +int rnd_hid_cfg_keys_add_by_desc(rnd_hid_cfg_keys_t *km, const lht_node_t *keydescn, const lht_node_t *action_node) +{ + return rnd_hid_cfg_keys_add_by_desc_(km, keydescn, action_node, NULL, 0); +} + +int rnd_hid_cfg_keys_del_by_strdesc(rnd_hid_cfg_keys_t *km, const char *keydesc) +{ + rnd_hid_cfg_mod_t mods[RND_HIDCFG_MAX_KEYSEQ_LEN]; + unsigned short int key_raws[RND_HIDCFG_MAX_KEYSEQ_LEN]; + unsigned short int key_trs[RND_HIDCFG_MAX_KEYSEQ_LEN]; + int slen, n; + htpp_t *phash = &km->keys; + rnd_hid_cfg_keyseq_t *ns; + rnd_hid_cfg_keyhash_t addr; + htpp_entry_t *e; + + slen = parse_keydesc(km, keydesc, mods, key_raws, key_trs, RND_HIDCFG_MAX_KEYSEQ_LEN, NULL); + if (slen <= 0) + return slen; + + for(n = 0; n < slen; n++) { + int terminal = (n == slen-1); + + addr.mods = mods[n]; + addr.key_raw = key_raws[n]; + addr.key_tr = key_trs[n]; + + ns = htpp_get(phash, &addr); + if (ns == NULL) + return -1; + + if (!terminal) + phash = &ns->seq_next; + } + + e = htpp_popentry(phash, &addr); + if (e != NULL) + rnd_hid_cfg_key_free(e->value); + + return 0; +} + +int rnd_hid_cfg_keys_del_by_desc(rnd_hid_cfg_keys_t *km, const lht_node_t *keydescn) +{ + switch(keydescn->type) { + case LHT_TEXT: return rnd_hid_cfg_keys_del_by_strdesc(km, keydescn->data.text.value); + case LHT_LIST: + { + int ret = 0; + lht_node_t *n; + for(n = keydescn->data.list.first; n != NULL; n = n->next) { + if (n->type != LHT_TEXT) + break; + ret |= rnd_hid_cfg_keys_del_by_strdesc(km, n->data.text.value); + } + return ret; + } + default:; + } + return -1; +} + + +static void gen_accel(gds_t *s, rnd_hid_cfg_keys_t *km, const char *keydesc, int *cnt, const char *sep, const lht_node_t *loc) +{ + rnd_hid_cfg_mod_t mods[RND_HIDCFG_MAX_KEYSEQ_LEN]; + unsigned short int key_raws[RND_HIDCFG_MAX_KEYSEQ_LEN]; + unsigned short int key_trs[RND_HIDCFG_MAX_KEYSEQ_LEN]; + int slen, n; + + slen = parse_keydesc(km, keydesc, mods, key_raws, key_trs, RND_HIDCFG_MAX_KEYSEQ_LEN, loc); + if (slen <= 0) + return; + + if (*cnt > 0) + gds_append_str(s, sep); + + for(n = 0; n < slen; n++) { + char buff[64]; + + if (n > 0) + gds_append(s, ' '); + + + if (key_raws[n]) { + if (km->key_name(key_raws[n], buff, sizeof(buff)) != 0) + strcpy(buff, ""); + } + else if (key_trs[n] != 0) { + buff[0] = key_trs[n]; + buff[1] ='\0'; + } + else + strcpy(buff, ""); + + if (mods[n] & RND_M_Alt) gds_append_str(s, "Alt-"); + if (mods[n] & RND_M_Ctrl) gds_append_str(s, "Ctrl-"); + if (mods[n] & RND_M_Shift) gds_append_str(s, "Shift-"); + gds_append_str(s, buff); + } +} + +char *rnd_hid_cfg_keys_gen_accel(rnd_hid_cfg_keys_t *km, const lht_node_t *keydescn, unsigned long mask, const char *sep) +{ + gds_t s; + int cnt = 0; + + memset(&s, 0, sizeof(s)); + + switch(keydescn->type) { + case LHT_TEXT: + if (mask & 1) + gen_accel(&s, km, keydescn->data.text.value, &cnt, sep, keydescn); + break; + case LHT_LIST: + { + int cnt; + lht_node_t *n; + for(n = keydescn->data.list.first, cnt = 0; n != NULL; n = n->next, cnt++, mask >>= 1) { + if (n->type != LHT_TEXT) + break; + if (!(mask & 1)) + continue; + gen_accel(&s, km, n->data.text.value, &cnt, sep, keydescn); + } + } + default:; + } + return s.array; +} + +char *rnd_hid_cfg_keys_gen_desc(rnd_hid_cfg_mod_t mods, unsigned short int key_raw, unsigned short int key_tr) +{ + gds_t s = {0}; + + if (key_tr != 0) { + if ((key_tr <= 32) || (key_tr >= 127)) + return NULL; + gds_append_str(&s, ""); + gds_append(&s, key_tr); + return s.array; + } + + + TODO("We should call km->key_name, but where this call is coming from, km is not available"); + if ((key_raw <= 32) || (key_raw >= 127)) + return NULL; + + if (mods & RND_M_Alt) gds_append_str(&s, "Alt-"); + if (mods & RND_M_Ctrl) gds_append_str(&s, "Ctrl-"); + if (mods & RND_M_Shift) gds_append_str(&s, "Shift-"); + if (s.used > 0) s.used--; /* remove the trailing '-' */ + gds_append_str(&s, ""); + gds_append(&s, key_raw); + return s.array; +} + + +int rnd_hid_cfg_keys_input_(rnd_hidlib_t *hl, rnd_hid_cfg_keys_t *km, rnd_hid_cfg_mod_t mods, unsigned short int key_raw, unsigned short int key_tr, rnd_hid_cfg_keyseq_t **seq, int *seq_len) +{ + rnd_hid_cfg_keyseq_t *ns; + rnd_hid_cfg_keyhash_t addr; + htpp_t *phash = (*seq_len == 0) ? &km->keys : &((seq[(*seq_len)-1])->seq_next); + + if (key_raw == 0) { + static int warned = 0; + if (!warned) { + rnd_message(RND_MSG_ERROR, "Keyboard translation error: probably the US layout is not enabled. Some hotkeys may not work properly\n"); + warned = 1; + } + /* happens if only the translated version is available. Try to reverse + engineer it as good as we can. */ + if (isalpha(key_tr)) { + if (isupper(key_tr)) { + key_raw = tolower(key_tr); + mods |= RND_M_Shift; + } + else + key_raw = key_tr; + } + else if (isdigit(key_tr)) + key_raw = key_tr; + /* the rest: punctuations should be handled by key_tr; special keys: well... */ + } + + /* first check for base key + mods */ + addr.mods = mods; + addr.key_raw = key_raw; + addr.key_tr = 0; + + ns = htpp_get(phash, &addr); + + /* if not found, try with translated key + limited mods */ + if (ns == NULL) { + addr.mods = mods & RND_M_Ctrl; + addr.key_raw = 0; + addr.key_tr = key_tr; + ns = htpp_get(phash, &addr); + } + + /* already in the tree */ + if (ns == NULL) { + (*seq_len) = 0; + return -1; + } + + seq[*seq_len] = ns; + (*seq_len)++; + + /* found a terminal node with an action */ + if (ns->action_node != NULL) { + km->seq_len_action = *seq_len; + (*seq_len) = 0; + rnd_event(hl, RND_EVENT_USER_INPUT_KEY, NULL); + return km->seq_len_action; + } + + rnd_event(hl, RND_EVENT_USER_INPUT_KEY, NULL); + return 0; +} + + +/*** key translation hash ***/ +static int xlate_conf_rev = -1; /* last conf rev the translation table got checked on */ +static int xlate_avail = 0; +static htpp_t xlate_hash; + +static void xlate_uninit(void) +{ + genht_uninit_deep(htpp, &xlate_hash, { + free(htent->key); + free(htent->value); + }); +} + +static void xlate_reload(rnd_hid_cfg_keys_t *km, rnd_conf_native_t *nat) +{ + gdl_iterator_t it; + rnd_conf_listitem_t *kt; + + if (xlate_avail) { + xlate_uninit(); + xlate_avail = 0; + } + + if (rnd_conflist_length(nat->val.list) < 1) + return; + + htpp_init(&xlate_hash, keyb_hash, keyb_eq); + rnd_conflist_foreach(nat->val.list, &it, kt) { + rnd_hid_cfg_keyhash_t k, v, *hk, *hv; + rnd_hid_cfg_mod_t m; + + /* parse key and value to temporary k & v */ + if (parse_keydesc(km, kt->name, &m, &k.key_raw, &k.key_tr, 1, kt->prop.src) != 1) { + rnd_message(RND_MSG_ERROR, "Invalid key translation left side: '%s'\n (config problem, check your editor/translate_key)\n", kt->name); + continue; + } + k.mods = m; + if (parse_keydesc(km, kt->payload, &m, &v.key_raw, &v.key_tr, 1, kt->prop.src) != 1) { + rnd_message(RND_MSG_ERROR, "Invalid key translation left side: '%s'\n (config problem, check your editor/translate_key)\n", kt->payload); + continue; + } + v.mods = m; + hv = htpp_get(&xlate_hash, &k); + if (hv != NULL) { + rnd_message(RND_MSG_ERROR, "Ignoring redundant key translation: '%s'\n (config problem, check your editor/translate_key)\n", kt->payload); + continue; + } + else { + /* new key-val pair, add */ + hk = malloc(sizeof(rnd_hid_cfg_keyhash_t)); memcpy(hk, &k, sizeof(k)); + hv = malloc(sizeof(rnd_hid_cfg_keyhash_t)); memcpy(hv, &v, sizeof(v)); + htpp_insert(&xlate_hash, hk, hv); + } + } + xlate_avail = 1; +} + +int rnd_hid_cfg_keys_input(rnd_hidlib_t *hl, rnd_hid_cfg_keys_t *km, rnd_hid_cfg_mod_t mods, unsigned short int key_raw, unsigned short int key_tr) +{ + rnd_hid_cfg_keyhash_t ck, *cv; + + if (rnd_conf_rev > xlate_conf_rev) { + rnd_conf_native_t *nat = rnd_conf_get_field("editor/translate_key"); + if ((nat != NULL) && (nat->rnd_conf_rev > xlate_conf_rev)) + xlate_reload(km, nat); + xlate_conf_rev = rnd_conf_rev; + } + + if (xlate_avail) { + /* apply the key translation table from our config */ + ck.mods = mods; + ck.key_raw = key_raw; + ck.key_tr = 0; + + /* check by raw... */ + cv = htpp_get(&xlate_hash, &ck); + if (cv == NULL) { + /* if not found also check by translated */ + ck.key_raw = 0; + ck.key_tr = key_tr; + cv = htpp_get(&xlate_hash, &ck); + } + + /* hit: replace input key from the xlate table */ + if (cv != NULL) { + mods = cv->mods; + if (cv->key_raw != 0) + key_tr = key_raw = cv->key_raw; + if (cv->key_tr != 0) + key_tr = key_raw = cv->key_tr; + } + } + + return rnd_hid_cfg_keys_input_(hl, km, mods, key_raw, key_tr, km->seq, &km->seq_len); +} + + +/*** key translation hash ends **/ + +int rnd_hid_cfg_keys_action_(rnd_hidlib_t *hl, rnd_hid_cfg_keyseq_t **seq, int seq_len) +{ + int res; + + if (seq_len < 1) + return -1; + + res = rnd_hid_cfg_action(hl, seq[seq_len-1]->action_node); + rnd_event(hl, RND_EVENT_USER_INPUT_POST, NULL); + return res; +} + +int rnd_hid_cfg_keys_action(rnd_hidlib_t *hl, rnd_hid_cfg_keys_t *km) +{ + int ret = rnd_hid_cfg_keys_action_(hl, km->seq, km->seq_len_action); + km->seq_len_action = 0; + return ret; +} + +int rnd_hid_cfg_keys_seq_(rnd_hid_cfg_keys_t *km, rnd_hid_cfg_keyseq_t **seq, int seq_len, char *dst, int dst_len) +{ + int n, sum = 0; + char *end = dst; + + dst_len -= 25; /* make room for a full key with modifiers, the \0 and the potential ellipsis */ + + for(n = 0; n < seq_len; n++) { + int k = seq[n]->addr.key_raw, mods = seq[n]->addr.mods, ll = 0, l; + + if (n != 0) { + *end = ' '; + end++; + ll = 1; + } + + if (mods & RND_M_Alt) { strncpy(end, "Alt-", dst_len); end += 4; ll += 4; } + if (mods & RND_M_Ctrl) { strncpy(end, "Ctrl-", dst_len); end += 5; ll += 5; } + if (mods & RND_M_Shift) { strncpy(end, "Shift-", dst_len); end += 6; ll += 6; } + + if (k == 0) + k = seq[n]->addr.key_tr; + + if (km->key_name(k, end, dst_len) == 0) { + l = strlen(end); + } + else { + strncpy(end, "", dst_len); + l = 9; + } + + ll += l; + + sum += ll; + dst_len -= ll; + end += l; + + if (dst_len <= 1) { + strcpy(dst, " ..."); + sum += 4; + dst_len -= 4; + end += 4; + break; + } + } + *end = '\0'; + return sum; +} + +int rnd_hid_cfg_keys_seq(rnd_hid_cfg_keys_t *km, char *dst, int dst_len) +{ + if (km->seq_len_action > 0) + return rnd_hid_cfg_keys_seq_(km, km->seq, km->seq_len_action, dst, dst_len); + else + return rnd_hid_cfg_keys_seq_(km, km->seq, km->seq_len, dst, dst_len); +} + +void rnd_hid_cfg_keys_uninit_module(void) +{ + if (xlate_avail) + xlate_uninit(); +} + Index: trunk/src/librnd/hid/hid_cfg_input.h =================================================================== --- trunk/src/librnd/hid/hid_cfg_input.h (nonexistent) +++ trunk/src/librnd/hid/hid_cfg_input.h (revision 34602) @@ -0,0 +1,142 @@ +#ifndef RND_HID_CFG_INPUT_H +#define RND_HID_CFG_INPUT_H + +#include +#include +#include +#include + +/************************** MOUSE ***************************/ + +typedef struct { + lht_node_t *mouse; + htip_t *mouse_mask; +} rnd_hid_cfg_mouse_t; + +int rnd_hid_cfg_mouse_init(rnd_hid_cfg_t *hr, rnd_hid_cfg_mouse_t *mouse); +void rnd_hid_cfg_mouse_action(rnd_hidlib_t *hl, rnd_hid_cfg_mouse_t *mouse, rnd_hid_cfg_mod_t button_and_mask, rnd_bool cmd_entry_active); + + +/************************** KEYBOARD ***************************/ +#define RND_HIDCFG_MAX_KEYSEQ_LEN 32 +typedef struct hid_cfg_keyhash_s { + unsigned short int mods; /* of rnd_hid_cfg_mod_t */ + unsigned short int key_raw; /* raw keyboard code (0 means use ->key_tr instead); this is in the config; e.g. on US keyboard shift+3 this is Shift3 */ + unsigned short int key_tr; /* rendered: gui-translated keyboard code (0 means use ->key_raw instead); this is in the config; e.g. on US keyboard shift+3 this is # */ +} rnd_hid_cfg_keyhash_t; + + +typedef struct rnd_hid_cfg_keyseq_s rnd_hid_cfg_keyseq_t; +struct rnd_hid_cfg_keyseq_s { + rnd_hid_cfg_keyhash_t addr; + + unsigned long int keysym; /* optional 32 bit long storage the GUI hid should cast to whatever the GUI backend supports */ + + const lht_node_t *action_node; /* terminal node: end of sequence, run actions */ + + htpp_t seq_next; /* ... or if node is NULL, a hash for each key that may follow the current one */ + rnd_hid_cfg_keyseq_t *parent; +}; + +/* Translate symbolic name to single-char keysym before processing; useful + for shortcuts like "Return -> '\r'" which are otherwise hard to describe + in text format */ +typedef struct rnd_hid_cfg_keytrans_s { + const char *name; + char sym; +} rnd_hid_cfg_keytrans_t; + +extern const rnd_hid_cfg_keytrans_t rnd_hid_cfg_key_default_trans[]; + +/* A complete tree of keyboard shortcuts/hotkeys */ +typedef struct rnd_hid_cfg_keys_s { + htpp_t keys; + + /* translate key sym description (the portion after ) to key_char; + desc is a \0 terminated string, len is only a hint. Should return 0 + on error. */ + unsigned short int (*translate_key)(const char *desc, int len); + + /* convert a key_char to human readable name, copy the string to out/out_len. + Return 0 on success. */ + int (*key_name)(unsigned short int key_char, char *out, int out_len); + + + int auto_chr; /* if non-zero: don't call translate_key() for 1-char symbols, handle the default way */ + const rnd_hid_cfg_keytrans_t *auto_tr; /* apply this table before calling translate_key() */ + + /* current sequence state */ + rnd_hid_cfg_keyseq_t *seq[RND_HIDCFG_MAX_KEYSEQ_LEN]; + int seq_len; + int seq_len_action; /* when an action node is hit, save sequence length for executing the action while seq_len is reset */ +} rnd_hid_cfg_keys_t; + + +/* Initialize a new keyboard context + Returns 0 on success. +*/ +int rnd_hid_cfg_keys_init(rnd_hid_cfg_keys_t *km); + +/* Free km's fields recursively */ +int rnd_hid_cfg_keys_uninit(rnd_hid_cfg_keys_t *km); + +/* Add the next key of a key sequence; key sequences form a tree. A key starting + a new key sequence should have parent set NULL, subsequent calls should have + parent set to the previously returned keyseq value. Terminal is non-zero if + this is the last key of the sequence. + Raw vs. translated keys are desribed at rnd_hid_cfg_keys_input(). + Returns NULL on error and loads errmsg if not NULL */ +rnd_hid_cfg_keyseq_t *rnd_hid_cfg_keys_add_under(rnd_hid_cfg_keys_t *km, rnd_hid_cfg_keyseq_t *parent, rnd_hid_cfg_mod_t mods, unsigned short int key_raw, unsigned short int key_tr, int terminal, const char **errmsg); + +/* Add a new key using a description (read from a lihata file usually) + If out_seq is not NULL, load the array with pointers pointing to each + key in the sequence, up to out_seq_len. + When key desc is a lihata node, it may be a list (multiple keys for the + same action). In this case return value and seq are set using the first key. + Returns -1 on failure or the length of the sequence. +*/ +int rnd_hid_cfg_keys_add_by_desc(rnd_hid_cfg_keys_t *km, const lht_node_t *keydesc, const lht_node_t *action_node); +int rnd_hid_cfg_keys_add_by_desc_(rnd_hid_cfg_keys_t *km, const lht_node_t *keydesc, const lht_node_t *action_node, rnd_hid_cfg_keyseq_t **out_seq, int out_seq_len); +int rnd_hid_cfg_keys_add_by_strdesc(rnd_hid_cfg_keys_t *km, const char *keydesc, const lht_node_t *action_node); +int rnd_hid_cfg_keys_add_by_strdesc_(rnd_hid_cfg_keys_t *km, const char *keydesc, const lht_node_t *action_node, rnd_hid_cfg_keyseq_t **out_seq, int out_seq_len); + + +int rnd_hid_cfg_keys_del_by_desc(rnd_hid_cfg_keys_t *km, const lht_node_t *keydesc); + +/* Allocate a new string and generate a human readable accel-text; mask determines + which keys on the list are generated (when multiple key sequences are + specified for the same action; from LSB to MSB, at most 32 keys) + Caller needs to free the string; returns NULL on error. + */ +char *rnd_hid_cfg_keys_gen_accel(rnd_hid_cfg_keys_t *km, const lht_node_t *keydescn, unsigned long mask, const char *sep); + +/* Allocate a new string and generate a key-desc; returns NULL on error */ +char *rnd_hid_cfg_keys_gen_desc(rnd_hid_cfg_mod_t mods, unsigned short int key_raw, unsigned short int key_tr); + + +/* Process next input key stroke. + Seq and seq_len must not be NULL as they are the internal state of multi-key + processing. Load seq array with pointers pointing to each key in the + sequence, up to seq_len. + Key_raw is the raw key code for base keys, without any translation, key_tr + is the translated character; e.g. shift+1 is always reported as key_raw=1 + and on US keyboard reported as key_tr=! + Returns: + -1 if the key stroke or sequence is invalid + 0 if more characters needed to complete the sequence + + a positive integer means the lookup succeeded and the return value + is the length of the resulting sequence. +*/ +int rnd_hid_cfg_keys_input(rnd_hidlib_t *hl, rnd_hid_cfg_keys_t *km, rnd_hid_cfg_mod_t mods, unsigned short int key_raw, unsigned short int key_tr); +int rnd_hid_cfg_keys_input_(rnd_hidlib_t *hl, rnd_hid_cfg_keys_t *km, rnd_hid_cfg_mod_t mods, unsigned short int key_raw, unsigned short int key_tr, rnd_hid_cfg_keyseq_t **seq, int *seq_len); + +/* Run the action for a key sequence looked up by rnd_hid_cfg_keys_input(). + Returns: the result of the action or -1 on error */ +int rnd_hid_cfg_keys_action(rnd_hidlib_t *hl, rnd_hid_cfg_keys_t *km); +int rnd_hid_cfg_keys_action_(rnd_hidlib_t *hl, rnd_hid_cfg_keyseq_t **seq, int seq_len); + +/* Print a squence into dst in human readable form; returns strlen(dst) */ +int rnd_hid_cfg_keys_seq(rnd_hid_cfg_keys_t *km, char *dst, int dst_len); +int rnd_hid_cfg_keys_seq_(rnd_hid_cfg_keys_t *km, rnd_hid_cfg_keyseq_t **seq, int seq_len, char *dst, int dst_len); + +#endif Index: trunk/src/librnd/hid/hid_dad.c =================================================================== --- trunk/src/librnd/hid/hid_dad.c (nonexistent) +++ trunk/src/librnd/hid/hid_dad.c (revision 34602) @@ -0,0 +1,157 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* widget-type-independent DAD functions */ + +#include +#include + +int rnd_dock_is_vert[RND_HID_DOCK_max] = {0, 0, 0, 1, 0, 1}; /* Update this if rnd_hid_dock_t changes */ +int rnd_dock_has_frame[RND_HID_DOCK_max] = {0, 0, 0, 1, 0, 0}; /* Update this if rnd_hid_dock_t changes */ + +typedef struct { + rnd_hatt_compflags_t flag; + const char *name; +} comflag_name_t; + +static comflag_name_t compflag_names[] = { + {RND_HATF_FRAME, "frame"}, + {RND_HATF_SCROLL, "scroll"}, + {RND_HATF_HIDE_TABLAB, "hide_tablab"}, + {RND_HATF_LEFT_TAB, "left_tab"}, + {RND_HATF_TREE_COL, "tree_col"}, + {RND_HATF_EXPFILL, "expfill"}, + {RND_HATF_TIGHT, "tight"}, + {0, NULL} +}; + +const char *rnd_hid_compflag_bit2name(rnd_hatt_compflags_t bit) +{ + comflag_name_t *n; + for(n = compflag_names; n->flag != 0; n++) + if (n->flag == bit) + return n->name; + return NULL; +} + +rnd_hatt_compflags_t rnd_hid_compflag_name2bit(const char *name) +{ + comflag_name_t *n; + for(n = compflag_names; n->flag != 0; n++) + if (strcmp(n->name, name) == 0) + return n->flag; + return 0; +} + +void rnd_hid_dad_close(void *hid_ctx, rnd_dad_retovr_t *retovr, int retval) +{ + retovr->valid = 1; + retovr->value = retval; + rnd_gui->attr_dlg_close(hid_ctx); +} + +void rnd_hid_dad_close_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_dad_retovr_t **retovr = attr->wdata; + rnd_hid_dad_close(hid_ctx, *retovr, attr->val.lng); +} + +int rnd_hid_dad_run(void *hid_ctx, rnd_dad_retovr_t *retovr) +{ + int ret; + + retovr->valid = 0; + retovr->dont_free++; + ret = rnd_gui->attr_dlg_run(hid_ctx); + if (retovr->valid) + ret = retovr->value; + retovr->dont_free--; + return ret; +} + +int rnd_hid_attrdlg_num_children(rnd_hid_attribute_t *attrs, int start_from, int n_attrs) +{ + int n, level = 1, cnt = 0; + + for(n = start_from; n < n_attrs; n++) { + if ((level == 1) && (attrs[n].type != RND_HATT_END)) + cnt++; + switch(attrs[n].type) { + case RND_HATT_END: + level--; + if (level == 0) + return cnt; + break; + case RND_HATT_BEGIN_TABLE: + case RND_HATT_BEGIN_HBOX: + case RND_HATT_BEGIN_VBOX: + case RND_HATT_BEGIN_COMPOUND: + level++; + break; + default: + break; + } + } + return cnt; +} + +int rnd_attribute_dialog_(const char *id, rnd_hid_attribute_t *attrs, int n_attrs, const char *title, void *caller_data, void **retovr, int defx, int defy, int minx, int miny, void **hid_ctx_out) +{ + int rv; + void *hid_ctx; + + if ((rnd_gui == NULL) || (rnd_gui->attr_dlg_new == NULL)) + return -1; + + hid_ctx = rnd_gui->attr_dlg_new(rnd_gui, id, attrs, n_attrs, title, caller_data, rnd_true, NULL, defx, defy, minx, miny); + if (hid_ctx_out != NULL) + *hid_ctx_out = hid_ctx; + rv = rnd_gui->attr_dlg_run(hid_ctx); + if ((retovr == NULL) || (*retovr != 0)) + rnd_gui->attr_dlg_close(hid_ctx); + + return rv ? 0 : 1; +} + +int rnd_attribute_dialog(const char *id, rnd_hid_attribute_t *attrs, int n_attrs, const char *title, void *caller_data) +{ + return rnd_attribute_dialog_(id, attrs, n_attrs, title, caller_data, NULL, 0, 0, 0, 0, NULL); +} + +int rnd_hid_dock_enter(rnd_hid_dad_subdialog_t *sub, rnd_hid_dock_t where, const char *id) +{ + if ((rnd_gui == NULL) || (rnd_gui->dock_enter == NULL)) + return -1; + return rnd_gui->dock_enter(rnd_gui, sub, where, id); +} + +void rnd_hid_dock_leave(rnd_hid_dad_subdialog_t *sub) +{ + if ((rnd_gui == NULL) || (rnd_gui->dock_leave == NULL)) + return; + rnd_gui->dock_leave(rnd_gui, sub); +} + Index: trunk/src/librnd/hid/hid_dad.h =================================================================== --- trunk/src/librnd/hid/hid_dad.h (nonexistent) +++ trunk/src/librnd/hid/hid_dad.h (revision 34602) @@ -0,0 +1,880 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017..2020 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef RND_HID_DAD_H +#define RND_HID_DAD_H + +#include +#include +#include +#include +#include +#include +#include + +#include + +typedef enum { + RND_HID_TEXT_INSERT, /* insert at cursor or replace selection */ + RND_HID_TEXT_REPLACE, /* replace the entire text */ + RND_HID_TEXT_APPEND, /* append to the end of the text */ + + /* modifiers (bitfield) */ + RND_HID_TEXT_MARKUP = 0x0010 /* interpret minimal html-like markup - some HIDs may ignore these */ +} rnd_hid_text_set_t; + +typedef struct { + /* cursor manipulation callbacks */ + void (*hid_get_xy)(rnd_hid_attribute_t *attrib, void *hid_ctx, long *x, long *y); /* can be very slow */ + long (*hid_get_offs)(rnd_hid_attribute_t *attrib, void *hid_ctx); + void (*hid_set_xy)(rnd_hid_attribute_t *attrib, void *hid_ctx, long x, long y); /* can be very slow */ + void (*hid_set_offs)(rnd_hid_attribute_t *attrib, void *hid_ctx, long offs); + void (*hid_scroll_to_bottom)(rnd_hid_attribute_t *attrib, void *hid_ctx); + void (*hid_set_text)(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_text_set_t how, const char *txt); + char *(*hid_get_text)(rnd_hid_attribute_t *attrib, void *hid_ctx); /* caller needs to free the result */ + void (*hid_set_readonly)(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_bool readonly); /* by default text views are not read-only */ + + /* optional callbacks the user set after widget creation */ + void *user_ctx; + void (*user_free_cb)(rnd_hid_attribute_t *attrib, void *user_ctx, void *hid_ctx); + + /* optional callbacks HIDs may set after widget creation */ + void *hid_wdata; + void (*hid_free_cb)(rnd_hid_attribute_t *attrib, void *hid_wdata); +} rnd_hid_text_t; + + +typedef struct { + int cols; /* number of columns used by this node (allocation size) */ + void *hid_data; /* the hid running the widget can use this field to store a custom pointer per row */ + gdl_list_t children; + gdl_elem_t link; + char *path; /* full path of the node; allocated/free'd by DAD (/ is the root, every entry is specified from the root, but the leading / is omitted; in non-tree case, this only points to the first col data) */ + unsigned hide:1; /* if non-zero, the row is not visible (e.g. filtered out) */ + + /* caller/user data */ + void *user_data; + union { + void *ptr; + long lng; + double dbl; + } user_data2; + char *cell[1]; /* each cell is a char *; the true length of the array is the value of the len field; the array is allocated together with the struct */ +} rnd_hid_row_t; + +typedef struct { + gdl_list_t rows; /* ordered list of first level rows (tree root) */ + htsp_t paths; /* translate first column paths iinto (rnd_hid_row_t *) */ + rnd_hid_attribute_t *attrib; + const char **hdr; /* optional column headers (NULL means disable header) */ + + /* optional callbacks the user set after widget creation */ + void *user_ctx; + void (*user_free_cb)(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row); + void (*user_selected_cb)(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row); + int (*user_browse_activate_cb)(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row); /* returns non-zero if the row should auto-activate while browsing (e.g. stepping with arrow keys) */ + const char *(*user_copy_to_clip_cb)(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row); /* returns the string to copy to clipboard for the given row (if unset, first column text is used) */ + + /* optional callbacks HIDs may set after widget creation */ + void *hid_wdata; + void (*hid_insert_cb)(rnd_hid_attribute_t *attrib, void *hid_wdata, rnd_hid_row_t *new_row); + void (*hid_modify_cb)(rnd_hid_attribute_t *attrib, void *hid_wdata, rnd_hid_row_t *row, int col); /* if col is negative, all columns have changed */ + void (*hid_remove_cb)(rnd_hid_attribute_t *attrib, void *hid_wdata, rnd_hid_row_t *row); + void (*hid_free_cb)(rnd_hid_attribute_t *attrib, void *hid_wdata, rnd_hid_row_t *row); + rnd_hid_row_t *(*hid_get_selected_cb)(rnd_hid_attribute_t *attrib, void *hid_wdata); + void (*hid_jumpto_cb)(rnd_hid_attribute_t *attrib, void *hid_wdata, rnd_hid_row_t *row); /* row = NULL means deselect all */ + void (*hid_expcoll_cb)(rnd_hid_attribute_t *attrib, void *hid_wdata, rnd_hid_row_t *row, int expanded); /* sets whether a row is expanded or collapsed */ + void (*hid_update_hide_cb)(rnd_hid_attribute_t *attrib, void *hid_wdata); +} rnd_hid_tree_t; + +typedef struct rnd_hid_preview_s rnd_hid_preview_t; +struct rnd_hid_preview_s { + rnd_hid_attribute_t *attrib; + + rnd_box_t initial_view; + unsigned initial_view_valid:1; + + int min_sizex_px, min_sizey_px; /* hint: widget minimum size in pixels */ + + /* optional callbacks the user set after widget creation */ + void *user_ctx; + void (*user_free_cb)(rnd_hid_attribute_t *attrib, void *user_ctx, void *hid_ctx); + void (*user_expose_cb)(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e); + rnd_bool (*user_mouse_cb)(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_mouse_ev_t kind, rnd_coord_t x, rnd_coord_t y); /* returns true if redraw is needed */ + rnd_bool (*user_key_cb)(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_bool release, rnd_hid_cfg_mod_t mods, unsigned short int key_raw, unsigned short int key_tr); /* returns true if redraw is needed */ + + /* optional callbacks HIDs may set after widget creation */ + void *hid_wdata; + void (*hid_zoomto_cb)(rnd_hid_attribute_t *attrib, void *hid_wdata, const rnd_box_t *view); /* redraw only if view == NULL */ + void (*hid_free_cb)(rnd_hid_attribute_t *attrib, void *hid_wdata); +}; + +typedef struct { + int wbegin, wend; /* widget index to the correspoding RND_HATT_BEGIN_COMPOUND and RND_HATT_END */ + + /* compound implementation callbacks */ + int (*widget_state)(rnd_hid_attribute_t *end, void *hid_ctx, int idx, rnd_bool enabled); + int (*widget_hide)(rnd_hid_attribute_t *end, void *hid_ctx, int idx, rnd_bool hide); + int (*set_value)(rnd_hid_attribute_t *end, void *hid_ctx, int idx, const rnd_hid_attr_val_t *val); /* set value runtime */ + void (*set_val_num)(rnd_hid_attribute_t *attr, long l, double d, rnd_coord_t c); /* set value during creation; attr is the END */ + void (*set_val_ptr)(rnd_hid_attribute_t *attr, void *ptr); /* set value during creation; attr is the END */ + void (*set_help)(rnd_hid_attribute_t *attr, const char *text); /* set the tooltip help; attr is the END */ + void (*set_field_num)(rnd_hid_attribute_t *attr, const char *fieldname, long l, double d, rnd_coord_t c); /* set value during creation; attr is the END */ + void (*set_field_ptr)(rnd_hid_attribute_t *attr, const char *fieldname, void *ptr); /* set value during creation; attr is the END */ + void (*set_geo)(rnd_hid_attribute_t *attr, rnd_hatt_compflags_t flg, int geo); /* set geometry during creation; attr is the END */ + void (*free)(rnd_hid_attribute_t *attrib); /* called by DAD on free'ing the RND_HATT_BEGIN_COMPOUND and RND_HATT_END_COMPOUND widget */ +} rnd_hid_compound_t; + +#include + +/*** Helpers for building dynamic attribute dialogs (DAD) ***/ +#define RND_DAD_DECL(table) \ + rnd_hid_attribute_t *table = NULL; \ + int table ## _append_lock = 0; \ + int table ## _len = 0; \ + int table ## _alloced = 0; \ + void *table ## _hid_ctx = NULL; \ + int table ## _defx = 0, table ## _defy = 0; \ + int table ## _minx = 0, table ## _miny = 0; \ + rnd_dad_retovr_t *table ## _ret_override; + +#define RND_DAD_DECL_NOINIT(table) \ + rnd_hid_attribute_t *table; \ + int table ## _append_lock; \ + int table ## _len; \ + int table ## _alloced; \ + void *table ## _hid_ctx; \ + int table ## _defx, table ## _defy; \ + int table ## _minx, table ## _miny; \ + rnd_dad_retovr_t *table ## _ret_override; + +/* Free all resources allocated by DAD macros for table */ +#define RND_DAD_FREE(table) \ +do { \ + int __n__; \ + if ((table ## _hid_ctx != NULL) && (table ## _ret_override != NULL)) \ + rnd_gui->attr_dlg_free(table ## _hid_ctx); \ + for(__n__ = 0; __n__ < table ## _len; __n__++) { \ + RND_DAD_FREE_FIELD(table, __n__); \ + } \ + free(table); \ + table = NULL; \ + table ## _hid_ctx = NULL; \ + table ## _len = 0; \ + table ## _alloced = 0; \ + table ## _append_lock = 0; \ + if ((table ## _ret_override != NULL) && (table ## _ret_override->dont_free == 0)) {\ + free(table ## _ret_override); \ + table ## _ret_override = NULL; \ + } \ +} while(0) + +#define RND_DAD_NEW(id, table, title, caller_data, modal, ev_cb) \ +do { \ + table ## _ret_override = calloc(sizeof(rnd_dad_retovr_t), 1); \ + table ## _append_lock = 1; \ + table ## _hid_ctx = rnd_gui->attr_dlg_new(rnd_gui, id, table, table ## _len, title, caller_data, modal, ev_cb, table ## _defx, table ## _defy, table ## _minx, table ## _miny); \ +} while(0) + +/* Sets the default window size (that is only a hint) - NOTE: must be called + before RND_DAD_NEW() */ +#define RND_DAD_DEFSIZE(table, width, height) \ +do { \ + table ## _defx = width; \ + table ## _defy = height; \ +} while(0) + +/* Sets the minimum window size (that is only a hint) - NOTE: must be called + before RND_DAD_NEW() */ +#define RND_DAD_MINSIZE(table, width, height) \ +do { \ + table ## _minx = width; \ + table ## _miny = height; \ +} while(0) + +#define RND_DAD_RUN(table) rnd_hid_dad_run(table ## _hid_ctx, table ## _ret_override) + +/* failed is zero on success and -1 on error (e.g. cancel) or an arbitrary + value set by ret_override (e.g. on close buttons) */ +#define RND_DAD_AUTORUN(id, table, title, caller_data, failed) \ +do { \ + int __ok__; \ + table ## _ret_override = calloc(sizeof(rnd_dad_retovr_t), 1); \ + table ## _ret_override->dont_free++; \ + table ## _ret_override->valid = 0; \ + table ## _append_lock = 1; \ + __ok__ = rnd_attribute_dialog_(id,table, table ## _len, title, caller_data, (void **)&(table ## _ret_override), table ## _defx, table ## _defy, table ## _minx, table ## _miny, &table ## _hid_ctx); \ + failed = (__ok__ == 0) ? -1 : 0; \ + if (table ## _ret_override->valid) \ + failed = table ## _ret_override->value; \ + table ## _ret_override->dont_free--; \ +} while(0) + +/* Return the index of the item currenty being edited */ +#define RND_DAD_CURRENT(table) (table ## _len - 1) + +/* Begin a new box or table */ +#define RND_DAD_BEGIN(table, item_type) \ + RND_DAD_ALLOC(table, item_type); + +#define RND_DAD_BEGIN_TABLE(table, cols) \ +do { \ + RND_DAD_BEGIN(table, RND_HATT_BEGIN_TABLE); \ + RND_DAD_SET_ATTR_FIELD(table, rnd_hatt_table_cols, cols); \ +} while(0) + +#define RND_DAD_BEGIN_TABBED(table, tabs) \ +do { \ + RND_DAD_BEGIN(table, RND_HATT_BEGIN_TABBED); \ + RND_DAD_SET_ATTR_FIELD(table, wdata, tabs); \ +} while(0) + +#define RND_DAD_BEGIN_HBOX(table) RND_DAD_BEGIN(table, RND_HATT_BEGIN_HBOX) +#define RND_DAD_BEGIN_VBOX(table) RND_DAD_BEGIN(table, RND_HATT_BEGIN_VBOX) +#define RND_DAD_END(table) RND_DAD_BEGIN(table, RND_HATT_END) +#define RND_DAD_COMPFLAG(table, val) RND_DAD_SET_ATTR_FIELD(table, rnd_hatt_flags, val | (table[table ## _len-1].rnd_hatt_flags & RND_HATF_TREE_COL)) + +#define RND_DAD_LABEL(table, text) \ +do { \ + RND_DAD_ALLOC(table, RND_HATT_LABEL); \ + RND_DAD_SET_ATTR_FIELD(table, name, rnd_strdup(text)); \ +} while(0) + +/* Add label usign printf formatting syntax: RND_DAD_LABELF(tbl, ("a=%d", 12)); */ +#define RND_DAD_LABELF(table, printf_args) \ +do { \ + RND_DAD_ALLOC(table, RND_HATT_LABEL); \ + RND_DAD_SET_ATTR_FIELD(table, name, rnd_strdup_printf printf_args); \ +} while(0) + +#define RND_DAD_STRING_SELECT_REGION(table, idx, first_char_offs, len) \ +do { \ + if (rnd_gui->attr_dlg_widget_poke != NULL) { \ + fgw_arg_t __args__[3]; \ + __args__[0].type = FGW_STR; __args__[0].val.cstr = "select"; \ + __args__[1].type = FGW_INT; __args__[1].val.nat_int = first_char_offs; \ + __args__[2].type = FGW_INT; __args__[2].val.nat_int = len; \ + rnd_gui->attr_dlg_widget_poke(table, idx, 3, __args__); \ + } \ +} while(0) + +#define RND_DAD_ENUM(table, choices) \ +do { \ + RND_DAD_ALLOC(table, RND_HATT_ENUM); \ + RND_DAD_SET_ATTR_FIELD(table, wdata, choices); \ +} while(0) + +#define RND_DAD_BOOL(table) RND_DAD_ALLOC(table, RND_HATT_BOOL); +#define RND_DAD_STRING(table) RND_DAD_ALLOC(table, RND_HATT_STRING); +#define RND_DAD_INTEGER(table) RND_DAD_SPIN_INT(table); +#define RND_DAD_REAL(table) RND_DAD_SPIN_DOUBLE(table); +#define RND_DAD_COORD(table) RND_DAD_SPIN_COORD(table); + +#define RND_DAD_TEXT(table, user_ctx_) \ +do { \ + rnd_hid_text_t *txt = calloc(sizeof(rnd_hid_text_t), 1); \ + txt->user_ctx = user_ctx_; \ + RND_DAD_ALLOC(table, RND_HATT_TEXT); \ + RND_DAD_SET_ATTR_FIELD(table, wdata, txt); \ +} while(0) + +#define RND_DAD_BUTTON(table, text) \ +do { \ + RND_DAD_ALLOC(table, RND_HATT_BUTTON); \ + table[table ## _len - 1].val.str = text; \ +} while(0) + +#define RND_DAD_BUTTON_CLOSE(table, text, retval) \ +do { \ + RND_DAD_ALLOC(table, RND_HATT_BUTTON); \ + table[table ## _len - 1].val.str = text; \ + table[table ## _len - 1].val.lng = retval; \ + table[table ## _len - 1].wdata = (&table ## _ret_override); \ + RND_DAD_CHANGE_CB(table, rnd_hid_dad_close_cb); \ +} while(0) + +/* Draw a set of close buttons without trying to fill a while hbox row */ +#define RND_DAD_BUTTON_CLOSES_NAKED(table, buttons) \ +do { \ + rnd_hid_dad_buttons_t *__n__; \ + RND_DAD_BEGIN_HBOX(table); \ + RND_DAD_COMPFLAG(table, RND_HATF_EXPFILL); \ + RND_DAD_END(table); \ + for(__n__ = buttons; __n__->label != NULL; __n__++) { \ + RND_DAD_BUTTON_CLOSE(table, __n__->label, __n__->retval); \ + } \ +} while(0) + +/* Draw a set of close buttons, adding a new hbox that tries to fill a whole row */ +#define RND_DAD_BUTTON_CLOSES(table, buttons) \ +do { \ + RND_DAD_BEGIN_HBOX(table); \ + RND_DAD_BUTTON_CLOSES_NAKED(table, buttons); \ + RND_DAD_END(table); \ +} while(0) + + +#define RND_DAD_PROGRESS(table) \ +do { \ + RND_DAD_ALLOC(table, RND_HATT_PROGRESS); \ +} while(0) + +#define RND_DAD_PREVIEW(table, expose_cb, mouse_cb, key_cb, free_cb, initial_view_box, min_sizex_px_, min_sizey_px_, user_ctx_) \ +do { \ + rnd_hid_preview_t *prv = calloc(sizeof(rnd_hid_preview_t), 1); \ + prv->user_ctx = user_ctx_; \ + prv->user_expose_cb = expose_cb; \ + prv->user_mouse_cb = mouse_cb; \ + prv->user_key_cb = key_cb; \ + prv->user_free_cb = free_cb; \ + prv->min_sizex_px = min_sizex_px_; \ + prv->min_sizey_px = min_sizey_px_; \ + if ((initial_view_box) != NULL) { \ + prv->initial_view.X1 = ((rnd_box_t *)(initial_view_box))->X1; \ + prv->initial_view.Y1 = ((rnd_box_t *)(initial_view_box))->Y1; \ + prv->initial_view.X2 = ((rnd_box_t *)(initial_view_box))->X2; \ + prv->initial_view.Y2 = ((rnd_box_t *)(initial_view_box))->Y2; \ + prv->initial_view_valid = 1; \ + } \ + RND_DAD_ALLOC(table, RND_HATT_PREVIEW); \ + prv->attrib = &table[table ## _len-1]; \ + RND_DAD_SET_ATTR_FIELD(table, wdata, prv); \ +} while(0) + +#define rnd_dad_preview_zoomto(attr, view) \ +do { \ + rnd_hid_preview_t *prv = ((attr)->wdata); \ + if (prv->hid_zoomto_cb != NULL) \ + prv->hid_zoomto_cb((attr), prv->hid_wdata, view); \ +} while(0) + + +#define RND_DAD_PICTURE(table, xpm) \ +do { \ + RND_DAD_ALLOC(table, RND_HATT_PICTURE); \ + table[table ## _len - 1].wdata = xpm; \ +} while(0) + +#define RND_DAD_PICBUTTON(table, xpm) \ +do { \ + RND_DAD_ALLOC(table, RND_HATT_PICBUTTON); \ + table[table ## _len - 1].wdata = xpm; \ +} while(0) + + +#define RND_DAD_COLOR(table) \ +do { \ + RND_DAD_ALLOC(table, RND_HATT_COLOR); \ +} while(0) + + +/* Create a horizontal or vertical pane. + pane_name is used when saving pane position in window geometry; + name is a const char *, not strdup'd or free'd (should be constant in the + caller). Name must contain only alphanumerical characters, dashes and + underscores */ + +#define RND_DAD_BEGIN_HPANE(table, pane_name) \ +do { \ + RND_DAD_BEGIN(table, RND_HATT_BEGIN_HPANE); \ + table[table ## _len - 1].val.dbl = 0.5; \ + table[table ## _len - 1].name = pane_name; \ +} while(0) + +#define RND_DAD_BEGIN_VPANE(table, pane_name) \ +do { \ + RND_DAD_BEGIN(table, RND_HATT_BEGIN_VPANE); \ + table[table ## _len - 1].val.dbl = 0.5; \ + table[table ## _len - 1].name = pane_name; \ +} while(0) + + +#define RND_DAD_TREE(table, cols, first_col_is_tree, opt_header) \ +do { \ + rnd_hid_tree_t *tree = calloc(sizeof(rnd_hid_tree_t), 1); \ + htsp_init(&tree->paths, strhash, strkeyeq); \ + RND_DAD_ALLOC(table, RND_HATT_TREE); \ + tree->attrib = &table[table ## _len-1]; \ + tree->hdr = opt_header; \ + RND_DAD_SET_ATTR_FIELD(table, rnd_hatt_table_cols, cols); \ + RND_DAD_SET_ATTR_FIELD(table, rnd_hatt_flags, first_col_is_tree ? RND_HATF_TREE_COL : 0); \ + RND_DAD_SET_ATTR_FIELD(table, wdata, tree); \ +} while(0) + +#define RND_DAD_TREE_APPEND(table, row_after, cells) \ + rnd_dad_tree_append(&table[table ## _len-1], row_after, cells) + +#define RND_DAD_TREE_APPEND_UNDER(table, parent_row, cells) \ + rnd_dad_tree_append_under(&table[table ## _len-1], parent_row, cells) + +#define RND_DAD_TREE_INSERT(table, row_before, cells) \ + rnd_dad_tree_insert(&table[table ## _len-1], row_before, cells) + +/* set the named tree user callback to func_or_data; name is automatically + appended with user_, any field prefixed with user_ in rnd_hid_tree_t + can be set */ +#define RND_DAD_TREE_SET_CB(table, name, func_or_data) \ +do { \ + rnd_hid_tree_t *__tree__ = table[table ## _len-1].wdata; \ + __tree__->user_ ## name = func_or_data; \ +} while(0) + + +#define RND_DAD_SUBDIALOG(table, sub) \ +do { \ + RND_DAD_ALLOC(table, RND_HATT_SUBDIALOG); \ + RND_DAD_SET_ATTR_FIELD(table, wdata, sub); \ +} while(0) + + +#define RND_DAD_DUP_ATTR(table, attr) \ +do { \ + RND_DAD_ALLOC(table, 0); \ + memcpy(&table[table ## _len-1], (attr), sizeof(rnd_hid_attribute_t)); \ + RND_DAD_UPDATE_INTERNAL(table, table ## _len-1); \ +} while(0) + +#define RND_DAD_DUP_EXPOPT_VAL(table, opt, val_attr) \ +do { \ + const rnd_export_opt_t *__opt__ = (opt); \ + RND_DAD_ALLOC(table, 0); \ + table[table ## _len-1].name = __opt__->name; \ + table[table ## _len-1].help_text = __opt__->help_text; \ + table[table ## _len-1].type = __opt__->type; \ + table[table ## _len-1].min_val = __opt__->min_val; \ + table[table ## _len-1].max_val = __opt__->max_val; \ + table[table ## _len-1].wdata = __opt__->enumerations; \ + table[table ## _len-1].val = (val_attr); \ + RND_DAD_UPDATE_INTERNAL(table, table ## _len-1); \ +} while(0) + + +/* Set properties of the current item */ +#define RND_DAD_MINVAL(table, val) RND_DAD_SET_ATTR_FIELD_SE(table, min_val, val) +#define RND_DAD_MAXVAL(table, val) RND_DAD_SET_ATTR_FIELD_SE(table, max_val, val) +#define RND_DAD_MINMAX(table, min, max) do { RND_DAD_SET_ATTR_FIELD_SE(table, min_val, min); RND_DAD_SET_ATTR_FIELD_SE(table, max_val, max); } while(0) +#define RND_DAD_CHANGE_CB(table, cb) RND_DAD_SET_ATTR_FIELD(table, change_cb, cb) +#define RND_DAD_RIGHT_CB(table, cb) RND_DAD_SET_ATTR_FIELD(table, right_cb, cb) +#define RND_DAD_ENTER_CB(table, cb) RND_DAD_SET_ATTR_FIELD(table, enter_cb, cb) + +#define RND_DAD_HELP(table, val) \ + do { \ + switch(table[table ## _len - 1].type) { \ + case RND_HATT_END: \ + { \ + rnd_hid_compound_t *cmp = table[table ## _len - 1].wdata; \ + if ((cmp != NULL) && (cmp->set_help != NULL)) \ + cmp->set_help(&table[table ## _len - 1], (val)); \ + } \ + break; \ + default: \ + RND_DAD_SET_ATTR_FIELD(table, help_text, val); \ + } \ + } while(0) + +#define RND_DAD_DEFAULT_PTR(table, val_) \ + do {\ + switch(table[table ## _len - 1].type) { \ + case RND_HATT_BEGIN_COMPOUND: \ + case RND_HATT_END: \ + { \ + rnd_hid_compound_t *cmp = table[table ## _len - 1].wdata; \ + if ((cmp != NULL) && (cmp->set_val_ptr != NULL)) \ + cmp->set_val_ptr(&table[table ## _len - 1], (void *)(val_)); \ + else \ + assert(0); \ + } \ + break; \ + default: \ + RND_DAD_SET_ATTR_FIELD_PTR(table, val, val_); \ + } \ + } while(0) + +#define RND_DAD_DEFAULT_NUM(table, val_) \ + do {\ + switch(table[table ## _len - 1].type) { \ + case RND_HATT_BEGIN_COMPOUND: \ + case RND_HATT_END: \ + { \ + rnd_hid_compound_t *cmp = table[table ## _len - 1].wdata; \ + if ((cmp != NULL) && (cmp->set_val_num != NULL)) \ + cmp->set_val_num(&table[table ## _len - 1], (long)(val_), (double)(val_), (rnd_coord_t)(val_)); \ + else \ + assert(0); \ + } \ + break; \ + default: \ + RND_DAD_SET_ATTR_FIELD_NUM(table, val, val_); \ + } \ + } while(0); + +/* safe way to call gui->attr_dlg_set_value() - resets the unused fields */ +#define RND_DAD_SET_VALUE(hid_ctx, wid, field, val_) \ + do { \ + rnd_hid_attr_val_t __val__; \ + memset(&__val__, 0, sizeof(__val__)); \ + __val__.field = val_; \ + rnd_gui->attr_dlg_set_value(hid_ctx, wid, &__val__); \ + } while(0) + +/*** DAD internals (do not use directly) ***/ + +/* Update widget internals after a potential attr pointer change */ +#define RND_DAD_UPDATE_INTERNAL(table, widx) \ + do { \ + rnd_hid_preview_t *__prv__; \ + rnd_hid_tree_t *__tree__; \ + switch(table[(widx)].type) { \ + case RND_HATT_PREVIEW: \ + __prv__ = table[(widx)].wdata; \ + __prv__->attrib = &table[(widx)]; \ + break; \ + case RND_HATT_TREE: \ + __tree__ = table[(widx)].wdata; \ + __tree__->attrib = &table[(widx)]; \ + break; \ + default: break; \ + } \ + } while(0) + +/* Allocate a new item at the end of the attribute table; updates stored + attribute pointers of existing items (e.g. previews, trees) as the base + address of the table may have changed. */ +#define RND_DAD_ALLOC(table, item_type) \ + do { \ + assert(table ## _append_lock == 0); \ + if (table ## _len >= table ## _alloced) { \ + int __n__; \ + table ## _alloced += 16; \ + table = realloc(table, sizeof(table[0]) * table ## _alloced); \ + for(__n__ = 0; __n__ < table ## _len; __n__++) { \ + RND_DAD_UPDATE_INTERNAL(table, __n__); \ + } \ + } \ + memset(&table[table ## _len], 0, sizeof(table[0])); \ + table[table ## _len].type = item_type; \ + table ## _len++; \ + } while(0) + +#define RND_DAD_SET_ATTR_FIELD(table, field, value) \ + table[table ## _len - 1].field = (value) + +#define RND_DAD_SET_ATTR_FIELD_SE(table, field, value) \ + do { \ + table[table ## _len - 1].field = (value); \ + RND_DAD_SET_ATTR_FIELD_SIDE_EFFECT(table, field, value); \ + } while(0) + +#define RND_DAD_OR_ATTR_FIELD(table, field, value) \ + table[table ## _len - 1].field |= (value) + +#define RND_DAD_SET_ATTR_FIELD_VAL(table, field, val) \ +do { \ + switch(table[table ## _len - 1].type) { \ + case RND_HATT_LABEL: \ + assert(0); \ + break; \ + case RND_HATT_INTEGER: \ + case RND_HATT_BOOL: \ + case RND_HATT_ENUM: \ + case RND_HATT_UNIT: \ + case RND_HATT_BEGIN_TABBED: \ + table[table ## _len - 1].field.lng = (int)val; \ + break; \ + case RND_HATT_COORD: \ + table[table ## _len - 1].field.crd = (rnd_coord_t)val; \ + break; \ + case RND_HATT_REAL: \ + case RND_HATT_PROGRESS: \ + case RND_HATT_BEGIN_HPANE: \ + case RND_HATT_BEGIN_VPANE: \ + table[table ## _len - 1].field.dbl = (double)val; \ + break; \ + case RND_HATT_STRING: \ + case RND_HATT_TEXT: \ + case RND_HATT_BUTTON: \ + case RND_HATT_TREE: \ + table[table ## _len - 1].field.str = (char *)val; \ + break; \ + case RND_HATT_COLOR: \ + table[table ## _len - 1].field.clr = *(rnd_color_t *)val; \ + break; \ + case RND_HATT_BEGIN_HBOX: \ + case RND_HATT_BEGIN_VBOX: \ + case RND_HATT_BEGIN_TABLE: \ + case RND_HATT_BEGIN_COMPOUND: \ + case RND_HATT_END: \ + case RND_HATT_PREVIEW: \ + case RND_HATT_PICTURE: \ + case RND_HATT_PICBUTTON: \ + assert(0); \ + } \ +} while(0) + +/* call compount set field */ +#define RND_DAD_SET_ATTR_FIELD_SIDE_EFFECT(table, field, val_) \ +do { \ + switch(table[table ## _len - 1].type) { \ + case RND_HATT_BEGIN_COMPOUND: \ + case RND_HATT_END: \ + { \ + rnd_hid_compound_t *cmp = table[table ## _len - 1].wdata; \ + if ((cmp != NULL) && (cmp->set_field_num != NULL)) \ + cmp->set_field_num(&table[table ## _len - 1], #field, (long)(val_), (double)(val_), (rnd_coord_t)(val_)); \ + else \ + assert(0); \ + } \ + break; \ + default:; \ + } \ +} while(0) + + +#define RND_DAD_SET_ATTR_FIELD_NUM(table, field, val_) \ +do { \ + switch(table[table ## _len - 1].type) { \ + case RND_HATT_LABEL: \ + case RND_HATT_SUBDIALOG: \ + assert(0); \ + break; \ + case RND_HATT_INTEGER: \ + case RND_HATT_BOOL: \ + case RND_HATT_ENUM: \ + case RND_HATT_BEGIN_TABBED: \ + table[table ## _len - 1].field.lng = (int)val_; \ + break; \ + case RND_HATT_COORD: \ + table[table ## _len - 1].field.crd = (rnd_coord_t)val_; \ + break; \ + case RND_HATT_REAL: \ + case RND_HATT_PROGRESS: \ + case RND_HATT_BEGIN_HPANE: \ + case RND_HATT_BEGIN_VPANE: \ + table[table ## _len - 1].field.dbl = (double)val_; \ + break; \ + case RND_HATT_STRING: \ + case RND_HATT_TEXT: \ + case RND_HATT_BUTTON: \ + case RND_HATT_TREE: \ + case RND_HATT_COLOR: \ + case RND_HATT_UNIT: \ + assert(!"please use the _PTR() variant instead of the _NUM() variant"); \ + break; \ + case RND_HATT_BEGIN_HBOX: \ + case RND_HATT_BEGIN_VBOX: \ + case RND_HATT_BEGIN_TABLE: \ + case RND_HATT_PREVIEW: \ + case RND_HATT_PICTURE: \ + case RND_HATT_PICBUTTON: \ + assert(0); \ + case RND_HATT_BEGIN_COMPOUND: \ + case RND_HATT_END: \ + RND_DAD_SET_ATTR_FIELD_SIDE_EFFECT(table, field, val_); \ + break; \ + } \ +} while(0) + +#define RND_DAD_SET_ATTR_FIELD_PTR(table, field, val_) \ +do { \ + switch(table[table ## _len - 1].type) { \ + case RND_HATT_LABEL: \ + assert(0); \ + break; \ + case RND_HATT_INTEGER: \ + case RND_HATT_BOOL: \ + case RND_HATT_ENUM: \ + case RND_HATT_BEGIN_TABBED: \ + case RND_HATT_COORD: \ + case RND_HATT_REAL: \ + case RND_HATT_PROGRESS: \ + case RND_HATT_BEGIN_HPANE: \ + case RND_HATT_BEGIN_VPANE: \ + assert(!"please use the _NUM() variant instead of the _PTR() variant"); \ + break; \ + case RND_HATT_UNIT: \ + { \ + int __n__, __v__ = rnd_get_n_units(0); \ + if (val_ != NULL) { \ + for(__n__ = 0; __n__ < __v__; __n__++) { \ + if (&rnd_units[__n__] == (rnd_unit_t *)(val_)) { \ + table[table ## _len - 1].field.lng = __n__; \ + break; \ + } \ + } \ + } \ + } \ + break; \ + case RND_HATT_STRING: \ + case RND_HATT_TEXT: \ + case RND_HATT_BUTTON: \ + case RND_HATT_TREE: \ + table[table ## _len - 1].field.str = (char *)val_; \ + break; \ + case RND_HATT_COLOR: \ + table[table ## _len - 1].field.clr = *((rnd_color_t *)val_); \ + break; \ + case RND_HATT_BEGIN_HBOX: \ + case RND_HATT_BEGIN_VBOX: \ + case RND_HATT_BEGIN_TABLE: \ + case RND_HATT_PREVIEW: \ + case RND_HATT_PICTURE: \ + case RND_HATT_PICBUTTON: \ + case RND_HATT_SUBDIALOG: \ + assert(0); \ + case RND_HATT_BEGIN_COMPOUND: \ + case RND_HATT_END: \ + { \ + rnd_hid_compound_t *cmp = table[table ## _len - 1].wdata; \ + if ((cmp != NULL) && (cmp->set_field_ptr != NULL)) \ + cmp->set_field_ptr(&table[table ## _len - 1], #field, (void *)(val_)); \ + else \ + assert(0); \ + } \ + break; \ + } \ +} while(0) + +#define RND_DAD_FREE_FIELD(table, field) \ +do { \ + switch(table[field].type) { \ + case RND_HATT_LABEL: \ + free((char *)table[field].name); \ + break; \ + case RND_HATT_INTEGER: \ + case RND_HATT_BOOL: \ + case RND_HATT_ENUM: \ + case RND_HATT_COORD: \ + case RND_HATT_UNIT: \ + case RND_HATT_REAL: \ + case RND_HATT_PROGRESS: \ + case RND_HATT_STRING: \ + case RND_HATT_BUTTON: \ + case RND_HATT_PICTURE: \ + case RND_HATT_PICBUTTON: \ + case RND_HATT_COLOR: \ + case RND_HATT_SUBDIALOG: \ + break; \ + case RND_HATT_TREE: \ + rnd_dad_tree_free(&table[field]); \ + break; \ + case RND_HATT_PREVIEW: \ + { \ + rnd_hid_preview_t *prv = table[field].wdata; \ + if (prv->user_free_cb != NULL) \ + prv->user_free_cb(&table[field], prv->user_ctx, prv->hid_wdata); \ + if (prv->hid_free_cb != NULL) \ + prv->hid_free_cb(&table[field], prv->hid_wdata); \ + free(prv); \ + } \ + break; \ + case RND_HATT_TEXT: \ + { \ + rnd_hid_text_t *txt = table[field].wdata; \ + if (txt->user_free_cb != NULL) \ + txt->user_free_cb(&table[field], txt->user_ctx, txt->hid_wdata); \ + if (txt->hid_free_cb != NULL) \ + txt->hid_free_cb(&table[field], txt->hid_wdata); \ + free(txt); \ + } \ + break; \ + case RND_HATT_BEGIN_COMPOUND: \ + case RND_HATT_END: \ + { \ + rnd_hid_compound_t *cmp = table[field].wdata; \ + if ((cmp != NULL) && (cmp->free != NULL)) \ + cmp->free(&table[field]); \ + } \ + case RND_HATT_BEGIN_HBOX: \ + case RND_HATT_BEGIN_VBOX: \ + case RND_HATT_BEGIN_HPANE: \ + case RND_HATT_BEGIN_VPANE: \ + case RND_HATT_BEGIN_TABLE: \ + case RND_HATT_BEGIN_TABBED: \ + break; \ + } \ +} while(0) + +#define RND_DAD_WIDTH_CHR(table, width) \ +do { \ + if ((table[table ## _len - 1].type) == RND_HATT_END) { \ + rnd_hid_compound_t *cmp = table[table ## _len - 1].wdata; \ + if (cmp->set_geo != NULL) \ + cmp->set_geo(&table[table ## _len - 1], RND_HATF_HEIGHT_CHR, (width)); \ + } \ + else { \ + RND_DAD_OR_ATTR_FIELD(table, hatt_flags, RND_HATF_HEIGHT_CHR); \ + RND_DAD_SET_ATTR_FIELD(table, geo_width, (width)); \ + } \ +} while(0) + +/* Internal: free all rows and caches and the tree itself */ +void rnd_dad_tree_free(rnd_hid_attribute_t *attr); + +/* internal: retval override for the auto-close buttons */ +typedef struct { + int dont_free; + int valid; + int value; +} rnd_dad_retovr_t; + +typedef struct { + const char *label; + int retval; +} rnd_hid_dad_buttons_t; + +void rnd_hid_dad_close(void *hid_ctx, rnd_dad_retovr_t *retovr, int retval); +void rnd_hid_dad_close_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); +int rnd_hid_dad_run(void *hid_ctx, rnd_dad_retovr_t *retovr); +void rnd_hid_iterate(rnd_hid_t *hid); + +/* sub-dialogs e.g. for the file selector dialog */ +struct rnd_hid_dad_subdialog_s { + /* filled in by the sub-dialog's creator */ + RND_DAD_DECL_NOINIT(dlg) + + /* filled in by the parent dialog's code, the subdialog's code should + call this to query/change properties of the parent dialog. cmd and + argc/argv are all specific to the given dialog. Returns 0 on success, + return payload may be placed in res (if it is not NULL). Parent poke: + close() - cancel/close the dialog */ + int (*parent_poke)(rnd_hid_dad_subdialog_t *sub, const char *cmd, rnd_event_arg_t *res, int argc, rnd_event_arg_t *argv); + + /* OPTIONAL: filled in by the sub-dialog's creator: called by the + sub-dialog's parent while the parent dialog is being closed. If + ok is false, the dialog was cancelled */ + void (*on_close)(rnd_hid_dad_subdialog_t *sub, rnd_bool ok); + + void *parent_ctx; /* used by the parent dialog code */ + void *sub_ctx; /* used by the sub-dialog's creator */ + + gdl_elem_t link; /* list of subdialogs: e.g. dock */ +}; + +typedef struct rnd_hid_export_opt_func_dad_s { + RND_DAD_DECL_NOINIT(dlg) +} rnd_hid_export_opt_func_dad_t; + +#endif Index: trunk/src/librnd/hid/hid_dad_spin.c =================================================================== --- trunk/src/librnd/hid/hid_dad_spin.c (nonexistent) +++ trunk/src/librnd/hid/hid_dad_spin.c (revision 34602) @@ -0,0 +1,672 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2019..2021 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Compound DAD widget for numeric value entry, creating a spinbox */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +gdl_list_t rnd_dad_coord_spins; + +const char *rnd_hid_dad_spin_up[] = { +"5 3 2 1", +" c None", +"+ c #000000", +" + ", +" +++ ", +"+++++", +}; + +const char *rnd_hid_dad_spin_down[] = { +"5 3 2 1", +" c None", +"+ c #000000", +"+++++", +" +++ ", +" + ", +}; + +const char *rnd_hid_dad_spin_unit[] = { +"4 4 2 1", +" c None", +"+ c #000000", +"+ +", +"+ +", +"+ +", +" ++ ", +}; + +const char *rnd_hid_dad_spin_warn[] = { +"9 9 3 1", +" c None", +"+ c #000000", +"* c #FF0000", +" ******* ", +"** **", +"* + + *", +"* + + *", +"* + + + *", +"* + + + *", +"* +++++ *", +"** **", +" ******* ", +}; + +static void spin_changed(void *hid_ctx, void *caller_data, rnd_hid_dad_spin_t *spin, rnd_hid_attribute_t *end) +{ + const char *s; + rnd_hid_attribute_t *str = end - spin->cmp.wend + spin->wstr; + + end->changed = 1; + + /* determine whether textual input is empty and indicate that in the compound end widget */ + s = str->val.str; + if (s == NULL) s = ""; + while(isspace(*s)) s++; + end->empty = (*s == '\0'); + + if (end->change_cb != NULL) + end->change_cb(hid_ctx, caller_data, end); +} + +static void spin_warn(void *hid_ctx, rnd_hid_dad_spin_t *spin, rnd_hid_attribute_t *end, const char *msg) +{ + rnd_gui->attr_dlg_widget_hide(hid_ctx, spin->wwarn, (msg == NULL)); + if (rnd_gui->attr_dlg_set_help != NULL) + rnd_gui->attr_dlg_set_help(hid_ctx, spin->wwarn, msg); +} + +static char *gen_str_coord(rnd_hid_dad_spin_t *spin, rnd_coord_t c, char *buf, int buflen) +{ + const rnd_unit_t *unit; + if (spin->unit != NULL) + unit = spin->unit; + else + unit = rnd_conf.editor.grid_unit; + if (buf != NULL) { + rnd_snprintf(buf, buflen, "%.06$m*", unit->suffix, c); + return buf; + } + return rnd_strdup_printf("%.06$m*", unit->suffix, c); +} + +typedef struct { + RND_DAD_DECL_NOINIT(dlg) + rnd_hid_attribute_t *end; + int wout, wunit, wstick, wglob, valid; + char buf[128]; +} spin_unit_t; + +static void spin_unit_chg_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_hid_attr_val_t hv; + spin_unit_t *su = (spin_unit_t *)caller_data; + const rnd_unit_t *unit; + int unum = su->dlg[su->wunit].val.lng; + int can_glob = su->wglob > 0; + int is_globbing = &su->dlg[su->wglob] == attr; + + if (!can_glob) + unit = &rnd_units[unum]; + else if ((!is_globbing) && (unum >= 0) && (unum < rnd_get_n_units(0))) + unit = &rnd_units[unum]; + else + unit = rnd_conf.editor.grid_unit; + + if (is_globbing && su->dlg[su->wglob].val.lng) { + /* global ticked in: also set the unit by force */ + unum = rnd_conf.editor.grid_unit - rnd_units; + hv.lng = unum; + rnd_gui->attr_dlg_set_value(hid_ctx, su->wunit, &hv); + } + + rnd_snprintf(su->buf, sizeof(su->buf), "%$m*", unit->suffix, su->end->val.crd); + hv.str = su->buf; + rnd_gui->attr_dlg_set_value(hid_ctx, su->wout, &hv); + if (!is_globbing && can_glob) { + /* unit changed: disable global, accept the user wants to use this unit */ + hv.lng = 0; + rnd_gui->attr_dlg_set_value(hid_ctx, su->wglob, &hv); + } + su->valid = 1; +} + +static void spin_unit_dialog(void *spin_hid_ctx, rnd_hid_dad_spin_t *spin, rnd_hid_attribute_t *end, rnd_hid_attribute_t *str) +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", -1}, {"ok", 0}, {NULL, 0}}; + spin_unit_t ctx; + const rnd_unit_t *def_unit; + int dlgfail; + + memset(&ctx, 0, sizeof(ctx)); + ctx.end = end; + + def_unit = spin->unit == NULL ? rnd_conf.editor.grid_unit : spin->unit; + + RND_DAD_BEGIN_VBOX(ctx.dlg); + RND_DAD_COMPFLAG(ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_TABLE(ctx.dlg, 2); + RND_DAD_COMPFLAG(ctx.dlg, RND_HATF_FRAME); + RND_DAD_LABEL(ctx.dlg, "Original:"); + RND_DAD_LABEL(ctx.dlg, str->val.str); + RND_DAD_LABEL(ctx.dlg, "With new unit:"); + RND_DAD_LABEL(ctx.dlg, ""); + ctx.wout = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_END(ctx.dlg); + + + RND_DAD_BEGIN_TABLE(ctx.dlg, 2); + RND_DAD_LABEL(ctx.dlg, "Preferred unit"); + RND_DAD_UNIT(ctx.dlg, spin->unit_family); + ctx.wunit = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_HELP(ctx.dlg, "Convert value to this unit and rewrite\nthe text entry field with the converted value."); + RND_DAD_DEFAULT_PTR(ctx.dlg, def_unit); + RND_DAD_CHANGE_CB(ctx.dlg, spin_unit_chg_cb); + + if (spin->unit_family == (RND_UNIT_METRIC | RND_UNIT_IMPERIAL)) { + RND_DAD_LABEL(ctx.dlg, "Use the global"); + RND_DAD_BOOL(ctx.dlg); + RND_DAD_HELP(ctx.dlg, "Ignore the above unit selection,\nuse the global unit (grid unit) in this spinbox,\nfollow changes of the global unit"); + ctx.wglob = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_DEFAULT_NUM(ctx.dlg, (spin->unit == NULL)); + RND_DAD_CHANGE_CB(ctx.dlg, spin_unit_chg_cb); + + RND_DAD_LABEL(ctx.dlg, "Stick to unit"); + RND_DAD_BOOL(ctx.dlg); + RND_DAD_HELP(ctx.dlg, "Upon any update from software, switch back to\the selected unit even if the user specified\na different unit in the text field."); + ctx.wstick = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_DEFAULT_NUM(ctx.dlg, spin->no_unit_chg); + RND_DAD_CHANGE_CB(ctx.dlg, spin_unit_chg_cb); + } + else { + ctx.wglob = -1; + ctx.wstick = -1; + } + + RND_DAD_END(ctx.dlg); + + RND_DAD_BEGIN_HBOX(ctx.dlg); + RND_DAD_COMPFLAG(ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_HBOX(ctx.dlg); + RND_DAD_COMPFLAG(ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx.dlg); + RND_DAD_BUTTON_CLOSES(ctx.dlg, clbtn); + RND_DAD_END(ctx.dlg); + RND_DAD_END(ctx.dlg); + + RND_DAD_AUTORUN("unit", ctx.dlg, "spinbox coord unit change", &ctx, dlgfail); + if ((dlgfail == 0) && (ctx.valid)) { + rnd_hid_attr_val_t hv; + int unum = ctx.dlg[ctx.wunit].val.lng; + int can_glob = (spin->unit_family == (RND_UNIT_METRIC | RND_UNIT_IMPERIAL)); + + if (!can_glob) + spin->unit = &rnd_units[unum]; + else if ((!ctx.dlg[ctx.wglob].val.lng) && (unum >= 0) && (unum < rnd_get_n_units(0))) + spin->unit = &rnd_units[unum]; + else + spin->unit = NULL; + + if (can_glob) + spin->no_unit_chg = ctx.dlg[ctx.wstick].val.lng; + else + spin->no_unit_chg = 1; + + hv.str = rnd_strdup(ctx.buf); + rnd_gui->attr_dlg_set_value(spin_hid_ctx, spin->wstr, &hv); + } + + RND_DAD_FREE(ctx.dlg); +} + +static double get_step(rnd_hid_dad_spin_t *spin, rnd_hid_attribute_t *end, rnd_hid_attribute_t *str) +{ + double v, step; + const rnd_unit_t *unit; + + if (spin->step > 0) + return spin->step; + + switch(spin->type) { + case RND_DAD_SPIN_INT: + step = pow(10, floor(log10(fabs((double)end->val.lng)) - 1.0)); + if (step < 1) + step = 1; + break; + case RND_DAD_SPIN_DOUBLE: + case RND_DAD_SPIN_FREQ: + v = end->val.dbl; + if (v == 0) + v = spin->vmax / 10; + if (v == 0) + step = 1; + else + step = pow(10, floor(log10(fabs(v)) - 1.0)); + break; + case RND_DAD_SPIN_COORD: + if (spin->unit == NULL) { + rnd_bool succ = 0; + if (str->val.str != NULL) + succ = rnd_get_value_unit(str->val.str, NULL, 0, &v, &unit); + if (!succ) { + v = end->val.crd; + unit = rnd_conf.editor.grid_unit; + } + } + else + unit = spin->unit; + v = rnd_coord_to_unit(unit, end->val.crd); + step = pow(10, floor(log10(fabs(v)) - 1.0)); + if (step <= 0.0) + step = 1; + step = rnd_unit_to_coord(unit, step); + break; + } + return step; +} + +#define SPIN_CLAMP(dst) \ + do { \ + if ((spin->vmin_valid) && (dst < spin->vmin)) { \ + dst = spin->vmin; \ + warn = "Value already at the minimum"; \ + } \ + if ((spin->vmax_valid) && (dst > spin->vmax)) { \ + dst = spin->vmax; \ + warn = "Value already at the maximum"; \ + } \ + } while(0) + +static void do_step(void *hid_ctx, rnd_hid_dad_spin_t *spin, rnd_hid_attribute_t *str, rnd_hid_attribute_t *end, double step) +{ + rnd_hid_attr_val_t hv; + const char *warn = NULL; + char buf[128]; + + switch(spin->type) { + case RND_DAD_SPIN_INT: + end->val.lng += step; + SPIN_CLAMP(end->val.lng); + sprintf(buf, "%ld", end->val.lng); + break; + case RND_DAD_SPIN_DOUBLE: + case RND_DAD_SPIN_FREQ: + end->val.dbl += step; + SPIN_CLAMP(end->val.dbl); + sprintf(buf, "%f", end->val.dbl); + break; + case RND_DAD_SPIN_COORD: + end->val.crd += step; + SPIN_CLAMP(end->val.crd); + spin->last_good_crd = end->val.crd; + gen_str_coord(spin, end->val.crd, buf, sizeof(buf)); + break; + } + + spin_warn(hid_ctx, spin, end, warn); + hv.str = rnd_strdup(buf); + spin->set_writeback_lock++; + rnd_gui->attr_dlg_set_value(hid_ctx, spin->wstr, &hv); + spin->set_writeback_lock--; +} + +void rnd_dad_spin_up_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_hid_dad_spin_t *spin = (rnd_hid_dad_spin_t *)attr->user_data; + rnd_hid_attribute_t *str = attr - spin->wup + spin->wstr; + rnd_hid_attribute_t *end = attr - spin->wup + spin->cmp.wend; + + rnd_dad_spin_txt_enter_cb_dry(hid_ctx, caller_data, str); /* fix up missing unit */ + + do_step(hid_ctx, spin, str, end, get_step(spin, end, str)); + spin_changed(hid_ctx, caller_data, spin, end); + rnd_dad_spin_txt_enter_call_users(hid_ctx, end); +} + +void rnd_dad_spin_down_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_hid_dad_spin_t *spin = (rnd_hid_dad_spin_t *)attr->user_data; + rnd_hid_attribute_t *str = attr - spin->wdown + spin->wstr; + rnd_hid_attribute_t *end = attr - spin->wdown + spin->cmp.wend; + + rnd_dad_spin_txt_enter_cb_dry(hid_ctx, caller_data, str); /* fix up missing unit */ + + do_step(hid_ctx, spin, str, end, -get_step(spin, end, str)); + spin_changed(hid_ctx, caller_data, spin, end); + rnd_dad_spin_txt_enter_call_users(hid_ctx, end); +} + +static int is_str_zero(const char *s) +{ + if (s == NULL) return 0; + + /* leading whitepsace */ + while(isspace(*s)) s++; + + /* 00.000 */ + while(*s == '0') s++; + if (*s == '.') { + s++; + while(*s == '0') s++; + } + + /* trailing whitepsace */ + while(isspace(*s)) s++; + + return *s == '\0'; +} + +void rnd_dad_spin_txt_change_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_hid_dad_spin_t *spin = (rnd_hid_dad_spin_t *)attr->user_data; + rnd_hid_attribute_t *str = attr; + rnd_hid_attribute_t *end = attr - spin->wstr + spin->cmp.wend; + char *ends, *warn = NULL; + long l; + double d; + rnd_bool succ, absolute; + const rnd_unit_t *unit; + + if (spin->set_writeback_lock) + return; + + switch(spin->type) { + case RND_DAD_SPIN_INT: + l = strtol(str->val.str, &ends, 10); + SPIN_CLAMP(l); + if (*ends != '\0') + warn = "Invalid integer - result is truncated"; + end->val.lng = l; + break; + case RND_DAD_SPIN_DOUBLE: + d = strtod(str->val.str, &ends); + SPIN_CLAMP(d); + if (*ends != '\0') + warn = "Invalid numeric - result is truncated"; + end->val.dbl = d; + break; + case RND_DAD_SPIN_COORD: + /* special case: 0 is okay without unit */ + if (is_str_zero(str->val.str)) { + end->val.crd = 0; + spin->last_good_crd = 0; + break; + } + succ = rnd_get_value_unit(str->val.str, &absolute, 0, &d, &unit); + if (succ) { + SPIN_CLAMP(d); + end->val.crd = d; + spin->last_good_crd = d; + } + else { + warn = "Invalid coord value or unit - result is truncated"; + end->val.crd = spin->last_good_crd; + } + if (!spin->no_unit_chg) + spin->unit = unit; + break; + default: rnd_trace("INTERNAL ERROR: spin_set_num\n"); + } + + spin_warn(hid_ctx, spin, end, warn); + spin_changed(hid_ctx, caller_data, spin, end); +} + +void rnd_dad_spin_txt_enter_cb_dry(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_hid_dad_spin_t *spin = (rnd_hid_dad_spin_t *)attr->user_data; + rnd_hid_attribute_t *str = attr; + rnd_hid_attribute_t *end = attr - spin->wstr + spin->cmp.wend; + const char *inval; + char *ends, *warn = NULL; + int changed = 0; + double d; + rnd_bool succ, absolute; + const rnd_unit_t *unit; + + if (spin->set_writeback_lock) + return; + + switch(spin->type) { + case RND_DAD_SPIN_COORD: + inval = str->val.str; + while(isspace(*inval)) inval++; + if (*inval == '\0') + inval = "0"; + succ = rnd_get_value_unit(inval, &absolute, 0, &d, &unit); + if (succ) + break; + strtod(inval, &ends); + while(isspace(*ends)) ends++; + if (*ends == '\0') { + rnd_hid_attr_val_t hv; + char *tmp = rnd_concat(inval, " ", rnd_conf.editor.grid_unit->suffix, NULL); + + changed = 1; + hv.str = tmp; + spin->set_writeback_lock++; + rnd_gui->attr_dlg_set_value(hid_ctx, spin->wstr, &hv); + spin->set_writeback_lock--; + succ = rnd_get_value_unit(str->val.str, &absolute, 0, &d, &unit); + if (succ) { + end->val.crd = d; + spin->last_good_crd = d; + } + free(tmp); + } + break; + default: + /* don't do anything extra for the rest */ + break; + } + + if (changed) { + spin_warn(hid_ctx, spin, end, warn); + spin_changed(hid_ctx, caller_data, spin, end); + } +} + +void rnd_dad_spin_txt_enter_call_users(void *hid_ctx, rnd_hid_attribute_t *end) +{ + struct { + void *caller_data; + } *hc = hid_ctx; + + if (end->enter_cb != NULL) + end->enter_cb(hid_ctx, hc->caller_data, end); +} + +void rnd_dad_spin_txt_enter_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_hid_dad_spin_t *spin = (rnd_hid_dad_spin_t *)attr->user_data; + rnd_hid_attribute_t *end = attr - spin->wstr + spin->cmp.wend; + + rnd_dad_spin_txt_enter_cb_dry(hid_ctx, caller_data, attr); + rnd_dad_spin_txt_enter_call_users(hid_ctx, end); +} + + +void rnd_dad_spin_unit_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_hid_dad_spin_t *spin = (rnd_hid_dad_spin_t *)attr->user_data; + rnd_hid_attribute_t *str = attr - spin->wunit + spin->wstr; + rnd_hid_attribute_t *end = attr - spin->wunit + spin->cmp.wend; + spin_unit_dialog(hid_ctx, spin, end, str); +} + +void rnd_dad_spin_set_num(rnd_hid_attribute_t *attr, long l, double d, rnd_coord_t c) +{ + rnd_hid_dad_spin_t *spin = attr->wdata; + rnd_hid_attribute_t *str = attr - spin->cmp.wend + spin->wstr; + + switch(spin->type) { + case RND_DAD_SPIN_INT: + attr->val.lng = l; + free((char *)str->val.str); + str->val.str = rnd_strdup_printf("%ld", l); + break; + case RND_DAD_SPIN_DOUBLE: + attr->val.dbl = d; + free((char *)str->val.str); + str->val.str = rnd_strdup_printf("%f", d); + break; + case RND_DAD_SPIN_COORD: + attr->val.crd = c; + spin->last_good_crd = c; + spin->unit = NULL; + free((char *)str->val.str); + str->val.str = gen_str_coord(spin, c, NULL, 0); + break; + default: rnd_trace("INTERNAL ERROR: spin_set_num\n"); + } +} + +void rnd_dad_spin_free(rnd_hid_attribute_t *attr) +{ + if (attr->type == RND_HATT_END) { + rnd_hid_dad_spin_t *spin = attr->wdata; + if (spin->type == RND_DAD_SPIN_COORD) + gdl_remove(&rnd_dad_coord_spins, spin, link); + free(spin); + } +} + +int rnd_dad_spin_widget_state(rnd_hid_attribute_t *end, void *hid_ctx, int idx, rnd_bool enabled) +{ + rnd_hid_dad_spin_t *spin = end->wdata; + return rnd_gui->attr_dlg_widget_state(hid_ctx, spin->wall, enabled); +} + +int rnd_dad_spin_widget_hide(rnd_hid_attribute_t *end, void *hid_ctx, int idx, rnd_bool hide) +{ + rnd_hid_dad_spin_t *spin = end->wdata; + return rnd_gui->attr_dlg_widget_hide(hid_ctx, spin->wall, hide); +} + +int rnd_dad_spin_set_value(rnd_hid_attribute_t *end, void *hid_ctx, int idx, const rnd_hid_attr_val_t *val) +{ + rnd_hid_dad_spin_t *spin = end->wdata; + rnd_hid_attribute_t *str = end - spin->cmp.wend + spin->wstr; + + /* do not modify the text field if the value is the same */ + switch(spin->type) { + case RND_DAD_SPIN_INT: + if (val->lng == end->val.lng) + return 0; + end->val.lng = val->lng; + break; + case RND_DAD_SPIN_DOUBLE: + case RND_DAD_SPIN_FREQ: + if (val->dbl == end->val.dbl) + return 0; + end->val.dbl = val->dbl; + break; + case RND_DAD_SPIN_COORD: + if (val->crd == end->val.crd) + return 0; + end->val.crd = val->crd; + spin->last_good_crd = val->crd; + break; + } + do_step(hid_ctx, spin, str, end, 0); /* cheap conversion + error checks */ + return 0; +} + +void rnd_dad_spin_set_help(rnd_hid_attribute_t *end, const char *help) +{ + rnd_hid_dad_spin_t *spin = end->wdata; + rnd_hid_attribute_t *str = end - spin->cmp.wend + spin->wstr; + + if ((spin->hid_ctx == NULL) || (*spin->hid_ctx == NULL)) /* while building */ + str->help_text = help; + else if (rnd_gui->attr_dlg_set_help != NULL) /* when the dialog is already running */ + rnd_gui->attr_dlg_set_help(*spin->hid_ctx, spin->wstr, help); +} + +void rnd_dad_spin_update_global_coords(void) +{ + rnd_hid_dad_spin_t *spin; + + + for(spin = gdl_first(&rnd_dad_coord_spins); spin != NULL; spin = gdl_next(&rnd_dad_coord_spins, spin)) { + rnd_hid_attribute_t *dlg; + void *hid_ctx; + + if ((spin->unit != NULL) || (spin->attrs == NULL) || (*spin->attrs == NULL) || (spin->hid_ctx == NULL) || (*spin->hid_ctx == NULL)) + continue; + + dlg = *spin->attrs; + hid_ctx = *spin->hid_ctx; + do_step(hid_ctx, spin, &dlg[spin->wstr], &dlg[spin->cmp.wend], 0); /* cheap conversion*/ + } +} + +void rnd_dad_spin_update_internal(rnd_hid_dad_spin_t *spin) +{ + rnd_hid_attribute_t *dlg = *spin->attrs, *end = dlg+spin->cmp.wend; + rnd_hid_attribute_t *str = dlg + spin->wstr; + void *hid_ctx = *spin->hid_ctx; + char buf[128]; + + if (hid_ctx == NULL) /* before run() */ + str->val.str = rnd_strdup(gen_str_coord(spin, end->val.crd, buf, sizeof(buf))); + else + do_step(hid_ctx, spin, &dlg[spin->wstr], &dlg[spin->cmp.wend], 0); /* cheap conversion*/ +} + +void rnd_dad_spin_set_geo(rnd_hid_attribute_t *end, rnd_hatt_compflags_t flg, int geo) +{ + rnd_hid_dad_spin_t *spin = end->wdata; + rnd_hid_attribute_t *str = end - spin->cmp.wend + spin->wstr; + + if (flg == RND_HATF_HEIGHT_CHR) { + str->hatt_flags |= RND_HATF_HEIGHT_CHR; + str->geo_width = geo; + } +} + +void rnd_dad_spin_set_field_num(rnd_hid_attribute_t *end, const char *fieldname, long l, double d, rnd_coord_t c) +{ + rnd_hid_dad_spin_t *spin = end->wdata; + if (strcmp(fieldname, "max_val") == 0) { + spin->vmax_valid = 1; + spin->vmax = d; + } + else if (strcmp(fieldname, "min_val") == 0) { + spin->vmin_valid = 1; + spin->vmin = d; + } +} + Index: trunk/src/librnd/hid/hid_dad_spin.h =================================================================== --- trunk/src/librnd/hid/hid_dad_spin.h (nonexistent) +++ trunk/src/librnd/hid/hid_dad_spin.h (revision 34602) @@ -0,0 +1,166 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Compound DAD widget for numeric value entry, creating a spinbox */ + +#ifndef RND_HID_DAD_SPIN_H +#define RND_HID_DAD_SPIN_H + +#include + +typedef struct { + rnd_hid_compound_t cmp; + double step; /* how much an up/down step modifies; 0 means automatic */ + double vmin, vmax; + unsigned vmin_valid:1; + unsigned vmax_valid:1; + unsigned no_unit_chg:1; + int wall, wstr, wup, wdown, wunit, wwarn; + const rnd_unit_t *unit; /* for RND_DAD_SPIN_COORD and RND_DAD_SPIN_FREQ only: current unit */ + rnd_family_t unit_family; + rnd_hid_attribute_t **attrs; + void **hid_ctx; + int set_writeback_lock; + rnd_coord_t last_good_crd; + enum { + RND_DAD_SPIN_INT, + RND_DAD_SPIN_DOUBLE, + RND_DAD_SPIN_COORD, + RND_DAD_SPIN_FREQ + } type; + rnd_hid_attr_type_t wtype; + gdl_elem_t link; + + /* Spare: see doc/developer/spare.txt */ + void (*spare_f1)(void), (*spare_f2)(void); + long spare_l1, spare_l2, spare_l3, spare_l4; + void *spare_p1, *spare_p2, *spare_p3, *spare_p4; + double spare_d1, spare_d2, spare_d3, spare_d4; + rnd_coord_t spare_c1, spare_c2, spare_c3, spare_c4; +} rnd_hid_dad_spin_t; + +#define RND_DAD_SPIN_INT(table) RND_DAD_SPIN_ANY(table, RND_DAD_SPIN_INT, RND_HATT_INTEGER, 0, 0) +#define RND_DAD_SPIN_DOUBLE(table) RND_DAD_SPIN_ANY(table, RND_DAD_SPIN_DOUBLE, RND_HATT_REAL, 0, 0) +#define RND_DAD_SPIN_COORD(table) RND_DAD_SPIN_ANY(table, RND_DAD_SPIN_COORD, RND_HATT_COORD, 1, RND_UNIT_METRIC | RND_UNIT_IMPERIAL) +#define RND_DAD_SPIN_FREQ(table) RND_DAD_SPIN_ANY(table, RND_DAD_SPIN_FREQ, RND_HATT_REAL, 1, RND_UNIT_FREQ) + +/* Return the widget-type (RND_DAD_HATT) of a spinbox at the RND_HATT_END widget; + useful for dispatching what value set to use */ +#define RND_DAD_SPIN_GET_TYPE(attr) \ + ((((attr)->type == RND_HATT_END) && (((rnd_hid_dad_spin_t *)((attr)->wdata))->cmp.free == rnd_dad_spin_free)) ? ((rnd_hid_dad_spin_t *)((attr)->wdata))->wtype : RND_HATT_END) + +/*** implementation ***/ + +#define RND_DAD_SPIN_ANY(table, typ, wtyp, has_unit, unit_family_) \ +do { \ + rnd_hid_dad_spin_t *spin = calloc(sizeof(rnd_hid_dad_spin_t), 1); \ + RND_DAD_BEGIN(table, RND_HATT_BEGIN_COMPOUND); \ + spin->cmp.wbegin = RND_DAD_CURRENT(table); \ + RND_DAD_SET_ATTR_FIELD(table, wdata, spin); \ + RND_DAD_BEGIN_HBOX(table); \ + spin->wall = RND_DAD_CURRENT(table); \ + RND_DAD_COMPFLAG(table, RND_HATF_TIGHT); \ + RND_DAD_STRING(table); \ + RND_DAD_DEFAULT_PTR(table, rnd_strdup("")); \ + RND_DAD_ENTER_CB(table, rnd_dad_spin_txt_enter_cb); \ + RND_DAD_CHANGE_CB(table, rnd_dad_spin_txt_change_cb); \ + RND_DAD_SET_ATTR_FIELD(table, user_data, (const char **)spin); \ + spin->wstr = RND_DAD_CURRENT(table); \ + RND_DAD_BEGIN_VBOX(table); \ + RND_DAD_COMPFLAG(table, RND_HATF_TIGHT); \ + RND_DAD_PICBUTTON(table, rnd_hid_dad_spin_up); \ + RND_DAD_CHANGE_CB(table, rnd_dad_spin_up_cb); \ + RND_DAD_SET_ATTR_FIELD(table, user_data, (const char **)spin); \ + spin->wup = RND_DAD_CURRENT(table); \ + RND_DAD_PICBUTTON(table, rnd_hid_dad_spin_down); \ + RND_DAD_CHANGE_CB(table, rnd_dad_spin_down_cb); \ + RND_DAD_SET_ATTR_FIELD(table, user_data, (const char **)spin); \ + spin->wdown = RND_DAD_CURRENT(table); \ + RND_DAD_END(table); \ + RND_DAD_BEGIN_VBOX(table); \ + RND_DAD_COMPFLAG(table, RND_HATF_TIGHT); \ + if (has_unit) { \ + RND_DAD_PICBUTTON(table, rnd_hid_dad_spin_unit); \ + RND_DAD_CHANGE_CB(table, rnd_dad_spin_unit_cb); \ + RND_DAD_SET_ATTR_FIELD(table, user_data, (const char **)spin); \ + spin->wunit = RND_DAD_CURRENT(table); \ + } \ + RND_DAD_PICTURE(table, rnd_hid_dad_spin_warn); \ + RND_DAD_COMPFLAG(table, RND_HATF_HIDE); \ + RND_DAD_SET_ATTR_FIELD(table, user_data, (const char **)spin); \ + spin->wwarn = RND_DAD_CURRENT(table); \ + RND_DAD_END(table); \ + RND_DAD_END(table); \ + RND_DAD_END(table); \ + RND_DAD_SET_ATTR_FIELD(table, wdata, spin); \ + spin->cmp.wend = RND_DAD_CURRENT(table); \ + \ + spin->cmp.free = rnd_dad_spin_free; \ + spin->cmp.set_val_num = rnd_dad_spin_set_num; \ + spin->cmp.widget_state = rnd_dad_spin_widget_state; \ + spin->cmp.widget_hide = rnd_dad_spin_widget_hide; \ + spin->cmp.set_value = rnd_dad_spin_set_value; \ + spin->cmp.set_help = rnd_dad_spin_set_help; \ + spin->cmp.set_geo = rnd_dad_spin_set_geo; \ + spin->cmp.set_field_num = rnd_dad_spin_set_field_num; \ + spin->type = typ; \ + spin->wtype = wtyp; \ + spin->attrs = &table; \ + spin->hid_ctx = &table ## _hid_ctx; \ + spin->unit_family = unit_family_; \ + \ + if (typ == RND_DAD_SPIN_COORD) \ + gdl_append(&rnd_dad_coord_spins, spin, link); \ +} while(0) + +extern const char *rnd_hid_dad_spin_up[]; +extern const char *rnd_hid_dad_spin_down[]; +extern const char *rnd_hid_dad_spin_unit[]; +extern const char *rnd_hid_dad_spin_unit[]; +extern const char *rnd_hid_dad_spin_warn[]; + +void rnd_dad_spin_up_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); +void rnd_dad_spin_down_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); +void rnd_dad_spin_txt_enter_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); +void rnd_dad_spin_txt_enter_cb_dry(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); +void rnd_dad_spin_txt_enter_call_users(void *hid_ctx, rnd_hid_attribute_t *end); /* call the user's enter_cb on end */ +void rnd_dad_spin_txt_change_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); +void rnd_dad_spin_unit_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); + +void rnd_dad_spin_free(rnd_hid_attribute_t *attrib); +void rnd_dad_spin_set_num(rnd_hid_attribute_t *attr, long l, double d, rnd_coord_t c); +int rnd_dad_spin_widget_state(rnd_hid_attribute_t *end, void *hid_ctx, int idx, rnd_bool enabled); +int rnd_dad_spin_widget_hide(rnd_hid_attribute_t *end, void *hid_ctx, int idx, rnd_bool hide); +int rnd_dad_spin_set_value(rnd_hid_attribute_t *end, void *hid_ctx, int idx, const rnd_hid_attr_val_t *val); +void rnd_dad_spin_set_help(rnd_hid_attribute_t *end, const char *help); +void rnd_dad_spin_set_geo(rnd_hid_attribute_t *end, rnd_hatt_compflags_t flg, int geo); +void rnd_dad_spin_set_field_num(rnd_hid_attribute_t *attr, const char *fieldname, long l, double d, rnd_coord_t c); + +void rnd_dad_spin_update_internal(rnd_hid_dad_spin_t *spin); /* update the widget from spin, before or after the dialog is realized */ + +extern gdl_list_t rnd_dad_coord_spins; /* list of all active coord spinboxes */ + +#endif Index: trunk/src/librnd/hid/hid_dad_tree.c =================================================================== --- trunk/src/librnd/hid/hid_dad_tree.c (nonexistent) +++ trunk/src/librnd/hid/hid_dad_tree.c (revision 34602) @@ -0,0 +1,122 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018,2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Non-inline utility functions for the DAD tree widget */ + +#include +#include + +/* recursively free a row list subtree */ +static void rnd_dad_tree_free_rowlist(rnd_hid_attribute_t *attr, gdl_list_t *list) +{ + rnd_hid_tree_t *tree = attr->wdata; + rnd_hid_row_t *r; + + while((r = gdl_first(list)) != NULL) { + gdl_remove(list, r, link); + rnd_dad_tree_free_rowlist(attr, &r->children); + + if (tree->hid_free_cb != NULL) + tree->hid_free_cb(tree->attrib, tree->hid_wdata, r); + + if (tree->user_free_cb != NULL) + tree->user_free_cb(tree->attrib, tree->hid_wdata, r); + + if (attr->rnd_hatt_flags & RND_HATF_TREE_COL) + free(r->path); + + free(r); + } +} + +/* Internal: free all rows and caches and the tree itself */ +void rnd_dad_tree_free(rnd_hid_attribute_t *attr) +{ + rnd_hid_tree_t *tree = attr->wdata; + htsp_uninit(&tree->paths); + rnd_dad_tree_free_rowlist(attr, &tree->rows); + free(tree); +} + +void rnd_dad_tree_hide_all(rnd_hid_tree_t *tree, gdl_list_t *rowlist, int val) +{ + rnd_hid_row_t *r; + for(r = gdl_first(rowlist); r != NULL; r = gdl_next(rowlist, r)) { + r->hide = val; + rnd_dad_tree_hide_all(tree, &r->children, val); + } +} + +void rnd_dad_tree_unhide_filter(rnd_hid_tree_t *tree, gdl_list_t *rowlist, int col, const char *text) +{ + rnd_hid_row_t *r, *pr; + + for(r = gdl_first(rowlist); r != NULL; r = gdl_next(rowlist, r)) { + if (strstr(r->cell[col], text) != NULL) { + rnd_dad_tree_hide_all(tree, &r->children, 0); /* if this is a node with children, show all children */ + for(pr = r; pr != NULL; pr = rnd_dad_tree_parent_row(tree, pr)) /* also show all parents so it is visible */ + pr->hide = 0; + } + rnd_dad_tree_unhide_filter(tree, &r->children, col, text); + } +} + +rnd_hid_row_t *rnd_dad_tree_mkdirp(rnd_hid_tree_t *tree, char *path, char **cells) +{ + char *cell[2] = {NULL}; + rnd_hid_row_t *parent; + char *last, *old; + + parent = htsp_get(&tree->paths, path); + if (parent != NULL) + return parent; + + last = strrchr(path, '/'); + + if (last == NULL) { + /* root dir */ + parent = htsp_get(&tree->paths, path); + if (parent != NULL) + return parent; + cell[0] = rnd_strdup(path); + return rnd_dad_tree_append(tree->attrib, NULL, cell); + } + +/* non-root-dir: get or create parent */ + *last = '\0'; + last++; + parent = rnd_dad_tree_mkdirp(tree, path, NULL); + + if (cells == NULL) { + cell[0] = rnd_strdup(last); + return rnd_dad_tree_append_under(tree->attrib, parent, cell); + } + + old = cell[0]; + cells[0] = rnd_strdup(last); + free(old); + return rnd_dad_tree_append_under(tree->attrib, parent, cells); +} Index: trunk/src/librnd/hid/hid_dad_tree.h =================================================================== --- trunk/src/librnd/hid/hid_dad_tree.h (nonexistent) +++ trunk/src/librnd/hid/hid_dad_tree.h (revision 34602) @@ -0,0 +1,322 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018,2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Inline helpers called by the DAD macros for the tree-table widget */ + +#ifndef RND_HID_DAD_TREE_H +#define RND_HID_DAD_TREE_H + +#include +#include +#include +#include +#include +#include + +/* recursively sets the hide flag on all nodes to val */ +void rnd_dad_tree_hide_all(rnd_hid_tree_t *tree, gdl_list_t *rowlist, int val); + +/* recursively unhide items that match text in the given column; parents are unhidden too */ +void rnd_dad_tree_unhide_filter(rnd_hid_tree_t *tree, gdl_list_t *rowlist, int col, const char *text); + +/* Recursively create the node and all parents in a tree. If cells is not NULL, + the target path row is created with these cells, else only the first col + is filled in. Temporarily modifies path (but changes it back) */ +rnd_hid_row_t *rnd_dad_tree_mkdirp(rnd_hid_tree_t *tree, char *path, char **cells); + +/* Internal: Allocate a new row and load the cells (but do not insert it anywhere) */ +RND_INLINE rnd_hid_row_t *rnd_dad_tree_new_row(char **cols) +{ + int num_cols; + rnd_hid_row_t *nrow; + char **s, **o; + for(s = cols, num_cols = 0; *s != NULL; s++, num_cols++); + + nrow = calloc(sizeof(rnd_hid_row_t) + sizeof(char *) * num_cols, 1); + nrow->cols = num_cols; + for(s = cols, o = nrow->cell; *s != NULL; s++, o++) + *o = *s; + + return nrow; +} + +RND_INLINE void rnd_dad_tree_free_row(rnd_hid_tree_t *tree, rnd_hid_row_t *row) +{ + int do_free_path = 0; + /* do this before the user callback just in case row->path == row->cell[0] + and the user callback free's it */ + if (row->path != NULL) { + htsp_pop(&tree->paths, row->path); + do_free_path = (row->path != row->cell[0]); /* user_free_cb may set row->cell[0] to NULL */ + } + + if (tree->user_free_cb != NULL) + tree->user_free_cb(tree->attrib, tree->hid_wdata, row); + + if (do_free_path) + free(row->path); + + free(row); +} + + +RND_INLINE rnd_hid_row_t *rnd_dad_tree_parent_row(rnd_hid_tree_t *tree, rnd_hid_row_t *row) +{ + char *ptr = (char *)row->link.parent; + if ((ptr == NULL) || ((gdl_list_t *)ptr == &tree->rows)) + return NULL; + + ptr -= offsetof(gdl_elem_t, parent); + ptr -= offsetof(rnd_hid_row_t, children); + return (rnd_hid_row_t *)ptr; +} + +RND_INLINE rnd_hid_row_t *rnd_dad_tree_prev_row(rnd_hid_tree_t *tree, rnd_hid_row_t *row) +{ + return row->link.prev; +} + +RND_INLINE rnd_hid_row_t *rnd_dad_tree_next_row(rnd_hid_tree_t *tree, rnd_hid_row_t *row) +{ + return row->link.next; +} + +/* recursively build a full path of a tree node in path */ +RND_INLINE void rnd_dad_tree_build_path(rnd_hid_tree_t *tree, gds_t *path, rnd_hid_row_t *row) +{ + rnd_hid_row_t *par = rnd_dad_tree_parent_row(tree, row); + if (par != NULL) + rnd_dad_tree_build_path(tree, path, par); + if (path->used > 0) + gds_append(path, '/'); + gds_append_str(path, row->cell[0]); +} + +/* calculate path of a row and insert it in the tree hash */ +RND_INLINE void rnd_dad_tree_set_hash(rnd_hid_attribute_t *attr, rnd_hid_row_t *row) +{ + rnd_hid_tree_t *tree = attr->wdata; + if (attr->rnd_hatt_flags & RND_HATF_TREE_COL) { + gds_t path; + gds_init(&path); + rnd_dad_tree_build_path(tree, &path, row); + row->path = path.array; + } + else + row->path = row->cell[0]; + htsp_set(&tree->paths, row->path, row); +} + +/* allocate a new row and append it after aft; if aft is NULL, the new row is appended at the + end of the list of entries in the root (== at the bottom of the list) */ +RND_INLINE rnd_hid_row_t *rnd_dad_tree_append(rnd_hid_attribute_t *attr, rnd_hid_row_t *aft, char **cols) +{ + rnd_hid_tree_t *tree = attr->wdata; + rnd_hid_row_t *nrow = rnd_dad_tree_new_row(cols); + gdl_list_t *par; /* the list that is the common parent of aft and the new row */ + + assert(attr == tree->attrib); + + if (aft == NULL) { + par = &tree->rows; + aft = gdl_last(par); + } + else + par = aft->link.parent; + + gdl_insert_after(par, aft, nrow, link); + rnd_dad_tree_set_hash(attr, nrow); + if (tree->hid_insert_cb != NULL) + tree->hid_insert_cb(tree->attrib, tree->hid_wdata, nrow); + return nrow; +} + +/* allocate a new row and inert it before bfr; if bfr is NULL, the new row is inserted at the + beginning of the list of entries in the root (== at the top of the list) */ +RND_INLINE rnd_hid_row_t *rnd_dad_tree_insert(rnd_hid_attribute_t *attr, rnd_hid_row_t *bfr, char **cols) +{ + rnd_hid_tree_t *tree = attr->wdata; + rnd_hid_row_t *nrow = rnd_dad_tree_new_row(cols); + gdl_list_t *par; /* the list that is the common parent of bfr and the new row */ + + assert(attr == tree->attrib); + + if (bfr == NULL) { + par = &tree->rows; + bfr = gdl_first(par); + } + else + par = bfr->link.parent; + + gdl_insert_before(par, bfr, nrow, link); + rnd_dad_tree_set_hash(attr, nrow); + if (tree->hid_insert_cb != NULL) + tree->hid_insert_cb(tree->attrib, tree->hid_wdata, nrow); + return nrow; +} + +/* allocate a new row and append it under prn; if prn is NULL, the new row is appended at the + end of the list of entries in the root (== at the bottom of the list) */ +RND_INLINE rnd_hid_row_t *rnd_dad_tree_append_under(rnd_hid_attribute_t *attr, rnd_hid_row_t *prn, char **cols) +{ + rnd_hid_tree_t *tree = attr->wdata; + rnd_hid_row_t *nrow = rnd_dad_tree_new_row(cols); + gdl_list_t *par; /* the list that is the common parent of aft and the new row */ + + assert(attr == tree->attrib); + + if (prn == NULL) + par = &tree->rows; + else + par = &prn->children; + + gdl_append(par, nrow, link); + rnd_dad_tree_set_hash(attr, nrow); + if (tree->hid_insert_cb != NULL) + tree->hid_insert_cb(tree->attrib, tree->hid_wdata, nrow); + return nrow; +} + +RND_INLINE int rnd_dad_tree_remove(rnd_hid_attribute_t *attr, rnd_hid_row_t *row) +{ + rnd_hid_tree_t *tree = attr->wdata; + rnd_hid_row_t *r, *rn, *par = rnd_dad_tree_parent_row(tree, row); + gdl_list_t *lst = (par == NULL) ? &tree->rows : &par->children; + int res = 0; + + assert(attr == tree->attrib); + + /* recursively remove all children */ + for(r = gdl_first(&row->children); r != NULL; r = rn) { + rn = gdl_next(&row->children, r); + res |= rnd_dad_tree_remove(attr, r); + } + + /* remove from gui */ + if (tree->hid_remove_cb != NULL) + tree->hid_remove_cb(tree->attrib, tree->hid_wdata, row); + else + res = -1; + + /* remove from dad */ + gdl_remove(lst, row, link); + rnd_dad_tree_free_row(tree, row); + return res; +} + +RND_INLINE void rnd_dad_tree_clear(rnd_hid_tree_t *tree) +{ + rnd_hid_row_t *r; + for(r = gdl_first(&tree->rows); r != NULL; r = gdl_first(&tree->rows)) + rnd_dad_tree_remove(tree->attrib, r); +} + +RND_INLINE rnd_hid_row_t *rnd_dad_tree_get_selected(rnd_hid_attribute_t *attr) +{ + rnd_hid_tree_t *tree = attr->wdata; + + assert(attr == tree->attrib); + + if (tree->hid_get_selected_cb == NULL) + return NULL; + + return tree->hid_get_selected_cb(tree->attrib, tree->hid_wdata); +} + +RND_INLINE void rnd_dad_tree_update_hide(rnd_hid_attribute_t *attr) +{ + rnd_hid_tree_t *tree = attr->wdata; + + assert(attr == tree->attrib); + + if (tree->hid_update_hide_cb != NULL) + tree->hid_update_hide_cb(tree->attrib, tree->hid_wdata); +} + +RND_INLINE int rnd_dad_tree_modify_cell(rnd_hid_attribute_t *attr, rnd_hid_row_t *row, int col, char *new_val) +{ + rnd_hid_tree_t *tree = attr->wdata; + + assert(attr == tree->attrib); + + if ((col < 0) || (col >= row->cols)) + return 0; + + if (col == 0) { + htsp_pop(&tree->paths, row->path); + free(row->path); + row->path = NULL; + } + + row->cell[col] = new_val; + + if (col == 0) + rnd_dad_tree_set_hash(attr, row); + + if (tree->hid_modify_cb != NULL) + tree->hid_modify_cb(tree->attrib, tree->hid_wdata, row, col); + + return 0; +} + +RND_INLINE void rnd_dad_tree_jumpto(rnd_hid_attribute_t *attr, rnd_hid_row_t *row) +{ + rnd_hid_tree_t *tree = attr->wdata; + + assert(attr == tree->attrib); + + if (tree->hid_jumpto_cb != NULL) + tree->hid_jumpto_cb(tree->attrib, tree->hid_wdata, row); +} + +RND_INLINE void rnd_dad_tree_expcoll_(rnd_hid_tree_t *tree, rnd_hid_row_t *row, rnd_bool expanded, rnd_bool recursive) +{ + if (recursive) { + rnd_hid_row_t *r; + for(r = gdl_first(&row->children); r != NULL; r = gdl_next(&row->children, r)) + rnd_dad_tree_expcoll_(tree, r, expanded, recursive); + } + if (gdl_first(&row->children) != NULL) + tree->hid_expcoll_cb(tree->attrib, tree->hid_wdata, row, expanded); +} + +RND_INLINE void rnd_dad_tree_expcoll(rnd_hid_attribute_t *attr, rnd_hid_row_t *row, rnd_bool expanded, rnd_bool recursive) +{ + rnd_hid_tree_t *tree = attr->wdata; + + assert(attr == tree->attrib); + + if (tree->hid_expcoll_cb != NULL) { + if (row == NULL) { + for(row = gdl_first(&tree->rows); row != NULL; row = gdl_next(&tree->rows, row)) + rnd_dad_tree_expcoll_(tree, row, expanded, recursive); + } + else + rnd_dad_tree_expcoll_(tree, row, expanded, recursive); + } +} + +#endif Index: trunk/src/librnd/hid/hid_dad_unit.c =================================================================== --- trunk/src/librnd/hid/hid_dad_unit.c (nonexistent) +++ trunk/src/librnd/hid/hid_dad_unit.c (revision 34602) @@ -0,0 +1,135 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Compound DAD widget for numeric value entry, creating a spinbox */ + +#include + +#include +#include +#include +#include + +void rnd_dad_unit_change_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_hid_dad_unit_t *unit = (rnd_hid_dad_unit_t *)attr->user_data; + rnd_hid_attribute_t *enu = attr; + rnd_hid_attribute_t *end = attr - unit->wenum + unit->cmp.wend; + const char **vals = enu->wdata; + const rnd_unit_t *u = get_unit_by_suffix(vals[enu->val.lng]); + int unit_id = u == NULL ? -1 : u - rnd_units; + + end->val.lng = unit_id; + end->changed = 1; + if (end->change_cb != NULL) + end->change_cb(hid_ctx, caller_data, end); +} + +void rnd_dad_unit_set_num(rnd_hid_attribute_t *attr, long unit_id, double unused1, rnd_coord_t unused2) +{ + int l; + rnd_hid_dad_unit_t *unit = attr->wdata; + rnd_hid_attribute_t *enu = attr - unit->cmp.wend + unit->wenum; + const char *target = rnd_units[unit_id].suffix; + const char **vals = enu->wdata; + + for(l = 0; vals[l] != NULL; l++) { + if (strcmp(target, vals[l]) == 0) { + enu->val.lng = l; + attr->val.lng = l; + } + } +} + +void rnd_dad_unit_set_val_ptr(rnd_hid_attribute_t *end, void *val_) +{ + const rnd_unit_t *val = val_; + int __n__, __v__ = rnd_get_n_units(1); + if (val != NULL) { + for(__n__ = 0; __n__ < __v__; __n__++) { + if (&rnd_units[__n__] == val) { + rnd_dad_unit_set_num(end, __n__, 0, 0); + return; + } + } + } +} + +int rnd_dad_unit_widget_state(rnd_hid_attribute_t *end, void *hid_ctx, int idx, rnd_bool enabled) +{ + rnd_hid_dad_unit_t *unit = end->wdata; + return rnd_gui->attr_dlg_widget_state(hid_ctx, unit->wenum, enabled); +} + +int rnd_dad_unit_widget_hide(rnd_hid_attribute_t *end, void *hid_ctx, int idx, rnd_bool hide) +{ + rnd_hid_dad_unit_t *unit = end->wdata; + return rnd_gui->attr_dlg_widget_hide(hid_ctx, unit->wenum, hide); +} + +int rnd_dad_unit_set_value(rnd_hid_attribute_t *end, void *hid_ctx, int idx, const rnd_hid_attr_val_t *val) +{ + rnd_hid_dad_unit_t *unit = end->wdata; + if (rnd_gui->attr_dlg_set_value(hid_ctx, unit->wenum, val) != 0) + return -1; + end->val.lng = val->lng; + return 0; +} + +void rnd_dad_unit_set_help(rnd_hid_attribute_t *end, const char *help) +{ + rnd_hid_dad_unit_t *unit = end->wdata; + rnd_hid_attribute_t *enu = end - unit->cmp.wend + unit->wenum; + + if ((unit->hid_ctx == NULL) || (*unit->hid_ctx == NULL)) /* while building */ + enu->help_text = help; + else if (rnd_gui->attr_dlg_set_help != NULL) /* when the dialog is already running */ + rnd_gui->attr_dlg_set_help(*unit->hid_ctx, unit->wenum, help); +} + +const char **rnd_dad_unit_enum = NULL; + +void rnd_dad_unit_init(enum rnd_family_e family) +{ + int len, n, i; + + if (rnd_dad_unit_enum != NULL) + return; + + len = rnd_get_n_units(0); + rnd_dad_unit_enum = malloc(sizeof(char *) * (len+1)); + for(n = i = 0; i < len; i++) { + if (rnd_units[i].family & family) + rnd_dad_unit_enum[n++] = rnd_units[i].suffix; + } + rnd_dad_unit_enum[n] = NULL; +} + +void rnd_dad_unit_uninit(void) +{ + free(rnd_dad_unit_enum); + rnd_dad_unit_enum = NULL; +} Index: trunk/src/librnd/hid/hid_dad_unit.h =================================================================== --- trunk/src/librnd/hid/hid_dad_unit.h (nonexistent) +++ trunk/src/librnd/hid/hid_dad_unit.h (revision 34602) @@ -0,0 +1,83 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Compound DAD widget for creating a unit change combo box */ + +#ifndef RND_HID_DAD_UNIT_H +#define RND_HID_DAD_UNIT_H + +#include + +#include + +typedef struct { + rnd_hid_compound_t cmp; + void **hid_ctx; + rnd_family_t family; /* which families of units are allowed in this spinbox */ + int wenum; +} rnd_hid_dad_unit_t; + +/*** implementation ***/ + + +#define RND_DAD_UNIT(table, family_) \ +do { \ + rnd_hid_dad_unit_t *unit = calloc(sizeof(rnd_hid_dad_unit_t), 1); \ + RND_DAD_BEGIN(table, RND_HATT_BEGIN_COMPOUND); \ + unit->cmp.wbegin = RND_DAD_CURRENT(table); \ + rnd_dad_unit_init(family_); \ + RND_DAD_ENUM(table, rnd_dad_unit_enum); \ + RND_DAD_CHANGE_CB(table, rnd_dad_unit_change_cb); \ + RND_DAD_SET_ATTR_FIELD(table, user_data, (const char **)unit); \ + unit->wenum = RND_DAD_CURRENT(table); \ + RND_DAD_END(table); \ + RND_DAD_SET_ATTR_FIELD(table, wdata, unit); \ + unit->cmp.wend = RND_DAD_CURRENT(table); \ + \ + unit->cmp.set_val_num = rnd_dad_unit_set_num; \ + unit->cmp.widget_state = rnd_dad_unit_widget_state; \ + unit->cmp.widget_hide = rnd_dad_unit_widget_hide; \ + unit->cmp.set_value = rnd_dad_unit_set_value; \ + unit->cmp.set_val_ptr = rnd_dad_unit_set_val_ptr; \ + unit->cmp.set_help = rnd_dad_unit_set_help; \ + unit->family = family_; \ + unit->hid_ctx = &table ## _hid_ctx; \ +} while(0) + +extern const char **rnd_dad_unit_enum; + +void rnd_dad_unit_set_num(rnd_hid_attribute_t *attr, long l, double unused1, rnd_coord_t unused2); +int rnd_dad_unit_widget_state(rnd_hid_attribute_t *end, void *hid_ctx, int idx, rnd_bool enabled); +int rnd_dad_unit_widget_hide(rnd_hid_attribute_t *end, void *hid_ctx, int idx, rnd_bool hide); +int rnd_dad_unit_set_value(rnd_hid_attribute_t *end, void *hid_ctx, int idx, const rnd_hid_attr_val_t *val); +void rnd_dad_unit_set_val_ptr(rnd_hid_attribute_t *end, void *val); +void rnd_dad_unit_set_help(rnd_hid_attribute_t *end, const char *help); +void rnd_dad_unit_change_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); + +void rnd_dad_unit_init(enum rnd_family_e family); +void rnd_dad_unit_uninit(void); + +#endif Index: trunk/src/librnd/hid/hid_dlg.c =================================================================== --- trunk/src/librnd/hid/hid_dlg.c (nonexistent) +++ trunk/src/librnd/hid/hid_dlg.c (revision 34602) @@ -0,0 +1,295 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 2004 harry eaton + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include + +#include +#include +#include +#include +#include + +static int hid_dlg_gui_inited = 0; + +/* Action and wrapper implementation for dialogs. If GUI is available, the + gui_ prefixed action is executed, else the cli_ prefixed one is used. If + nothing is available, the effect is equivalent to cancel. */ + +/* Call the gui_ or the cli_ action; act_name must be all lowercase! */ +static fgw_error_t call_dialog(const char *act_name, fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + char tmp[128]; + + strcpy(tmp, "gui_"); + strncpy(tmp+4, act_name, sizeof(tmp)-5); + if (RND_HAVE_GUI_ATTR_DLG && (fgw_func_lookup(&rnd_fgw, tmp) != NULL)) + return rnd_actionv_bin(RND_ACT_HIDLIB, tmp, res, argc, argv); + + tmp[0] = 'c'; tmp[1] = 'l'; + if (fgw_func_lookup(&rnd_fgw, tmp) != NULL) + return rnd_actionv_bin(RND_ACT_HIDLIB, tmp, res, argc, argv); + + return FGW_ERR_NOT_FOUND; +} + +static const char rnd_acts_PromptFor[] = "PromptFor([message[,default[,title]]])"; +static const char rnd_acth_PromptFor[] = "Prompt for a string. Returns the string (or NULL on cancel)"; +/* DOC: promptfor.html */ +static fgw_error_t rnd_act_PromptFor(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + return call_dialog("promptfor", res, argc, argv); +} + +char *rnd_hid_prompt_for(rnd_hidlib_t *hl, const char *msg, const char *default_string, const char *title) +{ + fgw_arg_t res, argv[4]; + + argv[1].type = FGW_STR; argv[1].val.cstr = msg; + argv[2].type = FGW_STR; argv[2].val.cstr = default_string; + argv[3].type = FGW_STR; argv[3].val.cstr = title; + + if (rnd_actionv_bin(hl, "PromptFor", &res, 4, argv) != 0) + return NULL; + + if (res.type == (FGW_STR | FGW_DYN)) + return res.val.str; + + fgw_arg_free(&rnd_fgw, &res); + return NULL; +} + +static const char rnd_acts_MessageBox[] = "MessageBox(icon, title, label, button_txt, button_retval, ...)"; +static const char rnd_acth_MessageBox[] = "Open a modal message dialog box with title and label. If icon string is not empty, display the named icon on the left. Present one or more window close buttons with different text and return value."; +static fgw_error_t rnd_act_MessageBox(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + return call_dialog("messagebox", res, argc, argv); +} + +int rnd_hid_message_box(rnd_hidlib_t *hl, const char *icon, const char *title, const char *label, ...) +{ + fgw_arg_t res, argv[128]; + int argc; + va_list ap; + + argv[1].type = FGW_STR; argv[1].val.cstr = icon; + argv[2].type = FGW_STR; argv[2].val.cstr = title; + argv[3].type = FGW_STR; argv[3].val.cstr = label; + argc = 4; + + va_start(ap, label); + for(;argc < 126;) { + argv[argc].type = FGW_STR; + argv[argc].val.cstr = va_arg(ap, const char *); + if (argv[argc].val.cstr == NULL) + break; + argc++; + argv[argc].type = FGW_INT; + argv[argc].val.nat_int = va_arg(ap, int); + argc++; + } + va_end(ap); + + if (rnd_actionv_bin(hl, "MessageBox", &res, argc, argv) != 0) + return -1; + + if (fgw_arg_conv(&rnd_fgw, &res, FGW_INT) == 0) + return res.val.nat_int; + + fgw_arg_free(&rnd_fgw, &res); + return -1; +} + +void rnd_hid_iterate(rnd_hid_t *hid) +{ + if (hid->iterate != NULL) + hid->iterate(hid); +} + +static const char *refresh = "progress refresh"; +static const char *cancel = "progress cancel"; +#define REFRESH_RATE 100 + +static void progress_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + rnd_hid_progress(0, 0, NULL); +} + +static void progress_close_btn_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_hid_progress(0, 0, cancel); +} + +static void progress_refresh_cb(rnd_hidval_t user_data) +{ + rnd_hid_progress(0, 0, refresh); +} + +static int rnd_gui_progress(long so_far, long total, const char *message) +{ + double now; + static rnd_hidval_t timer; + static int active = 0, cancelled = 0; + static int wp, have_timer = 0; + static rnd_hid_attr_val_t val; + static double last = 0; + static int closing = 0; + static struct { + RND_DAD_DECL_NOINIT(dlg) + } ctx; + + if (message == refresh) { + if (active) + last = rnd_dtime(); + have_timer = 0; + refresh_now:; + if (active) { + rnd_gui->attr_dlg_set_value(ctx.dlg_hid_ctx, wp, &val); + if (!have_timer) { + timer = rnd_gui->add_timer(rnd_gui, progress_refresh_cb, REFRESH_RATE, timer); + have_timer = 1; + } + rnd_hid_iterate(rnd_gui); + } + return 0; + } + + + if (message == cancel) { + cancelled = 1; + message = NULL; + } + + + /* If we are finished, destroy any dialog */ + if (so_far == 0 && total == 0 && message == NULL) { + if (active) { + if (have_timer) { + rnd_gui->stop_timer(rnd_gui, timer); + have_timer = 0; + } + if (!closing) { + closing = 1; + RND_DAD_FREE(ctx.dlg); + } + active = 0; + } + return 1; + } + + if (cancelled) { + cancelled = 0; + return 1; + } + + if (!active) { + RND_DAD_BEGIN_VBOX(ctx.dlg); + RND_DAD_LABEL(ctx.dlg, message); + RND_DAD_PROGRESS(ctx.dlg); + wp = RND_DAD_CURRENT(ctx.dlg); + + /* need to have a manual cancel button as it needs to call the close cb before really closing the window */ + RND_DAD_BEGIN_HBOX(ctx.dlg); + RND_DAD_BEGIN_HBOX(ctx.dlg); + RND_DAD_COMPFLAG(ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx.dlg); + RND_DAD_BUTTON(ctx.dlg, "cancel"); + RND_DAD_CHANGE_CB(ctx.dlg, progress_close_btn_cb); + RND_DAD_END(ctx.dlg); + RND_DAD_END(ctx.dlg); + + RND_DAD_NEW("progress", ctx.dlg, "Ringdove progress", &ctx, rnd_false, progress_close_cb); + active = 1; + cancelled = 0; + + timer = rnd_gui->add_timer(rnd_gui, progress_refresh_cb, REFRESH_RATE, timer); + have_timer = 1; + closing = 0; + } + + val.dbl = (double)so_far / (double)total; + + now = rnd_dtime(); + if (now >= (last + (REFRESH_RATE / 1000.0))) { + last = now; + goto refresh_now; + } + return 0; +} + + +int rnd_hid_progress(long so_far, long total, const char *message) +{ + if (rnd_gui == NULL) + return 0; + if ((rnd_gui->gui) && (RND_HAVE_GUI_ATTR_DLG) && (hid_dlg_gui_inited || rnd_gui->allow_dad_before_init)) + return rnd_gui_progress(so_far, total, message); + + return rnd_nogui_progress(so_far, total, message); +} + +static const char rnd_acts_Print[] = "Print()"; +static const char rnd_acth_Print[] = "Present the print export dialog for printing the layout from the GUI."; +/* DOC: print.html */ +static fgw_error_t rnd_act_Print(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + if (RND_HAVE_GUI_ATTR_DLG && (fgw_func_lookup(&rnd_fgw, "printgui") != NULL)) + return rnd_actionv_bin(RND_ACT_HIDLIB, "printgui", res, argc, argv); + rnd_message(RND_MSG_ERROR, "action Print() is available only under a GUI HID. Please use the lpr exporter instead.\n"); + return FGW_ERR_NOT_FOUND; +} + + +static rnd_action_t hid_dlg_action_list[] = { + {"PromptFor", rnd_act_PromptFor, rnd_acth_PromptFor, rnd_acts_PromptFor}, + {"MessageBox", rnd_act_MessageBox, rnd_acth_MessageBox, rnd_acts_MessageBox}, + {"Print", rnd_act_Print, rnd_acth_Print, rnd_acts_Print} +}; + +static const char *event_dlg_cookie = "hid_dlg"; + +static void hid_dlg_log_gui_init_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + hid_dlg_gui_inited = 1; +} + +void rnd_hid_dlg_uninit(void) +{ + rnd_event_unbind_allcookie(event_dlg_cookie); +} + +void rnd_hid_dlg_init(void) +{ + rnd_event_bind(RND_EVENT_GUI_INIT, hid_dlg_log_gui_init_ev, NULL, event_dlg_cookie); +} + +void rnd_hid_dlg_init2(void) +{ + RND_REGISTER_ACTIONS(hid_dlg_action_list, NULL); +} + Index: trunk/src/librnd/hid/hid_init.c =================================================================== --- trunk/src/librnd/hid/hid_init.c (nonexistent) +++ trunk/src/librnd/hid/hid_init.c (revision 34602) @@ -0,0 +1,1081 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 2004 harry eaton + * Copyright (C) 2016..2021 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include + +#include +#include +#include + +#ifdef __WIN32__ +#include +#endif + +#include + +#include + +#include +#include +#include + +/* for dlopen() and friends; will also solve all system-dependent includes + and provides a dl-compat layer on windows. Also solves the opendir related + includes. */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../../config.h" + +static const char *hid_init_cookie = "hidlib"; + + +int rnd_coord_t_size = sizeof(rnd_coord_t); + +const char *rnd_ver_str = RND_VER_STR; + +static const char *flt_any[] = {"*", "*.*", NULL}; + +const rnd_hid_fsd_filter_t rnd_hid_fsd_filter_any[] = { + { "all", NULL, flt_any }, + { NULL, NULL, NULL } +}; + +rnd_hid_t **rnd_hid_list = 0; +int rnd_hid_num_hids = 0; + +rnd_hid_t *rnd_render = NULL; +rnd_hid_t *rnd_exporter = NULL; + +int rnd_pixel_slop = 1; + +rnd_plugin_dir_t *rnd_plugin_dir_first = NULL, *rnd_plugin_dir_last = NULL; + +void rnd_hid_init() +{ + char *tmp; + + /* Setup a "nogui" default HID */ + rnd_render = rnd_gui = rnd_hid_nogui_get_hid(); + +#ifdef LIBRNDLIBDIR + /* librnd's own */ + tmp = LIBRNDLIBDIR RND_DIR_SEPARATOR_S "plugins" RND_DIR_SEPARATOR_S HOST; + rnd_plugin_add_dir(tmp); + + tmp = LIBRNDLIBDIR RND_DIR_SEPARATOR_S "plugins"; + rnd_plugin_add_dir(tmp); +#endif + + /* host app's */ +TODO("make this configurable - add to conf_prj_dsg_ignores avoid plugin injection") + tmp = rnd_concat(rnd_conf.rc.path.exec_prefix, RND_DIR_SEPARATOR_S, "lib", RND_DIR_SEPARATOR_S, rnd_app.package, RND_DIR_SEPARATOR_S, "plugins", RND_DIR_SEPARATOR_S, HOST, NULL); + rnd_plugin_add_dir(tmp); + free(tmp); + + tmp = rnd_concat(rnd_conf.rc.path.exec_prefix, RND_DIR_SEPARATOR_S, "lib", RND_DIR_SEPARATOR_S, rnd_app.package, RND_DIR_SEPARATOR_S, "plugins", NULL); + rnd_plugin_add_dir(tmp); + free(tmp); + + /* hardwired libdir, just in case exec-prefix goes wrong (e.g. linstall) */ + if (rnd_app.lib_dir != NULL) { + tmp = rnd_concat(rnd_app.lib_dir, RND_DIR_SEPARATOR_S, "plugins", RND_DIR_SEPARATOR_S, HOST, NULL); + rnd_plugin_add_dir(tmp); + free(tmp); + tmp = rnd_concat(rnd_app.lib_dir, RND_DIR_SEPARATOR_S, "plugins", NULL); + rnd_plugin_add_dir(tmp); + free(tmp); + } + + /* rnd_conf.rc.path.home is set by the conf_core immediately on startup */ + if ((rnd_conf.rc.path.home != NULL) && (rnd_app.dot_dir != NULL)) { + tmp = rnd_concat(rnd_conf.rc.path.home, RND_DIR_SEPARATOR_S, rnd_app.dot_dir, RND_DIR_SEPARATOR_S, "plugins", RND_DIR_SEPARATOR_S, HOST, NULL); + rnd_plugin_add_dir(tmp); + free(tmp); + + tmp = rnd_concat(rnd_conf.rc.path.home, RND_DIR_SEPARATOR_S, rnd_app.dot_dir, RND_DIR_SEPARATOR_S, "plugins", NULL); + rnd_plugin_add_dir(tmp); + free(tmp); + } + + tmp = rnd_concat("plugins", RND_DIR_SEPARATOR_S, HOST, NULL); + rnd_plugin_add_dir(tmp); + free(tmp); + + rnd_plugin_add_dir("plugins"); +} + +void rnd_hid_uninit(void) +{ + rnd_plugin_dir_t *pd, *next; + + if (rnd_hid_num_hids > 0) { + int i; + for (i = rnd_hid_num_hids-1; i >= 0; i--) { + if (rnd_hid_list[i]->uninit != NULL) + rnd_hid_list[i]->uninit(rnd_hid_list[i]); + } + } + + pup_uninit(&rnd_pup); + + rnd_export_uninit(); + + free(rnd_hid_list); + + for(pd = rnd_plugin_dir_first; pd != NULL; pd = next) { + next = pd->next; + free(pd->path); + free(pd); + } + rnd_plugin_dir_first = rnd_plugin_dir_last = NULL; +} + +void rnd_hid_register_hid(rnd_hid_t *hid) +{ + int i; + int sz = (rnd_hid_num_hids + 2) * sizeof(rnd_hid_t *); + + if (hid->struct_size != sizeof(rnd_hid_t)) { + fprintf(stderr, "Warning: hid \"%s\" has an incompatible ABI.\n", hid->name); + return; + } + + for (i = 0; i < rnd_hid_num_hids; i++) + if (hid == rnd_hid_list[i]) + return; + + rnd_hid_num_hids++; + if (rnd_hid_list) + rnd_hid_list = (rnd_hid_t **) realloc(rnd_hid_list, sz); + else + rnd_hid_list = (rnd_hid_t **) malloc(sz); + + rnd_hid_list[rnd_hid_num_hids - 1] = hid; + rnd_hid_list[rnd_hid_num_hids] = 0; +} + +void rnd_hid_remove_hid(rnd_hid_t *hid) +{ + int i; + + for (i = 0; i < rnd_hid_num_hids; i++) { + if (hid == rnd_hid_list[i]) { + rnd_hid_list[i] = rnd_hid_list[rnd_hid_num_hids - 1]; + rnd_hid_list[rnd_hid_num_hids - 1] = 0; + rnd_hid_num_hids--; + return; + } + } +} + +static void rnd_hid_load_gui_plugin(const char *plugname); + +void rnd_hid_do_all_gui_plugins(void *ctx, int (*cb)(void *ctx, const char *name, const char *dir, const char *fn)) +{ + char **dir; + gds_t tmp = {0}; + + if (rnd_conf.rc.verbose >= RND_MSG_INFO) + fprintf(stderr, " no HID preference; auto-loading all HID plugins available...\n"); + + for(dir = rnd_pup_paths; *dir != NULL; dir++) { + void *d = pup_open_dir(*dir); + const char *fn; + + if (d == NULL) continue; + + while((fn = pup_read_dir(d)) != NULL) { + if (strncmp(fn, "hid_", 4) == 0) { + char *s; + tmp.used = 0; + gds_append_str(&tmp, fn); + if (tmp.used < 4) + continue; + + /* accept *.pup only and truncate .pup from the end */ + s = tmp.array + tmp.used - 4; + if (strcmp(s, ".pup") != 0) + continue; + *s = '\0'; + if (cb(ctx, tmp.array, *dir, fn) != 0) + break; + } + } + + pup_close_dir(d); + } + gds_uninit(&tmp); +} + +static int load_all_gui_plugins_cb(void *ctx, const char *name, const char *dir, const char *fn) +{ + if (rnd_conf.rc.verbose >= RND_MSG_INFO) + fprintf(stderr, "-- all-hid-load: '%s' ('%s' from %s)\n", name, fn, dir); + rnd_hid_load_gui_plugin(name); + return 0; +} + +/* Load all hid_* plugins from all puplug search paths */ +static void rnd_hid_load_all_gui_plugins(void) +{ + rnd_hid_do_all_gui_plugins(NULL, load_all_gui_plugins_cb); +} + +static int list_gui_cb(void *ctx, const char *name, const char *dir, const char *fn) +{ + gds_t *tmp = ctx; + char *end, *line, buff[1024], *desc = ""; + FILE *f; + + tmp->used = 0; + gds_append_str(tmp, dir); + gds_append(tmp, RND_DIR_SEPARATOR_C); + gds_append_str(tmp, fn); + + f = rnd_fopen(NULL, tmp->array, "r"); + if (f != NULL) { + while((line = fgets(buff, sizeof(buff), f)) != NULL) { + while(isspace(*line)) line++; + if (strncmp(line, "$short", 6) == 0) { + desc = line + 6; + while(isspace(*desc)) desc++; + end = strpbrk(desc, "\r\n"); + if (end != NULL) + *end = '\0'; + break; + } + } + fclose(f); + } + + fprintf(stderr, "\t%-16s %s\n", name, desc); + return 0; +} + +void rnd_hid_print_all_gui_plugins(void) +{ + gds_t tmp = {0}; + const pup_buildin_t *b; + + rnd_hid_do_all_gui_plugins(&tmp, list_gui_cb); + + /* print buildins */ + for(b = pup_buildins; b->name != NULL; b++) + if (strncmp(b->name, "hid_", 4) == 0) + fprintf(stderr, "\t%-16s\n", b->name); + + gds_uninit(&tmp); +} + + +/* low level (pup) load a plugin if it is not already loaded; if plugname is + NULL, try to load all plugins */ +static void rnd_hid_load_gui_plugin(const char *plugname) +{ + int st; + + if (rnd_conf.rc.verbose >= RND_MSG_INFO) + fprintf(stderr, "GUI: want '%s'\n", plugname); + if (plugname == NULL) { + /* load all available GUI plugins; with a workaround: lesstif needs to be + loaded first because it is sensitive to link order of -lXm and -lXt; + if gtk or other X related GUI is loaded before, lesstif yields error */ + rnd_hid_load_gui_plugin("hid_lesstif"); + rnd_hid_load_all_gui_plugins(); + } + else { + char tmp[256]; + + /* prefix plugin name with hid_ */ + if ((plugname[0] != 'h') || strncmp(plugname, "hid_", 4) != 0) { + int l = strlen(plugname); + if (l > sizeof(tmp) - 8) { + fprintf(stderr, "rnd_hid_load_gui_plugin: plugin name too long: '%s'\n", plugname); + return; + } + strcpy(tmp, "hid_"); + memcpy(tmp+4, plugname, l+1); + plugname = tmp; + } + + /* do not load if already loaded */ + if (pup_lookup(&rnd_pup, plugname) != NULL) { + if (rnd_conf.rc.verbose >= RND_MSG_INFO) + fprintf(stderr, " already loaded %s\n", plugname); + return; + } + + /* load the plugin */ + if (rnd_conf.rc.verbose >= RND_MSG_INFO) + fprintf(stderr, " loading %s\n", plugname); + if (pup_load(&rnd_pup, (const char **)rnd_pup_paths, plugname, 0, &st) == NULL) { + if (rnd_conf.rc.verbose >= RND_MSG_INFO) + fprintf(stderr, " failed.\n"); + } + } +} + +rnd_hid_t *rnd_hid_find_gui(rnd_hidlib_t *hidlib, const char *preference) +{ + rnd_hid_t *gui; + int i; + + if (strncmp(preference, "hid_", 4) == 0) + preference += 4; + + /* ugly hack for historical reasons: some old configs and veteran users are used to the --gui gtk option */ + if ((preference != NULL) && (strcmp(preference, "gtk") == 0)) { + gui = rnd_hid_find_gui(hidlib, "gtk2_gl"); + if (gui != NULL) + return gui; + + gui = rnd_hid_find_gui(hidlib, "gtk2_gdk"); + if (gui != NULL) + return gui; + + gui = rnd_hid_find_gui(hidlib, "gtk4_gl"); + if (gui != NULL) + return gui; + + return NULL; + } + + rnd_hid_load_gui_plugin(preference); + + /* normal search */ + if (preference != NULL) { + for (i = 0; i < rnd_hid_num_hids; i++) { + if (!rnd_hid_list[i]->printer && !rnd_hid_list[i]->exporter && !strcmp(rnd_hid_list[i]->name, preference)) { + gui = rnd_hid_list[i]; + goto found; + } + } + return NULL; + } + + for (i = 0; i < rnd_hid_num_hids; i++) { + if (!rnd_hid_list[i]->printer && !rnd_hid_list[i]->exporter && !rnd_hid_list[i]->hide_from_gui) { + gui = rnd_hid_list[i]; + goto found; + } + } + + fprintf(stderr, "Error: No GUI available.\n"); + exit(1); + + found:; + if (gui->gui) { + char *fn = NULL; + int exact_fn = 0; + rnd_menu_patch_t *mp; + + if ((rnd_conf.rc.menu_file != NULL) && (*rnd_conf.rc.menu_file != '\0')) { + fn = rnd_strdup_printf(rnd_app.menu_name_fmt, rnd_conf.rc.menu_file); + exact_fn = (strchr(rnd_conf.rc.menu_file, '/') != NULL); + } + + mp = rnd_hid_menu_load(gui, hidlib, "librnd", 0, fn, exact_fn, rnd_app.default_embedded_menu, "base menu file"); + free(fn); + if (mp == NULL) { + fprintf(stderr, "Failed to load the menu file - can not start a GUI HID.\n"); + exit(1); + } + } + return gui; +} + +rnd_hid_t *rnd_hid_find_printer() +{ + int i; + + for (i = 0; i < rnd_hid_num_hids; i++) + if (rnd_hid_list[i]->printer) + return rnd_hid_list[i]; + + return 0; +} + +void rnd_hid_print_exporter_list(FILE *f, const char *prefix, const char *suffix) +{ + int i; + for (i = 0; i < rnd_hid_num_hids; i++) + if (rnd_hid_list[i]->exporter) + fprintf(f, "%s%s%s", prefix, rnd_hid_list[i]->name, suffix); +} + +rnd_hid_t *rnd_hid_find_exporter(const char *which) +{ + int i; + + if (which == NULL) { + fprintf(stderr, "Invalid exporter: need an exporter name, one of:"); + goto list; + } + + if (strcmp(which, "-list-") == 0) { + rnd_hid_print_exporter_list(stdout, "", "\n"); + return 0; + } + + for (i = 0; i < rnd_hid_num_hids; i++) + if (rnd_hid_list[i]->exporter && strcmp(which, rnd_hid_list[i]->name) == 0) + return rnd_hid_list[i]; + + fprintf(stderr, "Invalid exporter %s, available ones:", which); + + list:; + rnd_hid_print_exporter_list(stderr, " ", ""); + fprintf(stderr, "\n"); + + return 0; +} + +rnd_hid_t **rnd_hid_enumerate() +{ + return rnd_hid_list; +} + +const char *rnd_hid_export_fn(const char *filename) +{ + if (rnd_conf.rc.export_basename) { + const char *outfn = strrchr(filename, RND_DIR_SEPARATOR_C); + if (outfn == NULL) + return filename; + return outfn + 1; + } + else + return filename; +} + +extern void rnd_hid_dlg_uninit(void); +extern void rnd_hid_dlg_init(void); + +char *rnd_exec_prefix(char *argv0, const char *bin_dir, const char *bin_dir_to_execprefix) +{ + size_t l; + int haspath; + char *t1, *t2; + int found_bindir = 0; + char *exec_prefix = NULL; + char *bindir = NULL; + + + /* see if argv0 has enough of a path to let lrealpath give the + real path. This should be the case if you invoke pcb with + something like /usr/local/bin/pcb or ./pcb or ./foo/pcb + but if you just use pcb and it exists in your path, you'll + just get back pcb again. */ + haspath = (strchr(argv0, RND_DIR_SEPARATOR_C) != NULL); + +#ifdef DEBUG + printf("rnd_exec_prefix (%s): haspath = %d\n", argv0, haspath); +#endif + + if (haspath) { + bindir = rnd_lrealpath(argv0); + if (bindir == NULL) + bindir = rnd_strdup(argv0); + found_bindir = 1; + } + else { + char *path, *p, *tmps; + struct stat sb; + int r; + + tmps = getenv("PATH"); + + if (tmps != NULL) { + path = rnd_strdup(tmps); + + /* search through the font path for a font file */ + for (p = strtok(path, RND_PATH_DELIMETER); p && *p; p = strtok(NULL, RND_PATH_DELIMETER)) { +#ifdef DEBUG + printf("Looking for %s in %s\n", argv0, p); +#endif + if ((tmps = (char *) malloc((strlen(argv0) + strlen(p) + 2) * sizeof(char))) == NULL) { + fprintf(stderr, "rnd_exec_prefix(): malloc failed\n"); + exit(1); + } + sprintf(tmps, "%s%s%s", p, RND_DIR_SEPARATOR_S, argv0); + r = stat(tmps, &sb); + if (r == 0) { +#ifdef DEBUG + printf("Found it: \"%s\"\n", tmps); +#endif + bindir = rnd_lrealpath(tmps); + if (bindir == NULL) + bindir = rnd_strdup(tmps); + found_bindir = 1; + free(tmps); + break; + } + free(tmps); + } + free(path); + } + } + + if (found_bindir) { + /* strip off the executable name leaving only the path */ + t2 = NULL; + t1 = strchr(bindir, RND_DIR_SEPARATOR_C); + while (t1 != NULL && *t1 != '\0') { + t2 = t1; + t1 = strchr(t2 + 1, RND_DIR_SEPARATOR_C); + } + if (t2 != NULL) + *t2 = '\0'; + } + else { + /* we have failed to find out anything from argv[0] so fall back to the original install prefix */ + bindir = rnd_strdup(bin_dir); + } + + /* now find the path to exec_prefix */ + l = strlen(bindir) + 1 + strlen(bin_dir_to_execprefix) + 1; + if ((exec_prefix = (char *) malloc(l * sizeof(char))) == NULL) { + fprintf(stderr, "rnd_exec_prefix(): malloc failed\n"); + exit(1); + } + sprintf(exec_prefix, "%s%s%s", bindir, RND_DIR_SEPARATOR_S, bin_dir_to_execprefix); + free(bindir); + return exec_prefix; +} + +static void hidlib_gui_init_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + rnd_tool_gui_init(); + rnd_gui->set_mouse_cursor(rnd_gui, rnd_conf.editor.mode); /* make sure the mouse cursor is set up now that it is registered */ +} + +static void rnd_hid_init_init(void) +{ + rnd_event_bind(RND_EVENT_GUI_INIT, hidlib_gui_init_ev, NULL, hid_init_cookie); +} + +static void rnd_hid_init_uninit(void) +{ + rnd_event_unbind_allcookie(hid_init_cookie); +} + + +extern void rnd_menu_init1(void); + +void rnd_hidlib_init1(void (*conf_core_init)(void)) +{ + rnd_events_init(); + rnd_file_loaded_init(); + rnd_conf_init(); + conf_core_init(); + rnd_pcbhl_conf_postproc(); + rnd_hidlib_conf_init(); + rnd_hid_init_init(); + rnd_hid_dlg_init(); + rnd_hid_init(); + rnd_grid_init(); + rnd_color_init(); + rnd_menu_init1(); +} + +static vts0_t hidlib_conffile; + +extern void rnd_hidlib_error_init2(void); +extern void rnd_hid_dlg_init2(void); +extern void rnd_hid_nogui_init2(void); +extern void rnd_conf_act_init2(void); +extern void rnd_hid_act_init2(void); +extern void rnd_tool_act_init2(void); +extern void rnd_main_act_init2(void); +extern void rnd_menu_act_init2(void); +extern void rnd_anyload_init2(void); +extern void rnd_anyload_act_init2(void); +extern void rnd_conf_init2(void); + +void rnd_hidlib_init2(const pup_buildin_t *buildins, const pup_buildin_t *local_buildins) +{ + rnd_actions_init(); + + /* load custom config files in the order they were specified */ + if (hidlib_conffile.used > 0) { + int n; + for(n = 0; n < hidlib_conffile.used; n++) { + rnd_conf_role_t role = RND_CFR_CLI; + char *srole, *sep, *fn = hidlib_conffile.array[n]; + sep = strchr(fn, ';'); + if (sep != NULL) { + srole = fn; + *sep = '\0'; + fn = sep+1; + role = rnd_conf_role_parse(srole); + if (role == RND_CFR_invalid) { + fprintf(stderr, "Can't load -C config file '%s': invalid role '%s'\n", fn, srole); + free(hidlib_conffile.array[n]); + continue; + } + } + rnd_conf_load_as(role, fn, 0); + free(hidlib_conffile.array[n]); + } + vts0_uninit(&hidlib_conffile); + } + + rnd_conf_load_all(NULL, NULL); + + pup_init(&rnd_pup); + rnd_pup.error_stack_enable = 1; + + /* core actions */ + rnd_hidlib_error_init2(); + rnd_hid_dlg_init2(); + rnd_hid_nogui_init2(); + rnd_conf_act_init2(); + rnd_hid_act_init2(); + rnd_tool_act_init2(); + rnd_main_act_init2(); + rnd_menu_act_init2(); + rnd_conf_init2(); + + /* plugins: buildins */ + pup_buildin_load(&rnd_pup, buildins); + if (local_buildins != NULL) + pup_buildin_load(&rnd_pup, local_buildins); + pup_autoload_dir(&rnd_pup, NULL, NULL); + + rnd_conf_load_extra(NULL, NULL); + rnd_units_init(); + rnd_funchash_init(); + rnd_anyload_act_init2(); + + rnd_anyload_init2(); /* must be at the end because any init2() may register an anyload */ +} + +static void print_pup_err(pup_err_stack_t *entry, char *string) +{ + rnd_message(RND_MSG_ERROR, "puplug: %s\n", string); +} + +void rnd_hidlib_init3_auto(void) +{ + char **sp; + + if (rnd_pup.err_stack != NULL) { + rnd_message(RND_MSG_ERROR, "Some of the static linked buildins could not be loaded:\n"); + pup_err_stack_process_str(&rnd_pup, print_pup_err); + } + + for(sp = rnd_pup_paths; *sp != NULL; sp++) { + rnd_message(RND_MSG_DEBUG, "Loading plugins from '%s'\n", *sp); + pup_autoload_dir(&rnd_pup, *sp, (const char **)rnd_pup_paths); + } + + if (rnd_pup.err_stack != NULL) { + rnd_message(RND_MSG_ERROR, "Some of the dynamic linked plugins could not be loaded:\n"); + pup_err_stack_process_str(&rnd_pup, print_pup_err); + } +} + + +extern void rnd_menu_uninit(void); +extern void rnd_anyload_uninit(void); +extern void rnd_hid_cfg_keys_uninit_module(void); + + +void rnd_hidlib_uninit(void) +{ + rnd_hid_menu_merge_inhibit_inc(); /* make sure no menu merging happens during the uninitialization */ + rnd_grid_uninit(); + rnd_menu_uninit(); + rnd_hid_init_uninit(); + rnd_hid_dlg_uninit(); + + if (rnd_conf_isdirty(RND_CFR_USER)) + rnd_conf_save_file(NULL, NULL, NULL, RND_CFR_USER, NULL); + + rnd_hid_uninit(); + rnd_conf_uninit(); + rnd_plugin_uninit(); + rnd_actions_uninit(); + rnd_dad_unit_uninit(); + rnd_hid_cfg_keys_uninit_module(); + rnd_anyload_uninit(); + rnd_events_uninit(); +} + +/* parse arguments using the gui; if fails and fallback is enabled, try the next gui */ +int rnd_gui_parse_arguments(int autopick_gui, int *hid_argc, char **hid_argv[]) +{ + rnd_conf_listitem_t *apg = NULL; + + if ((autopick_gui >= 0) && (rnd_conf.rc.hid_fallback)) { /* start from the GUI we are initializing first */ + int n; + const char *g; + + rnd_conf_loop_list_str(&rnd_conf.rc.preferred_gui, apg, g, n) { + if (n == autopick_gui) + break; + } + } + + for(;;) { + int res; + if (rnd_gui->get_export_options != NULL) + rnd_gui->get_export_options(rnd_gui, NULL); + res = rnd_gui->parse_arguments(rnd_gui, hid_argc, hid_argv); + if (res == 0) + break; /* HID accepted, don't try anything else */ + if (res < 0) { + rnd_message(RND_MSG_ERROR, "Failed to initialize HID %s (unrecoverable, have to give up)\n", rnd_gui->name); + return -1; + } + fprintf(stderr, "Failed to initialize HID %s (recoverable)\n", rnd_gui->name); + if (apg == NULL) { + if (rnd_conf.rc.hid_fallback) { + ran_out_of_hids:; + rnd_message(RND_MSG_ERROR, "Tried all available HIDs, all failed, giving up.\n"); + } + else + rnd_message(RND_MSG_ERROR, "Not trying any other hid as fallback because rc/hid_fallback is disabled.\n"); + return -1; + } + + /* falling back to the next HID */ + do { + int n; + const char *g; + + apg = rnd_conf_list_next_str(apg, &g, &n); + if (apg == NULL) + goto ran_out_of_hids; + rnd_render = rnd_gui = rnd_hid_find_gui(NULL, g); + } while(rnd_gui == NULL); + } + return 0; +} + +#ifdef __WIN32__ +/* truncate the last dir segment; returns remaining length or 0 on failure */ +static int truncdir(char *dir) +{ + char *s; + + for(s = dir + strlen(dir) - 1; s >= dir; s--) { + if ((*s == '/') || (*s == '\\')) { + *s = '\0'; + return s - dir; + } + } + *dir = '\0'; + return 0; +} +extern int rnd_mkdir_(const char *path, int mode); +char *rnd_w32_root; +char *rnd_w32_libdir, *rnd_w32_bindir, *rnd_w32_sharedir, *rnd_w32_cachedir; +#endif + +void rnd_fix_locale_and_env_() +{ + static const char *lcs[] = { "LANG", "LC_NUMERIC", "LC_ALL", NULL }; + const char **lc; + + /* some Xlib calls tend ot hardwire setenv() to "" or NULL so a simple + setlocale() won't do the trick on GUI. Also set all related env var + to "C" so a setlocale(LC_ALL, "") will also do the right thing. */ + for(lc = lcs; *lc != NULL; lc++) + rnd_setenv(*lc, "C", 1); + + setlocale(LC_ALL, "C"); + + +#ifdef __WIN32__ + { + char *s, exedir[MAX_PATH]; + wchar_t *w, wexedir[MAX_PATH]; + + if (!GetModuleFileNameW(NULL, wexedir, MAX_PATH)) { + fprintf(stderr, "%s: GetModuleFileNameW(): failed to determine executable full path\n", rnd_app.package); + exit(1); + } + + for(w = wexedir, s = exedir; *w != 0; w++) + s += wctomb(s, *w); + *s = '\0'; + + truncdir(exedir); + + for(s = exedir; *s != '\0'; s++) + if (*s == '\\') + *s = '/'; + + rnd_w32_bindir = rnd_strdup(exedir); + truncdir(exedir); + rnd_w32_root = rnd_strdup(exedir); + rnd_w32_libdir = rnd_concat(exedir, "/lib/pcb-rnd", NULL); + rnd_w32_sharedir = rnd_concat(exedir, "/share/pcb-rnd", NULL); + + rnd_w32_cachedir = rnd_concat(rnd_w32_root, "/cache", NULL); + rnd_mkdir_(rnd_w32_cachedir, 0755); + +/* printf("WIN32 root='%s' libdir='%s' sharedir='%s'\n", rnd_w32_root, rnd_w32_libdir, rnd_w32_sharedir);*/ + } +#endif +} + +static int rnd_pcbhl_main_arg_match(const char *in, const char *shrt, const char *lng) +{ + return ((shrt != NULL) && (strcmp(in, shrt) == 0)) || ((lng != NULL) && (strcmp(in, lng) == 0)); +} + +void rnd_main_args_init(rnd_main_args_t *ga, int argc, const char **action_args) +{ + memset(ga, 0, sizeof(rnd_main_args_t)); + ga->hid_argv_orig = ga->hid_argv = calloc(sizeof(char *), argc); + vtp0_init(&ga->plugin_cli_conf); + ga->action_args = action_args; + ga->autopick_gui = -1; +} + +void rnd_main_args_uninit(rnd_main_args_t *ga) +{ + vtp0_uninit(&ga->plugin_cli_conf); + free(ga->hid_argv_orig); +} + +int rnd_main_args_add(rnd_main_args_t *ga, char *cmd, char *arg) +{ + const char **cs; + char *orig_cmd = cmd; + + if (*cmd == '-') { + cmd++; + if ((strcmp(cmd, "?") == 0) || (strcmp(cmd, "h") == 0) || (strcmp(cmd, "-help") == 0)) { + if (arg != NULL) { + /* memory leak, but who cares for --help? */ + ga->main_action = rnd_strdup_printf("PrintUsage(%s)", arg); + return 1; + } + ga->main_action = "PrintUsage()"; + return 0; + } + + if ((strcmp(cmd, "g") == 0) || (strcmp(cmd, "-gui") == 0) || (strcmp(cmd, "-hid") == 0)) { + ga->do_what = RND_DO_GUI; + ga->hid_name = arg; + return 1; + } + if ((strcmp(cmd, "x") == 0) || (strcmp(cmd, "-export") == 0)) { + ga->do_what = RND_DO_EXPORT; + ga->hid_name = arg; + return 1; + } + if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "-print") == 0)) { + ga->do_what = RND_DO_PRINT; + return 0; + } + + for(cs = ga->action_args; cs[2] != NULL; cs += RND_ACTION_ARGS_WIDTH) { + if (rnd_pcbhl_main_arg_match(cmd, cs[0], cs[1])) { + if (ga->main_action == NULL) { + ga->main_action = cs[2]; + ga->main_action_hint = cs[4]; + } + else + fprintf(stderr, "Warning: can't execute multiple command line actions, ignoring %s\n", orig_cmd); + return 0; + } + } + if (rnd_pcbhl_main_arg_match(cmd, "c", "-conf")) { + const char *why; + if (strncmp(arg, "plugins/", 8) == 0) { + /* plugins are not yet loaded or initialized so their configs are + unavailable. Store these settings until plugins are up. This + should not happen to non-plugin config items as those might + affect how plugins are searched/loaded. */ + const void **a = (const void **)vtp0_alloc_append(&ga->plugin_cli_conf, 1); + *a = arg; + } + else { + if (rnd_conf_set_from_cli(NULL, arg, NULL, &why) != 0) { + fprintf(stderr, "Error: failed to set config %s: %s\n", arg, why); + exit(1); + } + } + return 1; + } + if (rnd_pcbhl_main_arg_match(cmd, "C", "-conffile")) { + vts0_append(&hidlib_conffile, rnd_strdup(arg)); + return 1; + } + } + /* didn't handle argument, save it for the HID */ + ga->hid_argv[ga->hid_argc++] = orig_cmd; + return 0; +} + +static int apply_plugin_cli_conf(rnd_main_args_t *ga, int relax) +{ + int n; + for(n = 0; n < vtp0_len(&ga->plugin_cli_conf); n++) { + const char *why, *arg = ga->plugin_cli_conf.array[n]; + + if (ga->plugin_cli_conf.array[n] == NULL) continue; + + if (rnd_conf_set_from_cli(NULL, arg, NULL, &why) != 0) { + if (!relax) { + fprintf(stderr, "Error: failed to set config %s: %s\n", arg, why); + return 1; + } + } + else + ga->plugin_cli_conf.array[n] = NULL; /* remove if succesfully set so it won't be set again on multiple calls at different stages */ + } + return 0; +} + +int rnd_main_args_setup1(rnd_main_args_t *ga) +{ + /* Now that plugins are already initialized, apply plugin config items; + non-existing ones are not fatal as the GUI plugin is not yet loaded */ + apply_plugin_cli_conf(ga, 1); + + /* Export pcb from command line if requested. */ + switch(ga->do_what) { + case RND_DO_PRINT: rnd_render = rnd_exporter = rnd_gui = rnd_hid_find_printer(); break; + case RND_DO_EXPORT: rnd_render = rnd_exporter = rnd_gui = rnd_hid_find_exporter(ga->hid_name); break; + case RND_DO_GUI: + rnd_render = rnd_gui = rnd_hid_find_gui(NULL, ga->hid_name); + if (rnd_gui == NULL) { + rnd_message(RND_MSG_ERROR, "Can't find the gui (%s) requested.\n", ga->hid_name); + return 1; + } + break; + default: { + const char *g; + rnd_conf_listitem_t *i; + + rnd_render = rnd_gui = NULL; + rnd_conf_loop_list_str(&rnd_conf.rc.preferred_gui, i, g, ga->autopick_gui) { + rnd_render = rnd_gui = rnd_hid_find_gui(NULL, g); + if (rnd_gui != NULL) + break; + } + + /* try anything */ + if (rnd_gui == NULL) { + rnd_message(RND_MSG_WARNING, "Warning: can't find any of the preferred GUIs, falling back to anything available...\nYou may want to check if the plugin is loaded, try --dump-plugins and --dump-plugindirs\n"); + rnd_render = rnd_gui = rnd_hid_find_gui(NULL, NULL); + } + } + } + + /* Exit with error if GUI failed to start. */ + if (!rnd_gui) + return 1; + + /* Now that even the GUI plugin is initialized, apply remaining plugin config + items; non-existing ones are fatal */ + if (apply_plugin_cli_conf(ga, 0) != 0) + return 1; + + vtp0_uninit(&ga->plugin_cli_conf); + + return 0; +} + +int rnd_main_args_setup2(rnd_main_args_t *ga, int *exitval) +{ + *exitval = 0; + + /* plugins may have installed their new fields, reinterpret the config + (memory lht -> memory bin) to get the new fields */ + rnd_conf_update(NULL, -1); + + if (ga->main_action != NULL) { + int res = rnd_parse_command(NULL, ga->main_action, rnd_true); /* hidlib is NULL because there is no context yet */ + if ((res != 0) && (ga->main_action_hint != NULL)) + rnd_message(RND_MSG_ERROR, "\nHint: %s\n", ga->main_action_hint); + rnd_log_print_uninit_errs("main_action parse error"); + *exitval = res; + return 1; + } + + + if (rnd_gui_parse_arguments(ga->autopick_gui, &ga->hid_argc, &ga->hid_argv) != 0) { + rnd_log_print_uninit_errs("Export plugin argument parse error"); + return 1; + } + + return 0; +} + +int rnd_main_exported(rnd_main_args_t *ga, rnd_hidlib_t *hidlib, rnd_bool is_empty) +{ + if (!rnd_main_exporting) + return 0; + + if (is_empty) + rnd_message(RND_MSG_WARNING, "Exporting empty design (nothing loaded or drawn).\n"); + if (rnd_gui->set_hidlib != NULL) + rnd_gui->set_hidlib(rnd_gui, hidlib); + rnd_event(hidlib, RND_EVENT_EXPORT_SESSION_BEGIN, NULL); + rnd_gui->do_export(rnd_gui, 0); + rnd_event(hidlib, RND_EVENT_EXPORT_SESSION_END, NULL); + rnd_log_print_uninit_errs("Exporting"); + return 1; +} + +void rnd_mainloop_interactive(rnd_main_args_t *ga, rnd_hidlib_t *hidlib) +{ + rnd_hid_in_main_loop = 1; + rnd_event(hidlib, RND_EVENT_MAINLOOP_CHANGE, "i", rnd_hid_in_main_loop); + if (rnd_gui->set_hidlib != NULL) + rnd_gui->set_hidlib(rnd_gui, hidlib); + rnd_gui->do_export(rnd_gui, 0); + rnd_hid_in_main_loop = 0; + rnd_event(hidlib, RND_EVENT_MAINLOOP_CHANGE, "i", rnd_hid_in_main_loop); +} + Index: trunk/src/librnd/hid/hid_init.h =================================================================== --- trunk/src/librnd/hid/hid_init.h (nonexistent) +++ trunk/src/librnd/hid/hid_init.h (revision 34602) @@ -0,0 +1,200 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 2004 harry eaton + * Copyright (C) 2016..2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#ifndef RND_HID_INIT_H +#define RND_HID_INIT_H + +#include +#include +#include +#include + +#define RND_ACTION_ARGS_WIDTH 5 + +/* NULL terminated list of all static HID structures. Built by + hid_register_hid, used by hid_find_*() and rnd_hid_enumerate(). The + order in this list is the same as the order of hid_register_hid + calls. */ +extern rnd_hid_t **rnd_hid_list; + +/* Count of entries in the above. */ +extern int rnd_hid_num_hids; + +/* RND_VER_STR compiled into the binary so apps can print it */ +extern const char *rnd_ver_str; + +/* Call this as soon as possible from main(). No other HID calls are + valid until this is called. */ +void rnd_hid_init(void); + +/* Call this at exit */ +void rnd_hid_uninit(void); + +/* When the application runs in interactive mode, this is called to instantiate + one GUI HID which happens to be the GUI. This HID is the one that + interacts with the mouse and keyboard. */ +rnd_hid_t *rnd_hid_find_gui(rnd_hidlib_t *hidlib, const char *preference); + +/* Finds the one printer HID and instantiates it. */ +rnd_hid_t *rnd_hid_find_printer(void); + +/* Finds the indicated exporter HID and instantiates it. */ +rnd_hid_t *rnd_hid_find_exporter(const char *); + +/* This returns a NULL-terminated array of available HIDs. The only + real reason to use this is to locate all the export-style HIDs. */ +rnd_hid_t **rnd_hid_enumerate(void); + +/* HID internal interfaces. These may ONLY be called from the HID + modules, not from the common application code. */ + +/* A HID may use this if it does not need command line arguments in + any special format; for example, the Lesstif HID needs to use the + Xt parser, but the Postscript HID can use this function. */ +int rnd_hid_parse_command_line(int *argc, char ***argv); + +/* Called by the init funcs, used to set up rnd_hid_list. */ +extern void rnd_hid_register_hid(rnd_hid_t *hid); +void rnd_hid_remove_hid(rnd_hid_t *hid); + +typedef struct rnd_plugin_dir_s rnd_plugin_dir_t; +struct rnd_plugin_dir_s { + char *path; + int num_plugins; + rnd_plugin_dir_t *next; +}; + +extern rnd_plugin_dir_t *rnd_plugin_dir_first, *rnd_plugin_dir_last; + +/* Safe file name for inclusion in export file comments/headers; if the + user requested in the config, this becomes the basename of filename, + else it is the full file name */ +const char *rnd_hid_export_fn(const char *filename); + + +/*** main(), initialize ***/ + +typedef struct { + enum { + RND_DO_SOMETHING, + RND_DO_PRINT, + RND_DO_EXPORT, + RND_DO_GUI + } do_what; + int hid_argc; + const char *main_action, *main_action_hint; + vtp0_t plugin_cli_conf; + char **hid_argv_orig, **hid_argv; + const char *hid_name; + const char **action_args; + int autopick_gui; + + /* Spare: see doc/developer/spare.txt */ + void (*spare_f1)(void), (*spare_f2)(void); + long spare_l1, spare_l2, spare_l3, spare_l4; + void *spare_p1, *spare_p2, *spare_p3, *spare_p4; + double spare_d1, spare_d2, spare_d3, spare_d4; + rnd_coord_t spare_c1, spare_c2, spare_c3, spare_c4; +} rnd_main_args_t; + +/* call this before anything, to switch locale to "C" permanently; + also sets up the environment on win32. */ +#define rnd_fix_locale_and_env() do { rnd_init_macro_checks(); rnd_fix_locale_and_env_(); } while(0) + +/* This is called by the macro, do not call this directly */ +void rnd_fix_locale_and_env_(); + +/* Figure out the canonical name of the executed program + and return malloc'ed exec prefix that should be saved in the config + bin_dir is the full installation path of the bin dir, e.g. "/usr/local/bin" + bin_dir_to_execprefix is relative path between the two, typically ".." + */ +char *rnd_exec_prefix(char *argv0, const char *bin_dir, const char *bin_dir_to_execprefix); + +void rnd_hidlib_init1(void (*conf_core_init)(void)); /* before CLI argument parsing; conf_core_init should conf_reg() at least the hidlib related nodes */ +void rnd_hidlib_init2(const pup_buildin_t *buildins, const pup_buildin_t *local_buildins); /* after CLI argument parsing */ +void rnd_hidlib_init3_auto(void); +void rnd_hidlib_uninit(void); + +/* optional: hidlib aspects of main() */ +void rnd_main_args_init(rnd_main_args_t *ga, int argc, const char **action_args); +void rnd_main_args_uninit(rnd_main_args_t *ga); + +/* Parse the next argument using the next two argv[]s. Returns 0 if arg is + not consumed, 1 if consimed. */ +int rnd_main_args_add(rnd_main_args_t *ga, char *cmd, char *arg); + +/* returns non-zero on error (the application should exit); exitval is the + desired exit value of the executable when setup2 fails. */ +int rnd_main_args_setup1(rnd_main_args_t *ga); +int rnd_main_args_setup2(rnd_main_args_t *ga, int *exitval); + +/* if -x was specified, do the export and return 1 (the caller should + exit); else return 0 */ +int rnd_main_exported(rnd_main_args_t *ga, rnd_hidlib_t *hidlib, rnd_bool is_empty); + +/* launches the GUI or CLI; after it returns, if rnd_gui is not NULL, the user + has selected another GUI to switch to. */ +void rnd_mainloop_interactive(rnd_main_args_t *ga, rnd_hidlib_t *hidlib); + +/* parse arguments using the gui; if fails and fallback is enabled, try the next gui */ +int rnd_gui_parse_arguments(int autopick_gui, int *hid_argc, char **hid_argv[]); + +/* true if main() is called for printing or exporting (no interactive HID + shall be invoked) */ +#define rnd_main_exporting (rnd_gui->printer || rnd_gui->exporter) + +#ifdef __WIN32__ +extern char *rnd_w32_root; /* installation prefix; what would be $PREFIX on FHS, e.g. /usr/local */ +extern char *rnd_w32_libdir; /* on FHS this would be $PREFIX/lib*/ +extern char *rnd_w32_bindir; /* on FHS this would be $PREFIX/bin - on win32 this also hosts the dlls */ +extern char *rnd_w32_sharedir; /* on FHS this would be $PREFIX/share */ +extern char *rnd_w32_cachedir; /* where to store cache files, e.g. gdk pixbuf loader cache; persistent, but not part of the distribution */ +#endif + +/* Runtime checks that need to be compiled into the host application. Do not + use this directly. Invoked by rnd_fix_locale_and_env(). */ +#define rnd_init_macro_checks() \ + if (sizeof(rnd_coord_t) != rnd_coord_t_size) { \ + fprintf(stderr, "rnd_init_macro_checks: rnd_coord_t size mismatch between librnd and the host app; please recompile the host app\n"); \ + exit(1); \ + } + +extern int rnd_coord_t_size; + +/* Search all GUI plugins (even if they are not loaded) and call cb() + on them. If cb returns non-zero, cancel the search. */ +void rnd_hid_do_all_gui_plugins(void *ctx, int (*cb)(void *ctx, const char *name, const char *dir, const char *fn)); + +/* Print all GUI plugins available (not necessarily loaded) to stderr */ +void rnd_hid_print_all_gui_plugins(void); + + +#endif Index: trunk/src/librnd/hid/hid_inlines.h =================================================================== --- trunk/src/librnd/hid/hid_inlines.h (nonexistent) +++ trunk/src/librnd/hid/hid_inlines.h (revision 34602) @@ -0,0 +1,99 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef RND_HID_INLINES +#define RND_HID_INLINES + +#include +#include + +RND_INLINE rnd_hid_gc_t rnd_hid_make_gc(void) +{ + rnd_hid_gc_t res; + rnd_core_gc_t *hc; + res = rnd_render->make_gc(rnd_gui); + hc = (rnd_core_gc_t *)res; /* assumes first field is rnd_core_gc_t */ + hc->width = RND_MAX_COORD; + hc->cap = rnd_cap_invalid; + hc->xor = 0; + hc->faded = 0; + hc->hid = rnd_gui; + return res; +} + +RND_INLINE void rnd_hid_destroy_gc(rnd_hid_gc_t gc) +{ + rnd_render->destroy_gc(gc); +} + +RND_INLINE void rnd_hid_set_line_cap(rnd_hid_gc_t gc, rnd_cap_style_t style) +{ + rnd_core_gc_t *hc = (rnd_core_gc_t *)gc; + if (hc->cap != style) { + hc->cap = style; + rnd_render->set_line_cap(gc, style); + } +} + +RND_INLINE void rnd_hid_set_line_width(rnd_hid_gc_t gc, rnd_coord_t width) +{ + rnd_core_gc_t *hc = (rnd_core_gc_t *)gc; + if (hc->width != width) { + hc->width = width; + rnd_render->set_line_width(gc, width); + } +} + +RND_INLINE void rnd_hid_set_draw_xor(rnd_hid_gc_t gc, int xor) +{ + rnd_core_gc_t *hc = (rnd_core_gc_t *)gc; + if (hc->xor != xor) { + hc->xor = xor; + rnd_render->set_draw_xor(gc, xor); + } +} + +RND_INLINE void rnd_hid_set_draw_faded(rnd_hid_gc_t gc, int faded) +{ + rnd_core_gc_t *hc = (rnd_core_gc_t *)gc; + if (hc->faded != faded) { + hc->faded = faded; + rnd_render->set_draw_faded(gc, faded); + } +} + +RND_INLINE const char *rnd_hid_command_entry(const char *ovr, int *cursor) +{ + if ((rnd_gui == NULL) || (rnd_gui->command_entry == NULL)) { + if (cursor != NULL) + *cursor = -1; + return NULL; + } + return rnd_gui->command_entry(rnd_gui, ovr, cursor); +} + + +#endif Index: trunk/src/librnd/hid/hid_menu.c =================================================================== --- trunk/src/librnd/hid/hid_menu.c (nonexistent) +++ trunk/src/librnd/hid/hid_menu.c (revision 34602) @@ -0,0 +1,1477 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,2020,2021 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* menu file loading, menu merging: all files are loaded into the memory + where the final lihata document that represents the menu is merged; + then the new version is compared to the old version and differneces + applied to the menu system */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hid_menu.h" + +lht_node_t ins_as_first, *rnd_hid_menu_ins_as_first = &ins_as_first; + +static const char menu_cookie[] = "librnd/hid_menu"; +static const char menu_cookie_al[] = "librnd/hid_menu/anyload"; +static rnd_conf_hid_id_t menu_conf_id; + + +/*** load & merge ***/ + +rnd_menu_sys_t rnd_menu_sys; +static long next_menu_uid; + +void rnd_menu_sys_init(rnd_menu_sys_t *msys) +{ + memset(msys, 0, sizeof(rnd_menu_sys_t)); +} + +static void rnd_menu_sys_insert(rnd_menu_sys_t *msys, rnd_menu_patch_t *menu) +{ + int n; + rnd_menu_patch_t *m; + + menu->uid = next_menu_uid++; + + /* assume only a dozen of patch files -> linear search is good enough for now */ + for(n = 0; n < msys->patches.used; n++) { + m = msys->patches.array[n]; + if (m->prio > menu->prio) { + vtp0_insert_len(&msys->patches, n, (void **)&menu, 1); + msys->changes++; + return; + } + } + vtp0_append(&msys->patches, menu); + msys->changes++; +} + +static void menu_sys_remove(rnd_menu_sys_t *msys, int n, rnd_menu_patch_t *m) +{ + vtp0_remove(&msys->patches, n, 1); + lht_dom_uninit(m->cfg.doc); + free(m->cookie); + free(m->desc); + free(m); + msys->changes++; +} + +static void rnd_menu_sys_remove(rnd_menu_sys_t *msys, rnd_menu_patch_t *mp) +{ + int n; + + /* assume only a dozen of patch files -> linear search is good enough for now */ + for(n = 0; n < msys->patches.used; n++) { + rnd_menu_patch_t *m = msys->patches.array[n]; + if (mp == m) { + menu_sys_remove(msys, n, m); + n--; + } + } +} + +static void rnd_menu_sys_remove_cookie(rnd_menu_sys_t *msys, const char *cookie) +{ + int n; + + /* assume only a dozen of patch files -> linear search is good enough for now */ + for(n = 0; n < msys->patches.used; n++) { + rnd_menu_patch_t *m = msys->patches.array[n]; + if (strcmp(m->cookie, cookie) == 0) { + menu_sys_remove(msys, n, m); + n--; + } + } +} + +static rnd_menu_patch_t *rnd_menu_sys_find_cookie(rnd_menu_sys_t *msys, const char *cookie) +{ + int n; + + for(n = 0; n < msys->patches.used; n++) { + rnd_menu_patch_t *m = msys->patches.array[n]; + if (strcmp(m->cookie, cookie) == 0) + return m; + } + + return NULL; +} + +static lht_node_t *search_list_for_node(lht_node_t *list, lht_node_t *target) +{ + lht_node_t *n; + lht_dom_iterator_t it; + + for(n = lht_dom_first(&it, list); n != NULL; n = lht_dom_next(&it)) + if (strcmp(n->name, target->name) == 0) { + if ((n->type == LHT_TEXT) && (target->type == LHT_TEXT)) { /* text nodes are normally anonymous and the have to be compared by value */ + if (strcmp(n->data.text.value, target->data.text.value) == 0) + return n; + } + else + return n; + } + return NULL; +} + +#define submenu(node) ((node->type == LHT_HASH) ? (lht_dom_hash_get((node), "submenu")) : NULL) + +static void lht_tree_merge_list_submenu(lht_node_t *dst, lht_node_t *src, lht_err_t recurse(lht_node_t *, lht_node_t *)) +{ + lht_dom_iterator_t it; + lht_node_t *s, *a; + + for(s = lht_dom_first(&it, src); s != NULL; s = lht_dom_next(&it)) { + a = search_list_for_node(dst, s); + if (a == NULL) { /* append new items at the end */ + lht_tree_detach(s); /* removing an item from the list from the iterator is a special case that works since r584 */ + lht_dom_list_append(dst, s); + } + else { + lht_tree_detach(s); /* removing an item from the list from the iterator is a special case that works since r584 */ + recurse(a, s); + } + } +} + +static lht_err_t lht_tree_merge_list_submenu_prop(lht_node_t *dst, lht_node_t *src) +{ + lht_node_t *parent = dst->parent; + assert(parent->type == LHT_HASH); + lht_tree_del(dst); + lht_tree_detach(src); + lht_dom_hash_put(parent, src); + return LHTE_SUCCESS; +} + +static lht_err_t menu_tree_merge_hash(lht_node_t *dst, lht_node_t *src, lht_err_t recurse(lht_node_t *, lht_node_t *)) +{ + lht_dom_iterator_t it; + lht_node_t *d, *ssub, *dsub; + + /* menu special casing: submenus don't mix with plain menus */ + ssub = lht_dom_hash_get(src, "submenu"); + dsub = lht_dom_hash_get(dst, "submenu"); + if ((dsub == NULL) && (ssub != NULL)) { + /* overwrite plain menu with submenu */ + for(d = lht_dom_first(&it, dst); d != NULL; d = lht_dom_next(&it)) + lht_tree_del(d); + } + else if ((dsub != NULL) && (ssub == NULL)) + lht_tree_del(dsub); /* overwrite submenu with plain menu */ + + /* after sorting that out, do the default lihata merge: */ + return lht_tree_merge_hash(dst, src, recurse); +} + +static lht_err_t lht_tree_merge_menu(lht_node_t *dst, lht_node_t *src) +{ + lht_err_t e; + + switch(dst->type) { + case LHT_INVALID_TYPE: return LHTE_BROKEN_DOC; + case LHT_TEXT: lht_tree_merge_text(dst, src); break; + case LHT_TABLE: e = lht_tree_merge_table(dst, src); if (e != LHTE_SUCCESS) return e; break; + case LHT_HASH: e = menu_tree_merge_hash(dst, src, lht_tree_merge_menu); if (e != LHTE_SUCCESS) return e; break; + case LHT_LIST: + if ((strcmp(dst->name, "submenu") == 0) || (strcmp(dst->name, "main_menu") == 0) || (strcmp(dst->name, "popups") == 0)) + lht_tree_merge_list_submenu(dst, src, lht_tree_merge_menu); + else if (strcmp(dst->name, "anchored") == 0) + lht_tree_merge_list(dst, src); + else + return lht_tree_merge_list_submenu_prop(dst, src); + break; + case LHT_SYMLINK: + /* symlink text match */ + break; + } + lht_dom_node_free(src); + return LHTE_SUCCESS; +} + +#define GET_PATH_TEXT(instname, n, path) \ +do { \ + if (inst->type != LHT_HASH) { \ + rnd_message(RND_MSG_ERROR, "Menu merging error: " instname " patch instruction must be a hash node\n"); \ + return; \ + } \ + path = lht_dom_hash_get(inst, "path"); \ + if (path == NULL) { \ + rnd_message(RND_MSG_ERROR, "Menu merging error: " instname " patch instruction without a menu path\n"); \ + return; \ + } \ + if (path->type != LHT_TEXT) { \ + rnd_message(RND_MSG_ERROR, "Menu merging error: " instname " patch instruction menu path must be text\n"); \ + return; \ + } \ + n = rnd_hid_cfg_get_menu_at_node(dst, path->data.text.value, NULL, NULL); \ + if (n == NULL) \ + return; \ +} while(0) + +static void menu_patch_apply_remove_menu(lht_node_t *dst, lht_node_t *inst) +{ + lht_node_t *n, *path; + + GET_PATH_TEXT("remove_menu", n, path); + + if ((strcmp(n->name, "main_menu") == 0) || (strcmp(n->name, "popups") == 0) || (strcmp(n->name, "anchored") == 0)) { + if (submenu(n->parent) == NULL) { + rnd_message(RND_MSG_ERROR, "Menu merging error: remove_menu patch attempted to remove a menu root\n"); + return; + } + } + + lht_tree_del(n); +} + +static void menu_patch_apply_append_menu(lht_node_t *dst, lht_node_t *inst) +{ + lht_node_t *dn, *path, *isub, *tmp, *dsub; + + GET_PATH_TEXT("append_menu", dn, path); + + isub = lht_dom_hash_get(inst, "submenu"); \ + if ((isub == NULL) || (isub->type != LHT_LIST)) { + rnd_message(RND_MSG_ERROR, "Menu merging error: append_menu patch instruction submenu must a list\n"); + return; + } + dsub = submenu(dn); + if (dsub == NULL) { + rnd_message(RND_MSG_ERROR, "Menu merging error: append_menu patch instruction attempted to append to a non-submenu %s\n", dn->name); + return; + } + + tmp = lht_dom_duptree(isub); + lht_tree_merge_using(dsub, tmp, lht_tree_merge_menu); +} + + +static void menu_patch_apply_overwrite_menu_props(lht_node_t *dst, lht_node_t *inst) +{ + lht_node_t *dn, *sn, *path, *n, *tmp; + lht_dom_iterator_t it; + + GET_PATH_TEXT("overwrite_menu_props", dn, path); + + if (submenu(dn) != NULL) { + rnd_message(RND_MSG_ERROR, "Menu merging error: overwrite_menu_props patch instruction path refers to a menu that has submenus (not properties)\n"); + return; + } + + sn = lht_dom_hash_get(inst, "props"); + if ((sn == NULL) || (sn->type != LHT_HASH)) { + rnd_message(RND_MSG_ERROR, "Menu merging error: overwrite_menu_props patch instruction needs a ha:props child\n"); + return; + } + + /* replace each named child of dn enumerating src/props */ + for(n = lht_dom_first(&it, sn); n != NULL; n = lht_dom_next(&it)) { + tmp = lht_dom_hash_get(dn, n->name); + if (tmp != NULL) + lht_tree_del(tmp); + tmp = lht_dom_duptree(n); + lht_dom_hash_put(dn, tmp); + } +} + +/* check if node is a menu file root (not menu patch root!); for backward + compatibility: accept anonymous node as menu file if it has a main_menu child */ +#define is_menu_file_root(node) \ + (((node)->type == LHT_HASH) && ((strcmp((node)->name, "rnd-menu-v1") == 0) || ((((node)->name[0] == '\0')) && (lht_dom_hash_get(node, "main_menu") != NULL)))) + +static void menu_patch_apply(lht_node_t *dst, lht_node_t *src) +{ + lht_node_t *tmp; + + /* merging a complete menu file is easy: use lihata's default merge algorithm, + except for submenu lists where by-name merging is required */ + if (is_menu_file_root(src)) { + tmp = lht_dom_duptree(src); + lht_tree_merge_using(dst, tmp, lht_tree_merge_menu); + return; + } + + /* execute patching instructions */ + if ((src->type == LHT_HASH) && (strcmp(src->name, "rnd-menu-patch-v1") == 0)) { + lht_node_t *p, *patch = lht_dom_hash_get(src, "patch"); + if ((patch == NULL) || (patch->type != LHT_LIST)) { + rnd_message(RND_MSG_ERROR, "Menu merging error: patch instructions must be in a li:patch\n"); + return; + } + for(p = patch->data.list.first; p != NULL; p = p->next) { + if (p->type != LHT_HASH) { + rnd_message(RND_MSG_ERROR, "Menu merging error: invalid patch instruction %s (not a hash)\n", p->name); + continue; + } + if (strcmp(p->name, "remove_menu") == 0) + menu_patch_apply_remove_menu(dst, p); + else if (strcmp(p->name, "append_menu") == 0) + menu_patch_apply_append_menu(dst, p); + else if (strcmp(p->name, "overwrite_menu_props") == 0) + menu_patch_apply_overwrite_menu_props(dst, p); + else { + rnd_message(RND_MSG_ERROR, "Menu merging error: unknown patch instruction %s\n", p->name); + continue; + } + } + return; + } + + rnd_message(RND_MSG_ERROR, "Menu merging error: invalid menu file root: %s\n", src->name); +} + +static void create_menu_by_node(lht_node_t *dst, lht_node_t *ins_after, int is_popup) +{ + lht_node_t *parent; + int is_main; + + if (rnd_menu_sys.gui_nomod) + return; + + parent = dst->parent; + is_main = (strcmp(parent->name, "submenu") != 0); + if (!is_main) + parent = parent->parent; + + rnd_gui->create_menu_by_node(rnd_gui, is_popup, dst->name, is_main, parent, ins_after, dst); +} + +static void menu_merge_remove_recursive(lht_node_t *node) +{ + lht_node_t *n, *sub = submenu(node); + if (sub != NULL) { + lht_dom_iterator_t it; + for(n = lht_dom_first(&it, sub); n != NULL; n = lht_dom_next(&it)) + menu_merge_remove_recursive(n); + } + rnd_gui->remove_menu_node(rnd_gui, node); + lht_tree_del(node); +} + +/* replace menu subtree at dst with the one at src */ +static void menu_merge_replace(lht_node_t *dst, lht_node_t *src, int is_popup) +{ + lht_node_t *tmp, *n, *after = rnd_hid_menu_ins_as_first; + + assert(dst->parent->type = LHT_LIST); + + /* figure where the previous node at dst on the list so we can insert at the + same position after the removal */ + for(n = dst->parent->data.list.first; (n != NULL) && (n != dst); n = n->next) + after = n; + + tmp = lht_dom_duptree(src); + lht_dom_list_insert_after(dst, tmp); + + menu_merge_remove_recursive(dst); + create_menu_by_node(tmp, after, is_popup); +} + +static rnd_bool menu_plain_submenus_differ(lht_node_t *a, lht_node_t *b) +{ + lht_node_t *n, *m; + lht_dom_iterator_t it; + + if (a->type != b->type) + return 1; + + /* assume names match - the caller should have checked that in case of list */ + + switch(a->type) { + case LHT_TEXT: + case LHT_SYMLINK: + return (strcmp(a->data.text.value, b->data.text.value) != 0); + case LHT_HASH: + if (a->data.hash.tbl->used != b->data.hash.tbl->used) + return 1; + for(n = lht_dom_first(&it, a); n != NULL; n = lht_dom_next(&it)) { + m = lht_dom_hash_get(b, n->name); + if (m == NULL) + return 1; + if (menu_plain_submenus_differ(n, m)) + return 1; + } + return 0; + case LHT_LIST: + for(n = a->data.list.first, m = b->data.list.first;; n = n->next, m = m->next) { + if ((n == NULL) && (m == NULL)) + return 0; + if ((n == NULL) || (m == NULL)) /* list length mismatch */ + return 1; + if (menu_plain_submenus_differ(n, m)) + return 1; + } + break; + default: + return 1; /* unhandled type - shouldn't be in a menu, but when it is, it surely differs */ + } + return 1; /* can't get here anyway */ +} + +static void menu_merge_submenu(lht_node_t *dst, lht_node_t *src, int is_popup) +{ + lht_node_t *dn, *sn, *ssub, *dsub, *tmp; + lht_dom_iterator_t it; + + /* find nodes that are present in dst but not in src -> remove */ + for(dn = lht_dom_first(&it, dst); dn != NULL; dn = lht_dom_next(&it)) { + sn = search_list_for_node(src, dn); + if (sn == NULL) + menu_merge_remove_recursive(dn); + } + + /* find nodes that are present in both -> either recurse or modify */ + for(dn = lht_dom_first(&it, dst); dn != NULL; dn = lht_dom_next(&it)) { + sn = search_list_for_node(src, dn); + if (sn != NULL) { + ssub = submenu(sn); + dsub = submenu(dn); + if ((dsub == NULL) && (ssub == NULL)) { + /* modify: plain node is replaced by a plain node */ + if (menu_plain_submenus_differ(dn, sn)) + menu_merge_replace(dn, sn, is_popup); /* if they are not the same, have to replace */ + } + else if ((dsub != NULL) && (ssub != NULL)) + menu_merge_submenu(dsub, ssub, is_popup); /* same submenu -> recurse */ + else if ((dsub != NULL) && (ssub == NULL)) + menu_merge_replace(dn, sn, is_popup); /* modify: a submenu is replaced by a plain node */ + else if ((dsub == NULL) && (ssub != NULL)) + menu_merge_replace(dn, sn, is_popup); /* modify: a plain node is replaced by a submenu */ + } + } + + /* find nodes that are present in src but not in dst -> add */ + for(sn = lht_dom_first(&it, src); sn != NULL; sn = lht_dom_next(&it)) { + dn = search_list_for_node(dst, sn); + if (dn == NULL) { + tmp = lht_dom_duptree(sn); + lht_dom_list_append(dst, tmp); + + dn = search_list_for_node(dst, sn); + if (dn != NULL) + create_menu_by_node(dn, NULL, is_popup); + } + } +} + +typedef struct { + char *name; /* points into path*/ + char path[1]; /* extends longer */ +} anchor_t; + +static void append_anchor(vtp0_t *anch, gds_t *path, lht_node_t *n) +{ + anchor_t *a; + int save = path->used; + gds_append(path, '/'); + gds_append_str(path, n->data.text.value); + a = malloc(sizeof(anchor_t) + path->used+1); + memcpy(a->path, path->array, path->used+1); + a->name = a->path + save + 1; +/* printf(">anchor: '%s': %s\n", a->name, a->path);*/ + gds_truncate(path, save); + vtp0_append(anch, a); +} + +static void map_anchors_submenu(vtp0_t *anch, gds_t *path, lht_node_t *root) +{ + lht_node_t *n, *sm; + assert(root->type == LHT_LIST); + for(n = root->data.list.first; n != NULL; n = n->next) { + if ((n->type == LHT_TEXT) && (n->data.text.value != NULL) && (n->data.text.value[0] == '@')) + append_anchor(anch, path, n); + sm = submenu(n); + if (sm != NULL) { + int save = path->used; + gds_append(path, '/'); + gds_append_str(path, n->name); + map_anchors_submenu(anch, path, sm); + gds_truncate(path, save); + } + } +} + +/* Insert all items from a submenu list (src_lst) after the anchor node anode; + picks up new anchors inserted by the operation */ +static void menu_merge_anchored_at(vtp0_t *anch, lht_node_t *anode, lht_node_t *src_lst, anchor_t *a) +{ + lht_node_t *n, *after = anode, *nsub; + lht_dom_iterator_t it; + gds_t path = {0}; + long init_len; + int is_popup = (strncmp(a->path, "popups", 6) == 0); + + gds_append_str(&path, a->path); + init_len = path.used - strlen(a->name) - 1; + + for(n = lht_dom_first(&it, src_lst); n != NULL; n = lht_dom_next(&it)) { + lht_tree_detach(n); + lht_dom_list_insert_after(after, n); + + if ((n->type == LHT_TEXT) && (n->data.text.value != NULL) && (n->data.text.value[0] == '@')) { + /* we may have added an anchor */ + gds_truncate(&path, init_len); + append_anchor(anch, &path, n); + } + else { + /* if a whole submenu is appended, there might be new anchors in it */ + nsub = submenu(n); + if (nsub != NULL) { + gds_truncate(&path, init_len); + map_anchors_submenu(anch, &path, nsub); + } + } + create_menu_by_node(n, after, is_popup); + after = n; + } + + + gds_uninit(&path); +} + +/* Merge the li:anchored subtree: each item must be a ha:@anchor reference with + a li:submenu; look up the @anchor in the existing tree and insert each child + of the li_submenu after that @anchor in dst. */ +static void menu_merge_anchored(vtp0_t *anch, lht_node_t *dst, lht_node_t *src) +{ + if (src->type != LHT_LIST) { + rnd_message(RND_MSG_ERROR, "Menu merging error: /anchored must be a list\n"); + return; + } + + for(src = src->data.list.first; src != NULL; src = src->next) { + long n, found = 0; + lht_node_t *src_sub; + + if ((src->name == NULL) || (src->name[0] != '@')) { + rnd_message(RND_MSG_ERROR, "Menu merging error: /anchored subtree names must started with a '@' (ignoring offending node: %s)\n", src->name); + continue; + } + + src_sub = submenu(src); + if (src_sub == NULL) { + rnd_message(RND_MSG_ERROR, "Menu merging error: /anchored node without submenu (ignoring offending node: %s)\n", src->name); + continue; + } + + for(n = 0; n < anch->used; n++) { + anchor_t *a = anch->array[n]; + if (strcmp(src->name, a->name) == 0) { + lht_node_t *anode = rnd_hid_cfg_get_menu_at_node(dst, a->path, NULL, NULL); + if (anode != NULL) { +/* printf(" anchored! '%s' at %s: %p\n", src->name, a->path, anode);*/ + menu_merge_anchored_at(anch, anode, src_sub, a); + found++; + } + } + } + if (found == 0) { + rnd_message(RND_MSG_ERROR, "Menu merging error: anchor %s not found\n", src->name); + } + } +} + + /* recursive merge of the final trees starting from the root */ +static void menu_merge_root(lht_node_t *dst, lht_node_t *src) +{ + lht_node_t *dn, *sn; + vtp0_t anch = {0}; + gds_t path = {0}; + long n; + + assert(dst->type == LHT_HASH); + assert(src->type == LHT_HASH); + + dn = lht_dom_hash_get(dst, "main_menu"); + sn = lht_dom_hash_get(src, "main_menu"); + menu_merge_submenu(dn, sn, 0); + path.used = 0; + gds_append_str(&path, "main_menu"); + map_anchors_submenu(&anch, &path, dn); + + + dn = lht_dom_hash_get(dst, "popups"); + sn = lht_dom_hash_get(src, "popups"); + menu_merge_submenu(dn, sn, 1); + path.used = 0; + gds_append_str(&path, "popups"); + map_anchors_submenu(&anch, &path, dn); + + sn = lht_dom_hash_get(src, "anchored"); + if (sn != NULL) + menu_merge_anchored(&anch, dst, sn); + + for(n = 0; n < anch.used; n++) + free(anch.array[n]); + vtp0_uninit(&anch); + TODO("mouse, toolbar_static, scripts"); +} + +static lht_doc_t *new_menu_file() +{ + lht_doc_t *new = lht_dom_init(); + + new->root = lht_dom_node_alloc(LHT_HASH, "rnd-menu-v1"); + new->root->doc = new; + lht_dom_hash_put(new->root, lht_dom_node_alloc(LHT_LIST, "main_menu")); + lht_dom_hash_put(new->root, lht_dom_node_alloc(LHT_LIST, "popups")); + lht_dom_hash_put(new->root, lht_dom_node_alloc(LHT_LIST, "anchored")); + return new; +} + +static lht_doc_t *dup_base(rnd_menu_patch_t *base) +{ + lht_node_t *tmp; + lht_doc_t *new; + + if ((base == NULL) || (base->cfg.doc == NULL) || (base->cfg.doc->root == NULL)) + return new_menu_file(); + + new = lht_dom_init(); + new->root = lht_dom_node_alloc(LHT_HASH, "rnd-menu-v1"); + new->root->doc = new; + tmp = lht_dom_duptree(base->cfg.doc->root); + lht_tree_merge(new->root, tmp); + return new; +} + +static void lht_set_doc(lht_node_t *node, lht_doc_t *doc) +{ + lht_node_t *n; + lht_dom_iterator_t it; + + node->doc = doc; + for(n = lht_dom_first(&it, node); n != NULL; n = lht_dom_next(&it)) + lht_set_doc(n, doc); +} + +static void menu_merge(rnd_hid_t *hid) +{ + rnd_menu_patch_t *base = NULL; + int just_created = 0; + + if (!rnd_menu_sys.gui_ready || (rnd_menu_sys.inhibit > 0)) + return; + + if (rnd_menu_sys.patches.used > 0) + base = rnd_menu_sys.patches.array[0]; + + if (base != NULL) { + if (base->cfg.doc->root == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to load base menu file\n"); + base = NULL; + } + else if (!is_menu_file_root(base->cfg.doc->root)) { + rnd_message(RND_MSG_ERROR, "Base menu file %s has invalid root (should be: ha:rnd-menu-v1)\n", base->cfg.doc->root->name); + base = NULL; + } + } + else { + rnd_message(RND_MSG_ERROR, "Menu merging error: no menu file\n"); + return; + } + + if (hid->menu == NULL) { + hid->menu = calloc(sizeof(rnd_hid_cfg_t), 1); /* make sure the cache is cleared */ + hid->menu->doc = dup_base(base); + just_created = 1; + } + + if ((just_created == 0) || (rnd_menu_sys.patches.used > 1)) { + int n; + lht_doc_t *new; + + if ((base != NULL) && (base->cfg.doc != NULL) && (base->cfg.doc->root != NULL)) { + new = lht_dom_init(); + new->root = lht_dom_duptree(base->cfg.doc->root); + lht_set_doc(new->root, new); + } + else + new = new_menu_file(); + + /* apply all patches */ + for(n = 1; n < rnd_menu_sys.patches.used; n++) { + rnd_menu_patch_t *m = rnd_menu_sys.patches.array[n]; + menu_patch_apply(new->root, m->cfg.doc->root); + } + + /* perform the final tree merge */ + menu_merge_root(hid->menu->doc->root, new->root); + +#if 0 + { +#undef fopen + FILE *f = fopen("A_merged.lht", "w"); + lht_dom_export(hid->menu->doc->root, f, ""); + fclose(f); + } +#endif + + lht_dom_uninit(new); + + } + + rnd_menu_sys.last_merged = rnd_menu_sys.changes; + rnd_event(NULL, RND_EVENT_MENU_CHANGED, NULL); +} + +void rnd_hid_menu_gui_ready_to_create(rnd_hid_t *hid) +{ + rnd_menu_sys.gui_ready = 1; + rnd_menu_sys.gui_nomod = 1; + menu_merge(hid); +} + +void rnd_hid_menu_gui_ready_to_modify(rnd_hid_t *hid) +{ + rnd_menu_sys.gui_nomod = 0; +} + +static int determine_prio(lht_node_t *node, int default_prio) +{ + long l; + char *end; + + if ((node == NULL) || (node->type != LHT_HASH) || (strcmp(node->name, "rnd-menu-patch-v1") != 0)) + return default_prio; + node = lht_dom_hash_get(node, "prio"); + if (node == NULL) + return default_prio; + if (node->type != LHT_TEXT) { + rnd_message(RND_MSG_ERROR, "Menu merging error: ignoring prio (must be a text node)\n"); + return default_prio; + } + + l = strtol(node->data.text.value, &end, 10); + if ((*end != '\0') || (l < 1) || (l > 32767)) { + rnd_message(RND_MSG_ERROR, "Menu merging error: ignoring prio (must be an integer between 1 and 32k)\n"); + return default_prio; + } + + return l; +} + +void rnd_hid_menu_unload(rnd_hid_t *hid, const char *cookie) +{ + rnd_menu_sys_remove_cookie(&rnd_menu_sys, cookie); + menu_merge(rnd_gui); +} + +void rnd_hid_menu_unload_patch(rnd_hid_t *hid, rnd_menu_patch_t *mp) +{ + rnd_menu_sys_remove(&rnd_menu_sys, mp); + menu_merge(rnd_gui); +} + +static rnd_menu_patch_t *rnd_hid_menu_store_doc(rnd_hid_t *hid, lht_doc_t *doc, const char *cookie, int prio, const char *desc, rnd_bool has_file) +{ + rnd_menu_patch_t *menu = calloc(sizeof(rnd_menu_patch_t), 1); /* make sure the cache is cleared */ + + menu->cfg.doc = doc; + menu->prio = determine_prio(doc->root, prio); + menu->cookie = rnd_strdup(cookie); + menu->desc = rnd_strdup(desc); + menu->has_file = has_file; + + rnd_menu_sys_insert(&rnd_menu_sys, menu); + + menu_merge(hid); + + return menu; +} + +rnd_menu_patch_t *rnd_hid_menu_load(rnd_hid_t *hid, rnd_hidlib_t *hidlib, const char *cookie, int prio, const char *fn, int exact_fn, const char *embedded_fallback, const char *desc) +{ + lht_doc_t *doc = NULL; + int has_file = 0; + + if (fn != NULL) { + if (!exact_fn) { + /* try different paths to find the menu file inventing its exact name */ + char **paths = NULL, **p; + int fn_len = strlen(fn); + + if (rnd_app.menu_file_paths != NULL) { + rnd_paths_resolve_all(hidlib, rnd_app.menu_file_paths, paths, fn_len+4, rnd_false); + for(p = paths; *p != NULL; p++) { + if (doc == NULL) { + strcpy((*p)+strlen(*p), fn); + doc = rnd_hid_cfg_load_lht(hidlib, *p); + if (doc != NULL) { + rnd_file_loaded_set_at("menu", cookie, *p, desc); + has_file = 1; + } + } + free(*p); + } + free(paths); + } + } + else { + doc = rnd_hid_cfg_load_lht(hidlib, fn); + if (doc != NULL) { + rnd_file_loaded_set_at("menu", cookie, fn, desc); + has_file = 1; + } + } + } + + if ((doc == NULL) && (embedded_fallback != NULL)) { + doc = rnd_hid_cfg_load_str(embedded_fallback); + if (doc != NULL) + rnd_file_loaded_set_at("menu", cookie, "", desc); + } + if (doc == NULL) + return NULL; + + return rnd_hid_menu_store_doc(hid, doc, cookie, prio, desc, has_file); +} + +void rnd_hid_menu_merge_inhibit_inc(void) +{ + if (rnd_menu_sys.inhibit < 32767) + rnd_menu_sys.inhibit++; + else + rnd_message(RND_MSG_ERROR, "rnd_hid_menu_merge_inhibit_inc(): overflow\n"); +} + +void rnd_hid_menu_merge_inhibit_dec(void) +{ + if (rnd_menu_sys.inhibit > 0) { + rnd_menu_sys.inhibit--; + if (rnd_menu_sys.inhibit == 0) { + menu_merge(rnd_gui); + if ((rnd_gui != NULL) && (rnd_gui->update_menu_checkbox != NULL)) + rnd_gui->update_menu_checkbox(rnd_gui, NULL); + } + } + else + rnd_message(RND_MSG_ERROR, "rnd_hid_menu_merge_inhibit_dec(): underflow\n"); +} + +/*** utility ***/ + +lht_node_t *rnd_hid_cfg_get_menu_at_node(lht_node_t *at, const char *menu_path, lht_node_t *(*cb)(void *ctx, lht_node_t *node, const char *path, int rel_level), void *ctx) +{ + lht_err_t err; + lht_node_t *curr; + int level = 0, len = strlen(menu_path), iafter = 0; + char *next_seg, *path; + + path = malloc(len+4); /* need a few bytes after the end for the ':' */ + strcpy(path, menu_path); + + next_seg = path; + curr = at; + + /* Have to descend manually because of the submenu nodes */ + for(;;) { + char *next, *end; + lht_dom_iterator_t it; + + while(*next_seg == '/') next_seg++; + + if (curr != at->doc->root) { + if (level > 1) { + curr = lht_tree_path_(at->doc, curr, "submenu", 1, 0, &err); + if (curr == NULL) + break; + } + } + next = end = strchr(next_seg, '/'); + if (end == NULL) + end = next_seg + strlen(next_seg); + + *end = '\0'; + + /* find next_seg in the current level */ + for(curr = lht_dom_first(&it, curr); curr != NULL; curr = lht_dom_next(&it)) { + if (*next_seg == '@') { + /* looking for an anon text node with the value matching the anchor name */ + if ((curr->type == LHT_TEXT) && (strcmp(curr->data.text.value, next_seg) == 0)) { + iafter = 1; + break; + } + } + else { + /* looking for a hash node */ + if (strcmp(curr->name, next_seg) == 0) + break; + } + } + + if (cb != NULL) + curr = cb(ctx, curr, path, level); + + if (next != NULL) /* restore previous / so that path is a full path */ + *next = '/'; + next_seg = next; + if ((curr == NULL) || (next_seg == NULL)) + break; + next_seg++; + level++; + if (iafter) { + /* special case: insert after an @anchor and exit */ + if (cb != NULL) + curr = cb(ctx, NULL, path, level); + break; + } + } + + free(path); + return curr; +} + +lht_node_t *rnd_hid_cfg_get_menu_at(rnd_hid_cfg_t *hr, lht_node_t *at, const char *menu_path, lht_node_t *(*cb)(void *ctx, lht_node_t *node, const char *path, int rel_level), void *ctx) +{ + if (hr == NULL) + return NULL; + + return rnd_hid_cfg_get_menu_at_node(((at == NULL) ? hr->doc->root : at), menu_path, cb, ctx); +} + +lht_node_t *rnd_hid_cfg_get_menu(rnd_hid_cfg_t *hr, const char *menu_path) +{ + return rnd_hid_cfg_get_menu_at(hr, NULL, menu_path, NULL, NULL); +} + +lht_node_t *rnd_hid_cfg_menu_field(const lht_node_t *submenu, rnd_hid_cfg_menufield_t field, const char **field_name) +{ + lht_err_t err; + const char *fieldstr = NULL; + + switch(field) { + case RND_MF_ACCELERATOR: fieldstr = "a"; break; + case RND_MF_SUBMENU: fieldstr = "submenu"; break; + case RND_MF_CHECKED: fieldstr = "checked"; break; + case RND_MF_UPDATE_ON: fieldstr = "update_on"; break; + case RND_MF_SENSITIVE: fieldstr = "sensitive"; break; + case RND_MF_TIP: fieldstr = "tip"; break; + case RND_MF_ACTION: fieldstr = "action"; break; + } + if (field_name != NULL) + *field_name = fieldstr; + + if (fieldstr == NULL) + return NULL; + + return lht_tree_path_(submenu->doc, submenu, fieldstr, 1, 0, &err); +} + +typedef struct { + rnd_hid_cfg_t *hr; + lht_node_t *parent; + rnd_menu_prop_t props; + int target_level; + int err; + lht_node_t *after; +} create_menu_ctx_t; + +static lht_node_t *menu_create_sep(lht_node_t *parent, lht_node_t *ins_after) +{ + lht_node_t *n; + + if ((parent != NULL) && (parent->type != LHT_LIST)) + return NULL; + + /* ignore ins_after if we are already deeper in the tree */ + if ((ins_after != NULL) && (ins_after->parent != parent)) + ins_after = NULL; + + n = lht_dom_node_alloc(LHT_TEXT, NULL); + n->data.text.value = rnd_strdup("-"); + if (ins_after != NULL) + lht_dom_list_insert_after(ins_after, n); + else if (parent != NULL) + lht_dom_list_append(parent, n); + + return n; +} + +static const char *colorstr(const rnd_color_t *c) +{ + if (c == NULL) return NULL; + return c->str; +} + +static lht_node_t *create_menu_cb(void *ctx, lht_node_t *node, const char *path, int rel_level) +{ + int is_sep; + create_menu_ctx_t *cmc = ctx; + lht_node_t *psub; + + if (node == NULL) { /* level does not exist, create it */ + const char *name; + name = strrchr(path, '/'); + if (name != NULL) + name++; + else + name = path; + + if (rel_level <= 1) { + /* creating a main menu */ + char *end, *name = rnd_strdup(path); + for(end = name; *end == '/'; end++) ; + end = strchr(end, '/'); + *end = '\0'; + psub = cmc->parent = rnd_hid_cfg_get_menu(cmc->hr, name); + free(name); + } + else + psub = rnd_hid_cfg_menu_field(cmc->parent, RND_MF_SUBMENU, NULL); + + is_sep = (name[0] == '-') && (name[1] == '\0'); + if (rel_level == cmc->target_level) { + if (is_sep) + node = menu_create_sep(psub, cmc->after); + else + node = rnd_hid_cfg_create_hash_node(psub, cmc->after, name, "dyn", "1", "cookie", cmc->props.cookie, "a", cmc->props.accel, "tip", cmc->props.tip, "action", cmc->props.action, "checked", cmc->props.checked, "update_on", cmc->props.update_on, "foreground", colorstr(cmc->props.foreground), "background", colorstr(cmc->props.background), NULL); + if (node != NULL) + cmc->err = 0; + } + else { + if (is_sep) + node = menu_create_sep(psub, cmc->after); + else + node = rnd_hid_cfg_create_hash_node(psub, cmc->after, name, "dyn", "1", "cookie", cmc->props.cookie, NULL); + } + + if (node == NULL) + return NULL; + + if ((rel_level != cmc->target_level) || (cmc->props.action == NULL)) + lht_dom_hash_put(node, lht_dom_node_alloc(LHT_LIST, "submenu")); + + if (node->parent == NULL) { + lht_dom_list_append(psub, node); + } + else { + assert(node->parent == psub); + } + } + else { + /* existing level */ + if ((node->type == LHT_TEXT) && (node->data.text.value[0] == '@')) { + cmc->after = node; + goto skip_parent; + } + } + cmc->parent = node; + + skip_parent:; + return node; +} + +static int create_menu_manual_prop(rnd_menu_sys_t *msys, const char *path, const rnd_menu_prop_t *props) +{ + const char *name; + rnd_menu_patch_t *mp; + create_menu_ctx_t cmc; + + if (props->cookie == NULL) + return -1; + + mp = rnd_menu_sys_find_cookie(msys, props->cookie); + if (mp == NULL) { + mp = calloc(sizeof(rnd_menu_patch_t), 1); /* make sure the cache is cleared */ + mp->cfg.doc = new_menu_file(); + mp->prio = 500; + mp->cookie = rnd_strdup(props->cookie); + rnd_menu_sys_insert(msys, mp); + } + + memset(&cmc, 0, sizeof(cmc)); + cmc.hr = &mp->cfg; + cmc.err = -1; + cmc.props = *props; + + /* Allow creating new nodes only under certain main paths that correspond to menus */ + if (strncmp(path, "rnd-menu-v1/", 12) == 0) + path += 11; /* but keep the / */ + + name = path; + while(*name == '/') name++; + + if ((strncmp(name, "main_menu/", 10) == 0) || (strncmp(name, "popups/", 7) == 0) || (strncmp(name, "anchored/", 9) == 0)) { + /* calculate target level */ + for(cmc.target_level = 0; *name != '\0'; name++) { + if (*name == '/') { + cmc.target_level++; + while(*name == '/') name++; + name--; + } + } + + /* descend and visit each level, create missing levels */ + rnd_hid_cfg_get_menu_at(cmc.hr, NULL, path, create_menu_cb, &cmc); + } + + if (cmc.err == 0) { + msys->changes++; + menu_merge(rnd_gui); + } + + return cmc.err; +} + +static int create_menu_manual(rnd_menu_sys_t *msys, const char *path, const char *action, const char *tip, const char *cookie, const char *accel) +{ + rnd_menu_prop_t props = {0}; + + props.action = action; + props.tip = tip; + props.cookie = cookie; + props.accel = accel; + return create_menu_manual_prop(msys, path, &props); +} + +int rnd_hid_menu_create(const char *path, const rnd_menu_prop_t *props) +{ + return create_menu_manual_prop(&rnd_menu_sys, path, props); +} + +static int remove_menu_manual(rnd_menu_sys_t *msys, const char *path, const char *cookie) +{ + rnd_menu_patch_t *mp = rnd_menu_sys_find_cookie(msys, cookie); + lht_node_t *nd; + + if (mp == NULL) + return -1; + + nd = rnd_hid_cfg_get_menu_at(&mp->cfg, NULL, path, NULL, NULL); + if (nd == NULL) + return -1; + lht_tree_del(nd); + msys->changes++; + menu_merge(rnd_gui); + return 0; +} + +/*** actions ***/ + +static const char rnd_acts_CreateMenu[] = "CreateMenu(path)\nCreateMenu(path, action, tooltip, cookie, [accel])"; +static const char rnd_acth_CreateMenu[] = "Creates a new menu, popup (only path specified) or submenu (at least path and action are specified)"; +static fgw_error_t rnd_act_CreateMenu(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + if (rnd_gui == NULL) { + rnd_message(RND_MSG_ERROR, "Error: can't create menu, there's no GUI hid loaded\n"); + RND_ACT_IRES(-1); + return 0; + } + + RND_ACT_CONVARG(1, FGW_STR, CreateMenu, ;); + RND_ACT_MAY_CONVARG(2, FGW_STR, CreateMenu, ;); + RND_ACT_MAY_CONVARG(3, FGW_STR, CreateMenu, ;); + RND_ACT_MAY_CONVARG(4, FGW_STR, CreateMenu, ;); + RND_ACT_MAY_CONVARG(5, FGW_STR, CreateMenu, ;); + + if (argc > 1) { + int r = create_menu_manual(&rnd_menu_sys, argv[1].val.str, (argc > 2) ? argv[2].val.str : NULL, (argc > 3) ? argv[3].val.str : NULL, (argc > 4) ? argv[4].val.str : NULL, (argc > 5) ? argv[5].val.str : NULL); + if (r != 0) + rnd_message(RND_MSG_ERROR, "Error: failed to create the menu\n"); + RND_ACT_IRES(r); + return 0; + } + + RND_ACT_FAIL(CreateMenu); +} + +static const char rnd_acts_RemoveMenu[] = "RemoveMenu(path, cookie)"; +static const char rnd_acth_RemoveMenu[] = "Recursively removes a new menu, popup (only path specified) or submenu. "; +static fgw_error_t rnd_act_RemoveMenu(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + if (rnd_gui == NULL) { + rnd_message(RND_MSG_ERROR, "can't remove menu, there's no GUI hid loaded\n"); + RND_ACT_IRES(-1); + return 0; + } + + if (rnd_gui->remove_menu_node == NULL) { + rnd_message(RND_MSG_ERROR, "can't remove menu, the GUI doesn't support it\n"); + RND_ACT_IRES(-1); + return 0; + } + + RND_ACT_CONVARG(1, FGW_STR, RemoveMenu, ;); + RND_ACT_CONVARG(2, FGW_STR, RemoveMenu, ;); + if (remove_menu_manual(&rnd_menu_sys, argv[1].val.str, argv[2].val.str) != 0) { + rnd_message(RND_MSG_ERROR, "failed to remove some of the menu items\n"); + RND_ACT_IRES(-1); + } + else + RND_ACT_IRES(0); + return 0; +} + +static const char rnd_acts_MenuPatch[] = + "MenuPatch(load, cookie, path, desc)\n" + "MenuPatch(unload, cookie)\n" + "MenuPatch(list)\n" + "MenuPatch(InhibitInc|InhibitDec)"; +static const char rnd_acth_MenuPatch[] = "Manage menu patches"; +fgw_error_t rnd_act_MenuPatch(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int op; + const char *cookie = NULL, *path = NULL, *desc = ""; + + RND_ACT_CONVARG(1, FGW_KEYWORD, MenuPatch, op = fgw_keyword(&argv[1])); + RND_ACT_MAY_CONVARG(2, FGW_STR, MenuPatch, cookie = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, MenuPatch, path = argv[3].val.str); + RND_ACT_MAY_CONVARG(4, FGW_STR, MenuPatch, desc = argv[4].val.str); + + switch(op) { + case F_Load: + if ((cookie == NULL) || (path == NULL)) + RND_ACT_FAIL(MenuPatch); + if (rnd_hid_menu_load(rnd_gui, NULL, cookie, 500, path, 1, NULL, desc) == NULL) + rnd_message(RND_MSG_ERROR, "Failed to load menu patch %s\n", path); + RND_ACT_IRES(0); + return 0; + case F_Unload: + if (cookie == NULL) + RND_ACT_FAIL(MenuPatch); + rnd_menu_sys_remove_cookie(&rnd_menu_sys, cookie); + menu_merge(rnd_gui); + RND_ACT_IRES(0); + return 0; + case F_List: + { + int n; + rnd_message(RND_MSG_INFO, "Menu system:\n"); + for(n = 0; n < rnd_menu_sys.patches.used; n++) { + rnd_menu_patch_t *m = rnd_menu_sys.patches.array[n]; + rnd_message(RND_MSG_INFO, " [%ld] %s prio=%d %s: %s\n", m->uid, (n == 0 ? "base " : "addon"), m->prio, m->cookie, m->cfg.doc->root->file_name); + } + } + RND_ACT_IRES(0); + return 0; + case F_InhibitInc: rnd_hid_menu_merge_inhibit_inc(); break; + case F_InhibitDec: rnd_hid_menu_merge_inhibit_dec(); break; + default: + RND_ACT_FAIL(MenuPatch); + } + + RND_ACT_IRES(0); + return 0; +} + + +static int create_menu_by_node_debug(rnd_hid_t *hid, int is_popup, const char *name, int is_main, lht_node_t *parent, lht_node_t *ins_after, lht_node_t *menu_item) +{ + printf("menu debug: create: %s\n", name); + return 0; +} + + +static int remove_menu_node_debug(rnd_hid_t *hid, lht_node_t *nd) +{ + printf("menu debug: remove\n"); + return 0; +} + +static const char rnd_acts_MenuDebug[] = + "MenuDebug(save, path)\n"; +static const char rnd_acth_MenuDebug[] = "Menu debug helpers: save the merged menu in a file"; +fgw_error_t rnd_act_MenuDebug(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *op, *path; + FILE *f; + + + RND_ACT_CONVARG(1, FGW_STR, MenuDebug, op = argv[1].val.str); + + RND_ACT_IRES(1); + + if (rnd_strcasecmp(op, "save") == 0) { + RND_ACT_CONVARG(2, FGW_STR, MenuDebug, path = argv[2].val.str); + f = rnd_fopen(RND_ACT_HIDLIB, path, "w"); + if (f != NULL) { + lht_dom_export(rnd_gui->menu->doc->root, f, ""); + fclose(f); + RND_ACT_IRES(0); + } + else + rnd_message(RND_MSG_ERROR, "Failed to open '%s' for write\n", path); + } + else if (rnd_strcasecmp(op, "force-enable") == 0) { + if (rnd_gui->create_menu_by_node == NULL) + rnd_gui->create_menu_by_node = create_menu_by_node_debug; + if (rnd_gui->remove_menu_node == NULL) + rnd_gui->remove_menu_node = remove_menu_node_debug; + rnd_menu_sys.gui_ready = 1; + menu_merge(rnd_gui); + } + else + RND_ACT_FAIL(MenuDebug); + + + return 0; +} + +static rnd_action_t rnd_menu_action_list[] = { + {"CreateMenu", rnd_act_CreateMenu, rnd_acth_CreateMenu, rnd_acts_CreateMenu}, + {"RemoveMenu", rnd_act_RemoveMenu, rnd_acth_RemoveMenu, rnd_acts_RemoveMenu}, + {"MenuPatch", rnd_act_MenuPatch, rnd_acth_MenuPatch, rnd_acts_MenuPatch}, + {"MenuDebug", rnd_act_MenuDebug, rnd_acth_MenuDebug, rnd_acts_MenuDebug} +}; + +static void menu_conf_chg(rnd_conf_native_t *cfg, int arr_idx) +{ + int n; + rnd_conf_listitem_t *i; + const char *mfn; + + rnd_hid_menu_merge_inhibit_inc(); + + /* figure which menu files have conf patch associated (which are already loaded) */ + for(n = 0; n < rnd_menu_sys.patches.used; n++) { + rnd_menu_patch_t *m = rnd_menu_sys.patches.array[n]; + if (!m->has_file) continue; + mfn = m->cfg.doc->root->file_name; + m->cfg_found = 0; + if (mfn == NULL) + continue; + for(i = rnd_conflist_first((rnd_conflist_t *)&rnd_conf.rc.menu_patches); i != NULL; i = rnd_conflist_next(i)) { + const char **cfn = i->val.string; + if (strcmp(*cfn, mfn) == 0) { + m->cfg_found = 1; + break; + } + } + } + + /* remove anything we loaded for the config and we don't need anymore */ + for(n = 0; n < rnd_menu_sys.patches.used; n++) { + rnd_menu_patch_t *m = rnd_menu_sys.patches.array[n]; + if (!m->has_file) continue; + if (m->loaded_for_conf && !m->cfg_found) { + mfn = m->cfg.doc->root->file_name; +/* rnd_trace("cfg unload %s\n", mfn); */ + rnd_hid_menu_unload_patch(rnd_gui, m); + } + } + + /* load all files that are in the config but not in the menu system */ + for(i = rnd_conflist_first((rnd_conflist_t *)&rnd_conf.rc.menu_patches); i != NULL; i = rnd_conflist_next(i)) { + const char **cfn = i->val.string; + int found = 0; + + for(n = 0; n < rnd_menu_sys.patches.used; n++) { + rnd_menu_patch_t *m = rnd_menu_sys.patches.array[n]; + if (!m->has_file) continue; + mfn = m->cfg.doc->root->file_name; + if ((mfn != NULL) && (strcmp(*cfn, mfn) == 0)) { + found = 1; + break; + } + } + + if (!found) { +/* rnd_trace("cfg load %s\n", *cfn);*/ + rnd_menu_patch_t *m = rnd_hid_menu_load(rnd_gui, NULL, "cfg", 250, *cfn, 1, NULL, "Loaded from config node rc/menu_patches"); + if (m != NULL) + m->loaded_for_conf = 1; + } + } + + rnd_hid_menu_merge_inhibit_dec(); +} + +static int menu_anyload_subtree(const rnd_anyload_t *al, rnd_hidlib_t *hl, lht_node_t *root) +{ + lht_doc_t *doc; + rnd_menu_patch_t *menu; + + if (rnd_gui == NULL) + return 0; + + /* copy the root to a new doc, keep file name for at least the root node */ + doc = lht_dom_init(); + doc->root = lht_dom_duptree(root); + lht_dom_loc_newfile(doc, root->file_name); + doc->root->file_name = doc->active_file; + + menu = rnd_hid_menu_store_doc(rnd_gui, doc, menu_cookie_al, 500, "anyload", 1); + + if (menu == NULL) { + rnd_message(RND_MSG_ERROR, "menu anyload: failed to load menu patch from %s\n", doc->root->file_name); + lht_dom_uninit(doc); + return -1; + } + return 0; +} + +static rnd_anyload_t menu_anyload = {0}; + +void rnd_menu_init1(void) +{ + rnd_conf_native_t *n = rnd_conf_get_field("rc/menu_patches"); + menu_conf_id = rnd_conf_hid_reg(menu_cookie, NULL); + + rnd_menu_sys_init(&rnd_menu_sys); + + if (n != NULL) { + static rnd_conf_hid_callbacks_t cbs; + memset(&cbs, 0, sizeof(rnd_conf_hid_callbacks_t)); + cbs.val_change_post = menu_conf_chg; + rnd_conf_hid_set_cb(n, menu_conf_id, &cbs); + } + + menu_anyload.load_subtree = menu_anyload_subtree; + menu_anyload.cookie = menu_cookie_al; + rnd_anyload_reg("^rnd-menu-v[0-9]*$", &menu_anyload); +} + +void rnd_menu_act_init2(void) +{ + RND_REGISTER_ACTIONS(rnd_menu_action_list, NULL); +} + +void rnd_menu_uninit(void) +{ + rnd_anyload_unreg_by_cookie(menu_cookie_al); + rnd_conf_hid_unreg(menu_cookie); +} Index: trunk/src/librnd/hid/hid_menu.h =================================================================== --- trunk/src/librnd/hid/hid_menu.h (nonexistent) +++ trunk/src/librnd/hid/hid_menu.h (revision 34602) @@ -0,0 +1,87 @@ +#ifndef RND_HID_MENU_H +#define RND_HID_MENU_H + +#include +#include +#include + +typedef struct { + char *cookie, *desc; + rnd_hid_cfg_t cfg; + int prio; + long uid; + unsigned has_file:1; /* loaded from a file, can be reloaded any time */ + unsigned loaded_for_conf:1; /* loaded for rc.menu_patches */ + + /* internal/cache */ + unsigned cfg_found:1; +} rnd_menu_patch_t; + +typedef struct { + vtp0_t patches; /* list of (rnd_menu_patch_t *), ordered by priority, ascending */ + rnd_hid_cfg_t *merged; + long changes, last_merged; /* if changes > last_merged, we need to merge */ + int inhibit; + unsigned gui_ready:1; /* ready for the first merge */ + unsigned gui_nomod:1; /* do the merge but do not send any modification request - useful for the initial menu setup */ + unsigned alloced:1; /* whether ->merged is alloced (it is not, for the special case of patches->used <= 1 at the time of merging) */ +} rnd_menu_sys_t; + + +/* Search and load the menu file called from fn, using the menu search + path (from the conf system) if not given by an absolute path; if NULL or + not found, parse embedded_fallback instead (if it is not NULL). + Prio is ignored when loading a menu patch file with priority specified in the file. + Returns NULL on error. */ +rnd_menu_patch_t *rnd_hid_menu_load(rnd_hid_t *hid, rnd_hidlib_t *hidlib, const char *cookie, int prio, const char *fn, int exact_fn, const char *embedded_fallback, const char *desc); + +/* Unload a menu patch by cookie */ +void rnd_hid_menu_unload(rnd_hid_t *hid, const char *cookie); +void rnd_hid_menu_unload_patch(rnd_hid_t *hid, rnd_menu_patch_t *mp); + +/* inhibit menu merging: optimization for batch loading/unloading so only + one merge happens at the end */ +void rnd_hid_menu_merge_inhibit_inc(void); +void rnd_hid_menu_merge_inhibit_dec(void); + + +/* The GUI announces that it is ready for creating the menu; the initial + merge should happen, but no modification callbacks are done */ +void rnd_hid_menu_gui_ready_to_create(rnd_hid_t *hid); + +/* The GUI announces that it is ready for executing menu modification callbacks */ +void rnd_hid_menu_gui_ready_to_modify(rnd_hid_t *hid); + + +lht_node_t *rnd_hid_cfg_get_menu(rnd_hid_cfg_t *hr, const char *menu_path); +lht_node_t *rnd_hid_cfg_get_menu_at(rnd_hid_cfg_t *hr, lht_node_t *at, const char *menu_path, lht_node_t *(*cb)(void *ctx, lht_node_t *node, const char *path, int rel_level), void *ctx); +lht_node_t *rnd_hid_cfg_get_menu_at_node(lht_node_t *at, const char *menu_path, lht_node_t *(*cb)(void *ctx, lht_node_t *node, const char *path, int rel_level), void *ctx); + +/* plugins can manually create dynamic menus using this call; props->cookie + must be set, the menu patch is identified by that cookie */ +int rnd_hid_menu_create(const char *path, const rnd_menu_prop_t *props); + +/* Fields are retrieved using this enum so that HIDs don't need to hardwire + lihata node names */ +typedef enum { + RND_MF_ACCELERATOR, + RND_MF_SUBMENU, + RND_MF_CHECKED, + RND_MF_UPDATE_ON, + RND_MF_SENSITIVE, + RND_MF_TIP, + RND_MF_ACTION +} rnd_hid_cfg_menufield_t; + +/* Return a field of a submenu and optionally fill in field_name with the + field name expected in the lihata document (useful for error messages) */ +lht_node_t *rnd_hid_cfg_menu_field(const lht_node_t *submenu, rnd_hid_cfg_menufield_t field, const char **field_name); + +/* special value for indicating that the new menu node should be inserted on + top, as the first item (when passed in the ins_after argument */ +extern lht_node_t *rnd_hid_menu_ins_as_first; + +/* expose the menu system for the preferences dialog */ +extern rnd_menu_sys_t rnd_menu_sys; + +#endif Index: trunk/src/librnd/hid/hid_nogui.c =================================================================== --- trunk/src/librnd/hid/hid_nogui.c (nonexistent) +++ trunk/src/librnd/hid/hid_nogui.c (revision 34602) @@ -0,0 +1,522 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 2004 harry eaton + * Copyright (C) 2016..2018 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +/* This is the "gui" that is installed at startup, and is used when + there is no other real GUI to use. For the most part, it just + stops the application from (1) crashing randomly, and (2) doing + gui-specific things when it shouldn't. */ + +#define CRASH(func) fprintf(stderr, "HID error: pcb called GUI function %s without having a GUI available.\n", func); abort() + +static const char rnd_acth_cli[] = "Intenal: CLI frontend action. Do not use directly."; + +static rnd_hid_t nogui_hid; + +typedef struct rnd_hid_gc_s { + int nothing_interesting_here; +} rnd_hid_gc_s; + +static const rnd_export_opt_t *nogui_get_export_options(rnd_hid_t *hid, int *n_ret) +{ + if (n_ret != NULL) + *n_ret = 0; + return NULL; +} + +static void nogui_do_export(rnd_hid_t *hid, rnd_hid_attr_val_t *options) +{ + CRASH("do_export"); +} + +static int nogui_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + CRASH("parse_arguments"); +} + +static void nogui_invalidate_lr(rnd_hid_t *hid, rnd_coord_t l, rnd_coord_t r, rnd_coord_t t, rnd_coord_t b) +{ + CRASH("invalidate_lr"); +} + +static void nogui_invalidate_all(rnd_hid_t *hid) +{ + CRASH("invalidate_all"); +} + +static int nogui_set_layer_group(rnd_hid_t *hid, rnd_layergrp_id_t group, const char *purpose, int purpi, rnd_layer_id_t layer, unsigned int flags, int is_empty, rnd_xform_t **xform) +{ + CRASH("set_layer_group"); + return 0; +} + +static void nogui_end_layer(rnd_hid_t *hid) +{ +} + +static rnd_hid_gc_t nogui_make_gc(rnd_hid_t *hid) +{ + return 0; +} + +static void nogui_destroy_gc(rnd_hid_gc_t gc) +{ +} + +static void nogui_set_drawing_mode(rnd_hid_t *hid, rnd_composite_op_t op, rnd_bool direct, const rnd_box_t *screen) +{ + CRASH("set_drawing_mode"); +} + +static void nogui_render_burst(rnd_hid_t *hid, rnd_burst_op_t op, const rnd_box_t *screen) +{ + /* the HID may decide to ignore this hook */ +} + +static void nogui_set_color(rnd_hid_gc_t gc, const rnd_color_t *name) +{ + CRASH("set_color"); +} + +static void nogui_set_line_cap(rnd_hid_gc_t gc, rnd_cap_style_t style) +{ + CRASH("set_line_cap"); +} + +static void nogui_set_line_width(rnd_hid_gc_t gc, rnd_coord_t width) +{ + CRASH("set_line_width"); +} + +static void nogui_set_draw_xor(rnd_hid_gc_t gc, int xor_) +{ + CRASH("set_draw_xor"); +} + +static void nogui_set_draw_faded(rnd_hid_gc_t gc, int faded) +{ +} + +static void nogui_draw_line(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + CRASH("draw_line"); +} + +static void nogui_draw_arc(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t width, rnd_coord_t height, rnd_angle_t start_angle, rnd_angle_t end_angle) +{ + CRASH("draw_arc"); +} + +static void nogui_draw_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + CRASH("draw_rect"); +} + +static void nogui_fill_circle(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius) +{ + CRASH("fill_circle"); +} + +static void nogui_fill_polygon(rnd_hid_gc_t gc, int n_coords, rnd_coord_t * x, rnd_coord_t * y) +{ + CRASH("fill_polygon"); +} + +static void nogui_fill_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + CRASH("fill_rect"); +} + +static int nogui_shift_is_pressed(rnd_hid_t *hid) +{ + /* This is called from rnd_crosshair_grid_fit() when the design is loaded. */ + return 0; +} + +static int nogui_control_is_pressed(rnd_hid_t *hid) +{ + CRASH("control_is_pressed"); + return 0; +} + +static int nogui_mod1_is_pressed(rnd_hid_t *hid) +{ + CRASH("mod1_is_pressed"); + return 0; +} + +static int nogui_get_coords(rnd_hid_t *hid, const char *msg, rnd_coord_t *x, rnd_coord_t *y, int force) +{ + CRASH("get_coords"); +} + +static void nogui_set_crosshair(rnd_hid_t *hid, rnd_coord_t x, rnd_coord_t y, rnd_set_crosshair_t action) +{ +} + +static rnd_hidval_t nogui_add_timer(rnd_hid_t *hid, void (*func)(rnd_hidval_t user_data), unsigned long milliseconds, rnd_hidval_t user_data) +{ + rnd_hidval_t rv; + CRASH("add_timer"); + rv.lval = 0; + return rv; +} + +static void nogui_stop_timer(rnd_hid_t *hid, rnd_hidval_t timer) +{ + CRASH("stop_timer"); +} + +static rnd_hidval_t nogui_watch_file(rnd_hid_t *hid, int fd, unsigned int condition, rnd_bool (*func) (rnd_hidval_t watch, int fd, unsigned int condition, rnd_hidval_t user_data), rnd_hidval_t user_data) +{ + rnd_hidval_t rv; + CRASH("watch_file"); + rv.lval = 0; + return rv; +} + +static void nogui_unwatch_file(rnd_hid_t *hid, rnd_hidval_t watch) +{ + CRASH("unwatch_file"); +} + +#define MAX_LINE_LENGTH 1024 +static const char *CANCEL = "CANCEL"; +char *rnd_nogui_read_stdin_line(void) +{ + static char buf[MAX_LINE_LENGTH]; + char *s; + int i; + + s = fgets(buf, MAX_LINE_LENGTH, stdin); + if (s == NULL) { + printf("\n"); + return rnd_strdup(CANCEL); + } + + /* Strip any trailing newline characters */ + for (i = strlen(s) - 1; i >= 0; i--) + if (s[i] == '\r' || s[i] == '\n') + s[i] = '\0'; + + if (s[0] == '\0') + return NULL; + + return rnd_strdup(s); +} + +#undef MAX_LINE_LENGTH + +static fgw_error_t rnd_act_cli_PromptFor(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + char *answer; + const char *label, *default_str = "", *title = NULL; + const char *rnd_acts_cli_PromptFor = rnd_acth_cli; + + RND_ACT_CONVARG(1, FGW_STR, cli_PromptFor, label = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, cli_PromptFor, default_str = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, cli_PromptFor, title = argv[3].val.str); + + if (!rnd_conf.rc.quiet) { + char *tmp; + if (title != NULL) + printf("*** %s ***\n", title); + if (default_str) + printf("%s [%s] : ", label, default_str); + else + printf("%s : ", label); + + tmp = rnd_nogui_read_stdin_line(); + if (tmp == NULL) + answer = rnd_strdup((default_str != NULL) ? default_str : ""); + else + answer = tmp; /* always allocated */ + } + else + answer = rnd_strdup(""); + + res->type = FGW_STR | FGW_DYN; + res->val.str = answer; + return 0; +} + +static fgw_error_t rnd_act_cli_MessageBox(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *rnd_acts_cli_MessageBox = rnd_acth_cli; + const char *icon, *title, *label, *txt, *answer; + char *end; + int n, ret; + + res->type = FGW_INT; + if (rnd_conf.rc.quiet) { + cancel:; + res->val.nat_int = -1; + return 0; + } + + RND_ACT_CONVARG(1, FGW_STR, cli_MessageBox, icon = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, cli_MessageBox, title = argv[2].val.str); + RND_ACT_CONVARG(3, FGW_STR, cli_MessageBox, label = argv[3].val.str); + + printf("[%s] *** %s ***\n", icon, title); + + retry:; + printf("%s:\n", label); + for(n = 4; n < argc; n+=2) { + RND_ACT_CONVARG(n+0, FGW_STR, cli_MessageBox, txt = argv[n+0].val.str); + printf(" %d = %s\n", (n - 4)/2+1, txt); + } + printf("\nChose a number from above: "); + fflush(stdout); + answer = rnd_nogui_read_stdin_line(); + if ((answer == CANCEL) || (strcmp(answer, "cancel") == 0)) + goto cancel; + if (answer == NULL) + goto retry; + ret = strtol(answer, &end, 10); + if (((*end != '\0') && (*end != '\n') && (*end != '\r')) || (ret < 1) || (ret > (argc - 3) / 2)) { + printf("\nERROR: please type a number between 1 and %d\n", (argc - 4)/2+1); + goto retry; + } + n = (ret-1)*2+5; + RND_ACT_CONVARG(n, FGW_INT, cli_MessageBox, res->val.nat_int = argv[n].val.nat_int); + return 0; +} + +void *rnd_nogui_attr_dlg_new(rnd_hid_t *hid, const char *id, rnd_hid_attribute_t *attrs_, int n_attrs_, const char *title_, void *caller_data, rnd_bool modal, void (*button_cb)(void *caller_data, rnd_hid_attr_ev_t ev), int defx, int defy, int minx, int miny) +{ + CRASH("attr_dlg_new"); +} + +static int nogui_attr_dlg_run(void *hid_ctx) +{ + CRASH("attr_dlg_run"); +} + +static void nogui_attr_dlg_raise(void *hid_ctx) +{ + CRASH("attr_dlg_raise"); +} + +static void nogui_attr_dlg_close(void *hid_ctx) +{ + CRASH("attr_dlg_close"); +} + +static void nogui_attr_dlg_free(void *hid_ctx) +{ + CRASH("attr_dlg_free"); +} + +static void nogui_attr_dlg_property(void *hid_ctx, rnd_hat_property_t prop, const rnd_hid_attr_val_t *val) +{ + CRASH("attr_dlg_dlg_property"); +} + +static void nogui_beep(rnd_hid_t *hid) +{ + putchar(7); + fflush(stdout); +} + +int rnd_nogui_progress(long so_far, long total, const char *message) +{ + static int on = 0; + static double nextt; + double now; + + if (rnd_conf.rc.quiet) + return 0; + if (message == NULL) { + if ((on) && (rnd_conf.rc.verbose >= RND_MSG_INFO)) + fprintf(stderr, "progress: finished\n"); + on = 0; + } + else { + if ((rnd_conf.rc.verbose >= RND_MSG_INFO) || (rnd_gui != &nogui_hid)) { + now = rnd_dtime(); + if (now >= nextt) { + fprintf(stderr, "progress: %ld/%ld %s\n", so_far, total, message); + nextt = now + 0.2; + } + } + on = 1; + } + return 0; +} + +static int clip_warn(void) +{ + static int warned = 0; + if (!warned) { + rnd_message(RND_MSG_ERROR, "The current GUI HID does not support clipboard.\nClipboard is emulated, not shared withother programs\n"); + warned = 1; + } + return 0; +} + +static void *clip_data = NULL; +static size_t clip_len; +static rnd_hid_clipfmt_t clip_format; + +static int nogui_clip_set(rnd_hid_t *hid, rnd_hid_clipfmt_t format, const void *data, size_t len) +{ + free(clip_data); + clip_data = malloc(len); + if (clip_data != NULL) { + memcpy(clip_data, data, len); + clip_len = len; + clip_format = format; + } + else + clip_data = NULL; + return clip_warn(); +} + +static int nogui_clip_get(rnd_hid_t *hid, rnd_hid_clipfmt_t *format, void **data, size_t *len) +{ + if (clip_data == NULL) { + *data = NULL; + clip_warn(); + return -1; + } + *data = malloc(clip_len); + if (*data == NULL) { + *data = NULL; + return -1; + } + + memcpy(*data, clip_data, clip_len); + *format = clip_format; + *len = clip_len; + return clip_warn(); +} + +static void nogui_clip_free(rnd_hid_t *hid, rnd_hid_clipfmt_t format, void *data, size_t len) +{ + free(data); +} + +static void nogui_reg_mouse_cursor(rnd_hid_t *hid, int idx, const char *name, const unsigned char *pixel, const unsigned char *mask) +{ +} + +static void nogui_set_mouse_cursor(rnd_hid_t *hid, int idx) +{ +} + +static void nogui_set_top_title(rnd_hid_t *hid, const char *title) +{ +} + +void rnd_hid_nogui_init(rnd_hid_t * hid) +{ + hid->get_export_options = nogui_get_export_options; + hid->do_export = nogui_do_export; + hid->parse_arguments = nogui_parse_arguments; + hid->invalidate_lr = nogui_invalidate_lr; + hid->invalidate_all = nogui_invalidate_all; + hid->set_layer_group = nogui_set_layer_group; + hid->end_layer = nogui_end_layer; + hid->make_gc = nogui_make_gc; + hid->destroy_gc = nogui_destroy_gc; + hid->set_drawing_mode = nogui_set_drawing_mode; + hid->render_burst = nogui_render_burst; + hid->set_color = nogui_set_color; + hid->set_line_cap = nogui_set_line_cap; + hid->set_line_width = nogui_set_line_width; + hid->set_draw_xor = nogui_set_draw_xor; + hid->set_draw_faded = nogui_set_draw_faded; + hid->draw_line = nogui_draw_line; + hid->draw_arc = nogui_draw_arc; + hid->draw_rect = nogui_draw_rect; + hid->fill_circle = nogui_fill_circle; + hid->fill_polygon = nogui_fill_polygon; + hid->fill_rect = nogui_fill_rect; + hid->shift_is_pressed = nogui_shift_is_pressed; + hid->control_is_pressed = nogui_control_is_pressed; + hid->mod1_is_pressed = nogui_mod1_is_pressed; + hid->get_coords = nogui_get_coords; + hid->set_crosshair = nogui_set_crosshair; + hid->add_timer = nogui_add_timer; + hid->stop_timer = nogui_stop_timer; + hid->watch_file = nogui_watch_file; + hid->unwatch_file = nogui_unwatch_file; + hid->attr_dlg_new = rnd_nogui_attr_dlg_new; + hid->attr_dlg_run = nogui_attr_dlg_run; + hid->attr_dlg_raise = nogui_attr_dlg_raise; + hid->attr_dlg_close = nogui_attr_dlg_close; + hid->attr_dlg_free = nogui_attr_dlg_free; + hid->attr_dlg_property = nogui_attr_dlg_property; + hid->beep = nogui_beep; + hid->clip_set = nogui_clip_set; + hid->clip_get = nogui_clip_get; + hid->clip_free = nogui_clip_free; + hid->set_mouse_cursor = nogui_set_mouse_cursor; + hid->reg_mouse_cursor = nogui_reg_mouse_cursor; + hid->set_top_title = nogui_set_top_title; +} + + +rnd_hid_t *rnd_hid_nogui_get_hid(void) +{ + memset(&nogui_hid, 0, sizeof(rnd_hid_t)); + + nogui_hid.struct_size = sizeof(rnd_hid_t); + nogui_hid.name = "nogui"; + nogui_hid.description = "Default GUI when no other GUI is present. " "Does nothing."; + + rnd_hid_nogui_init(&nogui_hid); + + return &nogui_hid; +} + + +static rnd_action_t cli_dlg_action_list[] = { + {"cli_PromptFor", rnd_act_cli_PromptFor, rnd_acth_cli, NULL}, + {"cli_MessageBox", rnd_act_cli_MessageBox, rnd_acth_cli, NULL} +}; + + +void rnd_hid_nogui_init2(void) +{ + RND_REGISTER_ACTIONS(cli_dlg_action_list, NULL); +} + Index: trunk/src/librnd/hid/hid_nogui.h =================================================================== --- trunk/src/librnd/hid/hid_nogui.h (nonexistent) +++ trunk/src/librnd/hid/hid_nogui.h (revision 34602) @@ -0,0 +1,16 @@ +#ifndef RND_HID_COMMON_HIDNOGUI_H +#define RND_HID_COMMON_HIDNOGUI_H + +void rnd_hid_nogui_init(rnd_hid_t * hid); +rnd_hid_t *rnd_hid_nogui_get_hid(void); + +/* For checking if attr dialogs are not available: */ +void *rnd_nogui_attr_dlg_new(rnd_hid_t *hid, const char *id, rnd_hid_attribute_t *attrs_, int n_attrs_, const char *title_, void *caller_data, rnd_bool modal, void (*button_cb)(void *caller_data, rnd_hid_attr_ev_t ev), int defx, int defy, int minx, int miny); + +int rnd_nogui_progress(long so_far, long total, const char *message); + +/* Return a line of user input text, stripped of any newline characters. + Returns NULL if the user simply presses enter, or otherwise gives no input. */ +char *rnd_nogui_read_stdin_line(void); + +#endif Index: trunk/src/librnd/hid/pixmap.c =================================================================== --- trunk/src/librnd/hid/pixmap.c (nonexistent) +++ trunk/src/librnd/hid/pixmap.c (revision 34602) @@ -0,0 +1,205 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include +#include +#include + +#include +#include +#include + +static unsigned int pixmap_hash_(const void *key_, int pixels) +{ + rnd_pixmap_t *key = (rnd_pixmap_t *)key_; + unsigned int i; + + if (pixels && key->hash_valid) + return key->hash; + + i = longhash(key->sx); + i ^= longhash(key->sy); + i ^= longhash((long)(key->tr_rot * 1000.0) + (((long)key->tr_xmirror) << 3) + (((long)key->tr_ymirror) << 4)); + i ^= longhash((long)(key->tr_xscale * 1000.0) + (long)(key->tr_yscale * 1000.0)); + if (key->transp_valid) { + i ^= 0x900; + i ^= ((unsigned int)key->tr) << 6; + i ^= ((unsigned int)key->tg) << 14; + i ^= ((unsigned int)key->tb) << 22; + } + if (pixels) { + i ^= jenhash(key->p, key->size); + key->hash = i; + key->hash_valid = 1; + } + else + i ^= longhash(key->neutral_oid); + return i; +} + +unsigned int rnd_pixmap_hash_meta(const void *key) +{ + return pixmap_hash_(key, 0); +} + +unsigned int rnd_pixmap_hash_pixels(const void *key) +{ + return pixmap_hash_(key, 1); +} + + +static int pixmap_eq_(const void *keya_, const void *keyb_, int pixels) +{ + const rnd_pixmap_t *keya = keya_, *keyb = keyb_; + if ((keya->transp_valid) || (keyb->transp_valid)) { + if (keya->transp_valid != keyb->transp_valid) + return 0; + if ((keya->tr != keyb->tr) || (keya->tg != keyb->tg) || (keya->tb != keyb->tb)) + return 0; + } + if ((keya->tr_xmirror != keyb->tr_xmirror) || (keya->tr_ymirror != keyb->tr_ymirror)) + return 0; + if ((keya->tr_rot != keyb->tr_rot) || (keya->tr_xscale != keyb->tr_xscale) || (keya->tr_yscale != keyb->tr_yscale)) + return 0; + if ((keya->sx != keyb->sx) || (keya->sy != keyb->sy)) + return 0; + if (pixels) + return (memcmp(keya->p, keyb->p, keya->size) == 0); + else + return (keya->neutral_oid == keyb->neutral_oid); +} + +int rnd_pixmap_eq_meta(const void *keya, const void *keyb) +{ + return pixmap_eq_(keya, keyb, 0); +} + +int rnd_pixmap_eq_pixels(const void *keya, const void *keyb) +{ + return pixmap_eq_(keya, keyb, 1); +} + + +static rnd_pixmap_import_t *rnd_pixmap_chain; + +void rnd_pixmap_reg_import(const rnd_pixmap_import_t *imp, const char *cookie) +{ + rnd_pixmap_import_t *i = malloc(sizeof(rnd_pixmap_import_t)); + memcpy(i, imp, sizeof(rnd_pixmap_import_t)); + i->cookie = cookie; + i->next = rnd_pixmap_chain; + rnd_pixmap_chain = i; +} + +static void rnd_pixmap_unreg_(rnd_pixmap_import_t *i, rnd_pixmap_import_t *prev) +{ + if (prev == NULL) + rnd_pixmap_chain = i->next; + else + prev->next = i->next; + free(i); +} + +void rnd_pixmap_unreg_import_all(const char *cookie) +{ + rnd_pixmap_import_t *i, *prev = NULL, *next; + for(i = rnd_pixmap_chain; i != NULL; i = next) { + next = i->next; + if (i->cookie == cookie) + rnd_pixmap_unreg_(i, prev); + else + prev = i; + } +} + +void rnd_pixmap_uninit(void) +{ + rnd_pixmap_import_t *i; + for(i = rnd_pixmap_chain; i != NULL; i = i->next) + rnd_message(RND_MSG_ERROR, "rnd_pixmap_chain is not empty: %s. Fix your plugins!\n", i->cookie); +} + +int rnd_old_pixmap_load(rnd_hidlib_t *hidlib, rnd_pixmap_t *pxm, const char *fn) +{ + rnd_pixmap_import_t *i; + for(i = rnd_pixmap_chain; i != NULL; i = i->next) + if (i->load(hidlib, pxm, fn) == 0) + return 0; + return -1; +} + +rnd_pixmap_t *rnd_pixmap_load(rnd_hidlib_t *hidlib, const char *fn) +{ + rnd_pixmap_t *p = calloc(sizeof(rnd_pixmap_t), 1); + if (rnd_old_pixmap_load(hidlib, p, fn) == 0) + return p; + free(p); + return NULL; +} + +rnd_pixmap_t *rnd_pixmap_alloc(rnd_hidlib_t *hidlib, long sx, long sy) +{ + rnd_pixmap_t *p = calloc(sizeof(rnd_pixmap_t), 1); + p->sx = sx; + p->sy = sy; + p->size = sx * sy * 3; + p->p = malloc(p->size); + return p; +} + +rnd_pixmap_t *rnd_pixmap_dup(rnd_hidlib_t *hidlib, const rnd_pixmap_t *pxm) +{ + rnd_pixmap_t *r = malloc(sizeof(rnd_pixmap_t)); + memcpy(r, pxm, sizeof(rnd_pixmap_t)); + r->p = malloc(pxm->size); + memcpy(r->p, pxm->p, pxm->size); + r->hid_data = NULL; + r->hid_data_valid = 0; + r->refco = 0; + return r; +} + +void rnd_pixmap_free_hid_data(rnd_pixmap_t *pxm) +{ + if ((rnd_render != NULL) && (rnd_render->uninit_pixmap != NULL)) + rnd_render->uninit_pixmap(rnd_render, pxm); + pxm->hid_data_valid = 0; + pxm->hid_data = NULL; +} + +void rnd_pixmap_free_fields(rnd_pixmap_t *pxm) +{ + rnd_pixmap_free_hid_data(pxm); + free(pxm->p); +} + +void rnd_pixmap_free(rnd_pixmap_t *pxm) +{ + rnd_pixmap_free_fields(pxm); + free(pxm); +} Index: trunk/src/librnd/hid/pixmap.h =================================================================== --- trunk/src/librnd/hid/pixmap.h (nonexistent) +++ trunk/src/librnd/hid/pixmap.h (revision 34602) @@ -0,0 +1,103 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* generic pixmap (low level, part of the hidlib): draw, calculate hash, compare */ + +#ifndef RND_PIXMAP_H +#define RND_PIXMAP_H + +#include + +typedef struct rnd_pixmap_import_s rnd_pixmap_import_t; + +struct rnd_pixmap_import_s { + /* configured by the caller at registration */ + const char *name; + int (*load)(rnd_hidlib_t *hidlib, rnd_pixmap_t *pxm, const char *fn); + + /* filled in by code */ + rnd_pixmap_import_t *next; + const char *cookie; + + /* Spare: see doc/developer/spare.txt */ + void (*spare_f1)(void), (*spare_f2)(void); + long spare_l1, spare_l2, spare_l3, spare_l4; + void *spare_p1, *spare_p2, *spare_p3, *spare_p4; + double spare_d1, spare_d2, spare_d3, spare_d4; + rnd_coord_t spare_c1, spare_c2, spare_c3, spare_c4; +}; + +struct rnd_pixmap_s { + long size; /* total size of the array in memory (sx*sy*3) */ + long sx, sy; /* x and y dimensions */ + unsigned char tr, tg, tb; /* color of the transparent pixel if has_transp is 1 */ + unsigned int hash; /* precalculated hash value */ + unsigned char *p; /* pixel array in r,g,b rows of sx long each */ + unsigned long neutral_oid; /* UID of the pixmap in neutral position */ + unsigned long refco; /* optional reference counting */ + + void *hid_data; /* HID's version of the pixmap */ + + /* transformation info */ + rnd_angle_t tr_rot; /* rotation angle (0 if not transformed) */ + double tr_xscale; + double tr_yscale; + unsigned tr_xmirror:1; /* whether the pixmap is mirrored along the x axis (vertical mirror) */ + unsigned tr_ymirror:1; /* whether the pixmap is mirrored along the y axis (horizontal mirror) */ + + unsigned has_transp:1; /* 1 if the pixmap has any transparent pixels */ + unsigned transp_valid:1; /* 1 if transparent pixel is available */ + unsigned hash_valid:1; /* 1 if the has value has been calculated */ + unsigned hid_data_valid:1; /* 1 if hid_data is already generated and no data changed since - maintained by core, HIDs don't need to check */ + + /* Spare: see doc/developer/spare.txt */ + void (*spare_f1)(void), (*spare_f2)(void); + long spare_l1, spare_l2, spare_l3, spare_l4; + void *spare_p1, *spare_p2, *spare_p3, *spare_p4; + double spare_d1, spare_d2, spare_d3, spare_d4; + rnd_coord_t spare_c1, spare_c2, spare_c3, spare_c4; +}; + +void rnd_pixmap_reg_import(const rnd_pixmap_import_t *imp, const char *cookie); +void rnd_pixmap_unreg_import_all(const char *cookie); +void rnd_pixmap_uninit(void); + +int rnd_old_pixmap_load(rnd_hidlib_t *hidlib, rnd_pixmap_t *pxm, const char *fn); /* legacy API, should be removed */ +rnd_pixmap_t *rnd_pixmap_load(rnd_hidlib_t *hidlib, const char *fn); +rnd_pixmap_t *rnd_pixmap_alloc(rnd_hidlib_t *hidlib, long sx, long sy); +rnd_pixmap_t *rnd_pixmap_dup(rnd_hidlib_t *hidlib, const rnd_pixmap_t *pxm); + +unsigned int rnd_pixmap_hash_meta(const void *key); +unsigned int rnd_pixmap_hash_pixels(const void *key); +int rnd_pixmap_eq_meta(const void *keya, const void *keyb); +int rnd_pixmap_eq_pixels(const void *keya, const void *keyb); + + +void rnd_pixmap_free_hid_data(rnd_pixmap_t *pxm); +void rnd_pixmap_free_fields(rnd_pixmap_t *pxm); +void rnd_pixmap_free(rnd_pixmap_t *pxm); + +#endif Index: trunk/src/librnd/hid/tool.c =================================================================== --- trunk/src/librnd/hid/tool.c (nonexistent) +++ trunk/src/librnd/hid/tool.c (revision 34602) @@ -0,0 +1,370 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * Copyright (C) 2017,2019,2020 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include + +#include +#include +#include +#include +#include + +#define RND_MAX_MODESTACK_DEPTH 16 /* maximum depth of mode stack */ + +rnd_bool rnd_tool_is_saved = rnd_false; + +vtp0_t rnd_tools; + +rnd_toolid_t rnd_tool_prev_id; +rnd_toolid_t rnd_tool_next_id; +static int save_position = 0; +static int save_stack[RND_MAX_MODESTACK_DEPTH]; + +static void init_current_tool(void); +static void uninit_current_tool(void); + +static int tool_select_lock = 0; + +void rnd_tool_init(void) +{ + vtp0_init(&rnd_tools); +} + +void rnd_tool_uninit(void) +{ + while(vtp0_len(&rnd_tools) != 0) { + const rnd_tool_t *tool = rnd_tool_get(0); + rnd_message(RND_MSG_WARNING, "Unregistered tool: %s of %s; check your plugins, fix them to unregister their tools!\n", tool->name, tool->cookie); + rnd_tool_unreg_by_cookie(tool->cookie); + } + vtp0_uninit(&rnd_tools); +} + +void rnd_tool_chg_mode(rnd_hidlib_t *hl) +{ + if ((hl != NULL) && (!tool_select_lock)) + rnd_tool_select_by_id(hl, rnd_conf.editor.mode); +} + +rnd_toolid_t rnd_tool_reg(rnd_tool_t *tool, const char *cookie) +{ + rnd_toolid_t id; + if (rnd_tool_lookup(tool->name) != RND_TOOLID_INVALID) /* don't register two tools with the same name */ + return -1; + tool->cookie = cookie; + id = rnd_tools.used; + vtp0_append(&rnd_tools, (void *)tool); + if (rnd_gui != NULL) + rnd_gui->reg_mouse_cursor(rnd_gui, id, tool->cursor.name, tool->cursor.pixel, tool->cursor.mask); + rnd_event(NULL, RND_EVENT_TOOL_REG, "p", tool); + return id; +} + +void rnd_tool_unreg_by_cookie(const char *cookie) +{ + rnd_toolid_t n; + for(n = 0; n < vtp0_len(&rnd_tools); n++) { + const rnd_tool_t *tool = (const rnd_tool_t *)rnd_tools.array[n]; + if (tool->cookie == cookie) { + vtp0_remove(&rnd_tools, n, 1); + n--; + } + } +} + +rnd_toolid_t rnd_tool_lookup(const char *name) +{ + rnd_toolid_t n; + for(n = 0; n < vtp0_len(&rnd_tools); n++) { + const rnd_tool_t *tool = (const rnd_tool_t *)rnd_tools.array[n]; + if (strcmp(tool->name, name) == 0) + return n; + } + return RND_TOOLID_INVALID; +} + +int rnd_tool_select_by_name(rnd_hidlib_t *hidlib, const char *name) +{ + rnd_toolid_t id = rnd_tool_lookup(name); + if (id == RND_TOOLID_INVALID) + return -1; + return rnd_tool_select_by_id(hidlib, id); +} + +int rnd_tool_select_by_id(rnd_hidlib_t *hidlib, rnd_toolid_t id) +{ + char id_s[32]; + static rnd_bool recursing = rnd_false; + int ok = 1; + + if ((id < 0) || (id > vtp0_len(&rnd_tools))) + return -1; + + /* protect the cursor while changing the mode + * perform some additional stuff depending on the new mode + * reset 'state' of attached objects + */ + if (recursing) + return -1; + + /* check if the UI logic allows picking that tool */ + rnd_event(hidlib, RND_EVENT_TOOL_SELECT_PRE, "pi", &ok, id); + if (ok == 0) + id = rnd_conf.editor.mode; + + recursing = rnd_true; + + rnd_tool_prev_id = rnd_conf.editor.mode; + rnd_tool_next_id = id; + uninit_current_tool(); + sprintf(id_s, "%d", id); + tool_select_lock = 1; + rnd_conf_set(RND_CFR_DESIGN, "editor/mode", -1, id_s, RND_POL_OVERWRITE); + tool_select_lock = 0; + init_current_tool(); + + recursing = rnd_false; + + if (rnd_gui != NULL) + rnd_gui->set_mouse_cursor(rnd_gui, id); + return 0; +} + +int rnd_tool_select_highest(rnd_hidlib_t *hidlib) +{ + rnd_toolid_t n, bestn = RND_TOOLID_INVALID; + unsigned int bestp = -1; + for(n = 0; n < vtp0_len(&rnd_tools) && (bestp > 0); n++) { + const rnd_tool_t *tool = (const rnd_tool_t *)rnd_tools.array[n]; + if (tool->priority < bestp) { + bestp = tool->priority; + bestn = n; + } + } + if (bestn == RND_TOOLID_INVALID) + return -1; + return rnd_tool_select_by_id(hidlib, bestn); +} + +int rnd_tool_save(rnd_hidlib_t *hidlib) +{ + save_stack[save_position] = rnd_conf.editor.mode; + if (save_position < RND_MAX_MODESTACK_DEPTH - 1) + save_position++; + else + return -1; + return 0; +} + +int rnd_tool_restore(rnd_hidlib_t *hidlib) +{ + if (save_position == 0) { + rnd_message(RND_MSG_ERROR, "hace: underflow of restore mode\n"); + return -1; + } + return rnd_tool_select_by_id(hidlib, save_stack[--save_position]); +} + +void rnd_tool_gui_init(void) +{ + rnd_toolid_t n; + rnd_tool_t **tool; + + if (rnd_gui == NULL) + return; + + for(n = 0, tool = (rnd_tool_t **)rnd_tools.array; n < rnd_tools.used; n++,tool++) + if (*tool != NULL) + rnd_gui->reg_mouse_cursor(rnd_gui, n, (*tool)->cursor.name, (*tool)->cursor.pixel, (*tool)->cursor.mask); +} + +/**** current tool function wrappers ****/ +#define wrap(func, err_ret, prefix, args) \ + do { \ + const rnd_tool_t *tool; \ + if ((rnd_conf.editor.mode < 0) || (rnd_conf.editor.mode >= vtp0_len(&rnd_tools))) \ + { err_ret; } \ + tool = (const rnd_tool_t *)rnd_tools.array[rnd_conf.editor.mode]; \ + if (tool->func == NULL) \ + { err_ret; } \ + prefix tool->func args; \ + } while(0) + +#define wrap_void(func, args) wrap(func, return, ;, args) +#define wrap_retv(func, err_ret, args) wrap(func, err_ret, return, args) + +static void init_current_tool(void) +{ + wrap_void(init, ()); +} + +static void uninit_current_tool(void) +{ + wrap_void(uninit, ()); +} + +void rnd_tool_press(rnd_hidlib_t *hidlib) +{ + wrap_void(press, (hidlib)); +} + +void rnd_tool_release(rnd_hidlib_t *hidlib) +{ + wrap_void(release, (hidlib)); +} + +void rnd_tool_adjust_attached(rnd_hidlib_t *hl) +{ + wrap_void(adjust_attached, (hl)); +} + +void rnd_tool_draw_attached(rnd_hidlib_t *hl) +{ + wrap_void(draw_attached, (hl)); +} + +rnd_bool rnd_tool_undo_act(rnd_hidlib_t *hl) +{ + wrap_retv(undo_act, return rnd_true, (hl)); +} + +rnd_bool rnd_tool_redo_act(rnd_hidlib_t *hl) +{ + wrap_retv(redo_act, return rnd_true, (hl)); +} + +static void do_release(rnd_hidlib_t *hidlib) +{ + if (rnd_conf.temp.click_cmd_entry_active && (rnd_cli_mouse(hidlib, 0) == 0)) + return; + + hidlib->tool_grabbed.status = rnd_false; + + rnd_tool_release(hidlib); + + if (rnd_tool_is_saved) + rnd_tool_restore(hidlib); + rnd_tool_is_saved = rnd_false; + rnd_event(hidlib, RND_EVENT_TOOL_RELEASE, NULL); +} + +void rnd_tool_do_press(rnd_hidlib_t *hidlib) +{ + if (rnd_conf.temp.click_cmd_entry_active && (rnd_cli_mouse(hidlib, 1) == 0)) + return; + + hidlib->tool_grabbed.X = hidlib->tool_x; + hidlib->tool_grabbed.Y = hidlib->tool_y; + + rnd_tool_press(hidlib); + rnd_event(hidlib, RND_EVENT_TOOL_PRESS, NULL); +} + + +static const char rnd_acts_Tool[] = + "Tool(Arc|Arrow|Copy|InsertPoint|Line|Lock|Move|None|PasteBuffer)\n" + "Tool(Poly|Rectangle|Remove|Rotate|Text|Thermal|Via)\n" "Tool(Press|Release|Cancel|Stroke)\n" "Tool(Save|Restore)"; + +static const char rnd_acth_Tool[] = "Change or use the tool mode."; +/* DOC: tool.html */ +static fgw_error_t rnd_act_Tool(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_hidlib_t *hidlib = RND_ACT_HIDLIB; + const char *cmd; + RND_ACT_IRES(0); + RND_ACT_CONVARG(1, FGW_STR, Tool, cmd = argv[1].val.str); + + /* it is okay to use crosshair directly here, the mode command is called from a click when it needs coords */ + hidlib->tool_x = hidlib->ch_x; + hidlib->tool_y = hidlib->ch_y; + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_false); + if (rnd_strcasecmp(cmd, "Cancel") == 0) { + rnd_tool_select_by_id(RND_ACT_HIDLIB, rnd_conf.editor.mode); + } + else if (rnd_strcasecmp(cmd, "Escape") == 0) { + const rnd_tool_t *t; + escape:; + t = rnd_tool_get(rnd_conf.editor.mode); + if ((t == NULL) || (t->escape == NULL)) { + rnd_tool_select_by_name(RND_ACT_HIDLIB, "arrow"); + hidlib->tool_hit = hidlib->tool_click = 0; /* if the mouse button is still pressed, don't start selecting a box */ + } + else + t->escape(RND_ACT_HIDLIB); + } + else if ((rnd_strcasecmp(cmd, "Press") == 0) || (rnd_strcasecmp(cmd, "Notify") == 0)) { + rnd_tool_do_press(RND_ACT_HIDLIB); + } + else if (rnd_strcasecmp(cmd, "Release") == 0) { + if (rnd_conf.editor.enable_stroke) { + int handled = 0; + rnd_event(RND_ACT_HIDLIB, RND_EVENT_STROKE_FINISH, "p", &handled); + if (handled) { + /* Ugly hack: returning 1 here will break execution of the + action script, so actions after this one could do things + that would be executed only after non-recognized gestures */ + do_release(RND_ACT_HIDLIB); + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); + return 1; + } + } + do_release(RND_ACT_HIDLIB); + } + else if (rnd_strcasecmp(cmd, "Stroke") == 0) { + if (rnd_conf.editor.enable_stroke) + rnd_event(RND_ACT_HIDLIB, RND_EVENT_STROKE_START, "cc", hidlib->tool_x, hidlib->tool_y); + else + goto escape; /* Right mouse button restarts drawing mode. */ + } + else if (rnd_strcasecmp(cmd, "Restore") == 0) { /* restore the last saved tool */ + rnd_tool_restore(RND_ACT_HIDLIB); + } + else if (rnd_strcasecmp(cmd, "Save") == 0) { /* save currently selected tool */ + rnd_tool_save(RND_ACT_HIDLIB); + } + else { + if (rnd_tool_select_by_name(RND_ACT_HIDLIB, cmd) != 0) + rnd_message(RND_MSG_ERROR, "No such tool: '%s'\n", cmd); + } + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); + return 0; +} + +static rnd_action_t tool_action_list[] = { + {"Tool", rnd_act_Tool, rnd_acth_Tool, rnd_acts_Tool}, + {"Mode", rnd_act_Tool, rnd_acth_Tool, rnd_acts_Tool} +}; + +void rnd_tool_act_init2(void) +{ + RND_REGISTER_ACTIONS(tool_action_list, NULL); +} + + Index: trunk/src/librnd/hid/tool.h =================================================================== --- trunk/src/librnd/hid/tool.h (nonexistent) +++ trunk/src/librnd/hid/tool.h (revision 34602) @@ -0,0 +1,139 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017,2020 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef RND_TOOL_H +#define RND_TOOL_H + +#include + +#include +#include + +typedef int rnd_toolid_t; +#define RND_TOOLID_INVALID (-1) + +typedef struct rnd_tool_cursor_s { + const char *name; /* if no custom graphics is provided, use a stock cursor by name */ + const unsigned char *pixel; /* 32 bytes: 16*16 bitmap */ + const unsigned char *mask; /* 32 bytes: 16*16 mask (1 means draw pixel) */ +} rnd_tool_cursor_t; + +#define RND_TOOL_CURSOR_NAMED(name) { name, NULL, NULL } +#define RND_TOOL_CURSOR_XBM(pixel, mask) { NULL, pixel, mask } + +typedef enum rnd_tool_flags_e { + RND_TLF_AUTO_TOOLBAR = 1 /* automatically insert in the toolbar if the menu file didn't do it */ +} rnd_tool_flags_t; + +typedef struct rnd_tool_s { + const char *name; /* textual name of the tool */ + const char *help; /* help/tooltip that explains the feature */ + const char *cookie; /* plugin cookie _pointer_ of the registrar (comparision is pointer based, not strcmp) */ + unsigned int priority; /* lower values are higher priorities; escaping mode will try to select the highest prio tool */ + const char **icon; /* XPM for the tool buttons */ + rnd_tool_cursor_t cursor; /* name of the mouse cursor to switch to when the tool is activated */ + rnd_tool_flags_t flags; + + /* tool implementation */ + void (*init)(void); + void (*uninit)(void); + void (*press)(rnd_hidlib_t *hl); + void (*release)(rnd_hidlib_t *hl); + void (*adjust_attached)(rnd_hidlib_t *hl); + void (*draw_attached)(rnd_hidlib_t *hl); + rnd_bool (*undo_act)(rnd_hidlib_t *hl); + rnd_bool (*redo_act)(rnd_hidlib_t *hl); + void (*escape)(rnd_hidlib_t *hl); + + unsigned long user_flags; + + /* Spare: see doc/developer/spare.txt */ + void (*spare_f1)(void), (*spare_f2)(void); + long spare_l1, spare_l2, spare_l3, spare_l4; + void *spare_p1, *spare_p2, *spare_p3, *spare_p4; + double spare_d1, spare_d2, spare_d3, spare_d4; + rnd_coord_t spare_c1, spare_c2, spare_c3, spare_c4; +} rnd_tool_t; + +extern vtp0_t rnd_tools; +extern rnd_toolid_t rnd_tool_prev_id; +extern rnd_toolid_t rnd_tool_next_id; +extern rnd_bool rnd_tool_is_saved; + +/* (un)initialize the tool subsystem */ +void rnd_tool_init(void); +void rnd_tool_uninit(void); + +/* call this when the mode (tool) config node changes */ +void rnd_tool_chg_mode(rnd_hidlib_t *hl); + +/* Insert a new tool in rnd_tools; returns -1 on failure */ +rnd_toolid_t rnd_tool_reg(rnd_tool_t *tool, const char *cookie); + +/* Unregister all tools that has matching cookie */ +void rnd_tool_unreg_by_cookie(const char *cookie); + +/* Return the ID of a tool by name; returns -1 on error */ +rnd_toolid_t rnd_tool_lookup(const char *name); + + +/* Select a tool by name, id or pick the highest prio tool; return 0 on success */ +int rnd_tool_select_by_name(rnd_hidlib_t *hidlib, const char *name); +int rnd_tool_select_by_id(rnd_hidlib_t *hidlib, rnd_toolid_t id); +int rnd_tool_select_highest(rnd_hidlib_t *hidlib); + +int rnd_tool_save(rnd_hidlib_t *hidlib); +int rnd_tool_restore(rnd_hidlib_t *hidlib); + +/* Called after GUI_INIT; registers all mouse cursors in the GUI */ +void rnd_tool_gui_init(void); + + +/**** Tool function wrappers; calling these will operate on the current tool + as defined in rnd_conf.editor.mode ****/ + +void rnd_tool_press(rnd_hidlib_t *hidlib); +void rnd_tool_release(rnd_hidlib_t *hidlib); +void rnd_tool_adjust_attached(rnd_hidlib_t *hl); +void rnd_tool_draw_attached(rnd_hidlib_t *hl); +rnd_bool rnd_tool_undo_act(rnd_hidlib_t *hl); +rnd_bool rnd_tool_redo_act(rnd_hidlib_t *hl); + + +/* fake a click */ +void rnd_tool_do_press(rnd_hidlib_t *hidlib); + +/**** Low level, for internal use ****/ + +/* Get the tool pointer of a tool by id */ +RND_INLINE const rnd_tool_t *rnd_tool_get(long id) +{ + rnd_tool_t **tp = (rnd_tool_t **)vtp0_get(&rnd_tools, id, 0); + if (tp == NULL) return NULL; + return *tp; +} + +#endif Index: trunk/src/librnd/plugins/hid_batch/batch.c =================================================================== --- trunk/src/librnd/plugins/hid_batch/batch.c (revision 34601) +++ trunk/src/librnd/plugins/hid_batch/batch.c (revision 34602) @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include #include @@ -12,10 +12,10 @@ #include #include -#include +#include #include -#include -#include +#include +#include static const char *batch_cookie = "batch HID"; Index: trunk/src/librnd/plugins/hid_gtk2_gdk/gtkhid-gdk.c =================================================================== --- trunk/src/librnd/plugins/hid_gtk2_gdk/gtkhid-gdk.c (revision 34601) +++ trunk/src/librnd/plugins/hid_gtk2_gdk/gtkhid-gdk.c (revision 34602) @@ -3,11 +3,11 @@ #include -#include +#include #include #include -#include -#include +#include +#include #include #include Index: trunk/src/librnd/plugins/hid_gtk2_gdk/gtkhid-main.c =================================================================== --- trunk/src/librnd/plugins/hid_gtk2_gdk/gtkhid-main.c (revision 34601) +++ trunk/src/librnd/plugins/hid_gtk2_gdk/gtkhid-main.c (revision 34602) @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include Index: trunk/src/librnd/plugins/hid_gtk2_gl/gtkhid-gl.c =================================================================== --- trunk/src/librnd/plugins/hid_gtk2_gl/gtkhid-gl.c (revision 34601) +++ trunk/src/librnd/plugins/hid_gtk2_gl/gtkhid-gl.c (revision 34602) @@ -3,9 +3,9 @@ #include #include -#include +#include #include -#include +#include #include #include Index: trunk/src/librnd/plugins/hid_gtk2_gl/gtkhid-main.c =================================================================== --- trunk/src/librnd/plugins/hid_gtk2_gl/gtkhid-main.c (revision 34601) +++ trunk/src/librnd/plugins/hid_gtk2_gl/gtkhid-main.c (revision 34602) @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include Index: trunk/src/librnd/plugins/hid_gtk4_gl/gtkhid-main.c =================================================================== --- trunk/src/librnd/plugins/hid_gtk4_gl/gtkhid-main.c (revision 34601) +++ trunk/src/librnd/plugins/hid_gtk4_gl/gtkhid-main.c (revision 34602) @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include Index: trunk/src/librnd/plugins/hid_lesstif/dialogs.c =================================================================== --- trunk/src/librnd/plugins/hid_lesstif/dialogs.c (revision 34601) +++ trunk/src/librnd/plugins/hid_lesstif/dialogs.c (revision 34602) @@ -15,11 +15,11 @@ #include #include -#include +#include #include "lesstif.h" -#include +#include #include -#include +#include #include "ltf_stdarg.h" #include #include "dialogs.h" Index: trunk/src/librnd/plugins/hid_lesstif/dlg_attr_misc.c =================================================================== --- trunk/src/librnd/plugins/hid_lesstif/dlg_attr_misc.c (revision 34601) +++ trunk/src/librnd/plugins/hid_lesstif/dlg_attr_misc.c (revision 34602) @@ -32,7 +32,7 @@ #include "wt_xpm.h" #include "wt_colorbtn.h" -#include +#include #include Index: trunk/src/librnd/plugins/hid_lesstif/dlg_attr_tree.c =================================================================== --- trunk/src/librnd/plugins/hid_lesstif/dlg_attr_tree.c (revision 34601) +++ trunk/src/librnd/plugins/hid_lesstif/dlg_attr_tree.c (revision 34602) @@ -1,5 +1,5 @@ #include "xm_tree_table_widget.h" -#include +#include typedef struct { lesstif_attr_dlg_t *ctx; Index: trunk/src/librnd/plugins/hid_lesstif/lesstif.h =================================================================== --- trunk/src/librnd/plugins/hid_lesstif/lesstif.h (revision 34601) +++ trunk/src/librnd/plugins/hid_lesstif/lesstif.h (revision 34602) @@ -1,4 +1,4 @@ -#include +#include #define app_context lesstif_app_context #define appwidget lesstif_appwidget Index: trunk/src/librnd/plugins/hid_lesstif/main.c =================================================================== --- trunk/src/librnd/plugins/hid_lesstif/main.c (revision 34601) +++ trunk/src/librnd/plugins/hid_lesstif/main.c (revision 34602) @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include @@ -25,20 +25,20 @@ #include #include -#include -#include +#include +#include #include #include "lesstif.h" -#include -#include -#include -#include +#include +#include +#include +#include #include #include "ltf_stdarg.h" -#include +#include #include #include -#include +#include #include #include "wt_preview.h" Index: trunk/src/librnd/plugins/hid_lesstif/menu.c =================================================================== --- trunk/src/librnd/plugins/hid_lesstif/menu.c (revision 34601) +++ trunk/src/librnd/plugins/hid_lesstif/menu.c (revision 34602) @@ -11,10 +11,11 @@ #include #include -#include +#include +#include #include #include -#include +#include #include #include "lesstif.h" #include Index: trunk/src/librnd/plugins/hid_lesstif/wt_preview.c =================================================================== --- trunk/src/librnd/plugins/hid_lesstif/wt_preview.c (revision 34601) +++ trunk/src/librnd/plugins/hid_lesstif/wt_preview.c (revision 34602) @@ -26,7 +26,7 @@ #include "wt_preview.h" #include "dialogs.h" -#include +#include static gdl_list_t ltf_previews; Index: trunk/src/librnd/plugins/hid_mbtk_xlib/hid_mbtk_xlib.c =================================================================== --- trunk/src/librnd/plugins/hid_mbtk_xlib/hid_mbtk_xlib.c (revision 34601) +++ trunk/src/librnd/plugins/hid_mbtk_xlib/hid_mbtk_xlib.c (revision 34602) @@ -29,7 +29,7 @@ #include #include -#include +#include #include #include Index: trunk/src/librnd/plugins/hid_remote/remote.c =================================================================== --- trunk/src/librnd/plugins/hid_remote/remote.c (revision 34601) +++ trunk/src/librnd/plugins/hid_remote/remote.c (revision 34602) @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include #include @@ -14,9 +14,9 @@ #include "proto.h" -#include +#include #include -#include +#include static const char *remote_cookie = "remote HID"; Index: trunk/src/librnd/plugins/import_pixmap_gd/import_pixmap_gd.c =================================================================== --- trunk/src/librnd/plugins/import_pixmap_gd/import_pixmap_gd.c (revision 34601) +++ trunk/src/librnd/plugins/import_pixmap_gd/import_pixmap_gd.c (revision 34602) @@ -34,7 +34,7 @@ #include #include -#include +#include #include static const char *import_pixmap_gd_cookie = "import_pixmap_gd"; Index: trunk/src/librnd/plugins/import_pixmap_pnm/import_pixmap_pnm.c =================================================================== --- trunk/src/librnd/plugins/import_pixmap_pnm/import_pixmap_pnm.c (revision 34601) +++ trunk/src/librnd/plugins/import_pixmap_pnm/import_pixmap_pnm.c (revision 34602) @@ -34,7 +34,7 @@ #include #include -#include +#include #include #include #include Index: trunk/src/librnd/plugins/irc/irc.c =================================================================== --- trunk/src/librnd/plugins/irc/irc.c (revision 34601) +++ trunk/src/librnd/plugins/irc/irc.c (revision 34602) @@ -27,10 +27,10 @@ #include #include "config.h" #include -#include -#include +#include +#include #include -#include +#include #include #include #include Index: trunk/src/librnd/plugins/lib_exp_pixmap/draw_pixmap.c =================================================================== --- trunk/src/librnd/plugins/lib_exp_pixmap/draw_pixmap.c (revision 34601) +++ trunk/src/librnd/plugins/lib_exp_pixmap/draw_pixmap.c (revision 34602) @@ -41,9 +41,9 @@ #include #include #include -#include +#include #include -#include +#include #include Index: trunk/src/librnd/plugins/lib_exp_text/draw_eps.c =================================================================== --- trunk/src/librnd/plugins/lib_exp_text/draw_eps.c (revision 34601) +++ trunk/src/librnd/plugins/lib_exp_text/draw_eps.c (revision 34602) @@ -14,10 +14,10 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include "draw_eps.h" Index: trunk/src/librnd/plugins/lib_exp_text/draw_ps.c =================================================================== --- trunk/src/librnd/plugins/lib_exp_text/draw_ps.c (revision 34601) +++ trunk/src/librnd/plugins/lib_exp_text/draw_ps.c (revision 34602) @@ -17,9 +17,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include "media.h" #include "draw_ps.h" Index: trunk/src/librnd/plugins/lib_exp_text/draw_svg.c =================================================================== --- trunk/src/librnd/plugins/lib_exp_text/draw_svg.c (revision 34601) +++ trunk/src/librnd/plugins/lib_exp_text/draw_svg.c (revision 34602) @@ -47,10 +47,10 @@ #include #include -#include +#include -#include -#include +#include +#include #include "draw_svg.h" Index: trunk/src/librnd/plugins/lib_exp_text/lpr_hid.c =================================================================== --- trunk/src/librnd/plugins/lib_exp_text/lpr_hid.c (revision 34601) +++ trunk/src/librnd/plugins/lib_exp_text/lpr_hid.c (revision 34602) @@ -13,10 +13,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include "lpr_hid.h" Index: trunk/src/librnd/plugins/lib_gtk2_common/bu_menu.c =================================================================== --- trunk/src/librnd/plugins/lib_gtk2_common/bu_menu.c (revision 34601) +++ trunk/src/librnd/plugins/lib_gtk2_common/bu_menu.c (revision 34602) @@ -14,7 +14,8 @@ #include #include #include -#include +#include +#include #include #include "bu_menu.h" Index: trunk/src/librnd/plugins/lib_gtk2_common/bu_menu.h =================================================================== --- trunk/src/librnd/plugins/lib_gtk2_common/bu_menu.h (revision 34601) +++ trunk/src/librnd/plugins/lib_gtk2_common/bu_menu.h (revision 34602) @@ -6,7 +6,7 @@ #include #include -#include +#include #include typedef struct rnd_gtk_menu_ctx_s { Index: trunk/src/librnd/plugins/lib_gtk2_common/dlg_attribute.c =================================================================== --- trunk/src/librnd/plugins/lib_gtk2_common/dlg_attribute.c (revision 34601) +++ trunk/src/librnd/plugins/lib_gtk2_common/dlg_attribute.c (revision 34602) @@ -1,6 +1,6 @@ #include "compat.h" -#include +#include #define DLG_INCLUDES "librnd/plugins/lib_gtk2_common/dlg_includes.c" Index: trunk/src/librnd/plugins/lib_gtk4_common/bu_menu.h =================================================================== --- trunk/src/librnd/plugins/lib_gtk4_common/bu_menu.h (revision 34601) +++ trunk/src/librnd/plugins/lib_gtk4_common/bu_menu.h (revision 34602) @@ -6,7 +6,7 @@ #include #include -#include +#include #include typedef struct rnd_gtk_menu_ctx_s { Index: trunk/src/librnd/plugins/lib_gtk4_common/dlg_attribute.c =================================================================== --- trunk/src/librnd/plugins/lib_gtk4_common/dlg_attribute.c (revision 34601) +++ trunk/src/librnd/plugins/lib_gtk4_common/dlg_attribute.c (revision 34602) @@ -2,7 +2,7 @@ #define DLG_INCLUDES "librnd/plugins/lib_gtk4_common/dlg_includes.c" -#include +#include #include "gtkc_trunc_label.h" static inline GtkWidget *gtkc_dad_label_new(rnd_hid_attribute_t *attr) Index: trunk/src/librnd/plugins/lib_gtk_common/dlg_attribute.c =================================================================== --- trunk/src/librnd/plugins/lib_gtk_common/dlg_attribute.c (revision 34601) +++ trunk/src/librnd/plugins/lib_gtk_common/dlg_attribute.c (revision 34602) @@ -36,9 +36,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include #include #include Index: trunk/src/librnd/plugins/lib_gtk_common/dlg_attribute.h =================================================================== --- trunk/src/librnd/plugins/lib_gtk_common/dlg_attribute.h (revision 34601) +++ trunk/src/librnd/plugins/lib_gtk_common/dlg_attribute.h (revision 34602) @@ -1,5 +1,5 @@ #include -#include +#include #include "rnd_gtk.h" void *rnd_gtk_attr_dlg_new(rnd_hid_t *hid, rnd_gtk_t *gctx, const char *id, rnd_hid_attribute_t *attrs, int n_attrs, const char *title, void *caller_data, rnd_bool modal, void (*button_cb)(void *caller_data, rnd_hid_attr_ev_t ev), int defx, int defy, int minx, int miny); Index: trunk/src/librnd/plugins/lib_gtk_common/dlg_topwin.c =================================================================== --- trunk/src/librnd/plugins/lib_gtk_common/dlg_topwin.c (revision 34601) +++ trunk/src/librnd/plugins/lib_gtk_common/dlg_topwin.c (revision 34602) @@ -50,7 +50,8 @@ #include #include #include -#include +#include +#include #include "bu_pixbuf.h" #include "dlg_attribute.h" Index: trunk/src/librnd/plugins/lib_gtk_common/dlg_topwin.h =================================================================== --- trunk/src/librnd/plugins/lib_gtk_common/dlg_topwin.h (revision 34601) +++ trunk/src/librnd/plugins/lib_gtk_common/dlg_topwin.h (revision 34602) @@ -6,7 +6,7 @@ #include #include -#include +#include #include "rnd_gtk.h" #include "bu_command.h" Index: trunk/src/librnd/plugins/lib_gtk_common/glue_common.c =================================================================== --- trunk/src/librnd/plugins/lib_gtk_common/glue_common.c (revision 34601) +++ trunk/src/librnd/plugins/lib_gtk_common/glue_common.c (revision 34602) @@ -28,7 +28,7 @@ */ #include "config.h" -#include +#include #include "glue_common.h" @@ -48,7 +48,7 @@ #ifdef __WIN32__ -#include +#include #include static void rnd_gtkg_win32_init(void) Index: trunk/src/librnd/plugins/lib_gtk_common/glue_common.h =================================================================== --- trunk/src/librnd/plugins/lib_gtk_common/glue_common.h (revision 34601) +++ trunk/src/librnd/plugins/lib_gtk_common/glue_common.h (revision 34602) @@ -1,7 +1,7 @@ #ifndef RND_GTK_GLUE_COMMON_H #define RND_GTK_GLUE_COMMON_H -#include +#include #include "rnd_gtk.h" #include Index: trunk/src/librnd/plugins/lib_gtk_common/glue_hid.c =================================================================== --- trunk/src/librnd/plugins/lib_gtk_common/glue_hid.c (revision 34601) +++ trunk/src/librnd/plugins/lib_gtk_common/glue_hid.c (revision 34602) @@ -6,9 +6,10 @@ #include "rnd_gtk.h" #include #include "glue_hid.h" -#include -#include -#include +#include +#include +#include +#include #include "coord_conv.h" #include "in_keyboard.h" Index: trunk/src/librnd/plugins/lib_gtk_common/glue_hid.h =================================================================== --- trunk/src/librnd/plugins/lib_gtk_common/glue_hid.h (revision 34601) +++ trunk/src/librnd/plugins/lib_gtk_common/glue_hid.h (revision 34602) @@ -1,4 +1,4 @@ -#include +#include void rnd_gtk_glue_hid_init(rnd_hid_t *dst); int rnd_gtk_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv); Index: trunk/src/librnd/plugins/lib_gtk_common/gtk_gl_common.c =================================================================== --- trunk/src/librnd/plugins/lib_gtk_common/gtk_gl_common.c (revision 34601) +++ trunk/src/librnd/plugins/lib_gtk_common/gtk_gl_common.c (revision 34602) @@ -3,9 +3,9 @@ #include #include -#include +#include #include -#include +#include #include #include Index: trunk/src/librnd/plugins/lib_gtk_common/in_keyboard.h =================================================================== --- trunk/src/librnd/plugins/lib_gtk_common/in_keyboard.h (revision 34601) +++ trunk/src/librnd/plugins/lib_gtk_common/in_keyboard.h (revision 34602) @@ -4,7 +4,7 @@ #include #include -#include +#include #include "ui_zoompan.h" typedef enum { Index: trunk/src/librnd/plugins/lib_gtk_common/in_mouse.c =================================================================== --- trunk/src/librnd/plugins/lib_gtk_common/in_mouse.c (revision 34601) +++ trunk/src/librnd/plugins/lib_gtk_common/in_mouse.c (revision 34602) @@ -39,7 +39,7 @@ #include #include -#include +#include #define GVT_DONT_UNDEF #include "in_mouse.h" Index: trunk/src/librnd/plugins/lib_gtk_common/in_mouse.h =================================================================== --- trunk/src/librnd/plugins/lib_gtk_common/in_mouse.h (revision 34601) +++ trunk/src/librnd/plugins/lib_gtk_common/in_mouse.h (revision 34602) @@ -1,7 +1,7 @@ #ifndef RND_GTK_IN_MOUSE_H #define RND_GTK_IN_MOUSE_H -#include +#include #include "rnd_gtk.h" #include Index: trunk/src/librnd/plugins/lib_gtk_common/lib_gtk_config.h =================================================================== --- trunk/src/librnd/plugins/lib_gtk_common/lib_gtk_config.h (revision 34601) +++ trunk/src/librnd/plugins/lib_gtk_common/lib_gtk_config.h (revision 34602) @@ -1,4 +1,4 @@ -#include +#include #include #include Index: trunk/src/librnd/plugins/lib_gtk_common/rnd_gtk.h =================================================================== --- trunk/src/librnd/plugins/lib_gtk_common/rnd_gtk.h (revision 34601) +++ trunk/src/librnd/plugins/lib_gtk_common/rnd_gtk.h (revision 34602) @@ -29,7 +29,7 @@ #define RND_GTK_H #include -#include +#include #include typedef struct rnd_gtk_port_s rnd_gtk_port_t; Index: trunk/src/librnd/plugins/lib_gtk_common/util_listener.c =================================================================== --- trunk/src/librnd/plugins/lib_gtk_common/util_listener.c (revision 34601) +++ trunk/src/librnd/plugins/lib_gtk_common/util_listener.c (revision 34602) @@ -36,7 +36,7 @@ #include #include -#include +#include #include #include Index: trunk/src/librnd/plugins/lib_gtk_common/util_timer.h =================================================================== --- trunk/src/librnd/plugins/lib_gtk_common/util_timer.h (revision 34601) +++ trunk/src/librnd/plugins/lib_gtk_common/util_timer.h (revision 34602) @@ -1,4 +1,4 @@ -#include +#include #include "rnd_gtk.h" rnd_hidval_t rnd_gtk_add_timer(struct rnd_gtk_s *gctx, void (*func)(rnd_hidval_t user_data), unsigned long milliseconds, rnd_hidval_t user_data); Index: trunk/src/librnd/plugins/lib_gtk_common/util_watch.h =================================================================== --- trunk/src/librnd/plugins/lib_gtk_common/util_watch.h (revision 34601) +++ trunk/src/librnd/plugins/lib_gtk_common/util_watch.h (revision 34602) @@ -1,4 +1,4 @@ -#include +#include #include "rnd_gtk.h" rnd_hidval_t rnd_gtk_watch_file(rnd_gtk_t *gctx, int fd, unsigned int condition, Index: trunk/src/librnd/plugins/lib_gtk_common/wt_preview.h =================================================================== --- trunk/src/librnd/plugins/lib_gtk_common/wt_preview.h (revision 34601) +++ trunk/src/librnd/plugins/lib_gtk_common/wt_preview.h (revision 34602) @@ -37,7 +37,7 @@ #include #include -#include +#include #include "ui_zoompan.h" #include "rnd_gtk.h" Index: trunk/src/librnd/plugins/lib_hid_common/act_dad.c =================================================================== --- trunk/src/librnd/plugins/lib_hid_common/act_dad.c (revision 34601) +++ trunk/src/librnd/plugins/lib_hid_common/act_dad.c (revision 34602) @@ -32,8 +32,8 @@ #include #include #include -#include -#include +#include +#include #include #include "act_dad.h" Index: trunk/src/librnd/plugins/lib_hid_common/dlg_comm_m.c =================================================================== --- trunk/src/librnd/plugins/lib_hid_common/dlg_comm_m.c (revision 34601) +++ trunk/src/librnd/plugins/lib_hid_common/dlg_comm_m.c (revision 34602) @@ -30,7 +30,7 @@ #include #include -#include +#include #include #include "xpm.h" #include "dlg_comm_m.h" Index: trunk/src/librnd/plugins/lib_hid_common/dlg_export.c =================================================================== --- trunk/src/librnd/plugins/lib_hid_common/dlg_export.c (revision 34601) +++ trunk/src/librnd/plugins/lib_hid_common/dlg_export.c (revision 34602) @@ -27,10 +27,10 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include "dlg_export.h" typedef struct{ Index: trunk/src/librnd/plugins/lib_hid_common/dlg_fileselect.c =================================================================== --- trunk/src/librnd/plugins/lib_hid_common/dlg_fileselect.c (revision 34601) +++ trunk/src/librnd/plugins/lib_hid_common/dlg_fileselect.c (revision 34602) @@ -39,8 +39,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include Index: trunk/src/librnd/plugins/lib_hid_common/dlg_fileselect.h =================================================================== --- trunk/src/librnd/plugins/lib_hid_common/dlg_fileselect.h (revision 34601) +++ trunk/src/librnd/plugins/lib_hid_common/dlg_fileselect.h (revision 34602) @@ -1,5 +1,5 @@ #include -#include +#include #include char *rnd_dlg_fileselect(rnd_hid_t *hid, const char *title, const char *descr, const char *default_file, const char *default_ext, const rnd_hid_fsd_filter_t *flt, const char *history_tag, rnd_hid_fsd_flags_t flags, rnd_hid_dad_subdialog_t *sub); Index: trunk/src/librnd/plugins/lib_hid_common/dlg_log.c =================================================================== --- trunk/src/librnd/plugins/lib_hid_common/dlg_log.c (revision 34601) +++ trunk/src/librnd/plugins/lib_hid_common/dlg_log.c (revision 34602) @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include Index: trunk/src/librnd/plugins/lib_hid_common/dlg_plugins.c =================================================================== --- trunk/src/librnd/plugins/lib_hid_common/dlg_plugins.c (revision 34601) +++ trunk/src/librnd/plugins/lib_hid_common/dlg_plugins.c (revision 34602) @@ -25,9 +25,10 @@ */ #include +#include #include -#include -#include +#include +#include #include #include "dlg_plugins.h" Index: trunk/src/librnd/plugins/lib_hid_common/dlg_pref.c =================================================================== --- trunk/src/librnd/plugins/lib_hid_common/dlg_pref.c (revision 34601) +++ trunk/src/librnd/plugins/lib_hid_common/dlg_pref.c (revision 34602) @@ -38,8 +38,8 @@ #include #include #include -#include -#include +#include +#include #include Index: trunk/src/librnd/plugins/lib_hid_common/dlg_pref.h =================================================================== --- trunk/src/librnd/plugins/lib_hid_common/dlg_pref.h (revision 34601) +++ trunk/src/librnd/plugins/lib_hid_common/dlg_pref.h (revision 34602) @@ -5,7 +5,7 @@ #include #include -#include +#include #include typedef struct pref_conflist_s pref_confitem_t; Index: trunk/src/librnd/plugins/lib_hid_common/dlg_pref_confedit.c =================================================================== --- trunk/src/librnd/plugins/lib_hid_common/dlg_pref_confedit.c (revision 34601) +++ trunk/src/librnd/plugins/lib_hid_common/dlg_pref_confedit.c (revision 34602) @@ -26,7 +26,7 @@ /* Preferences dialog, conf tree tab -> edit conf node (input side) popup */ -#include +#include #define is_read_only(ctx) rnd_conf_is_read_only(ctx->role) Index: trunk/src/librnd/plugins/lib_hid_common/dlg_pref_key.c =================================================================== --- trunk/src/librnd/plugins/lib_hid_common/dlg_pref_key.c (revision 34601) +++ trunk/src/librnd/plugins/lib_hid_common/dlg_pref_key.c (revision 34602) @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include Index: trunk/src/librnd/plugins/lib_hid_common/dlg_pref_menu.c =================================================================== --- trunk/src/librnd/plugins/lib_hid_common/dlg_pref_menu.c (revision 34601) +++ trunk/src/librnd/plugins/lib_hid_common/dlg_pref_menu.c (revision 34602) @@ -26,7 +26,7 @@ /* Preferences dialog, menu tab */ -#include +#include #include #include Index: trunk/src/librnd/plugins/lib_hid_common/grid_menu.c =================================================================== --- trunk/src/librnd/plugins/lib_hid_common/grid_menu.c (revision 34601) +++ trunk/src/librnd/plugins/lib_hid_common/grid_menu.c (revision 34602) @@ -28,11 +28,11 @@ #include #include -#include +#include #include #include -#include -#include +#include +#include #include "grid_menu.h" Index: trunk/src/librnd/plugins/lib_hid_common/gui_act.c =================================================================== --- trunk/src/librnd/plugins/lib_hid_common/gui_act.c (revision 34601) +++ trunk/src/librnd/plugins/lib_hid_common/gui_act.c (revision 34602) @@ -34,16 +34,16 @@ */ #include #include -#include -#include +#include +#include #include #include -#include +#include #include #include -#include -#include -#include +#include +#include +#include void rnd_hidcore_crosshair_move_to(rnd_hidlib_t *hidlib, rnd_coord_t abs_x, rnd_coord_t abs_y, int mouse_mot) { @@ -340,6 +340,44 @@ return 0; } +static const char rnd_acts_LogGui[] = + "LogGui(export, [filename, [text|lihata])\n"; +static const char rnd_acth_LogGui[] = "Log() action GUI section"; +static fgw_error_t rnd_act_LogGui(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int ret; + const char *op = ""; + + RND_ACT_MAY_CONVARG(1, FGW_STR, LogGui, op = argv[1].val.str); + + if (rnd_strcasecmp(op, "Export") == 0) { + const char *fmts[] = { "text", "lihata", NULL }; + rnd_hid_dad_subdialog_t fmtsub; + char *fn; + int wfmt; + + memset(&fmtsub, 0, sizeof(fmtsub)); + RND_DAD_ENUM(fmtsub.dlg, fmts); + wfmt = RND_DAD_CURRENT(fmtsub.dlg); + fn = rnd_hid_fileselect(rnd_gui, "Export log", NULL, "log.txt", NULL, NULL, "log", 0, &fmtsub); + if (fn != NULL) { + ret = rnd_log_export(NULL, fn, (fmtsub.dlg[wfmt].val.lng == 1)); + if (ret != 0) + rnd_message(RND_MSG_ERROR, "Failed to export log to '%s'\n", fn); + free(fn); + } + else + ret = 0; + } + else { + RND_ACT_FAIL(LogGui); + ret = -1; + } + + RND_ACT_IRES(ret); + return 0; +} + static rnd_action_t rnd_gui_action_list[] = { {"FullScreen", rnd_act_FullScreen, rnd_acth_FullScreen, rnd_acts_FullScreen}, {"Cursor", rnd_act_Cursor, rnd_acth_Cursor, rnd_acts_Cursor}, @@ -347,10 +385,11 @@ {"Grid", rnd_act_grid, rnd_acth_grid, rnd_acts_grid}, {"GetXY", rnd_act_GetXY, rnd_acth_GetXY, rnd_acts_GetXY}, {"Benchmark", rnd_act_Benchmark, rnd_acth_Benchmark, rnd_acts_Benchmark}, - {"Redraw", rnd_act_Redraw, rnd_acth_Redraw, rnd_acts_Redraw} + {"Redraw", rnd_act_Redraw, rnd_acth_Redraw, rnd_acts_Redraw}, + {"LogGui", rnd_act_LogGui, rnd_acth_LogGui, rnd_acts_LogGui} }; -void rnd_gui_act_init2(void) +void rnd_gui_act_init(void) { RND_REGISTER_ACTIONS(rnd_gui_action_list, NULL); } Index: trunk/src/librnd/plugins/lib_hid_common/lead_user.c =================================================================== --- trunk/src/librnd/plugins/lib_hid_common/lead_user.c (revision 34601) +++ trunk/src/librnd/plugins/lib_hid_common/lead_user.c (revision 34602) @@ -30,7 +30,7 @@ #include #include -#include +#include #define LEAD_ARROW_LEN RND_MM_TO_COORD(3) #define LEAD_CENTER_RAD RND_MM_TO_COORD(0.5) Index: trunk/src/librnd/plugins/lib_hid_common/lib_hid_common.c =================================================================== --- trunk/src/librnd/plugins/lib_hid_common/lib_hid_common.c (revision 34601) +++ trunk/src/librnd/plugins/lib_hid_common/lib_hid_common.c (revision 34602) @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include "grid_menu.h" #include "cli_history.h" @@ -134,6 +134,8 @@ rnd_dlg_log_uninit(); } +extern void rnd_gui_act_init(void); + int pplg_init_lib_hid_common(void) { static rnd_conf_hid_callbacks_t ccb, ccbu; @@ -175,5 +177,7 @@ rnd_hid_fileselect_imp = rnd_dlg_fileselect; + rnd_gui_act_init(); + return 0; } Index: trunk/src/librnd/plugins/lib_hid_common/menu_helper.c =================================================================== --- trunk/src/librnd/plugins/lib_hid_common/menu_helper.c (revision 34601) +++ trunk/src/librnd/plugins/lib_hid_common/menu_helper.c (revision 34602) @@ -36,6 +36,7 @@ #include #include #include +#include #include "menu_helper.h" Index: trunk/src/librnd/plugins/lib_hid_common/toolbar.c =================================================================== --- trunk/src/librnd/plugins/lib_hid_common/toolbar.c (revision 34601) +++ trunk/src/librnd/plugins/lib_hid_common/toolbar.c (revision 34602) @@ -32,10 +32,11 @@ #include #include -#include +#include #include -#include -#include +#include +#include +#include #include #include #include Index: trunk/src/librnd/plugins/lib_hid_common/zoompan.h =================================================================== --- trunk/src/librnd/plugins/lib_hid_common/zoompan.h (revision 34601) +++ trunk/src/librnd/plugins/lib_hid_common/zoompan.h (revision 34602) @@ -24,7 +24,7 @@ * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") */ -#include +#include /* Return error from an action if there's no GUI, or set result to 0 if there's GUI */ Index: trunk/src/librnd/plugins/lib_hid_gl/hidgl.c =================================================================== --- trunk/src/librnd/plugins/lib_hid_gl/hidgl.c (revision 34601) +++ trunk/src/librnd/plugins/lib_hid_gl/hidgl.c (revision 34602) @@ -35,8 +35,8 @@ #include #include -#include -#include +#include +#include #include #include Index: trunk/src/librnd/plugins/lib_hid_gl/hidgl.h =================================================================== --- trunk/src/librnd/plugins/lib_hid_gl/hidgl.h (revision 34601) +++ trunk/src/librnd/plugins/lib_hid_gl/hidgl.h (revision 34602) @@ -30,7 +30,7 @@ #define RND_HID_COMMON_HIDGL_H #include -#include +#include /*extern float global_depth;*/ void hidgl_draw_local_grid(rnd_hidlib_t *hidlib, rnd_coord_t grd, rnd_coord_t cx, rnd_coord_t cy, int radius, double scale, rnd_bool cross_grid); Index: trunk/src/librnd/plugins/lib_mbtk_common/attr_dlg.h =================================================================== --- trunk/src/librnd/plugins/lib_mbtk_common/attr_dlg.h (revision 34601) +++ trunk/src/librnd/plugins/lib_mbtk_common/attr_dlg.h (revision 34602) @@ -1,4 +1,4 @@ -#include +#include #include #include Index: trunk/src/librnd/plugins/lib_mbtk_common/glue_hid.c =================================================================== --- trunk/src/librnd/plugins/lib_mbtk_common/glue_hid.c (revision 34601) +++ trunk/src/librnd/plugins/lib_mbtk_common/glue_hid.c (revision 34602) @@ -34,11 +34,11 @@ #include "attr_dlg.h" #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include #include Index: trunk/src/librnd/plugins/lib_mbtk_common/glue_hid.h =================================================================== --- trunk/src/librnd/plugins/lib_mbtk_common/glue_hid.h (revision 34601) +++ trunk/src/librnd/plugins/lib_mbtk_common/glue_hid.h (revision 34602) @@ -1,4 +1,4 @@ -#include +#include #include void rnd_mbtk_glue_hid_init(rnd_hid_t *dst, int (*init_backend)(rnd_mbtk_t *mctx, int *argc, char **argv[])); Index: trunk/src/librnd/plugins/lib_mbtk_common/keyboard.c =================================================================== --- trunk/src/librnd/plugins/lib_mbtk_common/keyboard.c (revision 34601) +++ trunk/src/librnd/plugins/lib_mbtk_common/keyboard.c (revision 34602) @@ -1,6 +1,6 @@ #include #include -#include +#include static rnd_hid_cfg_keys_t rnd_mbtk_keymap; Index: trunk/src/librnd/plugins/lib_mbtk_common/lib_mbtk_common.c =================================================================== --- trunk/src/librnd/plugins/lib_mbtk_common/lib_mbtk_common.c (revision 34601) +++ trunk/src/librnd/plugins/lib_mbtk_common/lib_mbtk_common.c (revision 34602) @@ -27,7 +27,7 @@ #include "config.h" #include -#include +#include int pplg_check_ver_lib_mbtk_common(int ver_needed) { return 0; } Index: trunk/src/librnd/plugins/loghid/hid-logger.h =================================================================== --- trunk/src/librnd/plugins/loghid/hid-logger.h (revision 34601) +++ trunk/src/librnd/plugins/loghid/hid-logger.h (revision 34602) @@ -1,7 +1,7 @@ #ifndef RND_HID_LOGGER_H #define RND_HID_LOGGER_H -#include +#include #include Index: trunk/src/librnd/plugins/loghid/loghid.c =================================================================== --- trunk/src/librnd/plugins/loghid/loghid.c (revision 34601) +++ trunk/src/librnd/plugins/loghid/loghid.c (revision 34602) @@ -36,9 +36,9 @@ #include #include #include "hid-logger.h" -#include -#include -#include +#include +#include +#include static const char *loghid_cookie = "loghid plugin"; Index: trunk/src/librnd/plugins/script/live_script.c =================================================================== --- trunk/src/librnd/plugins/script/live_script.c (revision 34601) +++ trunk/src/librnd/plugins/script/live_script.c (revision 34602) @@ -35,12 +35,12 @@ #include #include #include -#include +#include #include #include #include #include -#include +#include #include "script.h" Index: trunk/src/librnd/plugins/script/perma.c =================================================================== --- trunk/src/librnd/plugins/script/perma.c (revision 34601) +++ trunk/src/librnd/plugins/script/perma.c (revision 34602) @@ -32,7 +32,7 @@ #include #include -#include +#include static int perma_load(rnd_hidlib_t *hl, const char *dir, const char *id, const char *path_in, const char *lang) { Index: trunk/src/librnd/plugins/script/script.c =================================================================== --- trunk/src/librnd/plugins/script/script.c (revision 34601) +++ trunk/src/librnd/plugins/script/script.c (revision 34602) @@ -43,10 +43,10 @@ #include #include #include -#include +#include #include #include -#include +#include #include "script.h" #include "guess_lang.c" Index: trunk/src/librnd/plugins/script/script_act.c =================================================================== --- trunk/src/librnd/plugins/script/script_act.c (revision 34601) +++ trunk/src/librnd/plugins/script/script_act.c (revision 34602) @@ -28,8 +28,8 @@ */ #include -#include -#include +#include +#include #include "live_script.h" /*** dialog box ***/ Index: trunk/src/librnd/plugins/stroke/stroke.c =================================================================== --- trunk/src/librnd/plugins/stroke/stroke.c (revision 34601) +++ trunk/src/librnd/plugins/stroke/stroke.c (revision 34602) @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include "stroke_conf.h" Index: trunk/src/test-rnd.c =================================================================== --- trunk/src/test-rnd.c (revision 34601) +++ trunk/src/test-rnd.c (revision 34602) @@ -31,8 +31,8 @@ /* librnd headers */ #include -#include -#include +#include +#include #include #include #include @@ -62,7 +62,7 @@ } foobar; /*** crosshair ***/ -#include +#include #include rnd_hid_gc_t foobar_crosshair_gc; void foobar_crosshair_gui_init(void) Index: trunk/tests/conf/Makefile =================================================================== --- trunk/tests/conf/Makefile (revision 34601) +++ trunk/tests/conf/Makefile (revision 34602) @@ -8,7 +8,7 @@ HELPER_OBJS=conf_core.o LIBRND_OBJS= \ $(ROOT)/src/librnd/plugins/diag_rnd/diag_rnd.o \ - $(ROOT)/src/librnd-hid.a $(ROOT)/src/librnd-3rd.a + $(ROOT)/src/librnd-hid.a $(ROOT)/src/librnd-core.a $(ROOT)/src/librnd-3rd.a DEPH = \ $(ROOT)/src/librnd/core/conf.h \ Index: trunk/tests/conf/conftest.c =================================================================== --- trunk/tests/conf/conftest.c (revision 34601) +++ trunk/tests/conf/conftest.c (revision 34602) @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include #include Index: trunk/tests/librnd/Makefile =================================================================== --- trunk/tests/librnd/Makefile (revision 34601) +++ trunk/tests/librnd/Makefile (revision 34602) @@ -8,7 +8,7 @@ CFLAGS = -I$(LIBRND_ROOT)/include/librnd4 -I$(LIBRND_ROOT)/include/librnd4/librnd/src_3rd $(PCB_RND_C89FLAGS) $(CFLAGS_LIBRND) LDFLAGS = $(LIBRND_RDYNAMIC) $(LDFLAGS_LIBRND) -LIBRND_A = include/$(HL_LIBDIR)/librnd-font.a include/$(HL_LIBDIR)/librnd-poly.a include/$(HL_LIBDIR)/librnd-hid.a include/$(HL_LIBDIR)/librnd-3rd.a +LIBRND_A = include/$(HL_LIBDIR)/librnd-font.a include/$(HL_LIBDIR)/librnd-poly.a include/$(HL_LIBDIR)/librnd-hid.a include/$(HL_LIBDIR)/librnd-core.a include/$(HL_LIBDIR)/librnd-3rd.a all: librnd_test librnd_includes @@ -17,9 +17,10 @@ ./librnd_includes librnd_objs: $(LIBRND_A) - $(SCCBX) mkdir -p obj obj/font obj/poly obj/hid obj/3rd - $(SCCBX) rm -f obj/font/*.o obj/poly/*.o obj/hid/*.o obj/3rd/*.o + $(SCCBX) mkdir -p obj obj/font obj/poly obj/hid obj/core obj/3rd + $(SCCBX) rm -f obj/font/*.o obj/poly/*.o obj/hid/*.o obj/core/*.o obj/3rd/*.o cd obj/hid && ar x ../../include/$(HL_LIBDIR)/librnd-hid.a + cd obj/core && ar x ../../include/$(HL_LIBDIR)/librnd-core.a cd obj/font && ar x ../../include/$(HL_LIBDIR)/librnd-font.a cd obj/poly && ar x ../../include/$(HL_LIBDIR)/librnd-poly.a cd obj/3rd && ar x ../../include/$(HL_LIBDIR)/librnd-3rd.a @@ -26,7 +27,7 @@ librnd_test: librnd_test.o librnd_objs - $(CC) -o librnd_test librnd_test.o obj/hid/*.o obj/font/*.o obj/poly/*.o obj/3rd/*.o $(LDFLAGS) + $(CC) -o librnd_test librnd_test.o obj/hid/*.o obj/core/*.o obj/font/*.o obj/poly/*.o obj/3rd/*.o $(LDFLAGS) librnd_test.o: librnd_test.c includes @@ -33,7 +34,7 @@ $(CC) $(CFLAGS) -c -o librnd_test.o librnd_test.c librnd_includes: librnd_includes.o librnd_objs - $(CC) -o librnd_includes librnd_includes.o obj/hid/*.o obj/font/*.o obj/poly/*.o obj/3rd/*.o $(LDFLAGS) + $(CC) -o librnd_includes librnd_includes.o obj/hid/*.o obj/core/*.o obj/font/*.o obj/poly/*.o obj/3rd/*.o $(LDFLAGS) librd_includes.o: librnd_includes.c includes Index: trunk/tests/librnd/inc_all.h.in =================================================================== --- trunk/tests/librnd/inc_all.h.in (revision 34601) +++ trunk/tests/librnd/inc_all.h.in (revision 34602) @@ -1,4 +1,4 @@ -put /local/objs /local/librnd/HDRS_HIDLIB +put /local/objs /local/librnd/HDRS_CORELIB gsub /local/objs { } {\n} foreach /local/h in /local/objs Index: trunk/tests/librnd/librnd_test.c =================================================================== --- trunk/tests/librnd/librnd_test.c (revision 34601) +++ trunk/tests/librnd/librnd_test.c (revision 34602) @@ -1,8 +1,8 @@ #define RND_APP_PREFIX(x) rndtest_ ## x #include -#include -#include +#include +#include #include #include #include Index: trunk/tests/rnd_printf/Makefile =================================================================== --- trunk/tests/rnd_printf/Makefile (revision 34601) +++ trunk/tests/rnd_printf/Makefile (revision 34602) @@ -11,7 +11,7 @@ CFLAGS = $(PCB_RND_C89FLAGS) -I$(TRUNK) -I$(SRC) -I$(TRUNK)/src_3rd -I$(TRUNK)/src_3rd/liblihata LDLIBS = -lm -LIBPCB_BASE=$(SRC)/librnd-hid.a $(SRC)/librnd-3rd.a +LIBPCB_BASE=$(SRC)/librnd-hid.a $(SRC)/librnd-core.a $(SRC)/librnd-3rd.a include $(LIBRND)/core/librnd.mak LDFLAGS = $(LDFLAGS_LIBRND)