/* @(#)idiutil2.c 17.1.1.1 (ESO-DMD) 01/25/02 17:34:26 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. Correspondence concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /*********************************************************************** * * * file: idiutil2.c * * * * X11 independent internal service routines * * * ************************************************************************ * V 1.1 871201: P. Santin - Trieste Astronomical Observatory (X10) * * V 2.0 890102: K. Banse - ESO Garching (from now on) * 010522 last modif ************************************************************************ * contains the following routines: * * allrefr : Display Refresh of memories , cursors and roi * rectrefr : Display Refresh of rect_memories * clgraph : Clear graphics of a memory * curmove : Interactive Cursor Movement; * loc_mod : Modify Locator Data; * loc_zero : Zero Locator Data; * polyclear : Clear a polyline; * roimodify : Interactive Region of Interest Modify; * roimove : Interactive Region of Interest Move; * txtclear : Clear a text string; * copy_over : Copy overlay graphics to image channel * ***********************************************************************/ # include # include # include static int epsi2 = 2; /* must be synchronized with send_event */ /* in module idilocal3.c ! */ static int movcount = 0; static int temp; static int xdif, ydif; static int x, y, dxsize, dysize; static unsigned char pixls[2]; static LOCATOR *loca; /* */ /* ---- Refresh ------------------------------------------------------ */ /* general refresh of image memories */ void allrefr(dspno,mem,memid,flag) int dspno, memid, flag; MEM_DATA *mem; { int i, sx, sy, dx, dy; CONF_DATA *conf; ALPH_DATA *alph; conf = ididev[dspno].confptr; if (memid != conf->overlay) { if (mem->mmbm == (char *) 0) i = allo_mem(dspno,mem,memid); if (ididev[dspno].devtyp == 'g') cl_win(dspno,-1); /* ensure right background colour */ sx = mem->xscroll; if (sx >= 0) dx = 0; else { dx = -sx; sx = 0; } sy = mem->ysize - (ididev[dspno].ysize + mem->yscroll); if (sy >= 0) dy = 0; else { dy = -sy; sy = 0; } smv(flag,dspno,mem,memid,sx,sy,mem->xsize,mem->ysize,dx,dy); if (ididev[dspno].alpno >= 90) { alph = conf->alpmem[memid]; alprfr(dspno,alph); } } if (flag != 0) /* we don't come from IIZWSC_C */ { if (mem->gpntr != 0) polyrefr(dspno,mem,0,0); if (mem->tpntr != 0) txtrefr(dspno,mem,0,0); } } /* */ /* refresh only rectangles of image memories */ void rectrefr(dspno,mem,memid) int dspno, memid; MEM_DATA *mem; { int flag, sx, sy, dx, dy; CONF_DATA *conf; ALPH_DATA *alph; conf = ididev[dspno].confptr; if (mem->mmbm != (char *) 0) { sx = mem->xscroll + mem->xwoff; dx = mem->xwoff; sy = mem->ysize - (mem->ywoff + mem->ywdim); dy = ididev[dspno].ysize - (mem->ywoff+mem->ywdim); if (mem->zoom > 1) flag = 1; else flag = 11; /* to update only a rectangle */ smv(flag,dspno,mem,memid,sx,sy,mem->xwdim,mem->ywdim,dx,dy); if (ididev[dspno].alpno >= 90) { alph = conf->alpmem[memid]; alprfr(dspno,alph); } } } /* */ /* ---- Clear Graphics ------------------------------------------- */ void clgraph(mem) MEM_DATA *mem; { GLIST *gp; TLIST *tp; if (mem->gpntr != 0) { gp = mem->gpntr; gp->geln = 0; *gp->off = 0; } if (mem->tpntr != (TLIST *)0) { tp = mem->tpntr; tp->teln = 0; tp->off[0] = 0; } } /* */ /* ---- locator positions zero --------------------------------------- */ void loc_zero (dspno) int dspno; { ROI_DATA *roi; register int loopi; for (loopi=0; loopixpos = 0; loca->ypos = 0; loca->xdif = 0; loca->ydif = 0; loca->lowsp = 1; loca->spfact = 0; /* not used... */ loca->speed = loca->lowsp; } roi = ididev[dspno].roi; roi->radno = 4; /* reset to default */ } /* */ /* ---- locator modify ----------------------------------------------- */ void loc_mod(dspno,locno,lkey) int dspno, locno, lkey; /* dspno : display no. */ /* locno : locator no. */ /* lkey : locator key */ { static int locinc[10] = {0,1,2,4,8,16,32,64,100,200}; ROI_DATA *roi; if ((lkey < 10) && (lkey != -5)) { if (lkey < -10) /* just update */ { roi = ididev[dspno].roi; roi->radno = -(lkey + 10); /* -11,-12,-13,... => 1,2,3,... */ if (roi->radno == 2) roi->ymax = roi->xmax - roi->radiusm; /* distance value */ else if (roi->radno == 3) roi->ymax = roi->xmax - roi->radiuso; else roi->ymax = roi->xmax - roi->radiusi; } else { loca = intdevtable[dspno].loc[locno]; if (lkey < 0) { if (lkey == -1) /* update locator positions */ { loca->xdif = 0; loca->ydif = loca->speed; loca->ypos += loca->ydif; } else if (lkey == -2) { loca->xdif = 0; loca->ydif = - loca->speed; loca->ypos += loca->ydif; } else if (lkey == -3) { loca->ydif = 0; loca->xdif = loca->speed; loca->xpos += loca->xdif; } else { loca->ydif = 0; loca->xdif = - loca->speed; loca->xpos += loca->xdif; } } else loca->speed = loca->lowsp + locinc[lkey]; } } } /* */ /* ---- cursor move -------------------------------------------------- */ /* curno : cursor number */ /* locno : locator no. */ /* ldat : locator data */ /* lpos : locator positions */ void curmove (dspno,curno,locno,ldat,lpos) int dspno, curno, locno, ldat, *lpos; { CURS_DATA *curs; int kk, jj; curs = ididev[dspno].cursor[curno]; loca = intdevtable[dspno].loc[locno]; dxsize = ididev[dspno].xsize - 1; dysize = ididev[dspno].ysize - 1; /* depending on type of locator we compute new location or just read it */ if (locno > 0) /* if it's the arrow keys ... */ { loc_mod(dspno,locno,ldat); xdif = loca->xdif; ydif = loca->ydif; loca->xdif = 0; loca->ydif = 0; if ((xdif == 0) && (ydif == 0)) return; /* nothing to do */ curs->xpos += xdif; curs->ypos += ydif; } else { if ((lpos[0] == loca->xpos) && (lpos[1] == loca->ypos)) return; loca->xpos = lpos[0]; loca->ypos = lpos[1]; curs->xpos = loca->xpos + epsi2; curs->ypos = dysize - loca->ypos + epsi2; } if (curs->xpos < 0) curs->xpos = 0; else { if (curs->xpos > dxsize) curs->xpos = dxsize; } if (curs->ypos < 0) curs->ypos = 0; else { if (curs->ypos > dysize) curs->ypos = dysize; } draw_curs(dspno,1,dysize,curno,curs->xpos,curs->ypos,curs->sh,curs->col); show_pix8(dspno,curno,curs->xpos,curs->ypos,curs->xpos,curs->ypos,pixls); if (++movcount == 3) { movcount = 0; jj = 0; sh_loop: kk = ididev[dspno].shadow[jj++]; if (kk != -1) { draw_curs(kk,1,dysize,curno,curs->xpos,curs->ypos,curs->sh,curs->col); show_pix8(kk,curno,curs->xpos,curs->ypos,curs->xpos,curs->ypos,pixls); goto sh_loop; } } } /* */ /* ---- roi move ----------------------------------------------------- */ void roimove (dspno,locno,lpos) int dspno, locno, *lpos; { int cposx, cposy; int xd1, xd2, yd1, yd2; int xmi,xma,ymi,yma; int kk, jj; register int ra, rb; ROI_DATA *roi; loca = intdevtable[dspno].loc[locno]; if ((lpos[0] == loca->xpos) && (lpos[1] == loca->ypos)) return; roi = ididev[dspno].roi; dxsize = ididev[dspno].xsize -1; dysize = ididev[dspno].ysize -1; ra = lpos[0] + epsi2; /* new center */ rb = dysize - lpos[1] + epsi2; if (roi->sh == 0) /* rectangle */ { cposx = (roi->xmin + roi->xmax) / 2; /* old center */ cposy = (roi->ymin + roi->ymax) / 2; xd1 = cposx - roi->xmin; /* distance to borders */ xd2 = roi->xmax - cposx; yd1 = cposy - roi->ymin; yd2 = roi->ymax - cposy; /* if we are at the window border, we stay put */ xmi = ra - xd1; if ((xmi < 0) || (xmi > dxsize)) return; xma = ra + xd2; if (xma < xmi) xma = xmi; else { if (xma > dxsize) return; } ymi = rb - yd1; if ((ymi < 0) || (ymi > dysize)) return; yma = rb + yd2; if (yma < ymi) yma = ymi; else { if (yma > dysize) return; } /* update locator position */ roi->xmin = xmi; roi->xmax = xma; roi->ymin = ymi; roi->ymax = yma; draw_rroi(dspno,1,dysize,roi->xmin,roi->ymin,roi->xmax,roi->ymax,roi->col); show_pix8(dspno,2,roi->xmin,roi->ymin,roi->xmax,roi->ymax,pixls); } else /* circle(s) */ { /* if we are at the window border, we stay put */ xmi = ra - roi->radiusi; if ((xmi < 0) || (xmi > dxsize)) return; xma = ra + roi->radiusi; if ((xma < 0) || (xma > dxsize)) return; ymi = rb - roi->radiusi; if ((ymi < 0) || (ymi > dysize)) return; yma = rb + roi->radiusi; if ((yma < 0) || (yma > dysize)) return; roi->xmin = ra; roi->ymin = rb; draw_croi(dspno,1,dysize,roi->xmin,roi->ymin, roi->radiusi,roi->radiusm,roi->radiuso,roi->col); show_pix8(dspno,0,roi->xmin,roi->ymin,roi->xmin,roi->ymin,pixls); } loca->xpos = lpos[0]; loca->ypos = lpos[1]; if (++movcount == 3) { movcount = 0; jj = 0; sh_loop: kk = ididev[dspno].shadow[jj++]; if (kk != -1) { if (roi->sh == 0) { draw_rroi(kk,1,dysize,roi->xmin,roi->ymin,roi->xmax,roi->ymax, roi->col); show_pix8(kk,2,roi->xmin,roi->ymin,roi->xmax,roi->ymax,pixls); } else { draw_croi(kk,1,dysize,roi->xmin,roi->ymin, roi->radiusi,roi->radiusm,roi->radiuso,roi->col); show_pix8(kk,0,roi->xmin,roi->ymin,roi->xmin,roi->ymin,pixls); } goto sh_loop; } } } /* */ /* ---- roi modify --------------------------------------------------- */ void roimodify (dspno,locno) int dspno, locno; { int kk, jj; register int ra, rb; ROI_DATA *roi; loca = intdevtable[dspno].loc[locno]; x = loca->xdif; y = loca->ydif; loca->xdif = 0; loca->ydif = 0; roi = ididev[dspno].roi; dysize = ididev[dspno].ysize - 1; if (roi->sh == 0) /* rectangle */ { ra = roi->xmax; rb = roi->ymax; if (x != 0) { ra += x; if (ra < 0) ra = 0; else { dxsize = ididev[dspno].xsize - 1; if (ra > dxsize) ra = dxsize; } if (ra < roi->xmin) ra = roi->xmin; } else { if (y == 0) return; /* x=0 and y=0, => nothing to do */ } if (y != 0) { rb += y; if (rb < 0) rb = 0; else { if (rb > dysize) rb = dysize; } if (rb < roi->ymin) rb = roi->ymin; } roi->xmax = ra; roi->ymax = rb; draw_rroi(dspno,1,dysize,roi->xmin,roi->ymin,roi->xmax,roi->ymax,roi->col); show_pix8(dspno,2,roi->xmin,roi->ymin,roi->xmax,roi->ymax,pixls); } else /* circle(s) */ { if (x == 0) { if (y == 0) return; /* x=0 and y=0, => nothing to do */ x = y; /* so we only use x */ } rb = (roi->xmax + x) - roi->ymax; /* new rad = new ref_rad - distance */ /* update according to function keys F1, F2, F3 or F4 */ if (roi->radno == 2) /* only middle radius */ { if (roi->radiusm < 1) return; if (rb == roi->radiusm) { if (x < 0) rb -- ; /* for x/y = -1 */ else rb ++ ; /* for x/y = +1 */ } if ((roi->radiuso > 0) && (rb > roi->radiuso)) rb = roi->radiuso; if (rb < roi->radiusi) rb = roi->radiusi; roi->radiusm = rb; } else if (roi->radno == 3) /* only outer radius */ { if (roi->radiuso < 1) return; if (rb == roi->radiuso) { if (x < 0) rb -- ; /* for x/y = -1 */ else rb ++ ; /* for x/y = +1 */ } if (roi->radiusm > 0) { if (rb < roi->radiusm) rb = roi->radiusm; } else { if (rb < roi->radiusi) rb = roi->radiusi; } roi->radiuso = rb; } else { if (rb == roi->radiusi) { if (x < 0) rb -- ; /* for x/y = -1 */ else rb ++ ; /* for x/y = +1 */ } if (rb < 1) rb = 1; /* at least 1 pixel radius */ if (roi->radno == 4) /* change inner circle + others (relative) */ { ra = rb - roi->radiusi; /* diff. of new + old radius */ if (roi->radiusm > 0) roi->radiusm += ra; if (roi->radiuso > 0) roi->radiuso += ra; } else /* only inner radius */ { if (roi->radiusm > 0) { if (rb > roi->radiusm) rb = roi->radiusm; } else if (roi->radiuso > 0) { if (rb > roi->radiuso) rb = roi->radiuso; } } roi->radiusi = rb; } roi->xmax = rb + roi->ymax; /* update ref_radius */ draw_croi(dspno,1,dysize,roi->xmin,roi->ymin, roi->radiusi,roi->radiusm,roi->radiuso,roi->col); show_pix8(dspno,0,roi->xmin,roi->ymin,roi->xmin,roi->ymin,pixls); } jj = 0; sh_loop: kk = ididev[dspno].shadow[jj++]; if (kk != -1) { if (roi->sh == 0) { draw_rroi(kk,1,dysize,roi->xmin,roi->ymin,roi->xmax,roi->ymax, roi->col); show_pix8(kk,2,roi->xmin,roi->ymin,roi->xmax,roi->ymax,pixls); } else { draw_croi(kk,1,dysize,roi->xmin,roi->ymin, roi->radiusi,roi->radiusm,roi->radiuso,roi->col); show_pix8(kk,0,roi->xmin,roi->ymin,roi->xmin,roi->ymin,pixls); } goto sh_loop; } } /* */ /* ---- Clear Polyline on display bitmap ----------------------------- */ void polyclear(dspno,mem,xs,ys,np) int dspno, *xs, *ys, np; MEM_DATA *mem; { int kindx, koff, hit; int *goff, *gx, *gy, *gcount, *gcol, *glw; register int loopi, loopk; GLIST *gp; gp = mem->gpntr; if (gp == 0) return; kindx = gp->geln; if (kindx <= 0) return; x = *xs; dysize = ididev[dspno].ysize - 1; y = dysize - (*ys); hit = 0; again: goff = gp->off; gcount = gp->count; gcol = gp->color; glw = gp->lwidth; for (loopi=0; loopix + koff; if (*gx == x) { gy = gp->y + koff; if (*gy == y) { if (gp->geln == 1) { gp->geln = 0; *gp->off = 0; } else { hit = 1; temp = loopi; goto clean_up; } } } goff ++; gcount ++; gcol ++; glw ++; } if (hit == 1) polyrefr(dspno,mem,0,0); return; clean_up: for (loopi=temp; loopi<(kindx-1); loopi++) { *gcount = *(gcount+1); *gcol = *(gcol+1); *glw = *(glw+1); for (loopk=0; loopk<(*gcount); loopk++) { *gx = *(gx+np); *gy = *(gy+np); gx ++; gy ++; } *(goff+1) = (*goff) + (*gcount); goff ++; gcount ++; gcol ++; glw ++; } gp->geln --; kindx = gp->geln; goto again; /* there may be more */ } /* */ /* ---- Clear Text on display bitmap ----------------------------- */ void txtclear(dspno,mem,xs,ys,np) int dspno, xs, ys, np; MEM_DATA *mem; { int tindx, toff, hit, zoff; register int loopi, loopk; TLIST *tp; tp = mem->tpntr; if (tp == (TLIST *)0) return; tindx = tp->teln; if (tindx <= 0) return; x = xs; dysize = ididev[dspno].ysize - 1; y = dysize - ys; hit = 0; temp = 0; again: for (loopi=temp; loopix[loopi] == x) && (tp->y[loopi] == y)) { if (tp->teln == 1) { tp->teln = 0; tp->off[0] = 0; } else { hit = 1; temp = loopi; goto clean_up; } } } if (hit == 1) txtrefr(dspno,mem,0,0); return; clean_up: zoff = tp->off[temp+1]; /* offset of next element */ for (loopi=temp; loopi<(tindx-1); loopi++) { toff = tp->off[loopi]; tp->count[loopi] = tp->count[loopi+1]; tp->x[loopi] = tp->x[loopi+1]; tp->y[loopi] = tp->y[loopi+1]; tp->size[loopi] = tp->size[loopi+1]; tp->color[loopi] = tp->color[loopi+1]; for (loopk=0; loopkcount[loopi+1]; loopk++) { tp->text[toff++] = tp->text[zoff++]; } zoff = tp->off[loopi+2]; /* offset of [loop+1] in next loop */ tp->off[loopi+1] = tp->off[loopi] + tp->count[loopi]; } tp->teln --; tindx = tp->teln; goto again; /* there may be more */ } /* */ /* ---- Copy graphics from overlay channel to image memory ----------- */ void copy_over(dspno,memid,append) int dspno, memid, append; { int *x, *y, *off, *colo, *lw, *cou; int *ovx, *ovy, *ovoff, *ovcolo, *ovlw, *ovcou; int kk, kindx, ioff, coff; register int nr, mr; char *inpntr, *cpntr; CONF_DATA *conf; MEM_DATA *ovmem, *mem; GLIST *gpov, *gp; TLIST *tpov, *tp; conf = ididev[dspno].confptr; if (memid == conf->overlay) return; mem = conf->memory[memid]; ovmem = conf->memory[conf->overlay]; /* work on the graphics */ gpov = ovmem->gpntr; nr = gpov->geln; if (nr == 0) goto text_section; /* no graphics to copy */ gp = mem->gpntr; if (append == 1) { kindx = gp->geln; gp->geln += gpov->geln; } else { kindx = 0; gp->geln = gpov->geln; } off = gp->off + kindx; colo = gp->color + kindx; lw = gp->lwidth + kindx; cou = gp->count + kindx; x = gp->x + kindx; y = gp->y + kindx; ovoff = gpov->off; ovcolo = gpov->color; ovlw = gpov->lwidth; ovcou = gpov->count; ovx = gpov->x; ovy = gpov->y; for (nr=0; nrgeln; nr++) { /* copy offset, colour, linewidth, no_pnts */ *off++ = *ovoff++; *colo++ = *ovcolo++; *lw++ = *ovlw++; *cou++ = *ovcou++; } *off = *ovoff; /* offset is 1 index farther... */ cou = gp->count + kindx; for (nr=0; nrgeln; nr++) { /* for each graph_elem copy x,y */ for (mr=0; mr<(*cou); mr++) { *x++ = *ovx++; *y++ = *ovy++; } cou ++; } polyrefr(dspno,mem,1,memid); /* work on the text */ text_section: tpov = ovmem->tpntr; nr = tpov->teln; if (nr == 0) return; /* no text to copy */ tp = mem->tpntr; if (append == 1) { kindx = tp->teln; tp->teln += tpov->teln; } else { kindx = 0; tp->teln = tpov->teln; } off = tp->off + kindx; colo = tp->color + kindx; lw = tp->size + kindx; cou = tp->count + kindx; x = tp->x + kindx; y = tp->y + kindx; ovoff = tpov->off; ovcolo = tpov->color; ovlw = tpov->size; ovcou = tpov->count; ovx = tpov->x; ovy = tpov->y; for (nr=0; nrteln; nr++) { /* copy offset, colour, size, no_pnts */ *x++ = *ovx++; *y++ = *ovy++; *off++ = *ovoff++; *colo++ = *ovcolo++; *lw++ = *ovlw++; *cou++ = *ovcou++; } *off = *ovoff; /* offset is 1 index farther... */ coff = tp->off[kindx]; for (nr=0; nrteln; nr++) { ioff = tpov->off[nr]; inpntr = &(tpov->text[ioff]); cpntr = &(tp->text[coff]); kk = tpov->count[nr]; for (mr=0; mr