aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJoakim Verona2012-07-20 19:50:41 +0200
committerJoakim Verona2012-07-20 19:50:41 +0200
commit178a8604317dc1e86b30dda5a4415af1555521d1 (patch)
tree27a5b09a387f26bf7a044044d329ac2e78195978 /src
parent82da003bbce9d1b93480ba20713432f7c27bf7de (diff)
downloademacs-178a8604317dc1e86b30dda5a4415af1555521d1.tar.gz
emacs-178a8604317dc1e86b30dda5a4415af1555521d1.zip
xwgir-call-method invoke function on an xwidget dynamically
Diffstat (limited to 'src')
-rw-r--r--src/xwidget.c150
1 files changed, 141 insertions, 9 deletions
diff --git a/src/xwidget.c b/src/xwidget.c
index a9e3477d103..cfaf6d686bd 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -633,14 +633,149 @@ GtkWidget* xwgir_create(char* class){
633 GIObjectInfo* obj_info = g_irepository_find_by_name(repository, namespace, class); 633 GIObjectInfo* obj_info = g_irepository_find_by_name(repository, namespace, class);
634 GIFunctionInfo* f_info = g_object_info_find_method (obj_info, "new"); 634 GIFunctionInfo* f_info = g_object_info_find_method (obj_info, "new");
635 g_function_info_invoke(f_info, 635 g_function_info_invoke(f_info,
636 0, NULL, 636 NULL, 0,
637 0, NULL, 637 NULL, 0,
638 &return_value, 638 &return_value,
639 NULL); 639 NULL);
640 return return_value.v_pointer; 640 return return_value.v_pointer;
641 641
642} 642}
643 643
644int
645xwgir_convert_lisp_to_gir_arg(GIArgument* giarg,
646 GIArgInfo* arginfo,
647 Lisp_Object lisparg )
648{
649
650 GITypeTag tag;
651 gboolean is_pointer;
652 gboolean is_enum;
653 tag = g_type_info_get_tag (g_arg_info_get_type (arginfo));
654
655 switch (tag)
656 {
657 case GI_TYPE_TAG_BOOLEAN:
658 giarg->v_boolean = XFASTINT(lisparg);
659 break;
660 case GI_TYPE_TAG_INT8:
661 giarg->v_int8 = XFASTINT(lisparg);
662 break;
663 case GI_TYPE_TAG_UINT8:
664 giarg->v_uint8 = XFASTINT(lisparg);
665 break;
666 case GI_TYPE_TAG_INT16:
667 giarg->v_int16 = XFASTINT(lisparg);
668 break;
669 case GI_TYPE_TAG_UINT16:
670 giarg->v_uint16 = XFASTINT(lisparg);
671 break;
672 case GI_TYPE_TAG_INT32:
673 giarg->v_int32 = XFASTINT(lisparg);
674 break;
675 case GI_TYPE_TAG_UINT32:
676 giarg->v_uint32 = XFASTINT(lisparg);
677 break;
678
679 case GI_TYPE_TAG_INT64:
680 giarg->v_int64 = XFASTINT(lisparg);
681 break;
682 case GI_TYPE_TAG_UINT64:
683 giarg->v_uint64 = XFASTINT(lisparg);
684 break;
685
686
687 case GI_TYPE_TAG_FLOAT:
688 giarg->v_float = XFLOAT_DATA(lisparg);
689 break;
690
691 case GI_TYPE_TAG_DOUBLE:
692 giarg->v_double = XFLOAT_DATA(lisparg);
693 break;
694
695 case GI_TYPE_TAG_UTF8:
696 case GI_TYPE_TAG_FILENAME:
697 //giarg->v_string = SDATA(lisparg);
698 giarg->v_pointer = SDATA(lisparg);
699 break;
700
701 case GI_TYPE_TAG_ARRAY:
702 case GI_TYPE_TAG_GLIST:
703 case GI_TYPE_TAG_GSLIST:
704 case GI_TYPE_TAG_GHASH:
705 case GI_TYPE_TAG_ERROR:
706 case GI_TYPE_TAG_INTERFACE:
707 case GI_TYPE_TAG_VOID:
708 case GI_TYPE_TAG_UNICHAR:
709 case GI_TYPE_TAG_GTYPE:
710 //?? i dont know how to handle these yet TODO
711 printf("failed in my lisp to gir arg conversion duties. sob!\n");
712 return -1;
713 break;
714 }
715 return 0;
716}
717
718DEFUN ("xwgir-call-method", Fxwgir_call_method, Sxwgir_call_method, 3, 3, 0,
719 doc: /* call xwidget object method.*/)
720 (Lisp_Object xwidget, Lisp_Object method, Lisp_Object arguments)
721{
722 char* namespace = "Gtk";
723 char* namespace_version = "3.0";
724 GError *error = NULL;
725 GIRepository *repository;
726 GIArgument return_value;
727 GIArgument in_args[20];
728 /* GtkWidget* rv; */
729 repository = g_irepository_get_default();
730 g_irepository_require(repository, namespace, namespace_version, 0, &error);
731 if (error) {
732 printf("repo init error\n");
733 //for some reason the error struct is mysteriously corrupt TODO figure out
734 //g_error("ERROR: %s\n", error->message);
735 return Qnil;
736 }
737 struct xwidget* xw;
738 if(!XXWIDGETP(xwidget)) {printf("ERROR not an xwidget\n"); return Qnil;};
739 if(Qnil == xwidget) {printf("ERROR xwidget nil\n"); return Qnil;};
740 xw = XXWIDGET(xwidget);
741 if(NULL == xw) printf("ERROR xw is 0\n");
742
743 //we need the concrete widget, which happens in 2 ways depending on OSR or not TODO
744 GtkWidget* widget = (xwidget_view_lookup (xw, XWINDOW(FRAME_SELECTED_WINDOW (SELECTED_FRAME ()))) -> widget); //non osr case
745
746 //char* class = SDATA(SYMBOL_NAME(xw->type)); //this works but is unflexible
747 //figure out the class from the widget instead
748 char* class = G_OBJECT_TYPE_NAME(widget); //gives "GtkButton"(I want "Button")
749 class += strlen(namespace); //TODO check for corresponding api method
750 GIObjectInfo* obj_info = g_irepository_find_by_name(repository, namespace, class);
751 GIFunctionInfo* f_info = g_object_info_find_method (obj_info, SDATA(method));
752
753 //loop over args, convert from lisp to primitive type, given arg introspection data
754 //TODO g_callable_info_get_n_args(f_info) should match
755 int argscount = XFASTINT(Flength(arguments));
756 if(argscount != g_callable_info_get_n_args(f_info)){
757 printf("xwgir call method arg count doesn match! \n");
758 return Qnil;
759 }
760 int i;
761 for (i = 1; i < argscount + 1; ++i)
762 {
763 xwgir_convert_lisp_to_gir_arg(&in_args[i], g_callable_info_get_arg(f_info, i - 1), Fnth(i - 1, arguments));
764 }
765
766 in_args[0].v_pointer = widget;
767 if(g_function_info_invoke(f_info,
768 in_args, argscount + 1,
769 NULL, 0,
770 &return_value,
771 &error)) {
772 //g_error("ERROR: %s\n", error->message);
773 printf("invokation error\n");
774 return Qnil;
775 }
776 return Qt;
777}
778
644 779
645 780
646 781
@@ -678,9 +813,6 @@ xwidget_init_view (struct xwidget *xww,
678 } else if (EQ(xww->type, Qtoggle)) { 813 } else if (EQ(xww->type, Qtoggle)) {
679 xv->widget = gtk_toggle_button_new_with_label (XSTRING(xww->title)->data); 814 xv->widget = gtk_toggle_button_new_with_label (XSTRING(xww->title)->data);
680 //xv->widget = gtk_entry_new ();//temp hack to experiment with key propagation TODO entry widget is useful for testing 815 //xv->widget = gtk_entry_new ();//temp hack to experiment with key propagation TODO entry widget is useful for testing
681 } else if (EQ(xww->type, Qxwgir)) {
682 //this is just a test for xwgir
683 xv->widget = xwgir_create ("Button");
684 } else if (EQ(xww->type, Qsocket)) { 816 } else if (EQ(xww->type, Qsocket)) {
685 xv->widget = gtk_socket_new (); 817 xv->widget = gtk_socket_new ();
686 g_signal_connect_after(xv->widget, "plug-added", G_CALLBACK(xwidget_plug_added), "plug added"); 818 g_signal_connect_after(xv->widget, "plug-added", G_CALLBACK(xwidget_plug_added), "plug added");
@@ -1282,6 +1414,8 @@ syms_of_xwidget (void)
1282 defsubr (&Sxwidget_webkit_get_title); 1414 defsubr (&Sxwidget_webkit_get_title);
1283 DEFSYM (Qwebkit_osr ,"webkit-osr"); 1415 DEFSYM (Qwebkit_osr ,"webkit-osr");
1284#endif 1416#endif
1417
1418 defsubr (&Sxwgir_call_method );
1285 1419
1286 defsubr (&Sxwidget_size_request ); 1420 defsubr (&Sxwidget_size_request );
1287 defsubr (&Sxwidget_delete_zombies); 1421 defsubr (&Sxwidget_delete_zombies);
@@ -1298,15 +1432,13 @@ syms_of_xwidget (void)
1298 DEFSYM (Qcxwidget ,":xwidget"); 1432 DEFSYM (Qcxwidget ,":xwidget");
1299 DEFSYM (Qtitle ,":title"); 1433 DEFSYM (Qtitle ,":title");
1300 1434
1301 DEFSYM (Qbutton, "button"); 1435 DEFSYM (Qbutton, "Button"); //changed to match the gtk class because xwgir(experimental and not really needed)
1302 DEFSYM (Qtoggle, "toggle"); 1436 DEFSYM (Qtoggle, "ToggleButton");
1303 DEFSYM (Qslider, "slider"); 1437 DEFSYM (Qslider, "slider");
1304 DEFSYM (Qsocket, "socket"); 1438 DEFSYM (Qsocket, "socket");
1305 DEFSYM (Qsocket_osr, "socket-osr"); 1439 DEFSYM (Qsocket_osr, "socket-osr");
1306 DEFSYM (Qcairo, "cairo"); 1440 DEFSYM (Qcairo, "cairo");
1307 1441
1308 DEFSYM (Qxwgir, "xwgir");
1309
1310 DEFSYM (QCplist, ":plist"); 1442 DEFSYM (QCplist, ":plist");
1311 1443
1312 DEFVAR_LISP ("xwidget-alist", Vxwidget_alist, doc: /*xwidgets list*/); 1444 DEFVAR_LISP ("xwidget-alist", Vxwidget_alist, doc: /*xwidgets list*/);