// Copyright 2020 The Wuffs Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// ----------------

/*
imageviewer is a simple GUI program for viewing images. On Linux, GUI means
X11. To run:

$CXX imageviewer.cc -lxcb -lxcb-image -lxcb-render -lxcb-render-util && \
  ./a.out ../../test/data/bricks-*.gif; rm -f a.out

for a C++ compiler $CXX, such as clang++ or g++.

The Space and BackSpace keys cycle through the files, if more than one was
given as command line arguments. If none were given, the program reads from
stdin.

The Return key is equivalent to the Space key.

The ',' Comma and '.' Period keys cycle through background colors, which
matters if the image has fully or partially transparent pixels.

The '1' to '8' keys change the magnification zoom (or minification zoom with
the shift key). The '0' key toggles nearest neighbor and bilinear filtering.

The Escape key quits.
*/

#include <inttypes.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

// Wuffs ships as a "single file C library" or "header file library" as per
// https://github.com/nothings/stb/blob/master/docs/stb_howto.txt
//
// To use that single file as a "foo.c"-like implementation, instead of a
// "foo.h"-like header, #define WUFFS_IMPLEMENTATION before #include'ing or
// compiling it.
#define WUFFS_IMPLEMENTATION

// Defining the WUFFS_CONFIG__STATIC_FUNCTIONS macro is optional, but when
// combined with WUFFS_IMPLEMENTATION, it demonstrates making all of Wuffs'
// functions have static storage.
//
// This can help the compiler ignore or discard unused code, which can produce
// faster compiles and smaller binaries. Other motivations are discussed in the
// "ALLOW STATIC IMPLEMENTATION" section of
// https://raw.githubusercontent.com/nothings/stb/master/docs/stb_howto.txt
#define WUFFS_CONFIG__STATIC_FUNCTIONS

// Defining the WUFFS_CONFIG__MODULE* macros are optional, but it lets users of
// release/c/etc.c choose which parts of Wuffs to build. That file contains the
// entire Wuffs standard library, implementing a variety of codecs and file
// formats. Without this macro definition, an optimizing compiler or linker may
// very well discard Wuffs code for unused codecs, but listing the Wuffs
// modules we use makes that process explicit. Preprocessing means that such
// code simply isn't compiled.
#define WUFFS_CONFIG__MODULES
#define WUFFS_CONFIG__MODULE__ADLER32
#define WUFFS_CONFIG__MODULE__AUX__BASE
#define WUFFS_CONFIG__MODULE__AUX__IMAGE
#define WUFFS_CONFIG__MODULE__BASE
#define WUFFS_CONFIG__MODULE__BMP
#define WUFFS_CONFIG__MODULE__CRC32
#define WUFFS_CONFIG__MODULE__DEFLATE
#define WUFFS_CONFIG__MODULE__GIF
#define WUFFS_CONFIG__MODULE__LZW
#define WUFFS_CONFIG__MODULE__NIE
#define WUFFS_CONFIG__MODULE__PNG
#define WUFFS_CONFIG__MODULE__WBMP
#define WUFFS_CONFIG__MODULE__ZLIB

// If building this program in an environment that doesn't easily accommodate
// relative includes, you can use the script/inline-c-relative-includes.go
// program to generate a stand-alone C file.
#include "../../release/c/wuffs-unsupported-snapshot.c"

// X11 limits its image dimensions to uint16_t and some coordinates to int16_t.
#define MAX_INCL_DIMENSION 32767

#define NUM_BACKGROUND_COLORS 3
#define NUM_ZOOMS 8
#define SRC_BUFFER_ARRAY_SIZE (64 * 1024)

wuffs_base__color_u32_argb_premul g_background_colors[NUM_BACKGROUND_COLORS] = {
    0xFF000000,
    0xFFFFFFFF,
    0xFFA9009A,
};

uint32_t g_width = 0;
uint32_t g_height = 0;
wuffs_aux::MemOwner g_pixbuf_mem_owner(nullptr, &free);
wuffs_base__pixel_buffer g_pixbuf = {0};
uint32_t g_background_color_index = 0;
int32_t g_zoom = 0;
bool g_filter = false;

struct {
  int remaining_argc;
  char** remaining_argv;

