All pastes #835868 Raw Edit

Miscellany

public c v1 · immutable
#835868 ·published 2007-12-29 02:18 UTC
rendered paste body
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <X11/Xlib.h>#include <Imlib2.h>#include <Evas.h>#include <Ecore.h>#include <Ecore_X.h>#include <Ecore_Evas.h>#include <Edje.h>#define DATA_PATH "data"typedef struct _E_Band E_Band;void _eg_band_show();void _eg_band_hide();void _eg_band_resize(int w, int h);void _eg_band_move(int x, int y);void _eg_init();static int _eg_event_mouse_move_cb(void *data, int type, void *event);static int _eg_event_mouse_up_cb(void *data, int type, void *event);/* initial coords of region to grab */int grab_x, grab_y;/* the rubber band object */static E_Band *band = NULL;/* mouse move event */static Ecore_Event_Handler *event_mouse_move = NULL;/* mouse button up event */static Ecore_Event_Handler *event_mouse_up = NULL;/* input window that us used to get X events */static Ecore_X_Window input_window;/* rubber band structure */struct _E_Band{  /* gui components */  Ecore_Evas *ee;  Evas *evas;  Evas_Object *edj;};/** * Grab a part of the screen and return as an Evas object */Evas_Object *_eg_screen_area_grab(int x, int y, int w, int h){  Imlib_Image im;  Evas_Object *ob;    imlib_context_set_display(ecore_x_display_get());  imlib_context_set_drawable(RootWindow(ecore_x_display_get(),0));  imlib_context_set_visual( DefaultVisual(ecore_x_display_get(), DefaultScreen(ecore_x_display_get() ) ));  im = imlib_create_image_from_drawable(0, x,y,w,h,0);  imlib_context_set_image(im);	     	       imlib_image_set_format("argb");  ob = evas_object_image_add(band->evas);  evas_object_image_size_set(ob, w, h);  evas_object_image_data_copy_set(ob, imlib_image_get_data_for_reading_only());  evas_object_image_fill_set(ob, 0, 0,  w, h);  evas_object_resize(ob, w, h);	  evas_object_image_alpha_set(ob, 0);  imlib_free_image();  return ob;}/** * Show rubber band */void _eg_band_show(){  /* create rubber band if it doesnt exist */  if (!band)  {    /* allocate memory, create Ecore_Evas, create Edje object */    band = calloc(1, sizeof(E_Band));    band->ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 0, 0);    band->evas = ecore_evas_get(band->ee);    /* check if we have composite, if we do, use translucency */    if (ecore_x_composite_query() &&         ecore_x_screen_is_composited(0))    {      ecore_evas_alpha_set(band->ee, 1);    }    else    {      /* we dont have composite, use shaped windows */      ecore_evas_shaped_set(band->ee, 1);    }      band->edj = evas_object_image_add(band->evas);    evas_object_image_file_set(band->edj, "data/images/rect.png", NULL);    evas_object_image_border_set(band->edj, 3, 3, 3, 3);    evas_object_move(band->edj, 0, 0);    /* if we dont put these here, Evas messes up */    evas_object_resize(band->edj, 50, 50);    evas_object_image_fill_set(band->edj, 0, 0, 50, 50);    /* let the window manager ignore this window, and make it borderless */    ecore_evas_override_set(band->ee, 1);    ecore_evas_borderless_set(band->ee, 1);  }  ecore_evas_show(band->ee);  evas_object_show(band->edj);}/** * Hide rubber band */void _eg_band_hide(){  if (!band)    return;  ecore_evas_hide(band->ee);}/** * Resize rubber band */void _eg_band_resize(int w, int h){  if (!band)    return;  ecore_evas_resize(band->ee, w, h);  /* this is also the same problem with Evas as above */  if (w >= 6 && h >= 6)  {    evas_object_resize(band->edj, w, h);    evas_object_image_fill_set(band->edj, 0, 0, w, h);  }  _eg_band_show();}/** * Move the rubber band */void _eg_band_move(int x, int y){  if (!band)    return;  ecore_evas_move(band->ee, x, y);}/** * Start the selection of a region to grab */void _eg_grab_region_start(){  int px, py;  int sw, sh;  /* attach callbacks to mouse movement and click so   * we can resize the rubber band and hide it on a click   */  event_mouse_move = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_MOVE,                      _eg_event_mouse_move_cb, NULL);  event_mouse_up = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_BUTTON_UP,                    _eg_event_mouse_up_cb, NULL);     /* get our desktop's width and height */  ecore_x_window_geometry_get(0, NULL, NULL, &sw, &sh);  /* set up our input window to grab X events */  input_window = ecore_x_window_input_new(0, 0, 0, sw, sh);  ecore_x_window_show(input_window);  /* get our mouse cursor's curret x and y coords */  ecore_x_pointer_xy_get(input_window, &px, &py);    /* set initial grabbing coords */  grab_x = px;  grab_y = py;  /* show the rubber band */  _eg_band_show();/* move the rubber band */  _eg_band_move(grab_x, grab_y);}/** * End the selection of a region */void _eg_grab_region_end(){  int x, y, w, h;  Evas_Object *shot;  /* detach the events we added to move movement and click */  ecore_event_handler_del(event_mouse_move);  ecore_event_handler_del(event_mouse_up);  /* hide and delete our input window */  ecore_x_window_hide(input_window);  ecore_x_window_delete_request_send(input_window);  /* get the proper coords */  ecore_evas_geometry_get(band->ee, &x, &y, &w, &h);  /* hide the rubber band */  _eg_band_hide();  /* grab and save the shot to disk */  shot = _eg_screen_area_grab(x, y, w, h);  if (!evas_object_image_save(shot, "/tmp/egrab_tmp.jpg", NULL, NULL))  {    fprintf(stderr, "WARNING: Could not save screenshot to disk!\n");  }  evas_object_del(shot);  /* quit the application */  ecore_main_loop_quit();}/** * Called when a region grab is in progress and the mouse is moving */static int _eg_event_mouse_move_cb(void *data, int type, void *event){  int w, h;  Ecore_X_Event_Mouse_Move *ev = event;  w = ev->root.x - grab_x;  h = ev->root.y - grab_y;    /* figure out how to move the band */  if (w < 0 && h < 0)  {    int x, y;    ecore_x_pointer_xy_get(input_window, &x, &y);        _eg_band_move(x, y);    _eg_band_resize(-w, -h);  }  else if (w < 0 &&  h > 0)  {    int x, y;    ecore_x_pointer_xy_get(input_window, &x, &y);        _eg_band_move(x, grab_y);    _eg_band_resize(-w, h);  }  else if (w > 0 && h < 0)  {    int x, y;    ecore_x_pointer_xy_get(input_window, &x, &y);        _eg_band_move(grab_x, y);    _eg_band_resize(w, -h);  }  else  {    _eg_band_resize(w, h);  }  return 1;}/** * Called when a region grab is in progress and the mouse button is depressed */static int _eg_event_mouse_up_cb(void *data, int type, void *event){  _eg_grab_region_end();    return 1;}/** * Initialize Ecore_X with proper display * FIXME: This is segfaulting. Cant call ecore_x_window_root_list if not * init'ed. */void _eg_init(){  Ecore_X_Window *roots;  int screens, i;  char *dispstr, *subdisp;  char newdisp[255];  roots = ecore_x_window_root_list(&screens);  dispstr = DisplayString(ecore_x_display_get());  subdisp = strdup(dispstr);  for (i = 0; i < screens; i++)   {    dispstr = strchr(subdisp, ':');    if (dispstr)     {      dispstr = strchr(dispstr, '.');      if (NULL != dispstr)        *dispstr = '\0';    }    snprintf(newdisp, sizeof(newdisp), "%s.%d", subdisp, i);    ecore_x_init(newdisp);  }}int main(char *argc, char **argv){  ecore_init();  ecore_evas_init();  ecore_x_init(NULL);  edje_init();  _eg_grab_region_start();  ecore_main_loop_begin();  edje_shutdown();  ecore_x_shutdown();  ecore_evas_shutdown();  ecore_shutdown();  return 0;}