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

📄 gvx.c

📁 GSview 4.6 PostScript previewer。Ghostscript在MS-Windows, OS/2 and Unix下的图形化接口
💻 C
📖 第 1 页 / 共 4 页
字号:
{
    /* Tell GS thread to exit. */
    /* When it finishes, it will post the quit message */
    quitnow = TRUE;
    pending.unload = TRUE;
#ifdef MULTITHREAD
    pending.abort = TRUE;
    if (multithread)
	sem_post(&display.event);	/* unblock display thread */
#endif
}


void set_last_used(void)
{
    GtkWidget *w;
    GtkItem *item;
    GtkBin *bin;
    GtkWidget *label;
    char buf[MAXSTR];
    int i;
    for (i=0; i<4; i++) {
	w = last_file_widget[i];
	if (i < last_files_count) {
	    sprintf(buf, "%s", last_files[i]);
	    if (strlen(buf)>64) {
		int j;
		for (j=strlen(buf); j>0; j--)
		    if ((buf[j] == '/') || (buf[j] == '\\'))
			break;
		if (strlen(buf) - j > 28)
		    memmove(buf+3, buf+strlen(buf)+1-30, 30);
		else {
		    buf[5] = buf[6] = buf[7] = '.';
		    memmove(buf+8, buf+j, strlen(buf)+1-j);
		}
	    }
	    item = &GTK_MENU_ITEM(w)->item;
	    bin = &item->bin;
	    label = bin->child;
	    gtk_label_set_text(GTK_LABEL(label), buf);
	    gtk_widget_show(w);
	}
	else
	    gtk_widget_hide(w);
    }
}

/* enable/disable menu items based on document state */
void set_menu_sensitive(void)
{
/* not implemented yet */
    enable_menu_item(IDM_OPTIONMENU, IDM_SOUNDS, FALSE);
    enable_menu_item(IDM_OPTIONMENU, IDM_CFG, FALSE);
    enable_menu_item(IDM_VIEWMENU, IDM_FULLSCREEN, FALSE);
    enable_menu_item(IDM_HELPMENU, IDM_HELPSEARCH, FALSE);
}

/* callback from menu to gsview_command */
void gsview_wcmd(GtkWidget *w, gpointer data)
{
    int command = (int)data;
    command_on_done = 0;
    if (disable_gsview_wcmd)
       return;

    if (getting_bbox) {
	/* Using the menu is not allowed */
	/* Cancel get_bbox() */
	getting_bbox = FALSE;
	gtk_main_quit();
	return;
    }

    if (debug & DEBUG_GENERAL)
	gs_addmessf("gsview_wcmd: gsdll.state=%d\n", gsdll.state);

    gsview_command(command);
    if (debug & DEBUG_GENERAL)
	gs_addmessf("gsview_wcmd: now=%d next=%d unload=%d\n", 
	    pending.now, pending.next, pending.unload);

    if (pending.now || pending.next || pending.unload || quitnow) {
	if (display.bitcount == 0) {
	    gint x, y, width, height, depth;
	    gdk_window_get_geometry(window->window, &x, &y, 
		&width, &height, &depth);
	    display.planes = 1;
	    display.bitcount = depth;
	}
    
#ifdef MULTITHREAD
	if (multithread) {
	    /* release other thread if needed */
	    sem_post(&display.event);
	}
#endif
    }

    set_menu_sensitive();
    switch (command) {
	case IDM_OPEN:
	case IDM_SELECT:
	case IDM_LASTFILE1:
	case IDM_LASTFILE2:
	case IDM_LASTFILE3:
	case IDM_LASTFILE4:
	    set_last_used();	/* update last files */
    }
}

void selection_handle(GtkWidget *widget, GtkSelectionData *selection_data,
	guint info, guint time_stamp, gpointer data)
{
    guchar nulchar = '\0';
    if ( text_index && (text_mark_first != -1) && (text_mark_last != -1)) {
	/* copy text, not image */
	int first, last, line;
	int length;
	int i;
	char * data;
	char *p;
	first = text_mark_first;
	last = text_mark_last;
	if (first > last) {
	    first = text_mark_last;
	    last = text_mark_first;
	}
	line = text_index[first].line;
	length = 1;
	for (i=first; i<=last; i++) {
	    if (text_index[i].line != line) {
	        line = text_index[i].line;
		length += 2;
	    }
	    length += strlen( text_words + text_index[i].word ) + 1;
	}
	data = (char *)malloc(length);
	if (data == (char *)NULL) {
	    message_box("out of memory", 0);
	    gtk_selection_data_set(selection_data, GDK_SELECTION_TYPE_STRING,
		8, &nulchar, 0);
	    return;
	}
	line = text_index[first].line;
	p = data;
	for (i=first; i<=last; i++) {
	    if (text_index[i].line != line) {
	        line = text_index[i].line;
		strcpy(p, "\r\n");
		p += strlen(p);
	    }
	    strcpy(p, text_words + text_index[i].word);
	    strcat(p, " ");
	    p += strlen(p);
	}
        gtk_selection_data_set(selection_data, GDK_SELECTION_TYPE_STRING,
	    8, (guchar *)data, strlen(data));
    }
    else
        gtk_selection_data_set(selection_data, GDK_SELECTION_TYPE_STRING,
	    8, &nulchar, 0);
}

void 
selection_add(void)
{
    gtk_selection_add_target(img, GDK_SELECTION_PRIMARY,
	GDK_SELECTION_TYPE_STRING, 1);
    gtk_signal_connect(GTK_OBJECT(img), "selection_get",
	GTK_SIGNAL_FUNC(selection_handle), NULL);
}

void
selection_release(void)
{
    if (have_selection) {
	if (gdk_selection_owner_get(GDK_SELECTION_PRIMARY) == img->window)
	    gtk_selection_owner_set(NULL, GDK_SELECTION_PRIMARY,
		GDK_CURRENT_TIME);
	have_selection = FALSE;
    }
}

gint
button_release_event(GtkWidget *widget, GdkEventButton *event)
{
    if (event->button==1) {
	text_marking = FALSE;
	if ((text_mark_first != -1) && (text_mark_last != -1)) {
	    /* we have selected something, so claim the X selection */
	    have_selection = gtk_selection_owner_set(widget, 
		GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME);
	}
	else
	    selection_release();
	if (draghand) {
	    draghand = FALSE;
	}
    }
    return TRUE;
}

void
key_scroll_horz(int key)
{
    int delta = 0;
    GtkAdjustment *hadjust = gtk_scrolled_window_get_hadjustment(
	    GTK_SCROLLED_WINDOW(scroll_window));
    switch(key) {
	case GDK_Home:
	case GDK_KP_Home:
	    delta = -hadjust->value;
	    break;
	case GDK_End:
	case GDK_KP_End:
	    delta = (hadjust->upper - hadjust->page_size) - hadjust->value;
	    break;
	case GDK_Left:
	case GDK_KP_Left:
	    delta = -hadjust->step_increment;
	    break;
	case GDK_Right:
	case GDK_KP_Right:
	    delta = hadjust->step_increment;
	    break;
	case GDK_Page_Up:
	case GDK_KP_Page_Up:
	    delta = min(-1,-hadjust->page_increment);
	    break;
	case GDK_Page_Down:
	case GDK_KP_Page_Down:
	    delta = max(1,+hadjust->page_increment);
	    break;
	default:
	    delta = 0;
    }

    if (hadjust->value + delta < 0)
	delta = -hadjust->value;
    if (hadjust->value + delta >= hadjust->upper - hadjust->page_size)
	delta = hadjust->upper - hadjust->page_size - hadjust->value;

    set_scroll(hadjust->value + delta, -1);
}