  double screen_gamma;
} g_flags = {0};

static const char* g_usage =
    "Usage: imageviewer -flags input0.gif input1.png\n"
    "\n"
    "Flags:\n"
    "    -screen_gamma=N.N (default 2.2; 0 disables gamma correction)";

const char*  //
parse_flags(int argc, char** argv) {
  g_flags.screen_gamma = 2.2;

  int c = (argc > 0) ? 1 : 0;  // Skip argv[0], the program name.
  for (; c < argc; c++) {
    char* arg = argv[c];
    if (*arg++ != '-') {
      break;
    }

    // A double-dash "--foo" is equivalent to a single-dash "-foo". As special
    // cases, a bare "-" is not a flag (some programs may interpret it as
    // stdin) and a bare "--" means to stop parsing flags.
    if (*arg == '\x00') {
      break;
    } else if (*arg == '-') {
      arg++;
      if (*arg == '\x00') {
        c++;
        break;
      }
    }

    if (!strncmp(arg, "screen_gamma=", 13)) {
      g_flags.screen_gamma = atof(arg + 13);
      continue;
    }

    return g_usage;
  }

  g_flags.remaining_argc = argc - c;
  g_flags.remaining_argv = argv + c;
  return NULL;
}

class MyDecodeImageCallbacks : public wuffs_aux::DecodeImageCallbacks {
 public:
  MyDecodeImageCallbacks() : m_combined_gamma(1.0) {}

 private:
  std::string  //
  HandleMetadata(const wuffs_base__more_information& minfo,
                 wuffs_base__slice_u8 raw) override {
    if (minfo.flavor == WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_PARSED) {
      switch (minfo.metadata__fourcc()) {
        case WUFFS_BASE__FOURCC__GAMA:
          // metadata_parsed__gama returns the inverse gamma scaled by 1e5.
          m_combined_gamma =
              1e5 / (g_flags.screen_gamma * minfo.metadata_parsed__gama());
          break;
      }
    }
    return wuffs_aux::DecodeImageCallbacks::HandleMetadata(minfo, raw);
  }

  void  //
  Done(wuffs_aux::DecodeImageResult& result,
       wuffs_aux::sync_io::Input& input,
       wuffs_aux::IOBuffer& buffer,
       wuffs_base__image_decoder::unique_ptr image_decoder) override {
    // Apply basic color correction - gamma correction. Proper color correction
    // should also involve considering any CHRM, ICCP and SRGB metadata but
    // that requires a non-trivial amount of code (such as skcms, Skia's Color
    // Management System). To keep this example program simple, we only
    // consider GAMA metadata (and 8-bit color channels) here.
    //
    // This code also assumes that wuffs_aux::DecodeImageCallbacks defaults to
    // producing a WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL pixel buffer.
    if ((result.pixbuf.pixel_format().repr ==
         WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL) &&
        ((m_combined_gamma < 0.9999) || (1.0001 < m_combined_gamma))) {
      uint8_t lut[256];
      lut[0x00] = 0x00;
      lut[0xFF] = 0xFF;
      for (uint32_t i = 1; i < 0xFF; i++) {
        lut[i] =
            (uint8_t)(floor(255.0 * pow(i / 255.0, m_combined_gamma) + 0.5));
      }

      wuffs_base__table_u8 t = result.pixbuf.plane(0);
      size_t w4 = t.width / 4;
      for (size_t y = 0; y < t.height; y++) {
        uint8_t* ptr = t.ptr + (y * t.stride);
        for (size_t x = 0; x < w4; x++) {
          ptr[0] = lut[ptr[0]];
          ptr[1] = lut[ptr[1]];
          ptr[2] = lut[ptr[2]];
          ptr += 4;
        }
      }
    }
  }

  // m_combined_gamma holds the product of the screen gamma and the image
  // file's inverse gamma.
  double m_combined_gamma;
};

bool  //
load_image(const char* filename) {
  FILE* file = stdin;
  const char* adj_filename = "<stdin>";
  if (filename) {
    FILE* f = fopen(filename, "rb");
    if (f == NULL) {
      printf("%s: could not open file\n", filename);
      return false;
    }
    file = f;
    adj_filename = filename;
  }

  g_width = 0;
  g_height = 0;
  g_pixbuf_mem_owner.reset();
  g_pixbuf = wuffs_base__null_pixel_buffer();

  uint64_t dia_flags = 0;
  if (g_flags.screen_gamma > 0) {
    dia_flags |= wuffs_aux::DecodeImageArgFlags::REPORT_METADATA_GAMA;
  }

  MyDecodeImageCallbacks callbacks;
  wuffs_aux::sync_io::FileInput input(file);
  wuffs_aux::DecodeImageResult res = wuffs_aux::DecodeImage(
      callbacks, input, wuffs_aux::DecodeImageArgQuirks::DefaultValue(),
      wuffs_aux::DecodeImageArgFlags(dia_flags),
      // Use PIXEL_BLEND__SRC_OVER, not the default PIXEL_BLEND__SRC, because
      // we also pass a background color.
      wuffs_aux::DecodeImageArgPixelBlend(WUFFS_BASE__PIXEL_BLEND__SRC_OVER),
      wuffs_aux::DecodeImageArgBackgroundColor(
          g_background_colors[g_background_color_index]),
      wuffs_aux::DecodeImageArgMaxInclDimension(MAX_INCL_DIMENSION));
  if (filename) {
    fclose(file);
  }

  // wuffs_aux::DecodeImageCallbacks's default implementation should give us an
  // interleaved (not multi-planar) pixel buffer, so that all of the pixel data
  // is in a single 2-dimensional table (plane 0). Later on, we re-interpret
  // that table as XCB image data, which isn't something we could do if we had
  // e.g. multi-planar YCbCr.
  if (!res.pixbuf.pixcfg.pixel_format().is_interleaved()) {
    printf("%s: non-interleaved pixbuf\n", adj_filename);
    return false;
  }
  wuffs_base__table_u8 tab = res.pixbuf.plane(0);
  if (tab.width != tab.stride) {
    // The xcb_image_create_native call, later on, assumes that (tab.height *
    // tab.stride) bytes are readable, which isn't quite the same as what
    // wuffs_base__table__flattened_length(tab.width, tab.height, tab.stride)
    // returns unless the table is tight (its width equals its stride).
    printf("%s: could not allocate tight pixbuf\n", adj_filename);
    return false;
  }

  g_width = res.pixbuf.pixcfg.width();
  g_height = res.pixbuf.pixcfg.height();
  g_pixbuf_mem_owner = std::move(res.pixbuf_mem_owner);
  g_pixbuf = res.pixbuf;

  if (res.error_message.empty()) {
    printf("%s: ok (%" PRIu32 " x %" PRIu32 ")\n", adj_filename, g_width,
           g_height);
  } else {
    printf("%s: %s\n", adj_filename, res.error_message.c_str());
  }
  return res.pixbuf.pixcfg.is_valid();
}

// ---------------------------------------------------------------------

#if defined(__linux__)
#define SUPPORTED_OPERATING_SYSTEM

#include <xcb/render.h>
#include <xcb/xcb.h>
#include <xcb/xcb_image.h>
#include <xcb/xcb_renderutil.h>

#define XK_BackSpace 0xFF08
#define XK_Escape 0xFF1B
#define XK_Return 0xFF0D

uint32_t g_maximum_request_length = 0;  // Measured in 4-byte units.
xcb_atom_t g_atom_net_wm_name = XCB_NONE;
xcb_atom_t g_atom_utf8_string = XCB_NONE;
xcb_atom_t g_atom_wm_protocols = XCB_NONE;
xcb_atom_t g_atom_wm_delete_window = XCB_NONE;
xcb_pixmap_t g_pixmap = XCB_NONE;
xcb_gcontext_t g_pixmap_gc = XCB_NONE;
xcb_render_picture_t g_pixmap_picture = XCB_NONE;
xcb_render_pictforminfo_t* g_pictforminfo = NULL;
xcb_keysym_t* g_keysyms = NULL;
xcb_get_keyboard_mapping_reply_t* g_keyboard_mapping = NULL;

