diff options
author | Peter D'Hoye <peter.dhoye@gmail.com> | 2009-05-24 21:28:16 +0000 |
---|---|---|
committer | Peter D'Hoye <peter.dhoye@gmail.com> | 2009-05-24 21:28:16 +0000 |
commit | 526b5580dabbfed7cfe5439dc3a90ec727f563c2 (patch) | |
tree | 22b1af92348785daad16714ee5e2b633017e0e48 /apps/plugins/pdbox/PDa/src/g_readwrite.c | |
parent | 4f2dfcc01b260d946044ef2b6af5fe36cb772c8d (diff) | |
download | rockbox-526b5580dabbfed7cfe5439dc3a90ec727f563c2.tar.gz rockbox-526b5580dabbfed7cfe5439dc3a90ec727f563c2.zip |
Cut the files in half and it might work better (note to self: check your tree is really clean before patching)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21070 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/pdbox/PDa/src/g_readwrite.c')
-rw-r--r-- | apps/plugins/pdbox/PDa/src/g_readwrite.c | 722 |
1 files changed, 0 insertions, 722 deletions
diff --git a/apps/plugins/pdbox/PDa/src/g_readwrite.c b/apps/plugins/pdbox/PDa/src/g_readwrite.c index a25b60c443..55759dbf1a 100644 --- a/apps/plugins/pdbox/PDa/src/g_readwrite.c +++ b/apps/plugins/pdbox/PDa/src/g_readwrite.c | |||
@@ -721,726 +721,4 @@ void g_readwrite_setup(void) | |||
721 | class_addmethod(canvas_class, (t_method)canvas_menusaveas, | 721 | class_addmethod(canvas_class, (t_method)canvas_menusaveas, |
722 | gensym("menusaveas"), 0); | 722 | gensym("menusaveas"), 0); |
723 | } | 723 | } |
724 | /* Copyright (c) 1997-2002 Miller Puckette and others. | ||
725 | * For information on usage and redistribution, and for a DISCLAIMER OF ALL | ||
726 | * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ | ||
727 | |||
728 | /* this file reads and writes the "data" portions of a canvas to a file. | ||
729 | See also canvas_saveto(), etc., in g_editor.c. The data portion is a | ||
730 | collection of "scalar" objects. Routines here can save collections of | ||
731 | scalars into a file and reload them; also, support is included here for | ||
732 | */ | ||
733 | |||
734 | #include <stdlib.h> | ||
735 | #include <stdio.h> | ||
736 | #include "m_pd.h" | ||
737 | #include "g_canvas.h" | ||
738 | #include <string.h> | ||
739 | |||
740 | /* the following routines read "scalars" from a file into a canvas. */ | ||
741 | |||
742 | static int canvas_scanbinbuf(int natoms, t_atom *vec, int *p_indexout, | ||
743 | int *p_next) | ||
744 | { | ||
745 | int i, j; | ||
746 | int indexwas = *p_next; | ||
747 | *p_indexout = indexwas; | ||
748 | if (indexwas >= natoms) | ||
749 | return (0); | ||
750 | for (i = indexwas; i < natoms && vec[i].a_type != A_SEMI; i++) | ||
751 | ; | ||
752 | if (i >= natoms) | ||
753 | *p_next = i; | ||
754 | else *p_next = i + 1; | ||
755 | return (i - indexwas); | ||
756 | } | ||
757 | |||
758 | int glist_readscalar(t_glist *x, int natoms, t_atom *vec, | ||
759 | int *p_nextmsg, int selectit); | ||
760 | |||
761 | static void canvas_readerror(int natoms, t_atom *vec, int message, | ||
762 | int nline, char *s) | ||
763 | { | ||
764 | error(s); | ||
765 | startpost("line was:"); | ||
766 | postatom(nline, vec + message); | ||
767 | endpost(); | ||
768 | } | ||
769 | |||
770 | /* fill in the contents of the scalar into the vector w. */ | ||
771 | |||
772 | static void glist_readatoms(t_glist *x, int natoms, t_atom *vec, | ||
773 | int *p_nextmsg, t_symbol *templatesym, t_word *w, int argc, t_atom *argv) | ||
774 | { | ||
775 | int message, nline, n, i; | ||
776 | |||
777 | t_template *template = template_findbyname(templatesym); | ||
778 | if (!template) | ||
779 | { | ||
780 | error("%s: no such template", templatesym->s_name); | ||
781 | *p_nextmsg = natoms; | ||
782 | return; | ||
783 | } | ||
784 | word_restore(w, template, argc, argv); | ||
785 | n = template->t_n; | ||
786 | for (i = 0; i < n; i++) | ||
787 | { | ||
788 | if (template->t_vec[i].ds_type == DT_ARRAY) | ||
789 | { | ||
790 | int j; | ||
791 | t_array *a = w[i].w_array; | ||
792 | int elemsize = a->a_elemsize, nitems = 0; | ||
793 | t_symbol *arraytemplatesym = template->t_vec[i].ds_arraytemplate; | ||
794 | t_template *arraytemplate = | ||
795 | template_findbyname(arraytemplatesym); | ||
796 | if (!arraytemplate) | ||
797 | { | ||
798 | error("%s: no such template", arraytemplatesym->s_name); | ||
799 | } | ||
800 | else while (1) | ||
801 | { | ||
802 | t_word *element; | ||
803 | int nline = canvas_scanbinbuf(natoms, vec, &message, p_nextmsg); | ||
804 | /* empty line terminates array */ | ||
805 | if (!nline) | ||
806 | break; | ||
807 | array_resize(a, arraytemplate, nitems + 1); | ||
808 | element = (t_word *)(((char *)a->a_vec) + | ||
809 | nitems * elemsize); | ||
810 | glist_readatoms(x, natoms, vec, p_nextmsg, arraytemplatesym, | ||
811 | element, nline, vec + message); | ||
812 | nitems++; | ||
813 | } | ||
814 | } | ||
815 | else if (template->t_vec[i].ds_type == DT_LIST) | ||
816 | { | ||
817 | while (1) | ||
818 | { | ||
819 | if (!glist_readscalar(w->w_list, natoms, vec, | ||
820 | p_nextmsg, 0)) | ||
821 | break; | ||
822 | } | ||
823 | } | ||
824 | } | ||
825 | } | ||
826 | |||
827 | int glist_readscalar(t_glist *x, int natoms, t_atom *vec, | ||
828 | int *p_nextmsg, int selectit) | ||
829 | { | ||
830 | int message, i, j, nline; | ||
831 | t_template *template; | ||
832 | t_symbol *templatesym; | ||
833 | t_scalar *sc; | ||
834 | int nextmsg = *p_nextmsg; | ||
835 | int wasvis = glist_isvisible(x); | ||
836 | |||
837 | if (nextmsg >= natoms || vec[nextmsg].a_type != A_SYMBOL) | ||
838 | { | ||
839 | if (nextmsg < natoms) | ||
840 | post("stopping early: type %d", vec[nextmsg].a_type); | ||
841 | *p_nextmsg = natoms; | ||
842 | return (0); | ||
843 | } | ||
844 | templatesym = canvas_makebindsym(vec[nextmsg].a_w.w_symbol); | ||
845 | *p_nextmsg = nextmsg + 1; | ||
846 | |||
847 | if (!(template = template_findbyname(templatesym))) | ||
848 | { | ||
849 | error("canvas_read: %s: no such template", templatesym->s_name); | ||
850 | *p_nextmsg = natoms; | ||
851 | return (0); | ||
852 | } | ||
853 | sc = scalar_new(x, templatesym); | ||
854 | if (!sc) | ||
855 | { | ||
856 | error("couldn't create scalar \"%s\"", templatesym->s_name); | ||
857 | *p_nextmsg = natoms; | ||
858 | return (0); | ||
859 | } | ||
860 | if (wasvis) | ||
861 | { | ||
862 | /* temporarily lie about vis flag while this is built */ | ||
863 | glist_getcanvas(x)->gl_mapped = 0; | ||
864 | } | ||
865 | glist_add(x, &sc->sc_gobj); | ||
866 | |||
867 | nline = canvas_scanbinbuf(natoms, vec, &message, p_nextmsg); | ||
868 | glist_readatoms(x, natoms, vec, p_nextmsg, templatesym, sc->sc_vec, | ||
869 | nline, vec + message); | ||
870 | if (wasvis) | ||
871 | { | ||
872 | /* reset vis flag as before */ | ||
873 | glist_getcanvas(x)->gl_mapped = 1; | ||
874 | gobj_vis(&sc->sc_gobj, x, 1); | ||
875 | } | ||
876 | if (selectit) | ||
877 | { | ||
878 | glist_select(x, &sc->sc_gobj); | ||
879 | } | ||
880 | return (1); | ||
881 | } | ||
882 | |||
883 | void glist_readfrombinbuf(t_glist *x, t_binbuf *b, char *filename, int selectem) | ||
884 | { | ||
885 | t_canvas *canvas = glist_getcanvas(x); | ||
886 | int cr = 0, natoms, nline, message, nextmsg = 0, i, j, nitems; | ||
887 | t_atom *vec; | ||
888 | t_gobj *gobj; | ||
889 | |||
890 | natoms = binbuf_getnatom(b); | ||
891 | vec = binbuf_getvec(b); | ||
892 | |||
893 | |||
894 | /* check for file type */ | ||
895 | nline = canvas_scanbinbuf(natoms, vec, &message, &nextmsg); | ||
896 | if (nline != 1 && vec[message].a_type != A_SYMBOL && | ||
897 | strcmp(vec[message].a_w.w_symbol->s_name, "data")) | ||
898 | { | ||
899 | pd_error(x, "%s: file apparently of wrong type", filename); | ||
900 | binbuf_free(b); | ||
901 | return; | ||
902 | } | ||
903 | /* read in templates and check for consistency */ | ||
904 | while (1) | ||
905 | { | ||
906 | t_template *newtemplate, *existtemplate; | ||
907 | t_symbol *templatesym; | ||
908 | t_atom *templateargs = getbytes(0); | ||
909 | int ntemplateargs = 0, newnargs; | ||
910 | nline = canvas_scanbinbuf(natoms, vec, &message, &nextmsg); | ||
911 | if (nline < 2) | ||
912 | break; | ||
913 | else if (nline > 2) | ||
914 | canvas_readerror(natoms, vec, message, nline, | ||
915 | "extra items ignored"); | ||
916 | else if (vec[message].a_type != A_SYMBOL || | ||
917 | strcmp(vec[message].a_w.w_symbol->s_name, "template") || | ||
918 | vec[message + 1].a_type != A_SYMBOL) | ||
919 | { | ||
920 | canvas_readerror(natoms, vec, message, nline, | ||
921 | "bad template header"); | ||
922 | continue; | ||
923 | } | ||
924 | templatesym = canvas_makebindsym(vec[message + 1].a_w.w_symbol); | ||
925 | while (1) | ||
926 | { | ||
927 | nline = canvas_scanbinbuf(natoms, vec, &message, &nextmsg); | ||
928 | if (nline != 2 && nline != 3) | ||
929 | break; | ||
930 | newnargs = ntemplateargs + nline; | ||
931 | templateargs = (t_atom *)t_resizebytes(templateargs, | ||
932 | sizeof(*templateargs) * ntemplateargs, | ||
933 | sizeof(*templateargs) * newnargs); | ||
934 | templateargs[ntemplateargs] = vec[message]; | ||
935 | templateargs[ntemplateargs + 1] = vec[message + 1]; | ||
936 | if (nline == 3) | ||
937 | templateargs[ntemplateargs + 2] = vec[message + 2]; | ||
938 | ntemplateargs = newnargs; | ||
939 | } | ||
940 | newtemplate = template_new(templatesym, ntemplateargs, templateargs); | ||
941 | t_freebytes(templateargs, sizeof (*templateargs) * ntemplateargs); | ||
942 | if (!(existtemplate = template_findbyname(templatesym))) | ||
943 | { | ||
944 | error("%s: template not found in current patch", | ||
945 | templatesym->s_name); | ||
946 | template_free(newtemplate); | ||
947 | return; | ||
948 | } | ||
949 | if (!template_match(existtemplate, newtemplate)) | ||
950 | { | ||
951 | error("%s: template doesn't match current one", | ||
952 | templatesym->s_name); | ||
953 | template_free(newtemplate); | ||
954 | return; | ||
955 | } | ||
956 | template_free(newtemplate); | ||
957 | } | ||
958 | while (nextmsg < natoms) | ||
959 | { | ||
960 | glist_readscalar(x, natoms, vec, &nextmsg, selectem); | ||
961 | } | ||
962 | } | ||
963 | |||
964 | static void glist_doread(t_glist *x, t_symbol *filename, t_symbol *format, | ||
965 | int clearme) | ||
966 | { | ||
967 | t_binbuf *b = binbuf_new(); | ||
968 | t_canvas *canvas = glist_getcanvas(x); | ||
969 | int wasvis = glist_isvisible(canvas); | ||
970 | int cr = 0, natoms, nline, message, nextmsg = 0, i, j; | ||
971 | t_atom *vec; | ||
972 | |||
973 | if (!strcmp(format->s_name, "cr")) | ||
974 | cr = 1; | ||
975 | else if (*format->s_name) | ||
976 | error("qlist_read: unknown flag: %s", format->s_name); | ||
977 | |||
978 | if (binbuf_read_via_path(b, filename->s_name, | ||
979 | canvas_getdir(canvas)->s_name, cr)) | ||
980 | { | ||
981 | pd_error(x, "read failed"); | ||
982 | binbuf_free(b); | ||
983 | return; | ||
984 | } | ||
985 | if (wasvis) | ||
986 | canvas_vis(canvas, 0); | ||
987 | if (clearme) | ||
988 | glist_clear(x); | ||
989 | glist_readfrombinbuf(x, b, filename->s_name, 0); | ||
990 | if (wasvis) | ||
991 | canvas_vis(canvas, 1); | ||
992 | binbuf_free(b); | ||
993 | } | ||
994 | |||
995 | void glist_read(t_glist *x, t_symbol *filename, t_symbol *format) | ||
996 | { | ||
997 | glist_doread(x, filename, format, 1); | ||
998 | } | ||
999 | |||
1000 | void glist_mergefile(t_glist *x, t_symbol *filename, t_symbol *format) | ||
1001 | { | ||
1002 | glist_doread(x, filename, format, 0); | ||
1003 | } | ||
1004 | |||
1005 | /* read text from a "properties" window, called from a gfxstub set | ||
1006 | up in scalar_properties(). We try to restore the object; if successful | ||
1007 | we delete the scalar and put the new thing in its place on the list. */ | ||
1008 | void canvas_dataproperties(t_canvas *x, t_scalar *sc, t_binbuf *b) | ||
1009 | { | ||
1010 | int ntotal, nnew, scindex; | ||
1011 | t_gobj *y, *y2 = 0, *newone, *oldone = 0; | ||
1012 | for (y = x->gl_list, ntotal = 0, scindex = -1; y; y = y->g_next) | ||
1013 | { | ||
1014 | if (y == &sc->sc_gobj) | ||
1015 | scindex = ntotal, oldone = y; | ||
1016 | ntotal++; | ||
1017 | } | ||
1018 | |||
1019 | if (scindex == -1) | ||
1020 | bug("data_properties: scalar disappeared"); | ||
1021 | glist_readfrombinbuf(x, b, "properties dialog", 0); | ||
1022 | newone = 0; | ||
1023 | if (scindex >= 0) | ||
1024 | { | ||
1025 | /* take the new object off the list */ | ||
1026 | if (ntotal) | ||
1027 | { | ||
1028 | for (y = x->gl_list, nnew = 1; y2 = y->g_next; | ||
1029 | y = y2, nnew++) | ||
1030 | if (nnew == ntotal) | ||
1031 | { | ||
1032 | newone = y2; | ||
1033 | y->g_next = y2->g_next; | ||
1034 | break; | ||
1035 | } | ||
1036 | } | ||
1037 | else newone = x->gl_list, x->gl_list = newone->g_next; | ||
1038 | } | ||
1039 | if (!newone) | ||
1040 | error("couldn't update properties (perhaps a format problem?)"); | ||
1041 | else if (!oldone) | ||
1042 | bug("data_properties: couldn't find old element"); | ||
1043 | else | ||
1044 | { | ||
1045 | glist_delete(x, oldone); | ||
1046 | if (scindex > 0) | ||
1047 | { | ||
1048 | for (y = x->gl_list, nnew = 1; y; | ||
1049 | y = y->g_next, nnew++) | ||
1050 | if (nnew == scindex || !y->g_next) | ||
1051 | { | ||
1052 | newone->g_next = y->g_next; | ||
1053 | y->g_next = newone; | ||
1054 | goto didit; | ||
1055 | } | ||
1056 | bug("data_properties: can't reinsert"); | ||
1057 | } | ||
1058 | else newone->g_next = x->gl_list, x->gl_list = newone; | ||
1059 | } | ||
1060 | didit: | ||
1061 | ; | ||
1062 | } | ||
1063 | |||
1064 | /* ----------- routines to write data to a binbuf ----------- */ | ||
1065 | |||
1066 | void canvas_doaddtemplate(t_symbol *templatesym, | ||
1067 | int *p_ntemplates, t_symbol ***p_templatevec) | ||
1068 | { | ||
1069 | int n = *p_ntemplates, i; | ||
1070 | t_symbol **templatevec = *p_templatevec; | ||
1071 | for (i = 0; i < n; i++) | ||
1072 | if (templatevec[i] == templatesym) | ||
1073 | return; | ||
1074 | templatevec = (t_symbol **)t_resizebytes(templatevec, | ||
1075 | n * sizeof(*templatevec), (n+1) * sizeof(*templatevec)); | ||
1076 | templatevec[n] = templatesym; | ||
1077 | *p_templatevec = templatevec; | ||
1078 | *p_ntemplates = n+1; | ||
1079 | } | ||
1080 | |||
1081 | static void glist_writelist(t_gobj *y, t_binbuf *b); | ||
1082 | |||
1083 | void canvas_writescalar(t_symbol *templatesym, t_word *w, t_binbuf *b, | ||
1084 | int amarrayelement) | ||
1085 | { | ||
1086 | t_dataslot *ds; | ||
1087 | t_template *template = template_findbyname(templatesym); | ||
1088 | t_atom *a = (t_atom *)t_getbytes(0); | ||
1089 | int i, n = template->t_n, natom = 0; | ||
1090 | if (!amarrayelement) | ||
1091 | { | ||
1092 | t_atom templatename; | ||
1093 | SETSYMBOL(&templatename, gensym(templatesym->s_name + 3)); | ||
1094 | binbuf_add(b, 1, &templatename); | ||
1095 | } | ||
1096 | if (!template) | ||
1097 | bug("canvas_writescalar"); | ||
1098 | /* write the atoms (floats and symbols) */ | ||
1099 | for (i = 0; i < n; i++) | ||
1100 | { | ||
1101 | if (template->t_vec[i].ds_type == DT_FLOAT || | ||
1102 | template->t_vec[i].ds_type == DT_SYMBOL) | ||
1103 | { | ||
1104 | a = (t_atom *)t_resizebytes(a, | ||
1105 | natom * sizeof(*a), (natom + 1) * sizeof (*a)); | ||
1106 | if (template->t_vec[i].ds_type == DT_FLOAT) | ||
1107 | SETFLOAT(a + natom, w[i].w_float); | ||
1108 | else SETSYMBOL(a + natom, w[i].w_symbol); | ||
1109 | natom++; | ||
1110 | } | ||
1111 | } | ||
1112 | /* array elements have to have at least something */ | ||
1113 | if (natom == 0 && amarrayelement) | ||
1114 | SETSYMBOL(a + natom, &s_bang), natom++; | ||
1115 | binbuf_add(b, natom, a); | ||
1116 | binbuf_addsemi(b); | ||
1117 | t_freebytes(a, natom * sizeof(*a)); | ||
1118 | for (i = 0; i < n; i++) | ||
1119 | { | ||
1120 | if (template->t_vec[i].ds_type == DT_ARRAY) | ||
1121 | { | ||
1122 | int j; | ||
1123 | t_array *a = w[i].w_array; | ||
1124 | int elemsize = a->a_elemsize, nitems = a->a_n; | ||
1125 | t_symbol *arraytemplatesym = template->t_vec[i].ds_arraytemplate; | ||
1126 | for (j = 0; j < nitems; j++) | ||
1127 | canvas_writescalar(arraytemplatesym, | ||
1128 | (t_word *)(((char *)a->a_vec) + elemsize * j), b, 1); | ||
1129 | binbuf_addsemi(b); | ||
1130 | } | ||
1131 | else if (template->t_vec[i].ds_type == DT_LIST) | ||
1132 | { | ||
1133 | glist_writelist(w->w_list->gl_list, b); | ||
1134 | binbuf_addsemi(b); | ||
1135 | } | ||
1136 | } | ||
1137 | } | ||
1138 | 724 | ||
1139 | static void glist_writelist(t_gobj *y, t_binbuf *b) | ||
1140 | { | ||
1141 | for (; y; y = y->g_next) | ||
1142 | { | ||
1143 | if (pd_class(&y->g_pd) == scalar_class) | ||
1144 | { | ||
1145 | canvas_writescalar(((t_scalar *)y)->sc_template, | ||
1146 | ((t_scalar *)y)->sc_vec, b, 0); | ||
1147 | } | ||
1148 | } | ||
1149 | } | ||
1150 | |||
1151 | /* ------------ routines to write out templates for data ------- */ | ||
1152 | |||
1153 | static void canvas_addtemplatesforlist(t_gobj *y, | ||
1154 | int *p_ntemplates, t_symbol ***p_templatevec); | ||
1155 | |||
1156 | static void canvas_addtemplatesforscalar(t_symbol *templatesym, | ||
1157 | t_word *w, int *p_ntemplates, t_symbol ***p_templatevec) | ||
1158 | { | ||
1159 | t_dataslot *ds; | ||
1160 | int i; | ||
1161 | t_template *template = template_findbyname(templatesym); | ||
1162 | canvas_doaddtemplate(templatesym, p_ntemplates, p_templatevec); | ||
1163 | if (!template) | ||
1164 | bug("canvas_addtemplatesforscalar"); | ||
1165 | else for (ds = template->t_vec, i = template->t_n; i--; ds++, w++) | ||
1166 | { | ||
1167 | if (ds->ds_type == DT_ARRAY) | ||
1168 | { | ||
1169 | int j; | ||
1170 | t_array *a = w->w_array; | ||
1171 | int elemsize = a->a_elemsize, nitems = a->a_n; | ||
1172 | t_symbol *arraytemplatesym = ds->ds_arraytemplate; | ||
1173 | canvas_doaddtemplate(arraytemplatesym, p_ntemplates, p_templatevec); | ||
1174 | for (j = 0; j < nitems; j++) | ||
1175 | canvas_addtemplatesforscalar(arraytemplatesym, | ||
1176 | (t_word *)(((char *)a->a_vec) + elemsize * j), | ||
1177 | p_ntemplates, p_templatevec); | ||
1178 | } | ||
1179 | else if (ds->ds_type == DT_LIST) | ||
1180 | canvas_addtemplatesforlist(w->w_list->gl_list, | ||
1181 | p_ntemplates, p_templatevec); | ||
1182 | } | ||
1183 | } | ||
1184 | |||
1185 | static void canvas_addtemplatesforlist(t_gobj *y, | ||
1186 | int *p_ntemplates, t_symbol ***p_templatevec) | ||
1187 | { | ||
1188 | for (; y; y = y->g_next) | ||
1189 | { | ||
1190 | if (pd_class(&y->g_pd) == scalar_class) | ||
1191 | { | ||
1192 | canvas_addtemplatesforscalar(((t_scalar *)y)->sc_template, | ||
1193 | ((t_scalar *)y)->sc_vec, p_ntemplates, p_templatevec); | ||
1194 | } | ||
1195 | } | ||
1196 | } | ||
1197 | |||
1198 | /* write all "scalars" in a glist to a binbuf. */ | ||
1199 | t_binbuf *glist_writetobinbuf(t_glist *x, int wholething) | ||
1200 | { | ||
1201 | int i; | ||
1202 | t_symbol **templatevec = getbytes(0); | ||
1203 | int ntemplates = 0; | ||
1204 | t_gobj *y; | ||
1205 | t_binbuf *b = binbuf_new(); | ||
1206 | |||
1207 | for (y = x->gl_list; y; y = y->g_next) | ||
1208 | { | ||
1209 | if ((pd_class(&y->g_pd) == scalar_class) && | ||
1210 | (wholething || glist_isselected(x, y))) | ||
1211 | { | ||
1212 | canvas_addtemplatesforscalar(((t_scalar *)y)->sc_template, | ||
1213 | ((t_scalar *)y)->sc_vec, &ntemplates, &templatevec); | ||
1214 | } | ||
1215 | } | ||
1216 | binbuf_addv(b, "s;", gensym("data")); | ||
1217 | for (i = 0; i < ntemplates; i++) | ||
1218 | { | ||
1219 | t_template *template = template_findbyname(templatevec[i]); | ||
1220 | int j, m = template->t_n; | ||
1221 | /* drop "pd-" prefix from template symbol to print it: */ | ||
1222 | binbuf_addv(b, "ss;", gensym("template"), | ||
1223 | gensym(templatevec[i]->s_name + 3)); | ||
1224 | for (j = 0; j < m; j++) | ||
1225 | { | ||
1226 | t_symbol *type; | ||
1227 | switch (template->t_vec[j].ds_type) | ||
1228 | { | ||
1229 | case DT_FLOAT: type = &s_float; break; | ||
1230 | case DT_SYMBOL: type = &s_symbol; break; | ||
1231 | case DT_ARRAY: type = gensym("array"); break; | ||
1232 | case DT_LIST: type = &s_list; break; | ||
1233 | default: type = &s_float; bug("canvas_write"); | ||
1234 | } | ||
1235 | if (template->t_vec[j].ds_type == DT_ARRAY) | ||
1236 | binbuf_addv(b, "sss;", type, template->t_vec[j].ds_name, | ||
1237 | gensym(template->t_vec[j].ds_arraytemplate->s_name + 3)); | ||
1238 | else binbuf_addv(b, "ss;", type, template->t_vec[j].ds_name); | ||
1239 | } | ||
1240 | binbuf_addsemi(b); | ||
1241 | } | ||
1242 | binbuf_addsemi(b); | ||
1243 | /* now write out the objects themselves */ | ||
1244 | for (y = x->gl_list; y; y = y->g_next) | ||
1245 | { | ||
1246 | if ((pd_class(&y->g_pd) == scalar_class) && | ||
1247 | (wholething || glist_isselected(x, y))) | ||
1248 | { | ||
1249 | canvas_writescalar(((t_scalar *)y)->sc_template, | ||
1250 | ((t_scalar *)y)->sc_vec, b, 0); | ||
1251 | } | ||
1252 | } | ||
1253 | return (b); | ||
1254 | } | ||
1255 | |||
1256 | static void glist_write(t_glist *x, t_symbol *filename, t_symbol *format) | ||
1257 | { | ||
1258 | int cr = 0, i; | ||
1259 | t_binbuf *b; | ||
1260 | char buf[MAXPDSTRING]; | ||
1261 | t_symbol **templatevec = getbytes(0); | ||
1262 | int ntemplates = 0; | ||
1263 | t_gobj *y; | ||
1264 | t_canvas *canvas = glist_getcanvas(x); | ||
1265 | canvas_makefilename(canvas, filename->s_name, buf, MAXPDSTRING); | ||
1266 | if (!strcmp(format->s_name, "cr")) | ||
1267 | cr = 1; | ||
1268 | else if (*format->s_name) | ||
1269 | error("qlist_read: unknown flag: %s", format->s_name); | ||
1270 | |||
1271 | b = glist_writetobinbuf(x, 1); | ||
1272 | if (b) | ||
1273 | { | ||
1274 | if (binbuf_write(b, buf, "", cr)) | ||
1275 | error("%s: write failed", filename->s_name); | ||
1276 | binbuf_free(b); | ||
1277 | } | ||
1278 | } | ||
1279 | |||
1280 | /* ------ routines to save and restore canvases (patches) recursively. ----*/ | ||
1281 | |||
1282 | /* save to a binbuf, called recursively; cf. canvas_savetofile() which | ||
1283 | saves the document, and is only called on root canvases. */ | ||
1284 | static void canvas_saveto(t_canvas *x, t_binbuf *b) | ||
1285 | { | ||
1286 | t_gobj *y; | ||
1287 | t_linetraverser t; | ||
1288 | t_outconnect *oc; | ||
1289 | /* subpatch */ | ||
1290 | if (x->gl_owner && !x->gl_env) | ||
1291 | { | ||
1292 | binbuf_addv(b, "ssiiiisi;", gensym("#N"), gensym("canvas"), | ||
1293 | (t_int)(x->gl_screenx1), | ||
1294 | (t_int)(x->gl_screeny1), | ||
1295 | (t_int)(x->gl_screenx2 - x->gl_screenx1), | ||
1296 | (t_int)(x->gl_screeny2 - x->gl_screeny1), | ||
1297 | (*x->gl_name->s_name ? x->gl_name: gensym("(subpatch)")), | ||
1298 | x->gl_mapped); | ||
1299 | } | ||
1300 | /* root or abstraction */ | ||
1301 | else binbuf_addv(b, "ssiiiii;", gensym("#N"), gensym("canvas"), | ||
1302 | (t_int)(x->gl_screenx1), | ||
1303 | (t_int)(x->gl_screeny1), | ||
1304 | (t_int)(x->gl_screenx2 - x->gl_screenx1), | ||
1305 | (t_int)(x->gl_screeny2 - x->gl_screeny1), | ||
1306 | x->gl_font); | ||
1307 | |||
1308 | for (y = x->gl_list; y; y = y->g_next) | ||
1309 | gobj_save(y, b); | ||
1310 | |||
1311 | linetraverser_start(&t, x); | ||
1312 | while (oc = linetraverser_next(&t)) | ||
1313 | { | ||
1314 | int srcno = canvas_getindex(x, &t.tr_ob->ob_g); | ||
1315 | int sinkno = canvas_getindex(x, &t.tr_ob2->ob_g); | ||
1316 | binbuf_addv(b, "ssiiii;", gensym("#X"), gensym("connect"), | ||
1317 | srcno, t.tr_outno, sinkno, t.tr_inno); | ||
1318 | } | ||
1319 | /* unless everything is the default (as in ordinary subpatches) | ||
1320 | print out a "coords" message to set up the coordinate systems */ | ||
1321 | if (x->gl_isgraph || x->gl_x1 || x->gl_y1 || | ||
1322 | x->gl_x2 != 1 || x->gl_y2 != 1 || x->gl_pixwidth || x->gl_pixheight) | ||
1323 | binbuf_addv(b, "ssfffffff;", gensym("#X"), gensym("coords"), | ||
1324 | x->gl_x1, x->gl_y1, | ||
1325 | x->gl_x2, x->gl_y2, | ||
1326 | (float)x->gl_pixwidth, (float)x->gl_pixheight, | ||
1327 | (float)x->gl_isgraph); | ||
1328 | } | ||
1329 | |||
1330 | /* call this recursively to collect all the template names for | ||
1331 | a canvas or for the selection. */ | ||
1332 | static void canvas_collecttemplatesfor(t_canvas *x, int *ntemplatesp, | ||
1333 | t_symbol ***templatevecp, int wholething) | ||
1334 | { | ||
1335 | t_gobj *y; | ||
1336 | |||
1337 | for (y = x->gl_list; y; y = y->g_next) | ||
1338 | { | ||
1339 | if ((pd_class(&y->g_pd) == scalar_class) && | ||
1340 | (wholething || glist_isselected(x, y))) | ||
1341 | canvas_addtemplatesforscalar(((t_scalar *)y)->sc_template, | ||
1342 | ((t_scalar *)y)->sc_vec, ntemplatesp, templatevecp); | ||
1343 | else if ((pd_class(&y->g_pd) == canvas_class) && | ||
1344 | (wholething || glist_isselected(x, y))) | ||
1345 | canvas_collecttemplatesfor((t_canvas *)y, | ||
1346 | ntemplatesp, templatevecp, 1); | ||
1347 | } | ||
1348 | } | ||
1349 | |||
1350 | /* save the templates needed by a canvas to a binbuf. */ | ||
1351 | static void canvas_savetemplatesto(t_canvas *x, t_binbuf *b, int wholething) | ||
1352 | { | ||
1353 | t_symbol **templatevec = getbytes(0); | ||
1354 | int i, ntemplates = 0; | ||
1355 | t_gobj *y; | ||
1356 | canvas_collecttemplatesfor(x, &ntemplates, &templatevec, wholething); | ||
1357 | for (i = 0; i < ntemplates; i++) | ||
1358 | { | ||
1359 | t_template *template = template_findbyname(templatevec[i]); | ||
1360 | int j, m = template->t_n; | ||
1361 | if (!template) | ||
1362 | { | ||
1363 | bug("canvas_savetemplatesto"); | ||
1364 | continue; | ||
1365 | } | ||
1366 | /* drop "pd-" prefix from template symbol to print */ | ||
1367 | binbuf_addv(b, "sss", &s__N, gensym("struct"), | ||
1368 | gensym(templatevec[i]->s_name + 3)); | ||
1369 | for (j = 0; j < m; j++) | ||
1370 | { | ||
1371 | t_symbol *type; | ||
1372 | switch (template->t_vec[j].ds_type) | ||
1373 | { | ||
1374 | case DT_FLOAT: type = &s_float; break; | ||
1375 | case DT_SYMBOL: type = &s_symbol; break; | ||
1376 | case DT_ARRAY: type = gensym("array"); break; | ||
1377 | case DT_LIST: type = &s_list; break; | ||
1378 | default: type = &s_float; bug("canvas_write"); | ||
1379 | } | ||
1380 | if (template->t_vec[j].ds_type == DT_ARRAY) | ||
1381 | binbuf_addv(b, "sss", type, template->t_vec[j].ds_name, | ||
1382 | gensym(template->t_vec[j].ds_arraytemplate->s_name + 3)); | ||
1383 | else binbuf_addv(b, "ss", type, template->t_vec[j].ds_name); | ||
1384 | } | ||
1385 | binbuf_addsemi(b); | ||
1386 | } | ||
1387 | } | ||
1388 | |||
1389 | void canvas_reload(t_symbol *name, t_symbol *dir, t_gobj *except); | ||
1390 | |||
1391 | /* save a "root" canvas to a file; cf. canvas_saveto() which saves the | ||
1392 | body (and which is called recursively.) */ | ||
1393 | static void canvas_savetofile(t_canvas *x, t_symbol *filename, t_symbol *dir) | ||
1394 | { | ||
1395 | t_binbuf *b = binbuf_new(); | ||
1396 | canvas_savetemplatesto(x, b, 1); | ||
1397 | canvas_saveto(x, b); | ||
1398 | if (binbuf_write(b, filename->s_name, dir->s_name, 0)) sys_ouch(); | ||
1399 | else | ||
1400 | { | ||
1401 | /* if not an abstraction, reset title bar and directory */ | ||
1402 | if (!x->gl_owner) | ||
1403 | canvas_rename(x, filename, dir); | ||
1404 | post("saved to: %s/%s", dir->s_name, filename->s_name); | ||
1405 | canvas_dirty(x, 0); | ||
1406 | canvas_reload(filename, dir, &x->gl_gobj); | ||
1407 | } | ||
1408 | binbuf_free(b); | ||
1409 | } | ||
1410 | |||
1411 | static void canvas_menusaveas(t_canvas *x) | ||
1412 | { | ||
1413 | t_canvas *x2 = canvas_getrootfor(x); | ||
1414 | sys_vgui("pdtk_canvas_saveas .x%x \"%s\" \"%s\"\n", x2, | ||
1415 | x2->gl_name->s_name, canvas_getdir(x2)->s_name); | ||
1416 | } | ||
1417 | |||
1418 | static void canvas_menusave(t_canvas *x) | ||
1419 | { | ||
1420 | t_canvas *x2 = canvas_getrootfor(x); | ||
1421 | char *name = x2->gl_name->s_name; | ||
1422 | if (*name && strncmp(name, "Untitled", 8) | ||
1423 | && (strlen(name) < 4 || strcmp(name + strlen(name)-4, ".pat"))) | ||
1424 | canvas_savetofile(x2, x2->gl_name, canvas_getdir(x2)); | ||
1425 | else canvas_menusaveas(x2); | ||
1426 | } | ||
1427 | |||
1428 | |||
1429 | void g_readwrite_setup(void) | ||
1430 | { | ||
1431 | class_addmethod(canvas_class, (t_method)glist_write, | ||
1432 | gensym("write"), A_SYMBOL, A_DEFSYM, A_NULL); | ||
1433 | class_addmethod(canvas_class, (t_method)glist_read, | ||
1434 | gensym("read"), A_SYMBOL, A_DEFSYM, A_NULL); | ||
1435 | class_addmethod(canvas_class, (t_method)glist_mergefile, | ||
1436 | gensym("mergefile"), A_SYMBOL, A_DEFSYM, A_NULL); | ||
1437 | class_addmethod(canvas_class, (t_method)canvas_savetofile, | ||
1438 | gensym("savetofile"), A_SYMBOL, A_SYMBOL, 0); | ||
1439 | class_addmethod(canvas_class, (t_method)canvas_saveto, | ||
1440 | gensym("saveto"), A_CANT, 0); | ||
1441 | /* ------------------ from the menu ------------------------- */ | ||
1442 | class_addmethod(canvas_class, (t_method)canvas_menusave, | ||
1443 | gensym("menusave"), 0); | ||
1444 | class_addmethod(canvas_class, (t_method)canvas_menusaveas, | ||
1445 | gensym("menusaveas"), 0); | ||
1446 | } | ||