Ejemplo n.º 1
0
static void handle_delayed_updates(char *local_name)
{
	char *fname, *partialptr;
	int ndx;

	for (ndx = -1; (ndx = bitbag_next_bit(delayed_bits, ndx)) >= 0; ) {
		struct file_struct *file = cur_flist->files[ndx];
		fname = local_name ? local_name : f_name(file, NULL);
		if ((partialptr = partial_dir_fname(fname)) != NULL) {
			if (make_backups > 0 && !make_backup(fname))
				continue;
			if (verbose > 2) {
				rprintf(FINFO, "renaming %s to %s\n",
					partialptr, fname);
			}
			/* We don't use robust_rename() here because the
			 * partial-dir must be on the same drive. */
			if (do_rename(partialptr, fname) < 0) {
				rsyserr(FERROR_XFER, errno,
					"rename failed for %s (from %s)",
					full_fname(fname), partialptr);
			} else {
				if (remove_source_files
				 || (preserve_hard_links && F_IS_HLINKED(file)))
					send_msg_int(MSG_SUCCESS, ndx);
				handle_partial_dir(partialptr, PDIR_DELETE);
			}
		}
	}
}
Ejemplo n.º 2
0
/* finish off a file transfer, renaming the file and setting the permissions
   and ownership */
void finish_transfer(char *fname, char *fnametmp, struct file_struct *file)
{
	if (make_backups && !make_backup(fname))
		return;

	/* move tmp file over real file */
	if (robust_rename(fnametmp,fname) != 0) {
		if (errno == EXDEV) {
			/* rename failed on cross-filesystem link.  
			   Copy the file instead. */
			if (copy_file(fnametmp,fname, file->mode & INITACCESSPERMS)) {
				rprintf(FERROR,"copy %s -> %s : %s\n",
					fnametmp,fname,strerror(errno));
			} else {
				set_perms(fname,file,NULL,0);
			}
		} else {
			rprintf(FERROR,"rename %s -> %s : %s\n",
				fnametmp,fname,strerror(errno));
		}
		do_unlink(fnametmp);
	} else {
		set_perms(fname,file,NULL,0);
	}
}
Ejemplo n.º 3
0
void BACKUP_call_very_often(void){
  static bool has_inited = false;
  if (has_inited==false){
    RT_BACKUP_reset_timer();
    has_inited=true;
  }

  static bool is_playing = false;
  
  Player_State player_state = ATOMIC_GET(pc->player_state);
  
  if (!is_playing && player_state==PLAYER_STATE_PLAYING){
    is_playing = true;
    g_curr_playing_start_time = TIME_get_ms();
  }

  if (is_playing && player_state==PLAYER_STATE_STOPPED){
    is_playing = false;
    double added_playing_duration = TIME_get_ms() - g_curr_playing_start_time;
    g_curr_playing_duration += added_playing_duration;
  }

  if (is_playing)
    return;
  
  //printf("duration: %f\n",get_unbackuped_duration() / 1000.0);
  
  if (get_unbackuped_duration()  > get_backup_interval_ms()){
    make_backup();
    RT_BACKUP_reset_timer();
  }
}
Ejemplo n.º 4
0
static void handle_delayed_updates(struct file_list *flist, char *local_name)
{
	char *fname, *partialptr, numbuf[4];
	int i;

	for (i = -1; (i = next_delayed_bit(i)) >= 0; ) {
		struct file_struct *file = flist->files[i];
		fname = local_name ? local_name : f_name(file);
		if ((partialptr = partial_dir_fname(fname)) != NULL) {
			if (make_backups && !make_backup(fname))
				continue;
			if (verbose > 2) {
				rprintf(FINFO, "renaming %s to %s\n",
					safe_fname(partialptr),
					safe_fname(fname));
			}
			if (do_rename(partialptr, fname) < 0) {
				rsyserr(FERROR, errno,
					"rename failed for %s (from %s)",
					full_fname(fname),
					safe_fname(partialptr));
			} else {
				if (remove_sent_files
				    || (preserve_hard_links
				     && file->link_u.links)) {
					SIVAL(numbuf, 0, i);
					send_msg(MSG_SUCCESS,numbuf,4);
				}
				handle_partial_dir(partialptr,
						   PDIR_DELETE);
			}
		}
	}
}
Ejemplo n.º 5
0
FILE *ffopen(const char *file,const char *mode)
{
#ifdef SKIP_FFOPS
    return fopen(file,mode);
#else
    FILE *ff=NULL;
    char buf[256],*bf,*bufsize=0,*ptr;
    gmx_bool bRead;
    int  bs;

    if (mode[0]=='w') {
        make_backup(file);
    }
    where();

    bRead= (mode[0]=='r'&&mode[1]!='+');
    strcpy(buf,file);
    if (gmx_fexist(buf) || !bRead) {
        if ((ff=fopen(buf,mode))==NULL)
            gmx_file(buf);
        where();
        /* Check whether we should be using buffering (default) or not
         * (for debugging)
         */
        if (bUnbuffered || ((bufsize=getenv("LOG_BUFS")) != NULL)) {
            /* Check whether to use completely unbuffered */
            if (bUnbuffered)
                bs = 0;
            else
                bs=strtol(bufsize, NULL, 10); 
            if (bs <= 0)
                setbuf(ff,NULL); 
            else {
                snew(ptr,bs+8);
                if (setvbuf(ff,ptr,_IOFBF,bs) != 0)
                    gmx_file("Buffering File");
            }
        }
        where();
    }
    else {
        sprintf(buf,"%s.Z",file);
        if (gmx_fexist(buf)) {
            ff=uncompress(buf,mode);
        }
        else {
            sprintf(buf,"%s.gz",file);
            if (gmx_fexist(buf)) {
                ff=gunzip(buf,mode);
            }
            else 
                gmx_file(file);
        }
    }
    return ff;
#endif
}
Ejemplo n.º 6
0
int colvarproxy_gromacs::backup_file (char const *filename)
{
  if (std::string(filename).rfind(std::string(".colvars.state"))
      != std::string::npos) {
    return my_backup_file(filename, ".old");
  } else {
    // GROMACS has its own way to avoid overwriting files.
    //if (make_backup(filename)) return COLVARS_OK;
    //else return FILE_ERROR;
    make_backup(filename);
  }
  return COLVARS_OK;
}
Ejemplo n.º 7
0
void BACKUP_call_very_often(void){
  if (MIXER_is_saving())
    return;

  if (g_radium_runs_custom_exec)
    return;
  
  static bool has_inited = false;
  if (has_inited==false){
    RT_BACKUP_reset_timer();
    has_inited=true;
  }

  if (!editor_has_keyboard_focus()) // If showing popup menu, editing text widgets, etc. we don't want to disturb the user.
    return;

  if (QApplication::mouseButtons() != Qt::NoButton) // Wait until user doesn't use the mouse.
    return;
  
  static bool is_playing = false;
  
  Player_State player_state = ATOMIC_GET(pc->player_state);
  
  if (!is_playing && player_state==PLAYER_STATE_PLAYING){
    is_playing = true;
    g_curr_playing_start_time = TIME_get_ms();
  }

  if (is_playing && player_state==PLAYER_STATE_STOPPED){
    is_playing = false;
    double added_playing_duration = TIME_get_ms() - g_curr_playing_start_time;
    g_curr_playing_duration += added_playing_duration;
  }

  if (!doSaveBackupWhilePlaying())
    if (is_playing)
      return;
  
  //printf("duration: %f\n",get_unbackuped_duration() / 1000.0);

  if (SampleRecorder_Get_Num_Instances() > 0)
    return;
  
  if (get_unbackuped_duration()  > get_backup_interval_ms()){
    make_backup();
    RT_BACKUP_reset_timer();
  }
}
Ejemplo n.º 8
0
static exit_values_ty indent_multiple_files(void)
{
    exit_values_ty exit_status = total_success;
    
    int i;
    /* When multiple input files are specified, make a backup copy
     * and then output the indented code into the same filename. */

    for (i = 0; input_files; i++, input_files--)
    {
        exit_values_ty status;
        struct stat file_stats;

        in_name = in_file_names[i];
        out_name = in_file_names[i];
        current_input = read_file(in_file_names[i], &file_stats);

        open_output(out_name, "r+");

        make_backup(current_input, &file_stats); /* Aborts on failure. */

        /* We have safely made a backup so the open file can be truncated. */
          
        reopen_output_trunc(out_name);
          
        reset_parser();
        status = indent (current_input);

        if (status > exit_status)
        {
            exit_status = status;
        }

        if (settings.preserve_mtime)
        {
            close_output(&file_stats, out_name);
        }
        else
        {
            close_output(NULL, out_name);
        }
    }
    
    return exit_status;
}
Ejemplo n.º 9
0
static void update_topol(const char *topinout, int p_num, int n_num,
                         const char *p_name, const char *n_name, char *grpname)
{
    FILE    *fpin, *fpout;
    char     buf[STRLEN], buf2[STRLEN], *temp, **mol_line = NULL;
    int      line, i, nmol_line, sol_line, nsol_last;
    gmx_bool bMolecules;
    char     temporary_filename[STRLEN];

    printf("\nProcessing topology\n");
    fpin  = gmx_ffopen(topinout, "r");
    std::strncpy(temporary_filename, "temp.topXXXXXX", STRLEN);
    fpout = gmx_fopen_temporary(temporary_filename);

    line       = 0;
    bMolecules = FALSE;
    nmol_line  = 0;
    sol_line   = -1;
    nsol_last  = -1;
    while (fgets(buf, STRLEN, fpin))
    {
        line++;
        std::strcpy(buf2, buf);
        if ((temp = std::strchr(buf2, '\n')) != NULL)
        {
            temp[0] = '\0';
        }
        ltrim(buf2);
        if (buf2[0] == '[')
        {
            buf2[0] = ' ';
            if ((temp = std::strchr(buf2, '\n')) != NULL)
            {
                temp[0] = '\0';
            }
            rtrim(buf2);
            if (buf2[std::strlen(buf2)-1] == ']')
            {
                buf2[std::strlen(buf2)-1] = '\0';
                ltrim(buf2);
                rtrim(buf2);
                bMolecules = (gmx_strcasecmp(buf2, "molecules") == 0);
            }
            fprintf(fpout, "%s", buf);
        }
        else if (!bMolecules)
        {
            fprintf(fpout, "%s", buf);
        }
        else
        {
            /* Check if this is a line with solvent molecules */
            sscanf(buf, "%s", buf2);
            if (gmx_strcasecmp(buf2, grpname) == 0)
            {
                sol_line = nmol_line;
                sscanf(buf, "%*s %d", &nsol_last);
            }
            /* Store this molecules section line */
            srenew(mol_line, nmol_line+1);
            mol_line[nmol_line] = gmx_strdup(buf);
            nmol_line++;
        }
    }
    gmx_ffclose(fpin);

    if (sol_line == -1)
    {
        gmx_ffclose(fpout);
        gmx_fatal(FARGS, "No line with moleculetype '%s' found the [ molecules ] section of file '%s'", grpname, topinout);
    }
    if (nsol_last < p_num+n_num)
    {
        gmx_ffclose(fpout);
        gmx_fatal(FARGS, "The last entry for moleculetype '%s' in the [ molecules ] section of file '%s' has less solvent molecules (%d) than were replaced (%d)", grpname, topinout, nsol_last, p_num+n_num);
    }

    /* Print all the molecule entries */
    for (i = 0; i < nmol_line; i++)
    {
        if (i != sol_line)
        {
            fprintf(fpout, "%s", mol_line[i]);
        }
        else
        {
            printf("Replacing %d solute molecules in topology file (%s) "
                   " by %d %s and %d %s ions.\n",
                   p_num+n_num, topinout, p_num, p_name, n_num, n_name);
            nsol_last -= p_num + n_num;
            if (nsol_last > 0)
            {
                fprintf(fpout, "%-10s  %d\n", grpname, nsol_last);
            }
            if (p_num > 0)
            {
                fprintf(fpout, "%-15s  %d\n", p_name, p_num);
            }
            if (n_num > 0)
            {
                fprintf(fpout, "%-15s  %d\n", n_name, n_num);
            }
        }
    }
    gmx_ffclose(fpout);
    make_backup(topinout);
    gmx_file_rename(temporary_filename, topinout);
}
Ejemplo n.º 10
0
/*****************************************************************
 *
 *                     EXPORTED SECTION
 *
 *****************************************************************/
