Bugfix #4741
[blender.git] / source / blender / src / toets.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31
32  *
33  *
34  * General blender hot keys (toets = dutch), special hotkeys are in space.c
35  *
36  */
37
38 #include <string.h>
39 #include <math.h>
40
41 #ifdef WIN32
42 #include "BLI_winstuff.h"
43 #endif
44
45 #include "MEM_guardedalloc.h"
46
47 #include "PIL_time.h"
48
49 #include "nla.h"        /* Only for the #ifdef flag - To be removed later */
50
51 #include "BLI_blenlib.h"
52 #include "BLI_arithb.h"
53
54 #include "DNA_object_types.h"
55 #include "DNA_screen_types.h"
56 #include "DNA_scene_types.h"
57 #include "DNA_space_types.h"
58 #include "DNA_view3d_types.h"
59 #include "DNA_userdef_types.h"
60
61 #include "BKE_action.h"
62 #include "BKE_anim.h"
63 #include "BKE_blender.h"
64 #include "BKE_depsgraph.h"
65 #include "BKE_displist.h"
66 #include "BKE_global.h"
67 #include "BKE_image.h"
68 #include "BKE_ipo.h"
69 #include "BKE_key.h"
70 #include "BKE_scene.h"
71 #include "BKE_utildefines.h"
72
73 #include "BIF_butspace.h"
74 #include "BIF_editseq.h"
75 #include "BIF_editsound.h"
76 #include "BIF_editmesh.h"
77 #include "BIF_interface.h"
78 #include "BKE_object.h"
79 #include "BIF_poseobject.h"
80 #include "BIF_previewrender.h"
81 #include "BIF_renderwin.h"
82 #include "BIF_screen.h"
83 #include "BIF_space.h"
84 #include "BIF_toets.h"
85 #include "BIF_toolbox.h"
86 #include "BIF_usiblender.h"
87 #include "BIF_writeimage.h"
88
89 #include "BDR_vpaint.h"
90 #include "BDR_editobject.h"
91 #include "BDR_editface.h"
92
93 #include "BSE_filesel.h"        /* For activate_fileselect */
94 #include "BSE_drawview.h"       /* For play_anim */
95 #include "BSE_view.h"
96 #include "BSE_edit.h"
97 #include "BSE_editipo.h"
98 #include "BSE_headerbuttons.h"
99 #include "BSE_seqaudio.h"
100
101 #include "blendef.h"
102
103 #include "IMB_imbuf.h"
104 #include "IMB_imbuf_types.h"
105
106 #include "mydevice.h"
107
108 #include "BIF_poseobject.h"
109
110 /* ------------------------------------------------------------------------- */
111
112 static int is_an_active_object(void *ob) {
113         Base *base;
114         
115         for (base= FIRSTBASE; base; base= base->next)
116                 if (base->object == ob)
117                         return 1;
118         
119         return 0;
120 }
121
122 void persptoetsen(unsigned short event)
123 {
124         static Object *oldcamera=0;
125         float phi, si, q1[4], vec[3];
126         static int perspo=1;
127         int preview3d_event= 1;
128         
129         if(event==PADENTER) {
130                 if (G.qual == LR_SHIFTKEY) {
131                         view3d_set_1_to_1_viewborder(G.vd);
132                 } else {
133                         if (G.vd->persp==2) {
134                                 G.vd->camzoom= 0;
135                         } else {
136                                 G.vd->dist= 10.0;
137                         }
138                 }
139         }
140         else if((G.qual & (LR_SHIFTKEY | LR_CTRLKEY)) && (event != PAD0)) {
141                 
142                 /* indicate that this view is inverted */
143                 G.vd->flag2 |= V3D_OPP_DIRECTION_NAME;
144                 
145                 if(event==PAD0) {
146                         /* G.vd->persp= 3; */
147                 }
148                 else if(event==PAD7) {
149                         G.vd->viewquat[0]= 0.0;
150                         G.vd->viewquat[1]= -1.0;
151                         G.vd->viewquat[2]= 0.0;
152                         G.vd->viewquat[3]= 0.0;
153                         G.vd->view= 7;
154                         if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0; 
155                         else if(G.vd->persp>=2) G.vd->persp= perspo;
156                 }
157                 else if(event==PAD1) {
158                         G.vd->viewquat[0]= 0.0;
159                         G.vd->viewquat[1]= 0.0;
160                         G.vd->viewquat[2]= (float)-cos(M_PI/4.0);
161                         G.vd->viewquat[3]= (float)-cos(M_PI/4.0);
162                         G.vd->view=1;
163                         if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
164                         else if(G.vd->persp>=2) G.vd->persp= perspo;
165                 }
166                 else if(event==PAD3) {
167                         G.vd->viewquat[0]= 0.5;
168                         G.vd->viewquat[1]= -0.5;
169                         G.vd->viewquat[2]= 0.5;
170                         G.vd->viewquat[3]= 0.5;
171                         G.vd->view=3;
172                         if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
173                         else if(G.vd->persp>=2) G.vd->persp= perspo;
174                 }
175                 else if(event==PADMINUS) {
176                         /* this min and max is also in viewmove() */
177                         if(G.vd->persp==2) {
178                                 G.vd->camzoom-= 10;
179                                 if(G.vd->camzoom<-30) G.vd->camzoom= -30;
180                         }
181                         else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2f;
182                 }
183                 else if(event==PADPLUSKEY) {
184                         if(G.vd->persp==2) {
185                                 G.vd->camzoom+= 10;
186                                 if(G.vd->camzoom>300) G.vd->camzoom= 300;
187                         }
188                         else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333f;
189                 }
190                 else {
191
192                         initgrabz(0.0, 0.0, 0.0);
193                         
194                         if(event==PAD6) window_to_3d(vec, -32, 0);
195                         else if(event==PAD4) window_to_3d(vec, 32, 0);
196                         else if(event==PAD8) window_to_3d(vec, 0, -25);
197                         else if(event==PAD2) window_to_3d(vec, 0, 25);
198                         G.vd->ofs[0]+= vec[0];
199                         G.vd->ofs[1]+= vec[1];
200                         G.vd->ofs[2]+= vec[2];
201                 }
202         }
203         else {
204                 /* indicate that this view is not inverted */
205                 G.vd->flag2 &= ~V3D_OPP_DIRECTION_NAME;
206
207                 if(event==PAD7) {
208                         G.vd->viewquat[0]= 1.0;
209                         G.vd->viewquat[1]= 0.0;
210                         G.vd->viewquat[2]= 0.0;
211                         G.vd->viewquat[3]= 0.0;
212                         G.vd->view=7;
213                         if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
214                         else if(G.vd->persp>=2) G.vd->persp= perspo;
215                 }
216                 else if(event==PAD1) {
217                         G.vd->viewquat[0]= (float)cos(M_PI/4.0);
218                         G.vd->viewquat[1]= (float)-sin(M_PI/4.0);
219                         G.vd->viewquat[2]= 0.0;
220                         G.vd->viewquat[3]= 0.0;
221                         G.vd->view=1;
222                         if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
223                         else if(G.vd->persp>=2) G.vd->persp= perspo;
224                 }
225                 else if(event==PAD3) {
226                         G.vd->viewquat[0]= 0.5;
227                         G.vd->viewquat[1]= -0.5;
228                         G.vd->viewquat[2]= -0.5;
229                         G.vd->viewquat[3]= -0.5;
230                         G.vd->view=3;
231                         if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
232                         else if(G.vd->persp>=2) G.vd->persp= perspo;
233                 }
234                 else if(event==PADMINUS) {
235                         /* this min and max is also in viewmove() */
236                         if(G.vd->persp==2) {
237                                 G.vd->camzoom= MAX2(-30, G.vd->camzoom-5);
238                         }
239                         else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2f;
240                         if(G.vd->persp!=1) preview3d_event= 0;
241                 }
242                 else if(event==PADPLUSKEY) {
243                         if(G.vd->persp==2) {
244                                 G.vd->camzoom= MIN2(300, G.vd->camzoom+5);
245                         }
246                         else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333f;
247                         if(G.vd->persp!=1) preview3d_event= 0;
248                 }
249                 else if(event==PAD5) {
250                         if(G.vd->persp==1) G.vd->persp=0;
251                         else G.vd->persp=1;
252                 }
253                 else if(event==PAD0) {
254                         if(G.qual==LR_ALTKEY) {
255                                 if(oldcamera && is_an_active_object(oldcamera)) {
256                                         G.vd->camera= oldcamera;
257                                 }
258                                 
259                                 handle_view3d_lock();
260                         }
261                         else if(BASACT) {
262                                 /* check both G.vd as G.scene cameras */
263                                 if(G.qual==LR_CTRLKEY) {
264                                         if(G.vd->camera != OBACT || G.scene->camera != OBACT) {
265                                                 if(G.vd->camera && G.vd->camera->type==OB_CAMERA)
266                                                         oldcamera= G.vd->camera;
267                                                 
268                                                 G.vd->camera= OBACT;
269                                                 handle_view3d_lock();
270                                         }
271                                 }
272                                 else if((G.vd->camera==NULL || G.scene->camera==NULL) && OBACT->type==OB_CAMERA) {
273                                         G.vd->camera= OBACT;
274                                         handle_view3d_lock();
275                                 }
276                         }
277                         if(G.vd->camera==0) {
278                                 G.vd->camera= scene_find_camera(G.scene);
279                                 handle_view3d_lock();
280                         }
281                         
282                         if(G.vd->camera) {
283                                 G.vd->persp= 2;
284                                 G.vd->view= 0;
285                                 if(((G.qual & LR_CTRLKEY) && (G.qual & LR_ALTKEY)) || (G.qual & LR_SHIFTKEY)) {
286                                         void setcameratoview3d(void);   // view.c
287                                         setcameratoview3d();
288                                         DAG_object_flush_update(G.scene, G.scene->camera, OB_RECALC_OB);
289                                         BIF_undo_push("View to Camera position");
290                                         allqueue(REDRAWVIEW3D, 0);
291                                 }                               
292                         }
293                 }
294                 else if(event==PAD9) {
295                         countall();
296                         update_for_newframe();
297                         
298                         reset_slowparents();    /* editobject.c */
299                 }
300                 else if(G.vd->persp<2) {
301                         if(event==PAD4 || event==PAD6) {
302                                 /* z-axis */
303                                 phi= (float)(M_PI/24.0);
304                                 if(event==PAD6) phi= -phi;
305                                 si= (float)sin(phi);
306                                 q1[0]= (float)cos(phi);
307                                 q1[1]= q1[2]= 0.0;
308                                 q1[3]= si;
309                                 QuatMul(G.vd->viewquat, G.vd->viewquat, q1);
310                                 G.vd->view= 0;
311                         }
312                         if(event==PAD2 || event==PAD8) {
313                                 
314                                 /* horizontal axis */
315                                 VECCOPY(q1+1, G.vd->viewinv[0]);
316                                 
317                                 Normalise(q1+1);
318                                 phi= (float)(M_PI/24.0);
319                                 if(event==PAD2) phi= -phi;
320                                 si= (float)sin(phi);
321                                 q1[0]= (float)cos(phi);
322                                 q1[1]*= si;
323                                 q1[2]*= si;
324                                 q1[3]*= si;
325                                 QuatMul(G.vd->viewquat, G.vd->viewquat, q1);
326                                 G.vd->view= 0;
327                         }
328                 }
329
330                 if(G.vd->persp<2) perspo= G.vd->persp;
331         }
332         
333         if(preview3d_event) 
334                 BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
335         else
336                 BIF_view3d_previewrender_signal(curarea, PR_PROJECTED);
337
338         scrarea_queue_redraw(curarea);
339 }
340
341 int untitled(char * name)
342 {
343         if (G.save_over == 0 ) {
344                 char * c= BLI_last_slash(name);
345                 
346                 if (c)
347                         strcpy(&c[1], "untitled.blend");
348                 else
349                         strcpy(name, "untitled.blend");
350                         
351                 return(TRUE);
352         }
353         
354         return(FALSE);
355 }
356
357 char *recent_filelist(void)
358 {
359         struct RecentFile *recent;
360         int event, i, ofs;
361         char pup[2048], *p;
362
363         p= pup + sprintf(pup, "Open Recent%%t");
364         
365         if (G.sce[0]) {
366                 p+= sprintf(p, "|%s %%x%d", G.sce, 1);
367                 ofs = 1;
368         } else ofs = 0;
369
370         for (recent = G.recent_files.first, i=0; (i<10) && (recent); recent = recent->next, i++) {
371                 if (strcmp(recent->filename, G.sce)) {
372                         p+= sprintf(p, "|%s %%x%d", recent->filename, i+ofs+1);
373                 }
374         }
375         event= pupmenu(pup);
376         if(event>0) {
377                 if (ofs && (event==1))
378                         return(G.sce);
379                 else
380                         recent = BLI_findlink(&(G.recent_files), event-1-ofs);
381                         if(recent) return(recent->filename);
382         }
383         
384         return(NULL);
385 }
386
387 int blenderqread(unsigned short event, short val)
388 {
389         /* here do the general keys handling (not screen/window/space) */
390         /* return 0: do not pass on to the other queues */
391         extern int textediting;
392         extern void playback_anim();
393         ScrArea *sa;
394         Object *ob;
395         int textspace=0;
396         /* Changed str and dir size to 160, to make sure there is enough
397          * space for filenames. */
398         char dir[FILE_MAXDIR * 2], str[FILE_MAXFILE * 2];
399         char *recentfile;
400         
401         if(val==0) return 1;
402         if(event==MOUSEY || event==MOUSEX) return 1;
403         if (G.flags & G_FILE_AUTOPLAY) return 1;
404
405         if (curarea && curarea->spacetype==SPACE_TEXT) textspace= 1;
406         else if (curarea && curarea->spacetype==SPACE_SCRIPT) textspace= 1;
407
408         switch(event) {
409
410         case F1KEY:
411                 if(G.qual==0) {
412                         /* this exception because of the '?' button */
413                         if(curarea->spacetype==SPACE_INFO) {
414                                 sa= closest_bigger_area();
415                                 areawinset(sa->win);
416                         }
417                         
418                         activate_fileselect(FILE_BLENDER, "Open File", G.sce, BIF_read_file);
419                         return 0;
420                 }
421                 else if(G.qual==LR_SHIFTKEY) {
422                         activate_fileselect(FILE_LOADLIB, "Load Library", G.lib, 0);
423                         return 0;
424                 }
425                 break;
426         case F2KEY:
427                 if(G.qual==0) {
428                         strcpy(dir, G.sce);
429                         untitled(dir);
430                         activate_fileselect(FILE_BLENDER, "Save File", dir, BIF_write_file);
431                         return 0;
432                 }
433                 else if(G.qual==LR_CTRLKEY) {
434                         write_vrml_fs();
435                         return 0;
436                 }
437                 else if(G.qual==LR_SHIFTKEY) {
438                         write_dxf_fs();
439                         return 0;
440                 }
441                 break;
442         case F3KEY:
443                 if(G.qual==0) {
444                         BIF_save_rendered_image_fs(0);
445                         return 0;
446                 }
447                 else if(G.qual & LR_CTRLKEY) {
448                         BIF_screendump(0);
449                 }
450                 else if(G.qual & LR_SHIFTKEY) {
451                         BIF_save_rendered_image_fs(1);
452                 }
453                 break;
454         case F4KEY:
455                 if(G.qual==LR_SHIFTKEY) {
456
457                         memset(str, 0, 16);
458                         ob= OBACT;
459                         if(ob) strcpy(str, ob->id.name);
460
461                         activate_fileselect(FILE_MAIN, "Data Select", str, 0);
462                         return 0;
463                 }
464                 else if(G.qual==0) {
465                         extern_set_butspace(event, 1);
466                 }
467                 break;
468         case F5KEY:
469                 if(G.qual==LR_SHIFTKEY) {
470                         newspace(curarea, SPACE_VIEW3D);
471                         return 0;
472                 }
473                 else if(G.qual==0) {
474                         extern_set_butspace(event, 1);
475                 }
476                 break;
477         case F6KEY:
478                 if(G.qual==LR_SHIFTKEY) {
479                         newspace(curarea, SPACE_IPO);
480                         return 0;
481                 }
482                 else if(G.qual==0) {
483                         extern_set_butspace(event, 1);
484                 }
485                 break;
486         case F7KEY:
487                 if(G.qual==LR_SHIFTKEY) {
488                         newspace(curarea, SPACE_BUTS);
489                         return 0;
490                 }
491                 else if(G.qual==0) {
492                         extern_set_butspace(event, 1);
493                 }
494                 break;
495         case F8KEY:
496                 if(G.qual==LR_SHIFTKEY) {
497                         newspace(curarea, SPACE_SEQ);
498                         return 0;
499                 }
500                 else if(G.qual==0) {
501                         extern_set_butspace(event, 1);
502                 }
503                 break;
504         case F9KEY:
505                 if(G.qual==LR_SHIFTKEY) {
506                         newspace(curarea, SPACE_OOPS);
507                         return 0;
508                 }
509                 else if(G.qual==(LR_SHIFTKEY|LR_ALTKEY)) {
510                         newspace(curarea, SPACE_OOPS+256);
511                         return 0;
512                 }
513                 else if(G.qual==0) {
514                         extern_set_butspace(event, 1);
515                 }
516                 break;
517         case F10KEY:
518                 if(G.qual==LR_SHIFTKEY) {
519                         newspace(curarea, SPACE_IMAGE);
520                         return 0;
521                 }
522                 else if(G.qual==0) {
523                         extern_set_butspace(event, 1);
524                 }
525                 break;
526         case F11KEY:
527                 if(G.qual==LR_SHIFTKEY) {
528                         newspace(curarea, SPACE_TEXT);
529                         return 0;
530                 }
531                 else if (G.qual==LR_CTRLKEY) {
532                         playback_anim();
533                 }
534                 else if(G.qual==0) {
535                         BIF_toggle_render_display();
536                         return 0;
537                 }
538                 break;
539         case F12KEY:
540                 if(G.qual==LR_SHIFTKEY) {
541                         newspace(curarea, SPACE_ACTION);
542                         return 0;
543                 }
544                 else if (G.qual==(LR_SHIFTKEY|LR_CTRLKEY)) {
545                         newspace(curarea, SPACE_NLA);
546                         return 0;
547                 }
548                 else if (G.qual==LR_CTRLKEY) {
549                         BIF_do_render(1);
550                 }
551                 else {
552                         /* ctrl/alt + f12 should render too, for some macs have f12 assigned to cd eject */
553                         BIF_do_render(0);
554                 }
555                 return 0;
556                 break;
557         
558         case WHEELUPMOUSE:
559                 if(G.qual==LR_ALTKEY || G.qual==LR_COMMANDKEY) {
560                         if(CFRA>1) {
561                                 CFRA--;
562                                 update_for_newframe();
563                         }
564                         return 0;
565                 }
566                 break;
567         case WHEELDOWNMOUSE:
568                 if(G.qual==LR_ALTKEY || G.qual==LR_COMMANDKEY) {
569                         CFRA++;
570                         update_for_newframe();
571                         return 0;
572                 }
573                 break;
574                 
575         case LEFTARROWKEY:
576         case DOWNARROWKEY:
577                 if(textediting==0 && textspace==0) {
578
579 #if 0
580 //#ifdef _WIN32 // FULLSCREEN
581                         if(event==DOWNARROWKEY){
582                                 if (G.qual==LR_ALTKEY)
583                                         mainwindow_toggle_fullscreen(0);
584                                 else if(G.qual==0)
585                                         CFRA-= G.scene->jumpframe;
586                         }
587 #else
588                         if((event==DOWNARROWKEY)&&(G.qual==0))
589                                 CFRA-= G.scene->jumpframe;
590 #endif
591                         else if((event==LEFTARROWKEY)&&(G.qual==0))
592                                 CFRA--;
593                         
594                         if(G.qual==LR_SHIFTKEY)
595                                 CFRA= SFRA;
596                         if(CFRA<1) CFRA=1;
597         
598                         update_for_newframe();
599                         return 0;
600                 }
601                 break;
602
603         case RIGHTARROWKEY:
604         case UPARROWKEY:
605                 if(textediting==0 && textspace==0) {
606
607 #if 0
608 //#ifdef _WIN32 // FULLSCREEN
609                         if(event==UPARROWKEY){ 
610                                 if(G.qual==LR_ALTKEY)
611                                         mainwindow_toggle_fullscreen(1);
612                                 else if(G.qual==0)
613                                         CFRA+= G.scene->jumpframe;
614                         }
615 #else
616                         if((event==UPARROWKEY)&&(G.qual==0))
617                                 CFRA+= G.scene->jumpframe;
618 #endif
619                         else if((event==RIGHTARROWKEY)&&(G.qual==0))
620                                 CFRA++;
621
622                         if(G.qual==LR_SHIFTKEY)
623                                 CFRA= EFRA;
624                         
625                         update_for_newframe();
626                 }
627                 break;
628
629         case ESCKEY:
630                 sound_stop_all_sounds();        // whats this?
631                 
632                 /* stop playback on ESC always */
633                 rem_screenhandler(G.curscreen, SCREEN_HANDLER_ANIM);
634                 audiostream_stop();
635                 allqueue(REDRAWALL, 0);
636                 
637                 break;
638         case TABKEY:
639                 if(G.qual==0) {
640                         if(textspace==0) {
641                                 if(curarea->spacetype==SPACE_IPO)
642                                         set_editflag_editipo();
643                                 else if(curarea->spacetype==SPACE_SEQ)
644                                         enter_meta();
645                                 else if(curarea->spacetype==SPACE_NODE)
646                                         return 1;
647                                 else if(G.vd) {
648                                         /* also when Alt-E */
649                                         if(G.obedit==NULL) {
650                                                 enter_editmode();
651                                                 if(G.obedit) BIF_undo_push("Original"); // here, because all over code enter_editmode is abused
652                                         }
653                                         else
654                                                 exit_editmode(2); // freedata, and undo
655                                 }
656                                 return 0;
657                         }
658                 }
659                 else if(G.qual==LR_CTRLKEY){
660                         Object *ob= OBACT;
661                         if(ob) {
662                                 if(ob->type==OB_ARMATURE) {
663                                         if(ob->flag & OB_POSEMODE) exit_posemode();
664                                         else enter_posemode();
665                                 }
666                                 else if(ob->type==OB_MESH) {
667                                         if(ob==G.obedit) EM_selectmode_menu();
668                                         else set_wpaint();
669                                 }
670                         }
671                 }
672                 else if(G.qual==LR_SHIFTKEY) {  // ??
673                         if(G.obedit)
674                                 exit_editmode(2); // freedata, and undo
675                         if(G.f & G_FACESELECT)
676                                 set_faceselect();
677                         if(G.f & G_VERTEXPAINT)
678                                 set_vpaint();
679                         if(G.f & G_TEXTUREPAINT) {
680                                 G.f &= ~G_TEXTUREPAINT;
681                                 allqueue(REDRAWVIEW3D, 0);
682                                 allqueue(REDRAWBUTSEDIT, 0);
683                         }
684                         if(G.f & G_WEIGHTPAINT)
685                                 set_wpaint();
686                 }
687                 break;
688
689         case BACKSPACEKEY:
690                 break;
691
692         case AKEY:
693                 if(textediting==0 && textspace==0) {
694                         if(G.qual==(LR_SHIFTKEY|LR_ALTKEY)){
695                                 play_anim(1);
696                                 return 0;
697                         }
698                         else if(G.qual==LR_ALTKEY) {
699                                 play_anim(0);
700                                 return 0;
701                         }
702                 }
703                 break;
704         case EKEY:
705                 if(G.qual==LR_ALTKEY) {
706                         if(G.vd && textspace==0) {
707                                 if(G.obedit==0) {
708                                         enter_editmode();
709                                         BIF_undo_push("Original");
710                                 }
711                                 else
712                                         exit_editmode(2); // freedata, and undo
713                                 return 0;
714                         }                       
715                 }
716                 break;
717         case IKEY:
718                 if(textediting==0 && textspace==0 && curarea->spacetype!=SPACE_FILE && curarea->spacetype!=SPACE_IMASEL) {
719                         if(G.qual==0) {
720                                 common_insertkey();
721                                 return 0;
722                         }
723                 }
724                 break;
725         case JKEY:
726                 if(textediting==0 && textspace==0) {
727                         if (G.qual==0) {
728                                 BIF_swap_render_rects();
729                                 return 0;
730                         }
731                 }
732                 break;
733
734         case NKEY:
735                 if(textediting==0 && textspace==0) {
736                         if(G.qual & LR_CTRLKEY);
737                         else if(G.qual==0 || (G.qual & LR_SHIFTKEY)) {
738                                 if(curarea->spacetype==SPACE_VIEW3D);           // is new panel, in view3d queue
739                                 else if(curarea->spacetype==SPACE_IPO);                 // is new panel, in ipo queue
740                                 else if(curarea->spacetype==SPACE_IMAGE);                       // is new panel, in ipo queue
741                                 else if(curarea->spacetype==SPACE_ACTION);                      // is own queue
742                                 else if(curarea->spacetype==SPACE_NLA);                 // is new panel
743                                 else if(curarea->spacetype==SPACE_SEQ);                 // is new panel
744                                 else {
745                                         clever_numbuts();
746                                         return 0;
747                                 }
748                         }
749                 }
750                 break;
751                 
752         case OKEY:
753                 if(textediting==0) {
754                         if(G.qual==LR_CTRLKEY) {
755                                 recentfile = recent_filelist();
756                                 if(recentfile) {
757                                         BIF_read_file(recentfile);
758                                 }
759                                 return 0;
760                         }
761                 }
762                 break;
763                 
764         case SKEY:
765                 if(G.obedit==NULL) {
766                         if(G.qual==LR_CTRLKEY) {
767                                 strcpy(dir, G.sce);
768                                 if (untitled(dir)) {
769                                         activate_fileselect(FILE_BLENDER, "Save File", dir, BIF_write_file);
770                                 } else {
771                                         BIF_write_file(dir);
772                                         free_filesel_spec(dir);
773                                 }
774                                 return 0;
775                         }
776                 }
777                 break;
778         
779         case TKEY:
780                 if (G.qual==(LR_SHIFTKEY|LR_ALTKEY|LR_CTRLKEY)) {
781                         Object *ob = OBACT;
782                         int event = pupmenu(ob?"Time%t|draw|recalc ob|recalc data":"Time%t|draw");
783                         int a;
784                         double delta, stime;
785
786                         if (event < 0) return 0; /* cancelled by user */
787
788                         waitcursor(1);
789                         
790                         stime= PIL_check_seconds_timer();
791                         for(a=0; a<100000; a++) {
792                                 if (event==1) {
793                                         scrarea_do_windraw(curarea);
794                                 } else if (event==2) {
795                                         ob->recalc |= OB_RECALC_OB;
796                                         object_handle_update(ob);
797                                 } else if (event==3) {
798                                         ob->recalc |= OB_RECALC_DATA;
799                                         object_handle_update(ob);
800                                 }
801
802                                 delta= PIL_check_seconds_timer()-stime;
803                                 if (delta>5.0) break;
804                         }
805                         
806                         waitcursor(0);
807                         notice("%8.6f s/op - %6.2f ops/s - %d iterations", delta/a, a/delta, a);
808                         return 0;
809                 }
810                 else if(G.qual==(LR_ALTKEY|LR_CTRLKEY)) {
811                         int a;
812                         int event= pupmenu("10 Timer%t|draw|draw+swap|undo");
813                         if(event>0) {
814                                 double stime= PIL_check_seconds_timer();
815                                 char tmpstr[128];
816                                 int time;
817
818                                 waitcursor(1);
819                                 
820                                 for(a=0; a<10; a++) {
821                                         if (event==1) {
822                                                 scrarea_do_windraw(curarea);
823                                         } else if (event==2) {
824                                                 scrarea_do_windraw(curarea);
825                                                 screen_swapbuffers();
826                                         }
827                                         else if(event==3) {
828                                                 BIF_undo();
829                                                 BIF_redo();
830                                         }
831                                 }
832                         
833                                 time= (int) ((PIL_check_seconds_timer()-stime)*1000);
834                                 
835                                 if(event==1) sprintf(tmpstr, "draw %%t|%d ms", time);
836                                 if(event==2) sprintf(tmpstr, "d+sw %%t|%d ms", time);
837                                 if(event==3) sprintf(tmpstr, "undo %%t|%d ms", time);
838                         
839                                 waitcursor(0);
840                                 pupmenu(tmpstr);
841
842                         }
843                         return 0;
844                 }
845                 break;
846                                 
847         case UKEY:
848                 if(textediting==0) {
849                         if(G.qual==LR_CTRLKEY) {
850                                 if(okee("Save user defaults")) {
851                                         BIF_write_homefile();
852                                 }
853                                 return 0;
854                         }
855                         else if(G.qual==LR_ALTKEY) {
856                                 if(curarea->spacetype!=SPACE_TEXT) {
857                                         BIF_undo_menu();
858                                         return 0;
859                                 }
860                         }
861                 }
862                 break;
863                 
864         case WKEY:
865                 if(textediting==0) {
866                         if(G.qual==LR_CTRLKEY) {
867                                 strcpy(dir, G.sce);
868                                 if (untitled(dir)) {
869                                         activate_fileselect(FILE_BLENDER, "Save File", dir, BIF_write_file);
870                                 } else {
871                                         BIF_write_file(dir);
872                                         free_filesel_spec(dir);
873                                 }
874                                 return 0;
875                         }
876                         else if(G.qual==LR_ALTKEY) {
877                                 write_videoscape_fs();
878                                 return 0;
879                         }
880                 }
881                 break;
882                 
883         case XKEY:
884                 if(textspace==0 && textediting==0) {
885                         if(G.qual==LR_CTRLKEY) {
886                                 if(okee("Erase all")) {
887                                         if( BIF_read_homefile()==0) error("No file ~/.B.blend");
888                                 }
889                                 return 0;
890                         }
891                 }
892                 break;
893         case YKEY:      // redo alternative
894                 if(textspace==0) {
895                         if(G.qual==LR_CTRLKEY) {
896                                 BIF_redo(); 
897                                 return 0;
898                         }
899                 }
900                 break;
901         case ZKEY:      // undo
902                 if(textspace==0) {
903                         if(G.qual & (LR_CTRLKEY|LR_COMMANDKEY)) { // all combos with ctrl/commandkey are accepted
904                                 if ELEM(G.qual, LR_CTRLKEY, LR_COMMANDKEY) BIF_undo();
905                                 else BIF_redo(); // all combos with ctrl is redo
906                                 return 0;
907                         }
908                 }
909                 break; 
910         }
911         
912         return 1;
913 }
914
915 /* eof */