📄 scope_horiz.c
字号:
horiz->thread_period_ns = thread->period; /* calc max possible mult (to keep sample period <= 1 sec */ max_mult = (1000000000 / horiz->thread_period_ns); if (max_mult > 1000) { max_mult = 1000; } if (ctrl_shm->mult > max_mult) { ctrl_shm->mult = max_mult; } calc_horiz_scaling(); refresh_horiz_info(); return 0;}static void deactivate_sample_thread(void){ scope_horiz_t *horiz; /* get a pointer to the horiz data structure */ horiz = &(ctrl_usr->horiz); /* check for old sample thread */ if (ctrl_shm->thread_name[0] != '\0') { /* disconnect sample funct from old thread */ hal_del_funct_from_thread("scope.sample", ctrl_shm->thread_name); /* clear thread name from shared memory */ ctrl_shm->thread_name[0] = '\0'; }}static int activate_sample_thread(void){ scope_horiz_t *horiz; int rv; /* get a pointer to the horiz data structure */ horiz = &(ctrl_usr->horiz); /* has a thread name been specified? */ if (horiz->thread_name == NULL) { return -1; } /* shut down any prior thread */ /* (probably already sone, but just making sure */ deactivate_sample_thread(); /* hook sampling function to thread */ rv = hal_add_funct_to_thread("scope.sample", horiz->thread_name, -1); if ( rv < 0 ) { return rv; } /* store name of thread in shared memory */ strncpy(ctrl_shm->thread_name, horiz->thread_name, HAL_NAME_LEN + 1); /* give the code some time to get started */ ctrl_shm->watchdog = 0; invalidate_all_channels(); request_display_refresh(1); return 0;}static void mult_changed(GtkAdjustment * adj, gpointer gdata){ scope_horiz_t *horiz; int value; /* point to GUI widgets */ horiz = &(ctrl_usr->horiz); /* get value from spinbutton */ value = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(horiz->mult_spinbutton)); /* set it */ set_horiz_mult(value); /* set spinbutton to new value */ gtk_spin_button_set_value(GTK_SPIN_BUTTON(horiz->mult_spinbutton), ctrl_shm->mult);}static void zoom_changed(GtkAdjustment * adj, gpointer gdata){ set_horiz_zoom(adj->value);}static void pos_changed(GtkAdjustment * adj, gpointer gdata){ set_horiz_pos(adj->value / 1000.0);}static void rec_len_button(GtkWidget * widget, gpointer gdata){ int retval; char *title, *msg; if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) != TRUE) { /* not pressed, ignore it */ return; } retval = set_rec_len((int)gdata); if (retval < 0) { /* too many channels already enabled */ title = "Not enough channels"; msg = "This record length cannot handle the channels\n" "that are currently enabled. Pick a shorter\n" "record length that supports more channels."; dialog_generic_msg(ctrl_usr->main_win, title, msg, "OK", NULL, NULL, NULL); }}static void calc_horiz_scaling(void){ scope_horiz_t *horiz; float total_rec_time; long int desired_usec_per_div, actual_usec_per_div; int n, decade, sub_decade; horiz = &(ctrl_usr->horiz); if (horiz->thread_name == NULL) { horiz->thread_period_ns = 0; ctrl_shm->mult = 1; horiz->sample_period_ns = 0; horiz->sample_period = 0.0; horiz->disp_scale = 0.0; return; } horiz->sample_period_ns = horiz->thread_period_ns * ctrl_shm->mult; horiz->sample_period = horiz->sample_period_ns / 1000000000.0; total_rec_time = ctrl_shm->rec_len * horiz->sample_period; if (total_rec_time < 0.000010) { /* out of range, set to 1uS per div */ horiz->disp_scale = 0.000001; return; } desired_usec_per_div = (total_rec_time / 10.0) * 1000000.0; /* find scaling to display entire record */ decade = 1; sub_decade = 1; actual_usec_per_div = decade * sub_decade; while (actual_usec_per_div < desired_usec_per_div) { if (sub_decade == 1) { sub_decade = 2; } else if (sub_decade == 2) { sub_decade = 5; } else { sub_decade = 1; decade *= 10; } actual_usec_per_div = decade * sub_decade; } /* now correct for zoom factor */ for (n = 1; n < horiz->zoom_setting; n++) { if (sub_decade == 1) { sub_decade = 5; decade /= 10; } else if (sub_decade == 2) { sub_decade = 1; } else { /* sub_decade == 5 */ sub_decade = 2; } } if (decade == 0) { /* underflow from zoom, set to minimum */ decade = 1; sub_decade = 1; } actual_usec_per_div = decade * sub_decade; /* convert to floating point */ horiz->disp_scale = actual_usec_per_div / 1000000.0;}static void refresh_horiz_info(void){ scope_horiz_t *horiz; gchar *name; static gchar tmp[BUFLEN + 1], rate[BUFLEN + 1], period[BUFLEN + 1]; static gchar scale[BUFLEN + 1], rec_len[BUFLEN + 1], msg[BUFLEN + 1]; float freqval; horiz = &(ctrl_usr->horiz); if (horiz->thread_name == NULL) { name = "----"; } else { name = horiz->thread_name; } if (horiz->disp_scale == 0.0) { snprintf(scale, BUFLEN, "----"); } else { format_time_value(tmp, BUFLEN, horiz->disp_scale); snprintf(scale, BUFLEN, "%s\nper div", tmp); } if (horiz->sample_period == 0.0) { snprintf(period, BUFLEN, "----"); snprintf(rate, BUFLEN, "----"); } else { format_time_value(period, BUFLEN, horiz->sample_period); freqval = 1.0 / horiz->sample_period; format_freq_value(rate, BUFLEN, freqval); } if (ctrl_shm->rec_len == 0) { snprintf(rec_len, BUFLEN, "----"); } else { snprintf(rec_len, BUFLEN, "%d", ctrl_shm->rec_len); } snprintf(msg, BUFLEN, "%s samples\nat %s", rec_len, rate); gtk_label_set_text_if(horiz->thread_name_label, name); gtk_label_set_text_if(horiz->sample_rate_label, rate); gtk_label_set_text_if(horiz->scale_label, scale); gtk_label_set_text_if(horiz->sample_period_label, period); gtk_label_set_text_if(horiz->record_label, msg); refresh_state_info();}static void refresh_pos_disp(void){ scope_horiz_t *horiz; GdkDrawable *w; int width, height, depth; GdkGC *c; float disp_center, disp_start, disp_end; float rec_start, rec_curr, rec_end; float min, max, span, scale; int pre_trig; int rec_line_y, rec_line_left, rec_line_right; int box_y_off, box_top, box_bot, box_right, box_left; int trig_y_off, trig_line_top, trig_line_bot, trig_line_x; int rec_curr_x; horiz = &(ctrl_usr->horiz); /* get window to local var */ w = horiz->disp_area->window; if (w == NULL) { /* window isn't visible yet, do nothing */ return; } /* create drawing context if needed */ if (horiz->disp_context == NULL) { horiz->disp_context = gdk_gc_new(w); } /* get context to local var */ c = horiz->disp_context; /* get window dimensions */ gdk_window_get_geometry(w, NULL, NULL, &width, &height, &depth); /* these are based only on window dims */ rec_line_y = (height - 1) / 2; box_y_off = rec_line_y / 2; trig_y_off = rec_line_y; trig_line_top = rec_line_y - trig_y_off; trig_line_bot = rec_line_y + trig_y_off; box_top = rec_line_y - box_y_off; box_bot = rec_line_y + box_y_off; /* these need to be calculated */ pre_trig = ctrl_shm->rec_len * ctrl_usr->trig.position; /* times relative to trigger */ rec_start = -pre_trig * horiz->sample_period; rec_end = (ctrl_shm->rec_len - pre_trig) * horiz->sample_period; rec_curr = rec_start + (ctrl_shm->samples * horiz->sample_period); disp_center = rec_start + horiz->pos_setting * (rec_end - rec_start); disp_start = disp_center - 5.0 * horiz->disp_scale; disp_end = disp_center + 5.0 * horiz->disp_scale; if (rec_start < disp_start) { min = rec_start; } else { min = disp_start; } if (rec_end > disp_end) { max = rec_end; } else { max = disp_end; } span = max - min; scale = (width - 1) / span; trig_line_x = scale * (0 - min); rec_line_left = scale * (rec_start - min); rec_line_right = scale * (rec_end - min); rec_curr_x = scale * (rec_curr - min); box_left = scale * (disp_start - min); box_right = scale * (disp_end - min); /* draw stuff */ gdk_window_clear(w); gdk_draw_line(w, c, rec_line_left, rec_line_y + 1, rec_line_left, rec_line_y - 1); gdk_draw_line(w, c, rec_line_right, rec_line_y + 1, rec_line_right, rec_line_y - 1); gdk_draw_line(w, c, rec_line_left, rec_line_y + 1, rec_line_right, rec_line_y + 1); gdk_draw_line(w, c, rec_line_left, rec_line_y - 1, rec_line_right, rec_line_y - 1); gdk_draw_line(w, c, rec_line_left, rec_line_y, rec_curr_x, rec_line_y); gdk_draw_line(w, c, trig_line_x, trig_line_top, trig_line_x, trig_line_bot); gdk_draw_line(w, c, box_left, box_top, box_right, box_top); gdk_draw_line(w, c, box_left, box_bot, box_right, box_bot); gdk_draw_line(w, c, box_left, box_top, box_left, box_bot); gdk_draw_line(w, c, box_right, box_top, box_right, box_bot);}static void format_time_value(char *buf, int buflen, float timeval){ char *units; int decimals; /* convert to nanoseconds */ timeval *= 1000000000.0; units = "nSec"; if (timeval >= 1000.0) { timeval /= 1000.0; units = "uSec"; } if (timeval >= 1000.0) { timeval /= 1000.0; units = "mSec"; } if (timeval >= 1000.0) { timeval /= 1000.0; units = "Sec"; } decimals = 2; if (timeval >= 10.0) { decimals = 1; } if (timeval >= 100.0) { decimals = 0; } snprintf(buf, buflen, "%0.*f %s", decimals, timeval, units);}static void format_freq_value(char *buf, int buflen, float freqval){ char *units; int decimals; units = "Hz"; if (freqval >= 1000.0) { freqval /= 1000.0; units = "KHz"; } if (freqval >= 1000.0) { freqval /= 1000.0; units = "Mhz"; } decimals = 2; if (freqval >= 10.0) { decimals = 1; } if (freqval >= 100.0) { decimals = 0; } snprintf(buf, buflen, "%0.*f %s", decimals, freqval, units);}static gint horiz_press(GtkWidget *widget, GdkEventButton *event) { ctrl_usr->horiz.x0 = event->x; return TRUE;}static gint horiz_motion(GtkWidget *widget, GdkEventMotion *event) { scope_horiz_t *horiz = &(ctrl_usr->horiz); int motion; int pre_trig, width; float disp_center, disp_start, disp_end; float rec_start, rec_curr, rec_end; float min, max, span, scale; float newpos; int x, y; GdkModifierType state; if (event->is_hint) gdk_window_get_pointer (event->window, &x, &y, &state); else { x = event->x; y = event->y; state = event->state; } if(!(state & GDK_BUTTON1_MASK)) return TRUE; motion = x - horiz->x0; gdk_window_get_geometry(horiz->disp_area->window, 0, 0, &width, 0, 0); pre_trig = ctrl_shm->rec_len * ctrl_usr->trig.position; rec_start = -pre_trig * horiz->sample_period; rec_end = (ctrl_shm->rec_len - pre_trig) * horiz->sample_period; rec_curr = rec_start + (ctrl_shm->samples * horiz->sample_period); disp_center = rec_start + horiz->pos_setting * (rec_end - rec_start); disp_start = disp_center - 5.0 * horiz->disp_scale; disp_end = disp_center + 5.0 * horiz->disp_scale; if (rec_start < disp_start) { min = rec_start; } else { min = disp_start; } if (rec_end > disp_end) { max = rec_end; } else { max = disp_end; } span = max - min; scale = (width - 1) / span; newpos = GTK_ADJUSTMENT(horiz->pos_adj)->value + motion * 100 / scale; gtk_adjustment_set_value(GTK_ADJUSTMENT(horiz->pos_adj), newpos); horiz->x0 = event->x; return TRUE;}static gint horiz_release(GtkWidget *widget, GdkEventButton *event) { return TRUE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -