3 * sushivision copyright (C) 2006-2007 Monty <monty@xiph.org>
5 * sushivision is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * sushivision is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with sushivision; see the file COPYING. If not, write to the
17 * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
30 #include <sys/types.h>
35 // the background 'plane' is handled a little differently from the
36 // other planes. The bg plane doesn't bother with functions embedded
37 // in the plane struct. They're simply called directly by the panel
40 void bg_recompute_setup(sv_panel_t
*p
){
41 sv_planebg_t
*pl
= p
->bg
;
43 pl
->image_x
= _sv_dim_panelscale(payload
+ x_dim
, p
->w
, 0);
44 pl
->image_y
= _sv_dim_panelscale(payload
+ y_dim
, p
->h
, 1);
47 pl
->expose_bottom
= -1;
50 void bg_resize(sv_panel_t
*p
){
51 sv_planebg_t
*pl
= p
->bg
;
53 if(pl
->image_status_size
!= p
->h
){
54 unsigned char *n
=NULL
;
55 unsigned char *o
=NULL
;
56 int serialno
= p
->comp_serialno
;
58 pthread_mutex_unlock(pl
->status_m
);
59 n
= calloc(p
->h
,sizeof(*n
));
60 pthread_mutex_lock(pl
->status_m
);
61 if(serialno
== p
->comp_serialno
){
66 pthread_mutex_unlock(pl
->status_m
);
69 pthread_mutex_lock(pl
->status_m
);
70 return STATUS_WORKING
;
76 int bg_legend(sv_panel_t
*p
){
77 sv_planebg_t
*bg
= &p
->bg
;
78 sv_plot_t
*plot
= p
->plot
;
79 int serialno
= p
->legend_serialno
;
86 pthread_mutex_unlock(p
->status_m
);
87 _sv_plot_legend_clear(plot
);
88 pthread_mutex_lock(p
->status_m
);
89 if(serialno
!= p
->legend_serialno
)return STATUS_WORKING
;
91 // potentially add each dimension to the legend; add axis
92 // dimensions only if crosshairs are active
94 // display decimal precision relative to display scales
95 if(3-_sv_scalespace_decimal_exponent(&bg
->image_x
) > depth
)
96 depth
= 3-_sv_scalespace_decimal_exponent(&bg
->image_x
);
97 if(3-_sv_scalespace_decimal_exponent(&bg
->image_y
) > depth
)
98 depth
= 3-_sv_scalespace_decimal_exponent(&bg
->image_y
);
99 for(i
=0;i
<p
->dimensions
;i
++){
100 sv_dim_data_t
*d
= p
->dim_data
+i
;
102 for(j
=0;j
<p
->axes
;j
++)
103 if(p
->axis_dims
[j
] != i
&&
104 (j
<=2 || !p
->cross_active
)){
110 snprintf(buffer
,320,"%s = %+.*f",
114 pthread_mutex_unlock(p
->status_m
);
115 _sv_plot_legend_add(plot
,buffer
);
116 pthread_mutex_lock(p
->status_m
);
117 if(serialno
!= p
->legend_serialno
)return STATUS_WORKING
;
121 // add each active objective plane to the legend
122 // choose the value under the crosshairs
123 if(plot
->cross_active
){
124 // ask each plane for entries...
126 for(i
=0;i
<p
->planes
;i
++){
127 int retflag
=p
->plane_list
[i
]->legend(p
->plane_list
[i
],buffer
,320);
128 pthread_mutex_unlock(p
->status_m
);
129 if(retflag
&& !firstflag
)
130 _sv_plot_legend_add(plot
,NULL
);
132 _sv_plot_legend_add(plot
,buffer
);
133 pthread_mutex_lock(p
->status_m
);
134 if(serialno
!= p
->legend_serialno
)return STATUS_WORKING
;
139 pthread_mutex_unlock(p
->status_m
);
140 _sv_plot_draw_legend(plot
);
141 pthread_mutex_lock(p
->status_m
);
142 if(serialno
!= p
->legend_serialno
)return STATUS_WORKING
;
147 int bg_scale(sv_panel_t
*p
){
148 pthread_mutex_unlock(p
->status_m
);
149 _sv_plot_draw_scales(p
->graph
);
150 pthread_mutex_lock(p
->status_m
);
153 static void render_checks(sv_ucolor_t
*c
, int w
, int y
){
154 /* default checked background */
155 /* 16x16 'mid-checks' */
158 int phase
= (y
>>4)&1;
160 u_int32_t phaseval
= 0xff505050UL
;
161 if(phase
) phaseval
= 0xff808080UL
;
162 for(j
=0;j
<16 && x
<w
;j
++,x
++)
168 int bg_render(sv_panel_t
*p
){
169 sv_planebg_t
*bg
= &p
->bg
;
170 sv_plot_t
*plot
= p
->plot
;
171 int serialno
= p
->compute_serialno
;
181 if(bg
->bg
[0]=='#' && strlen(bg
->bg
)==7){
183 r
= (toupper(bg
->bg
[1])-65)*.0625 + (toupper(bg
->bg
[2])-65)*.00390625;
184 g
= (toupper(bg
->bg
[3])-65)*.0625 + (toupper(bg
->bg
[4])-65)*.00390625;
185 b
= (toupper(bg
->bg
[5])-65)*.0625 + (toupper(bg
->bg
[6])-65)*.00390625;
188 // look for a line that needs love
190 y
= bg
->image_nextline
;
191 bg
->image_nextline
++;
192 if(bg
->image_nextline
>=h
)bg
->image_nextline
=0;
194 if(bg
->image_flags
[y
]){
195 sv_scalespace_t ix
= bg
->image_x
;
196 sv_scalespace_t iy
= bg
->image_y
;
199 bg
->image_flags
[i
]=0;
200 bg
->image_outstanding
++;
202 pthread_mutex_unlock(p
->status_m
);
204 // bg renders a line at a time primarily as a concession to the 2d panels.
206 render_checks(line
,w
,y
);
208 u_int32_t val
= 0xff000000 | (r
<<16) | (g
<<8) | (b
);
209 for(i
=0;i
<w
;i
++)line
[i
]=val
;
212 // grab line from panels in order. Mix using plane native mix function
213 for(i
=0;i
<p
->planes
;i
++){
214 sv_ucolor_t
*mix(sv_ucolor_t
, sv_ucolor_t
) = p
->plane_list
[i
]->c
.mix
;
215 sv_ucolor_t
*pline
= p
->plane_list
[i
]->c
.image
[y
*w
]l
217 line
[j
] = mix(pline
[j
],line
[j
]);
220 pthread_mutex_lock(pl
->status_m
);
222 if(p
->compute_serialno
== serialno
){
223 bg
->image_outstanding
--;
225 plot_write_line(p
->plot
,line
);
227 //invalidate rectangle for expose
228 if(bg
->expose_top
== -1 || bg
->expose_top
> y
)
230 if(bg
->expose_bottom
== -1 || bg
->expose_bottom
< y
)
233 return STATUS_WORKING
;
237 if(bg
->image_outstanding
) return STATUS_BUSY
;
241 int bg_expose(sv_panel_t
*p
){
242 sv_planebg_t
*bg
= &p
->bg
;
243 if(pl
->expose_top
!= -1){
245 r
.y
= bg
->expose_top
;
246 r
.h
= bg
->expose_bottom
- bg
->expose_top
+1;
251 pl
->expose_bottom
= -1;
252 pthread_mutex_unlock(p
->status_m
);
254 // the only place worker thread should ever touch the GDK lock
256 gdk_invalidate_rectangle(GTK_WIDGET(p
->plot
),&r
,FALSE
);
264 sv_planebg_t
*sv_planebg_new(sv_panel_t
*p
){
265 sv_planebg_t
*ret
= calloc(1, sizeof(*ret
));
268 ret
->bg
= strdup("checks");