📄 xwin.c
字号:
value = MAKECOLOUR(pc); BOUT16(out, value); } } } else { if (g_host_be) { while (out < end) { pixel = *(data++); BSWAP16(pixel); SPLITCOLOUR16(pixel, pc); value = MAKECOLOUR(pc); LOUT16(out, value); } } else { while (out < end) { pixel = *(data++); SPLITCOLOUR16(pixel, pc); value = MAKECOLOUR(pc); LOUT16(out, value); } } }}static voidtranslate16to24(const uint16 * data, uint8 * out, uint8 * end){ uint32 value; uint16 pixel; PixelColour pc; if (g_compatible_arch) { /* *INDENT-OFF* */ REPEAT3 ( pixel = *(data++); SPLITCOLOUR16(pixel, pc); *(out++) = pc.blue; *(out++) = pc.green; *(out++) = pc.red; ) /* *INDENT-ON* */ } else if (g_xserver_be) { if (g_host_be) { while (out < end) { pixel = *(data++); BSWAP16(pixel); SPLITCOLOUR16(pixel, pc); value = MAKECOLOUR(pc); BOUT24(out, value); } } else { while (out < end) { pixel = *(data++); SPLITCOLOUR16(pixel, pc); value = MAKECOLOUR(pc); BOUT24(out, value); } } } else { if (g_host_be) { while (out < end) { pixel = *(data++); BSWAP16(pixel); SPLITCOLOUR16(pixel, pc); value = MAKECOLOUR(pc); LOUT24(out, value); } } else { while (out < end) { pixel = *(data++); SPLITCOLOUR16(pixel, pc); value = MAKECOLOUR(pc); LOUT24(out, value); } } }}static voidtranslate16to32(const uint16 * data, uint8 * out, uint8 * end){ uint16 pixel; uint32 value; PixelColour pc; if (g_compatible_arch) { /* *INDENT-OFF* */ REPEAT4 ( pixel = *(data++); SPLITCOLOUR16(pixel, pc); *(out++) = pc.blue; *(out++) = pc.green; *(out++) = pc.red; *(out++) = 0; ) /* *INDENT-ON* */ } else if (g_xserver_be) { if (g_host_be) { while (out < end) { pixel = *(data++); BSWAP16(pixel); SPLITCOLOUR16(pixel, pc); value = MAKECOLOUR(pc); BOUT32(out, value); } } else { while (out < end) { pixel = *(data++); SPLITCOLOUR16(pixel, pc); value = MAKECOLOUR(pc); BOUT32(out, value); } } } else { if (g_host_be) { while (out < end) { pixel = *(data++); BSWAP16(pixel); SPLITCOLOUR16(pixel, pc); value = MAKECOLOUR(pc); LOUT32(out, value); } } else { while (out < end) { pixel = *(data++); SPLITCOLOUR16(pixel, pc); value = MAKECOLOUR(pc); LOUT32(out, value); } } }}static voidtranslate24to16(const uint8 * data, uint8 * out, uint8 * end){ uint32 pixel = 0; uint16 value; PixelColour pc; while (out < end) { pixel = *(data++) << 16; pixel |= *(data++) << 8; pixel |= *(data++); SPLITCOLOUR24(pixel, pc); value = MAKECOLOUR(pc); if (g_xserver_be) { BOUT16(out, value); } else { LOUT16(out, value); } }}static voidtranslate24to24(const uint8 * data, uint8 * out, uint8 * end){ uint32 pixel; uint32 value; PixelColour pc; if (g_xserver_be) { while (out < end) { pixel = *(data++) << 16; pixel |= *(data++) << 8; pixel |= *(data++); SPLITCOLOUR24(pixel, pc); value = MAKECOLOUR(pc); BOUT24(out, value); } } else { while (out < end) { pixel = *(data++) << 16; pixel |= *(data++) << 8; pixel |= *(data++); SPLITCOLOUR24(pixel, pc); value = MAKECOLOUR(pc); LOUT24(out, value); } }}static voidtranslate24to32(const uint8 * data, uint8 * out, uint8 * end){ uint32 pixel; uint32 value; PixelColour pc; if (g_compatible_arch) { /* *INDENT-OFF* */#ifdef NEED_ALIGN REPEAT4 ( *(out++) = *(data++); *(out++) = *(data++); *(out++) = *(data++); *(out++) = 0; )#else REPEAT4 ( /* Only read 3 bytes. Reading 4 bytes means reading beyond buffer. */ *((uint32 *) out) = *((uint16 *) data) + (*((uint8 *) data + 2) << 16); out += 4; data += 3; )#endif /* *INDENT-ON* */ } else if (g_xserver_be) { 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. */ /* todo */ if (g_server_depth == 32 && g_depth == 24) { return data; } 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;}static voidxwin_refresh_pointer_map(void){ unsigned char phys_to_log_map[sizeof(g_pointer_log_to_phys_map)]; int i, pointer_buttons; pointer_buttons = XGetPointerMapping(g_display, phys_to_log_map, sizeof(phys_to_log_map)); if (pointer_buttons > sizeof(phys_to_log_map)) pointer_buttons = sizeof(phys_to_log_map); /* if multiple physical buttons map to the same logical button, then * use the lower numbered physical one */ for (i = pointer_buttons - 1; i >= 0; i--) { /* a user could specify arbitrary values for the logical button * number, ignore any that are abnormally large */ if (phys_to_log_map[i] > sizeof(g_pointer_log_to_phys_map)) continue; g_pointer_log_to_phys_map[phys_to_log_map[i] - 1] = i + 1; }}RD_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 RD_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]; RD_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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -