Example #1
0
File: swm.c Project: JuliusP/swm
static void
discover (void) {
	xcb_query_tree_reply_t      *r;
	xcb_window_t                *c;

	r = xcb_query_tree_reply(conn, xcb_query_tree(conn, scr->root), NULL);

	if (r == NULL) {
		warnx("cannot get a list of windows");
		return;
	}

	c = xcb_query_tree_children(r);

	for (unsigned int i = 0; i < r->children_len; i++) {
		setup_win(c[i]);
		focus(c[i], INACTIVE);
	}
	nextwin();
}
Example #2
0
File: swm.c Project: JuliusP/swm
static void
events_loop (void) {
	uint32_t values[3];
	xcb_generic_event_t *ev;
	xcb_get_geometry_reply_t *geom;
	xcb_window_t win = 0;

	/* loop */
	for (;;) {
		ev = xcb_wait_for_event(conn);

		if (ev == NULL)
			errx(1, "xcb connection broken");

		switch (ev->response_type & ~0x80) {

		case XCB_CREATE_NOTIFY: {
			xcb_create_notify_event_t *e;
			e = (xcb_create_notify_event_t *)ev;

			if (!e->override_redirect) {
				setup_win(e->window);
				focus(e->window, ACTIVE);
			}
		} break;

		case XCB_DESTROY_NOTIFY: {
			xcb_destroy_notify_event_t *e;
			e = (xcb_destroy_notify_event_t *)ev;

			xcb_kill_client(conn, e->window);
		} break;

		case XCB_KEY_PRESS: {
			xcb_key_press_event_t *e;
			e = (xcb_key_press_event_t *)ev;

			xcb_keysym_t keysym = xcb_get_keysym(e->detail);

			for (unsigned int i=0; i < LENGTH(keys); i++) {
				if (keys[i].keysym == keysym
				&& CLEANMASK(keys[i].mod) == CLEANMASK(e->state)
				&& keys[i].mfunc) {
					keys[i].mfunc(keys[i].x, keys[i].y);
				}
				else if (keys[i].keysym == keysym
				&& CLEANMASK(keys[i].mod) == CLEANMASK(e->state)
				&& keys[i].func) {
					keys[i].func();
				}
			}
				} break;

		case XCB_ENTER_NOTIFY: {
			xcb_enter_notify_event_t *e;
			e = (xcb_enter_notify_event_t *)ev;

			focus(e->event, ACTIVE);
		} break;

		case XCB_MAP_NOTIFY: {
			xcb_map_notify_event_t *e;
			e = (xcb_map_notify_event_t *)ev;

			if (!e->override_redirect) {
				xcb_map_window(conn, e->window);
				xcb_set_input_focus(conn,
					XCB_INPUT_FOCUS_POINTER_ROOT,
					e->window, XCB_CURRENT_TIME);
			}
		} break;

		case XCB_BUTTON_PRESS: {
			xcb_button_press_event_t *e;
			e = ( xcb_button_press_event_t *)ev;
			win = e->child;
			if (!win || win == scr->root)
				break;
			values[0] = XCB_STACK_MODE_ABOVE;
			xcb_configure_window(conn, win,
					XCB_CONFIG_WINDOW_STACK_MODE, values);
			geom = xcb_get_geometry_reply(conn,
					xcb_get_geometry(conn, win), NULL);
			if (1 == e->detail) {
				values[2] = 1;
				center_pointer(win);
			} else {
				values[2] = 3;
				xcb_warp_pointer(conn, XCB_NONE, win, 0, 0, 0,
						0, geom->width, geom->height);
			}
			xcb_grab_pointer(conn, 0, scr->root,
				XCB_EVENT_MASK_BUTTON_RELEASE
				| XCB_EVENT_MASK_BUTTON_MOTION
				| XCB_EVENT_MASK_POINTER_MOTION_HINT,
				XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC,
				scr->root, XCB_NONE, XCB_CURRENT_TIME);
			xcb_flush(conn);
		} break;

		case XCB_MOTION_NOTIFY: {
			xcb_query_pointer_reply_t *pointer;
			pointer = xcb_query_pointer_reply(conn,
					xcb_query_pointer(conn, scr->root), 0);
			if (values[2] == 1) {
				geom = xcb_get_geometry_reply(conn,
					xcb_get_geometry(conn, win), NULL);
				if (!geom) {
					break;
				}

				values[0] = (pointer->root_x + geom->width / 2
					> scr->width_in_pixels
					- (BORDERWIDTH*2))
					? scr->width_in_pixels - geom->width
					- (BORDERWIDTH*2)
					: pointer->root_x - geom->width / 2;
				values[1] = (pointer->root_y + geom->height / 2
					> scr->height_in_pixels
					- (BORDERWIDTH*2))
					? (scr->height_in_pixels - geom->height
					- (BORDERWIDTH*2))
					: pointer->root_y - geom->height / 2;

				if (pointer->root_x < geom->width/2)
					values[0] = 0;
				if (pointer->root_y < geom->height/2)
					values[1] = 0;

				xcb_configure_window(conn, win,
					XCB_CONFIG_WINDOW_X
					| XCB_CONFIG_WINDOW_Y, values);
				xcb_flush(conn);
			} else if (values[2] == 3) {
				focus(win, RESIZE);
				geom = xcb_get_geometry_reply(conn,
					xcb_get_geometry(conn, win), NULL);
				values[0] = pointer->root_x - geom->x;
				values[1] = pointer->root_y - geom->y;
				xcb_configure_window(conn, win,
					XCB_CONFIG_WINDOW_WIDTH
					| XCB_CONFIG_WINDOW_HEIGHT, values);
				xcb_flush(conn);
			}
		} break;

		case XCB_BUTTON_RELEASE:
			focus(win, ACTIVE);
			xcb_ungrab_pointer(conn, XCB_CURRENT_TIME);
			break;
		}

		xcb_flush(conn);
		free(ev);
	}
}
Example #3
0
File: image.c Project: pts/pts-qiv
/*
 *    Load & display image
 */
