~ubuntu-branches/ubuntu/hardy/xcircuit/hardy

« back to all changes in this revision

Viewing changes to libraries.c

  • Committer: Bazaar Package Importer
  • Author(s): Aanjhan Ranganathan
  • Date: 2006-04-18 23:51:39 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060418235139-s49pkhwdzxvsxm5k
Tags: 3.4.21-0ubuntu1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
8
8
/*-------------------------------------------------------------------------*/
9
9
 
10
10
#include <stdio.h>
 
11
#include <string.h>
11
12
#include <stdlib.h>
12
 
#include <string.h>
13
13
 
 
14
#ifndef XC_WIN32
14
15
#include <X11/Intrinsic.h>
15
16
#include <X11/StringDefs.h>
 
17
#endif
16
18
#ifdef TCL_WRAPPER 
17
19
#include <tk.h>
18
20
#else
 
21
#ifndef XC_WIN32
19
22
#include "Xw/Xw.h"
20
23
#endif
 
24
#endif
21
25
 
22
26
#include <math.h>
23
27
 
47
51
extern short fontcount;
48
52
extern fontinfo *fonts;
49
53
 
 
54
/*------------------------------------------------------*/
 
55
/* Check if a library exists                            */
 
56
/*-------------------------------------------------------*/
 
57
 
50
58
/*---------------------------------------------------------*/
51
59
/* Find the Helvetica font for use in labeling the objects */
52
60
/*---------------------------------------------------------*/
87
95
{
88
96
   /* Pop the object being edited from the push stack. */
89
97
 
90
 
   popobject(NULL, NULL, NULL);
 
98
   popobject(NULL, (pointertype)1, NULL);
91
99
}
92
100
 
93
101
/*------------------------------------------------------*/
98
106
/*   page number of page to the right.                  */
99
107
/*------------------------------------------------------*/
100
108
 
101
 
int pageposition(short libmode, XButtonEvent *event, int mode)
 
