3 ** Description: Creating 'real' UIs from lisp.
5 ** Created by: William M. Perry <wmperry@gnu.org>
6 ** Copyright (c) 2000 William M. Perry <wmperry@gnu.org>
13 #include "console-gtk.h"
16 #include "glyphs-gtk.h"
17 #include "objects-gtk.h"
26 /* XEmacs specific GTK types */
29 Lisp_Object Qemacs_ffip;
30 Lisp_Object Qemacs_gtk_objectp;
31 Lisp_Object Qemacs_gtk_boxedp;
33 Lisp_Object Venumeration_info;
35 static GHashTable *dll_cache;
37 Lisp_Object gtk_type_to_lisp (GtkArg *arg);
38 int lisp_to_gtk_type (Lisp_Object obj, GtkArg *arg);
39 int lisp_to_gtk_ret_type (Lisp_Object obj, GtkArg *arg);
40 void describe_gtk_arg (GtkArg *arg);
41 guint symbol_to_enum (Lisp_Object obj, GtkType t);
42 static guint lisp_to_flag (Lisp_Object obj, GtkType t);
43 static Lisp_Object flags_to_list (guint value, GtkType t);
44 static Lisp_Object enum_to_symbol (guint value, GtkType t);
46 #define NIL_OR_VOID_P(x) (NILP (x) || EQ (x, Qvoid))
49 initialize_dll_cache (void)
53 dll_cache = g_hash_table_new (g_str_hash, g_str_equal);
55 g_hash_table_insert (dll_cache, "---XEmacs Internal Handle---", dll_open (NULL));
59 DEFUN ("dll-load", Fdll_load, 1, 1, 0, /*
60 Load a shared library DLL into XEmacs. No initialization routines are required.
61 This is for loading dependency DLLs into XEmacs.
69 initialize_dll_cache ();
71 /* If the dll name has a directory component in it, then we should
73 if (!NILP (Fstring_match (build_string ("/"), dll, Qnil, Qnil)))
74 dll = Fexpand_file_name (dll, Qnil);
76 /* Check if we have already opened it first */
77 h = g_hash_table_lookup (dll_cache, XSTRING_DATA (dll));
81 h = dll_open ((char *) XSTRING_DATA (dll));
85 g_hash_table_insert (dll_cache, g_strdup (XSTRING_DATA (dll)), h);
89 signal_simple_error ("dll_open error", build_string (dll_error (NULL)));
92 return (h ? Qt : Qnil);
96 /* Gtk object importing */
97 EXFUN (Fgtk_import_type, 1);
99 static struct hash_table *internal_type_hash;
102 type_hash_equal(const void *arg1, const void *arg2)
104 return ((GtkType) arg1 == (GtkType) arg2);
108 type_hash_hash(const void *arg)
110 return ((unsigned long) arg);
114 type_already_imported_p (GtkType t)
118 /* These are cases that we don't need to import */
119 switch (GTK_FUNDAMENTAL_TYPE (t))
129 case GTK_TYPE_DOUBLE:
130 case GTK_TYPE_STRING:
132 case GTK_TYPE_POINTER:
133 case GTK_TYPE_SIGNAL:
135 case GTK_TYPE_CALLBACK:
136 case GTK_TYPE_C_CALLBACK:
137 case GTK_TYPE_FOREIGN:
141 if (!internal_type_hash)
143 internal_type_hash = make_general_hash_table (163, type_hash_hash, type_hash_equal);
147 if (gethash ((void *)t, internal_type_hash, (const void **)&retval))
155 mark_type_as_imported (GtkType t)
157 if (type_already_imported_p (t))
160 puthash ((void *) t, (void *) 1, internal_type_hash);
163 static void import_gtk_type (GtkType t);
166 import_gtk_object_internal (GtkType the_type)
168 GtkType original_type = the_type;
178 GtkObjectClass *klass;
179 GtkSignalQuery *query;
184 /* Register the type before we do anything else with it... */
187 if (!type_already_imported_p (the_type))
189 import_gtk_type (the_type);
194 /* We need to mark the object type as imported here or we
195 run the risk of SERIOUS recursion when we do automatic
196 argument type importing. mark_type_as_imported() is
197 smart enough to be a noop if we attempt to register
200 mark_type_as_imported (the_type);
203 args = gtk_object_query_args(the_type,&flags,&n_args);
205 /* First get the arguments the object can accept */
206 for (i = 0; i < n_args; i++)
208 if ((args[i].type != original_type) && !type_already_imported_p (args[i].type))
210 import_gtk_type (args[i].type);
218 /* Now lets publish the signals */
219 klass = (GtkObjectClass *) gtk_type_class (the_type);
220 signals = klass->signals;
221 n_signals = klass->nsignals;
223 for (i = 0; i < n_signals; i++)
225 query = gtk_signal_query (signals[i]);
226 /* What do we want to do here? */
231 the_type = gtk_type_parent(the_type);
232 } while (the_type != GTK_TYPE_INVALID);
236 import_gtk_enumeration_internal (GtkType the_type)
238 GtkEnumValue *vals = gtk_type_enum_get_values (the_type);
239 Lisp_Object assoc = Qnil;
241 if (NILP (Venumeration_info))
243 Venumeration_info = call2 (intern ("make-hashtable"), make_int (100), Qequal);
246 while (vals && vals->value_name)
248 assoc = Fcons (Fcons (intern (vals->value_nick), make_int (vals->value)), assoc);
249 assoc = Fcons (Fcons (intern (vals->value_name), make_int (vals->value)), assoc);
253 assoc = Fnreverse (assoc);
255 Fputhash (make_int (the_type), assoc, Venumeration_info);
259 import_gtk_type (GtkType t)
261 if (type_already_imported_p (t))
266 switch (GTK_FUNDAMENTAL_TYPE (t))
270 import_gtk_enumeration_internal (t);
272 case GTK_TYPE_OBJECT:
273 import_gtk_object_internal (t);
279 mark_type_as_imported (t);
283 /* Foreign function calls */
284 static emacs_ffi_data *
285 allocate_ffi_data (void)
287 emacs_ffi_data *data = alloc_lcrecord_type (emacs_ffi_data, &lrecord_emacs_ffi);
289 data->return_type = GTK_TYPE_NONE;
291 data->function_name = Qnil;
292 data->function_ptr = 0;
299 mark_ffi_data (Lisp_Object obj)
301 emacs_ffi_data *data = (emacs_ffi_data *) XFFI (obj);
303 mark_object (data->function_name);
308 ffi_object_printer (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
313 error ("printing unreadable object #<ffi %p", XFFI (obj)->function_ptr);
315 write_c_string ("#<ffi ", printcharfun);
316 print_internal (XFFI (obj)->function_name, printcharfun, 1);
317 if (XFFI (obj)->n_args)
319 sprintf (buf, " %d arguments", XFFI (obj)->n_args);
320 write_c_string (buf, printcharfun);
322 sprintf (buf, " %p>", (void *)XFFI (obj)->function_ptr);
323 write_c_string (buf, printcharfun);
326 DEFINE_LRECORD_IMPLEMENTATION ("ffi", emacs_ffi,
327 mark_ffi_data, ffi_object_printer,
328 0, 0, 0, NULL, emacs_ffi_data);
330 typedef GtkObject * (*__OBJECT_fn) ();
331 typedef gint (*__INT_fn) ();
332 typedef void (*__NONE_fn) ();
333 typedef gchar * (*__STRING_fn) ();
334 typedef gboolean (*__BOOL_fn) ();
335 typedef gfloat (*__FLOAT_fn) ();
336 typedef void * (*__POINTER_fn) ();
337 typedef GList * (*__LIST_fn) ();
339 /* An auto-generated file of marshalling functions. */
340 #include "emacs-marshals.c"
342 #define CONVERT_SINGLE_TYPE(var,nam,tp) case GTK_TYPE_##nam: GTK_VALUE_##nam (var) = * (tp *) v; break;
343 #define CONVERT_RETVAL(a,freep) \
345 void *v = GTK_VALUE_POINTER(a); \
346 switch (GTK_FUNDAMENTAL_TYPE (a.type)) \
348 CONVERT_SINGLE_TYPE(a,CHAR,gchar); \
349 CONVERT_SINGLE_TYPE(a,UCHAR,guchar); \
350 CONVERT_SINGLE_TYPE(a,BOOL,gboolean); \
351 CONVERT_SINGLE_TYPE(a,INT,gint); \
352 CONVERT_SINGLE_TYPE(a,UINT,guint); \
353 CONVERT_SINGLE_TYPE(a,LONG,glong); \
354 CONVERT_SINGLE_TYPE(a,ULONG,gulong); \
355 CONVERT_SINGLE_TYPE(a,FLOAT,gfloat); \
356 CONVERT_SINGLE_TYPE(a,DOUBLE,gdouble); \
357 CONVERT_SINGLE_TYPE(a,STRING,gchar *); \
358 CONVERT_SINGLE_TYPE(a,ENUM,gint); \
359 CONVERT_SINGLE_TYPE(a,FLAGS,guint); \
360 CONVERT_SINGLE_TYPE(a,BOXED,void *); \
361 CONVERT_SINGLE_TYPE(a,POINTER,void *); \
362 CONVERT_SINGLE_TYPE(a,OBJECT,GtkObject *); \
364 GTK_VALUE_POINTER (a) = * (void **) v; \
367 if (freep) xfree(v); \
370 gpointer __allocate_object_storage (GtkType t)
375 switch (GTK_FUNDAMENTAL_TYPE (t))
379 s = (sizeof (gchar));
382 s = (sizeof (guchar));
385 s = (sizeof (gboolean));
391 s = (sizeof (guint));
394 s = (sizeof (glong));
397 s = (sizeof (gulong));
400 s = (sizeof (gfloat));
402 case GTK_TYPE_DOUBLE:
403 s = (sizeof (gdouble));
405 case GTK_TYPE_STRING:
406 s = (sizeof (gchar *));
410 s = (sizeof (guint));
413 case GTK_TYPE_POINTER:
414 s = (sizeof (void *));
417 /* base type of the object system */
418 case GTK_TYPE_OBJECT:
419 s = (sizeof (GtkObject *));
423 if (GTK_FUNDAMENTAL_TYPE (t) == GTK_TYPE_LISTOF)
425 s = (sizeof (void *));
434 memset (rval, '\0', s);
440 Lisp_Object type_to_marshaller_type (GtkType t)
442 switch (GTK_FUNDAMENTAL_TYPE (t))
445 return (build_string ("NONE"));
449 return (build_string ("CHAR"));
451 return (build_string ("BOOL"));
456 return (build_string ("INT"));
459 return (build_string ("LONG"));
461 case GTK_TYPE_DOUBLE:
462 return (build_string ("FLOAT"));
463 case GTK_TYPE_STRING:
464 return (build_string ("STRING"));
466 case GTK_TYPE_POINTER:
467 return (build_string ("POINTER"));
468 case GTK_TYPE_OBJECT:
469 return (build_string ("OBJECT"));
470 case GTK_TYPE_CALLBACK:
471 return (build_string ("CALLBACK"));
473 /* I can't put this in the main switch statement because it is a
474 new fundamental type that is not fixed at compile time.
477 if (GTK_FUNDAMENTAL_TYPE (t) == GTK_TYPE_ARRAY)
478 return (build_string ("ARRAY"));
480 if (GTK_FUNDAMENTAL_TYPE (t) == GTK_TYPE_LISTOF)
481 return (build_string ("LIST"));
486 struct __dll_mapper_closure {
487 void * (*func) (dll_handle, const char *);
488 const char *obj_name;
492 static void __dll_mapper (gpointer key, gpointer value, gpointer user_data)
494 struct __dll_mapper_closure *closure = (struct __dll_mapper_closure *) user_data;
496 if (*(closure->storage) == NULL)
498 /* Need to see if it is in this one */
499 *(closure->storage) = closure->func ((dll_handle) value, closure->obj_name);
503 DEFUN ("gtk-import-variable-internal", Fgtk_import_variable_internal, 2, 2, 0, /*
504 Import a variable into the XEmacs namespace.
511 if (SYMBOLP (type)) type = Fsymbol_name (type);
516 initialize_dll_cache ();
517 xemacs_init_gtk_classes ();
519 arg.type = gtk_type_from_name ((char *) XSTRING_DATA (type));
521 if (arg.type == GTK_TYPE_INVALID)
523 signal_simple_error ("Unknown type", type);
526 /* Need to look thru the already-loaded dlls */
528 struct __dll_mapper_closure closure;
530 closure.func = dll_variable;
531 closure.obj_name = XSTRING_DATA (name);
532 closure.storage = &var;
534 g_hash_table_foreach (dll_cache, __dll_mapper, &closure);
539 signal_simple_error ("Could not locate variable", name);
542 GTK_VALUE_POINTER(arg) = var;
543 CONVERT_RETVAL (arg, 0);
544 return (gtk_type_to_lisp (&arg));
547 DEFUN ("gtk-import-function-internal", Fgtk_import_function_internal, 2, 3, 0, /*
548 Import a function into the XEmacs namespace.
550 (rettype, name, args))
552 Lisp_Object rval = Qnil;
553 Lisp_Object marshaller = Qnil;
554 emacs_ffi_data *data = NULL;
559 ffi_marshalling_function marshaller_func = NULL;
560 ffi_actual_function name_func = NULL;
562 CHECK_SYMBOL (rettype);
566 initialize_dll_cache ();
567 xemacs_init_gtk_classes ();
569 /* Need to look thru the already-loaded dlls */
571 struct __dll_mapper_closure closure;
573 closure.func = dll_function;
574 closure.obj_name = XSTRING_DATA (name);
575 closure.storage = (void **) &name_func;
577 g_hash_table_foreach (dll_cache, __dll_mapper, &closure);
582 signal_simple_error ("Could not locate function", name);
585 data = allocate_ffi_data ();
594 Lisp_Object tail = Qnil;
595 Lisp_Object value = args;
596 Lisp_Object type = Qnil;
598 EXTERNAL_LIST_LOOP (tail, value)
601 Lisp_Object marshaller_type = Qnil;
603 CHECK_SYMBOL (XCAR (tail));
605 type = Fsymbol_name (XCAR (tail));
607 the_type = gtk_type_from_name ((char *) XSTRING_DATA (type));
609 if (the_type == GTK_TYPE_INVALID)
611 signal_simple_error ("Unknown argument type", type);
614 /* All things must be reduced to their basest form... */
615 import_gtk_type (the_type);
616 data->args[n_args] = the_type; /* GTK_FUNDAMENTAL_TYPE (the_type); */
618 /* Now lets build up another chunk of our marshaller function name */
619 marshaller_type = type_to_marshaller_type (data->args[n_args]);
621 if (NILP (marshaller_type))
623 signal_simple_error ("Do not know how to marshal", type);
625 marshaller = concat3 (marshaller, build_string ("_"), marshaller_type);
631 marshaller = concat3 (marshaller, build_string ("_"), type_to_marshaller_type (GTK_TYPE_NONE));
634 rettype = Fsymbol_name (rettype);
635 data->return_type = gtk_type_from_name ((char *) XSTRING_DATA (rettype));
637 if (data->return_type == GTK_TYPE_INVALID)
639 signal_simple_error ("Unknown return type", rettype);
642 import_gtk_type (data->return_type);
644 marshaller = concat3 (type_to_marshaller_type (data->return_type), build_string ("_"), marshaller);
645 marshaller = concat2 (build_string ("emacs_gtk_marshal_"), marshaller);
647 marshaller_func = (ffi_marshalling_function) find_marshaller ((char *) XSTRING_DATA (marshaller));
649 if (!marshaller_func)
651 signal_simple_error ("Could not locate marshaller function", marshaller);
654 data->n_args = n_args;
655 data->function_name = name;
656 data->function_ptr = name_func;
657 data->marshal = marshaller_func;
659 XSETFFI (rval, data);
663 DEFUN ("gtk-call-function", Fgtk_call_function, 1, 2, 0, /*
664 Call an external function.
668 GtkArg the_args[MAX_GTK_ARGS];
670 Lisp_Object retval = Qnil;
675 n_args = XINT (Flength (args));
677 #ifdef XEMACS_IS_SMARTER_THAN_THE_PROGRAMMER
678 /* #### I think this is too dangerous to enable by default.
679 ** #### Genuine program bugs would probably be allowed to
680 ** #### slip by, and not be very easy to find.
681 ** #### Bill Perry July 9, 2000
683 if (n_args != XFFI(func)->n_args)
685 Lisp_Object for_append[3];
687 /* Signal an error if they pass in too many arguments */
688 if (n_args > XFFI(func)->n_args)
690 return Fsignal (Qwrong_number_of_arguments,
691 list2 (func, make_int (n_args)));
694 /* If they did not provide enough arguments, be nice and assume
695 ** they wanted `nil' in there.
697 for_append[0] = args;
698 for_append[1] = Fmake_list (make_int (XFFI(func)->n_args - n_args), Qnil);
700 args = Fappend (2, for_append);
703 if (n_args != XFFI(func)->n_args)
705 /* Signal an error if they do not pass in the correct # of arguments */
706 return Fsignal (Qwrong_number_of_arguments,
707 list2 (func, make_int (n_args)));
713 Lisp_Object tail = Qnil;
714 Lisp_Object value = args;
719 /* First we convert all of the arguments from Lisp to GtkArgs */
720 EXTERNAL_LIST_LOOP (tail, value)
722 the_args[n_args].type = XFFI (func)->args[n_args];
724 if (lisp_to_gtk_type (XCAR (tail), &the_args[n_args]))
726 /* There was some sort of an error */
727 signal_simple_error ("Error converting arguments", args);
733 /* Now we need to tack on space for a return value, if they have
735 if (XFFI (func)->return_type != GTK_TYPE_NONE)
737 the_args[n_args].type = XFFI (func)->return_type;
738 GTK_VALUE_POINTER (the_args[n_args]) = __allocate_object_storage (the_args[n_args].type);
742 XFFI (func)->marshal ((ffi_actual_function) (XFFI (func)->function_ptr), the_args);
744 if (XFFI (func)->return_type != GTK_TYPE_NONE)
746 CONVERT_RETVAL (the_args[n_args - 1], 1);
747 retval = gtk_type_to_lisp (&the_args[n_args - 1]);
750 /* Need to free any array or list pointers */
753 for (i = 0; i < n_args; i++)
755 if (GTK_FUNDAMENTAL_TYPE (the_args[i].type) == GTK_TYPE_ARRAY)
757 g_free (GTK_VALUE_POINTER (the_args[i]));
759 else if (GTK_FUNDAMENTAL_TYPE (the_args[i].type) == GTK_TYPE_LISTOF)
761 /* g_list_free (GTK_VALUE_POINTER (the_args[i])); */
771 /* GtkObject wrapping for Lisp */
773 emacs_gtk_object_printer (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
778 error ("printing unreadable object #<GtkObject %p>", XGTK_OBJECT (obj)->object);
780 write_c_string ("#<GtkObject (", printcharfun);
781 if (XGTK_OBJECT (obj)->alive_p)
782 write_c_string (gtk_type_name (GTK_OBJECT_TYPE (XGTK_OBJECT (obj)->object)), printcharfun);
784 write_c_string ("dead", printcharfun);
785 sprintf (buf, ") %p>", (void *) XGTK_OBJECT (obj)->object);
786 write_c_string (buf, printcharfun);
790 object_getprop (Lisp_Object obj, Lisp_Object prop)
792 Lisp_Object rval = Qnil;
793 Lisp_Object prop_name = Qnil;
794 GtkArgInfo *info = NULL;
798 CHECK_SYMBOL (prop); /* Shouldn't need to ever do this, but I'm paranoid */
800 prop_name = Fsymbol_name (prop);
802 args[0].name = (char *) XSTRING_DATA (prop_name);
804 err = gtk_object_arg_get_info (GTK_OBJECT_TYPE (XGTK_OBJECT (obj)->object),
810 /* Not a magic symbol, fall back to just looking in our real plist */
813 return (Fplist_get (XGTK_OBJECT (obj)->plist, prop, Qunbound));
816 if (!(info->arg_flags & GTK_ARG_READABLE))
818 signal_simple_error ("Attempt to get write-only property", prop);
821 gtk_object_getv (XGTK_OBJECT (obj)->object, 1, args);
823 if (args[0].type == GTK_TYPE_INVALID)
825 /* If we can't get the attribute, then let the code in Fget know
826 so it can use the default value supplied by the caller */
830 rval = gtk_type_to_lisp (&args[0]);
832 /* Free up any memory. According to the documentation and Havoc's
833 book, if the fundamental type of the returned value is
834 GTK_TYPE_STRING, GTK_TYPE_BOXED, or GTK_TYPE_ARGS, you are
835 responsible for freeing it. */
836 switch (GTK_FUNDAMENTAL_TYPE (args[0].type))
838 case GTK_TYPE_STRING:
839 g_free (GTK_VALUE_STRING (args[0]));
842 g_free (GTK_VALUE_BOXED (args[0]));
845 g_free (GTK_VALUE_ARGS (args[0]).args);
854 object_putprop (Lisp_Object obj, Lisp_Object prop, Lisp_Object value)
856 GtkArgInfo *info = NULL;
857 Lisp_Object prop_name = Qnil;
861 prop_name = Fsymbol_name (prop);
863 args[0].name = (char *) XSTRING_DATA (prop_name);
865 err = gtk_object_arg_get_info (GTK_OBJECT_TYPE (XGTK_OBJECT (obj)->object),
871 /* Not a magic symbol, fall back to just storing in our real plist */
874 XGTK_OBJECT (obj)->plist = Fplist_put (XGTK_OBJECT (obj)->plist, prop, value);
878 args[0].type = info->type;
880 if (lisp_to_gtk_type (value, &args[0]))
882 signal_simple_error ("Error converting to GtkType", value);
885 if (!(info->arg_flags & GTK_ARG_WRITABLE))
887 signal_simple_error ("Attemp to set read-only argument", prop);
890 gtk_object_setv (XGTK_OBJECT (obj)->object, 1, args);
896 mark_gtk_object_data (Lisp_Object obj)
898 return (XGTK_OBJECT (obj)->plist);
902 emacs_gtk_object_finalizer (void *header, int for_disksave)
904 emacs_gtk_object_data *data = (emacs_gtk_object_data *) header;
909 XSETGTK_OBJECT (obj, data);
912 ("Can't dump an emacs containing GtkObject objects", obj);
917 gtk_object_unref (data->object);
921 DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS ("GtkObject", emacs_gtk_object,
922 mark_gtk_object_data, /* marker function */
923 emacs_gtk_object_printer, /* print function */
924 emacs_gtk_object_finalizer, /* finalizer */
928 object_getprop, /* get prop */
929 object_putprop, /* put prop */
932 emacs_gtk_object_data);
934 static emacs_gtk_object_data *
935 allocate_emacs_gtk_object_data (void)
937 emacs_gtk_object_data *data = alloc_lcrecord_type (emacs_gtk_object_data,
938 &lrecord_emacs_gtk_object);
941 data->alive_p = FALSE;
947 /* We need to keep track of when the object is destroyed so that we
948 can mark it as dead, otherwise even our print routine (which calls
949 GTK_OBJECT_TYPE) will crap out and die. This is also used in the
950 lisp_to_gtk_type() routine to defend against passing dead objects
953 __notice_object_destruction (GtkObject *obj, gpointer user_data)
955 ungcpro_popup_callbacks ((GUI_ID) user_data);
958 Lisp_Object build_gtk_object (GtkObject *obj)
960 Lisp_Object retval = Qnil;
961 emacs_gtk_object_data *data = NULL;
964 id = (GUI_ID) gtk_object_get_data (obj, GTK_DATA_GUI_IDENTIFIER);
968 retval = get_gcpro_popup_callbacks (id);
973 data = allocate_emacs_gtk_object_data ();
976 data->alive_p = TRUE;
977 XSETGTK_OBJECT (retval, data);
980 gtk_object_set_data (obj, GTK_DATA_GUI_IDENTIFIER, (gpointer) id);
981 gcpro_popup_callbacks (id, retval);
982 gtk_object_ref (obj);
983 gtk_signal_connect (obj, "destroy", GTK_SIGNAL_FUNC (__notice_object_destruction), (gpointer)id);
990 __internal_callback_destroy (gpointer data)
992 Lisp_Object lisp_data;
994 VOID_TO_LISP (lisp_data, data);
996 ungcpro_popup_callbacks (XINT (XCAR (lisp_data)));
1000 __internal_callback_marshal (GtkObject *obj, gpointer data, guint n_args, GtkArg *args)
1002 Lisp_Object arg_list = Qnil;
1003 Lisp_Object callback_fn = Qnil;
1004 Lisp_Object callback_data = Qnil;
1005 Lisp_Object newargs[3];
1006 Lisp_Object rval = Qnil;
1007 struct gcpro gcpro1;
1010 VOID_TO_LISP (callback_fn, data);
1012 /* Nuke the GUI_ID off the front */
1013 callback_fn = XCDR (callback_fn);
1015 callback_data = XCAR (callback_fn);
1016 callback_fn = XCDR (callback_fn);
1018 /* The callback data goes at the very end of the argument list */
1019 arg_list = Fcons (callback_data, Qnil);
1021 /* Build up the argument list, lisp style */
1022 for (i = n_args - 1; i >= 0; i--)
1024 arg_list = Fcons (gtk_type_to_lisp (&args[i]), arg_list);
1027 /* We always pass the widget as the first parameter at the very least */
1028 arg_list = Fcons (build_gtk_object (obj), arg_list);
1030 GCPRO1 ((arg_list));
1032 newargs[0] = callback_fn;
1033 newargs[1] = arg_list;
1035 rval = Fapply (2, newargs);
1036 signal_fake_event ();
1038 if (args[n_args].type != GTK_TYPE_NONE)
1039 lisp_to_gtk_ret_type (rval, &args[n_args]);
1044 DEFUN ("gtk-signal-connect", Fgtk_signal_connect, 3, 6, 0, /*
1046 (obj, name, func, cb_data, object_signal, after_p))
1049 int c_object_signal;
1052 CHECK_GTK_OBJECT (obj);
1055 name = Fsymbol_name (name);
1057 CHECK_STRING (name);
1059 if (NILP (object_signal))
1060 c_object_signal = 0;
1062 c_object_signal = 1;
1070 func = Fcons (cb_data, func);
1071 func = Fcons (make_int (id), func);
1073 gcpro_popup_callbacks (id, func);
1075 gtk_signal_connect_full (XGTK_OBJECT (obj)->object, (char *) XSTRING_DATA (name),
1076 NULL, __internal_callback_marshal, LISP_TO_VOID (func),
1077 __internal_callback_destroy, c_object_signal, c_after);
1082 /* GTK_TYPE_BOXED wrapper for Emacs lisp */
1084 emacs_gtk_boxed_printer (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
1089 error ("printing unreadable object #<GtkBoxed %p>", XGTK_BOXED (obj)->object);
1091 write_c_string ("#<GtkBoxed (", printcharfun);
1092 write_c_string (gtk_type_name (XGTK_BOXED (obj)->object_type), printcharfun);
1093 sprintf (buf, ") %p>", (void *) XGTK_BOXED (obj)->object);
1094 write_c_string (buf, printcharfun);
1098 emacs_gtk_boxed_equality (Lisp_Object o1, Lisp_Object o2, int depth)
1100 emacs_gtk_boxed_data *data1 = XGTK_BOXED(o1);
1101 emacs_gtk_boxed_data *data2 = XGTK_BOXED(o2);
1103 return ((data1->object == data2->object) &&
1104 (data1->object_type == data2->object_type));
1107 static unsigned long
1108 emacs_gtk_boxed_hash (Lisp_Object obj, int depth)
1110 emacs_gtk_boxed_data *data = XGTK_BOXED(obj);
1111 return (HASH2 ((unsigned long)data->object, data->object_type));
1114 DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS ("GtkBoxed", emacs_gtk_boxed,
1115 0, /* marker function */
1116 emacs_gtk_boxed_printer, /* print function */
1118 emacs_gtk_boxed_equality, /* equality */
1119 emacs_gtk_boxed_hash, /* hash */
1125 emacs_gtk_boxed_data);
1127 /* Currently defined GTK_TYPE_BOXED structures are:
1141 static emacs_gtk_boxed_data *
1142 allocate_emacs_gtk_boxed_data (void)
1144 emacs_gtk_boxed_data *data = alloc_lcrecord_type (emacs_gtk_boxed_data,
1145 &lrecord_emacs_gtk_boxed);
1147 data->object = NULL;
1148 data->object_type = GTK_TYPE_INVALID;
1153 Lisp_Object build_gtk_boxed (void *obj, GtkType t)
1155 Lisp_Object retval = Qnil;
1156 emacs_gtk_boxed_data *data = NULL;
1158 if (GTK_FUNDAMENTAL_TYPE (t) != GTK_TYPE_BOXED)
1161 data = allocate_emacs_gtk_boxed_data ();
1163 data->object_type = t;
1165 XSETGTK_BOXED (retval, data);
1171 /* The automatically generated structure access routines */
1172 #include "emacs-widget-accessors.c"
1174 /* The hand generated funky functions that we can't just import using the FFI */
1175 #include "ui-byhand.c"
1177 /* The glade support */
1181 /* Type manipulation */
1182 DEFUN ("gtk-fundamental-type", Fgtk_fundamental_type, 1, 1, 0, /*
1183 Load a shared library DLL into XEmacs. No initialization routines are required.
1184 This is for loading dependency DLLs into XEmacs.
1191 type = Fsymbol_name (type);
1193 CHECK_STRING (type);
1195 t = gtk_type_from_name ((char *) XSTRING_DATA (type));
1197 if (t == GTK_TYPE_INVALID)
1199 signal_simple_error ("Not a GTK type", type);
1201 return (make_int (GTK_FUNDAMENTAL_TYPE (t)));
1204 DEFUN ("gtk-object-type", Fgtk_object_type, 1, 1, 0, /*
1205 Return the GtkType of OBJECT.
1209 CHECK_GTK_OBJECT (object);
1210 return (make_int (GTK_OBJECT_TYPE (XGTK_OBJECT (object)->object)));
1213 DEFUN ("gtk-describe-type", Fgtk_describe_type, 1, 1, 0, /*
1214 Returns a cons of two lists describing the Gtk object TYPE.
1215 The car is a list of all the signals that it will emit.
1216 The cdr is a list of all the magic properties it has.
1220 Lisp_Object rval, signals, props;
1223 props = signals = rval = Qnil;
1227 type = Fsymbol_name (type);
1232 t = gtk_type_from_name (XSTRING_DATA (type));
1233 if (t == GTK_TYPE_INVALID)
1235 signal_simple_error ("Not a GTK type", type);
1244 if (GTK_FUNDAMENTAL_TYPE (t) != GTK_TYPE_OBJECT)
1246 signal_simple_error ("Not a GtkObject", type);
1249 /* Need to do stupid shit like this to get the args
1250 ** registered... damn GTK and its lazy loading
1254 GtkObject *obj = gtk_object_newv (t, 0, args);
1256 gtk_object_destroy(obj);
1263 /* Do the magic arguments first */
1269 args = gtk_object_query_args(t,&flags,&n_args);
1271 for (i = 0; i < n_args; i++)
1273 props = Fcons (Fcons (intern (gtk_type_name(args[i].type)),
1274 intern (args[i].name)), props);
1281 /* Now the signals */
1283 GtkObjectClass *klass;
1284 GtkSignalQuery *query;
1285 guint32 *gtk_signals;
1288 klass = (GtkObjectClass *) gtk_type_class (t);
1289 gtk_signals = klass->signals;
1290 n_signals = klass->nsignals;
1292 for (i = 0; i < n_signals; i++)
1294 Lisp_Object params = Qnil;
1296 query = gtk_signal_query (gtk_signals[i]);
1304 for (j = query->nparams - 1; j >= 0; j--)
1306 params = Fcons (intern (gtk_type_name (query->params[j])), params);
1310 signals = Fcons (Fcons (intern (gtk_type_name (query->return_val)),
1311 Fcons (intern (query->signal_name),
1319 t = gtk_type_parent(t);
1320 } while (t != GTK_TYPE_INVALID);
1322 rval = Fcons (signals, props);
1329 syms_of_ui_gtk (void)
1331 INIT_LRECORD_IMPLEMENTATION (emacs_ffi);
1332 INIT_LRECORD_IMPLEMENTATION (emacs_gtk_object);
1333 INIT_LRECORD_IMPLEMENTATION (emacs_gtk_boxed);
1334 defsymbol (&Qemacs_ffip, "emacs-ffi-p");
1335 defsymbol (&Qemacs_gtk_objectp, "emacs-gtk-object-p");
1336 defsymbol (&Qemacs_gtk_boxedp, "emacs-gtk-boxed-p");
1337 defsymbol (&Qvoid, "void");
1338 DEFSUBR (Fdll_load);
1339 DEFSUBR (Fgtk_import_function_internal);
1340 DEFSUBR (Fgtk_import_variable_internal);
1341 DEFSUBR (Fgtk_signal_connect);
1342 DEFSUBR (Fgtk_call_function);
1343 DEFSUBR (Fgtk_fundamental_type);
1344 DEFSUBR (Fgtk_object_type);
1345 DEFSUBR (Fgtk_describe_type);
1346 syms_of_widget_accessors ();
1347 syms_of_ui_byhand ();
1352 vars_of_ui_gtk (void)
1354 Fprovide (intern ("gtk-ui"));
1355 DEFVAR_LISP ("gtk-enumeration-info", &Venumeration_info /*
1356 A hashtable holding type information about GTK enumerations and flags.
1357 Do NOT modify unless you really understand ui-gtk.c.
1360 Venumeration_info = Qnil;
1365 /* Various utility functions */
1366 void describe_gtk_arg (GtkArg *arg)
1370 switch (GTK_FUNDAMENTAL_TYPE (a.type))
1374 stderr_out ("char: %c\n", GTK_VALUE_CHAR (a));
1376 case GTK_TYPE_UCHAR:
1377 stderr_out ("uchar: %c\n", GTK_VALUE_CHAR (a));
1380 stderr_out ("uchar: %s\n", GTK_VALUE_BOOL (a) ? "true" : "false");
1383 stderr_out ("int: %d\n", GTK_VALUE_INT (a));
1386 stderr_out ("uint: %du\n", GTK_VALUE_UINT (a));
1389 stderr_out ("long: %ld\n", GTK_VALUE_LONG (a));
1391 case GTK_TYPE_ULONG:
1392 stderr_out ("ulong: %lu\n", GTK_VALUE_ULONG (a));
1394 case GTK_TYPE_FLOAT:
1395 stderr_out ("float: %g\n", GTK_VALUE_FLOAT (a));
1397 case GTK_TYPE_DOUBLE:
1398 stderr_out ("double: %f\n", GTK_VALUE_DOUBLE (a));
1400 case GTK_TYPE_STRING:
1401 stderr_out ("string: %s\n", GTK_VALUE_STRING (a));
1404 case GTK_TYPE_FLAGS:
1405 stderr_out ("%s: ", (a.type == GTK_TYPE_ENUM) ? "enum" : "flag");
1407 GtkEnumValue *vals = gtk_type_enum_get_values (a.type);
1409 while (vals && vals->value_name && (vals->value != GTK_VALUE_ENUM(a))) vals++;
1411 stderr_out ("%s\n", vals ? vals->value_name : "!!! UNKNOWN ENUM VALUE !!!");
1414 case GTK_TYPE_BOXED:
1415 stderr_out ("boxed: %p\n", GTK_VALUE_BOXED (a));
1417 case GTK_TYPE_POINTER:
1418 stderr_out ("pointer: %p\n", GTK_VALUE_BOXED (a));
1421 /* structured types */
1422 case GTK_TYPE_SIGNAL:
1423 case GTK_TYPE_ARGS: /* This we can do as a list of values */
1425 case GTK_TYPE_CALLBACK:
1426 stderr_out ("callback fn: ...\n");
1428 case GTK_TYPE_C_CALLBACK:
1429 case GTK_TYPE_FOREIGN:
1432 /* base type of the object system */
1433 case GTK_TYPE_OBJECT:
1434 if (GTK_VALUE_OBJECT (a))
1435 stderr_out ("object: %s\n", gtk_type_name (GTK_OBJECT_TYPE (GTK_VALUE_OBJECT (a))));
1437 stderr_out ("object: NULL\n");
1445 Lisp_Object gtk_type_to_lisp (GtkArg *arg)
1447 switch (GTK_FUNDAMENTAL_TYPE (arg->type))
1452 return (make_char (GTK_VALUE_CHAR (*arg)));
1453 case GTK_TYPE_UCHAR:
1454 return (make_char (GTK_VALUE_UCHAR (*arg)));
1456 return (GTK_VALUE_BOOL (*arg) ? Qt : Qnil);
1458 return (make_int (GTK_VALUE_INT (*arg)));
1460 return (make_int (GTK_VALUE_INT (*arg)));
1461 case GTK_TYPE_LONG: /* I think these are wrong! */
1462 return (make_int (GTK_VALUE_INT (*arg)));
1463 case GTK_TYPE_ULONG: /* I think these are wrong! */
1464 return (make_int (GTK_VALUE_INT (*arg)));
1465 case GTK_TYPE_FLOAT:
1466 return (make_float (GTK_VALUE_FLOAT (*arg)));
1467 case GTK_TYPE_DOUBLE:
1468 return (make_float (GTK_VALUE_DOUBLE (*arg)));
1469 case GTK_TYPE_STRING:
1470 return (build_string (GTK_VALUE_STRING (*arg)));
1471 case GTK_TYPE_FLAGS:
1472 return (flags_to_list (GTK_VALUE_FLAGS (*arg), arg->type));
1474 return (enum_to_symbol (GTK_VALUE_ENUM (*arg), arg->type));
1475 case GTK_TYPE_BOXED:
1476 if (arg->type == GTK_TYPE_GDK_EVENT)
1478 return (gdk_event_to_emacs_event((GdkEvent *) GTK_VALUE_BOXED (*arg)));
1481 if (GTK_VALUE_BOXED (*arg))
1482 return (build_gtk_boxed (GTK_VALUE_BOXED (*arg), arg->type));
1485 case GTK_TYPE_POINTER:
1486 if (GTK_VALUE_POINTER (*arg))
1490 VOID_TO_LISP (rval, GTK_VALUE_POINTER (*arg));
1495 case GTK_TYPE_OBJECT:
1496 if (GTK_VALUE_OBJECT (*arg))
1497 return (build_gtk_object (GTK_VALUE_OBJECT (*arg)));
1501 case GTK_TYPE_CALLBACK:
1505 VOID_TO_LISP (rval, GTK_VALUE_CALLBACK (*arg).data);
1511 if (GTK_FUNDAMENTAL_TYPE (arg->type) == GTK_TYPE_LISTOF)
1513 if (!GTK_VALUE_POINTER (*arg))
1517 return (xemacs_gtklist_to_list (arg));
1520 stderr_out ("Do not know how to convert `%s' to lisp!\n", gtk_type_name (arg->type));
1523 /* This is chuck reminding GCC to... SHUT UP! */
1527 int lisp_to_gtk_type (Lisp_Object obj, GtkArg *arg)
1529 switch (GTK_FUNDAMENTAL_TYPE (arg->type))
1538 CHECK_CHAR_COERCE_INT (obj);
1540 GTK_VALUE_CHAR (*arg) = c;
1543 case GTK_TYPE_UCHAR:
1547 CHECK_CHAR_COERCE_INT (obj);
1549 GTK_VALUE_CHAR (*arg) = c;
1553 GTK_VALUE_BOOL (*arg) = NILP (obj) ? FALSE : TRUE;
1557 if (NILP (obj) || EQ (Qt, obj))
1559 /* For we are a kind mistress and allow sending t/nil for
1560 1/0 to stupid GTK functions that say they take guint or
1561 gint in the header files, but actually treat it like a
1564 GTK_VALUE_INT(*arg) = NILP (obj) ? 0 : 1;
1569 GTK_VALUE_INT(*arg) = XINT (obj);
1573 case GTK_TYPE_ULONG:
1575 case GTK_TYPE_FLOAT:
1576 CHECK_INT_OR_FLOAT (obj);
1577 GTK_VALUE_FLOAT(*arg) = extract_float (obj);
1579 case GTK_TYPE_DOUBLE:
1580 CHECK_INT_OR_FLOAT (obj);
1581 GTK_VALUE_DOUBLE(*arg) = extract_float (obj);
1583 case GTK_TYPE_STRING:
1585 GTK_VALUE_STRING (*arg) = NULL;
1589 GTK_VALUE_STRING (*arg) = (char *) XSTRING_DATA (obj);
1593 case GTK_TYPE_FLAGS:
1594 /* Convert a lisp symbol to a GTK enum */
1595 GTK_VALUE_ENUM(*arg) = lisp_to_flag (obj, arg->type);
1597 case GTK_TYPE_BOXED:
1600 GTK_VALUE_BOXED(*arg) = NULL;
1602 else if (GTK_BOXEDP (obj))
1604 GTK_VALUE_BOXED(*arg) = XGTK_BOXED (obj)->object;
1606 else if (arg->type == GTK_TYPE_STYLE)
1608 obj = Ffind_face (obj);
1610 GTK_VALUE_BOXED(*arg) = face_to_style (obj);
1612 else if (arg->type == GTK_TYPE_GDK_GC)
1614 obj = Ffind_face (obj);
1616 GTK_VALUE_BOXED(*arg) = face_to_gc (obj);
1618 else if (arg->type == GTK_TYPE_GDK_WINDOW)
1622 Lisp_Object window = Fselected_window (Qnil);
1623 Lisp_Object instance = glyph_image_instance (obj, window, ERROR_ME_NOT, 1);
1624 struct Lisp_Image_Instance *p = XIMAGE_INSTANCE (instance);
1626 switch (XIMAGE_INSTANCE_TYPE (instance))
1630 case IMAGE_SUBWINDOW:
1632 GTK_VALUE_BOXED(*arg) = NULL;
1635 case IMAGE_MONO_PIXMAP:
1636 case IMAGE_COLOR_PIXMAP:
1637 GTK_VALUE_BOXED(*arg) = IMAGE_INSTANCE_GTK_PIXMAP (p);
1641 else if (GTK_OBJECTP (obj) && GTK_IS_WIDGET (XGTK_OBJECT (obj)->object))
1643 GTK_VALUE_BOXED(*arg) = GTK_WIDGET (XGTK_OBJECT (obj))->window;
1647 signal_simple_error ("Don't know how to convert object to GDK_WINDOW", obj);
1651 else if (arg->type == GTK_TYPE_GDK_COLOR)
1653 if (COLOR_SPECIFIERP (obj))
1655 /* If it is a specifier, we just convert it to an
1656 instance, and let the ifs below handle it.
1658 obj = Fspecifier_instance (obj, Qnil, Qnil, Qnil);
1661 if (COLOR_INSTANCEP (obj))
1664 GTK_VALUE_BOXED(*arg) = COLOR_INSTANCE_GTK_COLOR (XCOLOR_INSTANCE (obj));
1666 else if (STRINGP (obj))
1668 signal_simple_error ("Please use a color specifier or instance, not a string", obj);
1672 signal_simple_error ("Don't know hot to convert to GdkColor", obj);
1675 else if (arg->type == GTK_TYPE_GDK_FONT)
1679 /* If it is a symbol, we treat that as a face name */
1680 obj = Ffind_face (obj);
1685 /* If it is a face, we just grab the font specifier, and
1686 cascade down until we finally reach a FONT_INSTANCE
1688 obj = Fget (obj, Qfont, Qnil);
1691 if (FONT_SPECIFIERP (obj))
1693 /* If it is a specifier, we just convert it to an
1694 instance, and let the ifs below handle it
1696 obj = Fspecifier_instance (obj, Qnil, Qnil, Qnil);
1699 if (FONT_INSTANCEP (obj))
1702 GTK_VALUE_BOXED(*arg) = FONT_INSTANCE_GTK_FONT (XFONT_INSTANCE (obj));
1704 else if (STRINGP (obj))
1706 signal_simple_error ("Please use a font specifier or instance, not a string", obj);
1710 signal_simple_error ("Don't know hot to convert to GdkColor", obj);
1715 /* Unknown type to convert to boxed */
1716 stderr_out ("Don't know how to convert to boxed!\n");
1717 GTK_VALUE_BOXED(*arg) = NULL;
1721 case GTK_TYPE_POINTER:
1723 GTK_VALUE_POINTER(*arg) = NULL;
1725 GTK_VALUE_POINTER(*arg) = LISP_TO_VOID (obj);
1728 /* structured types */
1729 case GTK_TYPE_SIGNAL:
1730 case GTK_TYPE_ARGS: /* This we can do as a list of values */
1731 case GTK_TYPE_C_CALLBACK:
1732 case GTK_TYPE_FOREIGN:
1733 stderr_out ("Do not know how to convert `%s' from lisp!\n", gtk_type_name (arg->type));
1738 /* This is not used, and does not work with union type */
1739 case GTK_TYPE_CALLBACK:
1744 obj = Fcons (Qnil, obj); /* Empty data */
1745 obj = Fcons (make_int (id), obj);
1747 gcpro_popup_callbacks (id, obj);
1749 GTK_VALUE_CALLBACK(*arg).marshal = __internal_callback_marshal;
1750 GTK_VALUE_CALLBACK(*arg).data = (gpointer) obj;
1751 GTK_VALUE_CALLBACK(*arg).notify = __internal_callback_destroy;
1756 /* base type of the object system */
1757 case GTK_TYPE_OBJECT:
1759 GTK_VALUE_OBJECT (*arg) = NULL;
1762 CHECK_GTK_OBJECT (obj);
1763 if (XGTK_OBJECT (obj)->alive_p)
1764 GTK_VALUE_OBJECT (*arg) = XGTK_OBJECT (obj)->object;
1766 signal_simple_error ("Attempting to pass dead object to GTK function", obj);
1771 if (GTK_FUNDAMENTAL_TYPE (arg->type) == GTK_TYPE_ARRAY)
1774 GTK_VALUE_POINTER(*arg) = NULL;
1777 xemacs_list_to_array (obj, arg);
1780 else if (GTK_FUNDAMENTAL_TYPE (arg->type) == GTK_TYPE_LISTOF)
1783 GTK_VALUE_POINTER(*arg) = NULL;
1786 xemacs_list_to_gtklist (obj, arg);
1791 stderr_out ("Do not know how to convert `%s' from lisp!\n", gtk_type_name (arg->type));
1800 /* Convert lisp types to GTK return types. This is identical to
1801 lisp_to_gtk_type() except that the macro used to set the value is
1804 ### There should be some way of combining these two functions.
1806 int lisp_to_gtk_ret_type (Lisp_Object obj, GtkArg *arg)
1808 switch (GTK_FUNDAMENTAL_TYPE (arg->type))
1817 CHECK_CHAR_COERCE_INT (obj);
1819 *(GTK_RETLOC_CHAR (*arg)) = c;
1822 case GTK_TYPE_UCHAR:
1826 CHECK_CHAR_COERCE_INT (obj);
1828 *(GTK_RETLOC_CHAR (*arg)) = c;
1832 *(GTK_RETLOC_BOOL (*arg)) = NILP (obj) ? FALSE : TRUE;
1836 if (NILP (obj) || EQ (Qt, obj))
1838 /* For we are a kind mistress and allow sending t/nil for
1839 1/0 to stupid GTK functions that say they take guint or
1840 gint in the header files, but actually treat it like a
1843 *(GTK_RETLOC_INT(*arg)) = NILP (obj) ? 0 : 1;
1848 *(GTK_RETLOC_INT(*arg)) = XINT (obj);
1852 case GTK_TYPE_ULONG:
1854 case GTK_TYPE_FLOAT:
1855 CHECK_INT_OR_FLOAT (obj);
1856 *(GTK_RETLOC_FLOAT(*arg)) = extract_float (obj);
1858 case GTK_TYPE_DOUBLE:
1859 CHECK_INT_OR_FLOAT (obj);
1860 *(GTK_RETLOC_DOUBLE(*arg)) = extract_float (obj);
1862 case GTK_TYPE_STRING:
1864 *(GTK_RETLOC_STRING (*arg)) = NULL;
1868 *(GTK_RETLOC_STRING (*arg)) = (char *) XSTRING_DATA (obj);
1872 case GTK_TYPE_FLAGS:
1873 /* Convert a lisp symbol to a GTK enum */
1874 *(GTK_RETLOC_ENUM(*arg)) = lisp_to_flag (obj, arg->type);
1876 case GTK_TYPE_BOXED:
1879 *(GTK_RETLOC_BOXED(*arg)) = NULL;
1881 else if (GTK_BOXEDP (obj))
1883 *(GTK_RETLOC_BOXED(*arg)) = XGTK_BOXED (obj)->object;
1885 else if (arg->type == GTK_TYPE_STYLE)
1887 obj = Ffind_face (obj);
1889 *(GTK_RETLOC_BOXED(*arg)) = face_to_style (obj);
1891 else if (arg->type == GTK_TYPE_GDK_GC)
1893 obj = Ffind_face (obj);
1895 *(GTK_RETLOC_BOXED(*arg)) = face_to_gc (obj);
1897 else if (arg->type == GTK_TYPE_GDK_WINDOW)
1901 Lisp_Object window = Fselected_window (Qnil);
1902 Lisp_Object instance = glyph_image_instance (obj, window, ERROR_ME_NOT, 1);
1903 struct Lisp_Image_Instance *p = XIMAGE_INSTANCE (instance);
1905 switch (XIMAGE_INSTANCE_TYPE (instance))
1909 case IMAGE_SUBWINDOW:
1911 *(GTK_RETLOC_BOXED(*arg)) = NULL;
1914 case IMAGE_MONO_PIXMAP:
1915 case IMAGE_COLOR_PIXMAP:
1916 *(GTK_RETLOC_BOXED(*arg)) = IMAGE_INSTANCE_GTK_PIXMAP (p);
1920 else if (GTK_OBJECTP (obj) && GTK_IS_WIDGET (XGTK_OBJECT (obj)->object))
1922 *(GTK_RETLOC_BOXED(*arg)) = GTK_WIDGET (XGTK_OBJECT (obj))->window;
1926 signal_simple_error ("Don't know how to convert object to GDK_WINDOW", obj);
1930 else if (arg->type == GTK_TYPE_GDK_COLOR)
1932 if (COLOR_SPECIFIERP (obj))
1934 /* If it is a specifier, we just convert it to an
1935 instance, and let the ifs below handle it.
1937 obj = Fspecifier_instance (obj, Qnil, Qnil, Qnil);
1940 if (COLOR_INSTANCEP (obj))
1943 *(GTK_RETLOC_BOXED(*arg)) = COLOR_INSTANCE_GTK_COLOR (XCOLOR_INSTANCE (obj));
1945 else if (STRINGP (obj))
1947 signal_simple_error ("Please use a color specifier or instance, not a string", obj);
1951 signal_simple_error ("Don't know hot to convert to GdkColor", obj);
1954 else if (arg->type == GTK_TYPE_GDK_FONT)
1958 /* If it is a symbol, we treat that as a face name */
1959 obj = Ffind_face (obj);
1964 /* If it is a face, we just grab the font specifier, and
1965 cascade down until we finally reach a FONT_INSTANCE
1967 obj = Fget (obj, Qfont, Qnil);
1970 if (FONT_SPECIFIERP (obj))
1972 /* If it is a specifier, we just convert it to an
1973 instance, and let the ifs below handle it
1975 obj = Fspecifier_instance (obj, Qnil, Qnil, Qnil);
1978 if (FONT_INSTANCEP (obj))
1981 *(GTK_RETLOC_BOXED(*arg)) = FONT_INSTANCE_GTK_FONT (XFONT_INSTANCE (obj));
1983 else if (STRINGP (obj))
1985 signal_simple_error ("Please use a font specifier or instance, not a string", obj);
1989 signal_simple_error ("Don't know hot to convert to GdkColor", obj);
1994 /* Unknown type to convert to boxed */
1995 stderr_out ("Don't know how to convert to boxed!\n");
1996 *(GTK_RETLOC_BOXED(*arg)) = NULL;
2000 case GTK_TYPE_POINTER:
2002 *(GTK_RETLOC_POINTER(*arg)) = NULL;
2004 *(GTK_RETLOC_POINTER(*arg)) = LISP_TO_VOID (obj);
2007 /* structured types */
2008 case GTK_TYPE_SIGNAL:
2009 case GTK_TYPE_ARGS: /* This we can do as a list of values */
2010 case GTK_TYPE_C_CALLBACK:
2011 case GTK_TYPE_FOREIGN:
2012 stderr_out ("Do not know how to convert `%s' from lisp!\n", gtk_type_name (arg->type));
2017 /* This is not used, and does not work with union type */
2018 case GTK_TYPE_CALLBACK:
2023 obj = Fcons (Qnil, obj); /* Empty data */
2024 obj = Fcons (make_int (id), obj);
2026 gcpro_popup_callbacks (id, obj);
2028 *(GTK_RETLOC_CALLBACK(*arg)).marshal = __internal_callback_marshal;
2029 *(GTK_RETLOC_CALLBACK(*arg)).data = (gpointer) obj;
2030 *(GTK_RETLOC_CALLBACK(*arg)).notify = __internal_callback_destroy;
2035 /* base type of the object system */
2036 case GTK_TYPE_OBJECT:
2038 *(GTK_RETLOC_OBJECT (*arg)) = NULL;
2041 CHECK_GTK_OBJECT (obj);
2042 if (XGTK_OBJECT (obj)->alive_p)
2043 *(GTK_RETLOC_OBJECT (*arg)) = XGTK_OBJECT (obj)->object;
2045 signal_simple_error ("Attempting to pass dead object to GTK function", obj);
2050 if (GTK_FUNDAMENTAL_TYPE (arg->type) == GTK_TYPE_ARRAY)
2053 *(GTK_RETLOC_POINTER(*arg)) = NULL;
2056 xemacs_list_to_array (obj, arg);
2059 else if (GTK_FUNDAMENTAL_TYPE (arg->type) == GTK_TYPE_LISTOF)
2062 *(GTK_RETLOC_POINTER(*arg)) = NULL;
2065 xemacs_list_to_gtklist (obj, arg);
2070 stderr_out ("Do not know how to convert `%s' from lisp!\n", gtk_type_name (arg->type));
2079 /* This is used in glyphs-gtk.c as well */
2081 get_enumeration (GtkType t)
2085 if (NILP (Venumeration_info))
2087 Venumeration_info = call2 (intern ("make-hashtable"), make_int (100), Qequal);
2090 alist = Fgethash (make_int (t), Venumeration_info, Qnil);
2094 import_gtk_enumeration_internal (t);
2095 alist = Fgethash (make_int (t), Venumeration_info, Qnil);
2101 symbol_to_enum (Lisp_Object obj, GtkType t)
2103 Lisp_Object alist = get_enumeration (t);
2104 Lisp_Object value = Qnil;
2108 signal_simple_error ("Unkown enumeration", build_string (gtk_type_name (t)));
2111 value = Fassq (obj, alist);
2115 signal_simple_error ("Unknown value", obj);
2118 CHECK_INT (XCDR (value));
2120 return (XINT (XCDR (value)));
2124 lisp_to_flag (Lisp_Object obj, GtkType t)
2132 else if (SYMBOLP (obj))
2134 val = symbol_to_enum (obj, t);
2136 else if (LISTP (obj))
2140 val |= symbol_to_enum (XCAR (obj), t);
2152 flags_to_list (guint value, GtkType t)
2154 Lisp_Object rval = Qnil;
2155 Lisp_Object alist = get_enumeration (t);
2157 while (!NILP (alist))
2159 if (value & XINT (XCDR (XCAR (alist))))
2161 rval = Fcons (XCAR (XCAR (alist)), rval);
2162 value &= ~(XINT (XCDR (XCAR (alist))));
2164 alist = XCDR (alist);
2170 enum_to_symbol (guint value, GtkType t)
2172 Lisp_Object alist = get_enumeration (t);
2173 Lisp_Object cell = Qnil;
2177 signal_simple_error ("Unkown enumeration", build_string (gtk_type_name (t)));
2180 cell = Frassq (make_int (value), alist);
2182 return (NILP (cell) ? Qnil : XCAR (cell));