void qiv_load_image(qiv_image *q) {
  /* Don't initialize most variables here, initialize them after load_next_image: */
  struct stat st;
  const char *image_name;
  Imlib_Image *im;
  struct timeval load_before, load_after;

  char is_stat_ok;
  /* Used to omit slow disk operations if image_file doesn't exist or isn't
   * a file.
   */
  char is_maybe_image_file;
  char is_first_error = 1;

 load_next_image:
  is_stat_ok = 0;
  is_maybe_image_file = 1;
  image_name = image_names[image_idx];
  gettimeofday(&load_before, 0);

  if (imlib_context_get_image())
    imlib_free_image();

  q->real_w = q->real_h = -2;
  q->has_thumbnail = FALSE;
  if (!do_omit_load_stat) {
    is_stat_ok = 0 == stat(image_name, &st);
    is_maybe_image_file = is_stat_ok && S_ISREG(st.st_mode);
  }
  current_mtime = is_stat_ok ? st.st_mtime : 0;
  im = NULL;
  if (thumbnail && fullscreen && (is_stat_ok || maxpect)) {
    char *th_image_name =
        is_maybe_image_file ?
        get_thumbnail_filename(image_name, &is_maybe_image_file) : NULL;
    if (th_image_name) {
      im = imlib_load_image(th_image_name);
      if (im && maxpect) {
        get_image_dimensions(image_name, th_image_name,
                             &q->real_w, &q->real_h);
      }
      free(th_image_name);
      th_image_name = NULL;
    }
  }
  if (im) {  /* We have a dumb thumbnail in im. */
    if (maxpect) {
      current_mtime = 0;
      q->has_thumbnail = TRUE;
      /* Now im still has the thumbnail image. Keep it. */
    } else {  /* Use the real, non-thumbnail image instead. */
      imlib_context_set_image(im);
      imlib_free_image();
      im = is_maybe_image_file ? imlib_load_image((char*)image_name) : NULL;
    }
  } else {
    im = is_maybe_image_file ? imlib_load_image((char*)image_name) : NULL;
  }

  if (!im) { /* error */
    q->error = 1;
    q->orig_w = 400;
    q->orig_h = 300;

    if (to_root || to_root_t || to_root_s) {
      fprintf(stderr, "qiv: cannot load background_image\n");
      qiv_exit(1);
    }

    /* Shortcut to speed up lots of subsequent load failures. */
    if (is_first_error) {
      check_size(q, TRUE);
      if (first) {
        setup_win(q);
        first = 0;
      }
      gdk_window_set_background(q->win, &error_bg);
      gdk_beep();
      is_first_error = 0;
    }

    /* TODO(pts): Avoid the slow loop of copying pointers around in update_image_on_error. */
    update_image_on_error(q);
    /* This is a shortcut to avoid stack overflow in the recursion of
     * qiv_load_image -> update_image -> qiv_load_image -> update_image -> ...
     * if there are errors loading many subsequent images.
     */
    goto load_next_image;
  }

  if (thumbnail && !q->has_thumbnail && q->real_w < 0 && is_maybe_image_file) {
    FILE *f = fopen(image_name, "rb");
    if (f) {
      get_real_dimensions_fast(f, &q->real_w, &q->real_h);
      fclose(f);
    }
  }

  /* Retrieve image properties */
  imlib_context_set_image(im);
  q->error = 0;
  q->orig_w = imlib_image_get_width();
  q->orig_h = imlib_image_get_height();
  if (q->orig_w >= (1 << 23) / q->orig_h) {
    /* Workaround for Imlib2 1.4.6 on Ubuntu Trusty: PNG images with an
     * alpha channel and pixel count >= (1 << 23) are displayed as black.
     * imlib_image_query_pixel returns the correct value, but
     * imlib_render_pixmaps_for_whole_image_at_size renders only black
     * pixels if unzoomed.
     */
    Imlib_Color c;
    /* Without this call, imlib_image_set_has_alpha(0) is too early, and
     * it has no effect.
     */
    imlib_image_query_pixel(0, 0, &c);
    imlib_image_set_has_alpha(0);
  }
#ifdef HAVE_EXIF
  if (autorotate) {
    transform( q, orient( image_name));
  }
#endif

  check_size(q, TRUE);

  if (first) {
    setup_win(q);
    first = 0;
  }

  /* desktop-background -> exit */
  if (to_root || to_root_t || to_root_s) {
    set_desktop_image(q);
    if(slide)
      return;
    else
      qiv_exit(0);
  }

  gdk_window_set_background(q->win, &image_bg);

  if (do_grab || (fullscreen && !disable_grab) ) {
    gdk_keyboard_grab(q->win, FALSE, CurrentTime);
    gdk_pointer_grab(q->win, FALSE,
      GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK |
      GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK, NULL, NULL, CurrentTime);
  }

  gettimeofday(&load_after, 0);
  /* load_elapsed used by update_image. */
  load_elapsed = ((load_after.tv_sec +  load_after.tv_usec / 1.0e6) -
                 (load_before.tv_sec + load_before.tv_usec / 1.0e6));

  update_image(q, FULL_REDRAW);
//    if (magnify && !fullscreen) {  // [lc]
//     setup_magnify(q, &magnify_img);
//     update_magnify(q, &magnify_img, FULL_REDRAW, 0, 0);
//    }
}