⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scope_disp.c

📁 CNC 的开放码,EMC2 V2.2.8版
💻 C
📖 第 1 页 / 共 2 页
字号:
		    x = (((0.1 * m) / xminor) + fx) * xscale;		    gdk_draw_point(disp->win, disp->context, x, y);		}	    }	}    }}static int select_x, select_y, target;static double min_dist;static int select_trace(int x, int y) {    int n;    scope_disp_t *disp = &(ctrl_usr->disp);    min_dist = hypot(disp->width, disp->height) / 100.;    if(min_dist < 5) min_dist = 5;    target = -1;    DRAWING = 0;    select_x = x;    select_y = y;    for(n=0; n<16; n++) {        scope_vert_t *vert = &(ctrl_usr->vert);        draw_baseline(n+1, FALSE);        if((vert->chan_enabled[n]) && (vert->data_offset[n] >= 0)) {            draw_waveform(n+1, FALSE);        }    }    draw_triggerline(ctrl_shm->trig_chan, FALSE);    return target;}static int handle_release(GtkWidget *widget, GdkEventButton *event, gpointer data) {    return 1;}static void change_zoom(int dir, int x) {    scope_horiz_t *horiz = &(ctrl_usr->horiz);    scope_disp_t *disp = &(ctrl_usr->disp);    double old_pixels_per_sample, pixels_per_div,           pixels_per_sec, new_pixels_per_sample, old_fraction, new_fraction,           overall_record_length;    old_pixels_per_sample = disp->pixels_per_sample;    overall_record_length = horiz->sample_period * ctrl_shm->rec_len;    set_horiz_zoom(horiz->zoom_setting + dir);    /* calculate horizontal params that depend on width */    pixels_per_div = disp->width * 0.1;    pixels_per_sec = pixels_per_div / horiz->disp_scale;    disp->pixels_per_sample = new_pixels_per_sample =         pixels_per_sec * horiz->sample_period;    // how many samples away from the center of the window is this    // pixel?    old_fraction = (x - disp->width / 2) / old_pixels_per_sample / ctrl_shm->rec_len;    // and new?    new_fraction = (x - disp->width / 2) / new_pixels_per_sample / ctrl_shm->rec_len;    // displace by the difference    set_horiz_pos( horiz->pos_setting - new_fraction + old_fraction );}static int handle_click(GtkWidget *widget, GdkEventButton *event, gpointer data) {    scope_vert_t *vert = &(ctrl_usr->vert);    scope_disp_t *disp = &(ctrl_usr->disp);    motion_y = event->y;    motion_x = event->x;    if(event->button == 4) { // zoom in        change_zoom(1, event->x);    } else if(event->button == 5) { // zoom out        change_zoom(-1, event->x);    } else {        int z = select_trace(event->x, event->y);        int new_channel = z & 0xff;        int channel_part = z >> 8;         disp->selected_part = channel_part;        if(new_channel != vert->selected) {            if(z == -1) vert->selected = -1;            else vert->selected = new_channel;            channel_changed();        }        if(channel_part == 3) {            set_trigger_polarity(!ctrl_shm->trig_edge);        }    }    return 1;}static int get_cursor_info(double *t, double *v) {    if(!cursor_valid) return 0;    if(t) *t = cursor_time;    if(v) *v = cursor_value;    return 1;}static int handle_scroll(GtkWidget *widget, GdkEventScroll *event, gpointer data) {    change_zoom(event->direction ? -1 : 1, event->x);    return TRUE;}static void middle_drag(int dx) {    scope_disp_t *disp = &(ctrl_usr->disp);    scope_horiz_t *horiz = &(ctrl_usr->horiz);    float dt = (dx / disp->pixels_per_sample) / ctrl_shm->rec_len;    set_horiz_pos(horiz->pos_setting + 5 * dt);    refresh_display();}static double snap(int y) {    scope_disp_t *disp = &(ctrl_usr->disp);    double new_position = y * 1.0 / disp->height;    double mod = fmod(new_position, 0.05);    if(mod > .045) new_position = new_position + (.05-mod);    if(mod < .005) new_position = new_position - mod;    return new_position;}static void left_drag(int dy, int y, GdkModifierType state) {    scope_disp_t *disp = &(ctrl_usr->disp);    scope_vert_t *vert = &(ctrl_usr->vert);    scope_chan_t *chan = &(ctrl_usr->chan[vert->selected - 1]);    if(vert->selected == -1) return;    if(disp->selected_part == 2 || (state & GDK_CONTROL_MASK)) {        double new_position = snap(y);        set_trigger_level(new_position);    } else if(disp->selected_part == 1 || (state & GDK_SHIFT_MASK)) {        double new_position = snap(y);        set_vert_pos(new_position);        // chan->position = new_position;        refresh_display();        motion_y = y;    } else {        if(abs(dy) > 5) {            int direction = dy > 0 ? 1 : -1;            int baseline_y = chan->position * disp-> height;            int side = select_y > baseline_y ? -1 : 1;            set_vert_scale(chan->scale_index + direction * side);            motion_y = y;        }    }}static int handle_motion(GtkWidget *widget, GdkEventButton *event, gpointer data) {    scope_disp_t *disp = &(ctrl_usr->disp);    GdkModifierType mod;    int x, y;    gdk_window_get_pointer(disp->drawing->window, &x, &y, &mod);    if(mod & GDK_BUTTON1_MASK) {        left_drag(y-motion_y, y, event->state);        return TRUE;    }    if(mod & GDK_BUTTON2_MASK) {        middle_drag(motion_x - x);    }    motion_x = x;    refresh_display();    return TRUE;}#define TIPFORMAT "<tt>f(% 8.5f) = % 8.5f</tt>"static void update_readout(void) {    scope_vert_t *vert = &(ctrl_usr->vert);    char tip[512];    GdkRectangle r = {vert->readout_label->allocation.x,            vert->readout_label->allocation.y,            vert->readout_label->allocation.width,            vert->readout_label->allocation.height};    if(vert->selected != -1) {        double t=0, v=0;        int result = get_cursor_info(&t, &v);        if(result > 0) {             snprintf(tip, sizeof(tip), TIPFORMAT, t, v);        } else { 	    strcpy(tip, "");        }    } else {            strcpy(tip, "");    }    gtk_label_set_markup(GTK_LABEL(vert->readout_label), tip);    gtk_widget_draw(vert->readout_label, &r);}struct pt { double x, y; };static double dot(struct pt *a, struct pt *b) {    return a->x * b->x + a->y * b->y;}static double mag(struct pt *p) {    return hypot(p->x, p->y);}static double distance_point_line(int x, int y, int x1, int y1, int x2, int y2) {    struct pt M = {x2-x1, y2-y1},           Q = {x-x1, y-y1},           R;    double t0 = dot(&M, &Q) / dot(&M, &M);    if(t0 < 0) t0 = 0;    if(t0 > 1) t0 = 1;    R.x = x - (x1 + t0 * M.x);    R.y = y - (y1 + t0 * M.y);    return mag(&R);}#define COORDINATE_CLIP(coord)  ((coord < -32768) ? -32768 : (coord > 32767) ? 32767 : coord)void line(int chan_num, int x1, int y1, int x2, int y2) {    scope_disp_t *disp = &(ctrl_usr->disp);    if(DRAWING) {        gdk_draw_line(disp->win, disp->context, COORDINATE_CLIP(x1), COORDINATE_CLIP(y1), COORDINATE_CLIP(x2), COORDINATE_CLIP(y2));    } else {        double dist = distance_point_line(select_x, select_y, x1, y1, x2, y2);        if(dist < min_dist) {            min_dist = dist;            target = chan_num;        }    }}void lines(int chan_num, GdkPoint points[], gint npoints) {    double dist;    scope_disp_t *disp = &(ctrl_usr->disp);    if(DRAWING) {        gdk_draw_lines(disp->win, disp->context, points, npoints);    } else {        int x1 = points[0].x, y1 = points[0].y, x2, y2, i;        for(i=1; i<npoints; i++) {            x2 = points[i].x; y2 = points[i].y;            dist = distance_point_line(select_x, select_y, x1, y1, x2, y2);            if(dist < min_dist) {                min_dist = dist;                target = chan_num;            }            x1 = x2; y1 = y2;        }    }}staticvoid draw_triggerline(int chan_num, int highlight) {    static gint8 dashes[2] = {2,4};    scope_disp_t *disp = &(ctrl_usr->disp);    scope_chan_t *chan = &(ctrl_usr->chan[chan_num - 1]);    scope_trig_t *trig = &(ctrl_usr->trig);    double yfoffset = chan->vert_offset;    double ypoffset = chan->position * disp->height;    double yscale = disp->height / (-10.0 * chan->scale);    double fp_level =        chan->scale * ((chan->position - trig->level) * 10) +	chan->vert_offset;    int y1 = (fp_level-yfoffset) * yscale + ypoffset;    double dx = hypot(disp->width, disp->height) * .01;    double dy = dx * 1.3;    if(dx < 5) dx = 5;    if(dy < dx + 1) dy = dx + 1;    if(chan->data_type == HAL_BIT)        y1 = ypoffset;    if(ctrl_shm->trig_edge) dy = -dy;    if(highlight) {	gdk_gc_set_foreground(disp->context, &(disp->color_selected[chan_num-1]));    } else {	gdk_gc_set_foreground(disp->context, &(disp->color_normal[chan_num-1]));    }    gdk_gc_set_dashes(disp->context, 0, dashes, 2);    gdk_gc_set_line_attributes(disp->context, 0, GDK_LINE_ON_OFF_DASH, GDK_CAP_BUTT, GDK_JOIN_MITER);    line(chan_num | 0x200, 0, y1, disp->width, y1);    gdk_gc_set_line_attributes(disp->context, 0, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);    if(highlight) {        gdk_gc_set_foreground(disp->context, &(disp->color_grid));    } else {        gdk_gc_set_foreground(disp->context, &(disp->color_baseline));    }    line(chan_num | 0x300, 2*dx, y1, 2*dx, y1 + 2*dy);    line(chan_num | 0x300, dx, y1+dy, 2*dx, y1 + 2*dy);    line(chan_num | 0x300, 3*dx, y1+dy, 2*dx, y1 + 2*dy);}void draw_baseline(int chan_num, int highlight) {    scope_disp_t *disp = &(ctrl_usr->disp);    scope_chan_t *chan = &(ctrl_usr->chan[chan_num - 1]);    double yfoffset = chan->vert_offset;    double ypoffset = chan->position * disp->height;    double yscale = disp->height / (-10.0 * chan->scale);    int y1 = -yfoffset * yscale + ypoffset;;    if(highlight) {        gdk_gc_set_foreground(disp->context, &(disp->color_grid));    } else {        gdk_gc_set_foreground(disp->context, &(disp->color_baseline));    }    line(chan_num | 0x100, 0, y1, disp->width, y1);}/* waveform styles: if neither is defined, an intermediate style is used */// #define DRAW_STEPPED// #define DRAW_SMOOTHvoid draw_waveform(int chan_num, int highlight){    scope_data_t *dptr;    int start, end, n, sample_len;    scope_disp_t *disp;    scope_chan_t *chan;    double xscale, xoffset;    double yscale, yfoffset, ypoffset, fy;    hal_type_t type;    int x1, y1, x2, y2, miny, maxy, midx, ct, pn;    GdkPoint *points;    int first=1;    scope_horiz_t *horiz = &(ctrl_usr->horiz);    cursor_valid = 0;    disp = &(ctrl_usr->disp);    chan = &(ctrl_usr->chan[chan_num - 1]);    /* calculate a bunch of local vars */    sample_len = ctrl_shm->sample_len;    xscale = disp->pixels_per_sample;    xoffset = disp->horiz_offset;    miny = -disp->height;    maxy = 2 * disp->height;    type = chan->data_type;    yscale = disp->height / (-10.0 * chan->scale);    yfoffset = chan->vert_offset;    ypoffset = chan->position * disp->height;    /* point to first sample in the record for this channel */    dptr = ctrl_usr->disp_buf + ctrl_usr->vert.data_offset[chan_num - 1];    /* point to first one that gets displayed */    start = disp->start_sample;    end = disp->end_sample;    ct = end - start + 1;    points = alloca(2 * ct * sizeof(GdkPoint));    pn = 0;    n = start;    dptr += n * sample_len;    /* set color to draw */    if (highlight) {	gdk_gc_set_foreground(disp->context, &(disp->color_selected[chan_num-1]));    } else {	gdk_gc_set_foreground(disp->context, &(disp->color_normal[chan_num-1]));    }    x1 = y1 = 0;    while (n <= end) {	/* calc x coordinate of this point */	x2 = (n * xscale) - xoffset;	/* calc y coordinate of this point */	switch (type) {	case HAL_BIT:	    if (dptr->d_u8) {		fy = 1.0;	    } else {		fy = 0.0;	    };	    break;	case HAL_FLOAT:	    fy = dptr->d_float;	    break;	case HAL_S32:	    fy = dptr->d_s32;	    break;	case HAL_U32:	    fy = dptr->d_u32;	    break;	default:	    fy = 0.0;	    break;	}	y2 = ((fy - yfoffset) * yscale) + ypoffset;	if (y2 < miny) {	    y2 = miny;	} else if (y2 > maxy) {	    y2 = maxy;	}        x1 = COORDINATE_CLIP(x1);        x2 = COORDINATE_CLIP(x2);        y1 = COORDINATE_CLIP(y1);        y2 = COORDINATE_CLIP(y2);	/* don't draw segment ending at first point */	if (n > start) {            if(pn == 0) {                points[pn].x = x1; points[pn].y = y1; pn++;            }            if(xscale < 1) {                if(points[pn-1].x != x2 || points[pn-1].y != y2) {                    points[pn].x = x2; points[pn].y = y2; pn++;                }            } else {#if defined(DRAW_SMOOTH)                /* this is a smoothed line display */                points[pn].x = x2; points[pn].y = y2; pn++;#elif defined(DRAW_STEPPED)                /* this is a stepped one */                points[pn].x = x1; points[pn].y = y2; pn++;                points[pn].x = x2; points[pn].y = y2; pn++;#else                /* this is halfway between the two extremes */                midx = (x1 + x2) / 2;                if(midx != x2) {                    points[pn].x = midx; points[pn].y = y2; pn++;                }                points[pn].x = x2; points[pn].y = y2; pn++;#endif            }	    if(first && highlight && DRAWING && x2 >= motion_x) {		    first = 0;		    gdk_draw_arc(disp->win, disp->context, TRUE,				x2-3, y2-3, 7, 7, 0, 360*64);                    cursor_value = fy;                    cursor_time = (n - ctrl_shm->pre_trig)*horiz->sample_period;                    cursor_valid = 1;	    }	}	/* end of this segment is start of next one */	x1 = x2;	y1 = y2;	/* point to next sample */	dptr += sample_len;	n++;    }    if(pn) {        PangoLayout *p;        char scale[HAL_NAME_LEN];        char buffer[2 * HAL_NAME_LEN];        lines(chan_num, points, pn);        format_scale_value(scale, sizeof(scale), chan->scale);        snprintf(buffer, sizeof(buffer), "%s\n%s", chan->name, scale);        gdk_draw_layout(disp->win, disp->context, 5, points[0].y,                         p=gtk_widget_create_pango_layout(disp->drawing, buffer));        g_object_unref(p);    }}// vim:sts=4:sw=4:et

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -