⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 video_output_x11.c

📁 基于linux的DVD播放器程序
💻 C
📖 第 1 页 / 共 4 页
字号:
static void display_adjust_size(yuv_image_t *current_image,				int given_width, int given_height) {  int dpy_sar_frac_n, dpy_sar_frac_d;  int sar_frac_n, sar_frac_d;   int64_t scale_frac_n, scale_frac_d;  int base_width, base_height, max_width, max_height;  int new_width, new_height;    if(aspect_mode == AspectModeSrcVM) {    sar_frac_n // hack      = aspect_new_frac_d * current_image->info->picture.horizontal_size;    sar_frac_d // hack      = aspect_new_frac_n * current_image->info->picture.vertical_size;  }  /* Use the stream aspect */   else /* if(aspect_mode == AspectModeSrcMPEG) also default */ {    sar_frac_n = current_image->info->picture.sar_frac_n;    sar_frac_d = current_image->info->picture.sar_frac_d;  }  DpyInfoGetSAR(mydisplay, screen_nr, &dpy_sar_frac_n, &dpy_sar_frac_d);  // TODO replace image->sar.. with image->dar  scale_frac_n = (int64_t)dpy_sar_frac_n * (int64_t)sar_frac_d;   scale_frac_d = (int64_t)dpy_sar_frac_d * (int64_t)sar_frac_n;  #ifdef DEBUG  DNOTE("vo: sar: %d/%d, dpy_sar %d/%d, scale: %lld, %lld\n",	sar_frac_n, sar_frac_d,	dpy_sar_frac_n, dpy_sar_frac_d,	scale_frac_n, scale_frac_d); #endif    /*  area_t src_view_area;  switch(view_area_mode) {  case user:    src_view_area = user_view_area;    break;  case all:    src_view_area = picture_size;    break;  case pan_scan:    src_view_area = picture_display_size;    break;  }  */  if(view_area_mode == 0) {    new_view_area.x = 0;    new_view_area.y = 0;    new_view_area.width = current_image->info->picture.horizontal_size;    new_view_area.height = current_image->info->picture.vertical_size;    src_view_area = new_view_area;  } else if(view_area_mode == 1) {    src_view_area = new_view_area;  }	    if(src_view_area.x < 0) {    src_view_area.x = 0;    new_view_area.x = src_view_area.x;  }  if(src_view_area.y < 0) {    src_view_area.y = 0;    new_view_area.y = src_view_area.y;  }  if(src_view_area.x + src_view_area.width >     current_image->info->picture.horizontal_size) {    src_view_area.width =      current_image->info->picture.horizontal_size - src_view_area.x;    new_view_area.width = src_view_area.width;  }  if(src_view_area.y + src_view_area.height >     current_image->info->picture.vertical_size) {    src_view_area.height =      current_image->info->picture.vertical_size - src_view_area.y;    new_view_area.height = src_view_area.height;  }  /* Keep either the height or the width constant. */   if(scale_frac_n > scale_frac_d) {    base_width = (src_view_area.width *		  scale_frac_n) / scale_frac_d;    base_height = src_view_area.height;  } else {    base_width = src_view_area.width;    base_height = (src_view_area.height *		   scale_frac_d) / scale_frac_n;  }  //DNOTE("base %d x %d\n", base_width, base_height);    /* Do we have a predetermined size for the window? */   if(given_width != -1 && given_height != -1 &&     (window.win_state != WINDOW_STATE_FULLSCREEN)) {    max_width  = given_width;    max_height = given_height;  } else {    if(!scale.lock_window_size) {      /* Never make the window bigger than the screen. */      DpyInfoGetResolution(mydisplay, screen_nr, &max_width, &max_height);    } else {      max_width = window.window_area.width;      max_height = window.window_area.height;    }  }  //DNOTE("max %d x %d\n", max_width, max_height);    /* Fill the given area or keep the image at the same zoom level? */  if((window.win_state == WINDOW_STATE_FULLSCREEN)      || (given_width != -1 && given_height != -1)) {    /* Zoom so that the image fill the width. */    /* If the height gets to large it's adjusted/fixed below. */    new_width  = max_width;    new_height = (base_height * max_width) / base_width;  } else {    //DNOTE("using zoom %d / %d\n", scale.zoom_n, scale.zoom_d);    /* Use the provided zoom value. */    new_width  = (base_width  * scale.zoom_n) / scale.zoom_d;    new_height = (base_height * scale.zoom_n) / scale.zoom_d;  }  //DNOTE("new1 %d x %d\n", new_width, new_height);    /* Don't ever make it larger than the max limits. */  if(new_width > max_width) {    new_height = (new_height * max_width) / new_width;    new_width  = max_width;  }  if(new_height > max_height) {    new_width  = (new_width * max_height) / new_height;    new_height = max_height;  }  //DNOTE("new2 %d x %d\n", new_width, new_height);    /* Remeber what zoom level we ended up with. */  if(window.win_state != WINDOW_STATE_FULLSCREEN) {    /* Update zoom values. Use the smalles one. */    if((new_width * base_height) < (new_height * base_width)) {      scale.zoom_n = new_width;      scale.zoom_d = base_width;    } else {      scale.zoom_n = new_height;      scale.zoom_d = base_height;    }    //DNOTE("zoom2 %d / %d\n",     //        scale.zoom_n, scale.zoom_d);  }    /* Don't care about aspect and can't change the window size, use it all. */  if(!scale.preserve_aspect &&     (scale.lock_window_size ||      (window.win_state == WINDOW_STATE_FULLSCREEN))) {    new_width  = max_width;    new_height = max_height;  }    if((scale.lock_window_size ||      (window.win_state == WINDOW_STATE_FULLSCREEN))     || (given_width != -1 && given_height != -1))    display_change_size(current_image, new_width, new_height, False);  else    display_change_size(current_image, new_width, new_height, True);}  static void display_toggle_fullscreen(yuv_image_t *current_image) {  int root_x, root_y;  Window dummy_win;    XTranslateCoordinates(mydisplay, window.win,			DefaultRootWindow(mydisplay), 			0,			0,			&root_x,			&root_y,			&dummy_win);    DpyInfoUpdateResolution(mydisplay, screen_nr, root_x, root_y);    if(window.win_state != WINDOW_STATE_FULLSCREEN) {    ChangeWindowState(mydisplay, window.win, WINDOW_STATE_FULLSCREEN);    window.win_state = WINDOW_STATE_FULLSCREEN;  } else {     ChangeWindowState(mydisplay, window.win, WINDOW_STATE_NORMAL);      window.win_state = WINDOW_STATE_NORMAL;  }  }void clear_borders(void){  // top border  if(window.video_area.y > 0) {    XClearArea(mydisplay, window.win,	       0, 0,	       window.window_area.width,	       window.video_area.y - 0,	       False);  }  // bottom border  if((window.video_area.y + window.video_area.height) <     window.window_area.height) {    XClearArea(mydisplay, window.win,	       0, (window.video_area.y + window.video_area.height),	       window.window_area.width,	       window.window_area.height -	       (window.video_area.y + window.video_area.height),	       False);  }  // left border  if(window.video_area.x > 0) {    XClearArea(mydisplay, window.win,	       0, 0,	       window.video_area.x - 0,	       window.window_area.height,	       False);  }  // right border  if((window.video_area.x + window.video_area.width) <     window.window_area.width) {    XClearArea(mydisplay, window.win,	       (window.video_area.x + window.video_area.width), 0,	       window.window_area.width -	       (window.video_area.x + window.video_area.width),	       window.window_area.height,	       False);  }}void screenshot_mode(int mode){  switch(mode) {  case 0:    screenshot = 1;    break;  case 1:    screenshot_spu = 1;    break;  default:    break;  }}void check_x_events(yuv_image_t *current_image){  XEvent ev;  static clocktime_t prev_time;  clocktime_t cur_time;  static Bool cursor_visible = True;  static Time last_motion;    while(XCheckIfEvent(mydisplay, &ev, true_predicate, NULL) != False) {        switch(ev.type) {    case KeyPress:      // send keypress to whoever wants it      if(input_mask & INPUT_MASK_KeyPress) {	MsgEvent_t m_ev;	KeySym keysym;	XLookupString(&(ev.xkey), NULL, 0, &keysym, NULL);	m_ev.type = MsgEventQInputKeyPress;	m_ev.input.x = (ev.xkey.x - window.video_area.x) *	  src_view_area.width / window.video_area.width +	  src_view_area.x;	m_ev.input.y = (ev.xkey.y - window.video_area.y) *	  src_view_area.height / window.video_area.height +	  src_view_area.y;	m_ev.input.x_root = ev.xkey.x_root;	m_ev.input.y_root = ev.xkey.y_root;	m_ev.input.mod_mask = ev.xkey.state;	m_ev.input.input = keysym;	if(MsgSendEvent(msgq, input_client, &m_ev, IPC_NOWAIT) == -1) {	  switch(errno) {	  case EAGAIN:	    // msgq full, drop message	    break;#ifdef EIDRM	  case EIDRM:#endif	  case EINVAL:	    FATAL("%s", "keypress\n");	    perror("MsgSendEvent");	    display_exit(); //TODO clean up and exit	    break;	  default:	    FATAL("%s", "keypress, couldn't send notification\n");	    perror("MsgSendEvent");	    display_exit(); //TODO clean up and exit	    break;	  }	}      }      break;    case KeyRelease:      // send keyrelease to whoever wants it      if(input_mask & INPUT_MASK_KeyRelease) {	MsgEvent_t m_ev;	KeySym keysym;	XLookupString(&(ev.xkey), NULL, 0, &keysym, NULL);	m_ev.type = MsgEventQInputKeyRelease;	m_ev.input.x = (ev.xkey.x - window.video_area.x) *	  src_view_area.width / window.video_area.width +	  src_view_area.x;	m_ev.input.y = (ev.xkey.y - window.video_area.y) *	  src_view_area.height / window.video_area.height +	  src_view_area.y;	m_ev.input.x_root = ev.xkey.x_root;	m_ev.input.y_root = ev.xkey.y_root;	m_ev.input.mod_mask = ev.xkey.state;	m_ev.input.input = keysym;	if(MsgSendEvent(msgq, input_client, &m_ev, IPC_NOWAIT) == -1) {	  switch(errno) {	  case EAGAIN:	    // msgq full, drop message	    break;#ifdef EIDRM	  case EIDRM:#endif	  case EINVAL:	    FATAL("%s", "keyrelease\n");	    perror("MsgSendEvent");	    display_exit(); //TODO clean up and exit	    break;	  default:	    FATAL("%s", "keyrelease, couldn't send notification\n");	    perror("MsgSendEvent");	    display_exit(); //TODO clean up and exit	    break;	  }	}      }      break;    case ButtonPress:      // send buttonpress to whoever wants it      if(input_mask & INPUT_MASK_ButtonPress) {	MsgEvent_t m_ev;		m_ev.type = MsgEventQInputButtonPress;	m_ev.input.x = (ev.xbutton.x - window.video_area.x)*	  (int)src_view_area.width / (int)window.video_area.width +	  src_view_area.x;	m_ev.input.y = (ev.xbutton.y - window.video_area.y) *	  (int)src_view_area.height / (int)window.video_area.height +	  src_view_area.y;	m_ev.input.x_root = ev.xbutton.x_root;	m_ev.input.y_root = ev.xbutton.y_root;	m_ev.input.mod_mask = ev.xbutton.state;	m_ev.input.input = ev.xbutton.button;	if(ev.xbutton.button == 2) {	  view_area_mode = 2;	  new_view_area.x = m_ev.input.x;	  new_view_area.y = m_ev.input.y;	}	if(MsgSendEvent(msgq, input_client, &m_ev, IPC_NOWAIT) == -1) {	  switch(errno) {	  case EAGAIN:	    // msgq full, drop message	    break;#ifdef EIDRM	  case EIDRM:#endif	  case EINVAL:	    FATAL("%s", "buttonpress\n");	    perror("MsgSendEvent");	    display_exit(); //TODO clean up and exit	    break;	  default:	    FATAL("%s", "buttonpress, couldn't send notification\n");	    perror("MsgSendEvent");	    display_exit(); //TODO clean up and exit	    break;	  }	}      }            if(cursor_visible == False) {	restore_cursor(mydisplay, window.win);	cursor_visible = True;      }      clocktime_get(&prev_time);      break;    case ButtonRelease:      // send buttonrelease to whoever wants it      if(1/*input_mask & INPUT_MASK_ButtonRelease*/) {	MsgEvent_t m_ev;		m_ev.type = MsgEventQInputButtonRelease;	m_ev.input.x = (ev.xbutton.x - window.video_area.x)*	  (int)src_view_area.width / (int)window.video_area.width +	  src_view_area.x;	m_ev.input.y = (ev.xbutton.y - window.video_area.y) *	  (int)src_view_area.height / (int)window.video_area.height +	  src_view_area.y;	m_ev.input.x_root = ev.xbutton.x_root;	m_ev.input.y_root = ev.xbutton.y_root;	m_ev.input.mod_mask = ev.xbutton.state;	m_ev.input.input = ev.xbutton.button;	if(ev.xbutton.button == 2) {	  int w, h;	  w = m_ev.input.x - new_view_area.x;	  h = m_ev.input.y - new_view_area.y;	  if(w < 1 || h < 1) {	    view_area_mode = 0;	  } else {	    new_view_area.width = w;	    new_view_area.height = h; 	    view_area_mode = 1;	  }	}	      if(input_mask & INPUT_MASK_ButtonRelease) {	if(MsgSendEvent(msgq, input_client, &m_ev, IPC_NOWAIT) == -1) {	  switch(errno) {	  case EAGAIN:	    // msgq full, drop message	    break;#ifdef EIDRM	  case EIDRM:#endif	  case EINVAL:	    FATAL("%s", "buttonrelease\n");	    perror("MsgSendEvent");	    display_exit(); //TODO clean up and exit	    break;	  default:	    FATAL("%s", "buttonrelease, couldn't send notification\n");	    perror("MsgSendEvent");	    display_exit(); //TODO clean up and exit	    break;	  }	}      }      }      if(cursor_visible == False) {	restore_cursor(mydisplay, window.win);	cursor_visible = True;      }      clocktime_get(&prev_time);      break;    case MotionNotify:      if((ev.xmotion.time - last_motion) > 50) {	last_motion = ev.xmotion.time;		// send motion notify to whoever wants it	if(input_mask & INPUT_MASK_PointerMotion) {	  MsgEvent_t m_ev;	  	  m_ev.type = MsgEventQInputPointerMotion;	  m_ev.input.x = (ev.xmotion.x - window.video_area.x) *	    src_view_area.width / window.video_area.width +	    src_view_area.x;	  m_ev.input.y = (ev.xmotion.y - window.video_area.y) *	    src_view_area.height / window.video_area.height +	    src_view_area.y;	  m_ev.input.x_root = ev.xmotion.x_root;	  m_ev.input.y_root = ev.xmotion.y_root;	  m_ev.input.mod_mask = ev.xmotion.state;	  m_ev.input.input = 0;	  if(MsgSendEvent(msgq, input_client, &m_ev, IPC_NOWAIT) == -1) {	    switch(errno) {	    case EAGAIN:	      // msgq full, drop message	      break;#ifdef EIDRM	    case EIDRM:#endif	    case EINVAL:	      FATAL("%s", "pointermotion\n");	      perror("MsgSendEvent");	      display_exit(); //TODO clean up and exit	      break;	    default:	      FATAL("%s", "pointermotion, couldn't send notification\n");	      perror("MsgSendEvent");	      display_exit(); //TODO clean up and exit	      break;	    }	  }	}      }      if(cursor_visible == False) {	restore_cursor(mydisplay, window.win);	cursor_visible = True;      }      clocktime_get(&prev_time);      break;    case Expose:      // remove all Expose events in queue      while(XCheckTypedEvent(mydisplay, Expose, &ev) == True);            if(ev.xexpose.window == window.win) {	if(use_xv) {	  draw_win_xv(&window); 	} else {	  draw_win_x11(&window);	}      }      break;    case ConfigureNotify:      // remove all configure notify in queue      while(XCheckTypedEvent(mydisplay, ConfigureNotify, &ev) == True);             if(ev.xconfigure.window == window.win) {	Window dummy_win;	window.window_area.width = ev.xconfigure.width;	window.window_area.height = ev.xconfigure.height;		display_adjust_size(current_image, 			    ev.xconfigure.width, 			    ev.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);		DpyInfoUpdateResolution(mydisplay, screen_nr,				window.window_area.x,				window.window_area.y);	clear_borders();      }      break;    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -