📄 x.c
字号:
#ifdef SC_DEBUG MESSAGE("x_process_event\n");#endif last_was_mouse=0; while (XPending(x_display) || replay_event) { if (replay_event) replay_event = 0; else XNextEvent(x_display,&event); if (last_was_mouse&&(event.type==ButtonPress||event.type==ButtonRelease)) /* this is end of mouse move block --- call mouse handler */ { int a,b; last_was_mouse=0;#ifdef X_DEBUG MESSAGE("(MotionNotify event)\n"); { unsigned char txt[256]; sprintf(txt,"x=%d y=%d\n",last_event.xmotion.x,last_event.xmotion.y); MESSAGE(txt); }#endif gd=x_find_gd(&(last_event.xmotion.window)); if (!gd)break; a=B_LEFT; b=B_MOVE; if ((last_event.xmotion.state)&Button1Mask) { a=B_LEFT; b=B_DRAG;#ifdef X_DEBUG MESSAGE("left button/drag\n");#endif } if ((last_event.xmotion.state)&Button2Mask) { a=B_MIDDLE; b=B_DRAG;#ifdef X_DEBUG MESSAGE("middle button/drag\n");#endif } if ((last_event.xmotion.state)&Button3Mask) { a=B_RIGHT; b=B_DRAG;#ifdef X_DEBUG MESSAGE("right button/drag\n");#endif } x_clip_number(&(last_event.xmotion.x),gd->size.x1,gd->size.x2); x_clip_number(&(last_event.xmotion.y),gd->size.y1,gd->size.y2); gd->mouse_handler(gd,last_event.xmotion.x,last_event.xmotion.y,a|b); } switch(event.type) { case GraphicsExpose: /* redraw uncovered area during scroll */ { struct rect r;#ifdef X_DEBUG MESSAGE("(GraphicsExpose event)\n");#endif gd=x_find_gd(&(event.xgraphicsexpose.drawable)); if (!gd)break; r.x1=event.xgraphicsexpose.x; r.y1=event.xgraphicsexpose.y; r.x2=event.xgraphicsexpose.x+event.xgraphicsexpose.width; r.y2=event.xgraphicsexpose.y+event.xgraphicsexpose.height; gd->redraw_handler(gd,&r); } break; case Expose: /* redraw part of the window */ { struct rect r;#ifdef X_DEBUG MESSAGE("(Expose event)\n");#endif gd=x_find_gd(&(event.xexpose.window)); if (!gd)break; r.x1=event.xexpose.x; r.y1=event.xexpose.y; r.x2=event.xexpose.x+event.xexpose.width; r.y2=event.xexpose.y+event.xexpose.height; gd->redraw_handler(gd,&r); } break; case ConfigureNotify: /* resize window */#ifdef X_DEBUG MESSAGE("(ConfigureNotify event)\n"); { unsigned char txt[256]; sprintf(txt,"width=%d height=%d\n",event.xconfigure.width,event.xconfigure.height); MESSAGE(txt); }#endif gd=x_find_gd(&(event.xconfigure.window)); if (!gd)break; /* when window only moved and size is the same, do nothing */ if (gd->size.x2==event.xconfigure.width&&gd->size.y2==event.xconfigure.height)break; configure_notify_again: gd->size.x2=event.xconfigure.width; gd->size.y2=event.xconfigure.height; x_update_driver_param(event.xconfigure.width, event.xconfigure.height); while (XCheckWindowEvent(x_display,*((Window *)(gd->driver_data)),ExposureMask,&event)==True) ; if (XCheckWindowEvent(x_display,*((Window *)(gd->driver_data)),StructureNotifyMask,&event)==True) { if (event.type==ConfigureNotify) goto configure_notify_again; replay_event=1; } gd->resize_handler(gd); break; case KeyPress: /* a key was pressed */ { int f,k;#ifdef X_DEBUG MESSAGE("(KeyPress event)\n"); { unsigned char txt[256]; sprintf(txt,"keycode=%d state=%d\n",event.xkey.keycode,event.xkey.state); MESSAGE(txt); }#endif gd=x_find_gd(&(event.xkey.window)); if (!gd)break; if (x_translate_key((XKeyEvent*)(&event),&k,&f)) gd->keyboard_handler(gd,k,f); } break; case ClientMessage: if ( event.xclient.format!=32|| event.xclient.message_type!=x_wm_protocols_atom|| (Atom)event.xclient.data.l[0]!=x_delete_window_atom )break; /* This event is destroy window event from window manager */ case DestroyNotify:#ifdef X_DEBUG MESSAGE("(DestroyNotify event)\n");#endif gd=x_find_gd(&(event.xkey.window)); if (!gd)break; gd->keyboard_handler(gd,KBD_CLOSE,0); break; case ButtonRelease: /* mouse button was released */ { int a;#ifdef X_DEBUG MESSAGE("(ButtonRelease event)\n"); { unsigned char txt[256]; sprintf(txt,"x=%d y=%d buttons=%d mask=%d\n",event.xbutton.x,event.xbutton.y,event.xbutton.button,event.xbutton.state); MESSAGE(txt); }#endif gd=x_find_gd(&(event.xbutton.window)); if (!gd)break; last_was_mouse=0; switch(event.xbutton.button) { case 1: a=B_LEFT; break; case 3: a=B_RIGHT; break; case 2: a=B_MIDDLE; break; default: goto r_xx; } x_clip_number(&(event.xmotion.x),gd->size.x1,gd->size.x2); x_clip_number(&(event.xmotion.y),gd->size.y1,gd->size.y2); gd->mouse_handler(gd,event.xbutton.x,event.xbutton.y,a|B_UP); r_xx:; } break; case ButtonPress: /* mouse button was pressed */ { int a;#ifdef X_DEBUG MESSAGE("(ButtonPress event)\n"); { unsigned char txt[256]; sprintf(txt,"x=%d y=%d buttons=%d mask=%d\n",event.xbutton.x,event.xbutton.y,event.xbutton.button,event.xbutton.state); MESSAGE(txt); }#endif gd=x_find_gd(&(event.xbutton.window)); if (!gd)break; last_was_mouse=0; switch(event.xbutton.button) { case 1: a=B_LEFT; break; case 3: a=B_RIGHT; break; case 2: a=B_MIDDLE; break; case 4: a=B_WHEELUP; break; case 5: a=B_WHEELDOWN; break; case 6: a=B_WHEELLEFT; break; case 7: a=B_WHEELRIGHT; break; default: goto p_xx; } x_clip_number(&(event.xmotion.x),gd->size.x1,gd->size.x2); x_clip_number(&(event.xmotion.y),gd->size.y1,gd->size.y2); gd->mouse_handler(gd,event.xbutton.x,event.xbutton.y,a|(a != B_WHEELDOWN && a != B_WHEELUP && a != B_WHEELLEFT && a != B_WHEELRIGHT ? B_DOWN : B_MOVE)); p_xx:; } break; case MotionNotify: /* pointer moved */ {#ifdef X_DEBUG MESSAGE("(MotionNotify event)\n"); { unsigned char txt[256]; sprintf(txt,"x=%d y=%d\n",event.xmotion.x,event.xmotion.y); MESSAGE(txt); }#endif /* just sign, that this was mouse event */ last_was_mouse=1; last_event=event; } break; /* read clipboard */ case SelectionNotify:#ifdef X_DEBUG MESSAGE("xselectionnotify\n");#endif /* handled in x_get_clipboard_text */ break;/* This long code must be here in order to implement copying of stuff into the clipboard */ case SelectionRequest: { selection_request(&event); } break; case MapNotify: XFlush (x_display); break; default:#ifdef X_DEBUG { unsigned char txt[256]; sprintf(txt,"event=%d\n",event.type); MESSAGE(txt); }#endif break; } } if (last_was_mouse) /* lthat was end of mouse move block --- call mouse handler */ { int a,b; last_was_mouse=0;#ifdef X_DEBUG MESSAGE("(MotionNotify event)\n"); /* { unsigned char txt[256]; sprintf(txt,"x=%d y=%d\n",last_event.xmotion.x,last_event.xmotion.y); MESSAGE(txt); } */#endif gd=x_find_gd(&(last_event.xmotion.window)); if (!gd)goto ret; a=B_LEFT; b=B_MOVE; if ((last_event.xmotion.state)&Button1Mask) { a=B_LEFT; b=B_DRAG;#ifdef X_DEBUG MESSAGE("left button/drag\n");#endif } if ((last_event.xmotion.state)&Button2Mask) { a=B_MIDDLE; b=B_DRAG;#ifdef X_DEBUG MESSAGE("middle button/drag\n");#endif } if ((last_event.xmotion.state)&Button3Mask) { a=B_RIGHT; b=B_DRAG;#ifdef X_DEBUG MESSAGE("right button/drag\n");#endif } x_clip_number(&(last_event.xmotion.x),gd->size.x1,gd->size.x2); x_clip_number(&(last_event.xmotion.y),gd->size.y1,gd->size.y2); gd->mouse_handler(gd,last_event.xmotion.x,last_event.xmotion.y,a|b); } ret:;#ifdef SC_DEBUG MESSAGE("x_process_event end\n");#endif}/* returns pointer to string with driver parameter or NULL */static unsigned char * x_get_driver_param(void){ return x_driver_param;}/* initiate connection with X server */static unsigned char * x_init_driver(unsigned char *param, unsigned char *display){ XGCValues gcv; XSetWindowAttributes win_attr; XVisualInfo vinfo; int misordered=-1; n_wins=0;#if defined(HAVE_SETLOCALE) && defined(LC_CTYPE) setlocale(LC_CTYPE,"");#endif#ifdef X_DEBUG { unsigned char txt[256]; sprintf(txt,"x_init_driver(%s, %s)\n",param, display); MESSAGE(txt); }#endif x_input_encoding=-1;#if defined(HAVE_NL_LANGINFO) && defined(HAVE_LANGINFO_H) && defined(CODESET) { unsigned char *cp; cp=nl_langinfo(CODESET); x_input_encoding=get_cp_index(cp); }#endif if (x_input_encoding<0)x_driver.flags|=GD_NEED_CODEPAGE; if (!display||!(*display))display=0;/* X documentation says on XOpenDisplay(display_name) : display_name Specifies the hardware display name, which determines the dis- play and communications domain to be used. On a POSIX-confor- mant system, if the display_name is NULL, it defaults to the value of the DISPLAY environment variable. But OS/2 has problems when display_name is NULL ...*/ if (!display)display=getenv("DISPLAY");#ifndef __linux__ /* on Linux, do not assume XWINDOW present if $DISPLAY is not set --- rather open links on svgalib or framebuffer console */ if (!display)display=":0.0"; /* needed for MacOS X */#endif x_display=XOpenDisplay(display); if (!x_display) { unsigned char *err=init_str(); int l=0; add_to_str(&err,&l,"Can't open display \""); add_to_str(&err,&l,display?display:(unsigned char *)"(null)"); add_to_str(&err,&l,"\"\n"); return err; } x_hash_table_init(); x_bitmap_bit_order=BitmapBitOrder(x_display); x_fd=XConnectionNumber(x_display); x_screen=DefaultScreen(x_display); x_display_height=DisplayHeight(x_display,x_screen); x_display_width=DisplayWidth(x_display,x_screen); x_root_window=RootWindow(x_display,x_screen); x_default_window_width=x_display_width-50; x_default_window_height=x_display_height-50; x_driver_param=NULL; if (param) { char *p, *e, *f; int w,h; x_driver_param=stracpy(param); for (p=x_driver_param;(*p)&&(*p)!='x'&&(*p)!='X';p++); if (!(*p))goto done; *p=0; w=strtoul(x_driver_param,&e,10); h=strtoul(p+1,&f,10); if (!(*e)&&!(*f)&&w&&h){x_default_window_width=w;x_default_window_height=h;} *p='x'; done:; } /* find best visual */ {#define DEPTHS 5#define CLASSES 2 int depths[DEPTHS]={24, 16, 15, 8, 4}; int classes[CLASSES]={TrueColor, PseudoColor}; /* FIXME: dodelat DirectColor */ int a,b; for (a=0;a<DEPTHS;a++) for (b=0;b<CLASSES;b++) { if (XMatchVisualInfo(x_display, x_screen,depths[a],classes[b], &vinfo)) { x_default_visual=vinfo.visual; x_depth=vinfo.depth; /* determine bytes per pixel */ { XPixmapFormatValues *pfm; int n,i; pfm=XListPixmapFormats(x_display,&n); for (i=0;i<n;i++) if (pfm[i].depth==x_depth) { x_bitmap_bpp=pfm[i].bits_per_pixel<8?1:((pfm[i].bits_per_pixel)>>3); x_bitmap_scanline_pad=(pfm[i].scanline_pad)>>3; XFree(pfm); goto bytes_per_pixel_found; } if(n) XFree(pfm); continue; }bytes_per_pixel_found: /* test misordered flag */ switch(x_depth) { case 4: case 8: if (x_bitmap_bpp!=1)break; if (vinfo.red_mask>=vinfo.green_mask&&vinfo.green_mask>=vinfo.blue_mask) { misordered=0; goto visual_found; } break; case 15: case 16: if (x_bitmap_bpp!=2)break; if (x_bitmap_bit_order==MSBFirst&&vinfo.red_mask>vinfo.green_mask&&vinfo.green_mask>vinfo.blue_mask) { misordered=256; goto visual_found; } if (x_bitmap_bit_order==MSBFirst)break; if (vinfo.red_mask>vinfo.green_mask&&vinfo.green_mask>vinfo.blue_mask) { misordered=0; goto visual_found; } break; case 24: if (x_bitmap_bpp!=3&&x_bitmap_bpp!=4) break; if (vinfo.red_mask<vinfo.green_mask&&vinfo.green_mask<vinfo.blue_mask) { misordered=256; goto visual_found; } if (x_bitmap_bit_order==MSBFirst&&vinfo.red_mask>vinfo.green_mask&&vinfo.green_mask>vinfo.blue_mask) { misordered=512; goto visual_found; } if (vinfo.red_mask>vinfo.green_mask&&vinfo.green_mask>vinfo.blue_mask) { misordered=0; goto visual_found; } break; } } } x_free_hash_table(); if (x_driver_param) mem_free(x_driver_param); return stracpy("No supported color depth found.\n");visual_found:; } x_driver.depth=0; x_driver.depth|=x_bitmap_bpp; x_driver.depth|=x_depth<<3; x_driver.depth|=misordered; /* check if depth is sane */ switch (x_driver.depth) { case 33: case 65: case 122: case 130: case 451: case 195: case 196: case 378:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -