- another huge commit! read this!
[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 HAVE_CONFIG_H
42 #include <config.h>
43 #endif
44
45 #ifdef WIN32
46 #include "BLI_winstuff.h"
47 #endif
48
49 #include "MEM_guardedalloc.h"
50
51 #include "PIL_time.h"
52
53 #include "nla.h"        /* Only for the #ifdef flag - To be removed later */
54
55 #include "BLI_blenlib.h"
56 #include "BLI_arithb.h"
57 #include "BLI_editVert.h"
58
59 #include "DNA_object_types.h"
60 #include "DNA_screen_types.h"
61 #include "DNA_space_types.h"
62 #include "DNA_view3d_types.h"
63
64 #include "BKE_utildefines.h"
65 #include "BKE_global.h"
66 #include "BKE_anim.h"
67 #include "BKE_scene.h"
68 #include "BKE_ipo.h"
69 #include "BKE_action.h"
70 #include "BKE_ika.h"
71 #include "BKE_key.h"
72
73 #include "BIF_interface.h"
74 #include "BIF_screen.h"
75 #include "BIF_space.h"
76 #include "BIF_butspace.h"
77 #include "BIF_renderwin.h"
78 #include "BIF_toolbox.h"
79 #include "BIF_toets.h"
80 #include "BIF_editseq.h"
81 #include "BIF_editsound.h"
82 #include "BIF_poseobject.h"
83 #include "BIF_usiblender.h"
84
85 #include "BDR_vpaint.h"
86 #include "BDR_editobject.h"
87 #include "BDR_editface.h"
88
89 #include "BSE_filesel.h"        /* For activate_fileselect */
90 #include "BSE_drawview.h"       /* For play_anim */
91 #include "BSE_view.h"
92 #include "BSE_edit.h"
93 #include "BSE_editipo.h"
94 #include "BSE_headerbuttons.h"
95
96 #include "blendef.h"
97 #include "interface.h"
98 #include "render.h"
99
100 #include "IMB_imbuf.h"
101 #include "IMB_imbuf_types.h"
102
103 #include "mydevice.h"
104
105 #include "BIF_poseobject.h"
106
107 /* only used in toets.c */
108 /* this function doesn't really belong here */
109 /* ripped from render module */
110 void schrijfplaatje(char *name);
111
112
113 void write_imag(char *name)
114 {
115         /* from file select */
116         char str[256];
117
118         strcpy(str, name);
119         BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
120
121         if(saveover(str)) {
122                 if(BLI_testextensie(str,".blend")) {
123                         error("Wrong filename");
124                         return;
125                 }
126                 waitcursor(1); /* from screen.c */
127                 schrijfplaatje(str);
128                 strcpy(G.ima, name);
129                 waitcursor(0);
130         }
131 }
132
133
134 /* From matrix.h: it's really a [4][4]! */
135 /* originally in initrender... maybe add fileControl thingy? */
136
137 /* should be called write_image(char *name) :-) */
138 void schrijfplaatje(char *name)
139 {
140         struct ImBuf *ibuf=0;
141         unsigned int *temprect=0;
142         char str[FILE_MAXDIR+FILE_MAXFILE];
143
144         /* has RGBA been set? If so: use alpha channel for color zero */
145         IMB_alpha_to_col0(FALSE);
146
147         if(R.r.planes == 32) {
148                 /* everything with less than 50 % alpha -> col 0 */
149                 if(R.r.alphamode == R_ALPHAKEY) IMB_alpha_to_col0(2);
150                 /* only when 0 alpha -> col 0 */
151                 else IMB_alpha_to_col0(1);
152         }
153
154         /* Seems to me this is also superfluous.... */
155         if (R.r.imtype==R_FTYPE) {
156                 strcpy(str, R.r.ftype);
157                 BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
158
159                 ibuf = IMB_loadiffname(str, IB_test);
160                 if(ibuf) {
161                         ibuf->x = R.rectx;
162                         ibuf->y = R.recty;
163                 }
164                 else {
165                         error("Can't find filetype");
166                         G.afbreek= 1;
167                         return;
168                 }
169                 /* setdither(2); */
170         }
171
172         if(ibuf == 0) {
173                 ibuf= IMB_allocImBuf(R.rectx, R.recty, R.r.planes, 0, 0);
174         }
175
176         if(ibuf) {
177                 ibuf->rect= (unsigned int *) R.rectot;
178
179                 if(R.r.planes == 8) IMB_cspace(ibuf, rgb_to_bw);
180
181                 if(R.r.imtype== R_IRIS) {
182                         ibuf->ftype= IMAGIC;
183                 }
184                 else if(R.r.imtype==R_IRIZ) {
185                         ibuf->ftype= IMAGIC;
186                         if (ibuf->zbuf == 0) {
187                                 if (R.rectz) {
188                                         ibuf->zbuf = (int *)R.rectz;
189                                 }
190                                 else printf("no zbuf\n");
191                         }
192                 }
193                 else if(R.r.imtype==R_PNG) {
194                         ibuf->ftype= PNG;
195                 }
196                 else if((R.r.imtype==R_TARGA) || (R.r.imtype==R_PNG)) {
197                         ibuf->ftype= TGA;
198                 }
199                 else if(R.r.imtype==R_RAWTGA) {
200                         ibuf->ftype= RAWTGA;
201                 }
202                 else if(R.r.imtype==R_HAMX) {
203                         /* make copy */
204                         temprect= MEM_dupallocN(R.rectot);
205                         ibuf->ftype= AN_hamx;
206                 }
207                 else if(ELEM5(R.r.imtype, R_MOVIE, R_AVICODEC, R_AVIRAW, R_AVIJPEG, R_JPEG90)) {
208                         if(R.r.quality < 10) R.r.quality= 90;
209
210                         if(R.r.mode & R_FIELDS) ibuf->ftype= JPG_VID|R.r.quality;
211                         else ibuf->ftype= JPG|R.r.quality;
212                 }
213         
214                 RE_make_existing_file(name);
215
216                 if(IMB_saveiff(ibuf, name, IB_rect | IB_zbuf)==0) {
217                         perror(name);
218                         G.afbreek= 1;
219                 }
220
221                 IMB_freeImBuf(ibuf);
222
223                 if (R.r.imtype==R_HAMX) {
224                         MEM_freeN(R.rectot);
225                         R.rectot= temprect;
226                 }
227         }
228         else {
229                 G.afbreek= 1;
230         }
231 }
232
233
234
235 /* ------------------------------------------------------------------------- */
236
237 static int is_an_active_object(void *ob) {
238         Base *base;
239         
240         for (base= FIRSTBASE; base; base= base->next)
241                 if (base->object == ob)
242                         return 1;
243         
244         return 0;
245 }
246
247 void persptoetsen(unsigned short event)
248 {
249         static Object *oldcamera=0;
250         float phi, si, q1[4], vec[3];
251         static int perspo=1;
252         
253         if(event==PADENTER) {
254                 if (G.qual == LR_SHIFTKEY) {
255                         view3d_set_1_to_1_viewborder(G.vd);
256                 } else {
257                         if (G.vd->persp==2) {
258                                 G.vd->camzoom= 0.0;
259                         } else {
260                                 G.vd->dist= 10.0;
261                         }
262                 }
263         }
264         else if((G.qual & (LR_SHIFTKEY | LR_CTRLKEY)) && (event != PAD0)) {
265                 if(event==PAD0) {
266                         /* G.vd->persp= 3; */
267                 }
268                 else if(event==PAD7) {
269                         G.vd->viewquat[0]= 0.0;
270                         G.vd->viewquat[1]= -1.0;
271                         G.vd->viewquat[2]= 0.0;
272                         G.vd->viewquat[3]= 0.0;
273                         G.vd->view= 7;
274                         if(G.vd->persp>=2) G.vd->persp= perspo;
275                 }
276                 else if(event==PAD1) {
277                         G.vd->viewquat[0]= 0.0;
278                         G.vd->viewquat[1]= 0.0;
279                         G.vd->viewquat[2]= (float)-cos(M_PI/4.0);
280                         G.vd->viewquat[3]= (float)-cos(M_PI/4.0);
281                         G.vd->view=1;
282                         if(G.vd->persp>=2) G.vd->persp= perspo;
283                 }
284                 else if(event==PAD3) {
285                         G.vd->viewquat[0]= 0.5;
286                         G.vd->viewquat[1]= -0.5;
287                         G.vd->viewquat[2]= 0.5;
288                         G.vd->viewquat[3]= 0.5;
289                         G.vd->view=3;
290                         if(G.vd->persp>=2) G.vd->persp= perspo;
291                 }
292                 else if(event==PADMINUS) {
293                         /* this min and max is also in viewmove() */
294                         if(G.vd->persp==2) {
295                                         G.vd->camzoom-= 10;
296                                         if(G.vd->camzoom<-30) G.vd->camzoom= -30;
297                                 }
298                         else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2;
299                 }
300                 else if(event==PADPLUSKEY) {
301                         if(G.vd->persp==2) {
302                                         G.vd->camzoom+= 10;
303                                         if(G.vd->camzoom>300) G.vd->camzoom= 300;
304                         }
305                         else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333;
306                 }
307                 else {
308
309                         initgrabz(0.0, 0.0, 0.0);
310                         
311                         if(event==PAD6) window_to_3d(vec, -32, 0);
312                         else if(event==PAD4) window_to_3d(vec, 32, 0);
313                         else if(event==PAD8) window_to_3d(vec, 0, -25);
314                         else if(event==PAD2) window_to_3d(vec, 0, 25);
315                         G.vd->ofs[0]+= vec[0];
316                         G.vd->ofs[1]+= vec[1];
317                         G.vd->ofs[2]+= vec[2];
318                 }
319         }
320         else {
321
322                 if(event==PAD7) {
323                         G.vd->viewquat[0]= 1.0;
324                         G.vd->viewquat[1]= 0.0;
325                         G.vd->viewquat[2]= 0.0;
326                         G.vd->viewquat[3]= 0.0;
327                         G.vd->view=7;
328                         if(G.vd->persp>=2) G.vd->persp= perspo;
329                 }
330                 else if(event==PAD1) {
331                         G.vd->viewquat[0]= (float)cos(M_PI/4.0);
332                         G.vd->viewquat[1]= (float)-sin(M_PI/4.0);
333                         G.vd->viewquat[2]= 0.0;
334                         G.vd->viewquat[3]= 0.0;
335                         G.vd->view=1;
336                         if(G.vd->persp>=2) G.vd->persp= perspo;
337                 }
338                 else if(event==PAD3) {
339                         G.vd->viewquat[0]= 0.5;
340                         G.vd->viewquat[1]= -0.5;
341                         G.vd->viewquat[2]= -0.5;
342                         G.vd->viewquat[3]= -0.5;
343                         G.vd->view=3;
344                         if(G.vd->persp>=2) G.vd->persp= perspo;
345                 }
346                 else if(event==PADMINUS) {
347                         /* this min and max is also in viewmove() */
348                         if(G.vd->persp==2) {
349                                 G.vd->camzoom= MAX2(-30, G.vd->camzoom-5);
350                         }
351                         else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2;
352                 }
353                 else if(event==PADPLUSKEY) {
354                         if(G.vd->persp==2) {
355                                 G.vd->camzoom= MIN2(300, G.vd->camzoom+5);
356                         }
357                         else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333;
358                 }
359                 else if(event==PAD5) {
360                         if(G.vd->persp==1) G.vd->persp=0;
361                         else G.vd->persp=1;
362                 }
363                 else if(event==PAD0) {
364                         if(G.qual & LR_ALTKEY) {
365                                 if(oldcamera && is_an_active_object(oldcamera)) {
366                                         G.vd->camera= oldcamera;
367                                 }
368                                 
369                                 handle_view3d_lock();
370                         }
371                         else if(BASACT) {
372                                 if(G.qual & LR_CTRLKEY) {
373                                         if(G.vd->camera != OBACT) {
374                                                 if(G.vd->camera && G.vd->camera->type==OB_CAMERA)
375                                                         oldcamera= G.vd->camera;
376                                                 
377                                                 G.vd->camera= OBACT;
378                                                 handle_view3d_lock();
379                                         }
380                                 }
381                                 else if(G.vd->camera==0 && OBACT->type==OB_CAMERA) {
382                                         G.vd->camera= OBACT;
383                                         handle_view3d_lock();
384                                 }
385                         }
386                         if(G.vd->camera==0) {
387                                 G.vd->camera= scene_find_camera(G.scene);
388                                 handle_view3d_lock();
389                         }
390                         
391                         if(G.vd->camera) {
392                                 G.vd->persp= 2;
393                                 G.vd->view= 0;
394                                 if(G.qual & LR_SHIFTKEY) {
395                                         void setcameratoview3d(void);   // view.c
396                                         setcameratoview3d();
397                                 }                               
398                         }
399                 }
400                 else if(event==PAD9) {
401                         countall();
402                         do_all_ipos();
403                         do_all_keys();
404                         do_all_actions();
405                         do_all_ikas();
406
407                         reset_slowparents();    /* editobject.c */
408                 }
409                 else if(G.vd->persp<2) {
410                         if(event==PAD4 || event==PAD6) {
411                                 /* z-axis */
412                                 phi= (float)(M_PI/24.0);
413                                 if(event==PAD6) phi= -phi;
414                                 si= (float)sin(phi);
415                                 q1[0]= (float)cos(phi);
416                                 q1[1]= q1[2]= 0.0;
417                                 q1[3]= si;
418                                 QuatMul(G.vd->viewquat, G.vd->viewquat, q1);
419                                 G.vd->view= 0;
420                         }
421                         if(event==PAD2 || event==PAD8) {
422                                 
423                                 /* horizontal axis */
424                                 VECCOPY(q1+1, G.vd->viewinv[0]);
425                                 
426                                 Normalise(q1+1);
427                                 phi= (float)(M_PI/24.0);
428                                 if(event==PAD2) phi= -phi;
429                                 si= (float)sin(phi);
430                                 q1[0]= (float)cos(phi);
431                                 q1[1]*= si;
432                                 q1[2]*= si;
433                                 q1[3]*= si;
434                                 QuatMul(G.vd->viewquat, G.vd->viewquat, q1);
435                                 G.vd->view= 0;
436                         }
437                 }
438
439                 if(G.vd->persp<2) perspo= G.vd->persp;
440         }
441         scrarea_queue_redraw(curarea);
442 }
443
444 int untitled(char * name)
445 {
446         if (G.save_over == 0 ) {
447                 char * c= BLI_last_slash(name);
448                 
449                 if (c)
450                         strcpy(&c[1], "untitled.blend");
451                 else
452                         strcpy(name, "untitled.blend");
453                         
454                 return(TRUE);
455         }
456         
457         return(FALSE);
458 }
459
460 int save_image_filesel_str(char *str)
461 {
462         switch(G.scene->r.imtype) {
463         case R_PNG:
464                 strcpy(str, "SAVE PNG"); return 1;
465         case R_TARGA:
466                 strcpy(str, "SAVE TARGA"); return 1;
467         case R_RAWTGA:
468                 strcpy(str, "SAVE RAW TARGA"); return 1;
469         case R_IRIS:
470                 strcpy(str, "SAVE IRIS"); return 1;
471         case R_IRIZ:
472                 strcpy(str, "SAVE IRIS"); return 1;
473         case R_HAMX:
474                 strcpy(str, "SAVE HAMX"); return 1;
475         case R_FTYPE:
476                 strcpy(str, "SAVE FTYPE"); return 1;
477         case R_JPEG90:
478                 strcpy(str, "SAVE JPEG"); return 1;
479         default:
480                 strcpy(str, "SAVE IMAGE"); return 0;
481         }       
482 }
483
484 void BIF_save_rendered_image(void)
485 {
486         if(!R.rectot) {
487                 error("No image rendered");
488         } else {
489                 char dir[FILE_MAXDIR * 2], str[FILE_MAXFILE * 2];
490
491                 if(G.ima[0]==0) {
492                         strcpy(dir, G.sce);
493                         BLI_splitdirstring(dir, str);
494                         strcpy(G.ima, dir);
495                 }
496                 
497                 R.r.imtype= G.scene->r.imtype;
498                 R.r.quality= G.scene->r.quality;
499                 R.r.planes= G.scene->r.planes;
500         
501                 if (!save_image_filesel_str(str)) {
502                         error("Select an image type in DisplayButtons(F10)");
503                 } else {
504                         activate_fileselect(FILE_SPECIAL, str, G.ima, write_imag);
505                 }
506         }
507 }
508
509 int blenderqread(unsigned short event, short val)
510 {
511         /* here do the general keys handling (not screen/window/space) */
512         /* return 0: do not pass on to the other queues */
513         extern int textediting;
514         ScrArea *sa;
515         Object *ob;
516         int textspace=0;
517         /* Changed str and dir size to 160, to make sure there is enough
518          * space for filenames. */
519         char dir[FILE_MAXDIR * 2], str[FILE_MAXFILE * 2];
520         
521         if(val==0) return 1;
522         if(event==MOUSEY || event==MOUSEX) return 1;
523         if (G.flags & G_FLAGS_AUTOPLAY) return 1;
524
525         if (curarea && curarea->spacetype==SPACE_TEXT) textspace= 1;
526
527         switch(event) {
528
529         case F1KEY:
530                 if(G.qual==0) {
531                         /* this exception because of the '?' button */
532                         if(curarea->spacetype==SPACE_INFO) {
533                                 sa= closest_bigger_area();
534                                 areawinset(sa->win);
535                         }
536                         
537                         activate_fileselect(FILE_BLENDER, "LOAD FILE", G.sce, BIF_read_file);
538                         return 0;
539                 }
540                 else if(G.qual & LR_SHIFTKEY) {
541                         activate_fileselect(FILE_LOADLIB, "LOAD LIBRARY", G.lib, 0);
542                         return 0;
543                 }
544                 break;
545         case F2KEY:
546                 if(G.qual==0) {
547                         strcpy(dir, G.sce);
548                         untitled(dir);
549                         activate_fileselect(FILE_BLENDER, "SAVE FILE", dir, BIF_write_file);
550                         return 0;
551                 }
552                 else if(G.qual & LR_CTRLKEY) {
553                         write_vrml_fs();
554                         return 0;
555                 }
556                 else if(G.qual & LR_SHIFTKEY) {
557                         write_dxf_fs();
558                         return 0;
559                 }
560                 break;
561         case F3KEY:
562                 if(G.qual==0) {
563                         BIF_save_rendered_image();
564                         return 0;
565                 }
566                 else if(G.qual & LR_CTRLKEY) {
567                         BIF_screendump();
568                 }
569                 break;
570         case F4KEY:
571                 if(G.qual & LR_SHIFTKEY) {
572
573                         memset(str, 0, 16);
574                         ob= OBACT;
575                         if(ob) strcpy(str, ob->id.name);
576
577                         activate_fileselect(FILE_MAIN, "DATA SELECT", str, 0);
578                         return 0;
579                 }
580                 else extern_set_butspace(event);
581                 
582                 break;
583         case F5KEY:
584                 if(G.qual & LR_SHIFTKEY) {
585                         newspace(curarea, SPACE_VIEW3D);
586                         return 0;
587                 }
588                 else extern_set_butspace(event);
589                 break;
590         case F6KEY:
591                 if(G.qual & LR_SHIFTKEY) {
592                         newspace(curarea, SPACE_IPO);
593                         return 0;
594                 }
595                 else extern_set_butspace(event);
596                 break;
597         case F7KEY:
598                 if(G.qual & LR_SHIFTKEY) {
599                         newspace(curarea, SPACE_BUTS);
600                         return 0;
601                 }
602                 else extern_set_butspace(event);
603                 break;
604         case F8KEY:
605                 if(G.qual & LR_SHIFTKEY) {
606                         newspace(curarea, SPACE_SEQ);
607                         return 0;
608                 }
609                 else extern_set_butspace(event);
610                 break;
611         case F9KEY:
612                 if(G.qual & LR_SHIFTKEY) {
613                         newspace(curarea, SPACE_OOPS);
614                         return 0;
615                 }
616                 else extern_set_butspace(event);
617                 break;
618         case F10KEY:
619                 if(G.qual & LR_SHIFTKEY) {
620                         newspace(curarea, SPACE_IMAGE);
621                         return 0;
622                 }
623                 else extern_set_butspace(event);
624                 break;
625         case F11KEY:
626                 if(G.qual & LR_SHIFTKEY) {
627                         newspace(curarea, SPACE_TEXT);
628                         return 0;
629                 }
630                 else BIF_toggle_render_display();
631                 return 0;
632                 break;
633         case F12KEY:
634                 if(G.qual & LR_SHIFTKEY) {
635                         if (G.qual & LR_CTRLKEY){
636                                 newspace(curarea, SPACE_NLA);
637                                 return 0;
638                         }
639                         newspace(curarea, SPACE_ACTION);
640                         return 0;
641                 }
642                 else BIF_do_render(0);
643                 return 0;
644                 break;
645         
646         case LEFTARROWKEY:
647         case DOWNARROWKEY:
648                 if(textediting==0 && textspace==0) {
649
650 #ifdef _WIN32   // FULLSCREEN
651                         if(event==DOWNARROWKEY){
652                                 if (G.qual & LR_ALTKEY) mainwindow_toggle_fullscreen(0);
653                                 else CFRA-= 10;
654                         }
655 #else
656                         if(event==DOWNARROWKEY) CFRA-= 10;
657 #endif
658                         else CFRA--;
659                         
660                         if(G.qual & LR_SHIFTKEY) CFRA= SFRA;
661                         if(CFRA<1) CFRA=1;
662         
663                         update_for_newframe();
664                         return 0;
665                 }
666                 break;
667
668         case RIGHTARROWKEY:
669         case UPARROWKEY:
670                 if(textediting==0 && textspace==0) {
671
672 #ifdef _WIN32   // FULLSCREEN
673                         if(event==UPARROWKEY){ 
674                                 if(G.qual & LR_ALTKEY) mainwindow_toggle_fullscreen(1);
675                                 else CFRA+= 10;
676                         }
677 #else
678                         if(event==UPARROWKEY) CFRA+= 10;
679 #endif
680                         else CFRA++;
681
682                         if(G.qual & LR_SHIFTKEY) CFRA= EFRA;
683                         
684                         update_for_newframe();
685                 }
686                 break;
687         
688         case ESCKEY:
689                 sound_stop_all_sounds();
690                 break;
691         case TABKEY:
692                 if(G.qual==0 ) {
693                         if(textspace==0) {
694                                 if(curarea->spacetype==SPACE_IPO) set_editflag_editipo();
695                                 else if(curarea->spacetype==SPACE_SEQ) enter_meta();
696                                 else if(G.vd) {
697                                         /* also when Alt-E */
698                                         if(G.obedit==0) enter_editmode();
699                                         else exit_editmode(1);
700                                 }
701                                 return 0;
702                         }
703                 }
704                 else if(G.qual & LR_CTRLKEY){
705                         if(G.obpose) exit_posemode(1);
706                         else
707                                 enter_posemode();
708                         allqueue(REDRAWHEADERS, 0);     
709                         
710                 }
711                 else if(G.qual & LR_SHIFTKEY) {
712                         if(G.obedit) exit_editmode(1);
713                         if(G.f & G_FACESELECT) set_faceselect();
714                         if(G.f & G_VERTEXPAINT) set_vpaint();
715                         if(G.f & G_WEIGHTPAINT) set_wpaint();
716                         if(G.obpose) exit_posemode(1);
717                 }
718                 break;
719
720         case BACKSPACEKEY:
721                 break;
722
723         case AKEY:
724                 if(textediting==0 && textspace==0) {
725                         if(G.qual & LR_ALTKEY) {
726                                 if(G.qual & LR_SHIFTKEY) play_anim(1);
727                                 else play_anim(0);
728                                 return 0;
729                         }
730                 }
731                 break;
732         case EKEY:
733                 if(G.qual & LR_ALTKEY) {
734                         if(G.vd && textspace==0) {
735                                 if(G.obedit==0) enter_editmode();
736                                 else exit_editmode(1);
737                                 return 0;
738                         }                       
739                 }
740                 break;
741         case IKEY:
742                 if(textediting==0 && textspace==0 && curarea->spacetype!=SPACE_FILE && curarea->spacetype!=SPACE_IMASEL) {
743                         if(G.qual==0) {
744                                 common_insertkey();
745                                 return 0;
746                         }
747                 }
748                 break;
749         case JKEY:
750                 if(textediting==0 && textspace==0) {
751                         if(R.rectot && G.qual==0) {
752                                 BIF_swap_render_rects();
753                                 return 0;
754                         }
755                 }
756                 break;
757
758         case NKEY:
759                 if(textediting==0 && textspace==0 ) {
760                         if(G.qual & LR_CTRLKEY);
761                         else if(G.qual==0 || (G.qual & LR_SHIFTKEY)) {
762                                 clever_numbuts();
763                                 return 0;
764                         }
765                 }
766                 break;
767                 
768         case OKEY:
769                 if(textediting==0) {
770                         if(G.qual & LR_CTRLKEY) {
771                                 /* There seem to be crashes here sometimes.... String
772                                  * bound overwrites? I changed dir and str sizes,
773                                  * let's see if this reoccurs. */
774                                 sprintf(str, "Open file: %s", G.sce);
775                         
776                                 if(okee(str)) {
777                                         strcpy(dir, G.sce);
778                                         BIF_read_file(dir);
779                                 }
780                                 return 0;
781                         }
782                 }
783                 break;
784                 
785         case SKEY:
786                 if(G.obpose==0 && G.obedit==0) {
787                         if(G.qual & LR_CTRLKEY) {
788                                 if(G.qual & LR_SHIFTKEY);
789                                 else {
790                                         strcpy(dir, G.sce);
791                                         if (untitled(dir)) {
792                                                 activate_fileselect(FILE_BLENDER, "SAVE FILE", dir, BIF_write_file);
793                                         } else {
794                                                 BIF_write_file(dir);
795                                                 free_filesel_spec(dir);
796                                         }
797                                         return 0;
798                                 }
799                         }
800                 }
801                 break;
802         
803         case TKEY:
804                 if(G.qual & LR_ALTKEY) {
805                 if(G.qual & LR_CTRLKEY) {
806                         int a;
807
808                         if (G.qual & LR_SHIFTKEY) {
809                                 double delta, stime;
810
811                                 waitcursor(1);
812                                 
813                                 stime= PIL_check_seconds_timer();
814                                 for(a=0; a<100000; a++) {
815                                         scrarea_do_windraw(curarea);
816
817                                         delta= PIL_check_seconds_timer()-stime;
818                                         if (delta>5.0) break;
819                                 }
820                                 
821                                 waitcursor(0);
822                                 notice("FPS: %f (%d iterations)", a/delta, a);
823                         } else {
824                                 int event= pupmenu("10 Timer%t|draw|draw+swap");
825                                 if(event>0) {
826                                         double stime= PIL_check_seconds_timer();
827                                         char tmpstr[128];
828                                         int time;
829
830                                         printf("start timer\n");
831                                         waitcursor(1);
832                                                                         
833                                         for(a=0; a<10; a++) {
834                                                 scrarea_do_windraw(curarea);
835                                                 if(event==2) screen_swapbuffers();
836                                         }
837                                 
838                                         time= (PIL_check_seconds_timer()-stime)*1000;
839                                         
840                                         if(event==1) sprintf(tmpstr, "draw %%t|%d", time);
841                                         if(event==2) sprintf(tmpstr, "d+sw %%t|%d", time);
842                                 
843                                         waitcursor(0);
844                                         pupmenu(tmpstr);
845
846                                 }
847                         }
848                         return 0;
849                 }}
850                 break;
851                                 
852         case UKEY:
853                 if(textediting==0) {
854                         if(G.qual & LR_CTRLKEY) {
855                                 if(okee("SAVE USER DEFAULTS")) {
856                                         BIF_write_homefile();
857                                 }
858                                 return 0;
859                         }
860                 }
861                 break;
862                 
863         case WKEY:
864                 if(textediting==0) {
865                         if(G.qual & LR_CTRLKEY) {
866                                 if(G.qual & LR_SHIFTKEY);
867                                 else {
868                                         strcpy(dir, G.sce);
869                                         if (untitled(dir)) {
870                                                 activate_fileselect(FILE_BLENDER, "SAVE FILE", dir, BIF_write_file);
871                                         } else {
872                                                 BIF_write_file(dir);
873                                                 free_filesel_spec(dir);
874                                         }
875                                         return 0;
876                                 }
877                         }
878                         else if(G.qual & LR_ALTKEY) {
879                                 write_videoscape_fs();
880                         }
881                 }
882                 break;
883                 
884         case XKEY:
885                 if(textspace==0) {
886                         if(G.qual & LR_CTRLKEY) {
887                                 if(okee("ERASE ALL")) {
888                                         if( BIF_read_homefile()==0) error("No file ~/.B.blend");
889                                 }
890                                 return 0;
891                         }
892                 }
893                 break;
894         }
895         
896         return 1;
897 }
898
899 /* eof */