Updated copyright text/header in most source files.
[geda-gaf/peter-b.git] / gschem / src / g_hook.c
blob9866eafc43af826aa826506d31e9027e0a95d59b
1 /* gEDA - GPL Electronic Design Automation
2 * gschem - gEDA Schematic Capture
3 * Copyright (C) 1998-2010 Ales Hvezda
4 * Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details)
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
20 #include <config.h>
21 #include <stdio.h>
22 #ifdef HAVE_STRING_H
23 #include <string.h>
24 #endif
25 #include <math.h>
27 #include "gschem.h"
29 #ifdef HAVE_LIBDMALLOC
30 #include <dmalloc.h>
31 #endif
33 /* Private function declarations */
34 static void custom_world_get_single_object_bounds
35 (TOPLEVEL *toplevel, OBJECT *o_current,
36 int *left, int *top,
37 int *right, int *bottom,
38 GList *exclude_attrib_list,
39 GList *exclude_obj_type_list);
41 static void custom_world_get_object_glist_bounds
42 (TOPLEVEL *toplevel, GList *list,
43 int *left, int *top,
44 int *right, int *bottom,
45 GList *exclude_attrib_list,
46 GList *exclude_obj_type_list);
48 /*! \todo Finish function documentation!!!
49 * \brief
50 * \par Function Description
53 /* Makes a list of all attributes currently connected to object.
54 * Uses the attribute list returned by o_attrib_return_attribs()
56 SCM g_make_attrib_smob_list (GSCHEM_TOPLEVEL *w_current, OBJECT *object)
58 GList *attrib_list;
59 GList *a_iter;
60 OBJECT *a_current;
61 SCM smob_list = SCM_EOL;
63 if (object == NULL) {
64 return SCM_EOL;
67 attrib_list = o_attrib_return_attribs (object);
69 if (attrib_list == NULL)
70 return SCM_EOL;
72 /* go through attribs */
73 for (a_iter = attrib_list; a_iter != NULL;
74 a_iter = g_list_next (a_iter)) {
75 a_current = a_iter->data;
77 smob_list = scm_cons (g_make_attrib_smob (w_current->toplevel, a_current),
78 smob_list);
81 g_list_free (attrib_list);
83 return smob_list;
86 /*! \todo Finish function documentation!!!
87 * \brief
88 * \par Function Description
91 /**************************************************************************
92 * This function partly part of libgeda, since it belongs to the smob *
93 * definition. But since I use o_text_change, which is defined in gschem, *
94 * we have to do it like this. *
95 **************************************************************************/
96 SCM g_set_attrib_value_x(SCM attrib_smob, SCM scm_value)
98 SCM returned;
99 TOPLEVEL *toplevel;
100 OBJECT *o_attrib;
101 char *new_string;
103 returned = g_set_attrib_value_internal(attrib_smob, scm_value,
104 &toplevel, &o_attrib, &new_string);
106 o_text_change(global_window_current, o_attrib, new_string,
107 o_attrib->visibility, o_attrib->show_name_value);
109 g_free(new_string);
111 return returned;
114 /*! \todo Finish function documentation!!!
115 * \brief
116 * \par Function Description
120 * Adds an attribute <B>scm_attrib_name</B> with value <B>scm_attrib_value</B> to the given <B>object</B>.
121 The attribute has the visibility <B>scm_vis</B> and show <B>scm_show</B> flags.
122 The possible values are:
123 - <B>scm_vis</B>: scheme boolean. Visible (TRUE) or hidden (FALSE).
124 - <B>scm_show</B>: a list containing what to show: "name", "value", or both.
125 The return value is always TRUE.
127 SCM g_add_attrib(SCM object, SCM scm_attrib_name,
128 SCM scm_attrib_value, SCM scm_vis, SCM scm_show)
130 GSCHEM_TOPLEVEL *w_current=global_window_current;
131 TOPLEVEL *toplevel = w_current->toplevel;
132 OBJECT *o_current=NULL;
133 gboolean vis;
134 int show=0;
135 gchar *attrib_name=NULL;
136 gchar *attrib_value=NULL;
137 gchar *value=NULL;
138 int i;
139 gchar *newtext=NULL;
141 SCM_ASSERT (scm_is_string(scm_attrib_name), scm_attrib_name,
142 SCM_ARG2, "add-attribute-to-object");
143 SCM_ASSERT (scm_is_string(scm_attrib_value), scm_attrib_value,
144 SCM_ARG3, "add-attribute-to-object");
145 SCM_ASSERT (scm_boolean_p(scm_vis), scm_vis,
146 SCM_ARG4, "add-attribute-to-object");
147 SCM_ASSERT (scm_list_p(scm_show), scm_show,
148 SCM_ARG5, "add-attribute-to-object");
150 /* Get toplevel and o_current */
151 SCM_ASSERT (g_get_data_from_object_smob (object, &toplevel, &o_current),
152 object, SCM_ARG1, "add-attribute-to-object");
154 /* Get parameters */
155 attrib_name = SCM_STRING_CHARS(scm_attrib_name);
156 attrib_value = SCM_STRING_CHARS(scm_attrib_value);
157 vis = SCM_NFALSEP(scm_vis);
159 for (i=0; i<=scm_to_int(scm_length(scm_show))-1; i++) {
160 /* Check every element in the list. It should be a string! */
161 SCM_ASSERT(scm_list_ref(scm_show, scm_from_int(i)),
162 scm_show,
163 SCM_ARG5, "add-attribute-to-object");
164 SCM_ASSERT(scm_is_string(scm_list_ref(scm_show, scm_from_int(i))),
165 scm_show,
166 SCM_ARG5, "add-attribute-to-object");
168 value = SCM_STRING_CHARS(scm_list_ref(scm_show, scm_from_int(i)));
170 SCM_ASSERT(value, scm_show,
171 SCM_ARG5, "add-attribute-to-object");
173 /* Only "name" or "value" strings are allowed */
174 SCM_ASSERT(!((strcasecmp(value, "name") != 0) &&
175 (strcasecmp(value, "value") != 0) ), scm_show,
176 SCM_ARG5, "add-attribute-to-object");
178 /* show = 1 => show value;
179 show = 2 => show name;
180 show = 3 => show both */
181 if (strcasecmp(value, "value") == 0) {
182 show |= 1;
184 else if (strcasecmp(value, "name") == 0) {
185 show |= 2;
188 /* Show name and value (show = 3) => show=0 for gschem */
189 if (show == 3) {
190 show = 0;
193 newtext = g_strdup_printf("%s=%s", attrib_name, attrib_value);
194 o_attrib_add_attrib (w_current, newtext, vis, show, o_current);
195 g_free(newtext);
197 return SCM_BOOL_T;
201 /*! \todo Finish function documentation!!!
202 * \brief
203 * \par Function Description
207 * Returns a list with coords of the ends of the given pin <B>object</B>.
208 The list is ( (x0 y0) (x1 y1) ), where the beginning is at (x0,y0) and the end at (x1,y1).
209 The active connection end of the pin is the beginning, so this function cares about the whichend property of the pin object. If whichend is 1, then it has to reverse the ends.
211 SCM g_get_pin_ends(SCM object)
213 TOPLEVEL *toplevel;
214 OBJECT *o_current;
215 SCM coord1 = SCM_EOL;
216 SCM coord2 = SCM_EOL;
217 SCM coords = SCM_EOL;
219 /* Get toplevel and o_current */
220 SCM_ASSERT (g_get_data_from_object_smob (object, &toplevel, &o_current),
221 object, SCM_ARG1, "get-pin-ends");
223 /* Check that it is a pin object */
224 SCM_ASSERT (o_current != NULL,
225 object, SCM_ARG1, "get-pin-ends");
226 SCM_ASSERT (o_current->type == OBJ_PIN,
227 object, SCM_ARG1, "get-pin-ends");
228 SCM_ASSERT (o_current->line != NULL,
229 object, SCM_ARG1, "get-pin-ends");
231 coord1 = scm_cons(scm_from_int(o_current->line->x[0]),
232 scm_from_int(o_current->line->y[0]));
233 coord2 = scm_cons(scm_from_int(o_current->line->x[1]),
234 scm_from_int(o_current->line->y[1]));
235 if (o_current->whichend == 0) {
236 coords = scm_cons(coord1, scm_list(coord2));
237 } else {
238 coords = scm_cons(coord2, scm_list(coord1));
241 return coords;
244 /*! \todo Finish function documentation!!!
245 * \brief
246 * \par Function Description
250 * Sets several text properties of the given <B>attribute smob</B>:
251 - <B>coloridx</B>: The index of the text color, or -1 to keep previous color.
252 - <B>size</B>: Size (numeric) of the text, or -1 to keep the previous size.
253 - <B>alignment</B>: String with the alignment of the text. Possible values are:
254 * "" : Keep the previous alignment.
255 * "Lower Left"
256 * "Middle Left"
257 * "Upper Left"
258 * "Lower Middle"
259 * "Middle Middle"
260 * "Upper Middle"
261 * "Lower Right"
262 * "Middle Right"
263 * "Upper Right"
264 - <B>rotation</B>: Angle of the text, or -1 to keep previous angle.
265 - <B>x</B>, <B>y</B>: Coords of the text.
267 SCM g_set_attrib_text_properties(SCM attrib_smob, SCM scm_coloridx,
268 SCM scm_size, SCM scm_alignment,
269 SCM scm_rotation, SCM scm_x, SCM scm_y)
271 struct st_attrib_smob *attribute =
272 (struct st_attrib_smob *)SCM_CDR(attrib_smob);
273 OBJECT *object;
274 GSCHEM_TOPLEVEL *w_current = global_window_current;
275 TOPLEVEL *toplevel = w_current->toplevel;
277 int color = -1;
278 int size = -1;
279 char *alignment_string;
280 int alignment = -2;
281 int rotation = 0;
282 int x = -1, y = -1;
284 SCM_ASSERT (scm_is_integer(scm_coloridx), scm_coloridx,
285 SCM_ARG2, "set-attribute-text-properties!");
286 SCM_ASSERT ( scm_is_integer(scm_size),
287 scm_size, SCM_ARG3, "set-attribute-text-properties!");
288 SCM_ASSERT (scm_is_string(scm_alignment), scm_alignment,
289 SCM_ARG4, "set-attribute-text-properties!");
290 SCM_ASSERT ( scm_is_integer(scm_rotation),
291 scm_rotation, SCM_ARG5, "set-attribute-text-properties!");
292 SCM_ASSERT ( scm_is_integer(scm_x),
293 scm_x, SCM_ARG6, "set-attribute-text-properties!");
294 SCM_ASSERT ( scm_is_integer(scm_y),
295 scm_y, SCM_ARG7, "set-attribute-text-properties!");
297 color = scm_to_int(scm_coloridx);
299 SCM_ASSERT (!(color < -1 || color >= MAX_COLORS),
300 scm_coloridx, SCM_ARG2, "set-attribute-text-properties!");
302 size = scm_to_int(scm_size);
303 rotation = scm_to_int(scm_rotation);
304 x = scm_to_int(scm_x);
305 y = scm_to_int(scm_y);
307 alignment_string = SCM_STRING_CHARS(scm_alignment);
309 if (strlen(alignment_string) == 0) {
310 alignment = -1;
312 if (strcmp(alignment_string, "Lower Left") == 0) {
313 alignment = 0;
315 if (strcmp(alignment_string, "Middle Left") == 0) {
316 alignment = 1;
318 if (strcmp(alignment_string, "Upper Left") == 0) {
319 alignment = 2;
321 if (strcmp(alignment_string, "Lower Middle") == 0) {
322 alignment = 3;
324 if (strcmp(alignment_string, "Middle Middle") == 0) {
325 alignment = 4;
327 if (strcmp(alignment_string, "Upper Middle") == 0) {
328 alignment = 5;
330 if (strcmp(alignment_string, "Lower Right") == 0) {
331 alignment = 6;
333 if (strcmp(alignment_string, "Middle Right") == 0) {
334 alignment = 7;
336 if (strcmp(alignment_string, "Upper Right") == 0) {
337 alignment = 8;
339 if (alignment == -2) {
340 /* Bad specified */
341 SCM_ASSERT (scm_is_string(scm_alignment), scm_alignment,
342 SCM_ARG4, "set-attribute-text-properties!");
345 if (attribute &&
346 attribute->attribute) {
347 object = attribute->attribute;
348 if (object &&
349 object->text) {
350 o_invalidate (w_current, object);
351 if (x != -1) {
352 object->text->x = x;
354 if (y != -1) {
355 object->text->y = y;
357 if (size != -1) {
358 object->text->size = size;
360 if (alignment != -1) {
361 object->text->alignment = alignment;
363 if (rotation != -1) {
364 object->text->angle = rotation;
366 o_text_recreate(toplevel, object);
367 if (!toplevel->DONT_REDRAW) {
368 o_invalidate (w_current, object);
372 return SCM_BOOL_T;
375 /*! \brief Get the object bounds of the given object, excluding the object
376 * types given as parameters.
377 * \par Function Description
378 * Get the object bounds without considering the attributes in
379 * exclude_attrib_list, neither the object types included in
380 * exclude_obj_type_list
381 * \param [in] toplevel TOPLEVEL structure.
382 * \param [in] o_current The object we want to know the bounds of.
383 * \param [in] exclude_attrib_list A list with the attribute names we don't
384 * want to include when calculing the bounds.
385 * \param [in] exclude_obj_type_list A list with the object types we don't
386 * want to include when calculing the bounds.
387 * The object types are those used in (OBJECT *)->type converted into strings.
388 * \param [out] left Left bound of the object.
389 * \param [out] top Top bound of the object.
390 * \param [out] right Right bound of the object.
391 * \param [out] bottom Bottom bound of the object.
394 static void custom_world_get_single_object_bounds
395 (TOPLEVEL *toplevel, OBJECT *o_current,
396 int *left, int *top,
397 int *right, int *bottom,
398 GList *exclude_attrib_list,
399 GList *exclude_obj_type_list) {
400 OBJECT *obj_ptr = NULL;
401 OBJECT *a_current;
402 GList *a_iter;
403 int rleft, rright, rbottom, rtop;
404 char *name_ptr, aux_ptr[2];
405 gboolean include_text;
407 *left = rleft = toplevel->init_right;
408 *top = rtop = toplevel->init_bottom;;
409 *right = *bottom = rright = rbottom = 0;
411 obj_ptr = o_current;
412 sprintf(aux_ptr, "%c", obj_ptr->type);
413 include_text = TRUE;
414 if (!g_list_find_custom(exclude_obj_type_list, aux_ptr,
415 (GCompareFunc) &strcmp)) {
417 switch(obj_ptr->type) {
418 case (OBJ_PIN):
419 world_get_single_object_bounds (toplevel, obj_ptr,
420 &rleft, &rtop, &rright, &rbottom);
421 break;
422 case (OBJ_TEXT):
423 if (o_attrib_get_name_value (obj_ptr, &name_ptr, NULL) &&
424 g_list_find_custom (exclude_attrib_list, name_ptr, (GCompareFunc) &strcmp)) {
425 include_text = FALSE;
427 if (g_list_find_custom (exclude_attrib_list, "all",
428 (GCompareFunc) &strcmp)) {
429 include_text = FALSE;
431 if (include_text) {
432 world_get_single_object_bounds (toplevel, obj_ptr,
433 &rleft, &rtop, &rright, &rbottom);
435 g_free(name_ptr);
436 break;
437 case (OBJ_COMPLEX):
438 case (OBJ_PLACEHOLDER):
439 custom_world_get_object_glist_bounds (toplevel,
440 o_current->complex->prim_objs,
441 left, top, right, bottom,
442 exclude_attrib_list,
443 exclude_obj_type_list);
444 break;
446 default:
447 world_get_single_object_bounds (toplevel, obj_ptr,
448 &rleft, &rtop, &rright, &rbottom);
449 break;
452 if (rleft < *left) *left = rleft;
453 if (rtop < *top) *top = rtop;
454 if (rright > *right) *right = rright;
455 if (rbottom > *bottom) *bottom = rbottom;
457 /* If it's a pin object, check the pin attributes */
458 if (obj_ptr->type == OBJ_PIN) {
459 a_iter = obj_ptr->attribs;
460 while (a_iter != NULL) {
461 a_current = a_iter->data;
463 if (a_current->type == OBJ_TEXT) {
464 custom_world_get_single_object_bounds(toplevel,
465 a_current,
466 &rleft, &rtop,
467 &rright, &rbottom,
468 exclude_attrib_list,
469 exclude_obj_type_list);
470 if (rleft < *left) *left = rleft;
471 if (rtop < *top) *top = rtop;
472 if (rright > *right) *right = rright;
473 if (rbottom > *bottom) *bottom = rbottom;
476 a_iter = g_list_next (a_iter);
482 static void custom_world_get_object_glist_bounds
483 (TOPLEVEL *toplevel, GList *list,
484 int *left, int *top,
485 int *right, int *bottom,
486 GList *exclude_attrib_list,
487 GList *exclude_obj_type_list) {
489 OBJECT *o_current;
490 GList *iter;
491 int rleft, rtop, rright, rbottom;
493 *left = rleft = 999999;
494 *top = rtop = 9999999;
495 *right = rright = 0;
496 *bottom = rbottom = 0;
499 iter = list;
501 while (iter != NULL) {
502 o_current = (OBJECT *)iter->data;
503 custom_world_get_single_object_bounds (toplevel, o_current, &rleft, &rtop,
504 &rright, &rbottom,
505 exclude_attrib_list,
506 exclude_obj_type_list);
507 if (rleft < *left) *left = rleft;
508 if (rtop < *top) *top = rtop;
509 if (rright > *right) *right = rright;
510 if (rbottom > *bottom) *bottom = rbottom;
512 iter = g_list_next (iter);
516 /*! \brief Get the object bounds of the given object, excluding the object
517 * types or the attributes given as parameters.
518 * \par Function Description
519 * Get the object bounds without considering the attributes in
520 * scm_exclude_attribs, neither the object types included in
521 * scm_exclude_object_type
522 * \param [in] object_smob The object we want to know the bounds of.
523 * \param [in] scm_exclude_attribs A list with the attribute names we don't
524 * want to include when calculing the bounds.
525 * \param [in] scm_exclude_object_type A list with the object types we don't
526 * want to include when calculing the bounds.
527 * The object types are those used in (OBJECT *)->type converted into strings.
528 * \return a list of the bounds of the <B>object smob</B>.
529 * The list has the format: ( (left right) (top bottom) )
530 * WARNING: top and bottom are mis-named in world-coords,
531 * top is the smallest "y" value, and bottom is the largest.
532 * Be careful! This doesn't correspond to what you'd expect,
533 * nor to the coordinate system who's origin is the bottom, left of the page.
535 SCM g_get_object_bounds (SCM object_smob, SCM scm_exclude_attribs, SCM scm_exclude_object_type)
538 TOPLEVEL *toplevel=NULL;
539 OBJECT *object=NULL;
540 int left=0, right=0, bottom=0, top=0;
541 SCM returned = SCM_EOL;
542 SCM vertical = SCM_EOL;
543 SCM horizontal = SCM_EOL;
544 GList *exclude_attrib_list = NULL, *exclude_obj_type_list = NULL;
545 gboolean exclude_all_attribs = FALSE;
546 int i;
548 SCM_ASSERT (scm_list_p(scm_exclude_attribs), scm_exclude_attribs,
549 SCM_ARG2, "get-object-bounds");
550 SCM_ASSERT (scm_list_p(scm_exclude_object_type), scm_exclude_object_type,
551 SCM_ARG3, "get-object-bounds");
553 /* Build the exclude attrib list */
554 for (i=0; i <= scm_to_int(scm_length(scm_exclude_attribs))-1; i++) {
555 SCM_ASSERT (scm_is_string(scm_list_ref(scm_exclude_attribs, scm_from_int(i))),
556 scm_exclude_attribs,
557 SCM_ARG2, "get-object-bounds");
558 exclude_attrib_list = g_list_append(exclude_attrib_list,
559 SCM_STRING_CHARS(scm_list_ref(scm_exclude_attribs,
560 scm_from_int(i))));
563 /* Build the exclude object type list */
564 for (i=0; i <= scm_to_int(scm_length(scm_exclude_object_type))-1; i++) {
565 SCM_ASSERT (scm_is_string(scm_list_ref(scm_exclude_object_type, scm_from_int(i))),
566 scm_exclude_object_type,
567 SCM_ARG3, "get-object-bounds");
568 exclude_obj_type_list = g_list_append(exclude_obj_type_list,
569 SCM_STRING_CHARS(scm_list_ref(scm_exclude_object_type,
570 scm_from_int(i))));
573 /* Get toplevel and o_current. */
574 g_get_data_from_object_smob (object_smob, &toplevel, &object);
576 SCM_ASSERT (toplevel && object,
577 object_smob, SCM_ARG1, "get-object-bounds");
579 if (g_list_find_custom(exclude_attrib_list, "all", (GCompareFunc) &strcmp))
580 exclude_all_attribs = TRUE;
582 custom_world_get_single_object_bounds (toplevel, object,
583 &left, &top,
584 &right, &bottom,
585 exclude_attrib_list,
586 exclude_obj_type_list);
588 /* Free the exclude attrib_list. Don't free the nodes!! */
589 g_list_free(exclude_attrib_list);
591 /* Free the exclude attrib_list. Don't free the nodes!! */
592 g_list_free(exclude_obj_type_list);
594 horizontal = scm_cons (scm_from_int(left), scm_from_int(right));
595 vertical = scm_cons (scm_from_int(top), scm_from_int(bottom));
596 returned = scm_cons (horizontal, vertical);
597 return (returned);
600 /*! \todo Finish function documentation!!!
601 * \brief
602 * \par Function Description
606 *Returns a list of the pins of the <B>object smob</B>.
608 SCM g_get_object_pins (SCM object_smob)
610 TOPLEVEL *toplevel=NULL;
611 OBJECT *object=NULL;
612 OBJECT *prim_obj;
613 GList *iter;
614 SCM returned=SCM_EOL;
616 /* Get toplevel and o_current */
617 SCM_ASSERT (g_get_data_from_object_smob (object_smob, &toplevel, &object),
618 object_smob, SCM_ARG1, "get-object-pins");
620 if (!object) {
621 return (returned);
623 if (object->complex && object->complex->prim_objs) {
624 iter = object->complex->prim_objs;
625 while (iter != NULL) {
626 prim_obj = (OBJECT *)iter->data;
627 if (prim_obj->type == OBJ_PIN) {
628 returned = scm_cons (g_make_object_smob(toplevel, prim_obj),returned);
630 iter = g_list_next (iter);
634 return (returned);
637 /*! \brief Add a component to the page.
638 * \par Function Description
639 * Adds a component <B>scm_comp_name</B> to the schematic, at
640 * position (<B>scm_x</B>, <B>scm_y</B>), with some properties set by
641 * the parameters:
642 * \param [in,out] page_smob Schematic page
643 * \param [in] scm_comp_name Component to be added
644 * \param [in] scm_x Coordinate X of the symbol.
645 * \param [in] scm_y Coordinate Y of the symbol.
646 * \param [in] scm_angle Angle of rotation of the symbol.
647 * \param [in] scm_selectable True if the symbol is selectable, false otherwise.
648 * \param [in] scm_mirror True if the symbol is mirrored, false otherwise.
649 * If scm_comp_name is a scheme empty list, SCM_BOOL_F, or an empty
650 * string (""), then g_add_component returns SCM_BOOL_F without writing
651 * to the log.
652 * \return TRUE if the component was added, FALSE otherwise.
655 SCM g_add_component(SCM page_smob, SCM scm_comp_name, SCM scm_x, SCM scm_y,
656 SCM scm_angle, SCM scm_selectable, SCM scm_mirror)
658 TOPLEVEL *toplevel;
659 PAGE *page;
660 gboolean selectable, mirror;
661 gchar *comp_name;
662 int x, y, angle;
663 OBJECT *new_obj;
664 const CLibSymbol *clib;
666 /* Return if scm_comp_name is NULL (an empty list) or scheme's FALSE */
667 if (SCM_NULLP(scm_comp_name) ||
668 (SCM_BOOLP(scm_comp_name) && !(SCM_NFALSEP(scm_comp_name))) ) {
669 return SCM_BOOL_F;
672 /* Get toplevel and the page */
673 SCM_ASSERT (g_get_data_from_page_smob (page_smob, &toplevel, &page),
674 page_smob, SCM_ARG1, "add-component-at-xy");
675 /* Check the arguments */
676 SCM_ASSERT (scm_is_string(scm_comp_name), scm_comp_name,
677 SCM_ARG2, "add-component-at-xy");
678 SCM_ASSERT ( scm_is_integer(scm_x), scm_x,
679 SCM_ARG3, "add-component-at-xy");
680 SCM_ASSERT ( scm_is_integer(scm_y), scm_y,
681 SCM_ARG4, "add-component-at-xy");
682 SCM_ASSERT ( scm_is_integer(scm_angle), scm_angle,
683 SCM_ARG5, "add-component-at-xy");
684 SCM_ASSERT ( scm_boolean_p(scm_selectable), scm_selectable,
685 SCM_ARG6, "add-component-at-xy");
686 SCM_ASSERT ( scm_boolean_p(scm_mirror), scm_mirror,
687 SCM_ARG7, "add-component-at-xy");
689 /* Get the parameters */
690 comp_name = SCM_STRING_CHARS(scm_comp_name);
691 x = scm_to_int(scm_x);
692 y = scm_to_int(scm_y);
693 angle = scm_to_int(scm_angle);
694 selectable = SCM_NFALSEP(scm_selectable);
695 mirror = SCM_NFALSEP(scm_mirror);
697 SCM_ASSERT (comp_name, scm_comp_name,
698 SCM_ARG2, "add-component-at-xy");
700 if (strcmp(comp_name, "") == 0) {
701 return SCM_BOOL_F;
704 clib = s_clib_get_symbol_by_name (comp_name);
706 new_obj = o_complex_new (toplevel, 'C', DEFAULT_COLOR, x, y, angle, mirror,
707 clib, comp_name, selectable);
708 s_page_append_list (toplevel, page,
709 o_complex_promote_attribs (toplevel, new_obj));
710 s_page_append (toplevel, page, new_obj);
713 /* Run the add component hook for the new component */
714 if (scm_hook_empty_p(add_component_object_hook) == SCM_BOOL_F) {
715 scm_run_hook(add_component_object_hook,
716 scm_cons(g_make_object_smob(toplevel,
717 new_obj), SCM_EOL));
721 * For now, do not redraw the newly added complex, since this might cause
722 * flicker if you are zoom/panning right after this function executes
724 #if 0
725 /* Now the new component should be added to the object's list and
726 drawn in the screen */
727 o_invalidate (toplevel, new_object);
728 #endif
730 return SCM_BOOL_T;
733 /*! \brief Return the objects in a page.
734 * \par Function Description
735 * Returns an object smob list with all the objects in the given page.
736 * \param [in] page_smob Page to look at.
737 * \return the object smob list with the objects in the page.
740 SCM g_get_objects_in_page(SCM page_smob) {
742 TOPLEVEL *toplevel;
743 PAGE *page;
744 OBJECT *object;
745 const GList *iter;
746 SCM return_list=SCM_EOL;
748 /* Get toplevel and the page */
749 SCM_ASSERT (g_get_data_from_page_smob (page_smob, &toplevel, &page),
750 page_smob, SCM_ARG1, "add-component");
752 if (page && s_page_objects (page)) {
753 iter = s_page_objects (page);
754 while (iter != NULL) {
755 object = (OBJECT *)iter->data;
756 return_list = scm_cons (g_make_object_smob(toplevel, object),
757 return_list);
758 iter = g_list_next (iter);
762 return return_list;
765 SCM g_get_current_page(void)
767 return (g_make_page_smob(global_window_current->toplevel,
768 global_window_current->toplevel->page_current));