diff options
| author | Joakim Verona | 2012-07-20 19:50:41 +0200 |
|---|---|---|
| committer | Joakim Verona | 2012-07-20 19:50:41 +0200 |
| commit | 178a8604317dc1e86b30dda5a4415af1555521d1 (patch) | |
| tree | 27a5b09a387f26bf7a044044d329ac2e78195978 /src | |
| parent | 82da003bbce9d1b93480ba20713432f7c27bf7de (diff) | |
| download | emacs-178a8604317dc1e86b30dda5a4415af1555521d1.tar.gz emacs-178a8604317dc1e86b30dda5a4415af1555521d1.zip | |
xwgir-call-method invoke function on an xwidget dynamically
Diffstat (limited to 'src')
| -rw-r--r-- | src/xwidget.c | 150 |
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 | ||
| 644 | int | ||
| 645 | xwgir_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 | |||
| 718 | DEFUN ("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*/); |