+set_my_viewport(struct box *box)
+{
+ wl_fixed_t src_x, src_y, src_width, src_height;
+ int32_t dst_width = SURFACE_WIDTH;
+ int32_t dst_height = SURFACE_HEIGHT;
+
+ if (box->mode == MODE_NO_VIEWPORT)
+ return;
+
+ /* Cut the green border in half, take white border fully in,
+ * and black border fully out. The borders are 1px wide in buffer.
+ *
+ * The gl-renderer uses linear texture sampling, this means the
+ * top and left edges go to 100% green, bottom goes to 50% blue/black,
+ * right edge has thick white sliding to 50% red.
+ */
+ src_x = wl_fixed_from_double((RECT_X + 0.5) / BUFFER_SCALE);
+ src_y = wl_fixed_from_double((RECT_Y + 0.5) / BUFFER_SCALE);
+ src_width = wl_fixed_from_double((RECT_W - 0.5) / BUFFER_SCALE);
+ src_height = wl_fixed_from_double((RECT_H - 0.5) / BUFFER_SCALE);
+
+ if (box->scaler_version < 2 && box->mode != MODE_SRC_DST) {
+ fprintf(stderr, "Error: server's wl_scaler interface version "
+ "%d does not support this mode.\n",
+ box->scaler_version);
+ exit(1);
+ }
+
+ switch (box->mode){
+ case MODE_SRC_ONLY:
+ wl_viewport_set_source(box->viewport, src_x, src_y,
+ src_width, src_height);
+ break;
+ case MODE_DST_ONLY:
+ wl_viewport_set_destination(box->viewport,
+ dst_width, dst_height);
+ break;
+ case MODE_SRC_DST:
+ if (box->scaler_version < 2) {
+ wl_viewport_set(box->viewport,
+ src_x, src_y, src_width, src_height,
+ dst_width, dst_height);
+ } else {
+ wl_viewport_set_source(box->viewport, src_x, src_y,
+ src_width, src_height);
+ wl_viewport_set_destination(box->viewport,
+ dst_width, dst_height);
+ }
+ break;
+ default:
+ assert(!"not reached");
+ }
+}
+
+static void