void  //
init_keymap(xcb_connection_t* c, const xcb_setup_t* z) {
  xcb_get_keyboard_mapping_cookie_t cookie = xcb_get_keyboard_mapping(
      c, z->min_keycode, z->max_keycode - z->min_keycode + 1);
  g_keyboard_mapping = xcb_get_keyboard_mapping_reply(c, cookie, NULL);
  g_keysyms = (xcb_keysym_t*)(g_keyboard_mapping + 1);
}

xcb_window_t  //
make_window(xcb_connection_t* c, xcb_screen_t* s) {
  xcb_window_t w = xcb_generate_id(c);
  uint32_t value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
  uint32_t value_list[2];
  value_list[0] = s->black_pixel;
  value_list[1] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS;
  xcb_create_window(c, 0, w, s->root, 0, 0, 1024, 768, 0,
                    XCB_WINDOW_CLASS_INPUT_OUTPUT, s->root_visual, value_mask,
                    value_list);
  xcb_change_property(c, XCB_PROP_MODE_REPLACE, w, g_atom_net_wm_name,
                      g_atom_utf8_string, 8, 12, "Image Viewer");
  xcb_change_property(c, XCB_PROP_MODE_REPLACE, w, g_atom_wm_protocols,
                      XCB_ATOM_ATOM, 32, 1, &g_atom_wm_delete_window);
  xcb_map_window(c, w);
  return w;
}

void  //
apply_zoom_and_filter(xcb_connection_t* c) {
  static const xcb_render_fixed_t neg_zooms[NUM_ZOOMS] = {
      0x00010000,  // 1/1 as 16.16 fixed point
      0x00020000,  // 2/1
      0x00040000,  // 4/1
      0x00080000,  // 8/1
      0x00100000,  // 16/1
      0x00200000,  // 32/1
      0x00400000,  // 64/1
      0x00800000,  // 128/1
  };
  static const xcb_render_fixed_t pos_zooms[NUM_ZOOMS] = {
      0x00010000,  // 1/1 as 16.16 fixed point
      0x00008000,  // 1/2
      0x00004000,  // 1/4
      0x00002000,  // 1/8
      0x00001000,  // 1/16
      0x00000800,  // 1/32
      0x00000400,  // 1/64
      0x00000200,  // 1/128
  };

  xcb_render_fixed_t z = g_zoom < 0
                             ? neg_zooms[((uint32_t)(-g_zoom)) % NUM_ZOOMS]
                             : pos_zooms[((uint32_t)(+g_zoom)) % NUM_ZOOMS];
  xcb_render_set_picture_transform(c, g_pixmap_picture,
                                   ((xcb_render_transform_t){
                                       z, 0, 0,        //
                                       0, z, 0,        //
                                       0, 0, 0x10000,  //
                                   }));

  uint16_t f_len = 7;
  const char* f_ptr = "nearest";
  if (g_filter && (g_zoom != 0)) {
    f_len = 8;
    f_ptr = "bilinear";
  }
  xcb_render_set_picture_filter(c, g_pixmap_picture, f_len, f_ptr, 0, NULL);
}

// zoom_shift returns (a << g_zoom), roughly speaking, but saturates at an
// arbitrary value called M.
//
// The final two arguments to xcb_render_composite have uint16_t type (and
// UINT16_MAX is 65535), but in practice, values above M sometimes don't work
// in that the xcb_render_composite call has no visible effect.
//
// Some xrender debugging could potentially derive a more accurate maximum but
// for now, the M = 30000 round number will do.
uint16_t  //
zoom_shift(uint32_t a) {
  uint16_t M = 30000;
  uint64_t b = g_zoom < 0
                   ? (((uint64_t)a) >> (((uint32_t)(-g_zoom)) % NUM_ZOOMS))
                   : (((uint64_t)a) << (((uint32_t)(+g_zoom)) % NUM_ZOOMS));
  return (b < M) ? b : M;
}

