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

📄 sdlevent.c

📁 Coriander is a GUI for controlling a Digital Camera (in the sense of the IIDC specs issued by the 1
💻 C
字号:
/* * Copyright (C) 2000-2004 Damien Douxchamps  <ddouxchamps@users.sf.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include "coriander.h"#ifdef HAVE_SDLLIB//extern GtkWidget *main_window;//extern watchthread_info_t watchthread_info;//extern camera_t* camera;//extern int WM_cancel_display;//extern cursor_info_t cursor_info;//extern xvinfo_t xvinfo;//extern whitebal_data_t* whitebal_data;// This should be probed automatically.// This limitation might come from the video RAM.#define MAX_DISPLAY_WIDTH  8192#define MAX_DISPLAY_HEIGHT 8192intSDLEventStartThread(chain_t *display_service){  displaythread_info_t *info;  info=(displaythread_info_t*)display_service->data;  pthread_mutex_init(&info->mutex_cancel_event, NULL);  pthread_mutex_init(&info->mutex_event, NULL);  pthread_mutex_lock(&info->mutex_cancel_event);  info->cancel_event_req=0;  pthread_mutex_unlock(&info->mutex_cancel_event);  if (pthread_create(&info->event_thread, NULL, SDLEventThread, (void*)display_service))    return(1);  else    return(0);}void*SDLEventThread(void *arg){  chain_t* display_service;  displaythread_info_t *info;   display_service=(chain_t*)arg;  pthread_mutex_lock(&display_service->mutex_data);  info=(displaythread_info_t*)display_service->data;  pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);  pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL);  pthread_mutex_unlock(&display_service->mutex_data);  while (1) {    pthread_mutex_lock(&info->mutex_cancel_event);    if (info->cancel_event_req>0) {      pthread_mutex_unlock(&info->mutex_cancel_event);      return ((void*)1);    }    else {      pthread_mutex_unlock(&info->mutex_cancel_event);      pthread_mutex_lock(&info->mutex_event);      if (!SDLHandleEvent(display_service)) {	pthread_mutex_unlock(&info->mutex_event);	// SDL_QUIT called, close display thread	DisplayStopThread(camera);	// the following is only for the display_service button to be updated.	WM_cancel_display=1;	break;      }      else {	pthread_mutex_unlock(&info->mutex_event);	usleep(DELAY);      }    }  }  return ((void*)0);}voidSDLEventStopThread(chain_t *display_service){  displaythread_info_t *info;  info=(displaythread_info_t*)display_service->data;  // send request for cancellation:  pthread_mutex_lock(&info->mutex_cancel_event);  info->cancel_event_req=1;  pthread_mutex_unlock(&info->mutex_cancel_event);    // when cancellation occured, join:  pthread_join(info->event_thread, NULL);}intSDLHandleEvent(chain_t *display_service){  displaythread_info_t *info;  SDL_Event event;  info=(displaythread_info_t*)display_service->data;  while ( SDL_PollEvent(&event) ) {    pthread_mutex_lock(&display_service->mutex_data);    switch(event.type) {    case SDL_VIDEORESIZE:      SDLResizeDisplay(display_service, event.resize.w, event.resize.h);      break;    case SDL_KEYDOWN:      OnKeyPressed(display_service,event.key.keysym.sym, event.key.keysym.mod);      break;    case SDL_KEYUP:      OnKeyReleased(display_service,event.key.keysym.sym, event.key.keysym.mod);      break;    case SDL_MOUSEBUTTONDOWN:      OnMouseDown(display_service,event.button.button, event.button.x, event.button.y);      break;    case SDL_MOUSEBUTTONUP:      OnMouseUp(display_service,event.button.button, event.button.x, event.button.y);      break;    case SDL_MOUSEMOTION:      OnMouseMotion(display_service, event.motion.x, event.motion.y);      break;    case SDL_QUIT:      pthread_mutex_unlock(&display_service->mutex_data);      return(0);      break;    }    pthread_mutex_unlock(&display_service->mutex_data);  }  return(1);}voidOnKeyPressed(chain_t *display_service, int key, int mod){  displaythread_info_t *info;  info=(displaythread_info_t*)display_service->data;  //printf ("%s: 0x%02x\n", __FUNCTION__, key);  switch (key) {  case SDLK_n:    // set display to normal size    SDLResizeDisplay(display_service, display_service->current_buffer->width, display_service->current_buffer->height);    break;  case SDLK_f:    // toggle fullscreen mode    SDL_WM_ToggleFullScreen(info->sdlvideo);    break;  case SDLK_c:    // crop image    SDLCropImage(display_service);    break;  case SDLK_m:    // set F7 image to max size    SDLSetMaxSize(display_service);    break;  case SDLK_PAGEUP:    // image size +10%    SDLResizeDisplay(display_service, info->sdlvideorect.w*10/9, info->sdlvideorect.h*10/9);    break;  case SDLK_PAGEDOWN:    // image size -10%    SDLResizeDisplay(display_service, info->sdlvideorect.w*9/10, info->sdlvideorect.h*9/10);    break;#if 1    /* This should leave. SDL supplies the raw key with modifiers, so e.g.       'a' = SDLK_a,0 'A' = SDLK_a,KMOD_SHIFT, etc. On my keyboard, '<' is       SDLK_COMMA,KMOD_SHIFT and SDLK_GREATER will never arrive here.    */  case SDLK_GREATER:    // image size *2    if (mod&(KMOD_SHIFT)) {      SDLResizeDisplay(display_service, info->sdlvideorect.w/2, info->sdlvideorect.h/2);    } else {      SDLResizeDisplay(display_service, info->sdlvideorect.w*2, info->sdlvideorect.h*2);    }    break;  case SDLK_LESS:    // image size /2    if (mod&(KMOD_SHIFT)) {      SDLResizeDisplay(display_service, info->sdlvideorect.w*2, info->sdlvideorect.h*2);    } else {      SDLResizeDisplay(display_service, info->sdlvideorect.w/2, info->sdlvideorect.h/2);    }    break;#endif  }      }voidOnKeyReleased(chain_t *display_service, int key, int mod){}voidOnMouseDown(chain_t *display_service, int button, int x, int y){  displaythread_info_t *info;  Format7ModeInfo_t* f7info;  info=(displaythread_info_t*)display_service->data;  if (camera->misc_info.format==FORMAT_SCALABLE_IMAGE_SIZE) {    f7info=&camera->format7_info.mode[camera->misc_info.mode-MODE_FORMAT7_MIN];  }  switch (button) {  case SDL_BUTTON_LEFT:    pthread_mutex_lock(&watchthread_info.mutex_area);    watchthread_info.draw=1;    watchthread_info.mouse_down=1;    // there is some adaptation because the display size can be different    // from the real image size. (i.e. the image can be resized)    watchthread_info.first[0]= ((x*display_service->current_buffer->width /info->sdlvideorect.w));    watchthread_info.first[1]= ((y*display_service->current_buffer->height/info->sdlvideorect.h));    // zero size at first click, -> copy click coordinate to second corner    watchthread_info.second[0]=watchthread_info.first[0];    watchthread_info.second[1]=watchthread_info.first[1];    watchthread_info.upper_left[0]=watchthread_info.first[0];    watchthread_info.upper_left[1]=watchthread_info.first[1];    watchthread_info.lower_right[0]=watchthread_info.first[0];    watchthread_info.lower_right[1]=watchthread_info.first[1];    GetValidF7Crop(&watchthread_info, display_service);    pthread_mutex_unlock(&watchthread_info.mutex_area);    break;  case SDL_BUTTON_MIDDLE:    x=x*display_service->current_buffer->width/info->sdlvideorect.w; //rescaling    y=y*display_service->current_buffer->height/info->sdlvideorect.h;    // THIS IS ONLY VALID FOR YUYV!!    cursor_info.col_y=info->sdloverlay->pixels[0][(y*display_service->current_buffer->width+x)*2];    cursor_info.col_u=info->sdloverlay->pixels[0][(((y*display_service->current_buffer->width+x)>>1)<<2)+1]-127;    cursor_info.col_v=info->sdloverlay->pixels[0][(((y*display_service->current_buffer->width+x)>>1)<<2)+3]-127;    YUV2RGB(cursor_info.col_y, cursor_info.col_u, cursor_info.col_v,	    cursor_info.col_r, cursor_info.col_g, cursor_info.col_b);    cursor_info.x=x;    cursor_info.y=y;    cursor_info.update_req=1;    break;  case SDL_BUTTON_RIGHT:    //whitebal_data->x=x*display_service->current_buffer->width/info->sdlvideorect.w; //rescaling    //whitebal_data->y=y*display_service->current_buffer->height/info->sdlvideorect.h;    //whitebal_data->service=display_service;    //pthread_create(&whitebal_data->thread, NULL, AutoWhiteBalance, (void*)&whitebal_data);    break;  default:    //fprintf(stderr,"Bad button ID in SDL!\n");    break;  }}voidOnMouseUp(chain_t *display_service, int button, int x, int y){  displaythread_info_t *info;  info=(displaythread_info_t*)display_service->data;  switch (button) {  case SDL_BUTTON_LEFT:    pthread_mutex_lock(&watchthread_info.mutex_area);    watchthread_info.mouse_down=0;    // there is some adaptation because the display size can be different    // from the real image size. (i.e. the image can be resized)    //info->lower_right[0]=x*display_service->current_buffer->width/info->sdlvideorect.w;    //info->lower_right[1]=y*display_service->current_buffer->height/info->sdlvideorect.h;    pthread_mutex_unlock(&watchthread_info.mutex_area);    break;  case SDL_BUTTON_MIDDLE:    break;  case SDL_BUTTON_RIGHT:    break;  default:    //fprintf(stderr,"Bad button ID in SDL!\n");    break;  }}voidOnMouseMotion(chain_t *display_service, int x, int y){  displaythread_info_t *info;  info=(displaythread_info_t*)display_service->data;  pthread_mutex_lock(&watchthread_info.mutex_area);  if (watchthread_info.mouse_down==1) {    watchthread_info.second[0]=x*display_service->current_buffer->width/info->sdlvideorect.w;    watchthread_info.second[1]=y*display_service->current_buffer->height/info->sdlvideorect.h;    // we need to flip the corners if the pointer moves backwards    if (watchthread_info.second[0]<watchthread_info.first[0])      watchthread_info.upper_left[0]=watchthread_info.second[0];    else      watchthread_info.upper_left[0]=watchthread_info.first[0];    if (watchthread_info.second[1]<watchthread_info.first[1])      watchthread_info.upper_left[1]=watchthread_info.second[1];    else      watchthread_info.upper_left[1]=watchthread_info.first[1];    if (watchthread_info.second[0]>=watchthread_info.first[0])      watchthread_info.lower_right[0]=watchthread_info.second[0];    else      watchthread_info.lower_right[0]=watchthread_info.first[0];    if (watchthread_info.second[1]>=watchthread_info.first[1])      watchthread_info.lower_right[1]=watchthread_info.second[1];    else      watchthread_info.lower_right[1]=watchthread_info.first[1];       GetValidF7Crop(&watchthread_info,display_service);  }  pthread_mutex_unlock(&watchthread_info.mutex_area);  }voidSDLResizeDisplay(chain_t *display_service, int width, int height){      displaythread_info_t *info;  info=(displaythread_info_t*)display_service->data;  int prev_height, prev_width;  prev_width=info->sdlvideorect.w;  prev_height=info->sdlvideorect.h;  // check that the size is not too small or too large.  if ((width<1)||(height<1)||(width>MAX_DISPLAY_WIDTH)||(height>MAX_DISPLAY_HEIGHT))    return;  if (display_service->camera->prefs.display_keep_ratio>0) {    // keep aspect ratio and resize following which dimension we change    if (abs(width-info->sdlvideorect.w) >= (abs(height-info->sdlvideorect.h))) {      // we changed the width, set height accordingly      info->sdlvideorect.w = width;      info->sdlvideorect.h = (width * display_service->current_buffer->height) / display_service->current_buffer->width;    }    else {      // we changed the height, set width accordingly      info->sdlvideorect.w = (height * display_service->current_buffer->width) / display_service->current_buffer->height;      info->sdlvideorect.h = height;    }  }  else {    // bypass aspect keep:    info->sdlvideorect.w = width;    info->sdlvideorect.h = height;  }  // maximize display size to XV size if necessary  if ((xvinfo.max_width!=-1)&&(xvinfo.max_height!=-1)) {    if (info->sdlvideorect.w>xvinfo.max_width) {      info->sdlvideorect.w=xvinfo.max_width;    }    if (info->sdlvideorect.h>xvinfo.max_height) {      info->sdlvideorect.h=xvinfo.max_height;    }  }  // if size change is effective, re-set SDL stuff  if ((prev_width!=info->sdlvideorect.w)||(prev_height!=info->sdlvideorect.h)) {    // Free overlay & video surface    SDL_FreeYUVOverlay(info->sdloverlay);    SDL_FreeSurface(info->sdlvideo);        // new video mode    info->sdlvideo = SDL_SetVideoMode(info->sdlvideorect.w, info->sdlvideorect.h,				      info->sdlbpp, info->sdlflags);    if (info->sdlvideo == NULL) {      MainError(SDL_GetError());      SDL_Quit();      return;    }        // Create YUV Overlay      info->sdloverlay = SDL_CreateYUVOverlay(display_service->current_buffer->width,					    display_service->current_buffer->height,					    SDL_YUY2_OVERLAY, info->sdlvideo);    if (info->sdloverlay==NULL) {      MainError(SDL_GetError());      SDL_Quit();      return;    }  }  }voidSDLCropImage(chain_t *display_service){  pthread_mutex_lock(&watchthread_info.mutex_area);  watchthread_info.draw=0;  if (display_service->current_buffer->format==FORMAT_SCALABLE_IMAGE_SIZE)    watchthread_info.crop=1;  pthread_mutex_unlock(&watchthread_info.mutex_area);    }voidSDLSetMaxSize(chain_t *display_service){  pthread_mutex_lock(&watchthread_info.mutex_area);  watchthread_info.draw=0;  if (display_service->current_buffer->format==FORMAT_SCALABLE_IMAGE_SIZE) {    watchthread_info.crop=1;    watchthread_info.pos[0]=0;    watchthread_info.pos[1]=0;    watchthread_info.size[0]=camera->format7_info.mode[camera->misc_info.mode-MODE_FORMAT7_MIN].max_size_x;    watchthread_info.size[1]=camera->format7_info.mode[camera->misc_info.mode-MODE_FORMAT7_MIN].max_size_y;  }  pthread_mutex_unlock(&watchthread_info.mutex_area);}#endif

⌨️ 快捷键说明

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