void
key_scroll_vert(int key)
{
    int delta = 0;
    GtkAdjustment *vadjust = gtk_scrolled_window_get_vadjustment(
	    GTK_SCROLLED_WINDOW(scroll_window));
    switch(key) {
	case GDK_Home:
	case GDK_KP_Home:
	    delta = -vadjust->value;
	    break;
	case GDK_End:
	case GDK_KP_End:
	    delta = (vadjust->upper - vadjust->page_size) - vadjust->value;
	    break;
	case GDK_Up:
	case GDK_KP_Up:
	    delta = -vadjust->step_increment;
	    break;
	case GDK_Down:
	case GDK_KP_Down:
	    delta = vadjust->step_increment;
	    break;
	case GDK_Page_Up:
	case GDK_KP_Page_Up:
	    delta = min(-1,-vadjust->page_increment);
	    break;
	case GDK_Page_Down:
	case GDK_KP_Page_Down:
	    delta = max(1,+vadjust->page_increment);
	    break;
	default:
	    delta = 0;
    }

    if (vadjust->value + delta < 0)
	delta = -vadjust->value;
    if (vadjust->value + delta >= vadjust->upper - vadjust->page_size)
	delta = vadjust->upper - vadjust->page_size - vadjust->value;

    if ((gsdll.state != GS_IDLE) && 
	((key == GDK_Page_Down) || (key == GDK_KP_Page_Down) ||
	 (key == GDK_Page_Up) || (key == GDK_KP_Page_Up)) &&
	(delta == 0)) {
	/* Advance to next or previous page */
	int numpages = 0;
	request_mutex();
	if (psfile.dsc != (CDSC *)NULL)
	    numpages = psfile.dsc->page_count;
	release_mutex();
	switch(key) {
	    case GDK_Page_Up:
	    case GDK_KP_Page_Up:
	      if ((psfile.dsc != (CDSC *)NULL)
		    && (psfile.pagenum != 1)) {
		set_scroll(-1, vadjust->upper - vadjust->page_size);
		gsview_wcmd(NULL, (gpointer)IDM_PREV);
	      }
	      break;
	    case GDK_Page_Down:
	    case GDK_KP_Page_Down:
	      if ((psfile.dsc == (CDSC *)NULL)
		    || (psfile.pagenum < numpages)) {
		set_scroll(-1, 0);
		gsview_wcmd(NULL, (gpointer)IDM_NEXT);
	      }
	      break;
	}
    }
    else 
        set_scroll(-1, vadjust->value + delta);
}


gint 
key_press_event(GtkWidget *widget, GdkEventKey *event)
{

    if (event->state & GDK_MOD1_MASK) { 	/* Alt key down */
        switch (event->keyval) {
	    case GDK_comma:
	        gsview_wcmd(NULL, (gpointer)IDM_PREV);
		break;
	    case GDK_period:
	        gsview_wcmd(NULL, (gpointer)IDM_NEXT);
		break;
	}
	return TRUE;
    }

    switch (event->keyval) {
	case GDK_Alt_L:
	case GDK_Alt_R:
	    break;
	case GDK_KP_Up:
	case GDK_Up:
	case GDK_KP_Down:
	case GDK_Down:
	    key_scroll_vert(event->keyval);
	    break;
	case GDK_Page_Up:
	case GDK_KP_Page_Up:
	case GDK_Page_Down:
	case GDK_KP_Page_Down:
	case GDK_Home: case GDK_KP_Home:
	case GDK_End:
	case GDK_KP_End:
	    if (event->state & GDK_CONTROL_MASK)
		key_scroll_horz(event->keyval);
	    else
		key_scroll_vert(event->keyval);
	    break;
	case GDK_KP_Left:
	case GDK_KP_Right:
	case GDK_Left:
	case GDK_Right:
	    key_scroll_horz(event->keyval);
	    break;
	case GDK_BackSpace:
	    gsview_wcmd(NULL, (gpointer)IDM_PREVHOME);
	    break;
	case GDK_plus:
	case GDK_KP_Add:
	    gsview_wcmd(NULL, (gpointer)IDM_NEXT);
	    break;
	case GDK_minus:
	case GDK_KP_Subtract:
	    gsview_wcmd(NULL, (gpointer)IDM_PREV);
	    break;
	case GDK_less:
	case GDK_comma:
	    gsview_wcmd(NULL, (gpointer)IDM_MAGMINUS);
	    break;
	case GDK_greater:
	case GDK_period:
	    gsview_wcmd(NULL, (gpointer)IDM_MAGPLUS);
	    break;
	case GDK_F1:
	    gsview_wcmd(NULL, (gpointer)IDM_HELPCONTENT);
	    break;
	  /* ignore it 
	default:
	      g_print("Key press 0x%x 0x%x\n", event->keyval, event->state);
	   */
    }
    return TRUE;
}

