Two in one:
[blender.git] / source / blender / src / space.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  * - here initialize and free and handling SPACE data
34  */
35
36 #include <string.h>
37 #include <stdio.h>
38
39 #ifdef HAVE_CONFIG_H
40 #include <config.h>
41 #endif
42
43 #include "MEM_guardedalloc.h"
44 #include "MEM_CacheLimiterC-Api.h"
45
46 #ifdef INTERNATIONAL
47 #include "BIF_language.h"
48 #endif
49
50 #include "IMB_imbuf_types.h"
51 #include "IMB_imbuf.h"
52
53 #include "BLI_blenlib.h"
54 #include "BLI_arithb.h"
55 #include "BLI_gsqueue.h"
56 #include "BLI_linklist.h"
57
58 #include "DNA_action_types.h"
59 #include "DNA_armature_types.h"
60 #include "DNA_curve_types.h"
61 #include "DNA_group_types.h" /* used for select_same_group */
62 #include "DNA_image_types.h"
63 #include "DNA_ipo_types.h"
64 #include "DNA_mesh_types.h"
65 #include "DNA_meshdata_types.h"
66 #include "DNA_modifier_types.h" /* used for select grouped hooks */
67 #include "DNA_object_types.h"
68 #include "DNA_scene_types.h"
69 #include "DNA_screen_types.h"
70 #include "DNA_sequence_types.h"
71 #include "DNA_sound_types.h"
72 #include "DNA_space_types.h"
73 #include "DNA_userdef_types.h"
74 #include "DNA_view2d_types.h"
75 #include "DNA_view3d_types.h"
76
77 #include "BKE_blender.h"
78 #include "BKE_colortools.h"
79 #include "BKE_curve.h"
80 #include "BKE_depsgraph.h"
81 #include "BKE_displist.h"
82 #include "BKE_global.h"
83 #include "BKE_group.h"
84 #include "BKE_ipo.h"
85 #include "BKE_main.h"
86 #include "BKE_mesh.h"
87 #include "BKE_node.h"
88 #include "BKE_scene.h"
89 #include "BKE_utildefines.h"
90
91 #include "BIF_spacetypes.h"  /* first, nasty dependency with typedef */
92
93 #include "BIF_butspace.h"
94 #include "BIF_drawimage.h"
95 #include "BIF_drawseq.h"
96 #include "BIF_drawtext.h"
97 #include "BIF_drawscript.h"
98 #include "BIF_editarmature.h"
99 #include "BIF_editconstraint.h"
100 #include "BIF_editfont.h"
101 #include "BIF_editgroup.h"
102 #include "BIF_editkey.h"
103 #include "BIF_editlattice.h"
104 #include "BIF_editmesh.h"
105 #include "BIF_editmode_undo.h"
106 #include "BIF_editnla.h"
107 #include "BIF_editoops.h"
108 #include "BIF_editseq.h"
109 #include "BIF_editsima.h"
110 #include "BIF_editsound.h"
111 #include "BIF_editview.h"
112 #include "BIF_gl.h"
113 #include "BIF_imasel.h"
114 #include "BIF_interface.h"
115 #include "BIF_interface_icons.h"
116 #include "BIF_meshtools.h"
117 #include "BIF_mywindow.h"
118 #include "BIF_oops.h"
119 #include "BIF_poseobject.h"
120 #include "BIF_outliner.h"
121 #include "BIF_resources.h"
122 #include "BIF_retopo.h"
123 #include "BIF_screen.h"
124 #include "BIF_space.h"
125 #include "BIF_toets.h"
126 #include "BIF_toolbox.h"
127 #include "BIF_usiblender.h"
128 #include "BIF_previewrender.h"
129
130 #include "BSE_edit.h"
131 #include "BSE_view.h"
132 #include "BSE_editipo.h"
133 #include "BSE_drawipo.h"
134 #include "BSE_drawview.h"
135 #include "BSE_drawnla.h"
136 #include "BSE_filesel.h"
137 #include "BSE_headerbuttons.h"
138 #include "BSE_editnla_types.h"
139 #include "BSE_time.h"
140
141 #include "BDR_vpaint.h"
142 #include "BDR_editmball.h"
143 #include "BDR_editobject.h"
144 #include "BDR_editcurve.h"
145 #include "BDR_editface.h"
146 #include "BDR_drawmesh.h"
147 #include "BDR_drawobject.h"
148 #include "BDR_imagepaint.h"
149 #include "BDR_sculptmode.h"
150 #include "BDR_unwrapper.h"
151
152 #include "BLO_readfile.h" /* for BLO_blendhandle_close */
153
154 #include "PIL_time.h"
155
156 #include "BPY_extern.h"
157
158 #include "butspace.h"
159 #include "mydevice.h"
160 #include "blendef.h"
161 #include "datatoc.h"
162 #include "multires.h"
163
164 #include "BIF_transform.h"
165
166 #include "BKE_depsgraph.h"
167
168 #include "BSE_trans_types.h"
169
170 #include "SYS_System.h" /* for the user def menu ... should move elsewhere. */
171
172
173 extern void StartKetsjiShell(ScrArea *area, char* startscenename, struct Main* maggie, struct SpaceIpo* sipo,int always_use_expand_framing);
174 extern void StartKetsjiShellSimulation(ScrArea *area, char* startscenename, struct Main* maggie, struct SpaceIpo* sipo,int always_use_expand_framing);//rcruiz
175
176 /**
177  * When the mipmap setting changes, we want to redraw the view right
178  * away to reflect this setting.
179  */
180 void space_mipmap_button_function(int event);
181
182 void free_soundspace(SpaceSound *ssound);
183
184 /* *************************************** */
185
186 /* don't know yet how the handlers will evolve, for simplicity
187    i choose for an array with eventcodes, this saves in a file!
188    */
189 void add_blockhandler(ScrArea *sa, short eventcode, short val)
190 {
191         SpaceLink *sl= sa->spacedata.first;
192         short a;
193         
194         /* find empty spot */
195         for(a=0; a<SPACE_MAXHANDLER; a+=2) {
196                 if( sl->blockhandler[a]==eventcode ) {
197                         sl->blockhandler[a+1]= val;
198                         break;
199                 }
200                 else if( sl->blockhandler[a]==0) {
201                         sl->blockhandler[a]= eventcode;
202                         sl->blockhandler[a+1]= val;
203                         break;
204                 }
205         }
206         if(a==SPACE_MAXHANDLER) printf("error; max (4) blockhandlers reached!\n");
207 }
208
209 void rem_blockhandler(ScrArea *sa, short eventcode)
210 {
211         SpaceLink *sl= sa->spacedata.first;
212         short a;
213         
214         for(a=0; a<SPACE_MAXHANDLER; a+=2) {
215                 if( sl->blockhandler[a]==eventcode) {
216                         sl->blockhandler[a]= 0;
217                         
218                         /* specific free calls */
219                         if(eventcode==IMAGE_HANDLER_PREVIEW)
220                                 image_preview_event(0);
221                         break;
222                 }
223         }
224 }
225
226 void toggle_blockhandler(ScrArea *sa, short eventcode, short val)
227 {
228         SpaceLink *sl= sa->spacedata.first;
229         short a, addnew=1;
230         
231         /* find if it exists */
232         for(a=0; a<SPACE_MAXHANDLER; a+=2) {
233                 if( sl->blockhandler[a]==eventcode ) {
234                         sl->blockhandler[a]= 0;
235                         
236                         /* specific free calls */
237                         if(eventcode==VIEW3D_HANDLER_PREVIEW)
238                                 BIF_view3d_previewrender_free(sa->spacedata.first);
239                         else if(eventcode==IMAGE_HANDLER_PREVIEW)
240                                 image_preview_event(0);
241                         
242                         addnew= 0;
243                 }
244         }
245         if(addnew) add_blockhandler(sa, eventcode, val);
246 }
247
248
249
250 /* ************* SPACE: VIEW3D  ************* */
251
252 /*  extern void drawview3dspace(ScrArea *sa, void *spacedata); BSE_drawview.h */
253
254
255 void copy_view3d_lock(short val)
256 {
257         bScreen *sc;
258         int bit;
259         
260         /* from G.scene copy to the other views */
261         sc= G.main->screen.first;
262         
263         while(sc) {
264                 if(sc->scene==G.scene) {
265                         ScrArea *sa= sc->areabase.first;
266                         while(sa) {
267                                 SpaceLink *sl= sa->spacedata.first;
268                                 while(sl) {
269                                         if(sl->spacetype==SPACE_OOPS && val==REDRAW) {
270                                                 if(sa->win) scrarea_queue_winredraw(sa);
271                                         }
272                                         else if(sl->spacetype==SPACE_VIEW3D) {
273                                                 View3D *vd= (View3D*) sl;
274                                                 if(vd->scenelock && vd->localview==0) {
275                                                         vd->lay= G.scene->lay;
276                                                         vd->camera= G.scene->camera;
277                                                         
278                                                         if(vd->camera==0 && vd->persp>1) vd->persp= 1;
279                                                         
280                                                         if( (vd->lay & vd->layact) == 0) {
281                                                                 bit= 0;
282                                                                 while(bit<32) {
283                                                                         if(vd->lay & (1<<bit)) {
284                                                                                 vd->layact= 1<<bit;
285                                                                                 break;
286                                                                         }
287                                                                         bit++;
288                                                                 }
289                                                         }
290                                                         
291                                                         if(val==REDRAW && vd==sa->spacedata.first) {
292                                                                 if(sa->win) scrarea_queue_redraw(sa);
293                                                         }
294                                                 }
295                                         }
296                                         sl= sl->next;
297                                 }
298                                 sa= sa->next;
299                         }
300                 }
301                 sc= sc->id.next;
302         }
303 }
304
305 void handle_view3d_around()
306 {
307         bScreen *sc;
308         
309         if ((U.uiflag & USER_LOCKAROUND)==0) return;
310         
311         /* copies from G.vd->around to other view3ds */
312         
313         sc= G.main->screen.first;
314         
315         while(sc) {
316                 if(sc->scene==G.scene) {
317                         ScrArea *sa= sc->areabase.first;
318                         while(sa) {
319                                 SpaceLink *sl= sa->spacedata.first;
320                                 while(sl) {
321                                         if(sl->spacetype==SPACE_VIEW3D) {
322                                                 View3D *vd= (View3D*) sl;
323                                                 if (vd != G.vd) {
324                                                         vd->around= G.vd->around;
325                                                         if (G.vd->flag & V3D_ALIGN)
326                                                                 vd->flag |= V3D_ALIGN;
327                                                         else
328                                                                 vd->flag &= ~V3D_ALIGN;
329                                                         scrarea_queue_headredraw(sa);
330                                                 }
331                                         }
332                                         sl= sl->next;
333                                 }
334                                 sa= sa->next;
335                         }
336                 }
337                 sc= sc->id.next;
338         }
339 }
340
341 void handle_view3d_lock()
342 {
343         if (G.vd != NULL) {
344                 if(G.vd->localview==0 && G.vd->scenelock && curarea->spacetype==SPACE_VIEW3D) {
345
346                         /* copy to scene */
347                         G.scene->lay= G.vd->lay;
348                         G.scene->camera= G.vd->camera;
349         
350                         copy_view3d_lock(REDRAW);
351                 }
352         }
353 }
354
355 void space_set_commmandline_options(void) {
356         SYS_SystemHandle syshandle;
357         int a;
358                 
359         if ( (syshandle = SYS_GetSystem()) ) {
360                 /* User defined settings */
361                 a= (U.gameflags & USER_VERTEX_ARRAYS);
362                 SYS_WriteCommandLineInt(syshandle, "vertexarrays", a);
363
364                 a= (U.gameflags & USER_DISABLE_SOUND);
365                 SYS_WriteCommandLineInt(syshandle, "noaudio", a);
366
367                 a= (U.gameflags & USER_DISABLE_MIPMAP);
368                 set_mipmap(!a);
369                 SYS_WriteCommandLineInt(syshandle, "nomipmap", a);
370
371                 /* File specific settings: */
372                 /* Only test the first one. These two are switched
373                  * simultaneously. */
374                 a= (G.fileflags & G_FILE_SHOW_FRAMERATE);
375                 SYS_WriteCommandLineInt(syshandle, "show_framerate", a);
376                 SYS_WriteCommandLineInt(syshandle, "show_profile", a);
377
378                 /* When in wireframe mode, always draw debug props. */
379                 if (G.vd) {
380                         a = ( (G.fileflags & G_FILE_SHOW_DEBUG_PROPS) 
381                                   || (G.vd->drawtype == OB_WIRE)          
382                                   || (G.vd->drawtype == OB_SOLID)         );
383                         SYS_WriteCommandLineInt(syshandle, "show_properties", a);
384                 }
385                 
386                 a= (G.fileflags & G_FILE_SHOW_PHYSICS);
387                 SYS_WriteCommandLineInt(syshandle, "show_physics", a);
388
389                 a= (G.fileflags & G_FILE_ENABLE_ALL_FRAMES);
390                 SYS_WriteCommandLineInt(syshandle, "fixedtime", a);
391
392                 a= (G.fileflags & G_FILE_GAME_TO_IPO);
393                 SYS_WriteCommandLineInt(syshandle, "game2ipo", a);
394
395                 a=(G.fileflags & G_FILE_GAME_MAT);
396                 SYS_WriteCommandLineInt(syshandle, "blender_material", a);
397                 a=(G.fileflags & G_FILE_DIAPLAY_LISTS);
398                 SYS_WriteCommandLineInt(syshandle, "displaylists", a);
399
400
401         }
402 }
403
404 #if GAMEBLENDER == 1
405         /**
406          * These two routines imported from the gameengine, 
407          * I suspect a lot of the resetting stuff is cruft
408          * and can be removed, but it should be checked.
409          */
410 static void SaveState(void)
411 {
412         glPushAttrib(GL_ALL_ATTRIB_BITS);
413
414         init_realtime_GL();
415         init_gl_stuff();
416
417         if(G.f & G_TEXTUREPAINT)
418                 texpaint_enable_mipmap();
419
420         if(G.scene->camera==0 || G.scene->camera->type!=OB_CAMERA)
421                 error("no (correct) camera");
422
423         waitcursor(1);
424 }
425
426 static void RestoreState(void)
427 {
428         if(G.f & G_TEXTUREPAINT)
429                 texpaint_disable_mipmap();
430
431         curarea->win_swap = 0;
432         curarea->head_swap=0;
433         allqueue(REDRAWVIEW3D, 1);
434         allqueue(REDRAWBUTSALL, 0);
435         reset_slowparents();
436         waitcursor(0);
437         G.qual= 0;
438         glPopAttrib();
439 }
440
441 static LinkNode *save_and_reset_all_scene_cfra(void)
442 {
443         LinkNode *storelist= NULL;
444         Scene *sc;
445         
446         for (sc= G.main->scene.first; sc; sc= sc->id.next) {
447                 BLI_linklist_prepend(&storelist, (void*) (long) sc->r.cfra);
448
449                 /* why is this reset to 1 ?*/
450                 /* sc->r.cfra= 1;*/
451
452                 set_scene_bg(sc);
453         }
454         
455         BLI_linklist_reverse(&storelist);
456         
457         return storelist;
458 }
459
460 static void restore_all_scene_cfra(LinkNode *storelist) {
461         LinkNode *sc_store= storelist;
462         Scene *sc;
463         
464         for (sc= G.main->scene.first; sc; sc= sc->id.next) {
465                 int stored_cfra= (int) sc_store->link;
466                 
467                 sc->r.cfra= stored_cfra;
468                 set_scene_bg(sc);
469                 
470                 sc_store= sc_store->next;
471         }
472         
473         BLI_linklist_free(storelist, NULL);
474 }
475 #endif
476
477 void start_game(void)
478 {
479 #if GAMEBLENDER == 1
480 #ifndef NO_KETSJI
481         Scene *sc, *startscene = G.scene;
482         LinkNode *scene_cfra_store;
483
484                 /* XXX, silly code -  the game engine can
485                  * access any scene through logic, so we try 
486                  * to make sure each scene has a valid camera, 
487                  * just in case the game engine tries to use it.
488                  * 
489                  * Better would be to make a better routine
490                  * in the game engine for finding the camera.
491                  *  - zr
492                  * Note: yes, this is all very badly hacked! (ton)
493                  */
494         for (sc= G.main->scene.first; sc; sc= sc->id.next) {
495                 if (!sc->camera) {
496                         Base *base;
497         
498                         for (base= sc->base.first; base; base= base->next)
499                                 if (base->object->type==OB_CAMERA)
500                                         break;
501                         
502                         sc->camera= base?base->object:NULL;
503                 }
504         }
505
506         /* these two lines make sure front and backbuffer are equal. for swapbuffers */
507         markdirty_all();
508         screen_swapbuffers();
509
510         /* can start from header */
511         mywinset(curarea->win);
512     
513         scene_cfra_store= save_and_reset_all_scene_cfra();
514         
515
516         /* game engine will do its own sounds. */
517         sound_stop_all_sounds();
518         sound_exit_audio();
519         
520         /* Before jumping into Ketsji, we configure some settings. */
521         space_set_commmandline_options();
522
523         SaveState();
524         StartKetsjiShell(curarea, startscene->id.name+2, G.main,G.sipo, 1);
525         RestoreState();
526
527         /* Restart BPY - unload the game engine modules. */
528         BPY_end_python();
529         BPY_start_python(0, NULL); /* argc, argv stored there already */
530         BPY_post_start_python(); /* userpref path and menus init */
531
532         restore_all_scene_cfra(scene_cfra_store);
533         set_scene_bg(startscene);
534         scene_update_for_newframe(G.scene, G.scene->lay);
535
536         if (G.flags & G_FILE_AUTOPLAY)
537                 exit_usiblender();
538
539                 /* groups could have changed ipo */
540         allqueue(REDRAWNLA, 0);
541         allqueue(REDRAWACTION, 0);
542         allspace(REMAKEIPO, 0);
543         allqueue(REDRAWIPO, 0);
544 #endif
545 #else
546         notice("Game engine is disabled in this release!");
547 #endif
548 }
549
550 void start_RBSimulation(void)
551 {
552 #if GAMEBLENDER == 1
553 #ifndef NO_KETSJI
554         Scene *sc, *startscene = G.scene;
555         LinkNode *scene_cfra_store;
556
557                 /* XXX, silly code -  the game engine can
558                  * access any scene through logic, so we try
559                  * to make sure each scene has a valid camera,
560                  * just in case the game engine tries to use it.
561                  *
562                  * Better would be to make a better routine
563                  * in the game engine for finding the camera.
564                  *  - zr
565                  * Note: yes, this is all very badly hacked! (ton)
566                  */
567         for (sc= G.main->scene.first; sc; sc= sc->id.next) {
568                 if (!sc->camera) {
569                         Base *base;
570
571                         for (base= sc->base.first; base; base= base->next)
572                                 if (base->object->type==OB_CAMERA)
573                                         break;
574
575                         sc->camera= base?base->object:NULL;
576                 }
577         }
578
579         /* these two lines make sure front and backbuffer are equal. for swapbuffers */
580         markdirty_all();
581         screen_swapbuffers();
582
583         /* can start from header */
584         mywinset(curarea->win);
585
586         scene_cfra_store= save_and_reset_all_scene_cfra();
587
588
589         /* game engine will do its own sounds. */
590         sound_stop_all_sounds();
591         sound_exit_audio();
592
593         /* Before jumping into Ketsji, we configure some settings. */
594         space_set_commmandline_options();
595
596         SaveState();
597         StartKetsjiShellSimulation(curarea, startscene->id.name+2, G.main,G.sipo, 1);
598         RestoreState();
599         /* Restart BPY - unload the game engine modules. */
600         BPY_end_python();
601         BPY_start_python(0, NULL); /* argc, argv stored there already */
602         BPY_post_start_python(); /* userpref path and menus init */
603
604         restore_all_scene_cfra(scene_cfra_store);
605         set_scene_bg(startscene);
606         scene_update_for_newframe(G.scene, G.scene->lay);
607
608         if (G.flags & G_FILE_AUTOPLAY)
609                 exit_usiblender();
610
611                 /* groups could have changed ipo */
612         allqueue(REDRAWNLA, 0);
613         allqueue(REDRAWACTION, 0);
614         allspace(REMAKEIPO, 0);
615         allqueue(REDRAWIPO, 0);
616 #endif
617 #else
618         notice("YOU NEED GAME ENGIEN TO RUN THE SIMULATION!");
619 #endif
620 }
621
622 static void changeview3dspace(ScrArea *sa, void *spacedata)
623 {
624         setwinmatrixview3d(sa->winx, sa->winy, NULL);   /* 0= no pick rect */
625 }
626
627         /* Callable from editmode and faceselect mode from the
628          * moment, would be nice (and is easy) to generalize
629          * to any mode.
630          */
631 static void align_view_to_selected(View3D *v3d)
632 {
633         int nr= pupmenu("Align View%t|To Selected (top)%x2|To Selected (front)%x1|To Selected (side)%x0");
634
635         if (nr!=-1) {
636                 int axis= nr;
637
638                 if ((G.obedit) && (G.obedit->type == OB_MESH)) {
639                         editmesh_align_view_to_selected(v3d, axis);
640                         addqueue(v3d->area->win, REDRAW, 1);
641                 } else if (G.f & G_FACESELECT) {
642                         Object *obact= OBACT;
643                         if (obact && obact->type==OB_MESH) {
644                                 Mesh *me= obact->data;
645
646                                 if (me->mtface) {
647                                         faceselect_align_view_to_selected(v3d, me, axis);
648                                         addqueue(v3d->area->win, REDRAW, 1);
649                                 }
650                         }
651                 }
652         }
653 }
654
655 static void select_children(Object *ob, int recursive)
656 {
657         Base *base;
658
659         for (base= FIRSTBASE; base; base= base->next)
660                 if (ob == base->object->parent) {
661                         base->flag |= SELECT;
662                         base->object->flag |= SELECT;
663                         if (recursive) select_children(base->object, 1);
664                 }
665 }
666
667 static void select_parent(void) /* Makes parent active and de-selected OBACT */
668 {
669         Base *base, *startbase, *basact=NULL, *oldbasact;
670         
671         if (!(OBACT) || !(OBACT->parent)) return;
672         BASACT->flag &= (~SELECT);
673         BASACT->object->flag &= (~SELECT);
674         startbase=  FIRSTBASE;
675         if(BASACT && BASACT->next) startbase= BASACT->next;
676         base = startbase;
677         while(base) {
678                 if(base->object==BASACT->object->parent) { basact=base; break; }
679                 base=base->next;
680                 if(base==NULL) base= FIRSTBASE;
681                 if(base==startbase) break;
682         }
683         /* can be NULL if parent in other scene */
684         if(basact) {
685                 oldbasact = BASACT;
686                 BASACT = basact;
687                 basact->flag |= SELECT;         
688                 
689                 basact->object->flag= basact->flag;
690                 
691                 set_active_base(basact);
692         }
693 }
694
695 static void select_same_group(Object *ob)       /* Select objects in the same group as the active */
696 {
697         Base *base;
698         Group *group= find_group(ob);
699         if (!group || !ob)
700                 return;
701         
702         for (base= FIRSTBASE; base; base= base->next) {
703                 if (!(base->flag & SELECT) && object_in_group(base->object, group)) {
704                         base->flag |= SELECT;
705                         base->object->flag |= SELECT;
706                 }
707         }
708 }
709
710 static void select_object_hooks(Object *ob)     /* Select objects in the same group as the active */
711 {
712         Base *base;
713         ModifierData *md;
714         HookModifierData *hmd;
715         
716         if (!ob)
717                 return;
718         
719         for (md = ob->modifiers.first; md; md=md->next) {
720                 if (md->type==eModifierType_Hook) {
721                         hmd= (HookModifierData*) md;
722                         if (hmd->object && !(hmd->object->flag & SELECT)) {
723                                 base= object_in_scene(hmd->object, G.scene);
724                                 base->flag |= SELECT;
725                                 base->object->flag |= SELECT;
726                         }
727                 }
728         }
729 }
730
731 static void select_same_parent(Object *ob)      /* Select objects woth the same parent as the active (siblings), parent can be NULL also */
732 {
733         Base *base;
734         if (!ob)
735                 return;
736         
737         for (base= FIRSTBASE; base; base= base->next)
738                 if (base->object->parent==ob->parent) {
739                         base->flag |= SELECT;
740                         base->object->flag |= SELECT;
741                 }
742 }
743
744 static void select_same_type(Object *ob)        /* Select objects woth the same parent as the active (siblings), parent can be NULL also */
745 {
746         Base *base;
747         if (!ob)
748                 return;
749         
750         for (base= FIRSTBASE; base; base= base->next)
751                 if (base->object->type==ob->type) {
752                         base->flag |= SELECT;
753                         base->object->flag |= SELECT;
754                 }
755 }
756
757 void select_object_grouped(short nr)
758 {
759         Base *base;
760         
761         if(nr==6) {
762                 base= FIRSTBASE;
763                 while(base) {
764                         if (base->lay & OBACT->lay) {
765                                 base->flag |= SELECT;
766                                 base->object->flag |= SELECT;
767                         }
768                         base= base->next;
769                 }
770         }
771         else if(nr==1) select_children(OBACT, 1);
772         else if(nr==2) select_children(OBACT, 0);
773         else if(nr==3) select_parent();
774         else if(nr==4) select_same_parent(OBACT);       
775         else if(nr==5) select_same_type(OBACT); 
776         else if(nr==7) select_same_group(OBACT);
777         else if(nr==8) select_object_hooks(OBACT);
778         
779         
780         
781         
782         countall();
783         allqueue(REDRAWVIEW3D, 0);
784         allqueue(REDRAWBUTSOBJECT, 0);
785         allspace(REMAKEIPO, 0);
786         allqueue(REDRAWIPO, 0);
787 }
788
789 static void select_object_grouped_menu(void)
790 {
791         char *str;
792         short nr;
793
794         /* make menu string */
795         
796         str= MEM_mallocN(512, "groupmenu");
797         strcpy(str, "Select Grouped%t|Children%x1|"
798                     "Immediate Children%x2|Parent%x3|"
799                     "Siblings (Shared Parent)%x4|"
800                     "Objects of Same Type%x5|"
801                                 "Objects on Shared Layers%x6|"
802                 "Objects in Same Group%x7|"
803                 "Object Hooks%x8|");
804
805         /* here we go */
806         
807         nr= pupmenu(str);
808         MEM_freeN(str);
809         
810         select_object_grouped(nr);
811 }
812
813 void join_menu(void)
814 {
815         Object *ob= OBACT;
816         if (ob && !G.obedit) {
817                 if(ob->type == OB_MESH) {
818                         if(okee("Join selected meshes")==0) return;
819                         join_mesh();
820                 } else if(ob->type == OB_CURVE) {
821                         if(okee("Join selected curves")==0) return;
822                         join_curve(OB_CURVE);
823                 } else if(ob->type == OB_SURF) {
824                         if(okee("Join selected NURBS")==0) return;
825                         join_curve(OB_SURF);
826                 } else if(ob->type == OB_ARMATURE) {
827                         /*      Make sure the user wants to continue*/
828                         if(okee("Join selected armatures")==0) return;
829                         join_armature ();
830                 }
831         }
832 }
833
834 static unsigned short convert_for_nonumpad(unsigned short event)
835 {
836         if (event>=ZEROKEY && event<=NINEKEY) {
837                 return event - ZEROKEY + PAD0;
838         } else if (event==MINUSKEY) {
839                 return PADMINUS;
840         } else if (event==EQUALKEY) {
841                 return PADPLUSKEY;
842         } else if (event==BACKSLASHKEY) {
843                 return PADSLASHKEY;
844         } else {
845                 return event;
846         }
847 }
848
849 /* *************** */
850
851 void BIF_undo_push(char *str)
852 {
853         if(G.obedit) {
854                 if (U.undosteps == 0) return;
855
856                 if(G.obedit->type==OB_MESH)
857                         undo_push_mesh(str);
858                 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
859                         undo_push_curve(str);
860                 else if (G.obedit->type==OB_FONT)
861                         undo_push_font(str);
862                 else if (G.obedit->type==OB_MBALL)
863                         undo_push_mball(str);
864                 else if (G.obedit->type==OB_LATTICE)
865                         undo_push_lattice(str);
866                 else if (G.obedit->type==OB_ARMATURE)
867                         undo_push_armature(str);
868         }
869         else if(G.f & G_SCULPTMODE) {
870         }
871         else {
872                 if(U.uiflag & USER_GLOBALUNDO) 
873                         BKE_write_undo(str);
874         }
875 }
876
877 void BIF_undo(void)
878 {       
879         if(G.obedit) {
880                 if ELEM7(G.obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE)
881                         undo_editmode_step(1);
882         }
883         else {
884                 if(G.f & G_TEXTUREPAINT)
885                         imagepaint_undo();
886                 else if(G.f & G_SCULPTMODE)
887                         sculptmode_undo();
888                 else if(curarea->spacetype==SPACE_IMAGE && (G.sima->flag & SI_DRAWTOOL))
889                         imagepaint_undo();
890                 else {
891                         /* now also in faceselect mode */
892                         if(U.uiflag & USER_GLOBALUNDO) {
893                                 BKE_undo_step(1);
894                                 sound_initialize_sounds();
895                         }
896                 }
897         }
898 }
899
900 void BIF_redo(void)
901 {
902         if(G.obedit) {
903                 if ELEM7(G.obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE)
904                         undo_editmode_step(-1);
905         }
906         else {
907                 if(G.f & G_TEXTUREPAINT)
908                         imagepaint_undo();
909                 else if(G.f & G_SCULPTMODE)
910                         sculptmode_redo();
911                 else if(curarea->spacetype==SPACE_IMAGE && (G.sima->flag & SI_DRAWTOOL))
912                         imagepaint_undo();
913                 else {
914                         /* includes faceselect now */
915                         if(U.uiflag & USER_GLOBALUNDO) {
916                                 BKE_undo_step(-1);
917                                 sound_initialize_sounds();
918                         }
919                 }
920         }
921 }
922
923 void BIF_undo_menu(void)
924 {
925         if(G.obedit) {
926                 if ELEM7(G.obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE)
927                         undo_editmode_menu();
928                 allqueue(REDRAWALL, 0);
929         }
930         else {
931                 if(G.f & G_SCULPTMODE)
932                         sculptmode_undo_menu();
933                 else {
934                         if(U.uiflag & USER_GLOBALUNDO) {
935                                 char *menu= BKE_undo_menu_string();
936                                 if(menu) {
937                                         short event= pupmenu_col(menu, 20);
938                                         MEM_freeN(menu);
939                                         if(event>0) BKE_undo_number(event);
940                                 }
941                         }
942                 }
943         }
944 }
945
946 /* *************** */
947
948 void handle_view_middlemouse() {
949         /* use '&' here, because of alt+leftmouse which emulates middlemouse */
950         if(U.flag & USER_VIEWMOVE) {
951                 if((G.qual==LR_SHIFTKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_SHIFTKEY))))
952                         viewmove(0);
953                 else if((G.qual==LR_CTRLKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_CTRLKEY))))
954                         viewmove(2);
955                 else if((G.qual==0) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==LR_ALTKEY)))
956                         viewmove(1);
957         }
958         else {
959                 if((G.qual==LR_SHIFTKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_SHIFTKEY))))
960                         viewmove(1);
961                 else if((G.qual==LR_CTRLKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_CTRLKEY))))
962                         viewmove(2);
963                 else if((G.qual==0) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==LR_ALTKEY)))
964                         viewmove(0);
965         }
966 }
967
968 void handle_view_wheelup()
969 {
970         /* Regular:   Zoom in */
971         /* Shift:     Scroll up */
972         /* Ctrl:      Scroll right */
973         /* Alt-Shift: Rotate up */
974         /* Alt-Ctrl:  Rotate right */
975
976         if( G.qual & LR_SHIFTKEY ) {
977                 if( G.qual & LR_ALTKEY ) { 
978                         G.qual &= ~LR_SHIFTKEY;
979                         persptoetsen(PAD2);
980                         G.qual |= LR_SHIFTKEY;
981                 } else {
982                         persptoetsen(PAD2);
983                 }
984         } else if( G.qual & LR_CTRLKEY ) {
985                 if( G.qual & LR_ALTKEY ) { 
986                         G.qual &= ~LR_CTRLKEY;
987                         persptoetsen(PAD4);
988                         G.qual |= LR_CTRLKEY;
989                 } else {
990                         persptoetsen(PAD4);
991                 }
992         } else if(U.uiflag & USER_WHEELZOOMDIR) 
993                 persptoetsen(PADMINUS);
994         else
995                 persptoetsen(PADPLUSKEY);
996 }
997
998 void handle_view_wheeldown()
999 {
1000         /* Regular:   Zoom out */
1001         /* Shift:     Scroll down */
1002         /* Ctrl:      Scroll left */
1003         /* Alt-Shift: Rotate down */
1004         /* Alt-Ctrl:  Rotate left */
1005
1006         if( G.qual & LR_SHIFTKEY ) {
1007                 if( G.qual & LR_ALTKEY ) { 
1008                         G.qual &= ~LR_SHIFTKEY;
1009                         persptoetsen(PAD8);
1010                         G.qual |= LR_SHIFTKEY;
1011                 } else {
1012                         persptoetsen(PAD8);
1013                 }
1014         } else if( G.qual & LR_CTRLKEY ) {
1015                 if( G.qual & LR_ALTKEY ) { 
1016                         G.qual &= ~LR_CTRLKEY;
1017                         persptoetsen(PAD6);
1018                         G.qual |= LR_CTRLKEY;
1019                 } else {
1020                         persptoetsen(PAD6);
1021                 }
1022         } else if(U.uiflag & USER_WHEELZOOMDIR) 
1023                 persptoetsen(PADPLUSKEY);
1024         else
1025                 persptoetsen(PADMINUS);
1026 }
1027
1028 int mouse_in_header(ScrArea *sa)
1029 {
1030         short mouse[2];
1031         getmouseco_sc(mouse);
1032         return mouse[0] >= sa->headrct.xmin &&
1033                mouse[0] <= sa->headrct.xmax &&
1034                mouse[1] >= sa->headrct.ymin &&
1035                mouse[1] <= sa->headrct.ymax;
1036 }
1037
1038 static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
1039 {
1040         View3D *v3d= sa->spacedata.first;
1041         Object *ob= OBACT;      /* do not change! */
1042         float *curs;
1043         int doredraw= 0, pupval;
1044         unsigned short event= evt->event, origevent= evt->event;
1045         short val= evt->val;
1046         char ascii= evt->ascii;
1047         
1048         if(curarea->win==0) return;     /* when it comes from sa->headqread() */
1049         
1050         if(val) {
1051
1052                 if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0;
1053                 
1054                 if(event==UI_BUT_EVENT) do_butspace(val); /* temporal, view3d deserves own queue? */
1055                 
1056                 /* we consider manipulator a button, defaulting to leftmouse */
1057                 if(event==LEFTMOUSE) if(BIF_do_manipulator(sa)) return;
1058                 
1059                 /* swap mouse buttons based on user preference */
1060                 if (U.flag & USER_LMOUSESELECT) {
1061                         if (event==LEFTMOUSE) event = RIGHTMOUSE;
1062                         else if (event==RIGHTMOUSE) event = LEFTMOUSE;
1063                 }
1064
1065                 if(!mouse_in_header(sa)) {
1066                         if(!G.obedit && (G.f & G_SCULPTMODE)) {
1067                                 SculptSession *ss= sculpt_session();
1068                                 if(ss && ss->propset) {
1069                                         sculptmode_propset(event);
1070                                         return;
1071                                 }
1072                                 else if(event!=LEFTMOUSE && event!=MIDDLEMOUSE && (event==MOUSEY || event==MOUSEX)) {
1073                                         if(!bwin_qtest(sa->win))
1074                                                 allqueue(REDRAWVIEW3D, 0);
1075                                 }
1076                         }
1077
1078                         /* Handle retopo painting */
1079                         if(retopo_mesh_paint_check()) {
1080                                 if(!retopo_paint(event))
1081                                         return;
1082                         }
1083                 }
1084
1085                 /* run any view3d event handler script links */
1086                 if (event && sa->scriptlink.totscript)
1087                         if (BPY_do_spacehandlers(sa, event, SPACEHANDLER_VIEW3D_EVENT))
1088                                 return; /* return if event was processed (swallowed) by handler(s) */
1089
1090                 /* TEXTEDITING?? */
1091                 if((G.obedit) && G.obedit->type==OB_FONT) {
1092                         switch(event) {
1093                         
1094                         case LEFTMOUSE:
1095                                 mouse_cursor();
1096                                 break;
1097                         case MIDDLEMOUSE:
1098                                 /* use '&' here, because of alt+leftmouse which emulates middlemouse */
1099                                 if(U.flag & USER_VIEWMOVE) {
1100                                         if((G.qual==LR_SHIFTKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_SHIFTKEY))))
1101                                                 viewmove(0);
1102                                         else if((G.qual==LR_CTRLKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_CTRLKEY))))
1103                                                 viewmove(2);
1104                                         else if((G.qual==0) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==LR_ALTKEY)))
1105                                                 viewmove(1);
1106                                 }
1107                                 else {
1108                                         if((G.qual==LR_SHIFTKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_SHIFTKEY))))
1109                                                 viewmove(1);
1110                                         else if((G.qual==LR_CTRLKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_CTRLKEY))))
1111                                                 viewmove(2);
1112                                         else
1113                                                 viewmove(0);
1114                                 }
1115                                 break;
1116                                 
1117                         case WHEELUPMOUSE:
1118                                 /* Regular:   Zoom in */
1119                                 /* Shift:     Scroll up */
1120                                 /* Ctrl:      Scroll right */
1121                                 /* Alt-Shift: Rotate up */
1122                                 /* Alt-Ctrl:  Rotate right */
1123
1124                                 if( G.qual & LR_SHIFTKEY ) {
1125                                         if( G.qual & LR_ALTKEY ) { 
1126                                                 G.qual &= ~LR_SHIFTKEY;
1127                                                 persptoetsen(PAD2);
1128                                                 G.qual |= LR_SHIFTKEY;
1129                                         } else {
1130                                                 persptoetsen(PAD2);
1131                                         }
1132                                 } else if( G.qual & LR_CTRLKEY ) {
1133                                         if( G.qual & LR_ALTKEY ) { 
1134                                                 G.qual &= ~LR_CTRLKEY;
1135                                                 persptoetsen(PAD4);
1136                                                 G.qual |= LR_CTRLKEY;
1137                                         } else {
1138                                                 persptoetsen(PAD4);
1139                                         }
1140                                 } else if(U.uiflag & USER_WHEELZOOMDIR) 
1141                                         persptoetsen(PADMINUS);
1142                                 else
1143                                         persptoetsen(PADPLUSKEY);
1144
1145                                 doredraw= 1;
1146                                 break;
1147
1148                         case WHEELDOWNMOUSE:
1149                                 /* Regular:   Zoom out */
1150                                 /* Shift:     Scroll down */
1151                                 /* Ctrl:      Scroll left */
1152                                 /* Alt-Shift: Rotate down */
1153                                 /* Alt-Ctrl:  Rotate left */
1154
1155                                 if( G.qual & LR_SHIFTKEY ) {
1156                                         if( G.qual & LR_ALTKEY ) { 
1157                                                 G.qual &= ~LR_SHIFTKEY;
1158                                                 persptoetsen(PAD8);
1159                                                 G.qual |= LR_SHIFTKEY;
1160                                         } else {
1161                                                 persptoetsen(PAD8);
1162                                         }
1163                                 } else if( G.qual & LR_CTRLKEY ) {
1164                                         if( G.qual & LR_ALTKEY ) { 
1165                                                 G.qual &= ~LR_CTRLKEY;
1166                                                 persptoetsen(PAD6);
1167                                                 G.qual |= LR_CTRLKEY;
1168                                         } else {
1169                                                 persptoetsen(PAD6);
1170                                         }
1171                                 } else if(U.uiflag & USER_WHEELZOOMDIR) 
1172                                         persptoetsen(PADPLUSKEY);
1173                                 else
1174                                         persptoetsen(PADMINUS);
1175                                 
1176                                 doredraw= 1;
1177                                 break;
1178
1179                         case UKEY:
1180                                 if(G.qual==LR_ALTKEY) {
1181                                         remake_editText();
1182                                         doredraw= 1;
1183                                 } 
1184                                 else {
1185                                         do_textedit(event, val, ascii);
1186                                 }
1187                                 break;
1188                         case VKEY:
1189                                 if(G.qual==LR_ALTKEY) {
1190                                         paste_editText();
1191                                         doredraw= 1;
1192                                 } 
1193                                 else {
1194                                         do_textedit(event, val, ascii);
1195                                 }
1196                                 break;
1197                         case PAD0: case PAD1: case PAD2: case PAD3: case PAD4:
1198                         case PAD5: case PAD6: case PAD7: case PAD8: case PAD9:
1199                         case PADENTER:
1200                                 persptoetsen(event);
1201                                 doredraw= 1;
1202                                 break;
1203                                 
1204                         default:
1205                                 do_textedit(event, val, ascii);
1206                                 break;
1207                         }
1208                 }
1209                 else if(!G.obedit && (G.f & G_SCULPTMODE)) {
1210                         SculptData *sd= sculpt_data();
1211                         SculptSession *ss= sculpt_session();
1212                         BrushData *br= sculptmode_brush();
1213                         Mesh *me= get_mesh(OBACT);
1214                         char update_prop= 0;
1215                         
1216                         if(U.flag & USER_NONUMPAD) {
1217                                 event= convert_for_nonumpad(event);
1218                         }
1219                         
1220                         switch(event) {
1221                         case LEFTMOUSE:
1222                                 if(G.qual==LR_SHIFTKEY+LR_CTRLKEY)
1223                                         sculptmode_pmv(0);
1224                                 else if(!(ss && ss->propset))
1225                                         sculpt();
1226                                 break;
1227                         /* View */
1228                         case MIDDLEMOUSE:
1229                                 handle_view_middlemouse();
1230                                 break;
1231                         case WHEELUPMOUSE:
1232                                 handle_view_wheelup();
1233                                 doredraw= 1;
1234                                 break;
1235                         case WHEELDOWNMOUSE:
1236                                 handle_view_wheeldown();
1237                                 doredraw= 1;
1238                                 break;
1239                         case RIGHTMOUSE:
1240                                 if(G.qual==LR_SHIFTKEY+LR_CTRLKEY)
1241                                         sculptmode_pmv(1);
1242                                 break;
1243                         case PAD0: case PAD1: case PAD2: case PAD3: case PAD4:
1244                         case PAD5: case PAD6: case PAD7: case PAD8: case PAD9:
1245                         case PADPLUSKEY:
1246                         case PADMINUS:
1247                         case PADENTER:
1248                                 persptoetsen(event);
1249                                 doredraw= 1;
1250                                 break;
1251                         case BKEY:
1252                                 if(G.qual==LR_ALTKEY)
1253                                         view3d_edit_clipping(v3d);
1254                                 else if(G.qual==LR_SHIFTKEY) {
1255                                         if(G.vd->persp==2)
1256                                                 set_render_border();
1257                                         else
1258                                                 view3d_border_zoom();
1259                                 }
1260                                 break;
1261                         case PADSLASHKEY:
1262                                 if(!G.qual) {
1263                                         if(G.vd->localview) {
1264                                                 G.vd->localview= 0;
1265                                                 endlocalview(curarea);
1266                                         }
1267                                         else {
1268                                                 G.vd->localview= 1;
1269                                                 initlocalview();
1270                                         }
1271                                         allqueue(REDRAWVIEW3D, 1);
1272                                 }
1273                                 break;
1274                         /* Brush properties */
1275                         case AKEY:
1276                                 br->airbrush= !br->airbrush;
1277                                 update_prop= 1; break;
1278                         case FKEY:
1279                                 if(G.qual==0)
1280                                         sculptmode_propset_init(PropsetSize);
1281                                 if(G.qual==LR_SHIFTKEY)
1282                                         sculptmode_propset_init(PropsetStrength);
1283                                 if(G.qual==LR_CTRLKEY)
1284                                         sculptmode_propset_init(PropsetTexRot);
1285                                 break;
1286                         case VKEY:
1287                                 br->dir= br->dir==1 ? 2 : 1;
1288                                 update_prop= 1; break;
1289                         /* Set brush */
1290                         case DKEY:
1291                                 sd->brush_type= DRAW_BRUSH;
1292                                 update_prop= 1; break;
1293                         case SKEY:
1294                                 sd->brush_type= SMOOTH_BRUSH;
1295                                 update_prop= 1; break;
1296                         case PKEY:
1297                                 sd->brush_type= PINCH_BRUSH;
1298                                 update_prop= 1; break;
1299                         case IKEY:
1300                                 sd->brush_type= INFLATE_BRUSH;
1301                                 update_prop= 1; break;
1302                         case GKEY:
1303                                 sd->brush_type= GRAB_BRUSH;
1304                                 update_prop= 1; break;
1305                         case LKEY:
1306                                 sd->brush_type= LAYER_BRUSH;
1307                                 update_prop= 1; break;
1308                         /* Symmetry */
1309                         case XKEY:
1310                                 sd->symm^= SYMM_X;
1311                                 update_prop= 1; break;
1312                         case YKEY:
1313                                 sd->symm^= SYMM_Y;
1314                                 update_prop= 1; break;
1315                         case ZKEY:
1316                                 sd->symm^= SYMM_Z;
1317                                 update_prop= 1; break;
1318                         /* Interface */
1319                         case NKEY:
1320                                 if(G.qual==0) {
1321                                         toggle_blockhandler(curarea, VIEW3D_HANDLER_OBJECT, UI_PNL_TO_MOUSE);
1322                                         allqueue(REDRAWVIEW3D, 0);
1323                                 }
1324                                 break;
1325                         /* Multires */
1326                         case PAGEUPKEY:
1327                                 if(me && me->mr) {
1328                                         me->mr->newlvl= ((Mesh*)ob->data)->mr->current+1;
1329                                         multires_set_level(ob,ob->data);
1330                                 }
1331                                 break;
1332                         case PAGEDOWNKEY:
1333                                 if(me && me->mr) {
1334                                         me->mr->newlvl= ((Mesh*)ob->data)->mr->current-1;
1335                                         multires_set_level(ob,ob->data);
1336                                 }
1337                                 break;
1338                         /* Partial Visibility */
1339                         case HKEY:
1340                                 if(G.qual==LR_ALTKEY) {
1341                                         waitcursor(1);
1342                                         sculptmode_pmv_off(get_mesh(ob));
1343                                         BIF_undo_push("Partial mesh hide");
1344                                         allqueue(REDRAWVIEW3D,0);
1345                                         waitcursor(0);
1346                                 }
1347                                 break;
1348                         }
1349                         
1350                         /* Redraw buttons window as well as view 3d (for floating panel) */
1351                         if(update_prop) {
1352                                 allqueue(REDRAWVIEW3D, 0);
1353                                 allqueue(REDRAWBUTSEDIT, 0);
1354                         }
1355                 } else {
1356
1357                         if (U.flag & USER_NONUMPAD) {
1358                                 event= convert_for_nonumpad(event);
1359                         }
1360
1361                         switch(event) {
1362                         
1363                         /* Afterqueue events */
1364                         case BACKBUFDRAW:
1365                                 backdrawview3d(1);
1366                                 break;
1367                         case RENDERPREVIEW:
1368                                 BIF_view3d_previewrender(sa);
1369                                 break;
1370                                 
1371                         case TABKEY:
1372                                 // Shift-Tabe handling (other cases are in toets)
1373                                 if (G.qual == LR_SHIFTKEY)
1374                                 {
1375                                         // Snap toggle (only edit mesh right now)
1376                                         if (G.obedit && G.obedit->type==OB_MESH)
1377                                         {
1378                                                 G.vd->flag2 ^= V3D_TRANSFORM_SNAP;
1379                                                 allqueue(REDRAWHEADERS, 0);
1380                                         }                                       
1381                                 }
1382                                 break;
1383                                 
1384                         /* LEFTMOUSE and RIGHTMOUSE event codes can be swapped above,
1385                          * based on user preference USER_LMOUSESELECT
1386                          */
1387                         case LEFTMOUSE: 
1388                                 if ((G.obedit) || !(G.f&(G_VERTEXPAINT|G_WEIGHTPAINT|G_TEXTUREPAINT))) {
1389                                         mouse_cursor();
1390                                 }
1391                                 else if (G.f & G_WEIGHTPAINT) {
1392                                         weight_paint();
1393                                 }
1394                                 else if (G.f & G_VERTEXPAINT) {
1395                                         vertex_paint();
1396                                 }
1397                                 else if (G.f & G_TEXTUREPAINT) {
1398                                         imagepaint_paint(origevent==LEFTMOUSE? L_MOUSE: R_MOUSE, 1);
1399                                 }
1400                                 break;
1401                         case MIDDLEMOUSE:
1402                                 handle_view_middlemouse();
1403                                 break;
1404                         case RIGHTMOUSE:
1405                                 if((G.obedit) && (G.qual & LR_CTRLKEY)==0) {
1406                                         if(G.obedit->type==OB_MESH)
1407                                                 mouse_mesh();
1408                                         else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
1409                                                 mouse_nurb();
1410                                         else if(G.obedit->type==OB_MBALL)
1411                                                 mouse_mball();
1412                                         else if(G.obedit->type==OB_LATTICE)
1413                                                 mouse_lattice();
1414                                         else if(G.obedit->type==OB_ARMATURE)
1415                                                 mouse_armature();
1416                                 }
1417                                 else if((G.obedit && G.obedit->type==OB_MESH) && (G.qual == (LR_CTRLKEY|LR_ALTKEY)))
1418                                         mouse_mesh();   /* loop select for 1 mousebutton dudes */
1419                                 else if((G.obedit && G.obedit->type==OB_MESH) && (G.qual == (LR_CTRLKEY|LR_ALTKEY|LR_SHIFTKEY)))
1420                                         mouse_mesh();   /* loop select for 1 mousebutton dudes */
1421                                 else if(G.qual==LR_CTRLKEY)
1422                                         mouse_select(); /* also allow in editmode, for vertex parenting */
1423                                 else if(G.f & G_FACESELECT)
1424                                         face_select();
1425                                 else if( G.f & (G_VERTEXPAINT|G_TEXTUREPAINT))
1426                                         sample_vpaint();
1427                                 else
1428                                         mouse_select(); /* does poses too */
1429                                 break;
1430                         case WHEELUPMOUSE:
1431                                 handle_view_wheelup();
1432                                 doredraw= 1;
1433                                 break;
1434                         case WHEELDOWNMOUSE:
1435                                 handle_view_wheeldown();
1436                                 doredraw= 1;
1437                                 break;
1438
1439                         case ONEKEY:
1440                                 if(G.qual==LR_CTRLKEY) {
1441                                         flip_subdivison(1);
1442                                 }
1443                                 else do_layer_buttons(0); 
1444                                 break;
1445                                 
1446                         case TWOKEY:
1447                                 if(G.qual==LR_CTRLKEY) {
1448                                         flip_subdivison(2);
1449                                 }
1450                                 else do_layer_buttons(1); 
1451                                 break;
1452                                 
1453                         case THREEKEY:
1454                                 if(G.qual==LR_CTRLKEY) {
1455                                         flip_subdivison(3);
1456                                 }
1457                                 else if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
1458                                         if ( (G.obedit) && (G.obedit->type==OB_MESH) )
1459                                                 select_faces_by_numverts(3);
1460                                 }
1461                                 else do_layer_buttons(2); 
1462                                 break;
1463                                 
1464                         case FOURKEY:
1465                                 if(G.qual==LR_CTRLKEY) {
1466                                         flip_subdivison(4);
1467                                 }
1468                                 else if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
1469                                         if ( (G.obedit) && (G.obedit->type==OB_MESH) )
1470                                                 select_faces_by_numverts(4);
1471                                 }
1472                                 else do_layer_buttons(3); 
1473                                 break;
1474                                 
1475                         case FIVEKEY:
1476                                 if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
1477                                         if ( (G.obedit) && (G.obedit->type==OB_MESH) )
1478                                                 select_faces_by_numverts(5);
1479                                 }
1480                                 else do_layer_buttons(4);
1481                                 break;
1482
1483                         case SIXKEY:
1484                                 do_layer_buttons(5); break;
1485                         case SEVENKEY:
1486                                 do_layer_buttons(6); break;
1487                         case EIGHTKEY:
1488                                 do_layer_buttons(7); break;
1489                         case NINEKEY:
1490                                 do_layer_buttons(8); break;
1491                         case ZEROKEY:
1492                                 do_layer_buttons(9); break;
1493                         case MINUSKEY:
1494                                 do_layer_buttons(10); break;
1495                         case EQUALKEY:
1496                                 do_layer_buttons(11); break;
1497                         case ACCENTGRAVEKEY:
1498                                 do_layer_buttons(-1); break;
1499                         
1500                         case SPACEKEY:
1501                                 if(G.qual == LR_CTRLKEY) {
1502                                         val= pupmenu("Manipulator%t|Enable/Disable|Translate|Rotate|Scale|Combo");
1503                                         if(val>0) {
1504                                                 if(val==1) v3d->twflag ^= V3D_USE_MANIPULATOR;
1505                                                 else {
1506                                                         if(val==2) v3d->twtype= V3D_MANIP_TRANSLATE;
1507                                                         else if(val==3) v3d->twtype= V3D_MANIP_ROTATE;
1508                                                         else if(val==4) v3d->twtype= V3D_MANIP_SCALE;
1509                                                         else if(val==5) v3d->twtype= V3D_MANIP_TRANSLATE|V3D_MANIP_ROTATE|V3D_MANIP_SCALE;
1510                                                         v3d->twflag |= V3D_USE_MANIPULATOR;
1511                                                 }
1512                                                 doredraw= 1;
1513                                         }
1514                                 }
1515                                 else if(G.qual == LR_ALTKEY) {
1516                                         BIF_selectOrientation();
1517                                         doredraw= 1;
1518                                 }
1519
1520                                 break;
1521                                 
1522                         case AKEY:
1523                                 if(G.qual & LR_CTRLKEY) apply_object(); /* also with shift! */
1524                                 else if((G.qual==LR_SHIFTKEY)) {
1525                                         toolbox_n_add();
1526                                 }
1527                                 else {
1528                                         if(G.obedit) {
1529                                                 if(G.obedit->type==OB_MESH)
1530                                                         deselectall_mesh();
1531                                                 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
1532                                                         deselectall_nurb();
1533                                                 else if(G.obedit->type==OB_MBALL)
1534                                                         deselectall_mball();
1535                                                 else if(G.obedit->type==OB_LATTICE)
1536                                                         deselectall_Latt();
1537                                                 else if(G.obedit->type==OB_ARMATURE)
1538                                                         deselectall_armature(1);        /* 1 == toggle */
1539                                         }
1540                                         else if (ob && (ob->flag & OB_POSEMODE)){
1541                                                 deselectall_posearmature(ob, 1);
1542                                         }
1543                                         else {
1544                                                 if(G.f & G_FACESELECT) deselectall_tface();
1545                                                 else {
1546                                                         /* by design, the center of the active object 
1547                                                          * (which need not necessarily by selected) will
1548                                                          * still be drawn as if it were selected.
1549                                                          */
1550                                                         deselectall();
1551                                                 }
1552                                         }
1553                                 }
1554                                 break;
1555                         case BKEY:
1556                                 if(G.qual==LR_ALTKEY)
1557                                         view3d_edit_clipping(v3d);
1558                                 else if(G.qual==LR_SHIFTKEY)
1559                                 {
1560                                         if(G.vd->persp==2)
1561                                                 set_render_border();
1562                                         else
1563                                                 view3d_border_zoom();
1564                                 }
1565                                 else if(G.qual==LR_CTRLKEY) {
1566                                         if(okee("Bake all selected")) {
1567                                                 extern void softbody_bake(Object *ob);
1568                                                 extern void fluidsimBake(Object *ob);
1569                                                 softbody_bake(NULL);
1570                                                 /* also bake first domain of selected objects... */
1571                                                 fluidsimBake(NULL);
1572                                         }
1573                                 }
1574                                 else if(G.qual== (LR_ALTKEY|LR_CTRLKEY))
1575                                         objects_bake_render_menu();
1576                                 else if(G.qual==0)
1577                                         borderselect();
1578                                 break;
1579                         case CKEY:
1580                                 if(G.qual==LR_CTRLKEY) {
1581                                         if(ob && (ob->flag & OB_POSEMODE))
1582                                                 pose_copy_menu();       /* poseobject.c */
1583                                         else
1584                                                 copy_attr_menu();
1585                                 }
1586                                 else if(G.qual==LR_ALTKEY) {
1587                                         if(ob && (ob->flag & OB_POSEMODE))
1588                                                 pose_clear_constraints();       /* poseobject.c */
1589                                         else
1590                                                 convertmenu();  /* editobject.c */
1591                                 }
1592                                 else if(G.qual==(LR_ALTKEY|LR_CTRLKEY)) 
1593                                         add_constraint(0);      /* editconstraint.c, generic for objects and posemode */
1594                                 else if((G.qual==LR_SHIFTKEY)) {
1595                                         view3d_home(1);
1596                                         curs= give_cursor();
1597                                         curs[0]=curs[1]=curs[2]= 0.0;
1598                                         allqueue(REDRAWVIEW3D, 0);
1599                                 }
1600                                 else if((G.obedit) && ELEM(G.obedit->type, OB_CURVE, OB_SURF) ) {
1601                                         makecyclicNurb();
1602                                         DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
1603                                         allqueue(REDRAWVIEW3D, 0);
1604                                 }
1605                                 else if((G.qual==0)){
1606                                         if (G.vd->persp==2)
1607                                                 /* center the camera offset */
1608                                                 G.vd->camdx= G.vd->camdy= 0.0;
1609                                         else {
1610                                                 /*non camera center*/
1611                                                 curs= give_cursor();
1612                                                 G.vd->ofs[0]= -curs[0];
1613                                                 G.vd->ofs[1]= -curs[1];
1614                                                 G.vd->ofs[2]= -curs[2];
1615                                         }
1616                                         scrarea_queue_winredraw(curarea);
1617                                 }
1618                                 break;
1619                         case DKEY:
1620                                 if((G.qual==LR_SHIFTKEY)) {
1621                                         duplicate_context_selected();
1622                                 }
1623                                 else if(G.qual==LR_ALTKEY) {
1624                                         if(ob && (ob->flag & OB_POSEMODE))
1625                                                 error ("Duplicate not possible in posemode.");
1626                                         else if((G.obedit==NULL))
1627                                                 adduplicate(0, 0);
1628                                 }
1629                                 else if(G.qual==LR_CTRLKEY) {
1630                                         imagestodisplist();
1631                                 }
1632                                 else if((G.qual==0)){
1633                                         pupval= pupmenu("Draw mode%t|BoundBox %x1|Wire %x2|OpenGL Solid %x3|Shaded Solid %x4|Textured Solid %x5");
1634                                         if(pupval>0) {
1635                                                 G.vd->drawtype= pupval;
1636                                                 doredraw= 1;
1637                                         }
1638                                 }
1639                                 
1640                                 break;
1641                         case EKEY:
1642                                 if (G.qual==0){
1643                                         if(G.obedit) {
1644                                                 if(G.obedit->type==OB_MESH)
1645                                                         extrude_mesh();
1646                                                 else if(G.obedit->type==OB_CURVE)
1647                                                         addvert_Nurb('e');
1648                                                 else if(G.obedit->type==OB_SURF)
1649                                                         extrude_nurb();
1650                                                 else if(G.obedit->type==OB_ARMATURE)
1651                                                         extrude_armature(0);
1652                                         }
1653                                 }
1654                                 else if (G.qual==LR_CTRLKEY) {
1655                                         if(G.obedit && G.obedit->type==OB_MESH)
1656                                                 Edge_Menu();
1657                                         else if (G.f & G_FACESELECT)
1658                                                 seam_mark_clear_tface(0);
1659                                 }
1660                                 else if (G.qual==LR_SHIFTKEY) {
1661                                         if (G.obedit && G.obedit->type==OB_MESH) {
1662                                                 initTransform(TFM_CREASE, CTX_EDGE);
1663                                                 Transform();
1664                                         }
1665                                         else if (G.obedit && G.obedit->type==OB_ARMATURE) {
1666                                                 extrude_armature(1);
1667                                         }
1668                                 }
1669                                 break;
1670                         case FKEY:
1671                                 if(G.obedit) {
1672                                         if(G.obedit->type==OB_MESH) {
1673                                                 if((G.qual==LR_SHIFTKEY))
1674                                                         fill_mesh();
1675                                                 else if(G.qual==LR_ALTKEY)
1676                                                         beauty_fill();
1677                                                 else if(G.qual==LR_CTRLKEY)
1678                                                         edge_flip();
1679                                                 else if (G.qual==0)
1680                                                         addedgeface_mesh();
1681                                                 else if ( G.qual == 
1682                                                          (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
1683                                                         select_linked_flat_faces();
1684                                                 }
1685
1686                                         }
1687                                         else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) addsegment_nurb();
1688                                 }
1689                                 else if(G.qual==LR_CTRLKEY)
1690                                         sort_faces();
1691                                 else if((G.qual==LR_SHIFTKEY)) {
1692                                         if(ob && (ob->flag & OB_POSEMODE))
1693                                            pose_activate_flipped_bone();
1694                                         else if(G.f & G_WEIGHTPAINT)
1695                                                 pose_activate_flipped_bone();
1696                                         else
1697                                                 fly();
1698                                 }
1699                                 else {
1700                                         set_faceselect();
1701                                 }
1702                                 
1703                                 break;
1704                         case GKEY:
1705                                 if(G.qual == LR_CTRLKEY) 
1706                                         group_operation_with_menu();
1707                                 else if((G.qual==LR_SHIFTKEY))
1708                                         if(G.obedit) {
1709                                                 if(G.obedit->type==OB_MESH)
1710                                                         select_mesh_group_menu();
1711                                         } else
1712                                                 select_object_grouped_menu();
1713                                 else if(G.qual==LR_ALTKEY) {
1714                                         if(okee("Clear location")) {
1715                                                 clear_object('g');
1716                                         }
1717                                 }
1718                                 else if(G.qual== (LR_CTRLKEY|LR_ALTKEY)) {
1719                                         v3d->twtype= V3D_MANIP_TRANSLATE;
1720                                         doredraw= 1;
1721                                 }
1722                                 else if((G.qual==0)) {
1723                                         initTransform(TFM_TRANSLATION, CTX_NONE);
1724                                         Transform();
1725                                 }
1726                                 break;
1727                         case HKEY:
1728                                 if(G.obedit) {
1729                                         if(G.obedit->type==OB_MESH) {
1730                                                 if(G.qual==LR_CTRLKEY)
1731                                                         add_hook();
1732                                                 else if(G.qual==LR_ALTKEY)
1733                                                         reveal_mesh();
1734                                                 else if((G.qual==LR_SHIFTKEY))
1735                                                         hide_mesh(1);
1736                                                 else if((G.qual==0)) 
1737                                                         hide_mesh(0);
1738                                         }
1739                                         else if(G.obedit->type== OB_SURF) {
1740                                                 if(G.qual==LR_CTRLKEY)
1741                                                         add_hook();
1742                                                 else if(G.qual==LR_ALTKEY)
1743                                                         revealNurb();
1744                                                 else if((G.qual==LR_SHIFTKEY))
1745                                                         hideNurb(1);
1746                                                 else if((G.qual==0))
1747                                                         hideNurb(0);
1748                                         }
1749                                         else if(G.obedit->type==OB_CURVE) {
1750                                                 if(G.qual==LR_CTRLKEY)
1751                                                         add_hook();
1752                                                 else {
1753                                                         if(G.qual==LR_CTRLKEY)
1754                                                                 autocalchandlesNurb_all(1);     /* flag=1, selected */
1755                                                         else if((G.qual==LR_SHIFTKEY))
1756                                                                 sethandlesNurb(1);
1757                                                         else if((G.qual==0))
1758                                                                 sethandlesNurb(3);
1759                                                         
1760                                                         DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
1761                                                         BIF_undo_push("Handle change");
1762                                                         allqueue(REDRAWVIEW3D, 0);
1763                                                 }
1764                                         }
1765                                         else if(G.obedit->type==OB_LATTICE) {
1766                                                 if(G.qual==LR_CTRLKEY) add_hook();
1767                                         }
1768                                         else if(G.obedit->type==OB_MBALL) {
1769                                                 if(G.qual==LR_ALTKEY)
1770                                                         reveal_mball();
1771                                                 else if((G.qual==LR_SHIFTKEY))
1772                                                         hide_mball(1);
1773                                                 else if((G.qual==0)) 
1774                                                         hide_mball(0);
1775                                         }
1776                                         else if(G.obedit->type==OB_ARMATURE) {
1777                                                 if (G.qual==0)
1778                                                         hide_selected_armature_bones();
1779                                                 else if (G.qual==LR_SHIFTKEY)
1780                                                         hide_unselected_armature_bones();
1781                                                 else if (G.qual==LR_ALTKEY)
1782                                                         show_all_armature_bones();
1783                                         }
1784                                 }
1785                                 else if(G.f & G_FACESELECT)
1786                                         hide_tface();
1787                                 else if(ob && (ob->flag & OB_POSEMODE)) {
1788                                         if (G.qual==0)
1789                                                 hide_selected_pose_bones();
1790                                         else if (G.qual==LR_SHIFTKEY)
1791                                                 hide_unselected_pose_bones();
1792                                         else if (G.qual==LR_ALTKEY)
1793                                                 show_all_pose_bones();
1794                                 }
1795                                 break;
1796                         case IKEY:
1797                                 if(G.obedit);
1798                                 else if(G.qual==LR_CTRLKEY) {
1799                                         if(ob && ob->type==OB_ARMATURE) 
1800                                                 if(ob->flag & OB_POSEMODE) 
1801                                                         pose_add_IK();
1802                                 }
1803                                 else if(G.qual==LR_ALTKEY) {
1804                                         if(ob && ob->type==OB_ARMATURE) 
1805                                                 if(ob->flag & OB_POSEMODE) 
1806                                                         pose_clear_IK();
1807                                 }
1808                                 break;
1809                                 
1810                         case JKEY:
1811                                 if(G.qual==LR_CTRLKEY) {
1812                                         if( ob ) {
1813                                                 join_menu();
1814                                         }
1815                                         else if ((G.obedit) && ELEM(G.obedit->type, OB_CURVE, OB_SURF))
1816                                                 addsegment_nurb();
1817                                 }
1818                                 else if(G.obedit) {
1819                                         if(G.obedit->type==OB_MESH) {
1820                                                 join_triangles();
1821                                         }
1822                                 }
1823
1824                                 break;
1825                         case KKEY:
1826                                 if(G.obedit) {
1827                                         if (G.obedit->type==OB_MESH) {
1828                                                 if (G.qual==LR_SHIFTKEY)
1829                                                         KnifeSubdivide(KNIFE_PROMPT);
1830                                                 else if (G.qual==0)
1831                                                         LoopMenu();
1832                                         }
1833                                         else if(G.obedit->type==OB_SURF)
1834                                                 printknots();
1835                                 }
1836                                 else {
1837                                         if((G.qual==LR_SHIFTKEY)) {
1838                                                 if(G.f & G_FACESELECT)
1839                                                         if (G.f & G_WEIGHTPAINT)
1840                                                                 clear_wpaint_selectedfaces();
1841                                                         else
1842                                                                 clear_vpaint_selectedfaces();
1843                                                 else if(G.f & G_VERTEXPAINT)
1844                                                         clear_vpaint();
1845                                                 else
1846                                                         select_select_keys();
1847                                         }
1848                                         else if (G.qual==0)
1849                                                 set_ob_ipoflags();
1850                                 }
1851                                 
1852                                 break;
1853                         case LKEY:
1854                                 if(G.obedit) {
1855                                         if(G.obedit->type==OB_MESH)
1856                                                 selectconnected_mesh(G.qual);
1857                                         if(G.obedit->type==OB_ARMATURE)
1858                                                 selectconnected_armature();
1859                                         else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
1860                                                 selectconnected_nurb();
1861                                 }
1862                                 else if(ob && (ob->flag & OB_POSEMODE)) {
1863                                         selectconnected_posearmature();
1864                                 }
1865                                 else {
1866                                         if(G.f & G_FACESELECT) {
1867                                                 if((G.qual==0))
1868                                                         select_linked_tfaces(0);
1869                                                 else if((G.qual==LR_SHIFTKEY))
1870                                                         select_linked_tfaces(1);
1871                                                 else if(G.qual==LR_CTRLKEY)
1872                                                         select_linked_tfaces(2);
1873                                         }
1874                                         else {
1875                                                 if((G.qual==0))
1876                                                         make_local_menu();
1877                                                 else if((G.qual==LR_SHIFTKEY))
1878                                                         selectlinks_menu();
1879                                                 else if(G.qual==LR_CTRLKEY)
1880                                                         make_links_menu();
1881                                         }
1882                                 }
1883                                 break;
1884                         case MKEY:
1885                                 if((G.obedit==0) && (G.f & G_FACESELECT) && (G.qual==0))
1886                                         mirror_uv_tface();
1887                                 else if(G.obedit){
1888                                         if(G.qual==LR_ALTKEY) {
1889                                                 if(G.obedit->type==OB_MESH) {
1890                                                         mergemenu();
1891                                                         DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
1892                                                 }
1893                                         }
1894                                         else if((G.qual==0) || (G.qual==LR_CTRLKEY)) {
1895                                                 mirrormenu();
1896                                         }
1897                                         if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
1898                                                 if(G.obedit->type==OB_MESH) select_non_manifold();
1899                                         }
1900                                 }
1901                                 else if(G.qual & LR_CTRLKEY) {
1902                                         mirrormenu();
1903                                 }
1904                                 else if(G.qual==0 || G.qual==LR_SHIFTKEY) {
1905                                         if(ob && (ob->flag & OB_POSEMODE))
1906                                                 pose_movetolayer();
1907                                         else
1908                                                 movetolayer();
1909                                 }
1910                                 break;
1911                         case NKEY:
1912                                 if((G.qual==0)) {
1913                                         toggle_blockhandler(curarea, VIEW3D_HANDLER_OBJECT, UI_PNL_TO_MOUSE);
1914                                         allqueue(REDRAWVIEW3D, 0);
1915                                 }
1916                                 else if(G.obedit) {
1917                                         switch (G.obedit->type){
1918                                         case OB_ARMATURE:
1919                                                 if(G.qual==LR_CTRLKEY){
1920                                                         if (okee("Recalculate bone roll angles")) {
1921                                                                 auto_align_armature();
1922                                                                 allqueue(REDRAWVIEW3D, 0);
1923                                                         }
1924                                                 }
1925                                                 break;
1926                                         case OB_MESH: 
1927                                                 if(G.qual==(LR_SHIFTKEY|LR_CTRLKEY)) {
1928                                                         if(okee("Recalculate normals inside")) {
1929                                                                 righthandfaces(2);
1930                                                                 allqueue(REDRAWVIEW3D, 0);
1931                                                                 BIF_undo_push("Recalculate normals inside");
1932                                                         }
1933                                                 }
1934                                                 else if(G.qual==LR_CTRLKEY){
1935                                                         if(okee("Recalculate normals outside")) {
1936                                                                 righthandfaces(1);
1937                                                                 allqueue(REDRAWVIEW3D, 0);
1938                                                                 BIF_undo_push("Recalculate normals outside");
1939                                                         }
1940                                                 }
1941                                                 break;
1942                                         }
1943                                 }
1944                                 
1945                                 break;
1946                         case OKEY:
1947                                 if (G.obedit) {
1948                                         if (G.qual==LR_SHIFTKEY) {
1949                                                 G.scene->prop_mode = (G.scene->prop_mode+1)%7;
1950                                                 allqueue(REDRAWHEADERS, 0);
1951                                         }
1952                                         else if((G.qual==LR_ALTKEY)) {
1953                                                 if(G.scene->proportional==2) G.scene->proportional= 1;
1954                                                 else G.scene->proportional= 2;
1955                                                 allqueue(REDRAWHEADERS, 0);
1956                                         }
1957                                         else if((G.qual==0)) {
1958                                                 G.scene->proportional= !G.scene->proportional;
1959                                                 allqueue(REDRAWHEADERS, 0);
1960                                         }
1961                                 }
1962                                 else if((G.qual==LR_SHIFTKEY || G.qual==(LR_ALTKEY|LR_SHIFTKEY))) {
1963                                         flip_subdivison(-1);
1964                                 }
1965                                 else if(G.qual==LR_ALTKEY) {
1966                                         if(okee("Clear origin")) {
1967                                                 clear_object('o');
1968                                         }
1969                                 }
1970                                 break;
1971
1972                         case PKEY:
1973                                 if(G.obedit) {
1974                                         if(G.qual==LR_CTRLKEY || G.qual==(LR_SHIFTKEY|LR_CTRLKEY)) {
1975                                                 if(G.obedit->type==OB_ARMATURE)
1976                                                         make_bone_parent();
1977                                                 else
1978                                                         make_parent();
1979                                         }
1980                                         
1981                                         else if(G.qual==LR_ALTKEY && G.obedit->type==OB_ARMATURE)
1982                                                 clear_bone_parent();
1983                                         else if((G.qual==0) && (G.obedit->type==OB_ARMATURE)) 
1984                                                 select_bone_parent();
1985                                         else if((G.qual==0) && G.obedit->type==OB_MESH)
1986                                                 separatemenu();
1987                                         else if ((G.qual==0) && ELEM(G.obedit->type, OB_CURVE, OB_SURF))
1988                                                 separate_nurb();
1989                                         else if (G.qual==LR_SHIFTKEY) {
1990                                                 initTransform(TFM_PUSHPULL, CTX_NONE);
1991                                                 Transform();
1992                                         }
1993                                 }
1994                                 else if(G.qual==LR_CTRLKEY || G.qual==(LR_SHIFTKEY|LR_CTRLKEY))
1995                                         make_parent();
1996                                 else if(G.qual==LR_SHIFTKEY) {
1997                                         toggle_blockhandler(curarea, VIEW3D_HANDLER_PREVIEW, 0);
1998                                         doredraw= 1;
1999                                 }
2000                                 else if(G.qual==(LR_ALTKEY|LR_SHIFTKEY)) {
2001                                         initTransform(TFM_PUSHPULL, CTX_NONE);
2002                                         Transform();
2003                                 }
2004                                 else if(G.qual==LR_ALTKEY)
2005                                         clear_parent();
2006                                 else if(G.qual==(LR_ALTKEY|LR_CTRLKEY))
2007                                         make_proxy();
2008                                 else if(G.qual==(LR_ALTKEY|LR_CTRLKEY|LR_SHIFTKEY)) {
2009                         start_RBSimulation();
2010                                 }
2011                                 else if((G.qual==0) && (OBACT) && (OBACT->type==OB_ARMATURE) && (OBACT->flag & OB_POSEMODE))
2012                                         select_bone_parent();
2013                                 else if((G.qual==0)) {
2014                         start_game();
2015                                 }
2016                                 break;                          
2017                         case RKEY:
2018                                 if((G.obedit==0) && (G.f & G_FACESELECT) && (G.qual==0) && !(G.f & G_WEIGHTPAINT))
2019                                         rotate_uv_tface();
2020                                 else if(G.qual==LR_ALTKEY) {
2021                                         if(okee("Clear rotation")) {
2022                                                 clear_object('r');
2023                                         }
2024                                 } 
2025                                 else if(G.qual== (LR_CTRLKEY|LR_ALTKEY)) {
2026                                         v3d->twtype= V3D_MANIP_ROTATE;
2027                                         doredraw= 1;
2028                                 }
2029                                 else if (G.obedit) {
2030                                         if((G.qual==LR_SHIFTKEY)) {
2031                                                 if ELEM(G.obedit->type,  OB_CURVE, OB_SURF)                                     
2032                                                         selectrow_nurb();
2033                                         }
2034                                         else if(G.qual==LR_CTRLKEY) {
2035                                                 if (G.obedit->type==OB_MESH) {
2036                                                         CutEdgeloop(1);
2037                                                         BIF_undo_push("Cut Edgeloop");
2038                                                 }
2039                                                 else if (G.obedit->type==OB_ARMATURE) {
2040                                                         initTransform(TFM_BONE_ROLL, CTX_NONE);
2041                                                         Transform();
2042                                                 }
2043                                         }
2044                                         else if((G.qual==0)) {
2045                                                 initTransform(TFM_ROTATION, CTX_NONE);
2046                                                 Transform();
2047                                         }
2048                                 }
2049                                 else if((G.qual==0)) {
2050                                         initTransform(TFM_ROTATION, CTX_NONE);
2051                                         Transform();
2052                                 }
2053                                 break;
2054                         case SKEY:
2055                                 if(G.qual== (LR_CTRLKEY|LR_ALTKEY)) {
2056                                         v3d->twtype= V3D_MANIP_SCALE;
2057                                         doredraw= 1;
2058                                 }
2059                                 else if(G.obedit) {
2060                                         
2061                                         if(G.qual==LR_ALTKEY) {
2062                                                 if(G.obedit->type==OB_ARMATURE) {
2063                                                         initTransform(TFM_BONESIZE, CTX_NONE);
2064                                                 }
2065                                                 else if (G.obedit->type==OB_CURVE) {
2066                                                         initTransform(TFM_CURVE_SHRINKFATTEN, CTX_NONE);
2067                                                 } else {
2068                                                         initTransform(TFM_SHRINKFATTEN, CTX_NONE);
2069                                                 }
2070                                                 Transform();
2071                                         }
2072                                         else if(G.qual==LR_CTRLKEY) {
2073                                                 initTransform(TFM_SHEAR, CTX_NONE);
2074                                                 Transform();
2075                                         }
2076                                         else if(G.qual==LR_SHIFTKEY)
2077                                                 snapmenu();
2078                                         else if(G.qual==0) {
2079                                                 if(G.obedit->type==OB_ARMATURE) {
2080                                                         bArmature *arm= G.obedit->data;
2081                                                         if(arm->drawtype==ARM_ENVELOPE)
2082                                                                 initTransform(TFM_BONE_ENVELOPE, CTX_NONE);
2083                                                         else
2084                                                                 initTransform(TFM_RESIZE, CTX_NONE);
2085                                                 }
2086                                                 else
2087                                                         initTransform(TFM_RESIZE, CTX_NONE);
2088                                                 Transform();
2089                                         }
2090                                         else if(G.qual==(LR_SHIFTKEY|LR_CTRLKEY)){
2091                                                 initTransform(TFM_TOSPHERE, CTX_NONE);
2092                                                 Transform();
2093                                         }
2094                                         if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
2095                                                 if(G.obedit->type==OB_MESH) select_sharp_edges();
2096                                         }
2097                                 }
2098                                 else if(G.qual==LR_ALTKEY) {
2099                                         if(G.f & G_WEIGHTPAINT)
2100                                                 ob= ob->parent;
2101                                         if(ob && (ob->flag & OB_POSEMODE)) {
2102                                                 bArmature *arm= ob->data;
2103                                                 if( ELEM(arm->drawtype, ARM_B_BONE, ARM_ENVELOPE)) {
2104                                                         initTransform(TFM_BONESIZE, CTX_NONE);
2105                                                         Transform();
2106                                                         break;
2107                                                 }
2108                                         }
2109                                         
2110                                         if(okee("Clear scale")) {
2111                                                 clear_object('s');
2112                                         }
2113                                 }
2114                                 else if(G.qual==LR_SHIFTKEY) {
2115                                         snapmenu();
2116                                 }
2117                                 else if((G.qual==0)) {
2118                                         initTransform(TFM_RESIZE, CTX_NONE);
2119                                         Transform();
2120                                 }
2121                                 else if(G.qual==(LR_SHIFTKEY|LR_CTRLKEY)) {
2122                                         initTransform(TFM_TOSPHERE, CTX_NONE);
2123                                         Transform();
2124                                 }
2125                                 else if(G.qual==(LR_CTRLKEY|LR_ALTKEY|LR_SHIFTKEY)) {
2126                                         initTransform(TFM_SHEAR, CTX_NONE);
2127                                         Transform();
2128                                 }
2129                                 break;
2130                         case TKEY:
2131                                 if(G.obedit){
2132                                         if((G.qual & LR_CTRLKEY) && G.obedit->type==OB_MESH) {
2133                                                 convert_to_triface(G.qual & LR_SHIFTKEY);
2134                                                 allqueue(REDRAWVIEW3D, 0);
2135                                                 countall();
2136                                                 DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
2137                                         }
2138                                         if (G.obedit->type==OB_CURVE) {
2139                                                 if (G.qual==LR_ALTKEY) {
2140                                                         clear_tilt();
2141                                                 }
2142                                                 else if (G.qual==0) {
2143                                                         initTransform(TFM_TILT, CTX_NONE);
2144                                                         Transform();
2145                                                 }
2146                                         }
2147                                 }
2148                                 else if(G.qual==LR_CTRLKEY) {
2149                                         if(ob && (ob->flag & OB_POSEMODE));
2150                                         else make_track();
2151                                 }
2152                                 else if(G.qual==LR_ALTKEY) {
2153                                         if(ob && (ob->flag & OB_POSEMODE));
2154                                         else clear_track();
2155                                 }
2156                                 else if((G.qual==0)){
2157                                         texspace_edit();
2158                                 }
2159                                 
2160                                 break;
2161                         case UKEY:
2162                                 if(G.obedit) {
2163                                         if(G.obedit->type==OB_MESH) {
2164                                                 if(G.qual==0) BIF_undo(); else BIF_redo();
2165                                         }
2166                                         else if ELEM5(G.obedit->type, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE) {
2167                                                 if(G.qual==0) BIF_undo(); else BIF_redo();
2168                                         }
2169                                 }
2170                                 else if((G.qual==0)) {
2171                                         if(G.f & G_WEIGHTPAINT)
2172                                                 BIF_undo();
2173                                         else if(G.f & G_VERTEXPAINT)
2174                                                 BIF_undo();
2175                                         else if(G.f & G_TEXTUREPAINT)
2176                                                 imagepaint_undo();
2177                                         else if (G.f & G_FACESELECT)
2178                                                 uv_autocalc_tface();
2179                                         else {
2180                                                 single_user();
2181                                         }
2182                                 }
2183                                         
2184                                 break;
2185                         case VKEY:
2186                                 if((G.qual==LR_SHIFTKEY)) {
2187                                         if ((G.obedit) && G.obedit->type==OB_MESH) {
2188                                                 align_view_to_selected(v3d);
2189                                         }
2190                                         else if (G.f & G_FACESELECT) {
2191                                                 align_view_to_selected(v3d);
2192                                         }
2193                                 }
2194                                 else if(G.qual==LR_ALTKEY)
2195                                         image_aspect();
2196                                 else if (G.qual==0){
2197                                         if(G.obedit) {
2198                                                 if(G.obedit->type==OB_MESH) {
2199                                                         mesh_rip();
2200                                                 }
2201                                                 else if(G.obedit->type==OB_CURVE) {
2202                                                         sethandlesNurb(2);
2203                                                         DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
2204                                                         allqueue(REDRAWVIEW3D, 0);
2205                                                         BIF_undo_push("Handle change");
2206                                                 }
2207                                         }
2208                                         else if(ob && ob->type == OB_MESH) 
2209                                                 set_vpaint();
2210                                 }
2211                                 break;
2212                         case WKEY:
2213                                 if((G.qual==LR_SHIFTKEY)) {
2214                                         initTransform(TFM_WARP, CTX_NONE);
2215                                         Transform();
2216                                 }
2217                                 else if(G.qual==LR_ALTKEY) {
2218                                         /* if(G.obedit && G.obedit->type==OB_MESH) write_videoscape(); */
2219                                 }
2220                                 else if(G.qual==LR_CTRLKEY) {
2221                                         if(G.obedit) {
2222                                                 if ELEM(G.obedit->type,  OB_CURVE, OB_SURF) {
2223                                                         switchdirectionNurb2();
2224                                                 }
2225                                         }
2226                                 }
2227                                 else if((G.qual==0))
2228                                         special_editmenu();
2229                                 
2230                                 break;
2231                         case XKEY:
2232                         case DELKEY:
2233                                 if(G.qual==0 || G.qual==LR_SHIFTKEY)
2234                                         delete_context_selected();
2235                                 break;
2236                         case YKEY:
2237                                 if((G.qual==0) && (G.obedit)) {
2238                                         if(G.obedit->type==OB_MESH) split_mesh();
2239                                 }
2240                                 break;
2241                         case ZKEY:
2242                                 toggle_shading();
2243                                 
2244                                 scrarea_queue_headredraw(curarea);
2245                                 scrarea_queue_winredraw(curarea);
2246                                 break;
2247                         
2248                         case HOMEKEY:
2249                                 if(G.qual==0)
2250                                         view3d_home(0);
2251                                 break;
2252                         case COMMAKEY:
2253                                 if(G.qual==LR_CTRLKEY) {
2254                                         G.vd->around= V3D_CENTROID;
2255                                 } else if(G.qual==LR_SHIFTKEY) {
2256                                         G.vd->around= V3D_CENTROID;
2257                                 } else if(G.qual==0) {
2258                                         G.vd->around= V3D_CENTRE;
2259                                 }
2260                                 handle_view3d_around();
2261                                 
2262                                 scrarea_queue_headredraw(curarea);
2263                                 scrarea_queue_winredraw(curarea);
2264                                 break;
2265                                 
2266                         case PERIODKEY:
2267                                 if(G.qual==LR_CTRLKEY) {
2268                                         G.vd->around= V3D_LOCAL;
2269                                 }       else if(G.qual==0) {
2270                                         G.vd->around= V3D_CURSOR;
2271                                 }
2272                                 handle_view3d_around();
2273                                 
2274                                 scrarea_queue_headredraw(curarea);
2275                                 scrarea_queue_winredraw(curarea);
2276                                 break;
2277                         
2278                         case PADSLASHKEY:
2279                                 if(G.qual==0) {
2280                                         if(G.vd->localview) {
2281                                                 G.vd->localview= 0;
2282                                                 endlocalview(curarea);
2283                                         }
2284                                         else {
2285                                                 G.vd->localview= 1;
2286                                                 initlocalview();
2287                                         }
2288                                         scrarea_queue_headredraw(curarea);
2289                                 }
2290                                 break;
2291                         case PADASTERKEY:       /* '*' */
2292                                 if(G.qual==0) {
2293                                         if(ob) {
2294                                                 if ((G.obedit) && (G.obedit->type == OB_MESH)) {
2295                                                         editmesh_align_view_to_selected(G.vd, 2);
2296                                                 } 
2297                                                 else if (G.f & G_FACESELECT) {
2298                                                         if(ob->type==OB_MESH) {
2299                                                                 Mesh *me= ob->data;
2300                                                                 faceselect_align_view_to_selected(G.vd, me, 2);
2301                                                         }
2302                                                 }
2303                                                 else
2304                                                         obmat_to_viewmat(ob);
2305                                                 
2306                                                 if(G.vd->persp==2) G.vd->persp= 1;
2307                                                 scrarea_queue_winredraw(curarea);
2308                                         }
2309                                 }
2310                                 break;
2311                         case PADPERIOD: /* '.' */
2312                                 if(G.qual==0)
2313                                         centreview();
2314                                 break;
2315                         
2316                         case PAGEUPKEY:
2317                                 if(G.qual==LR_CTRLKEY)
2318                                         movekey_obipo(1);
2319                                 else if((G.qual==0))
2320                                         nextkey_obipo(1);       /* in editipo.c */
2321                                 break;
2322
2323                         case PAGEDOWNKEY:
2324                                 if(G.qual==LR_CTRLKEY)
2325                                         movekey_obipo(-1);
2326                                 else if((G.qual==0))
2327                                         nextkey_obipo(-1);
2328                                 break;
2329
2330                         case PAD0: case PAD1: case PAD2: case PAD3: case PAD4:
2331                         case PAD5: case PAD6: case PAD7: case PAD8: case PAD9:
2332                         case PADENTER:
2333                                 persptoetsen(event);
2334                                 doredraw= 1;
2335                                 break;
2336                         case PADMINUS:
2337                                 if ( (G.qual==LR_CTRLKEY)
2338                                          && (G.obedit) && (G.obedit->type==OB_MESH) )
2339                                         select_less();
2340                                 else if ( (G.qual==LR_CTRLKEY)
2341                                          && (G.obedit) && (G.obedit->type==OB_CURVE) )
2342                                         select_less_nurb();
2343                                 /*
2344                                 else if ( (G.qual==LR_CTRLKEY)
2345                                          && (G.obedit) && (G.obedit->type==OB_SURF) )
2346                                         select_less_nurb(); 
2347                                 */
2348                                 else {
2349                                         persptoetsen(event);
2350                                         doredraw= 1;
2351                                 }
2352                                 break;
2353
2354                         case PADPLUSKEY:
2355                                 if ( (G.qual==LR_CTRLKEY)
2356                                          && (G.obedit) && (G.obedit->type==OB_MESH) )
2357                                         select_more();
2358                                 else if ( (G.qual==LR_CTRLKEY)
2359                                          && (G.obedit) && (G.obedit->type==OB_CURVE) )
2360                                         select_more_nurb();
2361                                 /*
2362                                 else if ( (G.qual==LR_CTRLKEY)
2363                                          && (G.obedit) && (G.obedit->type==OB_SURF) )
2364                                         select_more_nurb();
2365                                 */
2366                                 else {
2367                                         persptoetsen(event);
2368                                         doredraw= 1;
2369                                 }
2370                                 break;
2371
2372                         case ESCKEY:
2373                                 if(G.qual==0) {
2374                                         if (G.vd->flag & V3D_DISPIMAGE) {
2375                                                 G.vd->flag &= ~V3D_DISPIMAGE;
2376                                                 doredraw= 1;
2377                                         }
2378                                 }
2379                                 break;
2380                         }
2381                 }
2382         }
2383         
2384         if(doredraw) {
2385                 scrarea_queue_winredraw(curarea);
2386                 scrarea_queue_headredraw(curarea);
2387         }
2388 }
2389
2390 static void initview3d(ScrArea *sa)
2391 {
2392         View3D *vd;
2393         
2394         vd= MEM_callocN(sizeof(View3D), "initview3d");
2395         BLI_addhead(&sa->spacedata, vd);        /* addhead! not addtail */
2396
2397         vd->spacetype= SPACE_VIEW3D;
2398         vd->blockscale= 0.7f;
2399         vd->viewquat[0]= 1.0f;
2400         vd->viewquat[1]= vd->viewquat[2]= vd->viewquat[3]= 0.0f;
2401         vd->persp= 1;
2402         vd->drawtype= OB_WIRE;
2403         vd->view= 7;
2404         vd->dist= 10.0;
2405         vd->lens= 35.0f;
2406         vd->near= 0.01f;
2407         vd->far= 500.0f;
2408         vd->grid= 1.0f;
2409         vd->gridlines= 16;
2410         vd->lay= vd->layact= 1;
2411         if(G.scene) {
2412                 vd->lay= vd->layact= G.scene->lay;
2413                 vd->camera= G.scene->camera;
2414         }
2415         vd->scenelock= 1;
2416         vd->gridflag |= V3D_SHOW_X;
2417         vd->gridflag |= V3D_SHOW_Y;
2418         vd->gridflag |= V3D_SHOW_FLOOR;
2419         vd->gridflag &= ~V3D_SHOW_Z;
2420
2421         vd->depths= NULL;
2422 }
2423
2424
2425 /* ******************** SPACE: IPO ********************** */
2426
2427 static void changeview2dspace(ScrArea *sa, void *spacedata)
2428 {
2429         if(G.v2d==0) return;
2430
2431         test_view2d(G.v2d, curarea->winx, curarea->winy);
2432         myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
2433 }
2434
2435 static void winqreadipospace(ScrArea *sa, void *spacedata, BWinEvent *evt)
2436 {
2437         extern void do_ipobuts(unsigned short event);   /* drawipo.c */
2438         unsigned short event= evt->event;
2439         short val= evt->val;
2440         SpaceIpo *sipo= curarea->spacedata.first;
2441         View2D *v2d= &sipo->v2d;
2442         float dx, dy;
2443         int cfra, doredraw= 0;
2444         short mval[2];
2445         short mousebut = L_MOUSE;
2446         
2447         if(sa->win==0) return;
2448
2449         if(val) {
2450                 if( uiDoBlocks(&sa->uiblocks, event)!=UI_NOTHING ) event= 0;
2451
2452                 /* swap mouse buttons based on user preference */
2453                 if (U.flag & USER_LMOUSESELECT) {
2454                         if (event == LEFTMOUSE) {
2455                                 event = RIGHTMOUSE;
2456                                 mousebut = L_MOUSE;
2457                         } else if (event == RIGHTMOUSE) {
2458                                 event = LEFTMOUSE;
2459                                 mousebut = R_MOUSE;
2460                         }
2461                 }
2462
2463                 switch(event) {
2464                 case UI_BUT_EVENT:
2465                         /* note: bad bad code, will be cleaned! is because event queues are all shattered */
2466                         if(val>0 && val < 256) do_ipowin_buts(val-1);
2467                         else do_ipobuts(val);
2468                         break;
2469                         
2470                 case LEFTMOUSE:
2471                         if( in_ipo_buttons() ) {
2472                                 do_ipo_selectbuttons();
2473                                 doredraw= 1;
2474                         }
2475                         else if(view2dmove(LEFTMOUSE)); /* only checks for sliders */
2476                         else if(G.qual & LR_CTRLKEY) add_vert_ipo();
2477                         else {
2478                                 do {
2479                                         getmouseco_areawin(mval);
2480                                         areamouseco_to_ipoco(v2d, mval, &dx, &dy);
2481                                         
2482                                         cfra= (int)dx;
2483                                         if(cfra< 1) cfra= 1;
2484                                         
2485                                         if( cfra!=CFRA ) {
2486                                                 CFRA= cfra;
2487                                                 update_for_newframe_nodraw(0);  /* 1 = nosound */
2488                                                 force_draw_all(0); /* To make constraint sliders redraw */
2489                                         }
2490                                         else PIL_sleep_ms(30);
2491                                 
2492                                 } while(get_mbut() & mousebut);
2493                         }
2494                         break;
2495                 case RIGHTMOUSE:
2496                         mouse_select_ipo();
2497                         allqueue(REDRAWTIME, 0);
2498                         allqueue(REDRAWIPO, 0);
2499                         allqueue(REDRAWACTION, 0);
2500                         allqueue(REDRAWNLA, 0);
2501                         allqueue(REDRAWSOUND, 0);
2502                         break;
2503                 case MIDDLEMOUSE:
2504                         if(in_ipo_buttons()) {
2505                                 scroll_ipobuts();
2506                         }
2507                         else view2dmove(event); /* in drawipo.c */
2508                         break;
2509                 case WHEELUPMOUSE:
2510                 case WHEELDOWNMOUSE:
2511                         view2dmove(event);      /* in drawipo.c */
2512                         break;
2513                 case PADPLUSKEY:
2514                         view2d_zoom(v2d, 0.1154f, sa->winx, sa->winy);
2515                         doredraw= 1;
2516                         break;
2517                 case PADMINUS:
2518                         view2d_zoom(v2d, -0.15f, sa->winx, sa->winy);
2519                         doredraw= 1;
2520                         break;
2521                 case PAGEUPKEY:
2522                         if(G.qual & LR_CTRLKEY)
2523                                 movekey_ipo(1);
2524                         else if(G.qual & LR_SHIFTKEY)
2525                                 nextkey_ipo(1);
2526                         else
2527                                 nextprev_marker(1);
2528                         break;
2529                 case PAGEDOWNKEY:
2530                         if(G.qual & LR_CTRLKEY)
2531                                 movekey_ipo(-1);
2532                         else if(G.qual & LR_SHIFTKEY)
2533                                 nextkey_ipo(-1);
2534                         else
2535                                 nextprev_marker(-1);
2536                         break;
2537                 case HOMEKEY:
2538                         if((G.qual==0))
2539                                 do_ipo_buttons(B_IPOHOME);
2540                         break;
2541                         
2542                 case AKEY:
2543                         if (G.qual & LR_CTRLKEY) {
2544                                 deselect_markers(1, 0);
2545                                 allqueue(REDRAWTIME, 0);
2546                                 allqueue(REDRAWIPO, 0);
2547                                 allqueue(REDRAWACTION, 0);
2548                                 allqueue(REDRAWNLA, 0);
2549                                 allqueue(REDRAWSOUND, 0);
2550                         }
2551                         else if (G.qual==0) {
2552                                 if(in_ipo_buttons()) {
2553                                         swap_visible_editipo();
2554                                 }
2555                                 else {
2556                                         swap_selectall_editipo();
2557                                 }
2558                                 allspace (REMAKEIPO, 0);
2559                                 allqueue (REDRAWNLA, 0);
2560                                 allqueue (REDRAWACTION, 0);
2561                         }
2562                         
2563                         break;
2564                 case BKEY:
2565                         if (G.qual==0)
2566                                 borderselect_ipo();
2567                         else if (G.qual==LR_CTRLKEY) {
2568                                 borderselect_markers();
2569                         }
2570                         break;
2571                 case CKEY:
2572                         if (G.qual==0)
2573                                 move_to_frame();
2574                         break;
2575                 case DKEY:
2576                         if (G.qual==LR_SHIFTKEY)
2577                                 add_duplicate_editipo();
2578                         else if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY))
2579                                 duplicate_marker();
2580                         break;
2581                 case GKEY:
2582                         if (G.qual & LR_CTRLKEY)
2583                                 transform_markers('g', 0);
2584                         else if (G.qual==0)
2585                                 transform_ipo('g');
2586                         break;
2587                 case HKEY:
2588                         if (G.qual==LR_ALTKEY)
2589                                 sethandles_ipo(HD_AUTO_ANIM);
2590                         if (G.qual==LR_SHIFTKEY)
2591                                 sethandles_ipo(HD_AUTO);
2592                         else if (G.qual==0)
2593                                 sethandles_ipo(HD_ALIGN);
2594                         break;
2595                 case JKEY:
2596                         if (G.qual==LR_CTRLKEY)
2597                                 join_ipo_menu();
2598                         break;
2599                 case KKEY:
2600                         if (G.qual==0) {
2601                                 ipo_toggle_showkey();
2602                                 scrarea_queue_headredraw(curarea);
2603                                 allqueue(REDRAWVIEW3D, 0);
2604                                 doredraw= 1;
2605                         }
2606                         break;
2607                 case MKEY:
2608                         if (G.qual==LR_SHIFTKEY) {
2609                                 ipo_mirror_menu();
2610                                 break;
2611                         }
2612                         if (G.qual == 0)
2613                                 add_marker(CFRA);
2614                         else if (G.qual == LR_CTRLKEY)
2615                                 rename_marker();
2616                         else 
2617                                 break;
2618                         allqueue(REDRAWTIME, 0);
2619                         allqueue(REDRAWIPO, 0);
2620                         allqueue(REDRAWACTION, 0);
2621                         allqueue(REDRAWNLA, 0);
2622                         allqueue(REDRAWSOUND, 0);
2623                         break;
2624                 case NKEY:
2625                         toggle_blockhandler(sa, IPO_HANDLER_PROPERTIES, UI_PNL_TO_MOUSE);
2626                         doredraw= 1;
2627                         break;
2628                 case OKEY: 
2629                         if (G.qual==LR_SHIFTKEY) 
2630                                 smooth_ipo();
2631                         else
2632                                 clean_ipo();
2633                         break;
2634                 case RKEY:
2635                         if (G.qual==0)
2636                                 ipo_record();
2637                         break;
2638                 case SKEY:
2639                         if (G.qual==LR_SHIFTKEY) {              
2640                                 ipo_snap_menu();
2641                         } 
2642                         else if (G.qual==0)
2643                                 transform_ipo('s');
2644                         break;
2645                 case TKEY:
2646                         if (G.qual==0)
2647                                 set_ipotype();
2648                         break;
2649                 case VKEY:
2650                         if (G.qual==0)
2651                                 sethandles_ipo(HD_VECT);
2652                         break;
2653                 case XKEY:
2654                 case DELKEY:
2655                         val= pupmenu("Erase selected%t|Keys %x1|Markers %x2");
2656                         if (val == 1)
2657                                 del_ipo(0);
2658                         else if (val == 2) {
2659                                 remove_marker();
2660                                 allqueue(REDRAWTIME, 0);
2661                                 allqueue(REDRAWIPO, 0);
2662                                 allqueue(REDRAWACTION, 0);
2663                                 allqueue(REDRAWNLA, 0);
2664                                 allqueue(REDRAWSOUND, 0);
2665                         }
2666                         break;
2667                 }
2668         }
2669
2670         if(doredraw) scrarea_queue_winredraw(sa);
2671 }
2672
2673 void initipo(ScrArea *sa)
2674 {
2675         SpaceIpo *sipo;
2676         
2677         sipo= MEM_callocN(sizeof(SpaceIpo), "initipo");
2678         BLI_addhead(&sa->spacedata, sipo);
2679
2680         sipo->spacetype= SPACE_IPO;
2681         sipo->blockscale= 0.7f;
2682         
2683         /* sipo space loopt van (0,-?) tot (??,?) */
2684         sipo->v2d.tot.xmin= 0.0;
2685         sipo->v2d.tot.ymin= -10.0;
2686         sipo->v2d.tot.xmax= G.scene->r.efra;
2687         sipo->v2d.tot.ymax= 10.0;
2688
2689         sipo->v2d.cur= sipo->v2d.tot;
2690
2691         sipo->v2d.min[0]= 0.01f;
2692         sipo->v2d.min[1]= 0.01f;
2693
2694         sipo->v2d.max[0]= 15000.0f;
2695         sipo->v2d.max[1]= 10000.0f;
2696         
2697         sipo->v2d.scroll= L_SCROLL+B_SCROLL;
2698         sipo->v2d.keeptot= 0;
2699
2700         sipo->blocktype= ID_OB;
2701 }
2702
2703 /* ******************** SPACE: INFO ********************** */
2704
2705 void space_mipmap_button_function(int event) {
2706         set_mipmap(!(U.gameflags & USER_DISABLE_MIPMAP));
2707
2708         allqueue(REDRAWVIEW3D, 0);
2709 }
2710
2711 #if 0
2712 static void space_sound_button_function(int event)
2713 {
2714         int a;
2715         SYS_SystemHandle syshandle;
2716
2717         if ((syshandle = SYS_GetSystem()))
2718         {
2719                 a = (U.gameflags & USER_DISABLE_SOUND);
2720                 SYS_WriteCommandLineInt(syshandle, "noaudio", a);
2721         }
2722 }
2723 #endif
2724
2725
2726 static char *iconfile_menu(void)
2727 {
2728         static char string[512];
2729         char *str = string;
2730         IconFile *ifile;
2731         ListBase *iconfilelist = BIF_iconfile_list();
2732         
2733         str += sprintf(str, "Built-in %%x0|%%l|"); 
2734         
2735         for(ifile=iconfilelist->first; ifile; ifile=ifile->next) {
2736                 str += sprintf(str, "%s %%x%d|", ifile->filename, ifile->index);
2737         }
2738
2739         return string;
2740 }
2741
2742 static void set_userdef_iconfile_cb(void *menuindex, void *unused2)
2743 {
2744         bTheme *btheme= U.themes.first;
2745         IconFile *ifile;
2746         ListBase *iconfilelist = BIF_iconfile_list();
2747         int index = *((int *)menuindex);