home *** CD-ROM | disk | FTP | other *** search
/ PC Shareware 1999 March / PCShareware-3-99.iso / IMPLE / DJGPP.RAR / DJGPP2 / XLIB-SR0.ZIP / SRC / XLIBEMU / CURSOR.C < prev    next >
C/C++ Source or Header  |  1994-01-14  |  9KB  |  410 lines

  1. /* $Id: cursor.c 1.2 1994/01/15 01:59:26 ulrich Exp $ */
  2. /*
  3.  * cursor.c
  4.  *
  5.  * X library cursor functions.
  6.  */
  7. #include "Xlibemu.h"
  8. #include <X11/cursorfont.h>
  9. #include "cursor.h"
  10.  
  11. #include <grxfont.h>
  12.  
  13. #define CURSOR_TABLE_MAX 100
  14.  
  15. _WCursor    cursor_table[CURSOR_TABLE_MAX] = { 0 };
  16. static int    cursor_table_max_used = 0;
  17.  
  18. GrCursor *
  19. GrBuildCursorFromBits (char *bits, char *mask_bits, int width, int height, int x_hot, int y_hot,
  20.                int fg, int bg)
  21. {
  22.   int x, y;
  23.   unsigned char mask;
  24.   char *data, *data_ptr;
  25.   int colors[3];
  26.   
  27.   data_ptr = data = (char *) alloca (width * height);
  28.  
  29.   for (y = 0; y < height; y++)
  30.     {
  31.       mask = 0x01;
  32.       for (x = 0; x < width; x++)
  33.     {
  34.       if (*(unsigned char *)bits & mask)
  35.         *data_ptr++ = 2;
  36.       else if (*(unsigned char *)mask_bits & mask)
  37.         *data_ptr++ = 1;
  38.       else
  39.         *data_ptr++ = 0;
  40.  
  41.       if (mask == 0x80) {
  42.         bits++;
  43.         mask_bits++;
  44.         mask = 0x01;
  45.       }
  46.       else mask <<= 1;
  47.     }
  48.       if (mask != 0x01) {
  49.     bits++;
  50.     mask_bits++;
  51.       }
  52.     }
  53.   colors[0] = 2;
  54.   colors[1] = bg;
  55.   colors[2] = fg;
  56.   return GrBuildCursor (data, width, height, x_hot, y_hot, colors);
  57. }
  58.  
  59. GrCursor *
  60. GrBuildXCursor (int shape, int fg, int bg)
  61. {
  62.   int width, height, x_hot, y_hot;
  63.   char *bits, *mask_bits;
  64.   switch (shape) {
  65. #define CASE_XC(name) \
  66.   case XC_ ## name: \
  67.     width = name ## _width; \
  68.     height = name ## _height; \
  69.     x_hot = name ## _x_hot; \
  70.     y_hot = name ## _y_hot; \
  71.     bits = name ## _bits; \
  72.     mask_bits = name ## _mask_bits; \
  73.     break
  74.  
  75.   CASE_XC(X_cursor);
  76.   CASE_XC(arrow);
  77.   CASE_XC(based_arrow_down);
  78.   CASE_XC(based_arrow_up);
  79.   CASE_XC(boat);
  80.   CASE_XC(bogosity);
  81.   CASE_XC(bottom_left_corner);
  82.   CASE_XC(bottom_right_corner);
  83.   CASE_XC(bottom_side);
  84.   CASE_XC(bottom_tee);
  85.   CASE_XC(box_spiral);
  86.   CASE_XC(center_ptr);
  87.   CASE_XC(circle);
  88.   CASE_XC(clock);
  89.   CASE_XC(coffee_mug);
  90.   CASE_XC(cross);
  91.   CASE_XC(cross_reverse);
  92.   CASE_XC(crosshair);
  93.   CASE_XC(diamond_cross);
  94.   CASE_XC(dot);
  95.   CASE_XC(dotbox);
  96.   CASE_XC(double_arrow);
  97.   CASE_XC(draft_large);
  98.   CASE_XC(draft_small);
  99.   CASE_XC(draped_box);
  100.   CASE_XC(exchange);
  101.   CASE_XC(fleur);
  102.   CASE_XC(gobbler);
  103.   CASE_XC(gumby);
  104.   CASE_XC(hand1);
  105.   CASE_XC(hand2);
  106.   CASE_XC(heart);
  107.   CASE_XC(icon);
  108.   CASE_XC(iron_cross);
  109.   CASE_XC(left_ptr);
  110.   CASE_XC(left_side);
  111.   CASE_XC(left_tee);
  112.   CASE_XC(leftbutton);
  113.   CASE_XC(ll_angle);
  114.   CASE_XC(lr_angle);
  115.   CASE_XC(man);
  116.   CASE_XC(middlebutton);
  117.   CASE_XC(mouse);
  118.   CASE_XC(pencil);
  119.   CASE_XC(pirate);
  120.   CASE_XC(plus);
  121.   CASE_XC(question_arrow);
  122.   CASE_XC(right_ptr);
  123.   CASE_XC(right_side);
  124.   CASE_XC(right_tee);
  125.   CASE_XC(rightbutton);
  126.   CASE_XC(rtl_logo);
  127.   CASE_XC(sailboat);
  128.   CASE_XC(sb_down_arrow);
  129.   CASE_XC(sb_h_double_arrow);
  130.   CASE_XC(sb_left_arrow);
  131.   CASE_XC(sb_right_arrow);
  132.   CASE_XC(sb_up_arrow);
  133.   CASE_XC(sb_v_double_arrow);
  134.   CASE_XC(shuttle);
  135.   CASE_XC(sizing);
  136.   CASE_XC(spider);
  137.   CASE_XC(spraycan);
  138.   CASE_XC(star);
  139.   CASE_XC(target);
  140.   CASE_XC(tcross);
  141.   CASE_XC(top_left_arrow);
  142.   CASE_XC(top_left_corner);
  143.   CASE_XC(top_right_corner);
  144.   CASE_XC(top_side);
  145.   CASE_XC(top_tee);
  146.   CASE_XC(trek);
  147.   CASE_XC(ul_angle);
  148.   CASE_XC(umbrella);
  149.   CASE_XC(ur_angle);
  150.   CASE_XC(watch);
  151.   CASE_XC(xterm);
  152.     
  153. #undef CASE_XC
  154.   default:
  155.     return (GrCursor *) 0;
  156.   }
  157.   return GrBuildCursorFromBits (bits, mask_bits, width, height, x_hot, y_hot, fg, bg);
  158. }
  159.  
  160.  
  161. Cursor
  162. XCreateGlyphCursor
  163. (Display*    display,
  164.  Font        source_font,
  165.  Font        mask_font,
  166.  unsigned int    source_char,
  167.  unsigned int    mask_char,
  168.  XColor*    foreground_color,
  169.  XColor*    background_color)
  170. {
  171.   char *src_bitmap;
  172.   char *msk_bitmap;
  173.   char *pixmap;
  174.   int src_width, src_height;
  175.   int msk_width, msk_height;
  176.   int width, height;
  177.   int chr;
  178.   int x, y;
  179.   XColor fgc, bgc;
  180.   Cursor cursor;
  181.   int colors[3];
  182.  
  183.   if (source_font == None) {
  184.     _WError (display, (XID) source_font, BadFont, X_CreateGlyphCursor);
  185.     return None;
  186.   }
  187.   if (mask_font == None) {
  188.     mask_font = source_font;
  189.   }
  190.   
  191.   if (source_char < source_font->fnt_minchar ||
  192.       source_char > source_font->fnt_maxchar) {
  193.     _WError (display, (XID) source_font, BadValue, X_CreateGlyphCursor);
  194.     return None;
  195.   }
  196.   if (mask_char < mask_font->fnt_minchar ||
  197.       mask_char > mask_font->fnt_maxchar) {
  198.     _WError (display, (XID) mask_font, BadValue, X_CreateGlyphCursor);
  199.     return None;
  200.   }
  201.  
  202.   chr = source_char - source_font->fnt_minchar;
  203.   if (source_font->fnt_isfixed) {
  204.     src_bitmap = FFP(source_font)->ff_bits + (chr * FFP(source_font)->ff_chrsize);
  205.     src_width = source_font->fnt_width;
  206.     src_height = source_font->fnt_height;
  207.   }
  208.   else {
  209.     src_bitmap = PFP(source_font)->pf_bits[chr];
  210.     src_width  = PFP(source_font)->pf_width[chr];
  211.     src_height = source_font->fnt_height;
  212.   }
  213.   chr = source_char - mask_font->fnt_minchar;
  214.   if (mask_font->fnt_isfixed) {
  215.     msk_bitmap = FFP(mask_font)->ff_bits + (chr * FFP(mask_font)->ff_chrsize);
  216.     msk_width = mask_font->fnt_width;
  217.     msk_height = mask_font->fnt_height;
  218.   }
  219.   else {
  220.     msk_bitmap = PFP(mask_font)->pf_bits[chr];
  221.     msk_width  = PFP(mask_font)->pf_width[chr];
  222.     msk_height = mask_font->fnt_height;
  223.   }
  224.   width = src_width;
  225.   if (msk_width > width) width = msk_width;
  226.   height = src_height; 
  227.   if (msk_height > height) height = msk_height;
  228.  
  229.   fgc = *foreground_color;
  230.   bgc = *background_color;
  231.   fgc.pixel = WhitePixel (display, DefaultScreen (display));
  232.   bgc.pixel = BlackPixel (display, DefaultScreen (display));
  233.   XAllocColor (display, DefaultColormap(display, DefaultScreen (display)), &fgc);
  234.   XAllocColor (display, DefaultColormap(display, DefaultScreen (display)), &bgc);
  235.  
  236. #define getbit(p,w,x,y) ((p[y * ((w+7)/8) + (x/8)] & (0x80 >> (x%8))) ? 1 : 0)
  237.  
  238.   pixmap = (char *) calloc (1, width * height);
  239.   for (y = 0; y < msk_height; y++)
  240.     for (x = 0; x < msk_width; x++) {
  241.       if (getbit (msk_bitmap, msk_width, x, y))
  242.     pixmap[y * width + x] = 1;
  243.     }
  244.   for (y = 0; y < src_height; y++)
  245.     for (x = 0; x < src_width; x++) {
  246.       if (getbit (src_bitmap, src_width, x, y))
  247.     pixmap[y * width + x] = 2;
  248.     }
  249. #undef getbit
  250.  
  251.   colors[0] = 2;
  252.   colors[1] = bgc.pixel;
  253.   colors[2] = fgc.pixel;
  254.   cursor = GrBuildCursor (pixmap, width, height,
  255.               source_font->fnt_undwidth,
  256.               source_font->fnt_baseline,
  257.               colors);
  258.   free (pixmap);
  259.   
  260.   return cursor;
  261. }
  262.  
  263. Cursor
  264. XCreateFontCursor
  265. (Display*    display,
  266.  unsigned int    shape)
  267. {
  268.   int i, first_free;
  269.  
  270.   if (shape > XC_num_glyphs)
  271.     return None;
  272.  
  273.   /* first look if cursor alread loaded */
  274.  
  275.   first_free = cursor_table_max_used;
  276.   for (i = 0; i < cursor_table_max_used; i++) {
  277.     if (cursor_table[i].cursor != NULL) {
  278.       if (cursor_table[i].shape == shape)
  279.     {
  280.       cursor_table[i].refcount++;
  281.       return cursor_table[i].cursor;
  282.     }
  283.     }
  284.     else {
  285.       if (i < first_free) first_free = i;
  286.     }
  287.   }
  288.  
  289.   if (first_free >= CURSOR_TABLE_MAX)
  290.     return None;
  291.  
  292.   cursor_table[first_free].shape = shape;
  293.   cursor_table[first_free].refcount = 1;
  294.   cursor_table[first_free].cursor =
  295.     GrBuildXCursor (shape,
  296.             BlackPixel(display, DefaultScreen (display)),
  297.             WhitePixel(display, DefaultScreen (display)));
  298.  
  299.   return cursor_table[first_free].cursor;
  300. }
  301.  
  302. Cursor XCreatePixmapCursor(
  303.     Display*        display,
  304.     Pixmap        source,
  305.     Pixmap        mask,
  306.     XColor*        foreground_color,
  307.     XColor*        background_color,
  308.     unsigned int    x,
  309.     unsigned int    y)
  310. {
  311.   return XCreateFontCursor (display, XC_X_cursor);
  312. }
  313.  
  314. Status
  315. XQueryBestCursor
  316. (Display*    display,
  317.  Drawable    d,
  318.  unsigned int   width,
  319.  unsigned int    height,
  320.  unsigned int*    width_return,
  321.  unsigned int*    height_return)
  322. {
  323.   *width_return = (width + 7) & ~7;
  324.   *height_return = (height + 7) & ~7;
  325.   return Success;
  326. }
  327.  
  328. int
  329. XFreeCursor
  330. (Display*    display,
  331.  Cursor        cursor)
  332. {
  333.   int i;
  334.  
  335.   for (i = 0; i < cursor_table_max_used; i++) {
  336.     if (cursor_table[i].cursor == cursor &&
  337.     cursor_table[i].refcount > 0)
  338.       {
  339.     if (--cursor_table[i].refcount == 0) {
  340.       GrDestroyCursor (cursor_table[i].cursor);
  341.       cursor_table[i].cursor = NULL;
  342.       if (i == (cursor_table_max_used - 1))
  343.         --cursor_table_max_used;
  344.     }
  345.     return 1;
  346.       }
  347.   }
  348.   return 0;
  349. }
  350.  
  351. int
  352. XRecolorCursor
  353. (Display*    display,
  354.  Cursor        cursor,
  355.  XColor*    foreground_color,
  356.  XColor*    background_color)
  357. {
  358.   return 0;
  359. }
  360.  
  361.  
  362. #ifdef TEST
  363.  
  364. int
  365. main()
  366. {
  367.   int xc, x, y, dx, dy, yellow;
  368.   GrCursor *cr;
  369.  
  370.   GrSetMode (GR_default_graphics);
  371.   GrClearScreen (GrAllocColor (84, 112, 170));
  372.   yellow = GrAllocColor (250, 250, 0);
  373.  
  374.   dx = dy = 64;
  375.  
  376.   x = dx;
  377.   y = dy;
  378.   for (xc = 0; xc < XC_num_glyphs; xc += 2)
  379.     {
  380.       cr = GrBuildXCursor (xc, GrBlack(), GrWhite());
  381.       GrLine (x-20, y, x+20, y, yellow);
  382.       GrLine (x, y-20, x, y+20, yellow);
  383.       GrMoveCursor (cr, x, y);
  384.       GrDisplayCursor (cr);
  385.       x += dx;
  386.       if (x >= GrScreenX() - dx)
  387.     y += dy, x = dx;
  388.     }
  389.  
  390.   MouseEventMode (1);
  391.   for (xc = 0; xc < XC_num_glyphs; )
  392.     {
  393.       MouseEvent event;
  394.       MouseGetEvent (M_EVENT|M_KEYPRESS, &event);
  395.       if (event.flags & M_KEYPRESS) {
  396.     break;
  397.       }
  398.       if (event.flags & M_BUTTON_DOWN) {
  399.     cr = GrBuildXCursor (xc, GrBlack(), GrWhite());
  400.     MouseSetCursor (cr);
  401.     xc += 2;
  402.       }
  403.     }
  404.  
  405.   GrSetMode (GR_default_text);
  406.  
  407.   exit (0);
  408. }
  409. #endif
  410.