1 /*   $Id: ddvcolor.c,v 1.23 2006/07/13 17:06:38 bollin Exp $
2 * ===========================================================================
3 *
4 *                            PUBLIC DOMAIN NOTICE
5 *            National Center for Biotechnology Information (NCBI)
6 *
7 *  This software/database is a "United States Government Work" under the
8 *  terms of the United States Copyright Act.  It was written as part of
9 *  the author's official duties as a United States Government employee and
10 *  thus cannot be copyrighted.  This software/database is freely available
11 *  to the public for use. The National Library of Medicine and the U.S.
12 *  Government do not place any restriction on its use or reproduction.
13 *  We would, however, appreciate having the NCBI and the author cited in
14 *  any work or product based on this material
15 *
16 *  Although all reasonable efforts have been taken to ensure the accuracy
17 *  and reliability of the software and data, the NLM and the U.S.
18 *  Government do not and cannot warrant the performance or results that
19 *  may be obtained by using this software or data. The NLM and the U.S.
20 *  Government disclaim all warranties, express or implied, including
21 *  warranties of performance, merchantability or fitness for any particular
22 *  purpose.
23 *
24 * ===========================================================================
25 *
26 * File Name:  $Id: ddvcolor.c,v 1.23 2006/07/13 17:06:38 bollin Exp $
27 *
28 * Author:  Lewis Geer
29 *
30 * Version Creation Date:   6/4/99
31 *
32 * $Revision: 1.23 $
33 *
34 * File Description: Shared color information for viewers
35 *
36 * Modifications:
37 * --------------------------------------------------------------------------
38 * $Log: ddvcolor.c,v $
39 * Revision 1.23  2006/07/13 17:06:38  bollin
40 * use Uint4 instead of Uint2 for itemID values
41 * removed unused variables
42 * resolved compiler warnings
43 *
44 * Revision 1.22  2000/03/06 18:35:22  thiessen
45 * fixes for 8-bit color
46 *
47 * Revision 1.21  2000/02/23 18:56:29  thiessen
48 * move to 1-based row numbers
49 *
50 * Revision 1.20  2000/02/15 22:40:57  lewisg
51 * add ability to launch udv so that it colors by row, fixes to colormgr, track rows from viewmgr, fix visual c projects
52 *
53 * Revision 1.19  2000/02/10 18:40:19  lewisg
54 * fix a freeing order for colorglobal
55 *
56 * Revision 1.18  2000/02/10 15:51:58  lewisg
57 * cn3d responds and send correct update messages.  many coloring bug fixes
58 *
59 * Revision 1.17  2000/02/10 14:15:18  durand
60 * add a function to build Feature colors table
61 *
62 * Revision 1.16  2000/01/28 19:25:39  lewisg
63 * columnwise binary search on color data
64 *
65 * Revision 1.15  1999/12/29 22:55:02  lewisg
66 * get rid of seqalign id
67 *
68 * Revision 1.14  1999/12/13 23:20:43  lewisg
69 * bug fixes: duplicate color structures eliminated, clear color doesn't clear case
70 *
71 * Revision 1.13  1999/12/11 01:30:34  lewisg
72 * fix bugs with sharing colors between ddv and cn3d
73 *
74 * Revision 1.12  1999/12/10 20:59:22  durand
75 * add support for italic, bold and underlined letters
76 *
77 * Revision 1.11  1999/11/24 21:24:23  vakatov
78 * Fixed for the C++ and/or MSVC DLL compilation
79 *
80 * Revision 1.10  1999/11/24 15:23:19  lewisg
81 * added color selection dialogs for SS
82 *
83 * Revision 1.9  1999/11/22 17:29:53  lewisg
84 * add back color selection dialogs, fix viewer3d half-selection bug
85 *
86 * Revision 1.8  1999/11/02 23:06:08  lewisg
87 * fix cn3d to launch correctly if there is no seqentry associated with bioseq
88 *
89 * Revision 1.7  1999/11/01 22:10:26  lewisg
90 * add ability to call color functions by type, and add this to cn3d
91 *
92 * Revision 1.6  1999/10/25 20:28:48  lewisg
93 * move ddvcolor to libncbiobj
94 *
95 * Revision 6.9  1999/10/15 20:56:40  lewisg
96 * append DDV_ColorGlobal as userdata.  free memory when cn3d terminates.
97 *
98 * Revision 6.8  1999/10/08 23:20:36  lewisg
99 * add case and box attributes to DDV_ColorCell
100 *
101 * Revision 6.7  1999/10/05 23:18:26  lewisg
102 * add ddv and udv to cn3d with memory management
103 *
104 * Revision 6.6  1999/09/21 19:50:36  kans
105 * cast on function parameter needed
106 *
107 * Revision 6.5  1999/09/21 18:09:13  lewisg
108 * binary search added to color manager, various bug fixes, etc.
109 *
110 * Revision 1.10  1999/09/03 23:27:32  lewisg
111 * minor speedups by avoiding casts
112 *
113 * Revision 1.9  1999/09/03 14:01:40  lewisg
114 * use faster seqid compare SAM_CompareID
115 *
116 * Revision 1.8  1999/09/01 23:02:59  lewisg
117 * binary search in color functions
118 *
119 * Revision 1.7  1999/08/13 22:08:16  lewisg
120 * color manager updated to use alignment coords
121 *
122 * Revision 1.6  1999/08/09 18:09:33  lewisg
123 * copy of ddvcolor from distrib to avoid changing daily build
124 *
125 * Revision 6.4  1999/07/20 14:38:11  durand
126 * update DDV_InRange to include the ends in the test
127 *
128 * Revision 6.3  1999/07/19 19:12:21  lewisg
129 * fix bug adding new pColor in old pMediaInfo.  Also added ability to detect overlaps when allocating new pColor
130 *
131 * Revision 6.2  1999/07/19 14:37:03  lewisg
132 * fix bug when allocating mediainfo with from != 0
133 *
134 * Revision 6.1  1999/07/16 18:46:46  lewisg
135 * moved ddvcolor from api to tools
136 *
137 * Revision 1.4  1999/07/13 23:24:48  lewisg
138 * added DDV_SipList
139 *
140 * Revision 1.3  1999/07/13 14:38:39  lewisg
141 * separated out networking code
142 *
143 * Revision 1.4  1999/06/24 17:48:28  lewisg
144 * added SpecialColors to global
145 *
146 * Revision 1.3  1999/06/16 13:51:50  lewisg
147 * added palette management functions from cn3d
148 *
149 * Revision 1.2  1999/06/14 17:20:47  lewisg
150 * minor bug fix for leaks
151 *
152 * Revision 1.1  1999/06/11 23:37:09  lewisg
153 * color management functions
154 *
155 *
156 *
157 * ==========================================================================
158 */
159 
160 #include <ncbi.h>
161 #include <objfdef.h>
162 #include <sequtil.h>
163 #include <ddvcolor.h>
164 #include <salutil.h>
165 #include <samutil.h>
166 
167 
168 /*****************************************************************************
169 *
170 *   get a color for a Feature.
171 *
172 *****************************************************************************/
DDV_GetFeatColor(DDV_ColorGlobal * pColorGlobal,Int1 idx)173 NLM_EXTERN DDV_ColorCell DDV_GetFeatColor(DDV_ColorGlobal* pColorGlobal, Int1 idx)
174 {
175 DDV_ColorCell dcc;
176 
177 	memset(&dcc,0,sizeof(DDV_ColorCell));
178 	if (idx<0 || idx>=FEATDEF_MAX) return(dcc);
179 	if (!pColorGlobal->SpeClr.pFeatColorTable) return(dcc);
180 
181 	return(pColorGlobal->SpeClr.pFeatColorTable[idx]);
182 }
183 
184 /*****************************************************************************
185 *
186 *   setup a DDV_ColorCell with r,g,b values.
187 *
188 *****************************************************************************/
DDV_GetColorRGB(Uint1 r,Uint1 g,Uint1 b)189 NLM_EXTERN DDV_ColorCell DDV_GetColorRGB(Uint1 r, Uint1 g, Uint1 b)
190 {
191 DDV_ColorCell dcc;
192 
193 	memset(&dcc,0,sizeof(DDV_ColorCell));
194 	dcc.rgb[0]=r;
195 	dcc.rgb[1]=g;
196 	dcc.rgb[2]=b;
197 
198 	return(dcc);
199 }
200 
201 /*****************************************************************************
202 *
203 *   Initialisation of the Feature colors table.
204 *
205 *****************************************************************************/
DDV_InitFeatureColors(void)206 static DDV_ColorCell * DDV_InitFeatureColors(void)
207 {
208 DDV_ColorCell * pClr;
209 Uint1    i;
210 
211 	pClr=(DDV_ColorCell *)MemNew(FEATDEF_MAX*sizeof(DDV_ColorCell));
212 	if (!pClr) return(NULL);
213 	for (i=0;i<FEATDEF_MAX;i++)
214 		pClr[i]=DDV_GetColorRGB(0,0,0);
215 
216 	/*Warning: values are one-based*/
217 	pClr[FEATDEF_GENE]=DDV_GetColorRGB(128,128,128);			/*gray*/
218 
219 	pClr[FEATDEF_precursor_RNA]=DDV_GetColorRGB(0,0,255);/*blue*/
220 	pClr[FEATDEF_misc_RNA]=DDV_GetColorRGB(0,0,255);
221 	pClr[FEATDEF_preRNA]=DDV_GetColorRGB(0,0,255);
222 	pClr[FEATDEF_mRNA]=DDV_GetColorRGB(0,0,255);
223 	pClr[FEATDEF_tRNA]=DDV_GetColorRGB(0,0,255);
224 	pClr[FEATDEF_rRNA]=DDV_GetColorRGB(0,0,255);
225 	pClr[FEATDEF_snRNA]=DDV_GetColorRGB(0,0,255);
226 	pClr[FEATDEF_scRNA]=DDV_GetColorRGB(0,0,255);
227 	pClr[FEATDEF_otherRNA]=DDV_GetColorRGB(0,0,255);
228 	pClr[FEATDEF_prim_transcript]=DDV_GetColorRGB(0,0,255);
229 
230 	pClr[FEATDEF_CDS]=DDV_GetColorRGB(255,150,255);	/*pink*/
231 	pClr[FEATDEF_exon]=DDV_GetColorRGB(255,150,255);
232 	pClr[FEATDEF_intron]=DDV_GetColorRGB(255,150,255);
233 
234 	pClr[FEATDEF_PROT]=DDV_GetColorRGB(0,128,0);		/*dk green*/
235 	pClr[FEATDEF_mat_peptide]=DDV_GetColorRGB(0,128,0);
236 	pClr[FEATDEF_sig_peptide]=DDV_GetColorRGB(0,128,0);
237 	pClr[FEATDEF_transit_peptide]=DDV_GetColorRGB(0,128,0);
238 	pClr[FEATDEF_preprotein]=DDV_GetColorRGB(0,128,0);
239 	pClr[FEATDEF_mat_peptide_aa]=DDV_GetColorRGB(0,128,0);
240 	pClr[FEATDEF_sig_peptide_aa]=DDV_GetColorRGB(0,128,0);
241 	pClr[FEATDEF_transit_peptide_aa]=DDV_GetColorRGB(0,128,0);
242 
243 
244 	pClr[FEATDEF_SITE]=DDV_GetColorRGB(255,0,0);		/*red*/
245 
246 	pClr[FEATDEF_REGION]=DDV_GetColorRGB(210,154,14);		/*orange*/
247 	pClr[FEATDEF_mutation]=DDV_GetColorRGB(210,154,14);
248 	pClr[FEATDEF_variation]=DDV_GetColorRGB(210,154,14);
249 
250 	pClr[FEATDEF_PSEC_STR]=DDV_GetColorRGB(104,201,220); /*cyan*/
251 
252 	pClr[FEATDEF_HET]=DDV_GetColorRGB(128,128,0);	/*yellow*/
253 
254 	pClr[FEATDEF_BOND]=DDV_GetColorRGB(255,92,255);	/*pink*/
255 
256 	return(pClr);
257 }
258 
259 
260 /*****************************************************************************
261 *
262 *   Set default values for DDV_Range.
263 *
264 *****************************************************************************/
265 
DDV_DefaultRange(DDV_Range * pRange,Int4 lFrom,Int4 lTo)266 NLM_EXTERN Int4 DDV_DefaultRange(DDV_Range *pRange, Int4 lFrom, Int4 lTo)
267 {
268     if(pRange == NULL || lFrom > lTo ) {
269         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_DefaultRange");
270         return 0;
271     }
272 
273     pRange->lFrom = lFrom;
274     pRange->lTo = lTo;
275     return 1;
276 }
277 
278 /*****************************************************************************
279 *
280 *   Constructor for DDV_ColorEntry structure.  DDV_ColorEntry is a
281 *   (Red, Green, Blue) color triplet and associated szName.
282 *
283 *****************************************************************************/
284 
DDV_CreateColorEntry(Char * szName,Nlm_Uint1 Red,Nlm_Uint1 Green,Nlm_Uint1 Blue)285 NLM_EXTERN DDV_ColorEntry * DDV_CreateColorEntry
286 (Char *szName, Nlm_Uint1 Red, Nlm_Uint1 Green, Nlm_Uint1 Blue)
287 {
288     DDV_ColorEntry *pColor;
289 
290     pColor = MemNew(sizeof(DDV_ColorEntry));
291     if (pColor == NULL) {
292         ErrPostEx(SEV_ERROR, 0, 0, "Invalid malloc in DDV_CreateColorEntry");
293         return NULL;
294     }
295 
296     pColor->Name = StringSave(szName);
297     pColor->Paints = NULL;
298     pColor->Index = 0;
299     DDV_SetColorCell(&pColor->ColorCell, Red, Green, Blue);
300     pColor->ColorCell.BottomBox = FALSE;
301     pColor->ColorCell.LeftBox = FALSE;
302     pColor->ColorCell.LowerCase = FALSE;
303     pColor->ColorCell.RightBox = FALSE;
304     pColor->ColorCell.TopBox = FALSE;
305     pColor->ColorCell.UseItalic = FALSE;
306     pColor->ColorCell.UseBold = FALSE;
307     pColor->ColorCell.UseUnderline = FALSE;
308 
309     return pColor;
310 }
311 
312 
313 /*****************************************************************************
314 *
315 *   Destructor for DDV_ColorEntry Color.
316 *
317 *****************************************************************************/
318 
319 /* destructor for Color structure */
DDV_DeleteColorEntry(DDV_ColorEntry * Color)320 NLM_EXTERN void DDV_DeleteColorEntry(DDV_ColorEntry *Color)
321 {
322     MemFree(Color->Name);
323     MemFree(Color->Paints);
324     MemFree(Color);
325 }
326 
327 
328 /*****************************************************************************
329 *
330 *   Frees a Palette.  Palette is a ValNode list of DDV_ColorEntries
331 *   Note that it frees the entire Valnode list pointed to by Palette and
332 *   sets Palette to NULL.
333 *
334 *****************************************************************************/
335 
DDV_FreePalette(ValNode ** Palette)336 NLM_EXTERN void DDV_FreePalette(ValNode **Palette)
337 {
338     ValNode *Index;
339 
340     if(Palette == NULL) {
341         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_FreePalette");
342         return;
343     }
344 
345     Index = *Palette;
346     while (Index) {
347         if (Index->data.ptrvalue)
348           DDV_DeleteColorEntry((DDV_ColorEntry *)(Index->data.ptrvalue));
349         Index = Index->next;
350     }
351     ValNodeFree(*Palette);
352     *Palette = NULL;
353 }
354 
355 /*****************************************************************************
356 *
357 *   Puts ColorCell on the Palette list if it isn't there already.
358 *
359 *****************************************************************************/
360 
DDV_RequestColor(ValNode ** Palette,DDV_ColorCell * ColorCell)361 NLM_EXTERN void DDV_RequestColor(ValNode **Palette, DDV_ColorCell *ColorCell)
362 {
363     DDV_ColorEntry *NewColor;
364 
365     if(Palette == NULL || ColorCell == NULL) {
366         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_RequestColor");
367         return;
368     }
369 
370     if ( DDV_SearchColor(*Palette, ColorCell) == NULL ) {
371         NewColor = DDV_CreateColorEntry
372           ("", ColorCell->rgb[0], ColorCell->rgb[1], ColorCell->rgb[2]);
373         if (!NewColor) return;
374         ValNodeAddPointer(Palette, 0, NewColor);
375     }
376     return;
377 }
378 
379 /*****************************************************************************
380 *
381 *   Puts ColorEntry on the Palette list if the sZname isn't there already,
382 *   Otherwise replaces the entry.  Does NOT make a copy of the DDV_ColorEntry
383 *
384 *****************************************************************************/
385 
DDV_RequestColorbyName(ValNode ** Palette,DDV_ColorEntry * pColorIn)386 NLM_EXTERN void DDV_RequestColorbyName
387 (ValNode **Palette, DDV_ColorEntry *pColorIn)
388 {
389     DDV_ColorEntry *pColorEntry;
390     ValNode *pvn;
391 
392     if(Palette == NULL || pColorIn == NULL) {
393         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_RequestColorbyName");
394         return;
395     }
396 
397     pColorEntry = DDV_SearchColorbyName(*Palette, pColorIn->Name);
398     if (pColorEntry == NULL) {
399         ValNodeAddPointer(Palette, 0, pColorIn);
400         return;
401     }
402     else {
403         for(pvn = *Palette; pvn->data.ptrvalue != pColorEntry;
404             pvn = pvn->next) continue;
405         DDV_DeleteColorEntry((DDV_ColorEntry*)pvn->data.ptrvalue);
406         pvn->data.ptrvalue = pColorIn;
407     }
408 }
409 
410 
411 /*****************************************************************************
412 *
413 *   Looks for ColorCell on the Palette.  Returns * to the
414 *   DDV_ColorEntry.
415 *
416 *****************************************************************************/
417 
DDV_SearchColor(ValNode * Palette,DDV_ColorCell * ColorCell)418 NLM_EXTERN DDV_ColorEntry * DDV_SearchColor
419 (ValNode *Palette, DDV_ColorCell *ColorCell)
420 {
421     ValNode *pvnPalette = Palette;
422 
423     if(ColorCell == NULL) {
424         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_SearchColor");
425         return NULL;
426     }
427 
428     while(pvnPalette) {
429         if(((DDV_ColorEntry *)(pvnPalette->data.ptrvalue))->ColorCell.rgb[0]
430             == ColorCell->rgb[0] &&
431             ((DDV_ColorEntry *)(pvnPalette->data.ptrvalue))->ColorCell.rgb[1]
432             == ColorCell->rgb[1]  &&
433             ((DDV_ColorEntry *)(pvnPalette->data.ptrvalue))->ColorCell.rgb[2]
434             == ColorCell->rgb[2] )
435             return (DDV_ColorEntry *)(pvnPalette->data.ptrvalue);
436         pvnPalette = pvnPalette->next;
437     }
438     return NULL;
439 }
440 
441 /*****************************************************************************
442 *
443 *   Looks for a DDV_ColorEntry on the Palette by szName.  Returns *
444 *   to the DDV_ColorEntry.
445 *
446 *****************************************************************************/
447 
DDV_SearchColorbyName(ValNode * Palette,Char * szName)448 NLM_EXTERN DDV_ColorEntry * DDV_SearchColorbyName
449 (ValNode *Palette, Char *szName)
450 {
451     ValNode *pvnPalette = Palette;
452 
453     while(pvnPalette) {
454         if(StrCmp(((DDV_ColorEntry *)(pvnPalette->data.ptrvalue))->Name,
455             szName) == 0 )
456             return (DDV_ColorEntry *)(pvnPalette->data.ptrvalue);
457         pvnPalette = pvnPalette->next;
458     }
459     return NULL;
460 }
461 
462 /*****************************************************************************
463 *
464 *   Looks for a DDV_ColorEntry on the Palette by szName.  Returns *
465 *   to ColorCell in the DDV_ColorEntry.
466 *
467 *****************************************************************************/
468 
DDV_SearchColorCellbyName(ValNode * Palette,Char * szName)469 NLM_EXTERN DDV_ColorCell * DDV_SearchColorCellbyName
470 (ValNode *Palette, Char *szName)
471 {
472     DDV_ColorEntry *pColorEntry;
473 
474     pColorEntry = DDV_SearchColorbyName(Palette, szName);
475     if(pColorEntry == NULL) return NULL;
476 
477     return &pColorEntry->ColorCell;
478 }
479 
480 /*****************************************************************************
481 *
482 *   Sets the Index in a DDV_ColorEntry according to position in Palette
483 *
484 *****************************************************************************/
485 
DDV_SetColorChoice(ValNode * Palette)486 NLM_EXTERN void DDV_SetColorChoice(ValNode *Palette)
487 /* sets the valnode choice value according to position in palette */
488 {
489     Int4 i = 0;
490     ValNode *pvnPalette = Palette;
491 
492     if(Palette == NULL) {
493         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_SetColorChoice");
494         return;
495     }
496 
497     while(pvnPalette) {
498         ((DDV_ColorEntry *)(pvnPalette->data.ptrvalue))->Index = i;
499         i++;
500         pvnPalette = pvnPalette->next;
501     }
502 }
503 
504 /*****************************************************************************
505 *
506 *   Returns the index into the Palette for a given ColorCell.
507 *   Return index on success, 0 on failure.
508 *
509 *****************************************************************************/
510 
DDV_ColorIndex(ValNode * Palette,DDV_ColorCell * ColorCell)511 NLM_EXTERN Int4 DDV_ColorIndex(ValNode *Palette, DDV_ColorCell *ColorCell)
512 /* returns the index into the palette for a given color */
513 {
514     DDV_ColorEntry *Color;
515 
516     if(Palette == NULL || ColorCell == NULL) {
517         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_ColorIndex");
518         return 0;
519     }
520 
521     Color = DDV_SearchColor(Palette, ColorCell);
522     if ( Color == NULL ) return 0;
523     else return Color->Index;
524 }
525 
526 
527 /*****************************************************************************
528 *
529 *   Sets colors in a ColorCell.
530 *
531 *****************************************************************************/
532 
DDV_SetColorInCell(DDV_ColorCell * pColorTo,Uint1 * Color)533 NLM_EXTERN void DDV_SetColorInCell(DDV_ColorCell *pColorTo, Uint1 *Color)
534 {
535     if(pColorTo == NULL || Color == NULL) return;
536     pColorTo->rgb[0] = Color[0];
537     pColorTo->rgb[1] = Color[1];
538     pColorTo->rgb[2] = Color[2];
539 }
540 
541 
542 /*****************************************************************************
543 *
544 *   Copy a DDV_ColorCell.
545 *   Return 1 on success, 0 on failure.
546 *
547 *****************************************************************************/
548 
DDV_CopyColorCell(DDV_ColorCell * pDestination,DDV_ColorCell * pSource)549 NLM_EXTERN Int4 DDV_CopyColorCell
550 (DDV_ColorCell *pDestination,  DDV_ColorCell *pSource)
551 {
552     if(pDestination == NULL || pSource == NULL) {
553         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_CopyColorCell");
554         return 0;
555     }
556 
557     MemCpy(pDestination, pSource, sizeof(DDV_ColorCell));
558     return 1;
559 }
560 
561 /*****************************************************************************
562 *
563 *   Set a color cell using Uint1 values
564 *   Return 1 on success, 0 on failure
565 *
566 *****************************************************************************/
567 
DDV_SetColorCell(DDV_ColorCell * pColorCell,Nlm_Uint1 Red,Nlm_Uint1 Green,Nlm_Uint1 Blue)568 NLM_EXTERN Int4 DDV_SetColorCell
569 (DDV_ColorCell *pColorCell, Nlm_Uint1 Red,
570  Nlm_Uint1 Green, Nlm_Uint1 Blue)
571 {
572     if(pColorCell == NULL) {
573         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_SetColorCell");
574         return 0;
575     }
576 
577     pColorCell->rgb[0] = Red;
578     pColorCell->rgb[1] = Green;
579     pColorCell->rgb[2] = Blue;
580     return 1;
581 }
582 
583 
584 /*****************************************************************************
585 *
586 *   Returns a DDV_ColorCell for a given lPosition if it is inside of pColor.
587 *   Returns NULL otherwise.
588 *
589 *****************************************************************************/
590 
DDV_GetCellByPosition(DDV_Color * pColor,Int4 lPosition)591 NLM_EXTERN DDV_ColorCell * DDV_GetCellByPosition
592 (DDV_Color *pColor, Int4 lPosition)
593 {
594     if(pColor == NULL) {
595         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_GetCellByPosition");
596         return NULL;
597     }
598 
599     if(SAM_InRange(lPosition, pColor->Range.lFrom,
600         pColor->Range.lTo) & SAM_NOLAP) return NULL;
601     return &(pColor->pColorCell[lPosition - pColor->Range.lFrom]);
602 }
603 
604 /*****************************************************************************
605 *
606 *   Sets a DDV_ColorCell for a given lPosition if it is inside of pColor.
607 *   Returns 1 on success, 0 on failure.
608 *
609 *****************************************************************************/
610 
DDV_SetCellByPosition(DDV_Color * pColor,Int4 lPosition,DDV_ColorCell * pColorCell)611 NLM_EXTERN Int4 DDV_SetCellByPosition
612 (DDV_Color * pColor, Int4 lPosition, DDV_ColorCell *pColorCell)
613 {
614     if(pColor == NULL || pColorCell == NULL) {
615         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_SetCellByPosition");
616         return 0;
617     }
618 
619     if(SAM_InRange(lPosition, pColor->Range.lFrom, pColor->Range.lTo)
620         & SAM_NOLAP) return 0;
621 
622     MemCpy(&pColor->pColorCell[lPosition - pColor->Range.lFrom],
623         pColorCell, sizeof(DDV_ColorCell));
624 
625     return 1;
626 }
627 
628 /*****************************************************************************
629 
630 Function: DDV_CreateColorCell()
631 
632 Purpose: Creates a new DDV_ColorCell and initializes it.
633 
634 Parameters: none
635 
636 Returns: pointer to new DDV_ColorCell or NULL on error
637 
638 *****************************************************************************/
639 
DDV_CreateColorCell(void)640 NLM_EXTERN DDV_ColorCell * DDV_CreateColorCell(void)
641 {
642     DDV_ColorCell *pColorCell;
643 
644     pColorCell = MemNew(sizeof(DDV_ColorCell));
645     if(pColorCell == NULL) return NULL;
646 
647     pColorCell->rgb[0] = 0;
648     pColorCell->rgb[1] = 0;
649     pColorCell->rgb[2] = 0;
650 
651     pColorCell->LowerCase = FALSE;
652     pColorCell->TopBox = FALSE;
653     pColorCell->RightBox = FALSE;
654     pColorCell->BottomBox = FALSE;
655     pColorCell->LeftBox = FALSE;
656     pColorCell->UseItalic = FALSE;
657     pColorCell->UseBold = FALSE;
658     pColorCell->UseUnderline = FALSE;
659 
660     return pColorCell;
661 }
662 
663 /*****************************************************************************
664 *
665 *   Creates a DDV_Color that spans the entire object with
666 *   coordinates lFrom to lTo.
667 *   The default color is taken from the pallete.
668 *   Returns NULL on error.
669 *
670 *****************************************************************************/
671 
DDV_CreateDefaultColor(DDV_ColorGlobal * pColorGlobal,Int4 lFrom,Int4 lTo)672 NLM_EXTERN DDV_Color * DDV_CreateDefaultColor
673 (DDV_ColorGlobal *pColorGlobal, Int4 lFrom, Int4 lTo)
674 {
675     DDV_Color *pColor;
676     Int4 i;
677     DDV_ColorCell *pColorCell;
678 
679     if (pColorGlobal == NULL || lFrom > lTo) {
680         ErrPostEx(SEV_ERROR, 0, 0,
681             "Invalid call on DDV_CreateDefaultColor");
682         return NULL;
683     }
684 
685     pColor = MemNew(sizeof(DDV_Color));
686     if (pColor == NULL) {
687         ErrPostEx(SEV_ERROR, 0, 0,
688             "Unable to malloc DDV_Color in DDV_CreateDefaultColor");
689         return NULL;
690     }
691 
692     pColor->Range.lFrom = lFrom;
693     pColor->Range.lTo = lTo;
694     pColor->pColorCell = MemNew(sizeof(DDV_ColorCell) * (lTo - lFrom + 1));
695     MemSet((void *)pColor->pColorCell, 0, sizeof(DDV_ColorCell) * (lTo - lFrom + 1));
696     if( pColor->pColorCell == NULL) {
697         ErrPostEx(SEV_ERROR, 0, 0,
698             "Unable to malloc DDV_ColorCells in DDV_CreateDefaultColor");
699         return NULL;
700     }
701 
702     pColorCell = DDV_SearchColorCellbyName(pColorGlobal->pvnSpecialColors,
703             "Default");
704     if(pColorCell == NULL) return NULL;
705 
706     DDV_RequestColor(&pColorGlobal->Palette, pColorCell);
707 
708     for(i = 0; i <= lTo - lFrom; i++) DDV_CopyColorCell(
709         &pColor->pColorCell[i], pColorCell);
710 
711     return pColor;
712 }
713 
714 /*****************************************************************************
715 *
716 *   Deletes a DDV_Color.
717 *   Returns 1 on success, 0 on failure.
718 *
719 *****************************************************************************/
720 
DDV_DeleteColor(DDV_Color * pColor)721 NLM_EXTERN Int4 DDV_DeleteColor(DDV_Color *pColor)
722 {
723     if(pColor == NULL) {
724         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_DeleteColor");
725         return 0;
726     }
727 
728     MemFree(pColor->pColorCell);
729     MemFree(pColor);
730     return 1;
731 }
732 
733 /* todo: delete mediainfo for a given sip */
734 /* todo: lock count for mediainfo */
735 
736 
737 /*****************************************************************************
738 *
739 *   Creates a new DDV_MediaInfo structure.  Creates a default color structure
740 *   for the given object specified by sip OR row.
741 *   Inserts the given pColor and sets fVisible.  Duplicates the sip.
742 *
743 *   Returns NULL on error.
744 *
745 *****************************************************************************/
746 
DDV_ComparePosition(DDV_Range * pRange1,DDV_Range * pRange2)747 static Int4 DDV_ComparePosition(DDV_Range *pRange1, DDV_Range *pRange2)
748 {
749     Int4 test;
750 
751     if(pRange1 == NULL || pRange2 == NULL) return 0;
752     test = SAM_RangeOverlap(pRange1->lFrom, pRange1->lTo,
753         pRange2->lFrom, pRange2->lTo);
754     if(test == SAM_NOLAPFRONT) return -1;
755     if(test == SAM_NOLAPBACK) return 1;
756     return 0;
757 }
758 
759 
DDV_NewMediaInfo(SeqId * sip,Int4 lRow,DDV_Color * pColor,Boolean fVisible)760 NLM_EXTERN DDV_MediaInfo * DDV_NewMediaInfo
761 (SeqId *sip,  Int4 lRow, DDV_Color *pColor, Boolean fVisible)
762 {
763     DDV_MediaInfo *pMediaInfo;
764 
765     if ((sip == NULL && lRow <= 0) || (sip != NULL && lRow > 0)) {
766         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_NewMediaInfo");
767         return NULL;
768     }
769 
770 
771     pMediaInfo = MemNew(sizeof(DDV_MediaInfo));
772     if (pMediaInfo == NULL) {
773         ErrPostEx(SEV_ERROR, 0, 0, "Invalid Malloc in DDV_NewMediaInfo");
774         return NULL;
775     }
776 
777     if(sip != NULL) pMediaInfo->Id.sip = SeqIdDupList(sip);
778     pMediaInfo->Id.lRow = lRow;
779 
780     pMediaInfo->pvnColor = NULL;
781     if(pColor != NULL) ValNodeAddPointer(&pMediaInfo->pvnColor, 0, pColor);
782     pMediaInfo->fVisible = fVisible;
783 
784     pMediaInfo->pSearchColor =
785       B_NewGlobal((B_CompareFunc) DDV_ComparePosition, 0);
786 
787     return pMediaInfo;
788 }
789 
790 /*****************************************************************************
791 *
792 *   Returns a ValNode list, each element of which points to the SeqId of a
793 *   sequence that has a corresponding DDV_MediaInfo structure in pColorGlobal.
794 *
795 *   The Valnode list should be freed by the calling routine.  However, the
796 *   SeqIds pointed to by the list should *not* be freed.
797 *
798 *   Returns NULL on error.
799 *
800 *****************************************************************************/
801 
DDV_IdList(DDV_ColorGlobal * pColorGlobal)802 NLM_EXTERN ValNode * DDV_IdList(DDV_ColorGlobal *pColorGlobal)
803 {
804     ValNode *pvn, *pvnReturn = NULL;
805     DDV_MediaInfo *pMediaInfo;
806 
807     if(pColorGlobal == NULL) {
808         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_SipList");
809         return NULL;
810     }
811 
812     for(pvn = pColorGlobal->pvnMediaInfo ; pvn != NULL; pvn = pvn->next) {
813         pMediaInfo = (DDV_MediaInfo *)pvn->data.ptrvalue;
814         if(pMediaInfo->Id.sip != NULL)
815             ValNodeAddPointer(&pvnReturn, 0, pMediaInfo->Id.sip);
816     }
817 
818     return pvnReturn;
819 }
820 
821 /*****************************************************************************
822 *
823 *   Creates a default MediaInfo structure if necessary and adds it to
824 *   pColorGlobal for the given object specified by sip OR lRow.
825 *   Duplicates the sip.
826 *   The sequence is visible by default.
827 *
828 *   If the coordinates do not exist in the MediaInfo structure (whether the
829 *   MediaInfo was freshly created or not) then a DDV_Color is added to the
830 *   MediaInfo to cover the coordinate requested.
831 *
832 *   Coordinates lFrom to lTo.
833 *
834 *****************************************************************************/
835 
DDV_DefaultMediaInfoByLen(DDV_ColorGlobal * pColorGlobal,SeqId * sip,Int4 lRow,Int4 lFrom,Int4 lTo)836 NLM_EXTERN Int4 DDV_DefaultMediaInfoByLen
837 (DDV_ColorGlobal * pColorGlobal, SeqId *sip, Int4 lRow, Int4 lFrom, Int4 lTo)
838 {
839     DDV_MediaInfo *pMediaInfo;
840     DDV_Color *pColor;
841     ValNode *pvn;
842     Int4 lOverlap;
843     DDV_Range Range;
844 
845     if(pColorGlobal == NULL || (sip == NULL && lRow <= 0) ||
846         (sip != NULL && lRow > 0) || lFrom > lTo) {
847         ErrPostEx(SEV_ERROR, 0, 0,
848             "Invalid call on DDV_DefaultMediaInfoByLen");
849         return 0;
850     }
851 
852     Range.lFrom = lFrom;
853     Range.lTo = lTo;
854 
855     /* check to see if it already exits */
856     pMediaInfo = DDV_GetMediaInfo(pColorGlobal, sip, lRow);
857     if(pMediaInfo == NULL) return 0;
858 
859     for(pvn = pMediaInfo->pvnColor; pvn != NULL; pvn = pvn->next) {
860         pColor = (DDV_Color *)pvn->data.ptrvalue;
861         lOverlap = SAM_RangeOverlap(Range.lFrom, Range.lTo,
862             pColor->Range.lFrom, pColor->Range.lTo);
863         if(lOverlap & SAM_NOLAP) continue;
864         else if(lOverlap == SAM_TOTALLAP ) return 1;
865         else if(lOverlap == SAM_FRONTLAP) {
866             lTo = pColor->Range.lFrom - 1;
867             break;
868         }
869         else if(lOverlap == SAM_BACKLAP) {
870             lFrom = pColor->Range.lTo + 1;
871             break;
872         }
873         else return 0;
874     }
875 
876     pColor = DDV_CreateDefaultColor(pColorGlobal, lFrom, lTo);
877     if(pColor == NULL) {
878         ErrPostEx(SEV_ERROR, 0, 0,
879             "Unable to create pColor in DDV_DefaultMediaInfoByLen");
880         return 0;
881     }
882     ValNodeAddPointer(&pMediaInfo->pvnColor, 0, pColor);
883     B_Insert(pMediaInfo->pSearchColor,
884         (void *)&pColor->Range, (void *) pColor);
885 
886     return 1;
887 }
888 
889 /*****************************************************************************
890 *
891 *   Simplified version of DDV_DefaultMediaInfoByLen for sequence coordinates
892 *   inly.  Retrieves the length and sets the coordinate system to sequence
893 *
894 *   Returns 1 on success, 0 on failure
895 *
896 *****************************************************************************/
897 
DDV_DefaultMediaInfo(DDV_ColorGlobal * pColorGlobal,SeqId * sip)898 NLM_EXTERN Int4 DDV_DefaultMediaInfo(DDV_ColorGlobal* pColorGlobal, SeqId *sip)
899 {
900     Int4 lLength;
901     Bioseq *bsp;
902 
903     if(pColorGlobal == NULL || sip == NULL) {
904         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_DefaultMediaInfo");
905         return 0;
906     }
907 
908     bsp = BioseqLockById(sip);
909     if(bsp == NULL) {
910        ErrPostEx (SEV_ERROR, 0, 0,
911            "BioseqLockById failed in DDV_DefaultMediaInfo");
912        return 0;
913     }
914 
915     lLength = BioseqGetLen(bsp) - 1;
916     BioseqUnlock (bsp);
917 
918     return DDV_DefaultMediaInfoByLen(pColorGlobal, sip, -1, 0, lLength);
919 }
920 
921 /*****************************************************************************
922 *
923 *   Deletes a DDV_MediaInfo structure.
924 *
925 *   Returns 1 on success, 0 on failure
926 *
927 *****************************************************************************/
928 
DDV_DeleteMediaInfo(DDV_MediaInfo * pMediaInfo)929 NLM_EXTERN Int4 DDV_DeleteMediaInfo(DDV_MediaInfo *pMediaInfo)
930 {
931     ValNode *pvn;
932 
933     if(pMediaInfo == NULL) {
934         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_DeleteMediaInfo");
935         return 0;
936     }
937 
938     SeqIdFree(pMediaInfo->Id.sip);
939 
940     for(pvn = pMediaInfo->pvnColor; pvn != NULL; pvn = pvn->next)
941         DDV_DeleteColor((DDV_Color *)pvn->data.ptrvalue);
942     ValNodeFree(pMediaInfo->pvnColor);
943     B_DeleteGlobal(pMediaInfo->pSearchColor);
944 
945     MemFree(pMediaInfo);
946     return 1;
947 }
948 
949 
950 
951 
952 /*****************************************************************************
953 *
954 *   The color function queue.  The queue is used to
955 *   register color function by szName (like "Color by Conservation") and to
956 *   give each function an lPriority.  The algorithm to determine what function
957 *   to call is:
958 *   - if requested, a default coloration is performed.
959 *   - look for an fOverride algorithm with the correct szName. If found, run it,
960 *     then stop.
961 *   - look for all function that match the correct szName OR have fCallMe set.
962 *     Run each algorithm in priority order.
963 *
964 *   Viewers must take care to set the visible bits beforehand as this
965 *   influences coloration.
966 *
967 *   pfnDDV_ColorFunc takes as arguments pData for user data and a range
968 *   lFrom to lTo.  If lTo < lFrom, the range should be ignored.
969 *
970 *****************************************************************************/
971 
972 
973 /*****************************************************************************
974 *
975 *   Returns a new color queue entry with name szName, priority lPriority.
976 *   fOverride is explained above.
977 *
978 *****************************************************************************/
979 
DDV_NewColorQueue(DDV_ColorFunc pfnColorFunc,Char * szName,Int4 lPriority,Boolean fOverride,Uint2 procid)980 NLM_EXTERN DDV_ColorQueue * DDV_NewColorQueue
981 (DDV_ColorFunc pfnColorFunc, Char * szName,
982  Int4 lPriority, Boolean fOverride, Uint2 procid)
983 {
984     DDV_ColorQueue *pColorQueue;
985 
986     if(pfnColorFunc == NULL) {
987         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_NewColorFn");
988         return NULL;
989     }
990 
991     pColorQueue = MemNew(sizeof(DDV_ColorQueue));
992     if(pColorQueue == NULL) {
993         ErrPostEx(SEV_ERROR, 0, 0, "Unable to Malloc in DDV_NewColorFn");
994         return NULL;
995     }
996 
997     pColorQueue->fOverride = fOverride;
998     pColorQueue->lPriority = lPriority;
999     pColorQueue->pfnColorFunc = pfnColorFunc;
1000     pColorQueue->szName = StringSave(szName);
1001     pColorQueue->next = NULL;
1002     pColorQueue->procid = procid;
1003 
1004     return pColorQueue;
1005 }
1006 
1007 /*****************************************************************************
1008 *
1009 *   Deletes a DDV_ColorQueue.
1010 *   Returns 1 on success, 0 on failure
1011 *
1012 *****************************************************************************/
1013 
DDV_DeleteColorQueue(DDV_ColorQueue * pColorQueue)1014 NLM_EXTERN Int4 DDV_DeleteColorQueue(DDV_ColorQueue *pColorQueue)
1015 {
1016     if(pColorQueue == NULL) {
1017         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_DeleteColorFn");
1018         return 0;
1019     }
1020     MemFree(pColorQueue->szName);
1021     MemFree(pColorQueue);
1022     return 1;
1023 }
1024 
1025 
1026 /*****************************************************************************
1027 
1028 Function: DDV_SetPaletteColor()
1029 
1030 Purpose: Sets a single color in the palette.  Trys to read the color out of
1031          the configuration file.  If it isn't there, puts it in the file using
1032          the supplied default
1033 
1034 Parameters: pColorGlobal, the color global object
1035             ParamFile, the name of the app property parameter file
1036             ColorName, the name of the color
1037             red, grn, blue, the default color
1038 
1039 *****************************************************************************/
1040 
DDV_SetPaletteColor(DDV_ColorGlobal * pColorGlobal,Char * ColorName,Char * ParamFile,Uint1 red,Uint1 grn,Uint1 blu)1041 NLM_EXTERN void DDV_SetPaletteColor
1042 (DDV_ColorGlobal *pColorGlobal, Char *ColorName,
1043  Char *ParamFile, Uint1 red, Uint1 grn, Uint1 blu)
1044 {
1045     DDV_ColorEntry *pColorEntry = NULL;
1046 
1047     if(pColorGlobal == NULL || ColorName == NULL || ParamFile == NULL) return;
1048 
1049     pColorEntry = DDV_SearchColorbyName(pColorGlobal->pvnSpecialColors,
1050         ColorName);
1051     if(pColorEntry == NULL) {
1052         pColorEntry = DDV_CreateColorEntry(ColorName, red, grn, blu);
1053         DDV_RequestColorbyName(&pColorGlobal->pvnSpecialColors, pColorEntry);
1054     }
1055 
1056     pColorEntry->ColorCell.rgb[0] = red;
1057     pColorEntry->ColorCell.rgb[1] = grn;
1058     pColorEntry->ColorCell.rgb[2] = blu;
1059 
1060     SetAppParamLong(ParamFile, "COLORS", ColorName, red<<16 | grn<<8 | blu);
1061 
1062 }
1063 
1064 
DDV_GetPaletteColor(DDV_ColorGlobal * pColorGlobal,Char * ColorName,Char * ParamFile,Uint1 red,Uint1 grn,Uint1 blu)1065 static void DDV_GetPaletteColor(DDV_ColorGlobal *pColorGlobal, Char *ColorName,
1066                          Char *ParamFile, Uint1 red, Uint1 grn, Uint1 blu)
1067 {
1068     long Value;
1069 
1070     if(pColorGlobal == NULL || ColorName == NULL || ParamFile == NULL) return;
1071 
1072     Value = GetAppParamLong(ParamFile, "COLORS", ColorName, -1);
1073     if(Value == -1) DDV_SetPaletteColor(pColorGlobal, ColorName, ParamFile,
1074         red, grn, blu);
1075     else DDV_SetPaletteColor(pColorGlobal, ColorName, ParamFile,
1076         (Uint1) DDVRED(Value), (Uint1) DDVGRN(Value), (Uint1) DDVBLU(Value));
1077 }
1078 
1079 /*****************************************************************************
1080 *
1081 *   Sets up default secondary structure colors in
1082 *   pColorGlobal->pvnSpecialColors palette.
1083 *   Returns 0 on failure.
1084 *
1085 *****************************************************************************/
1086 
DDV_DefaultSSColor(DDV_ColorGlobal * pColorGlobal,Char * ParamFile)1087 NLM_EXTERN Int4 DDV_DefaultSSColor
1088 (DDV_ColorGlobal * pColorGlobal, Char *ParamFile)
1089 {
1090 
1091     if(pColorGlobal == NULL) {
1092         ErrPostEx(SEV_ERROR, 0, 0, "Invalid Call on DDV_DefaultSSColor");
1093         return 0;
1094     }
1095 
1096     DDV_SetPaletteColor(pColorGlobal, "Highlight", ParamFile, 255, 255, 0);
1097     DDV_SetPaletteColor(pColorGlobal, "Background", ParamFile, 0, 0, 0);
1098     DDV_SetPaletteColor(pColorGlobal, "Helix", ParamFile, 0, 255, 0);
1099     DDV_SetPaletteColor(pColorGlobal, "Strand", ParamFile, 255, 165, 0);
1100     DDV_SetPaletteColor(pColorGlobal, "Turn", ParamFile, 255, 69, 0);
1101     DDV_SetPaletteColor(pColorGlobal, "Coil", ParamFile, 0, 255, 255);
1102     return 1;
1103 }
1104 
1105 
DDV_LoadSSColor(DDV_ColorGlobal * pColorGlobal,Char * ParamFile)1106 NLM_EXTERN void DDV_LoadSSColor(DDV_ColorGlobal * pColorGlobal, Char *ParamFile)
1107 {
1108     if(pColorGlobal == NULL) {
1109         ErrPostEx(SEV_ERROR, 0, 0, "Invalid Call on DDV_DefaultSSColor");
1110         return;
1111     }
1112 
1113     DDV_GetPaletteColor(pColorGlobal, "Highlight", ParamFile, 255, 255, 0);
1114     DDV_GetPaletteColor(pColorGlobal, "Background", ParamFile, 0, 0, 0);
1115     DDV_GetPaletteColor(pColorGlobal, "Helix", ParamFile, 0, 255, 0);
1116     DDV_GetPaletteColor(pColorGlobal, "Strand", ParamFile, 255, 165, 0);
1117     DDV_GetPaletteColor(pColorGlobal, "Turn", ParamFile, 255, 69, 0);
1118     DDV_GetPaletteColor(pColorGlobal, "Coil", ParamFile, 0, 255, 255);
1119 }
1120 
DDV_CompareRow(void * Key1,void * Key2)1121 static Int4 DDV_CompareRow(void *Key1, void *Key2)
1122 {
1123     if(Key1 == NULL || Key2 == NULL) return 1;
1124     else return *(int *)Key1 - *(int *)Key2;
1125 }
1126 
1127 /*****************************************************************************
1128 *
1129 *   Returns a new DDV_ColorGlobal structure.
1130 *   Returns NULL on failure.
1131 *
1132 *   Parameters: fDefaultColor, sets everything to the default color before
1133 *                              executing color functions
1134 *               pObject, the object this structure is coloring. can be NULL.
1135 *
1136 *****************************************************************************/
1137 
DDV_CreateColorGlobal(Boolean fDefaultColor,void * pObject)1138 NLM_EXTERN DDV_ColorGlobal * DDV_CreateColorGlobal(Boolean fDefaultColor,
1139                                                    void *pObject)
1140 {
1141     DDV_ColorGlobal *pColorGlobal;
1142     DDV_ColorEntry *pColorEntry;
1143 
1144     pColorGlobal = MemNew(sizeof(DDV_ColorGlobal));
1145     if(pColorGlobal == NULL) {
1146         ErrPostEx(SEV_ERROR, 0, 0, "Invalid Malloc in DDV_CreateColorGlobal");
1147         return NULL;
1148     }
1149 
1150     pColorGlobal->pObject = pObject;
1151     pColorGlobal->fColorByMaster = FALSE;
1152     pColorGlobal->fDefaultColor = fDefaultColor;
1153     pColorGlobal->MasterSeqId = NULL;
1154     pColorGlobal->pvnColorQueue = NULL;
1155     pColorGlobal->pvnAllColorFns = NULL;
1156     pColorGlobal->pvnMediaInfo = NULL;
1157     pColorGlobal->Palette = NULL;
1158     pColorGlobal->pvnSpecialColors = NULL;
1159     pColorGlobal->pvnUser2Row = NULL;
1160     pColorGlobal->pSearchMI =
1161       B_NewGlobal((B_CompareFunc) SAM_OrderSeqID, 0);
1162     pColorGlobal->pSearchMIRow =
1163       B_NewGlobal((B_CompareFunc) DDV_CompareRow, 0);
1164 
1165 
1166     pColorEntry = DDV_CreateColorEntry("Highlight", 255, 255, 0);
1167     ValNodeAddPointer(&pColorGlobal->pvnSpecialColors, 0, pColorEntry);
1168     pColorEntry = DDV_CreateColorEntry("Default", 0, 0, 0);
1169     ValNodeAddPointer(&pColorGlobal->pvnSpecialColors, 0, pColorEntry);
1170 
1171 	/*Feature Colors Table init*/
1172 	pColorGlobal->SpeClr.pFeatColorTable=DDV_InitFeatureColors();
1173 
1174     return pColorGlobal;
1175 }
1176 
1177 /*****************************************************************************
1178 *
1179 *   Deletes a  DDV_ColorGlobal structure.
1180 *   Returns 1 on success, 0 on failure
1181 *
1182 *****************************************************************************/
1183 
DDV_DeleteColorGlobal(DDV_ColorGlobal * pColorGlobal)1184 NLM_EXTERN Int4 DDV_DeleteColorGlobal(DDV_ColorGlobal *pColorGlobal)
1185 {
1186     ValNode *pvn;
1187 
1188     if(pColorGlobal == NULL) return 1;
1189 
1190     for(pvn = pColorGlobal->pvnColorQueue; pvn != NULL; pvn = pvn->next)
1191         DDV_DeleteColorQueue((DDV_ColorQueue *)pvn->data.ptrvalue);
1192     ValNodeFree(pColorGlobal->pvnColorQueue);
1193 
1194     for(pvn = pColorGlobal->pvnAllColorFns; pvn != NULL; pvn = pvn->next)
1195         DDV_DeleteColorQueue((DDV_ColorQueue *)pvn->data.ptrvalue);
1196     ValNodeFree(pColorGlobal->pvnAllColorFns);
1197 
1198     for(pvn = pColorGlobal->pvnMediaInfo ; pvn != NULL; pvn = pvn->next)
1199         DDV_DeleteMediaInfo((DDV_MediaInfo *)pvn->data.ptrvalue);
1200     ValNodeFree(pColorGlobal->pvnMediaInfo);
1201 
1202     DDV_FreePalette(&pColorGlobal->Palette);
1203     DDV_FreePalette(&pColorGlobal->pvnSpecialColors);
1204 
1205     B_DeleteGlobal(pColorGlobal->pSearchMI);
1206     B_DeleteGlobal(pColorGlobal->pSearchMIRow);
1207 	if (pColorGlobal->SpeClr.pFeatColorTable)
1208 		MemFree(pColorGlobal->SpeClr.pFeatColorTable);
1209     MemFree(pColorGlobal);
1210 
1211     return 1;
1212 }
1213 
1214 /*****************************************************************************
1215 *
1216 *   Completely deallocate all of the DDV_Color structures in pColorGlobal
1217 *   This is intended for simple minded garbage collection.
1218 *   Returns 1 on success, 0 on failure
1219 *
1220 *****************************************************************************/
1221 
DDV_ClearColor(DDV_ColorGlobal * pColorGlobal)1222 NLM_EXTERN Int4 DDV_ClearColor(DDV_ColorGlobal *pColorGlobal)
1223 {
1224     ValNode *pvn, *pvnColor;
1225     DDV_MediaInfo *pMediaInfo;
1226 
1227     if(pColorGlobal == NULL) {
1228         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_ClearColor");
1229         return 0;
1230     }
1231 
1232     for(pvn = pColorGlobal->pvnMediaInfo ; pvn != NULL; pvn = pvn->next) {
1233         pMediaInfo = (DDV_MediaInfo *)pvn->data.ptrvalue;
1234         for(pvnColor = pMediaInfo->pvnColor; pvnColor != NULL;
1235         pvnColor = pvnColor->next) {
1236             if(!DDV_DeleteColor((DDV_Color *)pvnColor->data.ptrvalue))
1237                 return 0;
1238         }
1239         ValNodeFree(pMediaInfo->pvnColor);
1240         pMediaInfo->pvnColor = NULL;
1241         B_DeleteGlobal(pMediaInfo->pSearchColor);
1242         pMediaInfo->pSearchColor =
1243             B_NewGlobal((B_CompareFunc) DDV_ComparePosition, 0);
1244     }
1245     return 1;
1246 }
1247 
1248 
1249 /*****************************************************************************
1250 *
1251 *   Delete all information for the given sip AND lRow.
1252 *   Returns 1 on success, 0 on failure
1253 *
1254 *****************************************************************************/
1255 
DDV_CompareAllIds(SeqId * sip,Int4 lRow,DDV_Id * pId)1256 static Boolean DDV_CompareAllIds(SeqId *sip, Int4 lRow,
1257                                  DDV_Id *pId)
1258 {
1259     Boolean retval = FALSE;
1260     if(sip != NULL) retval = SeqIdIn(sip, pId->sip);
1261     else if(lRow == pId->lRow) retval = TRUE;
1262     return retval;
1263 }
1264 
1265 
DDV_RemoveMediaInfo(DDV_ColorGlobal * pColorGlobal,SeqId * sip,Int4 lRow)1266 NLM_EXTERN Int4 DDV_RemoveMediaInfo
1267 (DDV_ColorGlobal *pColorGlobal, SeqId *sip, Int4 lRow)
1268 {
1269     ValNode *pvn, *pvnPrevious = NULL;
1270     DDV_MediaInfo *pMediaInfo;
1271 
1272     if(pColorGlobal == NULL || (sip == NULL && lRow <= 0) ||
1273        (sip != NULL && lRow > 0)) {
1274         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_RemoveMediaInfo");
1275         return 0;
1276     }
1277     /* todo: delete from b search */
1278     for(pvn = pColorGlobal->pvnMediaInfo ; pvn != NULL; pvn = pvn->next) {
1279         pMediaInfo = (DDV_MediaInfo *)pvn->data.ptrvalue;
1280 
1281         if(DDV_CompareAllIds(sip, lRow, &pMediaInfo->Id)) {
1282             DDV_DeleteMediaInfo(pMediaInfo);
1283             if(pvnPrevious != NULL) {  /* splice out node */
1284                 pvnPrevious->next = pvn->next;
1285             }
1286             else {  /* if first node */
1287                 pColorGlobal->pvnMediaInfo = pvn->next;
1288             }
1289             MemFree(pvn);
1290             break;
1291         }
1292         pvnPrevious = pvn;
1293     }
1294 
1295     return 1;
1296 }
1297 
1298 /*****************************************************************************
1299 *
1300 *   Add MediaInfo to DDV_ColorGlobal
1301 *   Returns 1 on success, 0 on failure
1302 *
1303 *****************************************************************************/
1304 
DDV_AddMediaInfo(DDV_ColorGlobal * pColorGlobal,DDV_MediaInfo * pMediaInfo)1305 NLM_EXTERN Int4 DDV_AddMediaInfo
1306 (DDV_ColorGlobal *pColorGlobal, DDV_MediaInfo *pMediaInfo)
1307 {
1308     if(pColorGlobal == NULL || pMediaInfo == NULL) {
1309         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_AddMediaInfo");
1310         return 0;
1311     }
1312 
1313     ValNodeAddPointer(&pColorGlobal->pvnMediaInfo, 0, pMediaInfo);
1314     if(pMediaInfo->Id.sip != NULL) B_Insert(pColorGlobal->pSearchMI,
1315         (void *)pMediaInfo->Id.sip, (void *) pMediaInfo);
1316     else B_Insert(pColorGlobal->pSearchMIRow,
1317         (void *)&pMediaInfo->Id.lRow, (void *) pMediaInfo);
1318     return 1;
1319 }
1320 
1321 /*****************************************************************************
1322 *
1323 *   Given a sip OR lRow, return the associated DDV_MediaInfo.
1324 *
1325 *****************************************************************************/
1326 
DDV_GetMediaInfo(DDV_ColorGlobal * pColorGlobal,SeqId * sip,Int4 lRow)1327 NLM_EXTERN DDV_MediaInfo * DDV_GetMediaInfo
1328 (DDV_ColorGlobal *pColorGlobal, SeqId * sip, Int4 lRow)
1329 {
1330     DDV_MediaInfo *pMediaInfo = NULL;
1331 
1332     if(pColorGlobal == NULL || (sip == NULL && lRow <= 0) ||
1333         (sip != NULL && lRow > 0) ) {
1334         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_GetMediaInfo");
1335         return NULL;
1336     }
1337 
1338     if(sip != NULL)
1339         pMediaInfo = (DDV_MediaInfo *)B_GetBag(pColorGlobal->pSearchMI,
1340             (void *)sip);
1341     else
1342         pMediaInfo = (DDV_MediaInfo *)B_GetBag(pColorGlobal->pSearchMIRow,
1343             (void *)&lRow);
1344 
1345     if(pMediaInfo == NULL) {
1346         pMediaInfo = DDV_NewMediaInfo(sip, lRow, NULL, TRUE);
1347         if(pMediaInfo == NULL) {
1348             ErrPostEx(SEV_ERROR, 0, 0, "No MediaInfo in DDV_GetMediaInfo");
1349             return NULL;
1350         }
1351         DDV_AddMediaInfo(pColorGlobal, pMediaInfo);
1352     }
1353 
1354     return pMediaInfo;
1355 }
1356 
1357 /*****************************************************************************
1358 *
1359 *   Given an sip OR lRow, return the visible state.
1360 *
1361 *****************************************************************************/
1362 
DDV_IsVisible(DDV_ColorGlobal * pColorGlobal,SeqId * sip,Int4 lRow)1363 NLM_EXTERN Boolean DDV_IsVisible
1364 (DDV_ColorGlobal *pColorGlobal, SeqId *sip, Int4 lRow)
1365 {
1366     DDV_MediaInfo *pMediaInfo;
1367 
1368     if(pColorGlobal == NULL || (sip == NULL && lRow <= 0) ||
1369         (sip != NULL && lRow > 0 )) {
1370         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_IsVisible");
1371         return TRUE;
1372     }
1373 
1374     pMediaInfo = DDV_GetMediaInfo(pColorGlobal, sip, lRow);
1375     if(pMediaInfo == NULL) return FALSE;
1376 
1377     return pMediaInfo->fVisible;
1378 }
1379 
1380 /*****************************************************************************
1381 *
1382 *   Set the visible state (fVisible) of a sip OR lRow.
1383 *   Returns 1 on success, 0 on failure.
1384 *
1385 *****************************************************************************/
1386 
DDV_SetVisible(DDV_ColorGlobal * pColorGlobal,SeqId * sip,Int4 lRow,Boolean fVisible)1387 NLM_EXTERN Int4 DDV_SetVisible
1388 (DDV_ColorGlobal *pColorGlobal, SeqId *sip, Int4 lRow, Boolean fVisible)
1389 {
1390     DDV_MediaInfo *pMediaInfo;
1391 
1392     if(pColorGlobal == NULL || (sip == NULL && lRow <= 0) ||
1393         (sip != NULL && lRow > 0)) {
1394         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_SetVisible");
1395         return 0;
1396     }
1397 
1398     pMediaInfo = DDV_GetMediaInfo(pColorGlobal, sip, lRow);
1399     if(pMediaInfo == NULL) return 0;
1400 
1401     pMediaInfo->fVisible = fVisible;
1402 
1403     return 1;
1404 }
1405 
1406 /*****************************************************************************
1407 *
1408 *   Retrieve a color for a sip OR lRow at lPosition in.
1409 *   Returns a DDV_ColorCell containing the color.  NULL on failure.
1410 *
1411 *   The DDV_ColorCell returned is read only.
1412 *
1413 *****************************************************************************/
1414 
DDV_GetColor(DDV_ColorGlobal * pColorGlobal,SeqId * sip,Int4 lRow,Int4 lPosition)1415 NLM_EXTERN DDV_ColorCell * DDV_GetColor
1416 (DDV_ColorGlobal *pColorGlobal, SeqId *sip, Int4 lRow, Int4 lPosition)
1417 {
1418     DDV_MediaInfo *pMediaInfo;
1419     DDV_Color *pColor;
1420     DDV_ColorCell *pColorCell = NULL;
1421     DDV_Range TestRange;
1422     Int4 retval = 0;
1423 
1424 
1425     if(pColorGlobal == NULL || (sip == NULL && lRow <= 0) ||
1426         (sip != NULL && lRow > 0)) {
1427         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_GetColor");
1428         return NULL;
1429     }
1430 
1431     pMediaInfo = DDV_GetMediaInfo(pColorGlobal, sip, lRow);
1432     if(pMediaInfo == NULL) return NULL;
1433 
1434     TestRange.lFrom = lPosition;
1435     TestRange.lTo = lPosition;
1436     pColor = (DDV_Color *)B_GetBag(pMediaInfo->pSearchColor,
1437             (void *)&TestRange);
1438     if(pColor != NULL) pColorCell =
1439         DDV_GetCellByPosition(pColor, lPosition);
1440 
1441     if(pColorCell == NULL) {
1442         DDV_DefaultMediaInfoByLen(pColorGlobal, sip, lRow, lPosition,
1443             lPosition + DDV_BUFSIZE);
1444         pColorCell = DDV_GetColor(pColorGlobal, sip, lRow, lPosition);
1445     }
1446     return pColorCell;
1447 
1448 }
1449 
1450 /*****************************************************************************
1451 *
1452 *   Set a color for in a DDV_MediaInfo at lPosition.  The color set is
1453 *   pColorCell.
1454 *   Returns 1 on success, 0 on failure.
1455 *
1456 *****************************************************************************/
1457 
DDV_SetColorInMediaInfo(DDV_ColorGlobal * pColorGlobal,DDV_MediaInfo * pMediaInfo,Int4 lPosition,DDV_ColorCell * pColorCell)1458 NLM_EXTERN Int4 DDV_SetColorInMediaInfo
1459 (DDV_ColorGlobal *pColorGlobal,
1460  DDV_MediaInfo *pMediaInfo, Int4 lPosition, DDV_ColorCell *pColorCell)
1461 {
1462     ValNode *pvn;
1463     DDV_Color *pColor;
1464     Int4 retval = 0;
1465     DDV_Range TestRange;
1466 
1467     if(pColorGlobal == NULL || pColorCell == NULL || pMediaInfo == NULL ) {
1468         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_SetColorInMediaInfo");
1469         return 0;
1470     }
1471 
1472     for(pvn = pMediaInfo->pvnColor; pvn != NULL; pvn = pvn->next) {
1473         pColor = (DDV_Color *)pvn->data.ptrvalue;
1474         retval = DDV_SetCellByPosition(pColor, lPosition, pColorCell);
1475         if(retval) break;
1476     }
1477     TestRange.lFrom = lPosition;
1478     TestRange.lTo = lPosition;
1479     pColor = (DDV_Color *)B_GetBag(pMediaInfo->pSearchColor,
1480             (void *)&TestRange);
1481     if(pColor != NULL) retval =
1482         DDV_SetCellByPosition(pColor, lPosition, pColorCell);
1483 
1484     if(retval) DDV_RequestColor(&pColorGlobal->Palette, pColorCell);
1485     else {
1486         DDV_DefaultMediaInfoByLen(pColorGlobal, pMediaInfo->Id.sip,
1487             pMediaInfo->Id.lRow, lPosition, lPosition + DDV_BUFSIZE);
1488         retval = DDV_SetColorInMediaInfo(pColorGlobal, pMediaInfo, lPosition,
1489             pColorCell);
1490         if(retval) DDV_RequestColor(&pColorGlobal->Palette, pColorCell);
1491     }
1492 
1493     return retval;
1494 }
1495 
1496 /*****************************************************************************
1497 *
1498 *   Set a color for a sip OR lRow at lPosition.  The color set is
1499 *   pColorCell.  Makes a copy of pColorCell.
1500 *   Returns 1 on success, 0 on failure.
1501 *
1502 *****************************************************************************/
1503 
DDV_SetColor(DDV_ColorGlobal * pColorGlobal,SeqId * sip,Int4 lRow,Int4 lPosition,DDV_ColorCell * pColorCell)1504 NLM_EXTERN Int4 DDV_SetColor
1505 (DDV_ColorGlobal *pColorGlobal, SeqId *sip, Int4 lRow,
1506  Int4 lPosition, DDV_ColorCell *pColorCell)
1507 {
1508     DDV_MediaInfo *pMediaInfo;
1509 
1510     if(pColorGlobal == NULL || pColorCell == NULL ||
1511        (sip == NULL && lRow <= 0) ||
1512        (sip != NULL && lRow > 0)) {
1513         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_SetColor");
1514         return 0;
1515     }
1516 
1517     pMediaInfo = DDV_GetMediaInfo(pColorGlobal, sip, lRow);
1518     if(pMediaInfo == NULL) return 0;
1519 
1520     return
1521       DDV_SetColorInMediaInfo(pColorGlobal, pMediaInfo, lPosition, pColorCell);
1522 
1523 }
1524 
1525 /*****************************************************************************
1526 *
1527 *   Set a color for a sip OR lRow at lPosition.
1528 *   Uses Uint1's for color input.
1529 *   Returns 1 on success, 0 on failure.
1530 *
1531 *****************************************************************************/
1532 
DDV_SetColorbyColor(DDV_ColorGlobal * pColorGlobal,SeqId * sip,Int4 lRow,Int4 lPosition,Uint1 red,Uint1 green,Uint1 blue)1533 NLM_EXTERN Int4 DDV_SetColorbyColor
1534 (DDV_ColorGlobal *pColorGlobal, SeqId *sip, Int4 lRow, Int4 lPosition,
1535  Uint1 red, Uint1 green, Uint1 blue)
1536 {
1537     DDV_ColorCell ColorCell;
1538 
1539     if(pColorGlobal == NULL || (sip == NULL && lRow <= 0) ||
1540         (sip != NULL && lRow > 0)) {
1541         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_SetColorbyColor");
1542         return 0;
1543     }
1544 
1545 
1546     ColorCell.rgb[0] = red;
1547     ColorCell.rgb[1] = green;
1548     ColorCell.rgb[2] = blue;
1549 
1550     return DDV_SetColor(pColorGlobal, sip, lRow, lPosition, &ColorCell);
1551 }
1552 
1553 
1554 /*****************************************************************************
1555 *
1556 *   Calls the color functions.  pData is for user data.
1557 *
1558 *   Returns 1 on success, 0 on failure.
1559 *
1560 *   Note that this only updates the colors.  It doesn't tell the applications
1561 *   to paint the colors.  This is done through OM_MSG_SETCOLOR with a new
1562 *   regiontype TBD.
1563 *
1564 *   fColorByMaster in DDV_ColorGlobal (i.e. color all sequence like the master
1565 *   sequence) is NOT handled by this function.  This
1566 *   is because this code has, in general, no idea if it is using alignment
1567 *   coordinates or alignment coordinates.  To color by master, the user must
1568 *   register a specific function to do this.
1569 *
1570 *   lFrom and lTo are the range coloring is done over.
1571 *
1572 *****************************************************************************/
1573 
DDV_ColorExecute(DDV_ColorGlobal * pColorGlobal,void * pData,DDV_Range * pRange,char * szName)1574 NLM_EXTERN Int4 DDV_ColorExecute
1575 (DDV_ColorGlobal *pColorGlobal, void * pData, DDV_Range *pRange, char *szName)
1576 {
1577     DDV_ColorQueue  *pcq, *pcqPrev;
1578     ValNode *pvn, *pvnPrev, *pvnPrevPrev, *pvnTemp;
1579     Int4 lCount = 0, i;
1580 
1581     if(pColorGlobal == NULL) {
1582         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_ColorExecute");
1583         return 0;
1584     }
1585 
1586     DDV_FreePalette(&pColorGlobal->Palette);
1587 
1588     /* color by default? */
1589     if(pColorGlobal->fDefaultColor) DDV_DefaultColor(pColorGlobal,
1590         NULL, NULL);
1591 
1592     /* look for an override */
1593     for(pvn = pColorGlobal->pvnColorQueue; pvn != NULL; pvn = pvn->next) {
1594         pcq = (DDV_ColorQueue *)pvn->data.ptrvalue;
1595         if(pcq->fOverride) {  /* this function is king */
1596             (*pcq->pfnColorFunc)(pColorGlobal, pData, pRange);
1597         }
1598         lCount++;
1599     }
1600 
1601     /* sort the color functions by priority */
1602 
1603     for(i = 0; i < lCount - 1; i++) {
1604         for(pvnPrevPrev = NULL,
1605             pvnPrev = pColorGlobal->pvnColorQueue,
1606             pvn = pColorGlobal->pvnColorQueue->next;
1607             pvn != NULL;
1608             pvnPrevPrev = pvnPrev,
1609             pvnPrev = pvn,
1610             pvn = pvn->next) {
1611 
1612             pcq = (DDV_ColorQueue *)pvn->data.ptrvalue;
1613             pcqPrev = (DDV_ColorQueue *)pvnPrev->data.ptrvalue;
1614 
1615             if(pcq->lPriority < pcqPrev->lPriority) {
1616                 pvnTemp = pvn->next;
1617                 pvn->next = pvnPrev;
1618                 pvnPrev->next = pvnTemp;
1619                 if(pvnPrevPrev != NULL) pvnPrevPrev->next = pvn;
1620                 else pColorGlobal->pvnColorQueue = pvn;
1621                 pvnTemp = pvnPrev;
1622                 pvnPrev = pvn;
1623                 pvn = pvnTemp;
1624             }
1625         }
1626     }
1627 
1628     /* call the color functions in priority order */
1629     for(pvn = pColorGlobal->pvnColorQueue; pvn != NULL; pvn = pvn->next) {
1630         pcq = (DDV_ColorQueue *)pvn->data.ptrvalue;
1631         if(StrCmp(szName, pcq->szName) == 0)
1632             (*pcq->pfnColorFunc)(pColorGlobal, pData, pRange);
1633     }
1634 
1635     return 1;
1636 }
1637 
1638 /*****************************************************************************
1639 *
1640 *   Callback for coloring all ColorCells by the default color.
1641 *
1642 *
1643 *****************************************************************************/
1644 
DDV_DefaultColor(DDV_ColorGlobal * pColorGlobal,void * pData,DDV_Range * pRange)1645 NLM_EXTERN void DDV_DefaultColor
1646 (DDV_ColorGlobal *pColorGlobal, void *pData, DDV_Range *pRange)
1647 {
1648     ValNode *pvnMediaInfo, *pvnColor;
1649     DDV_MediaInfo *pMediaInfo;
1650     DDV_Color *pColor;
1651     DDV_ColorCell *pccDefault;
1652     Int4 i;
1653 
1654     if(pColorGlobal == NULL) {
1655         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_DefaultColor");
1656         return;
1657     }
1658 
1659     pccDefault = DDV_SearchColorCellbyName(pColorGlobal->pvnSpecialColors,
1660         "Default");
1661 
1662     if(pColorGlobal == NULL) {
1663         ErrPostEx(SEV_ERROR, 0, 0, "DDV_DefaultColor: no default color");
1664         return;
1665     }
1666 
1667     for(pvnMediaInfo = pColorGlobal->pvnMediaInfo; pvnMediaInfo != NULL;
1668         pvnMediaInfo = pvnMediaInfo->next) {
1669         pMediaInfo = (DDV_MediaInfo *)pvnMediaInfo->data.ptrvalue;
1670         for(pvnColor = pMediaInfo->pvnColor; pvnColor != NULL;
1671             pvnColor = pvnColor->next) {
1672             pColor = (DDV_Color *)pvnColor->data.ptrvalue;
1673                 for(i = 0; i <= pColor->Range.lTo - pColor->Range.lFrom; i++)
1674                     DDV_CopyColorCell(&pColor->pColorCell[i], pccDefault);
1675         }
1676     }
1677         /* put the default color on palette */
1678     DDV_RequestColor(&pColorGlobal->Palette, pccDefault);
1679     return;
1680 }
1681 /*****************************************************************************
1682 *
1683 *   Clears all the colors (only the color) to the default
1684 *
1685 *****************************************************************************/
1686 
DDV_Clear2Default(DDV_ColorGlobal * pColorGlobal)1687 NLM_EXTERN Int4 DDV_Clear2Default(DDV_ColorGlobal *pColorGlobal)
1688 {
1689     ValNode *pvn, *pvnColor;
1690     DDV_MediaInfo *pMediaInfo;
1691     DDV_ColorCell *pColorCell;
1692     DDV_Color *pColor;
1693     Int4 i;
1694 
1695     if(pColorGlobal == NULL) {
1696         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_Clear2Default");
1697         return 0;
1698     }
1699 
1700     pColorCell = DDV_SearchColorCellbyName(pColorGlobal->pvnSpecialColors,
1701                 "Default");
1702     if(pColorCell == NULL) return 0;
1703 
1704     for(pvn = pColorGlobal->pvnMediaInfo ; pvn != NULL; pvn = pvn->next) {
1705         pMediaInfo = (DDV_MediaInfo *)pvn->data.ptrvalue;
1706         for(pvnColor = pMediaInfo->pvnColor; pvnColor != NULL;
1707         pvnColor = pvnColor->next) {
1708             pColor = (DDV_Color *)pvnColor->data.ptrvalue;
1709             if (pColor == NULL) continue;
1710 
1711             for(i = 0; i <= pColor->Range.lTo - pColor->Range.lFrom; i++) {
1712                 pColor->pColorCell[i].rgb[0] = pColorCell->rgb[0];
1713                 pColor->pColorCell[i].rgb[1] = pColorCell->rgb[1];
1714                 pColor->pColorCell[i].rgb[2] = pColorCell->rgb[2];
1715             }
1716         }
1717     }
1718     return 1;
1719 }
1720 
1721 /*****************************************************************************
1722 *
1723 *   Adds a DDV_ColorQueue to pColorGlobal
1724 *   Returns 1 on success, 0 on failure.
1725 *
1726 *****************************************************************************/
1727 
DDV_AddColorFunc(DDV_ColorGlobal * pColorGlobal,DDV_ColorQueue * pColorQueue)1728 NLM_EXTERN Int4 DDV_AddColorFunc
1729 (DDV_ColorGlobal *pColorGlobal, DDV_ColorQueue *pColorQueue)
1730 {
1731     if(pColorGlobal == NULL || pColorQueue == NULL) {
1732         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_AddColorQueue");
1733         return 0;
1734     }
1735 
1736     ValNodeAddPointer(&pColorGlobal->pvnColorQueue, 0, pColorQueue);
1737     return 1;
1738 }
1739 
1740 /*****************************************************************************
1741 *
1742 *   Deletes the given DDV_ColorFunc out of the ColorQueue
1743 *   Returns number deleted on success, 0 on failure.
1744 *
1745 *****************************************************************************/
1746 
DDV_DeleteColorFunc(DDV_ColorGlobal * pColorGlobal,DDV_ColorFunc pfnColorFunc)1747 NLM_EXTERN Int4 DDV_DeleteColorFunc
1748 (DDV_ColorGlobal *pColorGlobal, DDV_ColorFunc  pfnColorFunc)
1749 {
1750     ValNode *pvn, *pvnPrevious = NULL;
1751     DDV_ColorQueue *pColorQueue;
1752     Int4 retval = 0;
1753 
1754     if(pColorGlobal == NULL || pfnColorFunc == NULL) {
1755         ErrPostEx(SEV_ERROR, 0, 0, "Invalid call on DDV_DeleteColorQueue");
1756         return 0;
1757     }
1758 
1759     for(pvn = pColorGlobal->pvnColorQueue; pvn != NULL; pvn = pvn->next) {
1760         pColorQueue = (DDV_ColorQueue *)pvn->data.ptrvalue;
1761         if(pColorQueue->pfnColorFunc == pfnColorFunc) {
1762             DDV_DeleteColorQueue(pColorQueue);
1763             retval++;
1764             if(pvnPrevious != NULL) {  /* splice out node */
1765                 pvnPrevious->next = pvn->next;
1766             }
1767             else {  /* if first node */
1768                 pColorGlobal->pvnColorQueue = pvn->next;
1769             }
1770             MemFree(pvn);
1771             break;
1772         }
1773         pvnPrevious = pvn;
1774     }
1775 
1776     return retval;
1777 }
1778 
1779 /*****************************************************************************
1780 
1781 Function: DDV_AddColorGlobal()
1782 
1783 Purpose: Adds a DDV_ColorGlobal to an entity as userdata.
1784 
1785 Parameters: pColorGlobal, the OMProcControlPtr.
1786             pObject, pointer to the entity.
1787 
1788 Returns: 1 on success, 0 on failure
1789 
1790 Notes: - will only add to objects registered with the object manager
1791        - adds a free function to the userdata
1792        - the DDV_ColorGlobal userdata is identified by proc type
1793          OMPROC_COLORMGR
1794 
1795 *****************************************************************************/
1796 
DDV_FreeUserData(void * pColorGlobal)1797 static void * LIBCALLBACK DDV_FreeUserData(void *pColorGlobal)
1798 {
1799     if(pColorGlobal == NULL) return NULL;
1800     DDV_DeleteColorGlobal((DDV_ColorGlobal *)pColorGlobal);
1801     return NULL;
1802 }
1803 
1804 
DDV_AddColorGlobal(DDV_ColorGlobal * pColorGlobal,void * pObject)1805 NLM_EXTERN Int4 DDV_AddColorGlobal
1806 (DDV_ColorGlobal *pColorGlobal, void * pObject)
1807 {
1808     OMUserData *omudp;
1809     Uint2 entityID;
1810 
1811     if(pColorGlobal == NULL || pObject == NULL) return 0;
1812     entityID = ObjMgrGetEntityIDForPointer(pObject);
1813     if(entityID == 0) return 0;
1814     omudp = ObjMgrAddUserData (entityID, 0, OMPROC_COLORMGR, 0);
1815     if(omudp == NULL) return 0;
1816     omudp->userdata.ptrvalue = pColorGlobal;
1817     omudp->freefunc = DDV_FreeUserData;
1818 
1819     return 1;
1820 }
1821 
1822 
1823 /*****************************************************************************
1824 
1825 Function: DDV_GetColorGlobal()
1826 
1827 Purpose: Returns the DDV_ColorGlobal attached to an entity as userdata.
1828 
1829 Parameters: pObject, pointer to the entity.
1830 
1831 Returns: DDV_ColorGlobal * on success, NULL on failure
1832 
1833 *****************************************************************************/
1834 
DDV_GetColorGlobal(void * pObject)1835 NLM_EXTERN DDV_ColorGlobal * DDV_GetColorGlobal(void * pObject)
1836 {
1837     OMUserData *omudp;
1838     Uint2 entityID;
1839 
1840     if(pObject == NULL) return NULL;
1841     entityID = ObjMgrGetEntityIDForPointer(pObject);
1842     if(entityID == 0) return NULL;
1843     omudp = ObjMgrGetUserData(entityID, 0, OMPROC_COLORMGR, 0);
1844 
1845     if(omudp == NULL) return NULL;
1846     return (DDV_ColorGlobal *)omudp->userdata.ptrvalue;
1847 }
1848 
1849 
1850 /*****************************************************************************
1851 
1852 Function: DDV_GetColorGlobalEx()
1853 
1854 Purpose: Returns the DDV_ColorGlobal attached to an entity as userdata. If
1855          none is attached, create one and attach it.
1856 
1857 Parameters: pObject, pointer to the entity.
1858 
1859 Returns: DDV_ColorGlobal * on success, NULL on failure
1860 
1861 *****************************************************************************/
1862 
DDV_GetColorGlobalEx(void * pObject)1863 NLM_EXTERN DDV_ColorGlobal * DDV_GetColorGlobalEx(void * pObject)
1864 {
1865     DDV_ColorGlobal *pColorGlobal;
1866 
1867     pColorGlobal = DDV_GetColorGlobal(pObject);
1868     if (pColorGlobal != NULL) return pColorGlobal;
1869 
1870     pColorGlobal = DDV_CreateColorGlobal(FALSE, pObject);
1871     if(pColorGlobal == NULL) return NULL;
1872 
1873     if(DDV_AddColorGlobal(pColorGlobal, pObject)) return pColorGlobal;
1874 
1875     MemFree(pColorGlobal);
1876     return NULL;
1877 }
1878