gint
button_press_event(GtkWidget *widget, GdkEventButton *event)
{
    /* On some platforms, pressing the button causes us to be notified
     * that we have left the window, which prevents get_cursorpos()
     * from working.  Assume that if we got the button click,
     * we must have been in the window anyway.
     */
    in_img_window = TRUE;
    if (event->button==1) {
	if (getting_bbox)
	    bbox_click();
	else {
	    float x, y;
	    PDFLINK link;
	    int iword ;
	    if (get_cursorpos(&x, &y)) {
		if ( (iword = word_find((int)x, (int)y)) >= 0 ) {
		    /* remove any current selection */
		    highlight_words(text_mark_first, text_mark_last, FALSE);
		    /* mark new selection */
		    text_mark_first = text_mark_last = iword;
		    text_marking = TRUE;
		    highlight_words(text_mark_first, text_mark_last, TRUE);
		}
		else {
		    /* remove selection */
		    highlight_words(text_mark_first, text_mark_last, FALSE);
		    text_mark_first = text_mark_last = -1;
		}
		if (is_link(x, y, &link)) {
		    /* found link */
		    if (link.page == 0) {
			if (strcmp(link.action, "GoBack")==0)
			    history_back();
			else
			    gserror(IDS_NOLINKTARGET, NULL, 0, 
				SOUND_ERROR);
		    }
		    else {
			gsview_unzoom();
			pending.pagenum = link.page;
			history_add(pending.pagenum);
			pending.now = TRUE;
			gsview_wcmd(NULL, 0);
		    }
		}
	        else {
		    draghand = TRUE;
		    draghand_x = (int)event->x;
		    draghand_y = (int)event->y;
		}
		measure_setpoint(x, y);
	    }
	    else
	    {
	    }
	}
    }
#ifdef NOTUSED
    if (event->button==2) {
	/* button 2 not used */
    }
#endif
    if (event->button==3) {
	float x, y;
	int zwidth, zheight;
	int scrollx, scrolly;
	if (get_cursorpos(&x, &y)) {
	    zoom = !zoom;
	    /* This is the coordinate in pts that will become  */
	    /* the centre of the window. */
	    display.zoom_xoffset = (int)x;
	    display.zoom_yoffset = (int)y;
	    /* Get scroll bar position. */
	    /* x=0 is left, y=0 is top */
	    scrollx = (int)(gtk_scrolled_window_get_hadjustment(
		GTK_SCROLLED_WINDOW(scroll_window))->value);
	    scrolly = (int)(gtk_scrolled_window_get_vadjustment(
		GTK_SCROLLED_WINDOW(scroll_window))->value);
	    /* Get viewable area */
	    /* This is wrong because it ignores the size of the scrollbars */
	    zwidth = scroll_window->allocation.width;
	    zheight = scroll_window->allocation.height;
	    if (zwidth > image.width)
		zwidth = image.width;
	    if (zheight > image.height)
		zheight = image.height;

	    /* get coordinates of centre of viewable area */
	    /* relative to bottom left of page */
	    x = (scrollx + zwidth/2)*72.0/option.xdpi;
	    y = (image.height-(scrolly + zheight/2))*72.0/option.ydpi;
	    /* cope with rotated pages */
	    transform_point(&x, &y);
	    /* adjust zoom offset to put cursor position at centre */
	    x *= option.xdpi/72.0;
	    y *= option.ydpi/72.0;
	    display.zoom_xoffset -= (int)(x*72.0/option.zoom_xdpi);
	    display.zoom_yoffset -= (int)(y*72.0/option.zoom_ydpi);
	}
	else {
	    zoom = FALSE;
	}
	gsview_wcmd(NULL, (gpointer)IDM_ZOOM);
    }

    return TRUE;
}

gint
motion_notify_event(GtkWidget *widget, GdkEventMotion *event)
{
    float x, y;
    if (event->type == GDK_LEAVE_NOTIFY) {
	in_img_window = FALSE;
    }
    else if (event->type == GDK_MOTION_NOTIFY) {
#ifdef NOTUSED
	int x, y;
	GdkModifierType state;
	/* x,y is pixel offset from top left corner of window */
	if (event->is_hint)
	    gdk_window_get_pointer(event->window, &x, &y, &state);

⌨️ 快捷键说明

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