t_fileio *gmx_fio_open(const char *fn, const char *mode)
{
    t_fileio *fio = NULL;
    int       i;
    char      newmode[5];
    gmx_bool  bRead, bReadWrite;
    int       xdrid;

    if (fn2ftp(fn) == efTPA)
    {
        strcpy(newmode, mode);
    }
    else
    {
        /* sanitize the mode string */
        if (strncmp(mode, "r+", 2) == 0)
        {
            strcpy(newmode, "r+");
        }
        else if (mode[0] == 'r')
        {
            strcpy(newmode, "r");
        }
        else if (strncmp(mode, "w+", 2) == 0)
        {
            strcpy(newmode, "w+");
        }
        else if (mode[0] == 'w')
        {
            strcpy(newmode, "w");
        }
        else if (strncmp(mode, "a+", 2) == 0)
        {
            strcpy(newmode, "a+");
        }
        else if (mode[0] == 'a')
        {
            strcpy(newmode, "a");
        }
        else
        {
            gmx_fatal(FARGS, "DEATH HORROR in gmx_fio_open, mode is '%s'", mode);
        }
    }

    /* Check if it should be opened as a binary file */
    if (strncmp(ftp2ftype(fn2ftp(fn)), "ASCII", 5))
    {
        /* Not ascii, add b to file mode */
        if ((strchr(newmode, 'b') == NULL) && (strchr(newmode, 'B') == NULL))
        {
            strcat(newmode, "b");
        }
    }

    snew(fio, 1);
#ifdef GMX_THREAD_MPI
    tMPI_Lock_init(&(fio->mtx));
#endif
    bRead      = (newmode[0] == 'r' && newmode[1] != '+');
    bReadWrite = (newmode[1] == '+');
    fio->fp    = NULL;
    fio->xdr   = NULL;
    if (fn)
    {
        fio->iFTP   = fn2ftp(fn);
        fio->fn     = strdup(fn);
        fio->bStdio = FALSE;

        /* If this file type is in the list of XDR files, open it like that */
        if (in_ftpset(fio->iFTP, asize(ftpXDR), ftpXDR))
        {
            /* First check whether we have to make a backup,
             * only for writing, not for read or append.
             */
            if (newmode[0] == 'w')
            {
#ifndef GMX_FAHCORE
                /* only make backups for normal gromacs */
                make_backup(fn);
#endif
            }
            else
            {
                /* Check whether file exists */
                if (!gmx_fexist(fn))
                {
                    gmx_open(fn);
                }
            }
            /* Open the file */
            fio->fp = ffopen(fn, newmode);

            /* determine the XDR direction */
            if (newmode[0] == 'w' || newmode[0] == 'a')
            {
                fio->xdrmode = XDR_ENCODE;
            }
            else
            {
                fio->xdrmode = XDR_DECODE;
            }

            snew(fio->xdr, 1);
            xdrstdio_create(fio->xdr, fio->fp, fio->xdrmode);
        }
        else
        {
            /* If it is not, open it as a regular file */
            fio->fp = ffopen(fn, newmode);
        }

        /* for appending seek to end of file to make sure ftell gives correct position
         * important for checkpointing */
        if (newmode[0] == 'a')
        {
            gmx_fseek(fio->fp, 0, SEEK_END);
        }
    }
    else
    {
        /* Use stdin/stdout for I/O */
        fio->iFTP   = efTPA;
        fio->fp     = bRead ? stdin : stdout;
        fio->fn     = strdup("STDIO");
        fio->bStdio = TRUE;
    }
    fio->bRead             = bRead;
    fio->bReadWrite        = bReadWrite;
    fio->bDouble           = (sizeof(real) == sizeof(double));
    fio->bDebug            = FALSE;
    fio->bOpen             = TRUE;
    fio->bLargerThan_off_t = FALSE;

    /* set the reader/writer functions */
    gmx_fio_set_iotype(fio);

    /* and now insert this file into the list of open files. */
    gmx_fio_insert(fio);
    return fio;
}
Ejemplo n.º 11
0
void gmx_tng_open(const char       *filename,
                  char              mode,
                  tng_trajectory_t *tng)
{
#ifdef GMX_USE_TNG
    /* First check whether we have to make a backup,
     * only for writing, not for read or append.
     */
    if (mode == 'w')
    {
#ifndef GMX_FAHCORE
        /* only make backups for normal gromacs */
        make_backup(filename);
#endif
    }

    /* tng must not be pointing at already allocated memory.
     * Memory will be allocated by tng_util_trajectory_open() and must
     * later on be freed by tng_util_trajectory_close(). */
    if (TNG_SUCCESS != tng_util_trajectory_open(filename, mode, tng))
    {
        /* TNG does return more than one degree of error, but there is
           no use case for GROMACS handling the non-fatal errors
           gracefully. */
        gmx_fatal(FARGS,
                  "%s while opening %s for %s",
                  gmx_strerror("file"),
                  filename,
                  modeToVerb(mode));
    }

    if (mode == 'w' || mode == 'a')
    {
        /* FIXME in TNG: When adding data to the header, subsequent blocks might get
         * overwritten. This could be solved by moving the first trajectory
         * frame set(s) to the end of the file. Could that cause other problems,
         * e.g. when continuing a simulation? */
        char hostname[256];
        gmx_gethostname(hostname, 256);
        if (mode == 'w')
        {
            tng_first_computer_name_set(*tng, hostname);
        }
/* TODO: This should be implemented when the above fixme is done (adding data to
 * the header). */
//         else
//         {
//             tng_last_computer_name_set(*tng, hostname);
//         }

        char        programInfo[256];
        const char *precisionString = "";
#ifdef GMX_DOUBLE
        precisionString = " (double precision)";
#endif
        sprintf(programInfo, "%.100s, %.128s%.24s",
                gmx::getProgramContext().displayName(),
                GromacsVersion(), precisionString);
        if (mode == 'w')
        {
            tng_first_program_name_set(*tng, programInfo);
        }
/* TODO: This should be implemented when the above fixme is done (adding data to
 * the header). */
//         else
//         {
//             tng_last_program_name_set(*tng, programInfo);
//         }

#ifdef HAVE_UNISTD_H
        char username[256];
        getlogin_r(username, 256);
        if (mode == 'w')
        {
            tng_first_user_name_set(*tng, username);
        }
/* TODO: This should be implemented when the above fixme is done (adding data to
 * the header). */
//         else
//         {
//             tng_last_user_name_set(*tng, username);
//         }
#endif
    }
#else
    gmx_file("GROMACS was compiled without TNG support, cannot handle this file type");
    GMX_UNUSED_VALUE(filename);
    GMX_UNUSED_VALUE(mode);
    GMX_UNUSED_VALUE(tng);
#endif
}
Ejemplo n.º 12
0
/* Delete a file or directory.  If DEL_RECURSE is set in the flags, this will
 * delete recursively.
 *
 * Note that fbuf must point to a MAXPATHLEN buffer if the mode indicates it's
 * a directory! (The buffer is used for recursion, but returned unchanged.)
 */
