Two in one:
[blender.git] / source / blender / src / toets.c
index 5cc23d6914b7963ebf1d2237d7ce552036555243..355a1535f42dac2242a6241bf76e74cf9f431199 100644 (file)
@@ -53,6 +53,7 @@
 
 #include "DNA_object_types.h"
 #include "DNA_screen_types.h"
+#include "DNA_scene_types.h"
 #include "DNA_space_types.h"
 #include "DNA_view3d_types.h"
 #include "DNA_userdef_types.h"
 #include "BKE_action.h"
 #include "BKE_anim.h"
 #include "BKE_blender.h"
+#include "BKE_depsgraph.h"
 #include "BKE_displist.h"
 #include "BKE_global.h"
+#include "BKE_image.h"
 #include "BKE_ipo.h"
-#include "BKE_ika.h"
 #include "BKE_key.h"
 #include "BKE_scene.h"
 #include "BKE_utildefines.h"
 #include "BIF_editsound.h"
 #include "BIF_editmesh.h"
 #include "BIF_interface.h"
+#include "BKE_object.h"
 #include "BIF_poseobject.h"
+#include "BIF_previewrender.h"
 #include "BIF_renderwin.h"
+#include "BIF_retopo.h"
 #include "BIF_screen.h"
 #include "BIF_space.h"
 #include "BIF_toets.h"
 #include "BIF_toolbox.h"
 #include "BIF_usiblender.h"
+#include "BIF_writeimage.h"
 
+#include "BDR_sculptmode.h"
 #include "BDR_vpaint.h"
 #include "BDR_editobject.h"
 #include "BDR_editface.h"
 #include "BSE_seqaudio.h"
 
 #include "blendef.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 and initrender.c */
-/* this function doesn't really belong here */
-/* ripped from render module */
-void schrijfplaatje(char *name);
-
-
-static void write_imag(char *name)
-{
-       /* from file select */
-       char str[256];
-
-       strcpy(str, name);
-       BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
-
-       if(saveover(str)) {
-               if(BLI_testextensie(str,".blend")) {
-                       error("Wrong filename");
-                       return;
-               }
-               waitcursor(1); /* from screen.c */
-               schrijfplaatje(str);
-               strcpy(G.ima, name);
-               waitcursor(0);
-       }
-}
-
-
-/* From matrix.h: it's really a [4][4]! */
-/* originally in initrender... maybe add fileControl thingy? */
-
-/* should be called write_image(char *name) :-) */
-void schrijfplaatje(char *name)
-{
-       struct ImBuf *ibuf=0;
-       unsigned int *temprect=0;
-       char str[FILE_MAXDIR+FILE_MAXFILE];
-
-       /* has RGBA been set? If so: use alpha channel for color zero */
-       IMB_alpha_to_col0(FALSE);
-
-       if(R.r.planes == 32) {
-               /* everything with less than 50 % alpha -> col 0 */
-               if(R.r.alphamode == R_ALPHAKEY) IMB_alpha_to_col0(2);
-               /* only when 0 alpha -> col 0 */
-               else IMB_alpha_to_col0(1);
-       }
-
-       /* Seems to me this is also superfluous.... */
-       if (R.r.imtype==R_FTYPE) {
-               strcpy(str, R.r.ftype);
-               BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
-
-               ibuf = IMB_loadiffname(str, IB_test);
-               if(ibuf) {
-                       ibuf->x = R.rectx;
-                       ibuf->y = R.recty;
-               }
-               else {
-                       error("Can't find filetype");
-                       G.afbreek= 1;
-                       return;
-               }
-               /* setdither(2); */
-       }
-
-       if(ibuf == 0) {
-               ibuf= IMB_allocImBuf(R.rectx, R.recty, R.r.planes, 0, 0);
-       }
-
-       if(ibuf) {
-               ibuf->rect= (unsigned int *) R.rectot;
-//             ibuf->rect_float = R.rectftot;
-
-               if(R.r.planes == 8) IMB_cspace(ibuf, rgb_to_bw);
-
-               if(R.r.imtype== R_IRIS) {
-                       ibuf->ftype= IMAGIC;
-               }
-               else if(R.r.imtype==R_IRIZ) {
-                       ibuf->ftype= IMAGIC;
-                       if (ibuf->zbuf == 0) {
-                               if (R.rectz) {
-                                       ibuf->zbuf = (int *)R.rectz;
-                               }
-                               else printf("no zbuf\n");
-                       }
-               }
-               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;
-               }
-               else if(R.r.imtype==R_RAWTGA) {
-                       ibuf->ftype= RAWTGA;
-               }
-               else if(R.r.imtype==R_HAMX) {
-                       /* make copy */
-                       temprect= MEM_dupallocN(R.rectot);
-                       ibuf->ftype= AN_hamx;
-               }
-               else if(ELEM5(R.r.imtype, R_MOVIE, R_AVICODEC, R_AVIRAW, R_AVIJPEG, R_JPEG90)) {
-                       if(R.r.quality < 10) R.r.quality= 90;
-
-                       if(R.r.mode & R_FIELDS) ibuf->ftype= JPG_VID|R.r.quality;
-                       else ibuf->ftype= JPG|R.r.quality;
-               }
-       
-               RE_make_existing_file(name);
-
-               if(IMB_saveiff(ibuf, name, IB_rect | IB_zbuf)==0) {
-                       perror(name);
-                       G.afbreek= 1;
-               }
-
-               IMB_freeImBuf(ibuf);
-
-               if (R.r.imtype==R_HAMX) {
-                       MEM_freeN(R.rectot);
-                       R.rectot= temprect;
-               }
-       }
-       else {
-               G.afbreek= 1;
-       }
-}
-
-
-
 /* ------------------------------------------------------------------------- */
 
 static int is_an_active_object(void *ob) {
@@ -252,19 +126,26 @@ void persptoetsen(unsigned short event)
        static Object *oldcamera=0;
        float phi, si, q1[4], vec[3];
        static int perspo=1;
+       int preview3d_event= 1;
        
        if(event==PADENTER) {
                if (G.qual == LR_SHIFTKEY) {
                        view3d_set_1_to_1_viewborder(G.vd);
                } else {
                        if (G.vd->persp==2) {
-                               G.vd->camzoom= 0.0;
+                               G.vd->camzoom= 0;
                        } else {
                                G.vd->dist= 10.0;
                        }
                }
        }
        else if((G.qual & (LR_SHIFTKEY | LR_CTRLKEY)) && (event != PAD0)) {
+               
+               /* Indicate that this view is inverted,
+                * but only if it actually _was_ inverted (jobbe) */
+               if (event==PAD7 || event == PAD1 || event == PAD3)
+                       G.vd->flag2 |= V3D_OPP_DIRECTION_NAME;
+               
                if(event==PAD0) {
                        /* G.vd->persp= 3; */
                }
@@ -298,15 +179,15 @@ void persptoetsen(unsigned short event)
                else if(event==PADMINUS) {
                        /* this min and max is also in viewmove() */
                        if(G.vd->persp==2) {
-                                       G.vd->camzoom-= 10;
-                                       if(G.vd->camzoom<-30) G.vd->camzoom= -30;
-                               }
+                               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.2f;
                }
                else if(event==PADPLUSKEY) {
                        if(G.vd->persp==2) {
-                                       G.vd->camzoom+= 10;
-                                       if(G.vd->camzoom>300) G.vd->camzoom= 300;
+                               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*=.83333f;
                }
@@ -324,6 +205,11 @@ void persptoetsen(unsigned short event)
                }
        }
        else {
+               /* Indicate that this view is not inverted.
+                * Don't do this for PADMINUS/PADPLUSKEY, though. (jobbe)*/
+               if (event != PADMINUS && event != PADPLUSKEY)
+                       G.vd->flag2 &= ~V3D_OPP_DIRECTION_NAME;
+               
 
                if(event==PAD7) {
                        G.vd->viewquat[0]= 1.0;
@@ -358,12 +244,14 @@ void persptoetsen(unsigned short event)
                                G.vd->camzoom= MAX2(-30, G.vd->camzoom-5);
                        }
                        else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2f;
+                       if(G.vd->persp!=1) preview3d_event= 0;
                }
                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*=.83333f;
+                       if(G.vd->persp!=1) preview3d_event= 0;
                }
                else if(event==PAD5) {
                        if(G.vd->persp==1) G.vd->persp=0;
@@ -378,8 +266,9 @@ void persptoetsen(unsigned short event)
                                handle_view3d_lock();
                        }
                        else if(BASACT) {
+                               /* check both G.vd as G.scene cameras */
                                if(G.qual==LR_CTRLKEY) {
-                                       if(G.vd->camera != OBACT) {
+                                       if(G.vd->camera != OBACT || G.scene->camera != OBACT) {
                                                if(G.vd->camera && G.vd->camera->type==OB_CAMERA)
                                                        oldcamera= G.vd->camera;
                                                
@@ -387,7 +276,7 @@ void persptoetsen(unsigned short event)
                                                handle_view3d_lock();
                                        }
                                }
-                               else if(G.vd->camera==0 && OBACT->type==OB_CAMERA) {
+                               else if((G.vd->camera==NULL || G.scene->camera==NULL) && OBACT->type==OB_CAMERA) {
                                        G.vd->camera= OBACT;
                                        handle_view3d_lock();
                                }
@@ -403,23 +292,22 @@ void persptoetsen(unsigned short event)
                                if(((G.qual & LR_CTRLKEY) && (G.qual & LR_ALTKEY)) || (G.qual & LR_SHIFTKEY)) {
                                        void setcameratoview3d(void);   // view.c
                                        setcameratoview3d();
+                                       DAG_object_flush_update(G.scene, G.scene->camera, OB_RECALC_OB);
+                                       BIF_undo_push("View to Camera position");
+                                       allqueue(REDRAWVIEW3D, 0);
                                }                               
                        }
                }
                else if(event==PAD9) {
                        countall();
-                       do_all_ipos();
-                       do_all_keys();
-                       do_all_actions(NULL);
-                       do_all_ikas();
-                       test_all_displists();
+                       update_for_newframe();
                        
                        reset_slowparents();    /* editobject.c */
                }
                else if(G.vd->persp<2) {
                        if(event==PAD4 || event==PAD6) {
                                /* z-axis */
-                               phi= (float)(M_PI/24.0);
+                               phi= (float)(M_PI/360.0)*U.pad_rot_angle;
                                if(event==PAD6) phi= -phi;
                                si= (float)sin(phi);
                                q1[0]= (float)cos(phi);
@@ -434,7 +322,7 @@ void persptoetsen(unsigned short event)
                                VECCOPY(q1+1, G.vd->viewinv[0]);
                                
                                Normalise(q1+1);
-                               phi= (float)(M_PI/24.0);
+                               phi= (float)(M_PI/360.0)*U.pad_rot_angle;
                                if(event==PAD2) phi= -phi;
                                si= (float)sin(phi);
                                q1[0]= (float)cos(phi);
@@ -448,6 +336,14 @@ void persptoetsen(unsigned short event)
 
                if(G.vd->persp<2) perspo= G.vd->persp;
        }
+
+       retopo_force_update();
+       
+       if(preview3d_event) 
+               BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
+       else
+               BIF_view3d_previewrender_signal(curarea, PR_PROJECTED);
+
        scrarea_queue_redraw(curarea);
 }
 
@@ -467,55 +363,34 @@ int untitled(char * name)
        return(FALSE);
 }
 
-int save_image_filesel_str(char *str)
-{
-       switch(G.scene->r.imtype) {
-       case R_PNG:
-               strcpy(str, "Save PNG"); return 1;
-       case R_BMP:
-               strcpy(str, "Save BMP"); return 1;
-       case R_TARGA:
-               strcpy(str, "Save Targa"); return 1;
-       case R_RAWTGA:
-               strcpy(str, "Save Raw Targa"); return 1;
-       case R_IRIS:
-               strcpy(str, "Save IRIS"); return 1;
-       case R_IRIZ:
-               strcpy(str, "Save IRIS"); return 1;
-       case R_HAMX:
-               strcpy(str, "Save HAMX"); return 1;
-       case R_FTYPE:
-               strcpy(str, "Save Ftype"); return 1;
-       case R_JPEG90:
-               strcpy(str, "Save JPEG"); return 1;
-       default:
-               strcpy(str, "Save Image"); return 0;
-       }       
-}
-
-void BIF_save_rendered_image(void)
+char *recent_filelist(void)
 {
-       if(!R.rectot) {
-               error("No image rendered");
-       } else {
-               char dir[FILE_MAXDIR * 2], str[FILE_MAXFILE * 2];
+       struct RecentFile *recent;
+       int event, i, ofs;
+       char pup[2048], *p;
 
-               if(G.ima[0]==0) {
-                       strcpy(dir, G.sce);
-                       BLI_splitdirstring(dir, str);
-                       strcpy(G.ima, dir);
-               }
-               
-               R.r.imtype= G.scene->r.imtype;
-               R.r.quality= G.scene->r.quality;
-               R.r.planes= G.scene->r.planes;
+       p= pup + sprintf(pup, "Open Recent%%t");
        
-               if (!save_image_filesel_str(str)) {
-                       error("Select an image type in DisplayButtons(F10)");
-               } else {
-                       activate_fileselect(FILE_SPECIAL, str, G.ima, write_imag);
+       if (G.sce[0]) {
+               p+= sprintf(p, "|%s %%x%d", G.sce, 1);
+               ofs = 1;
+       } else ofs = 0;
+
+       for (recent = G.recent_files.first, i=0; (i<10) && (recent); recent = recent->next, i++) {
+               if (strcmp(recent->filename, G.sce)) {
+                       p+= sprintf(p, "|%s %%x%d", recent->filename, i+ofs+1);
                }
        }
+       event= pupmenu(pup);
+       if(event>0) {
+               if (ofs && (event==1))
+                       return(G.sce);
+               else
+                       recent = BLI_findlink(&(G.recent_files), event-1-ofs);
+                       if(recent) return(recent->filename);
+       }
+       
+       return(NULL);
 }
 
 int blenderqread(unsigned short event, short val)
@@ -523,16 +398,18 @@ int blenderqread(unsigned short event, short val)
        /* here do the general keys handling (not screen/window/space) */
        /* return 0: do not pass on to the other queues */
        extern int textediting;
+       extern void playback_anim();
        ScrArea *sa;
        Object *ob;
        int textspace=0;
        /* Changed str and dir size to 160, to make sure there is enough
         * space for filenames. */
        char dir[FILE_MAXDIR * 2], str[FILE_MAXFILE * 2];
+       char *recentfile;
        
        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;
@@ -573,11 +450,14 @@ int blenderqread(unsigned short event, short val)
                break;
        case F3KEY:
                if(G.qual==0) {
-                       BIF_save_rendered_image();
+                       BIF_save_rendered_image_fs();
+                       return 0;
+               }
+               else if(G.qual==LR_SHIFTKEY) {
+                       newspace(curarea, SPACE_NODE);
                        return 0;
                }
                else if(G.qual & LR_CTRLKEY) {
-                       /* all alt+ctrl+shift combos are needed here... */
                        BIF_screendump(0);
                }
                break;
@@ -588,11 +468,11 @@ int blenderqread(unsigned short event, short val)
                        ob= OBACT;
                        if(ob) strcpy(str, ob->id.name);
 
-                       activate_fileselect(FILE_MAIN, "Data Select", str, 0);
+                       activate_fileselect(FILE_MAIN, "Data Select", str, NULL);
                        return 0;
                }
                else if(G.qual==0) {
-                       extern_set_butspace(event);
+                       extern_set_butspace(event, 1);
                }
                break;
        case F5KEY:
@@ -601,7 +481,7 @@ int blenderqread(unsigned short event, short val)
                        return 0;
                }
                else if(G.qual==0) {
-                       extern_set_butspace(event);
+                       extern_set_butspace(event, 1);
                }
                break;
        case F6KEY:
@@ -610,7 +490,7 @@ int blenderqread(unsigned short event, short val)
                        return 0;
                }
                else if(G.qual==0) {
-                       extern_set_butspace(event);
+                       extern_set_butspace(event, 1);
                }
                break;
        case F7KEY:
@@ -619,7 +499,7 @@ int blenderqread(unsigned short event, short val)
                        return 0;
                }
                else if(G.qual==0) {
-                       extern_set_butspace(event);
+                       extern_set_butspace(event, 1);
                }
                break;
        case F8KEY:
@@ -628,7 +508,7 @@ int blenderqread(unsigned short event, short val)
                        return 0;
                }
                else if(G.qual==0) {
-                       extern_set_butspace(event);
+                       extern_set_butspace(event, 1);
                }
                break;
        case F9KEY:
@@ -641,7 +521,7 @@ int blenderqread(unsigned short event, short val)
                        return 0;
                }
                else if(G.qual==0) {
-                       extern_set_butspace(event);
+                       extern_set_butspace(event, 1);
                }
                break;
        case F10KEY:
@@ -650,7 +530,7 @@ int blenderqread(unsigned short event, short val)
                        return 0;
                }
                else if(G.qual==0) {
-                       extern_set_butspace(event);
+                       extern_set_butspace(event, 1);
                }
                break;
        case F11KEY:
@@ -658,6 +538,9 @@ int blenderqread(unsigned short event, short val)
                        newspace(curarea, SPACE_TEXT);
                        return 0;
                }
+               else if (G.qual==LR_CTRLKEY) {
+                       playback_anim();
+               }
                else if(G.qual==0) {
                        BIF_toggle_render_display();
                        return 0;
@@ -672,6 +555,9 @@ int blenderqread(unsigned short event, short val)
                        newspace(curarea, SPACE_NLA);
                        return 0;
                }
+               else if (G.qual==LR_CTRLKEY) {
+                       BIF_do_render(1);
+               }
                else {
                        /* ctrl/alt + f12 should render too, for some macs have f12 assigned to cd eject */
                        BIF_do_render(0);
@@ -679,6 +565,23 @@ int blenderqread(unsigned short event, short val)
                return 0;
                break;
        
+       case WHEELUPMOUSE:
+               if(G.qual==LR_ALTKEY || G.qual==LR_COMMANDKEY) {
+                       if(CFRA>1) {
+                               CFRA--;
+                               update_for_newframe();
+                       }
+                       return 0;
+               }
+               break;
+       case WHEELDOWNMOUSE:
+               if(G.qual==LR_ALTKEY || G.qual==LR_COMMANDKEY) {
+                       CFRA++;
+                       update_for_newframe();
+                       return 0;
+               }
+               break;
+               
        case LEFTARROWKEY:
        case DOWNARROWKEY:
                if(textediting==0 && textspace==0) {
@@ -689,11 +592,11 @@ int blenderqread(unsigned short event, short val)
                                if (G.qual==LR_ALTKEY)
                                        mainwindow_toggle_fullscreen(0);
                                else if(G.qual==0)
-                                       CFRA-= 10;
+                                       CFRA-= G.scene->jumpframe;
                        }
 #else
                        if((event==DOWNARROWKEY)&&(G.qual==0))
-                               CFRA-= 10;
+                               CFRA-= G.scene->jumpframe;
 #endif
                        else if((event==LEFTARROWKEY)&&(G.qual==0))
                                CFRA--;
@@ -717,11 +620,11 @@ int blenderqread(unsigned short event, short val)
                                if(G.qual==LR_ALTKEY)
                                        mainwindow_toggle_fullscreen(1);
                                else if(G.qual==0)
-                                       CFRA+= 10;
+                                       CFRA+= G.scene->jumpframe;
                        }
 #else
                        if((event==UPARROWKEY)&&(G.qual==0))
-                               CFRA+= 10;
+                               CFRA+= G.scene->jumpframe;
 #endif
                        else if((event==RIGHTARROWKEY)&&(G.qual==0))
                                CFRA++;
@@ -749,14 +652,16 @@ int blenderqread(unsigned short event, short val)
                                        set_editflag_editipo();
                                else if(curarea->spacetype==SPACE_SEQ)
                                        enter_meta();
+                               else if(curarea->spacetype==SPACE_NODE)
+                                       return 1;
                                else if(G.vd) {
                                        /* also when Alt-E */
                                        if(G.obedit==NULL) {
-                                               enter_editmode();
+                                               enter_editmode(EM_WAITCURSOR);
                                                if(G.obedit) BIF_undo_push("Original"); // here, because all over code enter_editmode is abused
                                        }
                                        else
-                                               exit_editmode(2); // freedata, and undo
+                                               exit_editmode(EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); // freedata, and undo
                                }
                                return 0;
                        }
@@ -765,31 +670,17 @@ int blenderqread(unsigned short event, short val)
                        Object *ob= OBACT;
                        if(ob) {
                                if(ob->type==OB_ARMATURE) {
-                                       if(G.obpose) exit_posemode(1);
+                                       if(ob->flag & OB_POSEMODE) exit_posemode();
                                        else enter_posemode();
                                }
                                else if(ob->type==OB_MESH) {
                                        if(ob==G.obedit) EM_selectmode_menu();
+                                       else if(G.f & G_SCULPTMODE)
+                                               sculptmode_selectbrush_menu();
+                                       else set_wpaint();
                                }
                        }
                }
-               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();
-                       if(G.obpose)
-                               exit_posemode(1);
-               }
                break;
 
        case BACKSPACEKEY:
@@ -811,18 +702,19 @@ int blenderqread(unsigned short event, short val)
                if(G.qual==LR_ALTKEY) {
                        if(G.vd && textspace==0) {
                                if(G.obedit==0) {
-                                       enter_editmode();
+                                       enter_editmode(EM_WAITCURSOR);
                                        BIF_undo_push("Original");
                                }
                                else
-                                       exit_editmode(2); // freedata, and undo
+                                       exit_editmode(EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); // freedata, and undo
                                return 0;
                        }                       
                }
                break;
        case IKEY:
-               if(textediting==0 && textspace==0 && curarea->spacetype!=SPACE_FILE && curarea->spacetype!=SPACE_IMASEL) {
-                       if(G.qual==0) {
+               if(textediting==0 && textspace==0 && !ELEM3(curarea->spacetype, SPACE_FILE, SPACE_IMASEL, SPACE_NODE)) {
+                       if(G.f & G_SCULPTMODE) return 1;
+                       else if(G.qual==0) {
                                common_insertkey();
                                return 0;
                        }
@@ -830,7 +722,7 @@ int blenderqread(unsigned short event, short val)
                break;
        case JKEY:
                if(textediting==0 && textspace==0) {
-                       if(R.rectot && G.qual==0) {
+                       if (G.qual==0) {
                                BIF_swap_render_rects();
                                return 0;
                        }
@@ -858,14 +750,9 @@ int blenderqread(unsigned short event, short val)
        case OKEY:
                if(textediting==0) {
                        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. */
-                               sprintf(str, "Open file: %s", G.sce);
-                       
-                               if(okee(str)) {
-                                       strcpy(dir, G.sce);
-                                       BIF_read_file(dir);
+                               recentfile = recent_filelist();
+                               if(recentfile) {
+                                       BIF_read_file(recentfile);
                                }
                                return 0;
                        }
@@ -873,7 +760,7 @@ int blenderqread(unsigned short event, short val)
                break;
                
        case SKEY:
-               if(G.obpose==0 && G.obedit==0) {
+               if(G.obedit==NULL) {
                        if(G.qual==LR_CTRLKEY) {
                                strcpy(dir, G.sce);
                                if (untitled(dir)) {
@@ -889,26 +776,38 @@ int blenderqread(unsigned short event, short val)
        
        case TKEY:
                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 (event < 0) return 0; /* cancelled by user */
+
                        waitcursor(1);
                        
                        stime= PIL_check_seconds_timer();
                        for(a=0; a<100000; a++) {
-                               scrarea_do_windraw(curarea);
+                               if (event==1) {
+                                       scrarea_do_windraw(curarea);
+                               } 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("FPS: %f (%d iterations)", a/delta, a);
+                       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|displist|undo");
+                       int event= pupmenu("10 Timer%t|draw|draw+swap|undo");
                        if(event>0) {
                                double stime= PIL_check_seconds_timer();
                                char tmpstr[128];
@@ -922,22 +821,18 @@ int blenderqread(unsigned short event, short val)
                                        } else if (event==2) {
                                                scrarea_do_windraw(curarea);
                                                screen_swapbuffers();
-                                       } else if (event==3) {
-                                               if (OBACT) {
-                                                       makeDispList(OBACT);
-                                               }
                                        }
-                                       else if(event==4) {
-                                               BKE_write_undo("10 timer");
+                                       else if(event==3) {
+                                               BIF_undo();
+                                               BIF_redo();
                                        }
                                }
                        
-                               time= (PIL_check_seconds_timer()-stime)*1000;
+                               time= (int) ((PIL_check_seconds_timer()-stime)*1000);
                                
                                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);
+                               if(event==3) sprintf(tmpstr, "undo %%t|%d ms", time);
                        
                                waitcursor(0);
                                pupmenu(tmpstr);
@@ -978,6 +873,7 @@ int blenderqread(unsigned short event, short val)
                        }
                        else if(G.qual==LR_ALTKEY) {
                                write_videoscape_fs();
+                               return 0;
                        }
                }
                break;
@@ -986,9 +882,6 @@ int blenderqread(unsigned short event, short val)
                if(textspace==0 && textediting==0) {
                        if(G.qual==LR_CTRLKEY) {
                                if(okee("Erase all")) {
-                                       strcpy(G.sce, BLI_gethome());
-                                       strcat(G.sce, "/untitled.blend");
-                                       BLI_clean(G.sce);
                                        if( BIF_read_homefile()==0) error("No file ~/.B.blend");
                                }
                                return 0;