bool  //
load(xcb_connection_t* c, xcb_window_t w, const char* filename) {
  if (g_pixmap != XCB_NONE) {
    xcb_render_free_picture(c, g_pixmap_picture);
    xcb_free_gc(c, g_pixmap_gc);
    xcb_free_pixmap(c, g_pixmap);
  }

  if (!load_image(filename)) {
    return false;
  }
  wuffs_base__table_u8 tab = g_pixbuf.plane(0);

  xcb_create_pixmap(c, g_pictforminfo->depth, g_pixmap, w, g_width, g_height);
  xcb_create_gc(c, g_pixmap_gc, g_pixmap, 0, NULL);
  xcb_render_create_picture(c, g_pixmap_picture, g_pixmap, g_pictforminfo->id,
                            0, NULL);
  apply_zoom_and_filter(c);

  // Copy the pixels from the X11 client process (this process) to the X11
  // server process. For large images, this may involve multiple xcb_image_put
  // calls, each copying part of the pixels (a strip that has the same width
  // but smaller height), to avoid XCB_CONN_CLOSED_REQ_LEN_EXCEED.
  if (g_width > 0) {
    uint32_t max_strip_height = g_maximum_request_length / g_width;
    for (uint32_t y = 0; y < g_height;) {
      uint32_t h = g_height - y;
      if (h > max_strip_height) {
        h = max_strip_height;
      }

      // Make libxcb-image interpret WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL as
      // XCB_PICT_STANDARD_ARGB_32 with byte_order XCB_IMAGE_ORDER_LSB_FIRST.
      xcb_image_t* unconverted =
          xcb_image_create(g_width,                      // width
                           h,                            // height
                           XCB_IMAGE_FORMAT_Z_PIXMAP,    // format
                           32,                           // xpad
                           g_pictforminfo->depth,        // depth
                           32,                           // bpp
                           32,                           // unit
                           XCB_IMAGE_ORDER_LSB_FIRST,    // byte_order
                           XCB_IMAGE_ORDER_MSB_FIRST,    // bit_order
                           NULL,                         // base
                           h * tab.stride,               // bytes
                           tab.ptr + (y * tab.stride));  // data

      xcb_image_t* converted =
          xcb_image_native(c, unconverted, true);  // true means to convert.
      if (converted != unconverted) {
        xcb_image_destroy(unconverted);
      }
      xcb_image_put(c, g_pixmap, g_pixmap_gc, converted, 0, y, 0);
      xcb_image_destroy(converted);

      y += h;
    }
  }

  return true;
}