enum delret delete_item(char *fbuf, uint16 mode, uint16 flags)
{
	enum delret ret;
	char *what;
	int ok;

	if (DEBUG_GTE(DEL, 2)) {
		rprintf(FINFO, "delete_item(%s) mode=%o flags=%d\n",
			fbuf, (int)mode, (int)flags);
	}

	if (flags & DEL_NO_UID_WRITE)
		do_chmod(fbuf, mode | S_IWUSR);

	if (S_ISDIR(mode) && !(flags & DEL_DIR_IS_EMPTY)) {
		/* This only happens on the first call to delete_item() since
		 * delete_dir_contents() always calls us w/DEL_DIR_IS_EMPTY. */
		ignore_perishable = 1;
		/* If DEL_RECURSE is not set, this just reports emptiness. */
		ret = delete_dir_contents(fbuf, flags);
		ignore_perishable = 0;
		if (ret == DR_NOT_EMPTY || ret == DR_AT_LIMIT)
			goto check_ret;
		/* OK: try to delete the directory. */
	}

	if (!(flags & DEL_MAKE_ROOM) && max_delete >= 0 && stats.deleted_files >= max_delete) {
		skipped_deletes++;
		return DR_AT_LIMIT;
	}

	if (S_ISDIR(mode)) {
		what = "rmdir";
		ok = do_rmdir(fbuf) == 0;
	} else {
		if (make_backups > 0 && !(flags & DEL_FOR_BACKUP) && (backup_dir || !is_backup_file(fbuf))) {
			what = "make_backup";
			ok = make_backup(fbuf, True);
			if (ok == 2) {
				what = "unlink";
				ok = robust_unlink(fbuf) == 0;
			}
		} else {
			what = "unlink";
			ok = robust_unlink(fbuf) == 0;
		}
	}

