src/events/SDL_mouse.c
author Szymon Wilczek
Sun, 06 Jul 2008 09:24:56 +0000
branchgsoc2008_manymouse
changeset 3766 24db5d326f57
parent 3765 ed9b7fe8f902
child 3767 abc8acb8e3d7
permissions -rw-r--r--
Pressure levels. Documentation http://wilku.ravenlord.ws/doku.php?id=documentation
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2006 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 
    24 /* General mouse handling code for SDL */
    25 
    26 #include "SDL_events.h"
    27 #include "SDL_events_c.h"
    28 #include "default_cursor.h"
    29 
    30 
    31 static int SDL_num_mice;
    32 static int SDL_current_mouse;
    33 static SDL_Mouse **SDL_mice;
    34 int *SDL_IdIndex;
    35 int SDL_highestId;
    36 int last_x, last_y;
    37 int x_max, y_max;
    38 /* Public functions */
    39 int
    40 SDL_MouseInit(void)
    41 {
    42     return (0);
    43 }
    44 
    45 SDL_Mouse *
    46 SDL_GetMouse(int index)
    47 {
    48     if (index < 0 || index >= SDL_num_mice) {
    49         return NULL;
    50     }
    51     return SDL_mice[index];
    52 }
    53 
    54 int
    55 SDL_AddMouse(const SDL_Mouse * mouse, int index, char* name,int pressure_max,int pressure_min)
    56 {
    57     SDL_Mouse **mice;
    58     int selected_mouse;
    59     char* temp_name;
    60     /* Add the mouse to the list of mice */
    61     if (index < 0 || index >= SDL_num_mice || SDL_mice[index]) {
    62         mice =
    63             (SDL_Mouse **) SDL_realloc(SDL_mice,
    64                                        (SDL_num_mice + 1) * sizeof(*mice));
    65         if (!mice) {
    66             SDL_OutOfMemory();
    67             return -1;
    68         }
    69 
    70         SDL_mice = mice;
    71         index = SDL_num_mice++;
    72     }
    73     SDL_mice[index] = (SDL_Mouse *) SDL_malloc(sizeof(*SDL_mice[index]));
    74     if (!SDL_mice[index]) {
    75         SDL_OutOfMemory();
    76         return -1;
    77     }
    78     *SDL_mice[index] = *mouse;
    79     SDL_mice[index]->name=SDL_malloc(strlen(name)*sizeof(char));
    80     strcpy(SDL_mice[index]->name,name);
    81     SDL_mice[index]->pressure_max=pressure_max;
    82     SDL_mice[index]->pressure_min=pressure_min;
    83     SDL_mice[index]->cursor_shown = SDL_TRUE;
    84     selected_mouse = SDL_SelectMouse(index);
    85     SDL_mice[index]->cur_cursor = NULL;
    86     SDL_mice[index]->def_cursor =
    87         SDL_CreateCursor(default_cdata, default_cmask, DEFAULT_CWIDTH,
    88                          DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY);
    89     SDL_SetCursor(SDL_mice[index]->def_cursor);
    90     SDL_mice[index]->proximity=SDL_TRUE;
    91     SDL_mice[index]->relative_mode=SDL_FALSE;
    92     SDL_SelectMouse(selected_mouse);
    93 
    94     return index;
    95 }
    96 
    97 void
    98 SDL_DelMouse(int index)
    99 {
   100     SDL_Mouse *mouse = SDL_GetMouse(index);
   101 
   102     if (!mouse) {
   103         return;
   104     }
   105 
   106     mouse->def_cursor = NULL;
   107     SDL_free(mouse->name);
   108     while (mouse->cursors) {
   109         SDL_FreeCursor(mouse->cursors);
   110     }
   111 
   112     if (mouse->FreeMouse) {
   113         mouse->FreeMouse(mouse);
   114     }
   115     SDL_free(mouse);
   116 
   117     SDL_mice[index] = NULL;
   118 }
   119 
   120 void
   121 SDL_ResetMouse(int index)
   122 {
   123     SDL_Mouse *mouse = SDL_GetMouse(index);
   124 
   125     if (!mouse) {
   126         return;
   127     }
   128 
   129     /* FIXME */
   130 }
   131 
   132 void
   133 SDL_MouseQuit(void)
   134 {
   135     int i;
   136 
   137     for (i = 0; i < SDL_num_mice; ++i) {
   138         SDL_DelMouse(i);
   139     }
   140     SDL_num_mice = 0;
   141     SDL_current_mouse = 0;
   142 
   143     if (SDL_mice) {
   144         SDL_free(SDL_mice);
   145         SDL_mice = NULL;
   146     }
   147 }
   148 
   149 int
   150 SDL_GetNumMice(void)
   151 {
   152     return SDL_num_mice;
   153 }
   154 
   155 int
   156 SDL_SelectMouse(int index)
   157 {
   158     if (index >= 0 && index < SDL_num_mice) {
   159         SDL_current_mouse = index;
   160     }
   161     return SDL_current_mouse;
   162 }
   163 
   164 SDL_WindowID
   165 SDL_GetMouseFocusWindow()
   166 {
   167     SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   168 
   169     if (!mouse) {
   170         return 0;
   171     }
   172     return mouse->focus;
   173 }
   174 
   175 static int SDLCALL
   176 FlushMouseMotion(void *param, SDL_Event * event)
   177 {
   178     if (event->type == SDL_MOUSEMOTION
   179         && event->motion.which == (Uint8) SDL_current_mouse) {
   180         return 0;
   181     } else {
   182         return 1;
   183     }
   184 }
   185 
   186 int
   187 SDL_SetRelativeMouseMode(SDL_bool enabled, int index)
   188 {
   189     SDL_Mouse *mouse = SDL_GetMouse(index);
   190 
   191     if (!mouse) {
   192         return -1;
   193     }
   194 
   195     /* Flush pending mouse motion */
   196     mouse->flush_motion = SDL_TRUE;
   197     SDL_PumpEvents();
   198     mouse->flush_motion = SDL_FALSE;
   199     SDL_FilterEvents(FlushMouseMotion, mouse);
   200 
   201     /* Set the relative mode */
   202     mouse->relative_mode = enabled;
   203 
   204     /* Update cursor visibility */
   205     SDL_SetCursor(NULL);
   206 
   207     if (!enabled) {
   208         /* Restore the expected mouse position */
   209         SDL_WarpMouseInWindow(mouse->focus, mouse->x, mouse->y);
   210     }
   211     return 0;
   212 }
   213 
   214 SDL_bool
   215 SDL_GetRelativeMouseMode()
   216 {
   217     SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   218 
   219     if (!mouse) {
   220         return SDL_FALSE;
   221     }
   222     return mouse->relative_mode;
   223 }
   224 
   225 Uint8
   226 SDL_GetMouseState(int *x, int *y)
   227 {
   228     SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   229 
   230     if (!mouse) {
   231         if (x) {
   232             *x = 0;
   233         }
   234         if (y) {
   235             *y = 0;
   236         }
   237         return 0;
   238     }
   239 
   240     if (x) {
   241         *x = mouse->x;
   242     }
   243     if (y) {
   244         *y = mouse->y;
   245     }
   246     return mouse->buttonstate;
   247 }
   248 
   249 Uint8
   250 SDL_GetRelativeMouseState(int *x, int *y)
   251 {
   252     SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   253 
   254     if (!mouse) {
   255         if (x) {
   256             *x = 0;
   257         }
   258         if (y) {
   259             *y = 0;
   260         }
   261         return 0;
   262     }
   263 
   264     if (x) {
   265         *x = mouse->xdelta;
   266     }
   267     if (y) {
   268         *y = mouse->ydelta;
   269     }
   270     mouse->xdelta = 0;
   271     mouse->ydelta = 0;
   272     return mouse->buttonstate;
   273 }
   274 
   275 void
   276 SDL_SetMouseFocus(int id, SDL_WindowID windowID)
   277 {
   278     int index = SDL_GetIndexById(id);
   279     SDL_Mouse *mouse = SDL_GetMouse(index);
   280     int i;
   281     SDL_bool focus;
   282 
   283     if (!mouse || (mouse->focus == windowID)) {
   284         return;
   285     }
   286 
   287     /* See if the current window has lost focus */
   288     if (mouse->focus) {
   289         focus = SDL_FALSE;
   290         for (i = 0; i < SDL_num_mice; ++i) {
   291             SDL_Mouse *check;
   292             if (i != index) {
   293                 check = SDL_GetMouse(i);
   294                 if (check && check->focus == mouse->focus) {
   295                     focus = SDL_TRUE;
   296                     break;
   297                 }
   298             }
   299         }
   300         if (!focus) {
   301             SDL_SendWindowEvent(mouse->focus, SDL_WINDOWEVENT_LEAVE, 0, 0);
   302         }
   303     }
   304 
   305     mouse->focus = windowID;
   306 
   307     if (mouse->focus) {
   308         focus = SDL_FALSE;
   309         for (i = 0; i < SDL_num_mice; ++i) {
   310             SDL_Mouse *check;
   311             if (i != index) {
   312                 check = SDL_GetMouse(i);
   313                 if (check && check->focus == mouse->focus) {
   314                     focus = SDL_TRUE;
   315                     break;
   316                 }
   317             }
   318         }
   319         if (!focus) {
   320             SDL_SendWindowEvent(mouse->focus, SDL_WINDOWEVENT_ENTER, 0, 0);
   321         }
   322     }
   323 }
   324 
   325 int
   326 SDL_SendProximity(int id, int x, int y, int type)
   327 {
   328     int index=SDL_GetIndexById(id);
   329     int posted=0;
   330     if(SDL_ProcessEvents[type]==SDL_ENABLE)
   331     {
   332         SDL_Event event;
   333         event.proximity.which=(Uint8)index;
   334         event.proximity.x=x;
   335         event.proximity.y=y;
   336         event.type=type;
   337         event.proximity.type=type;
   338         posted = (SDL_PushEvent(&event) > 0);
   339         if(type==SDL_PROXIMITYIN)
   340         {
   341             SDL_mice[index]->proximity=SDL_TRUE;
   342         }
   343         else
   344         {
   345             SDL_mice[index]->proximity=SDL_FALSE;
   346         }
   347     }
   348     return posted;
   349 }
   350 
   351 int
   352 SDL_SendMouseMotion(int id, int relative, int x, int y,int z)
   353 {
   354     int index=SDL_GetIndexById(id);
   355     SDL_Mouse *mouse = SDL_GetMouse(index);
   356     int posted;
   357     int xrel;
   358     int yrel;
   359 
   360     if (!mouse || mouse->flush_motion) {
   361         return 0;
   362     }
   363     if(mouse->proximity==SDL_FALSE)
   364     {
   365         last_x=x;
   366         last_y=y;
   367         return 0;
   368     }
   369     if (mouse->relative_mode==SDL_TRUE && mouse->proximity==SDL_TRUE) {
   370         /* Push the cursor around */
   371         xrel = x - last_x;
   372         yrel = y - last_y;
   373     } else {
   374         xrel = x - last_x;
   375         yrel = y - last_y;
   376     }
   377 
   378     /* Drop events that don't change state */
   379     if (!xrel && !yrel) {
   380 #if 0
   381         printf("Mouse event didn't change state - dropped!\n");
   382 #endif
   383         return 0;
   384     }
   385 
   386     /* Update internal mouse state */
   387     if (mouse->relative_mode==SDL_FALSE) {
   388         mouse->x = x;
   389         mouse->y = y;
   390     }
   391     else
   392     {
   393         if(mouse->x+xrel>x_max)
   394         {
   395             mouse->x=x_max;
   396         }
   397         else if(mouse->x+xrel<0)
   398         {
   399             mouse->x=0;
   400         }
   401         else
   402         {
   403             mouse->x+=xrel;
   404         }
   405         if(mouse->y+yrel>y_max)
   406         {
   407             mouse->y=y_max;
   408         }
   409         else if(mouse->y+yrel<0)
   410         {
   411             mouse->y=0;
   412         }
   413         else
   414         {
   415             mouse->y+=yrel;
   416         }
   417     }
   418     mouse->xdelta += xrel;
   419     mouse->ydelta += yrel;
   420     mouse->pressure=z;
   421 
   422     /* Move the mouse cursor, if needed */
   423     if (mouse->cursor_shown && !mouse->relative_mode &&
   424         mouse->MoveCursor && mouse->cur_cursor) {
   425         mouse->MoveCursor(mouse->cur_cursor);
   426     }
   427 
   428     /* Post the event, if desired */
   429     posted = 0;
   430     if (SDL_ProcessEvents[SDL_MOUSEMOTION] == SDL_ENABLE && SDL_mice[index]->proximity==SDL_TRUE) {
   431         SDL_Event event;
   432         event.motion.type = SDL_MOUSEMOTION;
   433 event.motion.which = (Uint8) index;
   434         event.motion.state = mouse->buttonstate;
   435         event.motion.x = mouse->x;
   436         event.motion.y = mouse->y;
   437         event.motion.pressure= mouse->pressure;
   438         event.motion.xrel = xrel;
   439         event.motion.yrel = yrel;
   440         event.motion.windowID = mouse->focus;
   441         event.motion.pressure_max=mouse->pressure_max;
   442         event.motion.pressure_min=mouse->pressure_min;
   443         posted = (SDL_PushEvent(&event) > 0);
   444     }
   445     last_x=x;
   446     last_y=y;
   447     return posted;
   448 }
   449 
   450 int
   451 SDL_SendMouseButton(int id, Uint8 state, Uint8 button)
   452 {
   453     int index=SDL_GetIndexById(id);
   454     SDL_Mouse *mouse = SDL_GetMouse(index);
   455     int posted;
   456     Uint8 type;
   457 
   458     if (!mouse) {
   459         return 0;
   460     }
   461 
   462     /* Figure out which event to perform */
   463     switch (state) {
   464     case SDL_PRESSED:
   465         if (mouse->buttonstate & SDL_BUTTON(button)) {
   466             /* Ignore this event, no state change */
   467             return 0;
   468         }
   469         type = SDL_MOUSEBUTTONDOWN;
   470         mouse->buttonstate |= SDL_BUTTON(button);
   471         break;
   472     case SDL_RELEASED:
   473         //if (!(mouse->buttonstate & SDL_BUTTON(button))) {
   474         //    /* Ignore this event, no state change */
   475         //    return 0;
   476         //}*/
   477         type = SDL_MOUSEBUTTONUP;
   478         mouse->buttonstate &= ~SDL_BUTTON(button);
   479         break;
   480     default:
   481         /* Invalid state -- bail */
   482         return 0;
   483     }
   484 
   485     /* Post the event, if desired */
   486     posted = 0;
   487     if (SDL_ProcessEvents[type] == SDL_ENABLE) {
   488         SDL_Event event;
   489         event.type = type;
   490         event.button.which = (Uint8) index;
   491         event.button.state = state;
   492         event.button.button = button;
   493         event.button.x = mouse->x;
   494         event.button.y = mouse->y;
   495         event.button.windowID = mouse->focus;
   496         posted = (SDL_PushEvent(&event) > 0);
   497     }
   498     return posted;
   499 }
   500 
   501 int
   502 SDL_SendMouseWheel(int index, int x, int y)
   503 {
   504     SDL_Mouse *mouse = SDL_GetMouse(index);
   505     int posted;
   506 
   507     if (!mouse || (!x && !y)) {
   508         return 0;
   509     }
   510 
   511     /* Post the event, if desired */
   512     posted = 0;
   513     if (SDL_ProcessEvents[SDL_MOUSEWHEEL] == SDL_ENABLE) {
   514         SDL_Event event;
   515         event.type = SDL_MOUSEWHEEL;
   516         event.wheel.which = (Uint8) index;
   517         event.wheel.x = x;
   518         event.wheel.y = y;
   519         event.wheel.windowID = mouse->focus;
   520         posted = (SDL_PushEvent(&event) > 0);
   521     }
   522     return posted;
   523 }
   524 
   525 void
   526 SDL_WarpMouseInWindow(SDL_WindowID windowID, int x, int y)
   527 {
   528     SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   529 
   530     if (!mouse) {
   531         return;
   532     }
   533 
   534     if (mouse->WarpMouse) {
   535         mouse->WarpMouse(mouse, windowID, x, y);
   536     } else {
   537         SDL_SetMouseFocus(SDL_current_mouse, windowID);
   538         SDL_SendMouseMotion(SDL_current_mouse, 0, x, y,0);
   539     }
   540 }
   541 
   542 SDL_Cursor *
   543 SDL_CreateCursor(const Uint8 * data, const Uint8 * mask,
   544                  int w, int h, int hot_x, int hot_y)
   545 {
   546     SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   547     SDL_Surface *surface;
   548     SDL_Cursor *cursor;
   549     int x, y;
   550     Uint32 *pixel;
   551     Uint8 datab, maskb;
   552     const Uint32 black = 0xFF000000;
   553     const Uint32 white = 0xFFFFFFFF;
   554     const Uint32 transparent = 0x00000000;
   555 
   556     if (!mouse) {
   557         SDL_SetError("No mice are initialized");
   558         return NULL;
   559     }
   560 
   561     if (!mouse->CreateCursor) {
   562         SDL_SetError("Current mouse doesn't have cursor support");
   563         return NULL;
   564     }
   565 
   566     /* Sanity check the hot spot */
   567     if ((hot_x < 0) || (hot_y < 0) || (hot_x >= w) || (hot_y >= h)) {
   568         SDL_SetError("Cursor hot spot doesn't lie within cursor");
   569         return NULL;
   570     }
   571 
   572     /* Make sure the width is a multiple of 8 */
   573     w = ((w + 7) & ~7);
   574 
   575     /* Create the surface from a bitmap */
   576     surface =
   577         SDL_CreateRGBSurface(0, w, h, 32, 0x00FF0000, 0x0000FF00, 0x000000FF,
   578                              0xFF000000);
   579     if (!surface) {
   580         return NULL;
   581     }
   582     for (y = 0; y < h; ++y) {
   583         pixel = (Uint32 *) ((Uint8 *) surface->pixels + y * surface->pitch);
   584         for (x = 0; x < w; ++x) {
   585             if ((x % 8) == 0) {
   586                 datab = *data++;
   587                 maskb = *mask++;
   588             }
   589             if (maskb & 0x80) {
   590                 *pixel++ = (datab & 0x80) ? black : white;
   591             } else {
   592                 *pixel++ = (datab & 0x80) ? black : transparent;
   593             }
   594             datab <<= 1;
   595             maskb <<= 1;
   596         }
   597     }
   598 
   599     cursor = mouse->CreateCursor(surface, hot_x, hot_y);
   600     if (cursor) {
   601         cursor->mouse = mouse;
   602         cursor->next = mouse->cursors;
   603         mouse->cursors = cursor;
   604     }
   605 
   606     SDL_FreeSurface(surface);
   607 
   608     return cursor;
   609 }
   610 
   611 /* SDL_SetCursor(NULL) can be used to force the cursor redraw,
   612    if this is desired for any reason.  This is used when setting
   613    the video mode and when the SDL window gains the mouse focus.
   614  */
   615 void
   616 SDL_SetCursor(SDL_Cursor * cursor)
   617 {
   618     SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   619 
   620     if (!mouse) {
   621         SDL_SetError("No mice are initialized");
   622         return;
   623     }
   624 
   625     /* Set the new cursor */
   626     if (cursor) {
   627         /* Make sure the cursor is still valid for this mouse */
   628         SDL_Cursor *found;
   629         for (found = mouse->cursors; found; found = found->next) {
   630             if (found == cursor) {
   631                 break;
   632             }
   633         }
   634         if (!found) {
   635             SDL_SetError("Cursor not associated with the current mouse");
   636             return;
   637         }
   638         mouse->cur_cursor = cursor;
   639     } else {
   640         cursor = mouse->cur_cursor;
   641     }
   642 
   643     if (cursor && mouse->cursor_shown && !mouse->relative_mode) {
   644         if (mouse->ShowCursor) {
   645             mouse->ShowCursor(cursor);
   646         }
   647     } else {
   648         if (mouse->ShowCursor) {
   649             mouse->ShowCursor(NULL);
   650         }
   651     }
   652 }
   653 
   654 SDL_Cursor *
   655 SDL_GetCursor(void)
   656 {
   657     SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   658 
   659     if (!mouse) {
   660         return NULL;
   661     }
   662     return mouse->cur_cursor;
   663 }
   664 
   665 void
   666 SDL_FreeCursor(SDL_Cursor * cursor)
   667 {
   668     SDL_Mouse *mouse;
   669     SDL_Cursor *curr, *prev;
   670 
   671     if (!cursor) {
   672         return;
   673     }
   674     mouse = cursor->mouse;
   675 
   676     if (cursor == mouse->def_cursor) {
   677         return;
   678     }
   679     if (cursor == mouse->cur_cursor) {
   680         SDL_SetCursor(mouse->def_cursor);
   681     }
   682 
   683     for (prev = NULL, curr = mouse->cursors; curr;
   684          prev = curr, curr = curr->next) {
   685         if (curr == cursor) {
   686             if (prev) {
   687                 prev->next = curr->next;
   688             } else {
   689                 mouse->cursors = curr->next;
   690             }
   691 
   692             if (mouse->FreeCursor) {
   693                 mouse->FreeCursor(curr);
   694             }
   695             return;
   696         }
   697     }
   698 }
   699 
   700 int
   701 SDL_ShowCursor(int toggle)
   702 {
   703     SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   704     SDL_bool shown;
   705 
   706     if (!mouse) {
   707         return 0;
   708     }
   709 
   710     shown = mouse->cursor_shown;
   711     if (toggle >= 0) {
   712         if (toggle) {
   713             mouse->cursor_shown = SDL_TRUE;
   714         } else {
   715             mouse->cursor_shown = SDL_FALSE;
   716         }
   717         if (mouse->cursor_shown != shown) {
   718             SDL_SetCursor(NULL);
   719         }
   720     }
   721     return shown;
   722 }
   723 
   724 void SDL_SetIndexId(int id, int index)
   725 {
   726     if(id>SDL_highestId)
   727     {
   728         int *indexes;
   729         indexes =
   730             (int*) SDL_realloc(SDL_IdIndex,
   731                                        (id + 1) * sizeof(int));
   732         if (!indexes) {
   733             SDL_OutOfMemory();
   734             return -1;
   735         }
   736         SDL_IdIndex=indexes;
   737         SDL_IdIndex[id]=index;
   738         SDL_highestId=id;
   739     }
   740     else
   741     {
   742         SDL_IdIndex[id]=index;
   743     }
   744 }
   745 
   746 int SDL_GetIndexById(int id)
   747 {
   748     if(id>SDL_highestId)
   749     {
   750         return -1;
   751     }
   752     else
   753     {
   754         return SDL_IdIndex[id];
   755     }
   756 }
   757 
   758 int SDL_GetNumOfMice(void)
   759 {
   760     return SDL_num_mice;
   761 }
   762 
   763 char* SDL_GetMouseName(int index)
   764 {
   765     SDL_Mouse* mouse = SDL_GetMouse(index);
   766     if(!mouse)
   767     {
   768         return NULL;
   769     }
   770     return mouse->name;
   771 }
   772 
   773 void SDL_UpdateCoordinates(int x, int y)
   774 {
   775     x_max=x;
   776     y_max=y;
   777 }
   778 /* vi: set ts=4 sw=4 expandtab: */