Made weight-painting more bearable :)
[blender.git] / source / blender / src / toets.c
index efd7da94e5be39c278711e2970a181b216402e56..d1b0844647e4c8a65e53736c3ac1df4ecfcac59c 100644 (file)
 #include <string.h>
 #include <math.h>
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 #ifdef WIN32
 #include "BLI_winstuff.h"
 #endif
 
 #include "BLI_blenlib.h"
 #include "BLI_arithb.h"
-#include "BLI_editVert.h"
 
 #include "DNA_object_types.h"
 #include "DNA_screen_types.h"
 #include "DNA_space_types.h"
 #include "DNA_view3d_types.h"
+#include "DNA_userdef_types.h"
 
-#include "BKE_utildefines.h"
-#include "BKE_global.h"
+#include "BKE_action.h"
 #include "BKE_anim.h"
-#include "BKE_scene.h"
+#include "BKE_blender.h"
+#include "BKE_depsgraph.h"
+#include "BKE_displist.h"
+#include "BKE_global.h"
 #include "BKE_ipo.h"
-#include "BKE_action.h"
-#include "BKE_ika.h"
 #include "BKE_key.h"
+#include "BKE_scene.h"
+#include "BKE_utildefines.h"
 
-#include "BIF_interface.h"
-#include "BIF_screen.h"
-#include "BIF_space.h"
 #include "BIF_butspace.h"
-#include "BIF_renderwin.h"
-#include "BIF_toolbox.h"
-#include "BIF_toets.h"
 #include "BIF_editseq.h"
 #include "BIF_editsound.h"
+#include "BIF_editmesh.h"
+#include "BIF_interface.h"
 #include "BIF_poseobject.h"
+#include "BIF_renderwin.h"
+#include "BKE_object.h"
+#include "BIF_screen.h"
+#include "BIF_space.h"
+#include "BIF_toets.h"
+#include "BIF_toolbox.h"
 #include "BIF_usiblender.h"
 
 #include "BDR_vpaint.h"
 #include "BSE_edit.h"
 #include "BSE_editipo.h"
 #include "BSE_headerbuttons.h"
+#include "BSE_seqaudio.h"
 
 #include "blendef.h"
-#include "interface.h"
-#include "render.h"
+#include "render.h"            // darn schrijfplaatje() (ton)
 
 #include "IMB_imbuf.h"
 #include "IMB_imbuf_types.h"
 
 #include "BIF_poseobject.h"
 
-/* only used in toets.c */
+/* only used in toets.c and initrender.c */
 /* this function doesn't really belong here */
 /* ripped from render module */
 void schrijfplaatje(char *name);
 
 