	if (ok) {
		if (!(flags & DEL_MAKE_ROOM)) {
			log_delete(fbuf, mode);
			stats.deleted_files++;
			if (S_ISREG(mode)) {
				/* Nothing more to count */
			} else if (S_ISDIR(mode))
				stats.deleted_dirs++;
#ifdef SUPPORT_LINKS
			else if (S_ISLNK(mode))
				stats.deleted_symlinks++;
#endif
			else if (IS_DEVICE(mode))
				stats.deleted_symlinks++;
			else
				stats.deleted_specials++;
		}
		ret = DR_SUCCESS;
	} else {
		if (S_ISDIR(mode) && errno == ENOTEMPTY) {
			rprintf(FINFO, "cannot delete non-empty directory: %s\n",
				fbuf);
			ret = DR_NOT_EMPTY;
		} else if (errno != ENOENT) {
			rsyserr(FERROR, errno, "delete_file: %s(%s) failed",
				what, fbuf);
			ret = DR_FAILURE;
		} else
			ret = DR_SUCCESS;
	}

  check_ret:
	if (ret != DR_SUCCESS && flags & DEL_MAKE_ROOM) {
		const char *desc;
		switch (flags & DEL_MAKE_ROOM) {
		case DEL_FOR_FILE: desc = "regular file"; break;
		case DEL_FOR_DIR: desc = "directory"; break;
		case DEL_FOR_SYMLINK: desc = "symlink"; break;
		case DEL_FOR_DEVICE: desc = "device file"; break;
		case DEL_FOR_SPECIAL: desc = "special file"; break;
		default: exit_cleanup(RERR_UNSUPPORTED); /* IMPOSSIBLE */
		}
		rprintf(FERROR_XFER, "could not make way for %s %s: %s\n",
			flags & DEL_FOR_BACKUP ? "backup" : "new",
			desc, fbuf);
	}
	return ret;
}
Ejemplo n.º 13
0
static exit_values_ty indent_single_file(BOOLEAN using_stdin)
{
    int            is_stdin    = false;
    exit_values_ty exit_status = total_success;
    struct stat    file_stats;

    if ((input_files == 0) || using_stdin)
    {
        input_files = 1;
        in_file_names[0] = "Standard input";
        in_name = in_file_names[0];
        current_input = read_stdin ();
        is_stdin = true;
    }
    else
    {
        /* 1 input file */

        in_name = in_file_names[0];
        current_input = read_file(in_file_names[0], &file_stats);

        if (!out_name && !settings.use_stdout)
        {
            out_name = in_file_names[0];
            make_backup(current_input, &file_stats);
        }
    }

    /* Use stdout if it was specified ("-st"), or neither input
     * nor output file was specified. */

    if (settings.use_stdout || !out_name)
    {
        open_output(NULL, NULL);
    }
    else
    {
        open_output(out_name, "w");
    }

    reset_parser ();

    exit_status = indent (current_input);

    if (input_files > 0 && !using_stdin && settings.preserve_mtime)
    {
        close_output(&file_stats, out_name);
    }
    else
    {
        close_output(NULL, out_name);
    }

    if (current_input) {
        if (!is_stdin && current_input->name)
            xfree(current_input->name);
        xfree(current_input->data);
    }

    return exit_status;
}
Ejemplo n.º 14
0
// motion_notify_event: When the mouse pointer is moved over the map area
// ------------------------------------------------------------------- >>
static gboolean motion_notify_event(GtkWidget *widget, GdkEventMotion *event)
{
	int x, y;
	bool redraw_map = false;
	bool update_map = false;
	GdkModifierType state;
	
	if (event->is_hint)
	{
		gdk_window_get_pointer(event->window, &x, &y, &state);
	}
	else
	{
		x = event->x;
		y = event->y;
		state = (GdkModifierType)(event->state);
	}

	mouse.set(x, y);

	// Selection box
	if (sel_box.x1() != -1)
	{
		sel_box.br.set(x, y);

		if (line_draw)
			line_drawbox();

		redraw_map = true;
	}
	else
	{
		if (binds.pressed("edit_selectbox"))
		{
			sel_box.tl.set(down_pos);
			sel_box.br.set(down_pos);
			//binds.clear("edit_selectbox");
		}
	}

	// Moving items
	if (items_moving)
	{
		move_items();
		redraw_map = update_map = true;
	}
	else
	{
		if (binds.pressed("edit_moveitems") && (selection() || hilight_item != -1))
		{
			items_moving = true;
			add_move_items();
			//binds.clear("edit_moveitems");
			redraw_map = update_map = true;
		}
	}

	// Quick thing angle
	if (thing_quickangle)
	{
		thing_setquickangle();
		redraw_map = update_map = true;
	}
	else
	{
		if (binds.pressed("thing_quickangle"))
		{
			make_backup(false, false, false, false, true);
			thing_quickangle = true;
			thing_setquickangle();
			redraw_map = update_map = true;
			//binds.clear("thing_quickangle");
		}
	}

	/*
	if (state & GDK_BUTTON3_MASK)
	{
		if (items_moving)
		{
			move_items();
			redraw_map = true;
			update_map = true;
		}
		else
		{
			add_move_items();
			items_moving = true;
			redraw_map = update_map = true;
		}
	}

	if (state & GDK_BUTTON2_MASK)
	{
		// Quick thing angle
		thing_quickangle = true;
		thing_setquickangle();
		redraw_map = true;
		update_map = true;
	}

	if (sel_box.x1() != -1)
	{
		sel_box.br.set(x, y);

		if (line_draw)
			line_drawbox();

		redraw_map = true;
	}
	else
	{
		if (line_draw || paste_mode)
			redraw_map = true;

		if (!thing_quickangle && !paste_mode)
		{
			int old_hilight = hilight_item;
			get_hilight_item(x, y);

			if (hilight_item != old_hilight)
				redraw_map = true;
		}
	}
	*/

	if (line_draw || paste_mode)
		redraw_map = true;

	if (!thing_quickangle && !paste_mode && !line_draw && sel_box.x1() == -1)
	{
		int old_hilight = hilight_item;
		get_hilight_item(x, y);

		if (hilight_item != old_hilight)
			redraw_map = true;
	}

	//if (redraw_map)
		force_map_redraw(update_map);

	update_status_bar();

	return TRUE;
}