int  //
main(int argc, char** argv) {
  const char* status = parse_flags(argc, argv);
  if (status) {
    fprintf(stderr, "%s\n", status);
    return 1;
  }

  xcb_connection_t* c = xcb_connect(NULL, NULL);

  g_maximum_request_length = xcb_get_maximum_request_length(c);
  // Our X11 requests (especially xcb_image_put) also need a header, in terms
  // of wire format. 256 4-byte units should be big enough.
  const uint32_t max_req_len_adjustment = 256;
  if (g_maximum_request_length < max_req_len_adjustment) {
    printf("XCB failure (maximum request length is too short)\n");
    exit(EXIT_FAILURE);
  }
  g_maximum_request_length -= max_req_len_adjustment;

  const xcb_setup_t* z = xcb_get_setup(c);
  xcb_screen_t* s = xcb_setup_roots_iterator(z).data;

  const xcb_render_query_pict_formats_reply_t* pict_formats =
      xcb_render_util_query_formats(c);
  g_pictforminfo = xcb_render_util_find_standard_format(
      pict_formats, XCB_PICT_STANDARD_ARGB_32);

  {
    xcb_intern_atom_cookie_t cookie0 =
        xcb_intern_atom(c, 1, 12, "_NET_WM_NAME");
    xcb_intern_atom_cookie_t cookie1 = xcb_intern_atom(c, 1, 11, "UTF8_STRING");
    xcb_intern_atom_cookie_t cookie2 =
        xcb_intern_atom(c, 1, 12, "WM_PROTOCOLS");
    xcb_intern_atom_cookie_t cookie3 =
        xcb_intern_atom(c, 1, 16, "WM_DELETE_WINDOW");
    xcb_intern_atom_reply_t* reply0 = xcb_intern_atom_reply(c, cookie0, NULL);
    xcb_intern_atom_reply_t* reply1 = xcb_intern_atom_reply(c, cookie1, NULL);
    xcb_intern_atom_reply_t* reply2 = xcb_intern_atom_reply(c, cookie2, NULL);
    xcb_intern_atom_reply_t* reply3 = xcb_intern_atom_reply(c, cookie3, NULL);
    g_atom_net_wm_name = reply0->atom;
    g_atom_utf8_string = reply1->atom;
    g_atom_wm_protocols = reply2->atom;
    g_atom_wm_delete_window = reply3->atom;
    free(reply0);
    free(reply1);
    free(reply2);
    free(reply3);
  }

  xcb_window_t w = make_window(c, s);
  xcb_render_picture_t p = xcb_generate_id(c);
  xcb_render_create_picture(
      c, p, w,
      xcb_render_util_find_visual_format(pict_formats, s->root_visual)->format,
      0, NULL);
  init_keymap(c, z);
  xcb_flush(c);

  g_pixmap = xcb_generate_id(c);
  g_pixmap_gc = xcb_generate_id(c);
  g_pixmap_picture = xcb_generate_id(c);

  bool loaded = load(
      c, w, (g_flags.remaining_argc > 0) ? g_flags.remaining_argv[0] : NULL);
  int arg = 0;

  while (true) {
    xcb_generic_event_t* event = xcb_wait_for_event(c);
    if (!event) {
      printf("XCB failure (error code %d)\n", xcb_connection_has_error(c));
      exit(EXIT_FAILURE);
    }

    bool reload = false;
    switch (event->response_type & 0x7F) {
      case XCB_EXPOSE: {
        xcb_expose_event_t* e = (xcb_expose_event_t*)event;
        if (loaded && (e->count == 0)) {
          xcb_render_composite(c, XCB_RENDER_PICT_OP_SRC, g_pixmap_picture,
                               XCB_NONE, p, 0, 0, 0, 0, 0, 0,
                               zoom_shift(g_width), zoom_shift(g_height));
          xcb_flush(c);
        }
        break;
      }

      case XCB_KEY_PRESS: {
        xcb_key_press_event_t* e = (xcb_key_press_event_t*)event;
        uint32_t i = e->detail;
        if ((z->min_keycode <= i) && (i <= z->max_keycode)) {
          i = g_keysyms[(i - z->min_keycode) *
                        g_keyboard_mapping->keysyms_per_keycode];
          switch (i) {
            case XK_Escape:
              return 0;

            case ' ':
            case XK_BackSpace:
            case XK_Return:
              if (g_flags.remaining_argc <= 1) {
                break;
              }
              arg += (i != XK_BackSpace) ? +1 : -1;
              if (arg < 0) {
                arg = g_flags.remaining_argc - 1;
              } else if (arg == g_flags.remaining_argc) {
                arg = 0;
              }
              reload = true;
              break;

            case ',':
            case '.':
              g_background_color_index +=
                  (i == ',') ? (NUM_BACKGROUND_COLORS - 1) : 1;
              g_background_color_index %= NUM_BACKGROUND_COLORS;
              reload = true;
              break;

            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
              if (i == '0') {
                g_filter = !g_filter;
              } else {
                int32_t z = i - '1';
                if (e->state & XCB_MOD_MASK_SHIFT) {
                  z = -z;
                }
                if (g_zoom == z) {
                  break;
                }
                g_zoom = z;
              }
              apply_zoom_and_filter(c);
              xcb_clear_area(c, 1, w, 0, 0, 0xFFFF, 0xFFFF);
              xcb_flush(c);
              break;
          }
        }
        break;
      }

      case XCB_CLIENT_MESSAGE: {
        xcb_client_message_event_t* e = (xcb_client_message_event_t*)event;
        if (e->data.data32[0] == g_atom_wm_delete_window) {
          return 0;
        }
        break;
      }
    }

    free(event);

    if (reload) {
      loaded = load(c, w, g_flags.remaining_argv[arg]);
      xcb_clear_area(c, 1, w, 0, 0, 0xFFFF, 0xFFFF);
      xcb_flush(c);
    }
  }
  return 0;
}

#endif  // defined(__linux__)

// ---------------------------------------------------------------------

#if !defined(SUPPORTED_OPERATING_SYSTEM)

int  //
main(int argc, char** argv) {
  printf("unsupported operating system\n");
  return 1;
}

#endif  // !defined(SUPPORTED_OPERATING_SYSTEM)
