📄 gvx.c
字号:
{
/* 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 = >K_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 + -