- Spanner * sl = dynamic_cast<Spanner*> (unsmob_grob (slur));
- SCM_ASSERT_TYPE (sl, slur, SCM_ARG1, __FUNCTION__, "spanner grob");
- SCM_ASSERT_TYPE (is_direction (dir), slur, SCM_ARG2, __FUNCTION__, "dir");
- return sl->get_bound (to_dir (dir))->self_scm ();
+ Grob *sc = unsmob_grob (grob);
+
+ LY_ASSERT_SMOB (Grob, grob, 1);
+ LY_ASSERT_TYPE (ly_is_symbol, sym, 2);
+ if (val == SCM_UNDEFINED)
+ val = SCM_EOL;
+
+ SCM retval = sc->internal_get_property (sym);
+ if (retval == SCM_EOL)
+ retval = val;
+
+ return retval;
+}
+
+LY_DEFINE (ly_grob_interfaces, "ly:grob-interfaces",
+ 1, 0, 0, (SCM grob),
+ "Return the interfaces list of grob @var{grob}.")
+{
+ Grob *sc = unsmob_grob (grob);
+
+ LY_ASSERT_SMOB (Grob, grob, 1);
+
+ return sc->interfaces ();
+}
+
+LY_DEFINE (ly_grob_object, "ly:grob-object",
+ 2, 0, 0, (SCM grob, SCM sym),
+ "Return the value of a pointer in grob @var{grob} of property"
+ " @var{sym}. It returns @code{'()} (end-of-list) if @var{sym}"
+ " is undefined in @var{grob}.")
+{
+ Grob *sc = unsmob_grob (grob);
+
+ LY_ASSERT_SMOB (Grob, grob, 1);
+ LY_ASSERT_TYPE (ly_is_symbol, sym, 2);
+
+ return sc->internal_get_object (sym);
+}
+
+LY_DEFINE (ly_grob_set_object_x, "ly:grob-set-object!",
+ 3, 0, 0, (SCM grob, SCM sym, SCM val),
+ "Set @var{sym} in grob @var{grob} to value @var{val}.")
+{
+ Grob *sc = unsmob_grob (grob);
+
+ LY_ASSERT_SMOB (Grob, grob, 1);
+ LY_ASSERT_TYPE (ly_is_symbol, sym, 2);
+
+ sc->set_object (sym, val);
+ return SCM_UNSPECIFIED;