-void write_imag(char *name)
+static void write_imag(char *name)
 {
        /* from file select */
        char str[256];
@@ -175,6 +175,7 @@ void schrijfplaatje(char *name)
 
        if(ibuf) {
                ibuf->rect= (unsigned int *) R.rectot;
+//             ibuf->rect_float = R.rectftot;
 
                if(R.r.planes == 8) IMB_cspace(ibuf, rgb_to_bw);
 
@@ -193,6 +194,9 @@ void schrijfplaatje(char *name)
                else if(R.r.imtype==R_PNG) {
                        ibuf->ftype= PNG;
                }
+               else if(R.r.imtype==R_BMP) {
+                       ibuf->ftype= BMP;
+               }
                else if((R.r.imtype==R_TARGA) || (R.r.imtype==R_PNG)) {
                        ibuf->ftype= TGA;
                }
@@ -271,7 +275,8 @@ void persptoetsen(unsigned short event)
                        G.vd->viewquat[2]= 0.0;
                        G.vd->viewquat[3]= 0.0;
                        G.vd->view= 7;
-                       if(G.vd->persp>=2) G.vd->persp= perspo;
+                       if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0; 
+                       else if(G.vd->persp>=2) G.vd->persp= perspo;
                }
                else if(event==PAD1) {
                        G.vd->viewquat[0]= 0.0;
@@ -279,7 +284,8 @@ void persptoetsen(unsigned short event)
                        G.vd->viewquat[2]= (float)-cos(M_PI/4.0);
                        G.vd->viewquat[3]= (float)-cos(M_PI/4.0);
                        G.vd->view=1;
-                       if(G.vd->persp>=2) G.vd->persp= perspo;
+                       if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
+                       else if(G.vd->persp>=2) G.vd->persp= perspo;
                }
                else if(event==PAD3) {
                        G.vd->viewquat[0]= 0.5;
@@ -287,7 +293,8 @@ void persptoetsen(unsigned short event)
                        G.vd->viewquat[2]= 0.5;
                        G.vd->viewquat[3]= 0.5;
                        G.vd->view=3;
-                       if(G.vd->persp>=2) G.vd->persp= perspo;
+                       if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
+                       else if(G.vd->persp>=2) G.vd->persp= perspo;
                }
                else if(event==PADMINUS) {
                        /* this min and max is also in viewmove() */
@@ -295,14 +302,14 @@ void persptoetsen(unsigned short event)
                                        G.vd->camzoom-= 10;
                                        if(G.vd->camzoom<-30) G.vd->camzoom= -30;
                                }
-                       else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2;
+                       else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2f;
                }
                else if(event==PADPLUSKEY) {
                        if(G.vd->persp==2) {
                                        G.vd->camzoom+= 10;
                                        if(G.vd->camzoom>300) G.vd->camzoom= 300;
                        }
-                       else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333;
+                       else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333f;
                }
                else {
 
@@ -325,7 +332,8 @@ void persptoetsen(unsigned short event)
                        G.vd->viewquat[2]= 0.0;
                        G.vd->viewquat[3]= 0.0;
                        G.vd->view=7;
-                       if(G.vd->persp>=2) G.vd->persp= perspo;
+                       if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
+                       else if(G.vd->persp>=2) G.vd->persp= perspo;
                }
                else if(event==PAD1) {
                        G.vd->viewquat[0]= (float)cos(M_PI/4.0);
@@ -333,7 +341,8 @@ void persptoetsen(unsigned short event)
                        G.vd->viewquat[2]= 0.0;
                        G.vd->viewquat[3]= 0.0;
                        G.vd->view=1;
-                       if(G.vd->persp>=2) G.vd->persp= perspo;
+                       if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
+                       else if(G.vd->persp>=2) G.vd->persp= perspo;
                }
                else if(event==PAD3) {
                        G.vd->viewquat[0]= 0.5;
@@ -341,27 +350,28 @@ void persptoetsen(unsigned short event)
                        G.vd->viewquat[2]= -0.5;
                        G.vd->viewquat[3]= -0.5;
                        G.vd->view=3;
-                       if(G.vd->persp>=2) G.vd->persp= perspo;
+                       if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
+                       else if(G.vd->persp>=2) G.vd->persp= perspo;
                }
                else if(event==PADMINUS) {
                        /* this min and max is also in viewmove() */
                        if(G.vd->persp==2) {
                                G.vd->camzoom= MAX2(-30, G.vd->camzoom-5);
                        }
-                       else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2;
+                       else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2f;
                }
                else if(event==PADPLUSKEY) {
                        if(G.vd->persp==2) {
                                G.vd->camzoom= MIN2(300, G.vd->camzoom+5);
                        }
-                       else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333;
+                       else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333f;
                }
                else if(event==PAD5) {
                        if(G.vd->persp==1) G.vd->persp=0;
                        else G.vd->persp=1;
                }
                else if(event==PAD0) {
-                       if(G.qual & LR_ALTKEY) {
+                       if(G.qual==LR_ALTKEY) {
                                if(oldcamera && is_an_active_object(oldcamera)) {
                                        G.vd->camera= oldcamera;
                                }
@@ -369,7 +379,7 @@ void persptoetsen(unsigned short event)
                                handle_view3d_lock();
                        }
                        else if(BASACT) {
-                               if(G.qual & LR_CTRLKEY) {
+                               if(G.qual==LR_CTRLKEY) {
                                        if(G.vd->camera != OBACT) {
                                                if(G.vd->camera && G.vd->camera->type==OB_CAMERA)
                                                        oldcamera= G.vd->camera;
@@ -391,7 +401,7 @@ void persptoetsen(unsigned short event)
                        if(G.vd->camera) {
                                G.vd->persp= 2;
                                G.vd->view= 0;
-                               if(G.qual & LR_SHIFTKEY) {
+                               if(((G.qual & LR_CTRLKEY) && (G.qual & LR_ALTKEY)) || (G.qual & LR_SHIFTKEY)) {
                                        void setcameratoview3d(void);   // view.c
                                        setcameratoview3d();
                                }                               
@@ -399,11 +409,8 @@ void persptoetsen(unsigned short event)
                }
                else if(event==PAD9) {
                        countall();
-                       do_all_ipos();
-                       do_all_keys();
-                       do_all_actions();
-                       do_all_ikas();
-
+                       update_for_newframe();
+                       
                        reset_slowparents();    /* editobject.c */
                }
                else if(G.vd->persp<2) {
@@ -461,23 +468,25 @@ int save_image_filesel_str(char *str)
 {
        switch(G.scene->r.imtype) {
        case R_PNG:
-               strcpy(str, "SAVE PNG"); return 1;
+               strcpy(str, "Save PNG"); return 1;
+       case R_BMP:
+               strcpy(str, "Save BMP"); return 1;
        case R_TARGA:
-               strcpy(str, "SAVE TARGA"); return 1;
+               strcpy(str, "Save Targa"); return 1;
        case R_RAWTGA:
-               strcpy(str, "SAVE RAW TARGA"); return 1;
+               strcpy(str, "Save Raw Targa"); return 1;
        case R_IRIS:
-               strcpy(str, "SAVE IRIS"); return 1;
+               strcpy(str, "Save IRIS"); return 1;
        case R_IRIZ:
-               strcpy(str, "SAVE IRIS"); return 1;
+               strcpy(str, "Save IRIS"); return 1;
        case R_HAMX:
-               strcpy(str, "SAVE HAMX"); return 1;
+               strcpy(str, "Save HAMX"); return 1;
        case R_FTYPE:
-               strcpy(str, "SAVE FTYPE"); return 1;
+               strcpy(str, "Save Ftype"); return 1;
        case R_JPEG90:
-               strcpy(str, "SAVE JPEG"); return 1;
+               strcpy(str, "Save JPEG"); return 1;
        default:
-               strcpy(str, "SAVE IMAGE"); return 0;
+               strcpy(str, "Save Image"); return 0;
        }       
 }
 
@@ -520,9 +529,10 @@ int blenderqread(unsigned short event, short val)
        
        if(val==0) return 1;
        if(event==MOUSEY || event==MOUSEX) return 1;
-       if (G.flags & G_FLAGS_AUTOPLAY) return 1;
+       if (G.flags & G_FILE_AUTOPLAY) return 1;
 
        if (curarea && curarea->spacetype==SPACE_TEXT) textspace= 1;
+       else if (curarea && curarea->spacetype==SPACE_SCRIPT) textspace= 1;
 
        switch(event) {
 
@@ -534,11 +544,11 @@ int blenderqread(unsigned short event, short val)
                                areawinset(sa->win);
                        }
                        
-                       activate_fileselect(FILE_BLENDER, "LOAD FILE", G.sce, BIF_read_file);
+                       activate_fileselect(FILE_BLENDER, "Open File", G.sce, BIF_read_file);
                        return 0;
                }
-               else if(G.qual & LR_SHIFTKEY) {
-                       activate_fileselect(FILE_LOADLIB, "LOAD LIBRARY", G.lib, 0);
+               else if(G.qual==LR_SHIFTKEY) {
+                       activate_fileselect(FILE_LOADLIB, "Load Library", G.lib, 0);
                        return 0;
                }
                break;
@@ -546,14 +556,14 @@ int blenderqread(unsigned short event, short val)
                if(G.qual==0) {
                        strcpy(dir, G.sce);
                        untitled(dir);
-                       activate_fileselect(FILE_BLENDER, "SAVE FILE", dir, BIF_write_file);
+                       activate_fileselect(FILE_BLENDER, "Save File", dir, BIF_write_file);
                        return 0;
                }
-               else if(G.qual & LR_CTRLKEY) {
+               else if(G.qual==LR_CTRLKEY) {
                        write_vrml_fs();
                        return 0;
                }
-               else if(G.qual & LR_SHIFTKEY) {
+               else if(G.qual==LR_SHIFTKEY) {
                        write_dxf_fs();
                        return 0;
                }
@@ -564,82 +574,105 @@ int blenderqread(unsigned short event, short val)
                        return 0;
                }
                else if(G.qual & LR_CTRLKEY) {
-                       BIF_screendump();
+                       /* all alt+ctrl+shift combos are needed here... */
+                       BIF_screendump(0);
                }
                break;
        case F4KEY:
-               if(G.qual & LR_SHIFTKEY) {
+               if(G.qual==LR_SHIFTKEY) {
 
                        memset(str, 0, 16);
                        ob= OBACT;
                        if(ob) strcpy(str, ob->id.name);
 
-                       activate_fileselect(FILE_MAIN, "DATA SELECT", str, 0);
+                       activate_fileselect(FILE_MAIN, "Data Select", str, 0);
                        return 0;
                }
-               else extern_set_butspace(event);
-               
+               else if(G.qual==0) {
+                       extern_set_butspace(event);
+               }
                break;
        case F5KEY:
-               if(G.qual & LR_SHIFTKEY) {
+               if(G.qual==LR_SHIFTKEY) {
                        newspace(curarea, SPACE_VIEW3D);
                        return 0;
                }
-               else extern_set_butspace(event);
+               else if(G.qual==0) {
+                       extern_set_butspace(event);
+               }
                break;
        case F6KEY:
-               if(G.qual & LR_SHIFTKEY) {
+               if(G.qual==LR_SHIFTKEY) {
                        newspace(curarea, SPACE_IPO);
                        return 0;
                }
-               else extern_set_butspace(event);
+               else if(G.qual==0) {
+                       extern_set_butspace(event);
+               }
                break;
        case F7KEY:
-               if(G.qual & LR_SHIFTKEY) {
+               if(G.qual==LR_SHIFTKEY) {
                        newspace(curarea, SPACE_BUTS);
                        return 0;
                }
-               else extern_set_butspace(event);
+               else if(G.qual==0) {
+                       extern_set_butspace(event);
+               }
                break;
        case F8KEY:
-               if(G.qual & LR_SHIFTKEY) {
+               if(G.qual==LR_SHIFTKEY) {
                        newspace(curarea, SPACE_SEQ);
                        return 0;
                }
-               else extern_set_butspace(event);
+               else if(G.qual==0) {
+                       extern_set_butspace(event);
+               }
                break;
        case F9KEY:
-               if(G.qual & LR_SHIFTKEY) {
+               if(G.qual==LR_SHIFTKEY) {
                        newspace(curarea, SPACE_OOPS);
                        return 0;
                }
-               else extern_set_butspace(event);
+               else if(G.qual==(LR_SHIFTKEY|LR_ALTKEY)) {
+                       newspace(curarea, SPACE_OOPS+256);
+                       return 0;
+               }
+               else if(G.qual==0) {
+                       extern_set_butspace(event);
+               }
                break;
        case F10KEY:
-               if(G.qual & LR_SHIFTKEY) {
+               if(G.qual==LR_SHIFTKEY) {
                        newspace(curarea, SPACE_IMAGE);
                        return 0;
                }
-               else extern_set_butspace(event);
+               else if(G.qual==0) {
+                       extern_set_butspace(event);
+               }
                break;
        case F11KEY:
-               if(G.qual & LR_SHIFTKEY) {
+               if(G.qual==LR_SHIFTKEY) {
                        newspace(curarea, SPACE_TEXT);
                        return 0;
                }
-               else BIF_toggle_render_display();
-               return 0;
+               else if(G.qual==0) {
+                       BIF_toggle_render_display();
+                       return 0;
+               }
                break;
        case F12KEY:
-               if(G.qual & LR_SHIFTKEY) {
-                       if (G.qual & LR_CTRLKEY){
-                               newspace(curarea, SPACE_NLA);
-                               return 0;
-                       }
+               if(G.qual==LR_SHIFTKEY) {
                        newspace(curarea, SPACE_ACTION);
                        return 0;
                }
-               else BIF_do_render(0);
+               else if (G.qual==(LR_SHIFTKEY|LR_CTRLKEY)) {
+                       newspace(curarea, SPACE_NLA);
+                       return 0;
+               }
+               else {
+                       /* ctrl/alt + f12 should render too, for some macs have f12 assigned to cd eject */
+                       BIF_do_render(0);
+               }
                return 0;
                break;
        
@@ -647,17 +680,23 @@ int blenderqread(unsigned short event, short val)
        case DOWNARROWKEY:
                if(textediting==0 && textspace==0) {
 
-#ifdef _WIN32  // FULLSCREEN
+#if 0
+//#ifdef _WIN32        // FULLSCREEN
                        if(event==DOWNARROWKEY){
-                               if (G.qual & LR_ALTKEY) mainwindow_toggle_fullscreen(0);
-                               else CFRA-= 10;
+                               if (G.qual==LR_ALTKEY)
+                                       mainwindow_toggle_fullscreen(0);
+                               else if(G.qual==0)
+                                       CFRA-= 10;
                        }
 #else
-                       if(event==DOWNARROWKEY) CFRA-= 10;
+                       if((event==DOWNARROWKEY)&&(G.qual==0))
+                               CFRA-= 10;
 #endif
-                       else CFRA--;
+                       else if((event==LEFTARROWKEY)&&(G.qual==0))
+                               CFRA--;
                        
-                       if(G.qual & LR_SHIFTKEY) CFRA= SFRA;
+                       if(G.qual==LR_SHIFTKEY)
+                               CFRA= SFRA;
                        if(CFRA<1) CFRA=1;
        
                        update_for_newframe();
@@ -669,51 +708,83 @@ int blenderqread(unsigned short event, short val)
        case UPARROWKEY:
                if(textediting==0 && textspace==0) {
 
-#ifdef _WIN32  // FULLSCREEN
+#if 0
+//#ifdef _WIN32        // FULLSCREEN
                        if(event==UPARROWKEY){ 
-                               if(G.qual & LR_ALTKEY) mainwindow_toggle_fullscreen(1);
-                               else CFRA+= 10;
+                               if(G.qual==LR_ALTKEY)
+                                       mainwindow_toggle_fullscreen(1);
+                               else if(G.qual==0)
+                                       CFRA+= 10;
                        }
 #else
-                       if(event==UPARROWKEY) CFRA+= 10;
+                       if((event==UPARROWKEY)&&(G.qual==0))
+                               CFRA+= 10;
 #endif
-                       else CFRA++;
+                       else if((event==RIGHTARROWKEY)&&(G.qual==0))
+                               CFRA++;
 
-                       if(G.qual & LR_SHIFTKEY) CFRA= EFRA;
+                       if(G.qual==LR_SHIFTKEY)
+                               CFRA= EFRA;
                        
                        update_for_newframe();
                }
                break;
-       
+
        case ESCKEY:
-               sound_stop_all_sounds();
+               sound_stop_all_sounds();        // whats this?
+               
+               /* stop playback on ESC always */
+               rem_screenhandler(G.curscreen, SCREEN_HANDLER_ANIM);
+               audiostream_stop();
+               allqueue(REDRAWALL, 0);
+               
                break;
        case TABKEY:
-               if(G.qual==0 ) {
+               if(G.qual==0) {
                        if(textspace==0) {
-                               if(curarea->spacetype==SPACE_IPO) set_editflag_editipo();
-                               else if(curarea->spacetype==SPACE_SEQ) enter_meta();
+                               if(curarea->spacetype==SPACE_IPO)
+                                       set_editflag_editipo();
+                               else if(curarea->spacetype==SPACE_SEQ)
+                                       enter_meta();
                                else if(G.vd) {
                                        /* also when Alt-E */
-                                       if(G.obedit==0) enter_editmode();
-                                       else exit_editmode(1);
+                                       if(G.obedit==NULL) {
+                                               enter_editmode();
+                                               if(G.obedit) BIF_undo_push("Original"); // here, because all over code enter_editmode is abused
+                                       }
+                                       else
+                                               exit_editmode(2); // freedata, and undo
                                }
                                return 0;
                        }
                }
-               else if(G.qual & LR_CTRLKEY){
-                       if(G.obpose) exit_posemode(1);
-                       else
-                               enter_posemode();
-                       allqueue(REDRAWHEADERS, 0);     
-                       
+               else if(G.qual==LR_CTRLKEY){
+                       Object *ob= OBACT;
+                       if(ob) {
+                               if(ob->type==OB_ARMATURE) {
+                                       if(ob->flag & OB_POSEMODE) exit_posemode();
+                                       else enter_posemode();
+                               }
+                               else if(ob->type==OB_MESH) {
+                                       if(ob==G.obedit) EM_selectmode_menu();
+                                       else set_wpaint();
+                               }
+                       }
                }
-               else if(G.qual & LR_SHIFTKEY) {
-                       if(G.obedit) exit_editmode(1);
-                       if(G.f & G_FACESELECT) set_faceselect();
-                       if(G.f & G_VERTEXPAINT) set_vpaint();
-                       if(G.f & G_WEIGHTPAINT) set_wpaint();
-                       if(G.obpose) exit_posemode(1);
+               else if(G.qual==LR_SHIFTKEY) {  // ??
+                       if(G.obedit)
+                               exit_editmode(2); // freedata, and undo
+                       if(G.f & G_FACESELECT)
+                               set_faceselect();
+                       if(G.f & G_VERTEXPAINT)
+                               set_vpaint();
+                       if(G.f & G_TEXTUREPAINT) {
+                               G.f &= ~G_TEXTUREPAINT;
+                               allqueue(REDRAWVIEW3D, 0);
+                               allqueue(REDRAWBUTSEDIT, 0);
+                       }
+                       if(G.f & G_WEIGHTPAINT)
+                               set_wpaint();
                }
                break;
 
@@ -722,18 +793,25 @@ int blenderqread(unsigned short event, short val)
 
        case AKEY:
                if(textediting==0 && textspace==0) {
-                       if(G.qual & LR_ALTKEY) {
-                               if(G.qual & LR_SHIFTKEY) play_anim(1);
-                               else play_anim(0);
+                       if(G.qual==(LR_SHIFTKEY|LR_ALTKEY)){
+                               play_anim(1);
+                               return 0;
+                       }
+                       else if(G.qual==LR_ALTKEY) {
+                               play_anim(0);
                                return 0;
                        }
                }
                break;
        case EKEY:
-               if(G.qual & LR_ALTKEY) {
+               if(G.qual==LR_ALTKEY) {
                        if(G.vd && textspace==0) {
-                               if(G.obedit==0) enter_editmode();
-                               else exit_editmode(1);
+                               if(G.obedit==0) {
+                                       enter_editmode();
+                                       BIF_undo_push("Original");
+                               }
+                               else
+                                       exit_editmode(2); // freedata, and undo
                                return 0;
                        }                       
                }
@@ -756,10 +834,16 @@ int blenderqread(unsigned short event, short val)
                break;
 
        case NKEY:
-               if(textediting==0 && textspace==0 ) {
+               if(textediting==0 && textspace==0) {
                        if(G.qual & LR_CTRLKEY);
                        else if(G.qual==0 || (G.qual & LR_SHIFTKEY)) {
-                               if(curarea->spacetype!=SPACE_VIEW3D) {
+                               if(curarea->spacetype==SPACE_VIEW3D);           // is new panel, in view3d queue
+                               else if(curarea->spacetype==SPACE_IPO);                 // is new panel, in ipo queue
+                               else if(curarea->spacetype==SPACE_IMAGE);                       // is new panel, in ipo queue
+                               else if(curarea->spacetype==SPACE_ACTION);                      // is own queue
+                               else if(curarea->spacetype==SPACE_NLA);                 // is new panel
+                               else if(curarea->spacetype==SPACE_SEQ);                 // is new panel
+                               else {
                                        clever_numbuts();
                                        return 0;
                                }
@@ -769,7 +853,7 @@ int blenderqread(unsigned short event, short val)
                
        case OKEY:
                if(textediting==0) {
-                       if(G.qual & LR_CTRLKEY) {
+                       if(G.qual==LR_CTRLKEY) {
                                /* There seem to be crashes here sometimes.... String
                                 * bound overwrites? I changed dir and str sizes,
                                 * let's see if this reoccurs. */
@@ -785,114 +869,148 @@ int blenderqread(unsigned short event, short val)
                break;
                
        case SKEY:
-               if(G.obpose==0 && G.obedit==0) {
-                       if(G.qual & LR_CTRLKEY) {
-                               if(G.qual & LR_SHIFTKEY);
-                               else {
-                                       strcpy(dir, G.sce);
-                                       if (untitled(dir)) {
-                                               activate_fileselect(FILE_BLENDER, "SAVE FILE", dir, BIF_write_file);
-                                       } else {
-                                               BIF_write_file(dir);
-                                               free_filesel_spec(dir);
-                                       }
-                                       return 0;
+               if(G.obedit==NULL) {
+                       if(G.qual==LR_CTRLKEY) {
+                               strcpy(dir, G.sce);
+                               if (untitled(dir)) {
+                                       activate_fileselect(FILE_BLENDER, "Save File", dir, BIF_write_file);
+                               } else {
+                                       BIF_write_file(dir);
+                                       free_filesel_spec(dir);
                                }
+                               return 0;
                        }
                }
                break;
        
        case TKEY:
-               if(G.qual & LR_ALTKEY) {
-               if(G.qual & LR_CTRLKEY) {
+               if (G.qual==(LR_SHIFTKEY|LR_ALTKEY|LR_CTRLKEY)) {
+                       Object *ob = OBACT;
+                       int event = pupmenu(ob?"Time%t|draw|recalc ob|recalc data":"Time%t|draw");
                        int a;
+                       double delta, stime;
 
-                       if (G.qual & LR_SHIFTKEY) {
-                               double delta, stime;
-
-                               waitcursor(1);
-                               
-                               stime= PIL_check_seconds_timer();
-                               for(a=0; a<100000; a++) {
+                       waitcursor(1);
+                       
+                       stime= PIL_check_seconds_timer();
+                       for(a=0; a<100000; a++) {
+                               if (event==1) {
                                        scrarea_do_windraw(curarea);
-
-                                       delta= PIL_check_seconds_timer()-stime;
-                                       if (delta>5.0) break;
+                               } else if (event==2) {
+                                       ob->recalc |= OB_RECALC_OB;
+                                       object_handle_update(ob);
+                               } else if (event==3) {
+                                       ob->recalc |= OB_RECALC_DATA;
+                                       object_handle_update(ob);
                                }
+
+                               delta= PIL_check_seconds_timer()-stime;
+                               if (delta>5.0) break;
+                       }
+                       
+                       waitcursor(0);
+                       notice("%8.6f s/op - %6.2f ops/s - %d iterations", delta/a, a/delta, a);
+                       return 0;
+               }
+               else if(G.qual==(LR_ALTKEY|LR_CTRLKEY)) {
+                       int a;
+                       int event= pupmenu("10 Timer%t|draw|draw+swap|undo");
+                       if(event>0) {
+                               double stime= PIL_check_seconds_timer();
+                               char tmpstr[128];
+                               int time;
+
+                               waitcursor(1);
                                
-                               waitcursor(0);
-                               notice("FPS: %f (%d iterations)", a/delta, a);
-                       } else {
-                               int event= pupmenu("10 Timer%t|draw|draw+swap");
-                               if(event>0) {
-                                       double stime= PIL_check_seconds_timer();
-                                       char tmpstr[128];
-                                       int time;
-
-                                       printf("start timer\n");
-                                       waitcursor(1);
-                                                                       
-                                       for(a=0; a<10; a++) {
+                               for(a=0; a<10; a++) {
+                                       if (event==1) {
                                                scrarea_do_windraw(curarea);
-                                               if(event==2) screen_swapbuffers();
+                                       } else if (event==2) {
+                                               scrarea_do_windraw(curarea);
+                                               screen_swapbuffers();
                                        }
+                                       else if(event==3) {
+                                               BKE_write_undo("10 timer");
+                                       }
+                               }
+                       
+                               time= (PIL_check_seconds_timer()-stime)*1000;
                                
-                                       time= (PIL_check_seconds_timer()-stime)*1000;
-                                       
-                                       if(event==1) sprintf(tmpstr, "draw %%t|%d", time);
-                                       if(event==2) sprintf(tmpstr, "d+sw %%t|%d", time);
-                               
-                                       waitcursor(0);
-                                       pupmenu(tmpstr);
+                               if(event==1) sprintf(tmpstr, "draw %%t|%d ms", time);
+                               if(event==2) sprintf(tmpstr, "d+sw %%t|%d ms", time);
+                               if(event==3) sprintf(tmpstr, "displist %%t|%d ms", time);
+                               if(event==4) sprintf(tmpstr, "undo %%t|%d ms", time);
+                       
+                               waitcursor(0);
+                               pupmenu(tmpstr);
 
-                               }
                        }
                        return 0;
-               }}
+               }
                break;
                                
        case UKEY:
                if(textediting==0) {
-                       if(G.qual & LR_CTRLKEY) {
-                               if(okee("SAVE USER DEFAULTS")) {
+                       if(G.qual==LR_CTRLKEY) {
+                               if(okee("Save user defaults")) {
                                        BIF_write_homefile();
                                }
                                return 0;
                        }
+                       else if(G.qual==LR_ALTKEY) {
+                               if(curarea->spacetype!=SPACE_TEXT) {
+                                       BIF_undo_menu();
+                                       return 0;
+                               }
+                       }
                }
                break;
                
        case WKEY:
                if(textediting==0) {
-                       if(G.qual & LR_CTRLKEY) {
-                               if(G.qual & LR_SHIFTKEY);
-                               else {
-                                       strcpy(dir, G.sce);
-                                       if (untitled(dir)) {
-                                               activate_fileselect(FILE_BLENDER, "SAVE FILE", dir, BIF_write_file);
-                                       } else {
-                                               BIF_write_file(dir);
-                                               free_filesel_spec(dir);
-                                       }
-                                       return 0;
+                       if(G.qual==LR_CTRLKEY) {
+                               strcpy(dir, G.sce);
+                               if (untitled(dir)) {
+                                       activate_fileselect(FILE_BLENDER, "Save File", dir, BIF_write_file);
+                               } else {
+                                       BIF_write_file(dir);
+                                       free_filesel_spec(dir);
                                }
+                               return 0;
                        }
-                       else if(G.qual & LR_ALTKEY) {
+                       else if(G.qual==LR_ALTKEY) {
                                write_videoscape_fs();
                        }
                }
                break;
                
        case XKEY:
-               if(textspace==0) {
-                       if(G.qual & LR_CTRLKEY) {
-                               if(okee("ERASE ALL")) {
+               if(textspace==0 && textediting==0) {
+                       if(G.qual==LR_CTRLKEY) {
+                               if(okee("Erase all")) {
                                        if( BIF_read_homefile()==0) error("No file ~/.B.blend");
                                }
                                return 0;
                        }
                }
                break;
+       case YKEY:      // redo alternative
+               if(textspace==0) {
+                       if(G.qual==LR_CTRLKEY) {
+                               BIF_redo(); 
+                               return 0;
+                       }
+               }
+               break;
+       case ZKEY:      // undo
+               if(textspace==0) {
+                       if(G.qual & (LR_CTRLKEY|LR_COMMANDKEY)) { // all combos with ctrl/commandkey are accepted
+                               if ELEM(G.qual, LR_CTRLKEY, LR_COMMANDKEY) BIF_undo();
+                               else BIF_redo(); // all combos with ctrl is redo
+                               return 0;
+                       }
+               }
+               break; 
        }
        
        return 1;