109
int pageposition(short libmode, int x, int y, int mode)
102
110
{
103
111
   int xin, yin, bpage, pages;
104
112
   int gxsize, gysize, xdel, ydel;
105
113
 
106
114
   pages = (libmode == PAGELIB) ? xobjs.pages : xobjs.numlibs;
107
115
   computespacing(libmode, &gxsize, &gysize, &xdel, &ydel);
108
 
   window_to_user(event->x, event->y, &areastruct.save);
 
116
   window_to_user(x, y, &areastruct.save);
109
117
 
110
118
   if (mode == 0) {     /* On-page */
111
119
      if (areastruct.save.x >= 0 && areastruct.save.y <= 0) {
274
282
}
275
283
 
276
284
/*------------------------------------------------------*/
 
285
/* Check if a library (given by name) exists.  If it    */
 
286
/* does, return the library number.  If not, return -1  */
 
287
/*------------------------------------------------------*/
 
288
 
 
289
int check_library(char *libname)
 
290
{
 
291
   int i;
 
292
   
 
293
   for (i = 0; i < xobjs.numlibs; i++)
 
294
      if (!strcmp(xobjs.libtop[i + LIBRARY]->thisobject->name, libname))
 
295
         return i;
 
296
 
 
297
   return -1;
 
298
}
 
299
 
 
300
/*------------------------------------------------------*/
277
301
/* ButtonPress handler during page catalog viewing mode */
278
302
/*------------------------------------------------------*/
279
303
 
280
 
void pagecatbutton(XButtonEvent *event)
 
304
void pagecat_op(int op, int x, int y)
281
305
{
282
306
   int bpage;
283
307
   short mode;
287
311
   }
288
312
   if (mode == LIBRARY) return;  /* Something went wrong if this happens */
289
313
 
290
 
   if (event->button == Button1 || event->button == Button2) {
291
 
      if ((bpage = pageposition(mode, event, 0)) >= 0) {
 
314
   if (op != XCF_Cancel) {
 
315
      if ((bpage = pageposition(mode, x, y, 0)) >= 0) {
292
316
                  
293
 
#ifdef SCHEMA
294
317
         if (eventmode == ASSOC_MODE) {
295
318
            if (mode == PAGELIB) {
296
319
               /* using changepage() allows use of new page for schematic */
299
322
               schemassoc(topobject, areastruct.stack->thisinst->thisobject);
300
323
               /* pop back to calling (symbol) page */
301
324
               catreturn();
302
 
               eventmode = PRESS_MODE;
 
325
               eventmode = NORMAL_MODE;
303
326
            }
304
327
            else {
 
328
               areastruct.lastlibrary = bpage;
305
329
               startcatalog(NULL, (pointertype)(LIBRARY + bpage), NULL);
306
330
            }
307
331
            return;
308
332
         }
309
 
         else
310
 
#endif
311
 
         if (event->button == Button1) {
 
333
         else if (op == XCF_Select) {
 
334
            if (mode == PAGELIB)    /* No such method for LIBLIB is defined. */
 
335
               select_add_element(OBJINST);
 
336
         }
 
337
         else if ((op == XCF_Library_Pop) || (op == XCF_Finish)) {
312
338
 
313
339
            /* like catreturn(), but don't actually go to the popped page */
314
 
            objectdeselect();
 
340
            unselect_all();
315
341
            eventmode = NORMAL_MODE;
316
342
            if (mode == PAGELIB) {
317
343
               newpage(bpage);
318
 
               eventmode = PRESS_MODE;
319
344
            }
320
345
            else {
321
346
               startcatalog(NULL, (pointertype)(LIBRARY + bpage), NULL);
322
347
            }
323
348
            return;
324
349
         }
325
 
         else {  /* Button2 */
326
 
            if (mode == PAGELIB)    /* No such method for LIBLIB is defined. */
327
 
               objectselect(OBJECT);
328
 
         }
329
350
      }
330
351
   }
331
352
   else {
382
403
objinstptr newpageinst(objectptr pageobj)
383
404
{
384
405
   objinstptr newinst = (objinstptr) malloc(sizeof(objinst));
385
 
   objectdefaults(newinst, pageobj, 0, 0);
386
 
   newinst->type = OBJECT;
 
406
   instancedefaults(newinst, pageobj, 0, 0);
 
407
   newinst->type = OBJINST;
387
408
   newinst->color = DEFAULTCOLOR;
388
409
   return newinst;
389
410
}
428
449
   /* from the list.                                                     */
429
450
 
430
451
   for (pgen = directory->plist; pgen < directory->plist + directory->parts; pgen++)
431
 
      if ((*pgen)->type == OBJECT) *pgen = NULL;
 
452
      if (IS_OBJINST(*pgen)) *pgen = NULL;
432
453
 
433
454
   reset(directory, NORMAL);
434
455
 
468
489
      (*drawbox)->width = 1.0;
469
490
      (*drawbox)->number = 4;
470
491
      (*drawbox)->points = (pointlist) malloc(4 * sizeof(XPoint));
471
 
      (*drawbox)->num_params = 0;
472
492
      (*drawbox)->passed = NULL;
473
493
      pointptr = (*drawbox)->points;
474
494
      pointptr->x = (i % gxsize) * xdel + margin;
493
513
         (*pagelabel)->color = DEFAULTCOLOR;
494
514
         (*pagelabel)->scale = 0.75;
495
515
         (*pagelabel)->string->data.font = fval;
496
 
         (*pagelabel)->num_params = 0;
497
516
         (*pagelabel)->passed = NULL;
498
517
         strptr = makesegment(&((*pagelabel)->string), NULL);
499
518
         strptr->type = TEXT_STRING;
532
551
 
533
552
   for (i = 0; i < libinst->parts; i++) {
534
553
      gelem = libinst->plist + i;
535
 
      if ((*gelem)->type == OBJECT) {
 
554
      if (IS_OBJINST(*gelem)) {
536
555
         pinst = TOOBJINST(gelem);
537
556
         if (pinst->thisobject == compobj) {
538
557
            /* recalculate scale and position of the object instance */
551
570
/* Rearrange pages      */
552
571
/*----------------------*/
553
572
 
554
 
void pagecatmove(XKeyEvent *event)
 
573
void pagecatmove(int x, int y)
555
574
{
556
575
   int bpage;
557
576
   objinstptr exchobj;
585
604
 
586
605
   /* If one object selected; find place to put from cursor position */
587
606
 
588
 
   else if ((bpage = pageposition(PAGELIB, (XButtonEvent *)event, 1)) >= 0) {
 
607
   else if ((bpage = pageposition(PAGELIB, x, y, 1)) >= 0) {
589
608
      int k, epage;
590
609
      Pagedata *eptr;
591
610
 
615
634
      }
616
635
   }
617
636
 
618
 
   objectdeselect();
 
637
   unselect_all();
619
638
   composelib(PAGELIB);
620
639
   drawarea(NULL, NULL, NULL);
621
640
}
636
655
   short fval;
637
656
   short llx, lly, width, height;
638
657
 
 
658
   int totalarea, targetwidth;
 
659
   double scale;
 
660
 
639
661
   /* Also make composelib() a wrapper for composepagelib() */
640
662
   if ((mode > FONTLIB) && (mode < LIBRARY)) {
641
663
      composepagelib(mode);
647
669
   /* call reset(), we find the pointer to the instance and NULL it.    */
648
670
   
649
671
   for (pgen = libpage->plist; pgen < libpage->plist + libpage->parts; pgen++)
650
 
      if ((*pgen)->type == OBJECT) *pgen = NULL;
 
672
      if (IS_OBJINST(*pgen)) *pgen = NULL;
651
673
 
652
674
   reset(libpage, NORMAL);
653
675
 
654
 
   /* Return if library defines no objects */
 
676
   /* Return if library defines no objects or virtual instances */
655
677
 
656
 
   if (xobjs.userlibs[mode - LIBRARY].number == 0) return;
 
678
   if (xobjs.userlibs[mode - LIBRARY].instlist == NULL) return;
657
679
 
658
680
   /* Find the Helvetica font for use in labeling the objects */
659
681
 
660
682
   fval = findhelvetica();
661
683
 
 
684
   /* experimental:  attempt to produce a library with the same aspect  */
 
685
   /* ratio as the drawing window.                                      */
 
686
 
 
687
   totalarea = 0;
 
688
   for (spec = xobjs.userlibs[mode - LIBRARY].instlist; spec != NULL;
 
689
                spec = spec->next) {
 
690
      libobj = spec->thisinst->thisobject;
 
691
 
 
692
      /* "Hidden" objects are not drawn */
 
693
      if (libobj->hidden == True) continue;
 
694
 
 
695
      drawinst = spec->thisinst;
 
696
      drawinst->position.x = 0;
 
697
      drawinst->position.y = 0;
 
698
 
 
699
      /* Get the bounding box of the instance in the page's coordinate system */
 
700
      calcinstbbox((genericptr *)(&drawinst), &llx, &lly, &width, &height);
 
701
      width -= llx;     /* convert urx to width */
 
702
      height -= lly;    /* convert ury to height */
 
703
      width += 30;      /* space padding */
 
704
      height += 30;     /* height padding */
 
705
      if (width < 200) width = 200;     /* minimum box width */
 
706
      if (height < 220) height = 220;   /* minimum box height */
 
707
      totalarea += (width * height);
 
708
   }
 
709
 
 
710
   scale = (double)totalarea / (double)(areastruct.width * areastruct.height);
 
711
   targetwidth = (int)(sqrt(scale) * (double)areastruct.width);
 
712
 
662
713
   /* generate the list of object instances and their labels */
663
714
 
664
715
   for (spec = xobjs.userlibs[mode - LIBRARY].instlist; spec != NULL;
680
731
      /* Determine the area needed on the page to draw the object */
681
732
 
682
733
      nxpos = xpos + ((width > 170) ? width + 30 : 200);
683
 
      if ((nxpos > (areastruct.width << 1)) && (xpos > 0)) {
 
734
      /* if ((nxpos > (areastruct.width << 1)) && (xpos > 0)) { */
 
735
      if ((nxpos > targetwidth) && (xpos > 0)) {
684
736
         nxpos -= xpos; 
685
737
         xpos = 0;
686
738
         ypos -= nypos;
756
808
                     
757
809
         for (testobj = (*compobj)->plist; testobj < (*compobj)->plist
758
810
                  + (*compobj)->parts; testobj++) {
759
 
            if ((*testobj)->type == OBJECT) {
 
811
            if (IS_OBJINST(*testobj)) {
760
812
               if (TOOBJINST(testobj)->thisobject == libobj->thisobject) return 2;
761
813
            }
762
814
         }
771
823
      *compobjp = compobj;
772
824
      for (testobj = (*compobj)->plist; testobj < (*compobj)->plist
773
825
               + (*compobj)->parts; testobj++) {
774
 
         if ((*testobj)->type == OBJECT) {
 
826
         if (IS_OBJINST(*testobj)) {
775
827
            if (TOOBJINST(testobj)->thisobject == libobj->thisobject) return 1;
776
828
         }
777
829
      }
802
854
          + areastruct.selects; newselect++) {
803
855
      libobj = SELTOOBJINST(newselect);
804
856
 
805
 
      if (libobj->thisobject->num_params == 0) {
 
857
      if (libobj->thisobject->params == NULL) {
806
858
         Wprintf("Virtual copy allowed only on objects with paramters.");
807
859
         /* (because currently there's no way to adjust rotation/scale  */
808
860
         /* of a non-parameterized instance from inside the library,    */
906
958
      }
907
959
      else {            /* All's clear to delete.                          */
908
960
 
909
 
         /* First remove any instances of this object in the delete buffer */
910
 
 
911
 
         for (compobj = xobjs.delbuffer.library; compobj != xobjs.delbuffer.library +
912
 
                xobjs.delbuffer.number; compobj++) {
913
 
            for (testobj = (*compobj)->plist; testobj < (*compobj)->plist
914
 
                  + (*compobj)->parts; testobj++) {
915
 
               if ((*testobj)->type == OBJECT) {
916
 
                  if (TOOBJINST(testobj)->thisobject == libobj->thisobject) {
917
 
                     free(TOOBJINST(testobj));
918
 
                     for (tobj = testobj; tobj < (*compobj)->plist
919
 
                           + (*compobj)->parts - 1; tobj++) {
920
 
                        (*tobj) = (*(tobj + 1));
921
 
                     }
922
 
                     (*compobj)->parts--;
923
 
                  }
924
 
               }
925
 
            }
926
 
         }
 
961
         /* Clear the undo stack so that any references to this object  */
 
962
         /* won't screw up the database (this could be kinder & gentler */
 
963
         /* by first checking if there are any references to the object */
 
964
         /* in the undo stack. . .                                      */
 
965
 
 
966
         flush_undo_stack();
 
967
 
 
968
         /* Next, remove the object from the library page. */
927
969
 
928
970
         for (tlib = libpage; tlib < libpage + *libpobjs; tlib++)
929
971
            if ((*tlib) == libobj->thisobject) {
1043
1085
/* Rearrange objects in the library                     */
1044
1086
/*------------------------------------------------------*/
1045
1087
 
1046
 
void catmove(XKeyEvent *event)
 
1088
void catmove(int x, int y)
1047
1089
{
1048
1090
   int i, j, s1, s2, ocentx, ocenty, rangex, rangey;
1049
1091
   liblistptr spec;
1052
1094
   /* make catmove() a wrapper for pagecatmove() */
1053
1095
 
1054
1096
   if ((i = is_library(topobject)) < 0) {
1055
 
      pagecatmove(event);
 
1097
      pagecatmove(x, y);
1056
1098
      return;
1057
1099
   }
1058
1100
 
1090
1132
   }
1091
1133
   else {       /* one object selected; find place to put from cursor position */
1092
1134
 
1093
 
      window_to_user(event->x, event->y, &areastruct.save);
 
1135
      window_to_user(x, y, &areastruct.save);
1094
1136
 
1095
1137
      s2 = -1;
1096
1138
      for (j = 0, spec = xobjs.userlibs[i].instlist; spec != NULL;
1118
1160
         else if (areastruct.save.y <=
1119
1161
                xobjs.libtop[i + LIBRARY]->thisobject->bbox.lowerleft.y +
1120
1162
                xobjs.libtop[i + LIBRARY]->thisobject->bbox.height) {
1121
 
            objectdeselect();   
 
1163
            unselect_all();     
1122
1164
            Wprintf("Could not find appropriate place to insert object");
1123
1165
            return;
1124
1166
         }
1128
1170
      linkedlistinsertafter(&(xobjs.userlibs[i].instlist), s1, s2);
1129
1171
   }
1130
1172
 
1131
 
   objectdeselect();
 
1173
   unselect_all();
1132
1174
   if ((i = is_library(topobject)) >= 0) composelib(LIBRARY + i);
1133
1175
 
1134
1176
   drawarea(NULL, NULL, NULL);
1143
1185
   short *newselect;
1144
1186
   objectptr *newobj, *curlib, oldobj;
1145
1187
   objinstptr libobj;
 
1188
   oparamptr ops, newops;
1146
1189
   int i, libnum = USERLIB - LIBRARY ;
1147
1190
 
1148
1191
   for (newselect = areastruct.selectlist; newselect < areastruct.selectlist
1174
1217
      (*newobj)->pcorner.x = oldobj->pcorner.x;
1175
1218
      (*newobj)->pcorner.y = oldobj->pcorner.y;
1176
1219
      (*newobj)->viewscale = oldobj->viewscale;
1177
 
#ifdef SCHEMA
1178
1220
      /* don't attach the same schematic. . . */
1179
1221
      (*newobj)->symschem = NULL;
 
1222
      /* don't copy highlights */
 
1223
      (*newobj)->highlight.netlist = NULL;
 
1224
      (*newobj)->highlight.thisinst = NULL;
1180
1225
 
1181
1226
      /* Copy the parameter structure */
1182
 
      (*newobj)->num_params = oldobj->num_params;
1183
 
      (*newobj)->params = (oparamptr *)malloc(oldobj->num_params *
1184
 
                sizeof(oparamptr));
1185
 
      for (i = 0; i < oldobj->num_params; i++) {
1186
 
         (*newobj)->params[i] = (oparamptr) malloc(sizeof(oparam));
1187
 
         (*newobj)->params[i]->type = oldobj->params[i]->type;
1188
 
         switch (oldobj->params[i]->type) {
 
1227
      (*newobj)->params = NULL;
 
1228
      for (ops = oldobj->params; ops != NULL; ops = ops->next) {
 
1229
         newops = (oparamptr)malloc(sizeof(oparam));
 
1230
         newops->next = (*newobj)->params;
 
1231
         newops->key = strdup(ops->key);
 
1232
         (*newobj)->params = newops;
 
1233
         newops->type = ops->type;
 
1234
         newops->which = ops->which;
 
1235
         switch (ops->type) {
1189
1236
            case XC_INT:
1190
 
               (*newobj)->params[i]->parameter.ivalue =
1191
 
                        oldobj->params[i]->parameter.ivalue;
 
1237
               newops->parameter.ivalue = ops->parameter.ivalue;
1192
1238
               break;
1193
1239
            case XC_FLOAT:
1194
 
               (*newobj)->params[i]->parameter.fvalue =
1195
 
                        oldobj->params[i]->parameter.fvalue;
 
1240
               newops->parameter.fvalue = ops->parameter.fvalue;
1196
1241
               break;
1197
1242
            case XC_STRING:
1198
 
               (*newobj)->params[i]->parameter.string =
1199
 
                        stringcopy(oldobj->params[i]->parameter.string);
 
1243
               newops->parameter.string = stringcopy(ops->parameter.string);
 
1244
               break;
 
1245
            case XC_EXPR:
 
1246
               newops->parameter.expr = strdup(ops->parameter.expr);
1200
1247
               break;
1201
1248
         }
1202
1249
      }
1203
1250
 
1204
1251
      (*newobj)->schemtype = oldobj->schemtype;
1205
 
      (*newobj)->netlist = NULL;
1206
 
      (*newobj)->portlist = NULL;
1207
 
      (*newobj)->calllist = NULL;
 
1252
      (*newobj)->netnames = NULL;
 
1253
      (*newobj)->ports = NULL;
 
1254
      (*newobj)->calls = NULL;
 
1255
      (*newobj)->polygons = NULL;
 
1256
      (*newobj)->labels = NULL;
1208
1257
      (*newobj)->valid = False;
1209
1258
      (*newobj)->traversed = False;
1210
 
      (*newobj)->devname = NULL;
1211
 
#endif
1212
1259
      (*newobj)->hidden = False;
1213
1260
 
1214
1261
      /* copy over all the elements of the original object */
1217
1264
      (*newobj)->plist = (genericptr *)malloc(sizeof(genericptr));
1218
1265
 
1219
1266
      for (i = 0; i < oldobj->parts; i++) {
1220
 
         switch((*(oldobj->plist + i))->type) {
 
1267
         switch(ELEMENTTYPE(*(oldobj->plist + i))) {
1221
1268
            case(PATH): {
1222
1269
               register pathptr *npath, cpath = TOPATH(oldobj->plist + i);
1223
1270
               register genericptr *gpart;
1227
1274
               (*npath)->parts = 0;
1228
1275
               (*npath)->plist = (genericptr *)malloc(cpath->parts *
1229
1276
                        sizeof(genericptr));
1230
 
               (*npath)->num_params = 0;
1231
1277
               (*npath)->passed = NULL;
1232
1278
               for (gpart = cpath->plist; gpart < cpath->plist + cpath->parts;
1233
1279
                        gpart++) {
1234
 
                  switch((*gpart)->type){
 
1280
                  switch(ELEMENTTYPE(*gpart)){
1235
1281
                     case ARC: {
1236
1282
                        arcptr copyarc = TOARC(gpart);
1237
1283
                        arcptr *newarc;
1284
1330
 
1285
1331
               clabel = TOLABEL(oldobj->plist + i);
1286
1332
               NEW_LABEL(nlabel, (*newobj));
1287
 
               (*nlabel)->rotation = clabel->rotation;
1288
 
               (*nlabel)->color = clabel->color;
1289
 
               (*nlabel)->position.x = clabel->position.x;
1290
 
               (*nlabel)->position.y = clabel->position.y;
1291
 
               (*nlabel)->scale = clabel->scale;
1292
 
               (*nlabel)->justify = clabel->justify;
1293
 
               (*nlabel)->string = stringcopy(clabel->string);
1294
 
               (*nlabel)->num_params = 0;
1295
 
               (*nlabel)->passed = NULL;
1296
 
#ifdef SCHEMA
1297
 
               (*nlabel)->pin = clabel->pin;
1298
 
#endif
 
1333
               labelcopy(*nlabel, clabel);
1299
1334
               } break;
1300
1335
      
1301
 
            case(OBJECT): {
 
1336
            case(OBJINST): {
1302
1337
               register objinstptr *ninst, cinst;
1303
1338
 
1304
1339
               cinst = TOOBJINST(oldobj->plist + i);
1305
1340
               NEW_OBJINST(ninst, (*newobj));
1306
 
               (*ninst)->rotation = cinst->rotation;
1307
 
               (*ninst)->color = cinst->color;
1308
 
               (*ninst)->position.x = cinst->position.x;
1309
 
               (*ninst)->position.y = cinst->position.y;
1310
 
               (*ninst)->scale = cinst->scale;
1311
 
               (*ninst)->thisobject = cinst->thisobject;
1312
 
               (*ninst)->num_params = 0;
1313
 
               (*ninst)->passed = NULL;
1314
 
 
1315
 
               /* Library instance's parameter list is always default (null) */
1316
 
               (*ninst)->params = NULL;
1317
 
               (*ninst)->bbox.lowerleft.x = cinst->thisobject->bbox.lowerleft.x;
1318
 
               (*ninst)->bbox.lowerleft.y = cinst->thisobject->bbox.lowerleft.y;
1319
 
               (*ninst)->bbox.width = cinst->thisobject->bbox.width;
1320
 
               (*ninst)->bbox.height = cinst->thisobject->bbox.height;
1321
 
 
1322
 
#ifdef SCHEMA
1323
 
               (*ninst)->schembbox = NULL;
1324
 
 
1325
 
               /* here---deal with attached schematics */
1326
 
#endif
 
1341
               instcopy(*ninst, cinst);
1327
1342
               } break;
1328
1343
         }
1329
1344
         (*newobj)->parts++;
1334
1349
   addtoinstlist(USERLIB - LIBRARY, *newobj, FALSE);
1335
1350
 
1336
1351
   composelib(USERLIB);
1337
 
   objectdeselect();
 
1352
   unselect_all();
1338
1353
 
1339
1354
   if (areastruct.topinstance == xobjs.libtop[USERLIB])
1340
1355
      drawarea(NULL, NULL, NULL);
1345
1360
/* ButtonPress handler during normal catalog viewing mode */
1346
1361
/*--------------------------------------------------------*/
1347
1362
 
1348
 
void catbutton(u_int mode, XButtonEvent *event)
 
1363
void catalog_op(int op, int x, int y)
1349
1364
{
1350
1365
   short *newselect;
1351
1366
   objinstptr *newobject, *libobj;
1353
1368
   short ocentx, ocenty, rangex, rangey, xdiff, ydiff, flag = 0;
1354
1369
   XPoint oldpos;
1355
1370
 
1356
 
   /* Make catbutton() a wrapper for pagecatbutton() */
 
1371
   /* Make catalog_op() a wrapper for pagecat_op() */
1357
1372
 
1358
1373
   if (is_library(topobject) < 0) {
1359
 
      pagecatbutton(event);
 
1374
      pagecat_op(op, x, y);
1360
1375
      return;
1361
1376
   }
1362
1377
 
1363
 
   if (event->button == Button1 || event->button == Button2) {
1364
 
 
1365
 
      window_to_user(event->x, event->y, &areastruct.save);
 
1378
   /* If XCF_Cancel was invoked, return without a selection. */
 
1379
 
 
1380
   if (op == XCF_Cancel) {
 
1381
      eventmode = NORMAL_MODE;
 
1382
      catreturn();
 
1383
   }
 
1384
   else {
 
1385
 
 
1386
      window_to_user(x, y, &areastruct.save);
1366
1387
        
1367
1388
      for (libobj = (objinstptr *)topobject->plist; libobj <
1368
1389
                (objinstptr *)topobject->plist + topobject->parts; libobj++) {
1369
 
         if ((*libobj)->type == OBJECT) {
 
1390
         if (IS_OBJINST(*libobj)) {
1370
1391
 
1371
1392
            ocentx = (*libobj)->position.x + (*libobj)->bbox.lowerleft.x
1372
1393
                + ((*libobj)->bbox.width >> 1);
1384
1405
 
1385
1406
               /* setup to move object around and draw the selected object */
1386
1407
 
1387
 
#ifdef SCHEMA
1388
1408
               if (eventmode == ASSOC_MODE) {
1389
1409
 
1390
1410
                  /* revert to old page */
1395
1415
                  schemassoc(topobject, (*libobj)->thisobject); 
1396
1416
                  setpage(TRUE);
1397
1417
                  catreturn();
1398
 
                  eventmode = PRESS_MODE;
 
1418
                  eventmode = NORMAL_MODE;
1399
1419
               }
1400
 
               else
1401
 
#endif
1402
 
               if (event->button == Button1) {
 
1420
               else if ((op == XCF_Library_Pop) || (op == XCF_Library_Copy)) {
1403
1421
 
1404
1422
                  /* revert to old page */
1405
1423
 
1410
1428
                  /* retrieve drawing window state and set position of object to
1411
1429
                     be correct in reference to that window */
1412
1430
 
1413
 
                  snap(event->x, event->y, &oldpos);
 
1431
                  snap(x, y, &oldpos);
1414
1432
 
1415
1433
                  setpage(FALSE);
1416
1434
            
1417
 
                  snap(event->x, event->y, &areastruct.save);
 
1435
                  snap(x, y, &areastruct.save);
1418
1436
                  xdiff = areastruct.save.x - oldpos.x;
1419
1437
                  ydiff = areastruct.save.y - oldpos.y;
1420
1438
 
1453
1471
                     *newselect = (short)(newobject - (objinstptr *)topobject->plist);
1454
1472
 
1455
1473
                  }
1456
 
                  if ((void *)mode == (void *)(1)) {
 
1474
                  if (op == XCF_Library_Copy) {
1457
1475
 
1458
 
                     /* key "c" pressed for "copy" */
 
1476
                     /* Key "c" pressed for "copy" (default binding) */
1459
1477
 
1460
1478
                     XDefineCursor(dpy, areastruct.areawin, COPYCURSOR);
1461
 
                     eventmode = COPY2_MODE;
 
1479
                     eventmode = COPY_MODE;
1462
1480
#ifndef TCL_WRAPPER
1463
1481
                     xcAddEventHandler(areastruct.area, PointerMotionMask, False,
1464
 
                          (xcEventHandler)drag, NULL);
 
1482
                          (xcEventHandler)xlib_drag, NULL);
1465
1483
#endif
1466
1484
                  }
1467
1485
                  else {
1468
 
                     eventmode = PRESS_MODE;
 
1486
                     eventmode = MOVE_MODE;
 
1487
                     areastruct.editcycle = 1;
1469
1488
                  }
1470
1489
#ifdef TCL_WRAPPER
 
1490
                  /* fprintf(stderr, "Creating event handler for xctk_drag: "); */
 
1491
                  /* printeventmode();          */
1471
1492
                  Tk_CreateEventHandler(areastruct.area, PointerMotionMask,
1472
1493
                        (Tk_EventProc *)xctk_drag, NULL);
1473
1494
#endif
 
1495
                  register_for_undo(XCF_Library_Pop, UNDO_MORE, areastruct.topinstance,
 
1496
                                areastruct.selectlist, areastruct.selects);
1474
1497
                  catreturn();
1475
1498
               }
1476
1499
 
1477
 
               /* If button2 was pressed, select and stay in the catalog. */
1478
 
               /* Could just do "objectselect" here, but would not cover   */
 
1500
               /* Select the closest element and stay in the catalog.      */
 
1501
               /* Could just do "select_element" here, but would not cover */
1479
1502
               /* the entire area in the directory surrounding the object. */
1480
1503
 
1481
 
               else {
 
1504
               else if (op == XCF_Select) {
1482
1505
                  short newinst = (short)(libobj - (objinstptr *)topobject->plist);
1483
1506
                  /* (ignore this object if it is already in the list of selects) */
1484
1507
                  for (newselect = areastruct.selectlist; newselect <
1497
1520
         }
1498
1521
      }
1499
1522
   }
1500
 
   /* If button3 was pressed, return without a selection. */
1501
 
 
1502
 
   else {
1503
 
      eventmode = NORMAL_MODE;
1504
 
      catreturn();
1505
 
   }
1506
1523
}
1507
1524
 
1508
1525
/*------------------------------*/
1541
1558
                (areastruct.topinstance == xobjs.libtop[libmod])) return;
1542
1559
 
1543
1560
   if (libmod == FONTLIB) {
1544
 
      XDefineCursor (dpy, areastruct.areawin, CROSS);
1545
 
      if (eventmode == TEXT2_MODE)
 
1561
      XDefineCursor (dpy, areastruct.areawin, DEFAULTCURSOR);
 
1562
      if (eventmode == TEXT_MODE)
1546
1563
         eventmode = FONTCAT_MODE;
1547
1564
      else
1548
 
         eventmode = FONTCAT2_MODE;
 
1565
         eventmode = EFONTCAT_MODE;
1549
1566
   }
1550
 
#ifdef SCHEMA
1551
1567
   else if (eventmode == ASSOC_MODE) {
1552
 
      XDefineCursor (dpy, areastruct.areawin, CROSS);
 
1568
      XDefineCursor (dpy, areastruct.areawin, DEFAULTCURSOR);
1553
1569
   }
1554
 
#endif
1555
1570
   else if (libmod == PAGELIB || libmod == LIBLIB) {
1556
 
      XDefineCursor (dpy, areastruct.areawin, CROSS);
 
1571
      XDefineCursor (dpy, areastruct.areawin, DEFAULTCURSOR);
1557
1572
      eventmode = CATALOG_MODE;
1558
1573
   }
1559
1574
   else
1575
1590
 
1576
1591
   areastruct.topinstance = xobjs.libtop[libmod];
1577
1592
   setpage(TRUE);
 
1593
   invalidate_graphics(topobject);
1578
1594
 
1579
1595
   /* draw the new screen */
1580
1596