File:  [Qemu by Fabrice Bellard] / qemu / cursor.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 19:17:35 2018 UTC (3 years, 1 month ago) by root
Branches: qemu, MAIN
CVS tags: qemu1001, HEAD
qemu 1.0.1

    1: #include "qemu-common.h"
    2: #include "console.h"
    3: 
    4: #include "cursor_hidden.xpm"
    5: #include "cursor_left_ptr.xpm"
    6: 
    7: /* for creating built-in cursors */
    8: static QEMUCursor *cursor_parse_xpm(const char *xpm[])
    9: {
   10:     QEMUCursor *c;
   11:     uint32_t ctab[128];
   12:     unsigned int width, height, colors, chars;
   13:     unsigned int line = 0, i, r, g, b, x, y, pixel;
   14:     char name[16];
   15:     uint8_t idx;
   16: 
   17:     /* parse header line: width, height, #colors, #chars */
   18:     if (sscanf(xpm[line], "%d %d %d %d", &width, &height, &colors, &chars) != 4) {
   19:         fprintf(stderr, "%s: header parse error: \"%s\"\n",
   20:                 __FUNCTION__, xpm[line]);
   21:         return NULL;
   22:     }
   23:     if (chars != 1) {
   24:         fprintf(stderr, "%s: chars != 1 not supported\n", __FUNCTION__);
   25:         return NULL;
   26:     }
   27:     line++;
   28: 
   29:     /* parse color table */
   30:     for (i = 0; i < colors; i++, line++) {
   31:         if (sscanf(xpm[line], "%c c %15s", &idx, name) == 2) {
   32:             if (sscanf(name, "#%02x%02x%02x", &r, &g, &b) == 3) {
   33:                 ctab[idx] = (0xff << 24) | (b << 16) | (g << 8) | r;
   34:                 continue;
   35:             }
   36:             if (strcmp(name, "None") == 0) {
   37:                 ctab[idx] = 0x00000000;
   38:                 continue;
   39:             }
   40:         }
   41:         fprintf(stderr, "%s: color parse error: \"%s\"\n",
   42:                 __FUNCTION__, xpm[line]);
   43:         return NULL;
   44:     }
   45: 
   46:     /* parse pixel data */
   47:     c = cursor_alloc(width, height);
   48:     for (pixel = 0, y = 0; y < height; y++, line++) {
   49:         for (x = 0; x < height; x++, pixel++) {
   50:             idx = xpm[line][x];
   51:             c->data[pixel] = ctab[idx];
   52:         }
   53:     }
   54:     return c;
   55: }
   56: 
   57: /* nice for debugging */
   58: void cursor_print_ascii_art(QEMUCursor *c, const char *prefix)
   59: {
   60:     uint32_t *data = c->data;
   61:     int x,y;
   62: 
   63:     for (y = 0; y < c->height; y++) {
   64:         fprintf(stderr, "%s: %2d: |", prefix, y);
   65:         for (x = 0; x < c->width; x++, data++) {
   66:             if ((*data & 0xff000000) != 0xff000000) {
   67:                 fprintf(stderr, " "); /* transparent */
   68:             } else if ((*data & 0x00ffffff) == 0x00ffffff) {
   69:                 fprintf(stderr, "."); /* white */
   70:             } else if ((*data & 0x00ffffff) == 0x00000000) {
   71:                 fprintf(stderr, "X"); /* black */
   72:             } else {
   73:                 fprintf(stderr, "o"); /* other */
   74:             }
   75:         }
   76:         fprintf(stderr, "|\n");
   77:     }
   78: }
   79: 
   80: QEMUCursor *cursor_builtin_hidden(void)
   81: {
   82:     QEMUCursor *c;
   83: 
   84:     c = cursor_parse_xpm(cursor_hidden_xpm);
   85:     return c;
   86: }
   87: 
   88: QEMUCursor *cursor_builtin_left_ptr(void)
   89: {
   90:     QEMUCursor *c;
   91: 
   92:     c = cursor_parse_xpm(cursor_left_ptr_xpm);
   93:     return c;
   94: }
   95: 
   96: QEMUCursor *cursor_alloc(int width, int height)
   97: {
   98:     QEMUCursor *c;
   99:     int datasize = width * height * sizeof(uint32_t);
  100: 
  101:     c = g_malloc0(sizeof(QEMUCursor) + datasize);
  102:     c->width  = width;
  103:     c->height = height;
  104:     c->refcount = 1;
  105:     return c;
  106: }
  107: 
  108: void cursor_get(QEMUCursor *c)
  109: {
  110:     c->refcount++;
  111: }
  112: 
  113: void cursor_put(QEMUCursor *c)
  114: {
  115:     if (c == NULL)
  116:         return;
  117:     c->refcount--;
  118:     if (c->refcount)
  119:         return;
  120:     g_free(c);
  121: }
  122: 
  123: int cursor_get_mono_bpl(QEMUCursor *c)
  124: {
  125:     return (c->width + 7) / 8;
  126: }
  127: 
  128: void cursor_set_mono(QEMUCursor *c,
  129:                      uint32_t foreground, uint32_t background, uint8_t *image,
  130:                      int transparent, uint8_t *mask)
  131: {
  132:     uint32_t *data = c->data;
  133:     uint8_t bit;
  134:     int x,y,bpl;
  135: 
  136:     bpl = cursor_get_mono_bpl(c);
  137:     for (y = 0; y < c->height; y++) {
  138:         bit = 0x80;
  139:         for (x = 0; x < c->width; x++, data++) {
  140:             if (transparent && mask[x/8] & bit) {
  141:                 *data = 0x00000000;
  142:             } else if (!transparent && !(mask[x/8] & bit)) {
  143:                 *data = 0x00000000;
  144:             } else if (image[x/8] & bit) {
  145:                 *data = 0xff000000 | foreground;
  146:             } else {
  147:                 *data = 0xff000000 | background;
  148:             }
  149:             bit >>= 1;
  150:             if (bit == 0) {
  151:                 bit = 0x80;
  152:             }
  153:         }
  154:         mask  += bpl;
  155:         image += bpl;
  156:     }
  157: }
  158: 
  159: void cursor_get_mono_image(QEMUCursor *c, int foreground, uint8_t *image)
  160: {
  161:     uint32_t *data = c->data;
  162:     uint8_t bit;
  163:     int x,y,bpl;
  164: 
  165:     bpl = cursor_get_mono_bpl(c);
  166:     memset(image, 0, bpl * c->height);
  167:     for (y = 0; y < c->height; y++) {
  168:         bit = 0x80;
  169:         for (x = 0; x < c->width; x++, data++) {
  170:             if (((*data & 0xff000000) == 0xff000000) &&
  171:                 ((*data & 0x00ffffff) == foreground)) {
  172:                 image[x/8] |= bit;
  173:             }
  174:             bit >>= 1;
  175:             if (bit == 0) {
  176:                 bit = 0x80;
  177:             }
  178:         }
  179:         image += bpl;
  180:     }
  181: }
  182: 
  183: void cursor_get_mono_mask(QEMUCursor *c, int transparent, uint8_t *mask)
  184: {
  185:     uint32_t *data = c->data;
  186:     uint8_t bit;
  187:     int x,y,bpl;
  188: 
  189:     bpl = cursor_get_mono_bpl(c);
  190:     memset(mask, 0, bpl * c->height);
  191:     for (y = 0; y < c->height; y++) {
  192:         bit = 0x80;
  193:         for (x = 0; x < c->width; x++, data++) {
  194:             if ((*data & 0xff000000) != 0xff000000) {
  195:                 if (transparent != 0) {
  196:                     mask[x/8] |= bit;
  197:                 }
  198:             } else {
  199:                 if (transparent == 0) {
  200:                     mask[x/8] |= bit;
  201:                 }
  202:             }
  203:             bit >>= 1;
  204:             if (bit == 0) {
  205:                 bit = 0x80;
  206:             }
  207:         }
  208:         mask += bpl;
  209:     }
  210: }

unix.superglobalmegacorp.com