📄 xwin.c
字号:
while (out < end) { pixel = *(data++) << 16; pixel |= *(data++) << 8; pixel |= *(data++); SPLITCOLOUR24(pixel, pc); value = MAKECOLOUR(pc); BOUT32(out, value); } } else { while (out < end) { pixel = *(data++) << 16; pixel |= *(data++) << 8; pixel |= *(data++); SPLITCOLOUR24(pixel, pc); value = MAKECOLOUR(pc); LOUT32(out, value); } }}static uint8 *translate_image(int width, int height, uint8 * data){ int size; uint8 *out; uint8 *end; /* If RDP depth and X Visual depths match, and arch(endian) matches, no need to translate: just return data. Note: select_visual should've already ensured g_no_translate is only set for compatible depths, but the RDP depth might've changed during connection negotiations. */ if (g_no_translate_image) { if ((g_depth == 15 && g_server_depth == 15) || (g_depth == 16 && g_server_depth == 16) || (g_depth == 24 && g_server_depth == 24)) return data; } size = width * height * (g_bpp / 8); out = (uint8 *) xmalloc(size); end = out + size; switch (g_server_depth) { case 24: switch (g_bpp) { case 32: translate24to32(data, out, end); break; case 24: translate24to24(data, out, end); break; case 16: translate24to16(data, out, end); break; } break; case 16: switch (g_bpp) { case 32: translate16to32((uint16 *) data, out, end); break; case 24: translate16to24((uint16 *) data, out, end); break; case 16: translate16to16((uint16 *) data, out, end); break; } break; case 15: switch (g_bpp) { case 32: translate15to32((uint16 *) data, out, end); break; case 24: translate15to24((uint16 *) data, out, end); break; case 16: translate15to16((uint16 *) data, out, end); break; } break; case 8: switch (g_bpp) { case 8: translate8to8(data, out, end); break; case 16: translate8to16(data, out, end); break; case 24: translate8to24(data, out, end); break; case 32: translate8to32(data, out, end); break; } break; } return out;}BOOLget_key_state(unsigned int state, uint32 keysym){ int modifierpos, key, keysymMask = 0; int offset; KeyCode keycode = XKeysymToKeycode(g_display, keysym); if (keycode == NoSymbol) return False; for (modifierpos = 0; modifierpos < 8; modifierpos++) { offset = g_mod_map->max_keypermod * modifierpos; for (key = 0; key < g_mod_map->max_keypermod; key++) { if (g_mod_map->modifiermap[offset + key] == keycode) keysymMask |= 1 << modifierpos; } } return (state & keysymMask) ? True : False;}static voidcalculate_shifts(uint32 mask, int *shift_r, int *shift_l){ *shift_l = ffs(mask) - 1; mask >>= *shift_l; *shift_r = 8 - ffs(mask & ~(mask >> 1));}/* Given a mask of a colour channel (e.g. XVisualInfo.red_mask), calculates the bits-per-pixel of this channel (a.k.a. colour weight). */static unsignedcalculate_mask_weight(uint32 mask){ unsigned weight = 0; do { weight += (mask & 1); } while (mask >>= 1); return weight;}static BOOLselect_visual(int screen_num){ XPixmapFormatValues *pfm; int pixmap_formats_count, visuals_count; XVisualInfo *vmatches = NULL; XVisualInfo template; int i; unsigned red_weight, blue_weight, green_weight; red_weight = blue_weight = green_weight = 0; if (g_server_depth == -1) { g_server_depth = DisplayPlanes(g_display, DefaultScreen(g_display)); } pfm = XListPixmapFormats(g_display, &pixmap_formats_count); if (pfm == NULL) { error("Unable to get list of pixmap formats from display.\n"); XCloseDisplay(g_display); return False; } /* Search for best TrueColor visual */ template.class = TrueColor; template.screen = screen_num; vmatches = XGetVisualInfo(g_display, VisualClassMask | VisualScreenMask, &template, &visuals_count); g_visual = NULL; g_no_translate_image = False; g_compatible_arch = False; if (vmatches != NULL) { for (i = 0; i < visuals_count; ++i) { XVisualInfo *visual_info = &vmatches[i]; BOOL can_translate_to_bpp = False; int j; /* Try to find a no-translation visual that'll allow us to use RDP bitmaps directly as ZPixmaps. */ if (!g_xserver_be && (((visual_info->depth == 15) && /* R5G5B5 */ (visual_info->red_mask == 0x7c00) && (visual_info->green_mask == 0x3e0) && (visual_info->blue_mask == 0x1f)) || ((visual_info->depth == 16) && /* R5G6B5 */ (visual_info->red_mask == 0xf800) && (visual_info->green_mask == 0x7e0) && (visual_info->blue_mask == 0x1f)) || ((visual_info->depth == 24) && /* R8G8B8 */ (visual_info->red_mask == 0xff0000) && (visual_info->green_mask == 0xff00) && (visual_info->blue_mask == 0xff)))) { g_visual = visual_info->visual; g_depth = visual_info->depth; g_compatible_arch = !g_host_be; g_no_translate_image = (visual_info->depth == g_server_depth); if (g_no_translate_image) /* We found the best visual */ break; } else { g_compatible_arch = False; } if (visual_info->depth > 24) { /* Avoid 32-bit visuals and likes like the plague. They're either untested or proven to work bad (e.g. nvidia's Composite 32-bit visual). Most implementation offer a 24-bit visual anyway. */ continue; } /* Only care for visuals, for whose BPPs (not depths!) we have a translateXtoY function. */ for (j = 0; j < pixmap_formats_count; ++j) { if (pfm[j].depth == visual_info->depth) { if ((pfm[j].bits_per_pixel == 16) || (pfm[j].bits_per_pixel == 24) || (pfm[j].bits_per_pixel == 32)) { can_translate_to_bpp = True; } break; } } /* Prefer formats which have the most colour depth. We're being truly aristocratic here, minding each weight on its own. */ if (can_translate_to_bpp) { unsigned vis_red_weight = calculate_mask_weight(visual_info->red_mask); unsigned vis_green_weight = calculate_mask_weight(visual_info->green_mask); unsigned vis_blue_weight = calculate_mask_weight(visual_info->blue_mask); if ((vis_red_weight >= red_weight) && (vis_green_weight >= green_weight) && (vis_blue_weight >= blue_weight)) { red_weight = vis_red_weight; green_weight = vis_green_weight; blue_weight = vis_blue_weight; g_visual = visual_info->visual; g_depth = visual_info->depth; } } } XFree(vmatches); } if (g_visual != NULL) { g_owncolmap = False; calculate_shifts(g_visual->red_mask, &g_red_shift_r, &g_red_shift_l); calculate_shifts(g_visual->green_mask, &g_green_shift_r, &g_green_shift_l); calculate_shifts(g_visual->blue_mask, &g_blue_shift_r, &g_blue_shift_l); } else { template.class = PseudoColor; template.depth = 8; template.colormap_size = 256; vmatches = XGetVisualInfo(g_display, VisualClassMask | VisualDepthMask | VisualColormapSizeMask, &template, &visuals_count); if (vmatches == NULL) { error("No usable TrueColor or PseudoColor visuals on this display.\n"); XCloseDisplay(g_display); XFree(pfm); return False; } /* we use a colourmap, so the default visual should do */ g_owncolmap = True; g_visual = vmatches[0].visual; g_depth = vmatches[0].depth; } g_bpp = 0; for (i = 0; i < pixmap_formats_count; ++i) { XPixmapFormatValues *pf = &pfm[i]; if (pf->depth == g_depth) { g_bpp = pf->bits_per_pixel; if (g_no_translate_image) { switch (g_server_depth) { case 15: case 16: if (g_bpp != 16) g_no_translate_image = False; break; case 24: /* Yes, this will force image translation on most modern servers which use 32 bits for R8G8B8. */ if (g_bpp != 24) g_no_translate_image = False; break; default: g_no_translate_image = False; break; } } /* Pixmap formats list is a depth-to-bpp mapping -- there's just a single entry for every depth, so we can safely break here */ break; } } XFree(pfm); pfm = NULL; return True;}static XErrorHandler g_old_error_handler;static interror_handler(Display * dpy, XErrorEvent * eev){ if ((eev->error_code == BadMatch) && (eev->request_code == X_ConfigureWindow)) { fprintf(stderr, "Got \"BadMatch\" when trying to restack windows.\n"); fprintf(stderr, "This is most likely caused by a broken window manager (commonly KWin).\n"); return 0; } return g_old_error_handler(dpy, eev);}BOOLui_init(void){ int screen_num; g_display = XOpenDisplay(NULL); if (g_display == NULL) { error("Failed to open display: %s\n", XDisplayName(NULL)); return False; } { uint16 endianess_test = 1; g_host_be = !(BOOL) (*(uint8 *) (&endianess_test)); } g_old_error_handler = XSetErrorHandler(error_handler); g_xserver_be = (ImageByteOrder(g_display) == MSBFirst); screen_num = DefaultScreen(g_display); g_x_socket = ConnectionNumber(g_display); g_screen = ScreenOfDisplay(g_display, screen_num); g_depth = DefaultDepthOfScreen(g_screen); if (!select_visual(screen_num)) return False; if (g_no_translate_image) { DEBUG(("Performance optimization possible: avoiding image translation (colour depth conversion).\n")); } if (g_server_depth > g_bpp) { warning("Remote desktop colour depth %d higher than display colour depth %d.\n", g_server_depth, g_bpp); } DEBUG(("RDP depth: %d, display depth: %d, display bpp: %d, X server BE: %d, host BE: %d\n", g_server_depth, g_depth, g_bpp, g_xserver_be, g_host_be)); if (!g_owncolmap) { g_xcolmap = XCreateColormap(g_display, RootWindowOfScreen(g_screen), g_visual, AllocNone); if (g_depth <= 8) warning("Display colour depth is %d bit: you may want to use -C for a private colourmap.\n", g_depth); } if ((!g_ownbackstore) && (DoesBackingStore(g_screen) != Always)) { warning("External BackingStore not available. Using internal.\n"); g_ownbackstore = True; } /* * Determine desktop size */ if (g_fullscreen) { g_width = WidthOfScreen(g_screen); g_height = HeightOfScreen(g_screen); g_using_full_workarea = True; } else if (g_width < 0) { /* Percent of screen */ if (-g_width >= 100) g_using_full_workarea = True; g_height = HeightOfScreen(g_screen) * (-g_width) / 100; g_width = WidthOfScreen(g_screen) * (-g_width) / 100; } else if (g_width == 0) { /* Fetch geometry from _NET_WORKAREA */ uint32 x, y, cx, cy; if (get_current_workarea(&x, &y, &cx, &cy) == 0) { g_width = cx; g_height = cy; g_using_full_workarea = True; } else { warning("Failed to get workarea: probably your window manager does not support extended hints\n"); g_width = WidthOfScreen(g_screen); g_height = HeightOfScreen(g_screen); } } /* make sure width is a multiple of 4 */ g_width = (g_width + 3) & ~3; g_mod_map = XGetModifierMapping(g_display); xkeymap_init(); if (g_enable_compose) g_IM = XOpenIM(g_display, NULL, NULL, NULL); xclip_init(); ewmh_init(); if (g_seamless_rdp) seamless_init(); DEBUG_RDP5(("server bpp %d client bpp %d depth %d\n", g_server_depth, g_bpp, g_depth)); return True;}voidui_deinit(void){ while (g_seamless_windows) { XDestroyWindow(g_display, g_seamless_windows->wnd); sw_remove_window(g_seamless_windows); } xclip_deinit(); if (g_IM != NULL) XCloseIM(g_IM); if (g_null_cursor != NULL) ui_destroy_cursor(g_null_cursor); XFreeModifiermap(g_mod_map); if (g_ownbackstore) XFreePixmap(g_display, g_backstore); XFreeGC(g_display, g_gc); XCloseDisplay(g_display); g_display = NULL;}static voidget_window_attribs(XSetWindowAttributes * attribs){ attribs->background_pixel = BlackPixelOfScreen(g_screen); attribs->background_pixel = WhitePixelOfScreen(g_screen); attribs->border_pixel = WhitePixelOfScreen(g_screen); attribs->backing_store = g_ownbackstore ? NotUseful : Always; attribs->override_redirect = g_fullscreen; attribs->colormap = g_xcolmap;}static voidget_input_mask(long *input_mask){ *input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | VisibilityChangeMask | FocusChangeMask | StructureNotifyMask; if (g_sendmotion) *input_mask |= PointerMotionMask; if (g_ownbackstore) *input_mask |= ExposureMask; if (g_fullscreen || g_grab_keyboard) *input_mask |= EnterWindowMask; if (g_grab_keyboard) *input_mask |= LeaveWindowMask;}BOOLui_create_window(void){ uint8 null_pointer_mask[1] = { 0x80 }; uint8 null_pointer_data[24] = { 0x00 }; XSetWindowAttributes attribs; XClassHint *classhints; XSizeHints *sizehints; int wndwidth, wndheight; long input_mask, ic_input_mask; XEvent xevent; wndwidth = g_fullscreen ? WidthOfScreen(g_screen) : g_width; wndheight = g_fullscreen ? HeightOfScreen(g_screen) : g_height; /* Handle -x-y portion of geometry string */ if (g_xpos < 0 || (g_xpos == 0 && (g_pos & 2))) g_xpos = WidthOfScreen(g_screen) + g_xpos - g_width; if (g_ypos < 0 || (g_ypos == 0 && (g_pos & 4))) g_ypos = HeightOfScreen(g_screen) + g_ypos - g_height; get_window_attribs(&attribs); g_wnd = XCreateWindow(g_display, RootWindowOfScreen(g_screen), g_xpos, g_ypos, wndwidth, wndheight, 0, g_depth, InputOutput, g_visual, CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap | CWBorderPixel, &attribs); if (g_gc == NULL) { g_gc = XCreateGC(g_display, g_wnd, 0, NULL); ui_reset_clip(); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -