📄 video_output_x11.c
字号:
if(dpy_str != NULL) { while(cfg_display) { if(cfg_display->name != NULL) { if(!strcmp(cfg_display->name, dpy_str)) { break; } } else { tmp_display = cfg_display; } cfg_display = cfg_display->next; } if(cfg_display == NULL) { NOTE("using default config for '%s'\n", dpy_str); cfg_display = tmp_display; } } DpyInfoSetEWMHFullscreen(cfg_display->ewmh_fullscreen); DpyInfoSetUserGeometry(dpy, screen_nr, cfg_display->geometry.width, cfg_display->geometry.height); DpyInfoSetUserResolution(dpy, screen_nr, cfg_display->resolution.horizontal_pixels, cfg_display->resolution.vertical_pixels); orig = DpyInfoOriginX11; if(cfg_display->geometry_src) { if(!strcmp(cfg_display->geometry_src, "user")) { orig = DpyInfoOriginUser; } } orig = DpyInfoSetUpdateGeometry(dpy, screen_nr, orig); { char *orig_str; switch(orig) { case DpyInfoOriginX11: orig_str = "X11"; break; case DpyInfoOriginUser: orig_str = "user"; break; default: orig_str = ""; } NOTE("Using '%s' as source for geometry\n", orig_str); } orig = DpyInfoOriginX11; if(cfg_display->resolution_src) { if(!strcmp(cfg_display->resolution_src, "user")) { orig = DpyInfoOriginUser; } else if(!strcmp(cfg_display->resolution_src, "XF86VidMode")) { orig = DpyInfoOriginXF86VidMode; } else if(!strcmp(cfg_display->resolution_src, "Xinerama")) { orig = DpyInfoOriginXinerama; } } orig = DpyInfoSetUpdateResolution(dpy, screen_nr, orig); { char *orig_str; switch(orig) { case DpyInfoOriginX11: orig_str = "X11"; break; case DpyInfoOriginXF86VidMode: orig_str = "XF86VidMode"; break; case DpyInfoOriginXinerama: orig_str = "Xinerama"; break; case DpyInfoOriginUser: orig_str = "user"; break; default: orig_str = ""; } NOTE("Using '%s' as source for resolution\n", orig_str); } DpyInfoUpdateGeometry(dpy, screen_nr); DpyInfoUpdateResolution(dpy, screen_nr, 0, 0); /* Query and calculate the displays aspect rate. */ { int width, height; int horizontal_pixels, vertical_pixels; int dpy_sar_frac_n, dpy_sar_frac_d; DpyInfoGetGeometry(dpy, screen_nr, &width, &height); DpyInfoGetResolution(dpy, screen_nr, &horizontal_pixels, &vertical_pixels); DpyInfoGetSAR(dpy, screen_nr, &dpy_sar_frac_n, &dpy_sar_frac_d); NOTE("Display w: %d, h: %d, hp: %d, vp: %d\n", width, height, horizontal_pixels, vertical_pixels); NOTE("Display sar: %d/%d = %f\n", dpy_sar_frac_n, dpy_sar_frac_d, (double)dpy_sar_frac_n/(double)dpy_sar_frac_d); } if(cfg_display->initial_state.fullscreen == 1) { zoom_mode = ZoomModeFullScreen; } else { zoom_mode = ZoomModeResizeAllowed; }}void display_reset(void){ //DNOTE("DEBUG[vo]: display_reset()\n"); if(use_xv) { XShmDetach(mydisplay, &shm_info); } else if(use_xshm) { XShmDetach(mydisplay, &shm_info); XDestroyImage(window.ximage); if(shmdt(shm_info.shmaddr) == -1) { FATAL("%s", "display_reset\n"); perror("shmdt"); exit(1); } if(shmctl(shm_info.shmid, IPC_RMID, 0) == -1) { FATAL("%s", "display_reset\n"); perror("shmctl"); exit(1); } memset(&shm_info, 0, sizeof(XShmSegmentInfo)); }}void display_init(int padded_width, int padded_height, int picture_buffer_shmid, char *picture_buffer_addr){ static int initialized = 0; Screen *scr; XSizeHints *size_hints; XClassHint *class_hints; char *string; XEvent xev; XGCValues xgcv; Colormap theCmap; XWindowAttributes attribs; XSetWindowAttributes xswa; unsigned long xswamask; XTextProperty window_name_prop, icon_name_prop; XVisualInfo *vinfo_list; int vinfo_nitems; long vinfo_mask; XVisualInfo vinfo_template; scale.image_width = padded_width; scale.image_height = padded_height; if(!initialized) {#ifdef HAVE_MLIB char *scalemode_str; if(getenv("USE_FFB2_YUV2RGB")) { use_ffb2_yuv2rgb = 1; use_ffb2_rgb = 0; } else if(getenv("USE_FFB2_RGB")) { use_ffb2_yuv2rgb = 0; use_ffb2_rgb = 1; } if((scalemode_str = getenv("OGLE_MLIB_SCALEMODE"))) { if(!strcmp(scalemode_str, "NEAREST")) { scalemode = MLIB_NEAREST; } else if(!strcmp(scalemode_str, "BILINEAR")) { scalemode = MLIB_BILINEAR; } else if(!strcmp(scalemode_str, "BICUBIC")) { scalemode = MLIB_BICUBIC; } else if(!strcmp(scalemode_str, "BICUBIC2")) { scalemode = MLIB_BICUBIC2; } }#endif /* HAVE_MLIB */ { char *env_val; if((env_val = getenv("OGLE_USE_XV"))) { if(!strcmp(env_val, "0")) { use_xv = 0; } } if((env_val = getenv("OGLE_USE_XSHM"))) { if(!strcmp(env_val, "0")) { use_xshm = 0; } } } mydisplay = XOpenDisplay(NULL); if(mydisplay == NULL) { FATAL("%s", "Cannot open display\n"); exit(1); } screen_nr = DefaultScreen(mydisplay); scr = XDefaultScreenOfDisplay(mydisplay); init_config(mydisplay); /* Assume (for now) that the window will be the same size as the source. */ scale.image_width = padded_width; scale.image_height = padded_height; /* TODO search for correct visual ... */ /* Make the window */ XGetWindowAttributes(mydisplay, DefaultRootWindow(mydisplay), &attribs); color_depth = attribs.depth; if(color_depth != 15 && color_depth != 16 && color_depth != 24 && color_depth != 32) { ERROR("%s", "Only 15, 16, 24, and 32bpp supported. Trying 24bpp!\n"); color_depth = 24; } vinfo_template.screen = screen_nr; vinfo_template.depth = color_depth; vinfo_template.class = TrueColor; vinfo_mask = VisualScreenMask | VisualDepthMask | VisualClassMask; vinfo_list = XGetVisualInfo(mydisplay, vinfo_mask, &vinfo_template, &vinfo_nitems); if(vinfo_list == NULL) { FATAL("%s", "No suitable visual found\n"); } else { int n = 0;#if USE_SOLARIS_XMU double gamma; for(n = 0; n < vinfo_nitems; n++) { if(XSolarisGetVisualGamma(mydisplay, screen_nr, vinfo_list[n].visual, &gamma) == Success) { if(gamma == 1.0) { // choose a visual with a gamma that can be changed break; } } } if(n == vinfo_nitems) { NOTE("%s", "No visual with adjustable gamma\n"); n = 0; }#endif NOTE("Found %d matching visuals, using visual id: %x\n", vinfo_nitems, (unsigned)vinfo_list[n].visualid); vinfo = vinfo_list[n]; XFree(vinfo_list); } size_hints = XAllocSizeHints(); size_hints->x = 0; size_hints->y = 0; size_hints->width = scale.image_width; size_hints->height = scale.image_height; size_hints->flags = /*PPosition |*/ PSize; /* If the chosen visual is the default, use the default Colormap, * otherwise it needs a colormap allocated. */ if (vinfo.visual == DefaultVisual(mydisplay, screen_nr) /* && !installColormap */ ) theCmap = DefaultColormap(mydisplay, screen_nr); else { theCmap = XCreateColormap(mydisplay, RootWindow(mydisplay, screen_nr), vinfo.visual, AllocNone); /* ?? XInstallColormap(display, cachedColormap); */ } xswa.background_pixel = 0; xswa.border_pixel = 1; xswa.colormap = theCmap; xswamask = CWBackPixel | CWBorderPixel | CWColormap; window.win_state = WINDOW_STATE_NORMAL; window.win = XCreateWindow(mydisplay, RootWindow(mydisplay,screen_nr), size_hints->x, size_hints->y, size_hints->width, size_hints->height, 0, color_depth, CopyFromParent, vinfo.visual, xswamask, &xswa); XSelectInput(mydisplay, window.win, StructureNotifyMask | ExposureMask | KeyPressMask | ButtonPressMask | KeyReleaseMask | ButtonReleaseMask | PointerMotionMask | PropertyChangeMask); create_transparent_cursor(mydisplay, window.win); /* Tell other applications/the window manager about us. */ class_hints = XAllocClassHint(); class_hints->res_class = "Ogle"; string = &title[0]; snprintf(&title[0], 99, "Ogle"); XStringListToTextProperty(&string, 1, &icon_name_prop); snprintf(&title[0], 99, "Ogle v%s", VERSION); XStringListToTextProperty(&string, 1, &window_name_prop); XSetWMProperties(mydisplay, window.win, &window_name_prop, &icon_name_prop, NULL, 0, size_hints, NULL, class_hints); XFree(class_hints); XFree(size_hints); /* Map window. */ XMapWindow(mydisplay, window.win); /* Wait for map. */ do { XNextEvent(mydisplay, &xev); switch(xev.type) { case ConfigureNotify: // remove all configure notify in queue while(XCheckTypedEvent(mydisplay, ConfigureNotify, &xev) == True); if(xev.xconfigure.window == window.win) { Window dummy_win; window.window_area.width = xev.xconfigure.width; window.window_area.height = xev.xconfigure.height; /* display_adjust_size(current_image, xev.xconfigure.width, xev.xconfigure.height); */ window.video_area.width = scale.image_width; window.video_area.height = scale.image_height; window.video_area.x = (window.window_area.width - window.video_area.width) / 2; window.video_area.y = (window.window_area.height - window.video_area.height) / 2; XTranslateCoordinates(mydisplay, window.win, DefaultRootWindow(mydisplay), 0, 0, &window.window_area.x, &window.window_area.y, &dummy_win); } break; default: break; } } while (xev.type != MapNotify || xev.xmap.event != window.win); XSync(mydisplay, False); /* Create the colormaps. (needed in the PutImage calls) */ mygc = XCreateGC(mydisplay, window.win, 0L, &xgcv); xshmeventbase = XShmGetEventBase(mydisplay); //DNOTE("xshmeventbase: %d\n", xshmeventbase); } /* Try to use XFree86 Xv (X video) extension for display. Sets use_xv to true on success. */ if(use_xv) { display_init_xv(picture_buffer_shmid, picture_buffer_addr, padded_width, padded_height); } /* Try XShm if we didn't have/couldn't use Xv. This also falls back to normal X11 if XShm fails. */ if(!use_xv) { display_init_xshm(); } if(!initialized) { /*** sun ffb2+ ***/ if(use_ffb2_yuv2rgb || use_ffb2_rgb) { fb_fd = open("/dev/fb", O_RDWR); yuyv_fb = (unsigned int *)mmap(NULL, 4*1024*1024, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0x0701a000); if(yuyv_fb == MAP_FAILED) { perror("mmap"); exit(1); } rgb_fb = (uint32_t *)mmap(NULL, 4*2048*1024, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0x05004000); if(rgb_fb == MAP_FAILED) { perror("mmap"); exit(1); } } /*** end sun ffb2+ ***/ /* Let the user know what mode we are running in. */ snprintf(&title[0], 99, "Ogle v%s %s%s", VERSION, use_xv ? "Xv " : "", use_xshm ? "XShm " : ""); XStringListToTextProperty(&string, 1, &window_name_prop); XSetWMName(mydisplay, window.win, &window_name_prop); } initialized = 1;}/* TODO display_change_size needs to be fixed */static void display_change_size(yuv_image_t *img, int new_width, int new_height, int resize_window) { int padded_width = img->info->picture.padded_width; int padded_height = img->info->picture.padded_height; //int alloc_width, alloc_height; int alloc_size; DNOTE("resize: %d, %d\n", new_width, new_height); /* If we cant scale (i.e no Xv or mediaLib) exit give up now. */#ifndef HAVE_MLIB if(!use_xv) return;#endif // Check to not 'reallocate' if the size is the same... if(scale.image_width == new_width && scale.image_height == new_height) { /* Might still need to force a change of the widow size. */ if(resize_window == True) { XResizeWindow(mydisplay, window.win, scale.image_width, scale.image_height); } return; } if(!use_xv) { XSync(mydisplay,True); /* Destroy old display */ if(use_xshm) XShmDetach(mydisplay, &shm_info); XDestroyImage(window.ximage); if(shmdt(shm_info.shmaddr) != 0) { FATAL("%s", "display_change_size"); perror("shmdt"); exit(1); } if(shmctl(shm_info.shmid, IPC_RMID, 0) != 0) { FATAL("%s", "display_change_size"); perror("shmctl"); exit(1); } memset(&shm_info, 0, sizeof(XShmSegmentInfo)); XSync(mydisplay, True); /* Create new display */ window.ximage = XShmCreateImage(mydisplay, vinfo.visual, color_depth, ZPixmap, NULL, &shm_info, new_width, new_height); if(window.ximage == NULL) { FATAL("%s", "XShmCreateImage failed\n"); exit(1); } // or that we allocate less than the minimum size... if(window.ximage->bytes_per_line * window.ximage->height < padded_width * padded_height * 4) { alloc_size = padded_width * padded_height * 4; } else { alloc_size = window.ximage->bytes_per_line * window.ximage->height; } /* Get a shared memory segment */ shm_info.shmid = shmget(IPC_PRIVATE, alloc_size, IPC_CREAT | 0666); if(shm_info.shmid == -1) { FATAL("%s", "display_change_size"); perror("shmget"); exit(1); } /* Attach shared memory segment */ shm_info.shmaddr = (char *) shmat(shm_info.shmid, 0, 0); if(shm_info.shmaddr == ((char *) -1)) { FATAL("%s", "display_change_size"); perror("shmat"); exit(1); } window.ximage->data = shm_info.shmaddr; shm_info.readOnly = False; if(use_xshm) XShmAttach(mydisplay, &shm_info); XSync(mydisplay, False); } /* Save the new size so we know what to scale to. */ scale.image_width = new_width; scale.image_height = new_height; /* Force a change of the window size. */ if(resize_window == True) { XResizeWindow(mydisplay, window.win, scale.image_width, scale.image_height); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -