📄 x.c
字号:
if ((x+(bmp->x)<=dev->clip.x1)||(y+(bmp->y)<=dev->clip.y1)) return; bmp_off_x = 0; bmp_off_y = 0; bmp_size_x = bmp->x; bmp_size_y = bmp->y; if (x < dev->clip.x1) { bmp_off_x = dev->clip.x1 - x; bmp_size_x -= dev->clip.x1 - x; x = dev->clip.x1; } if (x + bmp_size_x > dev->clip.x2) { bmp_size_x = dev->clip.x2 - x; } if (y < dev->clip.y1) { bmp_off_y = dev->clip.y1 - y; bmp_size_y -= dev->clip.y1 - y; y = dev->clip.y1; } if (y + bmp_size_y > dev->clip.y2) { bmp_size_y = dev->clip.y2 - y; } switch(XPIXMAPP(bmp->flags)->type) { case X_TYPE_PIXMAP: XCopyArea(x_display,*(XPIXMAPP(bmp->flags)->data.pixmap),*((Window*)(dev->driver_data)),x_drawbitmap_gc,bmp_off_x,bmp_off_y,bmp_size_x,bmp_size_y,x,y); break; case X_TYPE_IMAGE: XPutImage(x_display,*((Window *)(dev->driver_data)),x_drawbitmap_gc,XPIXMAPP(bmp->flags)->data.image,bmp_off_x,bmp_off_y,x,y,bmp_size_x,bmp_size_y); break; } X_FLUSH();}static void x_draw_bitmaps(struct graphics_device *dev, struct bitmap **bmps, int n, int x, int y){ int a;#ifdef X_DEBUG MESSAGE("x_draw_bitmaps\n");#endif if (!bmps)return; for (a=0;a<n;a++) { x_draw_bitmap(dev,bmps[a],x,y); x+=(bmps[a])->x; }}static void x_register_bitmap(struct bitmap *bmp){ struct x_pixmapa *p; XImage *image; Pixmap *pixmap; int can_create_pixmap; #ifdef X_DEBUG MESSAGE("x_register_bitmap\n");#endif X_FLUSH(); if (!bmp||!bmp->data||!bmp->x||!bmp->y)return; /* alloc struct x_bitmapa */ p=mem_alloc(sizeof(struct x_pixmapa)); /* alloc XImage in client's memory */ image=XCreateImage(x_display,x_default_visual,x_depth,ZPixmap,0,0,bmp->x,bmp->y,x_bitmap_scanline_pad<<3,bmp->skip); if (!image){mem_free(p);goto cant_create;} image->data=bmp->data; /* try to alloc XPixmap in server's memory */ can_create_pixmap=1; x_prepare_for_failure(); pixmap=mem_alloc(sizeof(Pixmap)); (*pixmap)=XCreatePixmap(x_display,fake_window,bmp->x,bmp->y,x_depth); if (x_test_for_failure()) { if (*pixmap) { x_prepare_for_failure(); XFreePixmap(x_display,*pixmap); x_test_for_failure(); *pixmap=0; } } if (!(*pixmap)){mem_free(pixmap);can_create_pixmap=0;} if (can_create_pixmap) {#ifdef X_DEBUG MESSAGE("x_register_bitmap: creating pixmap\n");#endif XPutImage(x_display,*pixmap,x_copy_gc,image,0,0,0,0,bmp->x,bmp->y); XDestroyImage(image); p->type=X_TYPE_PIXMAP; p->data.pixmap=pixmap; } else {#ifdef X_DEBUG MESSAGE("x_register_bitmap: creating image\n");#endif p->type=X_TYPE_IMAGE; p->data.image=image; } bmp->flags=p; return;cant_create: return;}int x_hscroll(struct graphics_device *dev, struct rect_set **set, int sc){ XEvent ev; struct rect r; *set=NULL; if (!sc)return 0; *set=init_rect_set(); if (!(*set))internal("Cannot allocate memory for rect set in scroll function.\n"); XCopyArea( x_display, *((Window*)(dev->driver_data)), *((Window*)(dev->driver_data)), x_scroll_gc, dev->clip.x1,dev->clip.y1, dev->clip.x2-dev->clip.x1,dev->clip.y2-dev->clip.y1, dev->clip.x1+sc,dev->clip.y1 ); XSync(x_display,False); /* ten sync tady musi byt, protoze potrebuju zarucit, aby vsechny * graphics-expose vyvolane timto scrollem byly vraceny v rect-set */ /* take all graphics expose events for this window and put them into the rect set */ while (XCheckWindowEvent(x_display,*((Window*)(dev->driver_data)),ExposureMask,&ev)==True) { switch(ev.type) { case GraphicsExpose: r.x1=ev.xgraphicsexpose.x; r.y1=ev.xgraphicsexpose.y; r.x2=ev.xgraphicsexpose.x+ev.xgraphicsexpose.width; r.y2=ev.xgraphicsexpose.y+ev.xgraphicsexpose.height; break; case Expose: r.x1=ev.xexpose.x; r.y1=ev.xexpose.y; r.x2=ev.xexpose.x+ev.xexpose.width; r.y2=ev.xexpose.y+ev.xexpose.height; break; default: continue; } if (r.x1 < dev->clip.x1 || r.x2 > dev->clip.x2 || r.y1 < dev->clip.y1 || r.y2 > dev->clip.y2) { switch(ev.type) { case GraphicsExpose: ev.xgraphicsexpose.x = 0; ev.xgraphicsexpose.y = 0; ev.xgraphicsexpose.width = dev->size.x2; ev.xgraphicsexpose.height = dev->size.y2; break; case Expose: ev.xexpose.x = 0; ev.xexpose.y = 0; ev.xexpose.width = dev->size.x2; ev.xexpose.height = dev->size.y2; break; } XPutBackEvent(x_display, &ev); mem_free(*set); *set = NULL; break; } add_to_rect_set(set,&r); } register_bottom_half(x_process_events, NULL);#ifdef SC_DEBUG MESSAGE("hscroll\n");#endif return 1;}int x_vscroll(struct graphics_device *dev, struct rect_set **set, int sc){ XEvent ev; struct rect r; *set=NULL; if (!sc)return 0; *set=init_rect_set(); if (!(*set))internal("Cannot allocate memory for rect set in scroll function.\n"); XCopyArea( x_display, *((Window*)(dev->driver_data)), *((Window*)(dev->driver_data)), x_scroll_gc, dev->clip.x1,dev->clip.y1, dev->clip.x2-dev->clip.x1,dev->clip.y2-dev->clip.y1, dev->clip.x1,dev->clip.y1+sc ); XSync(x_display,False); /* ten sync tady musi byt, protoze potrebuju zarucit, aby vsechny * graphics-expose vyvolane timto scrollem byly vraceny v rect-set */ /* take all graphics expose events for this window and put them into the rect set */ while (XCheckWindowEvent(x_display,*((Window*)(dev->driver_data)),ExposureMask,&ev)==True) { switch(ev.type) { case GraphicsExpose: r.x1=ev.xgraphicsexpose.x; r.y1=ev.xgraphicsexpose.y; r.x2=ev.xgraphicsexpose.x+ev.xgraphicsexpose.width; r.y2=ev.xgraphicsexpose.y+ev.xgraphicsexpose.height; break; case Expose: r.x1=ev.xexpose.x; r.y1=ev.xexpose.y; r.x2=ev.xexpose.x+ev.xexpose.width; r.y2=ev.xexpose.y+ev.xexpose.height; break; default: continue; } if (r.x1 < dev->clip.x1 || r.x2 > dev->clip.x2 || r.y1 < dev->clip.y1 || r.y2 > dev->clip.y2) { switch(ev.type) { case GraphicsExpose: ev.xgraphicsexpose.x = 0; ev.xgraphicsexpose.y = 0; ev.xgraphicsexpose.width = dev->size.x2; ev.xgraphicsexpose.height = dev->size.y2; break; case Expose: ev.xexpose.x = 0; ev.xexpose.y = 0; ev.xexpose.width = dev->size.x2; ev.xexpose.height = dev->size.y2; break; } XPutBackEvent(x_display, &ev); mem_free(*set); *set = NULL; break; } add_to_rect_set(set,&r); } register_bottom_half(x_process_events, NULL);#ifdef SC_DEBUG MESSAGE("vscroll\n");#endif return 1;}void *x_prepare_strip(struct bitmap *bmp, int top, int lines){ struct x_pixmapa *p=(struct x_pixmapa *)bmp->flags; XImage *image;#ifdef DEBUG if (lines <= 0) internal("x_prepare_strip: %d lines",lines);#endif#ifdef X_DEBUG MESSAGE("x_prepare_strip\n");#endif switch (p->type) { case X_TYPE_PIXMAP: image=XCreateImage(x_display,x_default_visual,x_depth,ZPixmap,0,0,bmp->x,lines,x_bitmap_scanline_pad<<3,bmp->skip); if (!image)internal("x_prepare_strip: Cannot alloc image.\n"); image->data=malloc(bmp->skip*lines); if (!(image->data))malloc_oom(); bmp->data=image; return image->data; case X_TYPE_IMAGE: return p->data.image->data+(bmp->skip*top); } internal("Unknown pixmap type found in x_prepare_strip. SOMETHING IS REALLY STRANGE!!!!\n"); fatal_tty_exit(); exit(RET_FATAL); /* never called */}void x_commit_strip(struct bitmap *bmp, int top, int lines){ struct x_pixmapa *p=(struct x_pixmapa *)bmp->flags;#ifdef X_DEBUG MESSAGE("x_commit_strip\n");#endif switch(p->type) { /* send image to pixmap in xserver */ case X_TYPE_PIXMAP: XPutImage(x_display,*(XPIXMAPP(bmp->flags)->data.pixmap),x_copy_gc,(XImage*)bmp->data,0,0,0,top,bmp->x,lines); XDestroyImage((XImage *)bmp->data); return; case X_TYPE_IMAGE: /* everything has been done by user */ return; }}void x_set_window_title(struct graphics_device *gd, unsigned char *title){ struct conv_table *ct = get_translation_table(utf8_table,x_input_encoding >= 0?x_input_encoding:0); unsigned char *t; XTextProperty windowName; if (!gd)internal("x_set_window_title called with NULL graphics_device pointer.\n"); t = convert_string(ct, title, strlen(title), NULL); clr_white(t); XStoreName(x_display,*(Window*)(gd->driver_data),t); XStringListToTextProperty((char**)(void *)(&t), 1, &windowName); XSetWMName(x_display, *(Window*)(gd->driver_data), &windowName); XSetWMIconName(x_display, *(Window*)(gd->driver_data), &windowName); XSync(x_display,False); register_bottom_half(x_process_events, NULL); mem_free(t);}/* gets string in UTF8 */void x_set_clipboard_text(struct graphics_device *gd, unsigned char * text){ x_clear_clipboard(); if(text && strlen(text)) { struct conv_table *ct; ct=get_translation_table(utf8_table,x_input_encoding < 0 ? drv->codepage : x_input_encoding); x_my_clipboard=convert_string(ct, text, strlen(text), NULL); XSetSelectionOwner (x_display, XA_PRIMARY, *(Window*)(gd->driver_data), CurrentTime); XFlush (x_display); }}void selection_request(XEvent *event){ XSelectionRequestEvent *req; XSelectionEvent sel; req = &(event->xselectionrequest); sel.type = SelectionNotify; sel.requestor = req->requestor; sel.selection = XA_PRIMARY; sel.target = req->target; sel.property = req->property; sel.time = req->time; sel.display = req->display; #ifdef X_DEBUG { unsigned char txt[256]; sprintf (txt,"xselectionrequest from %i\n",(int)event.xselection.requestor); MESSAGE(txt); sprintf (txt,"property:%i target:%i selection:%i\n", req->property,req->target, req->selection); MESSAGE(txt); } #endif if (req->target == XA_STRING) { XChangeProperty (x_display, sel.requestor, sel.property, XA_STRING, 8, PropModeReplace, x_my_clipboard, x_my_clipboard?strlen(x_my_clipboard):0 ); } else if (req->target == x_targets_atom) { unsigned tgt_atoms[2] /*= {x_targets_atom, XA_STRING }*/; tgt_atoms[0] = x_targets_atom; tgt_atoms[1] = XA_STRING; XChangeProperty (x_display, sel.requestor, sel.property, XA_ATOM, 32, PropModeReplace, (char*)&tgt_atoms, 2 ); } else { #ifdef X_DEBUG { unsigned char txt[256]; sprintf (txt,"Non-String wanted: %i\n",(int)req->target); MESSAGE(txt); } #endif sel.property= None; } XSendEvent (x_display, sel.requestor,0,0,(XEvent*)&sel); XFlush (x_display); }unsigned char *x_get_clipboard_text(void){ struct conv_table *ct; XEvent event; XConvertSelection(x_display, XA_PRIMARY, XA_STRING, x_sel_atom, fake_window, CurrentTime); while (1) { XSync(x_display, False); if (XCheckTypedEvent(x_display,SelectionRequest, &event)) { selection_request(&event); continue; } if (XCheckTypedEvent(x_display,SelectionNotify, &event)) break; x_wait_for_event(); } if (event.xselection.property) { unsigned char *buffer; unsigned long pty_size, pty_items; int pty_format, ret; Atom pty_type; if (event.xselection.target != XA_STRING) goto no_new_sel; if (event.xselection.property != x_sel_atom) goto no_new_sel; /* Get size and type of property */ ret = XGetWindowProperty( x_display, fake_window, event.xselection.property, 0, 0, False, AnyPropertyType, &pty_type, &pty_format, &pty_items, &pty_size, &buffer); if (ret != Success) goto no_new_sel; XFree(buffer); ret = XGetWindowProperty( x_display, fake_window, event.xselection.property, 0, (long)pty_size, True, AnyPropertyType, &pty_type, &pty_format, &pty_items, &pty_size, &buffer ); if(ret != Success) goto no_new_sel; pty_size = (pty_format>>3) * pty_items; x_clear_clipboard(); x_my_clipboard=stracpy(buffer); XFree(buffer); }no_new_sel: register_bottom_half(x_process_events, NULL); if (!x_my_clipboard) return NULL; ct=get_translation_table(x_input_encoding < 0 ? drv->codepage : x_input_encoding,utf8_table); return convert_string(ct, x_my_clipboard, strlen(x_my_clipboard), NULL);}int x_exec(unsigned char *command, int fg){ unsigned char *run; int retval; if (!fg) return system(command); run=subst_file(*x_driver.shell?x_driver.shell:(unsigned char *)"xterm -e %",command, 0); retval=system(run); mem_free(run); return retval;}struct graphics_driver x_driver={ "x", x_init_driver, x_init_device, x_shutdown_device, x_shutdown_driver, x_get_driver_param, x_get_empty_bitmap, /*x_get_filled_bitmap,*/ x_register_bitmap, x_prepare_strip, x_commit_strip, x_unregister_bitmap, x_draw_bitmap, x_draw_bitmaps, x_get_color, x_fill_area, x_draw_hline, x_draw_vline, x_hscroll, x_vscroll, x_set_clip_area, dummy_block, dummy_unblock, x_set_window_title, x_exec, 0, /* depth (filled in x_init_driver function) */ 0, 0, /* size (in X is empty) */ 0, /* flags */ 0, /* codepage */ NULL, /* shell */};#endif /* GRDRV_X */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -