Ejemplo n.º 1
0
int Flu_Wrap_Group :: Scrollbar :: handle( int event )
{
  if( event == FL_MOUSEWHEEL )
    {
      handle_drag( clamp( value() + linesize() * Fl::e_dy ) );
      return 1;
    }
  else
    return Fl_Scrollbar::handle( event );
}
Ejemplo n.º 2
0
void Fl_Value_Input_Spin::increment_cb() {
  if (!mouseobj) return;
  delta+=deltadir;
  double v;
  switch (drag) {
    case 3: v = increment(value(), deltadir*100); break;
    case 2: v = increment(value(), deltadir*10); break;
    default:v = increment(value(), deltadir); break;
  }
  v = round(v);
  handle_drag(soft()?softclamp(v):clamp(v));
}
Ejemplo n.º 3
0
void Fl_Scrollbar::increment_cb()
{
    double i;
    switch (which_pushed)
    {
        case UP_ARROW: i = -linesize(); break;
        default:i =  linesize(); break;
        case ABOVE_SLIDER: i = -pagesize(); break;
        case BELOW_SLIDER: i =  pagesize(); break;
    }
    handle_drag(value()+i);
}
Ejemplo n.º 4
0
void Flu_Spinner :: _setvalue( double v )
{
  if( _wrapRange )
    {
      while( v > maximum() )
	v = minimum() + (v - maximum());
      while( v < minimum() )
	v = maximum() - (minimum() - v);
    }
  else
    {
      v = clamp(v);
    }
  handle_drag(v);
}
Ejemplo n.º 5
0
int Fl_Dial::handle(int event)
{
    int X = 0; int Y = 0; int W = w(); int H = h();
    box()->inset(X,Y,W,H);
    switch (event)
    {
        case FL_PUSH:
            handle_push();
        case FL_DRAG:
        {
            int mx = Fl::event_x()-X-W/2;
            int my = Fl::event_y()-Y-H/2;
            if (!mx && !my) return 1;
            double angle = 270-atan2((float)-my, (float)mx)*180/M_PI;
            double oldangle = (a2-a1)*(value()-minimum())/(maximum()-minimum()) + a1;
            while (angle < oldangle-180) angle += 360;
            while (angle > oldangle+180) angle -= 360;
            double val;
            if ((a1<a2) ? (angle <= a1) : (angle >= a1))
            {
                val = minimum();
            }
            else if ((a1<a2) ? (angle >= a2) : (angle <= a2))
            {
                val = maximum();
            }
            else
            {
                val = minimum() + (maximum()-minimum())*(angle-a1)/(a2-a1);
            }
            handle_drag(val);
        } return 1;
        case FL_RELEASE:
            if (!Fl::pushed()) handle_release();
            return 1;
        default:
            return Fl_Valuator::handle(event);
    }
}
Ejemplo n.º 6
0
int Fl_Roller::handle(int event)
{
    static int ipos;
    int newpos = type()==HORIZONTAL ? Fl::event_x() : -Fl::event_y();
    switch (event)
    {
        case FL_PUSH:
            handle_push();
            ipos = newpos;
            return 1;
        case FL_DRAG:
            handle_drag(previous_value()+(newpos-ipos)*(step()?step():.01));
            return 1;
        case FL_RELEASE:
            handle_release();
            return 1;
        case FL_KEY:
            // Only arrows in the correct direction are used.  This allows the
            // opposite arrows to be used to navigate between a set of parellel
            // rollers.
            switch (Fl::event_key())
            {
                case FL_Up:
                case FL_Down:
                case FL_Home:
                case FL_End:
                    if (type()==HORIZONTAL) return 0;
                    break;
                case FL_Left:
                case FL_Right:
                    if (type() != HORIZONTAL) return 0;
            }                    // else fall through...
        default:
            return Fl_Valuator::handle(event);
    }
}
Ejemplo n.º 7
0
int Fl_Slider::handle(int event, int x, int y, int w, int h)
{

    switch (event)
    {
        case FL_FOCUS:
        case FL_UNFOCUS:
            redraw(FL_DAMAGE_ALL);
            return 1;
        case FL_PUSH:
            redraw(FL_DAMAGE_HIGHLIGHT);
            handle_push();
        case FL_DRAG:
            {
            // figure out the space the slider moves in and where the event is:
                int mx;
                if (horizontal())
                {
                    w = w-box()->dw();
                    mx = Fl::event_x()-x-box()->dx();
                }
                else
                {
                    w = h-box()->dh();
                    mx = Fl::event_y()-y-box()->dy();
                }
                if (w <= slider_size_) return 1;
                static int offcenter;
                int X = slider_position(value(), w);
                if (event == FL_PUSH)
                {
                    offcenter = mx-X;
                // we are done if they clicked on the slider:
                    if (offcenter >= (slider_size() ? 0 : -8) && offcenter <= slider_size_)
                        return 1;
                    if (Fl::event_button() > 1)
                    {
                    // Move the near end of the slider to the cursor. This is good
                    // for scrollbars.
                        offcenter = (offcenter < 0) ? 0 : slider_size_;
                    }
                    else
                    {
                    // Center the slider under the cursor, what most toolkits do
                        offcenter = slider_size_/2;
                    }
                }
                double v;
            RETRY:
                X = mx-offcenter;
                if (X < 0)
                {
                    X = 0;
                    offcenter = mx; if (offcenter < 0) offcenter = 0;
                }
                else if (X > (w-slider_size_))
                {
                    X = w-slider_size_;
                    offcenter = mx-X; if (offcenter > slider_size_) offcenter = slider_size_;
                }
                v = position_value(X, w);
                handle_drag(v);
            // make sure a click outside the sliderbar moves it:
                if (event == FL_PUSH && value() == previous_value())
                {
                    offcenter = slider_size_/2;
                    event = FL_DRAG;
                    goto RETRY;
                }
                return 1;
            }
        case FL_RELEASE:
            handle_release();
            redraw(FL_DAMAGE_HIGHLIGHT);
            return 1;
        case FL_KEY:
            // Only arrows in the correct direction are used.  This allows the
            // opposite arrows to be used to navigate between a set of parellel
            // sliders.
            switch (Fl::event_key())
            {
                case FL_Up:
                case FL_Down:
                    if (horizontal()) return 0;
                    break;
                case FL_Left:
                case FL_Right:
                    if (!horizontal()) return 0;
            }
        default:
            return Fl_Valuator::handle(event);
    }
}
Ejemplo n.º 8
0
int Fl_Scrollbar::handle(int event)
{
    // area of scrollbar:
    int X=0; int Y=0; int W=w(); int H=h(); box()->inset(X,Y,W,H);

    // adjust slider area to be inside the arrow buttons:
    if (vertical())
    {
        if (H >= 3*W) {Y += W; H -= 2*W;}
    }
    else
    {
        if (W >= 3*H) {X += H; W -= 2*H;}
    }

    // which widget part is highlighted?
    int mx = Fl::event_x();
    int my = Fl::event_y();
    int which_part;
    if (!Fl::event_inside(0, 0, w(), h())) which_part = NOTHING;
    else if (vertical())
    {
        if (my < Y) which_part = UP_ARROW;
        else if (my >= Y+H) which_part = DOWN_ARROW;
        else
        {
            int slidery = slider_position(value(), H);
            if (my < Y+slidery) which_part = ABOVE_SLIDER;
            else if (my >= Y+slidery+slider_size()) which_part = BELOW_SLIDER;
            else which_part = SLIDER;
        }
    }                            // horizontal
    else
    {
        if (mx < X) which_part = UP_ARROW;
        else if (mx >= X+W) which_part = DOWN_ARROW;
        else
        {
            int sliderx = slider_position(value(), W);
            if (mx < X+sliderx) which_part = ABOVE_SLIDER;
            else if (mx >= X+sliderx+slider_size()) which_part = BELOW_SLIDER;
            else which_part = SLIDER;
        }
    }
    switch (event)
    {
        case FL_FOCUS:
            return 0;
        case FL_ENTER:
        case FL_MOVE:
            if (!highlight_color()) return 1;
            if (which_part != which_highlight)
            {
                which_highlight = which_part;
                redraw(FL_DAMAGE_HIGHLIGHT);
            }
            return 1;
        case FL_LEAVE:
            if (which_highlight)
            {
                which_highlight = 0;
                redraw(FL_DAMAGE_HIGHLIGHT);
            }
            return 1;
        case FL_PUSH:
            // Clicking on the slider or middle or right click on the trough
            // gives us normal slider behavior:
            if (which_part == SLIDER ||
                Fl::event_button() > 1 && which_part > DOWN_ARROW)
            {
                which_pushed = SLIDER;
                return Fl_Slider::handle(event, X,Y,W,H);
            }
            handle_push();
            goto J1;
        case FL_DRAG:
            if (which_pushed==SLIDER) return Fl_Slider::handle(event, X,Y,W,H);
            if (which_part == SLIDER) which_part = NOTHING;
            // it is okay to switch between arrows and nothing, but no other
            // changes are allowed:
            if (!which_pushed && which_part <= DOWN_ARROW) ;
            else if (!which_part && which_pushed <= DOWN_ARROW) ;
            else which_part = which_pushed;
            J1:
            if (which_part != which_pushed)
            {
                Fl::remove_timeout(timeout_cb, this);
                which_highlight = which_pushed = which_part;
                redraw(FL_DAMAGE_HIGHLIGHT);
                if (which_part)
                {
                    Fl::add_timeout(INITIALREPEAT, timeout_cb, this);
                    increment_cb();
                }
            }
            return 1;
        case FL_RELEASE:
            if (which_pushed == SLIDER)
            {
                Fl_Slider::handle(event, X,Y,W,H);
            }
            else if (which_pushed)
            {
                Fl::remove_timeout(timeout_cb, this);
                handle_release();
                redraw(FL_DAMAGE_HIGHLIGHT);
            }
            which_pushed = NOTHING;
            return 1;
        case FL_MOUSEWHEEL:
            {
                float n = (vertical() ? Fl::event_dy() : Fl::event_dx())
                    * Fl_Style::wheel_scroll_lines * linesize();
                if (fabsf(n) > pagesize()) n = (n<0)?-pagesize():pagesize();
                handle_drag(value()+n);
                return 1;
            }
        case FL_KEY:
            if (vertical()) switch(Fl::event_key())
            {
                case FL_Home: handle_drag(maximum()); return 1;
                case FL_End:  handle_drag(minimum()); return 1;
                case FL_Page_Up: handle_drag(value()-pagesize()); return 1;
                case FL_Page_Down: handle_drag(value()+pagesize()); return 1;
            }                    // else fall through...
        default:
            return Fl_Slider::handle(event);
    }
}
Ejemplo n.º 9
0
int Fl_Value_Input_Spin::handle(int event) {
  double v;
  int olddelta;
  int mx = Fl::event_x();
  int my = Fl::event_y();
  int sxx = x(), syy = y(), sww = w(), shh = h();
  sxx += sww - buttonssize(); sww = buttonssize();
 
  if(!indrag && ( !sldrag || !((mx>=sxx && mx<=(sxx+sww)) &&
       (my>=syy && my<=(syy+shh))))  ) {  
          indrag=0;     
	  switch(event) {
            case FL_PUSH:
            case FL_DRAG:
	      sldrag=1;
	      break;
            case FL_FOCUS:
	       input.take_focus();
	       break;
           case FL_UNFOCUS:
	       redraw();
	       break;
	    default:
	      sldrag=0;
	  }
          input.type(step()>=1.0 ? FL_INT_INPUT : FL_FLOAT_INPUT);
          return input.handle(event);
  }

  switch (event) {
  case FL_PUSH:
//    if (!step()) goto DEFAULT;
    iy = my;
    ix = mx;
    drag = Fl::event_button();
    handle_push();
    indrag=1;
    mouseobj=1;
    Fl::add_timeout(.5, repeat_callback, this);  
    delta=0;
    if(Fl::event_inside(sxx,syy,sww,shh/2)) {
     deltadir=1;
    } else if (Fl::event_inside(sxx,syy+shh/2,sww,shh/2)) {
     deltadir=-1;
    } else {
     deltadir=0;
    }
    increment_cb();
    redraw();
    return 1;
  case FL_DRAG:
    if(mouseobj) {
      mouseobj=0;
      Fl::remove_timeout(repeat_callback, this);      
    }
//    if (!step()) goto DEFAULT;
    olddelta=delta;
    delta = - (Fl::event_y()-iy);
    if ((delta>5) || (delta<-5)  ) {  deltadir=((olddelta-delta)>0)?-1:(((olddelta-delta)<0)?1:0); } 
    else  { deltadir=0; delta = olddelta;}
    switch (drag) {
    case 3: v = increment(value(), deltadir*100); break;
    case 2: v = increment(value(), deltadir*10); break;
    default:v = increment(value(), deltadir); break;
    }
    v = round(v);
    handle_drag(soft()?softclamp(v):clamp(v));
    indrag=1;
    return 1;
  case FL_RELEASE:
    if(mouseobj) {
      Fl::remove_timeout(repeat_callback, this);      
    }
//    if (!step()) goto DEFAULT;
    indrag=0;
    delta=0;
    deltadir=0;
    mouseobj=0;
    handle_release();
    redraw();
    return 1;
  case FL_FOCUS:
    indrag=0;
    return input.take_focus();
  default:
    indrag=0;
    input.type(step()>=1.0 ? FL_INT_INPUT : FL_FLOAT_INPUT);
    return 1;
  }
}
Ejemplo n.º 10
0
int main(int argc, char* argv[]) {
    int sockfd, oldsockfd, portno, n;
    socklen_t clilen;
    struct sockaddr_in serv_addr, cli_addr;
    struct hostent *server;
    pthread_t recv_thread;
    Colormap map;

    Display* display;
    int screen_num;
    Window win;
    unsigned int display_width, display_height;
    unsigned int width, height;
    char *display_name = getenv("DISPLAY");
    GC gc, his_gc, refresh_gc;

    if(argc == 2) { // We are server
        sending = 1;
        if(argc < 2) {
            fprintf(stderr,"ERROR, no port provided\n");
            exit(1);
        }
        oldsockfd = socket(AF_INET, SOCK_STREAM, 0);
        if(oldsockfd < 0) error("ERROR opening socket");
        bzero((char *) &serv_addr, sizeof(serv_addr));
        portno = atoi(argv[1]);
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_addr.s_addr = INADDR_ANY;
        serv_addr.sin_port = htons(portno);
        int on = 1;
        if(setsockopt(oldsockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)) < 0) error("ERROR on sockopt");
        if(bind(oldsockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) error("ERROR on binding");
        listen(oldsockfd,5);
        clilen = sizeof(cli_addr);
        sockfd = accept(oldsockfd, (struct sockaddr *) &cli_addr, &clilen);
        if (sockfd < 0) error("ERROR on accept");
    }
    else if(argc == 3) { // We are client
        sending = 1;
        portno = atoi(argv[2]);
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd < 0) error("ERROR opening socket");
        server = gethostbyname(argv[1]);
        if(server == NULL) {
            fprintf(stderr,"ERROR, no such host\n");
            exit(0);
        }
        bzero((char *) &serv_addr, sizeof(serv_addr));
        serv_addr.sin_family = AF_INET;
        bcopy((char *)(server->h_addr), (char *)(&serv_addr.sin_addr.s_addr), server->h_length);
        serv_addr.sin_port = htons(portno);
        if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) error("ERROR connecting");
    }
    else {
        server = 0;
    }

    display = XOpenDisplay(display_name);
    if (display == NULL) {
        fprintf(stderr, "%s: cannot connect to X server '%s'\n", argv[0], display_name);
        exit(1);
    }

    screen_num = DefaultScreen(display);
    display_width = DisplayWidth(display, screen_num);
    display_height = DisplayHeight(display, screen_num);
    width = (display_width / 3);
    height = (display_height / 3);
    Atom wm_delete;
    win = create_simple_window(display, &wm_delete, width, height, 0, 0);


    XGCValues values;
    values.graphics_exposures = 0;
    gc = create_gc(display, win);
    his_gc = create_gc(display, win);
    refresh_gc = XCreateGC(display, win, GCGraphicsExposures, &values);

    XSetForeground(display, refresh_gc, WhitePixel(display, screen_num));
    XSetBackground(display, refresh_gc, WhitePixel(display, screen_num));

    map = DefaultColormap(display, 0);
    XParseColor(display, map, "#FFFFFF", &cols[0]);
    XAllocColor(display, map, &cols[0]);
    XParseColor(display, map, "#000000", &cols[1]);
    XAllocColor(display, map, &cols[1]);
    XParseColor(display, map, "#FF0000", &cols[2]);
    XAllocColor(display, map, &cols[2]);
    XParseColor(display, map, "#00FF00", &cols[3]);
    XAllocColor(display, map, &cols[3]);
    XParseColor(display, map, "#0000FF", &cols[4]);
    XAllocColor(display, map, &cols[4]);
    XParseColor(display, map, "#FFFF00", &cols[5]);
    XAllocColor(display, map, &cols[5]);
    XParseColor(display, map, "#FF00FF", &cols[6]);
    XAllocColor(display, map, &cols[6]);
    XParseColor(display, map, "#00FFFF", &cols[7]);
    XAllocColor(display, map, &cols[7]);
    XParseColor(display, map, "#999999", &cols[8]);
    XAllocColor(display, map, &cols[8]);
    XParseColor(display, map, "#666666", &cols[9]);
    XAllocColor(display, map, &cols[9]);

    set_title(display, win);

    back_buffer = XCreatePixmap(display, win, MAX_WIDTH, MAX_HEIGHT, DefaultDepth(display, screen_num));
    XFillRectangle(display, back_buffer, refresh_gc, 0, 0, MAX_WIDTH, MAX_HEIGHT);

    if(sending) {
        recv_info_t info;
        info.display = display;
        info.window = win;
        info.gc = gc;
        info.his_gc = his_gc;
        info.refresh_gc = refresh_gc;
        info.sockfd = sockfd;
        pthread_create(&recv_thread, NULL, recv_line, &info);
    }

    XSelectInput(display, win, ExposureMask | KeyPressMask | ButtonPressMask | Button1MotionMask | StructureNotifyMask);
    XEvent an_event;
    while(1) {
        XNextEvent(display, &an_event);
        switch(an_event.type) {
        case ClientMessage:
            if(an_event.xclient.data.l[0] == wm_delete) quitme(display, gc, his_gc, refresh_gc, sockfd, 0);
            break;
        case Expose:
            handle_expose(display, refresh_gc, (XExposeEvent*)&an_event.xexpose);
            break;
        case ConfigureNotify:
            width = an_event.xconfigure.width;
            height = an_event.xconfigure.height;
            break;
        case ButtonPress:
            handle_button_down(display, gc, (XButtonEvent*)&an_event.xbutton, width, height);
            break;
        case MotionNotify:
            handle_drag(display, gc, (XButtonEvent*)&an_event.xbutton, width, height, sockfd);
            break;
        case KeyPress:
            handle_key(display, win, gc, his_gc, refresh_gc, map, (XKeyEvent*)&an_event.xkey, sockfd);
            break;
        default:
            break;
        }
    }
    quitme(display, gc, his_gc, refresh_gc, sockfd, 0);
}
Ejemplo n.º 11
0
void
main(int argc, char* argv[])
{
  Display* display;		/* pointer to X Display structure.           */
  int screen_num;		/* number of screen to place the window on.  */
  Window win;			/* pointer to the newly created window.      */
  unsigned int display_width,
               display_height;	/* height and width of the X display.        */
  unsigned int width, height;	/* height and width for the new window.      */
  char *display_name = getenv("DISPLAY");  /* address of the X display.      */
  GC gc, rev_gc;		/* GC (graphics context) used for drawing    */
				/*  in our window.			     */
  short pixels[1000][1000];	/* used to store pixels on screen that were  */
				/* explicitly drawn or erased by the user.   */

  /* initialize the 'pixels' array to contain 0 values. */
  {
    int x, y;
    for (x=0; x<1000; x++)
      for (y=0; y<1000; y++)
        pixels[x][y] = 0;
  }

  /* open connection with the X server. */
  display = XOpenDisplay(display_name);
  if (display == NULL) {
    fprintf(stderr, "%s: cannot connect to X server '%s'\n",
            argv[0], display_name);
    exit(1);
  }

  /* get the geometry of the default screen for our display. */
  screen_num = DefaultScreen(display);
  display_width = DisplayWidth(display, screen_num);
  display_height = DisplayHeight(display, screen_num);

  /* make the new window occupy 1/9 of the screen's size. */
  width = (display_width / 3);
  height = (display_height / 3);
  printf("window width - '%d'; height - '%d'\n", width, height);

  /* create a simple window, as a direct child of the screen's   */
  /* root window. Use the screen's white color as the background */
  /* color of the window. Place the new window's top-left corner */
  /* at the given 'x,y' coordinates.                             */
  win = create_simple_window(display, width, height, 0, 0);

  /* allocate two new GCs (graphics contexts) for drawing in the window. */
  /* the first is used for drawing black over white, the second is used  */
  /* for drawing white over black.                                       */
  gc = create_gc(display, win, 0);
  rev_gc = create_gc(display, win, 1);

  /* subscribe to the given set of event types. */
  XSelectInput(display, win, ExposureMask | KeyPressMask |
                     ButtonPressMask | Button1MotionMask |
		     Button2MotionMask | Button3MotionMask | StructureNotifyMask);

  /* perform an events loop */
  {
    int done = 0;
    XEvent an_event;
    while (!done) {
      XNextEvent(display, &an_event);
      switch (an_event.type) {
        case Expose:
          /* redraw our window. */
	  handle_expose(display, gc, rev_gc, (XExposeEvent*)&an_event.xexpose,
             		width, height, pixels);
          break;
  
        case ConfigureNotify:
          /* update the size of our window, for expose events. */
          width = an_event.xconfigure.width;
          height = an_event.xconfigure.height;
          break;
  
        case ButtonPress:
          /* invert the pixel under the mouse pointer. */
          handle_button_down(display, gc, rev_gc,
                             (XButtonEvent*)&an_event.xbutton,
                             width, height, pixels);
          break;
  
        case MotionNotify:
          /* invert the pixel under the mouse pointer. */
          handle_drag(display, gc, rev_gc,
                      (XButtonEvent*)&an_event.xbutton,
                      width, height, pixels);
	  break;
  
        case KeyPress:
          /* exit the application by braking out of the events loop. */
          done = 1;
          break;
  
        default: /* ignore any other event types. */
          break;
      } /* end switch on event type */
    } /* end while events handling */
  }

  /* free the GCs. */
  XFreeGC(display, gc);
  XFreeGC(display, rev_gc);

  /* close the connection to the X server. */
  XCloseDisplay(display);
}
Ejemplo n.º 12
0
int Fl_Spin::handle(int event) {
  double v;
  int olddelta;
  int mx = Fl::event_x();
  int my = Fl::event_y();
  int sxx = x(), syy = y(), sww = w(), shh = h();
 
  switch (event) {
  case FL_PUSH:
//    if (!step()) goto DEFAULT;
    iy = my;
    ix = mx;
    drag = Fl::event_button();
    handle_push();
    indrag=1;
    mouseobj=1;
    Fl::add_timeout(.5, repeat_callback, this);  
    delta=0;
    if(Fl::event_inside(sxx,syy,sww,shh/2)) {
     deltadir=1;
    } else if (Fl::event_inside(sxx,syy+shh/2,sww,shh/2)) {
     deltadir=-1;
    } else {
     deltadir=0;
    }
    increment_cb();
    redraw();
    return 1;
  case FL_DRAG:
    if(mouseobj) {
      mouseobj=0;
      Fl::remove_timeout(repeat_callback, this);      
    }
//    if (!step()) goto DEFAULT;
    olddelta=delta;
    delta = - (Fl::event_y()-iy);
    if ((delta>5) || (delta<-5)  ) {  deltadir=((olddelta-delta)>0)?-1:(((olddelta-delta)<0)?1:0); } 
    else  { deltadir=0; delta = olddelta;}
    switch (drag) {
    case 3: v = increment(value(), deltadir*100); break;
    case 2: v = increment(value(), deltadir*10); break;
    default:v = increment(value(), deltadir); break;
    }
    v = round(v);
    handle_drag(soft()?softclamp(v):clamp(v));
    indrag=1;
    return 1;
  case FL_RELEASE:
    if(mouseobj) {
      Fl::remove_timeout(repeat_callback, this);      
    }
//    if (!step()) goto DEFAULT;
    indrag=0;
    delta=0;
    deltadir=0;
    mouseobj=0;
    handle_release();
    redraw();
    return 1;
  default:
    indrag=0;
    return Fl_Valuator::handle(event);
  }
}